public static void UpdateExchangeAssets(Contract contract)
        {
            bool buy = false;
            if (contract.Collateral < 0)
            {
                buy = true;
            }

            bool corporate = false;
            bool updateAssets = false;
            APICharacter character = UserAccount.CurrentGroup.GetCharacter(contract.OwnerID, ref corporate);
            DateTime assetsEffectiveDate = corporate ? character.Settings.CorpAssetsEffectiveDate :
                character.Settings.CharAssetsEffectiveDate;
            // We only need to worry about updating assets if the last assets update was
            // before the date of the contract (note 'IssueDate' = item exchange completed date)
            if (assetsEffectiveDate.CompareTo(contract.IssueDate) < 0) { updateAssets = true; }

            foreach (ContractItem item in contract.Items)
            {
                if (!buy)
                {
                    long qToFind = item.Quantity;
                    decimal itemBuyPrice = 0;

                    // Look for assets that are marked as 'for sale via contract'
                    AssetList assets = Assets.LoadAssets(
                        UserAccount.CurrentGroup.GetAssetAccessParams(APIDataType.Assets),
                        new List<long>(), item.ItemID, 0, 0, false,
                        (int)AssetStatus.States.ForSaleViaContract, true, true);

                    LookForAssetMatch(contract, updateAssets, ref qToFind, ref itemBuyPrice,
                        assets, false);
                    if (qToFind > 0)
                    {
                        LookForAssetMatch(contract, updateAssets, ref qToFind, ref itemBuyPrice,
                            assets, true);
                    }

                    if (qToFind > 0)
                    {
                        // Can't find any/enough assets 'for sale via contract' so check normal
                        // assets
                        assets = Assets.LoadAssets(
                            UserAccount.CurrentGroup.GetAssetAccessParams(APIDataType.Assets),
                            new List<long>(), item.ItemID, 0, 0, false,
                            (int)AssetStatus.States.Normal, true, false);

                        LookForAssetMatch(contract, updateAssets, ref qToFind, ref itemBuyPrice,
                            assets, false);
                        if (qToFind > 0)
                        {
                            LookForAssetMatch(contract, updateAssets, ref qToFind, ref itemBuyPrice,
                               assets, false);
                        }
                    }

                    long qFound = (item.Quantity - qToFind);
                    item.BuyPrice = (qFound > 0 ? (itemBuyPrice / qFound) : 0);
                }
                else
                {
                    // buy contract, first look for assets that are marked as 'bought via contract'
                    // If there are none then just add the asset directly.
                    long qToFind = item.Quantity;
                    bool updates = false;
                    EMMADataSet.AssetsDataTable assetData = new EMMADataSet.AssetsDataTable();
                    Assets.GetAssetsBoughtViaContract(assetData,
                        UserAccount.CurrentGroup.GetAssetAccessParams(APIDataType.Assets), item.ItemID);

                    foreach (EMMADataSet.AssetsRow asset in assetData)
                    {
                        if (qToFind > 0 && contract.OwnerID == asset.OwnerID)
                        {
                            long deltaQ = Math.Min(asset.Quantity, qToFind);
                            asset.Cost = -1 * item.SellPrice;
                            asset.CostCalc = true;
                            asset.BoughtViaContract = false;
                            updates = true;
                            // Note, we don't update asset quantities because the asset is
                            // clearly already there. (We found it by searching the database)
                            qToFind -= deltaQ;
                        }
                    }
                    if (qToFind > 0)
                    {
                        // We havn't found enough assets to match the contract.
                        // Check assets 'bought via contract' for all corps/chars in the report group
                        foreach (EMMADataSet.AssetsRow asset in assetData)
                        {
                            if (qToFind > 0)
                            {
                                long deltaQ = Math.Min(asset.Quantity, qToFind);
                                asset.Cost = -1 * item.SellPrice;
                                asset.CostCalc = true;
                                asset.BoughtViaContract = false;
                                updates = true;
                                qToFind -= deltaQ;
                            }
                        }
                    }
                    if (qToFind > 0)
                    {
                        // Still havn't managed to match everything. If we're updating assets
                        // (contract date later than asset effective date) then just create
                        // the new asset records directly.
                        // If we're not updating assets then look for an asset of the same type
                        // that does not have it's cost calculated and set that.
                        if (updateAssets)
                        {
                            Assets.ChangeAssets(contract.OwnerID, contract.PickupStationID,
                                item.ItemID, 0, (int)AssetStatus.States.Normal, false, qToFind,
                                -1 * item.SellPrice, true);
                        }
                        else
                        {
                            // Try to find existing assets that are the same type and do not have
                            // a calculated cost.
                            AssetList assets = Assets.LoadAssets(
                                UserAccount.CurrentGroup.GetAssetAccessParams(APIDataType.Assets),
                                new List<long>(), item.ItemID, 0, 0, false,
                                (int)AssetStatus.States.Normal, true, false);
                            foreach (Asset asset in assets)
                            {
                                if (qToFind > 0 && contract.OwnerID == asset.OwnerID &&
                                    (asset.UnitBuyPrice == 0 || !asset.UnitBuyPricePrecalculated))
                                {
                                    long deltaQ = Math.Min(asset.Quantity, qToFind);
                                    Assets.AddAssetToTable(assetData, asset.ID);
                                    EMMADataSet.AssetsRow assetRow = assetData.FindByID(asset.ID);
                                    assetRow.Cost = -1 * item.SellPrice;
                                    assetRow.CostCalc = true;
                                    updates = true;
                                    qToFind -= deltaQ;
                                }
                            }
                            if (qToFind > 0)
                            {
                                foreach (Asset asset in assets)
                                {
                                    if (qToFind > 0 &&
                                        (asset.UnitBuyPrice == 0 || !asset.UnitBuyPricePrecalculated))
                                    {
                                        long deltaQ = Math.Min(asset.Quantity, qToFind);
                                        Assets.AddAssetToTable(assetData, asset.ID);
                                        EMMADataSet.AssetsRow assetRow = assetData.FindByID(asset.ID);
                                        assetRow.Cost = -1 * item.SellPrice;
                                        assetRow.CostCalc = true;
                                        updates = true;
                                        qToFind -= deltaQ;
                                    }
                                }
                            }
                        }
                    }

                    if (updates) { Assets.UpdateDatabase(assetData); }

                }

            }
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="ownerID"></param>
        /// <param name="corpAsset"></param>
        /// <param name="locationID"></param>
        /// <param name="itemID"></param>
        /// <param name="containerID"></param>
        /// <param name="status"></param>
        /// <param name="autoConExclude"></param>
        /// <param name="deltaQuatnity"></param>
        public static void BuyAssets(long ownerID, long stationID, int itemID,
            long deltaQuantity, decimal addedItemsCost, DateTime assetsEffectiveDate,
            DateTime transactionDate)
        {
            long systemID = 0, regionID = 0;

            EveDataSet.staStationsRow station = Stations.GetStation(stationID);
            if (station != null)
            {
                systemID = station.solarSystemID;
                regionID = station.regionID;
            }

            // The situation described in the comments below should never arrise, just ignore it.

            //AssetAccessParams access = new AssetAccessParams(ownerID, !corpAsset, corpAsset);
            //List<AssetAccessParams> accessParams = new List<AssetAccessParams>();
            //accessParams.Add(access);
            //List<int> stationIDs= new List<int>();
            //stationIDs.Add(stationID);
            //List<int> regionIDs = new List<int>();
            //regionIDs.Add(regionID);

            //long currentQ = GetTotalQuantity(accessParams, itemID, stationIDs, regionIDs, false, false);

            // If the current quantity of assets at the station where the buy transaction occurs is less
            // that zero then we must have some transactions marked with the 'calc profit from assets'
            // flag.
            // We can use the value of these bought items to calculate the profit instead.
            // Note: Since this buy transaction must be occuring AFTER the sell transactions, these
            // cannot be the items that were sold. However, they must have gone somewhere and if the
            // quantity is just added to the negative amount already present then the purchase price
            // will effectively be 'lost'. This would be even worse than a little inaccuracy in profit
            // calculations.
            //if (currentQ < 0)
            //{

            //}
            //else
            //{
            //    lock (assetsTableAdapter)
            //    {
            //        assetsTableAdapter.AddQuantity(ownerID, corpAsset, itemID, stationID, systemID,
            //            regionID, (int)AssetStatus.States.Normal, 0, false, deltaQuantity, addedItemsCost, true);
            //    }
            //}

            if (assetsEffectiveDate.CompareTo(transactionDate) < 0)
            {
                // If the transaction occured after the last assets update effetive date then
                // just add the asset to the database.
                lock (assetsTableAdapter)
                {
                    assetsTableAdapter.AddQuantity(ownerID, itemID, stationID, systemID,
                        regionID, (int)AssetStatus.States.Normal, 0, false, deltaQuantity, addedItemsCost, true);
                }
            }
            else
            {
                // NOTE: Ideally, this shouldn't happen but it's here just in case.

                // If the transaction occured before the last assets update effetive date then
                // it must already be in the database.
                // Try and find it to set it's cost.
                long qToFind = deltaQuantity;
                bool updates = false;
                EMMADataSet.AssetsDataTable assetData = new EMMADataSet.AssetsDataTable();
                List<AssetAccessParams> accessParams = new List<AssetAccessParams>();
                accessParams.Add(new AssetAccessParams(ownerID));
                AssetList assets = Assets.LoadAssets(accessParams, new List<long>(), itemID,
                    0, 0, false, (int)AssetStatus.States.Normal, true, false);
                foreach (Asset asset in assets)
                {
                    if (qToFind > 0 && (asset.UnitBuyPrice == 0 || !asset.UnitBuyPricePrecalculated))
                    {
                        long deltaQ = Math.Min(asset.Quantity, qToFind);
                        Assets.AddAssetToTable(assetData, asset.ID);
                        EMMADataSet.AssetsRow assetRow = assetData.FindByID(asset.ID);
                        assetRow.Cost = addedItemsCost;
                        assetRow.CostCalc = true;
                        updates = true;
                        qToFind -= deltaQ;
                    }
                }
                if (updates) { Assets.UpdateDatabase(assetData); }
            }
        }
        private void ProcessAssetsAsMarked()
        {
            try
            {
                _errorCount = 0;
                int counter = 0;
                int total = _gainedAssets.Count + _lostAssets.Count;

                EMMADataSet.AssetsDataTable assetChanges = new EMMADataSet.AssetsDataTable();
                List<Asset> assetsToRemove = new List<Asset>();
                _gainedAssets.ItemFilter = "";
                foreach (Asset gainedAsset in _gainedAssets)
                {
                    long assetID = 0;
                    APICharacter character = UserAccount.CurrentGroup.GetCharacter(gainedAsset.OwnerID);
                    Assets.AssetExists(assetChanges, gainedAsset.OwnerID,
                        gainedAsset.LocationID, gainedAsset.ItemID, gainedAsset.StatusID,
                        gainedAsset.ContainerID != 0, gainedAsset.ContainerID, gainedAsset.IsContainer,
                        false, true, gainedAsset.AutoConExclude, false, gainedAsset.EveItemInstanceID, ref assetID);
                    EMMADataSet.AssetsRow assetRow = assetChanges.FindByID(assetID);

                    counter++;
                    UpdateStatus(counter, total, "Updating gained assets data", "", false);

                    if (assetRow != null)
                    {
                        switch (gainedAsset.ChangeTypeID)
                        {
                            case AssetChangeTypes.ChangeType.Found:
                                assetRow.Cost = 0;
                                assetRow.CostCalc = true;
                                AssetsProduced.Add(gainedAsset);
                                assetsToRemove.Add(gainedAsset);
                                break;
                            //case AssetChangeTypes.ChangeType.Made:
                            //    assetRow.Cost = gainedAsset.UnitBuyPricePrecalculated ? gainedAsset.UnitBuyPrice : 0;
                            //    assetRow.CostCalc = gainedAsset.UnitBuyPricePrecalculated;
                            //    AssetsProduced.Add(gainedAsset);
                            //    assetsToRemove.Add(gainedAsset);
                            //    break;
                            case AssetChangeTypes.ChangeType.WasNeverMissing:
                                assetRow.Cost = 0;
                                assetRow.CostCalc = false;
                                assetsToRemove.Add(gainedAsset);
                                break;
                            case AssetChangeTypes.ChangeType.BoughtViaContract:
                                assetRow.Cost = 0;
                                assetRow.CostCalc = false;
                                assetRow.BoughtViaContract = true;
                                assetsToRemove.Add(gainedAsset);
                                break;
                            case AssetChangeTypes.ChangeType.CancelledContract:
                                List<AssetAccessParams> access = new List<AssetAccessParams>();
                                //bool corporate = false;
                                access.Add(new AssetAccessParams(assetRow.OwnerID));
                                AssetList assets = Assets.LoadAssets(access, new List<long>(), assetRow.ItemID, 0, 0,
                                    false, (int)AssetStatus.States.ForSaleViaContract, true, true);
                                if (assets.Count > 0)
                                {
                                    List<long> matchedAssetsForSale = new List<long>();
                                    long qToFind = assetRow.Quantity;
                                    decimal totalCost = 0;
                                    long costq = 0;
                                    bool costPreCalc = false;
                                    foreach (Asset a in assets)
                                    {
                                        if (qToFind > 0)
                                        {
                                            long deltaQ = Math.Min(a.Quantity, qToFind);
                                            qToFind -= deltaQ;
                                            totalCost += a.UnitBuyPricePrecalculated ? a.TotalBuyPrice : 0;
                                            costq += a.UnitBuyPricePrecalculated ? deltaQ : 0;
                                            if (a.UnitBuyPricePrecalculated) { costPreCalc = true; }
                                            matchedAssetsForSale.Add(a.ID);
                                        }
                                    }

                                    assetRow.Cost = (costq > 0 ? totalCost / costq : 0);
                                    assetRow.CostCalc = costPreCalc;
                                    // We've set the cost of the asset, now to remove the old one(s).
                                    foreach (long matchedAssetID in matchedAssetsForSale)
                                    {
                                        EMMADataSet.AssetsRow assetData = Assets.GetAssetDetail(matchedAssetID);
                                        assetData.Delete();
                                        Assets.UpdateDatabase(assetData);
                                    }
                                }
                                else
                                {
                                    // Can't find old asset so don't know cost.
                                    assetRow.Cost = 0;
                                    assetRow.CostCalc = false;
                                }
                                break;
                            case AssetChangeTypes.ChangeType.Unknown:
                                // Can only be 'unknown' if we're in manufacturing mode.
                                // let the cross check sort it out...
                                break;
                            default:
                                throw new EMMAException(ExceptionSeverity.Error, "Unexpected gained asset change type: '" +
                                    gainedAsset.ChangeType + "' ", true);
                                break;
                        }
                    }
                    else
                    {
                        // This indicates that the asset row was removed due to being marked as unprocessed.
                        // i.e. the gain in items was from -x to 0.
                        // We can happily ignore this.
                        //new EMMAException(ExceptionSeverity.Warning, "Could not find gained asset to update\r\n" +
                        //    "\tOwner: " + gainedAsset.OwnerID + "\r\n\tCorpAsset: " + gainedAsset.CorpAsset +
                        //    "\r\n\tLocation: " + gainedAsset.LocationID + "\r\n\tItem : " + gainedAsset.ItemID +
                        //    "\r\n\tStatus: " + gainedAsset.StatusID + "\r\n\tContainerID: " +
                        //    gainedAsset.ContainerID + "\r\n\tIsContainer: " + gainedAsset.IsContainer.ToString() +
                        //    "\r\n\tAutoConExclude: " + gainedAsset.AutoConExclude.ToString() +
                        //    "\r\n\tEveItemInstanceID: " + gainedAsset.EveItemInstanceID, true);
                        //_errorCount++;
                    }
                }
                foreach (Asset a in assetsToRemove)
                {
                    _gainedAssets.Remove(a);
                }

                assetsToRemove = new List<Asset>();
                _lostAssets.ItemFilter = "";
                foreach (Asset lostAsset in _lostAssets)
                {
                    counter++;
                    UpdateStatus(counter, total, "Updating lost assets data", "", false);

                    switch (lostAsset.ChangeTypeID)
                    {
                        case AssetChangeTypes.ChangeType.ForSaleViaContract:
                            EMMADataSet.AssetsRow assetRow = assetChanges.NewAssetsRow();
                            assetRow.AutoConExclude = true;
                            assetRow.ContainerID = lostAsset.ContainerID;
                            assetRow.CorpAsset = lostAsset.CorpAsset;
                            assetRow.Cost = lostAsset.UnitBuyPricePrecalculated ? lostAsset.UnitBuyPrice : 0;
                            assetRow.CostCalc = lostAsset.UnitBuyPricePrecalculated;
                            assetRow.IsContainer = lostAsset.IsContainer;
                            assetRow.ItemID = lostAsset.ItemID;
                            assetRow.EveItemID = 0;
                            assetRow.LocationID = lostAsset.LocationID;
                            assetRow.OwnerID = lostAsset.OwnerID;
                            assetRow.Processed = false;
                            assetRow.Quantity = lostAsset.Quantity * -1;
                            assetRow.RegionID = lostAsset.RegionID;
                            assetRow.ReprocExclude = true;
                            assetRow.Status = (int)AssetStatus.States.ForSaleViaContract;
                            assetRow.SystemID = lostAsset.SystemID;
                            assetRow.BoughtViaContract = false;
                            assetChanges.AddAssetsRow(assetRow);
                            assetsToRemove.Add(lostAsset);
                            break;
                        case AssetChangeTypes.ChangeType.DestroyedOrUsed:
                            AssetsLost.Add(lostAsset);
                            assetsToRemove.Add(lostAsset);
                            break;
                        case AssetChangeTypes.ChangeType.NotLost:
                            EMMADataSet.AssetsRow assetRow2 = assetChanges.NewAssetsRow();
                            assetRow2.AutoConExclude = lostAsset.AutoConExclude;
                            assetRow2.ContainerID = lostAsset.ContainerID;
                            assetRow2.CorpAsset = lostAsset.CorpAsset;
                            assetRow2.Cost = lostAsset.UnitBuyPricePrecalculated ? lostAsset.UnitBuyPrice : 0;
                            assetRow2.CostCalc = lostAsset.UnitBuyPricePrecalculated;
                            assetRow2.IsContainer = lostAsset.IsContainer;
                            assetRow2.ItemID = lostAsset.ItemID;
                            assetRow2.EveItemID = lostAsset.EveItemInstanceID;
                            assetRow2.LocationID = lostAsset.LocationID;
                            assetRow2.OwnerID = lostAsset.OwnerID;
                            assetRow2.Processed = false;
                            assetRow2.Quantity = lostAsset.Quantity * -1;
                            assetRow2.RegionID = lostAsset.RegionID;
                            assetRow2.ReprocExclude = lostAsset.ReprocessorExclude;
                            assetRow2.Status = (int)AssetStatus.States.Normal;
                            assetRow2.SystemID = lostAsset.SystemID;
                            assetRow2.BoughtViaContract = false;
                            assetChanges.AddAssetsRow(assetRow2);
                            assetsToRemove.Add(lostAsset);
                            break;
                        case AssetChangeTypes.ChangeType.Unknown:
                            // Can only be 'unknown' if we're in manufacturing mode.
                            // let the cross check sort it out...
                            break;
                        default:
                            throw new EMMAException(ExceptionSeverity.Error, "Unexpected lost asset change type: '" +
                                lostAsset.ChangeType + "' ", true);
                            break;
                    }
                }

                foreach (Asset a in assetsToRemove)
                {
                    _lostAssets.Remove(a);
                }
                if (assetChanges.Count > 0)
                {
                    // Put any items that have not actually been lost back into the database.
                    // e.g. an item that is 'for sale via contract' will already have been removed from the
                    // database by this point so we need to create a new record and put it back in.
                    Assets.UpdateDatabase(assetChanges);
                }

                if (UserAccount.Settings.ManufacturingMode)
                {
                    CrossCheckAssetChanges();
                }
            }
            catch (Exception ex)
            {
                EMMAException emmaEx = ex as EMMAException;
                if (emmaEx == null)
                {
                    new EMMAException(ExceptionSeverity.Error, "Problem processing asset changes " +
                        "unacknowledged assets view", ex);
                }
                MessageBox.Show("Problem processing asset changes in unacknowledged assets view:\r\n" +
                    ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
            finally
            {
                UpdateStatus(0, 0, "FinalTasks", "", true);
            }
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="table"></param>
        /// <param name="ownerID"></param>
        /// <param name="corpAsset"></param>
        /// <param name="locationID"></param>
        /// <param name="itemID"></param>
        /// <param name="containerID"></param>
        /// <param name="isContainer"></param>
        /// <param name="assetID"></param>
        /// <returns></returns>
        public static bool AssetExists(EMMADataSet.AssetsDataTable table, long ownerID,
            long locationID, int itemID, int status, bool isContained, long containerID, bool isContainer,
            bool processed, bool ignoreProcessed, bool autoConExclude, bool ignoreAutoConEx,
            long eveItemInstanceID, ref long assetID)
        {
            bool? exists = false;
            long? assetRowID = 0;

            lock (assetsTableAdapter)
            {
                // Have to be carefull here cos the row could well already exist in our table...
                EMMADataSet.AssetsDataTable tmpTable = new EMMADataSet.AssetsDataTable();
                assetsTableAdapter.FillAssetExists(tmpTable, ownerID, locationID, itemID, status,
                    isContained, containerID, isContainer, processed, ignoreProcessed, autoConExclude,
                    ignoreAutoConEx, eveItemInstanceID, ref exists, ref assetRowID);
                long id = assetRowID.HasValue ? assetRowID.Value : 0;
                EMMADataSet.AssetsRow row = table.FindByID(id);
                if (row == null && id != 0)
                {
                    EMMADataSet.AssetsRow dbrow = tmpTable.FindByID(id);
                    table.ImportRow(dbrow);
                }
            }

            assetID = assetRowID.HasValue ? assetRowID.Value : 0;
            return exists.HasValue ? exists.Value : false;
        }
        private void CrossCheckAssetChanges(bool showAndHideData)
        {
            // Only allow one of these checks to be running at once. If a later check
            // attempts to start then it must wait for the current one to finish and then run.
            lock (_lostAssets)
            {
                if (showAndHideData) { HideData(); }

                try
                {
                    EMMADataSet.AssetsDataTable assetChanges = new EMMADataSet.AssetsDataTable();

                    // Try and match one character/corp gains to anothers losses.
                    List<Asset> gAssetsToRemove = new List<Asset>();
                    for (int i = 0; i < _gainedAssets.Count; i++)
                    {
                        UpdateStatus(i, _gainedAssets.Count, "", "", false);

                        Asset gainedAsset = _gainedAssets[i];
                        decimal totalCost = 0;
                        long qRemaining = gainedAsset.Quantity;
                        _lostAssets.ItemFilter = "ItemID = " + gainedAsset.ItemID;
                        List<Asset> assetsToRemove = new List<Asset>();
                        for (int j = 0; j < _lostAssets.FiltredItems.Count; j++)
                        {
                            Asset lostAsset = (Asset)_lostAssets.FiltredItems[j];

                            // If a match is found then use the cost of the lost items to calculate
                            // the cost of the gained items.
                            if (lostAsset.Quantity < 0 && gainedAsset.Quantity > 0)
                            {
                                long deltaQ = Math.Min(qRemaining, Math.Abs(lostAsset.Quantity));
                                totalCost += lostAsset.UnitBuyPrice * deltaQ;
                                qRemaining -= deltaQ;

                                lostAsset.Quantity += deltaQ;
                            }
                            if (lostAsset.Quantity == 0) { assetsToRemove.Add(lostAsset); }
                        }
                        // Remove any lost items that have been accounted for.
                        foreach (Asset a in assetsToRemove)
                        {
                            _lostAssets.FiltredItems.Remove(a);
                        }

                        // If we found some lost items to match against this gained item then
                        // retrieve the gained asset row from the database and recalculate
                        // the cost of the stack.
                        if (qRemaining < gainedAsset.Quantity)
                        {
                            long assetID = 0;
                            APICharacter character = UserAccount.CurrentGroup.GetCharacter(gainedAsset.OwnerID);
                            Assets.AssetExists(assetChanges, gainedAsset.OwnerID,
                                gainedAsset.LocationID, gainedAsset.ItemID, gainedAsset.StatusID,
                                gainedAsset.ContainerID != 0, gainedAsset.ContainerID, gainedAsset.IsContainer,
                                false, true, gainedAsset.AutoConExclude, false, gainedAsset.EveItemInstanceID,
                                ref assetID);
                            EMMADataSet.AssetsRow assetRow = assetChanges.FindByID(assetID);

                            // Note if the asset row is null then it is not in the database.
                            // i.e. we previously had a negative quantity of items here.
                            // In this case, we can try and match the assets with a transaction
                            // market with the 'calcProfitFromAssets' flag.
                            if (assetRow != null)
                            {
                                long totalQ = gainedAsset.Quantity - qRemaining;
                                if (assetRow.Quantity > gainedAsset.Quantity && assetRow.CostCalc)
                                {
                                    // If the asset stack contains more items than our 'gained' record
                                    // and it alreay has a calculated cost then take the stack's current
                                    // cost into account as well.
                                    totalCost += assetRow.Cost * (assetRow.Quantity - gainedAsset.Quantity);
                                    totalQ += assetRow.Quantity - gainedAsset.Quantity;
                                }
                                assetRow.Cost = totalCost / totalQ;
                                assetRow.CostCalc = true;
                            }
                            else
                            {
                            }
                        }

                        gainedAsset.Quantity = qRemaining;
                        if (gainedAsset.Quantity == 0)
                        {
                            gAssetsToRemove.Add(gainedAsset);
                        }
                    }

                    // Remove any gained items that have been accounted for.
                    foreach (Asset a in gAssetsToRemove)
                    {
                        _gainedAssets.Remove(a);
                    }

                    Assets.UpdateDatabase(assetChanges);

                    _lostAssets.ItemFilter = "";
                    _gainedAssets.ItemFilter = "";
                }
                catch (Exception ex)
                {
                    EMMAException emmaEx = ex as EMMAException;
                    if (emmaEx == null)
                    {
                        new EMMAException(ExceptionSeverity.Error, "Problem cross checking asset changes in " +
                            "unacknowledged assets view", ex);
                    }
                    MessageBox.Show("Problem cross checking asset changes in unacknowledged assets view:\r\n" +
                        ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }

                if (showAndHideData) { ShowData(); }
            }
        }