/// <summary>
        /// Creates a boolean slot for expression that comes from originalCellNum, i.e., 
        /// the value of the slot is <paramref name="expr"/> and the name is "_from{<paramref name="originalCellNum"/>}", e.g., _from2
        /// </summary>
        internal BooleanProjectedSlot(BoolExpression expr, CqlIdentifiers identifiers, int originalCellNum)
        {
            m_expr = expr;
            m_originalCell = new CellIdBoolean(identifiers, originalCellNum);

            Debug.Assert(!(expr.AsLiteral is CellIdBoolean) ||
                         BoolLiteral.EqualityComparer.Equals((CellIdBoolean)expr.AsLiteral, m_originalCell), "Cellid boolean for the slot and cell number disagree");
        }
        protected override bool IsEqualTo(BoolLiteral right)
        {
            CellIdBoolean rightBoolean = right as CellIdBoolean;

            if (rightBoolean == null)
            {
                return(false);
            }
            return(m_index == rightBoolean.m_index);
        }
        // Modifies _caseStatements and _topLevelWhereClause
        private List<LeftCellWrapper> RemapFromVariables()
        {
            var usedCells = new List<LeftCellWrapper>();
            // remap CellIdBooleans appearing in WHEN clauses and in topLevelWhereClause so the first used cell = 0, second = 1, etc.
            // This ordering is exploited in CQL generation
            var newNumber = 0;
            var literalRemap = new Dictionary<BoolLiteral, BoolLiteral>(BoolLiteral.EqualityIdentifierComparer);
            foreach (var leftCellWrapper in _context.AllWrappersForExtent)
            {
                if (_usedViews.Contains(leftCellWrapper.FragmentQuery))
                {
                    usedCells.Add(leftCellWrapper);
                    var oldNumber = leftCellWrapper.OnlyInputCell.CellNumber;
                    if (newNumber != oldNumber)
                    {
                        literalRemap[new CellIdBoolean(_identifiers, oldNumber)] = new CellIdBoolean(_identifiers, newNumber);
                    }
                    newNumber++;
                }
            }

            if (literalRemap.Count > 0)
            {
                // Remap _from literals in WHERE clause
                _topLevelWhereClause = _topLevelWhereClause.RemapLiterals(literalRemap);

                // Remap _from literals in case statements
                var newCaseStatements = new Dictionary<MemberPath, CaseStatement>();
                foreach (var entry in _caseStatements)
                {
                    var newCaseStatement = new CaseStatement(entry.Key);
                    Debug.Assert(entry.Value.ElseValue == null);
                    foreach (var clause in entry.Value.Clauses)
                    {
                        newCaseStatement.AddWhenThen(clause.Condition.RemapLiterals(literalRemap), clause.Value);
                    }
                    newCaseStatements[entry.Key] = newCaseStatement;
                }
                _caseStatements = newCaseStatements;
            }
            return usedCells;
        }