public function executeMigration(MigrationInterface $migration, $direction = MigrationInterface::UP, $fake = false)
    {
        $direction = ($direction === MigrationInterface::UP) ? MigrationInterface::UP : MigrationInterface::DOWN;
        $migration->setMigratingUp($direction === MigrationInterface::UP);

        $startTime = time();
        $migration->setAdapter($this->getAdapter());

        if (!$fake) {
            // begin the transaction if the adapter supports it
            if ($this->getAdapter()->hasTransactions()) {
                $this->getAdapter()->beginTransaction();
            }

            // Run the migration
            if (method_exists($migration, MigrationInterface::CHANGE)) {
                if ($direction === MigrationInterface::DOWN) {
                    // Create an instance of the ProxyAdapter so we can record all
                    // of the migration commands for reverse playback

                    /** @var \Phinx\Db\Adapter\ProxyAdapter $proxyAdapter */
                    $proxyAdapter = AdapterFactory::instance()
                        ->getWrapper('proxy', $this->getAdapter());
                    $migration->setAdapter($proxyAdapter);
                    /** @noinspection PhpUndefinedMethodInspection */
                    $migration->change();
                    $proxyAdapter->executeInvertedCommands();
                    $migration->setAdapter($this->getAdapter());
                } else {
                    /** @noinspection PhpUndefinedMethodInspection */
                    $migration->change();
                }
            } else {
                $migration->{$direction}();
            }

            // commit the transaction if the adapter supports it
            if ($this->getAdapter()->hasTransactions()) {
                $this->getAdapter()->commitTransaction();
            }
        }

        // Record it in the database
        $this->getAdapter()->migrated($migration, $direction, date('Y-m-d H:i:s', $startTime), date('Y-m-d H:i:s', time()));
    }