]> git.mxchange.org Git - core.git/blobdiff - framework/main/classes/file_directories/binary/class_BaseBinaryFile.php
Continued:
[core.git] / framework / main / classes / file_directories / binary / class_BaseBinaryFile.php
index 187ac493e0e64213d735ec799dab392f508b6deb..cb53584ff4af7017cf99723c2cd6686c4d1323c6 100644 (file)
@@ -4,14 +4,20 @@ namespace Org\Mxchange\CoreFramework\Filesystem\File;
 
 // Import framework stuff
 use Org\Mxchange\CoreFramework\Bootstrap\FrameworkBootstrap;
+use Org\Mxchange\CoreFramework\EntryPoint\ApplicationEntryPoint;
 use Org\Mxchange\CoreFramework\Factory\Object\ObjectFactory;
-use Org\Mxchange\CoreFramework\Filesystem\Block;
-use Org\Mxchange\CoreFramework\Filesystem\Block\CalculatableBlock;
 use Org\Mxchange\CoreFramework\Filesystem\File\BaseAbstractFile;
+use Org\Mxchange\CoreFramework\Filesystem\FilePointer;
+use Org\Mxchange\CoreFramework\Generic\FrameworkInterface;
+use Org\Mxchange\CoreFramework\Middleware\Debug\DebugMiddleware;
+use Org\Mxchange\CoreFramework\Traits\Index\IndexableTrait;
+use Org\Mxchange\CoreFramework\Traits\Stack\StackableTrait;
 
 // Import SPL stuff
 use \BadMethodCallException;
 use \InvalidArgumentException;
+use \LogicException;
+use \OutOfBoundsException;
 use \SplFileInfo;
 use \UnexpectedValueException;
 
@@ -20,7 +26,7 @@ use \UnexpectedValueException;
  *
  * @author             Roland Haeder <webmaster@ship-simu.org>
  * @version            0.0.0
- * @copyright  Copyright (c) 2007, 2008 Roland Haeder, 2009 - 2020 Core Developer Team
+ * @copyright  Copyright (c) 2007, 2008 Roland Haeder, 2009 - 2023 Core Developer Team
  * @license            GNU GPL 3.0 or any newer version
  * @link               http://www.ship-simu.org
  *
@@ -37,68 +43,15 @@ use \UnexpectedValueException;
  * You should have received a copy of the GNU General Public License
  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  */
-abstract class BaseBinaryFile extends BaseAbstractFile {
-       /**
-        * Separator for header data
-        */
-       const SEPARATOR_HEADER_DATA = 0x01;
-
-       /**
-        * Separator header->entries
-        */
-       const SEPARATOR_HEADER_ENTRIES = 0x02;
-
-       /**
-        * Separator group->hash
-        */
-       const SEPARATOR_GROUP_HASH = 0x03;
-
-       /**
-        * Separator hash->value
-        */
-       const SEPARATOR_HASH_VALUE = 0x04;
-
-       /**
-        * Separator entry->entry
-        */
-       const SEPARATOR_ENTRIES = 0x05;
-
-       /**
-        * Separator type->position
-        */
-       const SEPARATOR_TYPE_POSITION = 0x06;
-
-       /**
-        * Length of count
-        */
-       const LENGTH_COUNT = 20;
-
-       /**
-        * Length of position
-        */
-       const LENGTH_POSITION = 20;
-
-       /**
-        * Length of group
-        */
-       const LENGTH_GROUP = 10;
-
-       /**
-        * Maximum length of entry type
-        */
-       const LENGTH_TYPE = 20;
-
-       //***** Array elements for 'gaps' array *****
+abstract class BaseBinaryFile extends BaseAbstractFile implements BinaryFile {
+       // Load traits
+       use StackableTrait;
+       use IndexableTrait;
 
        /**
-        * Start of gap
+        * Configuration cache
         */
-       const GAPS_INDEX_START = 'start';
-
-       /**
-        * End of gap
-        */
-       const GAPS_INDEX_END = 'end';
+       private static $configCache = [];
 
        /**
         * Current seek position
@@ -135,11 +88,6 @@ abstract class BaseBinaryFile extends BaseAbstractFile {
         */
        private $currentBlock = '';
 
-       /**
-        * An instance of a Block class
-        */
-       private $blockInstance = NULL;
-
        /**
         * Protected constructor
         *
@@ -148,75 +96,53 @@ abstract class BaseBinaryFile extends BaseAbstractFile {
         */
        protected function __construct (string $className) {
                // Call parent constructor
+               /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage(sprintf('BASE-BINARY-FILE: className=%s - CALLED!', $className));
                parent::__construct($className);
 
-               // Init counters and gaps array
-               $this->initCountersGapsArray();
+               // Trace message
+               /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage('FRAMEWORK-DIRECTORY-POINTER: EXIT!');
        }
 
        /**
-        * Setter for Block instance
+        * Setter for backBuffer field
         *
-        * @param       $blockInstance  An instance of an Block class
+        * @param       $backBuffer             Characters to "store" in back-buffer
         * @return      void
         */
-       protected final function setBlockInstance (Block $blockInstance) {
-               $this->blockInstance = $blockInstance;
+       private function setBackBuffer (string $backBuffer) {
+               /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage(sprintf('BASE-BINARY-FILE: Setting backBuffer(%d)=%s - CALLED!', strlen($backBuffer), $backBuffer));
+               $this->backBuffer = $backBuffer;
        }
 
        /**
-        * Getter for Block instance
+        * Getter for backBuffer field
         *
-        * @return      $blockInstance  An instance of an Block class
+        * @return      $backBuffer             Characters "stored" in back-buffer
         */
-       public final function getBlockInstance () {
-               return $this->blockInstance;
+       private function getBackBuffer () {
+               /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage(sprintf('BASE-BINARY-FILE: Getting this->backBuffer(%d)=%s - CALLED!', strlen($this->backBuffer), $this->backBuffer));
+               return $this->backBuffer;
        }
 
        /**
-        * Checks whether the abstracted file only contains gaps by counting all
-        * gaps' bytes together and compare it to total length.
+        * Setter for current field
         *
-        * @return      $isGapsOnly             Whether the abstracted file only contains gaps
+        * @param       $current        Characters to set a currently loaded block
+        * @return      void
         */
-       private function isFileOnlyGaps () {
-               // Count every gap
-               /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('BASE-BINARY-FILE: CALLED!');
-               $gapsSize = 0;
-               foreach ($this->gaps as $gap) {
-                       // Calculate size of found gap: end-start including both
-                       $gapsSize += ($gap[self::GAPS_INDEX_END] - $gap[self::GAPS_INDEX_START]);
-               }
-
-               // Total gap size + header size must be same as file size
-               /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('BASE-BINARY-FILE: gapsSize=%s,this->headerSize=%s', $gapsSize, $this->getHeaderSize()));
-               $isGapsOnly = (($this->getHeaderSize() + $gapsSize) == $this->getFileSize());
-
-               // Return status
-               /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('BASE-BINARY-FILE: isGapsOnly=%d - EXIT!', intval($isGapsOnly)));
-               return $isGapsOnly;
+       private function setCurrentBlock (string $currentBlock) {
+               /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage(sprintf('BASE-BINARY-FILE: Setting currentBlock(%d)=%s - CALLED!', strlen($currentBlock), $currentBlock));
+               $this->currentBlock = $currentBlock;
        }
 
        /**
-        * Initializes counter for valid entries, arrays for damaged entries and
-        * an array for gap seek positions. If you call this method on your own,
-        * please re-analyze the file structure. So you are better to call
-        * analyzeFile() instead of this method.
+        * Gets currently read data
         *
-        * @return      void
+        * @return      $current        Currently read data
         */
-       public function initCountersGapsArray () {
-               // Init counter and seek position to header size
-               /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('BASE-BINARY-FILE: CALLED!');
-               $this->setCounter(0);
-               $this->setSeekPosition($this->getHeaderSize());
-
-               // Init arrays
-               $this->gaps = [];
-               $this->damagedEntries = [];
-
-               // Trace message
-               /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('BASE-BINARY-FILE: CALLED!');
+       public function getCurrentBlock () {
+               /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage(sprintf('BASE-BINARY-FILE: Getting this->currentBlock(%d)=%s - CALLED!', strlen($this->currentBlock), $this->currentBlock));
+               return $this->currentBlock;
        }
 
        /**
@@ -225,7 +151,7 @@ abstract class BaseBinaryFile extends BaseAbstractFile {
         * @return      $totalEntries   Size of file header
         */
        public final function getHeaderSize () {
-               // Get it
+               /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage(sprintf('BASE-BINARY-FILE: Getting this->headerSize=%d - CALLED!', $this->headerSize));
                return $this->headerSize;
        }
 
@@ -236,7 +162,7 @@ abstract class BaseBinaryFile extends BaseAbstractFile {
         * @return      void
         */
        public final function setHeaderSize (int $headerSize) {
-               // Set it
+               /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage(sprintf('BASE-BINARY-FILE: Setting headerSize=%d - CALLED!', $headerSize));
                $this->headerSize = $headerSize;
        }
 
@@ -267,7 +193,7 @@ abstract class BaseBinaryFile extends BaseAbstractFile {
         * @return      $seekPosition   Current seek position (stored here in object)
         */
        public final function getSeekPosition () {
-               /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('BASE-BINARY-FILE: Getting this->seekPosition=%d - CALLED!', $this->seekPosition));
+               /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage(sprintf('BASE-BINARY-FILE: Getting this->seekPosition=%d - CALLED!', $this->seekPosition));
                return $this->seekPosition;
        }
 
@@ -278,26 +204,112 @@ abstract class BaseBinaryFile extends BaseAbstractFile {
         * @return      void
         */
        protected final function setSeekPosition (int $seekPosition) {
-               /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('BASE-BINARY-FILE: Setting seekPosition=%d - CALLED!', $seekPosition));
+               /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage(sprintf('BASE-BINARY-FILE: Setting seekPosition=%d - CALLED!', $seekPosition));
                $this->seekPosition = $seekPosition;
        }
 
        /**
-        * Updates seekPosition attribute from file to avoid to much access on file.
+        * Checks whether the abstracted file only contains gaps by counting all
+        * gaps' bytes together and compare it to total length.
+        *
+        * @return      $isGapsOnly             Whether the abstracted file only contains gaps
+        * @throws      OutOfBoundsException    If calculated file size is larger than actual
+        */
+       public function isFileGapsOnly () {
+               // Count every gap
+               /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage('BASE-BINARY-FILE: CALLED!');
+               $gapsSize = 0;
+               /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugMessage(sprintf('BASE-BINARY-FILE: this->gaps()=%d', count($this->gaps)));
+               foreach ($this->gaps as $gap) {
+                       // Calculate size of found gap: end-start including both
+                       /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugMessage(sprintf('BASE-BINARY-FILE: gap[%s]=%d,ga[%s]=%d', BinaryFile::GAPS_INDEX_START, $gap[BinaryFile::GAPS_INDEX_START], BinaryFile::GAPS_INDEX_END, $gap[BinaryFile::GAPS_INDEX_END]));
+                       $gapsSize += ($gap[BinaryFile::GAPS_INDEX_END] - $gap[BinaryFile::GAPS_INDEX_START]);
+
+                       // Debug message
+                       /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugMessage(sprintf('BASE-BINARY-FILE: gapsSize=%d', $gapsSize));
+               }
+
+               // Total gap size + header size + 1 must be same as file size
+               /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugMessage(sprintf('BASE-BINARY-FILE: gapsSize=%d,this->headerSize=%d,this->fileSize=%d', $gapsSize, $this->getHeaderSize(), $this->getFileSize()));
+               $determinedFileSize = ($gapsSize + $this->getHeaderSize() + 1);
+
+               // Should not be more!
+               /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugMessage(sprintf('BASE-BINARY-FILE: determinedFileSize=%d,this->fileSize=%d', $determinedFileSize, $this->getFileSize()));
+               if ($determinedFileSize > $this->getFileSize()) {
+                       // Should not happen
+                       throw new OutOfBoundsException(sprintf('determinedFileSize=%d is larger than this->fileSize=%d', $determinedFileSize, $this->getFileSize()));
+               }
+
+               // Is it same?
+               $isGapsOnly = ($determinedFileSize == $this->getFileSize());
+
+               // Return flag
+               /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage(sprintf('BASE-BINARY-FILE: isGapsOnly=%d - EXIT!', intval($isGapsOnly)));
+               return $isGapsOnly;
+       }
+
+       /**
+        * Marks whole file as gaps-only (freshly created file
         *
+        * @param       $type   Type of file
+        * @param       $minimumBlockLength             Minimum block length
         * @return      void
         */
-       public function updateSeekPosition () {
-               // Get key (= seek position)
-               /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('BASE-BINARY-FILE: CALLED!');
-               $seekPosition = $this->key();
+       private function markFileGapsOnly (string $type, int $minimumBlockLength) {
+               // Is config cache there?
+               /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage(sprintf('BASE-BINARY-FILE: type=%s,minimumBlockLength=%d - CALLED!', $type, $minimumBlockLength));
+               if (!isset(self::$configCache[$type . '_pre_allocate_count'])) {
+                       // Then set it
+                       self::$configCache[$type . '_pre_allocate_count'] = FrameworkBootstrap::getConfigurationInstance()->getConfigEntry($type . '_pre_allocate_count');
+               }
 
-               // And set it here
-               /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('BASE-BINARY-FILE: seekPosition=%d', $seekPosition));
-               $this->setSeekPosition($seekPosition);
+               // Very simple to do ...
+               /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugMessage(sprintf('BASE-BINARY-FILE: self:configCache[%s_pre_allocate_count]()=%d', count(self::$configCache[$type . '_pre_allocate_count'])));
+               for ($idx = 0; $idx < self::$configCache[$type . '_pre_allocate_count']; $idx++) {
+                       // Calculate start/end positions
+                       $startPosition = $idx * $minimumBlockLength;
+                       $endPosition = $idx * $minimumBlockLength + $minimumBlockLength;
+
+                       // Mark start and end position as gap
+                       /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage(sprintf('BASE-BINARY-FILE: Invoking this->addGap(%d, %d) ...', $startPosition, $endPosition));
+                       $this->addGap($startPosition, $endPosition);
+               }
+
+               // Trace message
+               /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage('BASE-BINARY-FILE: EXIT!');
+       }
+
+       /**
+        * Adds a gap for given start and end position
+        *
+        * @param       $startPosition  Start seek position
+        * @param       $endPosition    End seek position
+        * @return      void
+        */
+       private function addGap(int $startPosition, int $endPosition) {
+               // Push to gaps array
+               /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage(sprintf('BASE-BINARY-FILE: startPosition=%d,endPosition=%d - CALLED!', $startPosition, $endPosition));
+               array_push($this->gaps, [
+                       BinaryFile::GAPS_INDEX_START  => $startPosition,
+                       BinaryFile::GAPS_INDEX_END    => $endPosition,
+               ]);
+
+               // Trace message
+               /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage('BASE-BINARY-FILE: EXIT!');
+       }
+
+       /**
+        * Initializes the back-buffer by setting it to an empty string.
+        *
+        * @return      void
+        */
+       private function initBackBuffer () {
+               // Simply call the setter
+               /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage('BASE-BINARY-FILE: CALLED!');
+               $this->setBackBuffer('');
 
                // Trace message
-               /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('BASE-BINARY-FILE: EXIT!');
+               /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage('BASE-BINARY-FILE: EXIT!');
        }
 
        /**
@@ -309,22 +321,22 @@ abstract class BaseBinaryFile extends BaseAbstractFile {
         */
        protected function rewindUpdateSeekPosition (bool $flushHeader = false) {
                // Seek to beginning of file
-               /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('BASE-BINARY-FILE: flushHeader=%d - CALLED!', intval($flushHeader)));
+               /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage(sprintf('BASE-BINARY-FILE: flushHeader=%d - CALLED!', intval($flushHeader)));
                $this->rewind();
 
                // And update seek position ...
-               /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('BASE-BINARY-FILE: Calling this->updateSeekPosition() ...');
+               /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage('BASE-BINARY-FILE: Invoking this->updateSeekPosition() ...');
                $this->updateSeekPosition();
 
                // Flush headers?
                if ($flushHeader) {
                        // ... to write it back into the file
-                       /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('BASE-BINARY-FILE: Calling this->flushFileHeader() ...');
+                       /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage('BASE-BINARY-FILE: Invoking this->flushFileHeader() ...');
                        $this->flushFileHeader();
                }
 
                // Trace message
-               /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('BASE-BINARY-FILE: EXIT!');
+               /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage('BASE-BINARY-FILE: EXIT!');
        }
 
        /**
@@ -334,108 +346,133 @@ abstract class BaseBinaryFile extends BaseAbstractFile {
         */
        protected function seekToOldPosition () {
                // Seek to currently ("old") saved position
-               /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('BASE-BINARY-FILE: CALLED!');
-               $this->seek($this->getSeekPosition());
+               /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage('BASE-BINARY-FILE: CALLED!');
+               $this->seek($this->determineSeekPosition());
 
                // Trace message
-               /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('BASE-BINARY-FILE: EXIT!');
+               /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage('BASE-BINARY-FILE: EXIT!');
        }
 
        /**
-        * Checks whether the block separator has been found
+        * Initializes this file class
         *
-        * @param       $str            String to look in
-        * @return      $isFound        Whether the block separator has been found
-        * @throws      InvalidArgumentException        If a parameter is not valid
+        * @param       $fileInfoInstance       An instance of a SplFileInfo class
+        * @return      void
         */
-       public static function isBlockSeparatorFound (string $str) {
-               // Validate parameter
-               /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('BASE-BINARY-FILE: str=%s - CALLED!', $str));
-               if (empty($str)) {
-                       // Throw IAE
-                       throw new InvalidArgumentException('Parameter "str" is empty');
-               }
+       protected function initFile (SplFileInfo $fileInfoInstance) {
+               // Get a file i/o pointer instance
+               /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage(sprintf('BASE-BINARY-FILE: fileInfoInstance[%s]=%s - CALLED!', get_class($fileInfoInstance), $fileInfoInstance));
+               $pointerInstance = ObjectFactory::createObjectByConfiguredName('file_raw_input_output_class', array($fileInfoInstance));
 
-               // Determine it
-               $isFound = (strpos($str, chr(self::SEPARATOR_ENTRIES)) !== false);
+               // ... and set it here
+               /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugMessage(sprintf('BASE-BINARY-FILE: Setting pointerInstance=%s ...', $pointerInstance->__toString()));
+               $this->setPointerInstance($pointerInstance);
 
-               // Return result
-               /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('BASE-BINARY-FILE: isFound=%d - EXIT!', intval($isFound)));
-               return $isFound;
+               // Trace message
+               /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage('BASE-BINARY-FILE: EXIT!');
        }
 
        /**
-        * Initializes the back-buffer by setting it to an empty string.
+        * Marks the currently loaded block as empty (with length of the block)
         *
+        * @param       $length         Length of the block
         * @return      void
+        * @throws      InvalidArgumentException        If a parameter is invalid
         */
-       private function initBackBuffer () {
-               // Simply call the setter
-               /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('BASE-BINARY-FILE: CALLED!');
-               $this->setBackBuffer('');
+       protected function markCurrentBlockAsEmpty (int $length) {
+               // Validate parameter
+               /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage(sprintf('BASE-BINARY-FILE: length=%d - CALLED!', $length));
+               if ($length < 1) {
+                       // Length cannot below one
+                       throw new InvalidArgumentException(sprintf('length=%d is not valid', $length), FrameworkInterface::EXCEPTION_INVALID_ARGUMENT);
+               }
+
+               // Get current seek position
+               $currentPosition = $this->determineSeekPosition();
+
+               // Now add it as gap entry
+               /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage(sprintf('BASE-BINARY-FILE: Invoking this->addGap(%d, %d) ..', ($currentPosition - $length), $currentPosition));
+               $this->addGap(($currentPosition - $length), $currentPosition);
 
                // Trace message
-               /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('BASE-BINARY-FILE: EXIT!');
+               /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage('BASE-BINARY-FILE: EXIT!');
        }
 
        /**
-        * Setter for backBuffer field
+        * Initializes counter for valid entries, arrays for damaged entries and
+        * an array for gap seek positions. If you call this method on your own,
+        * please re-analyze the file structure. So you are better to call
+        * analyzeFileStructure() instead of this method.
         *
-        * @param       $backBuffer             Characters to "store" in back-buffer
         * @return      void
         */
-       private function setBackBuffer (string $backBuffer) {
-               // ... and set it
-               $this->backBuffer = $backBuffer;
-       }
+       public function initCountersGapsArray () {
+               // Init counter and seek position to header size
+               /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage('BASE-BINARY-FILE: Invoking this->determineSeekPosition() - CALLED!');
+               $seekPosition = $this->getSeekPosition();
 
-       /**
-        * Getter for backBuffer field
-        *
-        * @return      $backBuffer             Characters "stored" in back-buffer
-        */
-       private function getBackBuffer () {
-               return $this->backBuffer;
+               // Set counter
+               /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugMessage(sprintf('BASE-BINARY-FILE: seekPosition=%d', $seekPosition));
+               $this->setCounter(0);
+
+               // Get header size
+               $headerSize = $this->getHeaderSize();
+
+               // Set it
+               /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugMessage(sprintf('BASE-BINARY-FILE: Setting this->seekPosition=%d ...', $headerSize));
+               $this->setSeekPosition($headerSize);
+
+               // Init arrays
+               $this->gaps = [];
+               $this->damagedEntries = [];
+
+               // Seek back to old position
+               /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage(sprintf('BASE-BINARY-FILE: Invoking this->seek(%d) ...', $seekPosition));
+               $this->seek($seekPosition);
+
+               // Trace message
+               /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage('BASE-BINARY-FILE: EXIT!');
        }
 
        /**
-        * Setter for currentBlock field
+        * Updates seekPosition attribute from file to avoid to much access on file.
         *
-        * @param       $currentBlock   Characters to set a currently loaded block
         * @return      void
         */
-       private function setCurrentBlock (string $currentBlock) {
-               // ... and set it
-               $this->currentBlock = $currentBlock;
-       }
+       public function updateSeekPosition () {
+               // Get key (= seek position)
+               /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage('BASE-BINARY-FILE: CALLED!');
+               $seekPosition = $this->determineSeekPosition();
 
-       /**
-        * Gets currently read data
-        *
-        * @return      $current        Currently read data
-        */
-       public function getCurrentBlock () {
-               // Return it
-               return $this->currentBlock;
+               // And set it here
+               /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugMessage(sprintf('BASE-BINARY-FILE: seekPosition=%d', $seekPosition));
+               $this->setSeekPosition($seekPosition);
+
+               // Trace message
+               /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage('BASE-BINARY-FILE: EXIT!');
        }
 
        /**
-        * Initializes this file class
+        * Checks whether the block separator has been found
         *
-        * @param       $fileInfoInstance       An instance of a SplFileInfo class
-        * @return      void
+        * @param       $str            String to look in
+        * @return      $isFound        Whether the block separator has been found
+        * @throws      InvalidArgumentException        If a parameter is not valid
         */
-       protected function initFile (SplFileInfo $fileInfoInstance) {
-               // Get a file i/o pointer instance
-               /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('BASE-BINARY-FILE: fileInfoInstance[%s]=%s - CALLED!', get_class($fileInfoInstance), $fileInfoInstance));
-               $pointerInstance = ObjectFactory::createObjectByConfiguredName('file_raw_input_output_class', array($fileInfoInstance));
+       public static function isBlockSeparatorFound (string $str) {
+               // Validate parameter
+               /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage(sprintf('BASE-BINARY-FILE: str=%s - CALLED!', $str));
+               if (empty($str)) {
+                       // Throw IAE
+                       throw new InvalidArgumentException('Parameter "str" is empty', FrameworkInterface::EXCEPTION_INVALID_ARGUMENT);
+               }
 
-               // ... and set it here
-               /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('BASE-BINARY-FILE: Setting pointerInstance=%s ...', $pointerInstance->__toString()));
-               $this->setPointerInstance($pointerInstance);
+               // Determine it
+               $isFound = (strpos($str, chr(BinaryFile::SEPARATOR_ENTRIES)) !== false);
 
-               // Trace message
-               /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('BASE-BINARY-FILE: EXIT!');
+               // Return result
+               /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage(sprintf('BASE-BINARY-FILE: isFound=%d - EXIT!', intval($isFound)));
+               return $isFound;
        }
 
        /**
@@ -445,45 +482,46 @@ abstract class BaseBinaryFile extends BaseAbstractFile {
         * @param       $data                   Data to be written
         * @param       $flushHeader    Whether to flush the header (default: flush)
         * @return      void
+        * @throws      OutOfBoundsException    If the position is not seekable
         * @throws      InvalidArgumentException        If a parameter is invalid
         */
        public function writeData (int $seekPosition, string $data, bool $flushHeader = true) {
                // Validate parameter
-               /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('BASE-BINARY-FILE: seekPosition=%s,data()=%d,flushHeader=%d - CALLED!', $seekPosition, strlen($data), intval($flushHeader)));
+               /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage(sprintf('BASE-BINARY-FILE: seekPosition=%s,data()=%d,flushHeader=%d - CALLED!', $seekPosition, strlen($data), intval($flushHeader)));
                if ($seekPosition < 0) {
                        // Invalid seek position
-                       throw new InvalidArgumentException(sprintf('seekPosition=%d is not valid', $seekPosition));
+                       throw new OutOfBoundsException(sprintf('seekPosition=%d is not valid', $seekPosition));
                } elseif (empty($data)) {
                        // Empty data is invalid, too
-                       throw new InvalidArgumentException('Parameter "data" is empty');
+                       throw new InvalidArgumentException('Parameter "data" is empty', FrameworkInterface::EXCEPTION_INVALID_ARGUMENT);
                }
 
                // Write data at given position
-               /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('BASE-BINARY-FILE: Calling this->writeAtPosition(%d,%s) ...', $seekPosition, $data));
+               /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage(sprintf('BASE-BINARY-FILE: Invoking this->writeAtPosition(%d,%s) ...', $seekPosition, $data));
                $this->writeAtPosition($seekPosition, $data);
 
                // Increment counter
-               /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('BASE-BINARY-FILE: Calling this->incrementCounter() ...');
+               /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage('BASE-BINARY-FILE: Invoking this->incrementCounter() ...');
                $this->incrementCounter();
 
                // Update seek position
-               /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('BASE-BINARY-FILE: Calling this->updateSeekPosition() ...');
+               /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage('BASE-BINARY-FILE: Invoking this->updateSeekPosition() ...');
                $this->updateSeekPosition();
 
                // Flush the header?
-               /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('BASE-BINARY-FILE: flushHeader=%d', intval($flushHeader)));
+               /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugMessage(sprintf('BASE-BINARY-FILE: flushHeader=%d', intval($flushHeader)));
                if ($flushHeader === true) {
                        // Flush header
-                       /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('BASE-BINARY-FILE: Calling this->flushFileHeader() ...');
+                       /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage('BASE-BINARY-FILE: Invoking this->flushFileHeader() ...');
                        $this->flushFileHeader();
 
                        // Seek to old position
-                       /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('BASE-BINARY-FILE: Calling this->seekToOldPosition() ...');
+                       /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage('BASE-BINARY-FILE: Invoking this->seekToOldPosition() ...');
                        $this->seekToOldPosition();
                }
 
                // Trace message
-               /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('BASE-BINARY-FILE: EXIT!');
+               /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage('BASE-BINARY-FILE: EXIT!');
        }
 
        /**
@@ -492,56 +530,29 @@ abstract class BaseBinaryFile extends BaseAbstractFile {
         * @param       $seekPosition   Seek position in file
         * @param       $dataStream             Data to be written
         * @return      mixed                   Number of writes bytes or false on error
+        * @throws      OutOfBoundsException    If the position is not seekable
         * @throws      InvalidArgumentException        If a parameter is not valid
         */
        public function writeAtPosition (int $seekPosition, string $dataStream) {
                // Validate parameter
-               /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('BASE-BINARY-FILE: seekPosition=%d,dataStream(%d)=%s - CALLED!', $seekPosition, strlen($dataStream), $dataStream));
+               /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage(sprintf('BASE-BINARY-FILE: seekPosition=%d,dataStream(%d)=%s - CALLED!', $seekPosition, strlen($dataStream), $dataStream));
                if ($seekPosition < 0) {
                        // Invalid seek position
-                       throw new InvalidArgumentException(sprintf('seekPosition=%d is not valid.', $seekPosition));
+                       throw new OutOfBoundsException(sprintf('seekPosition=%d is not valid.', $seekPosition));
                } elseif (empty($dataStream)) {
                        // Empty dataStream
-                       throw new InvalidArgumentException('Parameter "dataStream" is empty');
+                       throw new InvalidArgumentException('Parameter "dataStream" is empty', FrameworkInterface::EXCEPTION_INVALID_ARGUMENT);
                }
 
                // Call pointer's method
-               /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('BASE-BINARY-FILE: Calling this->pointerInstance->writeAtPosition(%d, %s) ...', $seekPosition, $dataStream));
+               /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage(sprintf('BASE-BINARY-FILE: Invoking this->pointerInstance->writeAtPosition(%d, %s) ...', $seekPosition, $dataStream));
                $status = $this->getPointerInstance()->writeAtPosition($seekPosition, $dataStream);
 
                // Return status
-               /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('BASE-BINARY-FILE: status[%s]=%d - EXIT!', gettype($status), $status));
+               /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage(sprintf('BASE-BINARY-FILE: status[%s]=%d - EXIT!', gettype($status), $status));
                return $status;
        }
 
-       /**
-        * Marks the currently loaded block as empty (with length of the block)
-        *
-        * @param       $length         Length of the block
-        * @return      void
-        * @throws      InvalidArgumentException        If a parameter is invalid
-        */
-       protected function markCurrentBlockAsEmpty (int $length) {
-               // Validate parameter
-               /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('BASE-BINARY-FILE: length=%d - CALLED!', $length));
-               if ($length < 1) {
-                       // Length cannot below one
-                       throw new InvalidArgumentException(sprintf('length=%d is not valid', $length));
-               }
-
-               // Get current seek position
-               $currentPosition = $this->key();
-
-               // Now add it as gap entry
-               array_push($this->gaps, array(
-                       self::GAPS_INDEX_START  => ($currentPosition - $length),
-                       self::GAPS_INDEX_END    => $currentPosition,
-               ));
-
-               // Trace message
-               /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('BASE-BINARY-FILE: EXIT!');
-       }
-
        /**
         * Checks whether the file header is initialized
         *
@@ -549,7 +560,7 @@ abstract class BaseBinaryFile extends BaseAbstractFile {
         */
        public function isFileHeaderInitialized () {
                // Default is not initialized
-               /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('BASE-BINARY-FILE: CALLED!');
+               /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage('BASE-BINARY-FILE: CALLED!');
                $isInitialized = false;
 
                // Is the file initialized?
@@ -558,19 +569,19 @@ abstract class BaseBinaryFile extends BaseAbstractFile {
                        $this->rewind();
 
                        // Read file header
-                       /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('BASE-BINARY-FILE: Calling this->readFileHeader() ...');
+                       /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage('BASE-BINARY-FILE: Invoking this->readFileHeader() ...');
                        $this->readFileHeader();
 
                        // Get header count
                        $headerCount = count($this->getHeader());
 
                        // The above method does already check the header
-                       /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('BASE-BINARY-FILE: headerCount=%d', $headerCount));
+                       /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugMessage(sprintf('BASE-BINARY-FILE: headerCount=%d', $headerCount));
                        $isInitialized = ($headerCount > 0);
                }
 
                // Return result
-               /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('BASE-BINARY-FILE: isInitialized=%d - EXIT!', intval($isInitialized)));
+               /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage(sprintf('BASE-BINARY-FILE: isInitialized=%d - EXIT!', intval($isInitialized)));
                return $isInitialized;
        }
 
@@ -578,24 +589,28 @@ abstract class BaseBinaryFile extends BaseAbstractFile {
         * Checks whether the assigned file has been initialized
         *
         * @return      $isInitialized          Whether the file's size is zero
+        * @throws      UnexpectedValueException        If an unexpected value was returned
         */
        public function isFileInitialized () {
                // Get it from iterator which holds the pointer instance. If false is returned
-               /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('BASE-BINARY-FILE: CALLED!');
+               /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage('BASE-BINARY-FILE: CALLED!');
                $fileSize = $this->size();
 
                /*
                 * The returned file size should not be false or NULL as this means
                 * that the pointer class does not work correctly.
                 */
-               /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('BASE-BINARY-FILE: fileSize[%s]=%d', gettype($fileSize), $fileSize));
-               assert(is_int($fileSize));
+               /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugMessage(sprintf('BASE-BINARY-FILE: fileSize[%s]=%d', gettype($fileSize), $fileSize));
+               if (!is_int($fileSize)) {
+                       // Bad file?
+                       throw new UnexpectedValueException(sprintf('fileSize[]=%s is unexpected', gettype($fileSize)), FrameworkInterface::EXCEPTION_UNEXPECTED_VALUE);
+               }
 
                // Is more than 0 returned?
                $isInitialized = ($fileSize > 0);
 
                // Return result
-               /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('BASE-BINARY-FILE: isInitialized=%d - EXIT!', intval($isInitialized)));
+               /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage(sprintf('BASE-BINARY-FILE: isInitialized=%d - EXIT!', intval($isInitialized)));
                return $isInitialized;
        }
 
@@ -607,63 +622,23 @@ abstract class BaseBinaryFile extends BaseAbstractFile {
         */
        public function createFileHeader () {
                // The file's header should not be initialized here
-               /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('BASE-BINARY-FILE: CALLED!');
+               /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage('BASE-BINARY-FILE: CALLED!');
                if ($this->isFileHeaderInitialized()) {
                        // Bad method call
-                       //* DEBUG-DIE: */ die(sprintf('[%s:%d]: this=%s', __METHOD__, __LINE__, print_r($this, TRUE)));
-                       throw new BadMethodCallException('File header is already initialized but method called');
+                       //* DEBUG-DIE: */ ApplicationEntryPoint::exitApplication(sprintf('[%s:%d]: this=%s', __METHOD__, __LINE__, print_r($this, TRUE)));
+                       throw new BadMethodCallException('File header is already initialized but method called', FrameworkInterface::EXCEPTION_BAD_METHOD_CALL);
                }
 
                // Simple flush file header which will create it.
-               /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('BASE-BINARY-FILE: Calling this->flushFileHeader() ...');
+               /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage('BASE-BINARY-FILE: Invoking this->flushFileHeader() ...');
                $this->flushFileHeader();
 
                // Rewind seek position (to beginning of file) and update/flush file header
-               /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('BASE-BINARY-FILE: Calling this->rewindUpdateSeekPosition() ...');
+               /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage('BASE-BINARY-FILE: Invoking this->rewindUpdateSeekPosition() ...');
                $this->rewindUpdateSeekPosition();
 
                // Trace message
-               /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('BASE-BINARY-FILE: EXIT!');
-       }
-
-       /**
-        * Pre-allocates file (if enabled) with some space for later faster write access.
-        *
-        * @param       $type   Type of the file
-        * @return      void
-        * @throws      InvalidArgumentException        If a parameter is empty
-        */
-       public function preAllocateFile (string $type) {
-               // Is it enabled?
-               /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('BASE-BINARY-FILE: type=%s - CALLED!', $type));
-               if (empty($type)) {
-                       // Empty type
-                       throw new InvalidArgumentException('Parameter "type" is empty');
-               } elseif (FrameworkBootstrap::getConfigurationInstance()->getConfigEntry($type . '_pre_allocate_enabled') != 'Y') {
-                       // Don't continue here.
-                       self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('BASE-BINARY-FILE: Not pre-allocating file.'));
-                       return;
-               }
-
-               // Message to user
-               self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('BASE-BINARY-FILE: Pre-allocating file ...');
-
-               // Calculate minimum length for one entry
-               $minimumBlockLength = $this->getBlockInstance()->calculateMinimumBlockLength();
-
-               // Calulcate seek position
-               /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('BASE-BINARY-FILE: minimumBlockLength=%s', $minimumBlockLength));
-               $seekPosition = $minimumBlockLength * FrameworkBootstrap::getConfigurationInstance()->getConfigEntry($type . '_pre_allocate_count');
-
-               // Now simply write a NUL there. This will pre-allocate the file.
-               /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('BASE-BINARY-FILE: Calling this->writeAtPosition(%d,NUL) ...', $seekPosition));
-               $this->writeAtPosition($seekPosition, chr(0));
-
-               // Rewind seek position
-               $this->rewind();
-
-               // Trace message
-               /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('BASE-BINARY-FILE: EXIT!');
+               /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage('BASE-BINARY-FILE: EXIT!');
        }
 
        /**
@@ -673,7 +648,12 @@ abstract class BaseBinaryFile extends BaseAbstractFile {
         */
        public function determineSeekPosition () {
                // Call pointer instance
-               return $this->getPointerInstance()->determineSeekPosition();
+               /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage('BASE-BINARY-FILE: CALLED!');
+               $seekPosition = $this->getPointerInstance()->determineSeekPosition();
+
+               // Return position
+               /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage(sprintf('BASE-BINARY-FILE: seekPosition=%d - EXIT!', $seekPosition));
+               return $seekPosition;
        }
 
        /**
@@ -682,10 +662,22 @@ abstract class BaseBinaryFile extends BaseAbstractFile {
         * @param       $offset         Offset to seek to (or used as "base" for other seeks)
         * @param       $whence         Added to offset (default: only use offset to seek to)
         * @return      $status         Status of file seek: 0 = success, -1 = failed
+        * @throws      OutOfBoundsException    If the position is not seekable
         */
        public function seek (int $offset, int $whence = SEEK_SET) {
+               // Validate parameter
+               /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage(sprintf('BASE-BINARY-FILE: offset=%d,whence=%d - CALLED!', $offset, $whence));
+               if ($offset < 0) {
+                       // No offset is smaller than zero
+                       throw new OutOfBoundsException(sprintf('offset=%d is not valid', $offset));
+               }
+
                // Call pointer instance
-               return $this->getPointerInstance()->seek($offset, $whence);
+               $status = $this->getPointerInstance()->seek($offset, $whence);
+
+               // Return status
+               /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage(sprintf('BASE-BINARY-FILE: status[%s]=%d - EXIT!', gettype($status), $status));
+               return $status;
        }
 
        /**
@@ -693,20 +685,41 @@ abstract class BaseBinaryFile extends BaseAbstractFile {
         *
         * @param       $bytes  Amount of bytes to read
         * @return      $data   Data read from file
+        * @throws      OutOfBoundsException    If the position is not seekable
         */
        public function read (int $bytes = 0) {
+               // Validate parameter
+               /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage(sprintf('BASE-BINARY-FILE: bytes=%d - CALLED!', $bytes));
+               if ($bytes < 0) {
+                       // Throw exception
+                       throw new OutOfBoundsException(sprintf('bytes=%d is not valid', $bytes));
+               }
+
                // Call pointer instance
-               return $this->getPointerInstance()->read($bytes);
+               /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage(sprintf('BASE-BINARY-FILE: Invoking this->pointerInstance->read(%d) ...', $bytes));
+               $data = $this->getPointerInstance()->read($bytes);
+
+               // Update seek position
+               /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage('BASE-BINARY-FILE: Invoking this->updateSeekPosition() ...');
+               $this->updateSeekPosition();
+
+               // Return data
+               /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage(sprintf('BASE-BINARY-FILE: data[%s]=%s - EXIT!', gettype($data), $data));
+               return $data;
        }
 
        /**
         * Rewinds to the beginning of the file
         *
-        * @return      $status         Status of this operation
+        * @return      void
         */
        public function rewind () {
                // Call pointer instance
-               return $this->getPointerInstance()->rewind();
+               /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage('BASE-BINARY-FILE: CALLED!');
+               $this->getPointerInstance()->rewind();
+
+               // Trace message
+               /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage('BASE-BINARY-FILE: EXIT!');
        }
 
        /**
@@ -717,88 +730,98 @@ abstract class BaseBinaryFile extends BaseAbstractFile {
         * @return      void
         * @throws      BadMethodCallException  If this method is called but file is not initialized
         */
-       public function analyzeFile () {
+       public function analyzeFileStructure () {
                // Make sure the file is initialized
-               /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('BASE-BINARY-FILE: CALLED!');
+               /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage('BASE-BINARY-FILE: CALLED!');
                if (!$this->isFileInitialized()) {
                        // Bad method call
-                       throw new BadMethodCallException('Method called but file is not initialized.');
+                       throw new BadMethodCallException('Method called but file is not initialized.', FrameworkInterface::EXCEPTION_BAD_METHOD_CALL);
                }
 
                // Init counters and gaps array
+               /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage('BASE-BINARY-FILE: Invoking this->initCounterGapsArrays() ...');
                $this->initCountersGapsArray();
 
                // Output message (as this may take some time)
-               self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('Analyzing file structure ... (this may take some time)'));
+               self::createDebugInstance(__CLASS__, __LINE__)->debugMessage(sprintf('Analyzing file structure ... (this may take some time)'));
 
-               // First rewind to the begining
-               $this->rewind();
+               // First Seek to right after file header
+               /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage(sprintf('BASE-BINARY-FILE: Invoking this->seek(%d) ...', $this->getHeaderSize() + 1));
+               $this->seek($this->getHeaderSize() + 1);
 
                // Then try to load all entries
-               while ($this->valid()) {
-                       // Go to next entry
-                       $this->next();
-
+               /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugMessage(sprintf('BASE-BINARY-FILE: this->seekPosition=%d, looping through file ...', $this->getSeekPosition()));
+               while ($this->isValid()) {
                        // Get current entry
                        $current = $this->getCurrentBlock();
 
+                       // Go to next entry
+                       /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage(sprintf('BASE-BINARY-FILE: current=%s, Invoking this->readNextBlock() ...', $current));
+                       $this->readNextBlock();
+
                        /*
                         * If the block is empty, maybe the whole file is? This could mean
                         * that the file has been pre-allocated.
                         */
-                       if (empty($current)) {
+                       /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugMessage(sprintf('BASE-BINARY-FILE: current(%d)[]=%s', strlen($current), gettype($current)));
+                       if (empty(trim($current, chr(0)))) {
                                // Then skip this part
+                               /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugMessage(sprintf('BASE-BINARY-FILE: current[]=%s is empty - CONTINUE!', gettype($current)));
                                continue;
                        }
 
-                       // Debug message
-                       /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('current()=%d', strlen($current)));
+                       // Handle current record
+                       /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugMessage(sprintf('BASE-BINARY-FILE: current(%d)[%s]=%s', strlen($current), gettype($current), $current));
                }
 
                // If the last read block is empty, check gaps
-               if (empty($current)) {
+               /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugMessage(sprintf('BASE-BINARY-FILE: current()=%d', strlen($current)));
+               if (empty(trim($current, chr(0)))) {
                        // Output message
-                       self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('Found a total of %s gaps.', count($this->gaps)));
+                       self::createDebugInstance(__CLASS__, __LINE__)->debugMessage(sprintf('BASE-BINARY-FILE: Found a total of %d gaps.', count($this->gaps)));
 
                        // Check gaps, if the whole file is empty.
-                       if ($this->isFileOnlyGaps()) {
+                       /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage('BASE-BINARY-FILE: Invoking this->isFileGapsOnly() ...');
+                       if ($this->isFileGapsOnly()) {
                                // Only gaps, so don't continue here.
+                               /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugMessage('BASE-BINARY-FILE: File is gaps-only - EXIT!');
                                return;
                        }
+               }
 
-                       /*
-                        * The above call has calculated a total size of all gaps. If the
-                        * percentage of gaps passes a "soft" limit and last
-                        * defragmentation is to far in the past, or if a "hard" limit has
-                        * reached, run defragmentation.
-                        */
-                       if ($this->isDefragmentationNeeded()) {
-                               // Run "defragmentation"
-                               $this->doRunDefragmentation();
-                       }
+               /*
+                * The above call has calculated a total size of all gaps. If the
+                * percentage of gaps passes a "soft" limit and last
+                * defragmentation is to far in the past, or if a "hard" limit has
+                * reached, run defragmentation.
+                */
+               /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage('BASE-BINARY-FILE: Invoking this->isDefragmentationNeeded() ...');
+               if ($this->isDefragmentationNeeded()) {
+                       // Run "defragmentation"
+                       /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage('BASE-BINARY-FILE: Invoking this->doRunDefragmentation() ...');
+                       $this->doRunDefragmentation();
                }
-               /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('BASE-BINARY-FILE: EXIT!');
+
+               // Trace message
+               /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage('BASE-BINARY-FILE: EXIT!');
        }
 
        /**
-        * Advances to next "block" of bytes
+        * Reads next "block" of given bytes into $currentBlock field. THis method
+        * loads the whole file into memory when the file is just freshly
+        * initialized (only zeros in it).
         *
         * @return      void
-        * @throws      UnexpectedValueException        If some unexpected value was found
+        * @throws      InvalidArgumentException        If a parameter is not valid
         */
-       public function next () {
-               // Is there nothing to read?
-               /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('BASE-BINARY-FILE: CALLED!');
-               if (!$this->valid()) {
-                       // Nothing to read
-                       return;
+       protected function readNextBlockByLength (int $length) {
+               // Validate parameter
+               /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage(sprintf('BASE-BINARY-FILE: this->seekPosition=%d,length=%d - CALLED!', $this->getSeekPosition(), $length));
+               if ($length < 1) {
+                       // Throw IAE
+                       throw new InvalidArgumentException(sprintf('length=%d is not valid', $length), FrameworkInterface::EXCEPTION_INVALID_ARGUMENT);
                }
 
-               // First calculate minimum block length
-               /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('BASE-BINARY-FILE: key()=%d', $this->key()));
-               $length = $this->getBlockInstance()->calculateMinimumBlockLength();
-               /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('BASE-BINARY-FILE: length=%d', $length));
-
                // Read possibly back-buffered bytes from previous call of next().
                $data = $this->getBackBuffer();
 
@@ -807,65 +830,117 @@ abstract class BaseBinaryFile extends BaseAbstractFile {
                 * "block" may not fit, so this loop will continue until the EOB or EOF
                 * has been reached whatever comes first.
                 */
-               /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('BASE-BINARY-FILE: data()=%d', strlen($data)));
+               /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugMessage(sprintf('BASE-BINARY-FILE: this->seekPosition=%d,data()=%d', $this->getSeekPosition(), strlen($data)));
                while ((!$this->isEndOfFileReached()) && (empty($data) || !self::isBlockSeparatorFound($data))) {
                        // Then read the next possible block
-                       /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('BASE-BINARY-FILE: Calling this->read(%d) ...', $length));
+                       /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugMessage(sprintf('BASE-BINARY-FILE: this->seekPosition=%d, Invoking this->read(%d) ...', $this->getSeekPosition(), $length));
                        $block = $this->read($length);
 
-                       // Is it all empty?
-                       /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('BASE-BINARY-FILE: block()=%d,length=%s', strlen($block), $length));
-                       if (strlen(trim($block, chr(0))) == 0) {
-                               // Mark this block as empty
-                               /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('BASE-BINARY-FILE: Calling markCurrentBlockAsEmpty(%d) ...', strlen($block)));
-                               $this->markCurrentBlockAsEmpty(strlen($block));
-
-                               // Skip to next block
-                               /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('BASE-BINARY-FILE: CONTINUE!');
-                               continue;
+                       // Is the block empty?
+                       /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugMessage(sprintf('BASE-BINARY-FILE: block()=%d,length=%d', strlen($block), $length));
+                       if (strlen($block) == 0) {
+                               // Read empty block, maybe EOF
+                               /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugMessage(sprintf('BASE-BINARY-FILE: this->seekPosition=%d, block is empty, maybe EOF reached - BREAK!', $this->getSeekPosition()));
+                               break;
+                       } elseif (empty(trim($block, chr(0)))) {
+                               // Mark it as empty
+                               /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugMessage(sprintf('BASE-BINARY-FILE: this->seekPosition=%d, Invoking this->markCurrentBlockAsEmpty(%d) ...', $this->getSeekPosition(), $length));
+                               $this->markCurrentBlockAsEmpty($length);
                        }
 
                        // At this block then
                        $data .= $block;
 
-                       // A debug message
-                       /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('BASE-BINARY-FILE: data()=%d', strlen($data)));
-               }
-
-               // EOF reached?
-               if ($this->isEndOfFileReached()) {
-                       // Set whole data as current read block
-                       /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('BASE-BINARY-FILE: Calling setCurrentBlock(%d) ...', strlen($data)));
-                       $this->setCurrentBlock($data);
-
-                       // Then abort here silently
-                       /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('BASE-BINARY-FILE: EOF reached - EXIT!');
-                       return;
+                       // Debug message
+                       /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugMessage(sprintf('BASE-BINARY-FILE: this->seekPosition=%d,data()=%d', $this->getSeekPosition(), strlen($data)));
                }
 
                /*
                 * Init back-buffer which is the data that has been found beyond the
                 * separator.
                 */
+               /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage('BASE-BINARY-FILE: Invoking this->initBackBuffer(), clearing this->currentBlock ...');
                $this->initBackBuffer();
+               $this->setCurrentBlock('');
 
-               // Separate data
-               $dataArray = explode(chr(self::SEPARATOR_ENTRIES), $data);
-
-               // This array must contain two elements
-               /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('BASE-BINARY-FILE: dataArray()=%d', count($dataArray)));
-               //* PRINTR-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('BASE-BINARY-FILE: dataArray=%s', print_r($dataArray, true)));
-               if (count($dataArray) != 2) {
-                       // Bad count
-                       throw new UnexpectedValueException(sprintf('dataArray()=%d is not expected, want 2', count($dataArray)));
+               // Is $data empty?
+               /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugMessage(sprintf('BASE-BINARY-FILE: data(%d)=%s', strlen($data), $data));
+               if (empty(trim($data, chr(0)))) {
+                       // Yes, maybe whole file was ...
+                       /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugMessage(sprintf('BASE-BINARY-FILE: this->seekPosition=%d, maybe empty file found - EXIT!', $this->getSeekPosition()));
+                       return;
                }
 
-               // Left part is the actual block, right one the back-buffer data
+               // Separate data
+               $dataArray = explode(chr(BinaryFile::SEPARATOR_ENTRIES), $data);
+
+               // Left part is the actual block, right one the back-buffer data, if found
+               /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugMessage(sprintf('BASE-BINARY-FILE: dataArray()=%d', count($dataArray)));
+               //* PRINTR-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugMessage(sprintf('BASE-BINARY-FILE: dataArray=%s', print_r($dataArray, true)));
                $this->setCurrentBlock($dataArray[0]);
-               $this->setBackBuffer($dataArray[1]);
+
+               // Is back buffere data found?
+               if (isset($dataArray[1]) && !empty(trim($dataArray[1], chr(0)))) {
+                       // Set back buffer
+                       /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugMessage(sprintf('BASE-BINARY-FILE: Setting this->backBuffer=%s ...', $dataArray[1]));
+                       $this->setBackBuffer($dataArray[1]);
+               }
+
+               // Trace message
+               /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage('BASE-BINARY-FILE: EXIT!');
+       }
+
+       /**
+        * Pre-allocates file (if enabled) with some space for later faster write access.
+        *
+        * @param       $type   Type of the file
+        * @return      void
+        * @throws      InvalidArgumentException        If a parameter is empty
+        */
+       protected function preAllocateFileByTypeLength (string $type, int $minimumBlockLength) {
+               // Is it enabled?
+               /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage(sprintf('BASE-BINARY-FILE: type=%s,minimumBlockLength=%d - CALLED!', $type, $minimumBlockLength));
+               if (empty($type)) {
+                       // Empty type
+                       throw new InvalidArgumentException('Parameter "type" is empty', FrameworkInterface::EXCEPTION_INVALID_ARGUMENT);
+               } elseif ($minimumBlockLength < 1) {
+                       // Invalid block length
+                       throw new InvalidArgumentException(sprintf('Parameter minimumBlockLength=%d is not valid', $minimumBlockLength), FrameworkInterface::EXCEPTION_INVALID_ARGUMENT);
+               } elseif (!FrameworkBootstrap::getConfigurationInstance()->isEnabled($type . '_pre_allocate')) {
+                       // Don't continue here.
+                       self::createDebugInstance(__CLASS__, __LINE__)->traceMessage('BASE-BINARY-FILE: Not pre-allocating file. - EXIT!');
+                       return;
+               }
+
+               // Get file size
+               $fileSize = $this->getFileSize();
+
+               // Calulcate seek position
+               /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugMessage(sprintf('BASE-BINARY-FILE: minimumBlockLength=%d,fileSize=%d', $minimumBlockLength, $fileSize));
+               $seekPosition = $this->getHeaderSize() + $minimumBlockLength * FrameworkBootstrap::getConfigurationInstance()->getConfigEntry($type . '_pre_allocate_count') + $fileSize ;
+
+               // Now simply write a NUL there. This will pre-allocate the file.
+               /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage(sprintf('BASE-BINARY-FILE: Invoking this->writeAtPosition(%d,NUL) ...', $seekPosition));
+               $this->writeAtPosition($seekPosition, chr(0));
+
+               // Is the seek position zero?
+               /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugMessage(sprintf('BASE-BINARY-FILE: fileSize=%d', $fileSize));
+               if ($fileSize == 0) {
+                       // Mark file as gaps-only
+                       /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage(sprintf('BASE-BINARY-FILE: Invoking this->markGapsOnly(%s,%d) ...', $type, $minimumBlockLength));
+                       $this->markFileGapsOnly($type, $minimumBlockLength);
+               } else {
+                       // Analyze file structure
+                       /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage('BASE-BINARY-FILE: Invoking this->analyzeFileStructure() ...');
+                       $this->analyzeFileStructure();
+               }
+
+               // Rewind seek position
+               /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage('BASE-BINARY-FILE: Invoking this->rewind() ...');
+               $this->rewind();
 
                // Trace message
-               /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('BASE-BINARY-FILE: EXIT!');
+               /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage('BASE-BINARY-FILE: EXIT!');
        }
 
        /**
@@ -873,36 +948,33 @@ abstract class BaseBinaryFile extends BaseAbstractFile {
         * This method will return true if an emptied (nulled) entry has been found.
         *
         * @return      $isValid        Whether the next entry is valid
-        * @throws      UnexpectedValueException        If some value is not expected
+        * @throws      InvalidArgumentException        If a parameter is not valid
         */
-       public function valid () {
-               // First calculate minimum block length
-               /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('BASE-BINARY-FILE: CALLED!');
-               $length = $this->getBlockInstance()->calculateMinimumBlockLength();
-
-               // Short be more than zero!
-               /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('BASE-BINARY-FILE: length=%d', $length));
+       protected function isValidByLength (int $length) {
+               // Validate parameter
+               /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage(sprintf('BASE-BINARY-FILE: length=%d - CALLED!', $length));
                if ($length < 1) {
-                       // Throw UVE
-                       throw new UnexpectedValueException(sprintf('length=%d is not expected', $length));
+                       // Throw IAE
+                       throw new InvalidArgumentException(sprintf('Parameter length=%d is not valid', $length), FrameworkInterface::EXCEPTION_INVALID_ARGUMENT);
                }
 
                // Get current seek position
-               $seekPosition = $this->key();
+               $seekPosition = $this->determineSeekPosition();
 
                // Then try to read it
-               /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('BASE-BINARY-FILE: seekPosition=%d', $seekPosition));
+               /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugMessage(sprintf('BASE-BINARY-FILE: seekPosition=%d', $seekPosition));
                $data = $this->read($length);
 
                // If some bytes could be read, all is fine
-               /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('BASE-BINARY-FILE: data[%s]()=%d', gettype($data), strlen($data)));
+               /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugMessage(sprintf('BASE-BINARY-FILE: data[%s]()=%d', gettype($data), strlen($data)));
                $isValid = ((is_string($data)) && (strlen($data) > 0));
 
                // Get header size
-               /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('BASE-BINARY-FILE: isValid=%d', intval($isValid)));
+               /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugMessage(sprintf('BASE-BINARY-FILE: isValid=%d', intval($isValid)));
                $headerSize = $this->getHeaderSize();
 
                // Is the seek position at or beyond the header?
+               /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugMessage(sprintf('BASE-BINARY-FILE: seekPosition=%d,headerSize=%d', $seekPosition, $headerSize));
                if ($seekPosition >= $headerSize) {
                        // Seek back to old position
                        $isValid = ($isValid && $this->seek($seekPosition) === 0);
@@ -912,52 +984,26 @@ abstract class BaseBinaryFile extends BaseAbstractFile {
                }
 
                // Return result
-               /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('BASE-BINARY-FILE: isValid=%d - EXIT!', intval($isValid)));
+               /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage(sprintf('BASE-BINARY-FILE: isValid=%d - EXIT!', intval($isValid)));
                return $isValid;
        }
 
        /**
-        * Gets current seek position ("key").
-        *
-        * @return      $key    Current key in iteration
-        */
-       public function key () {
-               // Call pointer instance
-               /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('BASE-BINARY-FILE: CALLED!');
-               $key = $this->getPointerInstance()->determineSeekPosition();
-
-               // Return key
-               /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('BASE-BINARY-FILE: key[%s]=%d - EXIT!', gettype($key), $key));
-               return $key;
-       }
-
-       /**
-        * Reads the file header
+        * Reads next "block" of bytes into $currentBlock field. THis method loads
+        * the whole file into memory when the file is just freshly initialized
+        * (only zeros in it).
         *
         * @return      void
         */
-       public function readFileHeader () {
-               // Call block instance
-               /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('BASE-BINARY-FILE: CALLED!');
-               $this->getBlockInstance()->readFileHeader();
-
-               // Trace message
-               /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('BASE-BINARY-FILE: EXIT!');
-       }
+       protected abstract function readNextBlock ();
 
        /**
-        * Flushes the file header
+        * Reads the file header
         *
         * @return      void
+        * @throws      LogicException  If both instances are not set
         */
-       public function flushFileHeader () {
-               // Call block instance
-               /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('BASE-BINARY-FILE: CALLED!');
-               $this->getBlockInstance()->flushFileHeader();
-
-               // Trace message
-               /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('BASE-BINARY-FILE: EXIT!');
-       }
+       public abstract function readFileHeader ();
 
        /**
         * Searches for next suitable gap the given length of data can fit in
@@ -969,17 +1015,24 @@ abstract class BaseBinaryFile extends BaseAbstractFile {
         */
        public function searchNextGap (int $length) {
                // If the file is only gaps, no need to seek
-               /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('BASE-BINARY-FILE: length=%d - CALLED!', $length));
+               /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage(sprintf('BASE-BINARY-FILE: length=%d - CALLED!', $length));
                if ($length <= 0) {
                        // Throw IAE
-                       throw new InvalidArgumentException(sprintf('length=%d is not valid', $length));
-               } elseif ($this->isFileOnlyGaps()) {
-                       // The first empty block is the first one right after the header
-                       return ($this->getHeaderSize() + 1);
+                       throw new InvalidArgumentException(sprintf('length=%d is not valid', $length), FrameworkInterface::EXCEPTION_INVALID_ARGUMENT);
+               } elseif ($this->isFileGapsOnly()) {
+                       /*
+                        * The first empty block is the 2nd one right after the header, so
+                        * one byte gap to the header.
+                        */
+                       $seekPosition = ($this->getHeaderSize() + 2);
+
+                       // Return position
+                       /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage(sprintf('BASE-BINARY-FILE: seekPosition=%d - EXIT!', $seekPosition));
+                       return $seekPosition;
                }
 
                // @TODO Unfinished
-               $this->partialStub('length=' . $length);
+               DebugMiddleware::getSelfInstance()->partialStub('length=' . $length);
        }
 
 }