Public/ObjectManager/New-RelativityObjectQueryCondition.ps1

function New-RelativityObjectQueryCondition
{
    <#
    .SYNOPSIS
    Creates a new query condition for use in Relativity's ObjectManager API based on fields or combined conditions.
 
    .DESCRIPTION
    The New-RelativityObjectQueryCondition function allows for the creation of query conditions to filter data in
    Relativity's ObjectManager API. It supports constructing conditions based on field comparisons or the combination
    of other conditions. The function offers flexibility in specifying the type of comparison for field-based
    conditions and logical operators for combining conditions.
 
    .PARAMETER Field
    Specifies the field name on which the condition will be applied. This parameter is mandatory in the FieldAndValue
    parameter set.
 
    .PARAMETER Value
    Specifies the value to compare against the field. The type of the value must be one of the supported types: Int32,
    Int32[], DateTime, Boolean, Decimal, Decimal[], String, String[], Guid, or Guid[]. This parameter is used in the
    FieldAndValue parameter set.
 
    .PARAMETER LeftCondition
    Specifies the left-hand side condition when combining two conditions. This parameter is mandatory in the
    ConditionAndCondition parameter set.
 
    .PARAMETER RightCondition
    Specifies the right-hand side condition when combining two conditions. This parameter is mandatory in the
    ConditionAndCondition parameter set.
 
    .PARAMETER Not
    A switch parameter that negates the condition. This switch is optional and can be used in both parameter sets.
 
    .PARAMETER And
    A switch parameter that specifies the logical AND operator when combining two conditions. This switch is mandatory
    when combining conditions in the ConditionAndCondition parameter set.
 
    .PARAMETER Or
    A switch parameter that specifies the logical OR operator when combining two conditions. This switch is mandatory
    when combining conditions in the ConditionAndCondition parameter set.
 
    .PARAMETER Eq
    A switch parameter that specifies an equality comparison operator. This switch is used in the FieldAndValue
    parameter set.
 
    .PARAMETER Ne
    A switch parameter that specifies a non-equality comparison operator. This switch is used in the FieldAndValue
    parameter set.
 
    .PARAMETER Gt
    A switch parameter that specifies a greater-than comparison operator. This switch is used in the FieldAndValue
    parameter set.
 
    .PARAMETER Ge
    A switch parameter that specifies a greater-than-or-equal-to comparison operator. This switch is used in the
    FieldAndValue parameter set.
 
    .PARAMETER Lt
    A switch parameter that specifies a less-than comparison operator. This switch is used in the FieldAndValue
    parameter set.
 
    .PARAMETER Le
    A switch parameter that specifies a less-than-or-equal-to comparison operator. This switch is used in the
    FieldAndValue parameter set.
 
    .PARAMETER In
    A switch parameter that specifies that the field's value must be within a specified set. This switch is used in
    the FieldAndValue parameter set.
 
    .PARAMETER MonthOf
    A switch parameter that specifies a comparison to a specific month. This switch is used in the FieldAndValue
    parameter set.
 
    .PARAMETER StartsWith
    A switch parameter that specifies that the field's value must start with a specified string. This switch is used
    in the FieldAndValue parameter set.
 
    .PARAMETER EndsWith
    A switch parameter that specifies that the field's value must end with a specified string. This switch is used in
    the FieldAndValue parameter set.
 
    .PARAMETER Like
    A switch parameter that allows for text content searching. This switch is used in the FieldAndValue parameter set.
 
    .PARAMETER Contains
    A switch parameter that specifies that either a text field's value must contain the specified string or that a
    multiobject or multichoice field value must be within a specified set. This switch is used in the FieldAndValue
    parameter set.
 
    .PARAMETER Intersect
    A switch parameter used to specify that the field's value must intersect with a specified set. This switch is used
    in the FieldAndValue parameter set.
 
    .PARAMETER IsSet
    A switch parameter used to specify that the field must be populated. This switch is used in the FieldAndValue
    parameter set.
 
    .PARAMETER SavedSearch
    A switch parameter used to modify the query to return document objects that are returned by a given saved search.
    This switch is used in the FieldAndValue parameter set.
 
    .PARAMETER View
    A switch parameter used to modify the query to return objects that are returned by a given view. This switch is
    used in the FieldAndValue parameter set.
 
    .PARAMETER Object
    A switch parameter used to modify the query to explicitly search single-object type fields. This switch is used in
    the FieldAndValue parameter set.
 
    .PARAMETER MultiObject
    A switch parameter used to modify the query to explicitly search multi-object type fields. This switch is used in
    the FieldAndValue parameter set.
 
    .PARAMETER Choice
    A switch parameter used to modify the query to explicitly search single-choice type fields. This switch is used in
    the FieldAndValue parameter set.
 
    .PARAMETER MultiChoice used to modify the query to explicitly search multi-choice type fields. This switch is used
    in the FieldAndValue parameter set.
 
    .PARAMETER User
    A switch parameter used to modify the query to explicitly search user type fields. This switch is used in the
    FieldAndValue parameter set.
 
    .EXAMPLE
    $Condition = New-RelativityObjectQueryCondition -Field "ArtifactID" -Eq -Value 1234567
    Creates a condition that checks if the ArtifactID field is equal to 1234567.
 
    .EXAMPLE
    $Condition1 = New-RelativityObjectQueryCondition -Field "SentDate" -Ge -Value ([DateTime] "2021-01-01")
    $Condition2 = New-RelativityObjectQueryCondition -Field "SentDate" -Le -Value ([DateTime] "2021-12-31")
    $Combined = New-RelativityObjectQueryCondition -LeftCondition $Condition1 -RightCondition -And $Condition2
    Combines two conditions to check if the SentDate field falls within the year 2021 using a logical AND.
 
    .EXAMPLE
    $Condition = New-RelativityObjectQueryCondition -Field "Name" -BeginsWith -Value "John%"
    Creates a condition to find records where the Name field starts with "John".
 
    .EXAMPLE
    $Condition1 = New-RelativityObjectQueryCondition -Field "Status" -Eq -Value "Active"
    $Condition2 = New-RelativityObjectQueryCondition -Field "Role" -Eq -Value "Administrator"
    $Combined = New-RelativityObjectQueryCondition -LeftCondition $Condition1 -Or -Not -RightCondition $Condition2
    Creates a condition that checks if either the Status is not 'Active' or the Role is not 'Administrator'.
    #>

    [CmdletBinding()]
    Param
    (
        [Parameter(Mandatory = $true, ParameterSetName = "FieldAndValue")]
        [ValidateNotNullOrEmpty()]
        [String] $Field,
        [Parameter(Mandatory = $false, ParameterSetName = "FieldAndValue")]
        [ValidateScript({
                $AllowedTypes = @(
                    [Int32],
                    [Int32[]],
                    [DateTime],
                    [Boolean],
                    [Decimal],
                    [Decimal[]]
                    [String],
                    [String[]],
                    [Guid],
                    [Guid[]]
                )
                [Boolean] $IsValidType = $false

                if (-not ($_ -is [Array] -and $_.GetType() -eq [Object[]]))
                {
                    foreach ($Type in $AllowedTypes)
                    {
                        if ($_ -is $Type)
                        {
                            $IsValidType = $true
                            break
                        }
                    }
                }

                if (-not $IsValidType)
                {
                    throw "Value must be one of the following types: Int32, Int32[], DateTime, Boolean, Decimal, " +
                    "String, String[], Guid, Guid[]. If you are certain the value matches one of these types, try" +
                    " explicitly casting the value to that type, e.g., [Int32[]] `$Value = @(42, 53)."
                }

                return $IsValidType
            })]
        [Object] $Value,
        [Parameter(Mandatory = $true, ParameterSetName = "ConditionAndCondition")]
        [ValidateNotNullOrEmpty()]
        [RelativityObjectQueryCondition] $LeftCondition,
        [Parameter(Mandatory = $true, ParameterSetName = "ConditionAndCondition")]
        [ValidateNotNullOrEmpty()]
        [RelativityObjectQueryCondition] $RightCondition,
        [Parameter(Mandatory = $false, ParameterSetName = "ConditionAndCondition")]
        [Parameter(Mandatory = $false, ParameterSetName = "FieldAndValue")]
        [Switch] $Not,
        [Parameter(Mandatory = $false, ParameterSetName = "ConditionAndCondition")]
        [Switch] $And,
        [Parameter(Mandatory = $false, ParameterSetName = "ConditionAndCondition")]
        [Switch] $Or,
        [Parameter(Mandatory = $false, ParameterSetName = "FieldAndValue")]
        [Switch] $Eq,
        [Parameter(Mandatory = $false, ParameterSetName = "FieldAndValue")]
        [Switch] $Ne,
        [Parameter(Mandatory = $false, ParameterSetName = "FieldAndValue")]
        [Switch] $Gt,
        [Parameter(Mandatory = $false, ParameterSetName = "FieldAndValue")]
        [Switch] $Ge,
        [Parameter(Mandatory = $false, ParameterSetName = "FieldAndValue")]
        [Switch] $Lt,
        [Parameter(Mandatory = $false, ParameterSetName = "FieldAndValue")]
        [Switch] $Le,
        [Parameter(Mandatory = $false, ParameterSetName = "FieldAndValue")]
        [Switch] $In,
        [Parameter(Mandatory = $false, ParameterSetName = "FieldAndValue")]
        [Switch] $MonthOf,
        [Parameter(Mandatory = $false, ParameterSetName = "FieldAndValue")]
        [Switch] $StartsWith,
        [Parameter(Mandatory = $false, ParameterSetName = "FieldAndValue")]
        [Switch] $EndsWith,
        [Parameter(Mandatory = $false, ParameterSetName = "FieldAndValue")]
        [Switch] $Like,
        [Parameter(Mandatory = $false, ParameterSetName = "FieldAndValue")]
        [Switch] $Contains,
        [Parameter(Mandatory = $false, ParameterSetName = "FieldAndValue")]
        [Switch] $Intersect,
        [Parameter(Mandatory = $false, ParameterSetName = "FieldAndValue")]
        [Switch] $IsSet,
        [Parameter(Mandatory = $false, ParameterSetName = "FieldAndValue")]
        [Switch] $SavedSearch,
        [Parameter(Mandatory = $false, ParameterSetName = "FieldAndValue")]
        [Switch] $View,
        [Parameter(Mandatory = $false, ParameterSetName = "FieldAndValue")]
        [Switch] $Object,
        [Parameter(Mandatory = $false, ParameterSetName = "FieldAndValue")]
        [Switch] $MultiObject,
        [Parameter(Mandatory = $false, ParameterSetName = "FieldAndValue")]
        [Switch] $Choice,
        [Parameter(Mandatory = $false, ParameterSetName = "FieldAndValue")]
        [Switch] $MultiChoice,
        [Parameter(Mandatory = $false, ParameterSetName = "FieldAndValue")]
        [Switch] $User
    )

    Begin
    {
        Write-Verbose "Starting New-RelativityObjectQueryCondition"

        if ($PSCmdlet.ParameterSetName -eq "FieldAndValue")
        {
            # Validate that one comparison operator switch has been specified.
            [Boolean[]] $Operators = @(
                $Eq,
                $Ne,
                $Gt,
                $Ge,
                $Lt,
                $Le,
                $In,
                $MonthOf,
                $StartsWith,
                $EndsWith,
                $Like,
                $Contains,
                $Intersect,
                $IsSet
            )

            [Int32] $TrueOperatorCount = ($Operators | Where-Object { $_ }).Count

            if ($TrueOperatorCount -ne 1)
            {
                throw "Exactly one comparison operator switch must be specified when using the Field and Value " +
                "parameter set."
            }

            # Validate that zero or one keyword switch has been specified.
            [Boolean[]] $Keywords = @(
                $SavedSearch,
                $View,
                $Object,
                $MultiObject,
                $Choice,
                $MultiChoice,
                $User
            )

            [Int32] $TrueKeywordCount = ($Keywords | Where-Object { $_ }).Count

            if ($TrueKeywordCount -gt 1)
            {
                throw "Zero or one keyword switch must be specified when using the Field and Value parameter set."
            }
        }

        if ($PSCmdlet.ParameterSetName -eq "ConditionAndCondition")
        {
            # Validate that one combination operator switch has been specified.
            [Boolean[]] $Operators = @(
                $And,
                $Or
            )

            [Int32] $TrueOperatorCount = ($Operators | Where-Object { $_ }).Count

            if ($TrueOperatorCount -ne 1)
            {
                throw "Exactly one combination operator switch must be specified when using the Condition and " +
                "Condition parameter set."
            }
        }
    }
    Process
    {
        try
        {
            $QueryCondition = $null

            if ($PSCmdlet.ParameterSetName -eq "FieldAndValue")
            {
                # Map the selected comparison operator to an enum we can feed to the RelativityObjectQueryCondition
                # constructor.
                Write-Verbose "Identifying active operator."

                $OperatorMap = @{
                    Eq = [RelativityObjectQueryConditionComparisonOperator]::Eq
                    Ne = [RelativityObjectQueryConditionComparisonOperator]::Ne
                    Gt = [RelativityObjectQueryConditionComparisonOperator]::Gt
                    Ge = [RelativityObjectQueryConditionComparisonOperator]::Ge
                    Lt = [RelativityObjectQueryConditionComparisonOperator]::Lt
                    Le = [RelativityObjectQueryConditionComparisonOperator]::Le
                    In = [RelativityObjectQueryConditionComparisonOperator]::In
                    MonthOf = [RelativityObjectQueryConditionComparisonOperator]::MonthOf
                    StartsWith = [RelativityObjectQueryConditionComparisonOperator]::StartsWith
                    EndsWith = [RelativityObjectQueryConditionComparisonOperator]::EndsWith
                    Like = [RelativityObjectQueryConditionComparisonOperator]::Like
                    Contains = [RelativityObjectQueryConditionComparisonOperator]::Contains
                    Intersect = [RelativityObjectQueryConditionComparisonOperator]::Intersect
                    IsSet = [RelativityObjectQueryConditionComparisonOperator]::IsSet
                }

                $ActiveOperator = $null
                foreach ($Key in $OperatorMap.Keys)
                {
                    if ((Get-Variable -Name $Key -ValueOnly))
                    {
                        [RelativityObjectQueryConditionComparisonOperator] $ActiveOperator = $OperatorMap[$Key]
                        break
                    }
                }

                Write-Verbose "Active operator == '$($ActiveOperator)'."

                # Map the selected keyword to an enum we can feed to the RelativityObjectQueryCondition constructor.
                Write-Verbose "Identifying active keyword."

                $KeywordMap = @{
                    SavedSearch = [RelativityObjectQueryConditionKeyword]::SavedSearch
                    View = [RelativityObjectQueryConditionKeyword]::View
                    Object = [RelativityObjectQueryConditionKeyword]::Object
                    MultiObject = [RelativityObjectQueryConditionKeyword]::MultiObject
                    Choice = [RelativityObjectQueryConditionKeyword]::Choice
                    MultiChoice = [RelativityObjectQueryConditionKeyword]::MultiChoice
                    User = [RelativityObjectQueryConditionKeyword]::User
                }

                $ActiveKeyword = $null
                foreach ($Key in $KeywordMap.Keys)
                {
                    if ((Get-Variable -Name $Key -ValueOnly))
                    {
                        [RelativityObjectQueryConditionKeyword] $ActiveKeyword = $KeywordMap[$Key]
                        break
                    }
                }

                if ($null -eq $ActiveKeyword)
                {
                    Write-Verbose "Active keyword == null."
                }
                else
                {
                    Write-Verbose "Active keyword == '$($ActiveKeyword)'."

                    # Map each keyword to the valid comparison operators associated with it.
                    $VerboseMessage = "Validating '$($ActiveOperator)' is a valid comparison operator for keyword " +
                    "'$($ActiveKeyword)'."
                    Write-Verbose $VerboseMessage

                    $KeywordValidOperators = @{
                        SavedSearch = @([RelativityObjectQueryConditionComparisonOperator]::In)
                        View = @([RelativityObjectQueryConditionComparisonOperator]::In)
                        Object = @(
                            [RelativityObjectQueryConditionComparisonOperator]::Eq,
                            [RelativityObjectQueryConditionComparisonOperator]::Ne,
                            [RelativityObjectQueryConditionComparisonOperator]::In
                        )
                        MultiObject = @(
                            [RelativityObjectQueryConditionComparisonOperator]::Contains,
                            [RelativityObjectQueryConditionComparisonOperator]::Intersect
                        )
                        Choice = @(
                            [RelativityObjectQueryConditionComparisonOperator]::Eq,
                            [RelativityObjectQueryConditionComparisonOperator]::Ne,
                            [RelativityObjectQueryConditionComparisonOperator]::In
                        )
                        MultiChoice = @(
                            [RelativityObjectQueryConditionComparisonOperator]::Contains,
                            [RelativityObjectQueryConditionComparisonOperator]::Intersect
                        )
                        User = @(
                            [RelativityObjectQueryConditionComparisonOperator]::Eq,
                            [RelativityObjectQueryConditionComparisonOperator]::Ne,
                            [RelativityObjectQueryConditionComparisonOperator]::Like
                        )
                    }

                    # Validate the comparison operator associated with the provided keyword.
                    [Boolean] $IsValidOperatorForKeyword = $false
                    [Boolean] $IsValidOperatorForKeyword = ($KeywordValidOperators[$ActiveKeyword.ToString()] |
                            Where-Object { $_ -eq $ActiveOperator }).Count

                    if (-not $IsValidOperatorForKeyword)
                    {
                        [String] $ErrorString = ""
                        $ErrorString += "Comparison operator must be one of the following for the selected keyword: " +
                    (($KeywordValidOperators[$ActiveKeyword.ToString()] |
                                ForEach-Object { $_.ToString() }) -join ", ") + "."

                        throw $ErrorString
                    }

                    Write-Verbose "'$($ActiveOperator)' is a valid comparison operator for the selected keyword."
                }

                # Map each comparison operator to the valid types associated with it.
                $VerboseMessage = "Validating '$($Value.GetType().Name)' is a valid type for operator " +
                "'$($ActiveOperator)'."
                Write-Verbose $VerboseMessage

                $OperatorValidTypes = @{
                    Eq = @([Int32], [DateTime], [Boolean], [Decimal], [String], [Guid])
                    Ne = @([Int32], [DateTime], [Boolean], [Decimal], [String], [Guid])
                    Gt = @([Int32], [DateTime], [Decimal], [String])
                    Ge = @([Int32], [DateTime], [Decimal], [String])
                    Lt = @([Int32], [DateTime], [Decimal], [String])
                    Le = @([Int32], [DateTime], [Decimal], [String])
                    In = @([Int32], [Int32[]], [Decimal], [Decimal[]], [String], [String[]], [Guid], [Guid[]])
                    MonthOf = @([Int32], [String])
                    StartsWith = @([String])
                    EndsWith = @([String])
                    Like = @([String])
                    Contains = @([Int32], [Int32[]], [String], [Guid], [Guid[]])
                    Intersect = @([Int32], [Int32[]])
                }

                # Validate that the type associated with the provided value is an approved type for the operator.
                [Boolean] $IsValidTypeForOperator = $false

                if ($ActiveOperator -ne [RelativityObjectQueryConditionComparisonOperator]::IsSet)
                {
                    [Boolean] $IsValidTypeForOperator = ($OperatorValidTypes[$ActiveOperator.ToString()] |
                            Where-Object { $Value.GetType() -eq $_ }).Count
                }
                elseif ($null -eq $Value)
                {
                    $IsValidTypeForOperator = $true
                }

                if (-not $IsValidTypeForOperator)
                {
                    [String] $ErrorString = ""
                    if ($ActiveOperator -ne [RelativityObjectQueryConditionComparisonOperator]::IsSet)
                    {
                        $ErrorString += "Value must be one of the following types for the selected comparison operator: " +
                    (($OperatorValidTypes[$ActiveOperator.ToString()] | ForEach-Object { $_ }) -join ", ") + "."
                    }
                    else
                    {
                        $ErrorString += "Value must be null for the selected comparison operator."
                    }

                    throw $ErrorString
                }

                Write-Verbose "'$($Value.GetType().Name)' is a valid type for the selected operator."

                if ($null -ne $ActiveKeyword)
                {
                    # Map each keyword to the valid types associated with it.
                    $VerboseMessage = "Validating '$($Value.GetType().Name)' is a valid type for keyword " +
                    "'$($ActiveKeyword)'."
                    Write-Verbose $VerboseMessage

                    $KeywordValidTypes = @{
                        SavedSearch = @([Int32])
                        View = @([Int32])
                        Object = @([Int32], [Int32[]])
                        MultiObject = @([Int32], [Int32[]])
                        Choice = @([Int32], [Int32[]], [Guid], [Guid[]])
                        MultiChoice = @([Int32], [Int32[]], [Guid], [Guid[]])
                        User = @([String])
                    }

                    # Validate that the type associated with the provided value is an approved type for the keyword.
                    [Boolean] $IsValidTypeForKeyword = $false

                    if ($null -eq $ActiveKeyword)
                    {
                        $IsValidTypeForKeyword = $true
                    }
                    else
                    {
                        [Boolean] $IsValidTypeForKeyword = ($KeywordValidTypes[$ActiveKeyword.ToString()] |
                                Where-Object { $Value.GetType() -eq $_ }).Count
                    }

                    if (-not $IsValidTypeForKeyword)
                    {
                        [String] $ErrorString = ""
                        $ErrorString += "Value must be one of the following types for the selected keyword: " +
                    (($KeywordValidTypes[$ActiveKeyword.ToString()] | ForEach-Object { $_ }) -join ", ") + "."

                        throw $ErrorString
                    }

                    Write-Verbose "'$($Value.GetType().Name)' is a valid type for the selected keyword."

                    # Map each keyword to the valid field names associated with it.
                    $VerboseMessage = "Validating '$($Field)' is a valid field name for keyword " +
                    "'$($ActiveKeyword)'."
                    Write-Verbose $VerboseMessage

                    $KeywordValidFields = @{
                        SavedSearch = @("ArtifactID")
                        View = @("ArtifactID")
                    }

                    # Validate that the field name provided is an approved field name for the keyword.
                    [Boolean] $IsValidFieldForKeyword = $false

                    if ($null -eq $ActiveKeyword -or -not ($KeywordValidFields.ContainsKey($ActiveKeyword.ToString())))
                    {
                        $IsValidFieldForKeyword = $true
                    }
                    else
                    {
                        [Boolean] $IsValidFieldForKeyword = ($KeywordValidFields[$ActiveKeyword.ToString()] |
                                Where-Object { $Field -eq $_ }).Count
                    }

                    if (-not $IsValidFieldForKeyword)
                    {
                        [String] $ErrorString = ""
                        $ErrorString += "Field name must be one of the following for the selected keyword: " +
                    (($KeywordValidFields[$ActiveKeyword.ToString()] | ForEach-Object { $_ }) -join ", ") + "."

                        throw $ErrorString
                    }

                    Write-Verbose "'$($Field)' is a valid field name for the selected keyword."
                }

                #Map each operator to the valid values associated with it.
                $VerboseMessage = "Validating Value is valid for operator '$($ActiveOperator)'."
                Write-Verbose $VerboseMessage

                $OperatorValidValues = @{
                    MonthOf = @(
                        [RelativityObjectQueryConditionMonthOf]::January,
                        [RelativityObjectQueryConditionMonthOf]::February,
                        [RelativityObjectQueryConditionMonthOf]::March,
                        [RelativityObjectQueryConditionMonthOf]::April,
                        [RelativityObjectQueryConditionMonthOf]::May,
                        [RelativityObjectQueryConditionMonthOf]::June,
                        [RelativityObjectQueryConditionMonthOf]::July,
                        [RelativityObjectQueryConditionMonthOf]::August,
                        [RelativityObjectQueryConditionMonthOf]::September,
                        [RelativityObjectQueryConditionMonthOf]::October,
                        [RelativityObjectQueryConditionMonthOf]::November,
                        [RelativityObjectQueryConditionMonthOf]::December
                    )
                }

                # Validate that the value provided is an approved value for the operator.
                [Boolean] $IsValidValueForOperator = $false

                if (-not $OperatorValidValues.ContainsKey($ActiveOperator.ToString()))
                {
                    $IsValidValueForOperator = $true
                }
                else
                {
                    [Boolean] $IsValidValueForOperator = ($OperatorValidValues[$ActiveOperator.ToString()] |
                            Where-Object { $Value -eq $_ }).Count
                }

                if (-not $IsValidValueForOperator)
                {
                    [String] $ErrorString = ""
                    $ErrorString += "Value must be one of the following for the selected operator: " +
                (($OperatorValidValues[$ActiveOperator.ToString()] | ForEach-Object { $_ }) -join ", ") + "."

                    throw $ErrorString
                }

                Write-Verbose "Value is valid for the selected operator."

                # Validation checks are passed, construct the RelativityObjectQueryCondition
                $QueryCondition = [RelativityObjectQueryCondition]::New(
                    $Not,
                    $Field,
                    $ActiveOperator,
                    $ActiveKeyword,
                    $Value
                )
            }
            elseif ($PSCmdlet.ParameterSetName -eq "ConditionAndCondition")
            {
                # Map the selected combination operator to an enum we can feed to the RelativityObjectQueryCondition
                # constructor.
                $OperatorMap = @{
                    And = [RelativityObjectQueryConditionCombinationOperator]::And
                    Or = [RelativityObjectQueryConditionCombinationOperator]::Or
                }

                $ActiveOperator = $null
                foreach ($Key in $OperatorMap.Keys)
                {
                    if ((Get-Variable -Name $Key -ValueOnly) -eq $true)
                    {
                        [RelativityObjectQueryConditionCombinationOperator] $ActiveOperator = $OperatorMap[$Key]
                        break
                    }
                }

                $QueryCondition = [RelativityObjectQueryCondition]::New(
                    $LeftCondition,
                    $ActiveOperator,
                    $Not,
                    $RightCondition
                )
            }

            return $QueryCondition
        }
        catch
        {
            Write-Error "An error occurred: $($_.Exception) type: $($_.GetType().FullName)"
            Write-Verbose "Logging parameter values:"

            (Get-Command -Name $PSCmdlet.MyInvocation.InvocationName).Parameters | ForEach-Object {
                $_.Values | ForEach-Object {
                    $Parameter = Get-Variable -Name $_.Name -ErrorAction SilentlyContinue

                    if ($null -ne $Parameter)
                    {
                        Write-Verbose "$($Parameter.Name): $($Parameter.Value)"
                    }
                }
            }

            throw
        }
    }
    End
    {
        Write-Verbose "Completed New-RelativityObjectQueryCondtion"
    }
}