/**
  * Look for table structure modifications and apply to them
  *
  * @param string $tableName
  * @param array $tableColumns
  */
 public function morphTable($tableName, $definition)
 {
     $defaultSchema = self::$_connection->getDefaultSchema();
     $tableExists = self::$_connection->tableExists($tableName, $defaultSchema);
     if (isset($definition['columns'])) {
         if (count($definition['columns']) == 0) {
             throw new ActiveRecordMigrationException('La tabla debe tener al menos una columna');
         }
         $fields = array();
         foreach ($definition['columns'] as $tableColumn) {
             if (!is_object($tableColumn)) {
                 throw new ActiveRecordMigrationException('La tabla debe tener al menos una columna');
             }
             $fields[$tableColumn->getName()] = $tableColumn;
         }
         if ($tableExists == true) {
             $localFields = array();
             $description = self::$_connection->describeTable($tableName, $defaultSchema);
             foreach ($description as $field) {
                 $localFields[$field['Field']] = $field;
             }
             foreach ($fields as $fieldName => $tableColumn) {
                 if (!isset($localFields[$fieldName])) {
                     self::$_connection->addColumn($tableName, $tableColumn->getSchemaName(), $tableColumn);
                 } else {
                     $changed = false;
                     $columnDefinition = strtolower(self::$_connection->getColumnDefinition($tableColumn));
                     if ($localFields[$fieldName]['Type'] != $columnDefinition) {
                         $changed = true;
                     }
                     if ($tableColumn->isNotNull() != true && $localFields[$fieldName]['Null'] == 'NO') {
                         $changed = true;
                     } else {
                         if ($tableColumn->isNotNull() == true && $localFields[$fieldName]['Null'] == 'YES') {
                             $changed = true;
                         }
                     }
                     if ($changed == true) {
                         self::$_connection->modifyColumn($tableName, $tableColumn->getSchemaName(), $tableColumn);
                     }
                 }
             }
             foreach ($localFields as $fieldName => $localField) {
                 if (!isset($fields[$fieldName])) {
                     self::$_connection->dropColumn($tableName, null, $fieldName);
                 }
             }
         } else {
             self::$_connection->createTable($tableName, $defaultSchema, $definition);
             if (method_exists($this, 'afterCreateTable')) {
                 $this->afterCreateTable();
             }
         }
     }
     if (isset($definition['references'])) {
         if ($tableExists == true) {
             $references = array();
             foreach ($definition['references'] as $tableReference) {
                 $references[$tableReference->getName()] = $tableReference;
             }
             $localReferences = self::$_connection->describeReferences($tableName, $defaultSchema);
             foreach ($definition['references'] as $tableReference) {
                 if (!isset($localReferences[$tableReference->getName()])) {
                     self::$_connection->addForeignKey($tableName, $tableReference->getSchemaName(), $tableReference);
                 } else {
                     $changed = false;
                     if ($tableReference->getReferencedTable() != $localReferences[$tableReference->getName()]['referencedTable']) {
                         $changed = true;
                     }
                     if ($changed == false) {
                         if (count($tableReference->getColumns()) != count($localReferences[$tableReference->getName()]['columns'])) {
                             $changed = true;
                         }
                     }
                     if ($changed == false) {
                         if (count($tableReference->getReferencedColumns()) != count($localReferences[$tableReference->getName()]['referencedColumns'])) {
                             $changed = true;
                         }
                     }
                     if ($changed == false) {
                         foreach ($tableReference->getColumns() as $columnName) {
                             if (!in_array($columnName, $localReferences[$tableReference->getName()]['columns'])) {
                                 $changed = true;
                                 break;
                             }
                         }
                     }
                     if ($changed == false) {
                         foreach ($tableReference->getReferencedColumns() as $columnName) {
                             if (!in_array($columnName, $localReferences[$tableReference->getName()]['referencedColumns'])) {
                                 $changed = true;
                                 break;
                             }
                         }
                     }
                     if ($changed == true) {
                         self::$_connection->dropForeignKey($tableName, $tableReference->getSchemaName(), $tableReference->getName());
                         self::$_connection->addForeignKey($tableName, $tableReference->getSchemaName(), $tableReference);
                     }
                 }
             }
             foreach ($localReferences as $referenceName => $reference) {
                 if (!isset($references[$referenceName])) {
                     self::$_connection->dropForeignKey($tableName, null, $referenceName);
                 }
             }
         }
     }
     if (isset($definition['indexes'])) {
         if ($tableExists == true) {
             $indexes = array();
             foreach ($definition['indexes'] as $tableIndex) {
                 $indexes[$tableIndex->getName()] = $tableIndex;
             }
             $localIndexes = self::$_connection->describeIndexes($tableName, $defaultSchema);
             foreach ($definition['indexes'] as $tableIndex) {
                 if (!isset($localIndexes[$tableIndex->getName()])) {
                     if ($tableIndex->getName() == 'PRIMARY') {
                         self::$_connection->addPrimaryKey($tableName, $tableColumn->getSchemaName(), $tableIndex);
                     } else {
                         self::$_connection->addIndex($tableName, $tableColumn->getSchemaName(), $tableIndex);
                     }
                 } else {
                     $changed = false;
                     if (count($tableIndex->getColumns()) != count($localIndexes[$tableIndex->getName()])) {
                         $changed = true;
                     } else {
                         foreach ($tableIndex->getColumns() as $columnName) {
                             if (!in_array($columnName, $localIndexes[$tableIndex->getName()])) {
                                 $changed = true;
                                 break;
                             }
                         }
                     }
                     if ($changed == true) {
                         if ($tableIndex->getName() == 'PRIMARY') {
                             self::$_connection->dropPrimaryKey($tableName, $tableColumn->getSchemaName());
                             self::$_connection->addPrimaryKey($tableName, $tableColumn->getSchemaName(), $tableIndex);
                         } else {
                             self::$_connection->dropIndex($tableName, $tableColumn->getSchemaName(), $tableIndex->getName());
                             self::$_connection->addIndex($tableName, $tableColumn->getSchemaName(), $tableIndex);
                         }
                     }
                 }
             }
             foreach ($localIndexes as $indexName => $indexColumns) {
                 if (!isset($indexes[$indexName])) {
                     self::$_connection->dropIndex($tableName, null, $indexName);
                 }
             }
         }
     }
 }