private DateTime?ReconcileDates(InmateBuffer Row, string RowDateName, DateTime?ItemDate, ref bool IsUpdated)
        {
            DateTime?rowDate = new DateTime?();
            bool     hasDate;

            switch (RowDateName)
            {
            case "DOB":
                hasDate = !Row.DOB_IsNull;
                if (hasDate)
                {
                    rowDate = new DateTime?(Row.DOB);
                }
                break;

            case "PHYSRLSDT":
                hasDate = !Row.PHYSRLSDT_IsNull;
                if (hasDate)
                {
                    rowDate = new DateTime?(Row.PHYSRLSDT);
                }
                break;

            case "RELEASED":
                hasDate = !Row.RELEASED_IsNull;
                if (hasDate)
                {
                    rowDate = new DateTime?(Row.RELEASED);
                }
                break;

            case "BOOKDT":
                hasDate = !Row.BOOKDT_IsNull;
                if (hasDate)
                {
                    rowDate = new DateTime?(Row.BOOKDT);
                }
                break;

            default:
                hasDate = !Row.BOOKED_IsNull;
                if (hasDate)
                {
                    rowDate = new DateTime?(Row.BOOKED);
                }
                break;
            }
            if (hasDate)
            {
                // row date has a value
                if (rowDate != ItemDate)
                {
                    // dates are different
                    IsUpdated = true;
                }
                return(rowDate);
            }
            else
            {
                // row date is null
                if (ItemDate.HasValue)
                {
                    // item date had a value. Set IsUpdated to true
                    IsUpdated = true;
                }
                // item date is also null - no change
                return(null);
            }
        }
        public override void ProcessInput(int inputID, PipelineBuffer buffer)
        {
            //int count = this
            while (buffer.NextRow())
            {
                switch (tableName)
                {
                case "charges":
                    var chargeRow = new ChargeBuffer(buffer, columnDictionary);
                    if (chargesServiceList.Exists(c => c.id.Equals(chargeRow.CHARGENBR)))
                    {
                        // get existing charge
                        var charge      = chargesServiceList.SingleOrDefault(c => c.id.Equals(chargeRow.CHARGENBR));
                        var needsUpdate = false;

                        if (chargeRow.INMATEID != charge.inmateId)
                        {
                            needsUpdate     = true;
                            charge.inmateId = chargeRow.INMATEID;
                        }
                        if (!chargeRow.BONDAMT_IsNull || (charge.bondAmount != null))     // only have to act if one has a value, if both are null we don't need to act
                        {
                            if (chargeRow.BONDAMT_IsNull && (charge.bondAmount != null))  // row is null, charge has value
                            {
                                // update to null
                                needsUpdate       = true;
                                charge.bondAmount = null;
                            }
                            else if (!chargeRow.BONDAMT_IsNull)
                            {
                                if (chargeRow.BONDAMT != charge.bondAmount)     // row has a value and they do not match
                                {
                                    // update to value
                                    needsUpdate       = true;
                                    charge.bondAmount = chargeRow.BONDAMT;
                                }
                                else if (charge.bondAmount == null)     // row has a value and charge is null
                                {
                                    needsUpdate       = true;
                                    charge.bondAmount = chargeRow.BONDAMT;
                                }
                            }
                        }
                        if (chargeRow.BONDTYPE != charge.bondType)
                        {
                            needsUpdate     = true;
                            charge.bondType = chargeRow.BONDTYPE;
                        }
                        if (chargeRow.BONDDESC != charge.bondDescription)
                        {
                            needsUpdate            = true;
                            charge.bondDescription = chargeRow.BONDDESC;
                        }
                        if (chargeRow.COURTDESC != charge.court)
                        {
                            needsUpdate  = true;
                            charge.court = chargeRow.COURTDESC;
                        }
                        if (chargeRow.MICRDESC.Replace('¿', ' ') != charge.charge)
                        {
                            needsUpdate   = true;
                            charge.charge = chargeRow.MICRDESC.Replace('¿', ' ');
                        }

                        if (needsUpdate)
                        {
                            // update Charge
                            var chargeBody = Serialize(charge);
                            UpdateItem(chargeBody, charge.id);
                            updates++;
                        }
                        chargesToSave.Add(charge);
                    }
                    else
                    {
                        // insert new charge
                        var newCharge     = new Charge(chargeRow);
                        var newChargeBody = Serialize(newCharge);
                        InsertItem(newChargeBody, newCharge.id);
                        adds++;
                        chargesToSave.Add(newCharge);
                        ComponentMetaData.FireInformation(0, ComponentMetaData.Name, string.Format("Created Charge {0}", newCharge.id), "", 0, ref pbCancel);
                    }
                    break;

                case "holds":
                    var holdRow = new HoldBuffer(buffer, columnDictionary);
                    if (holdsServiceList.Exists(h => h.id.Equals(string.Format("{0}-{1}", holdRow.ID, holdRow.WARRANTNUM))))
                    {
                        var hold      = holdsServiceList.SingleOrDefault(h => h.id.Equals(string.Format("{0}-{1}", holdRow.ID, holdRow.WARRANTNUM)));
                        var isUpdated = false;

                        if (hold.bondType != holdRow.BONDTYPE)
                        {
                            isUpdated     = true;
                            hold.bondType = holdRow.BONDTYPE;
                        }
                        if (hold.charge != holdRow.CHARGE)
                        {
                            isUpdated   = true;
                            hold.charge = holdRow.CHARGE;
                        }
                        if (hold.comment != holdRow.Comment)
                        {
                            isUpdated    = true;
                            hold.comment = holdRow.Comment;
                        }
                        if (hold.holdAgency != holdRow.HOLDAGENCY)
                        {
                            isUpdated       = true;
                            hold.holdAgency = holdRow.HOLDAGENCY;
                        }
                        if (!holdRow.BONDAMOUNT_IsNull || hold.bondAmount != null)      // at least one has a value
                        {
                            if (holdRow.BONDAMOUNT_IsNull && (hold.bondAmount != null)) // row is null, hold has a value
                            {
                                // set hold to null
                                isUpdated       = true;
                                hold.bondAmount = null;
                            }
                            else if (!holdRow.BONDAMOUNT_IsNull && (holdRow.BONDAMOUNT != hold.bondAmount))     // row has a value and they are not equal
                            {
                                isUpdated       = true;
                                hold.bondAmount = holdRow.BONDAMOUNT;
                            }
                        }

                        if (isUpdated)
                        {
                            // update Hold
                            var holdBody = Serialize(hold);
                            UpdateItem(holdBody, hold.id);
                            updates++;
                            ComponentMetaData.FireInformation(0, ComponentMetaData.Name, string.Format("Updated Hold {0}", hold.id), "", 0, ref pbCancel);
                        }
                        holdsToSave.Add(hold);
                    }
                    else
                    {
                        // insert hold
                        var newHold     = new Hold(holdRow);
                        var newHoldBody = Serialize(newHold);
                        InsertItem(newHoldBody, newHold.id);
                        adds++;
                        holdsToSave.Add(newHold);
                        ComponentMetaData.FireInformation(0, ComponentMetaData.Name, string.Format("Created Hold {0}", newHold.id), "", 0, ref pbCancel);
                    }
                    break;

                case "inmates":
                default:
                    var inmateRow = new InmateBuffer(buffer, columnDictionary);
                    if (inmatesServiceList.Exists(i => i.id.Equals(inmateRow.INMATEID)))
                    {
                        List <string> updateStr = new List <string>();
                        Inmate        item      = inmatesServiceList.SingleOrDefault(i => i.id.Equals(inmateRow.INMATEID));
                        var           isUpdated = false;
                        if (item.lastName != inmateRow.LASTNM)
                        {
                            isUpdated     = true;
                            item.lastName = inmateRow.LASTNM;
                        }
                        if (item.firstName != inmateRow.FIRSTNM)
                        {
                            isUpdated = true;
                            updateStr.Add("FirstName");
                            item.firstName = inmateRow.FIRSTNM;
                        }
                        if (item.middleName != inmateRow.MIDDLENM)
                        {
                            isUpdated = true;
                            updateStr.Add("MiddleName");
                            item.middleName = inmateRow.MIDDLENM;
                        }
                        if (item.bookedDate != inmateRow.BOOKDT)
                        {
                            isUpdated = true;
                            updateStr.Add("BookDt");
                            item.bookedDate = inmateRow.BOOKDT;
                            item.booked     = inmateRow.BOOKED;
                        }

                        if (item.bookingId != inmateRow.BOOKNBR)
                        {
                            isUpdated = true;
                            updateStr.Add("BookNbr");
                            item.bookingId = inmateRow.BOOKNBR;
                        }

                        // set or update inmate image
                        var webSvcImage = GetInmateImage(inmateRow.INMATEID, inmateRow.BOOKNBR);
                        if (item.inmateImage != webSvcImage)
                        {
                            isUpdated = true;
                            updateStr.Add("InmateImage");
                            item.inmateImage = webSvcImage;
                        }
                        // TODO: get Image from Service
                        item.birthDate   = ReconcileDates(inmateRow, "DOB", item.birthDate, ref isUpdated);
                        item.releaseDate = ReconcileDates(inmateRow, "PHYSRLSDT", item.releaseDate, ref isUpdated);
                        item.released    = ReconcileDates(inmateRow, "RELEASED", item.released, ref isUpdated);

                        if (item.gender != inmateRow.GENDERCD)
                        {
                            isUpdated = true;
                            updateStr.Add("GenderCd");
                            item.gender = inmateRow.GENDERCD;
                        }
                        if (item.jailLocation != inmateRow.FACILITYDESC)
                        {
                            isUpdated = true;
                            updateStr.Add("FacilityDesc");
                            item.jailLocation = inmateRow.FACILITYDESC;
                        }
                        if (!(inmateRow.ACTIVEHOLDS_IsNull && item.activeHolds == null))     // both have values
                        {
                            if (inmateRow.ACTIVEHOLDS_IsNull && item.activeHolds != null)    // row is null and item has value
                            {
                                isUpdated = true;
                                updateStr.Add("ActiveHolds");
                                item.activeHolds = null;
                            }
                            else if (!inmateRow.ACTIVEHOLDS_IsNull && (item.activeHolds != inmateRow.ACTIVEHOLDS))     // row is not null and values not the same
                            {
                                isUpdated = true;
                                updateStr.Add("ActiveHolds");
                                item.activeHolds = inmateRow.ACTIVEHOLDS;
                            }
                        }
                        if (isUpdated)
                        {
                            // TODO: update item on service
                            var inmateBody = Serialize(item);
                            UpdateItem(inmateBody, item.id);
                            updates++;
                            var updated = string.Join(", ", updateStr.ToArray());
                            ComponentMetaData.FireInformation(0, ComponentMetaData.Name, string.Format("Updated Inmate {0} with {1}", item.id, updated), "", 0, ref pbCancel);
                        }
                        inmatesToSave.Add(item);
                    }
                    else
                    {
                        // insert item
                        var newInmate = new Inmate(inmateRow);
                        newInmate.inmateImage = GetInmateImage(inmateRow.INMATEID, inmateRow.BOOKNBR);
                        var newInmateBody = Serialize(newInmate);
                        InsertItem(newInmateBody, newInmate.id);
                        adds++;
                        ComponentMetaData.FireInformation(0, ComponentMetaData.Name, string.Format("Created Inmate {0}", inmateRow.INMATEID), "", 0, ref pbCancel);
                        inmatesToSave.Add(newInmate);
                    }
                    break;
                }
            }
        }