// The maximum NTFS file size is 2^64 bytes, so total number of file clusters can be represented using long
        public void AllocateAdditionalClusters(NTFSVolume volume, long clustersToAllocate)
        {
            ulong desiredStartLCN = (ulong)DataRunSequence.DataLastLCN;
            KeyValuePairList <ulong, long> freeClusterRunList = volume.AllocateClusters(desiredStartLCN, clustersToAllocate);

            for (int index = 0; index < freeClusterRunList.Count; index++)
            {
                ulong runStartLCN = freeClusterRunList[index].Key;
                long  runLength   = freeClusterRunList[index].Value;

                bool mergeWithLastRun = (index == 0 && runStartLCN == desiredStartLCN);
                if (mergeWithLastRun)
                {
                    // we append this run to the last run
                    DataRun lastRun = DataRunSequence[DataRunSequence.Count - 1];
                    lastRun.RunLength += (long)runLength;
                    HighestVCN        += (long)runLength;
                }
                else
                {
                    DataRun run         = new DataRun();
                    ulong   previousLCN = (ulong)DataRunSequence.LastDataRunStartLCN;
                    run.RunOffset = (long)(runStartLCN - previousLCN);
                    run.RunLength = (long)runLength;
                    HighestVCN   += runLength;
                    DataRunSequence.Add(run);
                }
            }
        }
        private void AllocateAdditionalClusters(long clustersToAllocate)
        {
            KeyValuePairList <long, long> freeClusterRunList;
            DataRunSequence dataRuns = m_attributeRecord.DataRunSequence;

            if (dataRuns.Count == 0)
            {
                freeClusterRunList = m_volume.AllocateClusters(clustersToAllocate);
            }
            else
            {
                long desiredStartLCN = dataRuns.DataLastLCN + 1;
                freeClusterRunList = m_volume.AllocateClusters(desiredStartLCN, clustersToAllocate);

                long firstRunStartLCN = freeClusterRunList[0].Key;
                long firstRunLength   = freeClusterRunList[0].Value;
                if (firstRunStartLCN == desiredStartLCN)
                {
                    // Merge with last run
                    DataRun lastRun = dataRuns[dataRuns.Count - 1];
                    lastRun.RunLength            += firstRunLength;
                    m_attributeRecord.HighestVCN += (long)firstRunLength;
                    freeClusterRunList.RemoveAt(0);
                }
            }

            for (int index = 0; index < freeClusterRunList.Count; index++)
            {
                long runStartLCN = freeClusterRunList[index].Key;
                long runLength   = freeClusterRunList[index].Value;

                DataRun run         = new DataRun();
                long    previousLCN = m_attributeRecord.DataRunSequence.LastDataRunStartLCN;
                run.RunOffset = runStartLCN - previousLCN;
                run.RunLength = runLength;
                m_attributeRecord.HighestVCN += runLength;
                m_attributeRecord.DataRunSequence.Add(run);
            }

            // Extend() will update the FileRecord
            m_attributeRecord.AllocatedLength += (ulong)(clustersToAllocate * m_volume.BytesPerCluster);
        }