[med-svn] [openemr] 01/03: Incorrectly stripped phpmyadmin from source and not using the copyright file - reverting.

Ian Wallace iankarlwallace-guest at moszumanska.debian.org
Wed Jun 25 02:59:45 UTC 2014


This is an automated email from the git hooks/post-receive script.

iankarlwallace-guest pushed a commit to branch master
in repository openemr.

commit b29f538482220c7202a4f002c3a85128646f576f
Author: Ian Wallace <iankarlwallace at gmail.com>
Date:   Tue Jun 24 19:55:14 2014 -0700

    Incorrectly stripped phpmyadmin from source and not using the copyright file - reverting.
---
 phpmyadmin/ChangeLog                               |   225 +
 phpmyadmin/LICENSE                                 |   340 +
 phpmyadmin/README                                  |    84 +
 phpmyadmin/RELEASE-DATE-4.0.4                      |     1 +
 phpmyadmin/browse_foreigners.php                   |   340 +
 phpmyadmin/changelog.php                           |   152 +
 phpmyadmin/chk_rel.php                             |    15 +
 phpmyadmin/composer.json                           |    24 +
 phpmyadmin/config.inc.php                          |    37 +
 phpmyadmin/config.sample.inc.php                   |   141 +
 phpmyadmin/db_create.php                           |   148 +
 phpmyadmin/db_datadict.php                         |   291 +
 phpmyadmin/db_events.php                           |    26 +
 phpmyadmin/db_export.php                           |    90 +
 phpmyadmin/db_import.php                           |    28 +
 phpmyadmin/db_operations.php                       |   293 +
 phpmyadmin/db_printview.php                        |   252 +
 phpmyadmin/db_qbe.php                              |    68 +
 phpmyadmin/db_routines.php                         |    27 +
 phpmyadmin/db_search.php                           |    57 +
 phpmyadmin/db_sql.php                              |    65 +
 phpmyadmin/db_structure.php                        |   335 +
 phpmyadmin/db_tracking.php                         |   243 +
 phpmyadmin/db_triggers.php                         |    25 +
 phpmyadmin/doc/Makefile                            |   153 +
 phpmyadmin/doc/_ext/configext.py                   |   189 +
 phpmyadmin/doc/conf.py                             |   286 +
 phpmyadmin/doc/config.rst                          |  2776 ++
 phpmyadmin/doc/copyright.rst                       |    30 +
 phpmyadmin/doc/credits.rst                         |   597 +
 phpmyadmin/doc/developers.rst                      |    12 +
 phpmyadmin/doc/doctrees/config.doctree             |   Bin 0 -> 935625 bytes
 phpmyadmin/doc/doctrees/copyright.doctree          |   Bin 0 -> 6876 bytes
 phpmyadmin/doc/doctrees/credits.doctree            |   Bin 0 -> 135005 bytes
 phpmyadmin/doc/doctrees/developers.doctree         |   Bin 0 -> 4726 bytes
 phpmyadmin/doc/doctrees/environment.pickle         |   Bin 0 -> 243711 bytes
 phpmyadmin/doc/doctrees/faq.doctree                |   Bin 0 -> 595349 bytes
 phpmyadmin/doc/doctrees/glossary.doctree           |   Bin 0 -> 120004 bytes
 phpmyadmin/doc/doctrees/index.doctree              |   Bin 0 -> 6400 bytes
 phpmyadmin/doc/doctrees/intro.doctree              |   Bin 0 -> 29111 bytes
 phpmyadmin/doc/doctrees/other.doctree              |   Bin 0 -> 5433 bytes
 phpmyadmin/doc/doctrees/privileges.doctree         |   Bin 0 -> 11974 bytes
 phpmyadmin/doc/doctrees/require.doctree            |   Bin 0 -> 16868 bytes
 phpmyadmin/doc/doctrees/setup.doctree              |   Bin 0 -> 132201 bytes
 phpmyadmin/doc/doctrees/transformations.doctree    |   Bin 0 -> 33416 bytes
 phpmyadmin/doc/doctrees/user.doctree               |   Bin 0 -> 2928 bytes
 phpmyadmin/doc/doctrees/vendors.doctree            |   Bin 0 -> 8707 bytes
 phpmyadmin/doc/faq.rst                             |  2001 ++
 phpmyadmin/doc/glossary.rst                        |   406 +
 phpmyadmin/doc/html/.buildinfo                     |     4 +
 phpmyadmin/doc/html/_sources/config.txt            |  2776 ++
 phpmyadmin/doc/html/_sources/copyright.txt         |    30 +
 phpmyadmin/doc/html/_sources/credits.txt           |   597 +
 phpmyadmin/doc/html/_sources/developers.txt        |    12 +
 phpmyadmin/doc/html/_sources/faq.txt               |  2001 ++
 phpmyadmin/doc/html/_sources/glossary.txt          |   406 +
 phpmyadmin/doc/html/_sources/index.txt             |    32 +
 phpmyadmin/doc/html/_sources/intro.txt             |    68 +
 phpmyadmin/doc/html/_sources/other.txt             |    18 +
 phpmyadmin/doc/html/_sources/privileges.txt        |    50 +
 phpmyadmin/doc/html/_sources/require.txt           |    55 +
 phpmyadmin/doc/html/_sources/setup.txt             |   424 +
 phpmyadmin/doc/html/_sources/transformations.txt   |   138 +
 phpmyadmin/doc/html/_sources/user.txt              |     9 +
 phpmyadmin/doc/html/_sources/vendors.txt           |    34 +
 phpmyadmin/doc/html/_static/ajax-loader.gif        |   Bin 0 -> 673 bytes
 phpmyadmin/doc/html/_static/basic.css              |   540 +
 phpmyadmin/doc/html/_static/comment-bright.png     |   Bin 0 -> 3500 bytes
 phpmyadmin/doc/html/_static/comment-close.png      |   Bin 0 -> 3578 bytes
 phpmyadmin/doc/html/_static/comment.png            |   Bin 0 -> 3445 bytes
 phpmyadmin/doc/html/_static/default.css            |   256 +
 phpmyadmin/doc/html/_static/doctools.js            |   247 +
 phpmyadmin/doc/html/_static/down-pressed.png       |   Bin 0 -> 368 bytes
 phpmyadmin/doc/html/_static/down.png               |   Bin 0 -> 363 bytes
 phpmyadmin/doc/html/_static/file.png               |   Bin 0 -> 392 bytes
 phpmyadmin/doc/html/_static/jquery.js              |   154 +
 phpmyadmin/doc/html/_static/minus.png              |   Bin 0 -> 199 bytes
 phpmyadmin/doc/html/_static/plus.png               |   Bin 0 -> 199 bytes
 phpmyadmin/doc/html/_static/pygments.css           |    62 +
 phpmyadmin/doc/html/_static/searchtools.js         |   560 +
 phpmyadmin/doc/html/_static/sidebar.js             |   151 +
 phpmyadmin/doc/html/_static/underscore.js          |    23 +
 phpmyadmin/doc/html/_static/up-pressed.png         |   Bin 0 -> 372 bytes
 phpmyadmin/doc/html/_static/up.png                 |   Bin 0 -> 363 bytes
 phpmyadmin/doc/html/_static/websupport.js          |   808 +
 phpmyadmin/doc/html/config.html                    |  4896 +++
 phpmyadmin/doc/html/copyright.html                 |   134 +
 phpmyadmin/doc/html/credits.html                   |   658 +
 phpmyadmin/doc/html/developers.html                |   118 +
 phpmyadmin/doc/html/faq.html                       |  1780 ++
 phpmyadmin/doc/html/genindex.html                  |  3699 +++
 phpmyadmin/doc/html/glossary.html                  |   627 +
 phpmyadmin/doc/html/index.html                     |   206 +
 phpmyadmin/doc/html/intro.html                     |   182 +
 phpmyadmin/doc/html/objects.inv                    |   Bin 0 -> 9513 bytes
 phpmyadmin/doc/html/other.html                     |   135 +
 phpmyadmin/doc/html/privileges.html                |   169 +
 phpmyadmin/doc/html/require.html                   |   170 +
 phpmyadmin/doc/html/search.html                    |   100 +
 phpmyadmin/doc/html/searchindex.js                 |     1 +
 phpmyadmin/doc/html/setup.html                     |   481 +
 phpmyadmin/doc/html/transformations.html           |   240 +
 phpmyadmin/doc/html/user.html                      |   135 +
 phpmyadmin/doc/html/vendors.html                   |   147 +
 phpmyadmin/doc/index.rst                           |    32 +
 phpmyadmin/doc/intro.rst                           |    68 +
 phpmyadmin/doc/make.bat                            |   190 +
 phpmyadmin/doc/other.rst                           |    18 +
 phpmyadmin/doc/privileges.rst                      |    50 +
 phpmyadmin/doc/require.rst                         |    55 +
 phpmyadmin/doc/setup.rst                           |   424 +
 phpmyadmin/doc/transformations.rst                 |   138 +
 phpmyadmin/doc/user.rst                            |     9 +
 phpmyadmin/doc/vendors.rst                         |    34 +
 phpmyadmin/examples/config.manyhosts.inc.php       |    46 +
 phpmyadmin/examples/create_tables.sql              |   241 +
 phpmyadmin/examples/create_tables_drizzle.sql      |   228 +
 phpmyadmin/examples/openid.php                     |   158 +
 phpmyadmin/examples/signon-script.php              |    29 +
 phpmyadmin/examples/signon.php                     |    65 +
 phpmyadmin/examples/swekey.sample.conf             |    44 +
 .../examples/upgrade_tables_mysql_4_1_2+.sql       |   144 +
 phpmyadmin/export.php                              |   979 +
 phpmyadmin/favicon.ico                             |   Bin 0 -> 18902 bytes
 phpmyadmin/file_echo.php                           |    71 +
 phpmyadmin/gis_data_editor.php                     |   416 +
 phpmyadmin/import.php                              |   619 +
 phpmyadmin/import_status.php                       |   105 +
 phpmyadmin/index.php                               |   616 +
 phpmyadmin/js/OpenStreetMap.js                     |     1 +
 phpmyadmin/js/ajax.js                              |     1 +
 phpmyadmin/js/canvg/MIT-LICENSE.txt                |    22 +
 phpmyadmin/js/canvg/canvg.js                       |     1 +
 phpmyadmin/js/canvg/flashcanvas.js                 |     1 +
 phpmyadmin/js/canvg/flashcanvas.swf                |   Bin 0 -> 21235 bytes
 phpmyadmin/js/chart.js                             |     1 +
 phpmyadmin/js/codemirror/LICENSE                   |    19 +
 phpmyadmin/js/codemirror/lib/codemirror.js         |     1 +
 phpmyadmin/js/codemirror/mode/mysql/mysql.js       |     1 +
 phpmyadmin/js/common.js                            |     1 +
 phpmyadmin/js/config.js                            |     1 +
 phpmyadmin/js/date.js                              |     1 +
 phpmyadmin/js/db_operations.js                     |     1 +
 phpmyadmin/js/db_search.js                         |     1 +
 phpmyadmin/js/db_structure.js                      |     1 +
 phpmyadmin/js/export.js                            |     1 +
 phpmyadmin/js/functions.js                         |     1 +
 phpmyadmin/js/get_image.js.php                     |   138 +
 phpmyadmin/js/get_scripts.js.php                   |    38 +
 phpmyadmin/js/gis_data_editor.js                   |     1 +
 phpmyadmin/js/import.js                            |     1 +
 phpmyadmin/js/indexes.js                           |     1 +
 phpmyadmin/js/jqplot/excanvas.js                   |     1 +
 phpmyadmin/js/jqplot/jquery.jqplot.js              |     1 +
 phpmyadmin/js/jqplot/plugins/jqplot.barRenderer.js |     1 +
 .../js/jqplot/plugins/jqplot.byteFormatter.js      |     1 +
 .../plugins/jqplot.canvasAxisLabelRenderer.js      |     1 +
 .../js/jqplot/plugins/jqplot.canvasTextRenderer.js |     1 +
 .../jqplot/plugins/jqplot.categoryAxisRenderer.js  |     1 +
 phpmyadmin/js/jqplot/plugins/jqplot.cursor.js      |     1 +
 .../js/jqplot/plugins/jqplot.dateAxisRenderer.js   |     1 +
 phpmyadmin/js/jqplot/plugins/jqplot.highlighter.js |     1 +
 phpmyadmin/js/jqplot/plugins/jqplot.pieRenderer.js |     1 +
 phpmyadmin/js/jqplot/plugins/jqplot.pointLabels.js |     1 +
 phpmyadmin/js/jquery/jquery-1.8.3.js               |    21 +
 phpmyadmin/js/jquery/jquery-ui-1.9.2.custom.js     |    16 +
 phpmyadmin/js/jquery/jquery-ui-timepicker-addon.js |     1 +
 phpmyadmin/js/jquery/jquery.ba-hashchange-1.3.js   |     9 +
 phpmyadmin/js/jquery/jquery.cookie.js              |     1 +
 phpmyadmin/js/jquery/jquery.debounce-1.0.5.js      |     1 +
 phpmyadmin/js/jquery/jquery.event.drag-2.2.js      |     6 +
 phpmyadmin/js/jquery/jquery.fullscreen.js          |     1 +
 phpmyadmin/js/jquery/jquery.json-2.4.js            |     1 +
 phpmyadmin/js/jquery/jquery.menuResizer-1.0.js     |     1 +
 phpmyadmin/js/jquery/jquery.mousewheel.js          |    12 +
 phpmyadmin/js/jquery/jquery.sortableTable.js       |     1 +
 phpmyadmin/js/jquery/jquery.sprintf.js             |     1 +
 phpmyadmin/js/jquery/jquery.svg.js                 |     1 +
 phpmyadmin/js/jquery/jquery.tablesorter.js         |     1 +
 phpmyadmin/js/keyhandler.js                        |     1 +
 phpmyadmin/js/makegrid.js                          |     1 +
 phpmyadmin/js/messages.php                         |   530 +
 phpmyadmin/js/navigation.js                        |     1 +
 phpmyadmin/js/openlayers/OpenLayers.js             |     1 +
 phpmyadmin/js/openlayers/img/blank.gif             |   Bin 0 -> 42 bytes
 .../js/openlayers/img/cloud-popup-relative.png     |   Bin 0 -> 3177 bytes
 .../js/openlayers/img/drag-rectangle-off.png       |   Bin 0 -> 1202 bytes
 phpmyadmin/js/openlayers/img/drag-rectangle-on.png |   Bin 0 -> 1218 bytes
 phpmyadmin/js/openlayers/img/east-mini.png         |   Bin 0 -> 451 bytes
 .../js/openlayers/img/layer-switcher-maximize.png  |   Bin 0 -> 451 bytes
 .../js/openlayers/img/layer-switcher-minimize.png  |   Bin 0 -> 249 bytes
 phpmyadmin/js/openlayers/img/marker-blue.png       |   Bin 0 -> 992 bytes
 phpmyadmin/js/openlayers/img/marker-gold.png       |   Bin 0 -> 831 bytes
 phpmyadmin/js/openlayers/img/marker-green.png      |   Bin 0 -> 967 bytes
 phpmyadmin/js/openlayers/img/marker.png            |   Bin 0 -> 606 bytes
 .../js/openlayers/img/measuring-stick-off.png      |   Bin 0 -> 3343 bytes
 .../js/openlayers/img/measuring-stick-on.png       |   Bin 0 -> 3816 bytes
 phpmyadmin/js/openlayers/img/north-mini.png        |   Bin 0 -> 484 bytes
 phpmyadmin/js/openlayers/img/panning-hand-off.png  |   Bin 0 -> 3875 bytes
 phpmyadmin/js/openlayers/img/panning-hand-on.png   |   Bin 0 -> 3977 bytes
 phpmyadmin/js/openlayers/img/slider.png            |   Bin 0 -> 285 bytes
 phpmyadmin/js/openlayers/img/south-mini.png        |   Bin 0 -> 481 bytes
 phpmyadmin/js/openlayers/img/west-mini.png         |   Bin 0 -> 453 bytes
 phpmyadmin/js/openlayers/img/zoom-minus-mini.png   |   Bin 0 -> 359 bytes
 phpmyadmin/js/openlayers/img/zoom-plus-mini.png    |   Bin 0 -> 489 bytes
 phpmyadmin/js/openlayers/img/zoom-world-mini.png   |   Bin 0 -> 1072 bytes
 phpmyadmin/js/openlayers/img/zoombar.png           |   Bin 0 -> 463 bytes
 .../js/openlayers/theme/default/framedCloud.css    |     0
 phpmyadmin/js/openlayers/theme/default/google.css  |    10 +
 .../js/openlayers/theme/default/ie6-style.css      |     7 +
 .../openlayers/theme/default/img/add_point_off.png |   Bin 0 -> 1616 bytes
 .../openlayers/theme/default/img/add_point_on.png  |   Bin 0 -> 1464 bytes
 .../js/openlayers/theme/default/img/blank.gif      |   Bin 0 -> 42 bytes
 .../js/openlayers/theme/default/img/close.gif      |   Bin 0 -> 1078 bytes
 .../theme/default/img/drag-rectangle-off.png       |   Bin 0 -> 1202 bytes
 .../theme/default/img/drag-rectangle-on.png        |   Bin 0 -> 1218 bytes
 .../openlayers/theme/default/img/draw_line_off.png |   Bin 0 -> 1567 bytes
 .../openlayers/theme/default/img/draw_line_on.png  |   Bin 0 -> 1399 bytes
 .../theme/default/img/draw_point_off.png           |   Bin 0 -> 1612 bytes
 .../openlayers/theme/default/img/draw_point_on.png |   Bin 0 -> 1460 bytes
 .../theme/default/img/draw_polygon_off.png         |   Bin 0 -> 1546 bytes
 .../theme/default/img/draw_polygon_on.png          |   Bin 0 -> 1407 bytes
 .../theme/default/img/editing_tool_bar.png         |   Bin 0 -> 3901 bytes
 .../theme/default/img/move_feature_off.png         |   Bin 0 -> 1543 bytes
 .../theme/default/img/move_feature_on.png          |   Bin 0 -> 1379 bytes
 .../theme/default/img/navigation_history.png       |   Bin 0 -> 7021 bytes
 .../theme/default/img/overview_replacement.gif     |   Bin 0 -> 79 bytes
 .../theme/default/img/pan-panel-NOALPHA.png        |   Bin 0 -> 566 bytes
 .../js/openlayers/theme/default/img/pan-panel.png  |   Bin 0 -> 1287 bytes
 .../js/openlayers/theme/default/img/pan_off.png    |   Bin 0 -> 1696 bytes
 .../js/openlayers/theme/default/img/pan_on.png     |   Bin 0 -> 1568 bytes
 .../theme/default/img/panning-hand-off.png         |   Bin 0 -> 3875 bytes
 .../theme/default/img/panning-hand-on.png          |   Bin 0 -> 3977 bytes
 .../theme/default/img/remove_point_off.png         |   Bin 0 -> 1612 bytes
 .../theme/default/img/remove_point_on.png          |   Bin 0 -> 1464 bytes
 .../js/openlayers/theme/default/img/ruler.png      |   Bin 0 -> 1211 bytes
 .../theme/default/img/save_features_off.png        |   Bin 0 -> 357 bytes
 .../theme/default/img/save_features_on.png         |   Bin 0 -> 364 bytes
 .../openlayers/theme/default/img/view_next_off.png |   Bin 0 -> 1644 bytes
 .../openlayers/theme/default/img/view_next_on.png  |   Bin 0 -> 1686 bytes
 .../theme/default/img/view_previous_off.png        |   Bin 0 -> 1553 bytes
 .../theme/default/img/view_previous_on.png         |   Bin 0 -> 1592 bytes
 .../theme/default/img/zoom-panel-NOALPHA.png       |   Bin 0 -> 1173 bytes
 .../js/openlayers/theme/default/img/zoom-panel.png |   Bin 0 -> 1624 bytes
 phpmyadmin/js/openlayers/theme/default/style.css   |   397 +
 phpmyadmin/js/pmd/ajax.js                          |     1 +
 phpmyadmin/js/pmd/history.js                       |     1 +
 phpmyadmin/js/pmd/iecanvas.js                      |     1 +
 phpmyadmin/js/pmd/init.js                          |     1 +
 phpmyadmin/js/pmd/move.js                          |     1 +
 phpmyadmin/js/querywindow.js                       |     1 +
 phpmyadmin/js/replication.js                       |     1 +
 phpmyadmin/js/rte.js                               |     1 +
 phpmyadmin/js/server_databases.js                  |     1 +
 phpmyadmin/js/server_plugins.js                    |     1 +
 phpmyadmin/js/server_privileges.js                 |     1 +
 phpmyadmin/js/server_status.js                     |     1 +
 phpmyadmin/js/server_status_advisor.js             |     1 +
 phpmyadmin/js/server_status_monitor.js             |     1 +
 phpmyadmin/js/server_status_queries.js             |     1 +
 phpmyadmin/js/server_status_sorter.js              |     1 +
 phpmyadmin/js/server_status_variables.js           |     1 +
 phpmyadmin/js/server_variables.js                  |     1 +
 phpmyadmin/js/sql.js                               |     1 +
 phpmyadmin/js/tbl_change.js                        |     1 +
 phpmyadmin/js/tbl_chart.js                         |     1 +
 phpmyadmin/js/tbl_gis_visualization.js             |     1 +
 phpmyadmin/js/tbl_relation.js                      |     1 +
 phpmyadmin/js/tbl_select.js                        |     1 +
 phpmyadmin/js/tbl_structure.js                     |     1 +
 phpmyadmin/js/tbl_zoom_plot_jqplot.js              |     1 +
 phpmyadmin/libraries/.htaccess                     |     3 +
 phpmyadmin/libraries/Advisor.class.php             |   509 +
 phpmyadmin/libraries/Config.class.php              |  1829 ++
 phpmyadmin/libraries/DBQbe.class.php               |  1343 +
 phpmyadmin/libraries/DbSearch.class.php            |   489 +
 phpmyadmin/libraries/DisplayResults.class.php      |  5967 ++++
 phpmyadmin/libraries/Error.class.php               |   409 +
 phpmyadmin/libraries/Error_Handler.class.php       |   446 +
 phpmyadmin/libraries/File.class.php                |   863 +
 phpmyadmin/libraries/Footer.class.php              |   283 +
 phpmyadmin/libraries/Header.class.php              |   660 +
 phpmyadmin/libraries/Index.class.php               |   863 +
 phpmyadmin/libraries/List.class.php                |   121 +
 phpmyadmin/libraries/List_Database.class.php       |   318 +
 phpmyadmin/libraries/Menu.class.php                |   525 +
 phpmyadmin/libraries/Message.class.php             |   749 +
 phpmyadmin/libraries/OutputBuffering.class.php     |   148 +
 phpmyadmin/libraries/PDF.class.php                 |   143 +
 phpmyadmin/libraries/PMA.php                       |   106 +
 phpmyadmin/libraries/Partition.class.php           |    79 +
 phpmyadmin/libraries/RecentTable.class.php         |   210 +
 phpmyadmin/libraries/Response.class.php            |   377 +
 phpmyadmin/libraries/Scripts.class.php             |   243 +
 phpmyadmin/libraries/ServerStatusData.class.php    |   380 +
 phpmyadmin/libraries/StorageEngine.class.php       |   434 +
 phpmyadmin/libraries/Table.class.php               |  1664 ++
 phpmyadmin/libraries/TableSearch.class.php         |  1229 +
 phpmyadmin/libraries/Theme.class.php               |   601 +
 phpmyadmin/libraries/Theme_Manager.class.php       |   453 +
 phpmyadmin/libraries/Tracker.class.php             |  1079 +
 phpmyadmin/libraries/Types.class.php               |   984 +
 phpmyadmin/libraries/Util.class.php                |  4098 +++
 phpmyadmin/libraries/advisory_rules.txt            |   470 +
 .../libraries/bfShapeFiles/ShapeFile.lib.php       |   666 +
 phpmyadmin/libraries/bookmark.lib.php              |   208 +
 phpmyadmin/libraries/build_html_for_db.lib.php     |   180 +
 phpmyadmin/libraries/charset_conversion.lib.php    |    97 +
 phpmyadmin/libraries/check_user_privileges.lib.php |   165 +
 phpmyadmin/libraries/cleanup.lib.php               |    50 +
 phpmyadmin/libraries/common.inc.php                |  1142 +
 phpmyadmin/libraries/config.default.php            |  2824 ++
 phpmyadmin/libraries/config.values.php             |   239 +
 phpmyadmin/libraries/config/ConfigFile.class.php   |   549 +
 phpmyadmin/libraries/config/Form.class.php         |   210 +
 phpmyadmin/libraries/config/FormDisplay.class.php  |   831 +
 phpmyadmin/libraries/config/FormDisplay.tpl.php    |   489 +
 .../libraries/config/config_functions.lib.php      |    55 +
 phpmyadmin/libraries/config/messages.inc.php       |   523 +
 phpmyadmin/libraries/config/setup.forms.php        |   367 +
 .../libraries/config/user_preferences.forms.php    |   271 +
 phpmyadmin/libraries/config/validate.lib.php       |   584 +
 phpmyadmin/libraries/core.lib.php                  |   802 +
 .../libraries/data_dictionary_relations.lib.php    |   166 +
 phpmyadmin/libraries/database_interface.lib.php    |  2134 ++
 phpmyadmin/libraries/db_common.inc.php             |   100 +
 phpmyadmin/libraries/db_info.inc.php               |   224 +
 phpmyadmin/libraries/db_table_exists.lib.php       |   103 +
 phpmyadmin/libraries/dbi/drizzle-wrappers.lib.php  |   437 +
 phpmyadmin/libraries/dbi/drizzle.dbi.lib.php       |   667 +
 phpmyadmin/libraries/dbi/dummy.lib.php             |   511 +
 phpmyadmin/libraries/dbi/mysql.dbi.lib.php         |   552 +
 phpmyadmin/libraries/dbi/mysqli.dbi.lib.php        |   748 +
 .../libraries/display_change_password.lib.php      |    98 +
 .../libraries/display_create_database.lib.php      |    49 +
 phpmyadmin/libraries/display_create_table.lib.php  |    63 +
 phpmyadmin/libraries/display_export.lib.php        |   443 +
 phpmyadmin/libraries/display_git_revision.lib.php  |    83 +
 phpmyadmin/libraries/display_import.lib.php        |   338 +
 phpmyadmin/libraries/display_import_ajax.lib.php   |   132 +
 phpmyadmin/libraries/display_select_lang.lib.php   |    98 +
 phpmyadmin/libraries/engines/bdb.lib.php           |    84 +
 phpmyadmin/libraries/engines/berkeleydb.lib.php    |    24 +
 phpmyadmin/libraries/engines/binlog.lib.php        |    28 +
 phpmyadmin/libraries/engines/innobase.lib.php      |    23 +
 phpmyadmin/libraries/engines/innodb.lib.php        |   411 +
 phpmyadmin/libraries/engines/memory.lib.php        |    34 +
 phpmyadmin/libraries/engines/merge.lib.php         |    21 +
 phpmyadmin/libraries/engines/mrg_myisam.lib.php    |    33 +
 phpmyadmin/libraries/engines/myisam.lib.php        |    69 +
 phpmyadmin/libraries/engines/ndbcluster.lib.php    |    55 +
 phpmyadmin/libraries/engines/pbxt.lib.php          |   142 +
 .../libraries/engines/performance_schema.lib.php   |    28 +
 phpmyadmin/libraries/error.inc.php                 |    59 +
 phpmyadmin/libraries/file_listing.lib.php          |   103 +
 phpmyadmin/libraries/gis/pma_gis_factory.php       |    61 +
 phpmyadmin/libraries/gis/pma_gis_geometry.php      |   361 +
 .../libraries/gis/pma_gis_geometrycollection.php   |   336 +
 phpmyadmin/libraries/gis/pma_gis_linestring.php    |   298 +
 .../libraries/gis/pma_gis_multilinestring.php      |   370 +
 phpmyadmin/libraries/gis/pma_gis_multipoint.php    |   343 +
 phpmyadmin/libraries/gis/pma_gis_multipolygon.php  |   527 +
 phpmyadmin/libraries/gis/pma_gis_point.php         |   294 +
 phpmyadmin/libraries/gis/pma_gis_polygon.php       |   549 +
 phpmyadmin/libraries/gis/pma_gis_visualization.php |   503 +
 phpmyadmin/libraries/gis_visualization.lib.php     |   182 +
 phpmyadmin/libraries/iconv_wrapper.lib.php         |   105 +
 phpmyadmin/libraries/import.lib.php                |  1248 +
 phpmyadmin/libraries/index.lib.php                 |    44 +
 .../libraries/information_schema_relations.lib.php |   138 +
 phpmyadmin/libraries/insert_edit.lib.php           |  2366 ++
 phpmyadmin/libraries/ip_allow_deny.lib.php         |   327 +
 phpmyadmin/libraries/js_escape.lib.php             |   133 +
 phpmyadmin/libraries/kanji-encoding.lib.php        |   161 +
 phpmyadmin/libraries/language_stats.inc.php        |    76 +
 phpmyadmin/libraries/logging.lib.php               |    30 +
 phpmyadmin/libraries/mime.lib.php                  |    34 +
 phpmyadmin/libraries/mult_submits.inc.php          |   578 +
 phpmyadmin/libraries/mysql_charsets.lib.php        |   455 +
 .../libraries/navigation/Navigation.class.php      |    77 +
 .../navigation/NavigationHeader.class.php          |   298 +
 .../libraries/navigation/NavigationTree.class.php  |  1148 +
 .../libraries/navigation/NodeFactory.class.php     |    97 +
 .../libraries/navigation/Nodes/Node.class.php      |   455 +
 .../navigation/Nodes/Node_Column.class.php         |    71 +
 .../Nodes/Node_Column_Container.class.php          |    56 +
 .../navigation/Nodes/Node_Database.class.php       |   447 +
 .../navigation/Nodes/Node_Event.class.php          |    66 +
 .../Nodes/Node_Event_Container.class.php           |    52 +
 .../navigation/Nodes/Node_Function.class.php       |    67 +
 .../Nodes/Node_Function_Container.class.php        |    52 +
 .../navigation/Nodes/Node_Index.class.php          |    45 +
 .../Nodes/Node_Index_Container.class.php           |    54 +
 .../navigation/Nodes/Node_Procedure.class.php      |    67 +
 .../Nodes/Node_Procedure_Container.class.php       |    52 +
 .../navigation/Nodes/Node_Table.class.php          |   229 +
 .../Nodes/Node_Table_Container.class.php           |    54 +
 .../navigation/Nodes/Node_Trigger.class.php        |    45 +
 .../Nodes/Node_Trigger_Container.class.php         |    53 +
 .../libraries/navigation/Nodes/Node_View.class.php |    44 +
 .../navigation/Nodes/Node_View_Container.class.php |    50 +
 phpmyadmin/libraries/opendocument.lib.php          |   170 +
 phpmyadmin/libraries/operations.lib.php            |  1609 +
 phpmyadmin/libraries/parse_analyze.lib.php         |    61 +
 phpmyadmin/libraries/php-gettext/gettext.inc       |   536 +
 phpmyadmin/libraries/php-gettext/gettext.php       |   432 +
 phpmyadmin/libraries/php-gettext/streams.php       |   167 +
 phpmyadmin/libraries/phpseclib/Crypt/AES.php       |   612 +
 phpmyadmin/libraries/phpseclib/Crypt/Rijndael.php  |  1479 +
 phpmyadmin/libraries/plugin_interface.lib.php      |   508 +
 .../plugins/AuthenticationPlugin.class.php         |    51 +
 .../libraries/plugins/ExportPlugin.class.php       |   205 +
 .../libraries/plugins/ImportPlugin.class.php       |    59 +
 .../libraries/plugins/PluginManager.class.php      |   132 +
 .../libraries/plugins/PluginObserver.class.php     |    90 +
 .../plugins/TransformationsInterface.int.php       |    49 +
 .../plugins/TransformationsPlugin.class.php        |    49 +
 .../libraries/plugins/UploadInterface.int.php      |    36 +
 .../plugins/auth/AuthenticationConfig.class.php    |   172 +
 .../plugins/auth/AuthenticationCookie.class.php    |   696 +
 .../plugins/auth/AuthenticationHttp.class.php      |   249 +
 .../plugins/auth/AuthenticationSignon.class.php    |   284 +
 .../plugins/auth/swekey/authentication.inc.php     |   172 +
 .../libraries/plugins/auth/swekey/musbe-ca.crt     |    25 +
 .../plugins/auth/swekey/swekey.auth.lib.php        |   293 +
 .../libraries/plugins/auth/swekey/swekey.php       |   522 +
 .../plugins/export/ExportCodegen.class.php         |   423 +
 .../libraries/plugins/export/ExportCsv.class.php   |   345 +
 .../libraries/plugins/export/ExportExcel.class.php |   105 +
 .../plugins/export/ExportHtmlword.class.php        |   645 +
 .../libraries/plugins/export/ExportJson.class.php  |   221 +
 .../libraries/plugins/export/ExportLatex.class.php |   655 +
 .../plugins/export/ExportMediawiki.class.php       |   364 +
 .../libraries/plugins/export/ExportOds.class.php   |   334 +
 .../libraries/plugins/export/ExportOdt.class.php   |   734 +
 .../libraries/plugins/export/ExportPdf.class.php   |   268 +
 .../plugins/export/ExportPhparray.class.php        |   227 +
 .../libraries/plugins/export/ExportSql.class.php   |  1876 ++
 .../plugins/export/ExportTexytext.class.php        |   574 +
 .../libraries/plugins/export/ExportXml.class.php   |   536 +
 .../libraries/plugins/export/ExportYaml.class.php  |   214 +
 .../plugins/export/PMA_ExportPdf.class.php         |   408 +
 phpmyadmin/libraries/plugins/export/README         |   276 +
 .../plugins/export/TableProperty.class.php         |   288 +
 .../plugins/import/AbstractImportCsv.class.php     |    91 +
 .../libraries/plugins/import/ImportCsv.class.php   |   588 +
 .../libraries/plugins/import/ImportLdi.class.php   |   172 +
 .../plugins/import/ImportMediawiki.class.php       |   573 +
 .../libraries/plugins/import/ImportOds.class.php   |   415 +
 .../libraries/plugins/import/ImportShp.class.php   |   342 +
 .../libraries/plugins/import/ImportSql.class.php   |   440 +
 .../libraries/plugins/import/ImportXml.class.php   |   379 +
 phpmyadmin/libraries/plugins/import/README         |   173 +
 .../libraries/plugins/import/ShapeFile.class.php   |   102 +
 .../libraries/plugins/import/ShapeRecord.class.php |   161 +
 .../plugins/import/upload/UploadApc.class.php      |    84 +
 .../plugins/import/upload/UploadNoplugin.class.php |    64 +
 .../plugins/import/upload/UploadProgress.class.php |    94 +
 .../plugins/import/upload/UploadSession.class.php  |    96 +
 .../Application_Octetstream_Download.class.php     |    64 +
 .../Application_Octetstream_Hex.class.php          |    65 +
 .../transformations/Image_JPEG_Inline.class.php    |    65 +
 .../transformations/Image_JPEG_Link.class.php      |    65 +
 .../transformations/Image_PNG_Inline.class.php     |    65 +
 .../libraries/plugins/transformations/README       |     4 +
 .../libraries/plugins/transformations/TEMPLATE     |    68 +
 .../plugins/transformations/TEMPLATE_ABSTRACT      |    89 +
 .../transformations/Text_Plain_Append.class.php    |    66 +
 .../Text_Plain_Dateformat.class.php                |    65 +
 .../transformations/Text_Plain_External.class.php  |    65 +
 .../transformations/Text_Plain_Formatted.class.php |    65 +
 .../transformations/Text_Plain_Imagelink.class.php |    65 +
 .../transformations/Text_Plain_Link.class.php      |    65 +
 .../Text_Plain_Longtoipv4.class.php                |    65 +
 .../transformations/Text_Plain_Sql.class.php       |    65 +
 .../transformations/Text_Plain_Substring.class.php |    65 +
 .../abstract/AppendTransformationsPlugin.class.php |    86 +
 .../DateFormatTransformationsPlugin.class.php      |   178 +
 .../DownloadTransformationsPlugin.class.php        |   110 +
 .../ExternalTransformationsPlugin.class.php        |   182 +
 .../FormattedTransformationsPlugin.class.php       |    80 +
 .../abstract/HexTransformationsPlugin.class.php    |    91 +
 .../ImageLinkTransformationsPlugin.class.php       |    89 +
 .../abstract/InlineTransformationsPlugin.class.php |   103 +
 .../LongToIPv4TransformationsPlugin.class.php      |    83 +
 .../abstract/SQLTransformationsPlugin.class.php    |    81 +
 .../SubstringTransformationsPlugin.class.php       |   116 +
 .../TextImageLinkTransformationsPlugin.class.php   |    96 +
 .../TextLinkTransformationsPlugin.class.php        |    98 +
 .../transformations/generator_main_class.sh        |    16 +
 .../plugins/transformations/generator_plugin.sh    |    64 +
 phpmyadmin/libraries/pmd_common.php                |   262 +
 .../libraries/properties/PropertyItem.class.php    |    49 +
 .../options/OptionsPropertyGroup.class.php         |   104 +
 .../options/OptionsPropertyItem.class.php          |   127 +
 .../options/OptionsPropertyOneItem.class.php       |   172 +
 .../groups/OptionsPropertyMainGroup.class.php      |    35 +
 .../groups/OptionsPropertyRootGroup.class.php      |    35 +
 .../groups/OptionsPropertySubgroup.class.php       |    68 +
 .../options/items/BoolPropertyItem.class.php       |    35 +
 .../options/items/DocPropertyItem.class.php        |    35 +
 .../options/items/HiddenPropertyItem.class.php     |    35 +
 .../items/MessageOnlyPropertyItem.class.php        |    35 +
 .../options/items/RadioPropertyItem.class.php      |    35 +
 .../options/items/SelectPropertyItem.class.php     |    35 +
 .../options/items/TextPropertyItem.class.php       |    35 +
 .../plugins/ExportPluginProperties.class.php       |   214 +
 .../plugins/ImportPluginProperties.class.php       |   184 +
 .../plugins/PluginPropertyItem.class.php           |    36 +
 phpmyadmin/libraries/relation.lib.php              |  1396 +
 phpmyadmin/libraries/relation_cleanup.lib.php      |   165 +
 phpmyadmin/libraries/replication.inc.php           |   307 +
 phpmyadmin/libraries/replication_gui.lib.php       |   401 +
 phpmyadmin/libraries/rte/rte_events.lib.php        |   637 +
 phpmyadmin/libraries/rte/rte_export.lib.php        |   122 +
 phpmyadmin/libraries/rte/rte_footer.lib.php        |   127 +
 phpmyadmin/libraries/rte/rte_list.lib.php          |   366 +
 phpmyadmin/libraries/rte/rte_main.inc.php          |    92 +
 phpmyadmin/libraries/rte/rte_routines.lib.php      |  1676 ++
 phpmyadmin/libraries/rte/rte_triggers.lib.php      |   486 +
 phpmyadmin/libraries/rte/rte_words.lib.php         |    64 +
 phpmyadmin/libraries/sanitizing.lib.php            |   190 +
 .../libraries/schema/Dia_Relation_Schema.class.php |   835 +
 .../libraries/schema/Eps_Relation_Schema.class.php |   957 +
 .../schema/Export_Relation_Schema.class.php        |   244 +
 .../libraries/schema/Pdf_Relation_Schema.class.php |  1443 +
 .../libraries/schema/Svg_Relation_Schema.class.php |   950 +
 phpmyadmin/libraries/schema/User_Schema.class.php  |   933 +
 phpmyadmin/libraries/select_lang.lib.php           |   556 +
 phpmyadmin/libraries/select_server.lib.php         |   108 +
 phpmyadmin/libraries/server_common.inc.php         |    56 +
 phpmyadmin/libraries/server_privileges.lib.php     |  3355 +++
 phpmyadmin/libraries/server_variables_doc.php      |  1403 +
 phpmyadmin/libraries/session.inc.php               |   120 +
 phpmyadmin/libraries/special_schema_links.lib.php  |   323 +
 phpmyadmin/libraries/sql_query_form.lib.php        |   496 +
 phpmyadmin/libraries/sqlparser.data.php            |  2016 ++
 phpmyadmin/libraries/sqlparser.lib.php             |  2906 ++
 phpmyadmin/libraries/sqlvalidator.class.php        |   457 +
 phpmyadmin/libraries/sqlvalidator.lib.php          |   106 +
 phpmyadmin/libraries/string.lib.php                |   101 +
 phpmyadmin/libraries/string_mb.lib.php             |    71 +
 phpmyadmin/libraries/string_native.lib.php         |    71 +
 phpmyadmin/libraries/string_type_ctype.lib.php     |   104 +
 phpmyadmin/libraries/string_type_native.lib.php    |   133 +
 phpmyadmin/libraries/structure.lib.php             |  2513 ++
 phpmyadmin/libraries/sysinfo.lib.php               |   363 +
 .../libraries/tbl_columns_definition_form.inc.php  |   906 +
 phpmyadmin/libraries/tbl_common.inc.php            |    63 +
 phpmyadmin/libraries/tbl_info.inc.php              |   105 +
 phpmyadmin/libraries/tbl_views.lib.php             |   157 +
 phpmyadmin/libraries/tcpdf/LICENSE.TXT             |   858 +
 phpmyadmin/libraries/tcpdf/README.TXT              |    97 +
 phpmyadmin/libraries/tcpdf/config/tcpdf_config.php |   258 +
 phpmyadmin/libraries/tcpdf/encodings_maps.php      |   846 +
 .../tcpdf/fonts/dejavu-fonts-ttf-2.33/LICENSE      |    99 +
 phpmyadmin/libraries/tcpdf/fonts/dejavusans.ctg.z  |   Bin 0 -> 10120 bytes
 phpmyadmin/libraries/tcpdf/fonts/dejavusans.php    |    15 +
 phpmyadmin/libraries/tcpdf/fonts/dejavusans.z      |   Bin 0 -> 361229 bytes
 phpmyadmin/libraries/tcpdf/fonts/dejavusansb.ctg.z |   Bin 0 -> 9854 bytes
 phpmyadmin/libraries/tcpdf/fonts/dejavusansb.php   |    15 +
 phpmyadmin/libraries/tcpdf/fonts/dejavusansb.z     |   Bin 0 -> 333391 bytes
 phpmyadmin/libraries/tcpdf/fonts/helvetica.php     |    13 +
 phpmyadmin/libraries/tcpdf/htmlcolors.php          |   199 +
 phpmyadmin/libraries/tcpdf/tcpdf.php               | 29927 +++++++++++++++++++
 phpmyadmin/libraries/tcpdf/unicode_data.php        | 18371 ++++++++++++
 phpmyadmin/libraries/transformations.lib.php       |   412 +
 phpmyadmin/libraries/url_generating.lib.php        |   302 +
 phpmyadmin/libraries/user_preferences.inc.php      |    71 +
 phpmyadmin/libraries/user_preferences.lib.php      |   288 +
 phpmyadmin/libraries/vendor_config.php             |    76 +
 phpmyadmin/libraries/zip.lib.php                   |   216 +
 phpmyadmin/libraries/zip_extension.lib.php         |   188 +
 phpmyadmin/license.php                             |    31 +
 phpmyadmin/locale/ar/LC_MESSAGES/phpmyadmin.mo     |   Bin 0 -> 115250 bytes
 phpmyadmin/locale/bg/LC_MESSAGES/phpmyadmin.mo     |   Bin 0 -> 224973 bytes
 phpmyadmin/locale/ca/LC_MESSAGES/phpmyadmin.mo     |   Bin 0 -> 299247 bytes
 phpmyadmin/locale/cs/LC_MESSAGES/phpmyadmin.mo     |   Bin 0 -> 294865 bytes
 phpmyadmin/locale/da/LC_MESSAGES/phpmyadmin.mo     |   Bin 0 -> 289850 bytes
 phpmyadmin/locale/de/LC_MESSAGES/phpmyadmin.mo     |   Bin 0 -> 302646 bytes
 phpmyadmin/locale/el/LC_MESSAGES/phpmyadmin.mo     |   Bin 0 -> 407201 bytes
 phpmyadmin/locale/en_GB/LC_MESSAGES/phpmyadmin.mo  |   Bin 0 -> 280613 bytes
 phpmyadmin/locale/es/LC_MESSAGES/phpmyadmin.mo     |   Bin 0 -> 307246 bytes
 phpmyadmin/locale/et/LC_MESSAGES/phpmyadmin.mo     |   Bin 0 -> 285386 bytes
 phpmyadmin/locale/fi/LC_MESSAGES/phpmyadmin.mo     |   Bin 0 -> 177545 bytes
 phpmyadmin/locale/fr/LC_MESSAGES/phpmyadmin.mo     |   Bin 0 -> 305497 bytes
 phpmyadmin/locale/gl/LC_MESSAGES/phpmyadmin.mo     |   Bin 0 -> 299946 bytes
 phpmyadmin/locale/hi/LC_MESSAGES/phpmyadmin.mo     |   Bin 0 -> 169310 bytes
 phpmyadmin/locale/hr/LC_MESSAGES/phpmyadmin.mo     |   Bin 0 -> 101079 bytes
 phpmyadmin/locale/hu/LC_MESSAGES/phpmyadmin.mo     |   Bin 0 -> 204717 bytes
 phpmyadmin/locale/id/LC_MESSAGES/phpmyadmin.mo     |   Bin 0 -> 163565 bytes
 phpmyadmin/locale/it/LC_MESSAGES/phpmyadmin.mo     |   Bin 0 -> 275439 bytes
 phpmyadmin/locale/ja/LC_MESSAGES/phpmyadmin.mo     |   Bin 0 -> 313785 bytes
 phpmyadmin/locale/ko/LC_MESSAGES/phpmyadmin.mo     |   Bin 0 -> 166964 bytes
 phpmyadmin/locale/lt/LC_MESSAGES/phpmyadmin.mo     |   Bin 0 -> 154043 bytes
 phpmyadmin/locale/nb/LC_MESSAGES/phpmyadmin.mo     |   Bin 0 -> 181573 bytes
 phpmyadmin/locale/nl/LC_MESSAGES/phpmyadmin.mo     |   Bin 0 -> 298120 bytes
 phpmyadmin/locale/pl/LC_MESSAGES/phpmyadmin.mo     |   Bin 0 -> 296050 bytes
 phpmyadmin/locale/pt/LC_MESSAGES/phpmyadmin.mo     |   Bin 0 -> 120011 bytes
 phpmyadmin/locale/pt_BR/LC_MESSAGES/phpmyadmin.mo  |   Bin 0 -> 300910 bytes
 phpmyadmin/locale/ro/LC_MESSAGES/phpmyadmin.mo     |   Bin 0 -> 149400 bytes
 phpmyadmin/locale/ru/LC_MESSAGES/phpmyadmin.mo     |   Bin 0 -> 394178 bytes
 phpmyadmin/locale/si/LC_MESSAGES/phpmyadmin.mo     |   Bin 0 -> 297064 bytes
 phpmyadmin/locale/sk/LC_MESSAGES/phpmyadmin.mo     |   Bin 0 -> 221664 bytes
 phpmyadmin/locale/sl/LC_MESSAGES/phpmyadmin.mo     |   Bin 0 -> 292337 bytes
 .../locale/sr at latin/LC_MESSAGES/phpmyadmin.mo      |   Bin 0 -> 159377 bytes
 phpmyadmin/locale/sv/LC_MESSAGES/phpmyadmin.mo     |   Bin 0 -> 289017 bytes
 phpmyadmin/locale/th/LC_MESSAGES/phpmyadmin.mo     |   Bin 0 -> 136908 bytes
 phpmyadmin/locale/tr/LC_MESSAGES/phpmyadmin.mo     |   Bin 0 -> 300954 bytes
 phpmyadmin/locale/uk/LC_MESSAGES/phpmyadmin.mo     |   Bin 0 -> 344070 bytes
 phpmyadmin/locale/uz/LC_MESSAGES/phpmyadmin.mo     |   Bin 0 -> 178426 bytes
 .../locale/uz at latin/LC_MESSAGES/phpmyadmin.mo      |   Bin 0 -> 137336 bytes
 phpmyadmin/locale/zh_CN/LC_MESSAGES/phpmyadmin.mo  |   Bin 0 -> 263011 bytes
 phpmyadmin/locale/zh_TW/LC_MESSAGES/phpmyadmin.mo  |   Bin 0 -> 201513 bytes
 phpmyadmin/navigation.php                          |    27 +
 phpmyadmin/phpinfo.php                             |    21 +
 phpmyadmin/phpmyadmin.css.php                      |    31 +
 phpmyadmin/phpunit.xml.nocoverage                  |    47 +
 phpmyadmin/pmd_display_field.php                   |    61 +
 phpmyadmin/pmd_general.php                         |   879 +
 phpmyadmin/pmd_pdf.php                             |   156 +
 phpmyadmin/pmd_relation_new.php                    |   119 +
 phpmyadmin/pmd_relation_upd.php                    |    75 +
 phpmyadmin/pmd_save_pos.php                        |    84 +
 phpmyadmin/prefs_forms.php                         |    91 +
 phpmyadmin/prefs_manage.php                        |   331 +
 phpmyadmin/print.css                               |    92 +
 phpmyadmin/querywindow.php                         |   207 +
 phpmyadmin/robots.txt                              |     2 +
 phpmyadmin/schema_edit.php                         |   126 +
 phpmyadmin/schema_export.php                       |    66 +
 phpmyadmin/server_binlog.php                       |   219 +
 phpmyadmin/server_collations.php                   |    84 +
 phpmyadmin/server_databases.php                    |   349 +
 phpmyadmin/server_engines.php                      |   129 +
 phpmyadmin/server_export.php                       |    73 +
 phpmyadmin/server_import.php                       |    27 +
 phpmyadmin/server_plugins.php                      |   184 +
 phpmyadmin/server_privileges.php                   |   490 +
 phpmyadmin/server_replication.php                  |   349 +
 phpmyadmin/server_sql.php                          |    30 +
 phpmyadmin/server_status.php                       |   496 +
 phpmyadmin/server_status_advisor.php               |    74 +
 phpmyadmin/server_status_monitor.php               |   756 +
 phpmyadmin/server_status_queries.php               |   162 +
 phpmyadmin/server_status_variables.php             |   767 +
 phpmyadmin/server_variables.php                    |   247 +
 phpmyadmin/setup/ajax.js                           |    11 +
 phpmyadmin/setup/config.php                        |    78 +
 phpmyadmin/setup/frames/.htaccess                  |     3 +
 phpmyadmin/setup/frames/config.inc.php             |    48 +
 phpmyadmin/setup/frames/form.inc.php               |    36 +
 phpmyadmin/setup/frames/index.inc.php              |   276 +
 phpmyadmin/setup/frames/menu.inc.php               |    23 +
 phpmyadmin/setup/frames/servers.inc.php            |    49 +
 phpmyadmin/setup/index.php                         |    60 +
 phpmyadmin/setup/lib/.htaccess                     |     3 +
 phpmyadmin/setup/lib/ConfigGenerator.class.php     |   154 +
 phpmyadmin/setup/lib/common.inc.php                |    56 +
 phpmyadmin/setup/lib/form_processing.lib.php       |    62 +
 phpmyadmin/setup/lib/index.lib.php                 |   605 +
 phpmyadmin/setup/scripts.js                        |   204 +
 phpmyadmin/setup/styles.css                        |   631 +
 phpmyadmin/setup/validate.php                      |    30 +
 phpmyadmin/show_config_errors.php                  |    40 +
 phpmyadmin/sql.php                                 |  1740 ++
 phpmyadmin/tbl_addfield.php                        |   250 +
 phpmyadmin/tbl_change.php                          |   437 +
 phpmyadmin/tbl_chart.php                           |   266 +
 phpmyadmin/tbl_create.php                          |   450 +
 phpmyadmin/tbl_export.php                          |    85 +
 phpmyadmin/tbl_get_field.php                       |    67 +
 phpmyadmin/tbl_gis_visualization.php               |   220 +
 phpmyadmin/tbl_import.php                          |    30 +
 phpmyadmin/tbl_indexes.php                         |   365 +
 phpmyadmin/tbl_move_copy.php                       |   103 +
 phpmyadmin/tbl_operations.php                      |   378 +
 phpmyadmin/tbl_printview.php                       |   463 +
 phpmyadmin/tbl_relation.php                        |   689 +
 phpmyadmin/tbl_replace.php                         |   398 +
 phpmyadmin/tbl_row_action.php                      |   143 +
 phpmyadmin/tbl_select.php                          |    69 +
 phpmyadmin/tbl_sql.php                             |    46 +
 phpmyadmin/tbl_structure.php                       |   466 +
 phpmyadmin/tbl_tracking.php                        |   889 +
 phpmyadmin/tbl_triggers.php                        |    10 +
 phpmyadmin/tbl_zoom_select.php                     |   171 +
 phpmyadmin/themes.php                              |    31 +
 phpmyadmin/themes/dot.gif                          |   Bin 0 -> 43 bytes
 phpmyadmin/themes/original/css/common.css.php      |  2521 ++
 phpmyadmin/themes/original/css/navigation.css.php  |   252 +
 .../themes/original/img/ajax_clock_small.gif       |   Bin 0 -> 1810 bytes
 phpmyadmin/themes/original/img/arrow_ltr.png       |   Bin 0 -> 139 bytes
 phpmyadmin/themes/original/img/arrow_rtl.png       |   Bin 0 -> 136 bytes
 phpmyadmin/themes/original/img/b_bookmark.png      |   Bin 0 -> 252 bytes
 phpmyadmin/themes/original/img/b_browse.png        |   Bin 0 -> 157 bytes
 phpmyadmin/themes/original/img/b_calendar.png      |   Bin 0 -> 203 bytes
 phpmyadmin/themes/original/img/b_chart.png         |   Bin 0 -> 402 bytes
 phpmyadmin/themes/original/img/b_close.png         |   Bin 0 -> 180 bytes
 phpmyadmin/themes/original/img/b_column_add.png    |   Bin 0 -> 534 bytes
 phpmyadmin/themes/original/img/b_comment.png       |   Bin 0 -> 363 bytes
 phpmyadmin/themes/original/img/b_dbstatistics.png  |   Bin 0 -> 157 bytes
 phpmyadmin/themes/original/img/b_deltbl.png        |   Bin 0 -> 239 bytes
 phpmyadmin/themes/original/img/b_docs.png          |   Bin 0 -> 184 bytes
 phpmyadmin/themes/original/img/b_drop.png          |   Bin 0 -> 184 bytes
 phpmyadmin/themes/original/img/b_edit.png          |   Bin 0 -> 305 bytes
 phpmyadmin/themes/original/img/b_empty.png         |   Bin 0 -> 186 bytes
 phpmyadmin/themes/original/img/b_engine.png        |   Bin 0 -> 232 bytes
 phpmyadmin/themes/original/img/b_event_add.png     |   Bin 0 -> 863 bytes
 phpmyadmin/themes/original/img/b_events.png        |   Bin 0 -> 783 bytes
 phpmyadmin/themes/original/img/b_export.png        |   Bin 0 -> 199 bytes
 phpmyadmin/themes/original/img/b_ftext.png         |   Bin 0 -> 175 bytes
 phpmyadmin/themes/original/img/b_globe.gif         |   Bin 0 -> 1045 bytes
 phpmyadmin/themes/original/img/b_group.png         |   Bin 0 -> 796 bytes
 phpmyadmin/themes/original/img/b_help.png          |   Bin 0 -> 145 bytes
 phpmyadmin/themes/original/img/b_home.png          |   Bin 0 -> 238 bytes
 phpmyadmin/themes/original/img/b_import.png        |   Bin 0 -> 202 bytes
 phpmyadmin/themes/original/img/b_index.png         |   Bin 0 -> 207 bytes
 phpmyadmin/themes/original/img/b_index_add.png     |   Bin 0 -> 429 bytes
 phpmyadmin/themes/original/img/b_info.png          |   Bin 0 -> 147 bytes
 phpmyadmin/themes/original/img/b_inline_edit.png   |   Bin 0 -> 302 bytes
 phpmyadmin/themes/original/img/b_insrow.png        |   Bin 0 -> 183 bytes
 phpmyadmin/themes/original/img/b_minus.png         |   Bin 0 -> 110 bytes
 phpmyadmin/themes/original/img/b_more.png          |   Bin 0 -> 132 bytes
 phpmyadmin/themes/original/img/b_move.png          |   Bin 0 -> 168 bytes
 phpmyadmin/themes/original/img/b_newdb.png         |   Bin 0 -> 260 bytes
 phpmyadmin/themes/original/img/b_newtbl.png        |   Bin 0 -> 264 bytes
 phpmyadmin/themes/original/img/b_nextpage.png      |   Bin 0 -> 373 bytes
 phpmyadmin/themes/original/img/b_plus.png          |   Bin 0 -> 115 bytes
 phpmyadmin/themes/original/img/b_primary.png       |   Bin 0 -> 278 bytes
 phpmyadmin/themes/original/img/b_print.png         |   Bin 0 -> 396 bytes
 phpmyadmin/themes/original/img/b_props.png         |   Bin 0 -> 188 bytes
 phpmyadmin/themes/original/img/b_relations.png     |   Bin 0 -> 172 bytes
 phpmyadmin/themes/original/img/b_routine_add.png   |   Bin 0 -> 409 bytes
 phpmyadmin/themes/original/img/b_routines.png      |   Bin 0 -> 310 bytes
 phpmyadmin/themes/original/img/b_save.png          |   Bin 0 -> 844 bytes
 phpmyadmin/themes/original/img/b_sbrowse.png       |   Bin 0 -> 122 bytes
 phpmyadmin/themes/original/img/b_search.png        |   Bin 0 -> 442 bytes
 phpmyadmin/themes/original/img/b_selboard.png      |   Bin 0 -> 175 bytes
 phpmyadmin/themes/original/img/b_select.png        |   Bin 0 -> 387 bytes
 phpmyadmin/themes/original/img/b_snewtbl.png       |   Bin 0 -> 168 bytes
 phpmyadmin/themes/original/img/b_spatial.png       |   Bin 0 -> 379 bytes
 phpmyadmin/themes/original/img/b_sql.png           |   Bin 0 -> 208 bytes
 phpmyadmin/themes/original/img/b_sqlhelp.png       |   Bin 0 -> 173 bytes
 phpmyadmin/themes/original/img/b_table_add.png     |   Bin 0 -> 368 bytes
 phpmyadmin/themes/original/img/b_tblanalyse.png    |   Bin 0 -> 188 bytes
 phpmyadmin/themes/original/img/b_tblexport.png     |   Bin 0 -> 176 bytes
 phpmyadmin/themes/original/img/b_tblimport.png     |   Bin 0 -> 174 bytes
 phpmyadmin/themes/original/img/b_tblops.png        |   Bin 0 -> 220 bytes
 phpmyadmin/themes/original/img/b_tbloptimize.png   |   Bin 0 -> 198 bytes
 phpmyadmin/themes/original/img/b_tipp.png          |   Bin 0 -> 201 bytes
 phpmyadmin/themes/original/img/b_trigger_add.png   |   Bin 0 -> 615 bytes
 phpmyadmin/themes/original/img/b_triggers.png      |   Bin 0 -> 494 bytes
 phpmyadmin/themes/original/img/b_unique.png        |   Bin 0 -> 175 bytes
 phpmyadmin/themes/original/img/b_usradd.png        |   Bin 0 -> 352 bytes
 phpmyadmin/themes/original/img/b_usrcheck.png      |   Bin 0 -> 259 bytes
 phpmyadmin/themes/original/img/b_usrdrop.png       |   Bin 0 -> 289 bytes
 phpmyadmin/themes/original/img/b_usredit.png       |   Bin 0 -> 339 bytes
 phpmyadmin/themes/original/img/b_usrlist.png       |   Bin 0 -> 262 bytes
 phpmyadmin/themes/original/img/b_view.png          |   Bin 0 -> 646 bytes
 phpmyadmin/themes/original/img/b_view_add.png      |   Bin 0 -> 726 bytes
 phpmyadmin/themes/original/img/b_views.png         |   Bin 0 -> 326 bytes
 phpmyadmin/themes/original/img/bd_browse.png       |   Bin 0 -> 157 bytes
 phpmyadmin/themes/original/img/bd_deltbl.png       |   Bin 0 -> 278 bytes
 phpmyadmin/themes/original/img/bd_drop.png         |   Bin 0 -> 205 bytes
 phpmyadmin/themes/original/img/bd_edit.png         |   Bin 0 -> 226 bytes
 phpmyadmin/themes/original/img/bd_empty.png        |   Bin 0 -> 186 bytes
 phpmyadmin/themes/original/img/bd_export.png       |   Bin 0 -> 183 bytes
 phpmyadmin/themes/original/img/bd_ftext.png        |   Bin 0 -> 175 bytes
 phpmyadmin/themes/original/img/bd_index.png        |   Bin 0 -> 207 bytes
 phpmyadmin/themes/original/img/bd_insrow.png       |   Bin 0 -> 224 bytes
 phpmyadmin/themes/original/img/bd_nextpage.png     |   Bin 0 -> 110 bytes
 phpmyadmin/themes/original/img/bd_primary.png      |   Bin 0 -> 257 bytes
 phpmyadmin/themes/original/img/bd_sbrowse.png      |   Bin 0 -> 122 bytes
 phpmyadmin/themes/original/img/bd_select.png       |   Bin 0 -> 375 bytes
 phpmyadmin/themes/original/img/bd_spatial.png      |   Bin 0 -> 344 bytes
 phpmyadmin/themes/original/img/bd_unique.png       |   Bin 0 -> 175 bytes
 phpmyadmin/themes/original/img/cleardot.gif        |   Bin 0 -> 43 bytes
 phpmyadmin/themes/original/img/col_drop.png        |   Bin 0 -> 132 bytes
 phpmyadmin/themes/original/img/col_pointer.png     |   Bin 0 -> 101 bytes
 phpmyadmin/themes/original/img/col_pointer_ver.png |   Bin 0 -> 111 bytes
 phpmyadmin/themes/original/img/east-mini.png       |   Bin 0 -> 322 bytes
 phpmyadmin/themes/original/img/error.ico           |   Bin 0 -> 1150 bytes
 phpmyadmin/themes/original/img/eye.png             |   Bin 0 -> 721 bytes
 phpmyadmin/themes/original/img/eye_grey.png        |   Bin 0 -> 330 bytes
 phpmyadmin/themes/original/img/logo_left.png       |   Bin 0 -> 6796 bytes
 phpmyadmin/themes/original/img/logo_right.png      |   Bin 0 -> 4548 bytes
 phpmyadmin/themes/original/img/more.png            |   Bin 0 -> 117 bytes
 phpmyadmin/themes/original/img/new_data.png        |   Bin 0 -> 264 bytes
 .../themes/original/img/new_data_hovered.png       |   Bin 0 -> 264 bytes
 .../themes/original/img/new_data_selected.png      |   Bin 0 -> 179 bytes
 .../original/img/new_data_selected_hovered.png     |   Bin 0 -> 181 bytes
 phpmyadmin/themes/original/img/new_struct.png      |   Bin 0 -> 301 bytes
 .../themes/original/img/new_struct_hovered.png     |   Bin 0 -> 301 bytes
 .../themes/original/img/new_struct_selected.png    |   Bin 0 -> 189 bytes
 .../original/img/new_struct_selected_hovered.png   |   Bin 0 -> 196 bytes
 phpmyadmin/themes/original/img/north-mini.png      |   Bin 0 -> 327 bytes
 phpmyadmin/themes/original/img/pause.png           |   Bin 0 -> 271 bytes
 phpmyadmin/themes/original/img/play.png            |   Bin 0 -> 373 bytes
 phpmyadmin/themes/original/img/s_asc.png           |   Bin 0 -> 128 bytes
 phpmyadmin/themes/original/img/s_asci.png          |   Bin 0 -> 136 bytes
 phpmyadmin/themes/original/img/s_cancel.png        |   Bin 0 -> 310 bytes
 phpmyadmin/themes/original/img/s_cog.png           |   Bin 0 -> 222 bytes
 phpmyadmin/themes/original/img/s_db.png            |   Bin 0 -> 180 bytes
 phpmyadmin/themes/original/img/s_desc.png          |   Bin 0 -> 137 bytes
 phpmyadmin/themes/original/img/s_error.png         |   Bin 0 -> 173 bytes
 phpmyadmin/themes/original/img/s_error2.png        |   Bin 0 -> 152 bytes
 phpmyadmin/themes/original/img/s_fulltext.png      |   Bin 0 -> 193 bytes
 phpmyadmin/themes/original/img/s_host.png          |   Bin 0 -> 209 bytes
 phpmyadmin/themes/original/img/s_lang.png          |   Bin 0 -> 281 bytes
 phpmyadmin/themes/original/img/s_loggoff.png       |   Bin 0 -> 163 bytes
 phpmyadmin/themes/original/img/s_notice.png        |   Bin 0 -> 151 bytes
 phpmyadmin/themes/original/img/s_partialtext.png   |   Bin 0 -> 196 bytes
 phpmyadmin/themes/original/img/s_passwd.png        |   Bin 0 -> 353 bytes
 phpmyadmin/themes/original/img/s_really.png        |   Bin 0 -> 145 bytes
 phpmyadmin/themes/original/img/s_reload.png        |   Bin 0 -> 285 bytes
 phpmyadmin/themes/original/img/s_replication.png   |   Bin 0 -> 424 bytes
 phpmyadmin/themes/original/img/s_rights.png        |   Bin 0 -> 355 bytes
 phpmyadmin/themes/original/img/s_sortable.png      |   Bin 0 -> 132 bytes
 phpmyadmin/themes/original/img/s_status.png        |   Bin 0 -> 198 bytes
 phpmyadmin/themes/original/img/s_success.png       |   Bin 0 -> 589 bytes
 phpmyadmin/themes/original/img/s_sync.png          |   Bin 0 -> 498 bytes
 phpmyadmin/themes/original/img/s_tbl.png           |   Bin 0 -> 142 bytes
 phpmyadmin/themes/original/img/s_theme.png         |   Bin 0 -> 546 bytes
 phpmyadmin/themes/original/img/s_top.png           |   Bin 0 -> 443 bytes
 phpmyadmin/themes/original/img/s_vars.png          |   Bin 0 -> 190 bytes
 phpmyadmin/themes/original/img/s_views.png         |   Bin 0 -> 235 bytes
 phpmyadmin/themes/original/img/south-mini.png      |   Bin 0 -> 335 bytes
 phpmyadmin/themes/original/img/spacer.png          |   Bin 0 -> 84 bytes
 phpmyadmin/themes/original/img/sprites.png         |   Bin 0 -> 18431 bytes
 phpmyadmin/themes/original/img/toggle-ltr.png      |   Bin 0 -> 177 bytes
 phpmyadmin/themes/original/img/toggle-rtl.png      |   Bin 0 -> 177 bytes
 phpmyadmin/themes/original/img/vertical_line.png   |   Bin 0 -> 68 bytes
 phpmyadmin/themes/original/img/west-mini.png       |   Bin 0 -> 328 bytes
 phpmyadmin/themes/original/img/window-new.png      |   Bin 0 -> 484 bytes
 phpmyadmin/themes/original/img/zoom-minus-mini.png |   Bin 0 -> 247 bytes
 phpmyadmin/themes/original/img/zoom-plus-mini.png  |   Bin 0 -> 329 bytes
 phpmyadmin/themes/original/img/zoom-world-mini.png |   Bin 0 -> 808 bytes
 phpmyadmin/themes/original/info.inc.php            |    15 +
 .../jquery/images/ui-bg_flat_0_aaaaaa_40x100.png   |   Bin 0 -> 180 bytes
 .../jquery/images/ui-bg_flat_75_ffffff_40x100.png  |   Bin 0 -> 178 bytes
 .../jquery/images/ui-bg_glass_55_fbf9ee_1x400.png  |   Bin 0 -> 120 bytes
 .../jquery/images/ui-bg_glass_65_ffffff_1x400.png  |   Bin 0 -> 105 bytes
 .../jquery/images/ui-bg_glass_75_dadada_1x400.png  |   Bin 0 -> 159 bytes
 .../jquery/images/ui-bg_glass_75_e6e6e6_1x400.png  |   Bin 0 -> 110 bytes
 .../jquery/images/ui-bg_glass_95_fef1ec_1x400.png  |   Bin 0 -> 119 bytes
 .../ui-bg_highlight-soft_75_cccccc_1x100.png       |   Bin 0 -> 101 bytes
 .../jquery/images/ui-icons_222222_256x240.png      |   Bin 0 -> 4369 bytes
 .../jquery/images/ui-icons_2e83ff_256x240.png      |   Bin 0 -> 4369 bytes
 .../jquery/images/ui-icons_454545_256x240.png      |   Bin 0 -> 4369 bytes
 .../jquery/images/ui-icons_888888_256x240.png      |   Bin 0 -> 4369 bytes
 .../jquery/images/ui-icons_cd0a0a_256x240.png      |   Bin 0 -> 4369 bytes
 .../original/jquery/jquery-ui-1.9.2.custom.css     |   462 +
 phpmyadmin/themes/original/layout.inc.php          |   138 +
 phpmyadmin/themes/original/screen.png              |   Bin 0 -> 53043 bytes
 phpmyadmin/themes/original/sprites.lib.php         |   625 +
 phpmyadmin/themes/pmahomme/css/codemirror.css.php  |   162 +
 phpmyadmin/themes/pmahomme/css/common.css.php      |  2756 ++
 phpmyadmin/themes/pmahomme/css/enum_editor.css.php |    80 +
 phpmyadmin/themes/pmahomme/css/gis.css.php         |    65 +
 phpmyadmin/themes/pmahomme/css/jqplot.css.php      |   277 +
 phpmyadmin/themes/pmahomme/css/navigation.css.php  |   242 +
 phpmyadmin/themes/pmahomme/css/pmd.css.php         |   529 +
 .../themes/pmahomme/css/resizable-menu.css.php     |    57 +
 phpmyadmin/themes/pmahomme/css/rte.css.php         |    43 +
 .../themes/pmahomme/img/ajax_clock_small.gif       |   Bin 0 -> 1810 bytes
 phpmyadmin/themes/pmahomme/img/arrow_ltr.png       |   Bin 0 -> 139 bytes
 phpmyadmin/themes/pmahomme/img/arrow_rtl.png       |   Bin 0 -> 136 bytes
 phpmyadmin/themes/pmahomme/img/asc_order.png       |   Bin 0 -> 182 bytes
 phpmyadmin/themes/pmahomme/img/b_bookmark.png      |   Bin 0 -> 677 bytes
 phpmyadmin/themes/pmahomme/img/b_browse.png        |   Bin 0 -> 536 bytes
 phpmyadmin/themes/pmahomme/img/b_calendar.png      |   Bin 0 -> 638 bytes
 phpmyadmin/themes/pmahomme/img/b_chart.png         |   Bin 0 -> 504 bytes
 phpmyadmin/themes/pmahomme/img/b_close.png         |   Bin 0 -> 180 bytes
 phpmyadmin/themes/pmahomme/img/b_column_add.png    |   Bin 0 -> 534 bytes
 phpmyadmin/themes/pmahomme/img/b_comment.png       |   Bin 0 -> 454 bytes
 phpmyadmin/themes/pmahomme/img/b_dbstatistics.png  |   Bin 0 -> 504 bytes
 phpmyadmin/themes/pmahomme/img/b_deltbl.png        |   Bin 0 -> 623 bytes
 phpmyadmin/themes/pmahomme/img/b_docs.png          |   Bin 0 -> 756 bytes
 phpmyadmin/themes/pmahomme/img/b_docsql.png        |   Bin 0 -> 188 bytes
 phpmyadmin/themes/pmahomme/img/b_drop.png          |   Bin 0 -> 687 bytes
 phpmyadmin/themes/pmahomme/img/b_edit.png          |   Bin 0 -> 407 bytes
 phpmyadmin/themes/pmahomme/img/b_empty.png         |   Bin 0 -> 615 bytes
 phpmyadmin/themes/pmahomme/img/b_engine.png        |   Bin 0 -> 431 bytes
 phpmyadmin/themes/pmahomme/img/b_event_add.png     |   Bin 0 -> 863 bytes
 phpmyadmin/themes/pmahomme/img/b_events.png        |   Bin 0 -> 783 bytes
 phpmyadmin/themes/pmahomme/img/b_export.png        |   Bin 0 -> 606 bytes
 phpmyadmin/themes/pmahomme/img/b_firstpage.png     |   Bin 0 -> 754 bytes
 phpmyadmin/themes/pmahomme/img/b_ftext.png         |   Bin 0 -> 576 bytes
 phpmyadmin/themes/pmahomme/img/b_globe.gif         |   Bin 0 -> 1045 bytes
 phpmyadmin/themes/pmahomme/img/b_group.png         |   Bin 0 -> 796 bytes
 phpmyadmin/themes/pmahomme/img/b_help.png          |   Bin 0 -> 740 bytes
 phpmyadmin/themes/pmahomme/img/b_home.png          |   Bin 0 -> 801 bytes
 phpmyadmin/themes/pmahomme/img/b_import.png        |   Bin 0 -> 592 bytes
 phpmyadmin/themes/pmahomme/img/b_index.png         |   Bin 0 -> 708 bytes
 phpmyadmin/themes/pmahomme/img/b_index_add.png     |   Bin 0 -> 839 bytes
 phpmyadmin/themes/pmahomme/img/b_info.png          |   Bin 0 -> 147 bytes
 phpmyadmin/themes/pmahomme/img/b_inline_edit.png   |   Bin 0 -> 621 bytes
 phpmyadmin/themes/pmahomme/img/b_insrow.png        |   Bin 0 -> 183 bytes
 phpmyadmin/themes/pmahomme/img/b_lastpage.png      |   Bin 0 -> 746 bytes
 phpmyadmin/themes/pmahomme/img/b_minus.png         |   Bin 0 -> 224 bytes
 phpmyadmin/themes/pmahomme/img/b_more.png          |   Bin 0 -> 132 bytes
 phpmyadmin/themes/pmahomme/img/b_move.png          |   Bin 0 -> 520 bytes
 phpmyadmin/themes/pmahomme/img/b_newdb.png         |   Bin 0 -> 650 bytes
 phpmyadmin/themes/pmahomme/img/b_newtbl.png        |   Bin 0 -> 264 bytes
 phpmyadmin/themes/pmahomme/img/b_nextpage.png      |   Bin 0 -> 373 bytes
 phpmyadmin/themes/pmahomme/img/b_pdfdoc.png        |   Bin 0 -> 595 bytes
 phpmyadmin/themes/pmahomme/img/b_plus.png          |   Bin 0 -> 237 bytes
 phpmyadmin/themes/pmahomme/img/b_prevpage.png      |   Bin 0 -> 369 bytes
 phpmyadmin/themes/pmahomme/img/b_primary.png       |   Bin 0 -> 619 bytes
 phpmyadmin/themes/pmahomme/img/b_print.png         |   Bin 0 -> 702 bytes
 phpmyadmin/themes/pmahomme/img/b_props.png         |   Bin 0 -> 655 bytes
 phpmyadmin/themes/pmahomme/img/b_relations.png     |   Bin 0 -> 172 bytes
 phpmyadmin/themes/pmahomme/img/b_routine_add.png   |   Bin 0 -> 409 bytes
 phpmyadmin/themes/pmahomme/img/b_routines.png      |   Bin 0 -> 310 bytes
 phpmyadmin/themes/pmahomme/img/b_save.png          |   Bin 0 -> 585 bytes
 phpmyadmin/themes/pmahomme/img/b_sbrowse.png       |   Bin 0 -> 536 bytes
 phpmyadmin/themes/pmahomme/img/b_sdb.png           |   Bin 0 -> 148 bytes
 phpmyadmin/themes/pmahomme/img/b_search.png        |   Bin 0 -> 578 bytes
 phpmyadmin/themes/pmahomme/img/b_selboard.png      |   Bin 0 -> 676 bytes
 phpmyadmin/themes/pmahomme/img/b_select.png        |   Bin 0 -> 645 bytes
 phpmyadmin/themes/pmahomme/img/b_snewtbl.png       |   Bin 0 -> 717 bytes
 phpmyadmin/themes/pmahomme/img/b_spatial.png       |   Bin 0 -> 379 bytes
 phpmyadmin/themes/pmahomme/img/b_sql.png           |   Bin 0 -> 723 bytes
 phpmyadmin/themes/pmahomme/img/b_sqldoc.png        |   Bin 0 -> 194 bytes
 phpmyadmin/themes/pmahomme/img/b_sqlhelp.png       |   Bin 0 -> 590 bytes
 phpmyadmin/themes/pmahomme/img/b_table_add.png     |   Bin 0 -> 676 bytes
 phpmyadmin/themes/pmahomme/img/b_tblanalyse.png    |   Bin 0 -> 188 bytes
 phpmyadmin/themes/pmahomme/img/b_tblexport.png     |   Bin 0 -> 606 bytes
 phpmyadmin/themes/pmahomme/img/b_tblimport.png     |   Bin 0 -> 592 bytes
 phpmyadmin/themes/pmahomme/img/b_tblops.png        |   Bin 0 -> 618 bytes
 phpmyadmin/themes/pmahomme/img/b_tbloptimize.png   |   Bin 0 -> 198 bytes
 phpmyadmin/themes/pmahomme/img/b_tipp.png          |   Bin 0 -> 764 bytes
 phpmyadmin/themes/pmahomme/img/b_trigger_add.png   |   Bin 0 -> 615 bytes
 phpmyadmin/themes/pmahomme/img/b_triggers.png      |   Bin 0 -> 494 bytes
 phpmyadmin/themes/pmahomme/img/b_unique.png        |   Bin 0 -> 615 bytes
 phpmyadmin/themes/pmahomme/img/b_usradd.png        |   Bin 0 -> 750 bytes
 phpmyadmin/themes/pmahomme/img/b_usrcheck.png      |   Bin 0 -> 773 bytes
 phpmyadmin/themes/pmahomme/img/b_usrdrop.png       |   Bin 0 -> 756 bytes
 phpmyadmin/themes/pmahomme/img/b_usredit.png       |   Bin 0 -> 845 bytes
 phpmyadmin/themes/pmahomme/img/b_usrlist.png       |   Bin 0 -> 774 bytes
 phpmyadmin/themes/pmahomme/img/b_view.png          |   Bin 0 -> 646 bytes
 phpmyadmin/themes/pmahomme/img/b_view_add.png      |   Bin 0 -> 766 bytes
 phpmyadmin/themes/pmahomme/img/b_views.png         |   Bin 0 -> 630 bytes
 phpmyadmin/themes/pmahomme/img/bd_browse.png       |   Bin 0 -> 431 bytes
 phpmyadmin/themes/pmahomme/img/bd_deltbl.png       |   Bin 0 -> 510 bytes
 phpmyadmin/themes/pmahomme/img/bd_drop.png         |   Bin 0 -> 560 bytes
 phpmyadmin/themes/pmahomme/img/bd_edit.png         |   Bin 0 -> 271 bytes
 phpmyadmin/themes/pmahomme/img/bd_empty.png        |   Bin 0 -> 511 bytes
 phpmyadmin/themes/pmahomme/img/bd_export.png       |   Bin 0 -> 326 bytes
 phpmyadmin/themes/pmahomme/img/bd_firstpage.png    |   Bin 0 -> 613 bytes
 phpmyadmin/themes/pmahomme/img/bd_ftext.png        |   Bin 0 -> 473 bytes
 phpmyadmin/themes/pmahomme/img/bd_index.png        |   Bin 0 -> 560 bytes
 phpmyadmin/themes/pmahomme/img/bd_insrow.png       |   Bin 0 -> 224 bytes
 phpmyadmin/themes/pmahomme/img/bd_lastpage.png     |   Bin 0 -> 603 bytes
 phpmyadmin/themes/pmahomme/img/bd_nextpage.png     |   Bin 0 -> 302 bytes
 phpmyadmin/themes/pmahomme/img/bd_prevpage.png     |   Bin 0 -> 303 bytes
 phpmyadmin/themes/pmahomme/img/bd_primary.png      |   Bin 0 -> 476 bytes
 phpmyadmin/themes/pmahomme/img/bd_sbrowse.png      |   Bin 0 -> 431 bytes
 phpmyadmin/themes/pmahomme/img/bd_select.png       |   Bin 0 -> 536 bytes
 phpmyadmin/themes/pmahomme/img/bd_spatial.png      |   Bin 0 -> 375 bytes
 phpmyadmin/themes/pmahomme/img/bd_unique.png       |   Bin 0 -> 508 bytes
 phpmyadmin/themes/pmahomme/img/col_drop.png        |   Bin 0 -> 132 bytes
 phpmyadmin/themes/pmahomme/img/col_pointer.png     |   Bin 0 -> 113 bytes
 phpmyadmin/themes/pmahomme/img/col_pointer_ver.png |   Bin 0 -> 117 bytes
 phpmyadmin/themes/pmahomme/img/database.png        |   Bin 0 -> 353 bytes
 phpmyadmin/themes/pmahomme/img/east-mini.png       |   Bin 0 -> 322 bytes
 phpmyadmin/themes/pmahomme/img/error.ico           |   Bin 0 -> 5430 bytes
 phpmyadmin/themes/pmahomme/img/eye.png             |   Bin 0 -> 721 bytes
 phpmyadmin/themes/pmahomme/img/eye_grey.png        |   Bin 0 -> 330 bytes
 phpmyadmin/themes/pmahomme/img/item.png            |   Bin 0 -> 134 bytes
 phpmyadmin/themes/pmahomme/img/left_nav_bg.png     |   Bin 0 -> 297 bytes
 phpmyadmin/themes/pmahomme/img/logo_left.png       |   Bin 0 -> 2327 bytes
 phpmyadmin/themes/pmahomme/img/logo_right.png      |   Bin 0 -> 4548 bytes
 phpmyadmin/themes/pmahomme/img/more.png            |   Bin 0 -> 117 bytes
 phpmyadmin/themes/pmahomme/img/new_data.png        |   Bin 0 -> 264 bytes
 .../themes/pmahomme/img/new_data_hovered.png       |   Bin 0 -> 264 bytes
 .../themes/pmahomme/img/new_data_selected.png      |   Bin 0 -> 179 bytes
 .../pmahomme/img/new_data_selected_hovered.png     |   Bin 0 -> 181 bytes
 phpmyadmin/themes/pmahomme/img/new_struct.png      |   Bin 0 -> 301 bytes
 .../themes/pmahomme/img/new_struct_hovered.png     |   Bin 0 -> 301 bytes
 .../themes/pmahomme/img/new_struct_selected.png    |   Bin 0 -> 189 bytes
 .../pmahomme/img/new_struct_selected_hovered.png   |   Bin 0 -> 196 bytes
 phpmyadmin/themes/pmahomme/img/north-mini.png      |   Bin 0 -> 327 bytes
 phpmyadmin/themes/pmahomme/img/pause.png           |   Bin 0 -> 271 bytes
 phpmyadmin/themes/pmahomme/img/php_sym.png         |   Bin 0 -> 156 bytes
 phpmyadmin/themes/pmahomme/img/play.png            |   Bin 0 -> 373 bytes
 phpmyadmin/themes/pmahomme/img/pma_logo2.png       |   Bin 0 -> 1424 bytes
 phpmyadmin/themes/pmahomme/img/pmd/1.png           |   Bin 0 -> 101 bytes
 phpmyadmin/themes/pmahomme/img/pmd/2.png           |   Bin 0 -> 169 bytes
 phpmyadmin/themes/pmahomme/img/pmd/2leftarrow.png  |   Bin 0 -> 702 bytes
 .../themes/pmahomme/img/pmd/2leftarrow_m.png       |   Bin 0 -> 666 bytes
 phpmyadmin/themes/pmahomme/img/pmd/2rightarrow.png |   Bin 0 -> 737 bytes
 .../themes/pmahomme/img/pmd/2rightarrow_m.png      |   Bin 0 -> 699 bytes
 phpmyadmin/themes/pmahomme/img/pmd/3.png           |   Bin 0 -> 175 bytes
 phpmyadmin/themes/pmahomme/img/pmd/4.png           |   Bin 0 -> 181 bytes
 phpmyadmin/themes/pmahomme/img/pmd/5.png           |   Bin 0 -> 90 bytes
 phpmyadmin/themes/pmahomme/img/pmd/6.png           |   Bin 0 -> 98 bytes
 phpmyadmin/themes/pmahomme/img/pmd/7.png           |   Bin 0 -> 105 bytes
 phpmyadmin/themes/pmahomme/img/pmd/8.png           |   Bin 0 -> 88 bytes
 .../themes/pmahomme/img/pmd/FieldKey_small.png     |   Bin 0 -> 229 bytes
 phpmyadmin/themes/pmahomme/img/pmd/Field_small.png |   Bin 0 -> 275 bytes
 .../themes/pmahomme/img/pmd/Field_small_char.png   |   Bin 0 -> 154 bytes
 .../themes/pmahomme/img/pmd/Field_small_date.png   |   Bin 0 -> 156 bytes
 .../themes/pmahomme/img/pmd/Field_small_int.png    |   Bin 0 -> 145 bytes
 phpmyadmin/themes/pmahomme/img/pmd/Header.png      |   Bin 0 -> 125 bytes
 .../themes/pmahomme/img/pmd/Header_Linked.png      |   Bin 0 -> 108 bytes
 phpmyadmin/themes/pmahomme/img/pmd/and_icon.png    |   Bin 0 -> 792 bytes
 phpmyadmin/themes/pmahomme/img/pmd/ang_direct.png  |   Bin 0 -> 679 bytes
 phpmyadmin/themes/pmahomme/img/pmd/bord.png        |   Bin 0 -> 87 bytes
 phpmyadmin/themes/pmahomme/img/pmd/bottom.png      |   Bin 0 -> 734 bytes
 phpmyadmin/themes/pmahomme/img/pmd/def.png         |   Bin 0 -> 670 bytes
 .../themes/pmahomme/img/pmd/display_field.png      |   Bin 0 -> 685 bytes
 phpmyadmin/themes/pmahomme/img/pmd/downarrow1.png  |   Bin 0 -> 758 bytes
 phpmyadmin/themes/pmahomme/img/pmd/downarrow2.png  |   Bin 0 -> 772 bytes
 .../themes/pmahomme/img/pmd/downarrow2_m.png       |   Bin 0 -> 711 bytes
 phpmyadmin/themes/pmahomme/img/pmd/exec.png        |   Bin 0 -> 796 bytes
 phpmyadmin/themes/pmahomme/img/pmd/exec_small.png  |   Bin 0 -> 161 bytes
 .../themes/pmahomme/img/pmd/exitFullscreen.png     |   Bin 0 -> 444 bytes
 phpmyadmin/themes/pmahomme/img/pmd/favicon.ico     |   Bin 0 -> 1150 bytes
 phpmyadmin/themes/pmahomme/img/pmd/grid.png        |   Bin 0 -> 688 bytes
 phpmyadmin/themes/pmahomme/img/pmd/help.png        |   Bin 0 -> 714 bytes
 .../themes/pmahomme/img/pmd/help_relation.png      |   Bin 0 -> 920 bytes
 .../themes/pmahomme/img/pmd/left_panel_butt.png    |   Bin 0 -> 129 bytes
 .../themes/pmahomme/img/pmd/left_panel_tab.png     |   Bin 0 -> 133 bytes
 phpmyadmin/themes/pmahomme/img/pmd/minus.png       |   Bin 0 -> 1004 bytes
 phpmyadmin/themes/pmahomme/img/pmd/or_icon.png     |   Bin 0 -> 611 bytes
 phpmyadmin/themes/pmahomme/img/pmd/pdf.png         |   Bin 0 -> 905 bytes
 phpmyadmin/themes/pmahomme/img/pmd/plus.png        |   Bin 0 -> 969 bytes
 .../themes/pmahomme/img/pmd/query_builder.png      |   Bin 0 -> 685 bytes
 phpmyadmin/themes/pmahomme/img/pmd/relation.png    |   Bin 0 -> 295 bytes
 phpmyadmin/themes/pmahomme/img/pmd/reload.png      |   Bin 0 -> 874 bytes
 phpmyadmin/themes/pmahomme/img/pmd/resize.png      |   Bin 0 -> 121 bytes
 phpmyadmin/themes/pmahomme/img/pmd/rightarrow1.png |   Bin 0 -> 746 bytes
 phpmyadmin/themes/pmahomme/img/pmd/rightarrow2.png |   Bin 0 -> 757 bytes
 phpmyadmin/themes/pmahomme/img/pmd/save.png        |   Bin 0 -> 409 bytes
 phpmyadmin/themes/pmahomme/img/pmd/small_tab.png   |   Bin 0 -> 180 bytes
 phpmyadmin/themes/pmahomme/img/pmd/table.png       |   Bin 0 -> 163 bytes
 .../themes/pmahomme/img/pmd/toggle_lines.png       |   Bin 0 -> 630 bytes
 phpmyadmin/themes/pmahomme/img/pmd/top_panel.png   |   Bin 0 -> 173 bytes
 phpmyadmin/themes/pmahomme/img/pmd/uparrow2_m.png  |   Bin 0 -> 729 bytes
 .../themes/pmahomme/img/pmd/viewInFullscreen.png   |   Bin 0 -> 472 bytes
 phpmyadmin/themes/pmahomme/img/s_asc.png           |   Bin 0 -> 169 bytes
 phpmyadmin/themes/pmahomme/img/s_asci.png          |   Bin 0 -> 184 bytes
 phpmyadmin/themes/pmahomme/img/s_attention.png     |   Bin 0 -> 629 bytes
 phpmyadmin/themes/pmahomme/img/s_cancel.png        |   Bin 0 -> 575 bytes
 phpmyadmin/themes/pmahomme/img/s_cancel2.png       |   Bin 0 -> 305 bytes
 phpmyadmin/themes/pmahomme/img/s_cog.png           |   Bin 0 -> 475 bytes
 phpmyadmin/themes/pmahomme/img/s_db.png            |   Bin 0 -> 353 bytes
 phpmyadmin/themes/pmahomme/img/s_desc.png          |   Bin 0 -> 182 bytes
 phpmyadmin/themes/pmahomme/img/s_error.png         |   Bin 0 -> 664 bytes
 phpmyadmin/themes/pmahomme/img/s_error2.png        |   Bin 0 -> 152 bytes
 phpmyadmin/themes/pmahomme/img/s_fulltext.png      |   Bin 0 -> 193 bytes
 phpmyadmin/themes/pmahomme/img/s_host.png          |   Bin 0 -> 655 bytes
 phpmyadmin/themes/pmahomme/img/s_info.png          |   Bin 0 -> 740 bytes
 phpmyadmin/themes/pmahomme/img/s_lang.png          |   Bin 0 -> 755 bytes
 phpmyadmin/themes/pmahomme/img/s_loggoff.png       |   Bin 0 -> 651 bytes
 phpmyadmin/themes/pmahomme/img/s_notice.png        |   Bin 0 -> 629 bytes
 phpmyadmin/themes/pmahomme/img/s_okay.png          |   Bin 0 -> 772 bytes
 phpmyadmin/themes/pmahomme/img/s_partialtext.png   |   Bin 0 -> 196 bytes
 phpmyadmin/themes/pmahomme/img/s_passwd.png        |   Bin 0 -> 353 bytes
 phpmyadmin/themes/pmahomme/img/s_process.png       |   Bin 0 -> 475 bytes
 phpmyadmin/themes/pmahomme/img/s_really.png        |   Bin 0 -> 145 bytes
 phpmyadmin/themes/pmahomme/img/s_reload.png        |   Bin 0 -> 582 bytes
 phpmyadmin/themes/pmahomme/img/s_replication.png   |   Bin 0 -> 424 bytes
 phpmyadmin/themes/pmahomme/img/s_rights.png        |   Bin 0 -> 503 bytes
 phpmyadmin/themes/pmahomme/img/s_sortable.png      |   Bin 0 -> 234 bytes
 phpmyadmin/themes/pmahomme/img/s_status.png        |   Bin 0 -> 637 bytes
 phpmyadmin/themes/pmahomme/img/s_success.png       |   Bin 0 -> 552 bytes
 phpmyadmin/themes/pmahomme/img/s_sync.png          |   Bin 0 -> 498 bytes
 phpmyadmin/themes/pmahomme/img/s_tbl.png           |   Bin 0 -> 684 bytes
 phpmyadmin/themes/pmahomme/img/s_theme.png         |   Bin 0 -> 828 bytes
 phpmyadmin/themes/pmahomme/img/s_top.png           |   Bin 0 -> 443 bytes
 phpmyadmin/themes/pmahomme/img/s_vars.png          |   Bin 0 -> 614 bytes
 phpmyadmin/themes/pmahomme/img/s_views.png         |   Bin 0 -> 630 bytes
 phpmyadmin/themes/pmahomme/img/south-mini.png      |   Bin 0 -> 335 bytes
 phpmyadmin/themes/pmahomme/img/spacer.png          |   Bin 0 -> 84 bytes
 phpmyadmin/themes/pmahomme/img/sprites.png         |   Bin 0 -> 61899 bytes
 phpmyadmin/themes/pmahomme/img/toggle-ltr.png      |   Bin 0 -> 414 bytes
 phpmyadmin/themes/pmahomme/img/toggle-rtl.png      |   Bin 0 -> 414 bytes
 phpmyadmin/themes/pmahomme/img/vertical_line.png   |   Bin 0 -> 68 bytes
 phpmyadmin/themes/pmahomme/img/west-mini.png       |   Bin 0 -> 328 bytes
 phpmyadmin/themes/pmahomme/img/window-new.png      |   Bin 0 -> 484 bytes
 phpmyadmin/themes/pmahomme/img/zoom-minus-mini.png |   Bin 0 -> 247 bytes
 phpmyadmin/themes/pmahomme/img/zoom-plus-mini.png  |   Bin 0 -> 329 bytes
 phpmyadmin/themes/pmahomme/img/zoom-world-mini.png |   Bin 0 -> 808 bytes
 phpmyadmin/themes/pmahomme/info.inc.php            |    16 +
 .../jquery/images/ui-bg_flat_0_aaaaaa_40x100.png   |   Bin 0 -> 180 bytes
 .../jquery/images/ui-bg_flat_75_ffffff_40x100.png  |   Bin 0 -> 178 bytes
 .../jquery/images/ui-bg_glass_55_fbf9ee_1x400.png  |   Bin 0 -> 120 bytes
 .../jquery/images/ui-bg_glass_65_ffffff_1x400.png  |   Bin 0 -> 105 bytes
 .../jquery/images/ui-bg_glass_75_dadada_1x400.png  |   Bin 0 -> 159 bytes
 .../jquery/images/ui-bg_glass_75_e6e6e6_1x400.png  |   Bin 0 -> 110 bytes
 .../jquery/images/ui-bg_glass_95_fef1ec_1x400.png  |   Bin 0 -> 119 bytes
 .../ui-bg_highlight-soft_75_cccccc_1x100.png       |   Bin 0 -> 101 bytes
 .../jquery/images/ui-icons_222222_256x240.png      |   Bin 0 -> 4369 bytes
 .../jquery/images/ui-icons_2e83ff_256x240.png      |   Bin 0 -> 4369 bytes
 .../jquery/images/ui-icons_454545_256x240.png      |   Bin 0 -> 4369 bytes
 .../jquery/images/ui-icons_888888_256x240.png      |   Bin 0 -> 4369 bytes
 .../jquery/images/ui-icons_cd0a0a_256x240.png      |   Bin 0 -> 4369 bytes
 .../pmahomme/jquery/jquery-ui-1.9.2.custom.css     |   462 +
 phpmyadmin/themes/pmahomme/layout.inc.php          |   140 +
 phpmyadmin/themes/pmahomme/screen.png              |   Bin 0 -> 63100 bytes
 phpmyadmin/themes/pmahomme/sprites.lib.php         |   720 +
 phpmyadmin/themes/sprites.css.php                  |    82 +
 phpmyadmin/themes/svg_gradient.php                 |    30 +
 phpmyadmin/transformation_overview.php             |    58 +
 phpmyadmin/transformation_wrapper.php              |   149 +
 phpmyadmin/url.php                                 |    22 +
 phpmyadmin/user_password.php                       |   242 +
 phpmyadmin/version_check.php                       |    47 +
 phpmyadmin/view_create.php                         |   235 +
 phpmyadmin/view_operations.php                     |   102 +
 phpmyadmin/webapp.php                              |    55 +
 1114 files changed, 231381 insertions(+)

diff --git a/phpmyadmin/ChangeLog b/phpmyadmin/ChangeLog
new file mode 100644
index 0000000..b1430c4
--- /dev/null
+++ b/phpmyadmin/ChangeLog
@@ -0,0 +1,225 @@
+phpMyAdmin - ChangeLog
+======================
+
+4.0.4.1 ()
+- [security] Global variables scope injection vulnerability (see PMASA-2013-7)
+
+4.0.4.0 (2013-06-17)
+- bug #3959 Using DefaultTabDatabase in NavigationTree for Database Click
+- bug #3961 Avoid Suhosin warning when in simulation mode
+- bug #3897 Row Statistics and Space usage bugs
+- bug #3966 Only display "table has no unique column" message when applicable
+- bug #3960 NavigationBarIconic config not honored
+- bug #3965 Default language wrong with zh-TW
+- bug #3921 Call to undefined function PMA_isSuperuser() if default server is
+not set 
+- bug #3971 Ctrl/shift + click opens links in same window
+- bug #3964 Import using https does not work
+- bug Missing removeCRLF option in ExportCsv and ExportExcel plugins
+- bug #3631 Drop not working Visio schema export.
+- bug #3645 Better handling of invalid ODS documents
+- bug #3976 Number of pages
+- bug #3922 User privileges, database name unescaped
+
+4.0.3.0 (2013-06-05)
+- bug #3941 Recent tables list always empty
+- bug #3933 Do not translate "Open Document" in export settings
+- bug #3927 List of tables is missing after expanding in the navigation frame
+- bug #3942 Warnings about reserved word for many non reserved words
+- bug #3912 Exporting row selection, resulted by ORDER BY query
+- bug #3957 Cookies must be enabled past this point
+- bug #3956 "Browse foreign values" search filter / page selector not working
+- bug #3579 NOW() function incorrectly selected (partial regression)
+- [security] Javascript execution vulnerability in Create view,
+  reported by Maxim Rupp (see PMASA-2013-6)
+
+4.0.2.0 (2013-05-24)
+- bug #3902 Cannot browse when table name contains keyword "call"
++ center loading indicator for navigation refresh, related to bug #3920
+- bug #3925 Table sorting in navigation panel is case-sensitive
+- bug #3915 Import of CSV file (Replace table data with file) with duplicate values
+- bug #3907 undefined variables, function parameter problems
+- bug #3898 Structure not refreshed after column drop 
+- bug #3926 View is not updatable
+- bug #3919 PropertiesIconic not honored
+- bug #3930 Databases to choose for specific privileges show up escaped
+- bug #3910 Export database with empty table as a php array, does not produce valid PHP
+- bug #3936 Query profiler chart not loading from SQL Query page
+- bug #3946 Missing CSV import option "Do not abort on INSERT error"
+- bug #3943 Missing Operations>Table options>AUTO_INCREMENT
+- bug Missing CREATE DATABASE statement when exporting at database level
+- bug #3924 Show warning when CSV file does not contain data for all columns
+- bug #3947 Missing Sql Query after modify structure
+- bug #3948 Server export problems
+- bug #3917 CountTables directive is deprecated
+
+4.0.1.0 (2013-05-14)
+- bug #3879 Import broken for CSV using LOAD DATA
+- bug #3889 When login fails and error display is active, login data is displayed
+- bug #3890 [import] Web server upload directory import fails
+- bug #3891 [import] Server upload folder import file name missing in success message 
++ rfe #1421 [auth] Add retry button on connection failure with config auth
+- bug #3894 [interface] Provide feedback if no columns selected for multi-submit
+- bug #3799 [interface] Incorrect select field change on ctrl key navigation in Firefox
+- bug #3885 [browse] display_binary_as_hex option causes unexpected behavior
+- bug #3899 Git commit links to Github missing
+- bug #3900 CSP WARN in Firefox console
+- bug #3901 Setup script warning for config auth (stored login data) shows link BBcode
+- bug #3895 [browse] Fixed getting BLOB data
+- bug #3905 [export] Custom Exporting exports all databases
+- bug #3909 [import] Import of CSV FIle to selected table doesn't work
+- bug #3904 Browsing an empty table should not display its Structure
+- bug #3908 Calendar widget improperly redirects to home 
+- bug #3918 Greyed out tabs when there are no rows fixed 
+- bug #3916 [interface] Missing scrollbar (original theme)
++ [vendor] add tcpdf path to vendor_config.php
+- bug fix compat with tcpdf >= 6.0 (tested with 6.0.012)
+
+4.0.0.0 (2013-05-03)
++ Patch #3481047 for rfe #3480477 Insert as new row enhancement
++ Patch #3480999 Activate codemirror in the query window
+- Patch #3495284 XML Import - fix message and redirect
++ rfe #3484063 Null checkbox behavior
++ Patch #3497179 Contest-5: Add user: Allow create DB w/same name + grant u_%
++ Patch #3498201 Contest-6: Export all privileges
++ Patch #3502814 for rfe #3187077 Change password buttons should match
++ rfe #3488640 Expand table-group in non-light navigation frame if only one
++ Patch #3509360 Contest-3: Option "Truncate table" before "insert"
++ Patch #3506552 Contest-2: Show index information in the data dictionary
++ Patch #3510656 Contest-1: Ignoring foreign keys while dropping tables
+- Bug #3509686 Reverting sort on joined column does not work
++ New transformation: append string
++ rfe #3507804 Session upload progress (PHP 5.4)
++ rfe #3488185 draggable columns vs copy column name
++ Patch #3507001 Contest-4: Textarea for large character columns
++ Removed the PHP version of the ENUM editor
++ Patch #3507111 Display distinct results, linked to corresponding data rows
+- bug #3507917 [export] JSON has unescaped values for allegedly numeric columns
++ rfe #3516187 show tables creation, last update, last check timestamps in db_structure
+- bug #3059806 Supporting running from CIFS/Samba shares
+- bug #3516341 [export] Open Document Text, Word and Texy! Text show table structure twice
+- bug [export] Texy! Text: Columns containing Pipe Character don't export properly
++ [export] Show triggers in Open Document Text, Word and Texy! Text
+- Patch #3415061 [auth] Login screen appears under the page
++ rfe #3517354 [interface] Allow disabling CodeMirror with $cfg['CodemirrorEnable'] = false
++ rfe #3475567 [interface] New directive $cfg['HideStructureActions']
+- bug #3468272 [import] Fixed import of ODS with more paragraphs in a cell
+- bug #3510196 [core] Improved redirecting with ForceSSL option
++ rfe #3518852 [edit] edit blob but not other binary, new option $cfg['ProtectBinary'] = 'noblob'
++ Hide language select box if there are no locales installed
++ Removed some directives: verbose_check, SuggestDBName, LightTabs,
+VerboseMultiSubmit, ReplaceHelpImg
+- Patch #3500882 Fixing checkbox behaviour while editing identical rows
++ rfe #3441722 [interface] Display description of datatypes
++ rfe #3517835 [structure] Move columns easily
++ Ajaxified "Create View" functionality
++ [import] New plugin: import mediawiki
++ New navigation system
++ Discontinued the use of a frame-based layout
++ rfe #3528994 [interface] Allow wrapping possibly long values in replication-status table
++ [interface] Autoselect username input on cookie login page
+- bug #3563799 [interface] Grid editing destroying huge amount of data
++ [import] Remove support for the unactive docSQL import format
+- bug #3577443 [edit] "Browse foreign values" does not show on ajax edit
++ rfe #3522109 [browse] Grid editing: action to trigger it (or disable)
+- bug #3526598 [interface] SQL query not shown when creating table
++ Dropped configuration directive: AllowThirdPartyFraming
++ Dropped configuration directive: LeftFrameLight
++ Dropped configuration directive: DisplayDatabasesList
++ Dropped configuration directives: ShowTooltipAliasDB and ShowTooltipAliasTB
++ Dropped configuration directive: NaviDatabaseNameColor
++ Added configuration directive: MaxNavigationItems
++ Renamed configuration directive: LeftFrameDBTree => NavigationTreeEnableGrouping
++ Renamed configuration directive: LeftFrameDBSeparator => NavigationTreeDbSeparator
++ Renamed configuration directive: LeftFrameTableSeparator => NavigationTreeTableSeparator
++ Renamed configuration directive: LeftFrameTableLevel => NavigationTreeTableLevel
++ Renamed configuration directive: LeftPointerEnable => NavigationTreePointerEnable
++ Renamed configuration directive: LeftDefaultTabTable => NavigationTreeDefaultTabTable
++ Renamed configuration directive: LeftDisplayTableFilterMinimum => NavigationTreeDisplayTableFilterMinimum
++ Renamed configuration directive: LeftDisplayLogo => NavigationDisplayLogo
++ Renamed configuration directive: LeftLogoLink => NavigationLogoLink
++ Renamed configuration directive: LeftLogoLinkWindow => NavigationLogoLinkWindow
++ Renamed configuration directive: LeftDisplayServers => NavigationDisplayServers
++ Renamed configuration directive: LeftRecentTable => NumRecentTables
++ Renamed configuration directive: LeftDisplayDatabaseFilterMinimum => NavigationTreeDisplayDbFilterMinimum
++ Removed the "Mark row on click" feature; must now click the checkbox to mark
++ Removed the "Synchronize" feature
++ Improved layout of server variables page
++ rfe #1052091 [config] Double-underscores in PMA table names
++ Improved the "More" dropdown on the table structure page
++ [interface] Added "scroll to top" link in menubar
++ [designer] Fullscreen mode for the designer
++ Upgraded jquery to v1.8.3 and jquery-ui to v1.9.2
++ Patch #3597529 [status] Add raw value as title on server status page
++ Support MySQL 5.6 partitioning
++ Removed the AjaxEnable directive
++ rfe #3542567 Accept IPv6 ranges and IPv6 CIDR notations in $cfg['Servers'][$i]['AllowDeny']['rules']
+- Bug #3576788 Grid editing shows the value before silent truncation
+- Upgraded jqPlot to 1.0.4 r1121
+- Upgraded to jquery-ui-timepicker-addon 1.1.1
++ rfe #3599046 [interface] Added comments for indexes
+- Replaced qtip with jQuery UI tooltip
+- Upgraded CodeMirror to 2.37
+- bug #2951 [export] Correctly export decimal fields.
+- bug #3762 [core] Make Advisor work on Windows withou COM extension.
+- bug #3519 [export] Prevent infinite recursion in PDF export.
+- bug #3827 Table specific privileges not displayed for db name containing
+underscore 
+- rfe #1386 Add IF NOT EXISTS clause when copying database
+- No longer package .travis.yml configuration file when creating a release.
+- bug #3830 Can't export custom query because it lowercases table names
+- bug #3829 Enabling query profiling crashes javascript based navigation
++ rfe #879 Reserved word warning
++ Remove the database ordering sub-feature of the only_db directive
+- bug #3840 When exporting to gzip format, the data is compressed 2 times
++ rfe #1319 Permit to create index when creating foreign key
+- bug #3703 Incorrect updating of the list of users
+- bug #3853 Blowfish implementation might be broken (replace with phpseclib)
+- bug #3865 Using like operator on each backslash needs 4 backslash protection
+- bug #3860 Displayed git revision info is not set
+- bug #3871 Check referential integrity broken across databases
+- bug #3874 [export] No preselected option when exporting table
+- bug #3873 Can't copy table to target database if table exists there
+- bug #3683 Incorrect listing of records from to count
+- bug #3876 [import] PHP 5.2 - unexpected T_PAAMAYIM_NEKUDOTAYIM
+- [security] Local file inclusion vulnerability, reported by Janek Vind
+  (see PMASA-2013-4)
+- [security] Global variables overwrite in export.php, reported by Janek Vind
+  (see PMASA-2013-5)
+- bug #3892 [export] SQL Export files are empty
+
+3.5.8.1 (2013-04-24)
+- [security] Remote code execution (preg_replace), reported by Janek Vind
+  (see PMASA-2013-2)
+- [security] Locally Saved SQL Dump File Multiple File Extension Remote Code
+  Execution, reported by Janek Vind (see PMASA-2013-3)
+
+3.5.8.0 (2013-04-08)
+- bug #3828 MariaDB reported as MySQL
+- bug #3854 Incorrect header for Safari 6.0
+- bug #3705 Attempt to open trigger for edit gives NULL
+- Use HTML5 DOCTYPE 
+- [security] Self-XSS on GIS visualisation page, reported by Janek Vind
+- bug #3800 Incorrect keyhandler behaviour #2
+
+3.5.7.0 (2013-02-15)
+- bug #3779 [core] Problem with backslash in enum fields
+- bug #3816 Missing server_processlist.php
+- bug #3821 Safari: white page
+- Correct detection of the Chrome browser
+
+3.5.6.0 (2013-01-28)
+- bug #3593604 [status] Erroneous advisor rule
+- bug #3596070 [status] localStorage broken in server status monitor
+- bug #3598736 [routines] Editing a procedure with special characters
+- bug #3600322 [core] Visualize GIS data throws Fatal Error
+- bug #3599362 [core] Double-escaped error message
+- bug #3776 [cookies] Login without auth on second server
+
+         --- Older ChangeLogs can be found on our project website ---
+                     http://www.phpmyadmin.net/old-stuff/ChangeLogs/
+
+# vim: et ts=4 sw=4 sts=4
+# vim: ft=changelog fenc=utf-8
+# vim: fde=getline(v\:lnum-1)=~'^\\s*$'&&getline(v\:lnum)=~'\\S'?'>1'\:1&&v\:lnum>4&&getline(v\:lnum)!~'^#'
+# vim: fdn=1 fdm=expr
diff --git a/phpmyadmin/LICENSE b/phpmyadmin/LICENSE
new file mode 100644
index 0000000..3912109
--- /dev/null
+++ b/phpmyadmin/LICENSE
@@ -0,0 +1,340 @@
+		    GNU GENERAL PUBLIC LICENSE
+		       Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.
+                       51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+			    Preamble
+
+  The licenses for most software are designed to take away your
+freedom to share and change it.  By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users.  This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it.  (Some other Free Software Foundation software is covered by
+the GNU Library General Public License instead.)  You can apply it to
+your programs, too.
+
+  When we speak of free software, we are referring to freedom, not
+price.  Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+  To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+  For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have.  You must make sure that they, too, receive or can get the
+source code.  And you must show them these terms so they know their
+rights.
+
+  We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+  Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software.  If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+  Finally, any free program is threatened constantly by software
+patents.  We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary.  To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.
+

+		    GNU GENERAL PUBLIC LICENSE
+   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+  0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License.  The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language.  (Hereinafter, translation is included without limitation in
+the term "modification".)  Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope.  The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+  1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+  2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+    a) You must cause the modified files to carry prominent notices
+    stating that you changed the files and the date of any change.
+
+    b) You must cause any work that you distribute or publish, that in
+    whole or in part contains or is derived from the Program or any
+    part thereof, to be licensed as a whole at no charge to all third
+    parties under the terms of this License.
+
+    c) If the modified program normally reads commands interactively
+    when run, you must cause it, when started running for such
+    interactive use in the most ordinary way, to print or display an
+    announcement including an appropriate copyright notice and a
+    notice that there is no warranty (or else, saying that you provide
+    a warranty) and that users may redistribute the program under
+    these conditions, and telling the user how to view a copy of this
+    License.  (Exception: if the Program itself is interactive but
+    does not normally print such an announcement, your work based on
+    the Program is not required to print an announcement.)
+

+These requirements apply to the modified work as a whole.  If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works.  But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+  3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+    a) Accompany it with the complete corresponding machine-readable
+    source code, which must be distributed under the terms of Sections
+    1 and 2 above on a medium customarily used for software interchange; or,
+
+    b) Accompany it with a written offer, valid for at least three
+    years, to give any third party, for a charge no more than your
+    cost of physically performing source distribution, a complete
+    machine-readable copy of the corresponding source code, to be
+    distributed under the terms of Sections 1 and 2 above on a medium
+    customarily used for software interchange; or,
+
+    c) Accompany it with the information you received as to the offer
+    to distribute corresponding source code.  (This alternative is
+    allowed only for noncommercial distribution and only if you
+    received the program in object code or executable form with such
+    an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it.  For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable.  However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+

+  4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License.  Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+  5. You are not required to accept this License, since you have not
+signed it.  However, nothing else grants you permission to modify or
+distribute the Program or its derivative works.  These actions are
+prohibited by law if you do not accept this License.  Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+  6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions.  You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+  7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License.  If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all.  For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices.  Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+

+  8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded.  In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+  9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time.  Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number.  If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation.  If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+  10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission.  For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this.  Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+			    NO WARRANTY
+
+  11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+  12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+		     END OF TERMS AND CONDITIONS
+

+	    How to Apply These Terms to Your New Programs
+
+  If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+  To do so, attach the following notices to the program.  It is safest
+to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+    <one line to give the program's name and a brief idea of what it does.>
+    Copyright (C) <year>  <name of author>
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+    Gnomovision version 69, Copyright (C) year name of author
+    Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+    This is free software, and you are welcome to redistribute it
+    under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License.  Of course, the commands you use may
+be called something other than `show w' and `show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary.  Here is a sample; alter the names:
+
+  Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+  `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+  <signature of Ty Coon>, 1 April 1989
+  Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program into
+proprietary programs.  If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library.  If this is what you want to do, use the GNU Library General
+Public License instead of this License.
diff --git a/phpmyadmin/README b/phpmyadmin/README
new file mode 100644
index 0000000..94543f2
--- /dev/null
+++ b/phpmyadmin/README
@@ -0,0 +1,84 @@
+phpMyAdmin - Readme
+===================
+
+Version 4.0.4
+
+A set of PHP-scripts to manage MySQL over the web.
+
+http://www.phpmyadmin.net/
+
+Copyright
+---------
+
+Copyright (C) 1998-2000
+    Tobias Ratschiller <tobias_at_ratschiller.com>
+
+Copyright (C) 2001-2013
+    Marc Delisle <marc_at_infomarc.info>
+    Olivier Müller <om_at_omnis.ch>
+    Robin Johnson <robbat2_at_users.sourceforge.net>
+    Alexander M. Turek <me_at_derrabus.de>
+    Michal Čihař <michal_at_cihar.com>
+    Garvin Hicking <me_at_supergarv.de>
+    Michael Keck <mkkeck_at_users.sourceforge.net>
+    Sebastian Mendel <cybot_tm_at_users.sourceforge.net>
+    [check documentation for more details]
+
+License
+-------
+
+This program is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License version 2, as published by the
+Free Software Foundation.
+
+This program is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
+details.
+
+You should have received a copy of the GNU General Public License
+along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+Requirements
+------------
+
+* PHP 5.2 or later
+* MySQL 5.0 or later
+* a web-browser (doh!)
+
+Summary
+-------
+
+phpMyAdmin is intended to handle the administration of MySQL over the web.
+For a summary of features, please see the documentation in the doc folder.
+
+Download
+--------
+
+You can get the newest version at http://www.phpmyadmin.net/.
+
+More Information
+----------------
+
+Please see the documentation in the doc folder.
+
+Support
+-------
+
+See reference about support forums under http://www.phpmyadmin.net/
+
+
+Enjoy!
+------
+
+The phpMyAdmin Devel team
+
+
+PS:
+
+Please, don't send us emails with question like "How do I compile PHP with
+MySQL-support". We just don't have the time to be your free help desk.
+
+Please send your questions to the appropriate mailing lists / forums.  Before
+contacting us, please read the documentation (especially the FAQ part).
+
diff --git a/phpmyadmin/RELEASE-DATE-4.0.4 b/phpmyadmin/RELEASE-DATE-4.0.4
new file mode 100644
index 0000000..6eb670b
--- /dev/null
+++ b/phpmyadmin/RELEASE-DATE-4.0.4
@@ -0,0 +1 @@
+Mon Jun 17 16:28:34 UTC 2013
diff --git a/phpmyadmin/browse_foreigners.php b/phpmyadmin/browse_foreigners.php
new file mode 100644
index 0000000..9a9fdf9
--- /dev/null
+++ b/phpmyadmin/browse_foreigners.php
@@ -0,0 +1,340 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * display selection for relational field values
+ *
+ * @package PhpMyAdmin
+ */
+
+require_once 'libraries/common.inc.php';
+require_once 'libraries/transformations.lib.php';
+
+/**
+ * Sets globals from $_REQUEST
+ */
+$request_params = array(
+    'field',
+    'fieldkey',
+    'foreign_filter',
+    'pos',
+    'rownumber'
+);
+
+foreach ($request_params as $one_request_param) {
+    if (isset($_REQUEST[$one_request_param])) {
+        $GLOBALS[$one_request_param] = $_REQUEST[$one_request_param];
+    }
+}
+
+PMA_Util::checkParameters(array('db', 'table', 'field'));
+
+$response = PMA_Response::getInstance();
+$response->getFooter()->setMinimal();
+$header = $response->getHeader();
+$header->disableMenu();
+$header->setBodyId('body_browse_foreigners');
+
+/**
+ * Displays the frame
+ */
+
+$cfgRelation = PMA_getRelationsParam();
+$foreigners  = ($cfgRelation['relwork'] ? PMA_getForeigners($db, $table) : false);
+
+$override_total = true;
+
+if (! isset($pos)) {
+    $pos = 0;
+}
+
+$foreign_limit = 'LIMIT ' . $pos . ', ' . $GLOBALS['cfg']['MaxRows'] . ' ';
+if (isset($foreign_navig) && $foreign_navig == __('Show all')) {
+    unset($foreign_limit);
+}
+
+$foreignData = PMA_getForeignData(
+    $foreigners, $field, $override_total,
+    isset($foreign_filter) ? $foreign_filter : '', $foreign_limit
+);
+
+if (isset($rownumber)) {
+    $rownumber_param = '&rownumber=' . urlencode($rownumber);
+} else {
+    $rownumber_param = '';
+}
+
+$gotopage = '';
+$showall = '';
+
+if (is_array($foreignData['disp_row'])) {
+
+    if ($cfg['ShowAll']
+        && ($foreignData['the_total'] > $GLOBALS['cfg']['MaxRows'])
+    ) {
+        $showall = '<input type="submit" name="foreign_navig" value="'
+                 . __('Show all') . '" />';
+    }
+
+    $session_max_rows = $GLOBALS['cfg']['MaxRows'];
+    $pageNow = @floor($pos / $session_max_rows) + 1;
+    $nbTotalPage = @ceil($foreignData['the_total'] / $session_max_rows);
+
+    if ($foreignData['the_total'] > $GLOBALS['cfg']['MaxRows']) {
+        $gotopage = PMA_Util::pageselector(
+            'pos',
+            $session_max_rows,
+            $pageNow,
+            $nbTotalPage,
+            200,
+            5,
+            5,
+            20,
+            10,
+            __('Page number:')
+        );
+    }
+}
+
+
+
+if (isset($rownumber)) {
+    $element_name  = "        var element_name = field + '[multi_edit]["
+        . htmlspecialchars($rownumber) . "][' + fieldmd5 + ']';\n"
+        . "        var null_name = field_null + '[multi_edit]["
+        . htmlspecialchars($rownumber) . "][' + fieldmd5 + ']';\n";
+} else {
+    $element_name = "var element_name = field + '[]'";
+}
+$error = PMA_jsFormat(
+    __(
+        'The target browser window could not be updated. '
+        . 'Maybe you have closed the parent window, or '
+        . 'your browser\'s security settings are '
+        . 'configured to block cross-window updates.'
+    )
+);
+
+
+if (! isset($fieldkey) || ! is_numeric($fieldkey)) {
+    $fieldkey = 0;
+}
+
+$code = <<<EOC
+self.focus();
+function formupdate(fieldmd5, key) {
+    var \$inline = window.opener.jQuery('.browse_foreign_clicked');
+    if (\$inline.length != 0) {
+        \$inline.removeClass('browse_foreign_clicked')
+            // for grid editing,
+            // puts new value in the previous element which is
+            // a span with class curr_value, and trigger .change()
+            .prev('.curr_value').text(key).change();
+        // for zoom-search editing, puts new value in the previous
+        // element which is an input field
+        \$inline.prev('input[type=text]').val(key);
+        self.close();
+        return false;
+    }
+
+    if (opener && opener.document && opener.document.insertForm) {
+        var field = 'fields';
+        var field_null = 'fields_null';
+
+        $element_name
+
+        var element_name_alt = field + '[$fieldkey]';
+
+        if (opener.document.insertForm.elements[element_name]) {
+            // Edit/Insert form
+            opener.document.insertForm.elements[element_name].value = key;
+            if (opener.document.insertForm.elements[null_name]) {
+                opener.document.insertForm.elements[null_name].checked = false;
+            }
+            self.close();
+            return false;
+        } else if (opener.document.insertForm.elements[element_name_alt]) {
+            // Search form
+            opener.document.insertForm.elements[element_name_alt].value = key;
+            self.close();
+            return false;
+        }
+    }
+
+    alert('$error');
+}
+EOC;
+
+$header->getScripts()->addCode($code);
+
+// HTML output
+$output = '<form action="browse_foreigners.php" method="post">'
+    . '<fieldset>'
+    . PMA_generate_common_hidden_inputs($db, $table)
+    . '<input type="hidden" name="field" value="' . htmlspecialchars($field) . '" />'
+    . '<input type="hidden" name="fieldkey" value="'
+    . (isset($fieldkey) ? htmlspecialchars($fieldkey) : '') . '" />';
+
+if (isset($rownumber)) {
+    $output .= '<input type="hidden" name="rownumber" value="'
+        . htmlspecialchars($rownumber) . '" />';
+}
+$output .= '<span class="formelement">'
+    . '<label for="input_foreign_filter">' . __('Search') . ':' . '</label>'
+    . '<input type="text" name="foreign_filter" id="input_foreign_filter" value="'
+    . (isset($foreign_filter) ? htmlspecialchars($foreign_filter) : '') . '" />'
+    . '<input type="submit" name="submit_foreign_filter" value="'
+    .  __('Go') . '" />'
+    . '</span>'
+    . '<span class="formelement">' . $gotopage . '</span>'
+    . '<span class="formelement">' . $showall . '</span>'
+    . '</fieldset>'
+    . '</form>';
+
+$output .= '<table width="100%">';
+
+if (is_array($foreignData['disp_row'])) {
+    $header = '<tr>
+        <th>' . __('Keyname') . '</th>
+        <th>' . __('Description') . '</th>
+        <td width="20%"></td>
+        <th>' . __('Description') . '</th>
+        <th>' . __('Keyname') . '</th>
+    </tr>';
+
+    $output .= '<thead>' . $header . '</thead>' . "\n"
+        . '<tfoot>' . $header . '</tfoot>' . "\n"
+        . '<tbody>' . "\n";
+
+    $values = array();
+    $keys   = array();
+    foreach ($foreignData['disp_row'] as $relrow) {
+        if ($foreignData['foreign_display'] != false) {
+            $values[] = $relrow[$foreignData['foreign_display']];
+        } else {
+            $values[] = '';
+        }
+
+        $keys[] = $relrow[$foreignData['foreign_field']];
+    }
+
+    asort($keys);
+
+    $hcount = 0;
+    $odd_row = true;
+    $val_ordered_current_row = 0;
+    $val_ordered_current_equals_data = false;
+    $key_ordered_current_equals_data = false;
+    foreach ($keys as $key_ordered_current_row => $value) {
+        $hcount++;
+
+        if ($cfg['RepeatCells'] > 0 && $hcount > $cfg['RepeatCells']) {
+            $output .= $header;
+            $hcount = 0;
+            $odd_row = true;
+        }
+
+        $key_ordered_current_key = $keys[$key_ordered_current_row];
+        $key_ordered_current_val = $values[$key_ordered_current_row];
+
+        $val_ordered_current_key = $keys[$val_ordered_current_row];
+        $val_ordered_current_val = $values[$val_ordered_current_row];
+
+        $val_ordered_current_row++;
+
+        if (PMA_strlen($val_ordered_current_val) <= $cfg['LimitChars']) {
+            $val_ordered_current_val = htmlspecialchars(
+                $val_ordered_current_val
+            );
+            $val_ordered_current_val_title = '';
+        } else {
+            $val_ordered_current_val_title = htmlspecialchars(
+                $val_ordered_current_val
+            );
+            $val_ordered_current_val = htmlspecialchars(
+                PMA_substr($val_ordered_current_val, 0, $cfg['LimitChars'])
+                . '...'
+            );
+        }
+        if (PMA_strlen($key_ordered_current_val) <= $cfg['LimitChars']) {
+            $key_ordered_current_val = htmlspecialchars(
+                $key_ordered_current_val
+            );
+            $key_ordered_current_val_title = '';
+        } else {
+            $key_ordered_current_val_title = htmlspecialchars(
+                $key_ordered_current_val
+            );
+            $key_ordered_current_val = htmlspecialchars(
+                PMA_substr(
+                    $key_ordered_current_val, 0, $cfg['LimitChars']
+                ) . '...'
+            );
+        }
+
+        if (! empty($data)) {
+            $val_ordered_current_equals_data = $val_ordered_current_key == $data;
+            $key_ordered_current_equals_data = $key_ordered_current_key == $data;
+        }
+
+        $output .= '<tr class="noclick ' . ($odd_row ? 'odd' : 'even') . '">';
+        $odd_row = ! $odd_row;
+
+        $output .= '<td class="nowrap">'
+            . ($key_ordered_current_equals_data ? '<strong>' : '')
+            . '<a href="#" title="' . __('Use this value')
+            . ($key_ordered_current_val_title != ''
+                ? ': ' . $key_ordered_current_val_title
+                : '') . '"'
+            . ' onclick="formupdate(\'' . md5($field) . '\', \''
+            . PMA_jsFormat($key_ordered_current_key, false) . '\'); return false;">'
+            . htmlspecialchars($key_ordered_current_key)
+            . '</a>' . ($key_ordered_current_equals_data ? '</strong>' : '')
+            . '</td>';
+
+        $output .= '<td>'
+            . ($key_ordered_current_equals_data ? '<strong>' : '')
+            . '<a href="#" title="' . __('Use this value')
+            . ($key_ordered_current_val_title != '' ? ': '
+            . $key_ordered_current_val_title : '') . '" onclick="formupdate(\''
+            . md5($field) . '\', \''
+            . PMA_jsFormat($key_ordered_current_key, false)
+            . '\'); return false;">'
+            . $key_ordered_current_val . '</a>'
+            . ($key_ordered_current_equals_data ? '</strong>' : '')
+            . '</td>';
+
+        $output .= '<td width="20%">'
+            . '<img src="' . $GLOBALS['pmaThemeImage'] . 'spacer.png" alt=""'
+            . ' width="1" height="1" /></td>';
+
+        $output .= '<td>'
+            . ($val_ordered_current_equals_data ? '<strong>' : '')
+            . '<a href="#" title="' . __('Use this value')
+            .  ($val_ordered_current_val_title != '' ? ': '
+            . $val_ordered_current_val_title : '') . '" onclick="formupdate(\''
+            . md5($field) . '\', \''
+            . PMA_jsFormat($val_ordered_current_key, false)
+            . '\'); return false;">'
+            . $val_ordered_current_val . '</a>'
+            . ($val_ordered_current_equals_data ? '</strong>' : '')
+            . '</td>';
+
+        $output .= '<td class="nowrap">'
+            . ($val_ordered_current_equals_data ? '<strong>' : '')
+            . '<a href="#" title="' . __('Use this value')
+            . ($val_ordered_current_val_title != ''
+                ? ': ' . $val_ordered_current_val_title : '')
+            . '" onclick="formupdate(\'' . md5($field) . '\', \''
+            . PMA_jsFormat($val_ordered_current_key, false) . '\'); return false;">'
+            . htmlspecialchars($val_ordered_current_key)
+            . '</a>' . ($val_ordered_current_equals_data ? '</strong>' : '')
+            . '</td>';
+        $output .= '</tr>';
+    } // end while
+}
+
+$output .= '</tbody>'
+    . '</table>';
+
+$response->addHtml($output);
+?>
diff --git a/phpmyadmin/changelog.php b/phpmyadmin/changelog.php
new file mode 100644
index 0000000..c216c7f
--- /dev/null
+++ b/phpmyadmin/changelog.php
@@ -0,0 +1,152 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * Simple script to set correct charset for changelog
+ *
+ * @package PhpMyAdmin
+ */
+
+/**
+ * Gets core libraries and defines some variables
+ */
+require 'libraries/common.inc.php';
+
+$response = PMA_Response::getInstance();
+$response->disable();
+
+$filename = CHANGELOG_FILE;
+
+/**
+ * Read changelog.
+ */
+// Check if the file is available, some distributions remove these.
+if (is_readable($filename)) {
+
+    // Test if the if is in a compressed format
+    if (substr($filename, -3) == '.gz') {
+        ob_start();
+        readgzfile($filename);
+        $changelog = ob_get_contents();
+        ob_end_clean();
+    } else {
+        $changelog = file_get_contents($filename);
+    }
+} else {
+    printf(
+        __('The %s file is not available on this system, please visit www.phpmyadmin.net for more information.'),
+        $filename
+    );
+    exit;
+}
+
+/**
+ * Whole changelog in variable.
+ */
+$changelog = htmlspecialchars($changelog);
+
+$tracker_url = 'https://sourceforge.net/support/tracker.php?aid=\\1';
+$tracker_url_bug = 'https://sourceforge.net/p/phpmyadmin/bugs/\\1/';
+$tracker_url_rfe = 'https://sourceforge.net/p/phpmyadmin/feature-requests/\\1/';
+$tracker_url_patch = 'https://sourceforge.net/p/phpmyadmin/patches/\\1/';
+$github_url = 'https://github.com/phpmyadmin/phpmyadmin/';
+
+$replaces = array(
+    '@(http://[./a-zA-Z0-9.-_-]*[/a-zA-Z0-9_])@'
+    => '<a href="\\1">\\1</a>',
+
+    // sourceforge users
+    '/([0-9]{4}-[0-9]{2}-[0-9]{2}) (.+[^ ]) +<(.*)@users.sourceforge.net>/i'
+    => '\\1 <a href="https://sourceforge.net/users/\\3/">\\2</a>',
+    '/thanks to ([^\(\r\n]+) \(([-\w]+)\)/i'
+    => 'thanks to <a href="https://sourceforge.net/users/\\2/">\\1</a>',
+    '/thanks to ([^\(\r\n]+) -\s+([-\w]+)/i'
+    => 'thanks to <a href="https://sourceforge.net/users/\\2/">\\1</a>',
+
+    // mail address
+    '/([0-9]{4}-[0-9]{2}-[0-9]{2}) (.+[^ ]) +<(.*@.*)>/i'
+    => '\\1 <a href="mailto:\\3">\\2</a>',
+
+    // linking patches
+    '/patch\s*#?([0-9]{6,})/i'
+    => '<a href="' . $tracker_url . '">patch #\\1</a>',
+
+    // linking RFE
+    '/(?:rfe|feature)\s*#?([0-9]{6,})/i'
+    => '<a href="https://sourceforge.net/support/tracker.php?aid=\\1">RFE #\\1</a>',
+
+    // linking files
+    '/(\s+)([\\/a-z_0-9\.]+\.(?:php3?|html|pl|js|sh))/i'
+    => '\\1<a href="' . $github_url . 'commits/HEAD/\\2">\\2</a>',
+
+    // FAQ entries
+    '/FAQ ([0-9]+)\.([0-9a-z]+)/i'
+    => '<a href="http://docs.phpmyadmin.net/en/latest/faq.html#faq\\1-\\2">FAQ \\1.\\2</a>',
+
+    // linking bugs
+    '/bug\s*#?([0-9]{6,})/i'
+    => '<a href="https://sourceforge.net/support/tracker.php?aid=\\1">bug #\\1</a>',
+
+    // all other 6+ digit numbers are treated as bugs
+    '/(?<!bug|RFE|patch) #?([0-9]{6,})/i'
+    => '<a href="' . $tracker_url . '">bug #\\1</a>',
+
+    // transitioned SF.net project bug/rfe/patch links
+    // by the time we reach 6-digit numbers, we can probably retire the above links
+    '/patch\s*#?([0-9]{4,5}) /i'
+    => '<a href="' . $tracker_url_patch . '">patch #\\1</a> ',
+    '/(?:rfe|feature)\s*#?([0-9]{4,5}) /i'
+    => '<a href="' . $tracker_url_rfe . '">RFE #\\1</a> ',
+    '/bug\s*#?([0-9]{4,5}) /i'
+    => '<a href="' . $tracker_url_bug . '">bug #\\1</a> ',
+    '/(?<!bug|RFE|patch) #?([0-9]{4,5}) /i'
+    => '<a href="' . $tracker_url_bug . '">bug #\\1</a> ',
+
+    // CVE/CAN entries
+    '/((CAN|CVE)-[0-9]+-[0-9]+)/'
+    => '<a href="http://cve.mitre.org/cgi-bin/cvename.cgi?name=\\1">\\1</a>',
+
+    // PMASAentries
+    '/(PMASA-[0-9]+-[0-9]+)/'
+    => '<a href="http://www.phpmyadmin.net/home_page/security/\\1.php">\\1</a>',
+
+    // Highlight releases (with links)
+    '/([0-9]+)\.([0-9]+)\.([0-9]+)\.0 (\([0-9-]+\))/'
+    => '<a name="\\1_\\2_\\3"></a>'
+        . '<a href="' . $github_url . 'commits/RELEASE_\\1_\\2_\\3">'
+        . '\\1.\\2.\\3.0 \\4</a>',
+    '/([0-9]+)\.([0-9]+)\.([0-9]+)\.([1-9][0-9]*) (\([0-9-]+\))/'
+    => '<a name="\\1_\\2_\\3_\\4"></a>'
+        . '<a href="' . $github_url . 'commits/RELEASE_\\1_\\2_\\3_\\4">'
+        . '\\1.\\2.\\3.\\4 \\5</a>',
+
+    // Highlight releases (not linkable)
+    '/(    ### )(.*)/'
+    => '\\1<b>\\2</b>',
+
+);
+
+header('Content-type: text/html; charset=utf-8');
+?>
+<!DOCTYPE HTML>
+<html lang="en" dir="ltr">
+<head>
+    <link rel="icon" href="favicon.ico" type="image/x-icon" />
+    <link rel="shortcut icon" href="favicon.ico" type="image/x-icon" />
+    <title>phpMyAdmin - ChangeLog</title>
+    <meta charset="utf-8" />
+</head>
+<body>
+<h1>phpMyAdmin - ChangeLog</h1>
+<?php
+echo '<pre>';
+echo preg_replace(array_keys($replaces), $replaces, $changelog);
+echo '</pre>';
+?>
+<script type="text/javascript">
+var links = document.getElementsByTagName("a");
+for(var i = 0; i < links.length; i++) {
+    links[i].target = "_blank";
+}
+</script>
+</body>
+</html>
diff --git a/phpmyadmin/chk_rel.php b/phpmyadmin/chk_rel.php
new file mode 100644
index 0000000..915e8b2
--- /dev/null
+++ b/phpmyadmin/chk_rel.php
@@ -0,0 +1,15 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * Displays status of phpMyAdmin configuration storage
+ *
+ * @package PhpMyAdmin
+ */
+
+require_once 'libraries/common.inc.php';
+$response = PMA_Response::getInstance();
+$response->addHTML(
+    PMA_getRelationsParamDiagnostic(PMA_getRelationsParam())
+);
+
+?>
diff --git a/phpmyadmin/composer.json b/phpmyadmin/composer.json
new file mode 100644
index 0000000..ba03706
--- /dev/null
+++ b/phpmyadmin/composer.json
@@ -0,0 +1,24 @@
+{
+    "name": "phpmyadmin/phpmyadmin",
+    "type": "application",
+    "description": "MySQL web administration tool",
+    "keywords": ["phpmyadmin","mysql","web"],
+    "homepage": "http://www.phpmyadmin.net/",
+    "license": "GPL-2.0+",
+    "authors": [
+        {
+            "name": "The phpMyAdmin Team",
+            "email": "phpmyadmin-devel at lists.sourceforge.net",
+            "homepage": "http://www.phpmyadmin.net/home_page/team.php"
+        }
+    ],
+    "support": {
+        "forum": "https://sourceforge.net/p/phpmyadmin/discussion/Help",
+        "issues": "https://sourceforge.net/p/phpmyadmin/bugs/",
+        "wiki": "http://wiki.phpmyadmin.net/",
+        "source": "https://github.com/phpmyadmin/phpmyadmin"
+    },
+    "require": {
+        "php": ">=5.2.0"
+    }
+}
diff --git a/phpmyadmin/config.inc.php b/phpmyadmin/config.inc.php
new file mode 100644
index 0000000..e46a86b
--- /dev/null
+++ b/phpmyadmin/config.inc.php
@@ -0,0 +1,37 @@
+<?php
+/*
+ * Customized for OpenEMR.
+ *
+ */
+
+// Access control is dealt with by the ACL check
+$ignoreAuth = true;
+require_once("../interface/globals.php");
+require_once("../library/acl.inc");
+if ($GLOBALS['disable_phpmyadmin_link']) {
+  echo "You do not have access to this resource<br>";
+  exit;
+}
+if (! acl_check('admin', 'database')) {
+  echo "You do not have access to this resource<br>";
+  exit;
+}
+
+/* Servers configuration */
+$i = 0;
+
+/* Server localhost (config:openemr) [1] */
+$i++;
+
+/* For standard OpenEMR database access */
+$cfg['Servers'][$i]['auth_type'] = 'config';
+$cfg['Servers'][$i]['host'] = $sqlconf['host'];
+$cfg['Servers'][$i]['port'] = $sqlconf['port'];
+$cfg['Servers'][$i]['user'] = $sqlconf['login'];
+$cfg['Servers'][$i]['password'] = $sqlconf['pass'];
+$cfg['Servers'][$i]['only_db'] = $sqlconf['dbase'];
+
+/* Other mods for OpenEMR */
+$cfg['ShowCreateDb'] = false;
+$cfg['ShowPhpInfo'] = TRUE;
+?>
diff --git a/phpmyadmin/config.sample.inc.php b/phpmyadmin/config.sample.inc.php
new file mode 100644
index 0000000..10db2b5
--- /dev/null
+++ b/phpmyadmin/config.sample.inc.php
@@ -0,0 +1,141 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * phpMyAdmin sample configuration, you can use it as base for
+ * manual configuration. For easier setup you can use setup/
+ *
+ * All directives are explained in documentation in the doc/ folder
+ * or at <http://docs.phpmyadmin.net/>.
+ *
+ * @package PhpMyAdmin
+ */
+
+/*
+ * This is needed for cookie based authentication to encrypt password in
+ * cookie
+ */
+$cfg['blowfish_secret'] = 'a8b7c6d'; /* YOU MUST FILL IN THIS FOR COOKIE AUTH! */
+
+/*
+ * Servers configuration
+ */
+$i = 0;
+
+/*
+ * First server
+ */
+$i++;
+/* Authentication type */
+$cfg['Servers'][$i]['auth_type'] = 'cookie';
+/* Server parameters */
+$cfg['Servers'][$i]['host'] = 'localhost';
+$cfg['Servers'][$i]['connect_type'] = 'tcp';
+$cfg['Servers'][$i]['compress'] = false;
+/* Select mysql if your server does not have mysqli */
+$cfg['Servers'][$i]['extension'] = 'mysqli';
+$cfg['Servers'][$i]['AllowNoPassword'] = false;
+
+/*
+ * phpMyAdmin configuration storage settings.
+ */
+
+/* User used to manipulate with storage */
+// $cfg['Servers'][$i]['controlhost'] = '';
+// $cfg['Servers'][$i]['controluser'] = 'pma';
+// $cfg['Servers'][$i]['controlpass'] = 'pmapass';
+
+/* Storage database and tables */
+// $cfg['Servers'][$i]['pmadb'] = 'phpmyadmin';
+// $cfg['Servers'][$i]['bookmarktable'] = 'pma__bookmark';
+// $cfg['Servers'][$i]['relation'] = 'pma__relation';
+// $cfg['Servers'][$i]['table_info'] = 'pma__table_info';
+// $cfg['Servers'][$i]['table_coords'] = 'pma__table_coords';
+// $cfg['Servers'][$i]['pdf_pages'] = 'pma__pdf_pages';
+// $cfg['Servers'][$i]['column_info'] = 'pma__column_info';
+// $cfg['Servers'][$i]['history'] = 'pma__history';
+// $cfg['Servers'][$i]['table_uiprefs'] = 'pma__table_uiprefs';
+// $cfg['Servers'][$i]['tracking'] = 'pma__tracking';
+// $cfg['Servers'][$i]['designer_coords'] = 'pma__designer_coords';
+// $cfg['Servers'][$i]['userconfig'] = 'pma__userconfig';
+// $cfg['Servers'][$i]['recent'] = 'pma__recent';
+/* Contrib / Swekey authentication */
+// $cfg['Servers'][$i]['auth_swekey_config'] = '/etc/swekey-pma.conf';
+
+/*
+ * End of servers configuration
+ */
+
+/*
+ * Directories for saving/loading files from server
+ */
+$cfg['UploadDir'] = '';
+$cfg['SaveDir'] = '';
+
+/**
+ * Defines whether a user should be displayed a "show all (records)"
+ * button in browse mode or not.
+ * default = false
+ */
+//$cfg['ShowAll'] = true;
+
+/**
+ * Number of rows displayed when browsing a result set. If the result
+ * set contains more rows, "Previous" and "Next".
+ * default = 30
+ */
+//$cfg['MaxRows'] = 50;
+
+/**
+ * disallow editing of binary fields
+ * valid values are:
+ *   false    allow editing
+ *   'blob'   allow editing except for BLOB fields
+ *   'noblob' disallow editing except for BLOB fields
+ *   'all'    disallow editing
+ * default = blob
+ */
+//$cfg['ProtectBinary'] = 'false';
+
+/**
+ * Default language to use, if not browser-defined or user-defined
+ * (you find all languages in the locale folder)
+ * uncomment the desired line:
+ * default = 'en'
+ */
+//$cfg['DefaultLang'] = 'en';
+//$cfg['DefaultLang'] = 'de';
+
+/**
+ * default display direction (horizontal|vertical|horizontalflipped)
+ */
+//$cfg['DefaultDisplay'] = 'vertical';
+
+
+/**
+ * How many columns should be used for table display of a database?
+ * (a value larger than 1 results in some information being hidden)
+ * default = 1
+ */
+//$cfg['PropertiesNumColumns'] = 2;
+
+/**
+ * Set to true if you want DB-based query history.If false, this utilizes
+ * JS-routines to display query history (lost by window close)
+ *
+ * This requires configuration storage enabled, see above.
+ * default = false
+ */
+//$cfg['QueryHistoryDB'] = true;
+
+/**
+ * When using DB-based query history, how many entries should be kept?
+ *
+ * default = 25
+ */
+//$cfg['QueryHistoryMax'] = 100;
+
+/*
+ * You can find more configuration options in the documentation
+ * in the doc/ folder or at <http://docs.phpmyadmin.net/>.
+ */
+?>
diff --git a/phpmyadmin/db_create.php b/phpmyadmin/db_create.php
new file mode 100644
index 0000000..48ce084
--- /dev/null
+++ b/phpmyadmin/db_create.php
@@ -0,0 +1,148 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ *
+ * @package PhpMyAdmin
+ */
+
+/**
+ * Gets some core libraries
+ */
+require_once 'libraries/common.inc.php';
+
+require_once 'libraries/mysql_charsets.lib.php';
+if (! PMA_DRIZZLE) {
+    include_once 'libraries/replication.inc.php';
+}
+require 'libraries/build_html_for_db.lib.php';
+
+/**
+ * Sets globals from $_POST
+ */
+$post_params = array(
+    'db_collation',
+    'new_db'
+);
+foreach ($post_params as $one_post_param) {
+    if (isset($_POST[$one_post_param])) {
+        $GLOBALS[$one_post_param] = $_POST[$one_post_param];
+    }
+}
+
+PMA_Util::checkParameters(array('new_db'));
+
+/**
+ * Defines the url to return to in case of error in a sql statement
+ */
+$err_url = 'index.php?' . PMA_generate_common_url();
+
+/**
+ * Builds and executes the db creation sql query
+ */
+$sql_query = 'CREATE DATABASE ' . PMA_Util::backquote($new_db);
+if (! empty($db_collation)) {
+    list($db_charset) = explode('_', $db_collation);
+    if (in_array($db_charset, $mysql_charsets)
+        && in_array($db_collation, $mysql_collations[$db_charset])
+    ) {
+        $sql_query .= ' DEFAULT' . PMA_generateCharsetQueryPart($db_collation);
+    }
+    $db_collation_for_ajax = $db_collation;
+    unset($db_charset, $db_collation);
+}
+$sql_query .= ';';
+
+$result = PMA_DBI_try_query($sql_query);
+
+if (! $result) {
+    $message = PMA_Message::rawError(PMA_DBI_getError());
+    // avoid displaying the not-created db name in header or navi panel
+    $GLOBALS['db'] = '';
+    $GLOBALS['table'] = '';
+
+    /**
+     * If in an Ajax request, just display the message with {@link PMA_Response}
+     */
+    if ($GLOBALS['is_ajax_request'] == true) {
+        $response = PMA_Response::getInstance();
+        $response->isSuccess(false);
+        $response->addJSON('message', $message);
+    } else {
+        include_once 'index.php';
+    }
+} else {
+    $message = PMA_Message::success(__('Database %1$s has been created.'));
+    $message->addParam($new_db);
+    $GLOBALS['db'] = $new_db;
+
+    /**
+     * If in an Ajax request, build the output and send it
+     */
+    if ($GLOBALS['is_ajax_request'] == true) {
+        //Construct the html for the new database, so that it can be appended to
+        // the list of databases on server_databases.php
+
+        /**
+         * Build the array to be passed to {@link PMA_generate_common_url}
+         * to generate the links
+         *
+         * @global array $GLOBALS['db_url_params']
+         * @name $db_url_params
+         */
+        $db_url_params['db'] = $new_db;
+
+        $is_superuser = PMA_isSuperuser();
+        $column_order = PMA_getColumnOrder();
+        $url_query = PMA_generate_common_url($new_db);
+
+        /**
+         * String that will contain the output HTML
+         * @name    $new_db_string
+         */
+        $new_db_string = '<tr>';
+
+        if (empty($db_collation_for_ajax)) {
+            $db_collation_for_ajax = PMA_getServerCollation();
+        }
+
+        // $dbstats comes from the create table dialog
+        if (! empty($dbstats)) {
+            $current = array(
+                'SCHEMA_NAME' => $new_db,
+                'DEFAULT_COLLATION_NAME' => $db_collation_for_ajax,
+                'SCHEMA_TABLES' => '0',
+                'SCHEMA_TABLE_ROWS' => '0',
+                'SCHEMA_DATA_LENGTH' => '0',
+                'SCHEMA_MAX_DATA_LENGTH' => '0',
+                'SCHEMA_INDEX_LENGTH' => '0',
+                'SCHEMA_LENGTH' => '0',
+                'SCHEMA_DATA_FREE' => '0'
+            );
+        } else {
+            $current = array(
+                'SCHEMA_NAME' => $new_db
+            );
+        }
+
+        list($column_order, $generated_html) = PMA_buildHtmlForDb(
+            $current, $is_superuser, $url_query,
+            $column_order, $replication_types, $replication_info
+        );
+        $new_db_string .= $generated_html;
+
+        $new_db_string .= '</tr>';
+
+        $response = PMA_Response::getInstance();
+        $response->addJSON('message', $message);
+        $response->addJSON('new_db_string', $new_db_string);
+        $response->addJSON(
+            'sql_query',
+            PMA_Util::getMessage(
+                null, $sql_query, 'success'
+            )
+        );
+    } else {
+        include_once '' . $cfg['DefaultTabDatabase'];
+    }
+}
+?>
diff --git a/phpmyadmin/db_datadict.php b/phpmyadmin/db_datadict.php
new file mode 100644
index 0000000..8744aa4
--- /dev/null
+++ b/phpmyadmin/db_datadict.php
@@ -0,0 +1,291 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ *
+ * @package PhpMyAdmin
+ */
+
+/**
+ * Gets the variables sent or posted to this script, then displays headers
+ */
+require_once 'libraries/common.inc.php';
+
+if (! isset($selected_tbl)) {
+    include 'libraries/db_common.inc.php';
+    include 'libraries/db_info.inc.php';
+}
+
+$response = PMA_Response::getInstance();
+$header   = $response->getHeader();
+$header->enablePrintView();
+
+/**
+ * Gets the relations settings
+ */
+$cfgRelation  = PMA_getRelationsParam();
+
+require_once 'libraries/transformations.lib.php';
+require_once 'libraries/Index.class.php';
+
+/**
+ * Check parameters
+ */
+PMA_Util::checkParameters(array('db'));
+
+/**
+ * Defines the url to return to in case of error in a sql statement
+ */
+if (strlen($table)) {
+    $err_url = 'tbl_sql.php?' . PMA_generate_common_url($db, $table);
+} else {
+    $err_url = 'db_sql.php?' . PMA_generate_common_url($db);
+}
+
+if ($cfgRelation['commwork']) {
+    $comment = PMA_getDbComment($db);
+
+    /**
+     * Displays DB comment
+     */
+    if ($comment) {
+        echo '<p>' . __('Database comment: ')
+            . '<i>' . htmlspecialchars($comment) . '</i></p>';
+    } // end if
+}
+
+/**
+ * Selects the database and gets tables names
+ */
+PMA_DBI_select_db($db);
+$tables = PMA_DBI_get_tables($db);
+
+$count  = 0;
+foreach ($tables as $table) {
+    $comments = PMA_getComments($db, $table);
+
+    echo '<div>' . "\n";
+
+    echo '<h2>' . htmlspecialchars($table) . '</h2>' . "\n";
+
+    /**
+     * Gets table informations
+     */
+    $show_comment = PMA_Table::sGetStatusInfo($db, $table, 'TABLE_COMMENT');
+
+    /**
+     * Gets table keys and retains them
+     */
+
+    PMA_DBI_select_db($db);
+    $indexes      = PMA_DBI_get_table_indexes($db, $table);
+    $primary      = '';
+    $indexes      = array();
+    $lastIndex    = '';
+    $indexes_info = array();
+    $indexes_data = array();
+    $pk_array     = array(); // will be use to emphasis prim. keys in the table
+                             // view
+    foreach ($indexes as $row) {
+        // Backups the list of primary keys
+        if ($row['Key_name'] == 'PRIMARY') {
+            $primary   .= $row['Column_name'] . ', ';
+            $pk_array[$row['Column_name']] = 1;
+        }
+        // Retains keys informations
+        if ($row['Key_name'] != $lastIndex) {
+            $indexes[] = $row['Key_name'];
+            $lastIndex = $row['Key_name'];
+        }
+        $indexes_info[$row['Key_name']]['Sequences'][]     = $row['Seq_in_index'];
+        $indexes_info[$row['Key_name']]['Non_unique']      = $row['Non_unique'];
+        if (isset($row['Cardinality'])) {
+            $indexes_info[$row['Key_name']]['Cardinality'] = $row['Cardinality'];
+        }
+        // I don't know what does following column mean....
+        // $indexes_info[$row['Key_name']]['Packed']          = $row['Packed'];
+
+        $indexes_info[$row['Key_name']]['Comment']     = $row['Comment'];
+
+        $indexes_data[$row['Key_name']][$row['Seq_in_index']]['Column_name']  = $row['Column_name'];
+        if (isset($row['Sub_part'])) {
+            $indexes_data[$row['Key_name']][$row['Seq_in_index']]['Sub_part'] = $row['Sub_part'];
+        }
+
+    } // end while
+
+    /**
+     * Gets columns properties
+     */
+    $columns = PMA_DBI_get_columns($db, $table);
+    $fields_cnt  = count($columns);
+
+    if (PMA_MYSQL_INT_VERSION < 50025) {
+        // We need this to correctly learn if a TIMESTAMP is NOT NULL, since
+        // SHOW FULL COLUMNS or INFORMATION_SCHEMA incorrectly says NULL
+        // and SHOW CREATE TABLE says NOT NULL
+        // http://bugs.mysql.com/20910.
+
+        $show_create_table_query = 'SHOW CREATE TABLE '
+            . PMA_Util::backquote($db) . '.'
+            . PMA_Util::backquote($table);
+        $show_create_table = PMA_DBI_fetch_value(
+            $show_create_table_query, 0, 1
+        );
+        $analyzed_sql = PMA_SQP_analyze(PMA_SQP_parse($show_create_table));
+    }
+
+    // Check if we can use Relations
+    if (!empty($cfgRelation['relation'])) {
+        // Find which tables are related with the current one and write it in
+        // an array
+        $res_rel = PMA_getForeigners($db, $table);
+
+        if (count($res_rel) > 0) {
+            $have_rel = true;
+        } else {
+            $have_rel = false;
+        }
+    } else {
+        $have_rel = false;
+    } // end if
+
+
+    /**
+     * Displays the comments of the table if MySQL >= 3.23
+     */
+    if (!empty($show_comment)) {
+        echo __('Table comments') . ': ' . htmlspecialchars($show_comment) . '<br /><br />';
+    }
+
+    /**
+     * Displays the table structure
+     */
+    ?>
+
+<table width="100%" class="print">
+<tr><th width="50"><?php echo __('Column'); ?></th>
+    <th width="80"><?php echo __('Type'); ?></th>
+<?php /*    <th width="50"><?php echo __('Attributes'); ?></th>*/ ?>
+    <th width="40"><?php echo __('Null'); ?></th>
+    <th width="70"><?php echo __('Default'); ?></th>
+<?php /*    <th width="50"><?php echo __('Extra'); ?></th>*/ ?>
+    <?php
+    if ($have_rel) {
+        echo '    <th>' . __('Links to') . '</th>' . "\n";
+    }
+    echo '    <th>' . __('Comments') . '</th>' . "\n";
+    if ($cfgRelation['mimework']) {
+        echo '    <th>MIME</th>' . "\n";
+    }
+    ?>
+</tr>
+    <?php
+    $odd_row = true;
+    foreach ($columns as $row) {
+
+        if ($row['Null'] == '') {
+            $row['Null'] = 'NO';
+        }
+        $extracted_columnspec
+            = PMA_Util::extractColumnSpec($row['Type']);
+
+        // reformat mysql query output
+        // set or enum types: slashes single quotes inside options
+        if ('set' == $extracted_columnspec['type'] || 'enum' == $extracted_columnspec['type']) {
+            $type_nowrap  = '';
+
+        } else {
+            $type_nowrap  = ' class="nowrap"';
+        }
+        $type = htmlspecialchars($extracted_columnspec['print_type']);
+        $attribute     = $extracted_columnspec['attribute'];
+        if (! isset($row['Default'])) {
+            if ($row['Null'] != 'NO') {
+                $row['Default'] = '<i>NULL</i>';
+            }
+        } else {
+            $row['Default'] = htmlspecialchars($row['Default']);
+        }
+        $field_name = $row['Field'];
+
+        if (PMA_MYSQL_INT_VERSION < 50025
+            && ! empty($analyzed_sql[0]['create_table_fields'][$field_name]['type'])
+            && $analyzed_sql[0]['create_table_fields'][$field_name]['type'] == 'TIMESTAMP'
+            && $analyzed_sql[0]['create_table_fields'][$field_name]['timestamp_not_null']
+        ) {
+            // here, we have a TIMESTAMP that SHOW FULL COLUMNS reports as having the
+            // NULL attribute, but SHOW CREATE TABLE says the contrary. Believe
+            // the latter.
+            /**
+             * @todo merge this logic with the one in tbl_structure.php
+             * or move it in a function similar to PMA_DBI_get_columns_full()
+             * but based on SHOW CREATE TABLE because information_schema
+             * cannot be trusted in this case (MySQL bug)
+             */
+             $row['Null'] = 'NO';
+        }
+        ?>
+<tr class="<?php echo $odd_row ? 'odd' : 'even'; $odd_row = ! $odd_row; ?>">
+    <td class="nowrap">
+        <?php
+        if (isset($pk_array[$row['Field']])) {
+            echo '<u>' . htmlspecialchars($field_name) . '</u>';
+        } else {
+            echo htmlspecialchars($field_name);
+        }
+        ?>
+    </td>
+    <td<?php echo $type_nowrap; ?> lang="en" dir="ltr"><?php echo $type; ?></td>
+<?php /*    <td<?php echo $type_nowrap; ?>><?php echo $attribute; ?></td>*/ ?>
+    <td><?php echo (($row['Null'] == 'NO') ? __('No') : __('Yes')); ?></td>
+    <td class="nowrap"><?php
+    if (isset($row['Default'])) {
+        echo $row['Default'];
+    }
+    ?></td>
+<?php /*    <td<?php echo $type_nowrap; ?>><?php echo $row['Extra']; ?></td>*/ ?>
+        <?php
+        if ($have_rel) {
+            echo '    <td>';
+            if (isset($res_rel[$field_name])) {
+                echo htmlspecialchars($res_rel[$field_name]['foreign_table'] . ' -> ' . $res_rel[$field_name]['foreign_field']);
+            }
+            echo '</td>' . "\n";
+        }
+        echo '    <td>';
+        if (isset($comments[$field_name])) {
+            echo htmlspecialchars($comments[$field_name]);
+        }
+        echo '</td>' . "\n";
+        if ($cfgRelation['mimework']) {
+            $mime_map = PMA_getMIME($db, $table, true);
+
+            echo '    <td>';
+            if (isset($mime_map[$field_name])) {
+                echo htmlspecialchars(str_replace('_', '/', $mime_map[$field_name]['mimetype']));
+            }
+            echo '</td>' . "\n";
+        }
+        ?>
+</tr>
+        <?php
+    } // end foreach
+    $count++;
+    ?>
+</table>
+<?php
+// display indexes information
+    if (count(PMA_Index::getFromTable($table, $db)) > 0) {
+        echo PMA_Index::getView($table, $db, true);
+    }
+?>
+</div>
+    <?php
+} //ends main while
+
+/**
+ * Displays the footer
+ */
+echo PMA_Util::getButton();
+
+?>
diff --git a/phpmyadmin/db_events.php b/phpmyadmin/db_events.php
new file mode 100644
index 0000000..917778b
--- /dev/null
+++ b/phpmyadmin/db_events.php
@@ -0,0 +1,26 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * Events management.
+ *
+ * @package PhpMyAdmin
+ */
+
+/**
+ * Include required files
+ */
+require_once 'libraries/common.inc.php';
+require_once 'libraries/Util.class.php';
+
+/**
+ * Include all other files
+ */
+require_once 'libraries/rte/rte_events.lib.php';
+
+/**
+ * Do the magic
+ */
+$_PMA_RTE = 'EVN';
+require_once 'libraries/rte/rte_main.inc.php';
+
+?>
diff --git a/phpmyadmin/db_export.php b/phpmyadmin/db_export.php
new file mode 100644
index 0000000..2b2fde4
--- /dev/null
+++ b/phpmyadmin/db_export.php
@@ -0,0 +1,90 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * dumps a database
+ *
+ * @package PhpMyAdmin
+ */
+
+/**
+ * Gets some core libraries
+ */
+require_once 'libraries/common.inc.php';
+
+$response = PMA_Response::getInstance();
+$header   = $response->getHeader();
+$scripts  = $header->getScripts();
+$scripts->addFile('export.js');
+
+// $sub_part is also used in db_info.inc.php to see if we are coming from
+// db_export.php, in which case we don't obey $cfg['MaxTableList']
+$sub_part  = '_export';
+require_once 'libraries/db_common.inc.php';
+$url_query .= '&goto=db_export.php';
+require_once 'libraries/db_info.inc.php';
+
+/**
+ * Displays the form
+ */
+$export_page_title = __('View dump (schema) of database');
+
+// exit if no tables in db found
+if ($num_tables < 1) {
+    PMA_Message::error(__('No tables found in database.'))->display();
+    exit;
+} // end if
+
+$multi_values  = '<div>';
+$multi_values .= '<a href="#"';
+$multi_values .= ' onclick="setSelectOptions(\'dump\', \'table_select[]\', true); return false;">';
+$multi_values .= __('Select All');
+$multi_values .= '</a>';
+$multi_values .= ' / ';
+$multi_values .= '<a href="#"';
+$multi_values .= ' onclick="setSelectOptions(\'dump\', \'table_select[]\', false); return false;">';
+$multi_values .= __('Unselect All');
+$multi_values .= '</a><br />';
+
+$multi_values .= '<select name="table_select[]" id="table_select" size="10" multiple="multiple">';
+$multi_values .= "\n";
+
+if (!empty($selected_tbl) && empty($table_select)) {
+    $table_select = $selected_tbl;
+}
+
+// Check if the selected tables are defined in $_GET
+// (from clicking Back button on export.php)
+if (isset($_GET['table_select'])) {
+    $_GET['table_select'] = urldecode($_GET['table_select']);
+    $_GET['table_select'] = explode(",", $_GET['table_select']);
+}
+
+foreach ($tables as $each_table) {
+    if (isset($_GET['table_select'])) {
+        if (in_array($each_table['Name'], $_GET['table_select'])) {
+            $is_selected = ' selected="selected"';
+        } else {
+            $is_selected = '';
+        }
+    } elseif (isset($table_select)) {
+        if (in_array($each_table['Name'], $table_select)) {
+            $is_selected = ' selected="selected"';
+        } else {
+            $is_selected = '';
+        }
+    } else {
+        $is_selected = ' selected="selected"';
+    }
+    $table_html   = htmlspecialchars($each_table['Name']);
+    $multi_values .= '                <option value="' . $table_html . '"'
+        . $is_selected . '>'
+        . str_replace(' ', ' ', $table_html) . '</option>' . "\n";
+} // end for
+
+$multi_values .= "\n";
+$multi_values .= '</select></div>';
+
+$export_type = 'database';
+require_once 'libraries/display_export.lib.php';
+
+?>
diff --git a/phpmyadmin/db_import.php b/phpmyadmin/db_import.php
new file mode 100644
index 0000000..f8ea809
--- /dev/null
+++ b/phpmyadmin/db_import.php
@@ -0,0 +1,28 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ *
+ * @package PhpMyAdmin
+ */
+
+/**
+ *
+ */
+require_once 'libraries/common.inc.php';
+
+$response = PMA_Response::getInstance();
+$header   = $response->getHeader();
+$scripts  = $header->getScripts();
+$scripts->addFile('import.js');
+
+/**
+ * Gets tables informations and displays top links
+ */
+require 'libraries/db_common.inc.php';
+require 'libraries/db_info.inc.php';
+
+$import_type = 'database';
+require 'libraries/display_import.lib.php';
+
+?>
+
diff --git a/phpmyadmin/db_operations.php b/phpmyadmin/db_operations.php
new file mode 100644
index 0000000..338d385
--- /dev/null
+++ b/phpmyadmin/db_operations.php
@@ -0,0 +1,293 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * handles miscellaneous db operations:
+ *  - move/rename
+ *  - copy
+ *  - changing collation
+ *  - changing comment
+ *  - adding tables
+ *  - viewing PDF schemas
+ *
+ * @package PhpMyAdmin
+ */
+
+/**
+ * requirements
+ */
+require_once 'libraries/common.inc.php';
+require_once 'libraries/mysql_charsets.lib.php';
+
+/**
+ * functions implementation for this script
+ */
+require_once 'libraries/operations.lib.php';
+
+// add a javascript file for jQuery functions to handle Ajax actions
+$response = PMA_Response::getInstance();
+$header = $response->getHeader();
+$scripts = $header->getScripts();
+$scripts->addFile('db_operations.js');
+
+/**
+ * Rename/move or copy database
+ */
+if (strlen($db)
+    && (! empty($_REQUEST['db_rename']) || ! empty($_REQUEST['db_copy']))
+) {
+    if (! empty($_REQUEST['db_rename'])) {
+        $move = true;
+    } else {
+        $move = false;
+    }
+
+    if (! isset($_REQUEST['newname']) || ! strlen($_REQUEST['newname'])) {
+        $message = PMA_Message::error(__('The database name is empty!'));
+    } else {
+        $sql_query = ''; // in case target db exists
+        $_error = false;
+        if ($move
+            || (isset($_REQUEST['create_database_before_copying'])
+            && $_REQUEST['create_database_before_copying'])
+        ) {
+            $sql_query = PMA_getSqlQueryAndCreateDbBeforeCopy();
+        }
+
+        // here I don't use DELIMITER because it's not part of the
+        // language; I have to send each statement one by one
+
+        // to avoid selecting alternatively the current and new db
+        // we would need to modify the CREATE definitions to qualify
+        // the db name
+        PMA_runProcedureAndFunctionDefinitions($db);
+
+        // go back to current db, just in case
+        PMA_DBI_select_db($db);
+
+        $tables_full = PMA_DBI_get_tables_full($db);
+
+        include_once "libraries/plugin_interface.lib.php";
+        // remove all foreign key constraints, otherwise we can get errors
+        $export_sql_plugin = PMA_getPlugin(
+            "export",
+            "sql",
+            'libraries/plugins/export/',
+            array(
+                'single_table' => isset($single_table),
+                'export_type'  => 'database'
+            )
+        );
+        $GLOBALS['sql_constraints_query_full_db']
+            = PMA_getSqlConstraintsQueryForFullDb(
+                $tables_full, $export_sql_plugin, $move, $db
+            );
+
+        $views = PMA_getViewsAndCreateSqlViewStandIn(
+            $tables_full, $export_sql_plugin, $db
+        );
+
+        list($sql_query, $_error) = PMA_getSqlQueryForCopyTable(
+            $tables_full, $sql_query, $move, $db
+        );
+
+        // handle the views
+        if (! $_error) {
+            $_error = PMA_handleTheViews($views, $move, $db);
+        }
+        unset($views);
+
+        // now that all tables exist, create all the accumulated constraints
+        if (! $_error && count($GLOBALS['sql_constraints_query_full_db']) > 0) {
+            PMA_createAllAccumulatedConstraints();
+        }
+
+        if (! PMA_DRIZZLE && PMA_MYSQL_INT_VERSION >= 50100) {
+            // here DELIMITER is not used because it's not part of the
+            // language; each statement is sent one by one
+
+            PMA_runEventDefinitionsForDb($db);
+        }
+
+        // go back to current db, just in case
+        PMA_DBI_select_db($db);
+
+        // Duplicate the bookmarks for this db (done once for each db)
+        PMA_duplicateBookmarks($_error, $db);
+
+        if (! $_error && $move) {
+            /**
+             * cleanup pmadb stuff for this db
+             */
+            include_once 'libraries/relation_cleanup.lib.php';
+            PMA_relationsCleanupDatabase($db);
+
+            // if someday the RENAME DATABASE reappears, do not DROP
+            $local_query = 'DROP DATABASE ' . PMA_Util::backquote($db) . ';';
+            $sql_query .= "\n" . $local_query;
+            PMA_DBI_query($local_query);
+
+            $message = PMA_Message::success(__('Database %1$s has been renamed to %2$s'));
+            $message->addParam($db);
+            $message->addParam($_REQUEST['newname']);
+        } elseif (! $_error) {
+            $message = PMA_Message::success(__('Database %1$s has been copied to %2$s'));
+            $message->addParam($db);
+            $message->addParam($_REQUEST['newname']);
+        }
+        $reload     = true;
+
+        /* Change database to be used */
+        if (! $_error && $move) {
+            $db = $_REQUEST['newname'];
+        } elseif (! $_error) {
+            if (isset($_REQUEST['switch_to_new'])
+                && $_REQUEST['switch_to_new'] == 'true'
+            ) {
+                $GLOBALS['PMA_Config']->setCookie('pma_switch_to_new', 'true');
+                $db = $_REQUEST['newname'];
+            } else {
+                $GLOBALS['PMA_Config']->setCookie('pma_switch_to_new', '');
+            }
+        }
+
+        if ($_error && ! isset($message)) {
+            $message = PMA_Message::error();
+        }
+    }
+
+    /**
+     * Database has been successfully renamed/moved.  If in an Ajax request,
+     * generate the output with {@link PMA_Response} and exit
+     */
+    if ($GLOBALS['is_ajax_request'] == true) {
+        $response = PMA_Response::getInstance();
+        $response->isSuccess($message->isSuccess());
+        $response->addJSON('message', $message);
+        $response->addJSON('newname', $_REQUEST['newname']);
+        $response->addJSON(
+            'sql_query',
+            PMA_Util::getMessage(null, $sql_query)
+        );
+        exit;
+    }
+}
+
+/**
+ * Settings for relations stuff
+ */
+
+$cfgRelation = PMA_getRelationsParam();
+
+/**
+ * Check if comments were updated
+ * (must be done before displaying the menu tabs)
+ */
+if (isset($_REQUEST['comment'])) {
+    PMA_setDbComment($db, $_REQUEST['comment']);
+}
+
+/**
+ * Prepares the tables list if the user where not redirected to this script
+ * because there is no table in the database ($is_info is true)
+ */
+if (empty($is_info)) {
+    include 'libraries/db_common.inc.php';
+    $url_query .= '&goto=db_operations.php';
+
+    // Gets the database structure
+    $sub_part = '_structure';
+    include 'libraries/db_info.inc.php';
+    echo "\n";
+
+    if (isset($message)) {
+        echo PMA_Util::getMessage($message, $sql_query);
+        unset($message);
+    }
+}
+
+$_REQUEST['db_collation'] = PMA_getDbCollation($db);
+$is_information_schema = PMA_is_system_schema($db);
+
+if (!$is_information_schema) {
+    if ($cfgRelation['commwork']) {
+        /**
+         * database comment
+         */
+        $response->addHTML(PMA_getHtmlForDatabaseComment($db));
+    }
+
+    $response->addHTML('<div class="operations_half_width">');
+    ob_start();
+    include 'libraries/display_create_table.lib.php';
+    $content = ob_get_contents();
+    ob_end_clean();
+    $response->addHTML($content);
+    $response->addHTML('</div>');
+
+    /**
+     * rename database
+     */
+    if ($db != 'mysql') {
+        $response->addHTML(PMA_getHtmlForRenameDatabase($db));
+    }
+
+    // Drop link if allowed
+    // Don't even try to drop information_schema.
+    // You won't be able to. Believe me. You won't.
+    // Don't allow to easily drop mysql database, RFE #1327514.
+    if (($is_superuser || $GLOBALS['cfg']['AllowUserDropDatabase'])
+        && ! $db_is_information_schema
+        && (PMA_DRIZZLE || $db != 'mysql')
+    ) {
+        $response->addHTML(PMA_getHtmlForDropDatabaseLink($db));
+    }
+    /**
+     * Copy database
+     */
+    $response->addHTML(PMA_getHtmlForCopyDatabase($db));
+
+    /**
+     * Change database charset
+     */
+    $response->addHTML(PMA_getHtmlForChangeDatabaseCharset($db, $table));
+
+    if ($num_tables > 0
+        && ! $cfgRelation['allworks']
+        && $cfg['PmaNoRelation_DisableWarning'] == false
+    ) {
+        $message = PMA_Message::notice(
+            __('The phpMyAdmin configuration storage has been deactivated. To find out why click %shere%s.')
+        );
+        $message->addParam(
+            '<a href="' . $cfg['PmaAbsoluteUri'] . 'chk_rel.php?' . $url_query . '">',
+            false
+        );
+        $message->addParam('</a>', false);
+        /* Show error if user has configured something, notice elsewhere */
+        if (!empty($cfg['Servers'][$server]['pmadb'])) {
+            $message->isError(true);
+        }
+        $response->addHTML('<div class="operations_full_width">');
+        $response->addHTML($message->getDisplay());
+        $response->addHTML('</div>');
+    } // end if
+} // end if (!$is_information_schema)
+
+
+// not sure about displaying the PDF dialog in case db is information_schema
+if ($cfgRelation['pdfwork'] && $num_tables > 0) {
+    // We only show this if we find something in the new pdf_pages table
+    $test_query = '
+         SELECT *
+           FROM ' . PMA_Util::backquote($GLOBALS['cfgRelation']['db'])
+            . '.' . PMA_Util::backquote($cfgRelation['pdf_pages']) . '
+          WHERE db_name = \'' . PMA_Util::sqlAddSlashes($db) . '\'';
+    $test_rs    = PMA_queryAsControlUser($test_query, null, PMA_DBI_QUERY_STORE);
+
+    /*
+     * Export Relational Schema View
+     */
+    $response->addHTML(PMA_getHtmlForExportRelationalSchemaView($url_query));
+} // end if
+
+?>
diff --git a/phpmyadmin/db_printview.php b/phpmyadmin/db_printview.php
new file mode 100644
index 0000000..e0c2f14
--- /dev/null
+++ b/phpmyadmin/db_printview.php
@@ -0,0 +1,252 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ *
+ * @package PhpMyAdmin
+ */
+
+/**
+ *
+ */
+require_once 'libraries/common.inc.php';
+
+$response = PMA_Response::getInstance();
+$header   = $response->getHeader();
+$header->enablePrintView();
+
+PMA_Util::checkParameters(array('db'));
+
+/**
+ * Defines the url to return to in case of error in a sql statement
+ */
+$err_url = 'db_sql.php?' . PMA_generate_common_url($db);
+
+/**
+ * Settings for relations stuff
+ */
+$cfgRelation = PMA_getRelationsParam();
+
+/**
+ * Gets the list of the table in the current db and informations about these
+ * tables if possible
+ *
+ * @todo merge this speedup _optionaly_ into PMA_DBI_get_tables_full()
+ *
+// speedup view on locked tables
+// Special speedup for newer MySQL Versions (in 4.0 format changed)
+if ($cfg['SkipLockedTables'] == true) {
+    $result = PMA_DBI_query('SHOW OPEN TABLES FROM ' . PMA_Util::backquote($db) . ';');
+    // Blending out tables in use
+    if ($result != false && PMA_DBI_num_rows($result) > 0) {
+        while ($tmp = PMA_DBI_fetch_row($result)) {
+            // if in use memorize tablename
+            if (preg_match('@in_use=[1-9]+ at i', $tmp[0])) {
+                $sot_cache[$tmp[0]] = true;
+            }
+        }
+        PMA_DBI_free_result($result);
+
+        if (isset($sot_cache)) {
+            $result      = PMA_DBI_query('SHOW TABLES FROM ' . PMA_Util::backquote($db) . ';', null, PMA_DBI_QUERY_STORE);
+            if ($result != false && PMA_DBI_num_rows($result) > 0) {
+                while ($tmp = PMA_DBI_fetch_row($result)) {
+                    if (! isset($sot_cache[$tmp[0]])) {
+                        $sts_result  = PMA_DBI_query('SHOW TABLE STATUS FROM ' . PMA_Util::backquote($db) . ' LIKE \'' . sqlAddSlashes($tmp[0], true) . '\';');
+                        $sts_tmp     = PMA_DBI_fetch_assoc($sts_result);
+                        $tables[]    = $sts_tmp;
+                    } else { // table in use
+                        $tables[]    = array('Name' => $tmp[0]);
+                    }
+                }
+                PMA_DBI_free_result($result);
+                $sot_ready = true;
+            }
+        }
+        unset($tmp, $result);
+    }
+}
+
+if (! isset($sot_ready)) {
+    $result      = PMA_DBI_query('SHOW TABLE STATUS FROM ' . PMA_Util::backquote($db) . ';');
+    if (PMA_DBI_num_rows($result) > 0) {
+        while ($sts_tmp = PMA_DBI_fetch_assoc($result)) {
+            $tables[] = $sts_tmp;
+        }
+        PMA_DBI_free_result($result);
+        unset($res);
+    }
+}
+ */
+
+/**
+ * If there is at least one table, displays the printer friendly view, else
+ * an error message
+ */
+$tables = PMA_DBI_get_tables_full($db);
+$num_tables = count($tables);
+
+echo '<br />';
+
+// 1. No table
+if ($num_tables == 0) {
+    echo __('No tables found in database.');
+} else {
+// 2. Shows table information
+    ?>
+<table>
+<thead>
+<tr>
+    <th><?php echo __('Table'); ?></th>
+    <th><?php echo __('Rows'); ?></th>
+    <th><?php echo __('Type'); ?></th>
+    <?php
+    if ($cfg['ShowStats']) {
+        echo '<th>' . __('Size') . '</th>';
+    }
+    ?>
+    <th><?php echo __('Comments'); ?></th>
+</tr>
+</thead>
+<tbody>
+    <?php
+    $sum_entries = $sum_size = 0;
+    $odd_row = true;
+    foreach ($tables as $sts_data) {
+        if (PMA_Table::isMerge($db, $sts_data['TABLE_NAME'])
+            || strtoupper($sts_data['ENGINE']) == 'FEDERATED'
+        ) {
+            $merged_size = true;
+        } else {
+            $merged_size = false;
+        }
+        $sum_entries += $sts_data['TABLE_ROWS'];
+        ?>
+<tr class="<?php echo $odd_row ? 'odd' : 'even'; ?>">
+    <th>
+        <?php echo htmlspecialchars($sts_data['TABLE_NAME']); ?>
+    </th>
+        <?php
+
+        if (isset($sts_data['TABLE_ROWS'])) {
+            ?>
+    <td class="right">
+            <?php
+            if ($merged_size) {
+                echo '<i>' . PMA_Util::formatNumber($sts_data['TABLE_ROWS'], 0) . '</i>' . "\n";
+            } else {
+                echo PMA_Util::formatNumber($sts_data['TABLE_ROWS'], 0) . "\n";
+            }
+            ?>
+    </td>
+    <td class="nowrap">
+        <?php echo $sts_data['ENGINE']; ?>
+    </td>
+            <?php
+            if ($cfg['ShowStats']) {
+                $tblsize =  $sts_data['Data_length'] + $sts_data['Index_length'];
+                $sum_size += $tblsize;
+                list($formated_size, $unit)
+                    =  PMA_Util::formatByteDown($tblsize, 3, 1);
+                ?>
+    <td class="right nowrap">
+        <?php echo $formated_size . ' ' . $unit; ?>
+    </td>
+                <?php
+            } // end if
+        } else {
+            ?>
+    <td colspan="3" class="center">
+        <?php echo __('in use'); ?>
+    </td>
+            <?php
+        }
+        ?>
+    <td>
+        <?php
+        if (! empty($sts_data['Comment'])) {
+            echo htmlspecialchars($sts_data['Comment']);
+            $needs_break = '<br />';
+        } else {
+            $needs_break = '';
+        }
+
+        if (! empty($sts_data['Create_time'])
+            || ! empty($sts_data['Update_time'])
+            || ! empty($sts_data['Check_time'])
+        ) {
+            echo $needs_break;
+            ?>
+            <table width="100%">
+            <?php
+
+            if (! empty($sts_data['Create_time'])) {
+                ?>
+                <tr>
+                    <td class="right"><?php echo __('Creation') . ': '; ?></td>
+                    <td class="right"><?php echo PMA_Util::localisedDate(strtotime($sts_data['Create_time'])); ?></td>
+                </tr>
+                <?php
+            }
+
+            if (! empty($sts_data['Update_time'])) {
+                ?>
+                <tr>
+                    <td class="right"><?php echo __('Last update') . ': '; ?></td>
+                    <td class="right"><?php echo PMA_Util::localisedDate(strtotime($sts_data['Update_time'])); ?></td>
+                </tr>
+                <?php
+            }
+
+            if (! empty($sts_data['Check_time'])) {
+                ?>
+                <tr>
+                    <td class="right"><?php echo __('Last check') . ': '; ?></td>
+                    <td class="right"><?php echo PMA_Util::localisedDate(strtotime($sts_data['Check_time'])); ?></td>
+                </tr>
+                <?php
+            }
+            ?>
+            </table>
+            <?php
+        }
+        ?>
+    </td>
+</tr>
+        <?php
+    }
+    ?>
+<tr>
+    <th class="center">
+        <?php echo sprintf(_ngettext('%s table', '%s tables', $num_tables), PMA_Util::formatNumber($num_tables, 0)); ?>
+    </th>
+    <th class="right nowrap">
+        <?php echo PMA_Util::formatNumber($sum_entries, 0); ?>
+    </th>
+    <th class="center">
+        --
+    </th>
+    <?php
+    if ($cfg['ShowStats']) {
+        list($sum_formated, $unit)
+            = PMA_Util::formatByteDown($sum_size, 3, 1);
+        ?>
+    <th class="right nowrap">
+        <?php echo $sum_formated . ' ' . $unit; ?>
+    </th>
+        <?php
+    }
+    ?>
+    <th></th>
+</tr>
+</tbody>
+</table>
+    <?php
+}
+
+/**
+ * Displays the footer
+ */
+echo PMA_Util::getButton();
+
+echo "<div id='PMA_disable_floating_menubar'></div>\n";
+?>
diff --git a/phpmyadmin/db_qbe.php b/phpmyadmin/db_qbe.php
new file mode 100644
index 0000000..940758c
--- /dev/null
+++ b/phpmyadmin/db_qbe.php
@@ -0,0 +1,68 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * query by example the whole database
+ *
+ * @package PhpMyAdmin
+ */
+
+/**
+ * requirements
+ */
+require_once 'libraries/common.inc.php';
+require_once 'libraries/DBQbe.class.php';
+$response = PMA_Response::getInstance();
+
+// Gets the relation settings
+$cfgRelation = PMA_getRelationsParam();
+
+/**
+ * A query has been submitted -> (maybe) execute it
+ */
+$message_to_display = false;
+if (isset($_REQUEST['submit_sql']) && ! empty($sql_query)) {
+    if (! preg_match('@^SELECT at i', $sql_query)) {
+        $message_to_display = true;
+    } else {
+        $goto      = 'db_sql.php';
+        include 'sql.php';
+        exit;
+    }
+}
+
+$sub_part  = '_qbe';
+require 'libraries/db_common.inc.php';
+$url_query .= '&goto=db_qbe.php';
+$url_params['goto'] = 'db_qbe.php';
+require 'libraries/db_info.inc.php';
+
+if ($message_to_display) {
+    PMA_Message::error(__('You have to choose at least one column to display'))->display();
+}
+unset($message_to_display);
+
+// create new qbe search instance
+$db_qbe = new PMA_DBQbe($GLOBALS['db']);
+
+/**
+ * Displays the Query by example form
+ */
+if ($cfgRelation['designerwork']) {
+    $url = 'pmd_general.php' . PMA_generate_common_url(
+        array_merge(
+            $url_params,
+            array('query' => 1)
+        )
+    );
+    $response->addHTML(
+        PMA_Message::notice(
+            sprintf(
+                __('Switch to %svisual builder%s'),
+                '<a href="' . $url . '">',
+                '</a>'
+            )
+        )
+    );
+}
+$response->addHTML($db_qbe->getSelectionForm($cfgRelation));
+?>
diff --git a/phpmyadmin/db_routines.php b/phpmyadmin/db_routines.php
new file mode 100644
index 0000000..690da85
--- /dev/null
+++ b/phpmyadmin/db_routines.php
@@ -0,0 +1,27 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * Routines management.
+ *
+ * @package PhpMyAdmin
+ */
+
+/**
+ * Include required files
+ */
+require_once 'libraries/common.inc.php';
+require_once 'libraries/Util.class.php';
+require_once 'libraries/mysql_charsets.lib.php';
+
+/**
+ * Include all other files
+ */
+require_once 'libraries/rte/rte_routines.lib.php';
+
+/**
+ * Do the magic
+ */
+$_PMA_RTE = 'RTN';
+require_once 'libraries/rte/rte_main.inc.php';
+
+?>
diff --git a/phpmyadmin/db_search.php b/phpmyadmin/db_search.php
new file mode 100644
index 0000000..acfec8e
--- /dev/null
+++ b/phpmyadmin/db_search.php
@@ -0,0 +1,57 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * searchs the entire database
+ *
+ * @todo    make use of UNION when searching multiple tables
+ * @todo    display executed query, optional?
+ * @package PhpMyAdmin
+ */
+
+/**
+ * Gets some core libraries
+ */
+require_once 'libraries/common.inc.php';
+require_once 'libraries/DbSearch.class.php';
+
+$response = PMA_Response::getInstance();
+$header   = $response->getHeader();
+$scripts  = $header->getScripts();
+$scripts->addFile('db_search.js');
+$scripts->addFile('sql.js');
+$scripts->addFile('makegrid.js');
+$scripts->addFile('jquery/jquery-ui-timepicker-addon.js');
+
+require 'libraries/db_common.inc.php';
+
+// If config variable $GLOBALS['cfg']['Usedbsearch'] is on false : exit.
+if (! $GLOBALS['cfg']['UseDbSearch']) {
+    PMA_Util::mysqlDie(
+        __('Access denied'), '', false, $err_url
+    );
+} // end if
+$url_query .= '&goto=db_search.php';
+$url_params['goto'] = 'db_search.php';
+
+// Create a database search instance
+$db_search = new PMA_DbSearch($GLOBALS['db']);
+
+// Display top links if we are not in an Ajax request
+if ( $GLOBALS['is_ajax_request'] != true) {
+    include 'libraries/db_info.inc.php';
+}
+$response->addHTML('<div id="searchresults">');
+
+// Main search form has been submitted, get results
+if (isset($_REQUEST['submit_search'])) {
+    $response->addHTML($db_search->getSearchResults());
+}
+
+// If we are in an Ajax request, we need to exit after displaying all the HTML
+if ($GLOBALS['is_ajax_request'] == true && empty($_REQUEST['ajax_page_request'])) {
+    exit;
+}
+
+// Display the search form
+$response->addHTML($db_search->getSelectionForm($url_params));
+?>
diff --git a/phpmyadmin/db_sql.php b/phpmyadmin/db_sql.php
new file mode 100644
index 0000000..baced44
--- /dev/null
+++ b/phpmyadmin/db_sql.php
@@ -0,0 +1,65 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ *
+ * @package PhpMyAdmin
+ */
+
+/**
+ *
+ */
+require_once 'libraries/common.inc.php';
+
+/**
+ * Runs common work
+ */
+$response = PMA_Response::getInstance();
+$header   = $response->getHeader();
+$scripts  = $header->getScripts();
+$scripts->addFile('functions.js');
+$scripts->addFile('makegrid.js');
+$scripts->addFile('sql.js');
+
+require 'libraries/db_common.inc.php';
+require_once 'libraries/sql_query_form.lib.php';
+
+// After a syntax error, we return to this script
+// with the typed query in the textarea.
+$goto = 'db_sql.php';
+$back = 'db_sql.php';
+
+/**
+ * Sets globals from $_GET
+ */
+
+$get_params = array(
+    'db_query_force'
+);
+
+foreach ($get_params as $one_get_param) {
+    if (isset($_GET[$one_get_param])) {
+        $GLOBALS[$one_get_param] = $_GET[$one_get_param];
+    }
+}
+
+/**
+ * Gets informations about the database and, if it is empty, move to the
+ * "db_structure.php" script where table can be created
+ */
+require 'libraries/db_info.inc.php';
+if ($num_tables == 0 && empty($db_query_force)) {
+    $sub_part   = '';
+    $is_info    = true;
+    include 'db_structure.php';
+    exit();
+}
+
+/**
+ * Query box, bookmark, insert data from textfile
+ */
+PMA_sqlQueryForm(
+    true, false,
+    isset($_REQUEST['delimiter']) ? htmlspecialchars($_REQUEST['delimiter']) : ';'
+);
+
+?>
diff --git a/phpmyadmin/db_structure.php b/phpmyadmin/db_structure.php
new file mode 100644
index 0000000..ed5a481
--- /dev/null
+++ b/phpmyadmin/db_structure.php
@@ -0,0 +1,335 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ *
+ * @package PhpMyAdmin
+ */
+
+/**
+ *
+ */
+require_once 'libraries/common.inc.php';
+
+/**
+ * Function implementations for this script
+ */
+require_once 'libraries/structure.lib.php';
+
+$response = PMA_Response::getInstance();
+$header   = $response->getHeader();
+$scripts  = $header->getScripts();
+$scripts->addFile('db_structure.js');
+$scripts->addFile('tbl_change.js');
+$scripts->addFile('jquery/jquery-ui-timepicker-addon.js');
+
+$post_params = array(
+    'error',
+    'is_info',
+    'message',
+    'mult_btn',
+    'selected_tbl',
+    'submit_mult'
+);
+foreach ($post_params as $one_post_param) {
+    if (isset($_POST[$one_post_param])) {
+        $GLOBALS[$one_post_param] = $_POST[$one_post_param];
+    }
+}
+/**
+ * Prepares the tables list if the user where not redirected to this script
+ * because there is no table in the database ($is_info is true)
+ */
+if (empty($_POST['is_info'])) {
+    // Drops/deletes/etc. multiple tables if required
+    if ((!empty($_POST['submit_mult']) && isset($_POST['selected_tbl']))
+        || isset($_POST['mult_btn'])
+    ) {
+        $action = 'db_structure.php';
+        $err_url = 'db_structure.php?'. PMA_generate_common_url($db);
+
+        // see bug #2794840; in this case, code path is:
+        // db_structure.php -> libraries/mult_submits.inc.php -> sql.php
+        // -> db_structure.php and if we got an error on the multi submit,
+        // we must display it here and not call again mult_submits.inc.php
+        if (! isset($_POST['error']) || false === $_POST['error']) {
+            include 'libraries/mult_submits.inc.php';
+        }
+        if (empty($_POST['message'])) {
+            $_POST['message'] = PMA_Message::success();
+        }
+    }
+    include 'libraries/db_common.inc.php';
+    $url_query .= '&goto=db_structure.php';
+
+    // Gets the database structure
+    $sub_part = '_structure';
+    include 'libraries/db_info.inc.php';
+
+    if (!PMA_DRIZZLE) {
+        include_once 'libraries/replication.inc.php';
+    } else {
+        $server_slave_status = false;
+    }
+}
+
+require_once 'libraries/bookmark.lib.php';
+
+require_once 'libraries/mysql_charsets.lib.php';
+$db_collation = PMA_getDbCollation($db);
+
+$titles = PMA_Util::buildActionTitles();
+
+// 1. No tables
+
+if ($num_tables == 0) {
+    $response->addHTML(
+        '<p>' . __('No tables found in database') . '</p>' . "\n"
+    );
+    if (empty($db_is_information_schema)) {
+        ob_start();
+        include 'libraries/display_create_table.lib.php';
+        $content = ob_get_contents();
+        ob_end_clean();
+        $response->addHTML($content);
+        unset($content);
+    } // end if (Create Table dialog)
+    exit;
+}
+
+// else
+// 2. Shows table informations
+
+/**
+ * Displays the tables list
+ */
+$response->addHTML('<div id="tableslistcontainer">');
+$_url_params = array(
+    'pos' => $pos,
+    'db'  => $db);
+
+// Add the sort options if they exists
+if (isset($_REQUEST['sort'])) {
+    $_url_params['sort'] = $_REQUEST['sort'];
+}
+
+if (isset($_REQUEST['sort_order'])) {
+    $_url_params['sort_order'] = $_REQUEST['sort_order'];
+}
+
+$response->addHTML(
+    PMA_Util::getListNavigator(
+        $total_num_tables, $pos, $_url_params, 'db_structure.php',
+        'frame_content', $GLOBALS['cfg']['MaxTableList']
+    )
+);
+
+// tables form
+$response->addHTML(
+    '<form method="post" action="db_structure.php" '
+    . 'name="tablesForm" id="tablesForm">'
+);
+
+$response->addHTML(PMA_generate_common_hidden_inputs($db));
+
+$response->addHTML(
+    PMA_TableHeader($db_is_information_schema, $server_slave_status)
+);
+
+$i = $sum_entries = 0;
+$overhead_check = '';
+$create_time_all = '';
+$update_time_all = '';
+$check_time_all = '';
+$num_columns    = $cfg['PropertiesNumColumns'] > 1
+    ? ceil($num_tables / $cfg['PropertiesNumColumns']) + 1
+    : 0;
+$row_count      = 0;
+$sum_size       = (double) 0;
+$overhead_size  = (double) 0;
+
+$hidden_fields = array();
+$odd_row       = true;
+$sum_row_count_pre = '';
+
+foreach ($tables as $keyname => $current_table) {
+    // Get valid statistics whatever is the table type
+
+    $drop_query = '';
+    $drop_message = '';
+    $overhead = '';
+
+    $table_is_view = false;
+    $table_encoded = urlencode($current_table['TABLE_NAME']);
+    // Sets parameters for links
+    $tbl_url_query = $url_query . '&table=' . $table_encoded;
+    // do not list the previous table's size info for a view
+
+    list($current_table, $formatted_size, $unit, $formatted_overhead,
+        $overhead_unit, $overhead_size, $table_is_view, $sum_size)
+            = PMA_getStuffForEngineTypeTable(
+                $current_table, $db_is_information_schema,
+                $is_show_stats, $table_is_view, $sum_size, $overhead_size
+            );
+
+    if (! PMA_Table::isMerge($db, $current_table['TABLE_NAME'])) {
+        $sum_entries += $current_table['TABLE_ROWS'];
+    }
+
+    if (isset($current_table['Collation'])) {
+        $collation = '<dfn title="'
+            . PMA_getCollationDescr($current_table['Collation']) . '">'
+            . $current_table['Collation'] . '</dfn>';
+    } else {
+        $collation = '---';
+    }
+
+    if ($is_show_stats) {
+        if ($formatted_overhead != '') {
+            $overhead = '<a href="tbl_structure.php?'
+                . $tbl_url_query . '#showusage">'
+                . '<span>' . $formatted_overhead . '</span>'
+                . '<span class="unit">' . $overhead_unit . '</span>'
+                . '</a>' . "\n";
+            $overhead_check .=
+                "markAllRows('row_tbl_" . ($i + 1) . "');";
+        } else {
+            $overhead = '-';
+        }
+    } // end if
+
+    unset($showtable);
+
+    if ($GLOBALS['cfg']['ShowDbStructureCreation']) {
+        list($create_time, $create_time_all) = PMA_getTimeForCreateUpdateCheck(
+            $current_table, 'Create_time', $create_time_all
+        );
+    }
+
+    if ($GLOBALS['cfg']['ShowDbStructureLastUpdate']) {
+        // $showtable might already be set from ShowDbStructureCreation, see above
+        list($update_time, $update_time_all) = PMA_getTimeForCreateUpdateCheck(
+            $current_table, 'Update_time', $update_time_all
+        );
+    }
+
+    if ($GLOBALS['cfg']['ShowDbStructureLastCheck']) {
+        // $showtable might already be set from ShowDbStructureCreation, see above
+        list($check_time, $check_time_all) = PMA_getTimeForCreateUpdateCheck(
+            $current_table, 'Check_time', $check_time_all
+        );
+    }
+
+    list($alias, $truename) = PMA_getAliasAndTrueName(
+        $tooltip_aliasname, $current_table, $tooltip_truename
+    );
+
+    $i++;
+
+    $row_count++;
+    if ($table_is_view) {
+        $hidden_fields[] = '<input type="hidden" name="views[]" value="'
+            .  htmlspecialchars($current_table['TABLE_NAME']) . '" />';
+    }
+
+    /*
+     * Always activate links for Browse, Search and Empty, even if
+     * the icons are greyed, because
+     * 1. for views, we don't know the number of rows at this point
+     * 2. for tables, another source could have populated them since the
+     *    page was generated
+     *
+     * I could have used the PHP ternary conditional operator but I find
+     * the code easier to read without this operator.
+     */
+    list($browse_table, $search_table, $browse_table_label, $empty_table,
+        $tracking_icon) = PMA_getHtmlForActionLinks(
+            $current_table, $table_is_view, $tbl_url_query,
+            $titles, $truename, $db_is_information_schema, $url_query
+        );
+
+    if (! $db_is_information_schema) {
+        list($drop_query, $drop_message)
+            = PMA_getTableDropQueryAndMessage($table_is_view, $current_table);
+    }
+
+    if ($num_columns > 0
+        && $num_tables > $num_columns
+        && ($row_count % $num_columns) == 0
+    ) {
+        $row_count = 1;
+        $odd_row = true;
+
+        $response->addHTML(
+            '</tr></tbody></table>'
+        );
+
+        $response->addHTML(PMA_TableHeader(false, $server_slave_status));
+    }
+
+    list($do, $ignored) = PMA_getServerSlaveStatus(
+        $server_slave_status, $truename
+    );
+
+    list($html_output, $odd_row) = PMA_getHtmlForStructureTableRow(
+        $i, $odd_row, $table_is_view, $current_table,
+        $browse_table_label, $tracking_icon, $server_slave_status,
+        $browse_table, $tbl_url_query, $search_table, $db_is_information_schema,
+        $titles, $empty_table, $drop_query, $drop_message, $collation,
+        $formatted_size, $unit, $overhead,
+        (isset ($create_time) ? $create_time : ''),
+        (isset ($update_time) ? $update_time : ''),
+        (isset ($check_time) ? $check_time : ''),
+        $is_show_stats, $ignored, $do, $colspan_for_structure
+    );
+    $response->addHTML($html_output);
+
+} // end foreach
+
+// Show Summary
+$response->addHTML('</tbody>');
+$response->addHTML(
+    PMA_getHtmlBodyForTableSummary(
+        $num_tables, $server_slave_status, $db_is_information_schema, $sum_entries,
+        $db_collation, $is_show_stats, $sum_size, $overhead_size, $create_time_all,
+        $update_time_all, $check_time_all, $sum_row_count_pre
+    )
+);
+$response->addHTML('</table>');
+//check all
+$response->addHTML(
+    PMA_getHtmlForCheckAllTables(
+        $pmaThemeImage, $text_dir, $overhead_check,
+        $db_is_information_schema, $hidden_fields
+    )
+);
+$response->addHTML('</form>'); //end of form
+
+// display again the table list navigator
+$response->addHTML(
+    PMA_Util::getListNavigator(
+        $total_num_tables, $pos, $_url_params, 'db_structure.php',
+        'frame_content', $GLOBALS['cfg']['MaxTableList']
+    )
+);
+
+$response->addHTML('</div><hr />');
+
+/**
+ * Work on the database
+ */
+/* DATABASE WORK */
+/* Printable view of a table */
+$response->addHTML(
+    PMA_getHtmlForTablePrintViewLink($url_query)
+    . PMA_getHtmlForDataDictionaryLink($url_query)
+);
+
+if (empty($db_is_information_schema)) {
+    ob_start();
+    include 'libraries/display_create_table.lib.php';
+    $content = ob_get_contents();
+    ob_end_clean();
+    $response->addHTML($content);
+} // end if (Create Table dialog)
+
+?>
diff --git a/phpmyadmin/db_tracking.php b/phpmyadmin/db_tracking.php
new file mode 100644
index 0000000..e95a7e0
--- /dev/null
+++ b/phpmyadmin/db_tracking.php
@@ -0,0 +1,243 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * @package PhpMyAdmin
+ */
+
+/**
+ * Run common work
+ */
+require_once 'libraries/common.inc.php';
+
+//Get some js files needed for Ajax requests
+$response = PMA_Response::getInstance();
+$header   = $response->getHeader();
+$scripts  = $header->getScripts();
+$scripts->addFile('db_structure.js');
+
+/**
+ * If we are not in an Ajax request, then do the common work and show the links etc.
+ */
+require 'libraries/db_common.inc.php';
+$url_query .= '&goto=tbl_tracking.php&back=db_tracking.php';
+
+// Get the database structure
+$sub_part = '_structure';
+require 'libraries/db_info.inc.php';
+
+// Work to do?
+//  (here, do not use $_REQUEST['db] as it can be crafted)
+if (isset($_REQUEST['delete_tracking']) && isset($_REQUEST['table'])) {
+    PMA_Tracker::deleteTracking($GLOBALS['db'], $_REQUEST['table']);
+
+    /**
+     * If in an Ajax request, generate the success message and use
+     * {@link PMA_Response()} to send the output
+     */
+    if ($GLOBALS['is_ajax_request'] == true) {
+        $response = PMA_Response::getInstance();
+        $response->addJSON('message', PMA_Message::success());
+        exit;
+    }
+}
+
+// Get tracked data about the database
+$data = PMA_Tracker::getTrackedData($_REQUEST['db'], '', '1');
+
+// No tables present and no log exist
+if ($num_tables == 0 && count($data['ddlog']) == 0) {
+    echo '<p>' . __('No tables found in database.') . '</p>' . "\n";
+
+    if (empty($db_is_information_schema)) {
+        include 'libraries/display_create_table.lib.php';
+    }
+    exit;
+}
+
+// ---------------------------------------------------------------------------
+
+// Prepare statement to get HEAD version
+$all_tables_query = ' SELECT table_name, MAX(version) as version FROM ' .
+     PMA_Util::backquote($GLOBALS['cfg']['Server']['pmadb']) . '.' .
+     PMA_Util::backquote($GLOBALS['cfg']['Server']['tracking']) .
+     ' WHERE db_name = \'' . PMA_Util::sqlAddSlashes($_REQUEST['db']) . '\' ' .
+     ' GROUP BY table_name' .
+     ' ORDER BY table_name ASC';
+
+$all_tables_result = PMA_queryAsControlUser($all_tables_query);
+
+// If a HEAD version exists
+if (PMA_DBI_num_rows($all_tables_result) > 0) {
+?>
+    <div id="tracked_tables">
+    <h3><?php echo __('Tracked tables');?></h3>
+
+    <table id="versions" class="data">
+    <thead>
+    <tr>
+        <th><?php echo __('Database');?></th>
+        <th><?php echo __('Table');?></th>
+        <th><?php echo __('Last version');?></th>
+        <th><?php echo __('Created');?></th>
+        <th><?php echo __('Updated');?></th>
+        <th><?php echo __('Status');?></th>
+        <th><?php echo __('Action');?></th>
+        <th><?php echo __('Show');?></th>
+    </tr>
+    </thead>
+    <tbody>
+    <?php
+
+    // Print out information about versions
+
+    $drop_image_or_text = '';
+    if (true == $GLOBALS['cfg']['PropertiesIconic']) {
+        $drop_image_or_text .= PMA_Util::getImage(
+            'b_drop.png',
+            __('Delete tracking data for this table')
+        );
+    }
+    if ('both' === $GLOBALS['cfg']['PropertiesIconic']
+        || false === $GLOBALS['cfg']['PropertiesIconic']
+    ) {
+        $drop_image_or_text .= __('Drop');
+    }
+
+    $style = 'odd';
+    while ($one_result = PMA_DBI_fetch_array($all_tables_result)) {
+        list($table_name, $version_number) = $one_result;
+        $table_query = ' SELECT * FROM ' .
+             PMA_Util::backquote($GLOBALS['cfg']['Server']['pmadb']) . '.' .
+             PMA_Util::backquote($GLOBALS['cfg']['Server']['tracking']) .
+             ' WHERE `db_name` = \'' . PMA_Util::sqlAddSlashes($_REQUEST['db'])
+             . '\' AND `table_name`  = \'' . PMA_Util::sqlAddSlashes($table_name)
+             . '\' AND `version` = \'' . $version_number . '\'';
+
+        $table_result = PMA_queryAsControlUser($table_query);
+        $version_data = PMA_DBI_fetch_array($table_result);
+
+        if ($version_data['tracking_active'] == 1) {
+            $version_status = __('active');
+        } else {
+            $version_status = __('not active');
+        }
+        $tmp_link = 'tbl_tracking.php?' . $url_query . '&table='
+            . htmlspecialchars($version_data['table_name']);
+        $delete_link = 'db_tracking.php?' . $url_query . '&table='
+            . htmlspecialchars($version_data['table_name'])
+            . '&delete_tracking=true&amp';
+        ?>
+        <tr class="noclick <?php echo $style;?>">
+            <td><?php echo htmlspecialchars($version_data['db_name']);?></td>
+            <td><?php echo htmlspecialchars($version_data['table_name']);?></td>
+            <td><?php echo $version_data['version'];?></td>
+            <td><?php echo $version_data['date_created'];?></td>
+            <td><?php echo $version_data['date_updated'];?></td>
+            <td><?php echo $version_status;?></td>
+            <td><a class="drop_tracking_anchor ajax" href="<?php echo $delete_link;?>" ><?php echo $drop_image_or_text; ?></a></td>
+            <td> <a href="<?php echo $tmp_link; ?>"><?php echo __('Versions');?></a>
+               | <a href="<?php echo $tmp_link; ?>&report=true&version=<?php echo $version_data['version'];?>"><?php echo __('Tracking report');?></a>
+               | <a href="<?php echo $tmp_link; ?>&snapshot=true&version=<?php echo $version_data['version'];?>"><?php echo __('Structure snapshot');?></a></td>
+        </tr>
+        <?php
+        if ($style == 'even') {
+            $style = 'odd';
+        } else {
+            $style = 'even';
+        }
+    }
+    unset($tmp_link);
+    ?>
+    </tbody>
+    </table>
+    </div>
+<?php
+}
+
+$sep = $GLOBALS['cfg']['NavigationTreeTableSeparator'];
+
+// Get list of tables
+$table_list = PMA_Util::getTableList($GLOBALS['db']);
+
+// For each table try to get the tracking version
+foreach ($table_list as $key => $value) {
+    // If $value is a table group.
+    if (array_key_exists(('is' . $sep . 'group'), $value)
+        && $value['is' . $sep . 'group']
+    ) {
+        foreach ($value as $temp_table) {
+            // If $temp_table is a table with the value for 'Name' is set,
+            // rather than a propery of the table group.
+            if (is_array($temp_table)
+                && array_key_exists('Name', $temp_table)
+            ) {
+                $tracking_version = PMA_Tracker::getVersion(
+                    $GLOBALS['db'],
+                    $temp_table['Name']
+                );
+                if ($tracking_version == -1) {
+                    $my_tables[] = $temp_table['Name'];
+                }
+            }
+        }
+    } else { // If $value is a table.
+        if (PMA_Tracker::getVersion($GLOBALS['db'], $value['Name']) == -1) {
+            $my_tables[] = $value['Name'];
+        }
+    }
+}
+
+// If untracked tables exist
+if (isset($my_tables)) {
+?>
+    <h3><?php echo __('Untracked tables');?></h3>
+
+    <table id="noversions" class="data">
+    <thead>
+    <tr>
+        <th style="width: 300px"><?php echo __('Table');?></th>
+        <th></th>
+    </tr>
+    </thead>
+    <tbody>
+<?php
+    // Print out list of untracked tables
+
+    $style = 'odd';
+
+    foreach ($my_tables as $key => $tablename) {
+        if (PMA_Tracker::getVersion($GLOBALS['db'], $tablename) == -1) {
+            $my_link = '<a href="tbl_tracking.php?' . $url_query
+                . '&table=' . htmlspecialchars($tablename) .'">';
+            $my_link .= PMA_Util::getIcon('eye.png', __('Track table'));
+            $my_link .= '</a>';
+        ?>
+            <tr class="noclick <?php echo $style;?>">
+            <td><?php echo htmlspecialchars($tablename);?></td>
+            <td><?php echo $my_link;?></td>
+            </tr>
+        <?php
+            if ($style == 'even') {
+                $style = 'odd';
+            } else {
+                $style = 'even';
+            }
+        }
+    }
+    ?>
+    </tbody>
+    </table>
+
+<?php
+}
+// If available print out database log
+if (count($data['ddlog']) > 0) {
+    $log = '';
+    foreach ($data['ddlog'] as $entry) {
+        $log .= '# ' . $entry['date'] . ' ' . $entry['username'] . "\n"
+            . $entry['statement'] . "\n";
+    }
+    echo PMA_Util::getMessage(__('Database Log'), $log);
+}
+
+?>
diff --git a/phpmyadmin/db_triggers.php b/phpmyadmin/db_triggers.php
new file mode 100644
index 0000000..d1a2a8c
--- /dev/null
+++ b/phpmyadmin/db_triggers.php
@@ -0,0 +1,25 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * Triggers management.
+ *
+ * @package PhpMyAdmin
+ */
+
+/**
+ * Include required files
+ */
+require_once 'libraries/common.inc.php';
+
+/**
+ * Include all other files
+ */
+require_once 'libraries/rte/rte_triggers.lib.php';
+
+/**
+ * Do the magic
+ */
+$_PMA_RTE = 'TRI';
+require_once 'libraries/rte/rte_main.inc.php';
+
+?>
diff --git a/phpmyadmin/doc/Makefile b/phpmyadmin/doc/Makefile
new file mode 100644
index 0000000..1ee62c8
--- /dev/null
+++ b/phpmyadmin/doc/Makefile
@@ -0,0 +1,153 @@
+# Makefile for Sphinx documentation
+#
+
+# You can set these variables from the command line.
+SPHINXOPTS    =
+SPHINXBUILD   = sphinx-build
+PAPER         =
+BUILDDIR      = .
+
+# Internal variables.
+PAPEROPT_a4     = -D latex_paper_size=a4
+PAPEROPT_letter = -D latex_paper_size=letter
+ALLSPHINXOPTS   = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) .
+# the i18n builder cannot share the environment and doctrees with the others
+I18NSPHINXOPTS  = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) .
+
+.PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest gettext
+
+help:
+	@echo "Please use \`make <target>' where <target> is one of"
+	@echo "  html       to make standalone HTML files"
+	@echo "  dirhtml    to make HTML files named index.html in directories"
+	@echo "  singlehtml to make a single large HTML file"
+	@echo "  pickle     to make pickle files"
+	@echo "  json       to make JSON files"
+	@echo "  htmlhelp   to make HTML files and a HTML help project"
+	@echo "  qthelp     to make HTML files and a qthelp project"
+	@echo "  devhelp    to make HTML files and a Devhelp project"
+	@echo "  epub       to make an epub"
+	@echo "  latex      to make LaTeX files, you can set PAPER=a4 or PAPER=letter"
+	@echo "  latexpdf   to make LaTeX files and run them through pdflatex"
+	@echo "  text       to make text files"
+	@echo "  man        to make manual pages"
+	@echo "  texinfo    to make Texinfo files"
+	@echo "  info       to make Texinfo files and run them through makeinfo"
+	@echo "  gettext    to make PO message catalogs"
+	@echo "  changes    to make an overview of all changed/added/deprecated items"
+	@echo "  linkcheck  to check all external links for integrity"
+	@echo "  doctest    to run all doctests embedded in the documentation (if enabled)"
+
+clean:
+	-rm -rf $(BUILDDIR)/*
+
+html:
+	$(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html
+	@echo
+	@echo "Build finished. The HTML pages are in $(BUILDDIR)/html."
+
+dirhtml:
+	$(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml
+	@echo
+	@echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml."
+
+singlehtml:
+	$(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml
+	@echo
+	@echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml."
+
+pickle:
+	$(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle
+	@echo
+	@echo "Build finished; now you can process the pickle files."
+
+json:
+	$(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json
+	@echo
+	@echo "Build finished; now you can process the JSON files."
+
+htmlhelp:
+	$(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp
+	@echo
+	@echo "Build finished; now you can run HTML Help Workshop with the" \
+	      ".hhp project file in $(BUILDDIR)/htmlhelp."
+
+qthelp:
+	$(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp
+	@echo
+	@echo "Build finished; now you can run "qcollectiongenerator" with the" \
+	      ".qhcp project file in $(BUILDDIR)/qthelp, like this:"
+	@echo "# qcollectiongenerator $(BUILDDIR)/qthelp/phpMyAdmin.qhcp"
+	@echo "To view the help file:"
+	@echo "# assistant -collectionFile $(BUILDDIR)/qthelp/phpMyAdmin.qhc"
+
+devhelp:
+	$(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp
+	@echo
+	@echo "Build finished."
+	@echo "To view the help file:"
+	@echo "# mkdir -p $$HOME/.local/share/devhelp/phpMyAdmin"
+	@echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/phpMyAdmin"
+	@echo "# devhelp"
+
+epub:
+	$(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub
+	@echo
+	@echo "Build finished. The epub file is in $(BUILDDIR)/epub."
+
+latex:
+	$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
+	@echo
+	@echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex."
+	@echo "Run \`make' in that directory to run these through (pdf)latex" \
+	      "(use \`make latexpdf' here to do that automatically)."
+
+latexpdf:
+	$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
+	@echo "Running LaTeX files through pdflatex..."
+	$(MAKE) -C $(BUILDDIR)/latex all-pdf
+	@echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex."
+
+text:
+	$(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text
+	@echo
+	@echo "Build finished. The text files are in $(BUILDDIR)/text."
+
+man:
+	$(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man
+	@echo
+	@echo "Build finished. The manual pages are in $(BUILDDIR)/man."
+
+texinfo:
+	$(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo
+	@echo
+	@echo "Build finished. The Texinfo files are in $(BUILDDIR)/texinfo."
+	@echo "Run \`make' in that directory to run these through makeinfo" \
+	      "(use \`make info' here to do that automatically)."
+
+info:
+	$(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo
+	@echo "Running Texinfo files through makeinfo..."
+	make -C $(BUILDDIR)/texinfo info
+	@echo "makeinfo finished; the Info files are in $(BUILDDIR)/texinfo."
+
+gettext:
+	$(SPHINXBUILD) -b gettext $(I18NSPHINXOPTS) $(BUILDDIR)/locale
+	@echo
+	@echo "Build finished. The message catalogs are in $(BUILDDIR)/locale."
+
+changes:
+	$(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes
+	@echo
+	@echo "The overview file is in $(BUILDDIR)/changes."
+
+linkcheck:
+	$(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck
+	@echo
+	@echo "Link check complete; look for any errors in the above output " \
+	      "or in $(BUILDDIR)/linkcheck/output.txt."
+
+doctest:
+	$(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest
+	@echo "Testing of doctests in the sources finished, look at the " \
+	      "results in $(BUILDDIR)/doctest/output.txt."
diff --git a/phpmyadmin/doc/_ext/configext.py b/phpmyadmin/doc/_ext/configext.py
new file mode 100644
index 0000000..fdf3314
--- /dev/null
+++ b/phpmyadmin/doc/_ext/configext.py
@@ -0,0 +1,189 @@
+from sphinx.locale import l_, _
+from sphinx.domains import Domain, ObjType
+from sphinx.roles import XRefRole
+from sphinx.domains.std import GenericObject, StandardDomain
+from sphinx.directives import ObjectDescription
+from sphinx.util.nodes import clean_astext, make_refnode
+from sphinx.util import ws_re
+from sphinx import addnodes
+from sphinx.util.docfields import Field
+from docutils import nodes
+
+def get_id_from_cfg(text):
+    '''
+    Formats anchor ID from config option.
+    '''
+    if text[:6] == '$cfg[\'':
+        text = text[6:]
+    if text[-2:] == '\']':
+        text = text[:-2]
+    text = text.replace('[$i]', '')
+    parts = text.split("']['")
+    return parts
+
+
+class ConfigOption(ObjectDescription):
+    indextemplate = l_('configuration option; %s')
+    parse_node = None
+
+    has_arguments = True
+
+    doc_field_types = [
+        Field('default', label=l_('Default value'), has_arg=False,
+              names=('default', )),
+        Field('type', label=l_('Type'), has_arg=False,
+              names=('type',)),
+    ]
+
+
+    def handle_signature(self, sig, signode):
+        signode.clear()
+        signode += addnodes.desc_name(sig, sig)
+        # normalize whitespace like XRefRole does
+        name = ws_re.sub('', sig)
+        return name
+
+    def add_target_and_index(self, name, sig, signode):
+        targetparts =  get_id_from_cfg(name)
+        targetname = 'cfg_%s' % '_'.join(targetparts)
+        signode['ids'].append(targetname)
+        self.state.document.note_explicit_target(signode)
+        indextype = 'single'
+
+        # Generic index entries
+        indexentry = self.indextemplate % (name,)
+        self.indexnode['entries'].append((indextype, indexentry,
+                                          targetname, targetname))
+        self.indexnode['entries'].append((indextype, name,
+                                          targetname, targetname))
+
+        # Server section
+        if targetparts[0] == 'Servers' and len(targetparts) > 1:
+            indexname = ', '.join(targetparts[1:])
+            self.indexnode['entries'].append((indextype, l_('server configuration; %s') % indexname,
+                                              targetname, targetname))
+            self.indexnode['entries'].append((indextype, indexname,
+                                              targetname, targetname))
+        else:
+            indexname = ', '.join(targetparts)
+            self.indexnode['entries'].append((indextype, indexname,
+                                              targetname, targetname))
+
+        self.env.domaindata['config']['objects'][self.objtype, name] = \
+            self.env.docname, targetname
+
+
+class ConfigSectionXRefRole(XRefRole):
+    """
+    Cross-referencing role for configuration sections (adds an index entry).
+    """
+
+    def result_nodes(self, document, env, node, is_ref):
+        if not is_ref:
+            return [node], []
+        varname = node['reftarget']
+        tgtid = 'index-%s' % env.new_serialno('index')
+        indexnode = addnodes.index()
+        indexnode['entries'] = [
+            ('single', varname, tgtid, varname),
+            ('single', _('configuration section; %s') % varname, tgtid, varname)
+        ]
+        targetnode = nodes.target('', '', ids=[tgtid])
+        document.note_explicit_target(targetnode)
+        return [indexnode, targetnode, node], []
+
+class ConfigSection(ObjectDescription):
+    indextemplate = l_('configuration section; %s')
+    parse_node = None
+
+    def handle_signature(self, sig, signode):
+        if self.parse_node:
+            name = self.parse_node(self.env, sig, signode)
+        else:
+            signode.clear()
+            signode += addnodes.desc_name(sig, sig)
+            # normalize whitespace like XRefRole does
+            name = ws_re.sub('', sig)
+        return name
+
+    def add_target_and_index(self, name, sig, signode):
+        targetname = '%s-%s' % (self.objtype, name)
+        signode['ids'].append(targetname)
+        self.state.document.note_explicit_target(signode)
+        if self.indextemplate:
+            colon = self.indextemplate.find(':')
+            if colon != -1:
+                indextype = self.indextemplate[:colon].strip()
+                indexentry = self.indextemplate[colon+1:].strip() % (name,)
+            else:
+                indextype = 'single'
+                indexentry = self.indextemplate % (name,)
+            self.indexnode['entries'].append((indextype, indexentry,
+                                              targetname, targetname))
+        self.env.domaindata['config']['objects'][self.objtype, name] = \
+            self.env.docname, targetname
+
+
+class ConfigOptionXRefRole(XRefRole):
+    """
+    Cross-referencing role for configuration options (adds an index entry).
+    """
+
+    def result_nodes(self, document, env, node, is_ref):
+        if not is_ref:
+            return [node], []
+        varname = node['reftarget']
+        tgtid = 'index-%s' % env.new_serialno('index')
+        indexnode = addnodes.index()
+        indexnode['entries'] = [
+            ('single', varname, tgtid, varname),
+            ('single', _('configuration option; %s') % varname, tgtid, varname)
+        ]
+        targetnode = nodes.target('', '', ids=[tgtid])
+        document.note_explicit_target(targetnode)
+        return [indexnode, targetnode, node], []
+
+
+class ConfigFileDomain(Domain):
+    name = 'config'
+    label = 'Config'
+
+    object_types = {
+            'option':  ObjType(l_('config option'), 'option'),
+            'section':  ObjType(l_('config section'), 'section'),
+            }
+    directives = {
+            'option': ConfigOption,
+            'section': ConfigSection,
+            }
+    roles = {
+            'option': ConfigOptionXRefRole(),
+            'section': ConfigSectionXRefRole(),
+            }
+
+    initial_data = {
+        'objects': {},      # (type, name) -> docname, labelid
+    }
+
+    def clear_doc(self, docname):
+        for key, (fn, _) in self.data['objects'].items():
+            if fn == docname:
+                del self.data['objects'][key]
+
+    def resolve_xref(self, env, fromdocname, builder,
+                     typ, target, node, contnode):
+        docname, labelid = self.data['objects'].get((typ, target), ('', ''))
+        if not docname:
+            return None
+        else:
+            return make_refnode(builder, fromdocname, docname,
+                                labelid, contnode)
+
+    def get_objects(self):
+        for (type, name), info in self.data['objects'].iteritems():
+            yield (name, name, type, info[0], info[1],
+                   self.object_types[type].attrs['searchprio'])
+
+def setup(app):
+    app.add_domain(ConfigFileDomain)
+
diff --git a/phpmyadmin/doc/conf.py b/phpmyadmin/doc/conf.py
new file mode 100644
index 0000000..372d845
--- /dev/null
+++ b/phpmyadmin/doc/conf.py
@@ -0,0 +1,286 @@
+# -*- coding: utf-8 -*-
+#
+# phpMyAdmin documentation build configuration file, created by
+# sphinx-quickstart on Wed Sep 26 14:04:48 2012.
+#
+# This file is execfile()d with the current directory set to its containing dir.
+#
+# Note that not all possible configuration values are present in this
+# autogenerated file.
+#
+# All configuration values have a default; values that are commented out
+# serve to show the default.
+
+import sys, os
+
+# If extensions (or modules to document with autodoc) are in another directory,
+# add these directories to sys.path here. If the directory is relative to the
+# documentation root, use os.path.abspath to make it absolute, like shown here.
+#sys.path.insert(0, os.path.abspath('.'))
+sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), "_ext")))
+
+# -- General configuration -----------------------------------------------------
+
+# If your documentation needs a minimal Sphinx version, state it here.
+#needs_sphinx = '1.0'
+
+# Add any Sphinx extension module names here, as strings. They can be extensions
+# coming with Sphinx (named 'sphinx.ext.*') or your custom ones.
+extensions = ['configext']
+
+# Add any paths that contain templates here, relative to this directory.
+templates_path = ['_templates']
+
+# The suffix of source filenames.
+source_suffix = '.rst'
+
+# The encoding of source files.
+#source_encoding = 'utf-8-sig'
+
+# The master toctree document.
+master_doc = 'index'
+
+# General information about the project.
+project = u'phpMyAdmin'
+copyright = u'2012 - 2013, The phpMyAdmin devel team'
+
+# The version info for the project you're documenting, acts as replacement for
+# |version| and |release|, also used in various other places throughout the
+# built documents.
+#
+# The short X.Y version.
+version = '4.0.4'
+# The full version, including alpha/beta/rc tags.
+release = version
+
+# The language for content autogenerated by Sphinx. Refer to documentation
+# for a list of supported languages.
+#language = None
+
+# There are two options for replacing |today|: either, you set today to some
+# non-false value, then it is used:
+#today = ''
+# Else, today_fmt is used as the format for a strftime call.
+#today_fmt = '%B %d, %Y'
+
+# List of patterns, relative to source directory, that match files and
+# directories to ignore when looking for source files.
+exclude_patterns = ['_build', 'html', 'doctrees']
+
+# The reST default role (used for this markup: `text`) to use for all documents.
+#default_role = None
+
+# If true, '()' will be appended to :func: etc. cross-reference text.
+#add_function_parentheses = True
+
+# If true, the current module name will be prepended to all description
+# unit titles (such as .. function::).
+#add_module_names = True
+
+# If true, sectionauthor and moduleauthor directives will be shown in the
+# output. They are ignored by default.
+#show_authors = False
+
+# The name of the Pygments (syntax highlighting) style to use.
+pygments_style = 'sphinx'
+
+# A list of ignored prefixes for module index sorting.
+#modindex_common_prefix = []
+
+
+# -- Options for HTML output ---------------------------------------------------
+
+# The theme to use for HTML and HTML Help pages.  See the documentation for
+# a list of builtin themes.
+html_theme = 'default'
+
+# Theme options are theme-specific and customize the look and feel of a theme
+# further.  For a list of options available for each theme, see the
+# documentation.
+#html_theme_options = {}
+
+# Add any paths that contain custom themes here, relative to this directory.
+#html_theme_path = []
+
+# The name for this set of Sphinx documents.  If None, it defaults to
+# "<project> v<release> documentation".
+#html_title = None
+
+# A shorter title for the navigation bar.  Default is the same as html_title.
+#html_short_title = None
+
+# The name of an image file (relative to this directory) to place at the top
+# of the sidebar.
+#html_logo = None
+
+# The name of an image file (within the static path) to use as favicon of the
+# docs.  This file should be a Windows icon file (.ico) being 16x16 or 32x32
+# pixels large.
+#html_favicon = None
+
+# Add any paths that contain custom static files (such as style sheets) here,
+# relative to this directory. They are copied after the builtin static files,
+# so a file named "default.css" will overwrite the builtin "default.css".
+html_static_path = ['_static']
+
+# If not '', a 'Last updated on:' timestamp is inserted at every page bottom,
+# using the given strftime format.
+#html_last_updated_fmt = '%b %d, %Y'
+
+# If true, SmartyPants will be used to convert quotes and dashes to
+# typographically correct entities.
+#html_use_smartypants = True
+
+# Custom sidebar templates, maps document names to template names.
+#html_sidebars = {}
+
+# Additional templates that should be rendered to pages, maps page names to
+# template names.
+#html_additional_pages = {}
+
+# If false, no module index is generated.
+#html_domain_indices = True
+
+# If false, no index is generated.
+#html_use_index = True
+
+# If true, the index is split into individual pages for each letter.
+#html_split_index = False
+
+# If true, links to the reST sources are added to the pages.
+#html_show_sourcelink = True
+
+# If true, "Created using Sphinx" is shown in the HTML footer. Default is True.
+#html_show_sphinx = True
+
+# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True.
+#html_show_copyright = True
+
+# If true, an OpenSearch description file will be output, and all pages will
+# contain a <link> tag referring to it.  The value of this option must be the
+# base URL from which the finished HTML is served.
+#html_use_opensearch = ''
+
+# This is the file name suffix for HTML files (e.g. ".xhtml").
+#html_file_suffix = None
+
+# Output file base name for HTML help builder.
+htmlhelp_basename = 'phpMyAdmindoc'
+
+
+# -- Options for LaTeX output --------------------------------------------------
+
+latex_elements = {
+# The paper size ('letterpaper' or 'a4paper').
+#'papersize': 'letterpaper',
+
+# The font size ('10pt', '11pt' or '12pt').
+#'pointsize': '10pt',
+
+# Additional stuff for the LaTeX preamble.
+#'preamble': '',
+}
+
+# Grouping the document tree into LaTeX files. List of tuples
+# (source start file, target name, title, author, documentclass [howto/manual]).
+latex_documents = [
+  ('index', 'phpMyAdmin.tex', u'phpMyAdmin Documentation',
+   u'The phpMyAdmin devel team', 'manual'),
+]
+
+# The name of an image file (relative to this directory) to place at the top of
+# the title page.
+#latex_logo = None
+
+# For "manual" documents, if this is true, then toplevel headings are parts,
+# not chapters.
+#latex_use_parts = False
+
+# If true, show page references after internal links.
+#latex_show_pagerefs = False
+
+# If true, show URL addresses after external links.
+#latex_show_urls = False
+
+# Documents to append as an appendix to all manuals.
+#latex_appendices = []
+
+# If false, no module index is generated.
+#latex_domain_indices = True
+
+
+# -- Options for manual page output --------------------------------------------
+
+# One entry per manual page. List of tuples
+# (source start file, name, description, authors, manual section).
+man_pages = [
+    ('index', 'phpmyadmin', u'phpMyAdmin Documentation',
+     [u'The phpMyAdmin devel team'], 1)
+]
+
+# If true, show URL addresses after external links.
+#man_show_urls = False
+
+
+# -- Options for Texinfo output ------------------------------------------------
+
+# Grouping the document tree into Texinfo files. List of tuples
+# (source start file, target name, title, author,
+#  dir menu entry, description, category)
+texinfo_documents = [
+  ('index', 'phpMyAdmin', u'phpMyAdmin Documentation',
+   u'The phpMyAdmin devel team', 'phpMyAdmin', 'One line description of project.',
+   'Miscellaneous'),
+]
+
+# Documents to append as an appendix to all manuals.
+#texinfo_appendices = []
+
+# If false, no module index is generated.
+#texinfo_domain_indices = True
+
+# How to display URL addresses: 'footnote', 'no', or 'inline'.
+#texinfo_show_urls = 'footnote'
+
+
+# -- Options for Epub output ---------------------------------------------------
+
+# Bibliographic Dublin Core info.
+epub_title = u'phpMyAdmin'
+epub_author = u'The phpMyAdmin devel team'
+epub_publisher = u'The phpMyAdmin devel team'
+epub_copyright = copyright
+
+# The language of the text. It defaults to the language option
+# or en if the language is not set.
+#epub_language = ''
+
+# The scheme of the identifier. Typical schemes are ISBN or URL.
+#epub_scheme = ''
+
+# The unique identifier of the text. This can be a ISBN number
+# or the project homepage.
+#epub_identifier = ''
+
+# A unique identification for the text.
+#epub_uid = ''
+
+# A tuple containing the cover image and cover page html template filenames.
+#epub_cover = ()
+
+# HTML files that should be inserted before the pages created by sphinx.
+# The format is a list of tuples containing the path and title.
+#epub_pre_files = []
+
+# HTML files shat should be inserted after the pages created by sphinx.
+# The format is a list of tuples containing the path and title.
+#epub_post_files = []
+
+# A list of files that should not be packed into the epub file.
+#epub_exclude_files = []
+
+# The depth of the table of contents in toc.ncx.
+#epub_tocdepth = 3
+
+# Allow duplicate toc entries.
+#epub_tocdup = True
diff --git a/phpmyadmin/doc/config.rst b/phpmyadmin/doc/config.rst
new file mode 100644
index 0000000..2b9ced2
--- /dev/null
+++ b/phpmyadmin/doc/config.rst
@@ -0,0 +1,2776 @@
+.. index:: config.inc.php
+
+.. _config:
+
+Configuration
+=============
+
+Almost all configurable data is placed in :file:`config.inc.php`. If this file
+does not exist, please refer to the :ref:`setup` section to create one. This
+file only needs to contain the parameters you want to change from their
+corresponding default value in :file:`libraries/config.default.php`.
+
+The parameters which relate to design (like colors) are placed in
+:file:`themes/themename/layout.inc.php`. You might also want to create
+:file:`config.footer.inc.php` and :file:`config.header.inc.php` files to add
+your site specific code to be included on start and end of each page.
+
+.. note::
+
+    Some distributions (eg. Debian or Ubuntu) store :file:`config.inc.php` in
+    ``/etc/phpmyadmin`` instead of within phpMyAdmin sources.
+
+.. warning::
+
+    :term:`Mac` users should note that if you are on a version before
+    :term:`Mac OS X`, PHP does not seem to
+    like :term:`Mac` end of lines character (``\r``). So
+    ensure you choose the option that allows to use the \*nix end of line
+    character (``\n``) in your text editor before saving a script you have
+    modified.
+
+Basic settings
+--------------
+
+.. config:option:: $cfg['PmaAbsoluteUri']
+
+    :type: string
+    :default: ``''``
+
+    Sets here the complete :term:`URL` (with full path) to your phpMyAdmin
+    installation's directory. E.g.
+    ``http://www.example.net/path_to_your_phpMyAdmin_directory/``.  Note also
+    that the :term:`URL` on some web servers are case–sensitive. Don’t forget
+    the trailing slash at the end.
+
+    Starting with version 2.3.0, it is advisable to try leaving this blank. In
+    most cases phpMyAdmin automatically detects the proper setting. Users of
+    port forwarding will need to set :config:option:`$cfg['PmaAbsoluteUri']`
+    (`more info <https://sourceforge.net/p/phpmyadmin/support-requests/795/>`_).
+
+    A good test is to browse a table, edit a row and save it. There should be
+    an error message if phpMyAdmin is having trouble auto–detecting the correct
+    value. If you get an error that this must be set or if the autodetect code
+    fails to detect your path, please post a bug report on our bug tracker so
+    we can improve the code.
+
+    .. seealso:: :ref:`faq1_40`
+
+.. config:option:: $cfg['PmaNoRelation_DisableWarning']
+
+    :type: boolean
+    :default: false
+
+    Starting with version 2.3.0 phpMyAdmin offers a lot of features to
+    work with master / foreign – tables (see :config:option:`$cfg['Servers'][$i]['pmadb']`).  
+    
+    If you tried to set this
+    up and it does not work for you, have a look on the :guilabel:`Structure` page
+    of one database where you would like to use it. You will find a link
+    that will analyze why those features have been disabled.
+    
+    If you do not want to use those features set this variable to ``true`` to
+    stop this message from appearing.
+
+.. config:option:: $cfg['SuhosinDisableWarning']
+
+    :type: boolean
+    :default: false
+
+    A warning is displayed on the main page if Suhosin is detected. 
+    
+    You can set this parameter to ``true`` to stop this message from appearing.
+
+.. config:option:: $cfg['McryptDisableWarning']
+
+    :type: boolean
+    :default: false
+
+    Disable the default warning that is displayed if mcrypt is missing for
+    cookie authentication. 
+    
+    You can set this parameter to ``true`` to stop this message from appearing.
+
+.. config:option:: $cfg['ServerLibraryDifference_DisableWarning']
+
+    :type: boolean
+    :default: false
+
+    A warning is displayed on the main page if there is a difference
+    between the MySQL library and server version. 
+    
+    You can set this parameter to ``true`` to stop this message from appearing.
+
+.. config:option:: $cfg['ReservedWordDisableWarning']
+
+    :type: boolean
+    :default: false
+
+    This warning is displayed on the Structure page of a table if one or more
+    column names match with words which are MySQL reserved.
+
+    If you want to turn off this warning, you can set it to ``true`` and 
+    warning will not longer be displayed 
+
+.. config:option:: $cfg['TranslationWarningThreshold']
+
+    :type: integer
+    :default: 80
+
+    Show warning about incomplete translations on certain threshold.
+
+Server connection settings
+--------------------------
+
+.. config:option:: $cfg['Servers']
+
+    :type: array
+    :default: one server array with settings listed bellow
+
+    Since version 1.4.2, phpMyAdmin supports the administration of multiple
+    MySQL servers. Therefore, a :config:option:`$cfg['Servers']`-array has been
+    added which contains the login information for the different servers. The
+    first :config:option:`$cfg['Servers'][$i]['host']` contains the hostname of
+    the first server, the second :config:option:`$cfg['Servers'][$i]['host']`
+    the hostname of the second server, etc. In
+    :file:`libraries/config.default.php`, there is only one section for server
+    definition, however you can put as many as you need in
+    :file:`config.inc.php`, copy that block or needed parts (you don't have to
+    define all settings, just those you need to change).
+
+    .. note::
+       
+        The :config:option:`$cfg['Servers']` array starts with
+        $cfg['Servers'][1]. Do not use $cfg['Servers'][0]. If you want more
+        than one server, just copy following section (including $i
+        incrementation) serveral times. There is no need to define full server
+        array, just define values you need to change.
+
+
+.. config:option:: $cfg['Servers'][$i]['host']
+
+    :type: string
+    :default: ``'localhost'``
+
+    The hostname or :term:`IP` address of your $i-th MySQL-server. E.g.
+    ``localhost``.
+
+    Possible values are:
+
+    * hostname, e.g., ``'localhost'`` or ``'mydb.example.org'``
+    * IP address, e.g., ``'127.0.0.1'`` or ``'192.168.10.1'``
+    * dot - ``'.'``, i.e., use named pipes on windows systems
+    * empty - ``''``, disables this server
+
+.. config:option:: $cfg['Servers'][$i]['port']
+
+    :type: string
+    :default: ``''``
+
+    The port-number of your $i-th MySQL-server. Default is 3306 (leave
+    blank). 
+    
+    .. note::
+       
+       If you use ``localhost`` as the hostname, MySQL ignores this port number
+       and connects with the socket, so if you want to connect to a port
+       different from the default port, use ``127.0.0.1`` or the real hostname
+       in :config:option:`$cfg['Servers'][$i]['host']`.
+
+.. config:option:: $cfg['Servers'][$i]['socket']
+
+    :type: string
+    :default: ``''``
+
+    The path to the socket to use. Leave blank for default. To determine
+    the correct socket, check your MySQL configuration or, using the
+    :command:`mysql` command–line client, issue the ``status`` command. Among the
+    resulting information displayed will be the socket used.
+
+.. config:option:: $cfg['Servers'][$i]['ssl']
+
+    :type: boolean
+    :default: false
+
+    Whether to enable SSL for connection to MySQL server.
+
+.. config:option:: $cfg['Servers'][$i]['connect_type']
+
+    :type: string
+    :default: ``'tcp'``
+
+    What type connection to use with the MySQL server. Your options are
+    ``'socket'`` and ``'tcp'``. It defaults to tcp as that is nearly guaranteed
+    to be available on all MySQL servers, while sockets are not supported on
+    some platforms. To use the socket mode, your MySQL server must be on the
+    same machine as the Web server.
+
+.. config:option:: $cfg['Servers'][$i]['extension']
+
+    :type: string
+    :default: ``'mysqli'``
+
+    What php MySQL extension to use for the connection. Valid options are:
+
+    ``mysql``
+        The classic MySQL extension. 
+
+    ``mysqli`` 
+        The improved MySQL extension. This extension became available with PHP
+        5.0.0 and is the recommended way to connect to a server running MySQL
+        4.1.x or newer.
+
+.. config:option:: $cfg['Servers'][$i]['compress']
+
+    :type: boolean
+    :default: false
+
+    Whether to use a compressed protocol for the MySQL server connection
+    or not (experimental).
+
+.. _controlhost:
+.. config:option:: $cfg['Servers'][$i]['controlhost']
+
+    :type: string
+    :default: ``''``
+
+    Permits to use an alternate host to hold the configuration storage
+    data.
+
+.. _controluser:
+.. config:option:: $cfg['Servers'][$i]['controluser']
+
+    :type: string
+    :default: ``''``
+
+.. config:option:: $cfg['Servers'][$i]['controlpass']
+
+    :type: string
+    :default: ``''``
+
+    This special account is used for 2 distinct purposes: to make possible all
+    relational features (see :config:option:`$cfg['Servers'][$i]['pmadb']`) and,
+    for a MySQL server running with ``--skip-show-database``, to enable a
+    multi-user installation (:term:`HTTP` or cookie
+    authentication mode). 
+
+    When using :term:`HTTP` or
+    cookie authentication modes (or 'config' authentication mode since phpMyAdmin
+    2.2.1), you need to supply the details of a MySQL account that has ``SELECT``
+    privilege on the *mysql.user (all columns except "Password")*, *mysql.db (all
+    columns)* and *mysql.tables\_priv (all columns except "Grantor" and
+    "Timestamp")* tables. This account is used to check what databases the user
+    will see at login.
+
+    .. versionchanged:: 2.2.5 
+        those were called ``stduser`` and ``stdpass``
+
+    .. seealso:: :ref:`setup`, :ref:`authentication_modes`
+
+.. config:option:: $cfg['Servers'][$i]['auth_type']
+
+    :type: string
+    :default: ``'cookie'``
+
+    Whether config or cookie or :term:`HTTP` or signon authentication should be
+    used for this server.
+
+    * 'config' authentication (``$auth_type = 'config'``) is the plain old
+      way: username and password are stored in :file:`config.inc.php`.
+    * 'cookie' authentication mode (``$auth_type = 'cookie'``) as
+      introduced in 2.2.3 allows you to log in as any valid MySQL user with
+      the help of cookies. Username and password are stored in cookies
+      during the session and password is deleted when it ends. This can also
+      allow you to log in in arbitrary server if :config:option:`$cfg['AllowArbitraryServer']` enabled.
+    * 'http' authentication (was
+      called 'advanced' in previous versions and can be written also as
+      'http') (``$auth_type = 'http';'``) as introduced in 1.3.0 allows you to log in as any
+      valid MySQL user via HTTP-Auth.
+    * 'signon' authentication mode (``$auth_type = 'signon'``) as
+      introduced in 2.10.0 allows you to log in from prepared PHP session
+      data or using supplied PHP script. This is useful for implementing
+      single signon from another application. Sample way how to seed session
+      is in signon example: :file:`examples/signon.php`. There is also
+      alternative example using OpenID - :file:`examples/openid.php` and example
+      for scripts based solution - :file:`examples/signon-script.php`. You need
+      to configure :config:option:`$cfg['Servers'][$i]['SignonSession']` or 
+      :config:option:`$cfg['Servers'][$i]['SignonScript']` and 
+      :config:option:`$cfg['Servers'][$i]['SignonURL']` to use this authentication 
+      method.
+
+    .. seealso:: :ref:`authentication_modes`
+
+.. _servers_auth_http_realm:
+.. config:option:: $cfg['Servers'][$i]['auth_http_realm']
+
+    :type: string
+    :default: ``''``
+
+    When using auth\_type = ``http``, this field allows to define a custom
+    :term:`HTTP` Basic Auth Realm which will be displayed to the user. If not
+    explicitly specified in your configuration, a string combined of
+    "phpMyAdmin " and either :config:option:`$cfg['Servers'][$i]['verbose']` or
+    :config:option:`$cfg['Servers'][$i]['host']` will be used.
+
+.. _servers_auth_swekey_config:
+.. config:option:: $cfg['Servers'][$i]['auth_swekey_config']
+
+    :type: string
+    :default: ``''``
+
+    The name of the file containing :ref:`swekey` ids and login names for hardware
+    authentication. Leave empty to deactivate this feature.
+
+.. _servers_user:
+.. config:option:: $cfg['Servers'][$i]['user']
+
+    :type: string
+    :default: ``'root'``
+
+.. config:option:: $cfg['Servers'][$i]['password']
+
+    :type: string
+    :default: ``''``
+
+    When using :config:option:`$cfg['Servers'][$i]['auth_type']` set to
+    'config', this is the user/password-pair which phpMyAdmin will use to
+    connect to the MySQL server. This user/password pair is not needed when
+    :term:`HTTP` or cookie authentication is used
+    and should be empty.
+
+.. _servers_nopassword:
+.. config:option:: $cfg['Servers'][$i]['nopassword']
+
+    :type: boolean
+    :default: false
+
+    Allow attempt to log in without password when a login with password
+    fails. This can be used together with http authentication, when
+    authentication is done some other way and phpMyAdmin gets user name
+    from auth and uses empty password for connecting to MySQL. Password
+    login is still tried first, but as fallback, no password method is
+    tried.
+
+.. _servers_only_db:
+.. config:option:: $cfg['Servers'][$i]['only_db']
+
+    :type: string or array
+    :default: ``''``
+
+    If set to a (an array of) database name(s), only this (these)
+    database(s) will be shown to the user. Since phpMyAdmin 2.2.1,
+    this/these database(s) name(s) may contain MySQL wildcards characters
+    ("\_" and "%"): if you want to use literal instances of these
+    characters, escape them (I.E. use ``'my\_db'`` and not ``'my_db'``).
+
+    This setting is an efficient way to lower the server load since the
+    latter does not need to send MySQL requests to build the available
+    database list. But **it does not replace the privileges rules of the
+    MySQL database server**. If set, it just means only these databases
+    will be displayed but **not that all other databases can't be used.**
+
+    An example of using more that one database:
+
+    .. code-block:: php
+        
+        $cfg['Servers'][$i]['only_db'] = array('db1', 'db2');
+
+    .. versionchanged:: 4.0.0 
+        Previous versions permitted to specify the display order of 
+        the database names via this directive. 
+
+.. config:option:: $cfg['Servers'][$i]['hide_db']
+
+    :type: string
+    :default: ``''``
+
+    Regular expression for hiding some databases from unprivileged users.
+    This only hides them from listing, but a user is still able to access
+    them (using, for example, the SQL query area). To limit access, use
+    the MySQL privilege system.  For example, to hide all databases
+    starting with the letter "a", use
+
+    .. code-block:: php
+
+        $cfg['Servers'][$i]['hide_db'] = '^a';
+
+    and to hide both "db1" and "db2" use
+
+    .. code-block:: php
+
+        $cfg['Servers'][$i]['hide_db'] = '^(db1|db2)$';
+
+    More information on regular expressions can be found in the `PCRE
+    pattern syntax
+    <http://php.net/manual/en/reference.pcre.pattern.syntax.php>`_ portion
+    of the PHP reference manual.
+
+.. config:option:: $cfg['Servers'][$i]['verbose']
+
+    :type: string
+    :default: ``''``
+
+    Only useful when using phpMyAdmin with multiple server entries. If
+    set, this string will be displayed instead of the hostname in the
+    pull-down menu on the main page. This can be useful if you want to
+    show only certain databases on your system, for example. For HTTP
+    auth, all non-US-ASCII characters will be stripped.
+
+.. config:option:: $cfg['Servers'][$i]['pmadb']
+
+    :type: string
+    :default: ``''``
+
+    The name of the database containing the phpMyAdmin configuration
+    storage.  
+
+    See the :ref:`linked-tables`  section in this document to see the benefits of
+    this feature, and for a quick way of creating this database and the needed
+    tables.  
+
+    If you are the only user of this phpMyAdmin installation, you can use your
+    current database to store those special tables; in this case, just put your
+    current database name in :config:option:`$cfg['Servers'][$i]['pmadb']`. For a
+    multi-user installation, set this parameter to the name of your central
+    database containing the phpMyAdmin configuration storage.
+
+.. _bookmark:
+.. config:option:: $cfg['Servers'][$i]['bookmarktable']
+
+    :type: string
+    :default: ``''``
+
+    Since release 2.2.0 phpMyAdmin allows users to bookmark queries. This
+    can be useful for queries you often run. To allow the usage of this
+    functionality:
+
+    * set up :config:option:`$cfg['Servers'][$i]['pmadb']` and the phpMyAdmin configuration storage
+    * enter the table name in :config:option:`$cfg['Servers'][$i]['bookmarktable']`
+
+
+.. _relation:
+.. config:option:: $cfg['Servers'][$i]['relation']
+
+    :type: string
+    :default: ``''``
+
+    Since release 2.2.4 you can describe, in a special 'relation' table,
+    which column is a key in another table (a foreign key). phpMyAdmin
+    currently uses this to
+
+    * make clickable, when you browse the master table, the data values that
+      point to the foreign table;
+    * display in an optional tool-tip the "display column" when browsing the
+      master table, if you move the mouse to a column containing a foreign
+      key (use also the 'table\_info' table); (see :ref:`faqdisplay`)
+    * in edit/insert mode, display a drop-down list of possible foreign keys
+      (key value and "display column" are shown) (see :ref:`faq6_21`)
+    * display links on the table properties page, to check referential
+      integrity (display missing foreign keys) for each described key;
+    * in query-by-example, create automatic joins (see :ref:`faq6_6`)
+    * enable you to get a :term:`PDF` schema of
+      your database (also uses the table\_coords table).
+
+    The keys can be numeric or character. 
+
+    To allow the usage of this functionality:
+
+    * set up :config:option:`$cfg['Servers'][$i]['pmadb']` and the phpMyAdmin configuration storage
+    * put the relation table name in :config:option:`$cfg['Servers'][$i]['relation']`
+    * now as normal user open phpMyAdmin and for each one of your tables
+      where you want to use this feature, click :guilabel:`Structure/Relation view/`
+      and choose foreign columns.
+
+    .. note:: 
+       
+        In the current version, ``master_db`` must be the same as ``foreign_db``.
+        Those columns have been put in future development of the cross-db
+        relations.
+
+.. _table_info:
+.. config:option:: $cfg['Servers'][$i]['table_info']
+
+    :type: string
+    :default: ``''``
+
+    Since release 2.3.0 you can describe, in a special 'table\_info'
+    table, which column is to be displayed as a tool-tip when moving the
+    cursor over the corresponding key. This configuration variable will
+    hold the name of this special table. To allow the usage of this
+    functionality:
+
+    * set up :config:option:`$cfg['Servers'][$i]['pmadb']` and the phpMyAdmin configuration storage
+    * put the table name in :config:option:`$cfg['Servers'][$i]['table\_info']` (e.g.
+      ``pma__table_info``)
+    * then for each table where you want to use this feature, click
+      "Structure/Relation view/Choose column to display" to choose the
+      column.
+
+    .. seealso:: :ref:`faqdisplay`
+
+.. _table_coords:
+.. config:option:: $cfg['Servers'][$i]['table_coords']
+
+    :type: string
+    :default: ``''``
+
+.. config:option:: $cfg['Servers'][$i]['pdf_pages']
+
+    :type: string
+    :default: ``''``
+
+    Since release 2.3.0 you can have phpMyAdmin create :term:`PDF` pages
+    showing the relations between your tables. To do this it needs two tables
+    "pdf\_pages" (storing information about the available :term:`PDF` pages)
+    and "table\_coords" (storing coordinates where each table will be placed on
+    a :term:`PDF` schema output).  You must be using the "relation" feature. 
+
+    To allow the usage of this functionality:
+
+    * set up :config:option:`$cfg['Servers'][$i]['pmadb']` and the phpMyAdmin configuration storage
+    * put the correct table names in
+      :config:option:`$cfg['Servers'][$i]['table\_coords']` and
+      :config:option:`$cfg['Servers'][$i]['pdf\_pages']`
+
+    .. seealso:: :ref:`faqpdf`.
+
+.. _col_com:
+.. config:option:: $cfg['Servers'][$i]['column_info']
+
+    :type: string
+    :default: ``''``
+
+    This part requires a content update!  Since release 2.3.0 you can
+    store comments to describe each column for each table. These will then
+    be shown on the "printview". 
+
+    Starting with release 2.5.0, comments are consequently used on the table
+    property pages and table browse view, showing up as tool-tips above the
+    column name (properties page) or embedded within the header of table in
+    browse view. They can also be shown in a table dump. Please see the
+    relevant configuration directives later on. 
+
+    Also new in release 2.5.0 is a MIME- transformation system which is also
+    based on the following table structure. See :ref:`transformations` for
+    further information. To use the MIME- transformation system, your
+    column\_info table has to have the three new columns 'mimetype',
+    'transformation', 'transformation\_options'.
+
+
+    To allow the usage of this functionality:
+
+    * set up :config:option:`$cfg['Servers'][$i]['pmadb']` and the phpMyAdmin configuration storage
+    * put the table name in :config:option:`$cfg['Servers'][$i]['column\_info']` (e.g.
+      ``pma__column_info``)
+    * to update your PRE-2.5.0 Column\_comments Table use this:  and
+      remember that the Variable in :file:`config.inc.php` has been renamed from
+      :config:option:`$cfg['Servers'][$i]['column\_comments']` to
+      :config:option:`$cfg['Servers'][$i]['column\_info']`
+
+      .. code-block:: mysql
+
+           ALTER TABLE `pma__column_comments`
+           ADD `mimetype` VARCHAR( 255 ) NOT NULL,
+           ADD `transformation` VARCHAR( 255 ) NOT NULL,
+           ADD `transformation_options` VARCHAR( 255 ) NOT NULL;
+
+.. _history:
+.. config:option:: $cfg['Servers'][$i]['history']
+
+    :type: string
+    :default: ``''``
+
+    Since release 2.5.0 you can store your :term:`SQL` history, which means all
+    queries you entered manually into the phpMyAdmin interface. If you don't
+    want to use a table-based history, you can use the JavaScript-based
+    history. 
+
+    Using that, all your history items are deleted when closing the window.
+    Using :config:option:`$cfg['QueryHistoryMax']` you can specify an amount of
+    history items you want to have on hold. On every login, this list gets cut
+    to the maximum amount.
+
+    The query history is only available if JavaScript is enabled in
+    your browser. 
+
+    To allow the usage of this functionality:
+
+    * set up :config:option:`$cfg['Servers'][$i]['pmadb']` and the phpMyAdmin configuration storage
+    * put the table name in :config:option:`$cfg['Servers'][$i]['history']` (e.g.
+      ``pma__history``)
+
+.. _recent:
+.. config:option:: $cfg['Servers'][$i]['recent']
+
+    :type: string
+    :default: ``''``
+
+    Since release 3.5.0 you can show recently used tables in the
+    navigation panel. It helps you to jump across table directly, without
+    the need to select the database, and then select the table. Using
+    :config:option:`$cfg['NumRecentTables']` you can configure the maximum number
+    of recent tables shown. When you select a table from the list, it will jump to
+    the page specified in :config:option:`$cfg['NavigationTreeDefaultTabTable']`.
+
+
+    Without configuring the storage, you can still access the recently used tables,
+    but it will disappear after you logout. 
+
+    To allow the usage of this functionality persistently:
+
+    * set up :config:option:`$cfg['Servers'][$i]['pmadb']` and the phpMyAdmin configuration storage
+    * put the table name in :config:option:`$cfg['Servers'][$i]['recent']` (e.g.
+      ``pma__recent``)
+
+.. _table_uiprefs:
+.. config:option:: $cfg['Servers'][$i]['table_uiprefs']
+
+    :type: string
+    :default: ``''``
+
+    Since release 3.5.0 phpMyAdmin can be configured to remember several
+    things (sorted column :config:option:`$cfg['RememberSorting']`, column order,
+    and column visibility from a database table) for browsing tables. Without
+    configuring the storage, these features still can be used, but the values will
+    disappear after you logout. 
+
+    To allow the usage of these functionality persistently:
+
+    * set up :config:option:`$cfg['Servers'][$i]['pmadb']` and the phpMyAdmin configuration storage
+    * put the table name in :config:option:`$cfg['Servers'][$i]['table\_uiprefs']` (e.g.
+      ``pma__table_uiprefs``)
+
+
+.. _tracking:
+.. config:option:: $cfg['Servers'][$i]['tracking']
+
+    :type: string
+    :default: ``''``
+
+    Since release 3.3.x a tracking mechanism is available. It helps you to
+    track every :term:`SQL` command which is
+    executed by phpMyAdmin. The mechanism supports logging of data
+    manipulation and data definition statements. After enabling it you can
+    create versions of tables.  
+
+    The creation of a version has two effects:
+
+    * phpMyAdmin saves a snapshot of the table, including structure and
+      indexes.
+    * phpMyAdmin logs all commands which change the structure and/or data of
+      the table and links these commands with the version number.
+
+    Of course you can view the tracked changes. On the :guilabel:`Tracking`
+    page a complete report is available for every version. For the report you
+    can use filters, for example you can get a list of statements within a date
+    range. When you want to filter usernames you can enter \* for all names or
+    you enter a list of names separated by ','. In addition you can export the
+    (filtered) report to a file or to a temporary database.
+
+    To allow the usage of this functionality:
+
+    * set up :config:option:`$cfg['Servers'][$i]['pmadb']` and the phpMyAdmin configuration storage
+    * put the table name in :config:option:`$cfg['Servers'][$i]['tracking']` (e.g.
+      ``pma__tracking``)
+
+
+.. _tracking2:
+.. config:option:: $cfg['Servers'][$i]['tracking_version_auto_create']
+
+    :type: boolean
+    :default: false
+
+    Whether the tracking mechanism creates versions for tables and views
+    automatically.
+
+    If this is set to true and you create a table or view with
+
+    * CREATE TABLE ...
+    * CREATE VIEW ...
+
+    and no version exists for it, the mechanism will create a version for
+    you automatically.
+
+.. _tracking3:
+.. config:option:: $cfg['Servers'][$i]['tracking_default_statements']
+
+    :type: string
+    :default: ``'CREATE TABLE,ALTER TABLE,DROP TABLE,RENAME TABLE,CREATE INDEX,DROP INDEX,INSERT,UPDATE,DELETE,TRUNCATE,REPLACE,CREATE VIEW,ALTER VIEW,DROP VIEW,CREATE DATABASE,ALTER DATABASE,DROP DATABASE'``
+
+    Defines the list of statements the auto-creation uses for new
+    versions. 
+
+.. _tracking4:
+.. config:option:: $cfg['Servers'][$i]['tracking_add_drop_view']
+
+    :type: boolean
+    :default: true
+
+    Whether a DROP VIEW IF EXISTS statement will be added as first line to
+    the log when creating a view.
+
+.. _tracking5:
+.. config:option:: $cfg['Servers'][$i]['tracking_add_drop_table']
+
+    :type: boolean
+    :default: true
+
+    Whether a DROP TABLE IF EXISTS statement will be added as first line
+    to the log when creating a table.
+
+.. _tracking6:
+.. config:option:: $cfg['Servers'][$i]['tracking_add_drop_database']
+
+    :type: boolean
+    :default: true
+
+    Whether a DROP DATABASE IF EXISTS statement will be added as first
+    line to the log when creating a database.
+
+.. _userconfig:
+.. config:option:: $cfg['Servers'][$i]['userconfig']
+
+    :type: string
+    :default: ``''``
+
+    Since release 3.4.x phpMyAdmin allows users to set most preferences by
+    themselves and store them in the database.
+
+    If you don't allow for storing preferences in
+    :config:option:`$cfg['Servers'][$i]['pmadb']`, users can still personalize
+    phpMyAdmin, but settings will be saved in browser's local storage, or, it
+    is is unavailable, until the end of session.  
+
+    To allow the usage of this functionality:
+
+    * set up :config:option:`$cfg['Servers'][$i]['pmadb']` and the phpMyAdmin configuration storage
+    * put the table name in :config:option:`$cfg['Servers'][$i]['userconfig']`
+
+
+
+.. _designer_coords:
+.. config:option:: $cfg['Servers'][$i]['designer_coords']
+
+    :type: string
+    :default: ``''``
+
+    Since release 2.10.0 a Designer interface is available; it permits to
+    visually manage the relations.  
+
+    To allow the usage of this functionality:
+
+    * set up :config:option:`$cfg['Servers'][$i]['pmadb']` and the phpMyAdmin configuration storage
+    * put the table name in :config:option:`$cfg['Servers'][$i]['designer\_coords']`
+      (e.g. ``pma__designer_coords``)
+
+
+
+.. config:option:: $cfg['Servers'][$i]['MaxTableUiprefs']
+
+    :type: integer
+    :default: 100
+
+    Maximum number of rows saved in
+    :config:option:`$cfg['Servers'][$i]['table_uiprefs']` table. 
+
+    When tables are dropped or renamed,
+    :config:option:`$cfg['Servers'][$i]['table_uiprefs']` may contain invalid data
+    (referring to tables which no longer exist). We only keep this number of newest
+    rows in :config:option:`$cfg['Servers'][$i]['table_uiprefs']` and automatically
+    delete older rows.
+
+.. config:option:: $cfg['Servers'][$i]['AllowRoot']
+
+    :type: boolean
+    :default: true
+
+    Whether to allow root access. This is just a shortcut for the
+    :config:option:`$cfg['Servers'][$i]['AllowDeny']['rules']` below.
+
+.. config:option:: $cfg['Servers'][$i]['AllowNoPassword']
+
+    :type: boolean
+    :default: false
+
+    Whether to allow logins without a password. The default value of
+    ``false`` for this parameter prevents unintended access to a MySQL
+    server with was left with an empty password for root or on which an
+    anonymous (blank) user is defined.
+
+.. _servers_allowdeny_order:
+.. config:option:: $cfg['Servers'][$i]['AllowDeny']['order']
+
+    :type: string
+    :default: ``''``
+
+    If your rule order is empty, then :term:`IP`
+    authorization is disabled. 
+
+    If your rule order is set to
+    ``'deny,allow'`` then the system applies all deny rules followed by
+    allow rules. Access is allowed by default. Any client which does not
+    match a Deny command or does match an Allow command will be allowed
+    access to the server. 
+
+    If your rule order is set to ``'allow,deny'``
+    then the system applies all allow rules followed by deny rules. Access
+    is denied by default. Any client which does not match an Allow
+    directive or does match a Deny directive will be denied access to the
+    server. 
+
+    If your rule order is set to ``'explicit'``, authorization is
+    performed in a similar fashion to rule order 'deny,allow', with the
+    added restriction that your host/username combination **must** be
+    listed in the *allow* rules, and not listed in the *deny* rules. This
+    is the **most** secure means of using Allow/Deny rules, and was
+    available in Apache by specifying allow and deny rules without setting
+    any order. 
+
+    Please also see :config:option:`$cfg['TrustedProxies']` for
+    detecting IP address behind proxies.
+
+.. _servers_allowdeny_rules:
+.. config:option:: $cfg['Servers'][$i]['AllowDeny']['rules']
+
+    :type: array of strings
+    :default: array()
+
+    The general format for the rules is as such:
+
+    .. code-block:: none
+        
+        <'allow' | 'deny'> <username> [from] <ipmask>
+
+    If you wish to match all users, it is possible to use a ``'%'`` as a
+    wildcard in the *username* field.
+
+    There are a few shortcuts you can
+    use in the *ipmask* field as well (please note that those containing
+    SERVER\_ADDRESS might not be available on all webservers):
+
+    .. code-block:: none
+
+        
+        'all' -> 0.0.0.0/0
+        'localhost' -> 127.0.0.1/8
+        'localnetA' -> SERVER_ADDRESS/8
+        'localnetB' -> SERVER_ADDRESS/16
+        'localnetC' -> SERVER_ADDRESS/24
+
+    Having an empty rule list is equivalent to either using ``'allow %
+    from all'`` if your rule order is set to ``'deny,allow'`` or ``'deny %
+    from all'`` if your rule order is set to ``'allow,deny'`` or
+    ``'explicit'``.
+
+    For the :term:`IP address` matching
+    system, the following work: 
+
+    * ``xxx.xxx.xxx.xxx`` (an exact :term:`IP address`) 
+    * ``xxx.xxx.xxx.[yyy-zzz]`` (an :term:`IP address` range) 
+    * ``xxx.xxx.xxx.xxx/nn`` (CIDR, Classless Inter-Domain Routing type :term:`IP` addresses) 
+
+    But the following does not work: 
+
+    * ``xxx.xxx.xxx.xx[yyy-zzz]`` (partial :term:`IP` address range) 
+
+    For :term:`IPv6` addresses, the following work:
+
+    * ``xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx`` (an exact :term:`IPv6` address)
+    * ``xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:[yyyy-zzzz]`` (an :term:`IPv6` address range)
+    * ``xxxx:xxxx:xxxx:xxxx/nn`` (CIDR, Classless Inter-Domain Routing type :term:`IPv6` addresses)
+
+    But the following does not work:
+
+    * ``xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xx[yyy-zzz]`` (partial :term:`IPv6` address range)
+
+.. config:option:: $cfg['Servers'][$i]['DisableIS']
+
+    :type: boolean
+    :default: true
+
+    Disable using ``INFORMATION_SCHEMA`` to retrieve information (use
+    ``SHOW`` commands instead), because of speed issues when many
+    databases are present. Currently used in some parts of the code, more
+    to come.
+
+.. config:option:: $cfg['Servers'][$i]['ShowDatabasesCommand']
+
+    :type: string
+    :default: ``'SHOW DATABASES'``
+
+    On a server with a huge number of databases, the default ``SHOW DATABASES``
+    command used to fetch the name of available databases will probably be too
+    slow, so it can be replaced by faster commands. You can use ``#user#``
+    string will be replaced by current user.
+
+    When using ``false``, it will disable fetching databases from the server,
+    only databases in :config:option:`$cfg['Servers'][$i]['only_db']` will be
+    displayed.
+    
+    Examples:
+
+    * ``'SHOW DATABASES'``
+    * ``"SHOW DATABASES LIKE '#user#\_%'"``
+    * ``'SELECT DISTINCT TABLE_SCHEMA FROM information_schema.SCHEMA_PRIVILEGES'``
+    * ``'SELECT SCHEMA_NAME FROM information_schema.SCHEMATA'``
+    * ``false``
+
+.. config:option:: $cfg['Servers'][$i]['SignonScript']
+
+    :type: string
+    :default: ``''``
+
+    Name of PHP script to be sourced and executed to obtain login
+    credentials. This is alternative approach to session based single
+    signon. The script needs to provide function
+    ``get_login_credentials`` which returns list of username and
+    password, accepting single parameter of existing username (can be
+    empty). See :file:`examples/signon-script.php` for an example.
+
+.. config:option:: $cfg['Servers'][$i]['SignonSession']
+
+    :type: string
+    :default: ``''``
+
+    Name of session which will be used for signon authentication method.
+    You should use something different than ``phpMyAdmin``, because this
+    is session which phpMyAdmin uses internally. Takes effect only if 
+    :config:option:`$cfg['Servers'][$i]['SignonScript']` is not configured.
+
+.. config:option:: $cfg['Servers'][$i]['SignonURL']
+
+    :type: string
+    :default: ``''``
+
+    :term:`URL` where user will be redirected
+    to log in for signon authentication method. Should be absolute
+    including protocol.
+
+.. config:option:: $cfg['Servers'][$i]['LogoutURL']
+
+    :type: string
+    :default: ``''``
+
+    :term:`URL` where user will be redirected
+    after logout (doesn't affect config authentication method). Should be
+    absolute including protocol.
+
+.. config:option:: $cfg['Servers'][$i]['StatusCacheDatabases']
+
+    :type: array of strings
+    :default: array()
+
+    Enables caching of ``TABLE STATUS`` outputs for specific databases on
+    this server (in some cases ``TABLE STATUS`` can be very slow, so you
+    may want to cache it). APC is used (if the PHP extension is available,
+    if not, this setting is ignored silently). You have to provide 
+    :config:option:`$cfg['Servers'][$i]['StatusCacheLifetime']`. 
+    
+    Takes effect only if :config:option:`$cfg['Servers'][$i]['DisableIS']` is
+    ``true``.
+
+.. config:option:: $cfg['Servers'][$i]['StatusCacheLifetime']
+
+    :type: integer
+    :default: 0
+
+    Lifetime in seconds of the ``TABLE STATUS`` cache if 
+    :config:option:`$cfg['Servers'][$i]['StatusCacheDatabases']` is used.
+
+Generic settings
+----------------
+
+.. config:option:: $cfg['ServerDefault']
+
+    :type: integer
+    :default: 1
+
+    If you have more than one server configured, you can set
+    :config:option:`$cfg['ServerDefault']` to any one of them to autoconnect to that
+    server when phpMyAdmin is started, or set it to 0 to be given a list
+    of servers without logging in. 
+    
+    If you have only one server configured,
+    :config:option:`$cfg['ServerDefault']` MUST be set to that server.
+
+.. config:option:: $cfg['VersionCheck']
+
+    :type: boolean
+    :default: true
+
+    Enables check for latest versions using javascript on main phpMyAdmin
+    page.
+
+    .. note::
+
+        This setting can be adjusted by your vendor.
+
+.. config:option:: $cfg['MaxDbList']
+
+    :type: integer
+    :default: 100
+
+    The maximum number of database names to be displayed in the main panel's
+    database list.
+
+.. config:option:: $cfg['MaxNavigationItems']
+
+    :type: integer
+    :default: 25
+
+    The number of items that can be displayed on each page of the
+    navigation tree.
+
+.. config:option:: $cfg['MaxTableList']
+
+    :type: integer
+    :default: 250
+
+    The maximum number of table names to be displayed in the main panel's
+    list (except on the Export page). This limit is also enforced in the
+    navigation panel when in Light mode.
+
+.. config:option:: $cfg['ShowHint']
+
+    :type: boolean
+    :default: true
+
+    Whether or not to show hints (for example, hints when hovering over
+    table headers).
+
+.. config:option:: $cfg['MaxCharactersInDisplayedSQL']
+
+    :type: integer
+    :default: 1000
+
+    The maximum number of characters when a :term:`SQL` query is displayed. The
+    default limit of 1000 should be correct to avoid the display of tons of
+    hexadecimal codes that represent BLOBs, but some users have real
+    :term:`SQL` queries that are longer than 1000 characters. Also, if a
+    query's length exceeds this limit, this query is not saved in the history.
+
+.. config:option:: $cfg['PersistentConnections']
+
+    :type: boolean
+    :default: false
+
+    Whether `persistent connections <http://php.net/manual/en/features
+    .persistent-connections.php>`_ should be used or not. Works with
+    following extensions:
+
+    * mysql (`mysql\_pconnect <http://php.net/manual/en/function.mysql-
+      pconnect.php>`_),
+    * mysqli (requires PHP 5.3.0 or newer, `more information
+      <http://php.net/manual/en/mysqli.persistconns.php>`_).
+
+.. config:option:: $cfg['ForceSSL']
+
+    :type: boolean
+    :default: false
+
+    Whether to force using https while accessing phpMyAdmin.
+
+.. config:option:: $cfg['ExecTimeLimit']
+
+    :type: integer [number of seconds]
+    :default: 300
+
+    Set the number of seconds a script is allowed to run. If seconds is
+    set to zero, no time limit is imposed. This setting is used while
+    importing/exporting dump files but has
+    no effect when PHP is running in safe mode.
+
+.. config:option:: $cfg['SessionSavePath']
+
+    :type: string
+    :default: ``''``
+
+    Path for storing session data (`session\_save\_path PHP parameter
+    <http://php.net/session_save_path>`_).
+
+.. config:option:: $cfg['MemoryLimit']
+
+    :type: string [number of bytes]
+    :default: ``'0'``
+
+    Set the number of bytes a script is allowed to allocate. If set to
+    zero, no limit is imposed. 
+    
+    This setting is used while importing/exporting dump files and at some other
+    places in phpMyAdmin so you definitely don't want to put here a too low
+    value. It has no effect when PHP is running in safe mode. 
+    
+    You can also use any string as in :file:`php.ini`, eg. '16M'. Ensure you
+    don't omit the suffix (16 means 16 bytes!)
+
+.. config:option:: $cfg['SkipLockedTables']
+
+    :type: boolean
+    :default: false
+
+    Mark used tables and make it possible to show databases with locked
+    tables (since MySQL 3.23.30).
+
+.. config:option:: $cfg['ShowSQL']
+
+    :type: boolean
+    :default: true
+
+    Defines whether :term:`SQL` queries
+    generated by phpMyAdmin should be displayed or not.
+
+.. config:option:: $cfg['RetainQueryBox']
+
+    :type: boolean
+    :default: false
+
+    Defines whether the :term:`SQL` query box
+    should be kept displayed after its submission.
+
+.. config:option:: $cfg['CodemirrorEnable']
+
+    :type: boolean
+    :default: true
+
+    Defines whether to use a Javascript code editor for SQL query boxes.
+    CodeMirror provides syntax highlighting and line numbers.  However,
+    middle-clicking for pasting the clipboard contents in some Linux
+    distributions (such as Ubuntu) is not supported by all browsers.
+
+.. config:option:: $cfg['AllowUserDropDatabase']
+
+    :type: boolean
+    :default: false
+
+    Defines whether normal users (non-administrator) are allowed to delete
+    their own database or not. If set as false, the link :guilabel:`Drop
+    Database` will not be shown, and even a ``DROP DATABASE mydatabase`` will
+    be rejected. Quite practical for :term:`ISP` 's with many customers. 
+
+    .. note:: 
+       
+        This limitation of :term:`SQL` queries is not
+        as strict as when using MySQL privileges. This is due to nature of
+        :term:`SQL` queries which might be quite
+        complicated.  So this choice should be viewed as help to avoid accidental
+        dropping rather than strict privilege limitation.
+
+.. config:option:: $cfg['Confirm']
+
+    :type: boolean
+    :default: true
+
+    Whether a warning ("Are your really sure...") should be displayed when
+    you're about to lose data.
+
+.. config:option:: $cfg['UseDbSearch']
+
+    :type: boolean
+    :default: true
+
+    Define whether the "search string inside database" is enabled or not.
+
+.. config:option:: $cfg['IgnoreMultiSubmitErrors']
+
+    :type: boolean
+    :default: false
+
+    Define whether phpMyAdmin will continue executing a multi-query
+    statement if one of the queries fails. Default is to abort execution.
+
+Cookie authentication options
+-----------------------------
+
+.. config:option:: $cfg['blowfish_secret']
+
+    :type: string
+    :default: ``''``
+
+    The "cookie" auth\_type uses blowfish algorithm to encrypt the
+    password. If you are using the "cookie" auth\_type, enter here a
+    random passphrase of your choice. It will be used internally by the
+    blowfish algorithm: you won’t be prompted for this passphrase. There
+    is no maximum length for this secret. 
+
+    .. versionchanged:: 3.1.0
+        Since version 3.1.0 phpMyAdmin can generate this on the fly, but it
+        makes a bit weaker security as this generated secret is stored in
+        session and furthermore it makes impossible to recall user name from
+        cookie.
+
+.. config:option:: $cfg['LoginCookieRecall']
+
+    :type: boolean
+    :default: true
+
+    Define whether the previous login should be recalled or not in cookie
+    authentication mode. 
+    
+    This is automatically disabled if you do not have
+    configured :config:option:`$cfg['blowfish_secret']`.
+
+.. config:option:: $cfg['LoginCookieValidity']
+
+    :type: integer [number of seconds]
+    :default: 1440
+
+    Define how long a login cookie is valid. Please note that php
+    configuration option `session.gc\_maxlifetime
+    <http://php.net/manual/en/session.configuration.php#ini.session.gc-
+    maxlifetime>`_ might limit session validity and if the session is lost,
+    the login cookie is also invalidated. So it is a good idea to set
+    ``session.gc_maxlifetime`` at least to the same value of
+    :config:option:`$cfg['LoginCookieValidity']`.
+
+.. config:option:: $cfg['LoginCookieStore']
+
+    :type: integer [number of seconds]
+    :default: 0
+
+    Define how long login cookie should be stored in browser. Default 0
+    means that it will be kept for existing session. This is recommended
+    for not trusted environments.
+
+.. config:option:: $cfg['LoginCookieDeleteAll']
+
+    :type: boolean
+    :default: true
+
+    If enabled (default), logout deletes cookies for all servers,
+    otherwise only for current one. Setting this to false makes it easy to
+    forget to log out from other server, when you are using more of them.
+
+.. _AllowArbitraryServer:
+.. config:option:: $cfg['AllowArbitraryServer']
+
+    :type: boolean
+    :default: false
+
+    If enabled, allows you to log in to arbitrary servers using cookie
+    authentication.
+
+    .. note::
+       
+        Please use this carefully, as this may allow users access to MySQL servers
+        behind the firewall where your :term:`HTTP`
+        server is placed.
+
+Navigation panel setup
+----------------------
+
+.. config:option:: $cfg['NavigationTreeEnableGrouping']
+
+    :type: boolean
+    :default: true
+
+    Defines whether to group the databases based on a common prefix
+    in their name :config:option:`$cfg['NavigationTreeDbSeparator']`.
+
+.. config:option:: $cfg['NavigationTreeDbSeparator']
+
+    :type: string or array
+    :default: ``'_'``
+
+    The string used to separate the parts of the database name when
+    showing them in a tree. Alternatively you can specify more strings in
+    an array and all of them will be used as a separator.
+
+.. config:option:: $cfg['NavigationTreeTableSeparator']
+
+    :type: string or array
+    :default: ``'__'``
+
+    Defines a string to be used to nest table spaces. This means if you have
+    tables like ``first__second__third`` this will be shown as a three-level
+    hierarchy like: first > second > third.  If set to false or empty, the
+    feature is disabled. NOTE: You should not use this separator at the
+    beginning or end of a table name or multiple times after another without
+    any other characters in between.
+
+.. config:option:: $cfg['NavigationTreeTableLevel']
+
+    :type: integer
+    :default: 1
+
+    Defines how many sublevels should be displayed when splitting up
+    tables by the above separator.
+
+.. config:option:: $cfg['NumRecentTables']
+
+    :type: integer
+    :default: 10
+
+    The maximum number of recently used tables shown in the navigation
+    panel. Set this to 0 (zero) to disable the listing of recent tables.
+
+.. config:option:: $cfg['ShowTooltip']
+
+    :type: boolean
+    :default: true
+
+    Defines whether to display item comments as tooltips in navigation
+    panel or not.
+
+.. config:option:: $cfg['NavigationDisplayLogo']
+
+    :type: boolean
+    :default: true
+
+    Defines whether or not to display the phpMyAdmin logo at the top of
+    the navigation panel.
+
+.. config:option:: $cfg['NavigationLogoLink']
+
+    :type: string
+    :default: ``'index.php'``
+
+    Enter :term:`URL` where logo in the
+    navigation panel will point to. For use especially with self made
+    theme which changes this.
+
+.. config:option:: $cfg['NavigationLogoLinkWindow']
+
+    :type: string
+    :default: ``'main'``
+
+    Whether to open the linked page in the main window (``main``) or in a
+    new one (``new``). Note: use ``new`` if you are linking to
+    ``phpmyadmin.net``.
+
+.. config:option:: $cfg['NavigationTreeDisplayItemFilterMinimum']
+
+    :type: integer
+    :default: 30
+
+    Defines the minimum number of items (tables, views, routines and
+    events) to display a JavaScript filter box above the list of items in
+    the navigation tree. 
+    
+    To disable the filter completely some high number can be used (e.g. 9999)
+
+.. config:option:: $cfg['NavigationTreeDisplayDbFilterMinimum']
+
+    :type: integer
+    :default: 30
+
+    Defines the minimum number of databases to display a JavaScript filter
+    box above the list of databases in the navigation tree.
+    
+    To disable the filter completely some high number can be used
+    (e.g. 9999)
+
+.. config:option:: $cfg['NavigationDisplayServers']
+
+    :type: boolean
+    :default: true 
+
+    Defines whether or not to display a server choice at the top of the
+    navigation panel.
+
+.. config:option:: $cfg['DisplayServersList']
+
+    :type: boolean
+    :default: false
+
+    Defines whether to display this server choice as links instead of in a
+    drop-down.
+
+.. config:option:: $cfg['NavigationTreeDefaultTabTable']
+
+    :type: string
+    :default: ``'tbl_structure.php'``
+
+    Defines the tab displayed by default when clicking the small icon next
+    to each table name in the navigation panel. Possible values:
+
+    * ``tbl_structure.php``
+    * ``tbl_sql.php``
+    * ``tbl_select.php``
+    * ``tbl_change.php``
+    * ``sql.php``
+
+Main panel
+----------
+
+.. config:option:: $cfg['ShowStats']
+
+    :type: boolean
+    :default: true
+
+    Defines whether or not to display space usage and statistics about
+    databases and tables. Note that statistics requires at least MySQL
+    3.23.3 and that, at this date, MySQL doesn't return such information
+    for Berkeley DB tables.
+
+.. config:option:: $cfg['ShowServerInfo']
+
+    :type: boolean
+    :default: true
+
+    Defines whether to display detailed server information on main page.
+    You can additionally hide more information by using 
+    :config:option:`$cfg['Servers'][$i]['verbose']`.
+
+.. config:option:: $cfg['ShowPhpInfo']
+
+    :type: boolean
+    :default: false
+
+.. config:option:: $cfg['ShowChgPassword']
+
+    :type: boolean
+    :default: true
+
+.. config:option:: $cfg['ShowCreateDb']
+
+    :type: boolean
+    :default: true
+
+    Defines whether to display the :guilabel:`PHP information` and
+    :guilabel:`Change password` links and form for creating database or not at
+    the starting main (right) frame. This setting does not check MySQL commands
+    entered directly. 
+    
+    Please note that to block the usage of ``phpinfo()`` in scripts, you have to
+    put this in your :file:`php.ini`:
+
+    .. code-block:: ini
+
+        disable_functions = phpinfo()
+
+    Also note that enabling the :guilabel:`Change password` link has no effect
+    with config authentication mode: because of the hard coded password value
+    in the configuration file, end users can't be allowed to change their
+    passwords.
+
+Database structure
+------------------
+
+.. config:option:: $cfg['ShowDbStructureCreation']
+
+    :type: boolean
+    :default: false
+
+    Defines whether the database structure page (tables list) has a
+    "Creation" column that displays when each table was created.
+
+.. config:option:: $cfg['ShowDbStructureLastUpdate']
+
+    :type: boolean
+    :default: false
+
+    Defines whether the database structure page (tables list) has a "Last
+    update" column that displays when each table was last updated.
+
+.. config:option:: $cfg['ShowDbStructureLastCheck']
+
+    :type: boolean
+    :default: false
+
+    Defines whether the database structure page (tables list) has a "Last
+    check" column that displays when each table was last checked.
+
+.. config:option:: $cfg['HideStructureActions']
+
+    :type: boolean
+    :default: true
+
+    Defines whether the table structure actions are hidden under a "More"
+    drop-down.
+
+Browse mode
+-----------
+
+.. config:option:: $cfg['NavigationBarIconic']
+
+    :type: string
+    :default: true
+
+    Defines whether navigation bar buttons contain text or symbols only. A 
+    value of true displays icons, false displays text and 'both' displays 
+    both icons and text.
+
+.. config:option:: $cfg['ShowAll']
+
+    :type: boolean
+    :default: false
+
+    Defines whether a user should be displayed a "Show all" button in
+    browse mode or not in all cases. By default it is shown only on small
+    tables (less than 5 × :config:option:`$cfg['MaxRows']` rows) to avoid
+    performance issues while getting too many rows.
+
+.. config:option:: $cfg['MaxRows']
+
+    :type: integer
+    :default: 30
+
+    Number of rows displayed when browsing a result set and no LIMIT
+    clause is used. If the result set contains more rows, "Previous" and
+    "Next" links will be shown.
+
+.. config:option:: $cfg['Order']
+
+    :type: string
+    :default: ``'SMART'``
+
+    Defines whether columns are displayed in ascending (``ASC``) order, in
+    descending (``DESC``) order or in a "smart" (``SMART``) order - I.E.
+    descending order for columns of type TIME, DATE, DATETIME and
+    TIMESTAMP, ascending order else- by default.
+
+.. config:option:: $cfg['DisplayBinaryAsHex']
+
+    :type: boolean
+    :default: true
+
+    Defines whether the "Show binary contents as HEX" browse option is
+    ticked by default.
+
+.. config:option:: $cfg['GridEditing']
+
+    :type: string
+    :default: ``'double-click'``
+
+    Defines which action (``double-click`` or ``click``) triggers grid
+    editing. Can be deactived with the ``disabled`` value.
+
+.. config:option:: $cfg['SaveCellsAtOnce']
+
+    :type: boolean
+    :default: false
+
+    Defines whether or not to save all edited cells at once for grid
+    editing.
+
+Editing mode
+------------
+
+.. config:option:: $cfg['ProtectBinary']
+
+    :type: boolean or string
+    :default: ``'blob'``
+
+    Defines whether ``BLOB`` or ``BINARY`` columns are protected from
+    editing when browsing a table's content. Valid values are:
+
+    * ``false`` to allow editing of all columns;
+    * ``'blob'`` to allow editing of all columns except ``BLOBS``;
+    * ``'noblob'`` to disallow editing of all columns except ``BLOBS`` (the
+      opposite of ``'blob'``);
+    * ``'all'`` to disallow editing of all ``BINARY`` or ``BLOB`` columns.
+
+.. config:option:: $cfg['ShowFunctionFields']
+
+    :type: boolean
+    :default: true
+
+    Defines whether or not MySQL functions fields should be initially
+    displayed in edit/insert mode. Since version 2.10, the user can toggle
+    this setting from the interface.
+
+.. config:option:: $cfg['ShowFieldTypesInDataEditView']
+
+    :type: boolean
+    :default: true
+
+    Defines whether or not type fields should be initially displayed in
+    edit/insert mode. The user can toggle this setting from the interface.
+
+.. config:option:: $cfg['InsertRows']
+
+    :type: integer
+    :default: 2
+
+    Defines the maximum number of concurrent entries for the Insert page.
+
+.. config:option:: $cfg['ForeignKeyMaxLimit']
+
+    :type: integer
+    :default: 100
+
+    If there are fewer items than this in the set of foreign keys, then a
+    drop-down box of foreign keys is presented, in the style described by
+    the :config:option:`$cfg['ForeignKeyDropdownOrder']` setting.
+
+.. config:option:: $cfg['ForeignKeyDropdownOrder']
+
+    :type: array
+    :default: array('content-id', 'id-content')
+
+    For the foreign key drop-down fields, there are several methods of
+    display, offering both the key and value data. The contents of the
+    array should be one or both of the following strings: ``content-id``,
+    ``id-content``.
+
+Export and import settings
+--------------------------
+
+.. config:option:: $cfg['ZipDump']
+
+    :type: boolean
+    :default: true
+
+.. config:option:: $cfg['GZipDump']
+
+    :type: boolean
+    :default: true
+
+.. config:option:: $cfg['BZipDump']
+
+    :type: boolean
+    :default: true
+
+    Defines whether to allow the use of zip/GZip/BZip2 compression when
+    creating a dump file
+
+.. config:option:: $cfg['CompressOnFly']
+
+    :type: boolean
+    :default: true
+
+    Defines whether to allow on the fly compression for GZip/BZip2
+    compressed exports. This doesn't affect smaller dumps and allows users
+    to create larger dumps that won't otherwise fit in memory due to php
+    memory limit. Produced files contain more GZip/BZip2 headers, but all
+    normal programs handle this correctly.
+
+.. config:option:: $cfg['Export']
+
+    :type: array
+    :default: array(...)
+
+    In this array are defined default parameters for export, names of
+    items are similar to texts seen on export page, so you can easily
+    identify what they mean.
+
+.. config:option:: $cfg['Export']['method']
+
+    :type: string
+    :default: ``'quick'``
+
+    Defines how the export form is displayed when it loads. Valid values
+    are:
+
+    * ``quick`` to display the minimum number of options to configure
+    * ``custom`` to display every available option to configure
+    * ``custom-no-form`` same as ``custom`` but does not display the option
+      of using quick export
+
+
+
+.. config:option:: $cfg['Import']
+
+    :type: array
+    :default: array(...)
+
+    In this array are defined default parameters for import, names of
+    items are similar to texts seen on import page, so you can easily
+    identify what they mean.
+
+
+Tabs display settings
+---------------------
+
+.. config:option:: $cfg['PropertiesIconic']
+
+    :type: string
+    :default: ``'both'``
+
+    If set to ``true``, will display icons instead of text for db and table
+    properties links (like :guilabel:`Browse`, :guilabel:`Select`,
+    :guilabel:`Insert`, ...) and for the menu tabs. Can be set to ``'both'`` 
+    if you want icons AND text. When set to ``false``, will only show text.
+
+.. config:option:: $cfg['PropertiesNumColumns']
+
+    :type: integer
+    :default: 1
+
+    How many columns will be utilized to display the tables on the database
+    property view? When setting this to a value larger than 1, the type of the
+    database will be omitted for more display space.
+
+.. config:option:: $cfg['DefaultTabServer']
+
+    :type: string
+    :default: ``'index.php'``
+
+    Defines the tab displayed by default on server view. Possible values:
+
+    * ``main.php`` (recommended for multi-user setups)
+    * ``server_databases.php``,
+    * ``server_status.php``
+    * ``server_variables.php``
+    * ``server_privileges.php``
+
+.. config:option:: $cfg['DefaultTabDatabase']
+
+    :type: string
+    :default: ``'db_structure.php'``
+
+    Defines the tab displayed by default on database view. Possible
+    values: 
+    
+    * ``db_structure.php``
+    * ``db_sql.php`` 
+    * ``db_search.php``.
+
+.. config:option:: $cfg['DefaultTabTable']
+
+    :type: string
+    :default: ``'sql.php'``
+
+    Defines the tab displayed by default on table view. Possible values:
+
+    * ``tbl_structure.php``
+    * ``tbl_sql.php``
+    * ``tbl_select.php``
+    * ``tbl_change.php`` 
+    * ``sql.php``
+
+Documentation
+-------------
+
+.. config:option:: $cfg['MySQLManualBase']
+
+    :type: string
+    :default: ``'http://dev.mysql.com/doc/refman'``
+
+    If set to an :term:`URL` which points to
+    the MySQL documentation (type depends on
+    :config:option:`$cfg['MySQLManualType']`), appropriate help links are
+    generated. 
+
+    See `MySQL Documentation page <http://dev.mysql.com/doc/>`_ for more
+    information about MySQL manuals and their types.
+
+.. config:option:: $cfg['MySQLManualType']
+
+    :type: string
+    :default: ``'viewable'``
+
+    Type of MySQL documentation:
+
+    * viewable - "viewable online", current one used on MySQL website
+    * searchable - "Searchable, with user comments"
+    * chapters - "HTML, one page per chapter"
+    * big - "HTML, all on one page"
+    * none - do not show documentation links
+
+Languages
+---------
+
+.. config:option:: $cfg['DefaultLang']
+
+    :type: string
+    :default: ``'en'``
+
+    Defines the default language to use, if not browser-defined or user-
+    defined. The corresponding language file needs to be in
+    locale/*code*/LC\_MESSAGES/phpmyadmin.mo.
+
+.. config:option:: $cfg['DefaultConnectionCollation']
+
+    :type: string
+    :default: ``'utf8_general_ci'``
+
+    Defines the default connection collation to use, if not user-defined.
+    See the `MySQL documentation <http://dev.mysql.com/doc/mysql/en
+    /charset-charsets.html>`_ for list of possible values. This setting is
+    ignored when connected to Drizzle server.
+
+.. config:option:: $cfg['Lang']
+
+    :type: string
+    :default: not set
+
+    Force language to use. The corresponding language file needs to be in
+    locale/*code*/LC\_MESSAGES/phpmyadmin.mo.
+
+.. config:option:: $cfg['FilterLanguages']
+
+    :type: string
+    :default: ``''``
+
+    Limit list of available languages to those matching the given regular
+    expression. For example if you want only Czech and English, you should
+    set filter to ``'^(cs|en)'``.
+
+.. config:option:: $cfg['RecodingEngine']
+
+    :type: string
+    :default: ``'auto'``
+
+    You can select here which functions will be used for character set
+    conversion. Possible values are:
+
+    * auto - automatically use available one (first is tested iconv, then
+      recode)
+    * iconv - use iconv or libiconv functions
+    * recode - use recode\_string function
+    * none - disable encoding conversion
+
+    Enabled charset conversion activates a pull-down menu in the Export
+    and Import pages, to choose the character set when exporting a file.
+    The default value in this menu comes from
+    :config:option:`$cfg['Export']['charset']` and :config:option:`$cfg['Import']['charset']`.
+
+.. config:option:: $cfg['IconvExtraParams']
+
+    :type: string
+    :default: ``'//TRANSLIT'``
+
+    Specify some parameters for iconv used in charset conversion. See
+    `iconv documentation <http://www.gnu.org/software/libiconv/documentati
+    on/libiconv/iconv_open.3.html>`_ for details. By default
+    ``//TRANSLIT`` is used, so that invalid characters will be
+    transliterated.
+
+.. config:option:: $cfg['AvailableCharsets']
+
+    :type: array
+    :default: array(..._
+
+    Available character sets for MySQL conversion. You can add your own
+    (any of supported by recode/iconv) or remove these which you don't
+    use. Character sets will be shown in same order as here listed, so if
+    you frequently use some of these move them to the top.
+
+Web server settings
+-------------------
+
+.. config:option:: $cfg['OBGzip']
+
+    :type: string/boolean
+    :default: ``'auto'``
+
+    Defines whether to use GZip output buffering for increased speed in
+    :term:`HTTP` transfers. Set to
+    true/false for enabling/disabling. When set to 'auto' (string),
+    phpMyAdmin tries to enable output buffering and will automatically
+    disable it if your browser has some problems with buffering. IE6 with
+    a certain patch is known to cause data corruption when having enabled
+    buffering.
+
+.. config:option:: $cfg['TrustedProxies']
+
+    :type: array
+    :default: array()
+
+    Lists proxies and HTTP headers which are trusted for 
+    :config:option:`$cfg['Servers'][$i]['AllowDeny']['order']`. This list is by
+    default empty, you need to fill in some trusted proxy servers if you
+    want to use rules for IP addresses behind proxy. 
+
+    The following example specifies that phpMyAdmin should trust a
+    HTTP\_X\_FORWARDED\_FOR (``X -Forwarded-For``) header coming from the proxy
+    1.2.3.4:
+
+    .. code-block:: php
+        
+        $cfg['TrustedProxies'] = array('1.2.3.4' => 'HTTP_X_FORWARDED_FOR');
+
+    The :config:option:`$cfg['Servers'][$i]['AllowDeny']['rules']` directive uses the
+    client's IP address as usual.
+
+.. config:option:: $cfg['GD2Available']
+
+    :type: string
+    :default: ``'auto'``
+
+    Specifies whether GD >= 2 is available. If yes it can be used for MIME
+    transformations. Possible values are:
+
+    * auto - automatically detect
+    * yes - GD 2 functions can be used
+    * no - GD 2 function cannot be used
+
+.. config:option:: $cfg['CheckConfigurationPermissions']
+
+    :type: boolean
+    :default: true
+
+    We normally check the permissions on the configuration file to ensure
+    it's not world writable. However, phpMyAdmin could be installed on a
+    NTFS filesystem mounted on a non-Windows server, in which case the
+    permissions seems wrong but in fact cannot be detected. In this case a
+    sysadmin would set this parameter to ``false``.
+
+.. config:option:: $cfg['LinkLengthLimit']
+
+    :type: integer
+    :default: 1000
+
+    Limit for length of :term:`URL` in links.  When length would be above this
+    limit, it is replaced by form with button. This is required as some web
+    servers (:term:`IIS`) have problems with long :term:`URL` .
+ 
+.. config:option:: $cfg['CSPAllow']
+
+    :type: string
+    :default: ``''``
+
+    Additional string to include in allowed script sources in Content Security
+    Policy header.
+
+    This can be useful when you want to include some external javascript files
+    in :file:`config.footer.inc.php` or :file:`config.header.inc.php`, which
+    would be normally not allowed by Content Security Policy.
+
+.. config:option:: $cfg['DisableMultiTableMaintenance']
+
+    :type: boolean
+    :default: false
+
+    In the database Structure page, it's possible to mark some tables then
+    choose an operation like optimizing for many tables. This can slow
+    down a server; therefore, setting this to ``true`` prevents this kind
+    of multiple maintenance operation.
+
+Theme settings
+--------------
+
+.. config:option:: $cfg['NaviWidth']
+
+    :type: integer
+    :default:
+
+    Navigation panel width in pixels. See
+    :file:`themes/themename/layout.inc.php`.
+
+.. config:option:: $cfg['NaviBackground']
+
+    :type: string [CSS color for background]
+    :default:
+
+.. config:option:: $cfg['MainBackground']
+
+    :type: string [CSS color for background]
+    :default:
+
+    The background styles used for both the frames. See
+    :file:`themes/themename/layout.inc.php`.
+
+.. config:option:: $cfg['NaviPointerBackground']
+
+    :type: string [CSS color for background]
+    :default:
+
+.. config:option:: $cfg['NaviPointerColor']
+
+    :type: string [CSS color]
+    :default:
+
+    The style used for the pointer in the navi frame. See
+    :file:`themes/themename/layout.inc.php`.
+
+.. config:option:: $cfg['Border']
+
+    :type: integer
+    :default:
+
+    The size of a table's border. See :file:`themes/themename/layout.inc.php`.
+
+.. config:option:: $cfg['ThBackground']
+
+    :type: string [CSS color for background]
+    :default:
+
+.. config:option:: $cfg['ThColor']
+
+    :type: string [CSS color]
+    :default:
+
+    The style used for table headers. See
+    :file:`themes/themename/layout.inc.php`.
+
+.. _cfg_BgcolorOne:
+.. config:option:: $cfg['BgOne']
+
+    :type: string [CSS color]
+    :default:
+
+    The color (HTML) #1 for table rows. See
+    :file:`themes/themename/layout.inc.php`.
+
+.. _cfg_BgcolorTwo:
+.. config:option:: $cfg['BgTwo']
+
+    :type: string [CSS color]
+    :default:
+
+    The color (HTML) #2 for table rows. See
+    :file:`themes/themename/layout.inc.php`.
+
+.. config:option:: $cfg['BrowsePointerBackground']
+
+    :type: string [CSS color]
+    :default:
+
+.. config:option:: $cfg['BrowsePointerColor']
+
+    :type: string [CSS color]
+    :default:
+
+.. config:option:: $cfg['BrowseMarkerBackground']
+
+    :type: string [CSS color]
+    :default:
+
+.. config:option:: $cfg['BrowseMarkerColor']
+
+    :type: string [CSS color]
+    :default:
+
+    The colors (HTML) uses for the pointer and the marker in browse mode.
+    The former feature highlights the row over which your mouse is passing
+    and the latter lets you visually mark/unmark rows by clicking on the
+    corresponding checkbox. Highlighting / marking a column is done by
+    hovering over / clicking the column's header (outside of the text).
+    See :file:`themes/themename/layout.inc.php`.
+
+.. config:option:: $cfg['FontFamily']
+
+    :type: string
+    :default:
+
+    You put here a valid CSS font family value, for example ``arial, sans-
+    serif``. See :file:`themes/themename/layout.inc.php`.
+
+.. config:option:: $cfg['FontFamilyFixed']
+
+    :type: string
+    :default:
+
+    You put here a valid CSS font family value, for example ``monospace``.
+    This one is used in textarea. See :file:`themes/themename/layout.inc.php`.
+
+Design customization
+--------------------
+
+.. config:option:: $cfg['NavigationTreePointerEnable']
+
+    :type: boolean
+    :default: true
+
+    A value of ``true`` activates the navi pointer.
+
+.. config:option:: $cfg['BrowsePointerEnable']
+
+    :type: boolean
+    :default: true
+
+    Whether to activate the browse pointer or not.
+
+.. config:option:: $cfg['BrowseMarkerEnable']
+
+    :type: boolean
+    :default: true
+
+    Whether to activate the browse marker or not.
+
+.. config:option:: $cfg['LimitChars']
+
+    :type: integer
+    :default: 50
+
+    Maximum number of characters shown in any non-numeric field on browse
+    view. Can be turned off by a toggle button on the browse page.
+
+.. config:option:: $cfg['RowActionLinks']
+
+    :type: string
+    :default: ``'left'``
+
+    Defines the place where table row links (Edit, Copy, Delete) would be
+    put when tables contents are displayed (you may have them displayed at
+    the left side, right side, both sides or nowhere). "left" and "right"
+    are parsed as "top" and "bottom" with vertical display mode.
+
+.. config:option:: $cfg['DefaultDisplay']
+
+    :type: string
+    :default: ``'horizonta'``
+
+    There are 3 display modes: horizontal, horizontalflipped and vertical.
+    Define which one is displayed by default. The first mode displays each
+    row on a horizontal line, the second rotates the headers by 90
+    degrees, so you can use descriptive headers even though columns only
+    contain small values and still print them out. The vertical mode sorts
+    each row on a vertical lineup.
+
+.. config:option:: $cfg['RememberSorting']
+
+    :type: boolean
+    :default: true
+
+    If enabled, remember the sorting of each table when browsing them.
+
+.. config:option:: $cfg['HeaderFlipType']
+
+    :type: string
+    :default: ``'auto'``
+
+    The HeaderFlipType can be set to 'auto', 'css' or 'fake'. When using
+    'css' the rotation of the header for horizontalflipped is done via
+    CSS. The CSS transformation currently works only in Internet
+    Explorer.If set to 'fake' PHP does the transformation for you, but of
+    course this does not look as good as CSS. The 'auto' option enables
+    CSS transformation when browser supports it and use PHP based one
+    otherwise.
+
+.. config:option:: $cfg['ShowBrowseComments']
+
+    :type: boolean
+    :default: true
+
+.. config:option:: $cfg['ShowPropertyComments']
+
+    :type: boolean
+    :default: true
+
+    By setting the corresponding variable to ``true`` you can enable the
+    display of column comments in Browse or Property display. In browse
+    mode, the comments are shown inside the header. In property mode,
+    comments are displayed using a CSS-formatted dashed-line below the
+    name of the column. The comment is shown as a tool-tip for that
+    column.
+
+Text fields
+-----------
+
+.. config:option:: $cfg['CharEditing']
+
+    :type: string
+    :default: ``'input'``
+
+    Defines which type of editing controls should be used for CHAR and
+    VARCHAR columns. Possible values are:
+
+    * input - this allows to limit size of text to size of columns in MySQL,
+      but has problems with newlines in columns
+    * textarea - no problems with newlines in columns, but also no length
+      limitations
+
+.. config:option:: $cfg['MinSizeForInputField']
+
+    :type: integer
+    :default: 4
+
+    Defines the minimum size for input fields generated for CHAR and
+    VARCHAR columns.
+
+.. config:option:: $cfg['MaxSizeForInputField']
+
+    :type: integer
+    :default: 60
+
+    Defines the maximum size for input fields generated for CHAR and
+    VARCHAR columns.
+
+.. config:option:: $cfg['TextareaCols']
+
+    :type: integer
+    :default: 40
+
+.. config:option:: $cfg['TextareaRows']
+
+    :type: integer
+    :default: 15
+
+.. config:option:: $cfg['CharTextareaCols']
+
+    :type: integer
+    :default: 40
+
+.. config:option:: $cfg['CharTextareaRows']
+
+    :type: integer
+    :default: 2
+
+    Number of columns and rows for the textareas. This value will be
+    emphasized (\*2) for :term:`SQL` query
+    textareas and (\*1.25) for :term:`SQL`
+    textareas inside the query window.
+
+    The Char\* values are used for CHAR
+    and VARCHAR editing (if configured via :config:option:`$cfg['CharEditing']`).
+
+.. config:option:: $cfg['LongtextDoubleTextarea']
+
+    :type: boolean
+    :default: true
+
+    Defines whether textarea for LONGTEXT columns should have double size.
+
+.. config:option:: $cfg['TextareaAutoSelect']
+
+    :type: boolean
+    :default: false
+
+    Defines if the whole textarea of the query box will be selected on
+    click.
+
+
+SQL query box settings
+----------------------
+
+.. config:option:: $cfg['SQLQuery']['Edit']
+
+    :type: boolean
+    :default: true
+
+    Whether to display an edit link to change a query in any SQL Query
+    box.
+
+.. config:option:: $cfg['SQLQuery']['Explain']
+
+    :type: boolean
+    :default: true
+
+    Whether to display a link to explain a SELECT query in any SQL Query
+    box.
+
+.. config:option:: $cfg['SQLQuery']['ShowAsPHP']
+
+    :type: boolean
+    :default: true
+
+    Whether to display a link to wrap a query in PHP code in any SQL Query
+    box.
+
+.. config:option:: $cfg['SQLQuery']['Validate']
+
+    :type: boolean
+    :default: false
+
+    Whether to display a link to validate a query in any SQL Query box.
+
+    .. seealso:: :config:option:`$cfg['SQLValidator']`
+
+.. config:option:: $cfg['SQLQuery']['Refresh']
+
+    :type: boolean
+    :default: true
+
+    Whether to display a link to refresh a query in any SQL Query box.
+
+Web server upload/save/import directories
+-----------------------------------------
+
+.. config:option:: $cfg['UploadDir']
+
+    :type: string
+    :default: ``''``
+
+    The name of the directory where :term:`SQL` files have been uploaded by
+    other means than phpMyAdmin (for example, ftp). Those files are available
+    under a drop-down box when you click the database or table name, then the
+    Import tab. 
+
+    If
+    you want different directory for each user, %u will be replaced with
+    username. 
+
+    Please note that the file names must have the suffix ".sql"
+    (or ".sql.bz2" or ".sql.gz" if support for compressed formats is
+    enabled).
+
+    This feature is useful when your file is too big to be
+    uploaded via :term:`HTTP`, or when file
+    uploads are disabled in PHP.
+
+    .. note::
+       
+        If PHP is running in safe mode, this directory must be owned by the same
+        user as the owner of the phpMyAdmin scripts.  See also :ref:`faq1_16` for
+        alternatives.
+
+.. config:option:: $cfg['SaveDir']
+
+    :type: string
+    :default: ``''``
+
+    The name of the directory where dumps can be saved. 
+
+    If you want different directory for each user, %u will be replaced with
+    username.
+
+    Please note that the directory must exist and has to be writable for
+    the user running webserver. 
+
+    .. note:: 
+       
+        If PHP is running in safe mode, this directory must be owned by the same
+        user as the owner of the phpMyAdmin scripts.
+
+.. config:option:: $cfg['TempDir']
+
+    :type: string
+    :default: ``''``
+
+    The name of the directory where temporary files can be stored. 
+
+    This is needed for importing ESRI Shapefiles, see :ref:`faq6_30` and to
+    work around limitations of ``open_basedir`` for uploaded files, see
+    :ref:`faq1_11`.  
+
+    If the directory where phpMyAdmin is installed is
+    subject to an ``open_basedir`` restriction, you need to create a
+    temporary directory in some directory accessible by the web server.
+    However for security reasons, this directory should be outside the
+    tree published by webserver. If you cannot avoid having this directory
+    published by webserver, place at least an empty :file:`index.html` file
+    there, so that directory listing is not possible.
+
+    This directory should have as strict permissions as possible as the only
+    user required to access this directory is the one who runs the webserver.
+    If you have root privileges, simply make this user owner of this directory
+    and make it accessible only by it:
+
+    .. code-block:: sh
+
+        
+        chown www-data:www-data tmp
+        chmod 700 tmp
+
+    If you cannot change owner of the directory, you can achieve a similar
+    setup using :term:`ACL`:
+
+    .. code-block:: sh
+
+        chmod 700 tmp
+        setfacl -m "g:www-data:rwx" tmp
+        setfacl -d -m "g:www-data:rwx" tmp
+
+    If neither of above works for you, you can still make the directory
+    :command:`chmod 777`, but it might impose risk of other users on system
+    reading and writing data in this directory.
+
+Various display setting
+-----------------------
+
+.. config:option:: $cfg['ShowDisplayDirection']
+
+    :type: boolean
+    :default: false
+
+    Defines whether or not type display direction option is shown when
+    browsing a table.
+
+.. config:option:: $cfg['RepeatCells']
+
+    :type: integer
+    :default: 100
+
+    Repeat the headers every X cells, or 0 to deactivate.
+
+.. config:option:: $cfg['EditInWindow']
+
+    :type: boolean
+    :default: true
+
+.. config:option:: $cfg['QueryWindowWidth']
+
+    :type: integer
+    :default: 550
+
+.. config:option:: $cfg['QueryWindowHeight']
+
+    :type: integer
+    :default: 310
+
+.. config:option:: $cfg['QueryHistoryDB']
+
+    :type: boolean
+    :default: false
+
+.. config:option:: $cfg['QueryWindowDefTab']
+
+    :type: string
+    :default: ``'sql'``
+
+.. config:option:: $cfg['QueryHistoryMax']
+
+    :type: integer
+    :default: 25
+
+    All those variables affect the query window feature. A :term:`SQL` link or
+    icon is always displayed in the navigation panel. If JavaScript is enabled
+    in your browser, a click on this opens a distinct query window, which is a
+    direct interface to enter :term:`SQL` queries. Otherwise, the right panel
+    changes to display a query box. 
+
+    The size of this query window can be customized with
+    :config:option:`$cfg['QueryWindowWidth']` and
+    :config:option:`$cfg['QueryWindowHeight']` - both integers for the size in
+    pixels.  Note that normally, those parameters will be modified in
+    :file:`layout.inc.php`` for the theme you are using. 
+
+    If :config:option:`$cfg['EditInWindow']` is set to true, a click on [Edit]
+    from the results page (in the :guilabel:`Showing Rows` section) opens the
+    query window and puts the current query inside it. If set to false,
+    clicking on the link puts the :term:`SQL` query
+    in the right panel's query box.  
+
+    If :config:option:`$cfg['QueryHistoryDB']` is set to ``true``, all your
+    Queries are logged to a table, which has to be created by you (see
+    :config:option:`$cfg['Servers'][$i]['history']`). If set to false, all your
+    queries will be appended to the form, but only as long as your window is
+    opened they remain saved.  
+
+    When using the JavaScript based query window, it will always get updated
+    when you click on a new table/db to browse and will focus if you click on
+    :guilabel:`Edit SQL` after using a query. You can suppress updating the
+    query window by checking the box :guilabel:`Do not overwrite this query
+    from outside the window` below the query textarea. Then you can browse
+    tables/databases in the background without losing the contents of the
+    textarea, so this is especially useful when composing a query with tables
+    you first have to look in. The checkbox will get automatically checked
+    whenever you change the contents of the textarea. Please uncheck the button
+    whenever you definitely want the query window to get updated even though
+    you have made alterations. 
+
+    If :config:option:`$cfg['QueryHistoryDB']` is set to ``true`` you can
+    specify the amount of saved history items using
+    :config:option:`$cfg['QueryHistoryMax']`. 
+
+    The query window also has a custom tabbed look to group the features.
+    Using the variable :config:option:`$cfg['QueryWindowDefTab']` you can
+    specify the default tab to be used when opening the query window. It can be
+    set to either ``sql``, ``files``, ``history`` or ``full``.
+
+.. config:option:: $cfg['BrowseMIME']
+
+    :type: boolean
+    :default: true
+
+    Enable :ref:`transformations`.
+
+.. config:option:: $cfg['MaxExactCount']
+
+    :type: integer
+    :default: 0
+
+    For InnoDB tables, determines for how large tables phpMyAdmin should
+    get the exact row count using ``SELECT COUNT``. If the approximate row
+    count as returned by ``SHOW TABLE STATUS`` is smaller than this value,
+    ``SELECT COUNT`` will be used, otherwise the approximate count will be
+    used.
+
+.. config:option:: $cfg['MaxExactCountViews']
+
+    :type: integer
+    :default: 0
+
+    For VIEWs, since obtaining the exact count could have an impact on
+    performance, this value is the maximum to be displayed, using a
+    ``SELECT COUNT ... LIMIT``. Setting this to 0 bypasses any row
+    counting.
+
+.. config:option:: $cfg['NaturalOrder']
+
+    :type: boolean
+    :default: true
+
+    Sorts database and table names according to natural order (for
+    example, t1, t2, t10). Currently implemented in the navigation panel
+    and in Database view, for the table list.
+
+.. config:option:: $cfg['InitialSlidersState']
+
+    :type: string
+    :default: ``'closed'``
+
+    If set to ``'closed'``, the visual sliders are initially in a closed
+    state. A value of ``'open'`` does the reverse. To completely disable
+    all visual sliders, use ``'disabled'``.
+
+.. config:option:: $cfg['UserprefsDisallow']
+
+    :type: array
+    :default: array()
+
+    Contains names of configuration options (keys in ``$cfg`` array) that
+    users can't set through user preferences. For possible values, refer
+    to :file:`libraries/config/user_preferences.forms.php`.
+
+.. config:option:: $cfg['UserprefsDeveloperTab']
+
+    :type: boolean
+    :default: false
+
+    Activates in the user preferences a tab containing options for
+    developers of phpMyAdmin.
+
+Page titles
+-----------
+
+.. config:option:: $cfg['TitleTable']
+
+    :type: string
+    :default: ``'@HTTP_HOST@ / @VSERVER@ / @DATABASE@ / @TABLE@ | @PHPMYADMIN@'``
+
+.. config:option:: $cfg['TitleDatabase']
+
+    :type: string
+    :default: ``'@HTTP_HOST@ / @VSERVER@ / @DATABASE@ | @PHPMYADMIN@'``
+
+.. config:option:: $cfg['TitleServer']
+
+    :type: string
+    :default: ``'@HTTP_HOST@ / @VSERVER@ | @PHPMYADMIN@'``
+
+.. config:option:: $cfg['TitleDefault']
+
+    :type: string
+    :default: ``'@HTTP_HOST@ | @PHPMYADMIN@'``
+
+    Allows you to specify window's title bar. You can use :ref:`faq6_27`.
+
+Theme manager settings
+----------------------
+
+.. config:option:: $cfg['ThemePath']
+
+    :type: string
+    :default: ``'./themes'``
+
+    If theme manager is active, use this as the path of the subdirectory
+    containing all the themes.
+
+.. config:option:: $cfg['ThemeManager']
+
+    :type: boolean
+    :default: true
+
+    Enables user-selectable themes. See :ref:`faqthemes`.
+
+.. config:option:: $cfg['ThemeDefault']
+
+    :type: string
+    :default: ``'pmahomme'``
+
+    The default theme (a subdirectory under :config:option:`$cfg['ThemePath']`).
+
+.. config:option:: $cfg['ThemePerServer']
+
+    :type: boolean
+    :default: false
+
+    Whether to allow different theme for each server.
+
+Default queries
+---------------
+
+.. config:option:: $cfg['DefaultQueryTable']
+
+    :type: string
+    :default: ``'SELECT * FROM @TABLE@ WHERE 1'``
+
+.. config:option:: $cfg['DefaultQueryDatabase']
+
+    :type: string
+    :default: ``''``
+
+    Default queries that will be displayed in query boxes when user didn't
+    specify any. You can use standard :ref:`faq6_27`.
+
+SQL parser settings
+-------------------
+
+.. config:option:: $cfg['SQP']['fmtType']
+
+    :type: string
+    :default: ``'html'``
+
+    The main use of the new :term:`SQL` Parser
+    is to pretty-print :term:`SQL` queries. By
+    default we use HTML to format the query, but you can disable this by
+    setting this variable to ``'none'``.
+
+    Available options:
+
+    * ``'html'``
+    * ``'none'``
+
+.. _cfg_SQP:
+.. config:option:: $cfg['SQP']['fmtInd']
+
+    :type: float
+    :default: ``'1'``
+
+.. config:option:: $cfg['SQP']['fmtIndUnit']
+
+    :type: string
+    :default: ``'em'``
+
+    For the pretty-printing of :term:`SQL` queries,
+    under some cases the part of a query inside a bracket is indented. By
+    changing :config:option:`$cfg['SQP']['fmtInd']` you can change the amount
+    of this indent. 
+
+    Related in purpose is :config:option:`$cfg['SQP']['fmtIndUnit']` which
+    specifies the units of the indent amount that you specified. This is used
+    via stylesheets.
+
+    You can use any HTML unit, for example:
+
+    * ``'em'``
+    * ``'ex'``
+    * ``'pt'``
+    * ``'px'``
+
+.. config:option:: $cfg['SQP']['fmtColor']
+
+    :type: array of string tuples
+    :default:
+
+    This array is used to define the colours for each type of element of
+    the pretty-printed :term:`SQL` queries.
+    The tuple format is *class* => [*HTML colour code* | *empty string*]
+
+
+    If you specify an empty string for the color of a class, it is ignored
+    in creating the stylesheet. You should not alter the class names, only
+    the colour strings.
+    
+    **Class name key:**
+
+    comment
+        Applies to all comment sub-classes
+    comment\_mysql
+        Comments as ``"#...\n"``
+    comment\_ansi
+        Comments as ``"-- ...\n"``
+    comment\_c
+        Comments as ``"/*...*/"``
+    digit
+        Applies to all digit sub-classes
+    digit\_hex
+        Hexadecimal numbers
+    digit\_integer
+        Integer numbers
+    digit\_float
+        Floating point numbers
+    punct
+        Applies to all punctuation sub-classes
+    punct\_bracket\_open\_round
+        Opening brackets ``"("``
+    punct\_bracket\_close\_round
+        Closing brackets ``")"``
+    punct\_listsep
+        List item Separator ``","``
+    punct\_qualifier
+        Table/Column Qualifier ``"."``
+    punct\_queryend
+        End of query marker ``";"``
+    alpha
+        Applies to all alphabetic classes
+    alpha\_columnType
+        Identifiers matching a column type
+    alpha\_columnAttrib
+        Identifiers matching a database/table/column attribute
+    alpha\_functionName
+        Identifiers matching a MySQL function name
+    alpha\_reservedWord
+        Identifiers matching any other reserved word
+    alpha\_variable
+        Identifiers matching a :term:`SQL` variable ``"@foo"``
+    alpha\_identifier
+        All other identifiers
+    quote
+        Applies to all quotation mark classes
+    quote\_double
+        Double quotes ``"``
+    quote\_single
+        Single quotes ``'``
+    quote\_backtick
+        Backtick quotes `````
+
+SQL validator settings
+----------------------
+
+.. config:option:: $cfg['SQLValidator']
+
+    :type: array
+    :default: array(...)
+
+
+
+.. config:option:: $cfg['SQLValidator']['use']
+
+    :type: boolean
+    :default: false
+
+    phpMyAdmin now supports use of the `Mimer SQL Validator
+    <http://developer.mimer.com/validator/index.htm>`_ service, as originally
+    published on `Slashdot
+    <http://developers.slashdot.org/article.pl?sid=02/02/19/1720246>`_. For
+    help in setting up your system to use the service, see the
+    :ref:`faqsqlvalidator`.
+
+.. config:option:: $cfg['SQLValidator']['username']
+
+    :type: string
+    :default: ``''``
+
+.. config:option:: $cfg['SQLValidator']['password']
+
+    :type: string
+    :default: ``''``
+
+    The SOAP service allows you to log in with ``anonymous`` and any password,
+    so we use those by default. Instead, if you have an account with them, you
+    can put your login details here, and it will be used in place of the
+    anonymous login.
+
+MySQL settings
+--------------
+
+.. config:option:: $cfg['DefaultFunctions']
+
+    :type: array
+    :default: array(...)
+
+    Functions selected by default when inserting/changing row, Functions
+    are defined for meta types as (FUNC\_NUMBER, FUNC\_DATE, FUNC\_CHAR,
+    FUNC\_SPATIAL, FUNC\_UUID) and for ``first_timestamp``, which is used
+    for first timestamp column in table.
+
+
+Developer
+---------
+
+.. warning::
+
+    These settings might have huge effect on performance or security.
+
+.. config:option:: $cfg['DBG']
+
+    :type: array
+    :default: array(...)
+
+.. config:option:: $cfg['DBG']['sql']
+
+    :type: boolean
+    :default: false
+
+    Enable logging queries and execution times to be
+    displayed in the bottom of main page (right frame).
+
+.. config:option:: $cfg['Error_Handler']['display']
+
+    :type: boolean
+    :default: false
+
+    Whether to display errors from PHP or not.
+
+.. config:option:: $cfg['Error_Handler']['gather']
+
+    :type: boolean
+    :default: false
+
+    Whether to gather errors from PHP or not.
+ 
diff --git a/phpmyadmin/doc/copyright.rst b/phpmyadmin/doc/copyright.rst
new file mode 100644
index 0000000..cfcb863
--- /dev/null
+++ b/phpmyadmin/doc/copyright.rst
@@ -0,0 +1,30 @@
+.. _copyright:
+
+Copyright
+=========
+
+.. code-block:: none
+
+    Copyright (C) 1998-2000 Tobias Ratschiller <tobias_at_ratschiller.com>
+    Copyright (C) 2001-2013 Marc Delisle <marc_at_infomarc.info>
+        Olivier Müller <om_at_omnis.ch>
+        Robin Johnson <robbat2_at_users.sourceforge.net>
+        Alexander M. Turek <me_at_derrabus.de>
+        Michal Čihař <michal_at_cihar.com>
+        Garvin Hicking <me_at_supergarv.de>
+        Michael Keck <mkkeck_at_users.sourceforge.net>
+        Sebastian Mendel <cybot_tm_at_users.sourceforge.net>
+        [check credits for more details]
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License version 2, as
+published by the Free Software Foundation.
+
+This program is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program. If not, see `http://www.gnu.org/licenses/
+<http://www.gnu.org/licenses/>`_.
diff --git a/phpmyadmin/doc/credits.rst b/phpmyadmin/doc/credits.rst
new file mode 100644
index 0000000..21f5e18
--- /dev/null
+++ b/phpmyadmin/doc/credits.rst
@@ -0,0 +1,597 @@
+.. _credits:
+
+Credits
+=======
+
+
+Credits, in chronological order
++++++++++++++++++++++++++++++++
+
+* Tobias Ratschiller <tobias\_at\_ratschiller.com>
+
+  * creator of the phpmyadmin project
+
+  * maintainer from 1998 to summer 2000
+
+* Marc Delisle <marc\_at\_infomarc.info>
+
+  * multi-language version in December 1998
+
+  * various fixes and improvements
+
+  * :term:`SQL` analyser (most of it)
+
+  * current project maintainer
+
+* Olivier Müller <om\_at\_omnis.ch>
+
+  * started SourceForge phpMyAdmin project in March 2001
+
+  * sync'ed different existing CVS trees with new features and bugfixes
+
+  * multi-language improvements, dynamic language selection
+
+  * many bugfixes and improvements
+
+* Loïc Chapeaux <lolo\_at\_phpheaven.net>
+
+  * rewrote and optimized javascript, DHTML and DOM stuff
+
+  * rewrote the scripts so they fit the :term:`PEAR` coding standards and 
+    generate XHTML1.0 and CSS2 compliant codes
+
+  * improved the language detection system
+
+  * many bugfixes and improvements
+
+* Robin Johnson <robbat2\_at\_users.sourceforge.net>
+
+  * database maintenance controls
+
+  * table type code
+
+  * Host authentication :term:`IP` Allow/Deny
+
+  * DB-based configuration (Not completed)
+
+  * :term:`SQL` parser and pretty-printer
+
+  * :term:`SQL` validator
+
+  * many bugfixes and improvements
+
+* Armel Fauveau <armel.fauveau\_at\_globalis-ms.com>
+
+  * bookmarks feature
+
+  * multiple dump feature
+
+  * gzip dump feature
+
+  * zip dump feature
+
+* Geert Lund <glund\_at\_silversoft.dk>
+
+  * various fixes
+
+  * moderator of the phpMyAdmin former users forum at phpwizard.net
+
+* Korakot Chaovavanich <korakot\_at\_iname.com>
+
+  * "insert as new row" feature
+
+* Pete Kelly <webmaster\_at\_trafficg.com>
+
+  * rewrote and fix dump code
+
+  * bugfixes
+
+* Steve Alberty <alberty\_at\_neptunlabs.de>
+
+  * rewrote dump code for PHP4
+
+  * mySQL table statistics
+
+  * bugfixes
+
+* Benjamin Gandon <gandon\_at\_isia.cma.fr>
+
+  * main author of the version 2.1.0.1
+
+  * bugfixes
+
+* Alexander M. Turek <me\_at\_derrabus.de>
+
+  * MySQL 4.0 / 4.1 / 5.0 compatibility
+
+  * abstract database interface (PMA\_DBI) with MySQLi support
+
+  * privileges administration
+
+  * :term:`XML` exports
+
+  * various features and fixes
+
+  * German language file updates
+
+* Mike Beck <mike.beck\_at\_web.de>
+
+  * automatic joins in QBE
+
+  * links column in printview
+
+  * Relation view
+
+* Michal Čihař <michal\_at\_cihar.com>
+
+  * enhanced index creation/display feature
+
+  * feature to use a different charset for HTML than for MySQL
+
+  * improvements of export feature
+
+  * various features and fixes
+
+  * Czech language file updates
+
+* Christophe Gesché from the "MySQL Form Generator for PHPMyAdmin"
+  (http://sf.net/projects/phpmysqlformgen/)
+
+  * suggested the patch for multiple table printviews
+
+* Garvin Hicking <me\_at\_supergarv.de>
+
+  * built the patch for vertical display of table rows
+
+  * built the Javascript based Query window + :term:`SQL` history
+
+  * Improvement of column/db comments
+
+  * (MIME)-Transformations for columns
+
+  * Use custom alias names for Databases in left frame
+
+  * hierarchical/nested table display
+
+  * :term:`PDF`-scratchboard for WYSIWYG-
+    distribution of :term:`PDF` relations
+
+  * new icon sets
+
+  * vertical display of column properties page
+
+  * some bugfixes, features, support, German language additions
+
+* Yukihiro Kawada <kawada\_at\_den.fujifilm.co.jp>
+
+  * japanese kanji encoding conversion feature
+
+* Piotr Roszatycki <d3xter\_at\_users.sourceforge.net> and Dan Wilson
+
+  * the Cookie authentication mode
+
+* Axel Sander <n8falke\_at\_users.sourceforge.net>
+
+  * table relation-links feature
+
+* Maxime Delorme <delorme.maxime\_at\_free.fr>
+
+  * :term:`PDF` schema output, thanks also to
+    Olivier Plathey for the "FPDF" library (see <http://www.fpdf.org/>), Steven
+    Wittens for the "UFPDF" library (see <http://www.acko.net/node/56>) and
+    Nicola Asuni for the "TCPDF" library (see <http://www.tcpdf.org/>).
+
+* Olof Edlund <olof.edlund\_at\_upright.se>
+
+  * :term:`SQL` validator server
+
+* Ivan R. Lanin <ivanlanin\_at\_users.sourceforge.net>
+
+  * phpMyAdmin logo (until June 2004)
+
+* Mike Cochrane <mike\_at\_graftonhall.co.nz>
+
+  * blowfish library from the Horde project (withdrawn in release 4.0)
+
+* Marcel Tschopp <ne0x\_at\_users.sourceforge.net>
+
+  * mysqli support
+
+  * many bugfixes and improvements
+
+* Nicola Asuni (Tecnick.com)
+
+  * TCPDF library (`http://www.tcpdf.org <http://www.tcpdf.org>`_)
+
+* Michael Keck <mkkeck\_at\_users.sourceforge.net>
+
+  * redesign for 2.6.0
+
+  * phpMyAdmin sailboat logo (June 2004)
+
+* Mathias Landhäußer
+
+  * Representation at conferences
+
+* Sebastian Mendel <cybot\_tm\_at\_users.sourceforge.net>
+
+  * interface improvements
+
+  * various bugfixes
+
+* Ivan A Kirillov
+
+  * new relations Designer
+
+* Raj Kissu Rajandran (Google Summer of Code 2008)
+
+  * BLOBstreaming support (withdrawn in release 4.0)
+
+* Piotr Przybylski (Google Summer of Code 2008, 2010 and 2011)
+
+  * improved setup script
+
+  * user preferences
+
+  * Drizzle support
+
+* Derek Schaefer (Google Summer of Code 2009)
+
+  * Improved the import system
+
+* Alexander Rutkowski (Google Summer of Code 2009)
+
+  * Tracking mechanism
+
+* Zahra Naeem (Google Summer of Code 2009)
+
+  * Synchronization feature (removed in release 4.0)
+
+* Tomáš Srnka (Google Summer of Code 2009)
+
+  * Replication support
+
+* Muhammad Adnan (Google Summer of Code 2010)
+
+  * Relation schema export to multiple formats
+
+* Lori Lee (Google Summer of Code 2010)
+
+  * User interface improvements
+
+  * ENUM/SET editor
+
+  * Simplified interface for export/import
+
+* Ninad Pundalik (Google Summer of Code 2010)
+
+  * AJAXifying the interface
+
+* Martynas Mickevičius (Google Summer of Code 2010)
+
+  * Charts
+
+* Barrie Leslie
+
+  * BLOBstreaming support with PBMS PHP extension (withdrawn in release
+    4.0)
+
+* Ankit Gupta (Google Summer of Code 2010)
+
+  * Visual query builder
+
+* Madhura Jayaratne (Google Summer of Code 2011)
+
+  * OpenGIS support
+
+* Ammar Yasir (Google Summer of Code 2011)
+
+  * Zoom search
+
+* Aris Feryanto (Google Summer of Code 2011)
+
+  * Browse-mode improvements
+
+* Thilanka Kaushalya (Google Summer of Code 2011)
+
+  * AJAXification
+
+* Tyron Madlener (Google Summer of Code 2011)
+
+  * Query statistics and charts for the status page
+
+* Zarubin Stas (Google Summer of Code 2011)
+
+  * Automated testing
+
+* Rouslan Placella (Google Summer of Code 2011 and 2012)
+
+  * Improved support for Stored Routines, Triggers and Events
+
+  * Italian translation updates
+
+  * Removal of frames, new navigation
+
+* Dieter Adriaenssens
+
+  * Various bugfixes
+
+  * Dutch translation updates
+
+* Alex Marin (Google Summer of Code 2012)
+
+  * New plugins and properties system
+
+* Thilina Buddika Abeyrathna (Google Summer of Code 2012)
+  
+  * Refactoring
+
+* Atul Pratap Singh  (Google Summer of Code 2012)
+  
+  * Refactoring
+
+* Chanaka Indrajith (Google Summer of Code 2012)
+  
+  * Refactoring
+
+* Yasitha Pandithawatta (Google Summer of Code 2012)
+  
+  * Automated testing
+
+* Jim Wigginton (phpseclib.sourceforge.net)
+
+  * phpseclib
+
+And also to the following people who have contributed minor changes,
+enhancements, bugfixes or support for a new language since version
+2.1.0:
+
+Bora Alioglu, Ricardo ?, Sven-Erik Andersen, Alessandro Astarita,
+Péter Bakondy, Borges Botelho, Olivier Bussier, Neil Darlow, Mats
+Engstrom, Ian Davidson, Laurent Dhima, Kristof Hamann, Thomas Kläger,
+Lubos Klokner, Martin Marconcini, Girish Nair, David Nordenberg,
+Andreas Pauley, Bernard M. Piller, Laurent Haas, "Sakamoto", Yuval
+Sarna, www.securereality.com.au, Alexis Soulard, Alvar Soome, Siu Sun,
+Peter Svec, Michael Tacelosky, Rachim Tamsjadi, Kositer Uros, Luís V.,
+Martijn W. van der Lee, Algis Vainauskas, Daniel Villanueva, Vinay,
+Ignacio Vazquez-Abrams, Chee Wai, Jakub Wilk, Thomas Michael
+Winningham, Vilius Zigmantas, "Manuzhai".
+
+
+Translators
++++++++++++
+
+Following people have contributed to translation of phpMyAdmin:
+
+* Arabic 
+
+  * Abdullah Al-Saedi <abdullah.10\_at\_windowslive.com>
+
+* Bulgarian 
+
+  * stoyanster <stoyanster\_at\_gmail.com>
+
+* Catalan
+
+  * Xavier Navarro <xvnavarro\_at\_gmail.com>
+
+* Czech 
+
+  * Michal Čihař <michal\_at\_cihar.com>
+
+* Danish 
+
+  * opensource <opensource\_at\_jth.net>
+  * Jørgen Thomsen <opensource\_at\_jth.net>
+
+* German 
+
+  * mrbendig <mrbendig\_at\_mrbendig.com>
+  * torsten.funck <torsten.funck\_at\_googlemail.com>
+  * Sven Strickroth <email\_at\_cs-ware.de>
+  * typo3 <typo3\_at\_dirk-weise.de>
+  * Jo Michael <me\_at\_mynetx.net>
+
+* Greek 
+
+  * Panagiotis Papazoglou <papaz_p\_at\_yahoo.com>
+
+* English (United Kingdom)
+
+  * Robert Readman <robert_readman\_at\_hotmail.com>
+
+* Spanish
+
+  * Matías Bellone <matiasbellone\_at\_gmail.com>
+
+* French 
+
+  * Marc Delisle <marc\_at\_infomarc.info>
+
+* Hindi 
+
+  * u4663530 <u4663530\_at\_anu.edu.au>
+  * rsedwardian <rsedwardian\_at\_gmail.com>
+
+* Hungarian 
+
+  * gergo314 <gergo314\_at\_gmail.com>
+
+* Italian 
+
+  * Rouslan Placella <rouslan\_at\_placella.com>
+
+* Japanese 
+
+  * Yuichiro <yuichiro\_at\_pop07.odn.ne.jp>
+
+* Lithuanian 
+
+  * Kęstutis <forkik\_at\_gmail.com>
+
+* Norwegian Bokmål
+
+  * Sven-Erik Andersen <sven.erik.andersen\_at\_gmail.com>
+
+* Dutch 
+
+  * Dieter Adriaenssens <ruleant\_at\_users.sourceforge.net>
+  * Herman van Rink <rink\_at\_initfour.nl>
+
+* Polish 
+
+  * Stanisław Krukowski <stankruk\_at\_neostrada.pl>
+  * Marcin Kozioł <lord_dark\_at\_wp.pl>
+
+* Portuguese
+
+  * JoaoTMDias <contacto\_at\_joaodias.me>
+
+* Portuguese (Brazil) 
+
+  * wiltave <wiltave\_at\_gmail.com>
+  * emerson4br <emerson4br\_at\_gmail.com>
+
+* Romanian 
+
+  * alexukf <alex.ukf\_at\_gmail.com>
+
+* Russian 
+
+  * Victor Volkov <hanut\_at\_php-myadmin.ru>
+
+* Sinhala 
+
+  * Madhura Jayaratne <madhura.cj\_at\_gmail.com>
+
+* Slovak 
+
+  * Martin Lacina <martin\_at\_whistler.sk>
+
+* Slovenian 
+
+  * Domen <dbc334\_at\_gmail.com>
+
+* Swedish
+
+  * stefan <stefan\_at\_inkopsforum.se>
+
+* Tamil 
+
+  * ysajeepan <ysajeepan\_at\_live.com>
+
+* Telugu 
+
+  * veeven <veeven\_at\_gmail.com>
+
+* Thai 
+
+  * kanitchet <kanichet\_at\_hotmail.com>
+
+* Turkish
+
+  * Burak Yavuz <hitowerdigit\_at\_hotmail.com>
+
+* Uighur 
+
+  * gheni <gheni\_at\_yahoo.cn>
+
+* Ukrainian 
+
+  * typim <duke3d\_at\_ukr.net>
+  * oleg-ilnytskyi <ukraine.oleg\_at\_gmail.com>
+
+* Urdu 
+
+  * Mehbooob Khan <mehboobbugti\_at\_gmail.com>
+
+* Simplified Chinese
+
+  * shanyan baishui <Siramizu\_at\_gmail.com>
+
+* Traditional Chinese
+
+  * star <star\_at\_origin.club.tw>
+
+Documentation translators
++++++++++++++++++++++++++
+
+Following people have contributed to translation of phpMyAdmin documentation:
+
+* Czech 
+
+  * Michal Čihař <michal\_at\_cihar.com>
+
+* Greek 
+
+  * Panagiotis Papazoglou <papaz_p\_at\_yahoo.com>
+
+* English (United Kingdom) 
+
+  * Robert Readman <robert_readman\_at\_hotmail.com>
+
+* French 
+
+  * Cédric Corazza <cedric.corazza\_at\_wanadoo.fr>
+
+* Japanese 
+
+  * Yuichiro Takahashi <yuichiro\_at\_pop07.odn.ne.jp>
+
+* Polish 
+
+  * Stanisław Krukowski <stankruk\_at\_neostrada.pl>
+
+* Portuguese (Brazil) 
+
+  * mjaning <mjaning\_at\_gmail.com>
+
+* Slovenian 
+
+  * Domen <dbc334\_at\_gmail.com>
+
+Original Credits of Version 2.1.0
++++++++++++++++++++++++++++++++++
+
+This work is based on Peter Kuppelwieser's MySQL-Webadmin. It was his
+idea to create a web-based interface to MySQL using PHP3. Although I
+have not used any of his source-code, there are some concepts I've
+borrowed from him. phpMyAdmin was created because Peter told me he
+wasn't going to further develop his (great) tool.
+
+Thanks go to
+
+* Amalesh Kempf <ak-lsml\_at\_living-source.com> who contributed the
+  code for the check when dropping a table or database. He also
+  suggested that you should be able to specify the primary key on
+  tbl\_create.php3. To version 1.1.1 he contributed the ldi\_\*.php3-set
+  (Import text-files) as well as a bug-report. Plus many smaller
+  improvements.
+* Jan Legenhausen <jan\_at\_nrw.net>: He made many of the changes that
+  were introduced in 1.3.0 (including quite significant ones like the
+  authentication). For 1.4.1 he enhanced the table-dump feature. Plus
+  bug-fixes and help.
+* Marc Delisle <DelislMa\_at\_CollegeSherbrooke.qc.ca> made phpMyAdmin
+  language-independent by outsourcing the strings to a separate file. He
+  also contributed the French translation.
+* Alexandr Bravo <abravo\_at\_hq.admiral.ru> who contributed
+  tbl\_select.php3, a feature to display only some columns from a table.
+* Chris Jackson <chrisj\_at\_ctel.net> added support for MySQL functions
+  in tbl\_change.php3. He also added the "Query by Example" feature in
+  2.0.
+* Dave Walton <walton\_at\_nordicdms.com> added support for multiple
+  servers and is a regular contributor for bug-fixes.
+* Gabriel Ash <ga244\_at\_is8.nyu.edu> contributed the random access
+  features for 2.0.6.
+
+The following people have contributed minor changes, enhancements,
+bugfixes or support for a new language:
+
+Jim Kraai, Jordi Bruguera, Miquel Obrador, Geert Lund, Thomas
+Kleemann, Alexander Leidinger, Kiko Albiol, Daniel C. Chao, Pavel
+Piankov, Sascha Kettler, Joe Pruett, Renato Lins, Mark Kronsbein,
+Jannis Hermanns, G. Wieggers.
+
+And thanks to everyone else who sent me email with suggestions, bug-
+reports and or just some feedback.
+
diff --git a/phpmyadmin/doc/developers.rst b/phpmyadmin/doc/developers.rst
new file mode 100644
index 0000000..5574527
--- /dev/null
+++ b/phpmyadmin/doc/developers.rst
@@ -0,0 +1,12 @@
+.. _developers:
+
+Developers Information
+======================
+
+phpMyAdmin is Open Source, so you're invited to contribute to it. Many
+great features have been written by other people and you too can help
+to make phpMyAdmin a useful tool.
+
+You can check out all the possibilities to contribute in the
+`contribute section on our website 
+<http://www.phpmyadmin.net/home_page/improve.php>`_.
\ No newline at end of file
diff --git a/phpmyadmin/doc/doctrees/config.doctree b/phpmyadmin/doc/doctrees/config.doctree
new file mode 100644
index 0000000..98b1ab1
Binary files /dev/null and b/phpmyadmin/doc/doctrees/config.doctree differ
diff --git a/phpmyadmin/doc/doctrees/copyright.doctree b/phpmyadmin/doc/doctrees/copyright.doctree
new file mode 100644
index 0000000..26a6396
Binary files /dev/null and b/phpmyadmin/doc/doctrees/copyright.doctree differ
diff --git a/phpmyadmin/doc/doctrees/credits.doctree b/phpmyadmin/doc/doctrees/credits.doctree
new file mode 100644
index 0000000..9cb3aa4
Binary files /dev/null and b/phpmyadmin/doc/doctrees/credits.doctree differ
diff --git a/phpmyadmin/doc/doctrees/developers.doctree b/phpmyadmin/doc/doctrees/developers.doctree
new file mode 100644
index 0000000..de46098
Binary files /dev/null and b/phpmyadmin/doc/doctrees/developers.doctree differ
diff --git a/phpmyadmin/doc/doctrees/environment.pickle b/phpmyadmin/doc/doctrees/environment.pickle
new file mode 100644
index 0000000..170f078
Binary files /dev/null and b/phpmyadmin/doc/doctrees/environment.pickle differ
diff --git a/phpmyadmin/doc/doctrees/faq.doctree b/phpmyadmin/doc/doctrees/faq.doctree
new file mode 100644
index 0000000..115a6f9
Binary files /dev/null and b/phpmyadmin/doc/doctrees/faq.doctree differ
diff --git a/phpmyadmin/doc/doctrees/glossary.doctree b/phpmyadmin/doc/doctrees/glossary.doctree
new file mode 100644
index 0000000..55feceb
Binary files /dev/null and b/phpmyadmin/doc/doctrees/glossary.doctree differ
diff --git a/phpmyadmin/doc/doctrees/index.doctree b/phpmyadmin/doc/doctrees/index.doctree
new file mode 100644
index 0000000..9ffbf04
Binary files /dev/null and b/phpmyadmin/doc/doctrees/index.doctree differ
diff --git a/phpmyadmin/doc/doctrees/intro.doctree b/phpmyadmin/doc/doctrees/intro.doctree
new file mode 100644
index 0000000..43e694b
Binary files /dev/null and b/phpmyadmin/doc/doctrees/intro.doctree differ
diff --git a/phpmyadmin/doc/doctrees/other.doctree b/phpmyadmin/doc/doctrees/other.doctree
new file mode 100644
index 0000000..335834f
Binary files /dev/null and b/phpmyadmin/doc/doctrees/other.doctree differ
diff --git a/phpmyadmin/doc/doctrees/privileges.doctree b/phpmyadmin/doc/doctrees/privileges.doctree
new file mode 100644
index 0000000..3fb0766
Binary files /dev/null and b/phpmyadmin/doc/doctrees/privileges.doctree differ
diff --git a/phpmyadmin/doc/doctrees/require.doctree b/phpmyadmin/doc/doctrees/require.doctree
new file mode 100644
index 0000000..77571f7
Binary files /dev/null and b/phpmyadmin/doc/doctrees/require.doctree differ
diff --git a/phpmyadmin/doc/doctrees/setup.doctree b/phpmyadmin/doc/doctrees/setup.doctree
new file mode 100644
index 0000000..4a56db9
Binary files /dev/null and b/phpmyadmin/doc/doctrees/setup.doctree differ
diff --git a/phpmyadmin/doc/doctrees/transformations.doctree b/phpmyadmin/doc/doctrees/transformations.doctree
new file mode 100644
index 0000000..c382432
Binary files /dev/null and b/phpmyadmin/doc/doctrees/transformations.doctree differ
diff --git a/phpmyadmin/doc/doctrees/user.doctree b/phpmyadmin/doc/doctrees/user.doctree
new file mode 100644
index 0000000..d29bc16
Binary files /dev/null and b/phpmyadmin/doc/doctrees/user.doctree differ
diff --git a/phpmyadmin/doc/doctrees/vendors.doctree b/phpmyadmin/doc/doctrees/vendors.doctree
new file mode 100644
index 0000000..551c30c
Binary files /dev/null and b/phpmyadmin/doc/doctrees/vendors.doctree differ
diff --git a/phpmyadmin/doc/faq.rst b/phpmyadmin/doc/faq.rst
new file mode 100644
index 0000000..c77f428
--- /dev/null
+++ b/phpmyadmin/doc/faq.rst
@@ -0,0 +1,2001 @@
+.. _faq:
+
+FAQ - Frequently Asked Questions
+================================
+
+Please have a look at our `Link section
+<http://www.phpmyadmin.net/home_page/docs.php>`_ on the official
+phpMyAdmin homepage for in-depth coverage of phpMyAdmin's features and
+or interface.
+
+.. _faqserver:
+
+Server
+++++++
+
+.. _faq1_1:
+
+1.1 My server is crashing each time a specific action is required or phpMyAdmin sends a blank page or a page full of cryptic characters to my browser, what can I do?
+---------------------------------------------------------------------------------------------------------------------------------------------------------------------
+
+Try to set the :config:option:`$cfg['OBGzip']`  directive to ``false`` in your
+:file:`config.inc.php` file and the ``zlib.output_compression`` directive to
+``Off`` in your php configuration file.
+
+.. _faq1_2:
+
+1.2 My Apache server crashes when using phpMyAdmin.
+---------------------------------------------------
+
+You should first try the latest versions of Apache (and possibly MySQL). If
+your server keeps crashing, please ask for help in the various Apache support
+groups.
+
+.. seealso:: :ref:`faq1_1`
+
+.. _faq1_3:
+
+1.3 (withdrawn).
+----------------
+
+.. _faq1_4:
+
+1.4 Using phpMyAdmin on IIS, I'm displayed the error message: "The specified CGI application misbehaved by not returning a complete set of HTTP headers ...".
+-------------------------------------------------------------------------------------------------------------------------------------------------------------
+
+You just forgot to read the *install.txt* file from the PHP
+distribution. Have a look at the last message in this `PHP bug report #12061
+<http://bugs.php.net/bug.php?id=12061>`_ from the official PHP bug
+database.
+
+.. _faq1_5:
+
+1.5 Using phpMyAdmin on IIS, I'm facing crashes and/or many error messages with the HTTP.
+-----------------------------------------------------------------------------------------
+
+This is a known problem with the PHP :term:`ISAPI` filter: it's not so stable.
+Please use instead the cookie authentication mode.
+
+.. _faq1_6:
+
+1.6 I can't use phpMyAdmin on PWS: nothing is displayed!
+--------------------------------------------------------
+
+This seems to be a PWS bug. Filippo Simoncini found a workaround (at
+this time there is no better fix): remove or comment the ``DOCTYPE``
+declarations (2 lines) from the scripts :file:`libraries/Header.class.php`
+and :file:`index.php`.
+
+.. _faq1_7:
+
+1.7 How can I GZip or Bzip a dump or a CSV export? It does not seem to work.
+----------------------------------------------------------------------------
+
+These features are based on the ``gzencode()`` and ``bzcompress()``
+PHP functions to be more independent of the platform (Unix/Windows,
+Safe Mode or not, and so on). So, you must have Zlib/Bzip2 support
+(``--with-zlib`` and ``--with-bz2``).
+
+.. _faq1_8:
+
+1.8 I cannot insert a text file in a table, and I get an error about safe mode being in effect.
+-----------------------------------------------------------------------------------------------
+
+Your uploaded file is saved by PHP in the "upload dir", as defined in
+:file:`php.ini` by the variable ``upload_tmp_dir`` (usually the system
+default is */tmp*). We recommend the following setup for Apache
+servers running in safe mode, to enable uploads of files while being
+reasonably secure:
+
+* create a separate directory for uploads: :command:`mkdir /tmp/php`
+* give ownership to the Apache server's user.group: :command:`chown
+  apache.apache /tmp/php`
+* give proper permission: :command:`chmod 600 /tmp/php`
+* put ``upload_tmp_dir = /tmp/php`` in :file:`php.ini`
+* restart Apache
+
+.. _faq1_9:
+
+1.9 (withdrawn).
+----------------
+
+.. _faq1_10:
+
+1.10 I'm having troubles when uploading files with phpMyAdmin running on a secure server. My browser is Internet Explorer and I'm using the Apache server.
+----------------------------------------------------------------------------------------------------------------------------------------------------------
+
+As suggested by "Rob M" in the phpWizard forum, add this line to your
+*httpd.conf*:
+
+.. code-block:: apache
+
+    SetEnvIf User-Agent ".*MSIE.*" nokeepalive ssl-unclean-shutdown
+
+It seems to clear up many problems between Internet Explorer and SSL.
+
+.. _faq1_11:
+
+1.11 I get an 'open\_basedir restriction' while uploading a file from the query box.
+------------------------------------------------------------------------------------
+
+Since version 2.2.4, phpMyAdmin supports servers with open\_basedir
+restrictions. However you need to create temporary directory and configure it
+as :config:option:`$cfg['TempDir']`. The uploaded files will be moved there,
+and after execution of your :term:`SQL` commands, removed.
+
+.. _faq1_12:
+
+1.12 I have lost my MySQL root password, what can I do?
+-------------------------------------------------------
+
+The MySQL manual explains how to `reset the permissions
+<http://dev.mysql.com/doc/mysql/en/resetting-permissions.html>`_.
+
+.. _faq1_13:
+
+1.13 (withdrawn).
+-----------------
+
+.. _faq1_14:
+
+1.14 (withdrawn).
+-----------------
+
+.. _faq1_15:
+
+1.15 I have problems with *mysql.user* column names.
+----------------------------------------------------
+
+In previous MySQL versions, the ``User`` and ``Password``columns were
+named ``user`` and ``password``. Please modify your column names to
+align with current standards.
+
+.. _faq1_16:
+
+1.16 I cannot upload big dump files (memory, HTTP or timeout problems).
+-----------------------------------------------------------------------
+
+Starting with version 2.7.0, the import engine has been re–written and
+these problems should not occur. If possible, upgrade your phpMyAdmin
+to the latest version to take advantage of the new import features.
+
+The first things to check (or ask your host provider to check) are the
+values of ``upload_max_filesize``, ``memory_limit`` and
+``post_max_size`` in the :file:`php.ini` configuration file. All of these
+three settings limit the maximum size of data that can be submitted
+and handled by PHP. One user also said that ``post_max_size`` and
+``memory_limit`` need to be larger than ``upload_max_filesize``.
+There exist several workarounds if your upload is too big or your
+hosting provider is unwilling to change the settings:
+
+* Look at the :config:option:`$cfg['UploadDir']` feature. This allows one to upload a file to the server
+  via scp, ftp, or your favorite file transfer method. PhpMyAdmin is
+  then able to import the files from the temporary directory. More
+  information is available in the :ref:`config`  of this document.
+* Using a utility (such as `BigDump
+  <http://www.ozerov.de/bigdump.php>`_) to split the files before
+  uploading. We cannot support this or any third party applications, but
+  are aware of users having success with it.
+* If you have shell (command line) access, use MySQL to import the files
+  directly. You can do this by issuing the "source" command from within
+  MySQL:
+
+  .. code-block:: mysql
+
+    source filename.sql;
+
+.. _faq1_17:
+
+1.17 Which MySQL versions does phpMyAdmin support?
+--------------------------------------------------
+
+Since phpMyAdmin 3.0.x, only MySQL 5.0.1 and newer are supported. For
+older MySQL versions, you need to use the latest 2.x branch.
+phpMyAdmin can connect to your MySQL server using PHP's classic `MySQL
+extension <http://php.net/mysql>`_ as well as the `improved MySQL
+extension (MySQLi) <http://php.net/mysqli>`_ that is available in PHP
+5.0. The latter one should be used unless you have a good reason not
+to do so. When compiling PHP, we strongly recommend that you manually
+link the MySQL extension of your choice to a MySQL client library of
+at least the same minor version since the one that is bundled with
+some PHP distributions is rather old and might cause problems see
+:ref:`faq1_17a`. `MariaDB <http://mariadb.org/>`_ is also supported
+(versions 5.1 and 5.2 were tested). 
+
+.. versionchanged:: 3.5
+    Since phpMyAdmin 3.5 `Drizzle <http://www.drizzle.org/>`_ is supported.
+
+.. _faq1_17a:
+
+1.17a I cannot connect to the MySQL server. It always returns the error message, "Client does not support authentication protocol requested by server; consider upgrading MySQL client"
+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
+
+You tried to access MySQL with an old MySQL client library. The
+version of your MySQL client library can be checked in your phpinfo()
+output. In general, it should have at least the same minor version as
+your server - as mentioned in :ref:`faq1_17`. This problem is
+generally caused by using MySQL version 4.1 or newer. MySQL changed
+the authentication hash and your PHP is trying to use the old method.
+The proper solution is to use the `mysqli extension
+<http://www.php.net/mysqli>`_ with the proper client library to match
+your MySQL installation. Your chosen extension is specified in 
+:config:option:`$cfg['Servers'][$i]['extension']`. More
+information (and several workarounds) are located in the `MySQL
+Documentation <http://dev.mysql.com/doc/mysql/en/old-client.html>`_.
+
+.. _faq1_18:
+
+1.18 (withdrawn).
+-----------------
+
+.. _faq1_19:
+
+1.19 I can't run the "display relations" feature because the script seems not to know the font face I'm using!
+--------------------------------------------------------------------------------------------------------------
+
+The :term:`TCPDF` library we're using for this feature requires some special
+files to use font faces. Please refers to the `TCPDF manual
+<http://www.tcpdf.org/>`_ to build these files.
+
+.. _faqmysql:
+
+1.20 I receive the error "cannot load MySQL extension, please check PHP Configuration".
+---------------------------------------------------------------------------------------
+
+To connect to a MySQL server, PHP needs a set of MySQL functions
+called "MySQL extension". This extension may be part of the PHP
+distribution (compiled-in), otherwise it needs to be loaded
+dynamically. Its name is probably *mysql.so* or *php\_mysql.dll*.
+phpMyAdmin tried to load the extension but failed. Usually, the
+problem is solved by installing a software package called "PHP-MySQL"
+or something similar.
+
+.. _faq1_21:
+
+1.21 I am running the CGI version of PHP under Unix, and I cannot log in using cookie auth.
+-------------------------------------------------------------------------------------------
+
+In :file:`php.ini`, set ``mysql.max_links`` higher than 1.
+
+.. _faq1_22:
+
+1.22 I don't see the "Location of text file" field, so I cannot upload.
+-----------------------------------------------------------------------
+
+This is most likely because in :file:`php.ini`, your ``file_uploads``
+parameter is not set to "on".
+
+.. _faq1_23:
+
+1.23 I'm running MySQL on a Win32 machine. Each time I create a new table the table and column names are changed to lowercase!
+------------------------------------------------------------------------------------------------------------------------------
+
+This happens because the MySQL directive ``lower_case_table_names``
+defaults to 1 (``ON``) in the Win32 version of MySQL. You can change
+this behavior by simply changing the directive to 0 (``OFF``): Just
+edit your ``my.ini`` file that should be located in your Windows
+directory and add the following line to the group [mysqld]:
+
+.. code-block:: ini
+
+    set-variable = lower_case_table_names=0
+
+Next, save the file and restart the MySQL service. You can always
+check the value of this directive using the query
+
+.. code-block:: mysql
+
+    SHOW VARIABLES LIKE 'lower_case_table_names';
+
+.. _faq1_24:
+
+1.24 (withdrawn).
+-----------------
+
+.. _faq1_25:
+
+1.25 I am running Apache with mod\_gzip-1.3.26.1a on Windows XP, and I get problems, such as undefined variables when I run a SQL query.
+----------------------------------------------------------------------------------------------------------------------------------------
+
+A tip from Jose Fandos: put a comment on the following two lines in
+httpd.conf, like this:
+
+.. code-block:: apache
+
+    
+    # mod_gzip_item_include file \.php$
+    # mod_gzip_item_include mime "application/x-httpd-php.*"
+
+as this version of mod\_gzip on Apache (Windows) has problems handling
+PHP scripts. Of course you have to restart Apache.
+
+.. _faq1_26:
+
+1.26 I just installed phpMyAdmin in my document root of IIS but I get the error "No input file specified" when trying to run phpMyAdmin.
+----------------------------------------------------------------------------------------------------------------------------------------
+
+This is a permission problem. Right-click on the phpmyadmin folder and
+choose properties. Under the tab Security, click on "Add" and select
+the user "IUSR\_machine" from the list. Now set his permissions and it
+should work.
+
+.. _faq1_27:
+
+1.27 I get empty page when I want to view huge page (eg. db\_structure.php with plenty of tables).
+--------------------------------------------------------------------------------------------------
+
+This was caused by a `PHP bug <http://bugs.php.net/21079>`_ that occur when
+GZIP output buffering is enabled. If you turn off it (by
+:config:option:`$cfg['OBGzip']` in :file:`config.inc.php`), it should work.
+This bug will has been fixed in PHP 5.0.0.
+
+.. _faq1_28:
+
+1.28 My MySQL server sometimes refuses queries and returns the message 'Errorcode: 13'. What does this mean?
+------------------------------------------------------------------------------------------------------------
+
+This can happen due to a MySQL bug when having database / table names
+with upper case characters although ``lower_case_table_names`` is
+set to 1. To fix this, turn off this directive, convert all database
+and table names to lower case and turn it on again. Alternatively,
+there's a bug-fix available starting with MySQL 3.23.56 /
+4.0.11-gamma.
+
+.. _faq1_29:
+
+1.29 When I create a table or modify a column, I get an error and the columns are duplicated.
+---------------------------------------------------------------------------------------------
+
+It is possible to configure Apache in such a way that PHP has problems
+interpreting .php files.
+
+The problems occur when two different (and conflicting) set of
+directives are used:
+
+.. code-block:: apache
+
+    
+    SetOutputFilter PHP
+    SetInputFilter PHP
+
+and
+
+.. code-block:: apache
+
+    AddType application/x-httpd-php .php
+
+In the case we saw, one set of directives was in
+``/etc/httpd/conf/httpd.conf``, while the other set was in
+``/etc/httpd/conf/addon-modules/php.conf``. The recommended way is
+with ``AddType``, so just comment out the first set of lines and
+restart Apache:
+
+.. code-block:: apache
+
+    
+    #SetOutputFilter PHP
+    #SetInputFilter PHP
+
+.. _faq1_30:
+
+1.30 I get the error "navigation.php: Missing hash".
+----------------------------------------------------
+
+This problem is known to happen when the server is running Turck
+MMCache but upgrading MMCache to version 2.3.21 solves the problem.
+
+.. _faq1_31:
+
+1.31 Does phpMyAdmin support PHP 5?
+-----------------------------------
+
+Yes.
+
+Since release 3.0 only PHP 5.2 and newer. For older PHP versions, use
+phpMyAdmin 2.11.x.
+
+.. _faq1_32:
+
+1.32 Can I use HTTP authentication with IIS?
+--------------------------------------------
+
+Yes. This procedure was tested with phpMyAdmin 2.6.1, PHP 4.3.9 in
+:term:`ISAPI` mode under :term:`IIS` 5.1.
+
+#. In your :file:`php.ini` file, set ``cgi.rfc2616_headers = 0``
+#. In ``Web Site Properties -> File/Directory Security -> Anonymous
+   Access`` dialog box, check the ``Anonymous access`` checkbox and
+   uncheck any other checkboxes (i.e. uncheck ``Basic authentication``,
+   ``Integrated Windows authentication``, and ``Digest`` if it's
+   enabled.) Click ``OK``.
+#. In ``Custom Errors``, select the range of ``401;1`` through ``401;5``
+   and click the ``Set to Default`` button.
+
+.. seealso:: :rfc:`2616`
+
+.. _faq1_33:
+
+1.33 (withdrawn).
+-----------------
+
+.. _faq1_34:
+
+1.34 Can I access directly to database or table pages?
+------------------------------------------------------
+
+Yes. Out of the box, you can use :term:`URL` like http://server/phpMyAdmin/index.php?server=X&db=databas
+e&table=table&target=script. For ``server`` you use the server number
+which refers to the order of the server paragraph in
+:file:`config.inc.php`. Table and script parts are optional. If you want
+http://server/phpMyAdmin/database[/table][/script] :term:`URL`, you need to do some configuration. Following
+lines apply only for `Apache <http://httpd.apache.org>`_ web server.
+First make sure, that you have enabled some features within global
+configuration. You need ``Options FollowSymLinks`` and ``AllowOverride
+FileInfo`` enabled for directory where phpMyAdmin is installed and you
+need mod\_rewrite to be enabled. Then you just need to create
+following :term:`.htaccess` file in root folder of phpMyAdmin installation (don't
+forget to change directory name inside of it):
+
+.. code-block:: apache
+
+    
+    RewriteEngine On
+    RewriteBase /path_to_phpMyAdmin
+    RewriteRule ^([a-zA-Z0-9_]+)/([a-zA-Z0-9_]+)/([a-z_]+\.php)$ index.php?db=$1&table=$2&target=$3 [R]
+    RewriteRule ^([a-zA-Z0-9_]+)/([a-z_]+\.php)$ index.php?db=$1&target=$2 [R]
+    RewriteRule ^([a-zA-Z0-9_]+)/([a-zA-Z0-9_]+)$ index.php?db=$1&table=$2 [R]
+    RewriteRule ^([a-zA-Z0-9_]+)$ index.php?db=$1 [R]
+
+.. _faq1_35:
+
+1.35 Can I use HTTP authentication with Apache CGI?
+---------------------------------------------------
+
+Yes. However you need to pass authentication variable to :term:`CGI` using
+following rewrite rule:
+
+.. code-block:: apache
+
+    
+    RewriteEngine On
+    RewriteRule .* - [E=REMOTE_USER:%{HTTP:Authorization},L]
+
+.. _faq1_36:
+
+1.36 I get an error "500 Internal Server Error".
+------------------------------------------------
+
+There can be many explanations to this and a look at your server's
+error log file might give a clue.
+
+.. _faq1_37:
+
+1.37 I run phpMyAdmin on cluster of different machines and password encryption in cookie auth doesn't work.
+-----------------------------------------------------------------------------------------------------------
+
+If your cluster consist of different architectures, PHP code used for
+encryption/decryption won't work correct. This is caused by use of
+pack/unpack functions in code. Only solution is to use mcrypt
+extension which works fine in this case.
+
+.. _faq1_38:
+
+1.38 Can I use phpMyAdmin on a server on which Suhosin is enabled?
+------------------------------------------------------------------
+
+Yes but the default configuration values of Suhosin are known to cause
+problems with some operations, for example editing a table with many
+columns and no primary key or with textual primary key.
+
+Suhosin configuration might lead to malfunction in some cases and it
+can not be fully avoided as phpMyAdmin is kind of application which
+needs to transfer big amounts of columns in single HTTP request, what
+is something what Suhosin tries to prevent. Generally all
+``suhosin.request.*``, ``suhosin.post.*`` and ``suhosin.get.*``
+directives can have negative effect on phpMyAdmin usability. You can
+always find in your error logs which limit did cause dropping of
+variable, so you can diagnose the problem and adjust matching
+configuration variable.
+
+The default values for most Suhosin configuration options will work in
+most scenarios, however you might want to adjust at least following
+parameters:
+
+* `suhosin.request.max\_vars <http://www.hardened-
+  php.net/suhosin/configuration.html#suhosin.request.max_vars>`_ should
+  be increased (eg. 2048)
+* `suhosin.post.max\_vars <http://www.hardened-
+  php.net/suhosin/configuration.html#suhosin.post.max_vars>`_ should be
+  increased (eg. 2048)
+* `suhosin.request.max\_array\_index\_length <http://www.hardened-php.ne
+  t/suhosin/configuration.html#suhosin.request.max_array_index_length>`_
+  should be increased (eg. 256)
+* `suhosin.post.max\_array\_index\_length <http://www.hardened-php.net/s
+  uhosin/configuration.html#suhosin.post.max_array_index_length>`_
+  should be increased (eg. 256)
+* `suhosin.request.max\_totalname\_length <http://www.hardened-php.net/s
+  uhosin/configuration.html#suhosin.request.max_totalname_length>`_
+  should be increased (eg. 8192)
+* `suhosin.post.max\_totalname\_length <http://www.hardened-php.net/suho
+  sin/configuration.html#suhosin.post.max_totalname_length>`_ should be
+  increased (eg. 8192)
+* `suhosin.get.max\_value\_length <http://www.hardened-
+  php.net/suhosin/configuration.html#suhosin.get.max_value_length>`_
+  should be increased (eg. 1024)
+* `suhosin.sql.bailout\_on\_error <http://www.hardened-
+  php.net/suhosin/configuration.html#suhosin.sql.bailout_on_error>`_
+  needs to be disabled (the default)
+* `suhosin.log.\* <http://www.hardened-
+  php.net/suhosin/configuration.html#logging_configuration>`_ should not
+  include :term:`SQL`, otherwise you get big
+  slowdown
+
+You can also disable the warning using the :config:option:`$cfg['SuhosinDisableWarning']`.
+
+.. _faq1_39:
+
+1.39 When I try to connect via https, I can log in, but then my connection is redirected back to http. What can cause this behavior?
+------------------------------------------------------------------------------------------------------------------------------------
+
+Be sure that you have enabled ``SSLOptions`` and ``StdEnvVars`` in
+your Apache configuration. 
+
+.. seealso:: <http://httpd.apache.org/docs/2.0/mod/mod_ssl.html#ssloptions>
+
+.. _faq1_40:
+
+1.40 When accessing phpMyAdmin via an Apache reverse proxy, cookie login does not work.
+---------------------------------------------------------------------------------------
+
+To be able to use cookie auth Apache must know that it has to rewrite
+the set-cookie headers. Example from the Apache 2.2 documentation:
+
+.. code-block:: apache
+
+    
+    ProxyPass /mirror/foo/ http://backend.example.com/
+    ProxyPassReverse /mirror/foo/ http://backend.example.com/
+    ProxyPassReverseCookieDomain backend.example.com public.example.com
+    ProxyPassReverseCookiePath / /mirror/foo/
+
+Note: if the backend url looks like http://host/~user/phpmyadmin, the
+tilde (~) must be url encoded as %7E in the ProxyPassReverse\* lines.
+This is not specific to phpmyadmin, it's just the behavior of Apache.
+
+.. code-block:: apache
+
+    
+    ProxyPass /mirror/foo/ http://backend.example.com/~user/phpmyadmin
+    ProxyPassReverse /mirror/foo/ http://backend.example.com/%7Euser/phpmyadmin
+    ProxyPassReverseCookiePath /%7Euser/phpmyadmin /mirror/foo
+
+.. seealso:: <http://httpd.apache.org/docs/2.2/mod/mod_proxy.html>
+
+.. _faq1_41:
+
+1.41 When I view a database and ask to see its privileges, I get an error about an unknown column.
+--------------------------------------------------------------------------------------------------
+
+The MySQL server's privilege tables are not up to date, you need to
+run the :command:`mysql_upgrade` command on the server.
+
+.. _faq1_42:
+
+1.42 How can I prevent robots from accessing phpMyAdmin?
+--------------------------------------------------------
+
+You can add various rules to :term:`.htaccess` to filter access based on user agent
+field. This is quite easy to circumvent, but could prevent at least
+some robots accessing your installation.
+
+.. code-block:: apache
+
+    
+    RewriteEngine on
+    
+    # Allow only GET and POST verbs
+    RewriteCond %{REQUEST_METHOD} !^(GET|POST)$ [NC,OR]
+    
+    # Ban Typical Vulnerability Scanners and others
+    # Kick out Script Kiddies
+    RewriteCond %{HTTP_USER_AGENT} ^(java|curl|wget).* [NC,OR]
+    RewriteCond %{HTTP_USER_AGENT} ^.*(libwww-perl|curl|wget|python|nikto|wkito|pikto|scan|acunetix).* [NC,OR]
+    RewriteCond %{HTTP_USER_AGENT} ^.*(winhttp|HTTrack|clshttp|archiver|loader|email|harvest|extract|grab|miner).* [NC,OR]
+    
+    # Ban Search Engines, Crawlers to your administrative panel
+    # No reasons to access from bots
+    # Ultimately Better than the useless robots.txt
+    # Did google respect robots.txt?
+    # Try google: intitle:phpMyAdmin intext:"Welcome to phpMyAdmin *.*.*" intext:"Log in" -wiki -forum -forums -questions intext:"Cookies must be enabled"
+    RewriteCond %{HTTP_USER_AGENT} ^.*(AdsBot-Google|ia_archiver|Scooter|Ask.Jeeves|Baiduspider|Exabot|FAST.Enterprise.Crawler|FAST-WebCrawler|www\.neomo\.de|Gigabot|Mediapartners-Google|Google.Desktop|Feedfetcher-Google|Googlebot|heise-IT-Markt-Crawler|heritrix|ibm.com\cs/crawler|ICCrawler|ichiro|MJ12bot|MetagerBot|msnbot-NewsBlogs|msnbot|msnbot-media|NG-Search|lucene.apache.org|NutchCVS|OmniExplorer_Bot|online.link.validator|psbot0|Seekbot|Sensis.Web.Crawler|SEO.search.Crawler|Seoma.\[ [...]
+    RewriteRule .* - [F]
+
+.. _faq1_43:
+
+1.43 Why can't I display the structure of my table containing hundreds of columns? 
+----------------------------------------------------------------------------------
+
+Because your PHP's ``memory_limit`` is too low; adjust it in :file:`php.ini`.
+
+.. _faqconfig:
+
+Configuration
++++++++++++++
+
+.. _faq2_1:
+
+2.1 The error message "Warning: Cannot add header information - headers already sent by ..." is displayed, what's the problem?
+------------------------------------------------------------------------------------------------------------------------------
+
+Edit your :file:`config.inc.php` file and ensure there is nothing (I.E. no
+blank lines, no spaces, no characters...) neither before the ``<?php`` tag at
+the beginning, neither after the ``?>`` tag at the end. We also got a report
+from a user under :term:`IIS`, that used a zipped distribution kit: the file
+:file:`libraries/Config.class.php` contained an end-of-line character (hex 0A)
+at the end; removing this character cleared his errors.
+
+.. _faq2_2:
+
+2.2 phpMyAdmin can't connect to MySQL. What's wrong?
+----------------------------------------------------
+
+Either there is an error with your PHP setup or your username/password
+is wrong. Try to make a small script which uses mysql\_connect and see
+if it works. If it doesn't, it may be you haven't even compiled MySQL
+support into PHP.
+
+.. _faq2_3:
+
+2.3 The error message "Warning: MySQL Connection Failed: Can't connect to local MySQL server through socket '/tmp/mysql.sock' (111) ..." is displayed. What can I do?
+---------------------------------------------------------------------------------------------------------------------------------------------------------------------
+
+For RedHat users, Harald Legner suggests this on the mailing list:
+
+On my RedHat-Box the socket of MySQL is */var/lib/mysql/mysql.sock*.
+In your :file:`php.ini` you will find a line
+
+.. code-block:: ini
+
+    mysql.default_socket = /tmp/mysql.sock
+
+change it to
+
+.. code-block:: ini
+
+    mysql.default_socket = /var/lib/mysql/mysql.sock
+
+Then restart apache and it will work.
+
+Here is a fix suggested by Brad Ummer:
+
+* First, you need to determine what socket is being used by MySQL. To do
+  this, telnet to your server and go to the MySQL bin directory. In this
+  directory there should be a file named *mysqladmin*. Type
+  ``./mysqladmin variables``, and this should give you a bunch of info
+  about your MySQL server, including the socket (*/tmp/mysql.sock*, for
+  example).
+* Then, you need to tell PHP to use this socket. To do this in
+  phpMyAdmin, you need to complete the socket information in the
+  :file:`config.inc.php`. For example:
+  :config:option:`$cfg['Servers'][$i]['socket']`  Please also make sure that
+  the permissions of this file allow to be readable by your webserver (i.e.
+  '0755').
+
+Have also a look at the `corresponding section of the MySQL
+documentation <http://dev.mysql.com/doc/en/can-not-connect-to-
+server.html>`_.
+
+.. _faq2_4:
+
+2.4 Nothing is displayed by my browser when I try to run phpMyAdmin, what can I do?
+-----------------------------------------------------------------------------------
+
+Try to set the :config:option:`$cfg['OBGzip']` directive to ``false`` in the phpMyAdmin configuration
+file. It helps sometime. Also have a look at your PHP version number:
+if it contains "b" or "alpha" it means you're running a testing
+version of PHP. That's not a so good idea, please upgrade to a plain
+revision.
+
+.. _faq2_5:
+
+2.5 Each time I want to insert or change a row or drop a database or a table, an error 404 (page not found) is displayed or, with HTTP or cookie authentication, I'm asked to log in again. What's wrong?
+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
+
+Check the value you set for the :config:option:`$cfg['PmaAbsoluteUri']` directive in the phpMyAdmin
+configuration file.
+
+.. _faq2_6:
+
+2.6 I get an "Access denied for user: 'root at localhost' (Using password: YES)"-error when trying to access a MySQL-Server on a host which is port-forwarded for my localhost.
+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
+
+When you are using a port on your localhost, which you redirect via
+port-forwarding to another host, MySQL is not resolving the localhost
+as expected. Erik Wasser explains: The solution is: if your host is
+"localhost" MySQL (the command line tool :command:`mysql` as well) always
+tries to use the socket connection for speeding up things. And that
+doesn't work in this configuration with port forwarding. If you enter
+"127.0.0.1" as hostname, everything is right and MySQL uses the
+:term:`TCP` connection.
+
+.. _faqthemes:
+
+2.7 Using and creating themes
+-----------------------------
+
+Themes are configured with :config:option:`$cfg['ThemePath']`,
+:config:option:`$cfg['ThemeManager']` and :config:option:`$cfg['ThemeDefault']`.  
+Under :config:option:`$cfg['ThemePath']`, you should not delete the
+directory ``pmahomme`` or its underlying structure, because this is the
+system theme used by phpMyAdmin. ``pmahomme`` contains all images and
+styles, for backwards compatibility and for all themes that would not
+include images or css-files.  If :config:option:`$cfg['ThemeManager']`
+is enabled, you can select your favorite theme on the main page. Your selected
+theme will be stored in a cookie.
+
+To create a theme:
+
+* make a new subdirectory (for example "your\_theme\_name") under :config:option:`$cfg['ThemePath']` (by
+  default ``themes``)
+* copy the files and directories from ``pmahomme`` to "your\_theme\_name"
+* edit the css-files in "your\_theme\_name/css"
+* put your new images in "your\_theme\_name/img"
+* edit :file:`layout.inc.php` in "your\_theme\_name"
+* edit :file:`info.inc.php` in "your\_theme\_name" to contain your chosen
+  theme name, that will be visible in user interface
+* make a new screenshot of your theme and save it under
+  "your\_theme\_name/screen.png"
+
+In theme directory there is file :file:`info.inc.php` which contains theme
+verbose name, theme generation and theme version. These versions and
+generations are enumerated from 1 and do not have any direct
+dependence on phpMyAdmin version. Themes within same generation should
+be backwards compatible - theme with version 2 should work in
+phpMyAdmin requiring version 1. Themes with different generation are
+incompatible.
+
+If you do not want to use your own symbols and buttons, remove the
+directory "img" in "your\_theme\_name". phpMyAdmin will use the
+default icons and buttons (from the system-theme ``pmahomme``).
+
+.. _faqmissingparameters:
+
+2.8 I get "Missing parameters" errors, what can I do?
+-----------------------------------------------------
+
+Here are a few points to check:
+
+* In :file:`config.inc.php`, try to leave the :config:option:`$cfg['PmaAbsoluteUri']` directive empty. See also
+  :ref:`faq4_7`.
+* Maybe you have a broken PHP installation or you need to upgrade your
+  Zend Optimizer. See <http://bugs.php.net/bug.php?id=31134>.
+* If you are using Hardened PHP with the ini directive
+  ``varfilter.max_request_variables`` set to the default (200) or
+  another low value, you could get this error if your table has a high
+  number of columns. Adjust this setting accordingly. (Thanks to Klaus
+  Dorninger for the hint).
+* In the :file:`php.ini` directive ``arg_separator.input``, a value of ";"
+  will cause this error. Replace it with "&;".
+* If you are using `Hardened-PHP <http://www.hardened-php.net/>`_, you
+  might want to increase `request limits <http://www.hardened-
+  php.net/hphp/troubleshooting.html>`_.
+* The directory specified in the :file:`php.ini` directive
+  ``session.save_path`` does not exist or is read-only.
+
+.. _faq2_9:
+
+2.9 Seeing an upload progress bar
+---------------------------------
+
+To be able to see a progress bar during your uploads, your server must
+have the `APC <http://pecl.php.net/package/APC>`_ extension, the
+`uploadprogress <http://pecl.php.net/package/uploadprogress>`_ one, or
+you must be running PHP 5.4.0 or higher. Moreover, the JSON extension
+has to be enabled in your PHP.
+
+If using APC, you must set ``apc.rfc1867`` to ``on`` in your :file:`php.ini`.
+
+If using PHP 5.4.0 or higher, you must set
+``session.upload_progress.enabled`` to ``1`` in your :file:`php.ini`. However,
+starting from phpMyAdmin version 4.0.4, session-based upload progress has
+been temporarily deactivated due to its problematic behavior. 
+
+.. seealso:: :rfc:`1867`
+
+.. _faqlimitations:
+
+Known limitations
++++++++++++++++++
+
+.. _login_bug:
+
+3.1 When using HTTP authentication, a user who logged out can not log in again in with the same nick.
+-----------------------------------------------------------------------------------------------------
+
+This is related to the authentication mechanism (protocol) used by
+phpMyAdmin. To bypass this problem: just close all the opened browser
+windows and then go back to phpMyAdmin. You should be able to log in
+again.
+
+.. _faq3_2:
+
+3.2 When dumping a large table in compressed mode, I get a memory limit error or a time limit error.
+----------------------------------------------------------------------------------------------------
+
+Compressed dumps are built in memory and because of this are limited
+to php's memory limit. For GZip/BZip2 exports this can be overcome
+since 2.5.4 using :config:option:`$cfg['CompressOnFly']` (enabled by default).
+Zip exports can not be handled this way, so if you need Zip files for larger
+dump, you have to use another way.
+
+.. _faq3_3:
+
+3.3 With InnoDB tables, I lose foreign key relationships when I rename a table or a column.
+-------------------------------------------------------------------------------------------
+
+This is an InnoDB bug, see <http://bugs.mysql.com/bug.php?id=21704>.
+
+.. _faq3_4:
+
+3.4 I am unable to import dumps I created with the mysqldump tool bundled with the MySQL server distribution.
+-------------------------------------------------------------------------------------------------------------
+
+The problem is that older versions of ``mysqldump`` created invalid
+comments like this:
+
+.. code-block:: mysql
+
+    
+    -- MySQL dump 8.22
+    --
+    -- Host: localhost Database: database
+    ---------------------------------------------------------
+    -- Server version 3.23.54
+
+The invalid part of the code is the horizontal line made of dashes
+that appears once in every dump created with mysqldump. If you want to
+run your dump you have to turn it into valid MySQL. This means, you
+have to add a whitespace after the first two dashes of the line or add
+a # before it:  ``-- -------------------------------------------------------`` or
+``#---------------------------------------------------------``
+
+.. _faq3_5:
+
+3.5 When using nested folders, multiple hierarchies are displayed in a wrong manner.
+------------------------------------------------------------------------------------
+
+Please note that you should not use the separating string multiple
+times without any characters between them, or at the beginning/end of
+your table name. If you have to, think about using another
+TableSeparator or disabling that feature.
+
+.. seealso:: :config:option:`$cfg['NavigationTreeTableSeparator']`
+
+.. _faq3_6:
+
+3.6 What is currently not supported in phpMyAdmin about InnoDB?
+---------------------------------------------------------------
+
+In Relation view, being able to choose a table in another database, or
+having more than one index column in the foreign key. In Query-by-
+example (Query), automatic generation of the query LEFT JOIN from the
+foreign table.
+
+.. _faq3_7:
+
+3.7 I have table with many (100+) columns and when I try to browse table I get series of errors like "Warning: unable to parse url". How can this be fixed?
+-----------------------------------------------------------------------------------------------------------------------------------------------------------
+
+Your table neither have a primary key nor an unique one, so we must
+use a long expression to identify this row. This causes problems to
+parse\_url function. The workaround is to create a primary or unique
+key.
+
+.. _faq3_8:
+
+3.8 I cannot use (clickable) HTML-forms in columns where I put a MIME-Transformation onto!
+------------------------------------------------------------------------------------------
+
+Due to a surrounding form-container (for multi-row delete checkboxes),
+no nested forms can be put inside the table where phpMyAdmin displays
+the results. You can, however, use any form inside of a table if keep
+the parent form-container with the target to tbl\_row\_delete.php and
+just put your own input-elements inside. If you use a custom submit
+input field, the form will submit itself to the displaying page again,
+where you can validate the $HTTP\_POST\_VARS in a transformation. For
+a tutorial on how to effectively use transformations, see our `Link
+section <http://www.phpmyadmin.net/home_page/docs.php>`_ on the
+official phpMyAdmin-homepage.
+
+.. _faq3_9:
+
+3.9 I get error messages when using "--sql\_mode=ANSI" for the MySQL server.
+----------------------------------------------------------------------------
+
+When MySQL is running in ANSI-compatibility mode, there are some major
+differences in how :term:`SQL` is structured (see
+<http://dev.mysql.com/doc/mysql/en/ansi-mode.html>). Most important of all, the
+quote-character (") is interpreted as an identifier quote character and not as
+a string quote character, which makes many internal phpMyAdmin operations into
+invalid :term:`SQL` statements. There is no
+workaround to this behaviour.  News to this item will be posted in `Bug report
+#1013 <https://sourceforge.net/p/phpmyadmin/bugs/1013/>`_.
+
+.. _faq3_10:
+
+3.10 Homonyms and no primary key: When the results of a SELECT display more that one column with the same value (for example ``SELECT lastname from employees where firstname like 'A%'`` and two "Smith" values are displayed), if I click Edit I cannot be sure that I am editing the intended row.
+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
+
+Please make sure that your table has a primary key, so that phpMyAdmin
+can use it for the Edit and Delete links.
+
+.. _faq3_11:
+
+3.11 The number of rows for InnoDB tables is not correct.
+---------------------------------------------------------
+
+phpMyAdmin uses a quick method to get the row count, and this method only
+returns an approximate count in the case of InnoDB tables. See
+:config:option:`$cfg['MaxExactCount']` for a way to modify those results, but
+this could have a serious impact on performance.
+
+.. _faq3_12:
+
+3.12 (withdrawn).
+-----------------
+
+.. _faq3_13:
+
+3.13 I get an error when entering ``USE`` followed by a db name containing an hyphen.
+-------------------------------------------------------------------------------------
+
+The tests I have made with MySQL 5.1.49 shows that the API does not
+accept this syntax for the USE command.
+
+.. _faq3_14:
+
+3.14 I am not able to browse a table when I don't have the right to SELECT one of the columns.
+----------------------------------------------------------------------------------------------
+
+This has been a known limitation of phpMyAdmin since the beginning and
+it's not likely to be solved in the future.
+
+.. _faq3_15:
+
+3.15 (withdrawn).
+-----------------
+
+.. _faq3_16:
+
+3.16 (withdrawn).
+-----------------
+
+.. _faq3_17:
+
+3.17 (withdrawn).
+-----------------
+
+.. _faq3_18:
+
+3.18 When I import a CSV file that contains multiple tables, they are lumped together into a single table.
+----------------------------------------------------------------------------------------------------------
+
+There is no reliable way to differentiate tables in :term:`CSV` format. For the
+time being, you will have to break apart :term:`CSV` files containing multiple
+tables.
+
+.. _faq3_19:
+
+3.19 When I import a file and have phpMyAdmin determine the appropriate data structure it only uses int, decimal, and varchar types.
+------------------------------------------------------------------------------------------------------------------------------------
+
+Currently, the import type-detection system can only assign these
+MySQL types to columns. In future, more will likely be added but for
+the time being you will have to edit the structure to your liking
+post-import.  Also, you should note the fact that phpMyAdmin will use
+the size of the largest item in any given column as the column size
+for the appropriate type. If you know you will be adding larger items
+to that column then you should manually adjust the column sizes
+accordingly. This is done for the sake of efficiency.
+
+.. _faqmultiuser:
+
+ISPs, multi-user installations
+++++++++++++++++++++++++++++++
+
+.. _faq4_1:
+
+4.1 I'm an ISP. Can I setup one central copy of phpMyAdmin or do I need to install it for each customer?
+--------------------------------------------------------------------------------------------------------
+
+Since version 2.0.3, you can setup a central copy of phpMyAdmin for all your
+users. The development of this feature was kindly sponsored by NetCologne GmbH.
+This requires a properly setup MySQL user management and phpMyAdmin
+:term:`HTTP` or cookie authentication. 
+
+.. seealso:: :ref:`authentication_modes`
+
+.. _faq4_2:
+
+4.2 What's the preferred way of making phpMyAdmin secure against evil access?
+-----------------------------------------------------------------------------
+
+This depends on your system. If you're running a server which cannot be
+accessed by other people, it's sufficient to use the directory protection
+bundled with your webserver (with Apache you can use :term:`.htaccess` files,
+for example). If other people have telnet access to your server, you should use
+phpMyAdmin's :term:`HTTP` or cookie authentication features.  
+    
+Suggestions:
+
+* Your :file:`config.inc.php` file should be ``chmod 660``.
+* All your phpMyAdmin files should be chown -R phpmy.apache, where phpmy
+  is a user whose password is only known to you, and apache is the group
+  under which Apache runs.
+* Follow security recommendations for PHP and your webserver.
+
+.. _faq4_3:
+
+4.3 I get errors about not being able to include a file in */lang* or in */libraries*.
+--------------------------------------------------------------------------------------
+
+Check :file:`php.ini`, or ask your sysadmin to check it. The
+``include_path`` must contain "." somewhere in it, and
+``open_basedir``, if used, must contain "." and "./lang" to allow
+normal operation of phpMyAdmin.
+
+.. _faq4_4:
+
+4.4 phpMyAdmin always gives "Access denied" when using HTTP authentication.
+---------------------------------------------------------------------------
+
+This could happen for several reasons:
+
+* :config:option:`$cfg['Servers'][$i]['controluser']` and/or :config:option:`$cfg['Servers'][$i]['controlpass']`  are wrong.
+* The username/password you specify in the login dialog are invalid.
+* You have already setup a security mechanism for the phpMyAdmin-
+  directory, eg. a :term:`.htaccess` file. This would interfere with phpMyAdmin's
+  authentication, so remove it.
+
+.. _faq4_5:
+
+4.5 Is it possible to let users create their own databases?
+-----------------------------------------------------------
+
+Starting with 2.2.5, in the user management page, you can enter a
+wildcard database name for a user (for example "joe%"), and put the
+privileges you want. For example, adding ``SELECT, INSERT, UPDATE,
+DELETE, CREATE, DROP, INDEX, ALTER`` would let a user create/manage
+his/her database(s).
+
+.. _faq4_6:
+
+4.6 How can I use the Host-based authentication additions?
+----------------------------------------------------------
+
+If you have existing rules from an old :term:`.htaccess` file, you can take them and
+add a username between the ``'deny'``/``'allow'`` and ``'from'``
+strings. Using the username wildcard of ``'%'`` would be a major
+benefit here if your installation is suited to using it. Then you can
+just add those updated lines into the
+:config:option:`$cfg['Servers'][$i]['AllowDeny']['rules']` array.
+
+If you want a pre-made sample, you can try this fragment. It stops the
+'root' user from logging in from any networks other than the private
+network :term:`IP` blocks.
+
+.. code-block:: php
+
+    
+    //block root from logging in except from the private networks
+    $cfg['Servers'][$i]['AllowDeny']['order'] = 'deny,allow';
+    $cfg['Servers'][$i]['AllowDeny']['rules'] = array(
+        'deny root from all',
+        'allow root from localhost',
+        'allow root from 10.0.0.0/8',
+        'allow root from 192.168.0.0/16',
+        'allow root from 172.16.0.0/12',
+    );
+
+.. _faq4_7:
+
+4.7 Authentication window is displayed more than once, why?
+-----------------------------------------------------------
+
+This happens if you are using a :term:`URL` to start phpMyAdmin which is
+different than the one set in your :config:option:`$cfg['PmaAbsoluteUri']`. For
+example, a missing "www", or entering with an :term:`IP` address while a domain
+name is defined in the config file.
+
+.. _faq4_8:
+
+4.8 Which parameters can I use in the URL that starts phpMyAdmin?
+-----------------------------------------------------------------
+
+When starting phpMyAdmin, you can use the ``db``, ``pma_username``,
+``pma_password`` and ``server`` parameters. This last one can contain
+either the numeric host index (from ``$i`` of the configuration file)
+or one of the host names present in the configuration file. Using
+``pma_username`` and ``pma_password`` has been tested along with the
+usage of 'cookie' ``auth_type``.
+
+.. _faqbrowsers:
+
+Browsers or client OS
++++++++++++++++++++++
+
+.. _faq5_1:
+
+5.1 I get an out of memory error, and my controls are non-functional, when trying to create a table with more than 14 columns.
+------------------------------------------------------------------------------------------------------------------------------
+
+We could reproduce this problem only under Win98/98SE. Testing under
+WinNT4 or Win2K, we could easily create more than 60 columns.  A
+workaround is to create a smaller number of columns, then come back to
+your table properties and add the other columns.
+
+.. _faq5_2:
+
+5.2 With Xitami 2.5b4, phpMyAdmin won't process form fields.
+------------------------------------------------------------
+
+This is not a phpMyAdmin problem but a Xitami known bug: you'll face
+it with each script/website that use forms. Upgrade or downgrade your
+Xitami server.
+
+.. _faq5_3:
+
+5.3 I have problems dumping tables with Konqueror (phpMyAdmin 2.2.2).
+---------------------------------------------------------------------
+
+With Konqueror 2.1.1: plain dumps, zip and GZip dumps work ok, except
+that the proposed file name for the dump is always 'tbl\_dump.php'.
+Bzip2 dumps don't seem to work. With Konqueror 2.2.1: plain dumps
+work; zip dumps are placed into the user's temporary directory, so
+they must be moved before closing Konqueror, or else they disappear.
+GZip dumps give an error message. Testing needs to be done for
+Konqueror 2.2.2.
+
+.. _faq5_4:
+
+5.4 I can't use the cookie authentication mode because Internet Explorer never stores the cookies.
+--------------------------------------------------------------------------------------------------
+
+MS Internet Explorer seems to be really buggy about cookies, at least
+till version 6.
+
+.. _faq5_5:
+
+5.5 In Internet Explorer 5.0, I get JavaScript errors when browsing my rows.
+----------------------------------------------------------------------------
+
+Upgrade to at least Internet Explorer 5.5 SP2.
+
+.. _faq5_6:
+
+5.6 In Internet Explorer 5.0, 5.5 or 6.0, I get an error (like "Page not found") when trying to modify a row in a table with many columns, or with a text column.
+-----------------------------------------------------------------------------------------------------------------------------------------------------------------
+
+Your table neither have a primary key nor an unique one, so we must use a long
+:term:`URL` to identify this row. There is a limit on the length of the
+:term:`URL` in those browsers, and this not happen in Netscape, for example.
+The workaround is to create a primary or unique key, or use another browser.
+
+.. _faq5_7:
+
+5.7 I refresh (reload) my browser, and come back to the welcome page.
+---------------------------------------------------------------------
+
+Some browsers support right-clicking into the frame you want to
+refresh, just do this in the right frame.
+
+.. _faq5_8:
+
+5.8 With Mozilla 0.9.7 I have problems sending a query modified in the query box.
+---------------------------------------------------------------------------------
+
+Looks like a Mozilla bug: 0.9.6 was OK. We will keep an eye on future
+Mozilla versions.
+
+.. _faq5_9:
+
+5.9 With Mozilla 0.9.? to 1.0 and Netscape 7.0-PR1 I can't type a whitespace in the SQL-Query edit area: the page scrolls down.
+-------------------------------------------------------------------------------------------------------------------------------
+
+This is a Mozilla bug (see bug #26882 at `BugZilla
+<http://bugzilla.mozilla.org/>`_).
+
+.. _faq5_10:
+
+5.10 With Netscape 4.75 I get empty rows between each row of data in a CSV exported file.
+-----------------------------------------------------------------------------------------
+
+This is a known Netscape 4.75 bug: it adds some line feeds when
+exporting data in octet-stream mode. Since we can't detect the
+specific Netscape version, we cannot workaround this bug.
+
+.. _faq5_11:
+
+5.11 Extended-ASCII characters like German umlauts are displayed wrong.
+-----------------------------------------------------------------------
+
+Please ensure that you have set your browser's character set to the
+one of the language file you have selected on phpMyAdmin's start page.
+Alternatively, you can try the auto detection mode that is supported
+by the recent versions of the most browsers.
+
+.. _faq5_12:
+
+5.12 Mac OS X Safari browser changes special characters to "?".
+---------------------------------------------------------------
+
+This issue has been reported by a :term:`Mac OS X` user, who adds that Chimera,
+Netscape and Mozilla do not have this problem.
+
+.. _faq5_13:
+
+5.13 With Internet Explorer 5.5 or 6, and HTTP authentication type, I cannot manage two servers: I log in to the first one, then the other one, but if I switch back to the first, I have to log in on each operation.
+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
+
+This is a bug in Internet Explorer, other browsers do not behave this
+way.
+
+.. _faq5_14:
+
+5.14 Using Opera6, I can manage to get to the authentication, but nothing happens after that, only a blank screen.
+------------------------------------------------------------------------------------------------------------------
+
+Please upgrade to Opera7 at least.
+
+.. _faq5_15:
+
+5.15 I have display problems with Safari.
+-----------------------------------------
+
+Please upgrade to at least version 1.2.3.
+
+.. _faq5_16:
+
+5.16 With Internet Explorer, I get "Access is denied" Javascript errors. Or I cannot make phpMyAdmin work under Windows.
+------------------------------------------------------------------------------------------------------------------------
+
+Please check the following points:
+
+* Maybe you have defined your :config:option:`$cfg['PmaAbsoluteUri']` setting in
+  :file:`config.inc.php` to an :term:`IP` address and you are starting phpMyAdmin
+  with a :term:`URL` containing a domain name, or the reverse situation.
+* Security settings in IE and/or Microsoft Security Center are too high,
+  thus blocking scripts execution.
+* The Windows Firewall is blocking Apache and MySQL. You must allow
+  :term:`HTTP` ports (80 or 443) and MySQL
+  port (usually 3306) in the "in" and "out" directions.
+
+.. _faq5_17:
+
+5.17 With Firefox, I cannot delete rows of data or drop a database.
+-------------------------------------------------------------------
+
+Many users have confirmed that the Tabbrowser Extensions plugin they
+installed in their Firefox is causing the problem.
+
+.. _faq5_18:
+
+5.18 With Konqueror 4.2.x an invalid ``LIMIT`` clause is generated when I browse a table.
+-----------------------------------------------------------------------------------------
+
+This happens only when both of these conditions are met: using the
+``http`` authentication mode and ``register_globals`` being set to
+``On`` on the server. It seems to be a browser-specific problem;
+meanwhile use the ``cookie`` authentication mode.
+
+.. _faq5_19:
+
+5.19 I get JavaScript errors in my browser.
+-------------------------------------------
+
+Issues have been reported with some combinations of browser
+extensions. To troubleshoot, disable all extensions then clear your
+browser cache to see if the problem goes away.
+
+.. _faqusing:
+
+Using phpMyAdmin
+++++++++++++++++
+
+.. _faq6_1:
+
+6.1 I can't insert new rows into a table / I can't create a table - MySQL brings up a SQL error.
+------------------------------------------------------------------------------------------------
+
+Examine the :term:`SQL` error with care.
+Often the problem is caused by specifying a wrong column-type. Common
+errors include:
+
+* Using ``VARCHAR`` without a size argument
+* Using ``TEXT`` or ``BLOB`` with a size argument
+
+Also, look at the syntax chapter in the MySQL manual to confirm that
+your syntax is correct.
+
+.. _faq6_2:
+
+6.2 When I create a table, I set an index for two columns and phpMyAdmin generates only one index with those two columns.
+-------------------------------------------------------------------------------------------------------------------------
+
+This is the way to create a multi-columns index. If you want two
+indexes, create the first one when creating the table, save, then
+display the table properties and click the Index link to create the
+other index.
+
+.. _faq6_3:
+
+6.3 How can I insert a null value into my table?
+------------------------------------------------
+
+Since version 2.2.3, you have a checkbox for each column that can be
+null. Before 2.2.3, you had to enter "null", without the quotes, as
+the column's value. Since version 2.5.5, you have to use the checkbox
+to get a real NULL value, so if you enter "NULL" this means you want a
+literal NULL in the column, and not a NULL value (this works in PHP4).
+
+.. _faq6_4:
+
+6.4 How can I backup my database or table?
+------------------------------------------
+
+Click on a database or table name in the navigation panel, the properties will
+be displayed. Then on the menu, click "Export", you can dump the structure, the
+data, or both. This will generate standard :term:`SQL` statements that can be
+used to recreate your database/table.  You will need to choose "Save as file",
+so that phpMyAdmin can transmit the resulting dump to your station.  Depending
+on your PHP configuration, you will see options to compress the dump. See also
+the :config:option:`$cfg['ExecTimeLimit']` configuration variable. For
+additional help on this subject, look for the word "dump" in this document.
+
+.. _faq6_5:
+
+6.5 How can I restore (upload) my database or table using a dump? How can I run a ".sql" file?
+----------------------------------------------------------------------------------------------
+
+Click on a database name in the navigation panel, the properties will
+be displayed. Select "Import" from the list of tabs in the right–hand
+frame (or ":term:`SQL`" if your phpMyAdmin
+version is previous to 2.7.0). In the "Location of the text file"
+section, type in the path to your dump filename, or use the Browse
+button. Then click Go.  With version 2.7.0, the import engine has been
+re–written, if possible it is suggested that you upgrade to take
+advantage of the new features.  For additional help on this subject,
+look for the word "upload" in this document.
+
+.. _faq6_6:
+
+6.6 How can I use the relation table in Query-by-example?
+---------------------------------------------------------
+
+Here is an example with the tables persons, towns and countries, all
+located in the database mydb. If you don't have a ``pma__relation``
+table, create it as explained in the configuration section. Then
+create the example tables:
+
+.. code-block:: mysql
+
+    
+    CREATE TABLE REL_countries (
+    country_code char(1) NOT NULL default '',
+    description varchar(10) NOT NULL default '',
+    PRIMARY KEY (country_code)
+    ) TYPE=MyISAM;
+    
+    INSERT INTO REL_countries VALUES ('C', 'Canada');
+    
+    CREATE TABLE REL_persons (
+    id tinyint(4) NOT NULL auto_increment,
+    person_name varchar(32) NOT NULL default '',
+    town_code varchar(5) default '0',
+    country_code char(1) NOT NULL default '',
+    PRIMARY KEY (id)
+    ) TYPE=MyISAM;
+    
+    INSERT INTO REL_persons VALUES (11, 'Marc', 'S', '');
+    INSERT INTO REL_persons VALUES (15, 'Paul', 'S', 'C');
+    
+    CREATE TABLE REL_towns (
+    town_code varchar(5) NOT NULL default '0',
+    description varchar(30) NOT NULL default '',
+    PRIMARY KEY (town_code)
+    ) TYPE=MyISAM;
+    
+    INSERT INTO REL_towns VALUES ('S', 'Sherbrooke');
+    INSERT INTO REL_towns VALUES ('M', 'Montréal');
+
+To setup appropriate links and display information:
+
+* on table "REL\_persons" click Structure, then Relation view
+* in Links, for "town\_code" choose "REL\_towns->code"
+* in Links, for "country\_code" choose "REL\_countries->country\_code"
+* on table "REL\_towns" click Structure, then Relation view
+* in "Choose column to display", choose "description"
+* repeat the two previous steps for table "REL\_countries"
+
+Then test like this:
+
+* Click on your db name in the navigation panel
+* Choose "Query"
+* Use tables: persons, towns, countries
+* Click "Update query"
+* In the columns row, choose persons.person\_name and click the "Show"
+  tickbox
+* Do the same for towns.description and countries.descriptions in the
+  other 2 columns
+* Click "Update query" and you will see in the query box that the
+  correct joins have been generated
+* Click "Submit query"
+
+.. _faqdisplay:
+
+6.7 How can I use the "display column" feature?
+-----------------------------------------------
+
+Starting from the previous example, create the ``pma__table_info`` as
+explained in the configuration section, then browse your persons
+table, and move the mouse over a town code or country code.  See also
+:ref:`faq6_21` for an additional feature that "display column"
+enables: drop-down list of possible values.
+
+.. _faqpdf:
+
+6.8 How can I produce a PDF schema of my database?
+--------------------------------------------------
+
+First the configuration variables "relation", "table\_coords" and
+"pdf\_pages" have to be filled in.  Then you need to think about your
+schema layout. Which tables will go on which pages?
+
+* Select your database in the navigation panel.
+* Choose "Operations" in the navigation bar at the top.
+* Choose "Edit :term:`PDF` Pages" near the
+  bottom of the page.
+* Enter a name for the first :term:`PDF` page
+  and click Go. If you like, you can use the "automatic layout," which
+  will put all your linked tables onto the new page.
+* Select the name of the new page (making sure the Edit radio button is
+  selected) and click Go.
+* Select a table from the list, enter its coordinates and click Save.
+  Coordinates are relative; your diagram will be automatically scaled to
+  fit the page. When initially placing tables on the page, just pick any
+  coordinates -- say, 50x50. After clicking Save, you can then use the
+  :ref:`wysiwyg` to position the element correctly.
+* When you'd like to look at your :term:`PDF`, first be sure to click the Save 
+  button beneath the list of tables and coordinates, to save any changes you 
+  made there. Then scroll all the way down, select the :term:`PDF` options you 
+  want, and click Go.
+* Internet Explorer for Windows may suggest an incorrect filename when
+  you try to save a generated :term:`PDF`.
+  When saving a generated :term:`PDF`, be
+  sure that the filename ends in ".pdf", for example "schema.pdf".
+  Browsers on other operating systems, and other browsers on Windows, do
+  not have this problem.
+
+.. _faq6_9:
+
+6.9 phpMyAdmin is changing the type of one of my columns!
+---------------------------------------------------------
+
+No, it's MySQL that is doing `silent column type changing
+<http://dev.mysql.com/doc/en/silent-column-changes.html>`_.
+
+.. _underscore:
+
+6.10 When creating a privilege, what happens with underscores in the database name?
+-----------------------------------------------------------------------------------
+
+If you do not put a backslash before the underscore, this is a
+wildcard grant, and the underscore means "any character". So, if the
+database name is "john\_db", the user would get rights to john1db,
+john2db ... If you put a backslash before the underscore, it means
+that the database name will have a real underscore.
+
+.. _faq6_11:
+
+6.11 What is the curious symbol ø in the statistics pages?
+----------------------------------------------------------
+
+It means "average".
+
+.. _faqexport:
+
+6.12 I want to understand some Export options.
+----------------------------------------------
+
+**Structure:**
+
+* "Add DROP TABLE" will add a line telling MySQL to `drop the table
+  <http://dev.mysql.com/doc/mysql/en/drop-table.html>`_, if it already
+  exists during the import. It does NOT drop the table after your
+  export, it only affects the import file.
+* "If Not Exists" will only create the table if it doesn't exist.
+  Otherwise, you may get an error if the table name exists but has a
+  different structure.
+* "Add AUTO\_INCREMENT value" ensures that AUTO\_INCREMENT value (if
+  any) will be included in backup.
+* "Enclose table and column names with backquotes" ensures that column
+  and table names formed with special characters are protected.
+* "Add into comments" includes column comments, relations, and MIME
+  types set in the pmadb in the dump as :term:`SQL` comments 
+  (*/\* xxx \*/*).
+
+**Data:**
+
+* "Complete inserts" adds the column names on every INSERT command, for
+  better documentation (but resulting file is bigger).
+* "Extended inserts" provides a shorter dump file by using only once the
+  INSERT verb and the table name.
+* "Delayed inserts" are best explained in the `MySQL manual - INSERT DELAYED Syntax
+  <http://dev.mysql.com/doc/mysql/en/insert-delayed.html>`_.
+* "Ignore inserts" treats errors as a warning instead. Again, more info
+  is provided in the `MySQL manual - INSERT Syntax
+  <http://dev.mysql.com/doc/mysql/en/insert.html>`_, but basically with
+  this selected, invalid values are adjusted and inserted rather than
+  causing the entire statement to fail.
+
+.. _faq6_13:
+
+6.13 I would like to create a database with a dot in its name.
+--------------------------------------------------------------
+
+This is a bad idea, because in MySQL the syntax "database.table" is
+the normal way to reference a database and table name. Worse, MySQL
+will usually let you create a database with a dot, but then you cannot
+work with it, nor delete it.
+
+.. _faqsqlvalidator:
+
+6.14 How do I set up the SQL Validator?
+---------------------------------------
+
+To use SQL Validator, you need PHP with :term:`XML`, :term:`PCRE` and
+:term:`PEAR` support. In addition you need a :term:`SOAP` support, either as a
+PHP extension or as a PEAR SOAP module.
+
+To install :term:`PEAR` :term:`SOAP` module, run :command:`pear install
+Net_Socket Net_URL HTTP_Request Mail_Mime Net_DIME SOAP` to get the necessary
+:term:`PEAR` modules for usage.
+
+If you use the Validator, you should be aware that any :term:`SQL` statement
+you submit will be stored anonymously (database/table/column names, strings,
+numbers replaced with generic values). The Mimer :term:`SQL` Validator itself,
+is © 2001 Upright Database Technology. We utilize it as free SOAP service.
+
+.. _faq6_15:
+
+6.15 I want to add a BLOB column and put an index on it, but MySQL says "BLOB column '...' used in key specification without a key length".
+-------------------------------------------------------------------------------------------------------------------------------------------
+
+The right way to do this, is to create the column without any indexes,
+then display the table structure and use the "Create an index" dialog.
+On this page, you will be able to choose your BLOB column, and set a
+size to the index, which is the condition to create an index on a BLOB
+column.
+
+.. _faq6_16:
+
+6.16 How can I simply move in page with plenty editing fields?
+--------------------------------------------------------------
+
+You can use :kbd:`Ctrl+arrows` (:kbd:`Option+Arrows` in Safari) for moving on
+most pages with many editing fields (table structure changes, row editing,
+etc.).
+
+.. _faq6_17:
+
+6.17 Transformations: I can't enter my own mimetype! WTF is this feature then useful for?
+-----------------------------------------------------------------------------------------
+
+Slow down :). Defining mimetypes is of no use, if you can't put
+transformations on them. Otherwise you could just put a comment on the
+column. Because entering your own mimetype will cause serious syntax
+checking issues and validation, this introduces a high-risk false-
+user-input situation. Instead you have to initialize mimetypes using
+functions or empty mimetype definitions. 
+
+Plus, you have a whole overview of available mimetypes. Who knows all those
+mimetypes by heart so he/she can enter it at will?
+
+.. _faqbookmark:
+
+6.18 Bookmarks: Where can I store bookmarks? Why can't I see any bookmarks below the query box? What is this variable for?
+--------------------------------------------------------------------------------------------------------------------------
+
+Any query you have executed can be stored as a bookmark on the page
+where the results are displayed. You will find a button labeled
+'Bookmark this query' just at the end of the page. As soon as you have
+stored a bookmark, it is related to the database you run the query on.
+You can now access a bookmark dropdown on each page, the query box
+appears on for that database.
+
+You can also have, inside the query, a placeholder for a variable.
+This is done by inserting into the query a SQL comment between ``/*`` and 
+``*/``. Inside the comment, the special string ``[VARIABLE]`` is used. 
+Be aware that the whole query minus the SQL comment must be
+valid by itself, otherwise you won't be able to store it as a bookmark.
+
+When you execute the bookmark, everything typed into the *value* 
+input box on the query box page will replace the string ``/*[VARIABLE]*/`` in 
+your stored query.
+
+Also remember, that everything else inside the ``/*[VARIABLE]*/`` string for
+your query will remain the way it is, but will be stripped of the ``/**/``
+chars. So you can use:
+
+.. code-block:: mysql
+
+    /*, [VARIABLE] AS myname */
+    
+which will be expanded to 
+
+.. code-block:: mysql
+
+    , VARIABLE as myname
+    
+in your query, where VARIABLE is the string you entered in the input box. If an
+empty string is provided, no replacements are made. 
+
+A more complex example. Say you have stored
+this query: 
+
+.. code-block:: mysql
+
+    SELECT Name, Address FROM addresses WHERE 1 /* AND Name LIKE '%[VARIABLE]%' */
+    
+Say, you now enter "phpMyAdmin" as the variable for the stored query, the full
+query will be: 
+
+.. code-block:: mysql
+
+    SELECT Name, Address FROM addresses WHERE 1 AND Name LIKE '%phpMyAdmin%'
+
+You can use multiple occurrences of ``/*[VARIABLE]*/`` in a single query
+(that is, multiple occurrences of the *same* variable). 
+
+**NOTE THE ABSENCE OF SPACES** inside the ``/**/`` construct. Any spaces
+inserted there will be later also inserted as spaces in your query and may lead
+to unexpected results especially when using the variable expansion inside of a
+"LIKE ''" expression. 
+
+Your initial query which is going to be stored as a bookmark has to yield at
+least one result row so you can store the bookmark. You may have that to work
+around using well positioned ``/**/`` comments.
+
+.. _faq6_19:
+
+6.19 How can I create simple LATEX document to include exported table?
+----------------------------------------------------------------------
+
+You can simply include table in your LATEX documents,
+minimal sample document should look like following one (assuming you
+have table exported in file :file:`table.tex`):
+
+.. code-block:: latex
+
+    
+    \documentclass{article} % or any class you want
+    \usepackage{longtable}  % for displaying table
+    \begin{document}        % start of document
+    \include{table}         % including exported table
+    \end{document}          % end of document
+
+.. _faq6_20:
+
+6.20 I see a lot of databases which are not mine, and cannot access them.
+-------------------------------------------------------------------------
+
+You have one of these global privileges: CREATE TEMPORARY TABLES, SHOW
+DATABASES, LOCK TABLES. Those privileges also enable users to see all the
+database names. So if your users do not need those privileges, you can remove
+them and their databases list will shorten.
+
+.. seealso:: <http://bugs.mysql.com/179>
+
+.. _faq6_21:
+
+6.21 In edit/insert mode, how can I see a list of possible values for a column, based on some foreign table?
+------------------------------------------------------------------------------------------------------------
+
+You have to setup appropriate links between the tables, and also setup
+the "display column" in the foreign table. See :ref:`faq6_6` for an
+example. Then, if there are 100 values or less in the foreign table, a
+drop-down list of values will be available. You will see two lists of
+values, the first list containing the key and the display column, the
+second list containing the display column and the key. The reason for
+this is to be able to type the first letter of either the key or the
+display column. For 100 values or more, a distinct window will appear,
+to browse foreign key values and choose one. To change the default
+limit of 100, see :config:option:`$cfg['ForeignKeyMaxLimit']`.
+
+
+.. _faq6_22:
+
+6.22 Bookmarks: Can I execute a default bookmark automatically when entering Browse mode for a table?
+-----------------------------------------------------------------------------------------------------
+
+Yes. If a bookmark has the same label as a table name and it's not a
+public bookmark, it will be executed.
+
+.. _faq6_23:
+
+6.23 Export: I heard phpMyAdmin can export Microsoft Excel files?
+-----------------------------------------------------------------
+
+You can use :term:`CSV` for Microsoft Excel,
+which works out of the box. 
+
+.. versionchanged:: 3.4.5
+    Since phpMyAdmin 3.4.5 support for direct export to Microsoft Excel version
+    97 and newer was dropped.
+
+.. _faq6_24:
+
+6.24 Now that phpMyAdmin supports native MySQL 4.1.x column comments, what happens to my column comments stored in pmadb?
+-------------------------------------------------------------------------------------------------------------------------
+
+Automatic migration of a table's pmadb-style column comments to the
+native ones is done whenever you enter Structure page for this table.
+
+.. _faq6_25:
+
+6.25 (withdrawn).
+-----------------
+
+.. _faq6_26:
+
+6.26 How can I select a range of rows?
+--------------------------------------
+
+Click the first row of the range, hold the shift key and click the
+last row of the range. This works everywhere you see rows, for example
+in Browse mode or on the Structure page.
+
+.. _faq6_27:
+
+6.27 What format strings can I use?
+-----------------------------------
+
+In all places where phpMyAdmin accepts format strings, you can use
+``@VARIABLE@`` expansion and `strftime <http://php.net/strftime>`_
+format strings. The expanded variables depend on a context (for
+example, if you haven't chosen a table, you can not get the table
+name), but the following variables can be used:
+
+``@HTTP_HOST@``
+    HTTP host that runs phpMyAdmin
+``@SERVER@``
+    MySQL server name
+``@VERBOSE@``
+    Verbose MySQL server name as defined in :config:option:`$cfg['Servers'][$i]['verbose']`
+``@VSERVER@``
+    Verbose MySQL server name if set, otherwise normal
+``@DATABASE@``
+    Currently opened database
+``@TABLE@``
+    Currently opened table
+``@COLUMNS@``
+    Columns of the currently opened table
+``@PHPMYADMIN@``
+    phpMyAdmin with version
+
+.. _wysiwyg:
+
+6.28 How can I easily edit relational schema for export?
+--------------------------------------------------------
+
+By clicking on the button 'toggle scratchboard' on the page where you
+edit x/y coordinates of those elements you can activate a scratchboard
+where all your elements are placed. By clicking on an element, you can
+move them around in the pre-defined area and the x/y coordinates will
+get updated dynamically. Likewise, when entering a new position
+directly into the input field, the new position in the scratchboard
+changes after your cursor leaves the input field.
+
+You have to click on the 'OK'-button below the tables to save the new
+positions. If you want to place a new element, first add it to the
+table of elements and then you can drag the new element around.
+
+By changing the paper size and the orientation you can change the size
+of the scratchboard as well. You can do so by just changing the
+dropdown field below, and the scratchboard will resize automatically,
+without interfering with the current placement of the elements.
+
+If ever an element gets out of range you can either enlarge the paper
+size or click on the 'reset' button to place all elements below each
+other.
+
+.. _faq6_29:
+
+6.29 Why can't I get a chart from my query result table?
+--------------------------------------------------------
+
+Not every table can be put to the chart. Only tables with one, two or
+three columns can be visualised as a chart. Moreover the table must be
+in a special format for chart script to understand it. Currently
+supported formats can be found in the `wiki <http://wiki.phpmyadmin.ne
+t/pma/Charts#Data_formats_for_query_results_chart>`_.
+
+.. _faq6_30:
+
+6.30 Import: How can I import ESRI Shapefiles
+---------------------------------------------
+
+An ESRI Shapefile is actually a set of several files, where .shp file
+contains geometry data and .dbf file contains data related to those
+geometry data. To read data from .dbf file you need to have PHP
+compiled with the dBase extension (--enable-dbase). Otherwise only
+geometry data will be imported.
+
+To upload these set of files you can use either of the following
+methods:
+
+Configure upload directory with :config:option:`$cfg['UploadDir']`, upload both .shp and .dbf files with
+the same filename and chose the .shp file from the import page.
+
+Create a Zip archive with .shp and .dbf files and import it. For this
+to work, you need to set :config:option:`$cfg['TempDir']` to a place where the web server user can
+write (for example ``'./tmp'``).
+
+To create the temporary directory on a UNIX-based system, you can do:
+
+.. code-block:: sh
+
+    cd phpMyAdmin
+    mkdir tmp
+    chmod o+rwx tmp
+
+.. _faq6_31:
+
+6.31 How do I create a relation in designer?
+--------------------------------------------
+
+To select relation, click:  The display column is shown in pink. To
+set/unset a column as the display column, click the "Choose column to
+display" icon, then click on the appropriate column name.
+
+.. _faq6_32:
+
+6.32 How can I use the zoom search feature?
+-------------------------------------------
+
+The Zoom search feature is an alternative to table search feature. It allows
+you to explore a table by representing its data in a scatter plot. You can
+locate this feature by selecting a table and clicking the :guilabel:`Search`
+tab. One of the sub-tabs in the :guilabel:`Table Search` page is
+:guilabel:`Zoom Search`.  
+
+Consider the table REL\_persons in :ref:`faq6_6` for
+an example. To use zoom search, two columns need to be selected, for
+example, id and town\_code. The id values will be represented on one
+axis and town\_code values on the other axis. Each row will be
+represented as a point in a scatter plot based on its id and
+town\_code. You can include two additional search criteria apart from
+the two fields to display. 
+
+You can choose which field should be
+displayed as label for each point. If a display column has been set
+for the table (see :ref:`faqdisplay`), it is taken as the label unless
+you specify otherwise. You can also select the maximum number of rows
+you want to be displayed in the plot by specifing it in the 'Max rows
+to plot' field. Once you have decided over your criteria, click 'Go'
+to display the plot. 
+
+After the plot is generated, you can use the
+mousewheel to zoom in and out of the plot. In addition, panning
+feature is enabled to navigate through the plot. You can zoom-in to a
+certail level of detail and use panning to locate your area of
+interest. Clicking on a point opens a dialogue box, displaying field
+values of the data row represented by the point. You can edit the
+values if required and click on submit to issue an update query. Basic
+instructions on how to use can be viewed by clicking the 'How to use?'
+link located just above the plot.
+
+.. _faq6_33:
+
+6.33 When browsing a table, how can I copy a column name?
+---------------------------------------------------------
+
+Selecting the name of the column within the browse table header cell
+for copying is difficult, as the columns support reordering by
+dragging the header cells as well as sorting by clicking on the linked
+column name. To copy a column name, double-click on the empty area
+next to the column name, when the tooltip tells you to do so. This
+will show you an input box with the column name. You may right-click
+the column name within this input box to copy it to your clipboard.
+
+.. _faqproject:
+
+phpMyAdmin project
+++++++++++++++++++
+
+.. _faq7_1:
+
+7.1 I have found a bug. How do I inform developers?
+---------------------------------------------------
+
+Our Bug Tracker is located at <http://sf.net/projects/phpmyadmin/> under the
+Bugs section. But please first discuss your bug with other users:
+<https://sourceforge.net/projects/phpmyadmin/forums>.
+
+.. _faq7_2:
+
+7.2 I want to translate the messages to a new language or upgrade an existing language, where do I start?
+---------------------------------------------------------------------------------------------------------
+
+Translations are very welcome and all you need to have are the
+language skills. The easiest way is to use our `online translation
+service <https://l10n.cihar.com/projects/phpmyadmin/>`_. You can check
+out all the possibilities to translate in the `translate section on
+our website <http://www.phpmyadmin.net/home_page/translate.php>`_.
+
+.. _faq7_3:
+
+7.3 I would like to help out with the development of phpMyAdmin. How should I proceed?
+--------------------------------------------------------------------------------------
+
+We welcome every contribution to the development of phpMyAdmin. You
+can check out all the possibilities to contribute in the `contribute
+section on our website
+<http://www.phpmyadmin.net/home_page/improve.php>`_.
+
+.. seealso:: :ref:`developers`
+
+.. _faqsecurity:
+
+Security
+++++++++
+
+.. _faq8_1:
+
+8.1 Where can I get information about the security alerts issued for phpMyAdmin?
+--------------------------------------------------------------------------------
+
+Please refer to <http://www.phpmyadmin.net/home_page/security.php>.
+
+.. _faq8_2:
+
+8.2 How can I protect phpMyAdmin against brute force attacks?
+-------------------------------------------------------------
+
+If you use Apache web server, phpMyAdmin exports information about
+authentication to the Apache environment and it can be used in Apache
+logs. Currently there are two variables available:
+
+
+``userID``
+    User name of currently active user (he does not have to be logged in).
+``userStatus``
+    Status of currently active user, one of ``ok`` (user is logged in),
+    ``mysql-denied`` (MySQL denied user login), ``allow-denied`` (user denied
+    by allow/deny rules), ``root-denied`` (root is denied in configuration),
+    ``empty-denied`` (empty password is denied).
+
+``LogFormat`` directive for Apache can look like following:
+
+.. code-block:: apache
+
+    LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\" %{userID}n %{userStatus}n"   pma_combined
+
+You can then use any log analyzing tools to detect possible break-in
+attempts.
+
+.. _faqsynchronization:
+
+Synchronization
++++++++++++++++
+
+.. _faq9_1:
+
+9.1 (withdrawn). 
+----------------
+
+.. _faq9_2:
+
+9.2 (withdrawn). 
+----------------
+
diff --git a/phpmyadmin/doc/glossary.rst b/phpmyadmin/doc/glossary.rst
new file mode 100644
index 0000000..d558b44
--- /dev/null
+++ b/phpmyadmin/doc/glossary.rst
@@ -0,0 +1,406 @@
+.. _glossary:
+
+Glossary
+========
+
+From Wikipedia, the free encyclopedia
+
+.. glossary::
+
+    .htaccess
+      the default name of Apache's directory-level configuration file.	
+
+      .. seealso:: <http://www.wikipedia.org/wiki/.htaccess>
+
+    ACL
+      Access Contol List
+
+    Blowfish
+      a keyed, symmetric block cipher, designed in 1993 by Bruce Schneier.	
+
+      .. seealso:: <http://www.wikipedia.org/wiki/Blowfish_(cipher)>
+
+    Browser 
+      a software application that enables a user to display and interact with text, images, and other information typically located on a web page at a website on the World Wide Web.	
+
+      .. seealso:: <http://en.wikipedia.org/wiki/Web_browser>
+
+    bzip2
+      a free software/open source data compression algorithm and program developed by Julian Seward.	
+
+      .. seealso:: <http://www.wikipedia.org/wiki/Bzip2>
+
+    CGI 
+      Common Gateway Interface is an important World Wide Web technology that
+      enables a client web browser to request data from a program executed on
+      the Web server.	
+
+      .. seealso:: <http://www.wikipedia.org/wiki/CGI>
+
+    Changelog
+      a log or record of changes made to a project.	
+
+      .. seealso:: <http://www.wikipedia.org/wiki/Changelog>
+
+    Client
+      a computer system that accesses a (remote) service on another computer by some kind of network.	
+
+      .. seealso:: <http://www.wikipedia.org/wiki/Client_(computing)>
+
+    column
+      a set of data values of a particular simple type, one for each row of the table.	
+
+      .. seealso:: <http://www.wikipedia.org/wiki/Column_(database)>
+
+    Cookie
+      a packet of information sent by a server to a World Wide Web browser and then sent back by the browser each time it accesses that server.	
+
+      .. seealso:: <http://www.wikipedia.org/wiki/HTTP_cookie>
+
+    CSV
+      Comma- separated values	
+
+      .. seealso:: <http://www.wikipedia.org/wiki/Comma-separated_values>
+
+    DB 
+      look at :term:`database`
+
+    database
+      an organized collection of data.	
+
+      .. seealso:: <http://www.wikipedia.org/wiki/Database>
+
+    Engine 
+      look at :term:`storage engines`
+
+    extension
+      a PHP module that extends PHP with additional functionality.	
+
+      .. seealso:: <http://www.wikipedia.org/wiki/extension>
+
+    FAQ 
+      Frequently Asked Questions is a list of commonly asked question and there
+      answers.	
+
+      .. seealso:: <http://www.wikipedia.org/wiki/FAQ>
+
+    Field
+      one part of divided data/columns.	
+
+      .. seealso:: <http://www.wikipedia.org/wiki/Field_(computer_science)>
+
+    foreign key
+      a column or group of columns in a database row that point to a key column
+      or group of columns forming a key of another database row in some
+      (usually different) table.	
+
+      .. seealso:: <http://www.wikipedia.org/wiki/Foreign_key>
+
+    FPDF
+      the free :term:`PDF` library	
+
+      .. seealso:: <http://www.fpdf.org/>
+
+    GD 
+      Graphics Library by Thomas Boutell and others for dynamically manipulating images.	
+
+      .. seealso:: <http://www.wikipedia.org/wiki/GD_Graphics_Library>
+
+    GD2 
+      look at :term:`gd`
+
+    gzip
+      gzip is short for GNU zip, a GNU free software file compression program.	
+
+      .. seealso:: <http://www.wikipedia.org/wiki/Gzip>
+
+    host
+      any machine connected to a computer network, a node that has a hostname.	
+
+      .. seealso:: <http://www.wikipedia.org/wiki/Host>
+
+    hostname
+      the unique name by which a network attached device is known on a network.	
+
+      .. seealso:: <http://www.wikipedia.org/wiki/Hostname>
+
+    HTTP 
+      HyperText Transfer Protocol is the primary method used to transfer or
+      convey information on the World Wide Web.	
+
+      .. seealso:: <http://www.wikipedia.org/wiki/HyperText_Transfer_Protocol>
+
+    https
+      a :term:`HTTP`-connection with additional security measures.	
+
+      .. seealso:: <http://www.wikipedia.org/wiki/Https:_URI_scheme>
+
+    IEC
+      International Electrotechnical Commission
+
+    IIS 
+      Internet Information Services is a set of Internet-based services for
+      servers using Microsoft Windows.	
+
+      .. seealso:: <http://www.wikipedia.org/wiki/Internet_Information_Services>
+
+    Index
+      a feature that allows quick access to the rows in a table.	
+
+      .. seealso:: <http://www.wikipedia.org/wiki/Index_(database)>
+
+    IP 
+      Internet Protocol is a data-oriented protocol used by source and
+      destination hosts for communicating data across a packet-switched
+      internetwork.	
+
+      .. seealso:: <http://www.wikipedia.org/wiki/Internet_Protocol>
+
+    IP Address
+      a unique number that devices use in order to identify and communicate with each other on a network utilizing the Internet Protocol standard.	
+
+      .. seealso:: <http://www.wikipedia.org/wiki/IP_Address>
+
+    IPv6 
+      IPv6 (Internet Protocol version 6) is the latest revision of the 
+      Internet Protocol (:term:`IP`), designed to deal with the 
+      long-anticipated problem of its precedessor IPv4 running out of addresses.
+
+      .. seealso:: <http://www.wikipedia.org/wiki/IPv6>
+
+    ISAPI 
+      Internet Server Application Programming Interface is the API of Internet Information Services (IIS).	
+
+      .. seealso:: <http://www.wikipedia.org/wiki/ISAPI>
+
+    ISP 
+      Internet service provider is a business or organization that offers users
+      access to the Internet and related services.	
+
+      .. seealso:: <http://www.wikipedia.org/wiki/ISP>
+
+    ISO
+      International Standards Organisation
+
+    JPEG
+      a most commonly used standard method of lossy compression for photographic images.	
+
+      .. seealso:: <http://www.wikipedia.org/wiki/JPEG>
+
+    JPG 
+      look at :term:`jpeg`
+
+    Key
+      look at :term:`index`
+
+    LATEX
+      a document preparation system for the TEX typesetting program.	
+
+      .. seealso:: <http://www.wikipedia.org/wiki/LaTeX>
+
+    Mac
+       Apple Macintosh is line of personal computers is designed, developed, manufactured, and marketed by Apple Computer.	
+
+      .. seealso:: <http://www.wikipedia.org/wiki/Mac>
+
+    Mac OS X
+      the operating system which is included with all currently shipping Apple Macintosh computers in the consumer and professional markets.	
+
+      .. seealso:: <http://www.wikipedia.org/wiki/Mac_OS_X>
+
+    MCrypt
+      a cryptographic library.	
+
+      .. seealso:: <http://www.wikipedia.org/wiki/MCrypt>
+
+    mcrypt
+      the MCrypt PHP extension.	
+
+      .. seealso:: <http://php.net/mcrypt>
+
+    MIME 
+      Multipurpose Internet Mail Extensions is
+      an Internet Standard for the format of e-mail.	
+
+      .. seealso:: <http://www.wikipedia.org/wiki/MIME>
+
+    module
+      some sort of extension for the Apache Webserver.	
+
+      .. seealso:: <http://www.wikipedia.org/wiki/module>
+
+    MySQL
+      a multithreaded, multi-user, SQL (Structured Query Language) Database Management System (DBMS).	
+
+      .. seealso:: <http://www.wikipedia.org/wiki/MySQL>
+
+    mysqli
+      the improved MySQL client PHP extension.	
+
+      .. seealso:: <http://php.net/mysqli>
+
+    mysql
+      the MySQL client PHP extension.	
+
+      .. seealso:: <http://php.net/mysql>
+
+    OpenDocument
+      open standard for office documents.	
+
+      .. seealso:: <http://www.wikipedia.org/wiki/OpenDocument>
+
+    OS X
+      look at :term:`Mac OS X`.
+
+      .. seealso:: <http://www.wikipedia.org/wiki/OS_X>
+
+    PDF 
+      Portable Document Format is a file format developed by Adobe Systems for
+      representing two dimensional documents in a device independent and
+      resolution independent format.	
+
+      .. seealso:: <http://www.wikipedia.org/wiki/Portable_Document_Format>
+
+    PEAR
+      the PHP Extension and Application Repository.	
+
+      .. seealso:: <http://pear.php.net/>
+
+    PCRE 
+      Perl Compatible Regular Expressions is the perl-compatible regular
+      expression functions for PHP	
+
+      .. seealso:: <http://php.net/pcre>
+
+    PHP
+      short for "PHP: Hypertext Preprocessor", is an open-source, reflective
+      programming language used mainly for developing server-side applications
+      and dynamic web content, and more recently, a broader range of software
+      applications.	
+
+      .. seealso:: <http://www.wikipedia.org/wiki/PHP>
+
+    port
+      a connection through which data is sent and received.	
+
+      .. seealso:: <http://www.wikipedia.org/wiki/Port_(computing)>
+
+    RFC
+      Request for Comments (RFC) documents are a series of memoranda
+      encompassing new research, innovations, and methodologies applicable to
+      Internet technologies.	
+
+      .. seealso:: <http://www.wikipedia.org/wiki/Request_for_Comments>
+
+    RFC 1952
+      GZIP file format specification version 4.3
+
+      .. seealso:: :rfc:`1952`
+
+    Row (record, tuple)
+      represents a single, implicitly structured data item in a table.	
+
+      .. seealso:: <http://www.wikipedia.org/wiki/Row_(database)>
+
+    Server
+      a computer system that provides services to other computing systems over a network.	
+
+      .. seealso:: <http://www.wikipedia.org/wiki/Server_(computing)>
+
+    Storage Engines
+      handlers for different table types	
+
+      .. seealso:: <http://dev.mysql.com/doc/en/storage-engines.html>
+
+    SOAP
+      Simple Object Access Protocol is a protocol specification for exchanging
+      structured information in the implementation of Web Services in computer
+      networks.
+
+      .. seealso:: <http://en.wikipedia.org/wiki/SOAP>
+
+    socket
+      a form of inter-process communication.	
+
+      .. seealso:: <http://www.wikipedia.org/wiki/Socket#Computer_sockets>
+
+    SSL 
+      Secure Sockets Layer is a cryptographic protocol which provides secure
+      communication on the Internet.	
+
+      .. seealso:: <http://www.wikipedia.org/wiki/Secure_Sockets_Layer>
+
+    Stored procedure
+      a subroutine available to applications accessing a relational database system	
+
+      .. seealso:: <http://en.wikipedia.org/wiki/Stored_procedure>
+
+    SQL
+      Structured Query Language	
+
+      .. seealso:: <http://www.wikipedia.org/wiki/SQL>
+
+    table
+      a set of data elements (cells) that is organized, defined and stored as
+      horizontal rows and vertical columns where each item can be uniquely
+      identified by a label or key or by it?s position in relation to other
+      items.	
+
+      .. seealso:: <http://www.wikipedia.org/wiki/Table_(database)>
+
+    tar
+      a type of archive file format: the Tape ARchive format.	
+
+      .. seealso:: <http://www.wikipedia.org/wiki/Tar_(file_format)>
+
+    TCP 
+      Transmission Control Protocol is one of the core protocols of the
+      Internet protocol suite.	
+
+      .. seealso:: <http://www.wikipedia.org/wiki/TCP>
+
+    TCPDF
+      Rewrite of :term:`UFPDF` with various improvements.
+
+      .. seealso:: <http://www.tcpdf.org/>
+
+    trigger
+      a procedural code that is automatically executed in response to certain events on a particular table or view in a database	
+
+      .. seealso:: <http://en.wikipedia.org/wiki/Database_trigger>
+
+    UFPDF
+      Unicode/UTF-8 extension for :term:`FPDF`
+
+      .. seealso:: <http://www.acko.net/node/56>
+
+    URL
+      Uniform Resource Locator is a sequence of characters, conforming to a
+      standardized format, that is used for referring to resources, such as
+      documents and images on the Internet, by their location.	
+
+      .. seealso:: <http://www.wikipedia.org/wiki/URL>
+
+    Webserver
+      A computer (program) that is responsible for accepting HTTP requests from clients and serving them Web pages.	
+
+      .. seealso:: <http://www.wikipedia.org/wiki/Webserver>
+
+    XML 
+      Extensible Markup Language is a W3C-recommended general- purpose markup
+      language for creating special-purpose markup languages, capable of
+      describing many different kinds of data.	
+
+      .. seealso:: <http://www.wikipedia.org/wiki/XML>
+
+    ZIP
+      a popular data compression and archival format.	
+
+      .. seealso:: <http://www.wikipedia.org/wiki/ZIP_(file_format)>
+
+    zlib
+      an open-source, cross- platform data compression library by Jean-loup Gailly and Mark Adler.	
+
+      .. seealso:: <http://www.wikipedia.org/wiki/Zlib>
+
+
diff --git a/phpmyadmin/doc/html/.buildinfo b/phpmyadmin/doc/html/.buildinfo
new file mode 100644
index 0000000..65e7431
--- /dev/null
+++ b/phpmyadmin/doc/html/.buildinfo
@@ -0,0 +1,4 @@
+# Sphinx build info version 1
+# This file hashes the configuration used when building these files. When it is not found, a full rebuild will be done.
+config: 391ce1d2159bfa0058ee08a87344a0a5
+tags: fbb0d17656682115ca4d033fb2f83ba1
diff --git a/phpmyadmin/doc/html/_sources/config.txt b/phpmyadmin/doc/html/_sources/config.txt
new file mode 100644
index 0000000..2b9ced2
--- /dev/null
+++ b/phpmyadmin/doc/html/_sources/config.txt
@@ -0,0 +1,2776 @@
+.. index:: config.inc.php
+
+.. _config:
+
+Configuration
+=============
+
+Almost all configurable data is placed in :file:`config.inc.php`. If this file
+does not exist, please refer to the :ref:`setup` section to create one. This
+file only needs to contain the parameters you want to change from their
+corresponding default value in :file:`libraries/config.default.php`.
+
+The parameters which relate to design (like colors) are placed in
+:file:`themes/themename/layout.inc.php`. You might also want to create
+:file:`config.footer.inc.php` and :file:`config.header.inc.php` files to add
+your site specific code to be included on start and end of each page.
+
+.. note::
+
+    Some distributions (eg. Debian or Ubuntu) store :file:`config.inc.php` in
+    ``/etc/phpmyadmin`` instead of within phpMyAdmin sources.
+
+.. warning::
+
+    :term:`Mac` users should note that if you are on a version before
+    :term:`Mac OS X`, PHP does not seem to
+    like :term:`Mac` end of lines character (``\r``). So
+    ensure you choose the option that allows to use the \*nix end of line
+    character (``\n``) in your text editor before saving a script you have
+    modified.
+
+Basic settings
+--------------
+
+.. config:option:: $cfg['PmaAbsoluteUri']
+
+    :type: string
+    :default: ``''``
+
+    Sets here the complete :term:`URL` (with full path) to your phpMyAdmin
+    installation's directory. E.g.
+    ``http://www.example.net/path_to_your_phpMyAdmin_directory/``.  Note also
+    that the :term:`URL` on some web servers are case–sensitive. Don’t forget
+    the trailing slash at the end.
+
+    Starting with version 2.3.0, it is advisable to try leaving this blank. In
+    most cases phpMyAdmin automatically detects the proper setting. Users of
+    port forwarding will need to set :config:option:`$cfg['PmaAbsoluteUri']`
+    (`more info <https://sourceforge.net/p/phpmyadmin/support-requests/795/>`_).
+
+    A good test is to browse a table, edit a row and save it. There should be
+    an error message if phpMyAdmin is having trouble auto–detecting the correct
+    value. If you get an error that this must be set or if the autodetect code
+    fails to detect your path, please post a bug report on our bug tracker so
+    we can improve the code.
+
+    .. seealso:: :ref:`faq1_40`
+
+.. config:option:: $cfg['PmaNoRelation_DisableWarning']
+
+    :type: boolean
+    :default: false
+
+    Starting with version 2.3.0 phpMyAdmin offers a lot of features to
+    work with master / foreign – tables (see :config:option:`$cfg['Servers'][$i]['pmadb']`).  
+    
+    If you tried to set this
+    up and it does not work for you, have a look on the :guilabel:`Structure` page
+    of one database where you would like to use it. You will find a link
+    that will analyze why those features have been disabled.
+    
+    If you do not want to use those features set this variable to ``true`` to
+    stop this message from appearing.
+
+.. config:option:: $cfg['SuhosinDisableWarning']
+
+    :type: boolean
+    :default: false
+
+    A warning is displayed on the main page if Suhosin is detected. 
+    
+    You can set this parameter to ``true`` to stop this message from appearing.
+
+.. config:option:: $cfg['McryptDisableWarning']
+
+    :type: boolean
+    :default: false
+
+    Disable the default warning that is displayed if mcrypt is missing for
+    cookie authentication. 
+    
+    You can set this parameter to ``true`` to stop this message from appearing.
+
+.. config:option:: $cfg['ServerLibraryDifference_DisableWarning']
+
+    :type: boolean
+    :default: false
+
+    A warning is displayed on the main page if there is a difference
+    between the MySQL library and server version. 
+    
+    You can set this parameter to ``true`` to stop this message from appearing.
+
+.. config:option:: $cfg['ReservedWordDisableWarning']
+
+    :type: boolean
+    :default: false
+
+    This warning is displayed on the Structure page of a table if one or more
+    column names match with words which are MySQL reserved.
+
+    If you want to turn off this warning, you can set it to ``true`` and 
+    warning will not longer be displayed 
+
+.. config:option:: $cfg['TranslationWarningThreshold']
+
+    :type: integer
+    :default: 80
+
+    Show warning about incomplete translations on certain threshold.
+
+Server connection settings
+--------------------------
+
+.. config:option:: $cfg['Servers']
+
+    :type: array
+    :default: one server array with settings listed bellow
+
+    Since version 1.4.2, phpMyAdmin supports the administration of multiple
+    MySQL servers. Therefore, a :config:option:`$cfg['Servers']`-array has been
+    added which contains the login information for the different servers. The
+    first :config:option:`$cfg['Servers'][$i]['host']` contains the hostname of
+    the first server, the second :config:option:`$cfg['Servers'][$i]['host']`
+    the hostname of the second server, etc. In
+    :file:`libraries/config.default.php`, there is only one section for server
+    definition, however you can put as many as you need in
+    :file:`config.inc.php`, copy that block or needed parts (you don't have to
+    define all settings, just those you need to change).
+
+    .. note::
+       
+        The :config:option:`$cfg['Servers']` array starts with
+        $cfg['Servers'][1]. Do not use $cfg['Servers'][0]. If you want more
+        than one server, just copy following section (including $i
+        incrementation) serveral times. There is no need to define full server
+        array, just define values you need to change.
+
+
+.. config:option:: $cfg['Servers'][$i]['host']
+
+    :type: string
+    :default: ``'localhost'``
+
+    The hostname or :term:`IP` address of your $i-th MySQL-server. E.g.
+    ``localhost``.
+
+    Possible values are:
+
+    * hostname, e.g., ``'localhost'`` or ``'mydb.example.org'``
+    * IP address, e.g., ``'127.0.0.1'`` or ``'192.168.10.1'``
+    * dot - ``'.'``, i.e., use named pipes on windows systems
+    * empty - ``''``, disables this server
+
+.. config:option:: $cfg['Servers'][$i]['port']
+
+    :type: string
+    :default: ``''``
+
+    The port-number of your $i-th MySQL-server. Default is 3306 (leave
+    blank). 
+    
+    .. note::
+       
+       If you use ``localhost`` as the hostname, MySQL ignores this port number
+       and connects with the socket, so if you want to connect to a port
+       different from the default port, use ``127.0.0.1`` or the real hostname
+       in :config:option:`$cfg['Servers'][$i]['host']`.
+
+.. config:option:: $cfg['Servers'][$i]['socket']
+
+    :type: string
+    :default: ``''``
+
+    The path to the socket to use. Leave blank for default. To determine
+    the correct socket, check your MySQL configuration or, using the
+    :command:`mysql` command–line client, issue the ``status`` command. Among the
+    resulting information displayed will be the socket used.
+
+.. config:option:: $cfg['Servers'][$i]['ssl']
+
+    :type: boolean
+    :default: false
+
+    Whether to enable SSL for connection to MySQL server.
+
+.. config:option:: $cfg['Servers'][$i]['connect_type']
+
+    :type: string
+    :default: ``'tcp'``
+
+    What type connection to use with the MySQL server. Your options are
+    ``'socket'`` and ``'tcp'``. It defaults to tcp as that is nearly guaranteed
+    to be available on all MySQL servers, while sockets are not supported on
+    some platforms. To use the socket mode, your MySQL server must be on the
+    same machine as the Web server.
+
+.. config:option:: $cfg['Servers'][$i]['extension']
+
+    :type: string
+    :default: ``'mysqli'``
+
+    What php MySQL extension to use for the connection. Valid options are:
+
+    ``mysql``
+        The classic MySQL extension. 
+
+    ``mysqli`` 
+        The improved MySQL extension. This extension became available with PHP
+        5.0.0 and is the recommended way to connect to a server running MySQL
+        4.1.x or newer.
+
+.. config:option:: $cfg['Servers'][$i]['compress']
+
+    :type: boolean
+    :default: false
+
+    Whether to use a compressed protocol for the MySQL server connection
+    or not (experimental).
+
+.. _controlhost:
+.. config:option:: $cfg['Servers'][$i]['controlhost']
+
+    :type: string
+    :default: ``''``
+
+    Permits to use an alternate host to hold the configuration storage
+    data.
+
+.. _controluser:
+.. config:option:: $cfg['Servers'][$i]['controluser']
+
+    :type: string
+    :default: ``''``
+
+.. config:option:: $cfg['Servers'][$i]['controlpass']
+
+    :type: string
+    :default: ``''``
+
+    This special account is used for 2 distinct purposes: to make possible all
+    relational features (see :config:option:`$cfg['Servers'][$i]['pmadb']`) and,
+    for a MySQL server running with ``--skip-show-database``, to enable a
+    multi-user installation (:term:`HTTP` or cookie
+    authentication mode). 
+
+    When using :term:`HTTP` or
+    cookie authentication modes (or 'config' authentication mode since phpMyAdmin
+    2.2.1), you need to supply the details of a MySQL account that has ``SELECT``
+    privilege on the *mysql.user (all columns except "Password")*, *mysql.db (all
+    columns)* and *mysql.tables\_priv (all columns except "Grantor" and
+    "Timestamp")* tables. This account is used to check what databases the user
+    will see at login.
+
+    .. versionchanged:: 2.2.5 
+        those were called ``stduser`` and ``stdpass``
+
+    .. seealso:: :ref:`setup`, :ref:`authentication_modes`
+
+.. config:option:: $cfg['Servers'][$i]['auth_type']
+
+    :type: string
+    :default: ``'cookie'``
+
+    Whether config or cookie or :term:`HTTP` or signon authentication should be
+    used for this server.
+
+    * 'config' authentication (``$auth_type = 'config'``) is the plain old
+      way: username and password are stored in :file:`config.inc.php`.
+    * 'cookie' authentication mode (``$auth_type = 'cookie'``) as
+      introduced in 2.2.3 allows you to log in as any valid MySQL user with
+      the help of cookies. Username and password are stored in cookies
+      during the session and password is deleted when it ends. This can also
+      allow you to log in in arbitrary server if :config:option:`$cfg['AllowArbitraryServer']` enabled.
+    * 'http' authentication (was
+      called 'advanced' in previous versions and can be written also as
+      'http') (``$auth_type = 'http';'``) as introduced in 1.3.0 allows you to log in as any
+      valid MySQL user via HTTP-Auth.
+    * 'signon' authentication mode (``$auth_type = 'signon'``) as
+      introduced in 2.10.0 allows you to log in from prepared PHP session
+      data or using supplied PHP script. This is useful for implementing
+      single signon from another application. Sample way how to seed session
+      is in signon example: :file:`examples/signon.php`. There is also
+      alternative example using OpenID - :file:`examples/openid.php` and example
+      for scripts based solution - :file:`examples/signon-script.php`. You need
+      to configure :config:option:`$cfg['Servers'][$i]['SignonSession']` or 
+      :config:option:`$cfg['Servers'][$i]['SignonScript']` and 
+      :config:option:`$cfg['Servers'][$i]['SignonURL']` to use this authentication 
+      method.
+
+    .. seealso:: :ref:`authentication_modes`
+
+.. _servers_auth_http_realm:
+.. config:option:: $cfg['Servers'][$i]['auth_http_realm']
+
+    :type: string
+    :default: ``''``
+
+    When using auth\_type = ``http``, this field allows to define a custom
+    :term:`HTTP` Basic Auth Realm which will be displayed to the user. If not
+    explicitly specified in your configuration, a string combined of
+    "phpMyAdmin " and either :config:option:`$cfg['Servers'][$i]['verbose']` or
+    :config:option:`$cfg['Servers'][$i]['host']` will be used.
+
+.. _servers_auth_swekey_config:
+.. config:option:: $cfg['Servers'][$i]['auth_swekey_config']
+
+    :type: string
+    :default: ``''``
+
+    The name of the file containing :ref:`swekey` ids and login names for hardware
+    authentication. Leave empty to deactivate this feature.
+
+.. _servers_user:
+.. config:option:: $cfg['Servers'][$i]['user']
+
+    :type: string
+    :default: ``'root'``
+
+.. config:option:: $cfg['Servers'][$i]['password']
+
+    :type: string
+    :default: ``''``
+
+    When using :config:option:`$cfg['Servers'][$i]['auth_type']` set to
+    'config', this is the user/password-pair which phpMyAdmin will use to
+    connect to the MySQL server. This user/password pair is not needed when
+    :term:`HTTP` or cookie authentication is used
+    and should be empty.
+
+.. _servers_nopassword:
+.. config:option:: $cfg['Servers'][$i]['nopassword']
+
+    :type: boolean
+    :default: false
+
+    Allow attempt to log in without password when a login with password
+    fails. This can be used together with http authentication, when
+    authentication is done some other way and phpMyAdmin gets user name
+    from auth and uses empty password for connecting to MySQL. Password
+    login is still tried first, but as fallback, no password method is
+    tried.
+
+.. _servers_only_db:
+.. config:option:: $cfg['Servers'][$i]['only_db']
+
+    :type: string or array
+    :default: ``''``
+
+    If set to a (an array of) database name(s), only this (these)
+    database(s) will be shown to the user. Since phpMyAdmin 2.2.1,
+    this/these database(s) name(s) may contain MySQL wildcards characters
+    ("\_" and "%"): if you want to use literal instances of these
+    characters, escape them (I.E. use ``'my\_db'`` and not ``'my_db'``).
+
+    This setting is an efficient way to lower the server load since the
+    latter does not need to send MySQL requests to build the available
+    database list. But **it does not replace the privileges rules of the
+    MySQL database server**. If set, it just means only these databases
+    will be displayed but **not that all other databases can't be used.**
+
+    An example of using more that one database:
+
+    .. code-block:: php
+        
+        $cfg['Servers'][$i]['only_db'] = array('db1', 'db2');
+
+    .. versionchanged:: 4.0.0 
+        Previous versions permitted to specify the display order of 
+        the database names via this directive. 
+
+.. config:option:: $cfg['Servers'][$i]['hide_db']
+
+    :type: string
+    :default: ``''``
+
+    Regular expression for hiding some databases from unprivileged users.
+    This only hides them from listing, but a user is still able to access
+    them (using, for example, the SQL query area). To limit access, use
+    the MySQL privilege system.  For example, to hide all databases
+    starting with the letter "a", use
+
+    .. code-block:: php
+
+        $cfg['Servers'][$i]['hide_db'] = '^a';
+
+    and to hide both "db1" and "db2" use
+
+    .. code-block:: php
+
+        $cfg['Servers'][$i]['hide_db'] = '^(db1|db2)$';
+
+    More information on regular expressions can be found in the `PCRE
+    pattern syntax
+    <http://php.net/manual/en/reference.pcre.pattern.syntax.php>`_ portion
+    of the PHP reference manual.
+
+.. config:option:: $cfg['Servers'][$i]['verbose']
+
+    :type: string
+    :default: ``''``
+
+    Only useful when using phpMyAdmin with multiple server entries. If
+    set, this string will be displayed instead of the hostname in the
+    pull-down menu on the main page. This can be useful if you want to
+    show only certain databases on your system, for example. For HTTP
+    auth, all non-US-ASCII characters will be stripped.
+
+.. config:option:: $cfg['Servers'][$i]['pmadb']
+
+    :type: string
+    :default: ``''``
+
+    The name of the database containing the phpMyAdmin configuration
+    storage.  
+
+    See the :ref:`linked-tables`  section in this document to see the benefits of
+    this feature, and for a quick way of creating this database and the needed
+    tables.  
+
+    If you are the only user of this phpMyAdmin installation, you can use your
+    current database to store those special tables; in this case, just put your
+    current database name in :config:option:`$cfg['Servers'][$i]['pmadb']`. For a
+    multi-user installation, set this parameter to the name of your central
+    database containing the phpMyAdmin configuration storage.
+
+.. _bookmark:
+.. config:option:: $cfg['Servers'][$i]['bookmarktable']
+
+    :type: string
+    :default: ``''``
+
+    Since release 2.2.0 phpMyAdmin allows users to bookmark queries. This
+    can be useful for queries you often run. To allow the usage of this
+    functionality:
+
+    * set up :config:option:`$cfg['Servers'][$i]['pmadb']` and the phpMyAdmin configuration storage
+    * enter the table name in :config:option:`$cfg['Servers'][$i]['bookmarktable']`
+
+
+.. _relation:
+.. config:option:: $cfg['Servers'][$i]['relation']
+
+    :type: string
+    :default: ``''``
+
+    Since release 2.2.4 you can describe, in a special 'relation' table,
+    which column is a key in another table (a foreign key). phpMyAdmin
+    currently uses this to
+
+    * make clickable, when you browse the master table, the data values that
+      point to the foreign table;
+    * display in an optional tool-tip the "display column" when browsing the
+      master table, if you move the mouse to a column containing a foreign
+      key (use also the 'table\_info' table); (see :ref:`faqdisplay`)
+    * in edit/insert mode, display a drop-down list of possible foreign keys
+      (key value and "display column" are shown) (see :ref:`faq6_21`)
+    * display links on the table properties page, to check referential
+      integrity (display missing foreign keys) for each described key;
+    * in query-by-example, create automatic joins (see :ref:`faq6_6`)
+    * enable you to get a :term:`PDF` schema of
+      your database (also uses the table\_coords table).
+
+    The keys can be numeric or character. 
+
+    To allow the usage of this functionality:
+
+    * set up :config:option:`$cfg['Servers'][$i]['pmadb']` and the phpMyAdmin configuration storage
+    * put the relation table name in :config:option:`$cfg['Servers'][$i]['relation']`
+    * now as normal user open phpMyAdmin and for each one of your tables
+      where you want to use this feature, click :guilabel:`Structure/Relation view/`
+      and choose foreign columns.
+
+    .. note:: 
+       
+        In the current version, ``master_db`` must be the same as ``foreign_db``.
+        Those columns have been put in future development of the cross-db
+        relations.
+
+.. _table_info:
+.. config:option:: $cfg['Servers'][$i]['table_info']
+
+    :type: string
+    :default: ``''``
+
+    Since release 2.3.0 you can describe, in a special 'table\_info'
+    table, which column is to be displayed as a tool-tip when moving the
+    cursor over the corresponding key. This configuration variable will
+    hold the name of this special table. To allow the usage of this
+    functionality:
+
+    * set up :config:option:`$cfg['Servers'][$i]['pmadb']` and the phpMyAdmin configuration storage
+    * put the table name in :config:option:`$cfg['Servers'][$i]['table\_info']` (e.g.
+      ``pma__table_info``)
+    * then for each table where you want to use this feature, click
+      "Structure/Relation view/Choose column to display" to choose the
+      column.
+
+    .. seealso:: :ref:`faqdisplay`
+
+.. _table_coords:
+.. config:option:: $cfg['Servers'][$i]['table_coords']
+
+    :type: string
+    :default: ``''``
+
+.. config:option:: $cfg['Servers'][$i]['pdf_pages']
+
+    :type: string
+    :default: ``''``
+
+    Since release 2.3.0 you can have phpMyAdmin create :term:`PDF` pages
+    showing the relations between your tables. To do this it needs two tables
+    "pdf\_pages" (storing information about the available :term:`PDF` pages)
+    and "table\_coords" (storing coordinates where each table will be placed on
+    a :term:`PDF` schema output).  You must be using the "relation" feature. 
+
+    To allow the usage of this functionality:
+
+    * set up :config:option:`$cfg['Servers'][$i]['pmadb']` and the phpMyAdmin configuration storage
+    * put the correct table names in
+      :config:option:`$cfg['Servers'][$i]['table\_coords']` and
+      :config:option:`$cfg['Servers'][$i]['pdf\_pages']`
+
+    .. seealso:: :ref:`faqpdf`.
+
+.. _col_com:
+.. config:option:: $cfg['Servers'][$i]['column_info']
+
+    :type: string
+    :default: ``''``
+
+    This part requires a content update!  Since release 2.3.0 you can
+    store comments to describe each column for each table. These will then
+    be shown on the "printview". 
+
+    Starting with release 2.5.0, comments are consequently used on the table
+    property pages and table browse view, showing up as tool-tips above the
+    column name (properties page) or embedded within the header of table in
+    browse view. They can also be shown in a table dump. Please see the
+    relevant configuration directives later on. 
+
+    Also new in release 2.5.0 is a MIME- transformation system which is also
+    based on the following table structure. See :ref:`transformations` for
+    further information. To use the MIME- transformation system, your
+    column\_info table has to have the three new columns 'mimetype',
+    'transformation', 'transformation\_options'.
+
+
+    To allow the usage of this functionality:
+
+    * set up :config:option:`$cfg['Servers'][$i]['pmadb']` and the phpMyAdmin configuration storage
+    * put the table name in :config:option:`$cfg['Servers'][$i]['column\_info']` (e.g.
+      ``pma__column_info``)
+    * to update your PRE-2.5.0 Column\_comments Table use this:  and
+      remember that the Variable in :file:`config.inc.php` has been renamed from
+      :config:option:`$cfg['Servers'][$i]['column\_comments']` to
+      :config:option:`$cfg['Servers'][$i]['column\_info']`
+
+      .. code-block:: mysql
+
+           ALTER TABLE `pma__column_comments`
+           ADD `mimetype` VARCHAR( 255 ) NOT NULL,
+           ADD `transformation` VARCHAR( 255 ) NOT NULL,
+           ADD `transformation_options` VARCHAR( 255 ) NOT NULL;
+
+.. _history:
+.. config:option:: $cfg['Servers'][$i]['history']
+
+    :type: string
+    :default: ``''``
+
+    Since release 2.5.0 you can store your :term:`SQL` history, which means all
+    queries you entered manually into the phpMyAdmin interface. If you don't
+    want to use a table-based history, you can use the JavaScript-based
+    history. 
+
+    Using that, all your history items are deleted when closing the window.
+    Using :config:option:`$cfg['QueryHistoryMax']` you can specify an amount of
+    history items you want to have on hold. On every login, this list gets cut
+    to the maximum amount.
+
+    The query history is only available if JavaScript is enabled in
+    your browser. 
+
+    To allow the usage of this functionality:
+
+    * set up :config:option:`$cfg['Servers'][$i]['pmadb']` and the phpMyAdmin configuration storage
+    * put the table name in :config:option:`$cfg['Servers'][$i]['history']` (e.g.
+      ``pma__history``)
+
+.. _recent:
+.. config:option:: $cfg['Servers'][$i]['recent']
+
+    :type: string
+    :default: ``''``
+
+    Since release 3.5.0 you can show recently used tables in the
+    navigation panel. It helps you to jump across table directly, without
+    the need to select the database, and then select the table. Using
+    :config:option:`$cfg['NumRecentTables']` you can configure the maximum number
+    of recent tables shown. When you select a table from the list, it will jump to
+    the page specified in :config:option:`$cfg['NavigationTreeDefaultTabTable']`.
+
+
+    Without configuring the storage, you can still access the recently used tables,
+    but it will disappear after you logout. 
+
+    To allow the usage of this functionality persistently:
+
+    * set up :config:option:`$cfg['Servers'][$i]['pmadb']` and the phpMyAdmin configuration storage
+    * put the table name in :config:option:`$cfg['Servers'][$i]['recent']` (e.g.
+      ``pma__recent``)
+
+.. _table_uiprefs:
+.. config:option:: $cfg['Servers'][$i]['table_uiprefs']
+
+    :type: string
+    :default: ``''``
+
+    Since release 3.5.0 phpMyAdmin can be configured to remember several
+    things (sorted column :config:option:`$cfg['RememberSorting']`, column order,
+    and column visibility from a database table) for browsing tables. Without
+    configuring the storage, these features still can be used, but the values will
+    disappear after you logout. 
+
+    To allow the usage of these functionality persistently:
+
+    * set up :config:option:`$cfg['Servers'][$i]['pmadb']` and the phpMyAdmin configuration storage
+    * put the table name in :config:option:`$cfg['Servers'][$i]['table\_uiprefs']` (e.g.
+      ``pma__table_uiprefs``)
+
+
+.. _tracking:
+.. config:option:: $cfg['Servers'][$i]['tracking']
+
+    :type: string
+    :default: ``''``
+
+    Since release 3.3.x a tracking mechanism is available. It helps you to
+    track every :term:`SQL` command which is
+    executed by phpMyAdmin. The mechanism supports logging of data
+    manipulation and data definition statements. After enabling it you can
+    create versions of tables.  
+
+    The creation of a version has two effects:
+
+    * phpMyAdmin saves a snapshot of the table, including structure and
+      indexes.
+    * phpMyAdmin logs all commands which change the structure and/or data of
+      the table and links these commands with the version number.
+
+    Of course you can view the tracked changes. On the :guilabel:`Tracking`
+    page a complete report is available for every version. For the report you
+    can use filters, for example you can get a list of statements within a date
+    range. When you want to filter usernames you can enter \* for all names or
+    you enter a list of names separated by ','. In addition you can export the
+    (filtered) report to a file or to a temporary database.
+
+    To allow the usage of this functionality:
+
+    * set up :config:option:`$cfg['Servers'][$i]['pmadb']` and the phpMyAdmin configuration storage
+    * put the table name in :config:option:`$cfg['Servers'][$i]['tracking']` (e.g.
+      ``pma__tracking``)
+
+
+.. _tracking2:
+.. config:option:: $cfg['Servers'][$i]['tracking_version_auto_create']
+
+    :type: boolean
+    :default: false
+
+    Whether the tracking mechanism creates versions for tables and views
+    automatically.
+
+    If this is set to true and you create a table or view with
+
+    * CREATE TABLE ...
+    * CREATE VIEW ...
+
+    and no version exists for it, the mechanism will create a version for
+    you automatically.
+
+.. _tracking3:
+.. config:option:: $cfg['Servers'][$i]['tracking_default_statements']
+
+    :type: string
+    :default: ``'CREATE TABLE,ALTER TABLE,DROP TABLE,RENAME TABLE,CREATE INDEX,DROP INDEX,INSERT,UPDATE,DELETE,TRUNCATE,REPLACE,CREATE VIEW,ALTER VIEW,DROP VIEW,CREATE DATABASE,ALTER DATABASE,DROP DATABASE'``
+
+    Defines the list of statements the auto-creation uses for new
+    versions. 
+
+.. _tracking4:
+.. config:option:: $cfg['Servers'][$i]['tracking_add_drop_view']
+
+    :type: boolean
+    :default: true
+
+    Whether a DROP VIEW IF EXISTS statement will be added as first line to
+    the log when creating a view.
+
+.. _tracking5:
+.. config:option:: $cfg['Servers'][$i]['tracking_add_drop_table']
+
+    :type: boolean
+    :default: true
+
+    Whether a DROP TABLE IF EXISTS statement will be added as first line
+    to the log when creating a table.
+
+.. _tracking6:
+.. config:option:: $cfg['Servers'][$i]['tracking_add_drop_database']
+
+    :type: boolean
+    :default: true
+
+    Whether a DROP DATABASE IF EXISTS statement will be added as first
+    line to the log when creating a database.
+
+.. _userconfig:
+.. config:option:: $cfg['Servers'][$i]['userconfig']
+
+    :type: string
+    :default: ``''``
+
+    Since release 3.4.x phpMyAdmin allows users to set most preferences by
+    themselves and store them in the database.
+
+    If you don't allow for storing preferences in
+    :config:option:`$cfg['Servers'][$i]['pmadb']`, users can still personalize
+    phpMyAdmin, but settings will be saved in browser's local storage, or, it
+    is is unavailable, until the end of session.  
+
+    To allow the usage of this functionality:
+
+    * set up :config:option:`$cfg['Servers'][$i]['pmadb']` and the phpMyAdmin configuration storage
+    * put the table name in :config:option:`$cfg['Servers'][$i]['userconfig']`
+
+
+
+.. _designer_coords:
+.. config:option:: $cfg['Servers'][$i]['designer_coords']
+
+    :type: string
+    :default: ``''``
+
+    Since release 2.10.0 a Designer interface is available; it permits to
+    visually manage the relations.  
+
+    To allow the usage of this functionality:
+
+    * set up :config:option:`$cfg['Servers'][$i]['pmadb']` and the phpMyAdmin configuration storage
+    * put the table name in :config:option:`$cfg['Servers'][$i]['designer\_coords']`
+      (e.g. ``pma__designer_coords``)
+
+
+
+.. config:option:: $cfg['Servers'][$i]['MaxTableUiprefs']
+
+    :type: integer
+    :default: 100
+
+    Maximum number of rows saved in
+    :config:option:`$cfg['Servers'][$i]['table_uiprefs']` table. 
+
+    When tables are dropped or renamed,
+    :config:option:`$cfg['Servers'][$i]['table_uiprefs']` may contain invalid data
+    (referring to tables which no longer exist). We only keep this number of newest
+    rows in :config:option:`$cfg['Servers'][$i]['table_uiprefs']` and automatically
+    delete older rows.
+
+.. config:option:: $cfg['Servers'][$i]['AllowRoot']
+
+    :type: boolean
+    :default: true
+
+    Whether to allow root access. This is just a shortcut for the
+    :config:option:`$cfg['Servers'][$i]['AllowDeny']['rules']` below.
+
+.. config:option:: $cfg['Servers'][$i]['AllowNoPassword']
+
+    :type: boolean
+    :default: false
+
+    Whether to allow logins without a password. The default value of
+    ``false`` for this parameter prevents unintended access to a MySQL
+    server with was left with an empty password for root or on which an
+    anonymous (blank) user is defined.
+
+.. _servers_allowdeny_order:
+.. config:option:: $cfg['Servers'][$i]['AllowDeny']['order']
+
+    :type: string
+    :default: ``''``
+
+    If your rule order is empty, then :term:`IP`
+    authorization is disabled. 
+
+    If your rule order is set to
+    ``'deny,allow'`` then the system applies all deny rules followed by
+    allow rules. Access is allowed by default. Any client which does not
+    match a Deny command or does match an Allow command will be allowed
+    access to the server. 
+
+    If your rule order is set to ``'allow,deny'``
+    then the system applies all allow rules followed by deny rules. Access
+    is denied by default. Any client which does not match an Allow
+    directive or does match a Deny directive will be denied access to the
+    server. 
+
+    If your rule order is set to ``'explicit'``, authorization is
+    performed in a similar fashion to rule order 'deny,allow', with the
+    added restriction that your host/username combination **must** be
+    listed in the *allow* rules, and not listed in the *deny* rules. This
+    is the **most** secure means of using Allow/Deny rules, and was
+    available in Apache by specifying allow and deny rules without setting
+    any order. 
+
+    Please also see :config:option:`$cfg['TrustedProxies']` for
+    detecting IP address behind proxies.
+
+.. _servers_allowdeny_rules:
+.. config:option:: $cfg['Servers'][$i]['AllowDeny']['rules']
+
+    :type: array of strings
+    :default: array()
+
+    The general format for the rules is as such:
+
+    .. code-block:: none
+        
+        <'allow' | 'deny'> <username> [from] <ipmask>
+
+    If you wish to match all users, it is possible to use a ``'%'`` as a
+    wildcard in the *username* field.
+
+    There are a few shortcuts you can
+    use in the *ipmask* field as well (please note that those containing
+    SERVER\_ADDRESS might not be available on all webservers):
+
+    .. code-block:: none
+
+        
+        'all' -> 0.0.0.0/0
+        'localhost' -> 127.0.0.1/8
+        'localnetA' -> SERVER_ADDRESS/8
+        'localnetB' -> SERVER_ADDRESS/16
+        'localnetC' -> SERVER_ADDRESS/24
+
+    Having an empty rule list is equivalent to either using ``'allow %
+    from all'`` if your rule order is set to ``'deny,allow'`` or ``'deny %
+    from all'`` if your rule order is set to ``'allow,deny'`` or
+    ``'explicit'``.
+
+    For the :term:`IP address` matching
+    system, the following work: 
+
+    * ``xxx.xxx.xxx.xxx`` (an exact :term:`IP address`) 
+    * ``xxx.xxx.xxx.[yyy-zzz]`` (an :term:`IP address` range) 
+    * ``xxx.xxx.xxx.xxx/nn`` (CIDR, Classless Inter-Domain Routing type :term:`IP` addresses) 
+
+    But the following does not work: 
+
+    * ``xxx.xxx.xxx.xx[yyy-zzz]`` (partial :term:`IP` address range) 
+
+    For :term:`IPv6` addresses, the following work:
+
+    * ``xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx`` (an exact :term:`IPv6` address)
+    * ``xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:[yyyy-zzzz]`` (an :term:`IPv6` address range)
+    * ``xxxx:xxxx:xxxx:xxxx/nn`` (CIDR, Classless Inter-Domain Routing type :term:`IPv6` addresses)
+
+    But the following does not work:
+
+    * ``xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xx[yyy-zzz]`` (partial :term:`IPv6` address range)
+
+.. config:option:: $cfg['Servers'][$i]['DisableIS']
+
+    :type: boolean
+    :default: true
+
+    Disable using ``INFORMATION_SCHEMA`` to retrieve information (use
+    ``SHOW`` commands instead), because of speed issues when many
+    databases are present. Currently used in some parts of the code, more
+    to come.
+
+.. config:option:: $cfg['Servers'][$i]['ShowDatabasesCommand']
+
+    :type: string
+    :default: ``'SHOW DATABASES'``
+
+    On a server with a huge number of databases, the default ``SHOW DATABASES``
+    command used to fetch the name of available databases will probably be too
+    slow, so it can be replaced by faster commands. You can use ``#user#``
+    string will be replaced by current user.
+
+    When using ``false``, it will disable fetching databases from the server,
+    only databases in :config:option:`$cfg['Servers'][$i]['only_db']` will be
+    displayed.
+    
+    Examples:
+
+    * ``'SHOW DATABASES'``
+    * ``"SHOW DATABASES LIKE '#user#\_%'"``
+    * ``'SELECT DISTINCT TABLE_SCHEMA FROM information_schema.SCHEMA_PRIVILEGES'``
+    * ``'SELECT SCHEMA_NAME FROM information_schema.SCHEMATA'``
+    * ``false``
+
+.. config:option:: $cfg['Servers'][$i]['SignonScript']
+
+    :type: string
+    :default: ``''``
+
+    Name of PHP script to be sourced and executed to obtain login
+    credentials. This is alternative approach to session based single
+    signon. The script needs to provide function
+    ``get_login_credentials`` which returns list of username and
+    password, accepting single parameter of existing username (can be
+    empty). See :file:`examples/signon-script.php` for an example.
+
+.. config:option:: $cfg['Servers'][$i]['SignonSession']
+
+    :type: string
+    :default: ``''``
+
+    Name of session which will be used for signon authentication method.
+    You should use something different than ``phpMyAdmin``, because this
+    is session which phpMyAdmin uses internally. Takes effect only if 
+    :config:option:`$cfg['Servers'][$i]['SignonScript']` is not configured.
+
+.. config:option:: $cfg['Servers'][$i]['SignonURL']
+
+    :type: string
+    :default: ``''``
+
+    :term:`URL` where user will be redirected
+    to log in for signon authentication method. Should be absolute
+    including protocol.
+
+.. config:option:: $cfg['Servers'][$i]['LogoutURL']
+
+    :type: string
+    :default: ``''``
+
+    :term:`URL` where user will be redirected
+    after logout (doesn't affect config authentication method). Should be
+    absolute including protocol.
+
+.. config:option:: $cfg['Servers'][$i]['StatusCacheDatabases']
+
+    :type: array of strings
+    :default: array()
+
+    Enables caching of ``TABLE STATUS`` outputs for specific databases on
+    this server (in some cases ``TABLE STATUS`` can be very slow, so you
+    may want to cache it). APC is used (if the PHP extension is available,
+    if not, this setting is ignored silently). You have to provide 
+    :config:option:`$cfg['Servers'][$i]['StatusCacheLifetime']`. 
+    
+    Takes effect only if :config:option:`$cfg['Servers'][$i]['DisableIS']` is
+    ``true``.
+
+.. config:option:: $cfg['Servers'][$i]['StatusCacheLifetime']
+
+    :type: integer
+    :default: 0
+
+    Lifetime in seconds of the ``TABLE STATUS`` cache if 
+    :config:option:`$cfg['Servers'][$i]['StatusCacheDatabases']` is used.
+
+Generic settings
+----------------
+
+.. config:option:: $cfg['ServerDefault']
+
+    :type: integer
+    :default: 1
+
+    If you have more than one server configured, you can set
+    :config:option:`$cfg['ServerDefault']` to any one of them to autoconnect to that
+    server when phpMyAdmin is started, or set it to 0 to be given a list
+    of servers without logging in. 
+    
+    If you have only one server configured,
+    :config:option:`$cfg['ServerDefault']` MUST be set to that server.
+
+.. config:option:: $cfg['VersionCheck']
+
+    :type: boolean
+    :default: true
+
+    Enables check for latest versions using javascript on main phpMyAdmin
+    page.
+
+    .. note::
+
+        This setting can be adjusted by your vendor.
+
+.. config:option:: $cfg['MaxDbList']
+
+    :type: integer
+    :default: 100
+
+    The maximum number of database names to be displayed in the main panel's
+    database list.
+
+.. config:option:: $cfg['MaxNavigationItems']
+
+    :type: integer
+    :default: 25
+
+    The number of items that can be displayed on each page of the
+    navigation tree.
+
+.. config:option:: $cfg['MaxTableList']
+
+    :type: integer
+    :default: 250
+
+    The maximum number of table names to be displayed in the main panel's
+    list (except on the Export page). This limit is also enforced in the
+    navigation panel when in Light mode.
+
+.. config:option:: $cfg['ShowHint']
+
+    :type: boolean
+    :default: true
+
+    Whether or not to show hints (for example, hints when hovering over
+    table headers).
+
+.. config:option:: $cfg['MaxCharactersInDisplayedSQL']
+
+    :type: integer
+    :default: 1000
+
+    The maximum number of characters when a :term:`SQL` query is displayed. The
+    default limit of 1000 should be correct to avoid the display of tons of
+    hexadecimal codes that represent BLOBs, but some users have real
+    :term:`SQL` queries that are longer than 1000 characters. Also, if a
+    query's length exceeds this limit, this query is not saved in the history.
+
+.. config:option:: $cfg['PersistentConnections']
+
+    :type: boolean
+    :default: false
+
+    Whether `persistent connections <http://php.net/manual/en/features
+    .persistent-connections.php>`_ should be used or not. Works with
+    following extensions:
+
+    * mysql (`mysql\_pconnect <http://php.net/manual/en/function.mysql-
+      pconnect.php>`_),
+    * mysqli (requires PHP 5.3.0 or newer, `more information
+      <http://php.net/manual/en/mysqli.persistconns.php>`_).
+
+.. config:option:: $cfg['ForceSSL']
+
+    :type: boolean
+    :default: false
+
+    Whether to force using https while accessing phpMyAdmin.
+
+.. config:option:: $cfg['ExecTimeLimit']
+
+    :type: integer [number of seconds]
+    :default: 300
+
+    Set the number of seconds a script is allowed to run. If seconds is
+    set to zero, no time limit is imposed. This setting is used while
+    importing/exporting dump files but has
+    no effect when PHP is running in safe mode.
+
+.. config:option:: $cfg['SessionSavePath']
+
+    :type: string
+    :default: ``''``
+
+    Path for storing session data (`session\_save\_path PHP parameter
+    <http://php.net/session_save_path>`_).
+
+.. config:option:: $cfg['MemoryLimit']
+
+    :type: string [number of bytes]
+    :default: ``'0'``
+
+    Set the number of bytes a script is allowed to allocate. If set to
+    zero, no limit is imposed. 
+    
+    This setting is used while importing/exporting dump files and at some other
+    places in phpMyAdmin so you definitely don't want to put here a too low
+    value. It has no effect when PHP is running in safe mode. 
+    
+    You can also use any string as in :file:`php.ini`, eg. '16M'. Ensure you
+    don't omit the suffix (16 means 16 bytes!)
+
+.. config:option:: $cfg['SkipLockedTables']
+
+    :type: boolean
+    :default: false
+
+    Mark used tables and make it possible to show databases with locked
+    tables (since MySQL 3.23.30).
+
+.. config:option:: $cfg['ShowSQL']
+
+    :type: boolean
+    :default: true
+
+    Defines whether :term:`SQL` queries
+    generated by phpMyAdmin should be displayed or not.
+
+.. config:option:: $cfg['RetainQueryBox']
+
+    :type: boolean
+    :default: false
+
+    Defines whether the :term:`SQL` query box
+    should be kept displayed after its submission.
+
+.. config:option:: $cfg['CodemirrorEnable']
+
+    :type: boolean
+    :default: true
+
+    Defines whether to use a Javascript code editor for SQL query boxes.
+    CodeMirror provides syntax highlighting and line numbers.  However,
+    middle-clicking for pasting the clipboard contents in some Linux
+    distributions (such as Ubuntu) is not supported by all browsers.
+
+.. config:option:: $cfg['AllowUserDropDatabase']
+
+    :type: boolean
+    :default: false
+
+    Defines whether normal users (non-administrator) are allowed to delete
+    their own database or not. If set as false, the link :guilabel:`Drop
+    Database` will not be shown, and even a ``DROP DATABASE mydatabase`` will
+    be rejected. Quite practical for :term:`ISP` 's with many customers. 
+
+    .. note:: 
+       
+        This limitation of :term:`SQL` queries is not
+        as strict as when using MySQL privileges. This is due to nature of
+        :term:`SQL` queries which might be quite
+        complicated.  So this choice should be viewed as help to avoid accidental
+        dropping rather than strict privilege limitation.
+
+.. config:option:: $cfg['Confirm']
+
+    :type: boolean
+    :default: true
+
+    Whether a warning ("Are your really sure...") should be displayed when
+    you're about to lose data.
+
+.. config:option:: $cfg['UseDbSearch']
+
+    :type: boolean
+    :default: true
+
+    Define whether the "search string inside database" is enabled or not.
+
+.. config:option:: $cfg['IgnoreMultiSubmitErrors']
+
+    :type: boolean
+    :default: false
+
+    Define whether phpMyAdmin will continue executing a multi-query
+    statement if one of the queries fails. Default is to abort execution.
+
+Cookie authentication options
+-----------------------------
+
+.. config:option:: $cfg['blowfish_secret']
+
+    :type: string
+    :default: ``''``
+
+    The "cookie" auth\_type uses blowfish algorithm to encrypt the
+    password. If you are using the "cookie" auth\_type, enter here a
+    random passphrase of your choice. It will be used internally by the
+    blowfish algorithm: you won’t be prompted for this passphrase. There
+    is no maximum length for this secret. 
+
+    .. versionchanged:: 3.1.0
+        Since version 3.1.0 phpMyAdmin can generate this on the fly, but it
+        makes a bit weaker security as this generated secret is stored in
+        session and furthermore it makes impossible to recall user name from
+        cookie.
+
+.. config:option:: $cfg['LoginCookieRecall']
+
+    :type: boolean
+    :default: true
+
+    Define whether the previous login should be recalled or not in cookie
+    authentication mode. 
+    
+    This is automatically disabled if you do not have
+    configured :config:option:`$cfg['blowfish_secret']`.
+
+.. config:option:: $cfg['LoginCookieValidity']
+
+    :type: integer [number of seconds]
+    :default: 1440
+
+    Define how long a login cookie is valid. Please note that php
+    configuration option `session.gc\_maxlifetime
+    <http://php.net/manual/en/session.configuration.php#ini.session.gc-
+    maxlifetime>`_ might limit session validity and if the session is lost,
+    the login cookie is also invalidated. So it is a good idea to set
+    ``session.gc_maxlifetime`` at least to the same value of
+    :config:option:`$cfg['LoginCookieValidity']`.
+
+.. config:option:: $cfg['LoginCookieStore']
+
+    :type: integer [number of seconds]
+    :default: 0
+
+    Define how long login cookie should be stored in browser. Default 0
+    means that it will be kept for existing session. This is recommended
+    for not trusted environments.
+
+.. config:option:: $cfg['LoginCookieDeleteAll']
+
+    :type: boolean
+    :default: true
+
+    If enabled (default), logout deletes cookies for all servers,
+    otherwise only for current one. Setting this to false makes it easy to
+    forget to log out from other server, when you are using more of them.
+
+.. _AllowArbitraryServer:
+.. config:option:: $cfg['AllowArbitraryServer']
+
+    :type: boolean
+    :default: false
+
+    If enabled, allows you to log in to arbitrary servers using cookie
+    authentication.
+
+    .. note::
+       
+        Please use this carefully, as this may allow users access to MySQL servers
+        behind the firewall where your :term:`HTTP`
+        server is placed.
+
+Navigation panel setup
+----------------------
+
+.. config:option:: $cfg['NavigationTreeEnableGrouping']
+
+    :type: boolean
+    :default: true
+
+    Defines whether to group the databases based on a common prefix
+    in their name :config:option:`$cfg['NavigationTreeDbSeparator']`.
+
+.. config:option:: $cfg['NavigationTreeDbSeparator']
+
+    :type: string or array
+    :default: ``'_'``
+
+    The string used to separate the parts of the database name when
+    showing them in a tree. Alternatively you can specify more strings in
+    an array and all of them will be used as a separator.
+
+.. config:option:: $cfg['NavigationTreeTableSeparator']
+
+    :type: string or array
+    :default: ``'__'``
+
+    Defines a string to be used to nest table spaces. This means if you have
+    tables like ``first__second__third`` this will be shown as a three-level
+    hierarchy like: first > second > third.  If set to false or empty, the
+    feature is disabled. NOTE: You should not use this separator at the
+    beginning or end of a table name or multiple times after another without
+    any other characters in between.
+
+.. config:option:: $cfg['NavigationTreeTableLevel']
+
+    :type: integer
+    :default: 1
+
+    Defines how many sublevels should be displayed when splitting up
+    tables by the above separator.
+
+.. config:option:: $cfg['NumRecentTables']
+
+    :type: integer
+    :default: 10
+
+    The maximum number of recently used tables shown in the navigation
+    panel. Set this to 0 (zero) to disable the listing of recent tables.
+
+.. config:option:: $cfg['ShowTooltip']
+
+    :type: boolean
+    :default: true
+
+    Defines whether to display item comments as tooltips in navigation
+    panel or not.
+
+.. config:option:: $cfg['NavigationDisplayLogo']
+
+    :type: boolean
+    :default: true
+
+    Defines whether or not to display the phpMyAdmin logo at the top of
+    the navigation panel.
+
+.. config:option:: $cfg['NavigationLogoLink']
+
+    :type: string
+    :default: ``'index.php'``
+
+    Enter :term:`URL` where logo in the
+    navigation panel will point to. For use especially with self made
+    theme which changes this.
+
+.. config:option:: $cfg['NavigationLogoLinkWindow']
+
+    :type: string
+    :default: ``'main'``
+
+    Whether to open the linked page in the main window (``main``) or in a
+    new one (``new``). Note: use ``new`` if you are linking to
+    ``phpmyadmin.net``.
+
+.. config:option:: $cfg['NavigationTreeDisplayItemFilterMinimum']
+
+    :type: integer
+    :default: 30
+
+    Defines the minimum number of items (tables, views, routines and
+    events) to display a JavaScript filter box above the list of items in
+    the navigation tree. 
+    
+    To disable the filter completely some high number can be used (e.g. 9999)
+
+.. config:option:: $cfg['NavigationTreeDisplayDbFilterMinimum']
+
+    :type: integer
+    :default: 30
+
+    Defines the minimum number of databases to display a JavaScript filter
+    box above the list of databases in the navigation tree.
+    
+    To disable the filter completely some high number can be used
+    (e.g. 9999)
+
+.. config:option:: $cfg['NavigationDisplayServers']
+
+    :type: boolean
+    :default: true 
+
+    Defines whether or not to display a server choice at the top of the
+    navigation panel.
+
+.. config:option:: $cfg['DisplayServersList']
+
+    :type: boolean
+    :default: false
+
+    Defines whether to display this server choice as links instead of in a
+    drop-down.
+
+.. config:option:: $cfg['NavigationTreeDefaultTabTable']
+
+    :type: string
+    :default: ``'tbl_structure.php'``
+
+    Defines the tab displayed by default when clicking the small icon next
+    to each table name in the navigation panel. Possible values:
+
+    * ``tbl_structure.php``
+    * ``tbl_sql.php``
+    * ``tbl_select.php``
+    * ``tbl_change.php``
+    * ``sql.php``
+
+Main panel
+----------
+
+.. config:option:: $cfg['ShowStats']
+
+    :type: boolean
+    :default: true
+
+    Defines whether or not to display space usage and statistics about
+    databases and tables. Note that statistics requires at least MySQL
+    3.23.3 and that, at this date, MySQL doesn't return such information
+    for Berkeley DB tables.
+
+.. config:option:: $cfg['ShowServerInfo']
+
+    :type: boolean
+    :default: true
+
+    Defines whether to display detailed server information on main page.
+    You can additionally hide more information by using 
+    :config:option:`$cfg['Servers'][$i]['verbose']`.
+
+.. config:option:: $cfg['ShowPhpInfo']
+
+    :type: boolean
+    :default: false
+
+.. config:option:: $cfg['ShowChgPassword']
+
+    :type: boolean
+    :default: true
+
+.. config:option:: $cfg['ShowCreateDb']
+
+    :type: boolean
+    :default: true
+
+    Defines whether to display the :guilabel:`PHP information` and
+    :guilabel:`Change password` links and form for creating database or not at
+    the starting main (right) frame. This setting does not check MySQL commands
+    entered directly. 
+    
+    Please note that to block the usage of ``phpinfo()`` in scripts, you have to
+    put this in your :file:`php.ini`:
+
+    .. code-block:: ini
+
+        disable_functions = phpinfo()
+
+    Also note that enabling the :guilabel:`Change password` link has no effect
+    with config authentication mode: because of the hard coded password value
+    in the configuration file, end users can't be allowed to change their
+    passwords.
+
+Database structure
+------------------
+
+.. config:option:: $cfg['ShowDbStructureCreation']
+
+    :type: boolean
+    :default: false
+
+    Defines whether the database structure page (tables list) has a
+    "Creation" column that displays when each table was created.
+
+.. config:option:: $cfg['ShowDbStructureLastUpdate']
+
+    :type: boolean
+    :default: false
+
+    Defines whether the database structure page (tables list) has a "Last
+    update" column that displays when each table was last updated.
+
+.. config:option:: $cfg['ShowDbStructureLastCheck']
+
+    :type: boolean
+    :default: false
+
+    Defines whether the database structure page (tables list) has a "Last
+    check" column that displays when each table was last checked.
+
+.. config:option:: $cfg['HideStructureActions']
+
+    :type: boolean
+    :default: true
+
+    Defines whether the table structure actions are hidden under a "More"
+    drop-down.
+
+Browse mode
+-----------
+
+.. config:option:: $cfg['NavigationBarIconic']
+
+    :type: string
+    :default: true
+
+    Defines whether navigation bar buttons contain text or symbols only. A 
+    value of true displays icons, false displays text and 'both' displays 
+    both icons and text.
+
+.. config:option:: $cfg['ShowAll']
+
+    :type: boolean
+    :default: false
+
+    Defines whether a user should be displayed a "Show all" button in
+    browse mode or not in all cases. By default it is shown only on small
+    tables (less than 5 × :config:option:`$cfg['MaxRows']` rows) to avoid
+    performance issues while getting too many rows.
+
+.. config:option:: $cfg['MaxRows']
+
+    :type: integer
+    :default: 30
+
+    Number of rows displayed when browsing a result set and no LIMIT
+    clause is used. If the result set contains more rows, "Previous" and
+    "Next" links will be shown.
+
+.. config:option:: $cfg['Order']
+
+    :type: string
+    :default: ``'SMART'``
+
+    Defines whether columns are displayed in ascending (``ASC``) order, in
+    descending (``DESC``) order or in a "smart" (``SMART``) order - I.E.
+    descending order for columns of type TIME, DATE, DATETIME and
+    TIMESTAMP, ascending order else- by default.
+
+.. config:option:: $cfg['DisplayBinaryAsHex']
+
+    :type: boolean
+    :default: true
+
+    Defines whether the "Show binary contents as HEX" browse option is
+    ticked by default.
+
+.. config:option:: $cfg['GridEditing']
+
+    :type: string
+    :default: ``'double-click'``
+
+    Defines which action (``double-click`` or ``click``) triggers grid
+    editing. Can be deactived with the ``disabled`` value.
+
+.. config:option:: $cfg['SaveCellsAtOnce']
+
+    :type: boolean
+    :default: false
+
+    Defines whether or not to save all edited cells at once for grid
+    editing.
+
+Editing mode
+------------
+
+.. config:option:: $cfg['ProtectBinary']
+
+    :type: boolean or string
+    :default: ``'blob'``
+
+    Defines whether ``BLOB`` or ``BINARY`` columns are protected from
+    editing when browsing a table's content. Valid values are:
+
+    * ``false`` to allow editing of all columns;
+    * ``'blob'`` to allow editing of all columns except ``BLOBS``;
+    * ``'noblob'`` to disallow editing of all columns except ``BLOBS`` (the
+      opposite of ``'blob'``);
+    * ``'all'`` to disallow editing of all ``BINARY`` or ``BLOB`` columns.
+
+.. config:option:: $cfg['ShowFunctionFields']
+
+    :type: boolean
+    :default: true
+
+    Defines whether or not MySQL functions fields should be initially
+    displayed in edit/insert mode. Since version 2.10, the user can toggle
+    this setting from the interface.
+
+.. config:option:: $cfg['ShowFieldTypesInDataEditView']
+
+    :type: boolean
+    :default: true
+
+    Defines whether or not type fields should be initially displayed in
+    edit/insert mode. The user can toggle this setting from the interface.
+
+.. config:option:: $cfg['InsertRows']
+
+    :type: integer
+    :default: 2
+
+    Defines the maximum number of concurrent entries for the Insert page.
+
+.. config:option:: $cfg['ForeignKeyMaxLimit']
+
+    :type: integer
+    :default: 100
+
+    If there are fewer items than this in the set of foreign keys, then a
+    drop-down box of foreign keys is presented, in the style described by
+    the :config:option:`$cfg['ForeignKeyDropdownOrder']` setting.
+
+.. config:option:: $cfg['ForeignKeyDropdownOrder']
+
+    :type: array
+    :default: array('content-id', 'id-content')
+
+    For the foreign key drop-down fields, there are several methods of
+    display, offering both the key and value data. The contents of the
+    array should be one or both of the following strings: ``content-id``,
+    ``id-content``.
+
+Export and import settings
+--------------------------
+
+.. config:option:: $cfg['ZipDump']
+
+    :type: boolean
+    :default: true
+
+.. config:option:: $cfg['GZipDump']
+
+    :type: boolean
+    :default: true
+
+.. config:option:: $cfg['BZipDump']
+
+    :type: boolean
+    :default: true
+
+    Defines whether to allow the use of zip/GZip/BZip2 compression when
+    creating a dump file
+
+.. config:option:: $cfg['CompressOnFly']
+
+    :type: boolean
+    :default: true
+
+    Defines whether to allow on the fly compression for GZip/BZip2
+    compressed exports. This doesn't affect smaller dumps and allows users
+    to create larger dumps that won't otherwise fit in memory due to php
+    memory limit. Produced files contain more GZip/BZip2 headers, but all
+    normal programs handle this correctly.
+
+.. config:option:: $cfg['Export']
+
+    :type: array
+    :default: array(...)
+
+    In this array are defined default parameters for export, names of
+    items are similar to texts seen on export page, so you can easily
+    identify what they mean.
+
+.. config:option:: $cfg['Export']['method']
+
+    :type: string
+    :default: ``'quick'``
+
+    Defines how the export form is displayed when it loads. Valid values
+    are:
+
+    * ``quick`` to display the minimum number of options to configure
+    * ``custom`` to display every available option to configure
+    * ``custom-no-form`` same as ``custom`` but does not display the option
+      of using quick export
+
+
+
+.. config:option:: $cfg['Import']
+
+    :type: array
+    :default: array(...)
+
+    In this array are defined default parameters for import, names of
+    items are similar to texts seen on import page, so you can easily
+    identify what they mean.
+
+
+Tabs display settings
+---------------------
+
+.. config:option:: $cfg['PropertiesIconic']
+
+    :type: string
+    :default: ``'both'``
+
+    If set to ``true``, will display icons instead of text for db and table
+    properties links (like :guilabel:`Browse`, :guilabel:`Select`,
+    :guilabel:`Insert`, ...) and for the menu tabs. Can be set to ``'both'`` 
+    if you want icons AND text. When set to ``false``, will only show text.
+
+.. config:option:: $cfg['PropertiesNumColumns']
+
+    :type: integer
+    :default: 1
+
+    How many columns will be utilized to display the tables on the database
+    property view? When setting this to a value larger than 1, the type of the
+    database will be omitted for more display space.
+
+.. config:option:: $cfg['DefaultTabServer']
+
+    :type: string
+    :default: ``'index.php'``
+
+    Defines the tab displayed by default on server view. Possible values:
+
+    * ``main.php`` (recommended for multi-user setups)
+    * ``server_databases.php``,
+    * ``server_status.php``
+    * ``server_variables.php``
+    * ``server_privileges.php``
+
+.. config:option:: $cfg['DefaultTabDatabase']
+
+    :type: string
+    :default: ``'db_structure.php'``
+
+    Defines the tab displayed by default on database view. Possible
+    values: 
+    
+    * ``db_structure.php``
+    * ``db_sql.php`` 
+    * ``db_search.php``.
+
+.. config:option:: $cfg['DefaultTabTable']
+
+    :type: string
+    :default: ``'sql.php'``
+
+    Defines the tab displayed by default on table view. Possible values:
+
+    * ``tbl_structure.php``
+    * ``tbl_sql.php``
+    * ``tbl_select.php``
+    * ``tbl_change.php`` 
+    * ``sql.php``
+
+Documentation
+-------------
+
+.. config:option:: $cfg['MySQLManualBase']
+
+    :type: string
+    :default: ``'http://dev.mysql.com/doc/refman'``
+
+    If set to an :term:`URL` which points to
+    the MySQL documentation (type depends on
+    :config:option:`$cfg['MySQLManualType']`), appropriate help links are
+    generated. 
+
+    See `MySQL Documentation page <http://dev.mysql.com/doc/>`_ for more
+    information about MySQL manuals and their types.
+
+.. config:option:: $cfg['MySQLManualType']
+
+    :type: string
+    :default: ``'viewable'``
+
+    Type of MySQL documentation:
+
+    * viewable - "viewable online", current one used on MySQL website
+    * searchable - "Searchable, with user comments"
+    * chapters - "HTML, one page per chapter"
+    * big - "HTML, all on one page"
+    * none - do not show documentation links
+
+Languages
+---------
+
+.. config:option:: $cfg['DefaultLang']
+
+    :type: string
+    :default: ``'en'``
+
+    Defines the default language to use, if not browser-defined or user-
+    defined. The corresponding language file needs to be in
+    locale/*code*/LC\_MESSAGES/phpmyadmin.mo.
+
+.. config:option:: $cfg['DefaultConnectionCollation']
+
+    :type: string
+    :default: ``'utf8_general_ci'``
+
+    Defines the default connection collation to use, if not user-defined.
+    See the `MySQL documentation <http://dev.mysql.com/doc/mysql/en
+    /charset-charsets.html>`_ for list of possible values. This setting is
+    ignored when connected to Drizzle server.
+
+.. config:option:: $cfg['Lang']
+
+    :type: string
+    :default: not set
+
+    Force language to use. The corresponding language file needs to be in
+    locale/*code*/LC\_MESSAGES/phpmyadmin.mo.
+
+.. config:option:: $cfg['FilterLanguages']
+
+    :type: string
+    :default: ``''``
+
+    Limit list of available languages to those matching the given regular
+    expression. For example if you want only Czech and English, you should
+    set filter to ``'^(cs|en)'``.
+
+.. config:option:: $cfg['RecodingEngine']
+
+    :type: string
+    :default: ``'auto'``
+
+    You can select here which functions will be used for character set
+    conversion. Possible values are:
+
+    * auto - automatically use available one (first is tested iconv, then
+      recode)
+    * iconv - use iconv or libiconv functions
+    * recode - use recode\_string function
+    * none - disable encoding conversion
+
+    Enabled charset conversion activates a pull-down menu in the Export
+    and Import pages, to choose the character set when exporting a file.
+    The default value in this menu comes from
+    :config:option:`$cfg['Export']['charset']` and :config:option:`$cfg['Import']['charset']`.
+
+.. config:option:: $cfg['IconvExtraParams']
+
+    :type: string
+    :default: ``'//TRANSLIT'``
+
+    Specify some parameters for iconv used in charset conversion. See
+    `iconv documentation <http://www.gnu.org/software/libiconv/documentati
+    on/libiconv/iconv_open.3.html>`_ for details. By default
+    ``//TRANSLIT`` is used, so that invalid characters will be
+    transliterated.
+
+.. config:option:: $cfg['AvailableCharsets']
+
+    :type: array
+    :default: array(..._
+
+    Available character sets for MySQL conversion. You can add your own
+    (any of supported by recode/iconv) or remove these which you don't
+    use. Character sets will be shown in same order as here listed, so if
+    you frequently use some of these move them to the top.
+
+Web server settings
+-------------------
+
+.. config:option:: $cfg['OBGzip']
+
+    :type: string/boolean
+    :default: ``'auto'``
+
+    Defines whether to use GZip output buffering for increased speed in
+    :term:`HTTP` transfers. Set to
+    true/false for enabling/disabling. When set to 'auto' (string),
+    phpMyAdmin tries to enable output buffering and will automatically
+    disable it if your browser has some problems with buffering. IE6 with
+    a certain patch is known to cause data corruption when having enabled
+    buffering.
+
+.. config:option:: $cfg['TrustedProxies']
+
+    :type: array
+    :default: array()
+
+    Lists proxies and HTTP headers which are trusted for 
+    :config:option:`$cfg['Servers'][$i]['AllowDeny']['order']`. This list is by
+    default empty, you need to fill in some trusted proxy servers if you
+    want to use rules for IP addresses behind proxy. 
+
+    The following example specifies that phpMyAdmin should trust a
+    HTTP\_X\_FORWARDED\_FOR (``X -Forwarded-For``) header coming from the proxy
+    1.2.3.4:
+
+    .. code-block:: php
+        
+        $cfg['TrustedProxies'] = array('1.2.3.4' => 'HTTP_X_FORWARDED_FOR');
+
+    The :config:option:`$cfg['Servers'][$i]['AllowDeny']['rules']` directive uses the
+    client's IP address as usual.
+
+.. config:option:: $cfg['GD2Available']
+
+    :type: string
+    :default: ``'auto'``
+
+    Specifies whether GD >= 2 is available. If yes it can be used for MIME
+    transformations. Possible values are:
+
+    * auto - automatically detect
+    * yes - GD 2 functions can be used
+    * no - GD 2 function cannot be used
+
+.. config:option:: $cfg['CheckConfigurationPermissions']
+
+    :type: boolean
+    :default: true
+
+    We normally check the permissions on the configuration file to ensure
+    it's not world writable. However, phpMyAdmin could be installed on a
+    NTFS filesystem mounted on a non-Windows server, in which case the
+    permissions seems wrong but in fact cannot be detected. In this case a
+    sysadmin would set this parameter to ``false``.
+
+.. config:option:: $cfg['LinkLengthLimit']
+
+    :type: integer
+    :default: 1000
+
+    Limit for length of :term:`URL` in links.  When length would be above this
+    limit, it is replaced by form with button. This is required as some web
+    servers (:term:`IIS`) have problems with long :term:`URL` .
+ 
+.. config:option:: $cfg['CSPAllow']
+
+    :type: string
+    :default: ``''``
+
+    Additional string to include in allowed script sources in Content Security
+    Policy header.
+
+    This can be useful when you want to include some external javascript files
+    in :file:`config.footer.inc.php` or :file:`config.header.inc.php`, which
+    would be normally not allowed by Content Security Policy.
+
+.. config:option:: $cfg['DisableMultiTableMaintenance']
+
+    :type: boolean
+    :default: false
+
+    In the database Structure page, it's possible to mark some tables then
+    choose an operation like optimizing for many tables. This can slow
+    down a server; therefore, setting this to ``true`` prevents this kind
+    of multiple maintenance operation.
+
+Theme settings
+--------------
+
+.. config:option:: $cfg['NaviWidth']
+
+    :type: integer
+    :default:
+
+    Navigation panel width in pixels. See
+    :file:`themes/themename/layout.inc.php`.
+
+.. config:option:: $cfg['NaviBackground']
+
+    :type: string [CSS color for background]
+    :default:
+
+.. config:option:: $cfg['MainBackground']
+
+    :type: string [CSS color for background]
+    :default:
+
+    The background styles used for both the frames. See
+    :file:`themes/themename/layout.inc.php`.
+
+.. config:option:: $cfg['NaviPointerBackground']
+
+    :type: string [CSS color for background]
+    :default:
+
+.. config:option:: $cfg['NaviPointerColor']
+
+    :type: string [CSS color]
+    :default:
+
+    The style used for the pointer in the navi frame. See
+    :file:`themes/themename/layout.inc.php`.
+
+.. config:option:: $cfg['Border']
+
+    :type: integer
+    :default:
+
+    The size of a table's border. See :file:`themes/themename/layout.inc.php`.
+
+.. config:option:: $cfg['ThBackground']
+
+    :type: string [CSS color for background]
+    :default:
+
+.. config:option:: $cfg['ThColor']
+
+    :type: string [CSS color]
+    :default:
+
+    The style used for table headers. See
+    :file:`themes/themename/layout.inc.php`.
+
+.. _cfg_BgcolorOne:
+.. config:option:: $cfg['BgOne']
+
+    :type: string [CSS color]
+    :default:
+
+    The color (HTML) #1 for table rows. See
+    :file:`themes/themename/layout.inc.php`.
+
+.. _cfg_BgcolorTwo:
+.. config:option:: $cfg['BgTwo']
+
+    :type: string [CSS color]
+    :default:
+
+    The color (HTML) #2 for table rows. See
+    :file:`themes/themename/layout.inc.php`.
+
+.. config:option:: $cfg['BrowsePointerBackground']
+
+    :type: string [CSS color]
+    :default:
+
+.. config:option:: $cfg['BrowsePointerColor']
+
+    :type: string [CSS color]
+    :default:
+
+.. config:option:: $cfg['BrowseMarkerBackground']
+
+    :type: string [CSS color]
+    :default:
+
+.. config:option:: $cfg['BrowseMarkerColor']
+
+    :type: string [CSS color]
+    :default:
+
+    The colors (HTML) uses for the pointer and the marker in browse mode.
+    The former feature highlights the row over which your mouse is passing
+    and the latter lets you visually mark/unmark rows by clicking on the
+    corresponding checkbox. Highlighting / marking a column is done by
+    hovering over / clicking the column's header (outside of the text).
+    See :file:`themes/themename/layout.inc.php`.
+
+.. config:option:: $cfg['FontFamily']
+
+    :type: string
+    :default:
+
+    You put here a valid CSS font family value, for example ``arial, sans-
+    serif``. See :file:`themes/themename/layout.inc.php`.
+
+.. config:option:: $cfg['FontFamilyFixed']
+
+    :type: string
+    :default:
+
+    You put here a valid CSS font family value, for example ``monospace``.
+    This one is used in textarea. See :file:`themes/themename/layout.inc.php`.
+
+Design customization
+--------------------
+
+.. config:option:: $cfg['NavigationTreePointerEnable']
+
+    :type: boolean
+    :default: true
+
+    A value of ``true`` activates the navi pointer.
+
+.. config:option:: $cfg['BrowsePointerEnable']
+
+    :type: boolean
+    :default: true
+
+    Whether to activate the browse pointer or not.
+
+.. config:option:: $cfg['BrowseMarkerEnable']
+
+    :type: boolean
+    :default: true
+
+    Whether to activate the browse marker or not.
+
+.. config:option:: $cfg['LimitChars']
+
+    :type: integer
+    :default: 50
+
+    Maximum number of characters shown in any non-numeric field on browse
+    view. Can be turned off by a toggle button on the browse page.
+
+.. config:option:: $cfg['RowActionLinks']
+
+    :type: string
+    :default: ``'left'``
+
+    Defines the place where table row links (Edit, Copy, Delete) would be
+    put when tables contents are displayed (you may have them displayed at
+    the left side, right side, both sides or nowhere). "left" and "right"
+    are parsed as "top" and "bottom" with vertical display mode.
+
+.. config:option:: $cfg['DefaultDisplay']
+
+    :type: string
+    :default: ``'horizonta'``
+
+    There are 3 display modes: horizontal, horizontalflipped and vertical.
+    Define which one is displayed by default. The first mode displays each
+    row on a horizontal line, the second rotates the headers by 90
+    degrees, so you can use descriptive headers even though columns only
+    contain small values and still print them out. The vertical mode sorts
+    each row on a vertical lineup.
+
+.. config:option:: $cfg['RememberSorting']
+
+    :type: boolean
+    :default: true
+
+    If enabled, remember the sorting of each table when browsing them.
+
+.. config:option:: $cfg['HeaderFlipType']
+
+    :type: string
+    :default: ``'auto'``
+
+    The HeaderFlipType can be set to 'auto', 'css' or 'fake'. When using
+    'css' the rotation of the header for horizontalflipped is done via
+    CSS. The CSS transformation currently works only in Internet
+    Explorer.If set to 'fake' PHP does the transformation for you, but of
+    course this does not look as good as CSS. The 'auto' option enables
+    CSS transformation when browser supports it and use PHP based one
+    otherwise.
+
+.. config:option:: $cfg['ShowBrowseComments']
+
+    :type: boolean
+    :default: true
+
+.. config:option:: $cfg['ShowPropertyComments']
+
+    :type: boolean
+    :default: true
+
+    By setting the corresponding variable to ``true`` you can enable the
+    display of column comments in Browse or Property display. In browse
+    mode, the comments are shown inside the header. In property mode,
+    comments are displayed using a CSS-formatted dashed-line below the
+    name of the column. The comment is shown as a tool-tip for that
+    column.
+
+Text fields
+-----------
+
+.. config:option:: $cfg['CharEditing']
+
+    :type: string
+    :default: ``'input'``
+
+    Defines which type of editing controls should be used for CHAR and
+    VARCHAR columns. Possible values are:
+
+    * input - this allows to limit size of text to size of columns in MySQL,
+      but has problems with newlines in columns
+    * textarea - no problems with newlines in columns, but also no length
+      limitations
+
+.. config:option:: $cfg['MinSizeForInputField']
+
+    :type: integer
+    :default: 4
+
+    Defines the minimum size for input fields generated for CHAR and
+    VARCHAR columns.
+
+.. config:option:: $cfg['MaxSizeForInputField']
+
+    :type: integer
+    :default: 60
+
+    Defines the maximum size for input fields generated for CHAR and
+    VARCHAR columns.
+
+.. config:option:: $cfg['TextareaCols']
+
+    :type: integer
+    :default: 40
+
+.. config:option:: $cfg['TextareaRows']
+
+    :type: integer
+    :default: 15
+
+.. config:option:: $cfg['CharTextareaCols']
+
+    :type: integer
+    :default: 40
+
+.. config:option:: $cfg['CharTextareaRows']
+
+    :type: integer
+    :default: 2
+
+    Number of columns and rows for the textareas. This value will be
+    emphasized (\*2) for :term:`SQL` query
+    textareas and (\*1.25) for :term:`SQL`
+    textareas inside the query window.
+
+    The Char\* values are used for CHAR
+    and VARCHAR editing (if configured via :config:option:`$cfg['CharEditing']`).
+
+.. config:option:: $cfg['LongtextDoubleTextarea']
+
+    :type: boolean
+    :default: true
+
+    Defines whether textarea for LONGTEXT columns should have double size.
+
+.. config:option:: $cfg['TextareaAutoSelect']
+
+    :type: boolean
+    :default: false
+
+    Defines if the whole textarea of the query box will be selected on
+    click.
+
+
+SQL query box settings
+----------------------
+
+.. config:option:: $cfg['SQLQuery']['Edit']
+
+    :type: boolean
+    :default: true
+
+    Whether to display an edit link to change a query in any SQL Query
+    box.
+
+.. config:option:: $cfg['SQLQuery']['Explain']
+
+    :type: boolean
+    :default: true
+
+    Whether to display a link to explain a SELECT query in any SQL Query
+    box.
+
+.. config:option:: $cfg['SQLQuery']['ShowAsPHP']
+
+    :type: boolean
+    :default: true
+
+    Whether to display a link to wrap a query in PHP code in any SQL Query
+    box.
+
+.. config:option:: $cfg['SQLQuery']['Validate']
+
+    :type: boolean
+    :default: false
+
+    Whether to display a link to validate a query in any SQL Query box.
+
+    .. seealso:: :config:option:`$cfg['SQLValidator']`
+
+.. config:option:: $cfg['SQLQuery']['Refresh']
+
+    :type: boolean
+    :default: true
+
+    Whether to display a link to refresh a query in any SQL Query box.
+
+Web server upload/save/import directories
+-----------------------------------------
+
+.. config:option:: $cfg['UploadDir']
+
+    :type: string
+    :default: ``''``
+
+    The name of the directory where :term:`SQL` files have been uploaded by
+    other means than phpMyAdmin (for example, ftp). Those files are available
+    under a drop-down box when you click the database or table name, then the
+    Import tab. 
+
+    If
+    you want different directory for each user, %u will be replaced with
+    username. 
+
+    Please note that the file names must have the suffix ".sql"
+    (or ".sql.bz2" or ".sql.gz" if support for compressed formats is
+    enabled).
+
+    This feature is useful when your file is too big to be
+    uploaded via :term:`HTTP`, or when file
+    uploads are disabled in PHP.
+
+    .. note::
+       
+        If PHP is running in safe mode, this directory must be owned by the same
+        user as the owner of the phpMyAdmin scripts.  See also :ref:`faq1_16` for
+        alternatives.
+
+.. config:option:: $cfg['SaveDir']
+
+    :type: string
+    :default: ``''``
+
+    The name of the directory where dumps can be saved. 
+
+    If you want different directory for each user, %u will be replaced with
+    username.
+
+    Please note that the directory must exist and has to be writable for
+    the user running webserver. 
+
+    .. note:: 
+       
+        If PHP is running in safe mode, this directory must be owned by the same
+        user as the owner of the phpMyAdmin scripts.
+
+.. config:option:: $cfg['TempDir']
+
+    :type: string
+    :default: ``''``
+
+    The name of the directory where temporary files can be stored. 
+
+    This is needed for importing ESRI Shapefiles, see :ref:`faq6_30` and to
+    work around limitations of ``open_basedir`` for uploaded files, see
+    :ref:`faq1_11`.  
+
+    If the directory where phpMyAdmin is installed is
+    subject to an ``open_basedir`` restriction, you need to create a
+    temporary directory in some directory accessible by the web server.
+    However for security reasons, this directory should be outside the
+    tree published by webserver. If you cannot avoid having this directory
+    published by webserver, place at least an empty :file:`index.html` file
+    there, so that directory listing is not possible.
+
+    This directory should have as strict permissions as possible as the only
+    user required to access this directory is the one who runs the webserver.
+    If you have root privileges, simply make this user owner of this directory
+    and make it accessible only by it:
+
+    .. code-block:: sh
+
+        
+        chown www-data:www-data tmp
+        chmod 700 tmp
+
+    If you cannot change owner of the directory, you can achieve a similar
+    setup using :term:`ACL`:
+
+    .. code-block:: sh
+
+        chmod 700 tmp
+        setfacl -m "g:www-data:rwx" tmp
+        setfacl -d -m "g:www-data:rwx" tmp
+
+    If neither of above works for you, you can still make the directory
+    :command:`chmod 777`, but it might impose risk of other users on system
+    reading and writing data in this directory.
+
+Various display setting
+-----------------------
+
+.. config:option:: $cfg['ShowDisplayDirection']
+
+    :type: boolean
+    :default: false
+
+    Defines whether or not type display direction option is shown when
+    browsing a table.
+
+.. config:option:: $cfg['RepeatCells']
+
+    :type: integer
+    :default: 100
+
+    Repeat the headers every X cells, or 0 to deactivate.
+
+.. config:option:: $cfg['EditInWindow']
+
+    :type: boolean
+    :default: true
+
+.. config:option:: $cfg['QueryWindowWidth']
+
+    :type: integer
+    :default: 550
+
+.. config:option:: $cfg['QueryWindowHeight']
+
+    :type: integer
+    :default: 310
+
+.. config:option:: $cfg['QueryHistoryDB']
+
+    :type: boolean
+    :default: false
+
+.. config:option:: $cfg['QueryWindowDefTab']
+
+    :type: string
+    :default: ``'sql'``
+
+.. config:option:: $cfg['QueryHistoryMax']
+
+    :type: integer
+    :default: 25
+
+    All those variables affect the query window feature. A :term:`SQL` link or
+    icon is always displayed in the navigation panel. If JavaScript is enabled
+    in your browser, a click on this opens a distinct query window, which is a
+    direct interface to enter :term:`SQL` queries. Otherwise, the right panel
+    changes to display a query box. 
+
+    The size of this query window can be customized with
+    :config:option:`$cfg['QueryWindowWidth']` and
+    :config:option:`$cfg['QueryWindowHeight']` - both integers for the size in
+    pixels.  Note that normally, those parameters will be modified in
+    :file:`layout.inc.php`` for the theme you are using. 
+
+    If :config:option:`$cfg['EditInWindow']` is set to true, a click on [Edit]
+    from the results page (in the :guilabel:`Showing Rows` section) opens the
+    query window and puts the current query inside it. If set to false,
+    clicking on the link puts the :term:`SQL` query
+    in the right panel's query box.  
+
+    If :config:option:`$cfg['QueryHistoryDB']` is set to ``true``, all your
+    Queries are logged to a table, which has to be created by you (see
+    :config:option:`$cfg['Servers'][$i]['history']`). If set to false, all your
+    queries will be appended to the form, but only as long as your window is
+    opened they remain saved.  
+
+    When using the JavaScript based query window, it will always get updated
+    when you click on a new table/db to browse and will focus if you click on
+    :guilabel:`Edit SQL` after using a query. You can suppress updating the
+    query window by checking the box :guilabel:`Do not overwrite this query
+    from outside the window` below the query textarea. Then you can browse
+    tables/databases in the background without losing the contents of the
+    textarea, so this is especially useful when composing a query with tables
+    you first have to look in. The checkbox will get automatically checked
+    whenever you change the contents of the textarea. Please uncheck the button
+    whenever you definitely want the query window to get updated even though
+    you have made alterations. 
+
+    If :config:option:`$cfg['QueryHistoryDB']` is set to ``true`` you can
+    specify the amount of saved history items using
+    :config:option:`$cfg['QueryHistoryMax']`. 
+
+    The query window also has a custom tabbed look to group the features.
+    Using the variable :config:option:`$cfg['QueryWindowDefTab']` you can
+    specify the default tab to be used when opening the query window. It can be
+    set to either ``sql``, ``files``, ``history`` or ``full``.
+
+.. config:option:: $cfg['BrowseMIME']
+
+    :type: boolean
+    :default: true
+
+    Enable :ref:`transformations`.
+
+.. config:option:: $cfg['MaxExactCount']
+
+    :type: integer
+    :default: 0
+
+    For InnoDB tables, determines for how large tables phpMyAdmin should
+    get the exact row count using ``SELECT COUNT``. If the approximate row
+    count as returned by ``SHOW TABLE STATUS`` is smaller than this value,
+    ``SELECT COUNT`` will be used, otherwise the approximate count will be
+    used.
+
+.. config:option:: $cfg['MaxExactCountViews']
+
+    :type: integer
+    :default: 0
+
+    For VIEWs, since obtaining the exact count could have an impact on
+    performance, this value is the maximum to be displayed, using a
+    ``SELECT COUNT ... LIMIT``. Setting this to 0 bypasses any row
+    counting.
+
+.. config:option:: $cfg['NaturalOrder']
+
+    :type: boolean
+    :default: true
+
+    Sorts database and table names according to natural order (for
+    example, t1, t2, t10). Currently implemented in the navigation panel
+    and in Database view, for the table list.
+
+.. config:option:: $cfg['InitialSlidersState']
+
+    :type: string
+    :default: ``'closed'``
+
+    If set to ``'closed'``, the visual sliders are initially in a closed
+    state. A value of ``'open'`` does the reverse. To completely disable
+    all visual sliders, use ``'disabled'``.
+
+.. config:option:: $cfg['UserprefsDisallow']
+
+    :type: array
+    :default: array()
+
+    Contains names of configuration options (keys in ``$cfg`` array) that
+    users can't set through user preferences. For possible values, refer
+    to :file:`libraries/config/user_preferences.forms.php`.
+
+.. config:option:: $cfg['UserprefsDeveloperTab']
+
+    :type: boolean
+    :default: false
+
+    Activates in the user preferences a tab containing options for
+    developers of phpMyAdmin.
+
+Page titles
+-----------
+
+.. config:option:: $cfg['TitleTable']
+
+    :type: string
+    :default: ``'@HTTP_HOST@ / @VSERVER@ / @DATABASE@ / @TABLE@ | @PHPMYADMIN@'``
+
+.. config:option:: $cfg['TitleDatabase']
+
+    :type: string
+    :default: ``'@HTTP_HOST@ / @VSERVER@ / @DATABASE@ | @PHPMYADMIN@'``
+
+.. config:option:: $cfg['TitleServer']
+
+    :type: string
+    :default: ``'@HTTP_HOST@ / @VSERVER@ | @PHPMYADMIN@'``
+
+.. config:option:: $cfg['TitleDefault']
+
+    :type: string
+    :default: ``'@HTTP_HOST@ | @PHPMYADMIN@'``
+
+    Allows you to specify window's title bar. You can use :ref:`faq6_27`.
+
+Theme manager settings
+----------------------
+
+.. config:option:: $cfg['ThemePath']
+
+    :type: string
+    :default: ``'./themes'``
+
+    If theme manager is active, use this as the path of the subdirectory
+    containing all the themes.
+
+.. config:option:: $cfg['ThemeManager']
+
+    :type: boolean
+    :default: true
+
+    Enables user-selectable themes. See :ref:`faqthemes`.
+
+.. config:option:: $cfg['ThemeDefault']
+
+    :type: string
+    :default: ``'pmahomme'``
+
+    The default theme (a subdirectory under :config:option:`$cfg['ThemePath']`).
+
+.. config:option:: $cfg['ThemePerServer']
+
+    :type: boolean
+    :default: false
+
+    Whether to allow different theme for each server.
+
+Default queries
+---------------
+
+.. config:option:: $cfg['DefaultQueryTable']
+
+    :type: string
+    :default: ``'SELECT * FROM @TABLE@ WHERE 1'``
+
+.. config:option:: $cfg['DefaultQueryDatabase']
+
+    :type: string
+    :default: ``''``
+
+    Default queries that will be displayed in query boxes when user didn't
+    specify any. You can use standard :ref:`faq6_27`.
+
+SQL parser settings
+-------------------
+
+.. config:option:: $cfg['SQP']['fmtType']
+
+    :type: string
+    :default: ``'html'``
+
+    The main use of the new :term:`SQL` Parser
+    is to pretty-print :term:`SQL` queries. By
+    default we use HTML to format the query, but you can disable this by
+    setting this variable to ``'none'``.
+
+    Available options:
+
+    * ``'html'``
+    * ``'none'``
+
+.. _cfg_SQP:
+.. config:option:: $cfg['SQP']['fmtInd']
+
+    :type: float
+    :default: ``'1'``
+
+.. config:option:: $cfg['SQP']['fmtIndUnit']
+
+    :type: string
+    :default: ``'em'``
+
+    For the pretty-printing of :term:`SQL` queries,
+    under some cases the part of a query inside a bracket is indented. By
+    changing :config:option:`$cfg['SQP']['fmtInd']` you can change the amount
+    of this indent. 
+
+    Related in purpose is :config:option:`$cfg['SQP']['fmtIndUnit']` which
+    specifies the units of the indent amount that you specified. This is used
+    via stylesheets.
+
+    You can use any HTML unit, for example:
+
+    * ``'em'``
+    * ``'ex'``
+    * ``'pt'``
+    * ``'px'``
+
+.. config:option:: $cfg['SQP']['fmtColor']
+
+    :type: array of string tuples
+    :default:
+
+    This array is used to define the colours for each type of element of
+    the pretty-printed :term:`SQL` queries.
+    The tuple format is *class* => [*HTML colour code* | *empty string*]
+
+
+    If you specify an empty string for the color of a class, it is ignored
+    in creating the stylesheet. You should not alter the class names, only
+    the colour strings.
+    
+    **Class name key:**
+
+    comment
+        Applies to all comment sub-classes
+    comment\_mysql
+        Comments as ``"#...\n"``
+    comment\_ansi
+        Comments as ``"-- ...\n"``
+    comment\_c
+        Comments as ``"/*...*/"``
+    digit
+        Applies to all digit sub-classes
+    digit\_hex
+        Hexadecimal numbers
+    digit\_integer
+        Integer numbers
+    digit\_float
+        Floating point numbers
+    punct
+        Applies to all punctuation sub-classes
+    punct\_bracket\_open\_round
+        Opening brackets ``"("``
+    punct\_bracket\_close\_round
+        Closing brackets ``")"``
+    punct\_listsep
+        List item Separator ``","``
+    punct\_qualifier
+        Table/Column Qualifier ``"."``
+    punct\_queryend
+        End of query marker ``";"``
+    alpha
+        Applies to all alphabetic classes
+    alpha\_columnType
+        Identifiers matching a column type
+    alpha\_columnAttrib
+        Identifiers matching a database/table/column attribute
+    alpha\_functionName
+        Identifiers matching a MySQL function name
+    alpha\_reservedWord
+        Identifiers matching any other reserved word
+    alpha\_variable
+        Identifiers matching a :term:`SQL` variable ``"@foo"``
+    alpha\_identifier
+        All other identifiers
+    quote
+        Applies to all quotation mark classes
+    quote\_double
+        Double quotes ``"``
+    quote\_single
+        Single quotes ``'``
+    quote\_backtick
+        Backtick quotes `````
+
+SQL validator settings
+----------------------
+
+.. config:option:: $cfg['SQLValidator']
+
+    :type: array
+    :default: array(...)
+
+
+
+.. config:option:: $cfg['SQLValidator']['use']
+
+    :type: boolean
+    :default: false
+
+    phpMyAdmin now supports use of the `Mimer SQL Validator
+    <http://developer.mimer.com/validator/index.htm>`_ service, as originally
+    published on `Slashdot
+    <http://developers.slashdot.org/article.pl?sid=02/02/19/1720246>`_. For
+    help in setting up your system to use the service, see the
+    :ref:`faqsqlvalidator`.
+
+.. config:option:: $cfg['SQLValidator']['username']
+
+    :type: string
+    :default: ``''``
+
+.. config:option:: $cfg['SQLValidator']['password']
+
+    :type: string
+    :default: ``''``
+
+    The SOAP service allows you to log in with ``anonymous`` and any password,
+    so we use those by default. Instead, if you have an account with them, you
+    can put your login details here, and it will be used in place of the
+    anonymous login.
+
+MySQL settings
+--------------
+
+.. config:option:: $cfg['DefaultFunctions']
+
+    :type: array
+    :default: array(...)
+
+    Functions selected by default when inserting/changing row, Functions
+    are defined for meta types as (FUNC\_NUMBER, FUNC\_DATE, FUNC\_CHAR,
+    FUNC\_SPATIAL, FUNC\_UUID) and for ``first_timestamp``, which is used
+    for first timestamp column in table.
+
+
+Developer
+---------
+
+.. warning::
+
+    These settings might have huge effect on performance or security.
+
+.. config:option:: $cfg['DBG']
+
+    :type: array
+    :default: array(...)
+
+.. config:option:: $cfg['DBG']['sql']
+
+    :type: boolean
+    :default: false
+
+    Enable logging queries and execution times to be
+    displayed in the bottom of main page (right frame).
+
+.. config:option:: $cfg['Error_Handler']['display']
+
+    :type: boolean
+    :default: false
+
+    Whether to display errors from PHP or not.
+
+.. config:option:: $cfg['Error_Handler']['gather']
+
+    :type: boolean
+    :default: false
+
+    Whether to gather errors from PHP or not.
+ 
diff --git a/phpmyadmin/doc/html/_sources/copyright.txt b/phpmyadmin/doc/html/_sources/copyright.txt
new file mode 100644
index 0000000..cfcb863
--- /dev/null
+++ b/phpmyadmin/doc/html/_sources/copyright.txt
@@ -0,0 +1,30 @@
+.. _copyright:
+
+Copyright
+=========
+
+.. code-block:: none
+
+    Copyright (C) 1998-2000 Tobias Ratschiller <tobias_at_ratschiller.com>
+    Copyright (C) 2001-2013 Marc Delisle <marc_at_infomarc.info>
+        Olivier Müller <om_at_omnis.ch>
+        Robin Johnson <robbat2_at_users.sourceforge.net>
+        Alexander M. Turek <me_at_derrabus.de>
+        Michal Čihař <michal_at_cihar.com>
+        Garvin Hicking <me_at_supergarv.de>
+        Michael Keck <mkkeck_at_users.sourceforge.net>
+        Sebastian Mendel <cybot_tm_at_users.sourceforge.net>
+        [check credits for more details]
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License version 2, as
+published by the Free Software Foundation.
+
+This program is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program. If not, see `http://www.gnu.org/licenses/
+<http://www.gnu.org/licenses/>`_.
diff --git a/phpmyadmin/doc/html/_sources/credits.txt b/phpmyadmin/doc/html/_sources/credits.txt
new file mode 100644
index 0000000..21f5e18
--- /dev/null
+++ b/phpmyadmin/doc/html/_sources/credits.txt
@@ -0,0 +1,597 @@
+.. _credits:
+
+Credits
+=======
+
+
+Credits, in chronological order
++++++++++++++++++++++++++++++++
+
+* Tobias Ratschiller <tobias\_at\_ratschiller.com>
+
+  * creator of the phpmyadmin project
+
+  * maintainer from 1998 to summer 2000
+
+* Marc Delisle <marc\_at\_infomarc.info>
+
+  * multi-language version in December 1998
+
+  * various fixes and improvements
+
+  * :term:`SQL` analyser (most of it)
+
+  * current project maintainer
+
+* Olivier Müller <om\_at\_omnis.ch>
+
+  * started SourceForge phpMyAdmin project in March 2001
+
+  * sync'ed different existing CVS trees with new features and bugfixes
+
+  * multi-language improvements, dynamic language selection
+
+  * many bugfixes and improvements
+
+* Loïc Chapeaux <lolo\_at\_phpheaven.net>
+
+  * rewrote and optimized javascript, DHTML and DOM stuff
+
+  * rewrote the scripts so they fit the :term:`PEAR` coding standards and 
+    generate XHTML1.0 and CSS2 compliant codes
+
+  * improved the language detection system
+
+  * many bugfixes and improvements
+
+* Robin Johnson <robbat2\_at\_users.sourceforge.net>
+
+  * database maintenance controls
+
+  * table type code
+
+  * Host authentication :term:`IP` Allow/Deny
+
+  * DB-based configuration (Not completed)
+
+  * :term:`SQL` parser and pretty-printer
+
+  * :term:`SQL` validator
+
+  * many bugfixes and improvements
+
+* Armel Fauveau <armel.fauveau\_at\_globalis-ms.com>
+
+  * bookmarks feature
+
+  * multiple dump feature
+
+  * gzip dump feature
+
+  * zip dump feature
+
+* Geert Lund <glund\_at\_silversoft.dk>
+
+  * various fixes
+
+  * moderator of the phpMyAdmin former users forum at phpwizard.net
+
+* Korakot Chaovavanich <korakot\_at\_iname.com>
+
+  * "insert as new row" feature
+
+* Pete Kelly <webmaster\_at\_trafficg.com>
+
+  * rewrote and fix dump code
+
+  * bugfixes
+
+* Steve Alberty <alberty\_at\_neptunlabs.de>
+
+  * rewrote dump code for PHP4
+
+  * mySQL table statistics
+
+  * bugfixes
+
+* Benjamin Gandon <gandon\_at\_isia.cma.fr>
+
+  * main author of the version 2.1.0.1
+
+  * bugfixes
+
+* Alexander M. Turek <me\_at\_derrabus.de>
+
+  * MySQL 4.0 / 4.1 / 5.0 compatibility
+
+  * abstract database interface (PMA\_DBI) with MySQLi support
+
+  * privileges administration
+
+  * :term:`XML` exports
+
+  * various features and fixes
+
+  * German language file updates
+
+* Mike Beck <mike.beck\_at\_web.de>
+
+  * automatic joins in QBE
+
+  * links column in printview
+
+  * Relation view
+
+* Michal Čihař <michal\_at\_cihar.com>
+
+  * enhanced index creation/display feature
+
+  * feature to use a different charset for HTML than for MySQL
+
+  * improvements of export feature
+
+  * various features and fixes
+
+  * Czech language file updates
+
+* Christophe Gesché from the "MySQL Form Generator for PHPMyAdmin"
+  (http://sf.net/projects/phpmysqlformgen/)
+
+  * suggested the patch for multiple table printviews
+
+* Garvin Hicking <me\_at\_supergarv.de>
+
+  * built the patch for vertical display of table rows
+
+  * built the Javascript based Query window + :term:`SQL` history
+
+  * Improvement of column/db comments
+
+  * (MIME)-Transformations for columns
+
+  * Use custom alias names for Databases in left frame
+
+  * hierarchical/nested table display
+
+  * :term:`PDF`-scratchboard for WYSIWYG-
+    distribution of :term:`PDF` relations
+
+  * new icon sets
+
+  * vertical display of column properties page
+
+  * some bugfixes, features, support, German language additions
+
+* Yukihiro Kawada <kawada\_at\_den.fujifilm.co.jp>
+
+  * japanese kanji encoding conversion feature
+
+* Piotr Roszatycki <d3xter\_at\_users.sourceforge.net> and Dan Wilson
+
+  * the Cookie authentication mode
+
+* Axel Sander <n8falke\_at\_users.sourceforge.net>
+
+  * table relation-links feature
+
+* Maxime Delorme <delorme.maxime\_at\_free.fr>
+
+  * :term:`PDF` schema output, thanks also to
+    Olivier Plathey for the "FPDF" library (see <http://www.fpdf.org/>), Steven
+    Wittens for the "UFPDF" library (see <http://www.acko.net/node/56>) and
+    Nicola Asuni for the "TCPDF" library (see <http://www.tcpdf.org/>).
+
+* Olof Edlund <olof.edlund\_at\_upright.se>
+
+  * :term:`SQL` validator server
+
+* Ivan R. Lanin <ivanlanin\_at\_users.sourceforge.net>
+
+  * phpMyAdmin logo (until June 2004)
+
+* Mike Cochrane <mike\_at\_graftonhall.co.nz>
+
+  * blowfish library from the Horde project (withdrawn in release 4.0)
+
+* Marcel Tschopp <ne0x\_at\_users.sourceforge.net>
+
+  * mysqli support
+
+  * many bugfixes and improvements
+
+* Nicola Asuni (Tecnick.com)
+
+  * TCPDF library (`http://www.tcpdf.org <http://www.tcpdf.org>`_)
+
+* Michael Keck <mkkeck\_at\_users.sourceforge.net>
+
+  * redesign for 2.6.0
+
+  * phpMyAdmin sailboat logo (June 2004)
+
+* Mathias Landhäußer
+
+  * Representation at conferences
+
+* Sebastian Mendel <cybot\_tm\_at\_users.sourceforge.net>
+
+  * interface improvements
+
+  * various bugfixes
+
+* Ivan A Kirillov
+
+  * new relations Designer
+
+* Raj Kissu Rajandran (Google Summer of Code 2008)
+
+  * BLOBstreaming support (withdrawn in release 4.0)
+
+* Piotr Przybylski (Google Summer of Code 2008, 2010 and 2011)
+
+  * improved setup script
+
+  * user preferences
+
+  * Drizzle support
+
+* Derek Schaefer (Google Summer of Code 2009)
+
+  * Improved the import system
+
+* Alexander Rutkowski (Google Summer of Code 2009)
+
+  * Tracking mechanism
+
+* Zahra Naeem (Google Summer of Code 2009)
+
+  * Synchronization feature (removed in release 4.0)
+
+* Tomáš Srnka (Google Summer of Code 2009)
+
+  * Replication support
+
+* Muhammad Adnan (Google Summer of Code 2010)
+
+  * Relation schema export to multiple formats
+
+* Lori Lee (Google Summer of Code 2010)
+
+  * User interface improvements
+
+  * ENUM/SET editor
+
+  * Simplified interface for export/import
+
+* Ninad Pundalik (Google Summer of Code 2010)
+
+  * AJAXifying the interface
+
+* Martynas Mickevičius (Google Summer of Code 2010)
+
+  * Charts
+
+* Barrie Leslie
+
+  * BLOBstreaming support with PBMS PHP extension (withdrawn in release
+    4.0)
+
+* Ankit Gupta (Google Summer of Code 2010)
+
+  * Visual query builder
+
+* Madhura Jayaratne (Google Summer of Code 2011)
+
+  * OpenGIS support
+
+* Ammar Yasir (Google Summer of Code 2011)
+
+  * Zoom search
+
+* Aris Feryanto (Google Summer of Code 2011)
+
+  * Browse-mode improvements
+
+* Thilanka Kaushalya (Google Summer of Code 2011)
+
+  * AJAXification
+
+* Tyron Madlener (Google Summer of Code 2011)
+
+  * Query statistics and charts for the status page
+
+* Zarubin Stas (Google Summer of Code 2011)
+
+  * Automated testing
+
+* Rouslan Placella (Google Summer of Code 2011 and 2012)
+
+  * Improved support for Stored Routines, Triggers and Events
+
+  * Italian translation updates
+
+  * Removal of frames, new navigation
+
+* Dieter Adriaenssens
+
+  * Various bugfixes
+
+  * Dutch translation updates
+
+* Alex Marin (Google Summer of Code 2012)
+
+  * New plugins and properties system
+
+* Thilina Buddika Abeyrathna (Google Summer of Code 2012)
+  
+  * Refactoring
+
+* Atul Pratap Singh  (Google Summer of Code 2012)
+  
+  * Refactoring
+
+* Chanaka Indrajith (Google Summer of Code 2012)
+  
+  * Refactoring
+
+* Yasitha Pandithawatta (Google Summer of Code 2012)
+  
+  * Automated testing
+
+* Jim Wigginton (phpseclib.sourceforge.net)
+
+  * phpseclib
+
+And also to the following people who have contributed minor changes,
+enhancements, bugfixes or support for a new language since version
+2.1.0:
+
+Bora Alioglu, Ricardo ?, Sven-Erik Andersen, Alessandro Astarita,
+Péter Bakondy, Borges Botelho, Olivier Bussier, Neil Darlow, Mats
+Engstrom, Ian Davidson, Laurent Dhima, Kristof Hamann, Thomas Kläger,
+Lubos Klokner, Martin Marconcini, Girish Nair, David Nordenberg,
+Andreas Pauley, Bernard M. Piller, Laurent Haas, "Sakamoto", Yuval
+Sarna, www.securereality.com.au, Alexis Soulard, Alvar Soome, Siu Sun,
+Peter Svec, Michael Tacelosky, Rachim Tamsjadi, Kositer Uros, Luís V.,
+Martijn W. van der Lee, Algis Vainauskas, Daniel Villanueva, Vinay,
+Ignacio Vazquez-Abrams, Chee Wai, Jakub Wilk, Thomas Michael
+Winningham, Vilius Zigmantas, "Manuzhai".
+
+
+Translators
++++++++++++
+
+Following people have contributed to translation of phpMyAdmin:
+
+* Arabic 
+
+  * Abdullah Al-Saedi <abdullah.10\_at\_windowslive.com>
+
+* Bulgarian 
+
+  * stoyanster <stoyanster\_at\_gmail.com>
+
+* Catalan
+
+  * Xavier Navarro <xvnavarro\_at\_gmail.com>
+
+* Czech 
+
+  * Michal Čihař <michal\_at\_cihar.com>
+
+* Danish 
+
+  * opensource <opensource\_at\_jth.net>
+  * Jørgen Thomsen <opensource\_at\_jth.net>
+
+* German 
+
+  * mrbendig <mrbendig\_at\_mrbendig.com>
+  * torsten.funck <torsten.funck\_at\_googlemail.com>
+  * Sven Strickroth <email\_at\_cs-ware.de>
+  * typo3 <typo3\_at\_dirk-weise.de>
+  * Jo Michael <me\_at\_mynetx.net>
+
+* Greek 
+
+  * Panagiotis Papazoglou <papaz_p\_at\_yahoo.com>
+
+* English (United Kingdom)
+
+  * Robert Readman <robert_readman\_at\_hotmail.com>
+
+* Spanish
+
+  * Matías Bellone <matiasbellone\_at\_gmail.com>
+
+* French 
+
+  * Marc Delisle <marc\_at\_infomarc.info>
+
+* Hindi 
+
+  * u4663530 <u4663530\_at\_anu.edu.au>
+  * rsedwardian <rsedwardian\_at\_gmail.com>
+
+* Hungarian 
+
+  * gergo314 <gergo314\_at\_gmail.com>
+
+* Italian 
+
+  * Rouslan Placella <rouslan\_at\_placella.com>
+
+* Japanese 
+
+  * Yuichiro <yuichiro\_at\_pop07.odn.ne.jp>
+
+* Lithuanian 
+
+  * Kęstutis <forkik\_at\_gmail.com>
+
+* Norwegian Bokmål
+
+  * Sven-Erik Andersen <sven.erik.andersen\_at\_gmail.com>
+
+* Dutch 
+
+  * Dieter Adriaenssens <ruleant\_at\_users.sourceforge.net>
+  * Herman van Rink <rink\_at\_initfour.nl>
+
+* Polish 
+
+  * Stanisław Krukowski <stankruk\_at\_neostrada.pl>
+  * Marcin Kozioł <lord_dark\_at\_wp.pl>
+
+* Portuguese
+
+  * JoaoTMDias <contacto\_at\_joaodias.me>
+
+* Portuguese (Brazil) 
+
+  * wiltave <wiltave\_at\_gmail.com>
+  * emerson4br <emerson4br\_at\_gmail.com>
+
+* Romanian 
+
+  * alexukf <alex.ukf\_at\_gmail.com>
+
+* Russian 
+
+  * Victor Volkov <hanut\_at\_php-myadmin.ru>
+
+* Sinhala 
+
+  * Madhura Jayaratne <madhura.cj\_at\_gmail.com>
+
+* Slovak 
+
+  * Martin Lacina <martin\_at\_whistler.sk>
+
+* Slovenian 
+
+  * Domen <dbc334\_at\_gmail.com>
+
+* Swedish
+
+  * stefan <stefan\_at\_inkopsforum.se>
+
+* Tamil 
+
+  * ysajeepan <ysajeepan\_at\_live.com>
+
+* Telugu 
+
+  * veeven <veeven\_at\_gmail.com>
+
+* Thai 
+
+  * kanitchet <kanichet\_at\_hotmail.com>
+
+* Turkish
+
+  * Burak Yavuz <hitowerdigit\_at\_hotmail.com>
+
+* Uighur 
+
+  * gheni <gheni\_at\_yahoo.cn>
+
+* Ukrainian 
+
+  * typim <duke3d\_at\_ukr.net>
+  * oleg-ilnytskyi <ukraine.oleg\_at\_gmail.com>
+
+* Urdu 
+
+  * Mehbooob Khan <mehboobbugti\_at\_gmail.com>
+
+* Simplified Chinese
+
+  * shanyan baishui <Siramizu\_at\_gmail.com>
+
+* Traditional Chinese
+
+  * star <star\_at\_origin.club.tw>
+
+Documentation translators
++++++++++++++++++++++++++
+
+Following people have contributed to translation of phpMyAdmin documentation:
+
+* Czech 
+
+  * Michal Čihař <michal\_at\_cihar.com>
+
+* Greek 
+
+  * Panagiotis Papazoglou <papaz_p\_at\_yahoo.com>
+
+* English (United Kingdom) 
+
+  * Robert Readman <robert_readman\_at\_hotmail.com>
+
+* French 
+
+  * Cédric Corazza <cedric.corazza\_at\_wanadoo.fr>
+
+* Japanese 
+
+  * Yuichiro Takahashi <yuichiro\_at\_pop07.odn.ne.jp>
+
+* Polish 
+
+  * Stanisław Krukowski <stankruk\_at\_neostrada.pl>
+
+* Portuguese (Brazil) 
+
+  * mjaning <mjaning\_at\_gmail.com>
+
+* Slovenian 
+
+  * Domen <dbc334\_at\_gmail.com>
+
+Original Credits of Version 2.1.0
++++++++++++++++++++++++++++++++++
+
+This work is based on Peter Kuppelwieser's MySQL-Webadmin. It was his
+idea to create a web-based interface to MySQL using PHP3. Although I
+have not used any of his source-code, there are some concepts I've
+borrowed from him. phpMyAdmin was created because Peter told me he
+wasn't going to further develop his (great) tool.
+
+Thanks go to
+
+* Amalesh Kempf <ak-lsml\_at\_living-source.com> who contributed the
+  code for the check when dropping a table or database. He also
+  suggested that you should be able to specify the primary key on
+  tbl\_create.php3. To version 1.1.1 he contributed the ldi\_\*.php3-set
+  (Import text-files) as well as a bug-report. Plus many smaller
+  improvements.
+* Jan Legenhausen <jan\_at\_nrw.net>: He made many of the changes that
+  were introduced in 1.3.0 (including quite significant ones like the
+  authentication). For 1.4.1 he enhanced the table-dump feature. Plus
+  bug-fixes and help.
+* Marc Delisle <DelislMa\_at\_CollegeSherbrooke.qc.ca> made phpMyAdmin
+  language-independent by outsourcing the strings to a separate file. He
+  also contributed the French translation.
+* Alexandr Bravo <abravo\_at\_hq.admiral.ru> who contributed
+  tbl\_select.php3, a feature to display only some columns from a table.
+* Chris Jackson <chrisj\_at\_ctel.net> added support for MySQL functions
+  in tbl\_change.php3. He also added the "Query by Example" feature in
+  2.0.
+* Dave Walton <walton\_at\_nordicdms.com> added support for multiple
+  servers and is a regular contributor for bug-fixes.
+* Gabriel Ash <ga244\_at\_is8.nyu.edu> contributed the random access
+  features for 2.0.6.
+
+The following people have contributed minor changes, enhancements,
+bugfixes or support for a new language:
+
+Jim Kraai, Jordi Bruguera, Miquel Obrador, Geert Lund, Thomas
+Kleemann, Alexander Leidinger, Kiko Albiol, Daniel C. Chao, Pavel
+Piankov, Sascha Kettler, Joe Pruett, Renato Lins, Mark Kronsbein,
+Jannis Hermanns, G. Wieggers.
+
+And thanks to everyone else who sent me email with suggestions, bug-
+reports and or just some feedback.
+
diff --git a/phpmyadmin/doc/html/_sources/developers.txt b/phpmyadmin/doc/html/_sources/developers.txt
new file mode 100644
index 0000000..5574527
--- /dev/null
+++ b/phpmyadmin/doc/html/_sources/developers.txt
@@ -0,0 +1,12 @@
+.. _developers:
+
+Developers Information
+======================
+
+phpMyAdmin is Open Source, so you're invited to contribute to it. Many
+great features have been written by other people and you too can help
+to make phpMyAdmin a useful tool.
+
+You can check out all the possibilities to contribute in the
+`contribute section on our website 
+<http://www.phpmyadmin.net/home_page/improve.php>`_.
\ No newline at end of file
diff --git a/phpmyadmin/doc/html/_sources/faq.txt b/phpmyadmin/doc/html/_sources/faq.txt
new file mode 100644
index 0000000..c77f428
--- /dev/null
+++ b/phpmyadmin/doc/html/_sources/faq.txt
@@ -0,0 +1,2001 @@
+.. _faq:
+
+FAQ - Frequently Asked Questions
+================================
+
+Please have a look at our `Link section
+<http://www.phpmyadmin.net/home_page/docs.php>`_ on the official
+phpMyAdmin homepage for in-depth coverage of phpMyAdmin's features and
+or interface.
+
+.. _faqserver:
+
+Server
+++++++
+
+.. _faq1_1:
+
+1.1 My server is crashing each time a specific action is required or phpMyAdmin sends a blank page or a page full of cryptic characters to my browser, what can I do?
+---------------------------------------------------------------------------------------------------------------------------------------------------------------------
+
+Try to set the :config:option:`$cfg['OBGzip']`  directive to ``false`` in your
+:file:`config.inc.php` file and the ``zlib.output_compression`` directive to
+``Off`` in your php configuration file.
+
+.. _faq1_2:
+
+1.2 My Apache server crashes when using phpMyAdmin.
+---------------------------------------------------
+
+You should first try the latest versions of Apache (and possibly MySQL). If
+your server keeps crashing, please ask for help in the various Apache support
+groups.
+
+.. seealso:: :ref:`faq1_1`
+
+.. _faq1_3:
+
+1.3 (withdrawn).
+----------------
+
+.. _faq1_4:
+
+1.4 Using phpMyAdmin on IIS, I'm displayed the error message: "The specified CGI application misbehaved by not returning a complete set of HTTP headers ...".
+-------------------------------------------------------------------------------------------------------------------------------------------------------------
+
+You just forgot to read the *install.txt* file from the PHP
+distribution. Have a look at the last message in this `PHP bug report #12061
+<http://bugs.php.net/bug.php?id=12061>`_ from the official PHP bug
+database.
+
+.. _faq1_5:
+
+1.5 Using phpMyAdmin on IIS, I'm facing crashes and/or many error messages with the HTTP.
+-----------------------------------------------------------------------------------------
+
+This is a known problem with the PHP :term:`ISAPI` filter: it's not so stable.
+Please use instead the cookie authentication mode.
+
+.. _faq1_6:
+
+1.6 I can't use phpMyAdmin on PWS: nothing is displayed!
+--------------------------------------------------------
+
+This seems to be a PWS bug. Filippo Simoncini found a workaround (at
+this time there is no better fix): remove or comment the ``DOCTYPE``
+declarations (2 lines) from the scripts :file:`libraries/Header.class.php`
+and :file:`index.php`.
+
+.. _faq1_7:
+
+1.7 How can I GZip or Bzip a dump or a CSV export? It does not seem to work.
+----------------------------------------------------------------------------
+
+These features are based on the ``gzencode()`` and ``bzcompress()``
+PHP functions to be more independent of the platform (Unix/Windows,
+Safe Mode or not, and so on). So, you must have Zlib/Bzip2 support
+(``--with-zlib`` and ``--with-bz2``).
+
+.. _faq1_8:
+
+1.8 I cannot insert a text file in a table, and I get an error about safe mode being in effect.
+-----------------------------------------------------------------------------------------------
+
+Your uploaded file is saved by PHP in the "upload dir", as defined in
+:file:`php.ini` by the variable ``upload_tmp_dir`` (usually the system
+default is */tmp*). We recommend the following setup for Apache
+servers running in safe mode, to enable uploads of files while being
+reasonably secure:
+
+* create a separate directory for uploads: :command:`mkdir /tmp/php`
+* give ownership to the Apache server's user.group: :command:`chown
+  apache.apache /tmp/php`
+* give proper permission: :command:`chmod 600 /tmp/php`
+* put ``upload_tmp_dir = /tmp/php`` in :file:`php.ini`
+* restart Apache
+
+.. _faq1_9:
+
+1.9 (withdrawn).
+----------------
+
+.. _faq1_10:
+
+1.10 I'm having troubles when uploading files with phpMyAdmin running on a secure server. My browser is Internet Explorer and I'm using the Apache server.
+----------------------------------------------------------------------------------------------------------------------------------------------------------
+
+As suggested by "Rob M" in the phpWizard forum, add this line to your
+*httpd.conf*:
+
+.. code-block:: apache
+
+    SetEnvIf User-Agent ".*MSIE.*" nokeepalive ssl-unclean-shutdown
+
+It seems to clear up many problems between Internet Explorer and SSL.
+
+.. _faq1_11:
+
+1.11 I get an 'open\_basedir restriction' while uploading a file from the query box.
+------------------------------------------------------------------------------------
+
+Since version 2.2.4, phpMyAdmin supports servers with open\_basedir
+restrictions. However you need to create temporary directory and configure it
+as :config:option:`$cfg['TempDir']`. The uploaded files will be moved there,
+and after execution of your :term:`SQL` commands, removed.
+
+.. _faq1_12:
+
+1.12 I have lost my MySQL root password, what can I do?
+-------------------------------------------------------
+
+The MySQL manual explains how to `reset the permissions
+<http://dev.mysql.com/doc/mysql/en/resetting-permissions.html>`_.
+
+.. _faq1_13:
+
+1.13 (withdrawn).
+-----------------
+
+.. _faq1_14:
+
+1.14 (withdrawn).
+-----------------
+
+.. _faq1_15:
+
+1.15 I have problems with *mysql.user* column names.
+----------------------------------------------------
+
+In previous MySQL versions, the ``User`` and ``Password``columns were
+named ``user`` and ``password``. Please modify your column names to
+align with current standards.
+
+.. _faq1_16:
+
+1.16 I cannot upload big dump files (memory, HTTP or timeout problems).
+-----------------------------------------------------------------------
+
+Starting with version 2.7.0, the import engine has been re–written and
+these problems should not occur. If possible, upgrade your phpMyAdmin
+to the latest version to take advantage of the new import features.
+
+The first things to check (or ask your host provider to check) are the
+values of ``upload_max_filesize``, ``memory_limit`` and
+``post_max_size`` in the :file:`php.ini` configuration file. All of these
+three settings limit the maximum size of data that can be submitted
+and handled by PHP. One user also said that ``post_max_size`` and
+``memory_limit`` need to be larger than ``upload_max_filesize``.
+There exist several workarounds if your upload is too big or your
+hosting provider is unwilling to change the settings:
+
+* Look at the :config:option:`$cfg['UploadDir']` feature. This allows one to upload a file to the server
+  via scp, ftp, or your favorite file transfer method. PhpMyAdmin is
+  then able to import the files from the temporary directory. More
+  information is available in the :ref:`config`  of this document.
+* Using a utility (such as `BigDump
+  <http://www.ozerov.de/bigdump.php>`_) to split the files before
+  uploading. We cannot support this or any third party applications, but
+  are aware of users having success with it.
+* If you have shell (command line) access, use MySQL to import the files
+  directly. You can do this by issuing the "source" command from within
+  MySQL:
+
+  .. code-block:: mysql
+
+    source filename.sql;
+
+.. _faq1_17:
+
+1.17 Which MySQL versions does phpMyAdmin support?
+--------------------------------------------------
+
+Since phpMyAdmin 3.0.x, only MySQL 5.0.1 and newer are supported. For
+older MySQL versions, you need to use the latest 2.x branch.
+phpMyAdmin can connect to your MySQL server using PHP's classic `MySQL
+extension <http://php.net/mysql>`_ as well as the `improved MySQL
+extension (MySQLi) <http://php.net/mysqli>`_ that is available in PHP
+5.0. The latter one should be used unless you have a good reason not
+to do so. When compiling PHP, we strongly recommend that you manually
+link the MySQL extension of your choice to a MySQL client library of
+at least the same minor version since the one that is bundled with
+some PHP distributions is rather old and might cause problems see
+:ref:`faq1_17a`. `MariaDB <http://mariadb.org/>`_ is also supported
+(versions 5.1 and 5.2 were tested). 
+
+.. versionchanged:: 3.5
+    Since phpMyAdmin 3.5 `Drizzle <http://www.drizzle.org/>`_ is supported.
+
+.. _faq1_17a:
+
+1.17a I cannot connect to the MySQL server. It always returns the error message, "Client does not support authentication protocol requested by server; consider upgrading MySQL client"
+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
+
+You tried to access MySQL with an old MySQL client library. The
+version of your MySQL client library can be checked in your phpinfo()
+output. In general, it should have at least the same minor version as
+your server - as mentioned in :ref:`faq1_17`. This problem is
+generally caused by using MySQL version 4.1 or newer. MySQL changed
+the authentication hash and your PHP is trying to use the old method.
+The proper solution is to use the `mysqli extension
+<http://www.php.net/mysqli>`_ with the proper client library to match
+your MySQL installation. Your chosen extension is specified in 
+:config:option:`$cfg['Servers'][$i]['extension']`. More
+information (and several workarounds) are located in the `MySQL
+Documentation <http://dev.mysql.com/doc/mysql/en/old-client.html>`_.
+
+.. _faq1_18:
+
+1.18 (withdrawn).
+-----------------
+
+.. _faq1_19:
+
+1.19 I can't run the "display relations" feature because the script seems not to know the font face I'm using!
+--------------------------------------------------------------------------------------------------------------
+
+The :term:`TCPDF` library we're using for this feature requires some special
+files to use font faces. Please refers to the `TCPDF manual
+<http://www.tcpdf.org/>`_ to build these files.
+
+.. _faqmysql:
+
+1.20 I receive the error "cannot load MySQL extension, please check PHP Configuration".
+---------------------------------------------------------------------------------------
+
+To connect to a MySQL server, PHP needs a set of MySQL functions
+called "MySQL extension". This extension may be part of the PHP
+distribution (compiled-in), otherwise it needs to be loaded
+dynamically. Its name is probably *mysql.so* or *php\_mysql.dll*.
+phpMyAdmin tried to load the extension but failed. Usually, the
+problem is solved by installing a software package called "PHP-MySQL"
+or something similar.
+
+.. _faq1_21:
+
+1.21 I am running the CGI version of PHP under Unix, and I cannot log in using cookie auth.
+-------------------------------------------------------------------------------------------
+
+In :file:`php.ini`, set ``mysql.max_links`` higher than 1.
+
+.. _faq1_22:
+
+1.22 I don't see the "Location of text file" field, so I cannot upload.
+-----------------------------------------------------------------------
+
+This is most likely because in :file:`php.ini`, your ``file_uploads``
+parameter is not set to "on".
+
+.. _faq1_23:
+
+1.23 I'm running MySQL on a Win32 machine. Each time I create a new table the table and column names are changed to lowercase!
+------------------------------------------------------------------------------------------------------------------------------
+
+This happens because the MySQL directive ``lower_case_table_names``
+defaults to 1 (``ON``) in the Win32 version of MySQL. You can change
+this behavior by simply changing the directive to 0 (``OFF``): Just
+edit your ``my.ini`` file that should be located in your Windows
+directory and add the following line to the group [mysqld]:
+
+.. code-block:: ini
+
+    set-variable = lower_case_table_names=0
+
+Next, save the file and restart the MySQL service. You can always
+check the value of this directive using the query
+
+.. code-block:: mysql
+
+    SHOW VARIABLES LIKE 'lower_case_table_names';
+
+.. _faq1_24:
+
+1.24 (withdrawn).
+-----------------
+
+.. _faq1_25:
+
+1.25 I am running Apache with mod\_gzip-1.3.26.1a on Windows XP, and I get problems, such as undefined variables when I run a SQL query.
+----------------------------------------------------------------------------------------------------------------------------------------
+
+A tip from Jose Fandos: put a comment on the following two lines in
+httpd.conf, like this:
+
+.. code-block:: apache
+
+    
+    # mod_gzip_item_include file \.php$
+    # mod_gzip_item_include mime "application/x-httpd-php.*"
+
+as this version of mod\_gzip on Apache (Windows) has problems handling
+PHP scripts. Of course you have to restart Apache.
+
+.. _faq1_26:
+
+1.26 I just installed phpMyAdmin in my document root of IIS but I get the error "No input file specified" when trying to run phpMyAdmin.
+----------------------------------------------------------------------------------------------------------------------------------------
+
+This is a permission problem. Right-click on the phpmyadmin folder and
+choose properties. Under the tab Security, click on "Add" and select
+the user "IUSR\_machine" from the list. Now set his permissions and it
+should work.
+
+.. _faq1_27:
+
+1.27 I get empty page when I want to view huge page (eg. db\_structure.php with plenty of tables).
+--------------------------------------------------------------------------------------------------
+
+This was caused by a `PHP bug <http://bugs.php.net/21079>`_ that occur when
+GZIP output buffering is enabled. If you turn off it (by
+:config:option:`$cfg['OBGzip']` in :file:`config.inc.php`), it should work.
+This bug will has been fixed in PHP 5.0.0.
+
+.. _faq1_28:
+
+1.28 My MySQL server sometimes refuses queries and returns the message 'Errorcode: 13'. What does this mean?
+------------------------------------------------------------------------------------------------------------
+
+This can happen due to a MySQL bug when having database / table names
+with upper case characters although ``lower_case_table_names`` is
+set to 1. To fix this, turn off this directive, convert all database
+and table names to lower case and turn it on again. Alternatively,
+there's a bug-fix available starting with MySQL 3.23.56 /
+4.0.11-gamma.
+
+.. _faq1_29:
+
+1.29 When I create a table or modify a column, I get an error and the columns are duplicated.
+---------------------------------------------------------------------------------------------
+
+It is possible to configure Apache in such a way that PHP has problems
+interpreting .php files.
+
+The problems occur when two different (and conflicting) set of
+directives are used:
+
+.. code-block:: apache
+
+    
+    SetOutputFilter PHP
+    SetInputFilter PHP
+
+and
+
+.. code-block:: apache
+
+    AddType application/x-httpd-php .php
+
+In the case we saw, one set of directives was in
+``/etc/httpd/conf/httpd.conf``, while the other set was in
+``/etc/httpd/conf/addon-modules/php.conf``. The recommended way is
+with ``AddType``, so just comment out the first set of lines and
+restart Apache:
+
+.. code-block:: apache
+
+    
+    #SetOutputFilter PHP
+    #SetInputFilter PHP
+
+.. _faq1_30:
+
+1.30 I get the error "navigation.php: Missing hash".
+----------------------------------------------------
+
+This problem is known to happen when the server is running Turck
+MMCache but upgrading MMCache to version 2.3.21 solves the problem.
+
+.. _faq1_31:
+
+1.31 Does phpMyAdmin support PHP 5?
+-----------------------------------
+
+Yes.
+
+Since release 3.0 only PHP 5.2 and newer. For older PHP versions, use
+phpMyAdmin 2.11.x.
+
+.. _faq1_32:
+
+1.32 Can I use HTTP authentication with IIS?
+--------------------------------------------
+
+Yes. This procedure was tested with phpMyAdmin 2.6.1, PHP 4.3.9 in
+:term:`ISAPI` mode under :term:`IIS` 5.1.
+
+#. In your :file:`php.ini` file, set ``cgi.rfc2616_headers = 0``
+#. In ``Web Site Properties -> File/Directory Security -> Anonymous
+   Access`` dialog box, check the ``Anonymous access`` checkbox and
+   uncheck any other checkboxes (i.e. uncheck ``Basic authentication``,
+   ``Integrated Windows authentication``, and ``Digest`` if it's
+   enabled.) Click ``OK``.
+#. In ``Custom Errors``, select the range of ``401;1`` through ``401;5``
+   and click the ``Set to Default`` button.
+
+.. seealso:: :rfc:`2616`
+
+.. _faq1_33:
+
+1.33 (withdrawn).
+-----------------
+
+.. _faq1_34:
+
+1.34 Can I access directly to database or table pages?
+------------------------------------------------------
+
+Yes. Out of the box, you can use :term:`URL` like http://server/phpMyAdmin/index.php?server=X&db=databas
+e&table=table&target=script. For ``server`` you use the server number
+which refers to the order of the server paragraph in
+:file:`config.inc.php`. Table and script parts are optional. If you want
+http://server/phpMyAdmin/database[/table][/script] :term:`URL`, you need to do some configuration. Following
+lines apply only for `Apache <http://httpd.apache.org>`_ web server.
+First make sure, that you have enabled some features within global
+configuration. You need ``Options FollowSymLinks`` and ``AllowOverride
+FileInfo`` enabled for directory where phpMyAdmin is installed and you
+need mod\_rewrite to be enabled. Then you just need to create
+following :term:`.htaccess` file in root folder of phpMyAdmin installation (don't
+forget to change directory name inside of it):
+
+.. code-block:: apache
+
+    
+    RewriteEngine On
+    RewriteBase /path_to_phpMyAdmin
+    RewriteRule ^([a-zA-Z0-9_]+)/([a-zA-Z0-9_]+)/([a-z_]+\.php)$ index.php?db=$1&table=$2&target=$3 [R]
+    RewriteRule ^([a-zA-Z0-9_]+)/([a-z_]+\.php)$ index.php?db=$1&target=$2 [R]
+    RewriteRule ^([a-zA-Z0-9_]+)/([a-zA-Z0-9_]+)$ index.php?db=$1&table=$2 [R]
+    RewriteRule ^([a-zA-Z0-9_]+)$ index.php?db=$1 [R]
+
+.. _faq1_35:
+
+1.35 Can I use HTTP authentication with Apache CGI?
+---------------------------------------------------
+
+Yes. However you need to pass authentication variable to :term:`CGI` using
+following rewrite rule:
+
+.. code-block:: apache
+
+    
+    RewriteEngine On
+    RewriteRule .* - [E=REMOTE_USER:%{HTTP:Authorization},L]
+
+.. _faq1_36:
+
+1.36 I get an error "500 Internal Server Error".
+------------------------------------------------
+
+There can be many explanations to this and a look at your server's
+error log file might give a clue.
+
+.. _faq1_37:
+
+1.37 I run phpMyAdmin on cluster of different machines and password encryption in cookie auth doesn't work.
+-----------------------------------------------------------------------------------------------------------
+
+If your cluster consist of different architectures, PHP code used for
+encryption/decryption won't work correct. This is caused by use of
+pack/unpack functions in code. Only solution is to use mcrypt
+extension which works fine in this case.
+
+.. _faq1_38:
+
+1.38 Can I use phpMyAdmin on a server on which Suhosin is enabled?
+------------------------------------------------------------------
+
+Yes but the default configuration values of Suhosin are known to cause
+problems with some operations, for example editing a table with many
+columns and no primary key or with textual primary key.
+
+Suhosin configuration might lead to malfunction in some cases and it
+can not be fully avoided as phpMyAdmin is kind of application which
+needs to transfer big amounts of columns in single HTTP request, what
+is something what Suhosin tries to prevent. Generally all
+``suhosin.request.*``, ``suhosin.post.*`` and ``suhosin.get.*``
+directives can have negative effect on phpMyAdmin usability. You can
+always find in your error logs which limit did cause dropping of
+variable, so you can diagnose the problem and adjust matching
+configuration variable.
+
+The default values for most Suhosin configuration options will work in
+most scenarios, however you might want to adjust at least following
+parameters:
+
+* `suhosin.request.max\_vars <http://www.hardened-
+  php.net/suhosin/configuration.html#suhosin.request.max_vars>`_ should
+  be increased (eg. 2048)
+* `suhosin.post.max\_vars <http://www.hardened-
+  php.net/suhosin/configuration.html#suhosin.post.max_vars>`_ should be
+  increased (eg. 2048)
+* `suhosin.request.max\_array\_index\_length <http://www.hardened-php.ne
+  t/suhosin/configuration.html#suhosin.request.max_array_index_length>`_
+  should be increased (eg. 256)
+* `suhosin.post.max\_array\_index\_length <http://www.hardened-php.net/s
+  uhosin/configuration.html#suhosin.post.max_array_index_length>`_
+  should be increased (eg. 256)
+* `suhosin.request.max\_totalname\_length <http://www.hardened-php.net/s
+  uhosin/configuration.html#suhosin.request.max_totalname_length>`_
+  should be increased (eg. 8192)
+* `suhosin.post.max\_totalname\_length <http://www.hardened-php.net/suho
+  sin/configuration.html#suhosin.post.max_totalname_length>`_ should be
+  increased (eg. 8192)
+* `suhosin.get.max\_value\_length <http://www.hardened-
+  php.net/suhosin/configuration.html#suhosin.get.max_value_length>`_
+  should be increased (eg. 1024)
+* `suhosin.sql.bailout\_on\_error <http://www.hardened-
+  php.net/suhosin/configuration.html#suhosin.sql.bailout_on_error>`_
+  needs to be disabled (the default)
+* `suhosin.log.\* <http://www.hardened-
+  php.net/suhosin/configuration.html#logging_configuration>`_ should not
+  include :term:`SQL`, otherwise you get big
+  slowdown
+
+You can also disable the warning using the :config:option:`$cfg['SuhosinDisableWarning']`.
+
+.. _faq1_39:
+
+1.39 When I try to connect via https, I can log in, but then my connection is redirected back to http. What can cause this behavior?
+------------------------------------------------------------------------------------------------------------------------------------
+
+Be sure that you have enabled ``SSLOptions`` and ``StdEnvVars`` in
+your Apache configuration. 
+
+.. seealso:: <http://httpd.apache.org/docs/2.0/mod/mod_ssl.html#ssloptions>
+
+.. _faq1_40:
+
+1.40 When accessing phpMyAdmin via an Apache reverse proxy, cookie login does not work.
+---------------------------------------------------------------------------------------
+
+To be able to use cookie auth Apache must know that it has to rewrite
+the set-cookie headers. Example from the Apache 2.2 documentation:
+
+.. code-block:: apache
+
+    
+    ProxyPass /mirror/foo/ http://backend.example.com/
+    ProxyPassReverse /mirror/foo/ http://backend.example.com/
+    ProxyPassReverseCookieDomain backend.example.com public.example.com
+    ProxyPassReverseCookiePath / /mirror/foo/
+
+Note: if the backend url looks like http://host/~user/phpmyadmin, the
+tilde (~) must be url encoded as %7E in the ProxyPassReverse\* lines.
+This is not specific to phpmyadmin, it's just the behavior of Apache.
+
+.. code-block:: apache
+
+    
+    ProxyPass /mirror/foo/ http://backend.example.com/~user/phpmyadmin
+    ProxyPassReverse /mirror/foo/ http://backend.example.com/%7Euser/phpmyadmin
+    ProxyPassReverseCookiePath /%7Euser/phpmyadmin /mirror/foo
+
+.. seealso:: <http://httpd.apache.org/docs/2.2/mod/mod_proxy.html>
+
+.. _faq1_41:
+
+1.41 When I view a database and ask to see its privileges, I get an error about an unknown column.
+--------------------------------------------------------------------------------------------------
+
+The MySQL server's privilege tables are not up to date, you need to
+run the :command:`mysql_upgrade` command on the server.
+
+.. _faq1_42:
+
+1.42 How can I prevent robots from accessing phpMyAdmin?
+--------------------------------------------------------
+
+You can add various rules to :term:`.htaccess` to filter access based on user agent
+field. This is quite easy to circumvent, but could prevent at least
+some robots accessing your installation.
+
+.. code-block:: apache
+
+    
+    RewriteEngine on
+    
+    # Allow only GET and POST verbs
+    RewriteCond %{REQUEST_METHOD} !^(GET|POST)$ [NC,OR]
+    
+    # Ban Typical Vulnerability Scanners and others
+    # Kick out Script Kiddies
+    RewriteCond %{HTTP_USER_AGENT} ^(java|curl|wget).* [NC,OR]
+    RewriteCond %{HTTP_USER_AGENT} ^.*(libwww-perl|curl|wget|python|nikto|wkito|pikto|scan|acunetix).* [NC,OR]
+    RewriteCond %{HTTP_USER_AGENT} ^.*(winhttp|HTTrack|clshttp|archiver|loader|email|harvest|extract|grab|miner).* [NC,OR]
+    
+    # Ban Search Engines, Crawlers to your administrative panel
+    # No reasons to access from bots
+    # Ultimately Better than the useless robots.txt
+    # Did google respect robots.txt?
+    # Try google: intitle:phpMyAdmin intext:"Welcome to phpMyAdmin *.*.*" intext:"Log in" -wiki -forum -forums -questions intext:"Cookies must be enabled"
+    RewriteCond %{HTTP_USER_AGENT} ^.*(AdsBot-Google|ia_archiver|Scooter|Ask.Jeeves|Baiduspider|Exabot|FAST.Enterprise.Crawler|FAST-WebCrawler|www\.neomo\.de|Gigabot|Mediapartners-Google|Google.Desktop|Feedfetcher-Google|Googlebot|heise-IT-Markt-Crawler|heritrix|ibm.com\cs/crawler|ICCrawler|ichiro|MJ12bot|MetagerBot|msnbot-NewsBlogs|msnbot|msnbot-media|NG-Search|lucene.apache.org|NutchCVS|OmniExplorer_Bot|online.link.validator|psbot0|Seekbot|Sensis.Web.Crawler|SEO.search.Crawler|Seoma.\[ [...]
+    RewriteRule .* - [F]
+
+.. _faq1_43:
+
+1.43 Why can't I display the structure of my table containing hundreds of columns? 
+----------------------------------------------------------------------------------
+
+Because your PHP's ``memory_limit`` is too low; adjust it in :file:`php.ini`.
+
+.. _faqconfig:
+
+Configuration
++++++++++++++
+
+.. _faq2_1:
+
+2.1 The error message "Warning: Cannot add header information - headers already sent by ..." is displayed, what's the problem?
+------------------------------------------------------------------------------------------------------------------------------
+
+Edit your :file:`config.inc.php` file and ensure there is nothing (I.E. no
+blank lines, no spaces, no characters...) neither before the ``<?php`` tag at
+the beginning, neither after the ``?>`` tag at the end. We also got a report
+from a user under :term:`IIS`, that used a zipped distribution kit: the file
+:file:`libraries/Config.class.php` contained an end-of-line character (hex 0A)
+at the end; removing this character cleared his errors.
+
+.. _faq2_2:
+
+2.2 phpMyAdmin can't connect to MySQL. What's wrong?
+----------------------------------------------------
+
+Either there is an error with your PHP setup or your username/password
+is wrong. Try to make a small script which uses mysql\_connect and see
+if it works. If it doesn't, it may be you haven't even compiled MySQL
+support into PHP.
+
+.. _faq2_3:
+
+2.3 The error message "Warning: MySQL Connection Failed: Can't connect to local MySQL server through socket '/tmp/mysql.sock' (111) ..." is displayed. What can I do?
+---------------------------------------------------------------------------------------------------------------------------------------------------------------------
+
+For RedHat users, Harald Legner suggests this on the mailing list:
+
+On my RedHat-Box the socket of MySQL is */var/lib/mysql/mysql.sock*.
+In your :file:`php.ini` you will find a line
+
+.. code-block:: ini
+
+    mysql.default_socket = /tmp/mysql.sock
+
+change it to
+
+.. code-block:: ini
+
+    mysql.default_socket = /var/lib/mysql/mysql.sock
+
+Then restart apache and it will work.
+
+Here is a fix suggested by Brad Ummer:
+
+* First, you need to determine what socket is being used by MySQL. To do
+  this, telnet to your server and go to the MySQL bin directory. In this
+  directory there should be a file named *mysqladmin*. Type
+  ``./mysqladmin variables``, and this should give you a bunch of info
+  about your MySQL server, including the socket (*/tmp/mysql.sock*, for
+  example).
+* Then, you need to tell PHP to use this socket. To do this in
+  phpMyAdmin, you need to complete the socket information in the
+  :file:`config.inc.php`. For example:
+  :config:option:`$cfg['Servers'][$i]['socket']`  Please also make sure that
+  the permissions of this file allow to be readable by your webserver (i.e.
+  '0755').
+
+Have also a look at the `corresponding section of the MySQL
+documentation <http://dev.mysql.com/doc/en/can-not-connect-to-
+server.html>`_.
+
+.. _faq2_4:
+
+2.4 Nothing is displayed by my browser when I try to run phpMyAdmin, what can I do?
+-----------------------------------------------------------------------------------
+
+Try to set the :config:option:`$cfg['OBGzip']` directive to ``false`` in the phpMyAdmin configuration
+file. It helps sometime. Also have a look at your PHP version number:
+if it contains "b" or "alpha" it means you're running a testing
+version of PHP. That's not a so good idea, please upgrade to a plain
+revision.
+
+.. _faq2_5:
+
+2.5 Each time I want to insert or change a row or drop a database or a table, an error 404 (page not found) is displayed or, with HTTP or cookie authentication, I'm asked to log in again. What's wrong?
+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
+
+Check the value you set for the :config:option:`$cfg['PmaAbsoluteUri']` directive in the phpMyAdmin
+configuration file.
+
+.. _faq2_6:
+
+2.6 I get an "Access denied for user: 'root at localhost' (Using password: YES)"-error when trying to access a MySQL-Server on a host which is port-forwarded for my localhost.
+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
+
+When you are using a port on your localhost, which you redirect via
+port-forwarding to another host, MySQL is not resolving the localhost
+as expected. Erik Wasser explains: The solution is: if your host is
+"localhost" MySQL (the command line tool :command:`mysql` as well) always
+tries to use the socket connection for speeding up things. And that
+doesn't work in this configuration with port forwarding. If you enter
+"127.0.0.1" as hostname, everything is right and MySQL uses the
+:term:`TCP` connection.
+
+.. _faqthemes:
+
+2.7 Using and creating themes
+-----------------------------
+
+Themes are configured with :config:option:`$cfg['ThemePath']`,
+:config:option:`$cfg['ThemeManager']` and :config:option:`$cfg['ThemeDefault']`.  
+Under :config:option:`$cfg['ThemePath']`, you should not delete the
+directory ``pmahomme`` or its underlying structure, because this is the
+system theme used by phpMyAdmin. ``pmahomme`` contains all images and
+styles, for backwards compatibility and for all themes that would not
+include images or css-files.  If :config:option:`$cfg['ThemeManager']`
+is enabled, you can select your favorite theme on the main page. Your selected
+theme will be stored in a cookie.
+
+To create a theme:
+
+* make a new subdirectory (for example "your\_theme\_name") under :config:option:`$cfg['ThemePath']` (by
+  default ``themes``)
+* copy the files and directories from ``pmahomme`` to "your\_theme\_name"
+* edit the css-files in "your\_theme\_name/css"
+* put your new images in "your\_theme\_name/img"
+* edit :file:`layout.inc.php` in "your\_theme\_name"
+* edit :file:`info.inc.php` in "your\_theme\_name" to contain your chosen
+  theme name, that will be visible in user interface
+* make a new screenshot of your theme and save it under
+  "your\_theme\_name/screen.png"
+
+In theme directory there is file :file:`info.inc.php` which contains theme
+verbose name, theme generation and theme version. These versions and
+generations are enumerated from 1 and do not have any direct
+dependence on phpMyAdmin version. Themes within same generation should
+be backwards compatible - theme with version 2 should work in
+phpMyAdmin requiring version 1. Themes with different generation are
+incompatible.
+
+If you do not want to use your own symbols and buttons, remove the
+directory "img" in "your\_theme\_name". phpMyAdmin will use the
+default icons and buttons (from the system-theme ``pmahomme``).
+
+.. _faqmissingparameters:
+
+2.8 I get "Missing parameters" errors, what can I do?
+-----------------------------------------------------
+
+Here are a few points to check:
+
+* In :file:`config.inc.php`, try to leave the :config:option:`$cfg['PmaAbsoluteUri']` directive empty. See also
+  :ref:`faq4_7`.
+* Maybe you have a broken PHP installation or you need to upgrade your
+  Zend Optimizer. See <http://bugs.php.net/bug.php?id=31134>.
+* If you are using Hardened PHP with the ini directive
+  ``varfilter.max_request_variables`` set to the default (200) or
+  another low value, you could get this error if your table has a high
+  number of columns. Adjust this setting accordingly. (Thanks to Klaus
+  Dorninger for the hint).
+* In the :file:`php.ini` directive ``arg_separator.input``, a value of ";"
+  will cause this error. Replace it with "&;".
+* If you are using `Hardened-PHP <http://www.hardened-php.net/>`_, you
+  might want to increase `request limits <http://www.hardened-
+  php.net/hphp/troubleshooting.html>`_.
+* The directory specified in the :file:`php.ini` directive
+  ``session.save_path`` does not exist or is read-only.
+
+.. _faq2_9:
+
+2.9 Seeing an upload progress bar
+---------------------------------
+
+To be able to see a progress bar during your uploads, your server must
+have the `APC <http://pecl.php.net/package/APC>`_ extension, the
+`uploadprogress <http://pecl.php.net/package/uploadprogress>`_ one, or
+you must be running PHP 5.4.0 or higher. Moreover, the JSON extension
+has to be enabled in your PHP.
+
+If using APC, you must set ``apc.rfc1867`` to ``on`` in your :file:`php.ini`.
+
+If using PHP 5.4.0 or higher, you must set
+``session.upload_progress.enabled`` to ``1`` in your :file:`php.ini`. However,
+starting from phpMyAdmin version 4.0.4, session-based upload progress has
+been temporarily deactivated due to its problematic behavior. 
+
+.. seealso:: :rfc:`1867`
+
+.. _faqlimitations:
+
+Known limitations
++++++++++++++++++
+
+.. _login_bug:
+
+3.1 When using HTTP authentication, a user who logged out can not log in again in with the same nick.
+-----------------------------------------------------------------------------------------------------
+
+This is related to the authentication mechanism (protocol) used by
+phpMyAdmin. To bypass this problem: just close all the opened browser
+windows and then go back to phpMyAdmin. You should be able to log in
+again.
+
+.. _faq3_2:
+
+3.2 When dumping a large table in compressed mode, I get a memory limit error or a time limit error.
+----------------------------------------------------------------------------------------------------
+
+Compressed dumps are built in memory and because of this are limited
+to php's memory limit. For GZip/BZip2 exports this can be overcome
+since 2.5.4 using :config:option:`$cfg['CompressOnFly']` (enabled by default).
+Zip exports can not be handled this way, so if you need Zip files for larger
+dump, you have to use another way.
+
+.. _faq3_3:
+
+3.3 With InnoDB tables, I lose foreign key relationships when I rename a table or a column.
+-------------------------------------------------------------------------------------------
+
+This is an InnoDB bug, see <http://bugs.mysql.com/bug.php?id=21704>.
+
+.. _faq3_4:
+
+3.4 I am unable to import dumps I created with the mysqldump tool bundled with the MySQL server distribution.
+-------------------------------------------------------------------------------------------------------------
+
+The problem is that older versions of ``mysqldump`` created invalid
+comments like this:
+
+.. code-block:: mysql
+
+    
+    -- MySQL dump 8.22
+    --
+    -- Host: localhost Database: database
+    ---------------------------------------------------------
+    -- Server version 3.23.54
+
+The invalid part of the code is the horizontal line made of dashes
+that appears once in every dump created with mysqldump. If you want to
+run your dump you have to turn it into valid MySQL. This means, you
+have to add a whitespace after the first two dashes of the line or add
+a # before it:  ``-- -------------------------------------------------------`` or
+``#---------------------------------------------------------``
+
+.. _faq3_5:
+
+3.5 When using nested folders, multiple hierarchies are displayed in a wrong manner.
+------------------------------------------------------------------------------------
+
+Please note that you should not use the separating string multiple
+times without any characters between them, or at the beginning/end of
+your table name. If you have to, think about using another
+TableSeparator or disabling that feature.
+
+.. seealso:: :config:option:`$cfg['NavigationTreeTableSeparator']`
+
+.. _faq3_6:
+
+3.6 What is currently not supported in phpMyAdmin about InnoDB?
+---------------------------------------------------------------
+
+In Relation view, being able to choose a table in another database, or
+having more than one index column in the foreign key. In Query-by-
+example (Query), automatic generation of the query LEFT JOIN from the
+foreign table.
+
+.. _faq3_7:
+
+3.7 I have table with many (100+) columns and when I try to browse table I get series of errors like "Warning: unable to parse url". How can this be fixed?
+-----------------------------------------------------------------------------------------------------------------------------------------------------------
+
+Your table neither have a primary key nor an unique one, so we must
+use a long expression to identify this row. This causes problems to
+parse\_url function. The workaround is to create a primary or unique
+key.
+
+.. _faq3_8:
+
+3.8 I cannot use (clickable) HTML-forms in columns where I put a MIME-Transformation onto!
+------------------------------------------------------------------------------------------
+
+Due to a surrounding form-container (for multi-row delete checkboxes),
+no nested forms can be put inside the table where phpMyAdmin displays
+the results. You can, however, use any form inside of a table if keep
+the parent form-container with the target to tbl\_row\_delete.php and
+just put your own input-elements inside. If you use a custom submit
+input field, the form will submit itself to the displaying page again,
+where you can validate the $HTTP\_POST\_VARS in a transformation. For
+a tutorial on how to effectively use transformations, see our `Link
+section <http://www.phpmyadmin.net/home_page/docs.php>`_ on the
+official phpMyAdmin-homepage.
+
+.. _faq3_9:
+
+3.9 I get error messages when using "--sql\_mode=ANSI" for the MySQL server.
+----------------------------------------------------------------------------
+
+When MySQL is running in ANSI-compatibility mode, there are some major
+differences in how :term:`SQL` is structured (see
+<http://dev.mysql.com/doc/mysql/en/ansi-mode.html>). Most important of all, the
+quote-character (") is interpreted as an identifier quote character and not as
+a string quote character, which makes many internal phpMyAdmin operations into
+invalid :term:`SQL` statements. There is no
+workaround to this behaviour.  News to this item will be posted in `Bug report
+#1013 <https://sourceforge.net/p/phpmyadmin/bugs/1013/>`_.
+
+.. _faq3_10:
+
+3.10 Homonyms and no primary key: When the results of a SELECT display more that one column with the same value (for example ``SELECT lastname from employees where firstname like 'A%'`` and two "Smith" values are displayed), if I click Edit I cannot be sure that I am editing the intended row.
+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
+
+Please make sure that your table has a primary key, so that phpMyAdmin
+can use it for the Edit and Delete links.
+
+.. _faq3_11:
+
+3.11 The number of rows for InnoDB tables is not correct.
+---------------------------------------------------------
+
+phpMyAdmin uses a quick method to get the row count, and this method only
+returns an approximate count in the case of InnoDB tables. See
+:config:option:`$cfg['MaxExactCount']` for a way to modify those results, but
+this could have a serious impact on performance.
+
+.. _faq3_12:
+
+3.12 (withdrawn).
+-----------------
+
+.. _faq3_13:
+
+3.13 I get an error when entering ``USE`` followed by a db name containing an hyphen.
+-------------------------------------------------------------------------------------
+
+The tests I have made with MySQL 5.1.49 shows that the API does not
+accept this syntax for the USE command.
+
+.. _faq3_14:
+
+3.14 I am not able to browse a table when I don't have the right to SELECT one of the columns.
+----------------------------------------------------------------------------------------------
+
+This has been a known limitation of phpMyAdmin since the beginning and
+it's not likely to be solved in the future.
+
+.. _faq3_15:
+
+3.15 (withdrawn).
+-----------------
+
+.. _faq3_16:
+
+3.16 (withdrawn).
+-----------------
+
+.. _faq3_17:
+
+3.17 (withdrawn).
+-----------------
+
+.. _faq3_18:
+
+3.18 When I import a CSV file that contains multiple tables, they are lumped together into a single table.
+----------------------------------------------------------------------------------------------------------
+
+There is no reliable way to differentiate tables in :term:`CSV` format. For the
+time being, you will have to break apart :term:`CSV` files containing multiple
+tables.
+
+.. _faq3_19:
+
+3.19 When I import a file and have phpMyAdmin determine the appropriate data structure it only uses int, decimal, and varchar types.
+------------------------------------------------------------------------------------------------------------------------------------
+
+Currently, the import type-detection system can only assign these
+MySQL types to columns. In future, more will likely be added but for
+the time being you will have to edit the structure to your liking
+post-import.  Also, you should note the fact that phpMyAdmin will use
+the size of the largest item in any given column as the column size
+for the appropriate type. If you know you will be adding larger items
+to that column then you should manually adjust the column sizes
+accordingly. This is done for the sake of efficiency.
+
+.. _faqmultiuser:
+
+ISPs, multi-user installations
+++++++++++++++++++++++++++++++
+
+.. _faq4_1:
+
+4.1 I'm an ISP. Can I setup one central copy of phpMyAdmin or do I need to install it for each customer?
+--------------------------------------------------------------------------------------------------------
+
+Since version 2.0.3, you can setup a central copy of phpMyAdmin for all your
+users. The development of this feature was kindly sponsored by NetCologne GmbH.
+This requires a properly setup MySQL user management and phpMyAdmin
+:term:`HTTP` or cookie authentication. 
+
+.. seealso:: :ref:`authentication_modes`
+
+.. _faq4_2:
+
+4.2 What's the preferred way of making phpMyAdmin secure against evil access?
+-----------------------------------------------------------------------------
+
+This depends on your system. If you're running a server which cannot be
+accessed by other people, it's sufficient to use the directory protection
+bundled with your webserver (with Apache you can use :term:`.htaccess` files,
+for example). If other people have telnet access to your server, you should use
+phpMyAdmin's :term:`HTTP` or cookie authentication features.  
+    
+Suggestions:
+
+* Your :file:`config.inc.php` file should be ``chmod 660``.
+* All your phpMyAdmin files should be chown -R phpmy.apache, where phpmy
+  is a user whose password is only known to you, and apache is the group
+  under which Apache runs.
+* Follow security recommendations for PHP and your webserver.
+
+.. _faq4_3:
+
+4.3 I get errors about not being able to include a file in */lang* or in */libraries*.
+--------------------------------------------------------------------------------------
+
+Check :file:`php.ini`, or ask your sysadmin to check it. The
+``include_path`` must contain "." somewhere in it, and
+``open_basedir``, if used, must contain "." and "./lang" to allow
+normal operation of phpMyAdmin.
+
+.. _faq4_4:
+
+4.4 phpMyAdmin always gives "Access denied" when using HTTP authentication.
+---------------------------------------------------------------------------
+
+This could happen for several reasons:
+
+* :config:option:`$cfg['Servers'][$i]['controluser']` and/or :config:option:`$cfg['Servers'][$i]['controlpass']`  are wrong.
+* The username/password you specify in the login dialog are invalid.
+* You have already setup a security mechanism for the phpMyAdmin-
+  directory, eg. a :term:`.htaccess` file. This would interfere with phpMyAdmin's
+  authentication, so remove it.
+
+.. _faq4_5:
+
+4.5 Is it possible to let users create their own databases?
+-----------------------------------------------------------
+
+Starting with 2.2.5, in the user management page, you can enter a
+wildcard database name for a user (for example "joe%"), and put the
+privileges you want. For example, adding ``SELECT, INSERT, UPDATE,
+DELETE, CREATE, DROP, INDEX, ALTER`` would let a user create/manage
+his/her database(s).
+
+.. _faq4_6:
+
+4.6 How can I use the Host-based authentication additions?
+----------------------------------------------------------
+
+If you have existing rules from an old :term:`.htaccess` file, you can take them and
+add a username between the ``'deny'``/``'allow'`` and ``'from'``
+strings. Using the username wildcard of ``'%'`` would be a major
+benefit here if your installation is suited to using it. Then you can
+just add those updated lines into the
+:config:option:`$cfg['Servers'][$i]['AllowDeny']['rules']` array.
+
+If you want a pre-made sample, you can try this fragment. It stops the
+'root' user from logging in from any networks other than the private
+network :term:`IP` blocks.
+
+.. code-block:: php
+
+    
+    //block root from logging in except from the private networks
+    $cfg['Servers'][$i]['AllowDeny']['order'] = 'deny,allow';
+    $cfg['Servers'][$i]['AllowDeny']['rules'] = array(
+        'deny root from all',
+        'allow root from localhost',
+        'allow root from 10.0.0.0/8',
+        'allow root from 192.168.0.0/16',
+        'allow root from 172.16.0.0/12',
+    );
+
+.. _faq4_7:
+
+4.7 Authentication window is displayed more than once, why?
+-----------------------------------------------------------
+
+This happens if you are using a :term:`URL` to start phpMyAdmin which is
+different than the one set in your :config:option:`$cfg['PmaAbsoluteUri']`. For
+example, a missing "www", or entering with an :term:`IP` address while a domain
+name is defined in the config file.
+
+.. _faq4_8:
+
+4.8 Which parameters can I use in the URL that starts phpMyAdmin?
+-----------------------------------------------------------------
+
+When starting phpMyAdmin, you can use the ``db``, ``pma_username``,
+``pma_password`` and ``server`` parameters. This last one can contain
+either the numeric host index (from ``$i`` of the configuration file)
+or one of the host names present in the configuration file. Using
+``pma_username`` and ``pma_password`` has been tested along with the
+usage of 'cookie' ``auth_type``.
+
+.. _faqbrowsers:
+
+Browsers or client OS
++++++++++++++++++++++
+
+.. _faq5_1:
+
+5.1 I get an out of memory error, and my controls are non-functional, when trying to create a table with more than 14 columns.
+------------------------------------------------------------------------------------------------------------------------------
+
+We could reproduce this problem only under Win98/98SE. Testing under
+WinNT4 or Win2K, we could easily create more than 60 columns.  A
+workaround is to create a smaller number of columns, then come back to
+your table properties and add the other columns.
+
+.. _faq5_2:
+
+5.2 With Xitami 2.5b4, phpMyAdmin won't process form fields.
+------------------------------------------------------------
+
+This is not a phpMyAdmin problem but a Xitami known bug: you'll face
+it with each script/website that use forms. Upgrade or downgrade your
+Xitami server.
+
+.. _faq5_3:
+
+5.3 I have problems dumping tables with Konqueror (phpMyAdmin 2.2.2).
+---------------------------------------------------------------------
+
+With Konqueror 2.1.1: plain dumps, zip and GZip dumps work ok, except
+that the proposed file name for the dump is always 'tbl\_dump.php'.
+Bzip2 dumps don't seem to work. With Konqueror 2.2.1: plain dumps
+work; zip dumps are placed into the user's temporary directory, so
+they must be moved before closing Konqueror, or else they disappear.
+GZip dumps give an error message. Testing needs to be done for
+Konqueror 2.2.2.
+
+.. _faq5_4:
+
+5.4 I can't use the cookie authentication mode because Internet Explorer never stores the cookies.
+--------------------------------------------------------------------------------------------------
+
+MS Internet Explorer seems to be really buggy about cookies, at least
+till version 6.
+
+.. _faq5_5:
+
+5.5 In Internet Explorer 5.0, I get JavaScript errors when browsing my rows.
+----------------------------------------------------------------------------
+
+Upgrade to at least Internet Explorer 5.5 SP2.
+
+.. _faq5_6:
+
+5.6 In Internet Explorer 5.0, 5.5 or 6.0, I get an error (like "Page not found") when trying to modify a row in a table with many columns, or with a text column.
+-----------------------------------------------------------------------------------------------------------------------------------------------------------------
+
+Your table neither have a primary key nor an unique one, so we must use a long
+:term:`URL` to identify this row. There is a limit on the length of the
+:term:`URL` in those browsers, and this not happen in Netscape, for example.
+The workaround is to create a primary or unique key, or use another browser.
+
+.. _faq5_7:
+
+5.7 I refresh (reload) my browser, and come back to the welcome page.
+---------------------------------------------------------------------
+
+Some browsers support right-clicking into the frame you want to
+refresh, just do this in the right frame.
+
+.. _faq5_8:
+
+5.8 With Mozilla 0.9.7 I have problems sending a query modified in the query box.
+---------------------------------------------------------------------------------
+
+Looks like a Mozilla bug: 0.9.6 was OK. We will keep an eye on future
+Mozilla versions.
+
+.. _faq5_9:
+
+5.9 With Mozilla 0.9.? to 1.0 and Netscape 7.0-PR1 I can't type a whitespace in the SQL-Query edit area: the page scrolls down.
+-------------------------------------------------------------------------------------------------------------------------------
+
+This is a Mozilla bug (see bug #26882 at `BugZilla
+<http://bugzilla.mozilla.org/>`_).
+
+.. _faq5_10:
+
+5.10 With Netscape 4.75 I get empty rows between each row of data in a CSV exported file.
+-----------------------------------------------------------------------------------------
+
+This is a known Netscape 4.75 bug: it adds some line feeds when
+exporting data in octet-stream mode. Since we can't detect the
+specific Netscape version, we cannot workaround this bug.
+
+.. _faq5_11:
+
+5.11 Extended-ASCII characters like German umlauts are displayed wrong.
+-----------------------------------------------------------------------
+
+Please ensure that you have set your browser's character set to the
+one of the language file you have selected on phpMyAdmin's start page.
+Alternatively, you can try the auto detection mode that is supported
+by the recent versions of the most browsers.
+
+.. _faq5_12:
+
+5.12 Mac OS X Safari browser changes special characters to "?".
+---------------------------------------------------------------
+
+This issue has been reported by a :term:`Mac OS X` user, who adds that Chimera,
+Netscape and Mozilla do not have this problem.
+
+.. _faq5_13:
+
+5.13 With Internet Explorer 5.5 or 6, and HTTP authentication type, I cannot manage two servers: I log in to the first one, then the other one, but if I switch back to the first, I have to log in on each operation.
+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
+
+This is a bug in Internet Explorer, other browsers do not behave this
+way.
+
+.. _faq5_14:
+
+5.14 Using Opera6, I can manage to get to the authentication, but nothing happens after that, only a blank screen.
+------------------------------------------------------------------------------------------------------------------
+
+Please upgrade to Opera7 at least.
+
+.. _faq5_15:
+
+5.15 I have display problems with Safari.
+-----------------------------------------
+
+Please upgrade to at least version 1.2.3.
+
+.. _faq5_16:
+
+5.16 With Internet Explorer, I get "Access is denied" Javascript errors. Or I cannot make phpMyAdmin work under Windows.
+------------------------------------------------------------------------------------------------------------------------
+
+Please check the following points:
+
+* Maybe you have defined your :config:option:`$cfg['PmaAbsoluteUri']` setting in
+  :file:`config.inc.php` to an :term:`IP` address and you are starting phpMyAdmin
+  with a :term:`URL` containing a domain name, or the reverse situation.
+* Security settings in IE and/or Microsoft Security Center are too high,
+  thus blocking scripts execution.
+* The Windows Firewall is blocking Apache and MySQL. You must allow
+  :term:`HTTP` ports (80 or 443) and MySQL
+  port (usually 3306) in the "in" and "out" directions.
+
+.. _faq5_17:
+
+5.17 With Firefox, I cannot delete rows of data or drop a database.
+-------------------------------------------------------------------
+
+Many users have confirmed that the Tabbrowser Extensions plugin they
+installed in their Firefox is causing the problem.
+
+.. _faq5_18:
+
+5.18 With Konqueror 4.2.x an invalid ``LIMIT`` clause is generated when I browse a table.
+-----------------------------------------------------------------------------------------
+
+This happens only when both of these conditions are met: using the
+``http`` authentication mode and ``register_globals`` being set to
+``On`` on the server. It seems to be a browser-specific problem;
+meanwhile use the ``cookie`` authentication mode.
+
+.. _faq5_19:
+
+5.19 I get JavaScript errors in my browser.
+-------------------------------------------
+
+Issues have been reported with some combinations of browser
+extensions. To troubleshoot, disable all extensions then clear your
+browser cache to see if the problem goes away.
+
+.. _faqusing:
+
+Using phpMyAdmin
+++++++++++++++++
+
+.. _faq6_1:
+
+6.1 I can't insert new rows into a table / I can't create a table - MySQL brings up a SQL error.
+------------------------------------------------------------------------------------------------
+
+Examine the :term:`SQL` error with care.
+Often the problem is caused by specifying a wrong column-type. Common
+errors include:
+
+* Using ``VARCHAR`` without a size argument
+* Using ``TEXT`` or ``BLOB`` with a size argument
+
+Also, look at the syntax chapter in the MySQL manual to confirm that
+your syntax is correct.
+
+.. _faq6_2:
+
+6.2 When I create a table, I set an index for two columns and phpMyAdmin generates only one index with those two columns.
+-------------------------------------------------------------------------------------------------------------------------
+
+This is the way to create a multi-columns index. If you want two
+indexes, create the first one when creating the table, save, then
+display the table properties and click the Index link to create the
+other index.
+
+.. _faq6_3:
+
+6.3 How can I insert a null value into my table?
+------------------------------------------------
+
+Since version 2.2.3, you have a checkbox for each column that can be
+null. Before 2.2.3, you had to enter "null", without the quotes, as
+the column's value. Since version 2.5.5, you have to use the checkbox
+to get a real NULL value, so if you enter "NULL" this means you want a
+literal NULL in the column, and not a NULL value (this works in PHP4).
+
+.. _faq6_4:
+
+6.4 How can I backup my database or table?
+------------------------------------------
+
+Click on a database or table name in the navigation panel, the properties will
+be displayed. Then on the menu, click "Export", you can dump the structure, the
+data, or both. This will generate standard :term:`SQL` statements that can be
+used to recreate your database/table.  You will need to choose "Save as file",
+so that phpMyAdmin can transmit the resulting dump to your station.  Depending
+on your PHP configuration, you will see options to compress the dump. See also
+the :config:option:`$cfg['ExecTimeLimit']` configuration variable. For
+additional help on this subject, look for the word "dump" in this document.
+
+.. _faq6_5:
+
+6.5 How can I restore (upload) my database or table using a dump? How can I run a ".sql" file?
+----------------------------------------------------------------------------------------------
+
+Click on a database name in the navigation panel, the properties will
+be displayed. Select "Import" from the list of tabs in the right–hand
+frame (or ":term:`SQL`" if your phpMyAdmin
+version is previous to 2.7.0). In the "Location of the text file"
+section, type in the path to your dump filename, or use the Browse
+button. Then click Go.  With version 2.7.0, the import engine has been
+re–written, if possible it is suggested that you upgrade to take
+advantage of the new features.  For additional help on this subject,
+look for the word "upload" in this document.
+
+.. _faq6_6:
+
+6.6 How can I use the relation table in Query-by-example?
+---------------------------------------------------------
+
+Here is an example with the tables persons, towns and countries, all
+located in the database mydb. If you don't have a ``pma__relation``
+table, create it as explained in the configuration section. Then
+create the example tables:
+
+.. code-block:: mysql
+
+    
+    CREATE TABLE REL_countries (
+    country_code char(1) NOT NULL default '',
+    description varchar(10) NOT NULL default '',
+    PRIMARY KEY (country_code)
+    ) TYPE=MyISAM;
+    
+    INSERT INTO REL_countries VALUES ('C', 'Canada');
+    
+    CREATE TABLE REL_persons (
+    id tinyint(4) NOT NULL auto_increment,
+    person_name varchar(32) NOT NULL default '',
+    town_code varchar(5) default '0',
+    country_code char(1) NOT NULL default '',
+    PRIMARY KEY (id)
+    ) TYPE=MyISAM;
+    
+    INSERT INTO REL_persons VALUES (11, 'Marc', 'S', '');
+    INSERT INTO REL_persons VALUES (15, 'Paul', 'S', 'C');
+    
+    CREATE TABLE REL_towns (
+    town_code varchar(5) NOT NULL default '0',
+    description varchar(30) NOT NULL default '',
+    PRIMARY KEY (town_code)
+    ) TYPE=MyISAM;
+    
+    INSERT INTO REL_towns VALUES ('S', 'Sherbrooke');
+    INSERT INTO REL_towns VALUES ('M', 'Montréal');
+
+To setup appropriate links and display information:
+
+* on table "REL\_persons" click Structure, then Relation view
+* in Links, for "town\_code" choose "REL\_towns->code"
+* in Links, for "country\_code" choose "REL\_countries->country\_code"
+* on table "REL\_towns" click Structure, then Relation view
+* in "Choose column to display", choose "description"
+* repeat the two previous steps for table "REL\_countries"
+
+Then test like this:
+
+* Click on your db name in the navigation panel
+* Choose "Query"
+* Use tables: persons, towns, countries
+* Click "Update query"
+* In the columns row, choose persons.person\_name and click the "Show"
+  tickbox
+* Do the same for towns.description and countries.descriptions in the
+  other 2 columns
+* Click "Update query" and you will see in the query box that the
+  correct joins have been generated
+* Click "Submit query"
+
+.. _faqdisplay:
+
+6.7 How can I use the "display column" feature?
+-----------------------------------------------
+
+Starting from the previous example, create the ``pma__table_info`` as
+explained in the configuration section, then browse your persons
+table, and move the mouse over a town code or country code.  See also
+:ref:`faq6_21` for an additional feature that "display column"
+enables: drop-down list of possible values.
+
+.. _faqpdf:
+
+6.8 How can I produce a PDF schema of my database?
+--------------------------------------------------
+
+First the configuration variables "relation", "table\_coords" and
+"pdf\_pages" have to be filled in.  Then you need to think about your
+schema layout. Which tables will go on which pages?
+
+* Select your database in the navigation panel.
+* Choose "Operations" in the navigation bar at the top.
+* Choose "Edit :term:`PDF` Pages" near the
+  bottom of the page.
+* Enter a name for the first :term:`PDF` page
+  and click Go. If you like, you can use the "automatic layout," which
+  will put all your linked tables onto the new page.
+* Select the name of the new page (making sure the Edit radio button is
+  selected) and click Go.
+* Select a table from the list, enter its coordinates and click Save.
+  Coordinates are relative; your diagram will be automatically scaled to
+  fit the page. When initially placing tables on the page, just pick any
+  coordinates -- say, 50x50. After clicking Save, you can then use the
+  :ref:`wysiwyg` to position the element correctly.
+* When you'd like to look at your :term:`PDF`, first be sure to click the Save 
+  button beneath the list of tables and coordinates, to save any changes you 
+  made there. Then scroll all the way down, select the :term:`PDF` options you 
+  want, and click Go.
+* Internet Explorer for Windows may suggest an incorrect filename when
+  you try to save a generated :term:`PDF`.
+  When saving a generated :term:`PDF`, be
+  sure that the filename ends in ".pdf", for example "schema.pdf".
+  Browsers on other operating systems, and other browsers on Windows, do
+  not have this problem.
+
+.. _faq6_9:
+
+6.9 phpMyAdmin is changing the type of one of my columns!
+---------------------------------------------------------
+
+No, it's MySQL that is doing `silent column type changing
+<http://dev.mysql.com/doc/en/silent-column-changes.html>`_.
+
+.. _underscore:
+
+6.10 When creating a privilege, what happens with underscores in the database name?
+-----------------------------------------------------------------------------------
+
+If you do not put a backslash before the underscore, this is a
+wildcard grant, and the underscore means "any character". So, if the
+database name is "john\_db", the user would get rights to john1db,
+john2db ... If you put a backslash before the underscore, it means
+that the database name will have a real underscore.
+
+.. _faq6_11:
+
+6.11 What is the curious symbol ø in the statistics pages?
+----------------------------------------------------------
+
+It means "average".
+
+.. _faqexport:
+
+6.12 I want to understand some Export options.
+----------------------------------------------
+
+**Structure:**
+
+* "Add DROP TABLE" will add a line telling MySQL to `drop the table
+  <http://dev.mysql.com/doc/mysql/en/drop-table.html>`_, if it already
+  exists during the import. It does NOT drop the table after your
+  export, it only affects the import file.
+* "If Not Exists" will only create the table if it doesn't exist.
+  Otherwise, you may get an error if the table name exists but has a
+  different structure.
+* "Add AUTO\_INCREMENT value" ensures that AUTO\_INCREMENT value (if
+  any) will be included in backup.
+* "Enclose table and column names with backquotes" ensures that column
+  and table names formed with special characters are protected.
+* "Add into comments" includes column comments, relations, and MIME
+  types set in the pmadb in the dump as :term:`SQL` comments 
+  (*/\* xxx \*/*).
+
+**Data:**
+
+* "Complete inserts" adds the column names on every INSERT command, for
+  better documentation (but resulting file is bigger).
+* "Extended inserts" provides a shorter dump file by using only once the
+  INSERT verb and the table name.
+* "Delayed inserts" are best explained in the `MySQL manual - INSERT DELAYED Syntax
+  <http://dev.mysql.com/doc/mysql/en/insert-delayed.html>`_.
+* "Ignore inserts" treats errors as a warning instead. Again, more info
+  is provided in the `MySQL manual - INSERT Syntax
+  <http://dev.mysql.com/doc/mysql/en/insert.html>`_, but basically with
+  this selected, invalid values are adjusted and inserted rather than
+  causing the entire statement to fail.
+
+.. _faq6_13:
+
+6.13 I would like to create a database with a dot in its name.
+--------------------------------------------------------------
+
+This is a bad idea, because in MySQL the syntax "database.table" is
+the normal way to reference a database and table name. Worse, MySQL
+will usually let you create a database with a dot, but then you cannot
+work with it, nor delete it.
+
+.. _faqsqlvalidator:
+
+6.14 How do I set up the SQL Validator?
+---------------------------------------
+
+To use SQL Validator, you need PHP with :term:`XML`, :term:`PCRE` and
+:term:`PEAR` support. In addition you need a :term:`SOAP` support, either as a
+PHP extension or as a PEAR SOAP module.
+
+To install :term:`PEAR` :term:`SOAP` module, run :command:`pear install
+Net_Socket Net_URL HTTP_Request Mail_Mime Net_DIME SOAP` to get the necessary
+:term:`PEAR` modules for usage.
+
+If you use the Validator, you should be aware that any :term:`SQL` statement
+you submit will be stored anonymously (database/table/column names, strings,
+numbers replaced with generic values). The Mimer :term:`SQL` Validator itself,
+is © 2001 Upright Database Technology. We utilize it as free SOAP service.
+
+.. _faq6_15:
+
+6.15 I want to add a BLOB column and put an index on it, but MySQL says "BLOB column '...' used in key specification without a key length".
+-------------------------------------------------------------------------------------------------------------------------------------------
+
+The right way to do this, is to create the column without any indexes,
+then display the table structure and use the "Create an index" dialog.
+On this page, you will be able to choose your BLOB column, and set a
+size to the index, which is the condition to create an index on a BLOB
+column.
+
+.. _faq6_16:
+
+6.16 How can I simply move in page with plenty editing fields?
+--------------------------------------------------------------
+
+You can use :kbd:`Ctrl+arrows` (:kbd:`Option+Arrows` in Safari) for moving on
+most pages with many editing fields (table structure changes, row editing,
+etc.).
+
+.. _faq6_17:
+
+6.17 Transformations: I can't enter my own mimetype! WTF is this feature then useful for?
+-----------------------------------------------------------------------------------------
+
+Slow down :). Defining mimetypes is of no use, if you can't put
+transformations on them. Otherwise you could just put a comment on the
+column. Because entering your own mimetype will cause serious syntax
+checking issues and validation, this introduces a high-risk false-
+user-input situation. Instead you have to initialize mimetypes using
+functions or empty mimetype definitions. 
+
+Plus, you have a whole overview of available mimetypes. Who knows all those
+mimetypes by heart so he/she can enter it at will?
+
+.. _faqbookmark:
+
+6.18 Bookmarks: Where can I store bookmarks? Why can't I see any bookmarks below the query box? What is this variable for?
+--------------------------------------------------------------------------------------------------------------------------
+
+Any query you have executed can be stored as a bookmark on the page
+where the results are displayed. You will find a button labeled
+'Bookmark this query' just at the end of the page. As soon as you have
+stored a bookmark, it is related to the database you run the query on.
+You can now access a bookmark dropdown on each page, the query box
+appears on for that database.
+
+You can also have, inside the query, a placeholder for a variable.
+This is done by inserting into the query a SQL comment between ``/*`` and 
+``*/``. Inside the comment, the special string ``[VARIABLE]`` is used. 
+Be aware that the whole query minus the SQL comment must be
+valid by itself, otherwise you won't be able to store it as a bookmark.
+
+When you execute the bookmark, everything typed into the *value* 
+input box on the query box page will replace the string ``/*[VARIABLE]*/`` in 
+your stored query.
+
+Also remember, that everything else inside the ``/*[VARIABLE]*/`` string for
+your query will remain the way it is, but will be stripped of the ``/**/``
+chars. So you can use:
+
+.. code-block:: mysql
+
+    /*, [VARIABLE] AS myname */
+    
+which will be expanded to 
+
+.. code-block:: mysql
+
+    , VARIABLE as myname
+    
+in your query, where VARIABLE is the string you entered in the input box. If an
+empty string is provided, no replacements are made. 
+
+A more complex example. Say you have stored
+this query: 
+
+.. code-block:: mysql
+
+    SELECT Name, Address FROM addresses WHERE 1 /* AND Name LIKE '%[VARIABLE]%' */
+    
+Say, you now enter "phpMyAdmin" as the variable for the stored query, the full
+query will be: 
+
+.. code-block:: mysql
+
+    SELECT Name, Address FROM addresses WHERE 1 AND Name LIKE '%phpMyAdmin%'
+
+You can use multiple occurrences of ``/*[VARIABLE]*/`` in a single query
+(that is, multiple occurrences of the *same* variable). 
+
+**NOTE THE ABSENCE OF SPACES** inside the ``/**/`` construct. Any spaces
+inserted there will be later also inserted as spaces in your query and may lead
+to unexpected results especially when using the variable expansion inside of a
+"LIKE ''" expression. 
+
+Your initial query which is going to be stored as a bookmark has to yield at
+least one result row so you can store the bookmark. You may have that to work
+around using well positioned ``/**/`` comments.
+
+.. _faq6_19:
+
+6.19 How can I create simple LATEX document to include exported table?
+----------------------------------------------------------------------
+
+You can simply include table in your LATEX documents,
+minimal sample document should look like following one (assuming you
+have table exported in file :file:`table.tex`):
+
+.. code-block:: latex
+
+    
+    \documentclass{article} % or any class you want
+    \usepackage{longtable}  % for displaying table
+    \begin{document}        % start of document
+    \include{table}         % including exported table
+    \end{document}          % end of document
+
+.. _faq6_20:
+
+6.20 I see a lot of databases which are not mine, and cannot access them.
+-------------------------------------------------------------------------
+
+You have one of these global privileges: CREATE TEMPORARY TABLES, SHOW
+DATABASES, LOCK TABLES. Those privileges also enable users to see all the
+database names. So if your users do not need those privileges, you can remove
+them and their databases list will shorten.
+
+.. seealso:: <http://bugs.mysql.com/179>
+
+.. _faq6_21:
+
+6.21 In edit/insert mode, how can I see a list of possible values for a column, based on some foreign table?
+------------------------------------------------------------------------------------------------------------
+
+You have to setup appropriate links between the tables, and also setup
+the "display column" in the foreign table. See :ref:`faq6_6` for an
+example. Then, if there are 100 values or less in the foreign table, a
+drop-down list of values will be available. You will see two lists of
+values, the first list containing the key and the display column, the
+second list containing the display column and the key. The reason for
+this is to be able to type the first letter of either the key or the
+display column. For 100 values or more, a distinct window will appear,
+to browse foreign key values and choose one. To change the default
+limit of 100, see :config:option:`$cfg['ForeignKeyMaxLimit']`.
+
+
+.. _faq6_22:
+
+6.22 Bookmarks: Can I execute a default bookmark automatically when entering Browse mode for a table?
+-----------------------------------------------------------------------------------------------------
+
+Yes. If a bookmark has the same label as a table name and it's not a
+public bookmark, it will be executed.
+
+.. _faq6_23:
+
+6.23 Export: I heard phpMyAdmin can export Microsoft Excel files?
+-----------------------------------------------------------------
+
+You can use :term:`CSV` for Microsoft Excel,
+which works out of the box. 
+
+.. versionchanged:: 3.4.5
+    Since phpMyAdmin 3.4.5 support for direct export to Microsoft Excel version
+    97 and newer was dropped.
+
+.. _faq6_24:
+
+6.24 Now that phpMyAdmin supports native MySQL 4.1.x column comments, what happens to my column comments stored in pmadb?
+-------------------------------------------------------------------------------------------------------------------------
+
+Automatic migration of a table's pmadb-style column comments to the
+native ones is done whenever you enter Structure page for this table.
+
+.. _faq6_25:
+
+6.25 (withdrawn).
+-----------------
+
+.. _faq6_26:
+
+6.26 How can I select a range of rows?
+--------------------------------------
+
+Click the first row of the range, hold the shift key and click the
+last row of the range. This works everywhere you see rows, for example
+in Browse mode or on the Structure page.
+
+.. _faq6_27:
+
+6.27 What format strings can I use?
+-----------------------------------
+
+In all places where phpMyAdmin accepts format strings, you can use
+``@VARIABLE@`` expansion and `strftime <http://php.net/strftime>`_
+format strings. The expanded variables depend on a context (for
+example, if you haven't chosen a table, you can not get the table
+name), but the following variables can be used:
+
+``@HTTP_HOST@``
+    HTTP host that runs phpMyAdmin
+``@SERVER@``
+    MySQL server name
+``@VERBOSE@``
+    Verbose MySQL server name as defined in :config:option:`$cfg['Servers'][$i]['verbose']`
+``@VSERVER@``
+    Verbose MySQL server name if set, otherwise normal
+``@DATABASE@``
+    Currently opened database
+``@TABLE@``
+    Currently opened table
+``@COLUMNS@``
+    Columns of the currently opened table
+``@PHPMYADMIN@``
+    phpMyAdmin with version
+
+.. _wysiwyg:
+
+6.28 How can I easily edit relational schema for export?
+--------------------------------------------------------
+
+By clicking on the button 'toggle scratchboard' on the page where you
+edit x/y coordinates of those elements you can activate a scratchboard
+where all your elements are placed. By clicking on an element, you can
+move them around in the pre-defined area and the x/y coordinates will
+get updated dynamically. Likewise, when entering a new position
+directly into the input field, the new position in the scratchboard
+changes after your cursor leaves the input field.
+
+You have to click on the 'OK'-button below the tables to save the new
+positions. If you want to place a new element, first add it to the
+table of elements and then you can drag the new element around.
+
+By changing the paper size and the orientation you can change the size
+of the scratchboard as well. You can do so by just changing the
+dropdown field below, and the scratchboard will resize automatically,
+without interfering with the current placement of the elements.
+
+If ever an element gets out of range you can either enlarge the paper
+size or click on the 'reset' button to place all elements below each
+other.
+
+.. _faq6_29:
+
+6.29 Why can't I get a chart from my query result table?
+--------------------------------------------------------
+
+Not every table can be put to the chart. Only tables with one, two or
+three columns can be visualised as a chart. Moreover the table must be
+in a special format for chart script to understand it. Currently
+supported formats can be found in the `wiki <http://wiki.phpmyadmin.ne
+t/pma/Charts#Data_formats_for_query_results_chart>`_.
+
+.. _faq6_30:
+
+6.30 Import: How can I import ESRI Shapefiles
+---------------------------------------------
+
+An ESRI Shapefile is actually a set of several files, where .shp file
+contains geometry data and .dbf file contains data related to those
+geometry data. To read data from .dbf file you need to have PHP
+compiled with the dBase extension (--enable-dbase). Otherwise only
+geometry data will be imported.
+
+To upload these set of files you can use either of the following
+methods:
+
+Configure upload directory with :config:option:`$cfg['UploadDir']`, upload both .shp and .dbf files with
+the same filename and chose the .shp file from the import page.
+
+Create a Zip archive with .shp and .dbf files and import it. For this
+to work, you need to set :config:option:`$cfg['TempDir']` to a place where the web server user can
+write (for example ``'./tmp'``).
+
+To create the temporary directory on a UNIX-based system, you can do:
+
+.. code-block:: sh
+
+    cd phpMyAdmin
+    mkdir tmp
+    chmod o+rwx tmp
+
+.. _faq6_31:
+
+6.31 How do I create a relation in designer?
+--------------------------------------------
+
+To select relation, click:  The display column is shown in pink. To
+set/unset a column as the display column, click the "Choose column to
+display" icon, then click on the appropriate column name.
+
+.. _faq6_32:
+
+6.32 How can I use the zoom search feature?
+-------------------------------------------
+
+The Zoom search feature is an alternative to table search feature. It allows
+you to explore a table by representing its data in a scatter plot. You can
+locate this feature by selecting a table and clicking the :guilabel:`Search`
+tab. One of the sub-tabs in the :guilabel:`Table Search` page is
+:guilabel:`Zoom Search`.  
+
+Consider the table REL\_persons in :ref:`faq6_6` for
+an example. To use zoom search, two columns need to be selected, for
+example, id and town\_code. The id values will be represented on one
+axis and town\_code values on the other axis. Each row will be
+represented as a point in a scatter plot based on its id and
+town\_code. You can include two additional search criteria apart from
+the two fields to display. 
+
+You can choose which field should be
+displayed as label for each point. If a display column has been set
+for the table (see :ref:`faqdisplay`), it is taken as the label unless
+you specify otherwise. You can also select the maximum number of rows
+you want to be displayed in the plot by specifing it in the 'Max rows
+to plot' field. Once you have decided over your criteria, click 'Go'
+to display the plot. 
+
+After the plot is generated, you can use the
+mousewheel to zoom in and out of the plot. In addition, panning
+feature is enabled to navigate through the plot. You can zoom-in to a
+certail level of detail and use panning to locate your area of
+interest. Clicking on a point opens a dialogue box, displaying field
+values of the data row represented by the point. You can edit the
+values if required and click on submit to issue an update query. Basic
+instructions on how to use can be viewed by clicking the 'How to use?'
+link located just above the plot.
+
+.. _faq6_33:
+
+6.33 When browsing a table, how can I copy a column name?
+---------------------------------------------------------
+
+Selecting the name of the column within the browse table header cell
+for copying is difficult, as the columns support reordering by
+dragging the header cells as well as sorting by clicking on the linked
+column name. To copy a column name, double-click on the empty area
+next to the column name, when the tooltip tells you to do so. This
+will show you an input box with the column name. You may right-click
+the column name within this input box to copy it to your clipboard.
+
+.. _faqproject:
+
+phpMyAdmin project
+++++++++++++++++++
+
+.. _faq7_1:
+
+7.1 I have found a bug. How do I inform developers?
+---------------------------------------------------
+
+Our Bug Tracker is located at <http://sf.net/projects/phpmyadmin/> under the
+Bugs section. But please first discuss your bug with other users:
+<https://sourceforge.net/projects/phpmyadmin/forums>.
+
+.. _faq7_2:
+
+7.2 I want to translate the messages to a new language or upgrade an existing language, where do I start?
+---------------------------------------------------------------------------------------------------------
+
+Translations are very welcome and all you need to have are the
+language skills. The easiest way is to use our `online translation
+service <https://l10n.cihar.com/projects/phpmyadmin/>`_. You can check
+out all the possibilities to translate in the `translate section on
+our website <http://www.phpmyadmin.net/home_page/translate.php>`_.
+
+.. _faq7_3:
+
+7.3 I would like to help out with the development of phpMyAdmin. How should I proceed?
+--------------------------------------------------------------------------------------
+
+We welcome every contribution to the development of phpMyAdmin. You
+can check out all the possibilities to contribute in the `contribute
+section on our website
+<http://www.phpmyadmin.net/home_page/improve.php>`_.
+
+.. seealso:: :ref:`developers`
+
+.. _faqsecurity:
+
+Security
+++++++++
+
+.. _faq8_1:
+
+8.1 Where can I get information about the security alerts issued for phpMyAdmin?
+--------------------------------------------------------------------------------
+
+Please refer to <http://www.phpmyadmin.net/home_page/security.php>.
+
+.. _faq8_2:
+
+8.2 How can I protect phpMyAdmin against brute force attacks?
+-------------------------------------------------------------
+
+If you use Apache web server, phpMyAdmin exports information about
+authentication to the Apache environment and it can be used in Apache
+logs. Currently there are two variables available:
+
+
+``userID``
+    User name of currently active user (he does not have to be logged in).
+``userStatus``
+    Status of currently active user, one of ``ok`` (user is logged in),
+    ``mysql-denied`` (MySQL denied user login), ``allow-denied`` (user denied
+    by allow/deny rules), ``root-denied`` (root is denied in configuration),
+    ``empty-denied`` (empty password is denied).
+
+``LogFormat`` directive for Apache can look like following:
+
+.. code-block:: apache
+
+    LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\" %{userID}n %{userStatus}n"   pma_combined
+
+You can then use any log analyzing tools to detect possible break-in
+attempts.
+
+.. _faqsynchronization:
+
+Synchronization
++++++++++++++++
+
+.. _faq9_1:
+
+9.1 (withdrawn). 
+----------------
+
+.. _faq9_2:
+
+9.2 (withdrawn). 
+----------------
+
diff --git a/phpmyadmin/doc/html/_sources/glossary.txt b/phpmyadmin/doc/html/_sources/glossary.txt
new file mode 100644
index 0000000..d558b44
--- /dev/null
+++ b/phpmyadmin/doc/html/_sources/glossary.txt
@@ -0,0 +1,406 @@
+.. _glossary:
+
+Glossary
+========
+
+From Wikipedia, the free encyclopedia
+
+.. glossary::
+
+    .htaccess
+      the default name of Apache's directory-level configuration file.	
+
+      .. seealso:: <http://www.wikipedia.org/wiki/.htaccess>
+
+    ACL
+      Access Contol List
+
+    Blowfish
+      a keyed, symmetric block cipher, designed in 1993 by Bruce Schneier.	
+
+      .. seealso:: <http://www.wikipedia.org/wiki/Blowfish_(cipher)>
+
+    Browser 
+      a software application that enables a user to display and interact with text, images, and other information typically located on a web page at a website on the World Wide Web.	
+
+      .. seealso:: <http://en.wikipedia.org/wiki/Web_browser>
+
+    bzip2
+      a free software/open source data compression algorithm and program developed by Julian Seward.	
+
+      .. seealso:: <http://www.wikipedia.org/wiki/Bzip2>
+
+    CGI 
+      Common Gateway Interface is an important World Wide Web technology that
+      enables a client web browser to request data from a program executed on
+      the Web server.	
+
+      .. seealso:: <http://www.wikipedia.org/wiki/CGI>
+
+    Changelog
+      a log or record of changes made to a project.	
+
+      .. seealso:: <http://www.wikipedia.org/wiki/Changelog>
+
+    Client
+      a computer system that accesses a (remote) service on another computer by some kind of network.	
+
+      .. seealso:: <http://www.wikipedia.org/wiki/Client_(computing)>
+
+    column
+      a set of data values of a particular simple type, one for each row of the table.	
+
+      .. seealso:: <http://www.wikipedia.org/wiki/Column_(database)>
+
+    Cookie
+      a packet of information sent by a server to a World Wide Web browser and then sent back by the browser each time it accesses that server.	
+
+      .. seealso:: <http://www.wikipedia.org/wiki/HTTP_cookie>
+
+    CSV
+      Comma- separated values	
+
+      .. seealso:: <http://www.wikipedia.org/wiki/Comma-separated_values>
+
+    DB 
+      look at :term:`database`
+
+    database
+      an organized collection of data.	
+
+      .. seealso:: <http://www.wikipedia.org/wiki/Database>
+
+    Engine 
+      look at :term:`storage engines`
+
+    extension
+      a PHP module that extends PHP with additional functionality.	
+
+      .. seealso:: <http://www.wikipedia.org/wiki/extension>
+
+    FAQ 
+      Frequently Asked Questions is a list of commonly asked question and there
+      answers.	
+
+      .. seealso:: <http://www.wikipedia.org/wiki/FAQ>
+
+    Field
+      one part of divided data/columns.	
+
+      .. seealso:: <http://www.wikipedia.org/wiki/Field_(computer_science)>
+
+    foreign key
+      a column or group of columns in a database row that point to a key column
+      or group of columns forming a key of another database row in some
+      (usually different) table.	
+
+      .. seealso:: <http://www.wikipedia.org/wiki/Foreign_key>
+
+    FPDF
+      the free :term:`PDF` library	
+
+      .. seealso:: <http://www.fpdf.org/>
+
+    GD 
+      Graphics Library by Thomas Boutell and others for dynamically manipulating images.	
+
+      .. seealso:: <http://www.wikipedia.org/wiki/GD_Graphics_Library>
+
+    GD2 
+      look at :term:`gd`
+
+    gzip
+      gzip is short for GNU zip, a GNU free software file compression program.	
+
+      .. seealso:: <http://www.wikipedia.org/wiki/Gzip>
+
+    host
+      any machine connected to a computer network, a node that has a hostname.	
+
+      .. seealso:: <http://www.wikipedia.org/wiki/Host>
+
+    hostname
+      the unique name by which a network attached device is known on a network.	
+
+      .. seealso:: <http://www.wikipedia.org/wiki/Hostname>
+
+    HTTP 
+      HyperText Transfer Protocol is the primary method used to transfer or
+      convey information on the World Wide Web.	
+
+      .. seealso:: <http://www.wikipedia.org/wiki/HyperText_Transfer_Protocol>
+
+    https
+      a :term:`HTTP`-connection with additional security measures.	
+
+      .. seealso:: <http://www.wikipedia.org/wiki/Https:_URI_scheme>
+
+    IEC
+      International Electrotechnical Commission
+
+    IIS 
+      Internet Information Services is a set of Internet-based services for
+      servers using Microsoft Windows.	
+
+      .. seealso:: <http://www.wikipedia.org/wiki/Internet_Information_Services>
+
+    Index
+      a feature that allows quick access to the rows in a table.	
+
+      .. seealso:: <http://www.wikipedia.org/wiki/Index_(database)>
+
+    IP 
+      Internet Protocol is a data-oriented protocol used by source and
+      destination hosts for communicating data across a packet-switched
+      internetwork.	
+
+      .. seealso:: <http://www.wikipedia.org/wiki/Internet_Protocol>
+
+    IP Address
+      a unique number that devices use in order to identify and communicate with each other on a network utilizing the Internet Protocol standard.	
+
+      .. seealso:: <http://www.wikipedia.org/wiki/IP_Address>
+
+    IPv6 
+      IPv6 (Internet Protocol version 6) is the latest revision of the 
+      Internet Protocol (:term:`IP`), designed to deal with the 
+      long-anticipated problem of its precedessor IPv4 running out of addresses.
+
+      .. seealso:: <http://www.wikipedia.org/wiki/IPv6>
+
+    ISAPI 
+      Internet Server Application Programming Interface is the API of Internet Information Services (IIS).	
+
+      .. seealso:: <http://www.wikipedia.org/wiki/ISAPI>
+
+    ISP 
+      Internet service provider is a business or organization that offers users
+      access to the Internet and related services.	
+
+      .. seealso:: <http://www.wikipedia.org/wiki/ISP>
+
+    ISO
+      International Standards Organisation
+
+    JPEG
+      a most commonly used standard method of lossy compression for photographic images.	
+
+      .. seealso:: <http://www.wikipedia.org/wiki/JPEG>
+
+    JPG 
+      look at :term:`jpeg`
+
+    Key
+      look at :term:`index`
+
+    LATEX
+      a document preparation system for the TEX typesetting program.	
+
+      .. seealso:: <http://www.wikipedia.org/wiki/LaTeX>
+
+    Mac
+       Apple Macintosh is line of personal computers is designed, developed, manufactured, and marketed by Apple Computer.	
+
+      .. seealso:: <http://www.wikipedia.org/wiki/Mac>
+
+    Mac OS X
+      the operating system which is included with all currently shipping Apple Macintosh computers in the consumer and professional markets.	
+
+      .. seealso:: <http://www.wikipedia.org/wiki/Mac_OS_X>
+
+    MCrypt
+      a cryptographic library.	
+
+      .. seealso:: <http://www.wikipedia.org/wiki/MCrypt>
+
+    mcrypt
+      the MCrypt PHP extension.	
+
+      .. seealso:: <http://php.net/mcrypt>
+
+    MIME 
+      Multipurpose Internet Mail Extensions is
+      an Internet Standard for the format of e-mail.	
+
+      .. seealso:: <http://www.wikipedia.org/wiki/MIME>
+
+    module
+      some sort of extension for the Apache Webserver.	
+
+      .. seealso:: <http://www.wikipedia.org/wiki/module>
+
+    MySQL
+      a multithreaded, multi-user, SQL (Structured Query Language) Database Management System (DBMS).	
+
+      .. seealso:: <http://www.wikipedia.org/wiki/MySQL>
+
+    mysqli
+      the improved MySQL client PHP extension.	
+
+      .. seealso:: <http://php.net/mysqli>
+
+    mysql
+      the MySQL client PHP extension.	
+
+      .. seealso:: <http://php.net/mysql>
+
+    OpenDocument
+      open standard for office documents.	
+
+      .. seealso:: <http://www.wikipedia.org/wiki/OpenDocument>
+
+    OS X
+      look at :term:`Mac OS X`.
+
+      .. seealso:: <http://www.wikipedia.org/wiki/OS_X>
+
+    PDF 
+      Portable Document Format is a file format developed by Adobe Systems for
+      representing two dimensional documents in a device independent and
+      resolution independent format.	
+
+      .. seealso:: <http://www.wikipedia.org/wiki/Portable_Document_Format>
+
+    PEAR
+      the PHP Extension and Application Repository.	
+
+      .. seealso:: <http://pear.php.net/>
+
+    PCRE 
+      Perl Compatible Regular Expressions is the perl-compatible regular
+      expression functions for PHP	
+
+      .. seealso:: <http://php.net/pcre>
+
+    PHP
+      short for "PHP: Hypertext Preprocessor", is an open-source, reflective
+      programming language used mainly for developing server-side applications
+      and dynamic web content, and more recently, a broader range of software
+      applications.	
+
+      .. seealso:: <http://www.wikipedia.org/wiki/PHP>
+
+    port
+      a connection through which data is sent and received.	
+
+      .. seealso:: <http://www.wikipedia.org/wiki/Port_(computing)>
+
+    RFC
+      Request for Comments (RFC) documents are a series of memoranda
+      encompassing new research, innovations, and methodologies applicable to
+      Internet technologies.	
+
+      .. seealso:: <http://www.wikipedia.org/wiki/Request_for_Comments>
+
+    RFC 1952
+      GZIP file format specification version 4.3
+
+      .. seealso:: :rfc:`1952`
+
+    Row (record, tuple)
+      represents a single, implicitly structured data item in a table.	
+
+      .. seealso:: <http://www.wikipedia.org/wiki/Row_(database)>
+
+    Server
+      a computer system that provides services to other computing systems over a network.	
+
+      .. seealso:: <http://www.wikipedia.org/wiki/Server_(computing)>
+
+    Storage Engines
+      handlers for different table types	
+
+      .. seealso:: <http://dev.mysql.com/doc/en/storage-engines.html>
+
+    SOAP
+      Simple Object Access Protocol is a protocol specification for exchanging
+      structured information in the implementation of Web Services in computer
+      networks.
+
+      .. seealso:: <http://en.wikipedia.org/wiki/SOAP>
+
+    socket
+      a form of inter-process communication.	
+
+      .. seealso:: <http://www.wikipedia.org/wiki/Socket#Computer_sockets>
+
+    SSL 
+      Secure Sockets Layer is a cryptographic protocol which provides secure
+      communication on the Internet.	
+
+      .. seealso:: <http://www.wikipedia.org/wiki/Secure_Sockets_Layer>
+
+    Stored procedure
+      a subroutine available to applications accessing a relational database system	
+
+      .. seealso:: <http://en.wikipedia.org/wiki/Stored_procedure>
+
+    SQL
+      Structured Query Language	
+
+      .. seealso:: <http://www.wikipedia.org/wiki/SQL>
+
+    table
+      a set of data elements (cells) that is organized, defined and stored as
+      horizontal rows and vertical columns where each item can be uniquely
+      identified by a label or key or by it?s position in relation to other
+      items.	
+
+      .. seealso:: <http://www.wikipedia.org/wiki/Table_(database)>
+
+    tar
+      a type of archive file format: the Tape ARchive format.	
+
+      .. seealso:: <http://www.wikipedia.org/wiki/Tar_(file_format)>
+
+    TCP 
+      Transmission Control Protocol is one of the core protocols of the
+      Internet protocol suite.	
+
+      .. seealso:: <http://www.wikipedia.org/wiki/TCP>
+
+    TCPDF
+      Rewrite of :term:`UFPDF` with various improvements.
+
+      .. seealso:: <http://www.tcpdf.org/>
+
+    trigger
+      a procedural code that is automatically executed in response to certain events on a particular table or view in a database	
+
+      .. seealso:: <http://en.wikipedia.org/wiki/Database_trigger>
+
+    UFPDF
+      Unicode/UTF-8 extension for :term:`FPDF`
+
+      .. seealso:: <http://www.acko.net/node/56>
+
+    URL
+      Uniform Resource Locator is a sequence of characters, conforming to a
+      standardized format, that is used for referring to resources, such as
+      documents and images on the Internet, by their location.	
+
+      .. seealso:: <http://www.wikipedia.org/wiki/URL>
+
+    Webserver
+      A computer (program) that is responsible for accepting HTTP requests from clients and serving them Web pages.	
+
+      .. seealso:: <http://www.wikipedia.org/wiki/Webserver>
+
+    XML 
+      Extensible Markup Language is a W3C-recommended general- purpose markup
+      language for creating special-purpose markup languages, capable of
+      describing many different kinds of data.	
+
+      .. seealso:: <http://www.wikipedia.org/wiki/XML>
+
+    ZIP
+      a popular data compression and archival format.	
+
+      .. seealso:: <http://www.wikipedia.org/wiki/ZIP_(file_format)>
+
+    zlib
+      an open-source, cross- platform data compression library by Jean-loup Gailly and Mark Adler.	
+
+      .. seealso:: <http://www.wikipedia.org/wiki/Zlib>
+
+
diff --git a/phpmyadmin/doc/html/_sources/index.txt b/phpmyadmin/doc/html/_sources/index.txt
new file mode 100644
index 0000000..917ddf8
--- /dev/null
+++ b/phpmyadmin/doc/html/_sources/index.txt
@@ -0,0 +1,32 @@
+.. phpMyAdmin documentation master file, created by
+   sphinx-quickstart on Wed Sep 26 14:04:48 2012.
+   You can adapt this file completely to your liking, but it should at least
+   contain the root `toctree` directive.
+
+Welcome to phpMyAdmin's documentation!
+======================================
+
+Contents:
+
+.. toctree::
+    :maxdepth: 2
+
+    intro
+    require
+    setup
+    config
+    user
+    faq
+    developers
+    vendors
+    copyright
+    credits
+    glossary
+
+
+Indices and tables
+==================
+
+* :ref:`genindex`
+* :ref:`search`
+* :ref:`glossary`
diff --git a/phpmyadmin/doc/html/_sources/intro.txt b/phpmyadmin/doc/html/_sources/intro.txt
new file mode 100644
index 0000000..9d81e44
--- /dev/null
+++ b/phpmyadmin/doc/html/_sources/intro.txt
@@ -0,0 +1,68 @@
+.. _intro:
+
+Introduction
+============
+
+phpMyAdmin can manage a whole MySQL server (needs a super-user) as
+well as a single database. To accomplish the latter you'll need a
+properly set up MySQL user who can read/write only the desired
+database. It's up to you to look up the appropriate part in the MySQL
+manual.
+
+
+Supported features
+------------------
+
+Currently phpMyAdmin can:
+
+* browse and drop databases, tables, views, columns and indexes
+* display multiple results sets through stored procedures or queries
+* create, copy, drop, rename and alter databases, tables, columns and
+  indexes
+* maintenance server, databases and tables, with proposals on server
+  configuration
+* execute, edit and bookmark any :term:`SQL`-statement, even batch-queries
+* load text files into tables
+* create [#f1]_ and read dumps of tables
+* export [#f1]_ data to various formats: :term:`CSV`, :term:`XML`, :term:`PDF`, 
+  :term:`ISO`/:term:`IEC` 26300 - :term:`OpenDocument` Text and Spreadsheet, Microsoft 
+  Word 2000, and LATEX formats
+* import data and :term:`MySQL` structures from :term:`OpenDocument` spreadsheets, as
+  well as :term:`XML`, :term:`CSV`, and :term:`SQL` files
+* administer multiple servers
+* manage MySQL users and privileges
+* check referential integrity in MyISAM tables
+* using Query-by-example (QBE), create complex queries automatically
+  connecting required tables
+* create :term:`PDF` graphics of your
+  database layout
+* search globally in a database or a subset of it
+* transform stored data into any format using a set of predefined
+  functions, like displaying BLOB-data as image or download-link
+* track changes on databases, tables and views
+* support InnoDB tables and foreign keys see :ref:`faq3_6`
+* support mysqli, the improved MySQL extension see :ref:`faq1_17`
+* create, edit, call, export and drop stored procedures and functions
+* create, edit, export and drop events and triggers
+* communicate in `62 different languages
+  <http://www.phpmyadmin.net/home_page/translations.php>`_
+
+
+A word about users
+------------------
+
+Many people have difficulty understanding the concept of user
+management with regards to phpMyAdmin. When a user logs in to
+phpMyAdmin, that username and password are passed directly to MySQL.
+phpMyAdmin does no account management on its own (other than allowing
+one to manipulate the MySQL user account information); all users must
+be valid MySQL users.
+
+.. rubric:: Footnotes
+
+.. [#f1]
+
+    phpMyAdmin can compress (:term:`Zip`, :term:`GZip` :term:`RFC 1952` or
+    :term:`Bzip2` formats) dumps and :term:`CSV` exports if you use PHP with
+    :term:`Zlib` support (``--with-zlib``) and/or :term:`Bzip2` support
+    (``--with-bz2``).  Proper support may also need changes in :file:`php.ini`.
diff --git a/phpmyadmin/doc/html/_sources/other.txt b/phpmyadmin/doc/html/_sources/other.txt
new file mode 100644
index 0000000..aa95451
--- /dev/null
+++ b/phpmyadmin/doc/html/_sources/other.txt
@@ -0,0 +1,18 @@
+Other sources of information
+============================
+
+Printed Book
+------------
+
+The definitive guide to using phpMyAdmin is the book Mastering phpMyAdmin for
+Effective MySQL Management by Marc Delisle. You can get information on that
+book and other officially endorsed `books at the phpMyAdmin site`_.
+
+.. _books at the phpMyAdmin site: http://www.phpmyadmin.net/home_page/docs.php?books
+
+Tutorials
+---------
+
+Third party tutorials and articles are listed on our `wiki page`_.
+
+.. _wiki page: http://wiki.phpmyadmin.net/pma/Articles
diff --git a/phpmyadmin/doc/html/_sources/privileges.txt b/phpmyadmin/doc/html/_sources/privileges.txt
new file mode 100644
index 0000000..0c12932
--- /dev/null
+++ b/phpmyadmin/doc/html/_sources/privileges.txt
@@ -0,0 +1,50 @@
+User management
+===============
+
+User management is the process of controlling which users are allowed to
+connect to the MySQL server and what permissions they have on each database.
+phpMyAdmin does not handle user management, rather it passes the username and
+password on to MySQL, which then determines whether a user is permitted to
+perform a particular action. Within phpMyAdmin, administrators have full
+control over creating users, viewing and editing privileges for existing users,
+and removing users.
+
+Within phpMyAdmin, user management is controlled via the :guilabel:`Users` link
+from the main page. Users can be created, edited, and removed.  
+
+Creating a new user
+-------------------
+
+To create a new user, click the :guilabel:`Add a new user` link near the bottom
+of the :guilabel:`Users` page (you must be a "superuser", e.g., user "root").
+Use the textboxes and drop-downs to configure the user to your particular
+needs. You can then select whether to create a database for that user and grant
+specific global privileges. Once you've created the user (by clicking Go), you
+can define that user's permissions on a specific database (don't grant global
+privileges in that case). In general, users do not need any global privileges
+(other than USAGE), only permissions for their specific database.
+
+Editing an existing user
+------------------------
+
+To edit an existing user, simply click the pencil icon to the right of that
+user in the :guilabel:`Users` page. You can then edit their global- and
+database-specific privileges, change their password, or even copy those
+privileges to a new user.
+
+Deleting a user
+---------------
+
+From the :guilabel:`Users` page, check the checkbox for the user you wish to
+remove, select whether or not to also remove any databases of the same name (if
+they exist), and click Go.
+
+Assigning privileges to user for a specific database
+----------------------------------------------------
+
+Users are assigned to databases by editing the user record (from the
+:guilabel:`Users` link on the home page) not from within the :guilabel:`Users`
+link under the table. If you are creating a user specifically for a given table
+you will have to create the user first (with no global privileges) and then go
+back and edit that user to add the table and privileges for the individual
+table.
diff --git a/phpmyadmin/doc/html/_sources/require.txt b/phpmyadmin/doc/html/_sources/require.txt
new file mode 100644
index 0000000..1452ee3
--- /dev/null
+++ b/phpmyadmin/doc/html/_sources/require.txt
@@ -0,0 +1,55 @@
+.. _require:
+
+Requirements
+============
+
+Web server
+----------
+
+Since, phpMyAdmin's interface is based entirely in your browser, you'll need a
+web server (such as Apache, :term:`IIS`) to install phpMyAdmin's files into.
+
+PHP
+---
+
+* You need PHP 5.2.0 or newer, with ``session`` support, the Standard PHP Library 
+  (SPL) extension and JSON support.
+
+* To support uploading of ZIP files, you need the PHP ``zip`` extension.
+
+* For proper support of multibyte strings (eg. UTF-8, which is currently
+  the default), you should install the ``mbstring`` and ``ctype`` extensions.
+
+* You need GD2 support in PHP to display inline thumbnails of JPEGs
+  ("image/jpeg: inline") with their original aspect ratio.
+
+* When using the cookie authentication (the default), the `mcrypt
+  <http://www.php.net/mcrypt>`_ extension is strongly suggested for most
+  users and is **required** for 64–bit machines. Not using mcrypt will
+  cause phpMyAdmin to load pages significantly slower.
+
+* To support upload progress bars, see :ref:`faq2_9`.
+
+* To support XML and Open Document Spreadsheet importing, you need PHP
+  5.2.17 or newer and the `libxml <http://www.php.net/libxml>`_
+  extension.
+
+.. seealso:: :ref:`faq1_31`, :ref:`authentication_modes`
+
+Database
+--------
+
+phpMyAdmin support MySQL compatible databases. 
+
+* MySQL 5.0 or newer
+* MariaDB 5.0 or newer
+* Drizzle
+
+.. seealso:: :ref:`faq1_17`
+
+Web browser
+-----------
+
+To access phpMyAdmin you need a web browser with cookies and javascript
+enabled.
+
diff --git a/phpmyadmin/doc/html/_sources/setup.txt b/phpmyadmin/doc/html/_sources/setup.txt
new file mode 100644
index 0000000..850d67a
--- /dev/null
+++ b/phpmyadmin/doc/html/_sources/setup.txt
@@ -0,0 +1,424 @@
+.. _setup:
+
+Installation
+============
+
+phpMyAdmin does not apply any special security methods to the MySQL
+database server. It is still the system administrator's job to grant
+permissions on the MySQL databases properly. phpMyAdmin's :guilabel:`Users`
+page can be used for this.
+
+.. warning::
+
+    :term:`Mac` users should note that if you are on a version before
+    :term:`Mac OS X`, StuffIt unstuffs with :term:`Mac` formats. So you'll have
+    to resave as in BBEdit to Unix style ALL phpMyAdmin scripts before
+    uploading them to your server, as PHP seems not to like :term:`Mac`-style
+    end of lines character ("``\r``").
+
+.. _quick_install:
+
+Quick Install
++++++++++++++
+
+#. Choose an appropriate distribution kit from the phpmyadmin.net
+   Downloads page. Some kits contain only the English messages, others
+   contain all languages. We'll assume you chose a kit whose name 
+   looks like ``phpMyAdmin-x.x.x -all-languages.tar.gz``.
+#. Untar or unzip the distribution (be sure to unzip the subdirectories):
+   ``tar -xzvf phpMyAdmin_x.x.x-all-languages.tar.gz`` in your
+   webserver's document root. If you don't have direct access to your
+   document root, put the files in a directory on your local machine,
+   and, after step 4, transfer the directory on your web server using,
+   for example, ftp.
+#. Ensure that all the scripts have the appropriate owner (if PHP is
+   running in safe mode, having some scripts with an owner different from
+   the owner of other scripts will be a problem). See :ref:`faq4_2` and
+   :ref:`faq1_26` for suggestions.
+#. Now you must configure your installation. There are two methods that
+   can be used. Traditionally, users have hand-edited a copy of
+   :file:`config.inc.php`, but now a wizard-style setup script is provided
+   for those who prefer a graphical installation. Creating a
+   :file:`config.inc.php` is still a quick way to get started and needed for
+   some advanced features.
+
+
+Manualy creating file
+---------------------
+
+To manually create the file, simply use your text editor to create the
+file :file:`config.inc.php` (you can copy :file:`config.sample.inc.php` to get
+minimal configuration file) in the main (top-level) phpMyAdmin
+directory (the one that contains :file:`index.php`). phpMyAdmin first
+loads :file:`libraries/config.default.php` and then overrides those values
+with anything found in :file:`config.inc.php`. If the default value is
+okay for a particular setting, there is no need to include it in
+:file:`config.inc.php`. You'll need a few directives to get going, a
+simple configuration may look like this:
+
+.. code-block:: php
+
+    
+    <?php
+    $cfg['blowfish_secret'] = 'ba17c1ec07d65003';  // use here a value of your choice
+    
+    $i=0;
+    $i++;
+    $cfg['Servers'][$i]['auth_type']     = 'cookie';
+    ?>
+
+Or, if you prefer to not be prompted every time you log in:
+
+.. code-block:: php
+
+    
+    <?php
+    
+    $i=0;
+    $i++;
+    $cfg['Servers'][$i]['user']          = 'root';
+    $cfg['Servers'][$i]['password']      = 'cbb74bc'; // use here your password
+    $cfg['Servers'][$i]['auth_type']     = 'config';
+    ?>
+
+For a full explanation of possible configuration values, see the 
+:ref:`config` of this document.
+
+.. index:: Setup script
+
+.. _setup_script:
+
+Using Setup script
+------------------
+
+Instead of manually editing :file:`config.inc.php`, you can use the `Setup
+Script <setup/>`_. First you must manually create a folder ``config``
+in the phpMyAdmin directory. This is a security measure. On a
+Linux/Unix system you can use the following commands:
+
+.. code-block:: sh
+
+    
+    cd phpMyAdmin
+    mkdir config                        # create directory for saving
+    chmod o+rw config                   # give it world writable permissions
+
+And to edit an existing configuration, copy it over first:
+
+.. code-block:: sh
+
+    
+    cp config.inc.php config/           # copy current configuration for editing
+    chmod o+w config/config.inc.php     # give it world writable permissions
+
+On other platforms, simply create the folder and ensure that your web
+server has read and write access to it. :ref:`faq1_26` can help with
+this.
+
+Next, open ``setup/`` in your browser. Note that **changes are
+not saved to disk until explicitly choose ``Save``** from the
+*Configuration* area of the screen. Normally the script saves the new
+:file:`config.inc.php` to the ``config/`` directory, but if the webserver does
+not have the proper permissions you may see the error "Cannot load or
+save configuration." Ensure that the ``config/`` directory exists and
+has the proper permissions - or use the ``Download`` link to save the
+config file locally and upload (via FTP or some similar means) to the
+proper location.
+
+Once the file has been saved, it must be moved out of the ``config/``
+directory and the permissions must be reset, again as a security
+measure:
+
+.. code-block:: sh
+
+    
+    mv config/config.inc.php .         # move file to current directory
+    chmod o-rw config.inc.php          # remove world read and write permissions
+    rm -rf config                      # remove not needed directory
+
+Now the file is ready to be used. You can choose to review or edit the
+file with your favorite editor, if you prefer to set some advanced
+options which the setup script does not provide.
+
+#. If you are using the ``auth_type`` "config", it is suggested that you
+   protect the phpMyAdmin installation directory because using config
+   does not require a user to enter a password to access the phpMyAdmin
+   installation. Use of an alternate authentication method is
+   recommended, for example with HTTP–AUTH in a :term:`.htaccess` file or switch to using
+   ``auth_type`` cookie or http. See the :ref:`faqmultiuser`
+   for additional information, especially :ref:`faq4_4`.
+#. Open the `main phpMyAdmin directory <index.php>`_ in your browser.
+   phpMyAdmin should now display a welcome screen and your databases, or
+   a login dialog if using :term:`HTTP` or
+   cookie authentication mode.
+#. You should deny access to the ``./libraries`` and ``./setup/lib``
+   subfolders in your webserver configuration. For Apache you can use
+   supplied :term:`.htaccess`  file in that folder, for other webservers, you should
+   configure this yourself. Such configuration prevents from possible
+   path exposure and cross side scripting vulnerabilities that might
+   happen to be found in that code.
+#. It is generally good idea to protect public phpMyAdmin installation
+   against access by robots as they usually can not do anything good
+   there. You can do this using ``robots.txt`` file in root of your
+   webserver or limit access by web server configuration, see
+   :ref:`faq1_42`.
+
+.. index:: 
+    single: Configuration storage
+    single: phpMyAdmin configuration storage
+    single: pmadb
+
+.. _linked-tables:
+
+phpMyAdmin configuration storage
+++++++++++++++++++++++++++++++++
+
+For a whole set of new features (bookmarks, comments, :term:`SQL`-history,
+tracking mechanism, :term:`PDF`-generation, column contents transformation,
+etc.) you need to create a set of special tables.  Those tables can be located
+in your own database, or in a central database for a multi-user installation
+(this database would then be accessed by the controluser, so no other user
+should have rights to it).
+
+Please look at your ``./examples/`` directory, where you should find a
+file called *create\_tables.sql*. (If you are using a Windows server,
+pay special attention to :ref:`faq1_23`).
+
+If you already had this infrastructure and upgraded to MySQL 4.1.2 or
+newer, please use :file:`examples/upgrade_tables_mysql_4_1_2+.sql`
+and then create new tables by importing
+:file:`examples/create_tables.sql`.
+
+You can use your phpMyAdmin to create the tables for you. Please be
+aware that you may need special (administrator) privileges to create
+the database and tables, and that the script may need some tuning,
+depending on the database name.
+
+After having imported the :file:`examples/create_tables.sql` file, you
+should specify the table names in your :file:`config.inc.php` file. The
+directives used for that can be found in the :ref:`config`. You will also need to
+have a controluser with the proper rights to those tables (see section
+:ref:`authentication_modes` below).
+
+.. _upgrading:
+
+Upgrading from an older version
++++++++++++++++++++++++++++++++
+
+Simply copy :file:`config.inc.php` from your previous installation into
+the newly unpacked one. Configuration files from old versions may
+require some tweaking as some options have been changed or removed.
+For compatibility with PHP 6, remove a
+``set_magic_quotes_runtime(0);`` statement that you might find near
+the end of your configuration file.
+
+You should **not** copy :file:`libraries/config.default.php` over
+:file:`config.inc.php` because the default configuration file is version-
+specific.
+
+If you have upgraded your MySQL server from a version previous to 4.1.2 to
+version 5.x or newer and if you use the phpMyAdmin configuration storage, you
+should run the :term:`SQL` script found in
+:file:`examples/upgrade_tables_mysql_4_1_2+.sql`.
+
+.. index:: Authentication mode
+
+.. _authentication_modes:
+
+Using authentication modes
+++++++++++++++++++++++++++
+
+:term:`HTTP` and cookie authentication modes are recommended in a **multi-user
+environment** where you want to give users access to their own database and
+don't want them to play around with others. Nevertheless be aware that MS
+Internet Explorer seems to be really buggy about cookies, at least till version
+6. Even in a **single-user environment**, you might prefer to use :term:`HTTP`
+or cookie mode so that your user/password pair are not in clear in the
+configuration file.
+
+:term:`HTTP` and cookie authentication
+modes are more secure: the MySQL login information does not need to be
+set in the phpMyAdmin configuration file (except possibly for the 
+:config:option:`$cfg['Servers'][$i]['controluser']`).
+However, keep in mind that the password travels in plain text, unless
+you are using the HTTPS protocol. In cookie mode, the password is
+stored, encrypted with the blowfish algorithm, in a temporary cookie.
+
+.. note: 
+   
+    This section is only applicable if your MySQL server is running
+    with ``--skip-show-database``. 
+
+For ':term:`HTTP`' and 'cookie' modes, phpMyAdmin needs a controluser that has
+**only** the ``SELECT`` privilege on the *`mysql`.`user` (all columns except
+`Password`)*, *`mysql`.`db` (all columns)*, *`mysql`.`host` (all columns)* and
+*`mysql`.`tables\_priv` (all columns except `Grantor` and `Timestamp`)* tables.
+You must specify the details for the controluser in the :file:`config.inc.php`
+file under the :config:option:`$cfg['Servers'][$i]['controluser']` and
+:config:option:`$cfg['Servers'][$i]['controlpass']` settings. The following
+example assumes you want to use ``pma`` as the controluser and ``pmapass`` as
+the controlpass, but **this is only an example: use something else in your
+file!** Input these statements from the phpMyAdmin :term:`SQL` Query window or
+mysql command–line client. Of course you have to replace ``localhost`` with the
+webserver's host if it's not the same as the MySQL server's one. 
+
+If you want to use the many new relation and bookmark features:  (this of
+course requires that your :ref:`linked-tables` be set up).
+
+.. code-block:: mysql
+   
+   GRANT USAGE ON mysql.* TO 'pma'@'localhost' IDENTIFIED BY 'pmapass';
+   GRANT SELECT (
+   Host, User, Select_priv, Insert_priv, Update_priv, Delete_priv,
+   Create_priv, Drop_priv, Reload_priv, Shutdown_priv, Process_priv,
+   File_priv, Grant_priv, References_priv, Index_priv, Alter_priv,
+   Show_db_priv, Super_priv, Create_tmp_table_priv, Lock_tables_priv,
+   Execute_priv, Repl_slave_priv, Repl_client_priv
+   ) ON mysql.user TO 'pma'@'localhost';
+   GRANT SELECT ON mysql.db TO 'pma'@'localhost';
+   GRANT SELECT ON mysql.host TO 'pma'@'localhost';
+   GRANT SELECT (Host, Db, User, Table_name, Table_priv, Column_priv)
+   ON mysql.tables_priv TO 'pma'@'localhost';
+   
+If you want to use the many new relation and bookmark features:
+   
+.. code-block:: mysql
+   
+   GRANT SELECT, INSERT, UPDATE, DELETE ON <pma_db>.* TO 'pma'@'localhost';
+   
+(this of course requires that your phpMyAdmin
+configuration storage be set up).
+   
+Then each of the *true* users should be granted a set of privileges
+on a set of particular databases. Normally you shouldn't give global
+privileges to an ordinary user, unless you understand the impact of those
+privileges (for example, you are creating a superuser).
+For example, to grant the user *real_user* with all privileges on
+the database *user_base*:
+   
+.. code-block:: mysql
+   
+   GRANT ALL PRIVILEGES ON user_base.* TO 'real_user'@localhost IDENTIFIED BY 'real_password';
+   
+   
+What the user may now do is controlled entirely by the MySQL user management
+system. With HTTP or cookie authentication mode, you don't need to fill the
+user/password fields inside the :config:option:`$cfg['Servers']`.
+
+.. index:: pair: HTTP; Authentication mode
+
+HTTP authentication mode
+------------------------
+
+* Uses :term:`HTTP` Basic authentication
+  method and allows you to log in as any valid MySQL user.
+* Is supported with most PHP configurations. For :term:`IIS` (:term:`ISAPI`) 
+  support using :term:`CGI` PHP see :ref:`faq1_32`, for using with Apache 
+  :term:`CGI` see :ref:`faq1_35`.
+* See also :ref:`faq4_4` about not using the :term:`.htaccess` mechanism along with
+  ':term:`HTTP`' authentication mode.
+
+.. index:: pair: Cookie; Authentication mode
+
+.. _cookie:
+
+Cookie authentication mode
+--------------------------
+
+* You can use this method as a replacement for the :term:`HTTP` authentication 
+  (for example, if you're running :term:`IIS`).
+* Obviously, the user must enable cookies in the browser, but this is
+  now a requirement for all authentication modes.
+* With this mode, the user can truly log out of phpMyAdmin and log in
+  back with the same username.
+* If you want to log in to arbitrary server see :config:option:`$cfg['AllowArbitraryServer']` directive.
+* As mentioned in the :ref:`require` section, having the ``mcrypt`` extension will
+  speed up access considerably, but is not required.
+
+.. index:: pair: Signon; Authentication mode
+
+Signon authentication mode
+--------------------------
+
+* This mode is a convenient way of using credentials from another
+  application to authenticate to phpMyAdmin.
+* The other application has to store login information into session
+  data.
+
+.. seealso::
+    :config:option:`$cfg['Servers'][$i]['auth_type']`,
+    :config:option:`$cfg['Servers'][$i]['SignonSession']`,
+    :config:option:`$cfg['Servers'][$i]['SignonScript']`,
+    :config:option:`$cfg['Servers'][$i]['SignonURL']`
+
+
+.. index:: pair: Config; Authentication mode
+
+Config authentication mode
+--------------------------
+
+* This mode is the less secure one because it requires you to fill the
+  :config:option:`$cfg['Servers'][$i]['user']` and
+  :config:option:`$cfg['Servers'][$i]['password']`
+  fields (and as a result, anyone who can read your :file:`config.inc.php`
+  can discover your username and password).  But you don't need to setup
+  a "controluser" here: using the :config:option:`$cfg['Servers'][$i]['only_db']` might be enough.
+* In the :ref:`faqmultiuser` section, there is an entry explaining how
+  to protect your configuration file.
+* For additional security in this mode, you may wish to consider the
+  Host authentication :config:option:`$cfg['Servers'][$i]['AllowDeny']['order']`
+  and :config:option:`$cfg['Servers'][$i]['AllowDeny']['rules']` configuration directives.
+* Unlike cookie and http, does not require a user to log in when first
+  loading the phpMyAdmin site. This is by design but could allow any
+  user to access your installation. Use of some restriction method is
+  suggested, perhaps a :term:`.htaccess` file with the HTTP-AUTH directive or disallowing
+  incoming HTTP requests at one’s router or firewall will suffice (both
+  of which are beyond the scope of this manual but easily searchable
+  with Google).
+
+.. index:: pair: Swekey; Authentication mode
+
+.. _swekey:
+
+Swekey authentication mode
+--------------------------
+
+The Swekey is a low cost authentication USB key that can be used in
+web applications. When Swekey authentication is activated, phpMyAdmin
+requires the users's Swekey to be plugged before entering the login
+page (currently supported for cookie authentication mode only). Swekey
+Authentication is disabled by default. To enable it, add the following
+line to :file:`config.inc.php`:
+
+.. code-block:: php
+    
+    $cfg['Servers'][$i]['auth_swekey_config'] = '/etc/swekey.conf';
+
+You then have to create the ``swekey.conf`` file that will associate
+each user with their Swekey Id. It is important to place this file
+outside of your web server's document root (in the example, it is
+located in ``/etc``). A self documented sample file is provided in the
+``examples`` directory. Feel free to use it with your own users'
+information. If you want to purchase a Swekey please visit
+`http://phpmyadmin.net/auth\_key <http://phpmyadmin.net/auth_key>`_
+since this link provides funding for phpMyAdmin.
+
+.. seealso:: :config:option:`$cfg['Servers'][$i]['auth_swekey_config']`
+
+
+Securing your phpMyAdmin installation
++++++++++++++++++++++++++++++++++++++
+
+The phpMyAdmin team tries hardly to make the application secure, however there
+are always ways to make your installation more secure:
+
+* remove ``setup`` directory from phpMyAdmin, you will probably not 
+  use it after initial setup
+* prevent access to ``libraries`` directory from browser, 
+  as it is not needed, supplied ``.htaccess`` file does this
+* properly choose authentication method - :ref:`cookie`
+  is probably the best choice for shared hosting
+* in case you don't want all MySQL users to be able to access 
+  phpMyAdmin, you can use :config:option:`$cfg['Servers'][$i]['AllowDeny']['rules']` to limit them
+* consider hiding phpMyAdmin behind authentication proxy, so that 
+  MySQL credentials are not all users need to login
diff --git a/phpmyadmin/doc/html/_sources/transformations.txt b/phpmyadmin/doc/html/_sources/transformations.txt
new file mode 100644
index 0000000..4c3ce46
--- /dev/null
+++ b/phpmyadmin/doc/html/_sources/transformations.txt
@@ -0,0 +1,138 @@
+.. _transformations:
+
+Transformations
+===============
+
+.. _transformationsintro:
+
+Introduction
+++++++++++++
+
+To enable transformations, you have to setup the ``column_info``
+table and the proper directives. Please see the :ref:`config` on how to do so.
+
+You can apply different transformations to the contents of each
+column. The transformation will take the content of each column and
+transform it with certain rules defined in the selected
+transformation.
+
+Say you have a column 'filename' which contains a filename. Normally
+you would see in phpMyAdmin only this filename. Using transformations
+you can transform that filename into a HTML link, so you can click
+inside of the phpMyAdmin structure on the column's link and will see
+the file displayed in a new browser window. Using transformation
+options you can also specify strings to append/prepend to a string or
+the format you want the output stored in.
+
+For a general overview of all available transformations and their
+options, you can consult your *<www.your-host.com>/<your-install-
+dir>/transformation\_overview.php* installation.
+
+For a tutorial on how to effectively use transformations, see our
+`Link section <http://www.phpmyadmin.net/home_page/docs.php>`_ on the
+official phpMyAdmin homepage.
+
+.. _transformationshowto:
+
+Usage
++++++
+
+Go to your *tbl\_structure.php* page (i.e. reached through clicking on
+the 'Structure' link for a table). There click on "Change" (or change
+icon) and there you will see three new fields at the end of the line.
+They are called 'MIME-type', 'Browser transformation' and
+'Transformation options'.
+
+* The field 'MIME-type' is a drop-down field. Select the MIME-type that
+  corresponds to the column's contents. Please note that transformations
+  are inactive as long as no MIME-type is selected.
+* The field 'Browser transformation' is a drop-down field. You can
+  choose from a hopefully growing amount of pre-defined transformations.
+  See below for information on how to build your own transformation.
+  There are global transformations and mimetype-bound transformations.
+  Global transformations can be used for any mimetype. They will take
+  the mimetype, if necessary, into regard. Mimetype-bound
+  transformations usually only operate on a certain mimetype. There are
+  transformations which operate on the main mimetype (like 'image'),
+  which will most likely take the subtype into regard, and those who
+  only operate on a specific subtype (like 'image/jpeg'). You can use
+  transformations on mimetypes for which the function was not defined
+  for. There is no security check for you selected the right
+  transformation, so take care of what the output will be like.
+* The field 'Transformation options' is a free-type textfield. You have
+  to enter transform-function specific options here. Usually the
+  transforms can operate with default options, but it is generally a
+  good idea to look up the overview to see which options are necessary.
+  Much like the ENUM/SET-Fields, you have to split up several options
+  using the format 'a','b','c',...(NOTE THE MISSING BLANKS). This is
+  because internally the options will be parsed as an array, leaving the
+  first value the first element in the array, and so forth. If you want
+  to specify a MIME character set you can define it in the
+  transformation\_options. You have to put that outside of the pre-
+  defined options of the specific mime-transform, as the last value of
+  the set. Use the format "'; charset=XXX'". If you use a transform, for
+  which you can specify 2 options and you want to append a character
+  set, enter "'first parameter','second parameter','charset=us-ascii'".
+  You can, however use the defaults for the parameters: "'','','charset
+  =us-ascii'".
+
+.. _transformationsfiles:
+
+File structure
+++++++++++++++
+
+All specific transformations for mimetypes are defined through class
+files in the directory 'libraries/plugins/transformations/'. Each of
+them extends a certain transformation abstract class declared in
+libraries/plugins/transformations/abstract.
+
+They are stored in files to ease up customization and easy adding of
+new transformations.
+
+Because the user cannot enter own mimetypes, it is kept sure that
+transformations always work. It makes no sense to apply a
+transformation to a mimetype the transform-function doesn't know to
+handle.
+
+There is a file called '*transformations.lib.php*' that provides some
+basic functions which can be included by any other transform function.
+
+The file name convention is ``[Mimetype]_[Subtype]_[Transformation
+Name].class.php``, while the abtract class that it extends has the
+name ``[Transformation Name]TransformationsPlugin``. All of the
+methods that have to be implemented by a transformations plug-in are:
+
+#. getMIMEType() and getMIMESubtype() in the main class;
+#. getName(), getInfo() and applyTransformation() in the abstract class
+   it extends.
+
+The getMIMEType(), getMIMESubtype() and getName() methods return the
+name of the MIME type, MIME Subtype and transformation accordingly.
+getInfo() returns the transformation's description and possible
+options it may receive and applyTransformation() is the method that
+does the actual work of the transformation plug-in.
+
+Please see the libraries/plugins/transformations/TEMPLATE and
+libraries/plugins/transformations/TEMPLATE\_ABSTRACT files for adding
+your own transformation plug-in. You can also generate a new
+transformation plug-in (with or without the abstract transformation
+class), by using
+:file:`libraries/plugins/transformations/generator_plugin.sh` or
+:file:`libraries/plugins/transformations/generator_main_class.sh`.
+
+The applyTransformation() method always gets passed three variables:
+
+#. **$buffer** - Contains the text inside of the column. This is the
+   text, you want to transform.
+#. **$options** - Contains any user-passed options to a transform
+   function as an array.
+#. **$meta** - Contains an object with information about your column. The
+   data is drawn from the output of the `mysql\_fetch\_field()
+   <http://www.php.net/mysql_fetch_field>`_ function. This means, all
+   object properties described on the `manual page
+   <http://www.php.net/mysql_fetch_field>`_ are available in this
+   variable and can be used to transform a column accordingly to
+   unsigned/zerofill/not\_null/... properties. The $meta->mimetype
+   variable contains the original MIME-type of the column (i.e.
+   'text/plain', 'image/jpeg' etc.)
+
diff --git a/phpmyadmin/doc/html/_sources/user.txt b/phpmyadmin/doc/html/_sources/user.txt
new file mode 100644
index 0000000..ceaf723
--- /dev/null
+++ b/phpmyadmin/doc/html/_sources/user.txt
@@ -0,0 +1,9 @@
+User Guide
+==========
+
+.. toctree::
+    :maxdepth: 2
+
+    transformations
+    privileges
+    other
diff --git a/phpmyadmin/doc/html/_sources/vendors.txt b/phpmyadmin/doc/html/_sources/vendors.txt
new file mode 100644
index 0000000..13d7e55
--- /dev/null
+++ b/phpmyadmin/doc/html/_sources/vendors.txt
@@ -0,0 +1,34 @@
+Distributing and packaging phpMyAdmin
+=====================================
+
+This document is intended to give advices to people who want to
+redistribute phpMyAdmin inside other software package such as Linux
+distribution or some all in one package including web server and MySQL
+server.
+
+Generally you can customize some basic aspects (paths to some files and
+behavior) in :file:`libraries/vendor_config.php`.
+
+For example if you want setup script to generate config file in var, change
+``SETUP_CONFIG_FILE`` to :file:`/var/lib/phpmyadmin/config.inc.php` and you
+will also probably want to skip directory writable check, so set
+``SETUP_DIR_WRITABLE`` to false.
+
+External libraries
+------------------
+
+phpMyAdmin includes several external libraries, you might want to
+replace them with system ones if they are available, but please note
+that you should test whether version you provide is compatible with the
+one we ship.
+
+Currently known list of external libraries:
+
+js/jquery 
+    jQuery js framework and various jQuery based libraries.
+
+libraries/php-gettext 
+    php-gettext library
+libraries/tcpdf 
+    tcpdf library, stripped down of not needed files 
+
diff --git a/phpmyadmin/doc/html/_static/ajax-loader.gif b/phpmyadmin/doc/html/_static/ajax-loader.gif
new file mode 100644
index 0000000..61faf8c
Binary files /dev/null and b/phpmyadmin/doc/html/_static/ajax-loader.gif differ
diff --git a/phpmyadmin/doc/html/_static/basic.css b/phpmyadmin/doc/html/_static/basic.css
new file mode 100644
index 0000000..43e8baf
--- /dev/null
+++ b/phpmyadmin/doc/html/_static/basic.css
@@ -0,0 +1,540 @@
+/*
+ * basic.css
+ * ~~~~~~~~~
+ *
+ * Sphinx stylesheet -- basic theme.
+ *
+ * :copyright: Copyright 2007-2011 by the Sphinx team, see AUTHORS.
+ * :license: BSD, see LICENSE for details.
+ *
+ */
+
+/* -- main layout ----------------------------------------------------------- */
+
+div.clearer {
+    clear: both;
+}
+
+/* -- relbar ---------------------------------------------------------------- */
+
+div.related {
+    width: 100%;
+    font-size: 90%;
+}
+
+div.related h3 {
+    display: none;
+}
+
+div.related ul {
+    margin: 0;
+    padding: 0 0 0 10px;
+    list-style: none;
+}
+
+div.related li {
+    display: inline;
+}
+
+div.related li.right {
+    float: right;
+    margin-right: 5px;
+}
+
+/* -- sidebar --------------------------------------------------------------- */
+
+div.sphinxsidebarwrapper {
+    padding: 10px 5px 0 10px;
+}
+
+div.sphinxsidebar {
+    float: left;
+    width: 230px;
+    margin-left: -100%;
+    font-size: 90%;
+}
+
+div.sphinxsidebar ul {
+    list-style: none;
+}
+
+div.sphinxsidebar ul ul,
+div.sphinxsidebar ul.want-points {
+    margin-left: 20px;
+    list-style: square;
+}
+
+div.sphinxsidebar ul ul {
+    margin-top: 0;
+    margin-bottom: 0;
+}
+
+div.sphinxsidebar form {
+    margin-top: 10px;
+}
+
+div.sphinxsidebar input {
+    border: 1px solid #98dbcc;
+    font-family: sans-serif;
+    font-size: 1em;
+}
+
+div.sphinxsidebar #searchbox input[type="text"] {
+    width: 170px;
+}
+
+div.sphinxsidebar #searchbox input[type="submit"] {
+    width: 30px;
+}
+
+img {
+    border: 0;
+}
+
+/* -- search page ----------------------------------------------------------- */
+
+ul.search {
+    margin: 10px 0 0 20px;
+    padding: 0;
+}
+
+ul.search li {
+    padding: 5px 0 5px 20px;
+    background-image: url(file.png);
+    background-repeat: no-repeat;
+    background-position: 0 7px;
+}
+
+ul.search li a {
+    font-weight: bold;
+}
+
+ul.search li div.context {
+    color: #888;
+    margin: 2px 0 0 30px;
+    text-align: left;
+}
+
+ul.keywordmatches li.goodmatch a {
+    font-weight: bold;
+}
+
+/* -- index page ------------------------------------------------------------ */
+
+table.contentstable {
+    width: 90%;
+}
+
+table.contentstable p.biglink {
+    line-height: 150%;
+}
+
+a.biglink {
+    font-size: 1.3em;
+}
+
+span.linkdescr {
+    font-style: italic;
+    padding-top: 5px;
+    font-size: 90%;
+}
+
+/* -- general index --------------------------------------------------------- */
+
+table.indextable {
+    width: 100%;
+}
+
+table.indextable td {
+    text-align: left;
+    vertical-align: top;
+}
+
+table.indextable dl, table.indextable dd {
+    margin-top: 0;
+    margin-bottom: 0;
+}
+
+table.indextable tr.pcap {
+    height: 10px;
+}
+
+table.indextable tr.cap {
+    margin-top: 10px;
+    background-color: #f2f2f2;
+}
+
+img.toggler {
+    margin-right: 3px;
+    margin-top: 3px;
+    cursor: pointer;
+}
+
+div.modindex-jumpbox {
+    border-top: 1px solid #ddd;
+    border-bottom: 1px solid #ddd;
+    margin: 1em 0 1em 0;
+    padding: 0.4em;
+}
+
+div.genindex-jumpbox {
+    border-top: 1px solid #ddd;
+    border-bottom: 1px solid #ddd;
+    margin: 1em 0 1em 0;
+    padding: 0.4em;
+}
+
+/* -- general body styles --------------------------------------------------- */
+
+a.headerlink {
+    visibility: hidden;
+}
+
+h1:hover > a.headerlink,
+h2:hover > a.headerlink,
+h3:hover > a.headerlink,
+h4:hover > a.headerlink,
+h5:hover > a.headerlink,
+h6:hover > a.headerlink,
+dt:hover > a.headerlink {
+    visibility: visible;
+}
+
+div.body p.caption {
+    text-align: inherit;
+}
+
+div.body td {
+    text-align: left;
+}
+
+.field-list ul {
+    padding-left: 1em;
+}
+
+.first {
+    margin-top: 0 !important;
+}
+
+p.rubric {
+    margin-top: 30px;
+    font-weight: bold;
+}
+
+img.align-left, .figure.align-left, object.align-left {
+    clear: left;
+    float: left;
+    margin-right: 1em;
+}
+
+img.align-right, .figure.align-right, object.align-right {
+    clear: right;
+    float: right;
+    margin-left: 1em;
+}
+
+img.align-center, .figure.align-center, object.align-center {
+  display: block;
+  margin-left: auto;
+  margin-right: auto;
+}
+
+.align-left {
+    text-align: left;
+}
+
+.align-center {
+    text-align: center;
+}
+
+.align-right {
+    text-align: right;
+}
+
+/* -- sidebars -------------------------------------------------------------- */
+
+div.sidebar {
+    margin: 0 0 0.5em 1em;
+    border: 1px solid #ddb;
+    padding: 7px 7px 0 7px;
+    background-color: #ffe;
+    width: 40%;
+    float: right;
+}
+
+p.sidebar-title {
+    font-weight: bold;
+}
+
+/* -- topics ---------------------------------------------------------------- */
+
+div.topic {
+    border: 1px solid #ccc;
+    padding: 7px 7px 0 7px;
+    margin: 10px 0 10px 0;
+}
+
+p.topic-title {
+    font-size: 1.1em;
+    font-weight: bold;
+    margin-top: 10px;
+}
+
+/* -- admonitions ----------------------------------------------------------- */
+
+div.admonition {
+    margin-top: 10px;
+    margin-bottom: 10px;
+    padding: 7px;
+}
+
+div.admonition dt {
+    font-weight: bold;
+}
+
+div.admonition dl {
+    margin-bottom: 0;
+}
+
+p.admonition-title {
+    margin: 0px 10px 5px 0px;
+    font-weight: bold;
+}
+
+div.body p.centered {
+    text-align: center;
+    margin-top: 25px;
+}
+
+/* -- tables ---------------------------------------------------------------- */
+
+table.docutils {
+    border: 0;
+    border-collapse: collapse;
+}
+
+table.docutils td, table.docutils th {
+    padding: 1px 8px 1px 5px;
+    border-top: 0;
+    border-left: 0;
+    border-right: 0;
+    border-bottom: 1px solid #aaa;
+}
+
+table.field-list td, table.field-list th {
+    border: 0 !important;
+}
+
+table.footnote td, table.footnote th {
+    border: 0 !important;
+}
+
+th {
+    text-align: left;
+    padding-right: 5px;
+}
+
+table.citation {
+    border-left: solid 1px gray;
+    margin-left: 1px;
+}
+
+table.citation td {
+    border-bottom: none;
+}
+
+/* -- other body styles ----------------------------------------------------- */
+
+ol.arabic {
+    list-style: decimal;
+}
+
+ol.loweralpha {
+    list-style: lower-alpha;
+}
+
+ol.upperalpha {
+    list-style: upper-alpha;
+}
+
+ol.lowerroman {
+    list-style: lower-roman;
+}
+
+ol.upperroman {
+    list-style: upper-roman;
+}
+
+dl {
+    margin-bottom: 15px;
+}
+
+dd p {
+    margin-top: 0px;
+}
+
+dd ul, dd table {
+    margin-bottom: 10px;
+}
+
+dd {
+    margin-top: 3px;
+    margin-bottom: 10px;
+    margin-left: 30px;
+}
+
+dt:target, .highlighted {
+    background-color: #fbe54e;
+}
+
+dl.glossary dt {
+    font-weight: bold;
+    font-size: 1.1em;
+}
+
+.field-list ul {
+    margin: 0;
+    padding-left: 1em;
+}
+
+.field-list p {
+    margin: 0;
+}
+
+.refcount {
+    color: #060;
+}
+
+.optional {
+    font-size: 1.3em;
+}
+
+.versionmodified {
+    font-style: italic;
+}
+
+.system-message {
+    background-color: #fda;
+    padding: 5px;
+    border: 3px solid red;
+}
+
+.footnote:target  {
+    background-color: #ffa;
+}
+
+.line-block {
+    display: block;
+    margin-top: 1em;
+    margin-bottom: 1em;
+}
+
+.line-block .line-block {
+    margin-top: 0;
+    margin-bottom: 0;
+    margin-left: 1.5em;
+}
+
+.guilabel, .menuselection {
+    font-family: sans-serif;
+}
+
+.accelerator {
+    text-decoration: underline;
+}
+
+.classifier {
+    font-style: oblique;
+}
+
+abbr, acronym {
+    border-bottom: dotted 1px;
+    cursor: help;
+}
+
+/* -- code displays --------------------------------------------------------- */
+
+pre {
+    overflow: auto;
+    overflow-y: hidden;  /* fixes display issues on Chrome browsers */
+}
+
+td.linenos pre {
+    padding: 5px 0px;
+    border: 0;
+    background-color: transparent;
+    color: #aaa;
+}
+
+table.highlighttable {
+    margin-left: 0.5em;
+}
+
+table.highlighttable td {
+    padding: 0 0.5em 0 0.5em;
+}
+
+tt.descname {
+    background-color: transparent;
+    font-weight: bold;
+    font-size: 1.2em;
+}
+
+tt.descclassname {
+    background-color: transparent;
+}
+
+tt.xref, a tt {
+    background-color: transparent;
+    font-weight: bold;
+}
+
+h1 tt, h2 tt, h3 tt, h4 tt, h5 tt, h6 tt {
+    background-color: transparent;
+}
+
+.viewcode-link {
+    float: right;
+}
+
+.viewcode-back {
+    float: right;
+    font-family: sans-serif;
+}
+
+div.viewcode-block:target {
+    margin: -1px -10px;
+    padding: 0 10px;
+}
+
+/* -- math display ---------------------------------------------------------- */
+
+img.math {
+    vertical-align: middle;
+}
+
+div.body div.math p {
+    text-align: center;
+}
+
+span.eqno {
+    float: right;
+}
+
+/* -- printout stylesheet --------------------------------------------------- */
+
+ at media print {
+    div.document,
+    div.documentwrapper,
+    div.bodywrapper {
+        margin: 0 !important;
+        width: 100%;
+    }
+
+    div.sphinxsidebar,
+    div.related,
+    div.footer,
+    #top-link {
+        display: none;
+    }
+}
\ No newline at end of file
diff --git a/phpmyadmin/doc/html/_static/comment-bright.png b/phpmyadmin/doc/html/_static/comment-bright.png
new file mode 100644
index 0000000..551517b
Binary files /dev/null and b/phpmyadmin/doc/html/_static/comment-bright.png differ
diff --git a/phpmyadmin/doc/html/_static/comment-close.png b/phpmyadmin/doc/html/_static/comment-close.png
new file mode 100644
index 0000000..09b54be
Binary files /dev/null and b/phpmyadmin/doc/html/_static/comment-close.png differ
diff --git a/phpmyadmin/doc/html/_static/comment.png b/phpmyadmin/doc/html/_static/comment.png
new file mode 100644
index 0000000..92feb52
Binary files /dev/null and b/phpmyadmin/doc/html/_static/comment.png differ
diff --git a/phpmyadmin/doc/html/_static/default.css b/phpmyadmin/doc/html/_static/default.css
new file mode 100644
index 0000000..21f3f50
--- /dev/null
+++ b/phpmyadmin/doc/html/_static/default.css
@@ -0,0 +1,256 @@
+/*
+ * default.css_t
+ * ~~~~~~~~~~~~~
+ *
+ * Sphinx stylesheet -- default theme.
+ *
+ * :copyright: Copyright 2007-2011 by the Sphinx team, see AUTHORS.
+ * :license: BSD, see LICENSE for details.
+ *
+ */
+
+ at import url("basic.css");
+
+/* -- page layout ----------------------------------------------------------- */
+
+body {
+    font-family: sans-serif;
+    font-size: 100%;
+    background-color: #11303d;
+    color: #000;
+    margin: 0;
+    padding: 0;
+}
+
+div.document {
+    background-color: #1c4e63;
+}
+
+div.documentwrapper {
+    float: left;
+    width: 100%;
+}
+
+div.bodywrapper {
+    margin: 0 0 0 230px;
+}
+
+div.body {
+    background-color: #ffffff;
+    color: #000000;
+    padding: 0 20px 30px 20px;
+}
+
+div.footer {
+    color: #ffffff;
+    width: 100%;
+    padding: 9px 0 9px 0;
+    text-align: center;
+    font-size: 75%;
+}
+
+div.footer a {
+    color: #ffffff;
+    text-decoration: underline;
+}
+
+div.related {
+    background-color: #133f52;
+    line-height: 30px;
+    color: #ffffff;
+}
+
+div.related a {
+    color: #ffffff;
+}
+
+div.sphinxsidebar {
+}
+
+div.sphinxsidebar h3 {
+    font-family: 'Trebuchet MS', sans-serif;
+    color: #ffffff;
+    font-size: 1.4em;
+    font-weight: normal;
+    margin: 0;
+    padding: 0;
+}
+
+div.sphinxsidebar h3 a {
+    color: #ffffff;
+}
+
+div.sphinxsidebar h4 {
+    font-family: 'Trebuchet MS', sans-serif;
+    color: #ffffff;
+    font-size: 1.3em;
+    font-weight: normal;
+    margin: 5px 0 0 0;
+    padding: 0;
+}
+
+div.sphinxsidebar p {
+    color: #ffffff;
+}
+
+div.sphinxsidebar p.topless {
+    margin: 5px 10px 10px 10px;
+}
+
+div.sphinxsidebar ul {
+    margin: 10px;
+    padding: 0;
+    color: #ffffff;
+}
+
+div.sphinxsidebar a {
+    color: #98dbcc;
+}
+
+div.sphinxsidebar input {
+    border: 1px solid #98dbcc;
+    font-family: sans-serif;
+    font-size: 1em;
+}
+
+
+
+/* -- hyperlink styles ------------------------------------------------------ */
+
+a {
+    color: #355f7c;
+    text-decoration: none;
+}
+
+a:visited {
+    color: #355f7c;
+    text-decoration: none;
+}
+
+a:hover {
+    text-decoration: underline;
+}
+
+
+
+/* -- body styles ----------------------------------------------------------- */
+
+div.body h1,
+div.body h2,
+div.body h3,
+div.body h4,
+div.body h5,
+div.body h6 {
+    font-family: 'Trebuchet MS', sans-serif;
+    background-color: #f2f2f2;
+    font-weight: normal;
+    color: #20435c;
+    border-bottom: 1px solid #ccc;
+    margin: 20px -20px 10px -20px;
+    padding: 3px 0 3px 10px;
+}
+
+div.body h1 { margin-top: 0; font-size: 200%; }
+div.body h2 { font-size: 160%; }
+div.body h3 { font-size: 140%; }
+div.body h4 { font-size: 120%; }
+div.body h5 { font-size: 110%; }
+div.body h6 { font-size: 100%; }
+
+a.headerlink {
+    color: #c60f0f;
+    font-size: 0.8em;
+    padding: 0 4px 0 4px;
+    text-decoration: none;
+}
+
+a.headerlink:hover {
+    background-color: #c60f0f;
+    color: white;
+}
+
+div.body p, div.body dd, div.body li {
+    text-align: justify;
+    line-height: 130%;
+}
+
+div.admonition p.admonition-title + p {
+    display: inline;
+}
+
+div.admonition p {
+    margin-bottom: 5px;
+}
+
+div.admonition pre {
+    margin-bottom: 5px;
+}
+
+div.admonition ul, div.admonition ol {
+    margin-bottom: 5px;
+}
+
+div.note {
+    background-color: #eee;
+    border: 1px solid #ccc;
+}
+
+div.seealso {
+    background-color: #ffc;
+    border: 1px solid #ff6;
+}
+
+div.topic {
+    background-color: #eee;
+}
+
+div.warning {
+    background-color: #ffe4e4;
+    border: 1px solid #f66;
+}
+
+p.admonition-title {
+    display: inline;
+}
+
+p.admonition-title:after {
+    content: ":";
+}
+
+pre {
+    padding: 5px;
+    background-color: #eeffcc;
+    color: #333333;
+    line-height: 120%;
+    border: 1px solid #ac9;
+    border-left: none;
+    border-right: none;
+}
+
+tt {
+    background-color: #ecf0f3;
+    padding: 0 1px 0 1px;
+    font-size: 0.95em;
+}
+
+th {
+    background-color: #ede;
+}
+
+.warning tt {
+    background: #efc2c2;
+}
+
+.note tt {
+    background: #d6d6d6;
+}
+
+.viewcode-back {
+    font-family: sans-serif;
+}
+
+div.viewcode-block:target {
+    background-color: #f4debf;
+    border-top: 1px solid #ac9;
+    border-bottom: 1px solid #ac9;
+}
\ No newline at end of file
diff --git a/phpmyadmin/doc/html/_static/doctools.js b/phpmyadmin/doc/html/_static/doctools.js
new file mode 100644
index 0000000..d4619fd
--- /dev/null
+++ b/phpmyadmin/doc/html/_static/doctools.js
@@ -0,0 +1,247 @@
+/*
+ * doctools.js
+ * ~~~~~~~~~~~
+ *
+ * Sphinx JavaScript utilities for all documentation.
+ *
+ * :copyright: Copyright 2007-2011 by the Sphinx team, see AUTHORS.
+ * :license: BSD, see LICENSE for details.
+ *
+ */
+
+/**
+ * select a different prefix for underscore
+ */
+$u = _.noConflict();
+
+/**
+ * make the code below compatible with browsers without
+ * an installed firebug like debugger
+if (!window.console || !console.firebug) {
+  var names = ["log", "debug", "info", "warn", "error", "assert", "dir",
+    "dirxml", "group", "groupEnd", "time", "timeEnd", "count", "trace",
+    "profile", "profileEnd"];
+  window.console = {};
+  for (var i = 0; i < names.length; ++i)
+    window.console[names[i]] = function() {};
+}
+ */
+
+/**
+ * small helper function to urldecode strings
+ */
+jQuery.urldecode = function(x) {
+  return decodeURIComponent(x).replace(/\+/g, ' ');
+}
+
+/**
+ * small helper function to urlencode strings
+ */
+jQuery.urlencode = encodeURIComponent;
+
+/**
+ * This function returns the parsed url parameters of the
+ * current request. Multiple values per key are supported,
+ * it will always return arrays of strings for the value parts.
+ */
+jQuery.getQueryParameters = function(s) {
+  if (typeof s == 'undefined')
+    s = document.location.search;
+  var parts = s.substr(s.indexOf('?') + 1).split('&');
+  var result = {};
+  for (var i = 0; i < parts.length; i++) {
+    var tmp = parts[i].split('=', 2);
+    var key = jQuery.urldecode(tmp[0]);
+    var value = jQuery.urldecode(tmp[1]);
+    if (key in result)
+      result[key].push(value);
+    else
+      result[key] = [value];
+  }
+  return result;
+};
+
+/**
+ * small function to check if an array contains
+ * a given item.
+ */
+jQuery.contains = function(arr, item) {
+  for (var i = 0; i < arr.length; i++) {
+    if (arr[i] == item)
+      return true;
+  }
+  return false;
+};
+
+/**
+ * highlight a given string on a jquery object by wrapping it in
+ * span elements with the given class name.
+ */
+jQuery.fn.highlightText = function(text, className) {
+  function highlight(node) {
+    if (node.nodeType == 3) {
+      var val = node.nodeValue;
+      var pos = val.toLowerCase().indexOf(text);
+      if (pos >= 0 && !jQuery(node.parentNode).hasClass(className)) {
+        var span = document.createElement("span");
+        span.className = className;
+        span.appendChild(document.createTextNode(val.substr(pos, text.length)));
+        node.parentNode.insertBefore(span, node.parentNode.insertBefore(
+          document.createTextNode(val.substr(pos + text.length)),
+          node.nextSibling));
+        node.nodeValue = val.substr(0, pos);
+      }
+    }
+    else if (!jQuery(node).is("button, select, textarea")) {
+      jQuery.each(node.childNodes, function() {
+        highlight(this);
+      });
+    }
+  }
+  return this.each(function() {
+    highlight(this);
+  });
+};
+
+/**
+ * Small JavaScript module for the documentation.
+ */
+var Documentation = {
+
+  init : function() {
+    this.fixFirefoxAnchorBug();
+    this.highlightSearchWords();
+    this.initIndexTable();
+  },
+
+  /**
+   * i18n support
+   */
+  TRANSLATIONS : {},
+  PLURAL_EXPR : function(n) { return n == 1 ? 0 : 1; },
+  LOCALE : 'unknown',
+
+  // gettext and ngettext don't access this so that the functions
+  // can safely bound to a different name (_ = Documentation.gettext)
+  gettext : function(string) {
+    var translated = Documentation.TRANSLATIONS[string];
+    if (typeof translated == 'undefined')
+      return string;
+    return (typeof translated == 'string') ? translated : translated[0];
+  },
+
+  ngettext : function(singular, plural, n) {
+    var translated = Documentation.TRANSLATIONS[singular];
+    if (typeof translated == 'undefined')
+      return (n == 1) ? singular : plural;
+    return translated[Documentation.PLURALEXPR(n)];
+  },
+
+  addTranslations : function(catalog) {
+    for (var key in catalog.messages)
+      this.TRANSLATIONS[key] = catalog.messages[key];
+    this.PLURAL_EXPR = new Function('n', 'return +(' + catalog.plural_expr + ')');
+    this.LOCALE = catalog.locale;
+  },
+
+  /**
+   * add context elements like header anchor links
+   */
+  addContextElements : function() {
+    $('div[id] > :header:first').each(function() {
+      $('<a class="headerlink">\u00B6</a>').
+      attr('href', '#' + this.id).
+      attr('title', _('Permalink to this headline')).
+      appendTo(this);
+    });
+    $('dt[id]').each(function() {
+      $('<a class="headerlink">\u00B6</a>').
+      attr('href', '#' + this.id).
+      attr('title', _('Permalink to this definition')).
+      appendTo(this);
+    });
+  },
+
+  /**
+   * workaround a firefox stupidity
+   */
+  fixFirefoxAnchorBug : function() {
+    if (document.location.hash && $.browser.mozilla)
+      window.setTimeout(function() {
+        document.location.href += '';
+      }, 10);
+  },
+
+  /**
+   * highlight the search words provided in the url in the text
+   */
+  highlightSearchWords : function() {
+    var params = $.getQueryParameters();
+    var terms = (params.highlight) ? params.highlight[0].split(/\s+/) : [];
+    if (terms.length) {
+      var body = $('div.body');
+      window.setTimeout(function() {
+        $.each(terms, function() {
+          body.highlightText(this.toLowerCase(), 'highlighted');
+        });
+      }, 10);
+      $('<p class="highlight-link"><a href="javascript:Documentation.' +
+        'hideSearchWords()">' + _('Hide Search Matches') + '</a></p>')
+          .appendTo($('#searchbox'));
+    }
+  },
+
+  /**
+   * init the domain index toggle buttons
+   */
+  initIndexTable : function() {
+    var togglers = $('img.toggler').click(function() {
+      var src = $(this).attr('src');
+      var idnum = $(this).attr('id').substr(7);
+      $('tr.cg-' + idnum).toggle();
+      if (src.substr(-9) == 'minus.png')
+        $(this).attr('src', src.substr(0, src.length-9) + 'plus.png');
+      else
+        $(this).attr('src', src.substr(0, src.length-8) + 'minus.png');
+    }).css('display', '');
+    if (DOCUMENTATION_OPTIONS.COLLAPSE_INDEX) {
+        togglers.click();
+    }
+  },
+
+  /**
+   * helper function to hide the search marks again
+   */
+  hideSearchWords : function() {
+    $('#searchbox .highlight-link').fadeOut(300);
+    $('span.highlighted').removeClass('highlighted');
+  },
+
+  /**
+   * make the url absolute
+   */
+  makeURL : function(relativeURL) {
+    return DOCUMENTATION_OPTIONS.URL_ROOT + '/' + relativeURL;
+  },
+
+  /**
+   * get the current relative url
+   */
+  getCurrentURL : function() {
+    var path = document.location.pathname;
+    var parts = path.split(/\//);
+    $.each(DOCUMENTATION_OPTIONS.URL_ROOT.split(/\//), function() {
+      if (this == '..')
+        parts.pop();
+    });
+    var url = parts.join('/');
+    return path.substring(url.lastIndexOf('/') + 1, path.length - 1);
+  }
+};
+
+// quick alias for translations
+_ = Documentation.gettext;
+
+$(document).ready(function() {
+  Documentation.init();
+});
diff --git a/phpmyadmin/doc/html/_static/down-pressed.png b/phpmyadmin/doc/html/_static/down-pressed.png
new file mode 100644
index 0000000..6f7ad78
Binary files /dev/null and b/phpmyadmin/doc/html/_static/down-pressed.png differ
diff --git a/phpmyadmin/doc/html/_static/down.png b/phpmyadmin/doc/html/_static/down.png
new file mode 100644
index 0000000..3003a88
Binary files /dev/null and b/phpmyadmin/doc/html/_static/down.png differ
diff --git a/phpmyadmin/doc/html/_static/file.png b/phpmyadmin/doc/html/_static/file.png
new file mode 100644
index 0000000..d18082e
Binary files /dev/null and b/phpmyadmin/doc/html/_static/file.png differ
diff --git a/phpmyadmin/doc/html/_static/jquery.js b/phpmyadmin/doc/html/_static/jquery.js
new file mode 100644
index 0000000..7c24308
--- /dev/null
+++ b/phpmyadmin/doc/html/_static/jquery.js
@@ -0,0 +1,154 @@
+/*!
+ * jQuery JavaScript Library v1.4.2
+ * http://jquery.com/
+ *
+ * Copyright 2010, John Resig
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
+ *
+ * Includes Sizzle.js
+ * http://sizzlejs.com/
+ * Copyright 2010, The Dojo Foundation
+ * Released under the MIT, BSD, and GPL Licenses.
+ *
+ * Date: Sat Feb 13 22:33:48 2010 -0500
+ */
+(function(A,w){function ma(){if(!c.isReady){try{s.documentElement.doScroll("left")}catch(a){setTimeout(ma,1);return}c.ready()}}function Qa(a,b){b.src?c.ajax({url:b.src,async:false,dataType:"script"}):c.globalEval(b.text||b.textContent||b.innerHTML||"");b.parentNode&&b.parentNode.removeChild(b)}function X(a,b,d,f,e,j){var i=a.length;if(typeof b==="object"){for(var o in b)X(a,o,b[o],f,e,d);return a}if(d!==w){f=!j&&f&&c.isFunction(d);for(o=0;o<i;o++)e(a[o],b,f?d.call(a[o],o,e(a[o],b)):d,j); [...]
+e(a[0],b):w}function J(){return(new Date).getTime()}function Y(){return false}function Z(){return true}function na(a,b,d){d[0].type=a;return c.event.handle.apply(b,d)}function oa(a){var b,d=[],f=[],e=arguments,j,i,o,k,n,r;i=c.data(this,"events");if(!(a.liveFired===this||!i||!i.live||a.button&&a.type==="click")){a.liveFired=this;var u=i.live.slice(0);for(k=0;k<u.length;k++){i=u[k];i.origType.replace(O,"")===a.type?f.push(i.selector):u.splice(k--,1)}j=c(a.target).closest(f,a.currentTarget) [...]
+j.length;n<r;n++)for(k=0;k<u.length;k++){i=u[k];if(j[n].selector===i.selector){o=j[n].elem;f=null;if(i.preType==="mouseenter"||i.preType==="mouseleave")f=c(a.relatedTarget).closest(i.selector)[0];if(!f||f!==o)d.push({elem:o,handleObj:i})}}n=0;for(r=d.length;n<r;n++){j=d[n];a.currentTarget=j.elem;a.data=j.handleObj.data;a.handleObj=j.handleObj;if(j.handleObj.origHandler.apply(j.elem,e)===false){b=false;break}}return b}}function pa(a,b){return"live."+(a&&a!=="*"?a+".":"")+b.replace(/\./g," [...]
+"&")}function qa(a){return!a||!a.parentNode||a.parentNode.nodeType===11}function ra(a,b){var d=0;b.each(function(){if(this.nodeName===(a[d]&&a[d].nodeName)){var f=c.data(a[d++]),e=c.data(this,f);if(f=f&&f.events){delete e.handle;e.events={};for(var j in f)for(var i in f[j])c.event.add(this,j,f[j][i],f[j][i].data)}}})}function sa(a,b,d){var f,e,j;b=b&&b[0]?b[0].ownerDocument||b[0]:s;if(a.length===1&&typeof a[0]==="string"&&a[0].length<512&&b===s&&!ta.test(a[0])&&(c.support.checkClone||!ua [...]
+true;if(j=c.fragments[a[0]])if(j!==1)f=j}if(!f){f=b.createDocumentFragment();c.clean(a,b,f,d)}if(e)c.fragments[a[0]]=j?f:1;return{fragment:f,cacheable:e}}function K(a,b){var d={};c.each(va.concat.apply([],va.slice(0,b)),function(){d[this]=a});return d}function wa(a){return"scrollTo"in a&&a.document?a:a.nodeType===9?a.defaultView||a.parentWindow:false}var c=function(a,b){return new c.fn.init(a,b)},Ra=A.jQuery,Sa=A.$,s=A.document,T,Ta=/^[^<]*(<[\w\W]+>)[^>]*$|^#([\w-]+)$/,Ua=/^.[^:#\[\.,]* [...]
+Wa=/^(\s|\u00A0)+|(\s|\u00A0)+$/g,Xa=/^<(\w+)\s*\/?>(?:<\/\1>)?$/,P=navigator.userAgent,xa=false,Q=[],L,$=Object.prototype.toString,aa=Object.prototype.hasOwnProperty,ba=Array.prototype.push,R=Array.prototype.slice,ya=Array.prototype.indexOf;c.fn=c.prototype={init:function(a,b){var d,f;if(!a)return this;if(a.nodeType){this.context=this[0]=a;this.length=1;return this}if(a==="body"&&!b){this.context=s;this[0]=s.body;this.selector="body";this.length=1;return this}if(typeof a==="string")if(( [...]
+(d[1]||!b))if(d[1]){f=b?b.ownerDocument||b:s;if(a=Xa.exec(a))if(c.isPlainObject(b)){a=[s.createElement(a[1])];c.fn.attr.call(a,b,true)}else a=[f.createElement(a[1])];else{a=sa([d[1]],[f]);a=(a.cacheable?a.fragment.cloneNode(true):a.fragment).childNodes}return c.merge(this,a)}else{if(b=s.getElementById(d[2])){if(b.id!==d[2])return T.find(a);this.length=1;this[0]=b}this.context=s;this.selector=a;return this}else if(!b&&/^\w+$/.test(a)){this.selector=a;this.context=s;a=s.getElementsByTagNam [...]
+a)}else return!b||b.jquery?(b||T).find(a):c(b).find(a);else if(c.isFunction(a))return T.ready(a);if(a.selector!==w){this.selector=a.selector;this.context=a.context}return c.makeArray(a,this)},selector:"",jquery:"1.4.2",length:0,size:function(){return this.length},toArray:function(){return R.call(this,0)},get:function(a){return a==null?this.toArray():a<0?this.slice(a)[0]:this[a]},pushStack:function(a,b,d){var f=c();c.isArray(a)?ba.apply(f,a):c.merge(f,a);f.prevObject=this;f.context=this.c [...]
+"find")f.selector=this.selector+(this.selector?" ":"")+d;else if(b)f.selector=this.selector+"."+b+"("+d+")";return f},each:function(a,b){return c.each(this,a,b)},ready:function(a){c.bindReady();if(c.isReady)a.call(s,c);else Q&&Q.push(a);return this},eq:function(a){return a===-1?this.slice(a):this.slice(a,+a+1)},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},slice:function(){return this.pushStack(R.apply(this,arguments),"slice",R.call(arguments).join(","))},map:fu [...]
+function(b,d){return a.call(b,d,b)}))},end:function(){return this.prevObject||c(null)},push:ba,sort:[].sort,splice:[].splice};c.fn.init.prototype=c.fn;c.extend=c.fn.extend=function(){var a=arguments[0]||{},b=1,d=arguments.length,f=false,e,j,i,o;if(typeof a==="boolean"){f=a;a=arguments[1]||{};b=2}if(typeof a!=="object"&&!c.isFunction(a))a={};if(d===b){a=this;--b}for(;b<d;b++)if((e=arguments[b])!=null)for(j in e){i=a[j];o=e[j];if(a!==o)if(f&&o&&(c.isPlainObject(o)||c.isArray(o))){i=i&&(c.i [...]
+c.isArray(i))?i:c.isArray(o)?[]:{};a[j]=c.extend(f,i,o)}else if(o!==w)a[j]=o}return a};c.extend({noConflict:function(a){A.$=Sa;if(a)A.jQuery=Ra;return c},isReady:false,ready:function(){if(!c.isReady){if(!s.body)return setTimeout(c.ready,13);c.isReady=true;if(Q){for(var a,b=0;a=Q[b++];)a.call(s,c);Q=null}c.fn.triggerHandler&&c(s).triggerHandler("ready")}},bindReady:function(){if(!xa){xa=true;if(s.readyState==="complete")return c.ready();if(s.addEventListener){s.addEventListener("DOMConten [...]
+L,false);A.addEventListener("load",c.ready,false)}else if(s.attachEvent){s.attachEvent("onreadystatechange",L);A.attachEvent("onload",c.ready);var a=false;try{a=A.frameElement==null}catch(b){}s.documentElement.doScroll&&a&&ma()}}},isFunction:function(a){return $.call(a)==="[object Function]"},isArray:function(a){return $.call(a)==="[object Array]"},isPlainObject:function(a){if(!a||$.call(a)!=="[object Object]"||a.nodeType||a.setInterval)return false;if(a.constructor&&!aa.call(a,"construc [...]
+"isPrototypeOf"))return false;var b;for(b in a);return b===w||aa.call(a,b)},isEmptyObject:function(a){for(var b in a)return false;return true},error:function(a){throw a;},parseJSON:function(a){if(typeof a!=="string"||!a)return null;a=c.trim(a);if(/^[\],:{}\s]*$/.test(a.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g,"@").replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,"]").replace(/(?:^|:|,)(?:\s*\[)+/g,"")))return A.JSON&&A.JSON.parse?A.JSON.parse(a):(new Functi [...]
+a))();else c.error("Invalid JSON: "+a)},noop:function(){},globalEval:function(a){if(a&&Va.test(a)){var b=s.getElementsByTagName("head")[0]||s.documentElement,d=s.createElement("script");d.type="text/javascript";if(c.support.scriptEval)d.appendChild(s.createTextNode(a));else d.text=a;b.insertBefore(d,b.firstChild);b.removeChild(d)}},nodeName:function(a,b){return a.nodeName&&a.nodeName.toUpperCase()===b.toUpperCase()},each:function(a,b,d){var f,e=0,j=a.length,i=j===w||c.isFunction(a);if(d) [...]
+d)===false)break}else for(;e<j;){if(b.apply(a[e++],d)===false)break}else if(i)for(f in a){if(b.call(a[f],f,a[f])===false)break}else for(d=a[0];e<j&&b.call(d,e,d)!==false;d=a[++e]);return a},trim:function(a){return(a||"").replace(Wa,"")},makeArray:function(a,b){b=b||[];if(a!=null)a.length==null||typeof a==="string"||c.isFunction(a)||typeof a!=="function"&&a.setInterval?ba.call(b,a):c.merge(b,a);return b},inArray:function(a,b){if(b.indexOf)return b.indexOf(a);for(var d=0,f=b.length;d<f;d++ [...]
+a)return d;return-1},merge:function(a,b){var d=a.length,f=0;if(typeof b.length==="number")for(var e=b.length;f<e;f++)a[d++]=b[f];else for(;b[f]!==w;)a[d++]=b[f++];a.length=d;return a},grep:function(a,b,d){for(var f=[],e=0,j=a.length;e<j;e++)!d!==!b(a[e],e)&&f.push(a[e]);return f},map:function(a,b,d){for(var f=[],e,j=0,i=a.length;j<i;j++){e=b(a[j],j,d);if(e!=null)f[f.length]=e}return f.concat.apply([],f)},guid:1,proxy:function(a,b,d){if(arguments.length===2)if(typeof b==="string"){d=a;a=d [...]
+!c.isFunction(b)){d=b;b=w}if(!b&&a)b=function(){return a.apply(d||this,arguments)};if(a)b.guid=a.guid=a.guid||b.guid||c.guid++;return b},uaMatch:function(a){a=a.toLowerCase();a=/(webkit)[ \/]([\w.]+)/.exec(a)||/(opera)(?:.*version)?[ \/]([\w.]+)/.exec(a)||/(msie) ([\w.]+)/.exec(a)||!/compatible/.test(a)&&/(mozilla)(?:.*? rv:([\w.]+))?/.exec(a)||[];return{browser:a[1]||"",version:a[2]||"0"}},browser:{}});P=c.uaMatch(P);if(P.browser){c.browser[P.browser]=true;c.browser.version=P.version}if [...]
+true;if(ya)c.inArray=function(a,b){return ya.call(b,a)};T=c(s);if(s.addEventListener)L=function(){s.removeEventListener("DOMContentLoaded",L,false);c.ready()};else if(s.attachEvent)L=function(){if(s.readyState==="complete"){s.detachEvent("onreadystatechange",L);c.ready()}};(function(){c.support={};var a=s.documentElement,b=s.createElement("script"),d=s.createElement("div"),f="script"+J();d.style.display="none";d.innerHTML="   <link/><table></table><a href='/a' style='color:red;float:left [...]
+var e=d.getElementsByTagName("*"),j=d.getElementsByTagName("a")[0];if(!(!e||!e.length||!j)){c.support={leadingWhitespace:d.firstChild.nodeType===3,tbody:!d.getElementsByTagName("tbody").length,htmlSerialize:!!d.getElementsByTagName("link").length,style:/red/.test(j.getAttribute("style")),hrefNormalized:j.getAttribute("href")==="/a",opacity:/^0.55$/.test(j.style.opacity),cssFloat:!!j.style.cssFloat,checkOn:d.getElementsByTagName("input")[0].value==="on",optSelected:s.createElement("select [...]
+parentNode:d.removeChild(d.appendChild(s.createElement("div"))).parentNode===null,deleteExpando:true,checkClone:false,scriptEval:false,noCloneEvent:true,boxModel:null};b.type="text/javascript";try{b.appendChild(s.createTextNode("window."+f+"=1;"))}catch(i){}a.insertBefore(b,a.firstChild);if(A[f]){c.support.scriptEval=true;delete A[f]}try{delete b.test}catch(o){c.support.deleteExpando=false}a.removeChild(b);if(d.attachEvent&&d.fireEvent){d.attachEvent("onclick",function k(){c.support.noCl [...]
+false;d.detachEvent("onclick",k)});d.cloneNode(true).fireEvent("onclick")}d=s.createElement("div");d.innerHTML="<input type='radio' name='radiotest' checked='checked'/>";a=s.createDocumentFragment();a.appendChild(d.firstChild);c.support.checkClone=a.cloneNode(true).cloneNode(true).lastChild.checked;c(function(){var k=s.createElement("div");k.style.width=k.style.paddingLeft="1px";s.body.appendChild(k);c.boxModel=c.support.boxModel=k.offsetWidth===2;s.body.removeChild(k).style.display="non [...]
+s.createElement("div");k="on"+k;var r=k in n;if(!r){n.setAttribute(k,"return;");r=typeof n[k]==="function"}return r};c.support.submitBubbles=a("submit");c.support.changeBubbles=a("change");a=b=d=e=j=null}})();c.props={"for":"htmlFor","class":"className",readonly:"readOnly",maxlength:"maxLength",cellspacing:"cellSpacing",rowspan:"rowSpan",colspan:"colSpan",tabindex:"tabIndex",usemap:"useMap",frameborder:"frameBorder"};var G="jQuery"+J(),Ya=0,za={};c.extend({cache:{},expando:G,noData:{embe [...]
+applet:true},data:function(a,b,d){if(!(a.nodeName&&c.noData[a.nodeName.toLowerCase()])){a=a==A?za:a;var f=a[G],e=c.cache;if(!f&&typeof b==="string"&&d===w)return null;f||(f=++Ya);if(typeof b==="object"){a[G]=f;e[f]=c.extend(true,{},b)}else if(!e[f]){a[G]=f;e[f]={}}a=e[f];if(d!==w)a[b]=d;return typeof b==="string"?a[b]:a}},removeData:function(a,b){if(!(a.nodeName&&c.noData[a.nodeName.toLowerCase()])){a=a==A?za:a;var d=a[G],f=c.cache,e=f[d];if(b){if(e){delete e[b];c.isEmptyObject(e)&&c.rem [...]
+else a.removeAttribute&&a.removeAttribute(c.expando);delete f[d]}}}});c.fn.extend({data:function(a,b){if(typeof a==="undefined"&&this.length)return c.data(this[0]);else if(typeof a==="object")return this.each(function(){c.data(this,a)});var d=a.split(".");d[1]=d[1]?"."+d[1]:"";if(b===w){var f=this.triggerHandler("getData"+d[1]+"!",[d[0]]);if(f===w&&this.length)f=c.data(this[0],a);return f===w&&d[1]?this.data(d[0]):f}else return this.trigger("setData"+d[1]+"!",[d[0],b]).each(function(){c. [...]
+a,b)})},removeData:function(a){return this.each(function(){c.removeData(this,a)})}});c.extend({queue:function(a,b,d){if(a){b=(b||"fx")+"queue";var f=c.data(a,b);if(!d)return f||[];if(!f||c.isArray(d))f=c.data(a,b,c.makeArray(d));else f.push(d);return f}},dequeue:function(a,b){b=b||"fx";var d=c.queue(a,b),f=d.shift();if(f==="inprogress")f=d.shift();if(f){b==="fx"&&d.unshift("inprogress");f.call(a,function(){c.dequeue(a,b)})}}});c.fn.extend({queue:function(a,b){if(typeof a!=="string"){b=a; [...]
+w)return c.queue(this[0],a);return this.each(function(){var d=c.queue(this,a,b);a==="fx"&&d[0]!=="inprogress"&&c.dequeue(this,a)})},dequeue:function(a){return this.each(function(){c.dequeue(this,a)})},delay:function(a,b){a=c.fx?c.fx.speeds[a]||a:a;b=b||"fx";return this.queue(b,function(){var d=this;setTimeout(function(){c.dequeue(d,b)},a)})},clearQueue:function(a){return this.queue(a||"fx",[])}});var Aa=/[\n\t]/g,ca=/\s+/,Za=/\r/g,$a=/href|src|style/,ab=/(button|input)/i,bb=/(button|inpu [...]
+cb=/^(a|area)$/i,Ba=/radio|checkbox/;c.fn.extend({attr:function(a,b){return X(this,a,b,true,c.attr)},removeAttr:function(a){return this.each(function(){c.attr(this,a,"");this.nodeType===1&&this.removeAttribute(a)})},addClass:function(a){if(c.isFunction(a))return this.each(function(n){var r=c(this);r.addClass(a.call(this,n,r.attr("class")))});if(a&&typeof a==="string")for(var b=(a||"").split(ca),d=0,f=this.length;d<f;d++){var e=this[d];if(e.nodeType===1)if(e.className){for(var j=" "+e.cla [...]
+i=e.className,o=0,k=b.length;o<k;o++)if(j.indexOf(" "+b[o]+" ")<0)i+=" "+b[o];e.className=c.trim(i)}else e.className=a}return this},removeClass:function(a){if(c.isFunction(a))return this.each(function(k){var n=c(this);n.removeClass(a.call(this,k,n.attr("class")))});if(a&&typeof a==="string"||a===w)for(var b=(a||"").split(ca),d=0,f=this.length;d<f;d++){var e=this[d];if(e.nodeType===1&&e.className)if(a){for(var j=(" "+e.className+" ").replace(Aa," "),i=0,o=b.length;i<o;i++)j=j.replace(" "+ [...]
+" ");e.className=c.trim(j)}else e.className=""}return this},toggleClass:function(a,b){var d=typeof a,f=typeof b==="boolean";if(c.isFunction(a))return this.each(function(e){var j=c(this);j.toggleClass(a.call(this,e,j.attr("class"),b),b)});return this.each(function(){if(d==="string")for(var e,j=0,i=c(this),o=b,k=a.split(ca);e=k[j++];){o=f?o:!i.hasClass(e);i[o?"addClass":"removeClass"](e)}else if(d==="undefined"||d==="boolean"){this.className&&c.data(this,"__className__",this.className);thi [...]
+this.className||a===false?"":c.data(this,"__className__")||""}})},hasClass:function(a){a=" "+a+" ";for(var b=0,d=this.length;b<d;b++)if((" "+this[b].className+" ").replace(Aa," ").indexOf(a)>-1)return true;return false},val:function(a){if(a===w){var b=this[0];if(b){if(c.nodeName(b,"option"))return(b.attributes.value||{}).specified?b.value:b.text;if(c.nodeName(b,"select")){var d=b.selectedIndex,f=[],e=b.options;b=b.type==="select-one";if(d<0)return null;var j=b?d:0;for(d=b?d+1:e.length;j< [...]
+e[j];if(i.selected){a=c(i).val();if(b)return a;f.push(a)}}return f}if(Ba.test(b.type)&&!c.support.checkOn)return b.getAttribute("value")===null?"on":b.value;return(b.value||"").replace(Za,"")}return w}var o=c.isFunction(a);return this.each(function(k){var n=c(this),r=a;if(this.nodeType===1){if(o)r=a.call(this,k,n.val());if(typeof r==="number")r+="";if(c.isArray(r)&&Ba.test(this.type))this.checked=c.inArray(n.val(),r)>=0;else if(c.nodeName(this,"select")){var u=c.makeArray(r);c("option",t [...]
+c.inArray(c(this).val(),u)>=0});if(!u.length)this.selectedIndex=-1}else this.value=r}})}});c.extend({attrFn:{val:true,css:true,html:true,text:true,data:true,width:true,height:true,offset:true},attr:function(a,b,d,f){if(!a||a.nodeType===3||a.nodeType===8)return w;if(f&&b in c.attrFn)return c(a)[b](d);f=a.nodeType!==1||!c.isXMLDoc(a);var e=d!==w;b=f&&c.props[b]||b;if(a.nodeType===1){var j=$a.test(b);if(b in a&&f&&!j){if(e){b==="type"&&ab.test(a.nodeName)&&a.parentNode&&c.error("type proper [...]
+a[b]=d}if(c.nodeName(a,"form")&&a.getAttributeNode(b))return a.getAttributeNode(b).nodeValue;if(b==="tabIndex")return(b=a.getAttributeNode("tabIndex"))&&b.specified?b.value:bb.test(a.nodeName)||cb.test(a.nodeName)&&a.href?0:w;return a[b]}if(!c.support.style&&f&&b==="style"){if(e)a.style.cssText=""+d;return a.style.cssText}e&&a.setAttribute(b,""+d);a=!c.support.hrefNormalized&&f&&j?a.getAttribute(b,2):a.getAttribute(b);return a===null?w:a}return c.style(a,b,d)}});var O=/\.(.*)$/,db=functi [...]
+function(b){return"\\"+b})};c.event={add:function(a,b,d,f){if(!(a.nodeType===3||a.nodeType===8)){if(a.setInterval&&a!==A&&!a.frameElement)a=A;var e,j;if(d.handler){e=d;d=e.handler}if(!d.guid)d.guid=c.guid++;if(j=c.data(a)){var i=j.events=j.events||{},o=j.handle;if(!o)j.handle=o=function(){return typeof c!=="undefined"&&!c.event.triggered?c.event.handle.apply(o.elem,arguments):w};o.elem=a;b=b.split(" ");for(var k,n=0,r;k=b[n++];){j=e?c.extend({},e):{handler:d,data:f};if(k.indexOf(".")>-1) [...]
+k=r.shift();j.namespace=r.slice(0).sort().join(".")}else{r=[];j.namespace=""}j.type=k;j.guid=d.guid;var u=i[k],z=c.event.special[k]||{};if(!u){u=i[k]=[];if(!z.setup||z.setup.call(a,f,r,o)===false)if(a.addEventListener)a.addEventListener(k,o,false);else a.attachEvent&&a.attachEvent("on"+k,o)}if(z.add){z.add.call(a,j);if(!j.handler.guid)j.handler.guid=d.guid}u.push(j);c.event.global[k]=true}a=null}}},global:{},remove:function(a,b,d,f){if(!(a.nodeType===3||a.nodeType===8)){var e,j=0,i,o,k,n [...]
+C=z&&z.events;if(z&&C){if(b&&b.type){d=b.handler;b=b.type}if(!b||typeof b==="string"&&b.charAt(0)==="."){b=b||"";for(e in C)c.event.remove(a,e+b)}else{for(b=b.split(" ");e=b[j++];){n=e;i=e.indexOf(".")<0;o=[];if(!i){o=e.split(".");e=o.shift();k=new RegExp("(^|\\.)"+c.map(o.slice(0).sort(),db).join("\\.(?:.*\\.)?")+"(\\.|$)")}if(r=C[e])if(d){n=c.event.special[e]||{};for(B=f||0;B<r.length;B++){u=r[B];if(d.guid===u.guid){if(i||k.test(u.namespace)){f==null&&r.splice(B--,1);n.remove&&n.remove [...]
+null)break}}if(r.length===0||f!=null&&r.length===1){if(!n.teardown||n.teardown.call(a,o)===false)Ca(a,e,z.handle);delete C[e]}}else for(var B=0;B<r.length;B++){u=r[B];if(i||k.test(u.namespace)){c.event.remove(a,n,u.handler,B);r.splice(B--,1)}}}if(c.isEmptyObject(C)){if(b=z.handle)b.elem=null;delete z.events;delete z.handle;c.isEmptyObject(z)&&c.removeData(a)}}}}},trigger:function(a,b,d,f){var e=a.type||a;if(!f){a=typeof a==="object"?a[G]?a:c.extend(c.Event(e),a):c.Event(e);if(e.indexOf(" [...]
+e=e.slice(0,-1);a.exclusive=true}if(!d){a.stopPropagation();c.event.global[e]&&c.each(c.cache,function(){this.events&&this.events[e]&&c.event.trigger(a,b,this.handle.elem)})}if(!d||d.nodeType===3||d.nodeType===8)return w;a.result=w;a.target=d;b=c.makeArray(b);b.unshift(a)}a.currentTarget=d;(f=c.data(d,"handle"))&&f.apply(d,b);f=d.parentNode||d.ownerDocument;try{if(!(d&&d.nodeName&&c.noData[d.nodeName.toLowerCase()]))if(d["on"+e]&&d["on"+e].apply(d,b)===false)a.result=false}catch(j){}if(! [...]
+f)c.event.trigger(a,b,f,true);else if(!a.isDefaultPrevented()){f=a.target;var i,o=c.nodeName(f,"a")&&e==="click",k=c.event.special[e]||{};if((!k._default||k._default.call(d,a)===false)&&!o&&!(f&&f.nodeName&&c.noData[f.nodeName.toLowerCase()])){try{if(f[e]){if(i=f["on"+e])f["on"+e]=null;c.event.triggered=true;f[e]()}}catch(n){}if(i)f["on"+e]=i;c.event.triggered=false}}},handle:function(a){var b,d,f,e;a=arguments[0]=c.event.fix(a||A.event);a.currentTarget=this;b=a.type.indexOf(".")<0&&!a.e [...]
+if(!b){d=a.type.split(".");a.type=d.shift();f=new RegExp("(^|\\.)"+d.slice(0).sort().join("\\.(?:.*\\.)?")+"(\\.|$)")}e=c.data(this,"events");d=e[a.type];if(e&&d){d=d.slice(0);e=0;for(var j=d.length;e<j;e++){var i=d[e];if(b||f.test(i.namespace)){a.handler=i.handler;a.data=i.data;a.handleObj=i;i=i.handler.apply(this,arguments);if(i!==w){a.result=i;if(i===false){a.preventDefault();a.stopPropagation()}}if(a.isImmediatePropagationStopped())break}}}return a.result},props:"altKey attrChange at [...]
+fix:function(a){if(a[G])return a;var b=a;a=c.Event(b);for(var d=this.props.length,f;d;){f=this.props[--d];a[f]=b[f]}if(!a.target)a.target=a.srcElement||s;if(a.target.nodeType===3)a.target=a.target.parentNode;if(!a.relatedTarget&&a.fromElement)a.relatedTarget=a.fromElement===a.target?a.toElement:a.fromElement;if(a.pageX==null&&a.clientX!=null){b=s.documentElement;d=s.body;a.pageX=a.clientX+(b&&b.scrollLeft||d&&d.scrollLeft||0)-(b&&b.clientLeft||d&&d.clientLeft||0);a.pageY=a.clientY+(b&&b. [...]
+d&&d.scrollTop||0)-(b&&b.clientTop||d&&d.clientTop||0)}if(!a.which&&(a.charCode||a.charCode===0?a.charCode:a.keyCode))a.which=a.charCode||a.keyCode;if(!a.metaKey&&a.ctrlKey)a.metaKey=a.ctrlKey;if(!a.which&&a.button!==w)a.which=a.button&1?1:a.button&2?3:a.button&4?2:0;return a},guid:1E8,proxy:c.proxy,special:{ready:{setup:c.bindReady,teardown:c.noop},live:{add:function(a){c.event.add(this,a.origType,c.extend({},a,{handler:oa}))},remove:function(a){var b=true,d=a.origType.replace(O,"");c.e [...]
+"events").live||[],function(){if(d===this.origType.replace(O,""))return b=false});b&&c.event.remove(this,a.origType,oa)}},beforeunload:{setup:function(a,b,d){if(this.setInterval)this.onbeforeunload=d;return false},teardown:function(a,b){if(this.onbeforeunload===b)this.onbeforeunload=null}}}};var Ca=s.removeEventListener?function(a,b,d){a.removeEventListener(b,d,false)}:function(a,b,d){a.detachEvent("on"+b,d)};c.Event=function(a){if(!this.preventDefault)return new c.Event(a);if(a&&a.type) [...]
+a;this.type=a.type}else this.type=a;this.timeStamp=J();this[G]=true};c.Event.prototype={preventDefault:function(){this.isDefaultPrevented=Z;var a=this.originalEvent;if(a){a.preventDefault&&a.preventDefault();a.returnValue=false}},stopPropagation:function(){this.isPropagationStopped=Z;var a=this.originalEvent;if(a){a.stopPropagation&&a.stopPropagation();a.cancelBubble=true}},stopImmediatePropagation:function(){this.isImmediatePropagationStopped=Z;this.stopPropagation()},isDefaultPrevented [...]
+isImmediatePropagationStopped:Y};var Da=function(a){var b=a.relatedTarget;try{for(;b&&b!==this;)b=b.parentNode;if(b!==this){a.type=a.data;c.event.handle.apply(this,arguments)}}catch(d){}},Ea=function(a){a.type=a.data;c.event.handle.apply(this,arguments)};c.each({mouseenter:"mouseover",mouseleave:"mouseout"},function(a,b){c.event.special[a]={setup:function(d){c.event.add(this,b,d&&d.selector?Ea:Da,a)},teardown:function(d){c.event.remove(this,b,d&&d.selector?Ea:Da)}}});if(!c.support.submit [...]
+{setup:function(){if(this.nodeName.toLowerCase()!=="form"){c.event.add(this,"click.specialSubmit",function(a){var b=a.target,d=b.type;if((d==="submit"||d==="image")&&c(b).closest("form").length)return na("submit",this,arguments)});c.event.add(this,"keypress.specialSubmit",function(a){var b=a.target,d=b.type;if((d==="text"||d==="password")&&c(b).closest("form").length&&a.keyCode===13)return na("submit",this,arguments)})}else return false},teardown:function(){c.event.remove(this,".specialS [...]
+if(!c.support.changeBubbles){var da=/textarea|input|select/i,ea,Fa=function(a){var b=a.type,d=a.value;if(b==="radio"||b==="checkbox")d=a.checked;else if(b==="select-multiple")d=a.selectedIndex>-1?c.map(a.options,function(f){return f.selected}).join("-"):"";else if(a.nodeName.toLowerCase()==="select")d=a.selectedIndex;return d},fa=function(a,b){var d=a.target,f,e;if(!(!da.test(d.nodeName)||d.readOnly)){f=c.data(d,"_change_data");e=Fa(d);if(a.type!=="focusout"||d.type!=="radio")c.data(d,"_ [...]
+e);if(!(f===w||e===f))if(f!=null||e){a.type="change";return c.event.trigger(a,b,d)}}};c.event.special.change={filters:{focusout:fa,click:function(a){var b=a.target,d=b.type;if(d==="radio"||d==="checkbox"||b.nodeName.toLowerCase()==="select")return fa.call(this,a)},keydown:function(a){var b=a.target,d=b.type;if(a.keyCode===13&&b.nodeName.toLowerCase()!=="textarea"||a.keyCode===32&&(d==="checkbox"||d==="radio")||d==="select-multiple")return fa.call(this,a)},beforeactivate:function(a){a=a.t [...]
+"_change_data",Fa(a))}},setup:function(){if(this.type==="file")return false;for(var a in ea)c.event.add(this,a+".specialChange",ea[a]);return da.test(this.nodeName)},teardown:function(){c.event.remove(this,".specialChange");return da.test(this.nodeName)}};ea=c.event.special.change.filters}s.addEventListener&&c.each({focus:"focusin",blur:"focusout"},function(a,b){function d(f){f=c.event.fix(f);f.type=b;return c.event.handle.call(this,f)}c.event.special[b]={setup:function(){this.addEventLi [...]
+d,true)},teardown:function(){this.removeEventListener(a,d,true)}}});c.each(["bind","one"],function(a,b){c.fn[b]=function(d,f,e){if(typeof d==="object"){for(var j in d)this[b](j,f,d[j],e);return this}if(c.isFunction(f)){e=f;f=w}var i=b==="one"?c.proxy(e,function(k){c(this).unbind(k,i);return e.apply(this,arguments)}):e;if(d==="unload"&&b!=="one")this.one(d,f,e);else{j=0;for(var o=this.length;j<o;j++)c.event.add(this[j],d,i,f)}return this}});c.fn.extend({unbind:function(a,b){if(typeof a=== [...]
+!a.preventDefault)for(var d in a)this.unbind(d,a[d]);else{d=0;for(var f=this.length;d<f;d++)c.event.remove(this[d],a,b)}return this},delegate:function(a,b,d,f){return this.live(b,d,f,a)},undelegate:function(a,b,d){return arguments.length===0?this.unbind("live"):this.die(b,null,d,a)},trigger:function(a,b){return this.each(function(){c.event.trigger(a,b,this)})},triggerHandler:function(a,b){if(this[0]){a=c.Event(a);a.preventDefault();a.stopPropagation();c.event.trigger(a,b,this[0]);return  [...]
+toggle:function(a){for(var b=arguments,d=1;d<b.length;)c.proxy(a,b[d++]);return this.click(c.proxy(a,function(f){var e=(c.data(this,"lastToggle"+a.guid)||0)%d;c.data(this,"lastToggle"+a.guid,e+1);f.preventDefault();return b[e].apply(this,arguments)||false}))},hover:function(a,b){return this.mouseenter(a).mouseleave(b||a)}});var Ga={focus:"focusin",blur:"focusout",mouseenter:"mouseover",mouseleave:"mouseout"};c.each(["live","die"],function(a,b){c.fn[b]=function(d,f,e,j){var i,o=0,k,n,r=j| [...]
+u=j?this:c(this.context);if(c.isFunction(f)){e=f;f=w}for(d=(d||"").split(" ");(i=d[o++])!=null;){j=O.exec(i);k="";if(j){k=j[0];i=i.replace(O,"")}if(i==="hover")d.push("mouseenter"+k,"mouseleave"+k);else{n=i;if(i==="focus"||i==="blur"){d.push(Ga[i]+k);i+=k}else i=(Ga[i]||i)+k;b==="live"?u.each(function(){c.event.add(this,pa(i,r),{data:f,selector:r,handler:e,origType:i,origHandler:e,preType:n})}):u.unbind(pa(i,r),e)}}return this}});c.each("blur focus focusin focusout load resize scroll unl [...]
+function(a,b){c.fn[b]=function(d){return d?this.bind(b,d):this.trigger(b)};if(c.attrFn)c.attrFn[b]=true});A.attachEvent&&!A.addEventListener&&A.attachEvent("onunload",function(){for(var a in c.cache)if(c.cache[a].handle)try{c.event.remove(c.cache[a].handle.elem)}catch(b){}});(function(){function a(g){for(var h="",l,m=0;g[m];m++){l=g[m];if(l.nodeType===3||l.nodeType===4)h+=l.nodeValue;else if(l.nodeType!==8)h+=a(l.childNodes)}return h}function b(g,h,l,m,q,p){q=0;for(var v=m.length;q<v;q++ [...]
+if(t){t=t[g];for(var y=false;t;){if(t.sizcache===l){y=m[t.sizset];break}if(t.nodeType===1&&!p){t.sizcache=l;t.sizset=q}if(t.nodeName.toLowerCase()===h){y=t;break}t=t[g]}m[q]=y}}}function d(g,h,l,m,q,p){q=0;for(var v=m.length;q<v;q++){var t=m[q];if(t){t=t[g];for(var y=false;t;){if(t.sizcache===l){y=m[t.sizset];break}if(t.nodeType===1){if(!p){t.sizcache=l;t.sizset=q}if(typeof h!=="string"){if(t===h){y=true;break}}else if(k.filter(h,[t]).length>0){y=t;break}}t=t[g]}m[q]=y}}}var f=/((?:\((?: [...]
+e=0,j=Object.prototype.toString,i=false,o=true;[0,0].sort(function(){o=false;return 0});var k=function(g,h,l,m){l=l||[];var q=h=h||s;if(h.nodeType!==1&&h.nodeType!==9)return[];if(!g||typeof g!=="string")return l;for(var p=[],v,t,y,S,H=true,M=x(h),I=g;(f.exec(""),v=f.exec(I))!==null;){I=v[3];p.push(v[1]);if(v[2]){S=v[3];break}}if(p.length>1&&r.exec(g))if(p.length===2&&n.relative[p[0]])t=ga(p[0]+p[1],h);else for(t=n.relative[p[0]]?[h]:k(p.shift(),h);p.length;){g=p.shift();if(n.relative[g]) [...]
+t=ga(g,t)}else{if(!m&&p.length>1&&h.nodeType===9&&!M&&n.match.ID.test(p[0])&&!n.match.ID.test(p[p.length-1])){v=k.find(p.shift(),h,M);h=v.expr?k.filter(v.expr,v.set)[0]:v.set[0]}if(h){v=m?{expr:p.pop(),set:z(m)}:k.find(p.pop(),p.length===1&&(p[0]==="~"||p[0]==="+")&&h.parentNode?h.parentNode:h,M);t=v.expr?k.filter(v.expr,v.set):v.set;if(p.length>0)y=z(t);else H=false;for(;p.length;){var D=p.pop();v=D;if(n.relative[D])v=p.pop();else D="";if(v==null)v=h;n.relative[D](y,v,M)}}else y=[]}y||( [...]
+g);if(j.call(y)==="[object Array]")if(H)if(h&&h.nodeType===1)for(g=0;y[g]!=null;g++){if(y[g]&&(y[g]===true||y[g].nodeType===1&&E(h,y[g])))l.push(t[g])}else for(g=0;y[g]!=null;g++)y[g]&&y[g].nodeType===1&&l.push(t[g]);else l.push.apply(l,y);else z(y,l);if(S){k(S,q,l,m);k.uniqueSort(l)}return l};k.uniqueSort=function(g){if(B){i=o;g.sort(B);if(i)for(var h=1;h<g.length;h++)g[h]===g[h-1]&&g.splice(h--,1)}return g};k.matches=function(g,h){return k(g,null,null,h)};k.find=function(g,h,l){var m,q [...]
+for(var p=0,v=n.order.length;p<v;p++){var t=n.order[p];if(q=n.leftMatch[t].exec(g)){var y=q[1];q.splice(1,1);if(y.substr(y.length-1)!=="\\"){q[1]=(q[1]||"").replace(/\\/g,"");m=n.find[t](q,h,l);if(m!=null){g=g.replace(n.match[t],"");break}}}}m||(m=h.getElementsByTagName("*"));return{set:m,expr:g}};k.filter=function(g,h,l,m){for(var q=g,p=[],v=h,t,y,S=h&&h[0]&&x(h[0]);g&&h.length;){for(var H in n.filter)if((t=n.leftMatch[H].exec(g))!=null&&t[2]){var M=n.filter[H],I,D;D=t[1];y=false;t.spli [...]
+1)!=="\\"){if(v===p)p=[];if(n.preFilter[H])if(t=n.preFilter[H](t,v,l,p,m,S)){if(t===true)continue}else y=I=true;if(t)for(var U=0;(D=v[U])!=null;U++)if(D){I=M(D,t,U,v);var Ha=m^!!I;if(l&&I!=null)if(Ha)y=true;else v[U]=false;else if(Ha){p.push(D);y=true}}if(I!==w){l||(v=p);g=g.replace(n.match[H],"");if(!y)return[];break}}}if(g===q)if(y==null)k.error(g);else break;q=g}return v};k.error=function(g){throw"Syntax error, unrecognized expression: "+g;};var n=k.selectors={order:["ID","NAME","TAG" [...]
+CLASS:/\.((?:[\w\u00c0-\uFFFF-]|\\.)+)/,NAME:/\[name=['"]*((?:[\w\u00c0-\uFFFF-]|\\.)+)['"]*\]/,ATTR:/\[\s*((?:[\w\u00c0-\uFFFF-]|\\.)+)\s*(?:(\S?=)\s*(['"]*)(.*?)\3|)\s*\]/,TAG:/^((?:[\w\u00c0-\uFFFF\*-]|\\.)+)/,CHILD:/:(only|nth|last|first)-child(?:\((even|odd|[\dn+-]*)\))?/,POS:/:(nth|eq|gt|lt|first|last|even|odd)(?:\((\d*)\))?(?=[^-]|$)/,PSEUDO:/:((?:[\w\u00c0-\uFFFF-]|\\.)+)(?:\((['"]?)((?:\([^\)]+\)|[^\(\)]*)+)\2\))?/},leftMatch:{},attrMap:{"class":"className","for":"htmlFor"},attr [...]
+relative:{"+":function(g,h){var l=typeof h==="string",m=l&&!/\W/.test(h);l=l&&!m;if(m)h=h.toLowerCase();m=0;for(var q=g.length,p;m<q;m++)if(p=g[m]){for(;(p=p.previousSibling)&&p.nodeType!==1;);g[m]=l||p&&p.nodeName.toLowerCase()===h?p||false:p===h}l&&k.filter(h,g,true)},">":function(g,h){var l=typeof h==="string";if(l&&!/\W/.test(h)){h=h.toLowerCase();for(var m=0,q=g.length;m<q;m++){var p=g[m];if(p){l=p.parentNode;g[m]=l.nodeName.toLowerCase()===h?l:false}}}else{m=0;for(q=g.length;m<q;m+ [...]
+l?p.parentNode:p.parentNode===h;l&&k.filter(h,g,true)}},"":function(g,h,l){var m=e++,q=d;if(typeof h==="string"&&!/\W/.test(h)){var p=h=h.toLowerCase();q=b}q("parentNode",h,m,g,p,l)},"~":function(g,h,l){var m=e++,q=d;if(typeof h==="string"&&!/\W/.test(h)){var p=h=h.toLowerCase();q=b}q("previousSibling",h,m,g,p,l)}},find:{ID:function(g,h,l){if(typeof h.getElementById!=="undefined"&&!l)return(g=h.getElementById(g[1]))?[g]:[]},NAME:function(g,h){if(typeof h.getElementsByName!=="undefined"){ [...]
+h=h.getElementsByName(g[1]);for(var m=0,q=h.length;m<q;m++)h[m].getAttribute("name")===g[1]&&l.push(h[m]);return l.length===0?null:l}},TAG:function(g,h){return h.getElementsByTagName(g[1])}},preFilter:{CLASS:function(g,h,l,m,q,p){g=" "+g[1].replace(/\\/g,"")+" ";if(p)return g;p=0;for(var v;(v=h[p])!=null;p++)if(v)if(q^(v.className&&(" "+v.className+" ").replace(/[\t\n]/g," ").indexOf(g)>=0))l||m.push(v);else if(l)h[p]=false;return false},ID:function(g){return g[1].replace(/\\/g,"")},TAG: [...]
+CHILD:function(g){if(g[1]==="nth"){var h=/(-?)(\d*)n((?:\+|-)?\d*)/.exec(g[2]==="even"&&"2n"||g[2]==="odd"&&"2n+1"||!/\D/.test(g[2])&&"0n+"+g[2]||g[2]);g[2]=h[1]+(h[2]||1)-0;g[3]=h[3]-0}g[0]=e++;return g},ATTR:function(g,h,l,m,q,p){h=g[1].replace(/\\/g,"");if(!p&&n.attrMap[h])g[1]=n.attrMap[h];if(g[2]==="~=")g[4]=" "+g[4]+" ";return g},PSEUDO:function(g,h,l,m,q){if(g[1]==="not")if((f.exec(g[3])||"").length>1||/^\w/.test(g[3]))g[3]=k(g[3],null,null,h);else{g=k.filter(g[3],h,l,true^q);l||m [...]
+g);return false}else if(n.match.POS.test(g[0])||n.match.CHILD.test(g[0]))return true;return g},POS:function(g){g.unshift(true);return g}},filters:{enabled:function(g){return g.disabled===false&&g.type!=="hidden"},disabled:function(g){return g.disabled===true},checked:function(g){return g.checked===true},selected:function(g){return g.selected===true},parent:function(g){return!!g.firstChild},empty:function(g){return!g.firstChild},has:function(g,h,l){return!!k(l[3],g).length},header:functio [...]
+text:function(g){return"text"===g.type},radio:function(g){return"radio"===g.type},checkbox:function(g){return"checkbox"===g.type},file:function(g){return"file"===g.type},password:function(g){return"password"===g.type},submit:function(g){return"submit"===g.type},image:function(g){return"image"===g.type},reset:function(g){return"reset"===g.type},button:function(g){return"button"===g.type||g.nodeName.toLowerCase()==="button"},input:function(g){return/input|select|textarea|button/i.test(g.no [...]
+setFilters:{first:function(g,h){return h===0},last:function(g,h,l,m){return h===m.length-1},even:function(g,h){return h%2===0},odd:function(g,h){return h%2===1},lt:function(g,h,l){return h<l[3]-0},gt:function(g,h,l){return h>l[3]-0},nth:function(g,h,l){return l[3]-0===h},eq:function(g,h,l){return l[3]-0===h}},filter:{PSEUDO:function(g,h,l,m){var q=h[1],p=n.filters[q];if(p)return p(g,l,h,m);else if(q==="contains")return(g.textContent||g.innerText||a([g])||"").indexOf(h[3])>=0;else if(q=== [...]
+h[3];l=0;for(m=h.length;l<m;l++)if(h[l]===g)return false;return true}else k.error("Syntax error, unrecognized expression: "+q)},CHILD:function(g,h){var l=h[1],m=g;switch(l){case "only":case "first":for(;m=m.previousSibling;)if(m.nodeType===1)return false;if(l==="first")return true;m=g;case "last":for(;m=m.nextSibling;)if(m.nodeType===1)return false;return true;case "nth":l=h[2];var q=h[3];if(l===1&&q===0)return true;h=h[0];var p=g.parentNode;if(p&&(p.sizcache!==h||!g.nodeIndex)){var v=0; [...]
+m.nextSibling)if(m.nodeType===1)m.nodeIndex=++v;p.sizcache=h}g=g.nodeIndex-q;return l===0?g===0:g%l===0&&g/l>=0}},ID:function(g,h){return g.nodeType===1&&g.getAttribute("id")===h},TAG:function(g,h){return h==="*"&&g.nodeType===1||g.nodeName.toLowerCase()===h},CLASS:function(g,h){return(" "+(g.className||g.getAttribute("class"))+" ").indexOf(h)>-1},ATTR:function(g,h){var l=h[1];g=n.attrHandle[l]?n.attrHandle[l](g):g[l]!=null?g[l]:g.getAttribute(l);l=g+"";var m=h[2];h=h[4];return g==null?m [...]
+"="?l===h:m==="*="?l.indexOf(h)>=0:m==="~="?(" "+l+" ").indexOf(h)>=0:!h?l&&g!==false:m==="!="?l!==h:m==="^="?l.indexOf(h)===0:m==="$="?l.substr(l.length-h.length)===h:m==="|="?l===h||l.substr(0,h.length+1)===h+"-":false},POS:function(g,h,l,m){var q=n.setFilters[h[2]];if(q)return q(g,l,h,m)}}},r=n.match.POS;for(var u in n.match){n.match[u]=new RegExp(n.match[u].source+/(?![^\[]*\])(?![^\(]*\))/.source);n.leftMatch[u]=new RegExp(/(^(?:.|\r|\n)*?)/.source+n.match[u].source.replace(/\\(\d+) [...]
+h){return"\\"+(h-0+1)}))}var z=function(g,h){g=Array.prototype.slice.call(g,0);if(h){h.push.apply(h,g);return h}return g};try{Array.prototype.slice.call(s.documentElement.childNodes,0)}catch(C){z=function(g,h){h=h||[];if(j.call(g)==="[object Array]")Array.prototype.push.apply(h,g);else if(typeof g.length==="number")for(var l=0,m=g.length;l<m;l++)h.push(g[l]);else for(l=0;g[l];l++)h.push(g[l]);return h}}var B;if(s.documentElement.compareDocumentPosition)B=function(g,h){if(!g.compareDocume [...]
+!h.compareDocumentPosition){if(g==h)i=true;return g.compareDocumentPosition?-1:1}g=g.compareDocumentPosition(h)&4?-1:g===h?0:1;if(g===0)i=true;return g};else if("sourceIndex"in s.documentElement)B=function(g,h){if(!g.sourceIndex||!h.sourceIndex){if(g==h)i=true;return g.sourceIndex?-1:1}g=g.sourceIndex-h.sourceIndex;if(g===0)i=true;return g};else if(s.createRange)B=function(g,h){if(!g.ownerDocument||!h.ownerDocument){if(g==h)i=true;return g.ownerDocument?-1:1}var l=g.ownerDocument.createR [...]
+h.ownerDocument.createRange();l.setStart(g,0);l.setEnd(g,0);m.setStart(h,0);m.setEnd(h,0);g=l.compareBoundaryPoints(Range.START_TO_END,m);if(g===0)i=true;return g};(function(){var g=s.createElement("div"),h="script"+(new Date).getTime();g.innerHTML="<a name='"+h+"'/>";var l=s.documentElement;l.insertBefore(g,l.firstChild);if(s.getElementById(h)){n.find.ID=function(m,q,p){if(typeof q.getElementById!=="undefined"&&!p)return(q=q.getElementById(m[1]))?q.id===m[1]||typeof q.getAttributeNode!= [...]
+q.getAttributeNode("id").nodeValue===m[1]?[q]:w:[]};n.filter.ID=function(m,q){var p=typeof m.getAttributeNode!=="undefined"&&m.getAttributeNode("id");return m.nodeType===1&&p&&p.nodeValue===q}}l.removeChild(g);l=g=null})();(function(){var g=s.createElement("div");g.appendChild(s.createComment(""));if(g.getElementsByTagName("*").length>0)n.find.TAG=function(h,l){l=l.getElementsByTagName(h[1]);if(h[1]==="*"){h=[];for(var m=0;l[m];m++)l[m].nodeType===1&&h.push(l[m]);l=h}return l};g.innerHTM [...]
+if(g.firstChild&&typeof g.firstChild.getAttribute!=="undefined"&&g.firstChild.getAttribute("href")!=="#")n.attrHandle.href=function(h){return h.getAttribute("href",2)};g=null})();s.querySelectorAll&&function(){var g=k,h=s.createElement("div");h.innerHTML="<p class='TEST'></p>";if(!(h.querySelectorAll&&h.querySelectorAll(".TEST").length===0)){k=function(m,q,p,v){q=q||s;if(!v&&q.nodeType===9&&!x(q))try{return z(q.querySelectorAll(m),p)}catch(t){}return g(m,q,p,v)};for(var l in g)k[l]=g[l]; [...]
+(function(){var g=s.createElement("div");g.innerHTML="<div class='test e'></div><div class='test'></div>";if(!(!g.getElementsByClassName||g.getElementsByClassName("e").length===0)){g.lastChild.className="e";if(g.getElementsByClassName("e").length!==1){n.order.splice(1,0,"CLASS");n.find.CLASS=function(h,l,m){if(typeof l.getElementsByClassName!=="undefined"&&!m)return l.getElementsByClassName(h[1])};g=null}}})();var E=s.compareDocumentPosition?function(g,h){return!!(g.compareDocumentPositi [...]
+function(g,h){return g!==h&&(g.contains?g.contains(h):true)},x=function(g){return(g=(g?g.ownerDocument||g:0).documentElement)?g.nodeName!=="HTML":false},ga=function(g,h){var l=[],m="",q;for(h=h.nodeType?[h]:h;q=n.match.PSEUDO.exec(g);){m+=q[0];g=g.replace(n.match.PSEUDO,"")}g=n.relative[g]?g+"*":g;q=0;for(var p=h.length;q<p;q++)k(g,h[q],l);return k.filter(m,l)};c.find=k;c.expr=k.selectors;c.expr[":"]=c.expr.filters;c.unique=k.uniqueSort;c.text=a;c.isXMLDoc=x;c.contains=E})();var eb=/Unti [...]
+gb=/,/;R=Array.prototype.slice;var Ia=function(a,b,d){if(c.isFunction(b))return c.grep(a,function(e,j){return!!b.call(e,j,e)===d});else if(b.nodeType)return c.grep(a,function(e){return e===b===d});else if(typeof b==="string"){var f=c.grep(a,function(e){return e.nodeType===1});if(Ua.test(b))return c.filter(b,f,!d);else b=c.filter(b,f)}return c.grep(a,function(e){return c.inArray(e,b)>=0===d})};c.fn.extend({find:function(a){for(var b=this.pushStack("","find",a),d=0,f=0,e=this.length;f<e;f+ [...]
+c.find(a,this[f],b);if(f>0)for(var j=d;j<b.length;j++)for(var i=0;i<d;i++)if(b[i]===b[j]){b.splice(j--,1);break}}return b},has:function(a){var b=c(a);return this.filter(function(){for(var d=0,f=b.length;d<f;d++)if(c.contains(this,b[d]))return true})},not:function(a){return this.pushStack(Ia(this,a,false),"not",a)},filter:function(a){return this.pushStack(Ia(this,a,true),"filter",a)},is:function(a){return!!a&&c.filter(a,this).length>0},closest:function(a,b){if(c.isArray(a)){var d=[],f=thi [...]
+{},i;if(f&&a.length){e=0;for(var o=a.length;e<o;e++){i=a[e];j[i]||(j[i]=c.expr.match.POS.test(i)?c(i,b||this.context):i)}for(;f&&f.ownerDocument&&f!==b;){for(i in j){e=j[i];if(e.jquery?e.index(f)>-1:c(f).is(e)){d.push({selector:i,elem:f});delete j[i]}}f=f.parentNode}}return d}var k=c.expr.match.POS.test(a)?c(a,b||this.context):null;return this.map(function(n,r){for(;r&&r.ownerDocument&&r!==b;){if(k?k.index(r)>-1:c(r).is(a))return r;r=r.parentNode}return null})},index:function(a){if(!a||t [...]
+"string")return c.inArray(this[0],a?c(a):this.parent().children());return c.inArray(a.jquery?a[0]:a,this)},add:function(a,b){a=typeof a==="string"?c(a,b||this.context):c.makeArray(a);b=c.merge(this.get(),a);return this.pushStack(qa(a[0])||qa(b[0])?b:c.unique(b))},andSelf:function(){return this.add(this.prevObject)}});c.each({parent:function(a){return(a=a.parentNode)&&a.nodeType!==11?a:null},parents:function(a){return c.dir(a,"parentNode")},parentsUntil:function(a,b,d){return c.dir(a,"par [...]
+d)},next:function(a){return c.nth(a,2,"nextSibling")},prev:function(a){return c.nth(a,2,"previousSibling")},nextAll:function(a){return c.dir(a,"nextSibling")},prevAll:function(a){return c.dir(a,"previousSibling")},nextUntil:function(a,b,d){return c.dir(a,"nextSibling",d)},prevUntil:function(a,b,d){return c.dir(a,"previousSibling",d)},siblings:function(a){return c.sibling(a.parentNode.firstChild,a)},children:function(a){return c.sibling(a.firstChild)},contents:function(a){return c.nodeNam [...]
+a.contentDocument||a.contentWindow.document:c.makeArray(a.childNodes)}},function(a,b){c.fn[a]=function(d,f){var e=c.map(this,b,d);eb.test(a)||(f=d);if(f&&typeof f==="string")e=c.filter(f,e);e=this.length>1?c.unique(e):e;if((this.length>1||gb.test(f))&&fb.test(a))e=e.reverse();return this.pushStack(e,a,R.call(arguments).join(","))}});c.extend({filter:function(a,b,d){if(d)a=":not("+a+")";return c.find.matches(a,b)},dir:function(a,b,d){var f=[];for(a=a[b];a&&a.nodeType!==9&&(d===w||a.nodeTy [...]
+1&&f.push(a);a=a[b]}return f},nth:function(a,b,d){b=b||1;for(var f=0;a;a=a[d])if(a.nodeType===1&&++f===b)break;return a},sibling:function(a,b){for(var d=[];a;a=a.nextSibling)a.nodeType===1&&a!==b&&d.push(a);return d}});var Ja=/ jQuery\d+="(?:\d+|null)"/g,V=/^\s+/,Ka=/(<([\w:]+)[^>]*?)\/>/g,hb=/^(?:area|br|col|embed|hr|img|input|link|meta|param)$/i,La=/<([\w:]+)/,ib=/<tbody/i,jb=/<|&#?\w+;/,ta=/<script|<object|<embed|<option|<style/i,ua=/checked\s*(?:[^=]|=\s*.checked.)/i,Ma=function(a,b, [...]
+a:b+"></"+d+">"},F={option:[1,"<select multiple='multiple'>","</select>"],legend:[1,"<fieldset>","</fieldset>"],thead:[1,"<table>","</table>"],tr:[2,"<table><tbody>","</tbody></table>"],td:[3,"<table><tbody><tr>","</tr></tbody></table>"],col:[2,"<table><tbody></tbody><colgroup>","</colgroup></table>"],area:[1,"<map>","</map>"],_default:[0,"",""]};F.optgroup=F.option;F.tbody=F.tfoot=F.colgroup=F.caption=F.thead;F.th=F.td;if(!c.support.htmlSerialize)F._default=[1,"div<div>","</div>"];c.fn. [...]
+c(this);d.text(a.call(this,b,d.text()))});if(typeof a!=="object"&&a!==w)return this.empty().append((this[0]&&this[0].ownerDocument||s).createTextNode(a));return c.text(this)},wrapAll:function(a){if(c.isFunction(a))return this.each(function(d){c(this).wrapAll(a.call(this,d))});if(this[0]){var b=c(a,this[0].ownerDocument).eq(0).clone(true);this[0].parentNode&&b.insertBefore(this[0]);b.map(function(){for(var d=this;d.firstChild&&d.firstChild.nodeType===1;)d=d.firstChild;return d}).append(th [...]
+wrapInner:function(a){if(c.isFunction(a))return this.each(function(b){c(this).wrapInner(a.call(this,b))});return this.each(function(){var b=c(this),d=b.contents();d.length?d.wrapAll(a):b.append(a)})},wrap:function(a){return this.each(function(){c(this).wrapAll(a)})},unwrap:function(){return this.parent().each(function(){c.nodeName(this,"body")||c(this).replaceWith(this.childNodes)}).end()},append:function(){return this.domManip(arguments,true,function(a){this.nodeType===1&&this.appendChi [...]
+prepend:function(){return this.domManip(arguments,true,function(a){this.nodeType===1&&this.insertBefore(a,this.firstChild)})},before:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments,false,function(b){this.parentNode.insertBefore(b,this)});else if(arguments.length){var a=c(arguments[0]);a.push.apply(a,this.toArray());return this.pushStack(a,"before",arguments)}},after:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments,false,function(b){this.pa [...]
+this.nextSibling)});else if(arguments.length){var a=this.pushStack(this,"after",arguments);a.push.apply(a,c(arguments[0]).toArray());return a}},remove:function(a,b){for(var d=0,f;(f=this[d])!=null;d++)if(!a||c.filter(a,[f]).length){if(!b&&f.nodeType===1){c.cleanData(f.getElementsByTagName("*"));c.cleanData([f])}f.parentNode&&f.parentNode.removeChild(f)}return this},empty:function(){for(var a=0,b;(b=this[a])!=null;a++)for(b.nodeType===1&&c.cleanData(b.getElementsByTagName("*"));b.firstChi [...]
+return this},clone:function(a){var b=this.map(function(){if(!c.support.noCloneEvent&&!c.isXMLDoc(this)){var d=this.outerHTML,f=this.ownerDocument;if(!d){d=f.createElement("div");d.appendChild(this.cloneNode(true));d=d.innerHTML}return c.clean([d.replace(Ja,"").replace(/=([^="'>\s]+\/)>/g,'="$1">').replace(V,"")],f)[0]}else return this.cloneNode(true)});if(a===true){ra(this,b);ra(this.find("*"),b.find("*"))}return b},html:function(a){if(a===w)return this[0]&&this[0].nodeType===1?this[0].i [...]
+""):null;else if(typeof a==="string"&&!ta.test(a)&&(c.support.leadingWhitespace||!V.test(a))&&!F[(La.exec(a)||["",""])[1].toLowerCase()]){a=a.replace(Ka,Ma);try{for(var b=0,d=this.length;b<d;b++)if(this[b].nodeType===1){c.cleanData(this[b].getElementsByTagName("*"));this[b].innerHTML=a}}catch(f){this.empty().append(a)}}else c.isFunction(a)?this.each(function(e){var j=c(this),i=j.html();j.empty().append(function(){return a.call(this,e,i)})}):this.empty().append(a);return this},replaceWith [...]
+this[0].parentNode){if(c.isFunction(a))return this.each(function(b){var d=c(this),f=d.html();d.replaceWith(a.call(this,b,f))});if(typeof a!=="string")a=c(a).detach();return this.each(function(){var b=this.nextSibling,d=this.parentNode;c(this).remove();b?c(b).before(a):c(d).append(a)})}else return this.pushStack(c(c.isFunction(a)?a():a),"replaceWith",a)},detach:function(a){return this.remove(a,true)},domManip:function(a,b,d){function f(u){return c.nodeName(u,"table")?u.getElementsByTagNam [...]
+u.appendChild(u.ownerDocument.createElement("tbody")):u}var e,j,i=a[0],o=[],k;if(!c.support.checkClone&&arguments.length===3&&typeof i==="string"&&ua.test(i))return this.each(function(){c(this).domManip(a,b,d,true)});if(c.isFunction(i))return this.each(function(u){var z=c(this);a[0]=i.call(this,u,b?z.html():w);z.domManip(a,b,d)});if(this[0]){e=i&&i.parentNode;e=c.support.parentNode&&e&&e.nodeType===11&&e.childNodes.length===this.length?{fragment:e}:sa(a,this,o);k=e.fragment;if(j=k.childN [...]
+1?(k=k.firstChild):k.firstChild){b=b&&c.nodeName(j,"tr");for(var n=0,r=this.length;n<r;n++)d.call(b?f(this[n],j):this[n],n>0||e.cacheable||this.length>1?k.cloneNode(true):k)}o.length&&c.each(o,Qa)}return this}});c.fragments={};c.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(a,b){c.fn[a]=function(d){var f=[];d=c(d);var e=this.length===1&&this[0].parentNode;if(e&&e.nodeType===11&&e.childNodes.length===1&&d.length=== [...]
+return this}else{e=0;for(var j=d.length;e<j;e++){var i=(e>0?this.clone(true):this).get();c.fn[b].apply(c(d[e]),i);f=f.concat(i)}return this.pushStack(f,a,d.selector)}}});c.extend({clean:function(a,b,d,f){b=b||s;if(typeof b.createElement==="undefined")b=b.ownerDocument||b[0]&&b[0].ownerDocument||s;for(var e=[],j=0,i;(i=a[j])!=null;j++){if(typeof i==="number")i+="";if(i){if(typeof i==="string"&&!jb.test(i))i=b.createTextNode(i);else if(typeof i==="string"){i=i.replace(Ka,Ma);var o=(La.exec [...]
+""])[1].toLowerCase(),k=F[o]||F._default,n=k[0],r=b.createElement("div");for(r.innerHTML=k[1]+i+k[2];n--;)r=r.lastChild;if(!c.support.tbody){n=ib.test(i);o=o==="table"&&!n?r.firstChild&&r.firstChild.childNodes:k[1]==="<table>"&&!n?r.childNodes:[];for(k=o.length-1;k>=0;--k)c.nodeName(o[k],"tbody")&&!o[k].childNodes.length&&o[k].parentNode.removeChild(o[k])}!c.support.leadingWhitespace&&V.test(i)&&r.insertBefore(b.createTextNode(V.exec(i)[0]),r.firstChild);i=r.childNodes}if(i.nodeType)e.pu [...]
+c.merge(e,i)}}if(d)for(j=0;e[j];j++)if(f&&c.nodeName(e[j],"script")&&(!e[j].type||e[j].type.toLowerCase()==="text/javascript"))f.push(e[j].parentNode?e[j].parentNode.removeChild(e[j]):e[j]);else{e[j].nodeType===1&&e.splice.apply(e,[j+1,0].concat(c.makeArray(e[j].getElementsByTagName("script"))));d.appendChild(e[j])}return e},cleanData:function(a){for(var b,d,f=c.cache,e=c.event.special,j=c.support.deleteExpando,i=0,o;(o=a[i])!=null;i++)if(d=o[c.expando]){b=f[d];if(b.events)for(var k in b [...]
+c.event.remove(o,k):Ca(o,k,b.handle);if(j)delete o[c.expando];else o.removeAttribute&&o.removeAttribute(c.expando);delete f[d]}}});var kb=/z-?index|font-?weight|opacity|zoom|line-?height/i,Na=/alpha\([^)]*\)/,Oa=/opacity=([^)]*)/,ha=/float/i,ia=/-([a-z])/ig,lb=/([A-Z])/g,mb=/^-?\d+(?:px)?$/i,nb=/^-?\d/,ob={position:"absolute",visibility:"hidden",display:"block"},pb=["Left","Right"],qb=["Top","Bottom"],rb=s.defaultView&&s.defaultView.getComputedStyle,Pa=c.support.cssFloat?"cssFloat":"styl [...]
+function(a,b){return b.toUpperCase()};c.fn.css=function(a,b){return X(this,a,b,true,function(d,f,e){if(e===w)return c.curCSS(d,f);if(typeof e==="number"&&!kb.test(f))e+="px";c.style(d,f,e)})};c.extend({style:function(a,b,d){if(!a||a.nodeType===3||a.nodeType===8)return w;if((b==="width"||b==="height")&&parseFloat(d)<0)d=w;var f=a.style||a,e=d!==w;if(!c.support.opacity&&b==="opacity"){if(e){f.zoom=1;b=parseInt(d,10)+""==="NaN"?"":"alpha(opacity="+d*100+")";a=f.filter||c.curCSS(a,"filter")| [...]
+Na.test(a)?a.replace(Na,b):b}return f.filter&&f.filter.indexOf("opacity=")>=0?parseFloat(Oa.exec(f.filter)[1])/100+"":""}if(ha.test(b))b=Pa;b=b.replace(ia,ja);if(e)f[b]=d;return f[b]},css:function(a,b,d,f){if(b==="width"||b==="height"){var e,j=b==="width"?pb:qb;function i(){e=b==="width"?a.offsetWidth:a.offsetHeight;f!=="border"&&c.each(j,function(){f||(e-=parseFloat(c.curCSS(a,"padding"+this,true))||0);if(f==="margin")e+=parseFloat(c.curCSS(a,"margin"+this,true))||0;else e-=parseFloat(c [...]
+"border"+this+"Width",true))||0})}a.offsetWidth!==0?i():c.swap(a,ob,i);return Math.max(0,Math.round(e))}return c.curCSS(a,b,d)},curCSS:function(a,b,d){var f,e=a.style;if(!c.support.opacity&&b==="opacity"&&a.currentStyle){f=Oa.test(a.currentStyle.filter||"")?parseFloat(RegExp.$1)/100+"":"";return f===""?"1":f}if(ha.test(b))b=Pa;if(!d&&e&&e[b])f=e[b];else if(rb){if(ha.test(b))b="float";b=b.replace(lb,"-$1").toLowerCase();e=a.ownerDocument.defaultView;if(!e)return null;if(a=e.getComputedSty [...]
+a.getPropertyValue(b);if(b==="opacity"&&f==="")f="1"}else if(a.currentStyle){d=b.replace(ia,ja);f=a.currentStyle[b]||a.currentStyle[d];if(!mb.test(f)&&nb.test(f)){b=e.left;var j=a.runtimeStyle.left;a.runtimeStyle.left=a.currentStyle.left;e.left=d==="fontSize"?"1em":f||0;f=e.pixelLeft+"px";e.left=b;a.runtimeStyle.left=j}}return f},swap:function(a,b,d){var f={};for(var e in b){f[e]=a.style[e];a.style[e]=b[e]}d.call(a);for(e in b)a.style[e]=f[e]}});if(c.expr&&c.expr.filters){c.expr.filters. [...]
+a.offsetWidth,d=a.offsetHeight,f=a.nodeName.toLowerCase()==="tr";return b===0&&d===0&&!f?true:b>0&&d>0&&!f?false:c.curCSS(a,"display")==="none"};c.expr.filters.visible=function(a){return!c.expr.filters.hidden(a)}}var sb=J(),tb=/<script(.|\s)*?\/script>/gi,ub=/select|textarea/i,vb=/color|date|datetime|email|hidden|month|number|password|range|search|tel|text|time|url|week/i,N=/=\?(&|$)/,ka=/\?/,wb=/(\?|&)_=.*?(&|$)/,xb=/^(\w+:)?\/\/([^\/?#]+)/,yb=/%20/g,zb=c.fn.load;c.fn.extend({load:funct [...]
+"string")return zb.call(this,a);else if(!this.length)return this;var f=a.indexOf(" ");if(f>=0){var e=a.slice(f,a.length);a=a.slice(0,f)}f="GET";if(b)if(c.isFunction(b)){d=b;b=null}else if(typeof b==="object"){b=c.param(b,c.ajaxSettings.traditional);f="POST"}var j=this;c.ajax({url:a,type:f,dataType:"html",data:b,complete:function(i,o){if(o==="success"||o==="notmodified")j.html(e?c("<div />").append(i.responseText.replace(tb,"")).find(e):i.responseText);d&&j.each(d,[i.responseText,o,i])}}) [...]
+serialize:function(){return c.param(this.serializeArray())},serializeArray:function(){return this.map(function(){return this.elements?c.makeArray(this.elements):this}).filter(function(){return this.name&&!this.disabled&&(this.checked||ub.test(this.nodeName)||vb.test(this.type))}).map(function(a,b){a=c(this).val();return a==null?null:c.isArray(a)?c.map(a,function(d){return{name:b.name,value:d}}):{name:b.name,value:a}}).get()}});c.each("ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess [...]
+function(a,b){c.fn[b]=function(d){return this.bind(b,d)}});c.extend({get:function(a,b,d,f){if(c.isFunction(b)){f=f||d;d=b;b=null}return c.ajax({type:"GET",url:a,data:b,success:d,dataType:f})},getScript:function(a,b){return c.get(a,null,b,"script")},getJSON:function(a,b,d){return c.get(a,b,d,"json")},post:function(a,b,d,f){if(c.isFunction(b)){f=f||d;d=b;b={}}return c.ajax({type:"POST",url:a,data:b,success:d,dataType:f})},ajaxSetup:function(a){c.extend(c.ajaxSettings,a)},ajaxSettings:{url: [...]
+global:true,type:"GET",contentType:"application/x-www-form-urlencoded",processData:true,async:true,xhr:A.XMLHttpRequest&&(A.location.protocol!=="file:"||!A.ActiveXObject)?function(){return new A.XMLHttpRequest}:function(){try{return new A.ActiveXObject("Microsoft.XMLHTTP")}catch(a){}},accepts:{xml:"application/xml, text/xml",html:"text/html",script:"text/javascript, application/javascript",json:"application/json, text/javascript",text:"text/plain",_default:"*/*"}},lastModified:{},etag:{} [...]
+e.success.call(k,o,i,x);e.global&&f("ajaxSuccess",[x,e])}function d(){e.complete&&e.complete.call(k,x,i);e.global&&f("ajaxComplete",[x,e]);e.global&&!--c.active&&c.event.trigger("ajaxStop")}function f(q,p){(e.context?c(e.context):c.event).trigger(q,p)}var e=c.extend(true,{},c.ajaxSettings,a),j,i,o,k=a&&a.context||e,n=e.type.toUpperCase();if(e.data&&e.processData&&typeof e.data!=="string")e.data=c.param(e.data,e.traditional);if(e.dataType==="jsonp"){if(n==="GET")N.test(e.url)||(e.url+=(ka [...]
+"&":"?")+(e.jsonp||"callback")+"=?");else if(!e.data||!N.test(e.data))e.data=(e.data?e.data+"&":"")+(e.jsonp||"callback")+"=?";e.dataType="json"}if(e.dataType==="json"&&(e.data&&N.test(e.data)||N.test(e.url))){j=e.jsonpCallback||"jsonp"+sb++;if(e.data)e.data=(e.data+"").replace(N,"="+j+"$1");e.url=e.url.replace(N,"="+j+"$1");e.dataType="script";A[j]=A[j]||function(q){o=q;b();d();A[j]=w;try{delete A[j]}catch(p){}z&&z.removeChild(C)}}if(e.dataType==="script"&&e.cache===null)e.cache=false;i [...]
+false&&n==="GET"){var r=J(),u=e.url.replace(wb,"$1_="+r+"$2");e.url=u+(u===e.url?(ka.test(e.url)?"&":"?")+"_="+r:"")}if(e.data&&n==="GET")e.url+=(ka.test(e.url)?"&":"?")+e.data;e.global&&!c.active++&&c.event.trigger("ajaxStart");r=(r=xb.exec(e.url))&&(r[1]&&r[1]!==location.protocol||r[2]!==location.host);if(e.dataType==="script"&&n==="GET"&&r){var z=s.getElementsByTagName("head")[0]||s.documentElement,C=s.createElement("script");C.src=e.url;if(e.scriptCharset)C.charset=e.scriptCharset;if [...]
+false;C.onload=C.onreadystatechange=function(){if(!B&&(!this.readyState||this.readyState==="loaded"||this.readyState==="complete")){B=true;b();d();C.onload=C.onreadystatechange=null;z&&C.parentNode&&z.removeChild(C)}}}z.insertBefore(C,z.firstChild);return w}var E=false,x=e.xhr();if(x){e.username?x.open(n,e.url,e.async,e.username,e.password):x.open(n,e.url,e.async);try{if(e.data||a&&a.contentType)x.setRequestHeader("Content-Type",e.contentType);if(e.ifModified){c.lastModified[e.url]&&x.se [...]
+c.lastModified[e.url]);c.etag[e.url]&&x.setRequestHeader("If-None-Match",c.etag[e.url])}r||x.setRequestHeader("X-Requested-With","XMLHttpRequest");x.setRequestHeader("Accept",e.dataType&&e.accepts[e.dataType]?e.accepts[e.dataType]+", */*":e.accepts._default)}catch(ga){}if(e.beforeSend&&e.beforeSend.call(k,x,e)===false){e.global&&!--c.active&&c.event.trigger("ajaxStop");x.abort();return false}e.global&&f("ajaxSend",[x,e]);var g=x.onreadystatechange=function(q){if(!x||x.readyState===0||q== [...]
+d();E=true;if(x)x.onreadystatechange=c.noop}else if(!E&&x&&(x.readyState===4||q==="timeout")){E=true;x.onreadystatechange=c.noop;i=q==="timeout"?"timeout":!c.httpSuccess(x)?"error":e.ifModified&&c.httpNotModified(x,e.url)?"notmodified":"success";var p;if(i==="success")try{o=c.httpData(x,e.dataType,e)}catch(v){i="parsererror";p=v}if(i==="success"||i==="notmodified")j||b();else c.handleError(e,x,i,p);d();q==="timeout"&&x.abort();if(e.async)x=null}};try{var h=x.abort;x.abort=function(){x&&h [...]
+g("abort")}}catch(l){}e.async&&e.timeout>0&&setTimeout(function(){x&&!E&&g("timeout")},e.timeout);try{x.send(n==="POST"||n==="PUT"||n==="DELETE"?e.data:null)}catch(m){c.handleError(e,x,null,m);d()}e.async||g();return x}},handleError:function(a,b,d,f){if(a.error)a.error.call(a.context||a,b,d,f);if(a.global)(a.context?c(a.context):c.event).trigger("ajaxError",[b,a,f])},active:0,httpSuccess:function(a){try{return!a.status&&location.protocol==="file:"||a.status>=200&&a.status<300||a.status== [...]
+1223||a.status===0}catch(b){}return false},httpNotModified:function(a,b){var d=a.getResponseHeader("Last-Modified"),f=a.getResponseHeader("Etag");if(d)c.lastModified[b]=d;if(f)c.etag[b]=f;return a.status===304||a.status===0},httpData:function(a,b,d){var f=a.getResponseHeader("content-type")||"",e=b==="xml"||!b&&f.indexOf("xml")>=0;a=e?a.responseXML:a.responseText;e&&a.documentElement.nodeName==="parsererror"&&c.error("parsererror");if(d&&d.dataFilter)a=d.dataFilter(a,b);if(typeof a==="st [...]
+"json"||!b&&f.indexOf("json")>=0)a=c.parseJSON(a);else if(b==="script"||!b&&f.indexOf("javascript")>=0)c.globalEval(a);return a},param:function(a,b){function d(i,o){if(c.isArray(o))c.each(o,function(k,n){b||/\[\]$/.test(i)?f(i,n):d(i+"["+(typeof n==="object"||c.isArray(n)?k:"")+"]",n)});else!b&&o!=null&&typeof o==="object"?c.each(o,function(k,n){d(i+"["+k+"]",n)}):f(i,o)}function f(i,o){o=c.isFunction(o)?o():o;e[e.length]=encodeURIComponent(i)+"="+encodeURIComponent(o)}var e=[];if(b===w) [...]
+if(c.isArray(a)||a.jquery)c.each(a,function(){f(this.name,this.value)});else for(var j in a)d(j,a[j]);return e.join("&").replace(yb,"+")}});var la={},Ab=/toggle|show|hide/,Bb=/^([+-]=)?([\d+-.]+)(.*)$/,W,va=[["height","marginTop","marginBottom","paddingTop","paddingBottom"],["width","marginLeft","marginRight","paddingLeft","paddingRight"],["opacity"]];c.fn.extend({show:function(a,b){if(a||a===0)return this.animate(K("show",3),a,b);else{a=0;for(b=this.length;a<b;a++){var d=c.data(this[a], [...]
+this[a].style.display=d||"";if(c.css(this[a],"display")==="none"){d=this[a].nodeName;var f;if(la[d])f=la[d];else{var e=c("<"+d+" />").appendTo("body");f=e.css("display");if(f==="none")f="block";e.remove();la[d]=f}c.data(this[a],"olddisplay",f)}}a=0;for(b=this.length;a<b;a++)this[a].style.display=c.data(this[a],"olddisplay")||"";return this}},hide:function(a,b){if(a||a===0)return this.animate(K("hide",3),a,b);else{a=0;for(b=this.length;a<b;a++){var d=c.data(this[a],"olddisplay");!d&&d!==" [...]
+"olddisplay",c.css(this[a],"display"))}a=0;for(b=this.length;a<b;a++)this[a].style.display="none";return this}},_toggle:c.fn.toggle,toggle:function(a,b){var d=typeof a==="boolean";if(c.isFunction(a)&&c.isFunction(b))this._toggle.apply(this,arguments);else a==null||d?this.each(function(){var f=d?a:c(this).is(":hidden");c(this)[f?"show":"hide"]()}):this.animate(K("toggle",3),a,b);return this},fadeTo:function(a,b,d){return this.filter(":hidden").css("opacity",0).show().end().animate({opacit [...]
+animate:function(a,b,d,f){var e=c.speed(b,d,f);if(c.isEmptyObject(a))return this.each(e.complete);return this[e.queue===false?"each":"queue"](function(){var j=c.extend({},e),i,o=this.nodeType===1&&c(this).is(":hidden"),k=this;for(i in a){var n=i.replace(ia,ja);if(i!==n){a[n]=a[i];delete a[i];i=n}if(a[i]==="hide"&&o||a[i]==="show"&&!o)return j.complete.call(this);if((i==="height"||i==="width")&&this.style){j.display=c.css(this,"display");j.overflow=this.style.overflow}if(c.isArray(a[i])){ [...]
+j.specialEasing||{})[i]=a[i][1];a[i]=a[i][0]}}if(j.overflow!=null)this.style.overflow="hidden";j.curAnim=c.extend({},a);c.each(a,function(r,u){var z=new c.fx(k,j,r);if(Ab.test(u))z[u==="toggle"?o?"show":"hide":u](a);else{var C=Bb.exec(u),B=z.cur(true)||0;if(C){u=parseFloat(C[2]);var E=C[3]||"px";if(E!=="px"){k.style[r]=(u||1)+E;B=(u||1)/z.cur(true)*B;k.style[r]=B+E}if(C[1])u=(C[1]==="-="?-1:1)*u+B;z.custom(B,u,E)}else z.custom(B,u,"")}});return true})},stop:function(a,b){var d=c.timers;a [...]
+this.each(function(){for(var f=d.length-1;f>=0;f--)if(d[f].elem===this){b&&d[f](true);d.splice(f,1)}});b||this.dequeue();return this}});c.each({slideDown:K("show",1),slideUp:K("hide",1),slideToggle:K("toggle",1),fadeIn:{opacity:"show"},fadeOut:{opacity:"hide"}},function(a,b){c.fn[a]=function(d,f){return this.animate(b,d,f)}});c.extend({speed:function(a,b,d){var f=a&&typeof a==="object"?a:{complete:d||!d&&b||c.isFunction(a)&&a,duration:a,easing:d&&b||b&&!c.isFunction(b)&&b};f.duration=c.f [...]
+"number"?f.duration:c.fx.speeds[f.duration]||c.fx.speeds._default;f.old=f.complete;f.complete=function(){f.queue!==false&&c(this).dequeue();c.isFunction(f.old)&&f.old.call(this)};return f},easing:{linear:function(a,b,d,f){return d+f*a},swing:function(a,b,d,f){return(-Math.cos(a*Math.PI)/2+0.5)*f+d}},timers:[],fx:function(a,b,d){this.options=b;this.elem=a;this.prop=d;if(!b.orig)b.orig={}}});c.fx.prototype={update:function(){this.options.step&&this.options.step.call(this.elem,this.now,this [...]
+c.fx.step._default)(this);if((this.prop==="height"||this.prop==="width")&&this.elem.style)this.elem.style.display="block"},cur:function(a){if(this.elem[this.prop]!=null&&(!this.elem.style||this.elem.style[this.prop]==null))return this.elem[this.prop];return(a=parseFloat(c.css(this.elem,this.prop,a)))&&a>-10000?a:parseFloat(c.curCSS(this.elem,this.prop))||0},custom:function(a,b,d){function f(j){return e.step(j)}this.startTime=J();this.start=a;this.end=b;this.unit=d||this.unit||"px";this.n [...]
+this.pos=this.state=0;var e=this;f.elem=this.elem;if(f()&&c.timers.push(f)&&!W)W=setInterval(c.fx.tick,13)},show:function(){this.options.orig[this.prop]=c.style(this.elem,this.prop);this.options.show=true;this.custom(this.prop==="width"||this.prop==="height"?1:0,this.cur());c(this.elem).show()},hide:function(){this.options.orig[this.prop]=c.style(this.elem,this.prop);this.options.hide=true;this.custom(this.cur(),0)},step:function(a){var b=J(),d=true;if(a||b>=this.options.duration+this.st [...]
+this.end;this.pos=this.state=1;this.update();this.options.curAnim[this.prop]=true;for(var f in this.options.curAnim)if(this.options.curAnim[f]!==true)d=false;if(d){if(this.options.display!=null){this.elem.style.overflow=this.options.overflow;a=c.data(this.elem,"olddisplay");this.elem.style.display=a?a:this.options.display;if(c.css(this.elem,"display")==="none")this.elem.style.display="block"}this.options.hide&&c(this.elem).hide();if(this.options.hide||this.options.show)for(var e in this. [...]
+e,this.options.orig[e]);this.options.complete.call(this.elem)}return false}else{e=b-this.startTime;this.state=e/this.options.duration;a=this.options.easing||(c.easing.swing?"swing":"linear");this.pos=c.easing[this.options.specialEasing&&this.options.specialEasing[this.prop]||a](this.state,e,0,1,this.options.duration);this.now=this.start+(this.end-this.start)*this.pos;this.update()}return true}};c.extend(c.fx,{tick:function(){for(var a=c.timers,b=0;b<a.length;b++)a[b]()||a.splice(b--,1);a [...]
+c.fx.stop()},stop:function(){clearInterval(W);W=null},speeds:{slow:600,fast:200,_default:400},step:{opacity:function(a){c.style(a.elem,"opacity",a.now)},_default:function(a){if(a.elem.style&&a.elem.style[a.prop]!=null)a.elem.style[a.prop]=(a.prop==="width"||a.prop==="height"?Math.max(0,a.now):a.now)+a.unit;else a.elem[a.prop]=a.now}}});if(c.expr&&c.expr.filters)c.expr.filters.animated=function(a){return c.grep(c.timers,function(b){return a===b.elem}).length};c.fn.offset="getBoundingClien [...]
+function(a){var b=this[0];if(a)return this.each(function(e){c.offset.setOffset(this,a,e)});if(!b||!b.ownerDocument)return null;if(b===b.ownerDocument.body)return c.offset.bodyOffset(b);var d=b.getBoundingClientRect(),f=b.ownerDocument;b=f.body;f=f.documentElement;return{top:d.top+(self.pageYOffset||c.support.boxModel&&f.scrollTop||b.scrollTop)-(f.clientTop||b.clientTop||0),left:d.left+(self.pageXOffset||c.support.boxModel&&f.scrollLeft||b.scrollLeft)-(f.clientLeft||b.clientLeft||0)}}:fun [...]
+this[0];if(a)return this.each(function(r){c.offset.setOffset(this,a,r)});if(!b||!b.ownerDocument)return null;if(b===b.ownerDocument.body)return c.offset.bodyOffset(b);c.offset.initialize();var d=b.offsetParent,f=b,e=b.ownerDocument,j,i=e.documentElement,o=e.body;f=(e=e.defaultView)?e.getComputedStyle(b,null):b.currentStyle;for(var k=b.offsetTop,n=b.offsetLeft;(b=b.parentNode)&&b!==o&&b!==i;){if(c.offset.supportsFixedPosition&&f.position==="fixed")break;j=e?e.getComputedStyle(b,null):b.cu [...]
+k-=b.scrollTop;n-=b.scrollLeft;if(b===d){k+=b.offsetTop;n+=b.offsetLeft;if(c.offset.doesNotAddBorder&&!(c.offset.doesAddBorderForTableAndCells&&/^t(able|d|h)$/i.test(b.nodeName))){k+=parseFloat(j.borderTopWidth)||0;n+=parseFloat(j.borderLeftWidth)||0}f=d;d=b.offsetParent}if(c.offset.subtractsBorderForOverflowNotVisible&&j.overflow!=="visible"){k+=parseFloat(j.borderTopWidth)||0;n+=parseFloat(j.borderLeftWidth)||0}f=j}if(f.position==="relative"||f.position==="static"){k+=o.offsetTop;n+=o. [...]
+f.position==="fixed"){k+=Math.max(i.scrollTop,o.scrollTop);n+=Math.max(i.scrollLeft,o.scrollLeft)}return{top:k,left:n}};c.offset={initialize:function(){var a=s.body,b=s.createElement("div"),d,f,e,j=parseFloat(c.curCSS(a,"marginTop",true))||0;c.extend(b.style,{position:"absolute",top:0,left:0,margin:0,border:0,width:"1px",height:"1px",visibility:"hidden"});b.innerHTML="<div style='position:absolute;top:0;left:0;margin:0;border:5px solid #000;padding:0;width:1px;height:1px;'><div></div></d [...]
+a.insertBefore(b,a.firstChild);d=b.firstChild;f=d.firstChild;e=d.nextSibling.firstChild.firstChild;this.doesNotAddBorder=f.offsetTop!==5;this.doesAddBorderForTableAndCells=e.offsetTop===5;f.style.position="fixed";f.style.top="20px";this.supportsFixedPosition=f.offsetTop===20||f.offsetTop===15;f.style.position=f.style.top="";d.style.overflow="hidden";d.style.position="relative";this.subtractsBorderForOverflowNotVisible=f.offsetTop===-5;this.doesNotIncludeMarginInBodyOffset=a.offsetTop!==j [...]
+c.offset.initialize=c.noop},bodyOffset:function(a){var b=a.offsetTop,d=a.offsetLeft;c.offset.initialize();if(c.offset.doesNotIncludeMarginInBodyOffset){b+=parseFloat(c.curCSS(a,"marginTop",true))||0;d+=parseFloat(c.curCSS(a,"marginLeft",true))||0}return{top:b,left:d}},setOffset:function(a,b,d){if(/static/.test(c.curCSS(a,"position")))a.style.position="relative";var f=c(a),e=f.offset(),j=parseInt(c.curCSS(a,"top",true),10)||0,i=parseInt(c.curCSS(a,"left",true),10)||0;if(c.isFunction(b))b= [...]
+d,e);d={top:b.top-e.top+j,left:b.left-e.left+i};"using"in b?b.using.call(a,d):f.css(d)}};c.fn.extend({position:function(){if(!this[0])return null;var a=this[0],b=this.offsetParent(),d=this.offset(),f=/^body|html$/i.test(b[0].nodeName)?{top:0,left:0}:b.offset();d.top-=parseFloat(c.curCSS(a,"marginTop",true))||0;d.left-=parseFloat(c.curCSS(a,"marginLeft",true))||0;f.top+=parseFloat(c.curCSS(b[0],"borderTopWidth",true))||0;f.left+=parseFloat(c.curCSS(b[0],"borderLeftWidth",true))||0;return{ [...]
+f.top,left:d.left-f.left}},offsetParent:function(){return this.map(function(){for(var a=this.offsetParent||s.body;a&&!/^body|html$/i.test(a.nodeName)&&c.css(a,"position")==="static";)a=a.offsetParent;return a})}});c.each(["Left","Top"],function(a,b){var d="scroll"+b;c.fn[d]=function(f){var e=this[0],j;if(!e)return null;if(f!==w)return this.each(function(){if(j=wa(this))j.scrollTo(!a?f:c(j).scrollLeft(),a?f:c(j).scrollTop());else this[d]=f});else return(j=wa(e))?"pageXOffset"in j?j[a?"pag [...]
+"pageXOffset"]:c.support.boxModel&&j.document.documentElement[d]||j.document.body[d]:e[d]}});c.each(["Height","Width"],function(a,b){var d=b.toLowerCase();c.fn["inner"+b]=function(){return this[0]?c.css(this[0],d,false,"padding"):null};c.fn["outer"+b]=function(f){return this[0]?c.css(this[0],d,false,f?"margin":"border"):null};c.fn[d]=function(f){var e=this[0];if(!e)return f==null?null:this;if(c.isFunction(f))return this.each(function(j){var i=c(this);i[d](f.call(this,j,i[d]()))});return" [...]
+e&&e.document?e.document.compatMode==="CSS1Compat"&&e.document.documentElement["client"+b]||e.document.body["client"+b]:e.nodeType===9?Math.max(e.documentElement["client"+b],e.body["scroll"+b],e.documentElement["scroll"+b],e.body["offset"+b],e.documentElement["offset"+b]):f===w?c.css(e,d):this.css(d,typeof f==="string"?f:f+"px")}});A.jQuery=A.$=c})(window);
diff --git a/phpmyadmin/doc/html/_static/minus.png b/phpmyadmin/doc/html/_static/minus.png
new file mode 100644
index 0000000..da1c562
Binary files /dev/null and b/phpmyadmin/doc/html/_static/minus.png differ
diff --git a/phpmyadmin/doc/html/_static/plus.png b/phpmyadmin/doc/html/_static/plus.png
new file mode 100644
index 0000000..b3cb374
Binary files /dev/null and b/phpmyadmin/doc/html/_static/plus.png differ
diff --git a/phpmyadmin/doc/html/_static/pygments.css b/phpmyadmin/doc/html/_static/pygments.css
new file mode 100644
index 0000000..1a14f2a
--- /dev/null
+++ b/phpmyadmin/doc/html/_static/pygments.css
@@ -0,0 +1,62 @@
+.highlight .hll { background-color: #ffffcc }
+.highlight  { background: #eeffcc; }
+.highlight .c { color: #408090; font-style: italic } /* Comment */
+.highlight .err { border: 1px solid #FF0000 } /* Error */
+.highlight .k { color: #007020; font-weight: bold } /* Keyword */
+.highlight .o { color: #666666 } /* Operator */
+.highlight .cm { color: #408090; font-style: italic } /* Comment.Multiline */
+.highlight .cp { color: #007020 } /* Comment.Preproc */
+.highlight .c1 { color: #408090; font-style: italic } /* Comment.Single */
+.highlight .cs { color: #408090; background-color: #fff0f0 } /* Comment.Special */
+.highlight .gd { color: #A00000 } /* Generic.Deleted */
+.highlight .ge { font-style: italic } /* Generic.Emph */
+.highlight .gr { color: #FF0000 } /* Generic.Error */
+.highlight .gh { color: #000080; font-weight: bold } /* Generic.Heading */
+.highlight .gi { color: #00A000 } /* Generic.Inserted */
+.highlight .go { color: #303030 } /* Generic.Output */
+.highlight .gp { color: #c65d09; font-weight: bold } /* Generic.Prompt */
+.highlight .gs { font-weight: bold } /* Generic.Strong */
+.highlight .gu { color: #800080; font-weight: bold } /* Generic.Subheading */
+.highlight .gt { color: #0040D0 } /* Generic.Traceback */
+.highlight .kc { color: #007020; font-weight: bold } /* Keyword.Constant */
+.highlight .kd { color: #007020; font-weight: bold } /* Keyword.Declaration */
+.highlight .kn { color: #007020; font-weight: bold } /* Keyword.Namespace */
+.highlight .kp { color: #007020 } /* Keyword.Pseudo */
+.highlight .kr { color: #007020; font-weight: bold } /* Keyword.Reserved */
+.highlight .kt { color: #902000 } /* Keyword.Type */
+.highlight .m { color: #208050 } /* Literal.Number */
+.highlight .s { color: #4070a0 } /* Literal.String */
+.highlight .na { color: #4070a0 } /* Name.Attribute */
+.highlight .nb { color: #007020 } /* Name.Builtin */
+.highlight .nc { color: #0e84b5; font-weight: bold } /* Name.Class */
+.highlight .no { color: #60add5 } /* Name.Constant */
+.highlight .nd { color: #555555; font-weight: bold } /* Name.Decorator */
+.highlight .ni { color: #d55537; font-weight: bold } /* Name.Entity */
+.highlight .ne { color: #007020 } /* Name.Exception */
+.highlight .nf { color: #06287e } /* Name.Function */
+.highlight .nl { color: #002070; font-weight: bold } /* Name.Label */
+.highlight .nn { color: #0e84b5; font-weight: bold } /* Name.Namespace */
+.highlight .nt { color: #062873; font-weight: bold } /* Name.Tag */
+.highlight .nv { color: #bb60d5 } /* Name.Variable */
+.highlight .ow { color: #007020; font-weight: bold } /* Operator.Word */
+.highlight .w { color: #bbbbbb } /* Text.Whitespace */
+.highlight .mf { color: #208050 } /* Literal.Number.Float */
+.highlight .mh { color: #208050 } /* Literal.Number.Hex */
+.highlight .mi { color: #208050 } /* Literal.Number.Integer */
+.highlight .mo { color: #208050 } /* Literal.Number.Oct */
+.highlight .sb { color: #4070a0 } /* Literal.String.Backtick */
+.highlight .sc { color: #4070a0 } /* Literal.String.Char */
+.highlight .sd { color: #4070a0; font-style: italic } /* Literal.String.Doc */
+.highlight .s2 { color: #4070a0 } /* Literal.String.Double */
+.highlight .se { color: #4070a0; font-weight: bold } /* Literal.String.Escape */
+.highlight .sh { color: #4070a0 } /* Literal.String.Heredoc */
+.highlight .si { color: #70a0d0; font-style: italic } /* Literal.String.Interpol */
+.highlight .sx { color: #c65d09 } /* Literal.String.Other */
+.highlight .sr { color: #235388 } /* Literal.String.Regex */
+.highlight .s1 { color: #4070a0 } /* Literal.String.Single */
+.highlight .ss { color: #517918 } /* Literal.String.Symbol */
+.highlight .bp { color: #007020 } /* Name.Builtin.Pseudo */
+.highlight .vc { color: #bb60d5 } /* Name.Variable.Class */
+.highlight .vg { color: #bb60d5 } /* Name.Variable.Global */
+.highlight .vi { color: #bb60d5 } /* Name.Variable.Instance */
+.highlight .il { color: #208050 } /* Literal.Number.Integer.Long */
\ No newline at end of file
diff --git a/phpmyadmin/doc/html/_static/searchtools.js b/phpmyadmin/doc/html/_static/searchtools.js
new file mode 100644
index 0000000..663be4c
--- /dev/null
+++ b/phpmyadmin/doc/html/_static/searchtools.js
@@ -0,0 +1,560 @@
+/*
+ * searchtools.js_t
+ * ~~~~~~~~~~~~~~~~
+ *
+ * Sphinx JavaScript utilties for the full-text search.
+ *
+ * :copyright: Copyright 2007-2011 by the Sphinx team, see AUTHORS.
+ * :license: BSD, see LICENSE for details.
+ *
+ */
+
+/**
+ * helper function to return a node containing the
+ * search summary for a given text. keywords is a list
+ * of stemmed words, hlwords is the list of normal, unstemmed
+ * words. the first one is used to find the occurance, the
+ * latter for highlighting it.
+ */
+
+jQuery.makeSearchSummary = function(text, keywords, hlwords) {
+  var textLower = text.toLowerCase();
+  var start = 0;
+  $.each(keywords, function() {
+    var i = textLower.indexOf(this.toLowerCase());
+    if (i > -1)
+      start = i;
+  });
+  start = Math.max(start - 120, 0);
+  var excerpt = ((start > 0) ? '...' : '') +
+  $.trim(text.substr(start, 240)) +
+  ((start + 240 - text.length) ? '...' : '');
+  var rv = $('<div class="context"></div>').text(excerpt);
+  $.each(hlwords, function() {
+    rv = rv.highlightText(this, 'highlighted');
+  });
+  return rv;
+}
+
+
+/**
+ * Porter Stemmer
+ */
+var Stemmer = function() {
+
+  var step2list = {
+    ational: 'ate',
+    tional: 'tion',
+    enci: 'ence',
+    anci: 'ance',
+    izer: 'ize',
+    bli: 'ble',
+    alli: 'al',
+    entli: 'ent',
+    eli: 'e',
+    ousli: 'ous',
+    ization: 'ize',
+    ation: 'ate',
+    ator: 'ate',
+    alism: 'al',
+    iveness: 'ive',
+    fulness: 'ful',
+    ousness: 'ous',
+    aliti: 'al',
+    iviti: 'ive',
+    biliti: 'ble',
+    logi: 'log'
+  };
+
+  var step3list = {
+    icate: 'ic',
+    ative: '',
+    alize: 'al',
+    iciti: 'ic',
+    ical: 'ic',
+    ful: '',
+    ness: ''
+  };
+
+  var c = "[^aeiou]";          // consonant
+  var v = "[aeiouy]";          // vowel
+  var C = c + "[^aeiouy]*";    // consonant sequence
+  var V = v + "[aeiou]*";      // vowel sequence
+
+  var mgr0 = "^(" + C + ")?" + V + C;                      // [C]VC... is m>0
+  var meq1 = "^(" + C + ")?" + V + C + "(" + V + ")?$";    // [C]VC[V] is m=1
+  var mgr1 = "^(" + C + ")?" + V + C + V + C;              // [C]VCVC... is m>1
+  var s_v   = "^(" + C + ")?" + v;                         // vowel in stem
+
+  this.stemWord = function (w) {
+    var stem;
+    var suffix;
+    var firstch;
+    var origword = w;
+
+    if (w.length < 3)
+      return w;
+
+    var re;
+    var re2;
+    var re3;
+    var re4;
+
+    firstch = w.substr(0,1);
+    if (firstch == "y")
+      w = firstch.toUpperCase() + w.substr(1);
+
+    // Step 1a
+    re = /^(.+?)(ss|i)es$/;
+    re2 = /^(.+?)([^s])s$/;
+
+    if (re.test(w))
+      w = w.replace(re,"$1$2");
+    else if (re2.test(w))
+      w = w.replace(re2,"$1$2");
+
+    // Step 1b
+    re = /^(.+?)eed$/;
+    re2 = /^(.+?)(ed|ing)$/;
+    if (re.test(w)) {
+      var fp = re.exec(w);
+      re = new RegExp(mgr0);
+      if (re.test(fp[1])) {
+        re = /.$/;
+        w = w.replace(re,"");
+      }
+    }
+    else if (re2.test(w)) {
+      var fp = re2.exec(w);
+      stem = fp[1];
+      re2 = new RegExp(s_v);
+      if (re2.test(stem)) {
+        w = stem;
+        re2 = /(at|bl|iz)$/;
+        re3 = new RegExp("([^aeiouylsz])\\1$");
+        re4 = new RegExp("^" + C + v + "[^aeiouwxy]$");
+        if (re2.test(w))
+          w = w + "e";
+        else if (re3.test(w)) {
+          re = /.$/;
+          w = w.replace(re,"");
+        }
+        else if (re4.test(w))
+          w = w + "e";
+      }
+    }
+
+    // Step 1c
+    re = /^(.+?)y$/;
+    if (re.test(w)) {
+      var fp = re.exec(w);
+      stem = fp[1];
+      re = new RegExp(s_v);
+      if (re.test(stem))
+        w = stem + "i";
+    }
+
+    // Step 2
+    re = /^(.+?)(ational|tional|enci|anci|izer|bli|alli|entli|eli|ousli|ization|ation|ator|alism|iveness|fulness|ousness|aliti|iviti|biliti|logi)$/;
+    if (re.test(w)) {
+      var fp = re.exec(w);
+      stem = fp[1];
+      suffix = fp[2];
+      re = new RegExp(mgr0);
+      if (re.test(stem))
+        w = stem + step2list[suffix];
+    }
+
+    // Step 3
+    re = /^(.+?)(icate|ative|alize|iciti|ical|ful|ness)$/;
+    if (re.test(w)) {
+      var fp = re.exec(w);
+      stem = fp[1];
+      suffix = fp[2];
+      re = new RegExp(mgr0);
+      if (re.test(stem))
+        w = stem + step3list[suffix];
+    }
+
+    // Step 4
+    re = /^(.+?)(al|ance|ence|er|ic|able|ible|ant|ement|ment|ent|ou|ism|ate|iti|ous|ive|ize)$/;
+    re2 = /^(.+?)(s|t)(ion)$/;
+    if (re.test(w)) {
+      var fp = re.exec(w);
+      stem = fp[1];
+      re = new RegExp(mgr1);
+      if (re.test(stem))
+        w = stem;
+    }
+    else if (re2.test(w)) {
+      var fp = re2.exec(w);
+      stem = fp[1] + fp[2];
+      re2 = new RegExp(mgr1);
+      if (re2.test(stem))
+        w = stem;
+    }
+
+    // Step 5
+    re = /^(.+?)e$/;
+    if (re.test(w)) {
+      var fp = re.exec(w);
+      stem = fp[1];
+      re = new RegExp(mgr1);
+      re2 = new RegExp(meq1);
+      re3 = new RegExp("^" + C + v + "[^aeiouwxy]$");
+      if (re.test(stem) || (re2.test(stem) && !(re3.test(stem))))
+        w = stem;
+    }
+    re = /ll$/;
+    re2 = new RegExp(mgr1);
+    if (re.test(w) && re2.test(w)) {
+      re = /.$/;
+      w = w.replace(re,"");
+    }
+
+    // and turn initial Y back to y
+    if (firstch == "y")
+      w = firstch.toLowerCase() + w.substr(1);
+    return w;
+  }
+}
+
+
+/**
+ * Search Module
+ */
+var Search = {
+
+  _index : null,
+  _queued_query : null,
+  _pulse_status : -1,
+
+  init : function() {
+      var params = $.getQueryParameters();
+      if (params.q) {
+          var query = params.q[0];
+          $('input[name="q"]')[0].value = query;
+          this.performSearch(query);
+      }
+  },
+
+  loadIndex : function(url) {
+    $.ajax({type: "GET", url: url, data: null, success: null,
+            dataType: "script", cache: true});
+  },
+
+  setIndex : function(index) {
+    var q;
+    this._index = index;
+    if ((q = this._queued_query) !== null) {
+      this._queued_query = null;
+      Search.query(q);
+    }
+  },
+
+  hasIndex : function() {
+      return this._index !== null;
+  },
+
+  deferQuery : function(query) {
+      this._queued_query = query;
+  },
+
+  stopPulse : function() {
+      this._pulse_status = 0;
+  },
+
+  startPulse : function() {
+    if (this._pulse_status >= 0)
+        return;
+    function pulse() {
+      Search._pulse_status = (Search._pulse_status + 1) % 4;
+      var dotString = '';
+      for (var i = 0; i < Search._pulse_status; i++)
+        dotString += '.';
+      Search.dots.text(dotString);
+      if (Search._pulse_status > -1)
+        window.setTimeout(pulse, 500);
+    };
+    pulse();
+  },
+
+  /**
+   * perform a search for something
+   */
+  performSearch : function(query) {
+    // create the required interface elements
+    this.out = $('#search-results');
+    this.title = $('<h2>' + _('Searching') + '</h2>').appendTo(this.out);
+    this.dots = $('<span></span>').appendTo(this.title);
+    this.status = $('<p style="display: none"></p>').appendTo(this.out);
+    this.output = $('<ul class="search"/>').appendTo(this.out);
+
+    $('#search-progress').text(_('Preparing search...'));
+    this.startPulse();
+
+    // index already loaded, the browser was quick!
+    if (this.hasIndex())
+      this.query(query);
+    else
+      this.deferQuery(query);
+  },
+
+  query : function(query) {
+    var stopwords = ["and","then","into","it","as","are","in","if","for","no","there","their","was","is","be","to","that","but","they","not","such","with","by","a","on","these","of","will","this","near","the","or","at"];
+
+    // Stem the searchterms and add them to the correct list
+    var stemmer = new Stemmer();
+    var searchterms = [];
+    var excluded = [];
+    var hlterms = [];
+    var tmp = query.split(/\s+/);
+    var objectterms = [];
+    for (var i = 0; i < tmp.length; i++) {
+      if (tmp[i] != "") {
+          objectterms.push(tmp[i].toLowerCase());
+      }
+
+      if ($u.indexOf(stopwords, tmp[i]) != -1 || tmp[i].match(/^\d+$/) ||
+          tmp[i] == "") {
+        // skip this "word"
+        continue;
+      }
+      // stem the word
+      var word = stemmer.stemWord(tmp[i]).toLowerCase();
+      // select the correct list
+      if (word[0] == '-') {
+        var toAppend = excluded;
+        word = word.substr(1);
+      }
+      else {
+        var toAppend = searchterms;
+        hlterms.push(tmp[i].toLowerCase());
+      }
+      // only add if not already in the list
+      if (!$.contains(toAppend, word))
+        toAppend.push(word);
+    };
+    var highlightstring = '?highlight=' + $.urlencode(hlterms.join(" "));
+
+    // console.debug('SEARCH: searching for:');
+    // console.info('required: ', searchterms);
+    // console.info('excluded: ', excluded);
+
+    // prepare search
+    var filenames = this._index.filenames;
+    var titles = this._index.titles;
+    var terms = this._index.terms;
+    var fileMap = {};
+    var files = null;
+    // different result priorities
+    var importantResults = [];
+    var objectResults = [];
+    var regularResults = [];
+    var unimportantResults = [];
+    $('#search-progress').empty();
+
+    // lookup as object
+    for (var i = 0; i < objectterms.length; i++) {
+      var others = [].concat(objectterms.slice(0,i),
+                             objectterms.slice(i+1, objectterms.length))
+      var results = this.performObjectSearch(objectterms[i], others);
+      // Assume first word is most likely to be the object,
+      // other words more likely to be in description.
+      // Therefore put matches for earlier words first.
+      // (Results are eventually used in reverse order).
+      objectResults = results[0].concat(objectResults);
+      importantResults = results[1].concat(importantResults);
+      unimportantResults = results[2].concat(unimportantResults);
+    }
+
+    // perform the search on the required terms
+    for (var i = 0; i < searchterms.length; i++) {
+      var word = searchterms[i];
+      // no match but word was a required one
+      if ((files = terms[word]) == null)
+        break;
+      if (files.length == undefined) {
+        files = [files];
+      }
+      // create the mapping
+      for (var j = 0; j < files.length; j++) {
+        var file = files[j];
+        if (file in fileMap)
+          fileMap[file].push(word);
+        else
+          fileMap[file] = [word];
+      }
+    }
+
+    // now check if the files don't contain excluded terms
+    for (var file in fileMap) {
+      var valid = true;
+
+      // check if all requirements are matched
+      if (fileMap[file].length != searchterms.length)
+        continue;
+
+      // ensure that none of the excluded terms is in the
+      // search result.
+      for (var i = 0; i < excluded.length; i++) {
+        if (terms[excluded[i]] == file ||
+            $.contains(terms[excluded[i]] || [], file)) {
+          valid = false;
+          break;
+        }
+      }
+
+      // if we have still a valid result we can add it
+      // to the result list
+      if (valid)
+        regularResults.push([filenames[file], titles[file], '', null]);
+    }
+
+    // delete unused variables in order to not waste
+    // memory until list is retrieved completely
+    delete filenames, titles, terms;
+
+    // now sort the regular results descending by title
+    regularResults.sort(function(a, b) {
+      var left = a[1].toLowerCase();
+      var right = b[1].toLowerCase();
+      return (left > right) ? -1 : ((left < right) ? 1 : 0);
+    });
+
+    // combine all results
+    var results = unimportantResults.concat(regularResults)
+      .concat(objectResults).concat(importantResults);
+
+    // print the results
+    var resultCount = results.length;
+    function displayNextItem() {
+      // results left, load the summary and display it
+      if (results.length) {
+        var item = results.pop();
+        var listItem = $('<li style="display:none"></li>');
+        if (DOCUMENTATION_OPTIONS.FILE_SUFFIX == '') {
+          // dirhtml builder
+          var dirname = item[0] + '/';
+          if (dirname.match(/\/index\/$/)) {
+            dirname = dirname.substring(0, dirname.length-6);
+          } else if (dirname == 'index/') {
+            dirname = '';
+          }
+          listItem.append($('<a/>').attr('href',
+            DOCUMENTATION_OPTIONS.URL_ROOT + dirname +
+            highlightstring + item[2]).html(item[1]));
+        } else {
+          // normal html builders
+          listItem.append($('<a/>').attr('href',
+            item[0] + DOCUMENTATION_OPTIONS.FILE_SUFFIX +
+            highlightstring + item[2]).html(item[1]));
+        }
+        if (item[3]) {
+          listItem.append($('<span> (' + item[3] + ')</span>'));
+          Search.output.append(listItem);
+          listItem.slideDown(5, function() {
+            displayNextItem();
+          });
+        } else if (DOCUMENTATION_OPTIONS.HAS_SOURCE) {
+          $.get(DOCUMENTATION_OPTIONS.URL_ROOT + '_sources/' +
+                item[0] + '.txt', function(data) {
+            if (data != '') {
+              listItem.append($.makeSearchSummary(data, searchterms, hlterms));
+              Search.output.append(listItem);
+            }
+            listItem.slideDown(5, function() {
+              displayNextItem();
+            });
+          }, "text");
+        } else {
+          // no source available, just display title
+          Search.output.append(listItem);
+          listItem.slideDown(5, function() {
+            displayNextItem();
+          });
+        }
+      }
+      // search finished, update title and status message
+      else {
+        Search.stopPulse();
+        Search.title.text(_('Search Results'));
+        if (!resultCount)
+          Search.status.text(_('Your search did not match any documents. Please make sure that all words are spelled correctly and that you\'ve selected enough categories.'));
+        else
+            Search.status.text(_('Search finished, found %s page(s) matching the search query.').replace('%s', resultCount));
+        Search.status.fadeIn(500);
+      }
+    }
+    displayNextItem();
+  },
+
+  performObjectSearch : function(object, otherterms) {
+    var filenames = this._index.filenames;
+    var objects = this._index.objects;
+    var objnames = this._index.objnames;
+    var titles = this._index.titles;
+
+    var importantResults = [];
+    var objectResults = [];
+    var unimportantResults = [];
+
+    for (var prefix in objects) {
+      for (var name in objects[prefix]) {
+        var fullname = (prefix ? prefix + '.' : '') + name;
+        if (fullname.toLowerCase().indexOf(object) > -1) {
+          var match = objects[prefix][name];
+          var objname = objnames[match[1]][2];
+          var title = titles[match[0]];
+          // If more than one term searched for, we require other words to be
+          // found in the name/title/description
+          if (otherterms.length > 0) {
+            var haystack = (prefix + ' ' + name + ' ' +
+                            objname + ' ' + title).toLowerCase();
+            var allfound = true;
+            for (var i = 0; i < otherterms.length; i++) {
+              if (haystack.indexOf(otherterms[i]) == -1) {
+                allfound = false;
+                break;
+              }
+            }
+            if (!allfound) {
+              continue;
+            }
+          }
+          var descr = objname + _(', in ') + title;
+          anchor = match[3];
+          if (anchor == '')
+            anchor = fullname;
+          else if (anchor == '-')
+            anchor = objnames[match[1]][1] + '-' + fullname;
+          result = [filenames[match[0]], fullname, '#'+anchor, descr];
+          switch (match[2]) {
+          case 1: objectResults.push(result); break;
+          case 0: importantResults.push(result); break;
+          case 2: unimportantResults.push(result); break;
+          }
+        }
+      }
+    }
+
+    // sort results descending
+    objectResults.sort(function(a, b) {
+      return (a[1] > b[1]) ? -1 : ((a[1] < b[1]) ? 1 : 0);
+    });
+
+    importantResults.sort(function(a, b) {
+      return (a[1] > b[1]) ? -1 : ((a[1] < b[1]) ? 1 : 0);
+    });
+
+    unimportantResults.sort(function(a, b) {
+      return (a[1] > b[1]) ? -1 : ((a[1] < b[1]) ? 1 : 0);
+    });
+
+    return [importantResults, objectResults, unimportantResults]
+  }
+}
+
+$(document).ready(function() {
+  Search.init();
+});
\ No newline at end of file
diff --git a/phpmyadmin/doc/html/_static/sidebar.js b/phpmyadmin/doc/html/_static/sidebar.js
new file mode 100644
index 0000000..a45e192
--- /dev/null
+++ b/phpmyadmin/doc/html/_static/sidebar.js
@@ -0,0 +1,151 @@
+/*
+ * sidebar.js
+ * ~~~~~~~~~~
+ *
+ * This script makes the Sphinx sidebar collapsible.
+ *
+ * .sphinxsidebar contains .sphinxsidebarwrapper.  This script adds
+ * in .sphixsidebar, after .sphinxsidebarwrapper, the #sidebarbutton
+ * used to collapse and expand the sidebar.
+ *
+ * When the sidebar is collapsed the .sphinxsidebarwrapper is hidden
+ * and the width of the sidebar and the margin-left of the document
+ * are decreased. When the sidebar is expanded the opposite happens.
+ * This script saves a per-browser/per-session cookie used to
+ * remember the position of the sidebar among the pages.
+ * Once the browser is closed the cookie is deleted and the position
+ * reset to the default (expanded).
+ *
+ * :copyright: Copyright 2007-2011 by the Sphinx team, see AUTHORS.
+ * :license: BSD, see LICENSE for details.
+ *
+ */
+
+$(function() {
+  // global elements used by the functions.
+  // the 'sidebarbutton' element is defined as global after its
+  // creation, in the add_sidebar_button function
+  var bodywrapper = $('.bodywrapper');
+  var sidebar = $('.sphinxsidebar');
+  var sidebarwrapper = $('.sphinxsidebarwrapper');
+
+  // for some reason, the document has no sidebar; do not run into errors
+  if (!sidebar.length) return;
+
+  // original margin-left of the bodywrapper and width of the sidebar
+  // with the sidebar expanded
+  var bw_margin_expanded = bodywrapper.css('margin-left');
+  var ssb_width_expanded = sidebar.width();
+
+  // margin-left of the bodywrapper and width of the sidebar
+  // with the sidebar collapsed
+  var bw_margin_collapsed = '.8em';
+  var ssb_width_collapsed = '.8em';
+
+  // colors used by the current theme
+  var dark_color = $('.related').css('background-color');
+  var light_color = $('.document').css('background-color');
+
+  function sidebar_is_collapsed() {
+    return sidebarwrapper.is(':not(:visible)');
+  }
+
+  function toggle_sidebar() {
+    if (sidebar_is_collapsed())
+      expand_sidebar();
+    else
+      collapse_sidebar();
+  }
+
+  function collapse_sidebar() {
+    sidebarwrapper.hide();
+    sidebar.css('width', ssb_width_collapsed);
+    bodywrapper.css('margin-left', bw_margin_collapsed);
+    sidebarbutton.css({
+        'margin-left': '0',
+        'height': bodywrapper.height()
+    });
+    sidebarbutton.find('span').text('»');
+    sidebarbutton.attr('title', _('Expand sidebar'));
+    document.cookie = 'sidebar=collapsed';
+  }
+
+  function expand_sidebar() {
+    bodywrapper.css('margin-left', bw_margin_expanded);
+    sidebar.css('width', ssb_width_expanded);
+    sidebarwrapper.show();
+    sidebarbutton.css({
+        'margin-left': ssb_width_expanded-12,
+        'height': bodywrapper.height()
+    });
+    sidebarbutton.find('span').text('«');
+    sidebarbutton.attr('title', _('Collapse sidebar'));
+    document.cookie = 'sidebar=expanded';
+  }
+
+  function add_sidebar_button() {
+    sidebarwrapper.css({
+        'float': 'left',
+        'margin-right': '0',
+        'width': ssb_width_expanded - 28
+    });
+    // create the button
+    sidebar.append(
+        '<div id="sidebarbutton"><span>«</span></div>'
+    );
+    var sidebarbutton = $('#sidebarbutton');
+    light_color = sidebarbutton.css('background-color');
+    // find the height of the viewport to center the '<<' in the page
+    var viewport_height;
+    if (window.innerHeight)
+ 	  viewport_height = window.innerHeight;
+    else
+	  viewport_height = $(window).height();
+    sidebarbutton.find('span').css({
+        'display': 'block',
+        'margin-top': (viewport_height - sidebar.position().top - 20) / 2
+    });
+
+    sidebarbutton.click(toggle_sidebar);
+    sidebarbutton.attr('title', _('Collapse sidebar'));
+    sidebarbutton.css({
+        'color': '#FFFFFF',
+        'border-left': '1px solid ' + dark_color,
+        'font-size': '1.2em',
+        'cursor': 'pointer',
+        'height': bodywrapper.height(),
+        'padding-top': '1px',
+        'margin-left': ssb_width_expanded - 12
+    });
+
+    sidebarbutton.hover(
+      function () {
+          $(this).css('background-color', dark_color);
+      },
+      function () {
+          $(this).css('background-color', light_color);
+      }
+    );
+  }
+
+  function set_position_from_cookie() {
+    if (!document.cookie)
+      return;
+    var items = document.cookie.split(';');
+    for(var k=0; k<items.length; k++) {
+      var key_val = items[k].split('=');
+      var key = key_val[0];
+      if (key == 'sidebar') {
+        var value = key_val[1];
+        if ((value == 'collapsed') && (!sidebar_is_collapsed()))
+          collapse_sidebar();
+        else if ((value == 'expanded') && (sidebar_is_collapsed()))
+          expand_sidebar();
+      }
+    }
+  }
+
+  add_sidebar_button();
+  var sidebarbutton = $('#sidebarbutton');
+  set_position_from_cookie();
+});
diff --git a/phpmyadmin/doc/html/_static/underscore.js b/phpmyadmin/doc/html/_static/underscore.js
new file mode 100644
index 0000000..5d89914
--- /dev/null
+++ b/phpmyadmin/doc/html/_static/underscore.js
@@ -0,0 +1,23 @@
+// Underscore.js 0.5.5
+// (c) 2009 Jeremy Ashkenas, DocumentCloud Inc.
+// Underscore is freely distributable under the terms of the MIT license.
+// Portions of Underscore are inspired by or borrowed from Prototype.js,
+// Oliver Steele's Functional, and John Resig's Micro-Templating.
+// For all details and documentation:
+// http://documentcloud.github.com/underscore/
+(function(){var j=this,n=j._,i=function(a){this._wrapped=a},m=typeof StopIteration!=="undefined"?StopIteration:"__break__",b=j._=function(a){return new i(a)};if(typeof exports!=="undefined")exports._=b;var k=Array.prototype.slice,o=Array.prototype.unshift,p=Object.prototype.toString,q=Object.prototype.hasOwnProperty,r=Object.prototype.propertyIsEnumerable;b.VERSION="0.5.5";b.each=function(a,c,d){try{if(a.forEach)a.forEach(c,d);else if(b.isArray(a)||b.isArguments(a))for(var e=0,f=a.length [...]
+a[e],e,a);else{var g=b.keys(a);f=g.length;for(e=0;e<f;e++)c.call(d,a[g[e]],g[e],a)}}catch(h){if(h!=m)throw h;}return a};b.map=function(a,c,d){if(a&&b.isFunction(a.map))return a.map(c,d);var e=[];b.each(a,function(f,g,h){e.push(c.call(d,f,g,h))});return e};b.reduce=function(a,c,d,e){if(a&&b.isFunction(a.reduce))return a.reduce(b.bind(d,e),c);b.each(a,function(f,g,h){c=d.call(e,c,f,g,h)});return c};b.reduceRight=function(a,c,d,e){if(a&&b.isFunction(a.reduceRight))return a.reduceRight(b.bin [...]
+var f=b.clone(b.toArray(a)).reverse();b.each(f,function(g,h){c=d.call(e,c,g,h,a)});return c};b.detect=function(a,c,d){var e;b.each(a,function(f,g,h){if(c.call(d,f,g,h)){e=f;b.breakLoop()}});return e};b.select=function(a,c,d){if(a&&b.isFunction(a.filter))return a.filter(c,d);var e=[];b.each(a,function(f,g,h){c.call(d,f,g,h)&&e.push(f)});return e};b.reject=function(a,c,d){var e=[];b.each(a,function(f,g,h){!c.call(d,f,g,h)&&e.push(f)});return e};b.all=function(a,c,d){c=c||b.identity;if(a&&b [...]
+d);var e=true;b.each(a,function(f,g,h){(e=e&&c.call(d,f,g,h))||b.breakLoop()});return e};b.any=function(a,c,d){c=c||b.identity;if(a&&b.isFunction(a.some))return a.some(c,d);var e=false;b.each(a,function(f,g,h){if(e=c.call(d,f,g,h))b.breakLoop()});return e};b.include=function(a,c){if(b.isArray(a))return b.indexOf(a,c)!=-1;var d=false;b.each(a,function(e){if(d=e===c)b.breakLoop()});return d};b.invoke=function(a,c){var d=b.rest(arguments,2);return b.map(a,function(e){return(c?e[c]:e).apply( [...]
+function(a,c){return b.map(a,function(d){return d[c]})};b.max=function(a,c,d){if(!c&&b.isArray(a))return Math.max.apply(Math,a);var e={computed:-Infinity};b.each(a,function(f,g,h){g=c?c.call(d,f,g,h):f;g>=e.computed&&(e={value:f,computed:g})});return e.value};b.min=function(a,c,d){if(!c&&b.isArray(a))return Math.min.apply(Math,a);var e={computed:Infinity};b.each(a,function(f,g,h){g=c?c.call(d,f,g,h):f;g<e.computed&&(e={value:f,computed:g})});return e.value};b.sortBy=function(a,c,d){retur [...]
+function(e,f,g){return{value:e,criteria:c.call(d,e,f,g)}}).sort(function(e,f){e=e.criteria;f=f.criteria;return e<f?-1:e>f?1:0}),"value")};b.sortedIndex=function(a,c,d){d=d||b.identity;for(var e=0,f=a.length;e<f;){var g=e+f>>1;d(a[g])<d(c)?(e=g+1):(f=g)}return e};b.toArray=function(a){if(!a)return[];if(a.toArray)return a.toArray();if(b.isArray(a))return a;if(b.isArguments(a))return k.call(a);return b.values(a)};b.size=function(a){return b.toArray(a).length};b.first=function(a,c,d){return  [...]
+0,c):a[0]};b.rest=function(a,c,d){return k.call(a,b.isUndefined(c)||d?1:c)};b.last=function(a){return a[a.length-1]};b.compact=function(a){return b.select(a,function(c){return!!c})};b.flatten=function(a){return b.reduce(a,[],function(c,d){if(b.isArray(d))return c.concat(b.flatten(d));c.push(d);return c})};b.without=function(a){var c=b.rest(arguments);return b.select(a,function(d){return!b.include(c,d)})};b.uniq=function(a,c){return b.reduce(a,[],function(d,e,f){if(0==f||(c===true?b.last( [...]
+e)))d.push(e);return d})};b.intersect=function(a){var c=b.rest(arguments);return b.select(b.uniq(a),function(d){return b.all(c,function(e){return b.indexOf(e,d)>=0})})};b.zip=function(){for(var a=b.toArray(arguments),c=b.max(b.pluck(a,"length")),d=new Array(c),e=0;e<c;e++)d[e]=b.pluck(a,String(e));return d};b.indexOf=function(a,c){if(a.indexOf)return a.indexOf(c);for(var d=0,e=a.length;d<e;d++)if(a[d]===c)return d;return-1};b.lastIndexOf=function(a,c){if(a.lastIndexOf)return a.lastIndexO [...]
+a.length;d--;)if(a[d]===c)return d;return-1};b.range=function(a,c,d){var e=b.toArray(arguments),f=e.length<=1;a=f?0:e[0];c=f?e[0]:e[1];d=e[2]||1;e=Math.ceil((c-a)/d);if(e<=0)return[];e=new Array(e);f=a;for(var g=0;1;f+=d){if((d>0?f-c:c-f)>=0)return e;e[g++]=f}};b.bind=function(a,c){var d=b.rest(arguments,2);return function(){return a.apply(c||j,d.concat(b.toArray(arguments)))}};b.bindAll=function(a){var c=b.rest(arguments);if(c.length==0)c=b.functions(a);b.each(c,function(d){a[d]=b.bind( [...]
+return a};b.delay=function(a,c){var d=b.rest(arguments,2);return setTimeout(function(){return a.apply(a,d)},c)};b.defer=function(a){return b.delay.apply(b,[a,1].concat(b.rest(arguments)))};b.wrap=function(a,c){return function(){var d=[a].concat(b.toArray(arguments));return c.apply(c,d)}};b.compose=function(){var a=b.toArray(arguments);return function(){for(var c=b.toArray(arguments),d=a.length-1;d>=0;d--)c=[a[d].apply(this,c)];return c[0]}};b.keys=function(a){if(b.isArray(a))return b.ran [...]
+var c=[];for(var d in a)q.call(a,d)&&c.push(d);return c};b.values=function(a){return b.map(a,b.identity)};b.functions=function(a){return b.select(b.keys(a),function(c){return b.isFunction(a[c])}).sort()};b.extend=function(a,c){for(var d in c)a[d]=c[d];return a};b.clone=function(a){if(b.isArray(a))return a.slice(0);return b.extend({},a)};b.tap=function(a,c){c(a);return a};b.isEqual=function(a,c){if(a===c)return true;var d=typeof a;if(d!=typeof c)return false;if(a==c)return true;if(!a&&c|| [...]
+if(a.isEqual)return a.isEqual(c);if(b.isDate(a)&&b.isDate(c))return a.getTime()===c.getTime();if(b.isNaN(a)&&b.isNaN(c))return true;if(b.isRegExp(a)&&b.isRegExp(c))return a.source===c.source&&a.global===c.global&&a.ignoreCase===c.ignoreCase&&a.multiline===c.multiline;if(d!=="object")return false;if(a.length&&a.length!==c.length)return false;d=b.keys(a);var e=b.keys(c);if(d.length!=e.length)return false;for(var f in a)if(!b.isEqual(a[f],c[f]))return false;return true};b.isEmpty=function(a [...]
+0};b.isElement=function(a){return!!(a&&a.nodeType==1)};b.isArray=function(a){return!!(a&&a.concat&&a.unshift)};b.isArguments=function(a){return a&&b.isNumber(a.length)&&!b.isArray(a)&&!r.call(a,"length")};b.isFunction=function(a){return!!(a&&a.constructor&&a.call&&a.apply)};b.isString=function(a){return!!(a===""||a&&a.charCodeAt&&a.substr)};b.isNumber=function(a){return p.call(a)==="[object Number]"};b.isDate=function(a){return!!(a&&a.getTimezoneOffset&&a.setUTCFullYear)};b.isRegExp=func [...]
+a.test&&a.exec&&(a.ignoreCase||a.ignoreCase===false))};b.isNaN=function(a){return b.isNumber(a)&&isNaN(a)};b.isNull=function(a){return a===null};b.isUndefined=function(a){return typeof a=="undefined"};b.noConflict=function(){j._=n;return this};b.identity=function(a){return a};b.breakLoop=function(){throw m;};var s=0;b.uniqueId=function(a){var c=s++;return a?a+c:c};b.template=function(a,c){a=new Function("obj","var p=[],print=function(){p.push.apply(p,arguments);};with(obj){p.push('"+a.re [...]
+" ").replace(/'(?=[^%]*%>)/g,"\t").split("'").join("\\'").split("\t").join("'").replace(/<%=(.+?)%>/g,"',$1,'").split("<%").join("');").split("%>").join("p.push('")+"');}return p.join('');");return c?a(c):a};b.forEach=b.each;b.foldl=b.inject=b.reduce;b.foldr=b.reduceRight;b.filter=b.select;b.every=b.all;b.some=b.any;b.head=b.first;b.tail=b.rest;b.methods=b.functions;var l=function(a,c){return c?b(a).chain():a};b.each(b.functions(b),function(a){var c=b[a];i.prototype[a]=function(){var d=b [...]
+o.call(d,this._wrapped);return l(c.apply(b,d),this._chain)}});b.each(["pop","push","reverse","shift","sort","splice","unshift"],function(a){var c=Array.prototype[a];i.prototype[a]=function(){c.apply(this._wrapped,arguments);return l(this._wrapped,this._chain)}});b.each(["concat","join","slice"],function(a){var c=Array.prototype[a];i.prototype[a]=function(){return l(c.apply(this._wrapped,arguments),this._chain)}});i.prototype.chain=function(){this._chain=true;return this};i.prototype.valu [...]
diff --git a/phpmyadmin/doc/html/_static/up-pressed.png b/phpmyadmin/doc/html/_static/up-pressed.png
new file mode 100644
index 0000000..8bd587a
Binary files /dev/null and b/phpmyadmin/doc/html/_static/up-pressed.png differ
diff --git a/phpmyadmin/doc/html/_static/up.png b/phpmyadmin/doc/html/_static/up.png
new file mode 100644
index 0000000..b946256
Binary files /dev/null and b/phpmyadmin/doc/html/_static/up.png differ
diff --git a/phpmyadmin/doc/html/_static/websupport.js b/phpmyadmin/doc/html/_static/websupport.js
new file mode 100644
index 0000000..e9bd1b8
--- /dev/null
+++ b/phpmyadmin/doc/html/_static/websupport.js
@@ -0,0 +1,808 @@
+/*
+ * websupport.js
+ * ~~~~~~~~~~~~~
+ *
+ * sphinx.websupport utilties for all documentation.
+ *
+ * :copyright: Copyright 2007-2011 by the Sphinx team, see AUTHORS.
+ * :license: BSD, see LICENSE for details.
+ *
+ */
+
+(function($) {
+  $.fn.autogrow = function() {
+    return this.each(function() {
+    var textarea = this;
+
+    $.fn.autogrow.resize(textarea);
+
+    $(textarea)
+      .focus(function() {
+        textarea.interval = setInterval(function() {
+          $.fn.autogrow.resize(textarea);
+        }, 500);
+      })
+      .blur(function() {
+        clearInterval(textarea.interval);
+      });
+    });
+  };
+
+  $.fn.autogrow.resize = function(textarea) {
+    var lineHeight = parseInt($(textarea).css('line-height'), 10);
+    var lines = textarea.value.split('\n');
+    var columns = textarea.cols;
+    var lineCount = 0;
+    $.each(lines, function() {
+      lineCount += Math.ceil(this.length / columns) || 1;
+    });
+    var height = lineHeight * (lineCount + 1);
+    $(textarea).css('height', height);
+  };
+})(jQuery);
+
+(function($) {
+  var comp, by;
+
+  function init() {
+    initEvents();
+    initComparator();
+  }
+
+  function initEvents() {
+    $('a.comment-close').live("click", function(event) {
+      event.preventDefault();
+      hide($(this).attr('id').substring(2));
+    });
+    $('a.vote').live("click", function(event) {
+      event.preventDefault();
+      handleVote($(this));
+    });
+    $('a.reply').live("click", function(event) {
+      event.preventDefault();
+      openReply($(this).attr('id').substring(2));
+    });
+    $('a.close-reply').live("click", function(event) {
+      event.preventDefault();
+      closeReply($(this).attr('id').substring(2));
+    });
+    $('a.sort-option').live("click", function(event) {
+      event.preventDefault();
+      handleReSort($(this));
+    });
+    $('a.show-proposal').live("click", function(event) {
+      event.preventDefault();
+      showProposal($(this).attr('id').substring(2));
+    });
+    $('a.hide-proposal').live("click", function(event) {
+      event.preventDefault();
+      hideProposal($(this).attr('id').substring(2));
+    });
+    $('a.show-propose-change').live("click", function(event) {
+      event.preventDefault();
+      showProposeChange($(this).attr('id').substring(2));
+    });
+    $('a.hide-propose-change').live("click", function(event) {
+      event.preventDefault();
+      hideProposeChange($(this).attr('id').substring(2));
+    });
+    $('a.accept-comment').live("click", function(event) {
+      event.preventDefault();
+      acceptComment($(this).attr('id').substring(2));
+    });
+    $('a.delete-comment').live("click", function(event) {
+      event.preventDefault();
+      deleteComment($(this).attr('id').substring(2));
+    });
+    $('a.comment-markup').live("click", function(event) {
+      event.preventDefault();
+      toggleCommentMarkupBox($(this).attr('id').substring(2));
+    });
+  }
+
+  /**
+   * Set comp, which is a comparator function used for sorting and
+   * inserting comments into the list.
+   */
+  function setComparator() {
+    // If the first three letters are "asc", sort in ascending order
+    // and remove the prefix.
+    if (by.substring(0,3) == 'asc') {
+      var i = by.substring(3);
+      comp = function(a, b) { return a[i] - b[i]; };
+    } else {
+      // Otherwise sort in descending order.
+      comp = function(a, b) { return b[by] - a[by]; };
+    }
+
+    // Reset link styles and format the selected sort option.
+    $('a.sel').attr('href', '#').removeClass('sel');
+    $('a.by' + by).removeAttr('href').addClass('sel');
+  }
+
+  /**
+   * Create a comp function. If the user has preferences stored in
+   * the sortBy cookie, use those, otherwise use the default.
+   */
+  function initComparator() {
+    by = 'rating'; // Default to sort by rating.
+    // If the sortBy cookie is set, use that instead.
+    if (document.cookie.length > 0) {
+      var start = document.cookie.indexOf('sortBy=');
+      if (start != -1) {
+        start = start + 7;
+        var end = document.cookie.indexOf(";", start);
+        if (end == -1) {
+          end = document.cookie.length;
+          by = unescape(document.cookie.substring(start, end));
+        }
+      }
+    }
+    setComparator();
+  }
+
+  /**
+   * Show a comment div.
+   */
+  function show(id) {
+    $('#ao' + id).hide();
+    $('#ah' + id).show();
+    var context = $.extend({id: id}, opts);
+    var popup = $(renderTemplate(popupTemplate, context)).hide();
+    popup.find('textarea[name="proposal"]').hide();
+    popup.find('a.by' + by).addClass('sel');
+    var form = popup.find('#cf' + id);
+    form.submit(function(event) {
+      event.preventDefault();
+      addComment(form);
+    });
+    $('#s' + id).after(popup);
+    popup.slideDown('fast', function() {
+      getComments(id);
+    });
+  }
+
+  /**
+   * Hide a comment div.
+   */
+  function hide(id) {
+    $('#ah' + id).hide();
+    $('#ao' + id).show();
+    var div = $('#sc' + id);
+    div.slideUp('fast', function() {
+      div.remove();
+    });
+  }
+
+  /**
+   * Perform an ajax request to get comments for a node
+   * and insert the comments into the comments tree.
+   */
+  function getComments(id) {
+    $.ajax({
+     type: 'GET',
+     url: opts.getCommentsURL,
+     data: {node: id},
+     success: function(data, textStatus, request) {
+       var ul = $('#cl' + id);
+       var speed = 100;
+       $('#cf' + id)
+         .find('textarea[name="proposal"]')
+         .data('source', data.source);
+
+       if (data.comments.length === 0) {
+         ul.html('<li>No comments yet.</li>');
+         ul.data('empty', true);
+       } else {
+         // If there are comments, sort them and put them in the list.
+         var comments = sortComments(data.comments);
+         speed = data.comments.length * 100;
+         appendComments(comments, ul);
+         ul.data('empty', false);
+       }
+       $('#cn' + id).slideUp(speed + 200);
+       ul.slideDown(speed);
+     },
+     error: function(request, textStatus, error) {
+       showError('Oops, there was a problem retrieving the comments.');
+     },
+     dataType: 'json'
+    });
+  }
+
+  /**
+   * Add a comment via ajax and insert the comment into the comment tree.
+   */
+  function addComment(form) {
+    var node_id = form.find('input[name="node"]').val();
+    var parent_id = form.find('input[name="parent"]').val();
+    var text = form.find('textarea[name="comment"]').val();
+    var proposal = form.find('textarea[name="proposal"]').val();
+
+    if (text == '') {
+      showError('Please enter a comment.');
+      return;
+    }
+
+    // Disable the form that is being submitted.
+    form.find('textarea,input').attr('disabled', 'disabled');
+
+    // Send the comment to the server.
+    $.ajax({
+      type: "POST",
+      url: opts.addCommentURL,
+      dataType: 'json',
+      data: {
+        node: node_id,
+        parent: parent_id,
+        text: text,
+        proposal: proposal
+      },
+      success: function(data, textStatus, error) {
+        // Reset the form.
+        if (node_id) {
+          hideProposeChange(node_id);
+        }
+        form.find('textarea')
+          .val('')
+          .add(form.find('input'))
+          .removeAttr('disabled');
+	var ul = $('#cl' + (node_id || parent_id));
+        if (ul.data('empty')) {
+          $(ul).empty();
+          ul.data('empty', false);
+        }
+        insertComment(data.comment);
+        var ao = $('#ao' + node_id);
+        ao.find('img').attr({'src': opts.commentBrightImage});
+        if (node_id) {
+          // if this was a "root" comment, remove the commenting box
+          // (the user can get it back by reopening the comment popup)
+          $('#ca' + node_id).slideUp();
+        }
+      },
+      error: function(request, textStatus, error) {
+        form.find('textarea,input').removeAttr('disabled');
+        showError('Oops, there was a problem adding the comment.');
+      }
+    });
+  }
+
+  /**
+   * Recursively append comments to the main comment list and children
+   * lists, creating the comment tree.
+   */
+  function appendComments(comments, ul) {
+    $.each(comments, function() {
+      var div = createCommentDiv(this);
+      ul.append($(document.createElement('li')).html(div));
+      appendComments(this.children, div.find('ul.comment-children'));
+      // To avoid stagnating data, don't store the comments children in data.
+      this.children = null;
+      div.data('comment', this);
+    });
+  }
+
+  /**
+   * After adding a new comment, it must be inserted in the correct
+   * location in the comment tree.
+   */
+  function insertComment(comment) {
+    var div = createCommentDiv(comment);
+
+    // To avoid stagnating data, don't store the comments children in data.
+    comment.children = null;
+    div.data('comment', comment);
+
+    var ul = $('#cl' + (comment.node || comment.parent));
+    var siblings = getChildren(ul);
+
+    var li = $(document.createElement('li'));
+    li.hide();
+
+    // Determine where in the parents children list to insert this comment.
+    for(i=0; i < siblings.length; i++) {
+      if (comp(comment, siblings[i]) <= 0) {
+        $('#cd' + siblings[i].id)
+          .parent()
+          .before(li.html(div));
+        li.slideDown('fast');
+        return;
+      }
+    }
+
+    // If we get here, this comment rates lower than all the others,
+    // or it is the only comment in the list.
+    ul.append(li.html(div));
+    li.slideDown('fast');
+  }
+
+  function acceptComment(id) {
+    $.ajax({
+      type: 'POST',
+      url: opts.acceptCommentURL,
+      data: {id: id},
+      success: function(data, textStatus, request) {
+        $('#cm' + id).fadeOut('fast');
+        $('#cd' + id).removeClass('moderate');
+      },
+      error: function(request, textStatus, error) {
+        showError('Oops, there was a problem accepting the comment.');
+      }
+    });
+  }
+
+  function deleteComment(id) {
+    $.ajax({
+      type: 'POST',
+      url: opts.deleteCommentURL,
+      data: {id: id},
+      success: function(data, textStatus, request) {
+        var div = $('#cd' + id);
+        if (data == 'delete') {
+          // Moderator mode: remove the comment and all children immediately
+          div.slideUp('fast', function() {
+            div.remove();
+          });
+          return;
+        }
+        // User mode: only mark the comment as deleted
+        div
+          .find('span.user-id:first')
+          .text('[deleted]').end()
+          .find('div.comment-text:first')
+          .text('[deleted]').end()
+          .find('#cm' + id + ', #dc' + id + ', #ac' + id + ', #rc' + id +
+                ', #sp' + id + ', #hp' + id + ', #cr' + id + ', #rl' + id)
+          .remove();
+        var comment = div.data('comment');
+        comment.username = '[deleted]';
+        comment.text = '[deleted]';
+        div.data('comment', comment);
+      },
+      error: function(request, textStatus, error) {
+        showError('Oops, there was a problem deleting the comment.');
+      }
+    });
+  }
+
+  function showProposal(id) {
+    $('#sp' + id).hide();
+    $('#hp' + id).show();
+    $('#pr' + id).slideDown('fast');
+  }
+
+  function hideProposal(id) {
+    $('#hp' + id).hide();
+    $('#sp' + id).show();
+    $('#pr' + id).slideUp('fast');
+  }
+
+  function showProposeChange(id) {
+    $('#pc' + id).hide();
+    $('#hc' + id).show();
+    var textarea = $('#pt' + id);
+    textarea.val(textarea.data('source'));
+    $.fn.autogrow.resize(textarea[0]);
+    textarea.slideDown('fast');
+  }
+
+  function hideProposeChange(id) {
+    $('#hc' + id).hide();
+    $('#pc' + id).show();
+    var textarea = $('#pt' + id);
+    textarea.val('').removeAttr('disabled');
+    textarea.slideUp('fast');
+  }
+
+  function toggleCommentMarkupBox(id) {
+    $('#mb' + id).toggle();
+  }
+
+  /** Handle when the user clicks on a sort by link. */
+  function handleReSort(link) {
+    var classes = link.attr('class').split(/\s+/);
+    for (var i=0; i<classes.length; i++) {
+      if (classes[i] != 'sort-option') {
+	by = classes[i].substring(2);
+      }
+    }
+    setComparator();
+    // Save/update the sortBy cookie.
+    var expiration = new Date();
+    expiration.setDate(expiration.getDate() + 365);
+    document.cookie= 'sortBy=' + escape(by) +
+                     ';expires=' + expiration.toUTCString();
+    $('ul.comment-ul').each(function(index, ul) {
+      var comments = getChildren($(ul), true);
+      comments = sortComments(comments);
+      appendComments(comments, $(ul).empty());
+    });
+  }
+
+  /**
+   * Function to process a vote when a user clicks an arrow.
+   */
+  function handleVote(link) {
+    if (!opts.voting) {
+      showError("You'll need to login to vote.");
+      return;
+    }
+
+    var id = link.attr('id');
+    if (!id) {
+      // Didn't click on one of the voting arrows.
+      return;
+    }
+    // If it is an unvote, the new vote value is 0,
+    // Otherwise it's 1 for an upvote, or -1 for a downvote.
+    var value = 0;
+    if (id.charAt(1) != 'u') {
+      value = id.charAt(0) == 'u' ? 1 : -1;
+    }
+    // The data to be sent to the server.
+    var d = {
+      comment_id: id.substring(2),
+      value: value
+    };
+
+    // Swap the vote and unvote links.
+    link.hide();
+    $('#' + id.charAt(0) + (id.charAt(1) == 'u' ? 'v' : 'u') + d.comment_id)
+      .show();
+
+    // The div the comment is displayed in.
+    var div = $('div#cd' + d.comment_id);
+    var data = div.data('comment');
+
+    // If this is not an unvote, and the other vote arrow has
+    // already been pressed, unpress it.
+    if ((d.value !== 0) && (data.vote === d.value * -1)) {
+      $('#' + (d.value == 1 ? 'd' : 'u') + 'u' + d.comment_id).hide();
+      $('#' + (d.value == 1 ? 'd' : 'u') + 'v' + d.comment_id).show();
+    }
+
+    // Update the comments rating in the local data.
+    data.rating += (data.vote === 0) ? d.value : (d.value - data.vote);
+    data.vote = d.value;
+    div.data('comment', data);
+
+    // Change the rating text.
+    div.find('.rating:first')
+      .text(data.rating + ' point' + (data.rating == 1 ? '' : 's'));
+
+    // Send the vote information to the server.
+    $.ajax({
+      type: "POST",
+      url: opts.processVoteURL,
+      data: d,
+      error: function(request, textStatus, error) {
+        showError('Oops, there was a problem casting that vote.');
+      }
+    });
+  }
+
+  /**
+   * Open a reply form used to reply to an existing comment.
+   */
+  function openReply(id) {
+    // Swap out the reply link for the hide link
+    $('#rl' + id).hide();
+    $('#cr' + id).show();
+
+    // Add the reply li to the children ul.
+    var div = $(renderTemplate(replyTemplate, {id: id})).hide();
+    $('#cl' + id)
+      .prepend(div)
+      // Setup the submit handler for the reply form.
+      .find('#rf' + id)
+      .submit(function(event) {
+        event.preventDefault();
+        addComment($('#rf' + id));
+        closeReply(id);
+      })
+      .find('input[type=button]')
+      .click(function() {
+        closeReply(id);
+      });
+    div.slideDown('fast', function() {
+      $('#rf' + id).find('textarea').focus();
+    });
+  }
+
+  /**
+   * Close the reply form opened with openReply.
+   */
+  function closeReply(id) {
+    // Remove the reply div from the DOM.
+    $('#rd' + id).slideUp('fast', function() {
+      $(this).remove();
+    });
+
+    // Swap out the hide link for the reply link
+    $('#cr' + id).hide();
+    $('#rl' + id).show();
+  }
+
+  /**
+   * Recursively sort a tree of comments using the comp comparator.
+   */
+  function sortComments(comments) {
+    comments.sort(comp);
+    $.each(comments, function() {
+      this.children = sortComments(this.children);
+    });
+    return comments;
+  }
+
+  /**
+   * Get the children comments from a ul. If recursive is true,
+   * recursively include childrens' children.
+   */
+  function getChildren(ul, recursive) {
+    var children = [];
+    ul.children().children("[id^='cd']")
+      .each(function() {
+        var comment = $(this).data('comment');
+        if (recursive)
+          comment.children = getChildren($(this).find('#cl' + comment.id), true);
+        children.push(comment);
+      });
+    return children;
+  }
+
+  /** Create a div to display a comment in. */
+  function createCommentDiv(comment) {
+    if (!comment.displayed && !opts.moderator) {
+      return $('<div class="moderate">Thank you!  Your comment will show up '
+               + 'once it is has been approved by a moderator.</div>');
+    }
+    // Prettify the comment rating.
+    comment.pretty_rating = comment.rating + ' point' +
+      (comment.rating == 1 ? '' : 's');
+    // Make a class (for displaying not yet moderated comments differently)
+    comment.css_class = comment.displayed ? '' : ' moderate';
+    // Create a div for this comment.
+    var context = $.extend({}, opts, comment);
+    var div = $(renderTemplate(commentTemplate, context));
+
+    // If the user has voted on this comment, highlight the correct arrow.
+    if (comment.vote) {
+      var direction = (comment.vote == 1) ? 'u' : 'd';
+      div.find('#' + direction + 'v' + comment.id).hide();
+      div.find('#' + direction + 'u' + comment.id).show();
+    }
+
+    if (opts.moderator || comment.text != '[deleted]') {
+      div.find('a.reply').show();
+      if (comment.proposal_diff)
+        div.find('#sp' + comment.id).show();
+      if (opts.moderator && !comment.displayed)
+        div.find('#cm' + comment.id).show();
+      if (opts.moderator || (opts.username == comment.username))
+        div.find('#dc' + comment.id).show();
+    }
+    return div;
+  }
+
+  /**
+   * A simple template renderer. Placeholders such as <%id%> are replaced
+   * by context['id'] with items being escaped. Placeholders such as <#id#>
+   * are not escaped.
+   */
+  function renderTemplate(template, context) {
+    var esc = $(document.createElement('div'));
+
+    function handle(ph, escape) {
+      var cur = context;
+      $.each(ph.split('.'), function() {
+        cur = cur[this];
+      });
+      return escape ? esc.text(cur || "").html() : cur;
+    }
+
+    return template.replace(/<([%#])([\w\.]*)\1>/g, function() {
+      return handle(arguments[2], arguments[1] == '%' ? true : false);
+    });
+  }
+
+  /** Flash an error message briefly. */
+  function showError(message) {
+    $(document.createElement('div')).attr({'class': 'popup-error'})
+      .append($(document.createElement('div'))
+               .attr({'class': 'error-message'}).text(message))
+      .appendTo('body')
+      .fadeIn("slow")
+      .delay(2000)
+      .fadeOut("slow");
+  }
+
+  /** Add a link the user uses to open the comments popup. */
+  $.fn.comment = function() {
+    return this.each(function() {
+      var id = $(this).attr('id').substring(1);
+      var count = COMMENT_METADATA[id];
+      var title = count + ' comment' + (count == 1 ? '' : 's');
+      var image = count > 0 ? opts.commentBrightImage : opts.commentImage;
+      var addcls = count == 0 ? ' nocomment' : '';
+      $(this)
+        .append(
+          $(document.createElement('a')).attr({
+            href: '#',
+            'class': 'sphinx-comment-open' + addcls,
+            id: 'ao' + id
+          })
+            .append($(document.createElement('img')).attr({
+              src: image,
+              alt: 'comment',
+              title: title
+            }))
+            .click(function(event) {
+              event.preventDefault();
+              show($(this).attr('id').substring(2));
+            })
+        )
+        .append(
+          $(document.createElement('a')).attr({
+            href: '#',
+            'class': 'sphinx-comment-close hidden',
+            id: 'ah' + id
+          })
+            .append($(document.createElement('img')).attr({
+              src: opts.closeCommentImage,
+              alt: 'close',
+              title: 'close'
+            }))
+            .click(function(event) {
+              event.preventDefault();
+              hide($(this).attr('id').substring(2));
+            })
+        );
+    });
+  };
+
+  var opts = {
+    processVoteURL: '/_process_vote',
+    addCommentURL: '/_add_comment',
+    getCommentsURL: '/_get_comments',
+    acceptCommentURL: '/_accept_comment',
+    deleteCommentURL: '/_delete_comment',
+    commentImage: '/static/_static/comment.png',
+    closeCommentImage: '/static/_static/comment-close.png',
+    loadingImage: '/static/_static/ajax-loader.gif',
+    commentBrightImage: '/static/_static/comment-bright.png',
+    upArrow: '/static/_static/up.png',
+    downArrow: '/static/_static/down.png',
+    upArrowPressed: '/static/_static/up-pressed.png',
+    downArrowPressed: '/static/_static/down-pressed.png',
+    voting: false,
+    moderator: false
+  };
+
+  if (typeof COMMENT_OPTIONS != "undefined") {
+    opts = jQuery.extend(opts, COMMENT_OPTIONS);
+  }
+
+  var popupTemplate = '\
+    <div class="sphinx-comments" id="sc<%id%>">\
+      <p class="sort-options">\
+        Sort by:\
+        <a href="#" class="sort-option byrating">best rated</a>\
+        <a href="#" class="sort-option byascage">newest</a>\
+        <a href="#" class="sort-option byage">oldest</a>\
+      </p>\
+      <div class="comment-header">Comments</div>\
+      <div class="comment-loading" id="cn<%id%>">\
+        loading comments... <img src="<%loadingImage%>" alt="" /></div>\
+      <ul id="cl<%id%>" class="comment-ul"></ul>\
+      <div id="ca<%id%>">\
+      <p class="add-a-comment">Add a comment\
+        (<a href="#" class="comment-markup" id="ab<%id%>">markup</a>):</p>\
+      <div class="comment-markup-box" id="mb<%id%>">\
+        reStructured text markup: <i>*emph*</i>, <b>**strong**</b>, \
+        <tt>``code``</tt>, \
+        code blocks: <tt>::</tt> and an indented block after blank line</div>\
+      <form method="post" id="cf<%id%>" class="comment-form" action="">\
+        <textarea name="comment" cols="80"></textarea>\
+        <p class="propose-button">\
+          <a href="#" id="pc<%id%>" class="show-propose-change">\
+            Propose a change ▹\
+          </a>\
+          <a href="#" id="hc<%id%>" class="hide-propose-change">\
+            Propose a change ▿\
+          </a>\
+        </p>\
+        <textarea name="proposal" id="pt<%id%>" cols="80"\
+                  spellcheck="false"></textarea>\
+        <input type="submit" value="Add comment" />\
+        <input type="hidden" name="node" value="<%id%>" />\
+        <input type="hidden" name="parent" value="" />\
+      </form>\
+      </div>\
+    </div>';
+
+  var commentTemplate = '\
+    <div id="cd<%id%>" class="sphinx-comment<%css_class%>">\
+      <div class="vote">\
+        <div class="arrow">\
+          <a href="#" id="uv<%id%>" class="vote" title="vote up">\
+            <img src="<%upArrow%>" />\
+          </a>\
+          <a href="#" id="uu<%id%>" class="un vote" title="vote up">\
+            <img src="<%upArrowPressed%>" />\
+          </a>\
+        </div>\
+        <div class="arrow">\
+          <a href="#" id="dv<%id%>" class="vote" title="vote down">\
+            <img src="<%downArrow%>" id="da<%id%>" />\
+          </a>\
+          <a href="#" id="du<%id%>" class="un vote" title="vote down">\
+            <img src="<%downArrowPressed%>" />\
+          </a>\
+        </div>\
+      </div>\
+      <div class="comment-content">\
+        <p class="tagline comment">\
+          <span class="user-id"><%username%></span>\
+          <span class="rating"><%pretty_rating%></span>\
+          <span class="delta"><%time.delta%></span>\
+        </p>\
+        <div class="comment-text comment"><#text#></div>\
+        <p class="comment-opts comment">\
+          <a href="#" class="reply hidden" id="rl<%id%>">reply ▹</a>\
+          <a href="#" class="close-reply" id="cr<%id%>">reply ▿</a>\
+          <a href="#" id="sp<%id%>" class="show-proposal">proposal ▹</a>\
+          <a href="#" id="hp<%id%>" class="hide-proposal">proposal ▿</a>\
+          <a href="#" id="dc<%id%>" class="delete-comment hidden">delete</a>\
+          <span id="cm<%id%>" class="moderation hidden">\
+            <a href="#" id="ac<%id%>" class="accept-comment">accept</a>\
+          </span>\
+        </p>\
+        <pre class="proposal" id="pr<%id%>">\
+<#proposal_diff#>\
+        </pre>\
+          <ul class="comment-children" id="cl<%id%>"></ul>\
+        </div>\
+        <div class="clearleft"></div>\
+      </div>\
+    </div>';
+
+  var replyTemplate = '\
+    <li>\
+      <div class="reply-div" id="rd<%id%>">\
+        <form id="rf<%id%>">\
+          <textarea name="comment" cols="80"></textarea>\
+          <input type="submit" value="Add reply" />\
+          <input type="button" value="Cancel" />\
+          <input type="hidden" name="parent" value="<%id%>" />\
+          <input type="hidden" name="node" value="" />\
+        </form>\
+      </div>\
+    </li>';
+
+  $(document).ready(function() {
+    init();
+  });
+})(jQuery);
+
+$(document).ready(function() {
+  // add comment anchors for all paragraphs that are commentable
+  $('.sphinx-has-comment').comment();
+
+  // highlight search words in search results
+  $("div.context").each(function() {
+    var params = $.getQueryParameters();
+    var terms = (params.q) ? params.q[0].split(/\s+/) : [];
+    var result = $(this);
+    $.each(terms, function() {
+      result.highlightText(this.toLowerCase(), 'highlighted');
+    });
+  });
+
+  // directly open comment window if requested
+  var anchor = document.location.hash;
+  if (anchor.substring(0, 9) == '#comment-') {
+    $('#ao' + anchor.substring(9)).click();
+    document.location.hash = '#s' + anchor.substring(9);
+  }
+});
diff --git a/phpmyadmin/doc/html/config.html b/phpmyadmin/doc/html/config.html
new file mode 100644
index 0000000..9646bdf
--- /dev/null
+++ b/phpmyadmin/doc/html/config.html
@@ -0,0 +1,4896 @@
+
+
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+
+
+<html xmlns="http://www.w3.org/1999/xhtml">
+  <head>
+    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+    
+    <title>Configuration — phpMyAdmin 4.0.4 documentation</title>
+    
+    <link rel="stylesheet" href="_static/default.css" type="text/css" />
+    <link rel="stylesheet" href="_static/pygments.css" type="text/css" />
+    
+    <script type="text/javascript">
+      var DOCUMENTATION_OPTIONS = {
+        URL_ROOT:    '',
+        VERSION:     '4.0.4',
+        COLLAPSE_INDEX: false,
+        FILE_SUFFIX: '.html',
+        HAS_SOURCE:  true
+      };
+    </script>
+    <script type="text/javascript" src="_static/jquery.js"></script>
+    <script type="text/javascript" src="_static/underscore.js"></script>
+    <script type="text/javascript" src="_static/doctools.js"></script>
+    <link rel="copyright" title="Copyright" href="copyright.html" />
+    <link rel="top" title="phpMyAdmin 4.0.4 documentation" href="index.html" />
+    <link rel="next" title="User Guide" href="user.html" />
+    <link rel="prev" title="Installation" href="setup.html" /> 
+  </head>
+  <body>
+    <div class="related">
+      <h3>Navigation</h3>
+      <ul>
+        <li class="right" style="margin-right: 10px">
+          <a href="genindex.html" title="General Index"
+             accesskey="I">index</a></li>
+        <li class="right" >
+          <a href="user.html" title="User Guide"
+             accesskey="N">next</a> |</li>
+        <li class="right" >
+          <a href="setup.html" title="Installation"
+             accesskey="P">previous</a> |</li>
+        <li><a href="index.html">phpMyAdmin 4.0.4 documentation</a> »</li> 
+      </ul>
+    </div>  
+
+    <div class="document">
+      <div class="documentwrapper">
+        <div class="bodywrapper">
+          <div class="body">
+            
+  <div class="section" id="configuration">
+<span id="config"></span><span id="index-0"></span><h1>Configuration<a class="headerlink" href="#configuration" title="Permalink to this headline">¶</a></h1>
+<p>Almost all configurable data is placed in <tt class="file docutils literal"><span class="pre">config.inc.php</span></tt>. If this file
+does not exist, please refer to the <a class="reference internal" href="setup.html#setup"><em>Installation</em></a> section to create one. This
+file only needs to contain the parameters you want to change from their
+corresponding default value in <tt class="file docutils literal"><span class="pre">libraries/config.default.php</span></tt>.</p>
+<p>The parameters which relate to design (like colors) are placed in
+<tt class="file docutils literal"><span class="pre">themes/themename/layout.inc.php</span></tt>. You might also want to create
+<tt class="file docutils literal"><span class="pre">config.footer.inc.php</span></tt> and <tt class="file docutils literal"><span class="pre">config.header.inc.php</span></tt> files to add
+your site specific code to be included on start and end of each page.</p>
+<div class="admonition note">
+<p class="first admonition-title">Note</p>
+<p class="last">Some distributions (eg. Debian or Ubuntu) store <tt class="file docutils literal"><span class="pre">config.inc.php</span></tt> in
+<tt class="docutils literal"><span class="pre">/etc/phpmyadmin</span></tt> instead of within phpMyAdmin sources.</p>
+</div>
+<div class="admonition warning">
+<p class="first admonition-title">Warning</p>
+<p class="last"><a class="reference internal" href="glossary.html#term-mac"><em class="xref std std-term">Mac</em></a> users should note that if you are on a version before
+<a class="reference internal" href="glossary.html#term-mac-os-x"><em class="xref std std-term">Mac OS X</em></a>, PHP does not seem to
+like <a class="reference internal" href="glossary.html#term-mac"><em class="xref std std-term">Mac</em></a> end of lines character (<tt class="docutils literal"><span class="pre">\r</span></tt>). So
+ensure you choose the option that allows to use the *nix end of line
+character (<tt class="docutils literal"><span class="pre">\n</span></tt>) in your text editor before saving a script you have
+modified.</p>
+</div>
+<div class="section" id="basic-settings">
+<h2>Basic settings<a class="headerlink" href="#basic-settings" title="Permalink to this headline">¶</a></h2>
+<dl class="option">
+<dt id="cfg_PmaAbsoluteUri">
+<tt class="descname">$cfg['PmaAbsoluteUri']</tt><a class="headerlink" href="#cfg_PmaAbsoluteUri" title="Permalink to this definition">¶</a></dt>
+<dd><table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Type:</th><td class="field-body">string</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Default value:</th><td class="field-body"><tt class="docutils literal"><span class="pre">''</span></tt></td>
+</tr>
+</tbody>
+</table>
+<p>Sets here the complete <a class="reference internal" href="glossary.html#term-url"><em class="xref std std-term">URL</em></a> (with full path) to your phpMyAdmin
+installation’s directory. E.g.
+<tt class="docutils literal"><span class="pre">http://www.example.net/path_to_your_phpMyAdmin_directory/</span></tt>.  Note also
+that the <a class="reference internal" href="glossary.html#term-url"><em class="xref std std-term">URL</em></a> on some web servers are case–sensitive. Don’t forget
+the trailing slash at the end.</p>
+<p>Starting with version 2.3.0, it is advisable to try leaving this blank. In
+most cases phpMyAdmin automatically detects the proper setting. Users of
+port forwarding will need to set <span class="target" id="index-1"></span><a class="reference internal" href="#cfg_PmaAbsoluteUri"><tt class="xref config config-option docutils literal"><span class="pre">$cfg['PmaAbsoluteUri']</span></tt></a>
+(<a class="reference external" href="https://sourceforge.net/p/phpmyadmin/support-requests/795/">more info</a>).</p>
+<p>A good test is to browse a table, edit a row and save it. There should be
+an error message if phpMyAdmin is having trouble auto–detecting the correct
+value. If you get an error that this must be set or if the autodetect code
+fails to detect your path, please post a bug report on our bug tracker so
+we can improve the code.</p>
+<div class="admonition-see-also admonition seealso">
+<p class="first admonition-title">See also</p>
+<p class="last"><a class="reference internal" href="faq.html#faq1-40"><em>1.40 When accessing phpMyAdmin via an Apache reverse proxy, cookie login does not work.</em></a></p>
+</div>
+</dd></dl>
+
+<dl class="option">
+<dt id="cfg_PmaNoRelation_DisableWarning">
+<tt class="descname">$cfg['PmaNoRelation_DisableWarning']</tt><a class="headerlink" href="#cfg_PmaNoRelation_DisableWarning" title="Permalink to this definition">¶</a></dt>
+<dd><table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Type:</th><td class="field-body">boolean</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Default value:</th><td class="field-body">false</td>
+</tr>
+</tbody>
+</table>
+<p>Starting with version 2.3.0 phpMyAdmin offers a lot of features to
+work with master / foreign – tables (see <span class="target" id="index-2"></span><a class="reference internal" href="#cfg_Servers_pmadb"><tt class="xref config config-option docutils literal"><span class="pre">$cfg['Servers'][$i]['pmadb']</span></tt></a>).</p>
+<p>If you tried to set this
+up and it does not work for you, have a look on the <em class="guilabel">Structure</em> page
+of one database where you would like to use it. You will find a link
+that will analyze why those features have been disabled.</p>
+<p>If you do not want to use those features set this variable to <tt class="docutils literal"><span class="pre">true</span></tt> to
+stop this message from appearing.</p>
+</dd></dl>
+
+<dl class="option">
+<dt id="cfg_SuhosinDisableWarning">
+<tt class="descname">$cfg['SuhosinDisableWarning']</tt><a class="headerlink" href="#cfg_SuhosinDisableWarning" title="Permalink to this definition">¶</a></dt>
+<dd><table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Type:</th><td class="field-body">boolean</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Default value:</th><td class="field-body">false</td>
+</tr>
+</tbody>
+</table>
+<p>A warning is displayed on the main page if Suhosin is detected.</p>
+<p>You can set this parameter to <tt class="docutils literal"><span class="pre">true</span></tt> to stop this message from appearing.</p>
+</dd></dl>
+
+<dl class="option">
+<dt id="cfg_McryptDisableWarning">
+<tt class="descname">$cfg['McryptDisableWarning']</tt><a class="headerlink" href="#cfg_McryptDisableWarning" title="Permalink to this definition">¶</a></dt>
+<dd><table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Type:</th><td class="field-body">boolean</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Default value:</th><td class="field-body">false</td>
+</tr>
+</tbody>
+</table>
+<p>Disable the default warning that is displayed if mcrypt is missing for
+cookie authentication.</p>
+<p>You can set this parameter to <tt class="docutils literal"><span class="pre">true</span></tt> to stop this message from appearing.</p>
+</dd></dl>
+
+<dl class="option">
+<dt id="cfg_ServerLibraryDifference_DisableWarning">
+<tt class="descname">$cfg['ServerLibraryDifference_DisableWarning']</tt><a class="headerlink" href="#cfg_ServerLibraryDifference_DisableWarning" title="Permalink to this definition">¶</a></dt>
+<dd><table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Type:</th><td class="field-body">boolean</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Default value:</th><td class="field-body">false</td>
+</tr>
+</tbody>
+</table>
+<p>A warning is displayed on the main page if there is a difference
+between the MySQL library and server version.</p>
+<p>You can set this parameter to <tt class="docutils literal"><span class="pre">true</span></tt> to stop this message from appearing.</p>
+</dd></dl>
+
+<dl class="option">
+<dt id="cfg_ReservedWordDisableWarning">
+<tt class="descname">$cfg['ReservedWordDisableWarning']</tt><a class="headerlink" href="#cfg_ReservedWordDisableWarning" title="Permalink to this definition">¶</a></dt>
+<dd><table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Type:</th><td class="field-body">boolean</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Default value:</th><td class="field-body">false</td>
+</tr>
+</tbody>
+</table>
+<p>This warning is displayed on the Structure page of a table if one or more
+column names match with words which are MySQL reserved.</p>
+<p>If you want to turn off this warning, you can set it to <tt class="docutils literal"><span class="pre">true</span></tt> and
+warning will not longer be displayed</p>
+</dd></dl>
+
+<dl class="option">
+<dt id="cfg_TranslationWarningThreshold">
+<tt class="descname">$cfg['TranslationWarningThreshold']</tt><a class="headerlink" href="#cfg_TranslationWarningThreshold" title="Permalink to this definition">¶</a></dt>
+<dd><table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Type:</th><td class="field-body">integer</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Default value:</th><td class="field-body">80</td>
+</tr>
+</tbody>
+</table>
+<p>Show warning about incomplete translations on certain threshold.</p>
+</dd></dl>
+
+</div>
+<div class="section" id="server-connection-settings">
+<h2>Server connection settings<a class="headerlink" href="#server-connection-settings" title="Permalink to this headline">¶</a></h2>
+<dl class="option">
+<dt id="cfg_Servers">
+<tt class="descname">$cfg['Servers']</tt><a class="headerlink" href="#cfg_Servers" title="Permalink to this definition">¶</a></dt>
+<dd><table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Type:</th><td class="field-body">array</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Default value:</th><td class="field-body">one server array with settings listed bellow</td>
+</tr>
+</tbody>
+</table>
+<p>Since version 1.4.2, phpMyAdmin supports the administration of multiple
+MySQL servers. Therefore, a <span class="target" id="index-3"></span><a class="reference internal" href="#cfg_Servers"><tt class="xref config config-option docutils literal"><span class="pre">$cfg['Servers']</span></tt></a>-array has been
+added which contains the login information for the different servers. The
+first <span class="target" id="index-4"></span><a class="reference internal" href="#cfg_Servers_host"><tt class="xref config config-option docutils literal"><span class="pre">$cfg['Servers'][$i]['host']</span></tt></a> contains the hostname of
+the first server, the second <span class="target" id="index-5"></span><a class="reference internal" href="#cfg_Servers_host"><tt class="xref config config-option docutils literal"><span class="pre">$cfg['Servers'][$i]['host']</span></tt></a>
+the hostname of the second server, etc. In
+<tt class="file docutils literal"><span class="pre">libraries/config.default.php</span></tt>, there is only one section for server
+definition, however you can put as many as you need in
+<tt class="file docutils literal"><span class="pre">config.inc.php</span></tt>, copy that block or needed parts (you don’t have to
+define all settings, just those you need to change).</p>
+<div class="admonition note">
+<p class="first admonition-title">Note</p>
+<p class="last">The <span class="target" id="index-6"></span><a class="reference internal" href="#cfg_Servers"><tt class="xref config config-option docutils literal"><span class="pre">$cfg['Servers']</span></tt></a> array starts with
+$cfg[‘Servers’][1]. Do not use $cfg[‘Servers’][0]. If you want more
+than one server, just copy following section (including $i
+incrementation) serveral times. There is no need to define full server
+array, just define values you need to change.</p>
+</div>
+</dd></dl>
+
+<dl class="option">
+<dt id="cfg_Servers_host">
+<tt class="descname">$cfg['Servers'][$i]['host']</tt><a class="headerlink" href="#cfg_Servers_host" title="Permalink to this definition">¶</a></dt>
+<dd><table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Type:</th><td class="field-body">string</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Default value:</th><td class="field-body"><tt class="docutils literal"><span class="pre">'localhost'</span></tt></td>
+</tr>
+</tbody>
+</table>
+<p>The hostname or <a class="reference internal" href="glossary.html#term-ip"><em class="xref std std-term">IP</em></a> address of your $i-th MySQL-server. E.g.
+<tt class="docutils literal"><span class="pre">localhost</span></tt>.</p>
+<p>Possible values are:</p>
+<ul class="simple">
+<li>hostname, e.g., <tt class="docutils literal"><span class="pre">'localhost'</span></tt> or <tt class="docutils literal"><span class="pre">'mydb.example.org'</span></tt></li>
+<li>IP address, e.g., <tt class="docutils literal"><span class="pre">'127.0.0.1'</span></tt> or <tt class="docutils literal"><span class="pre">'192.168.10.1'</span></tt></li>
+<li>dot - <tt class="docutils literal"><span class="pre">'.'</span></tt>, i.e., use named pipes on windows systems</li>
+<li>empty - <tt class="docutils literal"><span class="pre">''</span></tt>, disables this server</li>
+</ul>
+</dd></dl>
+
+<dl class="option">
+<dt id="cfg_Servers_port">
+<tt class="descname">$cfg['Servers'][$i]['port']</tt><a class="headerlink" href="#cfg_Servers_port" title="Permalink to this definition">¶</a></dt>
+<dd><table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Type:</th><td class="field-body">string</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Default value:</th><td class="field-body"><tt class="docutils literal"><span class="pre">''</span></tt></td>
+</tr>
+</tbody>
+</table>
+<p>The port-number of your $i-th MySQL-server. Default is 3306 (leave
+blank).</p>
+<div class="admonition note">
+<p class="first admonition-title">Note</p>
+<p class="last">If you use <tt class="docutils literal"><span class="pre">localhost</span></tt> as the hostname, MySQL ignores this port number
+and connects with the socket, so if you want to connect to a port
+different from the default port, use <tt class="docutils literal"><span class="pre">127.0.0.1</span></tt> or the real hostname
+in <span class="target" id="index-7"></span><a class="reference internal" href="#cfg_Servers_host"><tt class="xref config config-option docutils literal"><span class="pre">$cfg['Servers'][$i]['host']</span></tt></a>.</p>
+</div>
+</dd></dl>
+
+<dl class="option">
+<dt id="cfg_Servers_socket">
+<tt class="descname">$cfg['Servers'][$i]['socket']</tt><a class="headerlink" href="#cfg_Servers_socket" title="Permalink to this definition">¶</a></dt>
+<dd><table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Type:</th><td class="field-body">string</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Default value:</th><td class="field-body"><tt class="docutils literal"><span class="pre">''</span></tt></td>
+</tr>
+</tbody>
+</table>
+<p>The path to the socket to use. Leave blank for default. To determine
+the correct socket, check your MySQL configuration or, using the
+<strong class="command">mysql</strong> command–line client, issue the <tt class="docutils literal"><span class="pre">status</span></tt> command. Among the
+resulting information displayed will be the socket used.</p>
+</dd></dl>
+
+<dl class="option">
+<dt id="cfg_Servers_ssl">
+<tt class="descname">$cfg['Servers'][$i]['ssl']</tt><a class="headerlink" href="#cfg_Servers_ssl" title="Permalink to this definition">¶</a></dt>
+<dd><table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Type:</th><td class="field-body">boolean</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Default value:</th><td class="field-body">false</td>
+</tr>
+</tbody>
+</table>
+<p>Whether to enable SSL for connection to MySQL server.</p>
+</dd></dl>
+
+<dl class="option">
+<dt id="cfg_Servers_connect_type">
+<tt class="descname">$cfg['Servers'][$i]['connect_type']</tt><a class="headerlink" href="#cfg_Servers_connect_type" title="Permalink to this definition">¶</a></dt>
+<dd><table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Type:</th><td class="field-body">string</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Default value:</th><td class="field-body"><tt class="docutils literal"><span class="pre">'tcp'</span></tt></td>
+</tr>
+</tbody>
+</table>
+<p>What type connection to use with the MySQL server. Your options are
+<tt class="docutils literal"><span class="pre">'socket'</span></tt> and <tt class="docutils literal"><span class="pre">'tcp'</span></tt>. It defaults to tcp as that is nearly guaranteed
+to be available on all MySQL servers, while sockets are not supported on
+some platforms. To use the socket mode, your MySQL server must be on the
+same machine as the Web server.</p>
+</dd></dl>
+
+<dl class="option">
+<dt id="cfg_Servers_extension">
+<tt class="descname">$cfg['Servers'][$i]['extension']</tt><a class="headerlink" href="#cfg_Servers_extension" title="Permalink to this definition">¶</a></dt>
+<dd><table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Type:</th><td class="field-body">string</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Default value:</th><td class="field-body"><tt class="docutils literal"><span class="pre">'mysqli'</span></tt></td>
+</tr>
+</tbody>
+</table>
+<p>What php MySQL extension to use for the connection. Valid options are:</p>
+<dl class="docutils">
+<dt><tt class="docutils literal"><span class="pre">mysql</span></tt></dt>
+<dd>The classic MySQL extension.</dd>
+<dt><tt class="docutils literal"><span class="pre">mysqli</span></tt></dt>
+<dd>The improved MySQL extension. This extension became available with PHP
+5.0.0 and is the recommended way to connect to a server running MySQL
+4.1.x or newer.</dd>
+</dl>
+</dd></dl>
+
+<dl class="option">
+<dt id="cfg_Servers_compress">
+<tt class="descname">$cfg['Servers'][$i]['compress']</tt><a class="headerlink" href="#cfg_Servers_compress" title="Permalink to this definition">¶</a></dt>
+<dd><table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Type:</th><td class="field-body">boolean</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Default value:</th><td class="field-body">false</td>
+</tr>
+</tbody>
+</table>
+<p>Whether to use a compressed protocol for the MySQL server connection
+or not (experimental).</p>
+</dd></dl>
+
+<span class="target" id="controlhost"></span><dl class="option">
+<dt id="cfg_Servers_controlhost">
+<tt class="descname">$cfg['Servers'][$i]['controlhost']</tt><a class="headerlink" href="#cfg_Servers_controlhost" title="Permalink to this definition">¶</a></dt>
+<dd><table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Type:</th><td class="field-body">string</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Default value:</th><td class="field-body"><tt class="docutils literal"><span class="pre">''</span></tt></td>
+</tr>
+</tbody>
+</table>
+<p>Permits to use an alternate host to hold the configuration storage
+data.</p>
+</dd></dl>
+
+<span class="target" id="controluser"></span><dl class="option">
+<dt id="cfg_Servers_controluser">
+<tt class="descname">$cfg['Servers'][$i]['controluser']</tt><a class="headerlink" href="#cfg_Servers_controluser" title="Permalink to this definition">¶</a></dt>
+<dd><table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Type:</th><td class="field-body">string</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Default value:</th><td class="field-body"><tt class="docutils literal"><span class="pre">''</span></tt></td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+<dl class="option">
+<dt id="cfg_Servers_controlpass">
+<tt class="descname">$cfg['Servers'][$i]['controlpass']</tt><a class="headerlink" href="#cfg_Servers_controlpass" title="Permalink to this definition">¶</a></dt>
+<dd><table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Type:</th><td class="field-body">string</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Default value:</th><td class="field-body"><tt class="docutils literal"><span class="pre">''</span></tt></td>
+</tr>
+</tbody>
+</table>
+<p>This special account is used for 2 distinct purposes: to make possible all
+relational features (see <span class="target" id="index-8"></span><a class="reference internal" href="#cfg_Servers_pmadb"><tt class="xref config config-option docutils literal"><span class="pre">$cfg['Servers'][$i]['pmadb']</span></tt></a>) and,
+for a MySQL server running with <tt class="docutils literal"><span class="pre">--skip-show-database</span></tt>, to enable a
+multi-user installation (<a class="reference internal" href="glossary.html#term-http"><em class="xref std std-term">HTTP</em></a> or cookie
+authentication mode).</p>
+<p>When using <a class="reference internal" href="glossary.html#term-http"><em class="xref std std-term">HTTP</em></a> or
+cookie authentication modes (or ‘config’ authentication mode since phpMyAdmin
+2.2.1), you need to supply the details of a MySQL account that has <tt class="docutils literal"><span class="pre">SELECT</span></tt>
+privilege on the <em>mysql.user (all columns except “Password”)</em>, <em>mysql.db (all
+columns)</em> and <em>mysql.tables_priv (all columns except “Grantor” and
+“Timestamp”)</em> tables. This account is used to check what databases the user
+will see at login.</p>
+<p class="versionchanged">
+<span class="versionmodified">Changed in version 2.2.5: </span>those were called <tt class="docutils literal"><span class="pre">stduser</span></tt> and <tt class="docutils literal"><span class="pre">stdpass</span></tt></p>
+<div class="admonition-see-also admonition seealso">
+<p class="first admonition-title">See also</p>
+<p class="last"><a class="reference internal" href="setup.html#setup"><em>Installation</em></a>, <a class="reference internal" href="setup.html#authentication-modes"><em>Using authentication modes</em></a></p>
+</div>
+</dd></dl>
+
+<dl class="option">
+<dt id="cfg_Servers_auth_type">
+<tt class="descname">$cfg['Servers'][$i]['auth_type']</tt><a class="headerlink" href="#cfg_Servers_auth_type" title="Permalink to this definition">¶</a></dt>
+<dd><table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Type:</th><td class="field-body">string</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Default value:</th><td class="field-body"><tt class="docutils literal"><span class="pre">'cookie'</span></tt></td>
+</tr>
+</tbody>
+</table>
+<p>Whether config or cookie or <a class="reference internal" href="glossary.html#term-http"><em class="xref std std-term">HTTP</em></a> or signon authentication should be
+used for this server.</p>
+<ul class="simple">
+<li>‘config’ authentication (<tt class="docutils literal"><span class="pre">$auth_type = 'config'</span></tt>) is the plain old
+way: username and password are stored in <tt class="file docutils literal"><span class="pre">config.inc.php</span></tt>.</li>
+<li>‘cookie’ authentication mode (<tt class="docutils literal"><span class="pre">$auth_type = 'cookie'</span></tt>) as
+introduced in 2.2.3 allows you to log in as any valid MySQL user with
+the help of cookies. Username and password are stored in cookies
+during the session and password is deleted when it ends. This can also
+allow you to log in in arbitrary server if <span class="target" id="index-9"></span><a class="reference internal" href="#cfg_AllowArbitraryServer"><tt class="xref config config-option docutils literal"><span class="pre">$cfg['AllowArbitraryServer']</span></tt></a> enabled.</li>
+<li>‘http’ authentication (was
+called ‘advanced’ in previous versions and can be written also as
+‘http’) (<tt class="docutils literal"><span class="pre">$auth_type = 'http';'</span></tt>) as introduced in 1.3.0 allows you to log in as any
+valid MySQL user via HTTP-Auth.</li>
+<li>‘signon’ authentication mode (<tt class="docutils literal"><span class="pre">$auth_type = 'signon'</span></tt>) as
+introduced in 2.10.0 allows you to log in from prepared PHP session
+data or using supplied PHP script. This is useful for implementing
+single signon from another application. Sample way how to seed session
+is in signon example: <tt class="file docutils literal"><span class="pre">examples/signon.php</span></tt>. There is also
+alternative example using OpenID - <tt class="file docutils literal"><span class="pre">examples/openid.php</span></tt> and example
+for scripts based solution - <tt class="file docutils literal"><span class="pre">examples/signon-script.php</span></tt>. You need
+to configure <span class="target" id="index-10"></span><a class="reference internal" href="#cfg_Servers_SignonSession"><tt class="xref config config-option docutils literal"><span class="pre">$cfg['Servers'][$i]['SignonSession']</span></tt></a> or
+<span class="target" id="index-11"></span><a class="reference internal" href="#cfg_Servers_SignonScript"><tt class="xref config config-option docutils literal"><span class="pre">$cfg['Servers'][$i]['SignonScript']</span></tt></a> and
+<span class="target" id="index-12"></span><a class="reference internal" href="#cfg_Servers_SignonURL"><tt class="xref config config-option docutils literal"><span class="pre">$cfg['Servers'][$i]['SignonURL']</span></tt></a> to use this authentication
+method.</li>
+</ul>
+<div class="admonition-see-also admonition seealso">
+<p class="first admonition-title">See also</p>
+<p class="last"><a class="reference internal" href="setup.html#authentication-modes"><em>Using authentication modes</em></a></p>
+</div>
+</dd></dl>
+
+<span class="target" id="servers-auth-http-realm"></span><dl class="option">
+<dt id="cfg_Servers_auth_http_realm">
+<tt class="descname">$cfg['Servers'][$i]['auth_http_realm']</tt><a class="headerlink" href="#cfg_Servers_auth_http_realm" title="Permalink to this definition">¶</a></dt>
+<dd><table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Type:</th><td class="field-body">string</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Default value:</th><td class="field-body"><tt class="docutils literal"><span class="pre">''</span></tt></td>
+</tr>
+</tbody>
+</table>
+<p>When using auth_type = <tt class="docutils literal"><span class="pre">http</span></tt>, this field allows to define a custom
+<a class="reference internal" href="glossary.html#term-http"><em class="xref std std-term">HTTP</em></a> Basic Auth Realm which will be displayed to the user. If not
+explicitly specified in your configuration, a string combined of
+“phpMyAdmin ” and either <span class="target" id="index-13"></span><a class="reference internal" href="#cfg_Servers_verbose"><tt class="xref config config-option docutils literal"><span class="pre">$cfg['Servers'][$i]['verbose']</span></tt></a> or
+<span class="target" id="index-14"></span><a class="reference internal" href="#cfg_Servers_host"><tt class="xref config config-option docutils literal"><span class="pre">$cfg['Servers'][$i]['host']</span></tt></a> will be used.</p>
+</dd></dl>
+
+<span class="target" id="servers-auth-swekey-config"></span><dl class="option">
+<dt id="cfg_Servers_auth_swekey_config">
+<tt class="descname">$cfg['Servers'][$i]['auth_swekey_config']</tt><a class="headerlink" href="#cfg_Servers_auth_swekey_config" title="Permalink to this definition">¶</a></dt>
+<dd><table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Type:</th><td class="field-body">string</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Default value:</th><td class="field-body"><tt class="docutils literal"><span class="pre">''</span></tt></td>
+</tr>
+</tbody>
+</table>
+<p>The name of the file containing <a class="reference internal" href="setup.html#swekey"><em>Swekey authentication mode</em></a> ids and login names for hardware
+authentication. Leave empty to deactivate this feature.</p>
+</dd></dl>
+
+<span class="target" id="servers-user"></span><dl class="option">
+<dt id="cfg_Servers_user">
+<tt class="descname">$cfg['Servers'][$i]['user']</tt><a class="headerlink" href="#cfg_Servers_user" title="Permalink to this definition">¶</a></dt>
+<dd><table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Type:</th><td class="field-body">string</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Default value:</th><td class="field-body"><tt class="docutils literal"><span class="pre">'root'</span></tt></td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+<dl class="option">
+<dt id="cfg_Servers_password">
+<tt class="descname">$cfg['Servers'][$i]['password']</tt><a class="headerlink" href="#cfg_Servers_password" title="Permalink to this definition">¶</a></dt>
+<dd><table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Type:</th><td class="field-body">string</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Default value:</th><td class="field-body"><tt class="docutils literal"><span class="pre">''</span></tt></td>
+</tr>
+</tbody>
+</table>
+<p>When using <span class="target" id="index-15"></span><a class="reference internal" href="#cfg_Servers_auth_type"><tt class="xref config config-option docutils literal"><span class="pre">$cfg['Servers'][$i]['auth_type']</span></tt></a> set to
+‘config’, this is the user/password-pair which phpMyAdmin will use to
+connect to the MySQL server. This user/password pair is not needed when
+<a class="reference internal" href="glossary.html#term-http"><em class="xref std std-term">HTTP</em></a> or cookie authentication is used
+and should be empty.</p>
+</dd></dl>
+
+<span class="target" id="servers-nopassword"></span><dl class="option">
+<dt id="cfg_Servers_nopassword">
+<tt class="descname">$cfg['Servers'][$i]['nopassword']</tt><a class="headerlink" href="#cfg_Servers_nopassword" title="Permalink to this definition">¶</a></dt>
+<dd><table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Type:</th><td class="field-body">boolean</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Default value:</th><td class="field-body">false</td>
+</tr>
+</tbody>
+</table>
+<p>Allow attempt to log in without password when a login with password
+fails. This can be used together with http authentication, when
+authentication is done some other way and phpMyAdmin gets user name
+from auth and uses empty password for connecting to MySQL. Password
+login is still tried first, but as fallback, no password method is
+tried.</p>
+</dd></dl>
+
+<span class="target" id="servers-only-db"></span><dl class="option">
+<dt id="cfg_Servers_only_db">
+<tt class="descname">$cfg['Servers'][$i]['only_db']</tt><a class="headerlink" href="#cfg_Servers_only_db" title="Permalink to this definition">¶</a></dt>
+<dd><table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Type:</th><td class="field-body">string or array</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Default value:</th><td class="field-body"><tt class="docutils literal"><span class="pre">''</span></tt></td>
+</tr>
+</tbody>
+</table>
+<p>If set to a (an array of) database name(s), only this (these)
+database(s) will be shown to the user. Since phpMyAdmin 2.2.1,
+this/these database(s) name(s) may contain MySQL wildcards characters
+(“_” and “%”): if you want to use literal instances of these
+characters, escape them (I.E. use <tt class="docutils literal"><span class="pre">'my\_db'</span></tt> and not <tt class="docutils literal"><span class="pre">'my_db'</span></tt>).</p>
+<p>This setting is an efficient way to lower the server load since the
+latter does not need to send MySQL requests to build the available
+database list. But <strong>it does not replace the privileges rules of the
+MySQL database server</strong>. If set, it just means only these databases
+will be displayed but <strong>not that all other databases can’t be used.</strong></p>
+<p>An example of using more that one database:</p>
+<div class="highlight-php"><div class="highlight"><pre><span class="x">$cfg['Servers'][$i]['only_db'] = array('db1', 'db2');</span>
+</pre></div>
+</div>
+<p class="versionchanged">
+<span class="versionmodified">Changed in version 4.0.0: </span>Previous versions permitted to specify the display order of
+the database names via this directive.</p>
+</dd></dl>
+
+<dl class="option">
+<dt id="cfg_Servers_hide_db">
+<tt class="descname">$cfg['Servers'][$i]['hide_db']</tt><a class="headerlink" href="#cfg_Servers_hide_db" title="Permalink to this definition">¶</a></dt>
+<dd><table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Type:</th><td class="field-body">string</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Default value:</th><td class="field-body"><tt class="docutils literal"><span class="pre">''</span></tt></td>
+</tr>
+</tbody>
+</table>
+<p>Regular expression for hiding some databases from unprivileged users.
+This only hides them from listing, but a user is still able to access
+them (using, for example, the SQL query area). To limit access, use
+the MySQL privilege system.  For example, to hide all databases
+starting with the letter “a”, use</p>
+<div class="highlight-php"><div class="highlight"><pre><span class="x">$cfg['Servers'][$i]['hide_db'] = '^a';</span>
+</pre></div>
+</div>
+<p>and to hide both “db1” and “db2” use</p>
+<div class="highlight-php"><div class="highlight"><pre><span class="x">$cfg['Servers'][$i]['hide_db'] = '^(db1|db2)$';</span>
+</pre></div>
+</div>
+<p>More information on regular expressions can be found in the <a class="reference external" href="http://php.net/manual/en/reference.pcre.pattern.syntax.php">PCRE
+pattern syntax</a> portion
+of the PHP reference manual.</p>
+</dd></dl>
+
+<dl class="option">
+<dt id="cfg_Servers_verbose">
+<tt class="descname">$cfg['Servers'][$i]['verbose']</tt><a class="headerlink" href="#cfg_Servers_verbose" title="Permalink to this definition">¶</a></dt>
+<dd><table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Type:</th><td class="field-body">string</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Default value:</th><td class="field-body"><tt class="docutils literal"><span class="pre">''</span></tt></td>
+</tr>
+</tbody>
+</table>
+<p>Only useful when using phpMyAdmin with multiple server entries. If
+set, this string will be displayed instead of the hostname in the
+pull-down menu on the main page. This can be useful if you want to
+show only certain databases on your system, for example. For HTTP
+auth, all non-US-ASCII characters will be stripped.</p>
+</dd></dl>
+
+<dl class="option">
+<dt id="cfg_Servers_pmadb">
+<tt class="descname">$cfg['Servers'][$i]['pmadb']</tt><a class="headerlink" href="#cfg_Servers_pmadb" title="Permalink to this definition">¶</a></dt>
+<dd><table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Type:</th><td class="field-body">string</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Default value:</th><td class="field-body"><tt class="docutils literal"><span class="pre">''</span></tt></td>
+</tr>
+</tbody>
+</table>
+<p>The name of the database containing the phpMyAdmin configuration
+storage.</p>
+<p>See the <a class="reference internal" href="setup.html#linked-tables"><em>phpMyAdmin configuration storage</em></a>  section in this document to see the benefits of
+this feature, and for a quick way of creating this database and the needed
+tables.</p>
+<p>If you are the only user of this phpMyAdmin installation, you can use your
+current database to store those special tables; in this case, just put your
+current database name in <span class="target" id="index-16"></span><a class="reference internal" href="#cfg_Servers_pmadb"><tt class="xref config config-option docutils literal"><span class="pre">$cfg['Servers'][$i]['pmadb']</span></tt></a>. For a
+multi-user installation, set this parameter to the name of your central
+database containing the phpMyAdmin configuration storage.</p>
+</dd></dl>
+
+<span class="target" id="bookmark"></span><dl class="option">
+<dt id="cfg_Servers_bookmarktable">
+<tt class="descname">$cfg['Servers'][$i]['bookmarktable']</tt><a class="headerlink" href="#cfg_Servers_bookmarktable" title="Permalink to this definition">¶</a></dt>
+<dd><table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Type:</th><td class="field-body">string</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Default value:</th><td class="field-body"><tt class="docutils literal"><span class="pre">''</span></tt></td>
+</tr>
+</tbody>
+</table>
+<p>Since release 2.2.0 phpMyAdmin allows users to bookmark queries. This
+can be useful for queries you often run. To allow the usage of this
+functionality:</p>
+<ul class="simple">
+<li>set up <span class="target" id="index-17"></span><a class="reference internal" href="#cfg_Servers_pmadb"><tt class="xref config config-option docutils literal"><span class="pre">$cfg['Servers'][$i]['pmadb']</span></tt></a> and the phpMyAdmin configuration storage</li>
+<li>enter the table name in <span class="target" id="index-18"></span><a class="reference internal" href="#cfg_Servers_bookmarktable"><tt class="xref config config-option docutils literal"><span class="pre">$cfg['Servers'][$i]['bookmarktable']</span></tt></a></li>
+</ul>
+</dd></dl>
+
+<span class="target" id="relation"></span><dl class="option">
+<dt id="cfg_Servers_relation">
+<tt class="descname">$cfg['Servers'][$i]['relation']</tt><a class="headerlink" href="#cfg_Servers_relation" title="Permalink to this definition">¶</a></dt>
+<dd><table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Type:</th><td class="field-body">string</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Default value:</th><td class="field-body"><tt class="docutils literal"><span class="pre">''</span></tt></td>
+</tr>
+</tbody>
+</table>
+<p>Since release 2.2.4 you can describe, in a special ‘relation’ table,
+which column is a key in another table (a foreign key). phpMyAdmin
+currently uses this to</p>
+<ul class="simple">
+<li>make clickable, when you browse the master table, the data values that
+point to the foreign table;</li>
+<li>display in an optional tool-tip the “display column” when browsing the
+master table, if you move the mouse to a column containing a foreign
+key (use also the ‘table_info’ table); (see <a class="reference internal" href="faq.html#faqdisplay"><em>6.7 How can I use the “display column” feature?</em></a>)</li>
+<li>in edit/insert mode, display a drop-down list of possible foreign keys
+(key value and “display column” are shown) (see <a class="reference internal" href="faq.html#faq6-21"><em>6.21 In edit/insert mode, how can I see a list of possible values for a column, based on some foreign table?</em></a>)</li>
+<li>display links on the table properties page, to check referential
+integrity (display missing foreign keys) for each described key;</li>
+<li>in query-by-example, create automatic joins (see <a class="reference internal" href="faq.html#faq6-6"><em>6.6 How can I use the relation table in Query-by-example?</em></a>)</li>
+<li>enable you to get a <a class="reference internal" href="glossary.html#term-pdf"><em class="xref std std-term">PDF</em></a> schema of
+your database (also uses the table_coords table).</li>
+</ul>
+<p>The keys can be numeric or character.</p>
+<p>To allow the usage of this functionality:</p>
+<ul class="simple">
+<li>set up <span class="target" id="index-19"></span><a class="reference internal" href="#cfg_Servers_pmadb"><tt class="xref config config-option docutils literal"><span class="pre">$cfg['Servers'][$i]['pmadb']</span></tt></a> and the phpMyAdmin configuration storage</li>
+<li>put the relation table name in <span class="target" id="index-20"></span><a class="reference internal" href="#cfg_Servers_relation"><tt class="xref config config-option docutils literal"><span class="pre">$cfg['Servers'][$i]['relation']</span></tt></a></li>
+<li>now as normal user open phpMyAdmin and for each one of your tables
+where you want to use this feature, click <em class="guilabel">Structure/Relation view/</em>
+and choose foreign columns.</li>
+</ul>
+<div class="admonition note">
+<p class="first admonition-title">Note</p>
+<p class="last">In the current version, <tt class="docutils literal"><span class="pre">master_db</span></tt> must be the same as <tt class="docutils literal"><span class="pre">foreign_db</span></tt>.
+Those columns have been put in future development of the cross-db
+relations.</p>
+</div>
+</dd></dl>
+
+<span class="target" id="table-info"></span><dl class="option">
+<dt id="cfg_Servers_table_info">
+<tt class="descname">$cfg['Servers'][$i]['table_info']</tt><a class="headerlink" href="#cfg_Servers_table_info" title="Permalink to this definition">¶</a></dt>
+<dd><table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Type:</th><td class="field-body">string</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Default value:</th><td class="field-body"><tt class="docutils literal"><span class="pre">''</span></tt></td>
+</tr>
+</tbody>
+</table>
+<p>Since release 2.3.0 you can describe, in a special ‘table_info’
+table, which column is to be displayed as a tool-tip when moving the
+cursor over the corresponding key. This configuration variable will
+hold the name of this special table. To allow the usage of this
+functionality:</p>
+<ul class="simple">
+<li>set up <span class="target" id="index-21"></span><a class="reference internal" href="#cfg_Servers_pmadb"><tt class="xref config config-option docutils literal"><span class="pre">$cfg['Servers'][$i]['pmadb']</span></tt></a> and the phpMyAdmin configuration storage</li>
+<li>put the table name in <span class="target" id="index-22"></span><a class="reference internal" href="#cfg_Servers_table_info"><tt class="xref config config-option docutils literal"><span class="pre">$cfg['Servers'][$i]['table_info']</span></tt></a> (e.g.
+<tt class="docutils literal"><span class="pre">pma__table_info</span></tt>)</li>
+<li>then for each table where you want to use this feature, click
+“Structure/Relation view/Choose column to display” to choose the
+column.</li>
+</ul>
+<div class="admonition-see-also admonition seealso">
+<p class="first admonition-title">See also</p>
+<p class="last"><a class="reference internal" href="faq.html#faqdisplay"><em>6.7 How can I use the “display column” feature?</em></a></p>
+</div>
+</dd></dl>
+
+<span class="target" id="table-coords"></span><dl class="option">
+<dt id="cfg_Servers_table_coords">
+<tt class="descname">$cfg['Servers'][$i]['table_coords']</tt><a class="headerlink" href="#cfg_Servers_table_coords" title="Permalink to this definition">¶</a></dt>
+<dd><table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Type:</th><td class="field-body">string</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Default value:</th><td class="field-body"><tt class="docutils literal"><span class="pre">''</span></tt></td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+<dl class="option">
+<dt id="cfg_Servers_pdf_pages">
+<tt class="descname">$cfg['Servers'][$i]['pdf_pages']</tt><a class="headerlink" href="#cfg_Servers_pdf_pages" title="Permalink to this definition">¶</a></dt>
+<dd><table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Type:</th><td class="field-body">string</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Default value:</th><td class="field-body"><tt class="docutils literal"><span class="pre">''</span></tt></td>
+</tr>
+</tbody>
+</table>
+<p>Since release 2.3.0 you can have phpMyAdmin create <a class="reference internal" href="glossary.html#term-pdf"><em class="xref std std-term">PDF</em></a> pages
+showing the relations between your tables. To do this it needs two tables
+“pdf_pages” (storing information about the available <a class="reference internal" href="glossary.html#term-pdf"><em class="xref std std-term">PDF</em></a> pages)
+and “table_coords” (storing coordinates where each table will be placed on
+a <a class="reference internal" href="glossary.html#term-pdf"><em class="xref std std-term">PDF</em></a> schema output).  You must be using the “relation” feature.</p>
+<p>To allow the usage of this functionality:</p>
+<ul class="simple">
+<li>set up <span class="target" id="index-23"></span><a class="reference internal" href="#cfg_Servers_pmadb"><tt class="xref config config-option docutils literal"><span class="pre">$cfg['Servers'][$i]['pmadb']</span></tt></a> and the phpMyAdmin configuration storage</li>
+<li>put the correct table names in
+<span class="target" id="index-24"></span><a class="reference internal" href="#cfg_Servers_table_coords"><tt class="xref config config-option docutils literal"><span class="pre">$cfg['Servers'][$i]['table_coords']</span></tt></a> and
+<span class="target" id="index-25"></span><a class="reference internal" href="#cfg_Servers_pdf_pages"><tt class="xref config config-option docutils literal"><span class="pre">$cfg['Servers'][$i]['pdf_pages']</span></tt></a></li>
+</ul>
+<div class="admonition-see-also admonition seealso">
+<p class="first admonition-title">See also</p>
+<p class="last"><a class="reference internal" href="faq.html#faqpdf"><em>6.8 How can I produce a PDF schema of my database?</em></a>.</p>
+</div>
+</dd></dl>
+
+<span class="target" id="col-com"></span><dl class="option">
+<dt id="cfg_Servers_column_info">
+<tt class="descname">$cfg['Servers'][$i]['column_info']</tt><a class="headerlink" href="#cfg_Servers_column_info" title="Permalink to this definition">¶</a></dt>
+<dd><table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Type:</th><td class="field-body">string</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Default value:</th><td class="field-body"><tt class="docutils literal"><span class="pre">''</span></tt></td>
+</tr>
+</tbody>
+</table>
+<p>This part requires a content update!  Since release 2.3.0 you can
+store comments to describe each column for each table. These will then
+be shown on the “printview”.</p>
+<p>Starting with release 2.5.0, comments are consequently used on the table
+property pages and table browse view, showing up as tool-tips above the
+column name (properties page) or embedded within the header of table in
+browse view. They can also be shown in a table dump. Please see the
+relevant configuration directives later on.</p>
+<p>Also new in release 2.5.0 is a MIME- transformation system which is also
+based on the following table structure. See <a class="reference internal" href="transformations.html#transformations"><em>Transformations</em></a> for
+further information. To use the MIME- transformation system, your
+column_info table has to have the three new columns ‘mimetype’,
+‘transformation’, ‘transformation_options’.</p>
+<p>To allow the usage of this functionality:</p>
+<ul>
+<li><p class="first">set up <span class="target" id="index-26"></span><a class="reference internal" href="#cfg_Servers_pmadb"><tt class="xref config config-option docutils literal"><span class="pre">$cfg['Servers'][$i]['pmadb']</span></tt></a> and the phpMyAdmin configuration storage</p>
+</li>
+<li><p class="first">put the table name in <span class="target" id="index-27"></span><a class="reference internal" href="#cfg_Servers_column_info"><tt class="xref config config-option docutils literal"><span class="pre">$cfg['Servers'][$i]['column_info']</span></tt></a> (e.g.
+<tt class="docutils literal"><span class="pre">pma__column_info</span></tt>)</p>
+</li>
+<li><p class="first">to update your PRE-2.5.0 Column_comments Table use this:  and
+remember that the Variable in <tt class="file docutils literal"><span class="pre">config.inc.php</span></tt> has been renamed from
+<span class="target" id="index-28"></span><tt class="xref config config-option docutils literal"><span class="pre">$cfg['Servers'][$i]['column_comments']</span></tt> to
+<span class="target" id="index-29"></span><a class="reference internal" href="#cfg_Servers_column_info"><tt class="xref config config-option docutils literal"><span class="pre">$cfg['Servers'][$i]['column_info']</span></tt></a></p>
+<div class="highlight-mysql"><div class="highlight"><pre><span class="k">ALTER</span> <span class="k">TABLE</span> <span class="ss">`pma__column_comments`</span>
+<span class="k">ADD</span> <span class="ss">`mimetype`</span> <span class="kt">VARCHAR</span><span class="p">(</span> <span class="mi">255</span> <span class="p">)</span> <span class="k">NOT</span> <span class="no">NULL</span><span class="p">,</span>
+<span class="k">ADD</span> <span class="ss">`transformation`</span> <span class="kt">VARCHAR</span><span class="p">(</span> <span class="mi">255</span> <span class="p">)</span> <span class="k">NOT</span> <span class="no">NULL</span><span class="p">,</span>
+<span class="k">ADD</span> <span class="ss">`transformation_options`</span> <span class="kt">VARCHAR</span><span class="p">(</span> <span class="mi">255</span> <span class="p">)</span> <span class="k">NOT</span> <span class="no">NULL</span><span class="p">;</span>
+</pre></div>
+</div>
+</li>
+</ul>
+</dd></dl>
+
+<span class="target" id="history"></span><dl class="option">
+<dt id="cfg_Servers_history">
+<tt class="descname">$cfg['Servers'][$i]['history']</tt><a class="headerlink" href="#cfg_Servers_history" title="Permalink to this definition">¶</a></dt>
+<dd><table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Type:</th><td class="field-body">string</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Default value:</th><td class="field-body"><tt class="docutils literal"><span class="pre">''</span></tt></td>
+</tr>
+</tbody>
+</table>
+<p>Since release 2.5.0 you can store your <a class="reference internal" href="glossary.html#term-sql"><em class="xref std std-term">SQL</em></a> history, which means all
+queries you entered manually into the phpMyAdmin interface. If you don’t
+want to use a table-based history, you can use the JavaScript-based
+history.</p>
+<p>Using that, all your history items are deleted when closing the window.
+Using <span class="target" id="index-30"></span><a class="reference internal" href="#cfg_QueryHistoryMax"><tt class="xref config config-option docutils literal"><span class="pre">$cfg['QueryHistoryMax']</span></tt></a> you can specify an amount of
+history items you want to have on hold. On every login, this list gets cut
+to the maximum amount.</p>
+<p>The query history is only available if JavaScript is enabled in
+your browser.</p>
+<p>To allow the usage of this functionality:</p>
+<ul class="simple">
+<li>set up <span class="target" id="index-31"></span><a class="reference internal" href="#cfg_Servers_pmadb"><tt class="xref config config-option docutils literal"><span class="pre">$cfg['Servers'][$i]['pmadb']</span></tt></a> and the phpMyAdmin configuration storage</li>
+<li>put the table name in <span class="target" id="index-32"></span><a class="reference internal" href="#cfg_Servers_history"><tt class="xref config config-option docutils literal"><span class="pre">$cfg['Servers'][$i]['history']</span></tt></a> (e.g.
+<tt class="docutils literal"><span class="pre">pma__history</span></tt>)</li>
+</ul>
+</dd></dl>
+
+<span class="target" id="recent"></span><dl class="option">
+<dt id="cfg_Servers_recent">
+<tt class="descname">$cfg['Servers'][$i]['recent']</tt><a class="headerlink" href="#cfg_Servers_recent" title="Permalink to this definition">¶</a></dt>
+<dd><table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Type:</th><td class="field-body">string</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Default value:</th><td class="field-body"><tt class="docutils literal"><span class="pre">''</span></tt></td>
+</tr>
+</tbody>
+</table>
+<p>Since release 3.5.0 you can show recently used tables in the
+navigation panel. It helps you to jump across table directly, without
+the need to select the database, and then select the table. Using
+<span class="target" id="index-33"></span><a class="reference internal" href="#cfg_NumRecentTables"><tt class="xref config config-option docutils literal"><span class="pre">$cfg['NumRecentTables']</span></tt></a> you can configure the maximum number
+of recent tables shown. When you select a table from the list, it will jump to
+the page specified in <span class="target" id="index-34"></span><a class="reference internal" href="#cfg_NavigationTreeDefaultTabTable"><tt class="xref config config-option docutils literal"><span class="pre">$cfg['NavigationTreeDefaultTabTable']</span></tt></a>.</p>
+<p>Without configuring the storage, you can still access the recently used tables,
+but it will disappear after you logout.</p>
+<p>To allow the usage of this functionality persistently:</p>
+<ul class="simple">
+<li>set up <span class="target" id="index-35"></span><a class="reference internal" href="#cfg_Servers_pmadb"><tt class="xref config config-option docutils literal"><span class="pre">$cfg['Servers'][$i]['pmadb']</span></tt></a> and the phpMyAdmin configuration storage</li>
+<li>put the table name in <span class="target" id="index-36"></span><a class="reference internal" href="#cfg_Servers_recent"><tt class="xref config config-option docutils literal"><span class="pre">$cfg['Servers'][$i]['recent']</span></tt></a> (e.g.
+<tt class="docutils literal"><span class="pre">pma__recent</span></tt>)</li>
+</ul>
+</dd></dl>
+
+<span class="target" id="table-uiprefs"></span><dl class="option">
+<dt id="cfg_Servers_table_uiprefs">
+<tt class="descname">$cfg['Servers'][$i]['table_uiprefs']</tt><a class="headerlink" href="#cfg_Servers_table_uiprefs" title="Permalink to this definition">¶</a></dt>
+<dd><table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Type:</th><td class="field-body">string</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Default value:</th><td class="field-body"><tt class="docutils literal"><span class="pre">''</span></tt></td>
+</tr>
+</tbody>
+</table>
+<p>Since release 3.5.0 phpMyAdmin can be configured to remember several
+things (sorted column <span class="target" id="index-37"></span><a class="reference internal" href="#cfg_RememberSorting"><tt class="xref config config-option docutils literal"><span class="pre">$cfg['RememberSorting']</span></tt></a>, column order,
+and column visibility from a database table) for browsing tables. Without
+configuring the storage, these features still can be used, but the values will
+disappear after you logout.</p>
+<p>To allow the usage of these functionality persistently:</p>
+<ul class="simple">
+<li>set up <span class="target" id="index-38"></span><a class="reference internal" href="#cfg_Servers_pmadb"><tt class="xref config config-option docutils literal"><span class="pre">$cfg['Servers'][$i]['pmadb']</span></tt></a> and the phpMyAdmin configuration storage</li>
+<li>put the table name in <span class="target" id="index-39"></span><a class="reference internal" href="#cfg_Servers_table_uiprefs"><tt class="xref config config-option docutils literal"><span class="pre">$cfg['Servers'][$i]['table_uiprefs']</span></tt></a> (e.g.
+<tt class="docutils literal"><span class="pre">pma__table_uiprefs</span></tt>)</li>
+</ul>
+</dd></dl>
+
+<span class="target" id="tracking"></span><dl class="option">
+<dt id="cfg_Servers_tracking">
+<tt class="descname">$cfg['Servers'][$i]['tracking']</tt><a class="headerlink" href="#cfg_Servers_tracking" title="Permalink to this definition">¶</a></dt>
+<dd><table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Type:</th><td class="field-body">string</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Default value:</th><td class="field-body"><tt class="docutils literal"><span class="pre">''</span></tt></td>
+</tr>
+</tbody>
+</table>
+<p>Since release 3.3.x a tracking mechanism is available. It helps you to
+track every <a class="reference internal" href="glossary.html#term-sql"><em class="xref std std-term">SQL</em></a> command which is
+executed by phpMyAdmin. The mechanism supports logging of data
+manipulation and data definition statements. After enabling it you can
+create versions of tables.</p>
+<p>The creation of a version has two effects:</p>
+<ul class="simple">
+<li>phpMyAdmin saves a snapshot of the table, including structure and
+indexes.</li>
+<li>phpMyAdmin logs all commands which change the structure and/or data of
+the table and links these commands with the version number.</li>
+</ul>
+<p>Of course you can view the tracked changes. On the <em class="guilabel">Tracking</em>
+page a complete report is available for every version. For the report you
+can use filters, for example you can get a list of statements within a date
+range. When you want to filter usernames you can enter * for all names or
+you enter a list of names separated by ‘,’. In addition you can export the
+(filtered) report to a file or to a temporary database.</p>
+<p>To allow the usage of this functionality:</p>
+<ul class="simple">
+<li>set up <span class="target" id="index-40"></span><a class="reference internal" href="#cfg_Servers_pmadb"><tt class="xref config config-option docutils literal"><span class="pre">$cfg['Servers'][$i]['pmadb']</span></tt></a> and the phpMyAdmin configuration storage</li>
+<li>put the table name in <span class="target" id="index-41"></span><a class="reference internal" href="#cfg_Servers_tracking"><tt class="xref config config-option docutils literal"><span class="pre">$cfg['Servers'][$i]['tracking']</span></tt></a> (e.g.
+<tt class="docutils literal"><span class="pre">pma__tracking</span></tt>)</li>
+</ul>
+</dd></dl>
+
+<span class="target" id="tracking2"></span><dl class="option">
+<dt id="cfg_Servers_tracking_version_auto_create">
+<tt class="descname">$cfg['Servers'][$i]['tracking_version_auto_create']</tt><a class="headerlink" href="#cfg_Servers_tracking_version_auto_create" title="Permalink to this definition">¶</a></dt>
+<dd><table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Type:</th><td class="field-body">boolean</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Default value:</th><td class="field-body">false</td>
+</tr>
+</tbody>
+</table>
+<p>Whether the tracking mechanism creates versions for tables and views
+automatically.</p>
+<p>If this is set to true and you create a table or view with</p>
+<ul class="simple">
+<li>CREATE TABLE ...</li>
+<li>CREATE VIEW ...</li>
+</ul>
+<p>and no version exists for it, the mechanism will create a version for
+you automatically.</p>
+</dd></dl>
+
+<span class="target" id="tracking3"></span><dl class="option">
+<dt id="cfg_Servers_tracking_default_statements">
+<tt class="descname">$cfg['Servers'][$i]['tracking_default_statements']</tt><a class="headerlink" href="#cfg_Servers_tracking_default_statements" title="Permalink to this definition">¶</a></dt>
+<dd><table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Type:</th><td class="field-body">string</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Default value:</th><td class="field-body"><tt class="docutils literal"><span class="pre">'CREATE</span> <span class="pre">TABLE,ALTER</span> <span class="pre">TABLE,DROP</span> <span class="pre">TABLE,RENAME</span> <span class="pre">TABLE,CREATE</span> <span class="pre">INDEX,DROP</span> <span class="pre">INDEX,INSERT,UPDATE,DELETE,TRUNCATE,REPLACE,CREATE</span> <span class="pre">VIEW,ALTER</span> <span class="pre">VIEW,DROP</span> <spa [...]
+</tr>
+</tbody>
+</table>
+<p>Defines the list of statements the auto-creation uses for new
+versions.</p>
+</dd></dl>
+
+<span class="target" id="tracking4"></span><dl class="option">
+<dt id="cfg_Servers_tracking_add_drop_view">
+<tt class="descname">$cfg['Servers'][$i]['tracking_add_drop_view']</tt><a class="headerlink" href="#cfg_Servers_tracking_add_drop_view" title="Permalink to this definition">¶</a></dt>
+<dd><table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Type:</th><td class="field-body">boolean</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Default value:</th><td class="field-body">true</td>
+</tr>
+</tbody>
+</table>
+<p>Whether a DROP VIEW IF EXISTS statement will be added as first line to
+the log when creating a view.</p>
+</dd></dl>
+
+<span class="target" id="tracking5"></span><dl class="option">
+<dt id="cfg_Servers_tracking_add_drop_table">
+<tt class="descname">$cfg['Servers'][$i]['tracking_add_drop_table']</tt><a class="headerlink" href="#cfg_Servers_tracking_add_drop_table" title="Permalink to this definition">¶</a></dt>
+<dd><table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Type:</th><td class="field-body">boolean</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Default value:</th><td class="field-body">true</td>
+</tr>
+</tbody>
+</table>
+<p>Whether a DROP TABLE IF EXISTS statement will be added as first line
+to the log when creating a table.</p>
+</dd></dl>
+
+<span class="target" id="tracking6"></span><dl class="option">
+<dt id="cfg_Servers_tracking_add_drop_database">
+<tt class="descname">$cfg['Servers'][$i]['tracking_add_drop_database']</tt><a class="headerlink" href="#cfg_Servers_tracking_add_drop_database" title="Permalink to this definition">¶</a></dt>
+<dd><table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Type:</th><td class="field-body">boolean</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Default value:</th><td class="field-body">true</td>
+</tr>
+</tbody>
+</table>
+<p>Whether a DROP DATABASE IF EXISTS statement will be added as first
+line to the log when creating a database.</p>
+</dd></dl>
+
+<span class="target" id="userconfig"></span><dl class="option">
+<dt id="cfg_Servers_userconfig">
+<tt class="descname">$cfg['Servers'][$i]['userconfig']</tt><a class="headerlink" href="#cfg_Servers_userconfig" title="Permalink to this definition">¶</a></dt>
+<dd><table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Type:</th><td class="field-body">string</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Default value:</th><td class="field-body"><tt class="docutils literal"><span class="pre">''</span></tt></td>
+</tr>
+</tbody>
+</table>
+<p>Since release 3.4.x phpMyAdmin allows users to set most preferences by
+themselves and store them in the database.</p>
+<p>If you don’t allow for storing preferences in
+<span class="target" id="index-42"></span><a class="reference internal" href="#cfg_Servers_pmadb"><tt class="xref config config-option docutils literal"><span class="pre">$cfg['Servers'][$i]['pmadb']</span></tt></a>, users can still personalize
+phpMyAdmin, but settings will be saved in browser’s local storage, or, it
+is is unavailable, until the end of session.</p>
+<p>To allow the usage of this functionality:</p>
+<ul class="simple">
+<li>set up <span class="target" id="index-43"></span><a class="reference internal" href="#cfg_Servers_pmadb"><tt class="xref config config-option docutils literal"><span class="pre">$cfg['Servers'][$i]['pmadb']</span></tt></a> and the phpMyAdmin configuration storage</li>
+<li>put the table name in <span class="target" id="index-44"></span><a class="reference internal" href="#cfg_Servers_userconfig"><tt class="xref config config-option docutils literal"><span class="pre">$cfg['Servers'][$i]['userconfig']</span></tt></a></li>
+</ul>
+</dd></dl>
+
+<span class="target" id="designer-coords"></span><dl class="option">
+<dt id="cfg_Servers_designer_coords">
+<tt class="descname">$cfg['Servers'][$i]['designer_coords']</tt><a class="headerlink" href="#cfg_Servers_designer_coords" title="Permalink to this definition">¶</a></dt>
+<dd><table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Type:</th><td class="field-body">string</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Default value:</th><td class="field-body"><tt class="docutils literal"><span class="pre">''</span></tt></td>
+</tr>
+</tbody>
+</table>
+<p>Since release 2.10.0 a Designer interface is available; it permits to
+visually manage the relations.</p>
+<p>To allow the usage of this functionality:</p>
+<ul class="simple">
+<li>set up <span class="target" id="index-45"></span><a class="reference internal" href="#cfg_Servers_pmadb"><tt class="xref config config-option docutils literal"><span class="pre">$cfg['Servers'][$i]['pmadb']</span></tt></a> and the phpMyAdmin configuration storage</li>
+<li>put the table name in <span class="target" id="index-46"></span><a class="reference internal" href="#cfg_Servers_designer_coords"><tt class="xref config config-option docutils literal"><span class="pre">$cfg['Servers'][$i]['designer_coords']</span></tt></a>
+(e.g. <tt class="docutils literal"><span class="pre">pma__designer_coords</span></tt>)</li>
+</ul>
+</dd></dl>
+
+<dl class="option">
+<dt id="cfg_Servers_MaxTableUiprefs">
+<tt class="descname">$cfg['Servers'][$i]['MaxTableUiprefs']</tt><a class="headerlink" href="#cfg_Servers_MaxTableUiprefs" title="Permalink to this definition">¶</a></dt>
+<dd><table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Type:</th><td class="field-body">integer</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Default value:</th><td class="field-body">100</td>
+</tr>
+</tbody>
+</table>
+<p>Maximum number of rows saved in
+<span class="target" id="index-47"></span><a class="reference internal" href="#cfg_Servers_table_uiprefs"><tt class="xref config config-option docutils literal"><span class="pre">$cfg['Servers'][$i]['table_uiprefs']</span></tt></a> table.</p>
+<p>When tables are dropped or renamed,
+<span class="target" id="index-48"></span><a class="reference internal" href="#cfg_Servers_table_uiprefs"><tt class="xref config config-option docutils literal"><span class="pre">$cfg['Servers'][$i]['table_uiprefs']</span></tt></a> may contain invalid data
+(referring to tables which no longer exist). We only keep this number of newest
+rows in <span class="target" id="index-49"></span><a class="reference internal" href="#cfg_Servers_table_uiprefs"><tt class="xref config config-option docutils literal"><span class="pre">$cfg['Servers'][$i]['table_uiprefs']</span></tt></a> and automatically
+delete older rows.</p>
+</dd></dl>
+
+<dl class="option">
+<dt id="cfg_Servers_AllowRoot">
+<tt class="descname">$cfg['Servers'][$i]['AllowRoot']</tt><a class="headerlink" href="#cfg_Servers_AllowRoot" title="Permalink to this definition">¶</a></dt>
+<dd><table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Type:</th><td class="field-body">boolean</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Default value:</th><td class="field-body">true</td>
+</tr>
+</tbody>
+</table>
+<p>Whether to allow root access. This is just a shortcut for the
+<span class="target" id="index-50"></span><a class="reference internal" href="#cfg_Servers_AllowDeny_rules"><tt class="xref config config-option docutils literal"><span class="pre">$cfg['Servers'][$i]['AllowDeny']['rules']</span></tt></a> below.</p>
+</dd></dl>
+
+<dl class="option">
+<dt id="cfg_Servers_AllowNoPassword">
+<tt class="descname">$cfg['Servers'][$i]['AllowNoPassword']</tt><a class="headerlink" href="#cfg_Servers_AllowNoPassword" title="Permalink to this definition">¶</a></dt>
+<dd><table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Type:</th><td class="field-body">boolean</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Default value:</th><td class="field-body">false</td>
+</tr>
+</tbody>
+</table>
+<p>Whether to allow logins without a password. The default value of
+<tt class="docutils literal"><span class="pre">false</span></tt> for this parameter prevents unintended access to a MySQL
+server with was left with an empty password for root or on which an
+anonymous (blank) user is defined.</p>
+</dd></dl>
+
+<span class="target" id="servers-allowdeny-order"></span><dl class="option">
+<dt id="cfg_Servers_AllowDeny_order">
+<tt class="descname">$cfg['Servers'][$i]['AllowDeny']['order']</tt><a class="headerlink" href="#cfg_Servers_AllowDeny_order" title="Permalink to this definition">¶</a></dt>
+<dd><table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Type:</th><td class="field-body">string</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Default value:</th><td class="field-body"><tt class="docutils literal"><span class="pre">''</span></tt></td>
+</tr>
+</tbody>
+</table>
+<p>If your rule order is empty, then <a class="reference internal" href="glossary.html#term-ip"><em class="xref std std-term">IP</em></a>
+authorization is disabled.</p>
+<p>If your rule order is set to
+<tt class="docutils literal"><span class="pre">'deny,allow'</span></tt> then the system applies all deny rules followed by
+allow rules. Access is allowed by default. Any client which does not
+match a Deny command or does match an Allow command will be allowed
+access to the server.</p>
+<p>If your rule order is set to <tt class="docutils literal"><span class="pre">'allow,deny'</span></tt>
+then the system applies all allow rules followed by deny rules. Access
+is denied by default. Any client which does not match an Allow
+directive or does match a Deny directive will be denied access to the
+server.</p>
+<p>If your rule order is set to <tt class="docutils literal"><span class="pre">'explicit'</span></tt>, authorization is
+performed in a similar fashion to rule order ‘deny,allow’, with the
+added restriction that your host/username combination <strong>must</strong> be
+listed in the <em>allow</em> rules, and not listed in the <em>deny</em> rules. This
+is the <strong>most</strong> secure means of using Allow/Deny rules, and was
+available in Apache by specifying allow and deny rules without setting
+any order.</p>
+<p>Please also see <span class="target" id="index-51"></span><a class="reference internal" href="#cfg_TrustedProxies"><tt class="xref config config-option docutils literal"><span class="pre">$cfg['TrustedProxies']</span></tt></a> for
+detecting IP address behind proxies.</p>
+</dd></dl>
+
+<span class="target" id="servers-allowdeny-rules"></span><dl class="option">
+<dt id="cfg_Servers_AllowDeny_rules">
+<tt class="descname">$cfg['Servers'][$i]['AllowDeny']['rules']</tt><a class="headerlink" href="#cfg_Servers_AllowDeny_rules" title="Permalink to this definition">¶</a></dt>
+<dd><table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Type:</th><td class="field-body">array of strings</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Default value:</th><td class="field-body">array()</td>
+</tr>
+</tbody>
+</table>
+<p>The general format for the rules is as such:</p>
+<div class="highlight-none"><div class="highlight"><pre><'allow' | 'deny'> <username> [from] <ipmask>
+</pre></div>
+</div>
+<p>If you wish to match all users, it is possible to use a <tt class="docutils literal"><span class="pre">'%'</span></tt> as a
+wildcard in the <em>username</em> field.</p>
+<p>There are a few shortcuts you can
+use in the <em>ipmask</em> field as well (please note that those containing
+SERVER_ADDRESS might not be available on all webservers):</p>
+<div class="highlight-none"><div class="highlight"><pre>'all' -> 0.0.0.0/0
+'localhost' -> 127.0.0.1/8
+'localnetA' -> SERVER_ADDRESS/8
+'localnetB' -> SERVER_ADDRESS/16
+'localnetC' -> SERVER_ADDRESS/24
+</pre></div>
+</div>
+<p>Having an empty rule list is equivalent to either using <tt class="docutils literal"><span class="pre">'allow</span> <span class="pre">%</span>
+<span class="pre">from</span> <span class="pre">all'</span></tt> if your rule order is set to <tt class="docutils literal"><span class="pre">'deny,allow'</span></tt> or <tt class="docutils literal"><span class="pre">'deny</span> <span class="pre">%</span>
+<span class="pre">from</span> <span class="pre">all'</span></tt> if your rule order is set to <tt class="docutils literal"><span class="pre">'allow,deny'</span></tt> or
+<tt class="docutils literal"><span class="pre">'explicit'</span></tt>.</p>
+<p>For the <a class="reference internal" href="glossary.html#term-ip-address"><em class="xref std std-term">IP address</em></a> matching
+system, the following work:</p>
+<ul class="simple">
+<li><tt class="docutils literal"><span class="pre">xxx.xxx.xxx.xxx</span></tt> (an exact <a class="reference internal" href="glossary.html#term-ip-address"><em class="xref std std-term">IP address</em></a>)</li>
+<li><tt class="docutils literal"><span class="pre">xxx.xxx.xxx.[yyy-zzz]</span></tt> (an <a class="reference internal" href="glossary.html#term-ip-address"><em class="xref std std-term">IP address</em></a> range)</li>
+<li><tt class="docutils literal"><span class="pre">xxx.xxx.xxx.xxx/nn</span></tt> (CIDR, Classless Inter-Domain Routing type <a class="reference internal" href="glossary.html#term-ip"><em class="xref std std-term">IP</em></a> addresses)</li>
+</ul>
+<p>But the following does not work:</p>
+<ul class="simple">
+<li><tt class="docutils literal"><span class="pre">xxx.xxx.xxx.xx[yyy-zzz]</span></tt> (partial <a class="reference internal" href="glossary.html#term-ip"><em class="xref std std-term">IP</em></a> address range)</li>
+</ul>
+<p>For <a class="reference internal" href="glossary.html#term-ipv6"><em class="xref std std-term">IPv6</em></a> addresses, the following work:</p>
+<ul class="simple">
+<li><tt class="docutils literal"><span class="pre">xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx</span></tt> (an exact <a class="reference internal" href="glossary.html#term-ipv6"><em class="xref std std-term">IPv6</em></a> address)</li>
+<li><tt class="docutils literal"><span class="pre">xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:[yyyy-zzzz]</span></tt> (an <a class="reference internal" href="glossary.html#term-ipv6"><em class="xref std std-term">IPv6</em></a> address range)</li>
+<li><tt class="docutils literal"><span class="pre">xxxx:xxxx:xxxx:xxxx/nn</span></tt> (CIDR, Classless Inter-Domain Routing type <a class="reference internal" href="glossary.html#term-ipv6"><em class="xref std std-term">IPv6</em></a> addresses)</li>
+</ul>
+<p>But the following does not work:</p>
+<ul class="simple">
+<li><tt class="docutils literal"><span class="pre">xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xx[yyy-zzz]</span></tt> (partial <a class="reference internal" href="glossary.html#term-ipv6"><em class="xref std std-term">IPv6</em></a> address range)</li>
+</ul>
+</dd></dl>
+
+<dl class="option">
+<dt id="cfg_Servers_DisableIS">
+<tt class="descname">$cfg['Servers'][$i]['DisableIS']</tt><a class="headerlink" href="#cfg_Servers_DisableIS" title="Permalink to this definition">¶</a></dt>
+<dd><table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Type:</th><td class="field-body">boolean</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Default value:</th><td class="field-body">true</td>
+</tr>
+</tbody>
+</table>
+<p>Disable using <tt class="docutils literal"><span class="pre">INFORMATION_SCHEMA</span></tt> to retrieve information (use
+<tt class="docutils literal"><span class="pre">SHOW</span></tt> commands instead), because of speed issues when many
+databases are present. Currently used in some parts of the code, more
+to come.</p>
+</dd></dl>
+
+<dl class="option">
+<dt id="cfg_Servers_ShowDatabasesCommand">
+<tt class="descname">$cfg['Servers'][$i]['ShowDatabasesCommand']</tt><a class="headerlink" href="#cfg_Servers_ShowDatabasesCommand" title="Permalink to this definition">¶</a></dt>
+<dd><table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Type:</th><td class="field-body">string</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Default value:</th><td class="field-body"><tt class="docutils literal"><span class="pre">'SHOW</span> <span class="pre">DATABASES'</span></tt></td>
+</tr>
+</tbody>
+</table>
+<p>On a server with a huge number of databases, the default <tt class="docutils literal"><span class="pre">SHOW</span> <span class="pre">DATABASES</span></tt>
+command used to fetch the name of available databases will probably be too
+slow, so it can be replaced by faster commands. You can use <tt class="docutils literal"><span class="pre">#user#</span></tt>
+string will be replaced by current user.</p>
+<p>When using <tt class="docutils literal"><span class="pre">false</span></tt>, it will disable fetching databases from the server,
+only databases in <span class="target" id="index-52"></span><a class="reference internal" href="#cfg_Servers_only_db"><tt class="xref config config-option docutils literal"><span class="pre">$cfg['Servers'][$i]['only_db']</span></tt></a> will be
+displayed.</p>
+<p>Examples:</p>
+<ul class="simple">
+<li><tt class="docutils literal"><span class="pre">'SHOW</span> <span class="pre">DATABASES'</span></tt></li>
+<li><tt class="docutils literal"><span class="pre">"SHOW</span> <span class="pre">DATABASES</span> <span class="pre">LIKE</span> <span class="pre">'#user#\_%'"</span></tt></li>
+<li><tt class="docutils literal"><span class="pre">'SELECT</span> <span class="pre">DISTINCT</span> <span class="pre">TABLE_SCHEMA</span> <span class="pre">FROM</span> <span class="pre">information_schema.SCHEMA_PRIVILEGES'</span></tt></li>
+<li><tt class="docutils literal"><span class="pre">'SELECT</span> <span class="pre">SCHEMA_NAME</span> <span class="pre">FROM</span> <span class="pre">information_schema.SCHEMATA'</span></tt></li>
+<li><tt class="docutils literal"><span class="pre">false</span></tt></li>
+</ul>
+</dd></dl>
+
+<dl class="option">
+<dt id="cfg_Servers_SignonScript">
+<tt class="descname">$cfg['Servers'][$i]['SignonScript']</tt><a class="headerlink" href="#cfg_Servers_SignonScript" title="Permalink to this definition">¶</a></dt>
+<dd><table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Type:</th><td class="field-body">string</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Default value:</th><td class="field-body"><tt class="docutils literal"><span class="pre">''</span></tt></td>
+</tr>
+</tbody>
+</table>
+<p>Name of PHP script to be sourced and executed to obtain login
+credentials. This is alternative approach to session based single
+signon. The script needs to provide function
+<tt class="docutils literal"><span class="pre">get_login_credentials</span></tt> which returns list of username and
+password, accepting single parameter of existing username (can be
+empty). See <tt class="file docutils literal"><span class="pre">examples/signon-script.php</span></tt> for an example.</p>
+</dd></dl>
+
+<dl class="option">
+<dt id="cfg_Servers_SignonSession">
+<tt class="descname">$cfg['Servers'][$i]['SignonSession']</tt><a class="headerlink" href="#cfg_Servers_SignonSession" title="Permalink to this definition">¶</a></dt>
+<dd><table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Type:</th><td class="field-body">string</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Default value:</th><td class="field-body"><tt class="docutils literal"><span class="pre">''</span></tt></td>
+</tr>
+</tbody>
+</table>
+<p>Name of session which will be used for signon authentication method.
+You should use something different than <tt class="docutils literal"><span class="pre">phpMyAdmin</span></tt>, because this
+is session which phpMyAdmin uses internally. Takes effect only if
+<span class="target" id="index-53"></span><a class="reference internal" href="#cfg_Servers_SignonScript"><tt class="xref config config-option docutils literal"><span class="pre">$cfg['Servers'][$i]['SignonScript']</span></tt></a> is not configured.</p>
+</dd></dl>
+
+<dl class="option">
+<dt id="cfg_Servers_SignonURL">
+<tt class="descname">$cfg['Servers'][$i]['SignonURL']</tt><a class="headerlink" href="#cfg_Servers_SignonURL" title="Permalink to this definition">¶</a></dt>
+<dd><table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Type:</th><td class="field-body">string</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Default value:</th><td class="field-body"><tt class="docutils literal"><span class="pre">''</span></tt></td>
+</tr>
+</tbody>
+</table>
+<p><a class="reference internal" href="glossary.html#term-url"><em class="xref std std-term">URL</em></a> where user will be redirected
+to log in for signon authentication method. Should be absolute
+including protocol.</p>
+</dd></dl>
+
+<dl class="option">
+<dt id="cfg_Servers_LogoutURL">
+<tt class="descname">$cfg['Servers'][$i]['LogoutURL']</tt><a class="headerlink" href="#cfg_Servers_LogoutURL" title="Permalink to this definition">¶</a></dt>
+<dd><table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Type:</th><td class="field-body">string</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Default value:</th><td class="field-body"><tt class="docutils literal"><span class="pre">''</span></tt></td>
+</tr>
+</tbody>
+</table>
+<p><a class="reference internal" href="glossary.html#term-url"><em class="xref std std-term">URL</em></a> where user will be redirected
+after logout (doesn’t affect config authentication method). Should be
+absolute including protocol.</p>
+</dd></dl>
+
+<dl class="option">
+<dt id="cfg_Servers_StatusCacheDatabases">
+<tt class="descname">$cfg['Servers'][$i]['StatusCacheDatabases']</tt><a class="headerlink" href="#cfg_Servers_StatusCacheDatabases" title="Permalink to this definition">¶</a></dt>
+<dd><table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Type:</th><td class="field-body">array of strings</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Default value:</th><td class="field-body">array()</td>
+</tr>
+</tbody>
+</table>
+<p>Enables caching of <tt class="docutils literal"><span class="pre">TABLE</span> <span class="pre">STATUS</span></tt> outputs for specific databases on
+this server (in some cases <tt class="docutils literal"><span class="pre">TABLE</span> <span class="pre">STATUS</span></tt> can be very slow, so you
+may want to cache it). APC is used (if the PHP extension is available,
+if not, this setting is ignored silently). You have to provide
+<span class="target" id="index-54"></span><a class="reference internal" href="#cfg_Servers_StatusCacheLifetime"><tt class="xref config config-option docutils literal"><span class="pre">$cfg['Servers'][$i]['StatusCacheLifetime']</span></tt></a>.</p>
+<p>Takes effect only if <span class="target" id="index-55"></span><a class="reference internal" href="#cfg_Servers_DisableIS"><tt class="xref config config-option docutils literal"><span class="pre">$cfg['Servers'][$i]['DisableIS']</span></tt></a> is
+<tt class="docutils literal"><span class="pre">true</span></tt>.</p>
+</dd></dl>
+
+<dl class="option">
+<dt id="cfg_Servers_StatusCacheLifetime">
+<tt class="descname">$cfg['Servers'][$i]['StatusCacheLifetime']</tt><a class="headerlink" href="#cfg_Servers_StatusCacheLifetime" title="Permalink to this definition">¶</a></dt>
+<dd><table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Type:</th><td class="field-body">integer</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Default value:</th><td class="field-body">0</td>
+</tr>
+</tbody>
+</table>
+<p>Lifetime in seconds of the <tt class="docutils literal"><span class="pre">TABLE</span> <span class="pre">STATUS</span></tt> cache if
+<span class="target" id="index-56"></span><a class="reference internal" href="#cfg_Servers_StatusCacheDatabases"><tt class="xref config config-option docutils literal"><span class="pre">$cfg['Servers'][$i]['StatusCacheDatabases']</span></tt></a> is used.</p>
+</dd></dl>
+
+</div>
+<div class="section" id="generic-settings">
+<h2>Generic settings<a class="headerlink" href="#generic-settings" title="Permalink to this headline">¶</a></h2>
+<dl class="option">
+<dt id="cfg_ServerDefault">
+<tt class="descname">$cfg['ServerDefault']</tt><a class="headerlink" href="#cfg_ServerDefault" title="Permalink to this definition">¶</a></dt>
+<dd><table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Type:</th><td class="field-body">integer</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Default value:</th><td class="field-body">1</td>
+</tr>
+</tbody>
+</table>
+<p>If you have more than one server configured, you can set
+<span class="target" id="index-57"></span><a class="reference internal" href="#cfg_ServerDefault"><tt class="xref config config-option docutils literal"><span class="pre">$cfg['ServerDefault']</span></tt></a> to any one of them to autoconnect to that
+server when phpMyAdmin is started, or set it to 0 to be given a list
+of servers without logging in.</p>
+<p>If you have only one server configured,
+<span class="target" id="index-58"></span><a class="reference internal" href="#cfg_ServerDefault"><tt class="xref config config-option docutils literal"><span class="pre">$cfg['ServerDefault']</span></tt></a> MUST be set to that server.</p>
+</dd></dl>
+
+<dl class="option">
+<dt id="cfg_VersionCheck">
+<tt class="descname">$cfg['VersionCheck']</tt><a class="headerlink" href="#cfg_VersionCheck" title="Permalink to this definition">¶</a></dt>
+<dd><table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Type:</th><td class="field-body">boolean</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Default value:</th><td class="field-body">true</td>
+</tr>
+</tbody>
+</table>
+<p>Enables check for latest versions using javascript on main phpMyAdmin
+page.</p>
+<div class="admonition note">
+<p class="first admonition-title">Note</p>
+<p class="last">This setting can be adjusted by your vendor.</p>
+</div>
+</dd></dl>
+
+<dl class="option">
+<dt id="cfg_MaxDbList">
+<tt class="descname">$cfg['MaxDbList']</tt><a class="headerlink" href="#cfg_MaxDbList" title="Permalink to this definition">¶</a></dt>
+<dd><table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Type:</th><td class="field-body">integer</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Default value:</th><td class="field-body">100</td>
+</tr>
+</tbody>
+</table>
+<p>The maximum number of database names to be displayed in the main panel’s
+database list.</p>
+</dd></dl>
+
+<dl class="option">
+<dt id="cfg_MaxNavigationItems">
+<tt class="descname">$cfg['MaxNavigationItems']</tt><a class="headerlink" href="#cfg_MaxNavigationItems" title="Permalink to this definition">¶</a></dt>
+<dd><table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Type:</th><td class="field-body">integer</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Default value:</th><td class="field-body">25</td>
+</tr>
+</tbody>
+</table>
+<p>The number of items that can be displayed on each page of the
+navigation tree.</p>
+</dd></dl>
+
+<dl class="option">
+<dt id="cfg_MaxTableList">
+<tt class="descname">$cfg['MaxTableList']</tt><a class="headerlink" href="#cfg_MaxTableList" title="Permalink to this definition">¶</a></dt>
+<dd><table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Type:</th><td class="field-body">integer</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Default value:</th><td class="field-body">250</td>
+</tr>
+</tbody>
+</table>
+<p>The maximum number of table names to be displayed in the main panel’s
+list (except on the Export page). This limit is also enforced in the
+navigation panel when in Light mode.</p>
+</dd></dl>
+
+<dl class="option">
+<dt id="cfg_ShowHint">
+<tt class="descname">$cfg['ShowHint']</tt><a class="headerlink" href="#cfg_ShowHint" title="Permalink to this definition">¶</a></dt>
+<dd><table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Type:</th><td class="field-body">boolean</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Default value:</th><td class="field-body">true</td>
+</tr>
+</tbody>
+</table>
+<p>Whether or not to show hints (for example, hints when hovering over
+table headers).</p>
+</dd></dl>
+
+<dl class="option">
+<dt id="cfg_MaxCharactersInDisplayedSQL">
+<tt class="descname">$cfg['MaxCharactersInDisplayedSQL']</tt><a class="headerlink" href="#cfg_MaxCharactersInDisplayedSQL" title="Permalink to this definition">¶</a></dt>
+<dd><table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Type:</th><td class="field-body">integer</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Default value:</th><td class="field-body">1000</td>
+</tr>
+</tbody>
+</table>
+<p>The maximum number of characters when a <a class="reference internal" href="glossary.html#term-sql"><em class="xref std std-term">SQL</em></a> query is displayed. The
+default limit of 1000 should be correct to avoid the display of tons of
+hexadecimal codes that represent BLOBs, but some users have real
+<a class="reference internal" href="glossary.html#term-sql"><em class="xref std std-term">SQL</em></a> queries that are longer than 1000 characters. Also, if a
+query’s length exceeds this limit, this query is not saved in the history.</p>
+</dd></dl>
+
+<dl class="option">
+<dt id="cfg_PersistentConnections">
+<tt class="descname">$cfg['PersistentConnections']</tt><a class="headerlink" href="#cfg_PersistentConnections" title="Permalink to this definition">¶</a></dt>
+<dd><table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Type:</th><td class="field-body">boolean</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Default value:</th><td class="field-body">false</td>
+</tr>
+</tbody>
+</table>
+<p>Whether <a class="reference external" href="http://php.net/manual/en/features.persistent-connections.php">persistent connections</a> should be used or not. Works with
+following extensions:</p>
+<ul class="simple">
+<li>mysql (<a class="reference external" href="http://php.net/manual/en/function.mysql-pconnect.php">mysql_pconnect</a>),</li>
+<li>mysqli (requires PHP 5.3.0 or newer, <a class="reference external" href="http://php.net/manual/en/mysqli.persistconns.php">more information</a>).</li>
+</ul>
+</dd></dl>
+
+<dl class="option">
+<dt id="cfg_ForceSSL">
+<tt class="descname">$cfg['ForceSSL']</tt><a class="headerlink" href="#cfg_ForceSSL" title="Permalink to this definition">¶</a></dt>
+<dd><table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Type:</th><td class="field-body">boolean</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Default value:</th><td class="field-body">false</td>
+</tr>
+</tbody>
+</table>
+<p>Whether to force using https while accessing phpMyAdmin.</p>
+</dd></dl>
+
+<dl class="option">
+<dt id="cfg_ExecTimeLimit">
+<tt class="descname">$cfg['ExecTimeLimit']</tt><a class="headerlink" href="#cfg_ExecTimeLimit" title="Permalink to this definition">¶</a></dt>
+<dd><table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Type:</th><td class="field-body">integer [number of seconds]</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Default value:</th><td class="field-body">300</td>
+</tr>
+</tbody>
+</table>
+<p>Set the number of seconds a script is allowed to run. If seconds is
+set to zero, no time limit is imposed. This setting is used while
+importing/exporting dump files but has
+no effect when PHP is running in safe mode.</p>
+</dd></dl>
+
+<dl class="option">
+<dt id="cfg_SessionSavePath">
+<tt class="descname">$cfg['SessionSavePath']</tt><a class="headerlink" href="#cfg_SessionSavePath" title="Permalink to this definition">¶</a></dt>
+<dd><table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Type:</th><td class="field-body">string</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Default value:</th><td class="field-body"><tt class="docutils literal"><span class="pre">''</span></tt></td>
+</tr>
+</tbody>
+</table>
+<p>Path for storing session data (<a class="reference external" href="http://php.net/session_save_path">session_save_path PHP parameter</a>).</p>
+</dd></dl>
+
+<dl class="option">
+<dt id="cfg_MemoryLimit">
+<tt class="descname">$cfg['MemoryLimit']</tt><a class="headerlink" href="#cfg_MemoryLimit" title="Permalink to this definition">¶</a></dt>
+<dd><table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Type:</th><td class="field-body">string [number of bytes]</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Default value:</th><td class="field-body"><tt class="docutils literal"><span class="pre">'0'</span></tt></td>
+</tr>
+</tbody>
+</table>
+<p>Set the number of bytes a script is allowed to allocate. If set to
+zero, no limit is imposed.</p>
+<p>This setting is used while importing/exporting dump files and at some other
+places in phpMyAdmin so you definitely don’t want to put here a too low
+value. It has no effect when PHP is running in safe mode.</p>
+<p>You can also use any string as in <tt class="file docutils literal"><span class="pre">php.ini</span></tt>, eg. ‘16M’. Ensure you
+don’t omit the suffix (16 means 16 bytes!)</p>
+</dd></dl>
+
+<dl class="option">
+<dt id="cfg_SkipLockedTables">
+<tt class="descname">$cfg['SkipLockedTables']</tt><a class="headerlink" href="#cfg_SkipLockedTables" title="Permalink to this definition">¶</a></dt>
+<dd><table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Type:</th><td class="field-body">boolean</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Default value:</th><td class="field-body">false</td>
+</tr>
+</tbody>
+</table>
+<p>Mark used tables and make it possible to show databases with locked
+tables (since MySQL 3.23.30).</p>
+</dd></dl>
+
+<dl class="option">
+<dt id="cfg_ShowSQL">
+<tt class="descname">$cfg['ShowSQL']</tt><a class="headerlink" href="#cfg_ShowSQL" title="Permalink to this definition">¶</a></dt>
+<dd><table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Type:</th><td class="field-body">boolean</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Default value:</th><td class="field-body">true</td>
+</tr>
+</tbody>
+</table>
+<p>Defines whether <a class="reference internal" href="glossary.html#term-sql"><em class="xref std std-term">SQL</em></a> queries
+generated by phpMyAdmin should be displayed or not.</p>
+</dd></dl>
+
+<dl class="option">
+<dt id="cfg_RetainQueryBox">
+<tt class="descname">$cfg['RetainQueryBox']</tt><a class="headerlink" href="#cfg_RetainQueryBox" title="Permalink to this definition">¶</a></dt>
+<dd><table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Type:</th><td class="field-body">boolean</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Default value:</th><td class="field-body">false</td>
+</tr>
+</tbody>
+</table>
+<p>Defines whether the <a class="reference internal" href="glossary.html#term-sql"><em class="xref std std-term">SQL</em></a> query box
+should be kept displayed after its submission.</p>
+</dd></dl>
+
+<dl class="option">
+<dt id="cfg_CodemirrorEnable">
+<tt class="descname">$cfg['CodemirrorEnable']</tt><a class="headerlink" href="#cfg_CodemirrorEnable" title="Permalink to this definition">¶</a></dt>
+<dd><table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Type:</th><td class="field-body">boolean</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Default value:</th><td class="field-body">true</td>
+</tr>
+</tbody>
+</table>
+<p>Defines whether to use a Javascript code editor for SQL query boxes.
+CodeMirror provides syntax highlighting and line numbers.  However,
+middle-clicking for pasting the clipboard contents in some Linux
+distributions (such as Ubuntu) is not supported by all browsers.</p>
+</dd></dl>
+
+<dl class="option">
+<dt id="cfg_AllowUserDropDatabase">
+<tt class="descname">$cfg['AllowUserDropDatabase']</tt><a class="headerlink" href="#cfg_AllowUserDropDatabase" title="Permalink to this definition">¶</a></dt>
+<dd><table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Type:</th><td class="field-body">boolean</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Default value:</th><td class="field-body">false</td>
+</tr>
+</tbody>
+</table>
+<p>Defines whether normal users (non-administrator) are allowed to delete
+their own database or not. If set as false, the link <em class="guilabel">Drop
+Database</em> will not be shown, and even a <tt class="docutils literal"><span class="pre">DROP</span> <span class="pre">DATABASE</span> <span class="pre">mydatabase</span></tt> will
+be rejected. Quite practical for <a class="reference internal" href="glossary.html#term-isp"><em class="xref std std-term">ISP</em></a> ‘s with many customers.</p>
+<div class="admonition note">
+<p class="first admonition-title">Note</p>
+<p class="last">This limitation of <a class="reference internal" href="glossary.html#term-sql"><em class="xref std std-term">SQL</em></a> queries is not
+as strict as when using MySQL privileges. This is due to nature of
+<a class="reference internal" href="glossary.html#term-sql"><em class="xref std std-term">SQL</em></a> queries which might be quite
+complicated.  So this choice should be viewed as help to avoid accidental
+dropping rather than strict privilege limitation.</p>
+</div>
+</dd></dl>
+
+<dl class="option">
+<dt id="cfg_Confirm">
+<tt class="descname">$cfg['Confirm']</tt><a class="headerlink" href="#cfg_Confirm" title="Permalink to this definition">¶</a></dt>
+<dd><table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Type:</th><td class="field-body">boolean</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Default value:</th><td class="field-body">true</td>
+</tr>
+</tbody>
+</table>
+<p>Whether a warning (“Are your really sure...”) should be displayed when
+you’re about to lose data.</p>
+</dd></dl>
+
+<dl class="option">
+<dt id="cfg_UseDbSearch">
+<tt class="descname">$cfg['UseDbSearch']</tt><a class="headerlink" href="#cfg_UseDbSearch" title="Permalink to this definition">¶</a></dt>
+<dd><table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Type:</th><td class="field-body">boolean</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Default value:</th><td class="field-body">true</td>
+</tr>
+</tbody>
+</table>
+<p>Define whether the “search string inside database” is enabled or not.</p>
+</dd></dl>
+
+<dl class="option">
+<dt id="cfg_IgnoreMultiSubmitErrors">
+<tt class="descname">$cfg['IgnoreMultiSubmitErrors']</tt><a class="headerlink" href="#cfg_IgnoreMultiSubmitErrors" title="Permalink to this definition">¶</a></dt>
+<dd><table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Type:</th><td class="field-body">boolean</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Default value:</th><td class="field-body">false</td>
+</tr>
+</tbody>
+</table>
+<p>Define whether phpMyAdmin will continue executing a multi-query
+statement if one of the queries fails. Default is to abort execution.</p>
+</dd></dl>
+
+</div>
+<div class="section" id="cookie-authentication-options">
+<h2>Cookie authentication options<a class="headerlink" href="#cookie-authentication-options" title="Permalink to this headline">¶</a></h2>
+<dl class="option">
+<dt id="cfg_blowfish_secret">
+<tt class="descname">$cfg['blowfish_secret']</tt><a class="headerlink" href="#cfg_blowfish_secret" title="Permalink to this definition">¶</a></dt>
+<dd><table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Type:</th><td class="field-body">string</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Default value:</th><td class="field-body"><tt class="docutils literal"><span class="pre">''</span></tt></td>
+</tr>
+</tbody>
+</table>
+<p>The “cookie” auth_type uses blowfish algorithm to encrypt the
+password. If you are using the “cookie” auth_type, enter here a
+random passphrase of your choice. It will be used internally by the
+blowfish algorithm: you won’t be prompted for this passphrase. There
+is no maximum length for this secret.</p>
+<p class="versionchanged">
+<span class="versionmodified">Changed in version 3.1.0: </span>Since version 3.1.0 phpMyAdmin can generate this on the fly, but it
+makes a bit weaker security as this generated secret is stored in
+session and furthermore it makes impossible to recall user name from
+cookie.</p>
+</dd></dl>
+
+<dl class="option">
+<dt id="cfg_LoginCookieRecall">
+<tt class="descname">$cfg['LoginCookieRecall']</tt><a class="headerlink" href="#cfg_LoginCookieRecall" title="Permalink to this definition">¶</a></dt>
+<dd><table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Type:</th><td class="field-body">boolean</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Default value:</th><td class="field-body">true</td>
+</tr>
+</tbody>
+</table>
+<p>Define whether the previous login should be recalled or not in cookie
+authentication mode.</p>
+<p>This is automatically disabled if you do not have
+configured <span class="target" id="index-59"></span><a class="reference internal" href="#cfg_blowfish_secret"><tt class="xref config config-option docutils literal"><span class="pre">$cfg['blowfish_secret']</span></tt></a>.</p>
+</dd></dl>
+
+<dl class="option">
+<dt id="cfg_LoginCookieValidity">
+<tt class="descname">$cfg['LoginCookieValidity']</tt><a class="headerlink" href="#cfg_LoginCookieValidity" title="Permalink to this definition">¶</a></dt>
+<dd><table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Type:</th><td class="field-body">integer [number of seconds]</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Default value:</th><td class="field-body">1440</td>
+</tr>
+</tbody>
+</table>
+<p>Define how long a login cookie is valid. Please note that php
+configuration option <a class="reference external" href="http://php.net/manual/en/session.configuration.php#ini.session.gc-maxlifetime">session.gc_maxlifetime</a> might limit session validity and if the session is lost,
+the login cookie is also invalidated. So it is a good idea to set
+<tt class="docutils literal"><span class="pre">session.gc_maxlifetime</span></tt> at least to the same value of
+<span class="target" id="index-60"></span><a class="reference internal" href="#cfg_LoginCookieValidity"><tt class="xref config config-option docutils literal"><span class="pre">$cfg['LoginCookieValidity']</span></tt></a>.</p>
+</dd></dl>
+
+<dl class="option">
+<dt id="cfg_LoginCookieStore">
+<tt class="descname">$cfg['LoginCookieStore']</tt><a class="headerlink" href="#cfg_LoginCookieStore" title="Permalink to this definition">¶</a></dt>
+<dd><table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Type:</th><td class="field-body">integer [number of seconds]</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Default value:</th><td class="field-body">0</td>
+</tr>
+</tbody>
+</table>
+<p>Define how long login cookie should be stored in browser. Default 0
+means that it will be kept for existing session. This is recommended
+for not trusted environments.</p>
+</dd></dl>
+
+<dl class="option">
+<dt id="cfg_LoginCookieDeleteAll">
+<tt class="descname">$cfg['LoginCookieDeleteAll']</tt><a class="headerlink" href="#cfg_LoginCookieDeleteAll" title="Permalink to this definition">¶</a></dt>
+<dd><table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Type:</th><td class="field-body">boolean</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Default value:</th><td class="field-body">true</td>
+</tr>
+</tbody>
+</table>
+<p>If enabled (default), logout deletes cookies for all servers,
+otherwise only for current one. Setting this to false makes it easy to
+forget to log out from other server, when you are using more of them.</p>
+</dd></dl>
+
+<span class="target" id="allowarbitraryserver"></span><dl class="option">
+<dt id="cfg_AllowArbitraryServer">
+<tt class="descname">$cfg['AllowArbitraryServer']</tt><a class="headerlink" href="#cfg_AllowArbitraryServer" title="Permalink to this definition">¶</a></dt>
+<dd><table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Type:</th><td class="field-body">boolean</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Default value:</th><td class="field-body">false</td>
+</tr>
+</tbody>
+</table>
+<p>If enabled, allows you to log in to arbitrary servers using cookie
+authentication.</p>
+<div class="admonition note">
+<p class="first admonition-title">Note</p>
+<p class="last">Please use this carefully, as this may allow users access to MySQL servers
+behind the firewall where your <a class="reference internal" href="glossary.html#term-http"><em class="xref std std-term">HTTP</em></a>
+server is placed.</p>
+</div>
+</dd></dl>
+
+</div>
+<div class="section" id="navigation-panel-setup">
+<h2>Navigation panel setup<a class="headerlink" href="#navigation-panel-setup" title="Permalink to this headline">¶</a></h2>
+<dl class="option">
+<dt id="cfg_NavigationTreeEnableGrouping">
+<tt class="descname">$cfg['NavigationTreeEnableGrouping']</tt><a class="headerlink" href="#cfg_NavigationTreeEnableGrouping" title="Permalink to this definition">¶</a></dt>
+<dd><table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Type:</th><td class="field-body">boolean</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Default value:</th><td class="field-body">true</td>
+</tr>
+</tbody>
+</table>
+<p>Defines whether to group the databases based on a common prefix
+in their name <span class="target" id="index-61"></span><a class="reference internal" href="#cfg_NavigationTreeDbSeparator"><tt class="xref config config-option docutils literal"><span class="pre">$cfg['NavigationTreeDbSeparator']</span></tt></a>.</p>
+</dd></dl>
+
+<dl class="option">
+<dt id="cfg_NavigationTreeDbSeparator">
+<tt class="descname">$cfg['NavigationTreeDbSeparator']</tt><a class="headerlink" href="#cfg_NavigationTreeDbSeparator" title="Permalink to this definition">¶</a></dt>
+<dd><table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Type:</th><td class="field-body">string or array</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Default value:</th><td class="field-body"><tt class="docutils literal"><span class="pre">'_'</span></tt></td>
+</tr>
+</tbody>
+</table>
+<p>The string used to separate the parts of the database name when
+showing them in a tree. Alternatively you can specify more strings in
+an array and all of them will be used as a separator.</p>
+</dd></dl>
+
+<dl class="option">
+<dt id="cfg_NavigationTreeTableSeparator">
+<tt class="descname">$cfg['NavigationTreeTableSeparator']</tt><a class="headerlink" href="#cfg_NavigationTreeTableSeparator" title="Permalink to this definition">¶</a></dt>
+<dd><table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Type:</th><td class="field-body">string or array</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Default value:</th><td class="field-body"><tt class="docutils literal"><span class="pre">'__'</span></tt></td>
+</tr>
+</tbody>
+</table>
+<p>Defines a string to be used to nest table spaces. This means if you have
+tables like <tt class="docutils literal"><span class="pre">first__second__third</span></tt> this will be shown as a three-level
+hierarchy like: first > second > third.  If set to false or empty, the
+feature is disabled. NOTE: You should not use this separator at the
+beginning or end of a table name or multiple times after another without
+any other characters in between.</p>
+</dd></dl>
+
+<dl class="option">
+<dt id="cfg_NavigationTreeTableLevel">
+<tt class="descname">$cfg['NavigationTreeTableLevel']</tt><a class="headerlink" href="#cfg_NavigationTreeTableLevel" title="Permalink to this definition">¶</a></dt>
+<dd><table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Type:</th><td class="field-body">integer</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Default value:</th><td class="field-body">1</td>
+</tr>
+</tbody>
+</table>
+<p>Defines how many sublevels should be displayed when splitting up
+tables by the above separator.</p>
+</dd></dl>
+
+<dl class="option">
+<dt id="cfg_NumRecentTables">
+<tt class="descname">$cfg['NumRecentTables']</tt><a class="headerlink" href="#cfg_NumRecentTables" title="Permalink to this definition">¶</a></dt>
+<dd><table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Type:</th><td class="field-body">integer</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Default value:</th><td class="field-body">10</td>
+</tr>
+</tbody>
+</table>
+<p>The maximum number of recently used tables shown in the navigation
+panel. Set this to 0 (zero) to disable the listing of recent tables.</p>
+</dd></dl>
+
+<dl class="option">
+<dt id="cfg_ShowTooltip">
+<tt class="descname">$cfg['ShowTooltip']</tt><a class="headerlink" href="#cfg_ShowTooltip" title="Permalink to this definition">¶</a></dt>
+<dd><table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Type:</th><td class="field-body">boolean</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Default value:</th><td class="field-body">true</td>
+</tr>
+</tbody>
+</table>
+<p>Defines whether to display item comments as tooltips in navigation
+panel or not.</p>
+</dd></dl>
+
+<dl class="option">
+<dt id="cfg_NavigationDisplayLogo">
+<tt class="descname">$cfg['NavigationDisplayLogo']</tt><a class="headerlink" href="#cfg_NavigationDisplayLogo" title="Permalink to this definition">¶</a></dt>
+<dd><table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Type:</th><td class="field-body">boolean</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Default value:</th><td class="field-body">true</td>
+</tr>
+</tbody>
+</table>
+<p>Defines whether or not to display the phpMyAdmin logo at the top of
+the navigation panel.</p>
+</dd></dl>
+
+<dl class="option">
+<dt id="cfg_NavigationLogoLink">
+<tt class="descname">$cfg['NavigationLogoLink']</tt><a class="headerlink" href="#cfg_NavigationLogoLink" title="Permalink to this definition">¶</a></dt>
+<dd><table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Type:</th><td class="field-body">string</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Default value:</th><td class="field-body"><tt class="docutils literal"><span class="pre">'index.php'</span></tt></td>
+</tr>
+</tbody>
+</table>
+<p>Enter <a class="reference internal" href="glossary.html#term-url"><em class="xref std std-term">URL</em></a> where logo in the
+navigation panel will point to. For use especially with self made
+theme which changes this.</p>
+</dd></dl>
+
+<dl class="option">
+<dt id="cfg_NavigationLogoLinkWindow">
+<tt class="descname">$cfg['NavigationLogoLinkWindow']</tt><a class="headerlink" href="#cfg_NavigationLogoLinkWindow" title="Permalink to this definition">¶</a></dt>
+<dd><table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Type:</th><td class="field-body">string</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Default value:</th><td class="field-body"><tt class="docutils literal"><span class="pre">'main'</span></tt></td>
+</tr>
+</tbody>
+</table>
+<p>Whether to open the linked page in the main window (<tt class="docutils literal"><span class="pre">main</span></tt>) or in a
+new one (<tt class="docutils literal"><span class="pre">new</span></tt>). Note: use <tt class="docutils literal"><span class="pre">new</span></tt> if you are linking to
+<tt class="docutils literal"><span class="pre">phpmyadmin.net</span></tt>.</p>
+</dd></dl>
+
+<dl class="option">
+<dt id="cfg_NavigationTreeDisplayItemFilterMinimum">
+<tt class="descname">$cfg['NavigationTreeDisplayItemFilterMinimum']</tt><a class="headerlink" href="#cfg_NavigationTreeDisplayItemFilterMinimum" title="Permalink to this definition">¶</a></dt>
+<dd><table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Type:</th><td class="field-body">integer</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Default value:</th><td class="field-body">30</td>
+</tr>
+</tbody>
+</table>
+<p>Defines the minimum number of items (tables, views, routines and
+events) to display a JavaScript filter box above the list of items in
+the navigation tree.</p>
+<p>To disable the filter completely some high number can be used (e.g. 9999)</p>
+</dd></dl>
+
+<dl class="option">
+<dt id="cfg_NavigationTreeDisplayDbFilterMinimum">
+<tt class="descname">$cfg['NavigationTreeDisplayDbFilterMinimum']</tt><a class="headerlink" href="#cfg_NavigationTreeDisplayDbFilterMinimum" title="Permalink to this definition">¶</a></dt>
+<dd><table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Type:</th><td class="field-body">integer</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Default value:</th><td class="field-body">30</td>
+</tr>
+</tbody>
+</table>
+<p>Defines the minimum number of databases to display a JavaScript filter
+box above the list of databases in the navigation tree.</p>
+<p>To disable the filter completely some high number can be used
+(e.g. 9999)</p>
+</dd></dl>
+
+<dl class="option">
+<dt id="cfg_NavigationDisplayServers">
+<tt class="descname">$cfg['NavigationDisplayServers']</tt><a class="headerlink" href="#cfg_NavigationDisplayServers" title="Permalink to this definition">¶</a></dt>
+<dd><table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Type:</th><td class="field-body">boolean</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Default value:</th><td class="field-body">true</td>
+</tr>
+</tbody>
+</table>
+<p>Defines whether or not to display a server choice at the top of the
+navigation panel.</p>
+</dd></dl>
+
+<dl class="option">
+<dt id="cfg_DisplayServersList">
+<tt class="descname">$cfg['DisplayServersList']</tt><a class="headerlink" href="#cfg_DisplayServersList" title="Permalink to this definition">¶</a></dt>
+<dd><table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Type:</th><td class="field-body">boolean</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Default value:</th><td class="field-body">false</td>
+</tr>
+</tbody>
+</table>
+<p>Defines whether to display this server choice as links instead of in a
+drop-down.</p>
+</dd></dl>
+
+<dl class="option">
+<dt id="cfg_NavigationTreeDefaultTabTable">
+<tt class="descname">$cfg['NavigationTreeDefaultTabTable']</tt><a class="headerlink" href="#cfg_NavigationTreeDefaultTabTable" title="Permalink to this definition">¶</a></dt>
+<dd><table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Type:</th><td class="field-body">string</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Default value:</th><td class="field-body"><tt class="docutils literal"><span class="pre">'tbl_structure.php'</span></tt></td>
+</tr>
+</tbody>
+</table>
+<p>Defines the tab displayed by default when clicking the small icon next
+to each table name in the navigation panel. Possible values:</p>
+<ul class="simple">
+<li><tt class="docutils literal"><span class="pre">tbl_structure.php</span></tt></li>
+<li><tt class="docutils literal"><span class="pre">tbl_sql.php</span></tt></li>
+<li><tt class="docutils literal"><span class="pre">tbl_select.php</span></tt></li>
+<li><tt class="docutils literal"><span class="pre">tbl_change.php</span></tt></li>
+<li><tt class="docutils literal"><span class="pre">sql.php</span></tt></li>
+</ul>
+</dd></dl>
+
+</div>
+<div class="section" id="main-panel">
+<h2>Main panel<a class="headerlink" href="#main-panel" title="Permalink to this headline">¶</a></h2>
+<dl class="option">
+<dt id="cfg_ShowStats">
+<tt class="descname">$cfg['ShowStats']</tt><a class="headerlink" href="#cfg_ShowStats" title="Permalink to this definition">¶</a></dt>
+<dd><table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Type:</th><td class="field-body">boolean</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Default value:</th><td class="field-body">true</td>
+</tr>
+</tbody>
+</table>
+<p>Defines whether or not to display space usage and statistics about
+databases and tables. Note that statistics requires at least MySQL
+3.23.3 and that, at this date, MySQL doesn’t return such information
+for Berkeley DB tables.</p>
+</dd></dl>
+
+<dl class="option">
+<dt id="cfg_ShowServerInfo">
+<tt class="descname">$cfg['ShowServerInfo']</tt><a class="headerlink" href="#cfg_ShowServerInfo" title="Permalink to this definition">¶</a></dt>
+<dd><table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Type:</th><td class="field-body">boolean</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Default value:</th><td class="field-body">true</td>
+</tr>
+</tbody>
+</table>
+<p>Defines whether to display detailed server information on main page.
+You can additionally hide more information by using
+<span class="target" id="index-62"></span><a class="reference internal" href="#cfg_Servers_verbose"><tt class="xref config config-option docutils literal"><span class="pre">$cfg['Servers'][$i]['verbose']</span></tt></a>.</p>
+</dd></dl>
+
+<dl class="option">
+<dt id="cfg_ShowPhpInfo">
+<tt class="descname">$cfg['ShowPhpInfo']</tt><a class="headerlink" href="#cfg_ShowPhpInfo" title="Permalink to this definition">¶</a></dt>
+<dd><table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Type:</th><td class="field-body">boolean</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Default value:</th><td class="field-body">false</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+<dl class="option">
+<dt id="cfg_ShowChgPassword">
+<tt class="descname">$cfg['ShowChgPassword']</tt><a class="headerlink" href="#cfg_ShowChgPassword" title="Permalink to this definition">¶</a></dt>
+<dd><table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Type:</th><td class="field-body">boolean</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Default value:</th><td class="field-body">true</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+<dl class="option">
+<dt id="cfg_ShowCreateDb">
+<tt class="descname">$cfg['ShowCreateDb']</tt><a class="headerlink" href="#cfg_ShowCreateDb" title="Permalink to this definition">¶</a></dt>
+<dd><table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Type:</th><td class="field-body">boolean</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Default value:</th><td class="field-body">true</td>
+</tr>
+</tbody>
+</table>
+<p>Defines whether to display the <em class="guilabel">PHP information</em> and
+<em class="guilabel">Change password</em> links and form for creating database or not at
+the starting main (right) frame. This setting does not check MySQL commands
+entered directly.</p>
+<p>Please note that to block the usage of <tt class="docutils literal"><span class="pre">phpinfo()</span></tt> in scripts, you have to
+put this in your <tt class="file docutils literal"><span class="pre">php.ini</span></tt>:</p>
+<div class="highlight-ini"><div class="highlight"><pre><span class="na">disable_functions</span> <span class="o">=</span> <span class="s">phpinfo()</span>
+</pre></div>
+</div>
+<p>Also note that enabling the <em class="guilabel">Change password</em> link has no effect
+with config authentication mode: because of the hard coded password value
+in the configuration file, end users can’t be allowed to change their
+passwords.</p>
+</dd></dl>
+
+</div>
+<div class="section" id="database-structure">
+<h2>Database structure<a class="headerlink" href="#database-structure" title="Permalink to this headline">¶</a></h2>
+<dl class="option">
+<dt id="cfg_ShowDbStructureCreation">
+<tt class="descname">$cfg['ShowDbStructureCreation']</tt><a class="headerlink" href="#cfg_ShowDbStructureCreation" title="Permalink to this definition">¶</a></dt>
+<dd><table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Type:</th><td class="field-body">boolean</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Default value:</th><td class="field-body">false</td>
+</tr>
+</tbody>
+</table>
+<p>Defines whether the database structure page (tables list) has a
+“Creation” column that displays when each table was created.</p>
+</dd></dl>
+
+<dl class="option">
+<dt id="cfg_ShowDbStructureLastUpdate">
+<tt class="descname">$cfg['ShowDbStructureLastUpdate']</tt><a class="headerlink" href="#cfg_ShowDbStructureLastUpdate" title="Permalink to this definition">¶</a></dt>
+<dd><table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Type:</th><td class="field-body">boolean</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Default value:</th><td class="field-body">false</td>
+</tr>
+</tbody>
+</table>
+<p>Defines whether the database structure page (tables list) has a “Last
+update” column that displays when each table was last updated.</p>
+</dd></dl>
+
+<dl class="option">
+<dt id="cfg_ShowDbStructureLastCheck">
+<tt class="descname">$cfg['ShowDbStructureLastCheck']</tt><a class="headerlink" href="#cfg_ShowDbStructureLastCheck" title="Permalink to this definition">¶</a></dt>
+<dd><table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Type:</th><td class="field-body">boolean</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Default value:</th><td class="field-body">false</td>
+</tr>
+</tbody>
+</table>
+<p>Defines whether the database structure page (tables list) has a “Last
+check” column that displays when each table was last checked.</p>
+</dd></dl>
+
+<dl class="option">
+<dt id="cfg_HideStructureActions">
+<tt class="descname">$cfg['HideStructureActions']</tt><a class="headerlink" href="#cfg_HideStructureActions" title="Permalink to this definition">¶</a></dt>
+<dd><table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Type:</th><td class="field-body">boolean</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Default value:</th><td class="field-body">true</td>
+</tr>
+</tbody>
+</table>
+<p>Defines whether the table structure actions are hidden under a “More”
+drop-down.</p>
+</dd></dl>
+
+</div>
+<div class="section" id="browse-mode">
+<h2>Browse mode<a class="headerlink" href="#browse-mode" title="Permalink to this headline">¶</a></h2>
+<dl class="option">
+<dt id="cfg_NavigationBarIconic">
+<tt class="descname">$cfg['NavigationBarIconic']</tt><a class="headerlink" href="#cfg_NavigationBarIconic" title="Permalink to this definition">¶</a></dt>
+<dd><table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Type:</th><td class="field-body">string</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Default value:</th><td class="field-body">true</td>
+</tr>
+</tbody>
+</table>
+<p>Defines whether navigation bar buttons contain text or symbols only. A
+value of true displays icons, false displays text and ‘both’ displays
+both icons and text.</p>
+</dd></dl>
+
+<dl class="option">
+<dt id="cfg_ShowAll">
+<tt class="descname">$cfg['ShowAll']</tt><a class="headerlink" href="#cfg_ShowAll" title="Permalink to this definition">¶</a></dt>
+<dd><table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Type:</th><td class="field-body">boolean</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Default value:</th><td class="field-body">false</td>
+</tr>
+</tbody>
+</table>
+<p>Defines whether a user should be displayed a “Show all” button in
+browse mode or not in all cases. By default it is shown only on small
+tables (less than 5 × <span class="target" id="index-63"></span><a class="reference internal" href="#cfg_MaxRows"><tt class="xref config config-option docutils literal"><span class="pre">$cfg['MaxRows']</span></tt></a> rows) to avoid
+performance issues while getting too many rows.</p>
+</dd></dl>
+
+<dl class="option">
+<dt id="cfg_MaxRows">
+<tt class="descname">$cfg['MaxRows']</tt><a class="headerlink" href="#cfg_MaxRows" title="Permalink to this definition">¶</a></dt>
+<dd><table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Type:</th><td class="field-body">integer</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Default value:</th><td class="field-body">30</td>
+</tr>
+</tbody>
+</table>
+<p>Number of rows displayed when browsing a result set and no LIMIT
+clause is used. If the result set contains more rows, “Previous” and
+“Next” links will be shown.</p>
+</dd></dl>
+
+<dl class="option">
+<dt id="cfg_Order">
+<tt class="descname">$cfg['Order']</tt><a class="headerlink" href="#cfg_Order" title="Permalink to this definition">¶</a></dt>
+<dd><table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Type:</th><td class="field-body">string</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Default value:</th><td class="field-body"><tt class="docutils literal"><span class="pre">'SMART'</span></tt></td>
+</tr>
+</tbody>
+</table>
+<p>Defines whether columns are displayed in ascending (<tt class="docutils literal"><span class="pre">ASC</span></tt>) order, in
+descending (<tt class="docutils literal"><span class="pre">DESC</span></tt>) order or in a “smart” (<tt class="docutils literal"><span class="pre">SMART</span></tt>) order - I.E.
+descending order for columns of type TIME, DATE, DATETIME and
+TIMESTAMP, ascending order else- by default.</p>
+</dd></dl>
+
+<dl class="option">
+<dt id="cfg_DisplayBinaryAsHex">
+<tt class="descname">$cfg['DisplayBinaryAsHex']</tt><a class="headerlink" href="#cfg_DisplayBinaryAsHex" title="Permalink to this definition">¶</a></dt>
+<dd><table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Type:</th><td class="field-body">boolean</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Default value:</th><td class="field-body">true</td>
+</tr>
+</tbody>
+</table>
+<p>Defines whether the “Show binary contents as HEX” browse option is
+ticked by default.</p>
+</dd></dl>
+
+<dl class="option">
+<dt id="cfg_GridEditing">
+<tt class="descname">$cfg['GridEditing']</tt><a class="headerlink" href="#cfg_GridEditing" title="Permalink to this definition">¶</a></dt>
+<dd><table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Type:</th><td class="field-body">string</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Default value:</th><td class="field-body"><tt class="docutils literal"><span class="pre">'double-click'</span></tt></td>
+</tr>
+</tbody>
+</table>
+<p>Defines which action (<tt class="docutils literal"><span class="pre">double-click</span></tt> or <tt class="docutils literal"><span class="pre">click</span></tt>) triggers grid
+editing. Can be deactived with the <tt class="docutils literal"><span class="pre">disabled</span></tt> value.</p>
+</dd></dl>
+
+<dl class="option">
+<dt id="cfg_SaveCellsAtOnce">
+<tt class="descname">$cfg['SaveCellsAtOnce']</tt><a class="headerlink" href="#cfg_SaveCellsAtOnce" title="Permalink to this definition">¶</a></dt>
+<dd><table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Type:</th><td class="field-body">boolean</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Default value:</th><td class="field-body">false</td>
+</tr>
+</tbody>
+</table>
+<p>Defines whether or not to save all edited cells at once for grid
+editing.</p>
+</dd></dl>
+
+</div>
+<div class="section" id="editing-mode">
+<h2>Editing mode<a class="headerlink" href="#editing-mode" title="Permalink to this headline">¶</a></h2>
+<dl class="option">
+<dt id="cfg_ProtectBinary">
+<tt class="descname">$cfg['ProtectBinary']</tt><a class="headerlink" href="#cfg_ProtectBinary" title="Permalink to this definition">¶</a></dt>
+<dd><table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Type:</th><td class="field-body">boolean or string</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Default value:</th><td class="field-body"><tt class="docutils literal"><span class="pre">'blob'</span></tt></td>
+</tr>
+</tbody>
+</table>
+<p>Defines whether <tt class="docutils literal"><span class="pre">BLOB</span></tt> or <tt class="docutils literal"><span class="pre">BINARY</span></tt> columns are protected from
+editing when browsing a table’s content. Valid values are:</p>
+<ul class="simple">
+<li><tt class="docutils literal"><span class="pre">false</span></tt> to allow editing of all columns;</li>
+<li><tt class="docutils literal"><span class="pre">'blob'</span></tt> to allow editing of all columns except <tt class="docutils literal"><span class="pre">BLOBS</span></tt>;</li>
+<li><tt class="docutils literal"><span class="pre">'noblob'</span></tt> to disallow editing of all columns except <tt class="docutils literal"><span class="pre">BLOBS</span></tt> (the
+opposite of <tt class="docutils literal"><span class="pre">'blob'</span></tt>);</li>
+<li><tt class="docutils literal"><span class="pre">'all'</span></tt> to disallow editing of all <tt class="docutils literal"><span class="pre">BINARY</span></tt> or <tt class="docutils literal"><span class="pre">BLOB</span></tt> columns.</li>
+</ul>
+</dd></dl>
+
+<dl class="option">
+<dt id="cfg_ShowFunctionFields">
+<tt class="descname">$cfg['ShowFunctionFields']</tt><a class="headerlink" href="#cfg_ShowFunctionFields" title="Permalink to this definition">¶</a></dt>
+<dd><table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Type:</th><td class="field-body">boolean</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Default value:</th><td class="field-body">true</td>
+</tr>
+</tbody>
+</table>
+<p>Defines whether or not MySQL functions fields should be initially
+displayed in edit/insert mode. Since version 2.10, the user can toggle
+this setting from the interface.</p>
+</dd></dl>
+
+<dl class="option">
+<dt id="cfg_ShowFieldTypesInDataEditView">
+<tt class="descname">$cfg['ShowFieldTypesInDataEditView']</tt><a class="headerlink" href="#cfg_ShowFieldTypesInDataEditView" title="Permalink to this definition">¶</a></dt>
+<dd><table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Type:</th><td class="field-body">boolean</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Default value:</th><td class="field-body">true</td>
+</tr>
+</tbody>
+</table>
+<p>Defines whether or not type fields should be initially displayed in
+edit/insert mode. The user can toggle this setting from the interface.</p>
+</dd></dl>
+
+<dl class="option">
+<dt id="cfg_InsertRows">
+<tt class="descname">$cfg['InsertRows']</tt><a class="headerlink" href="#cfg_InsertRows" title="Permalink to this definition">¶</a></dt>
+<dd><table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Type:</th><td class="field-body">integer</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Default value:</th><td class="field-body">2</td>
+</tr>
+</tbody>
+</table>
+<p>Defines the maximum number of concurrent entries for the Insert page.</p>
+</dd></dl>
+
+<dl class="option">
+<dt id="cfg_ForeignKeyMaxLimit">
+<tt class="descname">$cfg['ForeignKeyMaxLimit']</tt><a class="headerlink" href="#cfg_ForeignKeyMaxLimit" title="Permalink to this definition">¶</a></dt>
+<dd><table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Type:</th><td class="field-body">integer</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Default value:</th><td class="field-body">100</td>
+</tr>
+</tbody>
+</table>
+<p>If there are fewer items than this in the set of foreign keys, then a
+drop-down box of foreign keys is presented, in the style described by
+the <span class="target" id="index-64"></span><a class="reference internal" href="#cfg_ForeignKeyDropdownOrder"><tt class="xref config config-option docutils literal"><span class="pre">$cfg['ForeignKeyDropdownOrder']</span></tt></a> setting.</p>
+</dd></dl>
+
+<dl class="option">
+<dt id="cfg_ForeignKeyDropdownOrder">
+<tt class="descname">$cfg['ForeignKeyDropdownOrder']</tt><a class="headerlink" href="#cfg_ForeignKeyDropdownOrder" title="Permalink to this definition">¶</a></dt>
+<dd><table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Type:</th><td class="field-body">array</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Default value:</th><td class="field-body">array(‘content-id’, ‘id-content’)</td>
+</tr>
+</tbody>
+</table>
+<p>For the foreign key drop-down fields, there are several methods of
+display, offering both the key and value data. The contents of the
+array should be one or both of the following strings: <tt class="docutils literal"><span class="pre">content-id</span></tt>,
+<tt class="docutils literal"><span class="pre">id-content</span></tt>.</p>
+</dd></dl>
+
+</div>
+<div class="section" id="export-and-import-settings">
+<h2>Export and import settings<a class="headerlink" href="#export-and-import-settings" title="Permalink to this headline">¶</a></h2>
+<dl class="option">
+<dt id="cfg_ZipDump">
+<tt class="descname">$cfg['ZipDump']</tt><a class="headerlink" href="#cfg_ZipDump" title="Permalink to this definition">¶</a></dt>
+<dd><table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Type:</th><td class="field-body">boolean</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Default value:</th><td class="field-body">true</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+<dl class="option">
+<dt id="cfg_GZipDump">
+<tt class="descname">$cfg['GZipDump']</tt><a class="headerlink" href="#cfg_GZipDump" title="Permalink to this definition">¶</a></dt>
+<dd><table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Type:</th><td class="field-body">boolean</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Default value:</th><td class="field-body">true</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+<dl class="option">
+<dt id="cfg_BZipDump">
+<tt class="descname">$cfg['BZipDump']</tt><a class="headerlink" href="#cfg_BZipDump" title="Permalink to this definition">¶</a></dt>
+<dd><table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Type:</th><td class="field-body">boolean</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Default value:</th><td class="field-body">true</td>
+</tr>
+</tbody>
+</table>
+<p>Defines whether to allow the use of zip/GZip/BZip2 compression when
+creating a dump file</p>
+</dd></dl>
+
+<dl class="option">
+<dt id="cfg_CompressOnFly">
+<tt class="descname">$cfg['CompressOnFly']</tt><a class="headerlink" href="#cfg_CompressOnFly" title="Permalink to this definition">¶</a></dt>
+<dd><table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Type:</th><td class="field-body">boolean</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Default value:</th><td class="field-body">true</td>
+</tr>
+</tbody>
+</table>
+<p>Defines whether to allow on the fly compression for GZip/BZip2
+compressed exports. This doesn’t affect smaller dumps and allows users
+to create larger dumps that won’t otherwise fit in memory due to php
+memory limit. Produced files contain more GZip/BZip2 headers, but all
+normal programs handle this correctly.</p>
+</dd></dl>
+
+<dl class="option">
+<dt id="cfg_Export">
+<tt class="descname">$cfg['Export']</tt><a class="headerlink" href="#cfg_Export" title="Permalink to this definition">¶</a></dt>
+<dd><table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Type:</th><td class="field-body">array</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Default value:</th><td class="field-body">array(...)</td>
+</tr>
+</tbody>
+</table>
+<p>In this array are defined default parameters for export, names of
+items are similar to texts seen on export page, so you can easily
+identify what they mean.</p>
+</dd></dl>
+
+<dl class="option">
+<dt id="cfg_Export_method">
+<tt class="descname">$cfg['Export']['method']</tt><a class="headerlink" href="#cfg_Export_method" title="Permalink to this definition">¶</a></dt>
+<dd><table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Type:</th><td class="field-body">string</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Default value:</th><td class="field-body"><tt class="docutils literal"><span class="pre">'quick'</span></tt></td>
+</tr>
+</tbody>
+</table>
+<p>Defines how the export form is displayed when it loads. Valid values
+are:</p>
+<ul class="simple">
+<li><tt class="docutils literal"><span class="pre">quick</span></tt> to display the minimum number of options to configure</li>
+<li><tt class="docutils literal"><span class="pre">custom</span></tt> to display every available option to configure</li>
+<li><tt class="docutils literal"><span class="pre">custom-no-form</span></tt> same as <tt class="docutils literal"><span class="pre">custom</span></tt> but does not display the option
+of using quick export</li>
+</ul>
+</dd></dl>
+
+<dl class="option">
+<dt id="cfg_Import">
+<tt class="descname">$cfg['Import']</tt><a class="headerlink" href="#cfg_Import" title="Permalink to this definition">¶</a></dt>
+<dd><table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Type:</th><td class="field-body">array</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Default value:</th><td class="field-body">array(...)</td>
+</tr>
+</tbody>
+</table>
+<p>In this array are defined default parameters for import, names of
+items are similar to texts seen on import page, so you can easily
+identify what they mean.</p>
+</dd></dl>
+
+</div>
+<div class="section" id="tabs-display-settings">
+<h2>Tabs display settings<a class="headerlink" href="#tabs-display-settings" title="Permalink to this headline">¶</a></h2>
+<dl class="option">
+<dt id="cfg_PropertiesIconic">
+<tt class="descname">$cfg['PropertiesIconic']</tt><a class="headerlink" href="#cfg_PropertiesIconic" title="Permalink to this definition">¶</a></dt>
+<dd><table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Type:</th><td class="field-body">string</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Default value:</th><td class="field-body"><tt class="docutils literal"><span class="pre">'both'</span></tt></td>
+</tr>
+</tbody>
+</table>
+<p>If set to <tt class="docutils literal"><span class="pre">true</span></tt>, will display icons instead of text for db and table
+properties links (like <em class="guilabel">Browse</em>, <em class="guilabel">Select</em>,
+<em class="guilabel">Insert</em>, ...) and for the menu tabs. Can be set to <tt class="docutils literal"><span class="pre">'both'</span></tt>
+if you want icons AND text. When set to <tt class="docutils literal"><span class="pre">false</span></tt>, will only show text.</p>
+</dd></dl>
+
+<dl class="option">
+<dt id="cfg_PropertiesNumColumns">
+<tt class="descname">$cfg['PropertiesNumColumns']</tt><a class="headerlink" href="#cfg_PropertiesNumColumns" title="Permalink to this definition">¶</a></dt>
+<dd><table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Type:</th><td class="field-body">integer</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Default value:</th><td class="field-body">1</td>
+</tr>
+</tbody>
+</table>
+<p>How many columns will be utilized to display the tables on the database
+property view? When setting this to a value larger than 1, the type of the
+database will be omitted for more display space.</p>
+</dd></dl>
+
+<dl class="option">
+<dt id="cfg_DefaultTabServer">
+<tt class="descname">$cfg['DefaultTabServer']</tt><a class="headerlink" href="#cfg_DefaultTabServer" title="Permalink to this definition">¶</a></dt>
+<dd><table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Type:</th><td class="field-body">string</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Default value:</th><td class="field-body"><tt class="docutils literal"><span class="pre">'index.php'</span></tt></td>
+</tr>
+</tbody>
+</table>
+<p>Defines the tab displayed by default on server view. Possible values:</p>
+<ul class="simple">
+<li><tt class="docutils literal"><span class="pre">main.php</span></tt> (recommended for multi-user setups)</li>
+<li><tt class="docutils literal"><span class="pre">server_databases.php</span></tt>,</li>
+<li><tt class="docutils literal"><span class="pre">server_status.php</span></tt></li>
+<li><tt class="docutils literal"><span class="pre">server_variables.php</span></tt></li>
+<li><tt class="docutils literal"><span class="pre">server_privileges.php</span></tt></li>
+</ul>
+</dd></dl>
+
+<dl class="option">
+<dt id="cfg_DefaultTabDatabase">
+<tt class="descname">$cfg['DefaultTabDatabase']</tt><a class="headerlink" href="#cfg_DefaultTabDatabase" title="Permalink to this definition">¶</a></dt>
+<dd><table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Type:</th><td class="field-body">string</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Default value:</th><td class="field-body"><tt class="docutils literal"><span class="pre">'db_structure.php'</span></tt></td>
+</tr>
+</tbody>
+</table>
+<p>Defines the tab displayed by default on database view. Possible
+values:</p>
+<ul class="simple">
+<li><tt class="docutils literal"><span class="pre">db_structure.php</span></tt></li>
+<li><tt class="docutils literal"><span class="pre">db_sql.php</span></tt></li>
+<li><tt class="docutils literal"><span class="pre">db_search.php</span></tt>.</li>
+</ul>
+</dd></dl>
+
+<dl class="option">
+<dt id="cfg_DefaultTabTable">
+<tt class="descname">$cfg['DefaultTabTable']</tt><a class="headerlink" href="#cfg_DefaultTabTable" title="Permalink to this definition">¶</a></dt>
+<dd><table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Type:</th><td class="field-body">string</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Default value:</th><td class="field-body"><tt class="docutils literal"><span class="pre">'sql.php'</span></tt></td>
+</tr>
+</tbody>
+</table>
+<p>Defines the tab displayed by default on table view. Possible values:</p>
+<ul class="simple">
+<li><tt class="docutils literal"><span class="pre">tbl_structure.php</span></tt></li>
+<li><tt class="docutils literal"><span class="pre">tbl_sql.php</span></tt></li>
+<li><tt class="docutils literal"><span class="pre">tbl_select.php</span></tt></li>
+<li><tt class="docutils literal"><span class="pre">tbl_change.php</span></tt></li>
+<li><tt class="docutils literal"><span class="pre">sql.php</span></tt></li>
+</ul>
+</dd></dl>
+
+</div>
+<div class="section" id="documentation">
+<h2>Documentation<a class="headerlink" href="#documentation" title="Permalink to this headline">¶</a></h2>
+<dl class="option">
+<dt id="cfg_MySQLManualBase">
+<tt class="descname">$cfg['MySQLManualBase']</tt><a class="headerlink" href="#cfg_MySQLManualBase" title="Permalink to this definition">¶</a></dt>
+<dd><table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Type:</th><td class="field-body">string</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Default value:</th><td class="field-body"><tt class="docutils literal"><span class="pre">'http://dev.mysql.com/doc/refman'</span></tt></td>
+</tr>
+</tbody>
+</table>
+<p>If set to an <a class="reference internal" href="glossary.html#term-url"><em class="xref std std-term">URL</em></a> which points to
+the MySQL documentation (type depends on
+<span class="target" id="index-65"></span><a class="reference internal" href="#cfg_MySQLManualType"><tt class="xref config config-option docutils literal"><span class="pre">$cfg['MySQLManualType']</span></tt></a>), appropriate help links are
+generated.</p>
+<p>See <a class="reference external" href="http://dev.mysql.com/doc/">MySQL Documentation page</a> for more
+information about MySQL manuals and their types.</p>
+</dd></dl>
+
+<dl class="option">
+<dt id="cfg_MySQLManualType">
+<tt class="descname">$cfg['MySQLManualType']</tt><a class="headerlink" href="#cfg_MySQLManualType" title="Permalink to this definition">¶</a></dt>
+<dd><table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Type:</th><td class="field-body">string</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Default value:</th><td class="field-body"><tt class="docutils literal"><span class="pre">'viewable'</span></tt></td>
+</tr>
+</tbody>
+</table>
+<p>Type of MySQL documentation:</p>
+<ul class="simple">
+<li>viewable - “viewable online”, current one used on MySQL website</li>
+<li>searchable - “Searchable, with user comments”</li>
+<li>chapters - “HTML, one page per chapter”</li>
+<li>big - “HTML, all on one page”</li>
+<li>none - do not show documentation links</li>
+</ul>
+</dd></dl>
+
+</div>
+<div class="section" id="languages">
+<h2>Languages<a class="headerlink" href="#languages" title="Permalink to this headline">¶</a></h2>
+<dl class="option">
+<dt id="cfg_DefaultLang">
+<tt class="descname">$cfg['DefaultLang']</tt><a class="headerlink" href="#cfg_DefaultLang" title="Permalink to this definition">¶</a></dt>
+<dd><table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Type:</th><td class="field-body">string</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Default value:</th><td class="field-body"><tt class="docutils literal"><span class="pre">'en'</span></tt></td>
+</tr>
+</tbody>
+</table>
+<p>Defines the default language to use, if not browser-defined or user-
+defined. The corresponding language file needs to be in
+locale/<em>code</em>/LC_MESSAGES/phpmyadmin.mo.</p>
+</dd></dl>
+
+<dl class="option">
+<dt id="cfg_DefaultConnectionCollation">
+<tt class="descname">$cfg['DefaultConnectionCollation']</tt><a class="headerlink" href="#cfg_DefaultConnectionCollation" title="Permalink to this definition">¶</a></dt>
+<dd><table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Type:</th><td class="field-body">string</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Default value:</th><td class="field-body"><tt class="docutils literal"><span class="pre">'utf8_general_ci'</span></tt></td>
+</tr>
+</tbody>
+</table>
+<p>Defines the default connection collation to use, if not user-defined.
+See the <a class="reference external" href="http://dev.mysql.com/doc/mysql/en/charset-charsets.html">MySQL documentation</a> for list of possible values. This setting is
+ignored when connected to Drizzle server.</p>
+</dd></dl>
+
+<dl class="option">
+<dt id="cfg_Lang">
+<tt class="descname">$cfg['Lang']</tt><a class="headerlink" href="#cfg_Lang" title="Permalink to this definition">¶</a></dt>
+<dd><table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Type:</th><td class="field-body">string</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Default value:</th><td class="field-body">not set</td>
+</tr>
+</tbody>
+</table>
+<p>Force language to use. The corresponding language file needs to be in
+locale/<em>code</em>/LC_MESSAGES/phpmyadmin.mo.</p>
+</dd></dl>
+
+<dl class="option">
+<dt id="cfg_FilterLanguages">
+<tt class="descname">$cfg['FilterLanguages']</tt><a class="headerlink" href="#cfg_FilterLanguages" title="Permalink to this definition">¶</a></dt>
+<dd><table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Type:</th><td class="field-body">string</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Default value:</th><td class="field-body"><tt class="docutils literal"><span class="pre">''</span></tt></td>
+</tr>
+</tbody>
+</table>
+<p>Limit list of available languages to those matching the given regular
+expression. For example if you want only Czech and English, you should
+set filter to <tt class="docutils literal"><span class="pre">'^(cs|en)'</span></tt>.</p>
+</dd></dl>
+
+<dl class="option">
+<dt id="cfg_RecodingEngine">
+<tt class="descname">$cfg['RecodingEngine']</tt><a class="headerlink" href="#cfg_RecodingEngine" title="Permalink to this definition">¶</a></dt>
+<dd><table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Type:</th><td class="field-body">string</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Default value:</th><td class="field-body"><tt class="docutils literal"><span class="pre">'auto'</span></tt></td>
+</tr>
+</tbody>
+</table>
+<p>You can select here which functions will be used for character set
+conversion. Possible values are:</p>
+<ul class="simple">
+<li>auto - automatically use available one (first is tested iconv, then
+recode)</li>
+<li>iconv - use iconv or libiconv functions</li>
+<li>recode - use recode_string function</li>
+<li>none - disable encoding conversion</li>
+</ul>
+<p>Enabled charset conversion activates a pull-down menu in the Export
+and Import pages, to choose the character set when exporting a file.
+The default value in this menu comes from
+<span class="target" id="index-66"></span><tt class="xref config config-option docutils literal"><span class="pre">$cfg['Export']['charset']</span></tt> and <span class="target" id="index-67"></span><tt class="xref config config-option docutils literal"><span class="pre">$cfg['Import']['charset']</span></tt>.</p>
+</dd></dl>
+
+<dl class="option">
+<dt id="cfg_IconvExtraParams">
+<tt class="descname">$cfg['IconvExtraParams']</tt><a class="headerlink" href="#cfg_IconvExtraParams" title="Permalink to this definition">¶</a></dt>
+<dd><table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Type:</th><td class="field-body">string</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Default value:</th><td class="field-body"><tt class="docutils literal"><span class="pre">'//TRANSLIT'</span></tt></td>
+</tr>
+</tbody>
+</table>
+<p>Specify some parameters for iconv used in charset conversion. See
+<a class="reference external" href="http://www.gnu.org/software/libiconv/documentation/libiconv/iconv_open.3.html">iconv documentation</a> for details. By default
+<tt class="docutils literal"><span class="pre">//TRANSLIT</span></tt> is used, so that invalid characters will be
+transliterated.</p>
+</dd></dl>
+
+<dl class="option">
+<dt id="cfg_AvailableCharsets">
+<tt class="descname">$cfg['AvailableCharsets']</tt><a class="headerlink" href="#cfg_AvailableCharsets" title="Permalink to this definition">¶</a></dt>
+<dd><table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Type:</th><td class="field-body">array</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Default value:</th><td class="field-body">array(..._</td>
+</tr>
+</tbody>
+</table>
+<p>Available character sets for MySQL conversion. You can add your own
+(any of supported by recode/iconv) or remove these which you don’t
+use. Character sets will be shown in same order as here listed, so if
+you frequently use some of these move them to the top.</p>
+</dd></dl>
+
+</div>
+<div class="section" id="web-server-settings">
+<h2>Web server settings<a class="headerlink" href="#web-server-settings" title="Permalink to this headline">¶</a></h2>
+<dl class="option">
+<dt id="cfg_OBGzip">
+<tt class="descname">$cfg['OBGzip']</tt><a class="headerlink" href="#cfg_OBGzip" title="Permalink to this definition">¶</a></dt>
+<dd><table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Type:</th><td class="field-body">string/boolean</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Default value:</th><td class="field-body"><tt class="docutils literal"><span class="pre">'auto'</span></tt></td>
+</tr>
+</tbody>
+</table>
+<p>Defines whether to use GZip output buffering for increased speed in
+<a class="reference internal" href="glossary.html#term-http"><em class="xref std std-term">HTTP</em></a> transfers. Set to
+true/false for enabling/disabling. When set to ‘auto’ (string),
+phpMyAdmin tries to enable output buffering and will automatically
+disable it if your browser has some problems with buffering. IE6 with
+a certain patch is known to cause data corruption when having enabled
+buffering.</p>
+</dd></dl>
+
+<dl class="option">
+<dt id="cfg_TrustedProxies">
+<tt class="descname">$cfg['TrustedProxies']</tt><a class="headerlink" href="#cfg_TrustedProxies" title="Permalink to this definition">¶</a></dt>
+<dd><table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Type:</th><td class="field-body">array</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Default value:</th><td class="field-body">array()</td>
+</tr>
+</tbody>
+</table>
+<p>Lists proxies and HTTP headers which are trusted for
+<span class="target" id="index-68"></span><a class="reference internal" href="#cfg_Servers_AllowDeny_order"><tt class="xref config config-option docutils literal"><span class="pre">$cfg['Servers'][$i]['AllowDeny']['order']</span></tt></a>. This list is by
+default empty, you need to fill in some trusted proxy servers if you
+want to use rules for IP addresses behind proxy.</p>
+<p>The following example specifies that phpMyAdmin should trust a
+HTTP_X_FORWARDED_FOR (<tt class="docutils literal"><span class="pre">X</span> <span class="pre">-Forwarded-For</span></tt>) header coming from the proxy
+1.2.3.4:</p>
+<div class="highlight-php"><div class="highlight"><pre><span class="x">$cfg['TrustedProxies'] = array('1.2.3.4' => 'HTTP_X_FORWARDED_FOR');</span>
+</pre></div>
+</div>
+<p>The <span class="target" id="index-69"></span><a class="reference internal" href="#cfg_Servers_AllowDeny_rules"><tt class="xref config config-option docutils literal"><span class="pre">$cfg['Servers'][$i]['AllowDeny']['rules']</span></tt></a> directive uses the
+client’s IP address as usual.</p>
+</dd></dl>
+
+<dl class="option">
+<dt id="cfg_GD2Available">
+<tt class="descname">$cfg['GD2Available']</tt><a class="headerlink" href="#cfg_GD2Available" title="Permalink to this definition">¶</a></dt>
+<dd><table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Type:</th><td class="field-body">string</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Default value:</th><td class="field-body"><tt class="docutils literal"><span class="pre">'auto'</span></tt></td>
+</tr>
+</tbody>
+</table>
+<p>Specifies whether GD >= 2 is available. If yes it can be used for MIME
+transformations. Possible values are:</p>
+<ul class="simple">
+<li>auto - automatically detect</li>
+<li>yes - GD 2 functions can be used</li>
+<li>no - GD 2 function cannot be used</li>
+</ul>
+</dd></dl>
+
+<dl class="option">
+<dt id="cfg_CheckConfigurationPermissions">
+<tt class="descname">$cfg['CheckConfigurationPermissions']</tt><a class="headerlink" href="#cfg_CheckConfigurationPermissions" title="Permalink to this definition">¶</a></dt>
+<dd><table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Type:</th><td class="field-body">boolean</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Default value:</th><td class="field-body">true</td>
+</tr>
+</tbody>
+</table>
+<p>We normally check the permissions on the configuration file to ensure
+it’s not world writable. However, phpMyAdmin could be installed on a
+NTFS filesystem mounted on a non-Windows server, in which case the
+permissions seems wrong but in fact cannot be detected. In this case a
+sysadmin would set this parameter to <tt class="docutils literal"><span class="pre">false</span></tt>.</p>
+</dd></dl>
+
+<dl class="option">
+<dt id="cfg_LinkLengthLimit">
+<tt class="descname">$cfg['LinkLengthLimit']</tt><a class="headerlink" href="#cfg_LinkLengthLimit" title="Permalink to this definition">¶</a></dt>
+<dd><table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Type:</th><td class="field-body">integer</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Default value:</th><td class="field-body">1000</td>
+</tr>
+</tbody>
+</table>
+<p>Limit for length of <a class="reference internal" href="glossary.html#term-url"><em class="xref std std-term">URL</em></a> in links.  When length would be above this
+limit, it is replaced by form with button. This is required as some web
+servers (<a class="reference internal" href="glossary.html#term-iis"><em class="xref std std-term">IIS</em></a>) have problems with long <a class="reference internal" href="glossary.html#term-url"><em class="xref std std-term">URL</em></a> .</p>
+</dd></dl>
+
+<dl class="option">
+<dt id="cfg_CSPAllow">
+<tt class="descname">$cfg['CSPAllow']</tt><a class="headerlink" href="#cfg_CSPAllow" title="Permalink to this definition">¶</a></dt>
+<dd><table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Type:</th><td class="field-body">string</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Default value:</th><td class="field-body"><tt class="docutils literal"><span class="pre">''</span></tt></td>
+</tr>
+</tbody>
+</table>
+<p>Additional string to include in allowed script sources in Content Security
+Policy header.</p>
+<p>This can be useful when you want to include some external javascript files
+in <tt class="file docutils literal"><span class="pre">config.footer.inc.php</span></tt> or <tt class="file docutils literal"><span class="pre">config.header.inc.php</span></tt>, which
+would be normally not allowed by Content Security Policy.</p>
+</dd></dl>
+
+<dl class="option">
+<dt id="cfg_DisableMultiTableMaintenance">
+<tt class="descname">$cfg['DisableMultiTableMaintenance']</tt><a class="headerlink" href="#cfg_DisableMultiTableMaintenance" title="Permalink to this definition">¶</a></dt>
+<dd><table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Type:</th><td class="field-body">boolean</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Default value:</th><td class="field-body">false</td>
+</tr>
+</tbody>
+</table>
+<p>In the database Structure page, it’s possible to mark some tables then
+choose an operation like optimizing for many tables. This can slow
+down a server; therefore, setting this to <tt class="docutils literal"><span class="pre">true</span></tt> prevents this kind
+of multiple maintenance operation.</p>
+</dd></dl>
+
+</div>
+<div class="section" id="theme-settings">
+<h2>Theme settings<a class="headerlink" href="#theme-settings" title="Permalink to this headline">¶</a></h2>
+<dl class="option">
+<dt id="cfg_NaviWidth">
+<tt class="descname">$cfg['NaviWidth']</tt><a class="headerlink" href="#cfg_NaviWidth" title="Permalink to this definition">¶</a></dt>
+<dd><table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Type:</th><td class="field-body">integer</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Default value:</th><td class="field-body"></td>
+</tr>
+</tbody>
+</table>
+<p>Navigation panel width in pixels. See
+<tt class="file docutils literal"><span class="pre">themes/themename/layout.inc.php</span></tt>.</p>
+</dd></dl>
+
+<dl class="option">
+<dt id="cfg_NaviBackground">
+<tt class="descname">$cfg['NaviBackground']</tt><a class="headerlink" href="#cfg_NaviBackground" title="Permalink to this definition">¶</a></dt>
+<dd><table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Type:</th><td class="field-body">string [CSS color for background]</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Default value:</th><td class="field-body"></td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+<dl class="option">
+<dt id="cfg_MainBackground">
+<tt class="descname">$cfg['MainBackground']</tt><a class="headerlink" href="#cfg_MainBackground" title="Permalink to this definition">¶</a></dt>
+<dd><table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Type:</th><td class="field-body">string [CSS color for background]</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Default value:</th><td class="field-body"></td>
+</tr>
+</tbody>
+</table>
+<p>The background styles used for both the frames. See
+<tt class="file docutils literal"><span class="pre">themes/themename/layout.inc.php</span></tt>.</p>
+</dd></dl>
+
+<dl class="option">
+<dt id="cfg_NaviPointerBackground">
+<tt class="descname">$cfg['NaviPointerBackground']</tt><a class="headerlink" href="#cfg_NaviPointerBackground" title="Permalink to this definition">¶</a></dt>
+<dd><table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Type:</th><td class="field-body">string [CSS color for background]</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Default value:</th><td class="field-body"></td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+<dl class="option">
+<dt id="cfg_NaviPointerColor">
+<tt class="descname">$cfg['NaviPointerColor']</tt><a class="headerlink" href="#cfg_NaviPointerColor" title="Permalink to this definition">¶</a></dt>
+<dd><table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Type:</th><td class="field-body">string [CSS color]</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Default value:</th><td class="field-body"></td>
+</tr>
+</tbody>
+</table>
+<p>The style used for the pointer in the navi frame. See
+<tt class="file docutils literal"><span class="pre">themes/themename/layout.inc.php</span></tt>.</p>
+</dd></dl>
+
+<dl class="option">
+<dt id="cfg_Border">
+<tt class="descname">$cfg['Border']</tt><a class="headerlink" href="#cfg_Border" title="Permalink to this definition">¶</a></dt>
+<dd><table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Type:</th><td class="field-body">integer</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Default value:</th><td class="field-body"></td>
+</tr>
+</tbody>
+</table>
+<p>The size of a table’s border. See <tt class="file docutils literal"><span class="pre">themes/themename/layout.inc.php</span></tt>.</p>
+</dd></dl>
+
+<dl class="option">
+<dt id="cfg_ThBackground">
+<tt class="descname">$cfg['ThBackground']</tt><a class="headerlink" href="#cfg_ThBackground" title="Permalink to this definition">¶</a></dt>
+<dd><table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Type:</th><td class="field-body">string [CSS color for background]</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Default value:</th><td class="field-body"></td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+<dl class="option">
+<dt id="cfg_ThColor">
+<tt class="descname">$cfg['ThColor']</tt><a class="headerlink" href="#cfg_ThColor" title="Permalink to this definition">¶</a></dt>
+<dd><table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Type:</th><td class="field-body">string [CSS color]</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Default value:</th><td class="field-body"></td>
+</tr>
+</tbody>
+</table>
+<p>The style used for table headers. See
+<tt class="file docutils literal"><span class="pre">themes/themename/layout.inc.php</span></tt>.</p>
+</dd></dl>
+
+<span class="target" id="cfg-bgcolorone"></span><dl class="option">
+<dt id="cfg_BgOne">
+<tt class="descname">$cfg['BgOne']</tt><a class="headerlink" href="#cfg_BgOne" title="Permalink to this definition">¶</a></dt>
+<dd><table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Type:</th><td class="field-body">string [CSS color]</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Default value:</th><td class="field-body"></td>
+</tr>
+</tbody>
+</table>
+<p>The color (HTML) #1 for table rows. See
+<tt class="file docutils literal"><span class="pre">themes/themename/layout.inc.php</span></tt>.</p>
+</dd></dl>
+
+<span class="target" id="cfg-bgcolortwo"></span><dl class="option">
+<dt id="cfg_BgTwo">
+<tt class="descname">$cfg['BgTwo']</tt><a class="headerlink" href="#cfg_BgTwo" title="Permalink to this definition">¶</a></dt>
+<dd><table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Type:</th><td class="field-body">string [CSS color]</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Default value:</th><td class="field-body"></td>
+</tr>
+</tbody>
+</table>
+<p>The color (HTML) #2 for table rows. See
+<tt class="file docutils literal"><span class="pre">themes/themename/layout.inc.php</span></tt>.</p>
+</dd></dl>
+
+<dl class="option">
+<dt id="cfg_BrowsePointerBackground">
+<tt class="descname">$cfg['BrowsePointerBackground']</tt><a class="headerlink" href="#cfg_BrowsePointerBackground" title="Permalink to this definition">¶</a></dt>
+<dd><table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Type:</th><td class="field-body">string [CSS color]</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Default value:</th><td class="field-body"></td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+<dl class="option">
+<dt id="cfg_BrowsePointerColor">
+<tt class="descname">$cfg['BrowsePointerColor']</tt><a class="headerlink" href="#cfg_BrowsePointerColor" title="Permalink to this definition">¶</a></dt>
+<dd><table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Type:</th><td class="field-body">string [CSS color]</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Default value:</th><td class="field-body"></td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+<dl class="option">
+<dt id="cfg_BrowseMarkerBackground">
+<tt class="descname">$cfg['BrowseMarkerBackground']</tt><a class="headerlink" href="#cfg_BrowseMarkerBackground" title="Permalink to this definition">¶</a></dt>
+<dd><table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Type:</th><td class="field-body">string [CSS color]</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Default value:</th><td class="field-body"></td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+<dl class="option">
+<dt id="cfg_BrowseMarkerColor">
+<tt class="descname">$cfg['BrowseMarkerColor']</tt><a class="headerlink" href="#cfg_BrowseMarkerColor" title="Permalink to this definition">¶</a></dt>
+<dd><table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Type:</th><td class="field-body">string [CSS color]</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Default value:</th><td class="field-body"></td>
+</tr>
+</tbody>
+</table>
+<p>The colors (HTML) uses for the pointer and the marker in browse mode.
+The former feature highlights the row over which your mouse is passing
+and the latter lets you visually mark/unmark rows by clicking on the
+corresponding checkbox. Highlighting / marking a column is done by
+hovering over / clicking the column’s header (outside of the text).
+See <tt class="file docutils literal"><span class="pre">themes/themename/layout.inc.php</span></tt>.</p>
+</dd></dl>
+
+<dl class="option">
+<dt id="cfg_FontFamily">
+<tt class="descname">$cfg['FontFamily']</tt><a class="headerlink" href="#cfg_FontFamily" title="Permalink to this definition">¶</a></dt>
+<dd><table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Type:</th><td class="field-body">string</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Default value:</th><td class="field-body"></td>
+</tr>
+</tbody>
+</table>
+<p>You put here a valid CSS font family value, for example <tt class="docutils literal"><span class="pre">arial,</span> <span class="pre">sans-</span>
+<span class="pre">serif</span></tt>. See <tt class="file docutils literal"><span class="pre">themes/themename/layout.inc.php</span></tt>.</p>
+</dd></dl>
+
+<dl class="option">
+<dt id="cfg_FontFamilyFixed">
+<tt class="descname">$cfg['FontFamilyFixed']</tt><a class="headerlink" href="#cfg_FontFamilyFixed" title="Permalink to this definition">¶</a></dt>
+<dd><table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Type:</th><td class="field-body">string</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Default value:</th><td class="field-body"></td>
+</tr>
+</tbody>
+</table>
+<p>You put here a valid CSS font family value, for example <tt class="docutils literal"><span class="pre">monospace</span></tt>.
+This one is used in textarea. See <tt class="file docutils literal"><span class="pre">themes/themename/layout.inc.php</span></tt>.</p>
+</dd></dl>
+
+</div>
+<div class="section" id="design-customization">
+<h2>Design customization<a class="headerlink" href="#design-customization" title="Permalink to this headline">¶</a></h2>
+<dl class="option">
+<dt id="cfg_NavigationTreePointerEnable">
+<tt class="descname">$cfg['NavigationTreePointerEnable']</tt><a class="headerlink" href="#cfg_NavigationTreePointerEnable" title="Permalink to this definition">¶</a></dt>
+<dd><table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Type:</th><td class="field-body">boolean</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Default value:</th><td class="field-body">true</td>
+</tr>
+</tbody>
+</table>
+<p>A value of <tt class="docutils literal"><span class="pre">true</span></tt> activates the navi pointer.</p>
+</dd></dl>
+
+<dl class="option">
+<dt id="cfg_BrowsePointerEnable">
+<tt class="descname">$cfg['BrowsePointerEnable']</tt><a class="headerlink" href="#cfg_BrowsePointerEnable" title="Permalink to this definition">¶</a></dt>
+<dd><table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Type:</th><td class="field-body">boolean</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Default value:</th><td class="field-body">true</td>
+</tr>
+</tbody>
+</table>
+<p>Whether to activate the browse pointer or not.</p>
+</dd></dl>
+
+<dl class="option">
+<dt id="cfg_BrowseMarkerEnable">
+<tt class="descname">$cfg['BrowseMarkerEnable']</tt><a class="headerlink" href="#cfg_BrowseMarkerEnable" title="Permalink to this definition">¶</a></dt>
+<dd><table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Type:</th><td class="field-body">boolean</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Default value:</th><td class="field-body">true</td>
+</tr>
+</tbody>
+</table>
+<p>Whether to activate the browse marker or not.</p>
+</dd></dl>
+
+<dl class="option">
+<dt id="cfg_LimitChars">
+<tt class="descname">$cfg['LimitChars']</tt><a class="headerlink" href="#cfg_LimitChars" title="Permalink to this definition">¶</a></dt>
+<dd><table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Type:</th><td class="field-body">integer</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Default value:</th><td class="field-body">50</td>
+</tr>
+</tbody>
+</table>
+<p>Maximum number of characters shown in any non-numeric field on browse
+view. Can be turned off by a toggle button on the browse page.</p>
+</dd></dl>
+
+<dl class="option">
+<dt id="cfg_RowActionLinks">
+<tt class="descname">$cfg['RowActionLinks']</tt><a class="headerlink" href="#cfg_RowActionLinks" title="Permalink to this definition">¶</a></dt>
+<dd><table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Type:</th><td class="field-body">string</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Default value:</th><td class="field-body"><tt class="docutils literal"><span class="pre">'left'</span></tt></td>
+</tr>
+</tbody>
+</table>
+<p>Defines the place where table row links (Edit, Copy, Delete) would be
+put when tables contents are displayed (you may have them displayed at
+the left side, right side, both sides or nowhere). “left” and “right”
+are parsed as “top” and “bottom” with vertical display mode.</p>
+</dd></dl>
+
+<dl class="option">
+<dt id="cfg_DefaultDisplay">
+<tt class="descname">$cfg['DefaultDisplay']</tt><a class="headerlink" href="#cfg_DefaultDisplay" title="Permalink to this definition">¶</a></dt>
+<dd><table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Type:</th><td class="field-body">string</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Default value:</th><td class="field-body"><tt class="docutils literal"><span class="pre">'horizonta'</span></tt></td>
+</tr>
+</tbody>
+</table>
+<p>There are 3 display modes: horizontal, horizontalflipped and vertical.
+Define which one is displayed by default. The first mode displays each
+row on a horizontal line, the second rotates the headers by 90
+degrees, so you can use descriptive headers even though columns only
+contain small values and still print them out. The vertical mode sorts
+each row on a vertical lineup.</p>
+</dd></dl>
+
+<dl class="option">
+<dt id="cfg_RememberSorting">
+<tt class="descname">$cfg['RememberSorting']</tt><a class="headerlink" href="#cfg_RememberSorting" title="Permalink to this definition">¶</a></dt>
+<dd><table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Type:</th><td class="field-body">boolean</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Default value:</th><td class="field-body">true</td>
+</tr>
+</tbody>
+</table>
+<p>If enabled, remember the sorting of each table when browsing them.</p>
+</dd></dl>
+
+<dl class="option">
+<dt id="cfg_HeaderFlipType">
+<tt class="descname">$cfg['HeaderFlipType']</tt><a class="headerlink" href="#cfg_HeaderFlipType" title="Permalink to this definition">¶</a></dt>
+<dd><table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Type:</th><td class="field-body">string</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Default value:</th><td class="field-body"><tt class="docutils literal"><span class="pre">'auto'</span></tt></td>
+</tr>
+</tbody>
+</table>
+<p>The HeaderFlipType can be set to ‘auto’, ‘css’ or ‘fake’. When using
+‘css’ the rotation of the header for horizontalflipped is done via
+CSS. The CSS transformation currently works only in Internet
+Explorer.If set to ‘fake’ PHP does the transformation for you, but of
+course this does not look as good as CSS. The ‘auto’ option enables
+CSS transformation when browser supports it and use PHP based one
+otherwise.</p>
+</dd></dl>
+
+<dl class="option">
+<dt id="cfg_ShowBrowseComments">
+<tt class="descname">$cfg['ShowBrowseComments']</tt><a class="headerlink" href="#cfg_ShowBrowseComments" title="Permalink to this definition">¶</a></dt>
+<dd><table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Type:</th><td class="field-body">boolean</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Default value:</th><td class="field-body">true</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+<dl class="option">
+<dt id="cfg_ShowPropertyComments">
+<tt class="descname">$cfg['ShowPropertyComments']</tt><a class="headerlink" href="#cfg_ShowPropertyComments" title="Permalink to this definition">¶</a></dt>
+<dd><table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Type:</th><td class="field-body">boolean</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Default value:</th><td class="field-body">true</td>
+</tr>
+</tbody>
+</table>
+<p>By setting the corresponding variable to <tt class="docutils literal"><span class="pre">true</span></tt> you can enable the
+display of column comments in Browse or Property display. In browse
+mode, the comments are shown inside the header. In property mode,
+comments are displayed using a CSS-formatted dashed-line below the
+name of the column. The comment is shown as a tool-tip for that
+column.</p>
+</dd></dl>
+
+</div>
+<div class="section" id="text-fields">
+<h2>Text fields<a class="headerlink" href="#text-fields" title="Permalink to this headline">¶</a></h2>
+<dl class="option">
+<dt id="cfg_CharEditing">
+<tt class="descname">$cfg['CharEditing']</tt><a class="headerlink" href="#cfg_CharEditing" title="Permalink to this definition">¶</a></dt>
+<dd><table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Type:</th><td class="field-body">string</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Default value:</th><td class="field-body"><tt class="docutils literal"><span class="pre">'input'</span></tt></td>
+</tr>
+</tbody>
+</table>
+<p>Defines which type of editing controls should be used for CHAR and
+VARCHAR columns. Possible values are:</p>
+<ul class="simple">
+<li>input - this allows to limit size of text to size of columns in MySQL,
+but has problems with newlines in columns</li>
+<li>textarea - no problems with newlines in columns, but also no length
+limitations</li>
+</ul>
+</dd></dl>
+
+<dl class="option">
+<dt id="cfg_MinSizeForInputField">
+<tt class="descname">$cfg['MinSizeForInputField']</tt><a class="headerlink" href="#cfg_MinSizeForInputField" title="Permalink to this definition">¶</a></dt>
+<dd><table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Type:</th><td class="field-body">integer</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Default value:</th><td class="field-body">4</td>
+</tr>
+</tbody>
+</table>
+<p>Defines the minimum size for input fields generated for CHAR and
+VARCHAR columns.</p>
+</dd></dl>
+
+<dl class="option">
+<dt id="cfg_MaxSizeForInputField">
+<tt class="descname">$cfg['MaxSizeForInputField']</tt><a class="headerlink" href="#cfg_MaxSizeForInputField" title="Permalink to this definition">¶</a></dt>
+<dd><table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Type:</th><td class="field-body">integer</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Default value:</th><td class="field-body">60</td>
+</tr>
+</tbody>
+</table>
+<p>Defines the maximum size for input fields generated for CHAR and
+VARCHAR columns.</p>
+</dd></dl>
+
+<dl class="option">
+<dt id="cfg_TextareaCols">
+<tt class="descname">$cfg['TextareaCols']</tt><a class="headerlink" href="#cfg_TextareaCols" title="Permalink to this definition">¶</a></dt>
+<dd><table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Type:</th><td class="field-body">integer</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Default value:</th><td class="field-body">40</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+<dl class="option">
+<dt id="cfg_TextareaRows">
+<tt class="descname">$cfg['TextareaRows']</tt><a class="headerlink" href="#cfg_TextareaRows" title="Permalink to this definition">¶</a></dt>
+<dd><table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Type:</th><td class="field-body">integer</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Default value:</th><td class="field-body">15</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+<dl class="option">
+<dt id="cfg_CharTextareaCols">
+<tt class="descname">$cfg['CharTextareaCols']</tt><a class="headerlink" href="#cfg_CharTextareaCols" title="Permalink to this definition">¶</a></dt>
+<dd><table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Type:</th><td class="field-body">integer</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Default value:</th><td class="field-body">40</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+<dl class="option">
+<dt id="cfg_CharTextareaRows">
+<tt class="descname">$cfg['CharTextareaRows']</tt><a class="headerlink" href="#cfg_CharTextareaRows" title="Permalink to this definition">¶</a></dt>
+<dd><table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Type:</th><td class="field-body">integer</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Default value:</th><td class="field-body">2</td>
+</tr>
+</tbody>
+</table>
+<p>Number of columns and rows for the textareas. This value will be
+emphasized (*2) for <a class="reference internal" href="glossary.html#term-sql"><em class="xref std std-term">SQL</em></a> query
+textareas and (*1.25) for <a class="reference internal" href="glossary.html#term-sql"><em class="xref std std-term">SQL</em></a>
+textareas inside the query window.</p>
+<p>The Char* values are used for CHAR
+and VARCHAR editing (if configured via <span class="target" id="index-70"></span><a class="reference internal" href="#cfg_CharEditing"><tt class="xref config config-option docutils literal"><span class="pre">$cfg['CharEditing']</span></tt></a>).</p>
+</dd></dl>
+
+<dl class="option">
+<dt id="cfg_LongtextDoubleTextarea">
+<tt class="descname">$cfg['LongtextDoubleTextarea']</tt><a class="headerlink" href="#cfg_LongtextDoubleTextarea" title="Permalink to this definition">¶</a></dt>
+<dd><table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Type:</th><td class="field-body">boolean</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Default value:</th><td class="field-body">true</td>
+</tr>
+</tbody>
+</table>
+<p>Defines whether textarea for LONGTEXT columns should have double size.</p>
+</dd></dl>
+
+<dl class="option">
+<dt id="cfg_TextareaAutoSelect">
+<tt class="descname">$cfg['TextareaAutoSelect']</tt><a class="headerlink" href="#cfg_TextareaAutoSelect" title="Permalink to this definition">¶</a></dt>
+<dd><table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Type:</th><td class="field-body">boolean</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Default value:</th><td class="field-body">false</td>
+</tr>
+</tbody>
+</table>
+<p>Defines if the whole textarea of the query box will be selected on
+click.</p>
+</dd></dl>
+
+</div>
+<div class="section" id="sql-query-box-settings">
+<h2>SQL query box settings<a class="headerlink" href="#sql-query-box-settings" title="Permalink to this headline">¶</a></h2>
+<dl class="option">
+<dt id="cfg_SQLQuery_Edit">
+<tt class="descname">$cfg['SQLQuery']['Edit']</tt><a class="headerlink" href="#cfg_SQLQuery_Edit" title="Permalink to this definition">¶</a></dt>
+<dd><table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Type:</th><td class="field-body">boolean</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Default value:</th><td class="field-body">true</td>
+</tr>
+</tbody>
+</table>
+<p>Whether to display an edit link to change a query in any SQL Query
+box.</p>
+</dd></dl>
+
+<dl class="option">
+<dt id="cfg_SQLQuery_Explain">
+<tt class="descname">$cfg['SQLQuery']['Explain']</tt><a class="headerlink" href="#cfg_SQLQuery_Explain" title="Permalink to this definition">¶</a></dt>
+<dd><table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Type:</th><td class="field-body">boolean</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Default value:</th><td class="field-body">true</td>
+</tr>
+</tbody>
+</table>
+<p>Whether to display a link to explain a SELECT query in any SQL Query
+box.</p>
+</dd></dl>
+
+<dl class="option">
+<dt id="cfg_SQLQuery_ShowAsPHP">
+<tt class="descname">$cfg['SQLQuery']['ShowAsPHP']</tt><a class="headerlink" href="#cfg_SQLQuery_ShowAsPHP" title="Permalink to this definition">¶</a></dt>
+<dd><table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Type:</th><td class="field-body">boolean</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Default value:</th><td class="field-body">true</td>
+</tr>
+</tbody>
+</table>
+<p>Whether to display a link to wrap a query in PHP code in any SQL Query
+box.</p>
+</dd></dl>
+
+<dl class="option">
+<dt id="cfg_SQLQuery_Validate">
+<tt class="descname">$cfg['SQLQuery']['Validate']</tt><a class="headerlink" href="#cfg_SQLQuery_Validate" title="Permalink to this definition">¶</a></dt>
+<dd><table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Type:</th><td class="field-body">boolean</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Default value:</th><td class="field-body">false</td>
+</tr>
+</tbody>
+</table>
+<p>Whether to display a link to validate a query in any SQL Query box.</p>
+<div class="admonition-see-also admonition seealso">
+<p class="first admonition-title">See also</p>
+<p class="last"><span class="target" id="index-71"></span><a class="reference internal" href="#cfg_SQLValidator"><tt class="xref config config-option docutils literal"><span class="pre">$cfg['SQLValidator']</span></tt></a></p>
+</div>
+</dd></dl>
+
+<dl class="option">
+<dt id="cfg_SQLQuery_Refresh">
+<tt class="descname">$cfg['SQLQuery']['Refresh']</tt><a class="headerlink" href="#cfg_SQLQuery_Refresh" title="Permalink to this definition">¶</a></dt>
+<dd><table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Type:</th><td class="field-body">boolean</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Default value:</th><td class="field-body">true</td>
+</tr>
+</tbody>
+</table>
+<p>Whether to display a link to refresh a query in any SQL Query box.</p>
+</dd></dl>
+
+</div>
+<div class="section" id="web-server-upload-save-import-directories">
+<h2>Web server upload/save/import directories<a class="headerlink" href="#web-server-upload-save-import-directories" title="Permalink to this headline">¶</a></h2>
+<dl class="option">
+<dt id="cfg_UploadDir">
+<tt class="descname">$cfg['UploadDir']</tt><a class="headerlink" href="#cfg_UploadDir" title="Permalink to this definition">¶</a></dt>
+<dd><table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Type:</th><td class="field-body">string</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Default value:</th><td class="field-body"><tt class="docutils literal"><span class="pre">''</span></tt></td>
+</tr>
+</tbody>
+</table>
+<p>The name of the directory where <a class="reference internal" href="glossary.html#term-sql"><em class="xref std std-term">SQL</em></a> files have been uploaded by
+other means than phpMyAdmin (for example, ftp). Those files are available
+under a drop-down box when you click the database or table name, then the
+Import tab.</p>
+<p>If
+you want different directory for each user, %u will be replaced with
+username.</p>
+<p>Please note that the file names must have the suffix ”.sql”
+(or ”.sql.bz2” or ”.sql.gz” if support for compressed formats is
+enabled).</p>
+<p>This feature is useful when your file is too big to be
+uploaded via <a class="reference internal" href="glossary.html#term-http"><em class="xref std std-term">HTTP</em></a>, or when file
+uploads are disabled in PHP.</p>
+<div class="admonition note">
+<p class="first admonition-title">Note</p>
+<p class="last">If PHP is running in safe mode, this directory must be owned by the same
+user as the owner of the phpMyAdmin scripts.  See also <a class="reference internal" href="faq.html#faq1-16"><em>1.16 I cannot upload big dump files (memory, HTTP or timeout problems).</em></a> for
+alternatives.</p>
+</div>
+</dd></dl>
+
+<dl class="option">
+<dt id="cfg_SaveDir">
+<tt class="descname">$cfg['SaveDir']</tt><a class="headerlink" href="#cfg_SaveDir" title="Permalink to this definition">¶</a></dt>
+<dd><table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Type:</th><td class="field-body">string</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Default value:</th><td class="field-body"><tt class="docutils literal"><span class="pre">''</span></tt></td>
+</tr>
+</tbody>
+</table>
+<p>The name of the directory where dumps can be saved.</p>
+<p>If you want different directory for each user, %u will be replaced with
+username.</p>
+<p>Please note that the directory must exist and has to be writable for
+the user running webserver.</p>
+<div class="admonition note">
+<p class="first admonition-title">Note</p>
+<p class="last">If PHP is running in safe mode, this directory must be owned by the same
+user as the owner of the phpMyAdmin scripts.</p>
+</div>
+</dd></dl>
+
+<dl class="option">
+<dt id="cfg_TempDir">
+<tt class="descname">$cfg['TempDir']</tt><a class="headerlink" href="#cfg_TempDir" title="Permalink to this definition">¶</a></dt>
+<dd><table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Type:</th><td class="field-body">string</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Default value:</th><td class="field-body"><tt class="docutils literal"><span class="pre">''</span></tt></td>
+</tr>
+</tbody>
+</table>
+<p>The name of the directory where temporary files can be stored.</p>
+<p>This is needed for importing ESRI Shapefiles, see <a class="reference internal" href="faq.html#faq6-30"><em>6.30 Import: How can I import ESRI Shapefiles</em></a> and to
+work around limitations of <tt class="docutils literal"><span class="pre">open_basedir</span></tt> for uploaded files, see
+<a class="reference internal" href="faq.html#faq1-11"><em>1.11 I get an ‘open_basedir restriction’ while uploading a file from the query box.</em></a>.</p>
+<p>If the directory where phpMyAdmin is installed is
+subject to an <tt class="docutils literal"><span class="pre">open_basedir</span></tt> restriction, you need to create a
+temporary directory in some directory accessible by the web server.
+However for security reasons, this directory should be outside the
+tree published by webserver. If you cannot avoid having this directory
+published by webserver, place at least an empty <tt class="file docutils literal"><span class="pre">index.html</span></tt> file
+there, so that directory listing is not possible.</p>
+<p>This directory should have as strict permissions as possible as the only
+user required to access this directory is the one who runs the webserver.
+If you have root privileges, simply make this user owner of this directory
+and make it accessible only by it:</p>
+<div class="highlight-sh"><div class="highlight"><pre>chown www-data:www-data tmp
+chmod 700 tmp
+</pre></div>
+</div>
+<p>If you cannot change owner of the directory, you can achieve a similar
+setup using <a class="reference internal" href="glossary.html#term-acl"><em class="xref std std-term">ACL</em></a>:</p>
+<div class="highlight-sh"><div class="highlight"><pre>chmod 700 tmp
+setfacl -m <span class="s2">"g:www-data:rwx"</span> tmp
+setfacl -d -m <span class="s2">"g:www-data:rwx"</span> tmp
+</pre></div>
+</div>
+<p>If neither of above works for you, you can still make the directory
+<strong class="command">chmod 777</strong>, but it might impose risk of other users on system
+reading and writing data in this directory.</p>
+</dd></dl>
+
+</div>
+<div class="section" id="various-display-setting">
+<h2>Various display setting<a class="headerlink" href="#various-display-setting" title="Permalink to this headline">¶</a></h2>
+<dl class="option">
+<dt id="cfg_ShowDisplayDirection">
+<tt class="descname">$cfg['ShowDisplayDirection']</tt><a class="headerlink" href="#cfg_ShowDisplayDirection" title="Permalink to this definition">¶</a></dt>
+<dd><table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Type:</th><td class="field-body">boolean</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Default value:</th><td class="field-body">false</td>
+</tr>
+</tbody>
+</table>
+<p>Defines whether or not type display direction option is shown when
+browsing a table.</p>
+</dd></dl>
+
+<dl class="option">
+<dt id="cfg_RepeatCells">
+<tt class="descname">$cfg['RepeatCells']</tt><a class="headerlink" href="#cfg_RepeatCells" title="Permalink to this definition">¶</a></dt>
+<dd><table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Type:</th><td class="field-body">integer</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Default value:</th><td class="field-body">100</td>
+</tr>
+</tbody>
+</table>
+<p>Repeat the headers every X cells, or 0 to deactivate.</p>
+</dd></dl>
+
+<dl class="option">
+<dt id="cfg_EditInWindow">
+<tt class="descname">$cfg['EditInWindow']</tt><a class="headerlink" href="#cfg_EditInWindow" title="Permalink to this definition">¶</a></dt>
+<dd><table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Type:</th><td class="field-body">boolean</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Default value:</th><td class="field-body">true</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+<dl class="option">
+<dt id="cfg_QueryWindowWidth">
+<tt class="descname">$cfg['QueryWindowWidth']</tt><a class="headerlink" href="#cfg_QueryWindowWidth" title="Permalink to this definition">¶</a></dt>
+<dd><table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Type:</th><td class="field-body">integer</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Default value:</th><td class="field-body">550</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+<dl class="option">
+<dt id="cfg_QueryWindowHeight">
+<tt class="descname">$cfg['QueryWindowHeight']</tt><a class="headerlink" href="#cfg_QueryWindowHeight" title="Permalink to this definition">¶</a></dt>
+<dd><table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Type:</th><td class="field-body">integer</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Default value:</th><td class="field-body">310</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+<dl class="option">
+<dt id="cfg_QueryHistoryDB">
+<tt class="descname">$cfg['QueryHistoryDB']</tt><a class="headerlink" href="#cfg_QueryHistoryDB" title="Permalink to this definition">¶</a></dt>
+<dd><table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Type:</th><td class="field-body">boolean</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Default value:</th><td class="field-body">false</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+<dl class="option">
+<dt id="cfg_QueryWindowDefTab">
+<tt class="descname">$cfg['QueryWindowDefTab']</tt><a class="headerlink" href="#cfg_QueryWindowDefTab" title="Permalink to this definition">¶</a></dt>
+<dd><table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Type:</th><td class="field-body">string</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Default value:</th><td class="field-body"><tt class="docutils literal"><span class="pre">'sql'</span></tt></td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+<dl class="option">
+<dt id="cfg_QueryHistoryMax">
+<tt class="descname">$cfg['QueryHistoryMax']</tt><a class="headerlink" href="#cfg_QueryHistoryMax" title="Permalink to this definition">¶</a></dt>
+<dd><table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Type:</th><td class="field-body">integer</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Default value:</th><td class="field-body">25</td>
+</tr>
+</tbody>
+</table>
+<p>All those variables affect the query window feature. A <a class="reference internal" href="glossary.html#term-sql"><em class="xref std std-term">SQL</em></a> link or
+icon is always displayed in the navigation panel. If JavaScript is enabled
+in your browser, a click on this opens a distinct query window, which is a
+direct interface to enter <a class="reference internal" href="glossary.html#term-sql"><em class="xref std std-term">SQL</em></a> queries. Otherwise, the right panel
+changes to display a query box.</p>
+<p>The size of this query window can be customized with
+<span class="target" id="index-72"></span><a class="reference internal" href="#cfg_QueryWindowWidth"><tt class="xref config config-option docutils literal"><span class="pre">$cfg['QueryWindowWidth']</span></tt></a> and
+<span class="target" id="index-73"></span><a class="reference internal" href="#cfg_QueryWindowHeight"><tt class="xref config config-option docutils literal"><span class="pre">$cfg['QueryWindowHeight']</span></tt></a> - both integers for the size in
+pixels.  Note that normally, those parameters will be modified in
+<tt class="file docutils literal"><span class="pre">layout.inc.php`</span></tt> for the theme you are using.</p>
+<p>If <span class="target" id="index-74"></span><a class="reference internal" href="#cfg_EditInWindow"><tt class="xref config config-option docutils literal"><span class="pre">$cfg['EditInWindow']</span></tt></a> is set to true, a click on [Edit]
+from the results page (in the <em class="guilabel">Showing Rows</em> section) opens the
+query window and puts the current query inside it. If set to false,
+clicking on the link puts the <a class="reference internal" href="glossary.html#term-sql"><em class="xref std std-term">SQL</em></a> query
+in the right panel’s query box.</p>
+<p>If <span class="target" id="index-75"></span><a class="reference internal" href="#cfg_QueryHistoryDB"><tt class="xref config config-option docutils literal"><span class="pre">$cfg['QueryHistoryDB']</span></tt></a> is set to <tt class="docutils literal"><span class="pre">true</span></tt>, all your
+Queries are logged to a table, which has to be created by you (see
+<span class="target" id="index-76"></span><a class="reference internal" href="#cfg_Servers_history"><tt class="xref config config-option docutils literal"><span class="pre">$cfg['Servers'][$i]['history']</span></tt></a>). If set to false, all your
+queries will be appended to the form, but only as long as your window is
+opened they remain saved.</p>
+<p>When using the JavaScript based query window, it will always get updated
+when you click on a new table/db to browse and will focus if you click on
+<em class="guilabel">Edit SQL</em> after using a query. You can suppress updating the
+query window by checking the box <em class="guilabel">Do not overwrite this query
+from outside the window</em> below the query textarea. Then you can browse
+tables/databases in the background without losing the contents of the
+textarea, so this is especially useful when composing a query with tables
+you first have to look in. The checkbox will get automatically checked
+whenever you change the contents of the textarea. Please uncheck the button
+whenever you definitely want the query window to get updated even though
+you have made alterations.</p>
+<p>If <span class="target" id="index-77"></span><a class="reference internal" href="#cfg_QueryHistoryDB"><tt class="xref config config-option docutils literal"><span class="pre">$cfg['QueryHistoryDB']</span></tt></a> is set to <tt class="docutils literal"><span class="pre">true</span></tt> you can
+specify the amount of saved history items using
+<span class="target" id="index-78"></span><a class="reference internal" href="#cfg_QueryHistoryMax"><tt class="xref config config-option docutils literal"><span class="pre">$cfg['QueryHistoryMax']</span></tt></a>.</p>
+<p>The query window also has a custom tabbed look to group the features.
+Using the variable <span class="target" id="index-79"></span><a class="reference internal" href="#cfg_QueryWindowDefTab"><tt class="xref config config-option docutils literal"><span class="pre">$cfg['QueryWindowDefTab']</span></tt></a> you can
+specify the default tab to be used when opening the query window. It can be
+set to either <tt class="docutils literal"><span class="pre">sql</span></tt>, <tt class="docutils literal"><span class="pre">files</span></tt>, <tt class="docutils literal"><span class="pre">history</span></tt> or <tt class="docutils literal"><span class="pre">full</span></tt>.</p>
+</dd></dl>
+
+<dl class="option">
+<dt id="cfg_BrowseMIME">
+<tt class="descname">$cfg['BrowseMIME']</tt><a class="headerlink" href="#cfg_BrowseMIME" title="Permalink to this definition">¶</a></dt>
+<dd><table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Type:</th><td class="field-body">boolean</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Default value:</th><td class="field-body">true</td>
+</tr>
+</tbody>
+</table>
+<p>Enable <a class="reference internal" href="transformations.html#transformations"><em>Transformations</em></a>.</p>
+</dd></dl>
+
+<dl class="option">
+<dt id="cfg_MaxExactCount">
+<tt class="descname">$cfg['MaxExactCount']</tt><a class="headerlink" href="#cfg_MaxExactCount" title="Permalink to this definition">¶</a></dt>
+<dd><table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Type:</th><td class="field-body">integer</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Default value:</th><td class="field-body">0</td>
+</tr>
+</tbody>
+</table>
+<p>For InnoDB tables, determines for how large tables phpMyAdmin should
+get the exact row count using <tt class="docutils literal"><span class="pre">SELECT</span> <span class="pre">COUNT</span></tt>. If the approximate row
+count as returned by <tt class="docutils literal"><span class="pre">SHOW</span> <span class="pre">TABLE</span> <span class="pre">STATUS</span></tt> is smaller than this value,
+<tt class="docutils literal"><span class="pre">SELECT</span> <span class="pre">COUNT</span></tt> will be used, otherwise the approximate count will be
+used.</p>
+</dd></dl>
+
+<dl class="option">
+<dt id="cfg_MaxExactCountViews">
+<tt class="descname">$cfg['MaxExactCountViews']</tt><a class="headerlink" href="#cfg_MaxExactCountViews" title="Permalink to this definition">¶</a></dt>
+<dd><table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Type:</th><td class="field-body">integer</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Default value:</th><td class="field-body">0</td>
+</tr>
+</tbody>
+</table>
+<p>For VIEWs, since obtaining the exact count could have an impact on
+performance, this value is the maximum to be displayed, using a
+<tt class="docutils literal"><span class="pre">SELECT</span> <span class="pre">COUNT</span> <span class="pre">...</span> <span class="pre">LIMIT</span></tt>. Setting this to 0 bypasses any row
+counting.</p>
+</dd></dl>
+
+<dl class="option">
+<dt id="cfg_NaturalOrder">
+<tt class="descname">$cfg['NaturalOrder']</tt><a class="headerlink" href="#cfg_NaturalOrder" title="Permalink to this definition">¶</a></dt>
+<dd><table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Type:</th><td class="field-body">boolean</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Default value:</th><td class="field-body">true</td>
+</tr>
+</tbody>
+</table>
+<p>Sorts database and table names according to natural order (for
+example, t1, t2, t10). Currently implemented in the navigation panel
+and in Database view, for the table list.</p>
+</dd></dl>
+
+<dl class="option">
+<dt id="cfg_InitialSlidersState">
+<tt class="descname">$cfg['InitialSlidersState']</tt><a class="headerlink" href="#cfg_InitialSlidersState" title="Permalink to this definition">¶</a></dt>
+<dd><table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Type:</th><td class="field-body">string</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Default value:</th><td class="field-body"><tt class="docutils literal"><span class="pre">'closed'</span></tt></td>
+</tr>
+</tbody>
+</table>
+<p>If set to <tt class="docutils literal"><span class="pre">'closed'</span></tt>, the visual sliders are initially in a closed
+state. A value of <tt class="docutils literal"><span class="pre">'open'</span></tt> does the reverse. To completely disable
+all visual sliders, use <tt class="docutils literal"><span class="pre">'disabled'</span></tt>.</p>
+</dd></dl>
+
+<dl class="option">
+<dt id="cfg_UserprefsDisallow">
+<tt class="descname">$cfg['UserprefsDisallow']</tt><a class="headerlink" href="#cfg_UserprefsDisallow" title="Permalink to this definition">¶</a></dt>
+<dd><table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Type:</th><td class="field-body">array</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Default value:</th><td class="field-body">array()</td>
+</tr>
+</tbody>
+</table>
+<p>Contains names of configuration options (keys in <tt class="docutils literal"><span class="pre">$cfg</span></tt> array) that
+users can’t set through user preferences. For possible values, refer
+to <tt class="file docutils literal"><span class="pre">libraries/config/user_preferences.forms.php</span></tt>.</p>
+</dd></dl>
+
+<dl class="option">
+<dt id="cfg_UserprefsDeveloperTab">
+<tt class="descname">$cfg['UserprefsDeveloperTab']</tt><a class="headerlink" href="#cfg_UserprefsDeveloperTab" title="Permalink to this definition">¶</a></dt>
+<dd><table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Type:</th><td class="field-body">boolean</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Default value:</th><td class="field-body">false</td>
+</tr>
+</tbody>
+</table>
+<p>Activates in the user preferences a tab containing options for
+developers of phpMyAdmin.</p>
+</dd></dl>
+
+</div>
+<div class="section" id="page-titles">
+<h2>Page titles<a class="headerlink" href="#page-titles" title="Permalink to this headline">¶</a></h2>
+<dl class="option">
+<dt id="cfg_TitleTable">
+<tt class="descname">$cfg['TitleTable']</tt><a class="headerlink" href="#cfg_TitleTable" title="Permalink to this definition">¶</a></dt>
+<dd><table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Type:</th><td class="field-body">string</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Default value:</th><td class="field-body"><tt class="docutils literal"><span class="pre">'@HTTP_HOST@</span> <span class="pre">/</span> <span class="pre">@VSERVER@</span> <span class="pre">/</span> <span class="pre">@DATABASE@</span> <span class="pre">/</span> <span class="pre">@TABLE@</span> <span class="pre">|</span> <span class="pre">@PHPMYADMIN@'</span></tt></td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+<dl class="option">
+<dt id="cfg_TitleDatabase">
+<tt class="descname">$cfg['TitleDatabase']</tt><a class="headerlink" href="#cfg_TitleDatabase" title="Permalink to this definition">¶</a></dt>
+<dd><table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Type:</th><td class="field-body">string</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Default value:</th><td class="field-body"><tt class="docutils literal"><span class="pre">'@HTTP_HOST@</span> <span class="pre">/</span> <span class="pre">@VSERVER@</span> <span class="pre">/</span> <span class="pre">@DATABASE@</span> <span class="pre">|</span> <span class="pre">@PHPMYADMIN@'</span></tt></td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+<dl class="option">
+<dt id="cfg_TitleServer">
+<tt class="descname">$cfg['TitleServer']</tt><a class="headerlink" href="#cfg_TitleServer" title="Permalink to this definition">¶</a></dt>
+<dd><table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Type:</th><td class="field-body">string</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Default value:</th><td class="field-body"><tt class="docutils literal"><span class="pre">'@HTTP_HOST@</span> <span class="pre">/</span> <span class="pre">@VSERVER@</span> <span class="pre">|</span> <span class="pre">@PHPMYADMIN@'</span></tt></td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+<dl class="option">
+<dt id="cfg_TitleDefault">
+<tt class="descname">$cfg['TitleDefault']</tt><a class="headerlink" href="#cfg_TitleDefault" title="Permalink to this definition">¶</a></dt>
+<dd><table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Type:</th><td class="field-body">string</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Default value:</th><td class="field-body"><tt class="docutils literal"><span class="pre">'@HTTP_HOST@</span> <span class="pre">|</span> <span class="pre">@PHPMYADMIN@'</span></tt></td>
+</tr>
+</tbody>
+</table>
+<p>Allows you to specify window’s title bar. You can use <a class="reference internal" href="faq.html#faq6-27"><em>6.27 What format strings can I use?</em></a>.</p>
+</dd></dl>
+
+</div>
+<div class="section" id="theme-manager-settings">
+<h2>Theme manager settings<a class="headerlink" href="#theme-manager-settings" title="Permalink to this headline">¶</a></h2>
+<dl class="option">
+<dt id="cfg_ThemePath">
+<tt class="descname">$cfg['ThemePath']</tt><a class="headerlink" href="#cfg_ThemePath" title="Permalink to this definition">¶</a></dt>
+<dd><table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Type:</th><td class="field-body">string</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Default value:</th><td class="field-body"><tt class="docutils literal"><span class="pre">'./themes'</span></tt></td>
+</tr>
+</tbody>
+</table>
+<p>If theme manager is active, use this as the path of the subdirectory
+containing all the themes.</p>
+</dd></dl>
+
+<dl class="option">
+<dt id="cfg_ThemeManager">
+<tt class="descname">$cfg['ThemeManager']</tt><a class="headerlink" href="#cfg_ThemeManager" title="Permalink to this definition">¶</a></dt>
+<dd><table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Type:</th><td class="field-body">boolean</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Default value:</th><td class="field-body">true</td>
+</tr>
+</tbody>
+</table>
+<p>Enables user-selectable themes. See <a class="reference internal" href="faq.html#faqthemes"><em>2.7 Using and creating themes</em></a>.</p>
+</dd></dl>
+
+<dl class="option">
+<dt id="cfg_ThemeDefault">
+<tt class="descname">$cfg['ThemeDefault']</tt><a class="headerlink" href="#cfg_ThemeDefault" title="Permalink to this definition">¶</a></dt>
+<dd><table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Type:</th><td class="field-body">string</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Default value:</th><td class="field-body"><tt class="docutils literal"><span class="pre">'pmahomme'</span></tt></td>
+</tr>
+</tbody>
+</table>
+<p>The default theme (a subdirectory under <span class="target" id="index-80"></span><a class="reference internal" href="#cfg_ThemePath"><tt class="xref config config-option docutils literal"><span class="pre">$cfg['ThemePath']</span></tt></a>).</p>
+</dd></dl>
+
+<dl class="option">
+<dt id="cfg_ThemePerServer">
+<tt class="descname">$cfg['ThemePerServer']</tt><a class="headerlink" href="#cfg_ThemePerServer" title="Permalink to this definition">¶</a></dt>
+<dd><table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Type:</th><td class="field-body">boolean</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Default value:</th><td class="field-body">false</td>
+</tr>
+</tbody>
+</table>
+<p>Whether to allow different theme for each server.</p>
+</dd></dl>
+
+</div>
+<div class="section" id="default-queries">
+<h2>Default queries<a class="headerlink" href="#default-queries" title="Permalink to this headline">¶</a></h2>
+<dl class="option">
+<dt id="cfg_DefaultQueryTable">
+<tt class="descname">$cfg['DefaultQueryTable']</tt><a class="headerlink" href="#cfg_DefaultQueryTable" title="Permalink to this definition">¶</a></dt>
+<dd><table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Type:</th><td class="field-body">string</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Default value:</th><td class="field-body"><tt class="docutils literal"><span class="pre">'SELECT</span> <span class="pre">*</span> <span class="pre">FROM</span> <span class="pre">@TABLE@</span> <span class="pre">WHERE</span> <span class="pre">1'</span></tt></td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+<dl class="option">
+<dt id="cfg_DefaultQueryDatabase">
+<tt class="descname">$cfg['DefaultQueryDatabase']</tt><a class="headerlink" href="#cfg_DefaultQueryDatabase" title="Permalink to this definition">¶</a></dt>
+<dd><table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Type:</th><td class="field-body">string</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Default value:</th><td class="field-body"><tt class="docutils literal"><span class="pre">''</span></tt></td>
+</tr>
+</tbody>
+</table>
+<p>Default queries that will be displayed in query boxes when user didn’t
+specify any. You can use standard <a class="reference internal" href="faq.html#faq6-27"><em>6.27 What format strings can I use?</em></a>.</p>
+</dd></dl>
+
+</div>
+<div class="section" id="sql-parser-settings">
+<h2>SQL parser settings<a class="headerlink" href="#sql-parser-settings" title="Permalink to this headline">¶</a></h2>
+<dl class="option">
+<dt id="cfg_SQP_fmtType">
+<tt class="descname">$cfg['SQP']['fmtType']</tt><a class="headerlink" href="#cfg_SQP_fmtType" title="Permalink to this definition">¶</a></dt>
+<dd><table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Type:</th><td class="field-body">string</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Default value:</th><td class="field-body"><tt class="docutils literal"><span class="pre">'html'</span></tt></td>
+</tr>
+</tbody>
+</table>
+<p>The main use of the new <a class="reference internal" href="glossary.html#term-sql"><em class="xref std std-term">SQL</em></a> Parser
+is to pretty-print <a class="reference internal" href="glossary.html#term-sql"><em class="xref std std-term">SQL</em></a> queries. By
+default we use HTML to format the query, but you can disable this by
+setting this variable to <tt class="docutils literal"><span class="pre">'none'</span></tt>.</p>
+<p>Available options:</p>
+<ul class="simple">
+<li><tt class="docutils literal"><span class="pre">'html'</span></tt></li>
+<li><tt class="docutils literal"><span class="pre">'none'</span></tt></li>
+</ul>
+</dd></dl>
+
+<span class="target" id="cfg-sqp"></span><dl class="option">
+<dt id="cfg_SQP_fmtInd">
+<tt class="descname">$cfg['SQP']['fmtInd']</tt><a class="headerlink" href="#cfg_SQP_fmtInd" title="Permalink to this definition">¶</a></dt>
+<dd><table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Type:</th><td class="field-body">float</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Default value:</th><td class="field-body"><tt class="docutils literal"><span class="pre">'1'</span></tt></td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+<dl class="option">
+<dt id="cfg_SQP_fmtIndUnit">
+<tt class="descname">$cfg['SQP']['fmtIndUnit']</tt><a class="headerlink" href="#cfg_SQP_fmtIndUnit" title="Permalink to this definition">¶</a></dt>
+<dd><table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Type:</th><td class="field-body">string</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Default value:</th><td class="field-body"><tt class="docutils literal"><span class="pre">'em'</span></tt></td>
+</tr>
+</tbody>
+</table>
+<p>For the pretty-printing of <a class="reference internal" href="glossary.html#term-sql"><em class="xref std std-term">SQL</em></a> queries,
+under some cases the part of a query inside a bracket is indented. By
+changing <span class="target" id="index-81"></span><a class="reference internal" href="#cfg_SQP_fmtInd"><tt class="xref config config-option docutils literal"><span class="pre">$cfg['SQP']['fmtInd']</span></tt></a> you can change the amount
+of this indent.</p>
+<p>Related in purpose is <span class="target" id="index-82"></span><a class="reference internal" href="#cfg_SQP_fmtIndUnit"><tt class="xref config config-option docutils literal"><span class="pre">$cfg['SQP']['fmtIndUnit']</span></tt></a> which
+specifies the units of the indent amount that you specified. This is used
+via stylesheets.</p>
+<p>You can use any HTML unit, for example:</p>
+<ul class="simple">
+<li><tt class="docutils literal"><span class="pre">'em'</span></tt></li>
+<li><tt class="docutils literal"><span class="pre">'ex'</span></tt></li>
+<li><tt class="docutils literal"><span class="pre">'pt'</span></tt></li>
+<li><tt class="docutils literal"><span class="pre">'px'</span></tt></li>
+</ul>
+</dd></dl>
+
+<dl class="option">
+<dt id="cfg_SQP_fmtColor">
+<tt class="descname">$cfg['SQP']['fmtColor']</tt><a class="headerlink" href="#cfg_SQP_fmtColor" title="Permalink to this definition">¶</a></dt>
+<dd><table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Type:</th><td class="field-body">array of string tuples</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Default value:</th><td class="field-body"></td>
+</tr>
+</tbody>
+</table>
+<p>This array is used to define the colours for each type of element of
+the pretty-printed <a class="reference internal" href="glossary.html#term-sql"><em class="xref std std-term">SQL</em></a> queries.
+The tuple format is <em>class</em> => [<em>HTML colour code</em> | <em>empty string</em>]</p>
+<p>If you specify an empty string for the color of a class, it is ignored
+in creating the stylesheet. You should not alter the class names, only
+the colour strings.</p>
+<p><strong>Class name key:</strong></p>
+<dl class="docutils">
+<dt>comment</dt>
+<dd>Applies to all comment sub-classes</dd>
+<dt>comment_mysql</dt>
+<dd>Comments as <tt class="docutils literal"><span class="pre">"#...\n"</span></tt></dd>
+<dt>comment_ansi</dt>
+<dd>Comments as <tt class="docutils literal"><span class="pre">"--</span> <span class="pre">...\n"</span></tt></dd>
+<dt>comment_c</dt>
+<dd>Comments as <tt class="docutils literal"><span class="pre">"/*...*/"</span></tt></dd>
+<dt>digit</dt>
+<dd>Applies to all digit sub-classes</dd>
+<dt>digit_hex</dt>
+<dd>Hexadecimal numbers</dd>
+<dt>digit_integer</dt>
+<dd>Integer numbers</dd>
+<dt>digit_float</dt>
+<dd>Floating point numbers</dd>
+<dt>punct</dt>
+<dd>Applies to all punctuation sub-classes</dd>
+<dt>punct_bracket_open_round</dt>
+<dd>Opening brackets <tt class="docutils literal"><span class="pre">"("</span></tt></dd>
+<dt>punct_bracket_close_round</dt>
+<dd>Closing brackets <tt class="docutils literal"><span class="pre">")"</span></tt></dd>
+<dt>punct_listsep</dt>
+<dd>List item Separator <tt class="docutils literal"><span class="pre">","</span></tt></dd>
+<dt>punct_qualifier</dt>
+<dd>Table/Column Qualifier <tt class="docutils literal"><span class="pre">"."</span></tt></dd>
+<dt>punct_queryend</dt>
+<dd>End of query marker <tt class="docutils literal"><span class="pre">";"</span></tt></dd>
+<dt>alpha</dt>
+<dd>Applies to all alphabetic classes</dd>
+<dt>alpha_columnType</dt>
+<dd>Identifiers matching a column type</dd>
+<dt>alpha_columnAttrib</dt>
+<dd>Identifiers matching a database/table/column attribute</dd>
+<dt>alpha_functionName</dt>
+<dd>Identifiers matching a MySQL function name</dd>
+<dt>alpha_reservedWord</dt>
+<dd>Identifiers matching any other reserved word</dd>
+<dt>alpha_variable</dt>
+<dd>Identifiers matching a <a class="reference internal" href="glossary.html#term-sql"><em class="xref std std-term">SQL</em></a> variable <tt class="docutils literal"><span class="pre">"@foo"</span></tt></dd>
+<dt>alpha_identifier</dt>
+<dd>All other identifiers</dd>
+<dt>quote</dt>
+<dd>Applies to all quotation mark classes</dd>
+<dt>quote_double</dt>
+<dd>Double quotes <tt class="docutils literal"><span class="pre">"</span></tt></dd>
+<dt>quote_single</dt>
+<dd>Single quotes <tt class="docutils literal"><span class="pre">'</span></tt></dd>
+<dt>quote_backtick</dt>
+<dd>Backtick quotes <tt class="docutils literal"><span class="pre">`</span></tt></dd>
+</dl>
+</dd></dl>
+
+</div>
+<div class="section" id="sql-validator-settings">
+<h2>SQL validator settings<a class="headerlink" href="#sql-validator-settings" title="Permalink to this headline">¶</a></h2>
+<dl class="option">
+<dt id="cfg_SQLValidator">
+<tt class="descname">$cfg['SQLValidator']</tt><a class="headerlink" href="#cfg_SQLValidator" title="Permalink to this definition">¶</a></dt>
+<dd><table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Type:</th><td class="field-body">array</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Default value:</th><td class="field-body">array(...)</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+<dl class="option">
+<dt id="cfg_SQLValidator_use">
+<tt class="descname">$cfg['SQLValidator']['use']</tt><a class="headerlink" href="#cfg_SQLValidator_use" title="Permalink to this definition">¶</a></dt>
+<dd><table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Type:</th><td class="field-body">boolean</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Default value:</th><td class="field-body">false</td>
+</tr>
+</tbody>
+</table>
+<p>phpMyAdmin now supports use of the <a class="reference external" href="http://developer.mimer.com/validator/index.htm">Mimer SQL Validator</a> service, as originally
+published on <a class="reference external" href="http://developers.slashdot.org/article.pl?sid=02/02/19/1720246">Slashdot</a>. For
+help in setting up your system to use the service, see the
+<a class="reference internal" href="faq.html#faqsqlvalidator"><em>6.14 How do I set up the SQL Validator?</em></a>.</p>
+</dd></dl>
+
+<dl class="option">
+<dt id="cfg_SQLValidator_username">
+<tt class="descname">$cfg['SQLValidator']['username']</tt><a class="headerlink" href="#cfg_SQLValidator_username" title="Permalink to this definition">¶</a></dt>
+<dd><table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Type:</th><td class="field-body">string</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Default value:</th><td class="field-body"><tt class="docutils literal"><span class="pre">''</span></tt></td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+<dl class="option">
+<dt id="cfg_SQLValidator_password">
+<tt class="descname">$cfg['SQLValidator']['password']</tt><a class="headerlink" href="#cfg_SQLValidator_password" title="Permalink to this definition">¶</a></dt>
+<dd><table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Type:</th><td class="field-body">string</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Default value:</th><td class="field-body"><tt class="docutils literal"><span class="pre">''</span></tt></td>
+</tr>
+</tbody>
+</table>
+<p>The SOAP service allows you to log in with <tt class="docutils literal"><span class="pre">anonymous</span></tt> and any password,
+so we use those by default. Instead, if you have an account with them, you
+can put your login details here, and it will be used in place of the
+anonymous login.</p>
+</dd></dl>
+
+</div>
+<div class="section" id="mysql-settings">
+<h2>MySQL settings<a class="headerlink" href="#mysql-settings" title="Permalink to this headline">¶</a></h2>
+<dl class="option">
+<dt id="cfg_DefaultFunctions">
+<tt class="descname">$cfg['DefaultFunctions']</tt><a class="headerlink" href="#cfg_DefaultFunctions" title="Permalink to this definition">¶</a></dt>
+<dd><table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Type:</th><td class="field-body">array</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Default value:</th><td class="field-body">array(...)</td>
+</tr>
+</tbody>
+</table>
+<p>Functions selected by default when inserting/changing row, Functions
+are defined for meta types as (FUNC_NUMBER, FUNC_DATE, FUNC_CHAR,
+FUNC_SPATIAL, FUNC_UUID) and for <tt class="docutils literal"><span class="pre">first_timestamp</span></tt>, which is used
+for first timestamp column in table.</p>
+</dd></dl>
+
+</div>
+<div class="section" id="developer">
+<h2>Developer<a class="headerlink" href="#developer" title="Permalink to this headline">¶</a></h2>
+<div class="admonition warning">
+<p class="first admonition-title">Warning</p>
+<p class="last">These settings might have huge effect on performance or security.</p>
+</div>
+<dl class="option">
+<dt id="cfg_DBG">
+<tt class="descname">$cfg['DBG']</tt><a class="headerlink" href="#cfg_DBG" title="Permalink to this definition">¶</a></dt>
+<dd><table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Type:</th><td class="field-body">array</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Default value:</th><td class="field-body">array(...)</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+<dl class="option">
+<dt id="cfg_DBG_sql">
+<tt class="descname">$cfg['DBG']['sql']</tt><a class="headerlink" href="#cfg_DBG_sql" title="Permalink to this definition">¶</a></dt>
+<dd><table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Type:</th><td class="field-body">boolean</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Default value:</th><td class="field-body">false</td>
+</tr>
+</tbody>
+</table>
+<p>Enable logging queries and execution times to be
+displayed in the bottom of main page (right frame).</p>
+</dd></dl>
+
+<dl class="option">
+<dt id="cfg_Error_Handler_display">
+<tt class="descname">$cfg['Error_Handler']['display']</tt><a class="headerlink" href="#cfg_Error_Handler_display" title="Permalink to this definition">¶</a></dt>
+<dd><table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Type:</th><td class="field-body">boolean</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Default value:</th><td class="field-body">false</td>
+</tr>
+</tbody>
+</table>
+<p>Whether to display errors from PHP or not.</p>
+</dd></dl>
+
+<dl class="option">
+<dt id="cfg_Error_Handler_gather">
+<tt class="descname">$cfg['Error_Handler']['gather']</tt><a class="headerlink" href="#cfg_Error_Handler_gather" title="Permalink to this definition">¶</a></dt>
+<dd><table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Type:</th><td class="field-body">boolean</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Default value:</th><td class="field-body">false</td>
+</tr>
+</tbody>
+</table>
+<p>Whether to gather errors from PHP or not.</p>
+</dd></dl>
+
+</div>
+</div>
+
+
+          </div>
+        </div>
+      </div>
+      <div class="sphinxsidebar">
+        <div class="sphinxsidebarwrapper">
+  <h3><a href="index.html">Table Of Contents</a></h3>
+  <ul>
+<li><a class="reference internal" href="#">Configuration</a><ul>
+<li><a class="reference internal" href="#basic-settings">Basic settings</a></li>
+<li><a class="reference internal" href="#server-connection-settings">Server connection settings</a></li>
+<li><a class="reference internal" href="#generic-settings">Generic settings</a></li>
+<li><a class="reference internal" href="#cookie-authentication-options">Cookie authentication options</a></li>
+<li><a class="reference internal" href="#navigation-panel-setup">Navigation panel setup</a></li>
+<li><a class="reference internal" href="#main-panel">Main panel</a></li>
+<li><a class="reference internal" href="#database-structure">Database structure</a></li>
+<li><a class="reference internal" href="#browse-mode">Browse mode</a></li>
+<li><a class="reference internal" href="#editing-mode">Editing mode</a></li>
+<li><a class="reference internal" href="#export-and-import-settings">Export and import settings</a></li>
+<li><a class="reference internal" href="#tabs-display-settings">Tabs display settings</a></li>
+<li><a class="reference internal" href="#documentation">Documentation</a></li>
+<li><a class="reference internal" href="#languages">Languages</a></li>
+<li><a class="reference internal" href="#web-server-settings">Web server settings</a></li>
+<li><a class="reference internal" href="#theme-settings">Theme settings</a></li>
+<li><a class="reference internal" href="#design-customization">Design customization</a></li>
+<li><a class="reference internal" href="#text-fields">Text fields</a></li>
+<li><a class="reference internal" href="#sql-query-box-settings">SQL query box settings</a></li>
+<li><a class="reference internal" href="#web-server-upload-save-import-directories">Web server upload/save/import directories</a></li>
+<li><a class="reference internal" href="#various-display-setting">Various display setting</a></li>
+<li><a class="reference internal" href="#page-titles">Page titles</a></li>
+<li><a class="reference internal" href="#theme-manager-settings">Theme manager settings</a></li>
+<li><a class="reference internal" href="#default-queries">Default queries</a></li>
+<li><a class="reference internal" href="#sql-parser-settings">SQL parser settings</a></li>
+<li><a class="reference internal" href="#sql-validator-settings">SQL validator settings</a></li>
+<li><a class="reference internal" href="#mysql-settings">MySQL settings</a></li>
+<li><a class="reference internal" href="#developer">Developer</a></li>
+</ul>
+</li>
+</ul>
+
+  <h4>Previous topic</h4>
+  <p class="topless"><a href="setup.html"
+                        title="previous chapter">Installation</a></p>
+  <h4>Next topic</h4>
+  <p class="topless"><a href="user.html"
+                        title="next chapter">User Guide</a></p>
+  <h3>This Page</h3>
+  <ul class="this-page-menu">
+    <li><a href="_sources/config.txt"
+           rel="nofollow">Show Source</a></li>
+  </ul>
+<div id="searchbox" style="display: none">
+  <h3>Quick search</h3>
+    <form class="search" action="search.html" method="get">
+      <input type="text" name="q" />
+      <input type="submit" value="Go" />
+      <input type="hidden" name="check_keywords" value="yes" />
+      <input type="hidden" name="area" value="default" />
+    </form>
+    <p class="searchtip" style="font-size: 90%">
+    Enter search terms or a module, class or function name.
+    </p>
+</div>
+<script type="text/javascript">$('#searchbox').show(0);</script>
+        </div>
+      </div>
+      <div class="clearer"></div>
+    </div>
+    <div class="related">
+      <h3>Navigation</h3>
+      <ul>
+        <li class="right" style="margin-right: 10px">
+          <a href="genindex.html" title="General Index"
+             >index</a></li>
+        <li class="right" >
+          <a href="user.html" title="User Guide"
+             >next</a> |</li>
+        <li class="right" >
+          <a href="setup.html" title="Installation"
+             >previous</a> |</li>
+        <li><a href="index.html">phpMyAdmin 4.0.4 documentation</a> »</li> 
+      </ul>
+    </div>
+    <div class="footer">
+        © <a href="copyright.html">Copyright</a> 2012 - 2013, The phpMyAdmin devel team.
+      Created using <a href="http://sphinx.pocoo.org/">Sphinx</a> 1.1.3.
+    </div>
+  </body>
+</html>
\ No newline at end of file
diff --git a/phpmyadmin/doc/html/copyright.html b/phpmyadmin/doc/html/copyright.html
new file mode 100644
index 0000000..f6a207a
--- /dev/null
+++ b/phpmyadmin/doc/html/copyright.html
@@ -0,0 +1,134 @@
+
+
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+
+
+<html xmlns="http://www.w3.org/1999/xhtml">
+  <head>
+    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+    
+    <title>Copyright — phpMyAdmin 4.0.4 documentation</title>
+    
+    <link rel="stylesheet" href="_static/default.css" type="text/css" />
+    <link rel="stylesheet" href="_static/pygments.css" type="text/css" />
+    
+    <script type="text/javascript">
+      var DOCUMENTATION_OPTIONS = {
+        URL_ROOT:    '',
+        VERSION:     '4.0.4',
+        COLLAPSE_INDEX: false,
+        FILE_SUFFIX: '.html',
+        HAS_SOURCE:  true
+      };
+    </script>
+    <script type="text/javascript" src="_static/jquery.js"></script>
+    <script type="text/javascript" src="_static/underscore.js"></script>
+    <script type="text/javascript" src="_static/doctools.js"></script>
+    <link rel="copyright" title="Copyright" href="#" />
+    <link rel="top" title="phpMyAdmin 4.0.4 documentation" href="index.html" />
+    <link rel="next" title="Credits" href="credits.html" />
+    <link rel="prev" title="Distributing and packaging phpMyAdmin" href="vendors.html" /> 
+  </head>
+  <body>
+    <div class="related">
+      <h3>Navigation</h3>
+      <ul>
+        <li class="right" style="margin-right: 10px">
+          <a href="genindex.html" title="General Index"
+             accesskey="I">index</a></li>
+        <li class="right" >
+          <a href="credits.html" title="Credits"
+             accesskey="N">next</a> |</li>
+        <li class="right" >
+          <a href="vendors.html" title="Distributing and packaging phpMyAdmin"
+             accesskey="P">previous</a> |</li>
+        <li><a href="index.html">phpMyAdmin 4.0.4 documentation</a> »</li> 
+      </ul>
+    </div>  
+
+    <div class="document">
+      <div class="documentwrapper">
+        <div class="bodywrapper">
+          <div class="body">
+            
+  <div class="section" id="copyright">
+<span id="id1"></span><h1>Copyright<a class="headerlink" href="#copyright" title="Permalink to this headline">¶</a></h1>
+<div class="highlight-none"><div class="highlight"><pre>Copyright (C) 1998-2000 Tobias Ratschiller <tobias_at_ratschiller.com>
+Copyright (C) 2001-2013 Marc Delisle <marc_at_infomarc.info>
+    Olivier Müller <om_at_omnis.ch>
+    Robin Johnson <robbat2_at_users.sourceforge.net>
+    Alexander M. Turek <me_at_derrabus.de>
+    Michal Čihař <michal_at_cihar.com>
+    Garvin Hicking <me_at_supergarv.de>
+    Michael Keck <mkkeck_at_users.sourceforge.net>
+    Sebastian Mendel <cybot_tm_at_users.sourceforge.net>
+    [check credits for more details]
+</pre></div>
+</div>
+<p>This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License version 2, as
+published by the Free Software Foundation.</p>
+<p>This program is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.</p>
+<p>You should have received a copy of the GNU General Public License
+along with this program. If not, see <a class="reference external" href="http://www.gnu.org/licenses/">http://www.gnu.org/licenses/</a>.</p>
+</div>
+
+
+          </div>
+        </div>
+      </div>
+      <div class="sphinxsidebar">
+        <div class="sphinxsidebarwrapper">
+  <h4>Previous topic</h4>
+  <p class="topless"><a href="vendors.html"
+                        title="previous chapter">Distributing and packaging phpMyAdmin</a></p>
+  <h4>Next topic</h4>
+  <p class="topless"><a href="credits.html"
+                        title="next chapter">Credits</a></p>
+  <h3>This Page</h3>
+  <ul class="this-page-menu">
+    <li><a href="_sources/copyright.txt"
+           rel="nofollow">Show Source</a></li>
+  </ul>
+<div id="searchbox" style="display: none">
+  <h3>Quick search</h3>
+    <form class="search" action="search.html" method="get">
+      <input type="text" name="q" />
+      <input type="submit" value="Go" />
+      <input type="hidden" name="check_keywords" value="yes" />
+      <input type="hidden" name="area" value="default" />
+    </form>
+    <p class="searchtip" style="font-size: 90%">
+    Enter search terms or a module, class or function name.
+    </p>
+</div>
+<script type="text/javascript">$('#searchbox').show(0);</script>
+        </div>
+      </div>
+      <div class="clearer"></div>
+    </div>
+    <div class="related">
+      <h3>Navigation</h3>
+      <ul>
+        <li class="right" style="margin-right: 10px">
+          <a href="genindex.html" title="General Index"
+             >index</a></li>
+        <li class="right" >
+          <a href="credits.html" title="Credits"
+             >next</a> |</li>
+        <li class="right" >
+          <a href="vendors.html" title="Distributing and packaging phpMyAdmin"
+             >previous</a> |</li>
+        <li><a href="index.html">phpMyAdmin 4.0.4 documentation</a> »</li> 
+      </ul>
+    </div>
+    <div class="footer">
+        © <a href="#">Copyright</a> 2012 - 2013, The phpMyAdmin devel team.
+      Created using <a href="http://sphinx.pocoo.org/">Sphinx</a> 1.1.3.
+    </div>
+  </body>
+</html>
\ No newline at end of file
diff --git a/phpmyadmin/doc/html/credits.html b/phpmyadmin/doc/html/credits.html
new file mode 100644
index 0000000..747dfd9
--- /dev/null
+++ b/phpmyadmin/doc/html/credits.html
@@ -0,0 +1,658 @@
+
+
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+
+
+<html xmlns="http://www.w3.org/1999/xhtml">
+  <head>
+    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+    
+    <title>Credits — phpMyAdmin 4.0.4 documentation</title>
+    
+    <link rel="stylesheet" href="_static/default.css" type="text/css" />
+    <link rel="stylesheet" href="_static/pygments.css" type="text/css" />
+    
+    <script type="text/javascript">
+      var DOCUMENTATION_OPTIONS = {
+        URL_ROOT:    '',
+        VERSION:     '4.0.4',
+        COLLAPSE_INDEX: false,
+        FILE_SUFFIX: '.html',
+        HAS_SOURCE:  true
+      };
+    </script>
+    <script type="text/javascript" src="_static/jquery.js"></script>
+    <script type="text/javascript" src="_static/underscore.js"></script>
+    <script type="text/javascript" src="_static/doctools.js"></script>
+    <link rel="copyright" title="Copyright" href="copyright.html" />
+    <link rel="top" title="phpMyAdmin 4.0.4 documentation" href="index.html" />
+    <link rel="next" title="Glossary" href="glossary.html" />
+    <link rel="prev" title="Copyright" href="copyright.html" /> 
+  </head>
+  <body>
+    <div class="related">
+      <h3>Navigation</h3>
+      <ul>
+        <li class="right" style="margin-right: 10px">
+          <a href="genindex.html" title="General Index"
+             accesskey="I">index</a></li>
+        <li class="right" >
+          <a href="glossary.html" title="Glossary"
+             accesskey="N">next</a> |</li>
+        <li class="right" >
+          <a href="copyright.html" title="Copyright"
+             accesskey="P">previous</a> |</li>
+        <li><a href="index.html">phpMyAdmin 4.0.4 documentation</a> »</li> 
+      </ul>
+    </div>  
+
+    <div class="document">
+      <div class="documentwrapper">
+        <div class="bodywrapper">
+          <div class="body">
+            
+  <div class="section" id="credits">
+<span id="id1"></span><h1>Credits<a class="headerlink" href="#credits" title="Permalink to this headline">¶</a></h1>
+<div class="section" id="credits-in-chronological-order">
+<h2>Credits, in chronological order<a class="headerlink" href="#credits-in-chronological-order" title="Permalink to this headline">¶</a></h2>
+<ul class="simple">
+<li>Tobias Ratschiller <tobias_at_ratschiller.com><ul>
+<li>creator of the phpmyadmin project</li>
+<li>maintainer from 1998 to summer 2000</li>
+</ul>
+</li>
+<li>Marc Delisle <marc_at_infomarc.info><ul>
+<li>multi-language version in December 1998</li>
+<li>various fixes and improvements</li>
+<li><a class="reference internal" href="glossary.html#term-sql"><em class="xref std std-term">SQL</em></a> analyser (most of it)</li>
+<li>current project maintainer</li>
+</ul>
+</li>
+<li>Olivier Müller <om_at_omnis.ch><ul>
+<li>started SourceForge phpMyAdmin project in March 2001</li>
+<li>sync’ed different existing CVS trees with new features and bugfixes</li>
+<li>multi-language improvements, dynamic language selection</li>
+<li>many bugfixes and improvements</li>
+</ul>
+</li>
+<li>Loïc Chapeaux <lolo_at_phpheaven.net><ul>
+<li>rewrote and optimized javascript, DHTML and DOM stuff</li>
+<li>rewrote the scripts so they fit the <a class="reference internal" href="glossary.html#term-pear"><em class="xref std std-term">PEAR</em></a> coding standards and
+generate XHTML1.0 and CSS2 compliant codes</li>
+<li>improved the language detection system</li>
+<li>many bugfixes and improvements</li>
+</ul>
+</li>
+<li>Robin Johnson <robbat2_at_users.sourceforge.net><ul>
+<li>database maintenance controls</li>
+<li>table type code</li>
+<li>Host authentication <a class="reference internal" href="glossary.html#term-ip"><em class="xref std std-term">IP</em></a> Allow/Deny</li>
+<li>DB-based configuration (Not completed)</li>
+<li><a class="reference internal" href="glossary.html#term-sql"><em class="xref std std-term">SQL</em></a> parser and pretty-printer</li>
+<li><a class="reference internal" href="glossary.html#term-sql"><em class="xref std std-term">SQL</em></a> validator</li>
+<li>many bugfixes and improvements</li>
+</ul>
+</li>
+<li>Armel Fauveau <armel.fauveau_at_globalis-ms.com><ul>
+<li>bookmarks feature</li>
+<li>multiple dump feature</li>
+<li>gzip dump feature</li>
+<li>zip dump feature</li>
+</ul>
+</li>
+<li>Geert Lund <glund_at_silversoft.dk><ul>
+<li>various fixes</li>
+<li>moderator of the phpMyAdmin former users forum at phpwizard.net</li>
+</ul>
+</li>
+<li>Korakot Chaovavanich <korakot_at_iname.com><ul>
+<li>“insert as new row” feature</li>
+</ul>
+</li>
+<li>Pete Kelly <webmaster_at_trafficg.com><ul>
+<li>rewrote and fix dump code</li>
+<li>bugfixes</li>
+</ul>
+</li>
+<li>Steve Alberty <alberty_at_neptunlabs.de><ul>
+<li>rewrote dump code for PHP4</li>
+<li>mySQL table statistics</li>
+<li>bugfixes</li>
+</ul>
+</li>
+<li>Benjamin Gandon <gandon_at_isia.cma.fr><ul>
+<li>main author of the version 2.1.0.1</li>
+<li>bugfixes</li>
+</ul>
+</li>
+<li>Alexander M. Turek <me_at_derrabus.de><ul>
+<li>MySQL 4.0 / 4.1 / 5.0 compatibility</li>
+<li>abstract database interface (PMA_DBI) with MySQLi support</li>
+<li>privileges administration</li>
+<li><a class="reference internal" href="glossary.html#term-xml"><em class="xref std std-term">XML</em></a> exports</li>
+<li>various features and fixes</li>
+<li>German language file updates</li>
+</ul>
+</li>
+<li>Mike Beck <mike.beck_at_web.de><ul>
+<li>automatic joins in QBE</li>
+<li>links column in printview</li>
+<li>Relation view</li>
+</ul>
+</li>
+<li>Michal Čihař <michal_at_cihar.com><ul>
+<li>enhanced index creation/display feature</li>
+<li>feature to use a different charset for HTML than for MySQL</li>
+<li>improvements of export feature</li>
+<li>various features and fixes</li>
+<li>Czech language file updates</li>
+</ul>
+</li>
+<li>Christophe Gesché from the “MySQL Form Generator for PHPMyAdmin”
+(<a class="reference external" href="http://sf.net/projects/phpmysqlformgen/">http://sf.net/projects/phpmysqlformgen/</a>)<ul>
+<li>suggested the patch for multiple table printviews</li>
+</ul>
+</li>
+<li>Garvin Hicking <me_at_supergarv.de><ul>
+<li>built the patch for vertical display of table rows</li>
+<li>built the Javascript based Query window + <a class="reference internal" href="glossary.html#term-sql"><em class="xref std std-term">SQL</em></a> history</li>
+<li>Improvement of column/db comments</li>
+<li>(MIME)-Transformations for columns</li>
+<li>Use custom alias names for Databases in left frame</li>
+<li>hierarchical/nested table display</li>
+<li><a class="reference internal" href="glossary.html#term-pdf"><em class="xref std std-term">PDF</em></a>-scratchboard for WYSIWYG-
+distribution of <a class="reference internal" href="glossary.html#term-pdf"><em class="xref std std-term">PDF</em></a> relations</li>
+<li>new icon sets</li>
+<li>vertical display of column properties page</li>
+<li>some bugfixes, features, support, German language additions</li>
+</ul>
+</li>
+<li>Yukihiro Kawada <kawada_at_den.fujifilm.co.jp><ul>
+<li>japanese kanji encoding conversion feature</li>
+</ul>
+</li>
+<li>Piotr Roszatycki <d3xter_at_users.sourceforge.net> and Dan Wilson<ul>
+<li>the Cookie authentication mode</li>
+</ul>
+</li>
+<li>Axel Sander <n8falke_at_users.sourceforge.net><ul>
+<li>table relation-links feature</li>
+</ul>
+</li>
+<li>Maxime Delorme <delorme.maxime_at_free.fr><ul>
+<li><a class="reference internal" href="glossary.html#term-pdf"><em class="xref std std-term">PDF</em></a> schema output, thanks also to
+Olivier Plathey for the “FPDF” library (see <<a class="reference external" href="http://www.fpdf.org/">http://www.fpdf.org/</a>>), Steven
+Wittens for the “UFPDF” library (see <<a class="reference external" href="http://www.acko.net/node/56">http://www.acko.net/node/56</a>>) and
+Nicola Asuni for the “TCPDF” library (see <<a class="reference external" href="http://www.tcpdf.org/">http://www.tcpdf.org/</a>>).</li>
+</ul>
+</li>
+<li>Olof Edlund <olof.edlund_at_upright.se><ul>
+<li><a class="reference internal" href="glossary.html#term-sql"><em class="xref std std-term">SQL</em></a> validator server</li>
+</ul>
+</li>
+<li>Ivan R. Lanin <ivanlanin_at_users.sourceforge.net><ul>
+<li>phpMyAdmin logo (until June 2004)</li>
+</ul>
+</li>
+<li>Mike Cochrane <mike_at_graftonhall.co.nz><ul>
+<li>blowfish library from the Horde project (withdrawn in release 4.0)</li>
+</ul>
+</li>
+<li>Marcel Tschopp <ne0x_at_users.sourceforge.net><ul>
+<li>mysqli support</li>
+<li>many bugfixes and improvements</li>
+</ul>
+</li>
+<li>Nicola Asuni (Tecnick.com)<ul>
+<li>TCPDF library (<a class="reference external" href="http://www.tcpdf.org">http://www.tcpdf.org</a>)</li>
+</ul>
+</li>
+<li>Michael Keck <mkkeck_at_users.sourceforge.net><ul>
+<li>redesign for 2.6.0</li>
+<li>phpMyAdmin sailboat logo (June 2004)</li>
+</ul>
+</li>
+<li>Mathias Landhäußer<ul>
+<li>Representation at conferences</li>
+</ul>
+</li>
+<li>Sebastian Mendel <cybot_tm_at_users.sourceforge.net><ul>
+<li>interface improvements</li>
+<li>various bugfixes</li>
+</ul>
+</li>
+<li>Ivan A Kirillov<ul>
+<li>new relations Designer</li>
+</ul>
+</li>
+<li>Raj Kissu Rajandran (Google Summer of Code 2008)<ul>
+<li>BLOBstreaming support (withdrawn in release 4.0)</li>
+</ul>
+</li>
+<li>Piotr Przybylski (Google Summer of Code 2008, 2010 and 2011)<ul>
+<li>improved setup script</li>
+<li>user preferences</li>
+<li>Drizzle support</li>
+</ul>
+</li>
+<li>Derek Schaefer (Google Summer of Code 2009)<ul>
+<li>Improved the import system</li>
+</ul>
+</li>
+<li>Alexander Rutkowski (Google Summer of Code 2009)<ul>
+<li>Tracking mechanism</li>
+</ul>
+</li>
+<li>Zahra Naeem (Google Summer of Code 2009)<ul>
+<li>Synchronization feature (removed in release 4.0)</li>
+</ul>
+</li>
+<li>Tomáš Srnka (Google Summer of Code 2009)<ul>
+<li>Replication support</li>
+</ul>
+</li>
+<li>Muhammad Adnan (Google Summer of Code 2010)<ul>
+<li>Relation schema export to multiple formats</li>
+</ul>
+</li>
+<li>Lori Lee (Google Summer of Code 2010)<ul>
+<li>User interface improvements</li>
+<li>ENUM/SET editor</li>
+<li>Simplified interface for export/import</li>
+</ul>
+</li>
+<li>Ninad Pundalik (Google Summer of Code 2010)<ul>
+<li>AJAXifying the interface</li>
+</ul>
+</li>
+<li>Martynas Mickevičius (Google Summer of Code 2010)<ul>
+<li>Charts</li>
+</ul>
+</li>
+<li>Barrie Leslie<ul>
+<li>BLOBstreaming support with PBMS PHP extension (withdrawn in release
+4.0)</li>
+</ul>
+</li>
+<li>Ankit Gupta (Google Summer of Code 2010)<ul>
+<li>Visual query builder</li>
+</ul>
+</li>
+<li>Madhura Jayaratne (Google Summer of Code 2011)<ul>
+<li>OpenGIS support</li>
+</ul>
+</li>
+<li>Ammar Yasir (Google Summer of Code 2011)<ul>
+<li>Zoom search</li>
+</ul>
+</li>
+<li>Aris Feryanto (Google Summer of Code 2011)<ul>
+<li>Browse-mode improvements</li>
+</ul>
+</li>
+<li>Thilanka Kaushalya (Google Summer of Code 2011)<ul>
+<li>AJAXification</li>
+</ul>
+</li>
+<li>Tyron Madlener (Google Summer of Code 2011)<ul>
+<li>Query statistics and charts for the status page</li>
+</ul>
+</li>
+<li>Zarubin Stas (Google Summer of Code 2011)<ul>
+<li>Automated testing</li>
+</ul>
+</li>
+<li>Rouslan Placella (Google Summer of Code 2011 and 2012)<ul>
+<li>Improved support for Stored Routines, Triggers and Events</li>
+<li>Italian translation updates</li>
+<li>Removal of frames, new navigation</li>
+</ul>
+</li>
+<li>Dieter Adriaenssens<ul>
+<li>Various bugfixes</li>
+<li>Dutch translation updates</li>
+</ul>
+</li>
+<li>Alex Marin (Google Summer of Code 2012)<ul>
+<li>New plugins and properties system</li>
+</ul>
+</li>
+<li>Thilina Buddika Abeyrathna (Google Summer of Code 2012)<ul>
+<li>Refactoring</li>
+</ul>
+</li>
+<li>Atul Pratap Singh  (Google Summer of Code 2012)<ul>
+<li>Refactoring</li>
+</ul>
+</li>
+<li>Chanaka Indrajith (Google Summer of Code 2012)<ul>
+<li>Refactoring</li>
+</ul>
+</li>
+<li>Yasitha Pandithawatta (Google Summer of Code 2012)<ul>
+<li>Automated testing</li>
+</ul>
+</li>
+<li>Jim Wigginton (phpseclib.sourceforge.net)<ul>
+<li>phpseclib</li>
+</ul>
+</li>
+</ul>
+<p>And also to the following people who have contributed minor changes,
+enhancements, bugfixes or support for a new language since version
+2.1.0:</p>
+<p>Bora Alioglu, Ricardo ?, Sven-Erik Andersen, Alessandro Astarita,
+Péter Bakondy, Borges Botelho, Olivier Bussier, Neil Darlow, Mats
+Engstrom, Ian Davidson, Laurent Dhima, Kristof Hamann, Thomas Kläger,
+Lubos Klokner, Martin Marconcini, Girish Nair, David Nordenberg,
+Andreas Pauley, Bernard M. Piller, Laurent Haas, “Sakamoto”, Yuval
+Sarna, www.securereality.com.au, Alexis Soulard, Alvar Soome, Siu Sun,
+Peter Svec, Michael Tacelosky, Rachim Tamsjadi, Kositer Uros, Luís V.,
+Martijn W. van der Lee, Algis Vainauskas, Daniel Villanueva, Vinay,
+Ignacio Vazquez-Abrams, Chee Wai, Jakub Wilk, Thomas Michael
+Winningham, Vilius Zigmantas, “Manuzhai”.</p>
+</div>
+<div class="section" id="translators">
+<h2>Translators<a class="headerlink" href="#translators" title="Permalink to this headline">¶</a></h2>
+<p>Following people have contributed to translation of phpMyAdmin:</p>
+<ul class="simple">
+<li>Arabic<ul>
+<li>Abdullah Al-Saedi <abdullah.10_at_windowslive.com></li>
+</ul>
+</li>
+<li>Bulgarian<ul>
+<li>stoyanster <stoyanster_at_gmail.com></li>
+</ul>
+</li>
+<li>Catalan<ul>
+<li>Xavier Navarro <xvnavarro_at_gmail.com></li>
+</ul>
+</li>
+<li>Czech<ul>
+<li>Michal Čihař <michal_at_cihar.com></li>
+</ul>
+</li>
+<li>Danish<ul>
+<li>opensource <opensource_at_jth.net></li>
+<li>Jørgen Thomsen <opensource_at_jth.net></li>
+</ul>
+</li>
+<li>German<ul>
+<li>mrbendig <mrbendig_at_mrbendig.com></li>
+<li>torsten.funck <torsten.funck_at_googlemail.com></li>
+<li>Sven Strickroth <email_at_cs-ware.de></li>
+<li>typo3 <typo3_at_dirk-weise.de></li>
+<li>Jo Michael <me_at_mynetx.net></li>
+</ul>
+</li>
+<li>Greek<ul>
+<li>Panagiotis Papazoglou <papaz_p_at_yahoo.com></li>
+</ul>
+</li>
+<li>English (United Kingdom)<ul>
+<li>Robert Readman <robert_readman_at_hotmail.com></li>
+</ul>
+</li>
+<li>Spanish<ul>
+<li>Matías Bellone <matiasbellone_at_gmail.com></li>
+</ul>
+</li>
+<li>French<ul>
+<li>Marc Delisle <marc_at_infomarc.info></li>
+</ul>
+</li>
+<li>Hindi<ul>
+<li>u4663530 <u4663530_at_anu.edu.au></li>
+<li>rsedwardian <rsedwardian_at_gmail.com></li>
+</ul>
+</li>
+<li>Hungarian<ul>
+<li>gergo314 <gergo314_at_gmail.com></li>
+</ul>
+</li>
+<li>Italian<ul>
+<li>Rouslan Placella <rouslan_at_placella.com></li>
+</ul>
+</li>
+<li>Japanese<ul>
+<li>Yuichiro <yuichiro_at_pop07.odn.ne.jp></li>
+</ul>
+</li>
+<li>Lithuanian<ul>
+<li>Kęstutis <forkik_at_gmail.com></li>
+</ul>
+</li>
+<li>Norwegian Bokmål<ul>
+<li>Sven-Erik Andersen <sven.erik.andersen_at_gmail.com></li>
+</ul>
+</li>
+<li>Dutch<ul>
+<li>Dieter Adriaenssens <ruleant_at_users.sourceforge.net></li>
+<li>Herman van Rink <rink_at_initfour.nl></li>
+</ul>
+</li>
+<li>Polish<ul>
+<li>Stanisław Krukowski <stankruk_at_neostrada.pl></li>
+<li>Marcin Kozioł <lord_dark_at_wp.pl></li>
+</ul>
+</li>
+<li>Portuguese<ul>
+<li>JoaoTMDias <contacto_at_joaodias.me></li>
+</ul>
+</li>
+<li>Portuguese (Brazil)<ul>
+<li>wiltave <wiltave_at_gmail.com></li>
+<li>emerson4br <emerson4br_at_gmail.com></li>
+</ul>
+</li>
+<li>Romanian<ul>
+<li>alexukf <alex.ukf_at_gmail.com></li>
+</ul>
+</li>
+<li>Russian<ul>
+<li>Victor Volkov <hanut_at_php-myadmin.ru></li>
+</ul>
+</li>
+<li>Sinhala<ul>
+<li>Madhura Jayaratne <madhura.cj_at_gmail.com></li>
+</ul>
+</li>
+<li>Slovak<ul>
+<li>Martin Lacina <martin_at_whistler.sk></li>
+</ul>
+</li>
+<li>Slovenian<ul>
+<li>Domen <dbc334_at_gmail.com></li>
+</ul>
+</li>
+<li>Swedish<ul>
+<li>stefan <stefan_at_inkopsforum.se></li>
+</ul>
+</li>
+<li>Tamil<ul>
+<li>ysajeepan <ysajeepan_at_live.com></li>
+</ul>
+</li>
+<li>Telugu<ul>
+<li>veeven <veeven_at_gmail.com></li>
+</ul>
+</li>
+<li>Thai<ul>
+<li>kanitchet <kanichet_at_hotmail.com></li>
+</ul>
+</li>
+<li>Turkish<ul>
+<li>Burak Yavuz <hitowerdigit_at_hotmail.com></li>
+</ul>
+</li>
+<li>Uighur<ul>
+<li>gheni <gheni_at_yahoo.cn></li>
+</ul>
+</li>
+<li>Ukrainian<ul>
+<li>typim <duke3d_at_ukr.net></li>
+<li>oleg-ilnytskyi <ukraine.oleg_at_gmail.com></li>
+</ul>
+</li>
+<li>Urdu<ul>
+<li>Mehbooob Khan <mehboobbugti_at_gmail.com></li>
+</ul>
+</li>
+<li>Simplified Chinese<ul>
+<li>shanyan baishui <Siramizu_at_gmail.com></li>
+</ul>
+</li>
+<li>Traditional Chinese<ul>
+<li>star <star_at_origin.club.tw></li>
+</ul>
+</li>
+</ul>
+</div>
+<div class="section" id="documentation-translators">
+<h2>Documentation translators<a class="headerlink" href="#documentation-translators" title="Permalink to this headline">¶</a></h2>
+<p>Following people have contributed to translation of phpMyAdmin documentation:</p>
+<ul class="simple">
+<li>Czech<ul>
+<li>Michal Čihař <michal_at_cihar.com></li>
+</ul>
+</li>
+<li>Greek<ul>
+<li>Panagiotis Papazoglou <papaz_p_at_yahoo.com></li>
+</ul>
+</li>
+<li>English (United Kingdom)<ul>
+<li>Robert Readman <robert_readman_at_hotmail.com></li>
+</ul>
+</li>
+<li>French<ul>
+<li>Cédric Corazza <cedric.corazza_at_wanadoo.fr></li>
+</ul>
+</li>
+<li>Japanese<ul>
+<li>Yuichiro Takahashi <yuichiro_at_pop07.odn.ne.jp></li>
+</ul>
+</li>
+<li>Polish<ul>
+<li>Stanisław Krukowski <stankruk_at_neostrada.pl></li>
+</ul>
+</li>
+<li>Portuguese (Brazil)<ul>
+<li>mjaning <mjaning_at_gmail.com></li>
+</ul>
+</li>
+<li>Slovenian<ul>
+<li>Domen <dbc334_at_gmail.com></li>
+</ul>
+</li>
+</ul>
+</div>
+<div class="section" id="original-credits-of-version-2-1-0">
+<h2>Original Credits of Version 2.1.0<a class="headerlink" href="#original-credits-of-version-2-1-0" title="Permalink to this headline">¶</a></h2>
+<p>This work is based on Peter Kuppelwieser’s MySQL-Webadmin. It was his
+idea to create a web-based interface to MySQL using PHP3. Although I
+have not used any of his source-code, there are some concepts I’ve
+borrowed from him. phpMyAdmin was created because Peter told me he
+wasn’t going to further develop his (great) tool.</p>
+<p>Thanks go to</p>
+<ul class="simple">
+<li>Amalesh Kempf <ak-lsml_at_living-source.com> who contributed the
+code for the check when dropping a table or database. He also
+suggested that you should be able to specify the primary key on
+tbl_create.php3. To version 1.1.1 he contributed the ldi_*.php3-set
+(Import text-files) as well as a bug-report. Plus many smaller
+improvements.</li>
+<li>Jan Legenhausen <jan_at_nrw.net>: He made many of the changes that
+were introduced in 1.3.0 (including quite significant ones like the
+authentication). For 1.4.1 he enhanced the table-dump feature. Plus
+bug-fixes and help.</li>
+<li>Marc Delisle <DelislMa_at_CollegeSherbrooke.qc.ca> made phpMyAdmin
+language-independent by outsourcing the strings to a separate file. He
+also contributed the French translation.</li>
+<li>Alexandr Bravo <abravo_at_hq.admiral.ru> who contributed
+tbl_select.php3, a feature to display only some columns from a table.</li>
+<li>Chris Jackson <chrisj_at_ctel.net> added support for MySQL functions
+in tbl_change.php3. He also added the “Query by Example” feature in
+2.0.</li>
+<li>Dave Walton <walton_at_nordicdms.com> added support for multiple
+servers and is a regular contributor for bug-fixes.</li>
+<li>Gabriel Ash <ga244_at_is8.nyu.edu> contributed the random access
+features for 2.0.6.</li>
+</ul>
+<p>The following people have contributed minor changes, enhancements,
+bugfixes or support for a new language:</p>
+<p>Jim Kraai, Jordi Bruguera, Miquel Obrador, Geert Lund, Thomas
+Kleemann, Alexander Leidinger, Kiko Albiol, Daniel C. Chao, Pavel
+Piankov, Sascha Kettler, Joe Pruett, Renato Lins, Mark Kronsbein,
+Jannis Hermanns, G. Wieggers.</p>
+<p>And thanks to everyone else who sent me email with suggestions, bug-
+reports and or just some feedback.</p>
+</div>
+</div>
+
+
+          </div>
+        </div>
+      </div>
+      <div class="sphinxsidebar">
+        <div class="sphinxsidebarwrapper">
+  <h3><a href="index.html">Table Of Contents</a></h3>
+  <ul>
+<li><a class="reference internal" href="#">Credits</a><ul>
+<li><a class="reference internal" href="#credits-in-chronological-order">Credits, in chronological order</a></li>
+<li><a class="reference internal" href="#translators">Translators</a></li>
+<li><a class="reference internal" href="#documentation-translators">Documentation translators</a></li>
+<li><a class="reference internal" href="#original-credits-of-version-2-1-0">Original Credits of Version 2.1.0</a></li>
+</ul>
+</li>
+</ul>
+
+  <h4>Previous topic</h4>
+  <p class="topless"><a href="copyright.html"
+                        title="previous chapter">Copyright</a></p>
+  <h4>Next topic</h4>
+  <p class="topless"><a href="glossary.html"
+                        title="next chapter">Glossary</a></p>
+  <h3>This Page</h3>
+  <ul class="this-page-menu">
+    <li><a href="_sources/credits.txt"
+           rel="nofollow">Show Source</a></li>
+  </ul>
+<div id="searchbox" style="display: none">
+  <h3>Quick search</h3>
+    <form class="search" action="search.html" method="get">
+      <input type="text" name="q" />
+      <input type="submit" value="Go" />
+      <input type="hidden" name="check_keywords" value="yes" />
+      <input type="hidden" name="area" value="default" />
+    </form>
+    <p class="searchtip" style="font-size: 90%">
+    Enter search terms or a module, class or function name.
+    </p>
+</div>
+<script type="text/javascript">$('#searchbox').show(0);</script>
+        </div>
+      </div>
+      <div class="clearer"></div>
+    </div>
+    <div class="related">
+      <h3>Navigation</h3>
+      <ul>
+        <li class="right" style="margin-right: 10px">
+          <a href="genindex.html" title="General Index"
+             >index</a></li>
+        <li class="right" >
+          <a href="glossary.html" title="Glossary"
+             >next</a> |</li>
+        <li class="right" >
+          <a href="copyright.html" title="Copyright"
+             >previous</a> |</li>
+        <li><a href="index.html">phpMyAdmin 4.0.4 documentation</a> »</li> 
+      </ul>
+    </div>
+    <div class="footer">
+        © <a href="copyright.html">Copyright</a> 2012 - 2013, The phpMyAdmin devel team.
+      Created using <a href="http://sphinx.pocoo.org/">Sphinx</a> 1.1.3.
+    </div>
+  </body>
+</html>
\ No newline at end of file
diff --git a/phpmyadmin/doc/html/developers.html b/phpmyadmin/doc/html/developers.html
new file mode 100644
index 0000000..d1789e6
--- /dev/null
+++ b/phpmyadmin/doc/html/developers.html
@@ -0,0 +1,118 @@
+
+
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+
+
+<html xmlns="http://www.w3.org/1999/xhtml">
+  <head>
+    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+    
+    <title>Developers Information — phpMyAdmin 4.0.4 documentation</title>
+    
+    <link rel="stylesheet" href="_static/default.css" type="text/css" />
+    <link rel="stylesheet" href="_static/pygments.css" type="text/css" />
+    
+    <script type="text/javascript">
+      var DOCUMENTATION_OPTIONS = {
+        URL_ROOT:    '',
+        VERSION:     '4.0.4',
+        COLLAPSE_INDEX: false,
+        FILE_SUFFIX: '.html',
+        HAS_SOURCE:  true
+      };
+    </script>
+    <script type="text/javascript" src="_static/jquery.js"></script>
+    <script type="text/javascript" src="_static/underscore.js"></script>
+    <script type="text/javascript" src="_static/doctools.js"></script>
+    <link rel="copyright" title="Copyright" href="copyright.html" />
+    <link rel="top" title="phpMyAdmin 4.0.4 documentation" href="index.html" />
+    <link rel="next" title="Distributing and packaging phpMyAdmin" href="vendors.html" />
+    <link rel="prev" title="FAQ - Frequently Asked Questions" href="faq.html" /> 
+  </head>
+  <body>
+    <div class="related">
+      <h3>Navigation</h3>
+      <ul>
+        <li class="right" style="margin-right: 10px">
+          <a href="genindex.html" title="General Index"
+             accesskey="I">index</a></li>
+        <li class="right" >
+          <a href="vendors.html" title="Distributing and packaging phpMyAdmin"
+             accesskey="N">next</a> |</li>
+        <li class="right" >
+          <a href="faq.html" title="FAQ - Frequently Asked Questions"
+             accesskey="P">previous</a> |</li>
+        <li><a href="index.html">phpMyAdmin 4.0.4 documentation</a> »</li> 
+      </ul>
+    </div>  
+
+    <div class="document">
+      <div class="documentwrapper">
+        <div class="bodywrapper">
+          <div class="body">
+            
+  <div class="section" id="developers-information">
+<span id="developers"></span><h1>Developers Information<a class="headerlink" href="#developers-information" title="Permalink to this headline">¶</a></h1>
+<p>phpMyAdmin is Open Source, so you’re invited to contribute to it. Many
+great features have been written by other people and you too can help
+to make phpMyAdmin a useful tool.</p>
+<p>You can check out all the possibilities to contribute in the
+<a class="reference external" href="http://www.phpmyadmin.net/home_page/improve.php">contribute section on our website</a>.</p>
+</div>
+
+
+          </div>
+        </div>
+      </div>
+      <div class="sphinxsidebar">
+        <div class="sphinxsidebarwrapper">
+  <h4>Previous topic</h4>
+  <p class="topless"><a href="faq.html"
+                        title="previous chapter">FAQ - Frequently Asked Questions</a></p>
+  <h4>Next topic</h4>
+  <p class="topless"><a href="vendors.html"
+                        title="next chapter">Distributing and packaging phpMyAdmin</a></p>
+  <h3>This Page</h3>
+  <ul class="this-page-menu">
+    <li><a href="_sources/developers.txt"
+           rel="nofollow">Show Source</a></li>
+  </ul>
+<div id="searchbox" style="display: none">
+  <h3>Quick search</h3>
+    <form class="search" action="search.html" method="get">
+      <input type="text" name="q" />
+      <input type="submit" value="Go" />
+      <input type="hidden" name="check_keywords" value="yes" />
+      <input type="hidden" name="area" value="default" />
+    </form>
+    <p class="searchtip" style="font-size: 90%">
+    Enter search terms or a module, class or function name.
+    </p>
+</div>
+<script type="text/javascript">$('#searchbox').show(0);</script>
+        </div>
+      </div>
+      <div class="clearer"></div>
+    </div>
+    <div class="related">
+      <h3>Navigation</h3>
+      <ul>
+        <li class="right" style="margin-right: 10px">
+          <a href="genindex.html" title="General Index"
+             >index</a></li>
+        <li class="right" >
+          <a href="vendors.html" title="Distributing and packaging phpMyAdmin"
+             >next</a> |</li>
+        <li class="right" >
+          <a href="faq.html" title="FAQ - Frequently Asked Questions"
+             >previous</a> |</li>
+        <li><a href="index.html">phpMyAdmin 4.0.4 documentation</a> »</li> 
+      </ul>
+    </div>
+    <div class="footer">
+        © <a href="copyright.html">Copyright</a> 2012 - 2013, The phpMyAdmin devel team.
+      Created using <a href="http://sphinx.pocoo.org/">Sphinx</a> 1.1.3.
+    </div>
+  </body>
+</html>
\ No newline at end of file
diff --git a/phpmyadmin/doc/html/faq.html b/phpmyadmin/doc/html/faq.html
new file mode 100644
index 0000000..f3ecca5
--- /dev/null
+++ b/phpmyadmin/doc/html/faq.html
@@ -0,0 +1,1780 @@
+
+
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+
+
+<html xmlns="http://www.w3.org/1999/xhtml">
+  <head>
+    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+    
+    <title>FAQ - Frequently Asked Questions — phpMyAdmin 4.0.4 documentation</title>
+    
+    <link rel="stylesheet" href="_static/default.css" type="text/css" />
+    <link rel="stylesheet" href="_static/pygments.css" type="text/css" />
+    
+    <script type="text/javascript">
+      var DOCUMENTATION_OPTIONS = {
+        URL_ROOT:    '',
+        VERSION:     '4.0.4',
+        COLLAPSE_INDEX: false,
+        FILE_SUFFIX: '.html',
+        HAS_SOURCE:  true
+      };
+    </script>
+    <script type="text/javascript" src="_static/jquery.js"></script>
+    <script type="text/javascript" src="_static/underscore.js"></script>
+    <script type="text/javascript" src="_static/doctools.js"></script>
+    <link rel="copyright" title="Copyright" href="copyright.html" />
+    <link rel="top" title="phpMyAdmin 4.0.4 documentation" href="index.html" />
+    <link rel="next" title="Developers Information" href="developers.html" />
+    <link rel="prev" title="Other sources of information" href="other.html" /> 
+  </head>
+  <body>
+    <div class="related">
+      <h3>Navigation</h3>
+      <ul>
+        <li class="right" style="margin-right: 10px">
+          <a href="genindex.html" title="General Index"
+             accesskey="I">index</a></li>
+        <li class="right" >
+          <a href="developers.html" title="Developers Information"
+             accesskey="N">next</a> |</li>
+        <li class="right" >
+          <a href="other.html" title="Other sources of information"
+             accesskey="P">previous</a> |</li>
+        <li><a href="index.html">phpMyAdmin 4.0.4 documentation</a> »</li> 
+      </ul>
+    </div>  
+
+    <div class="document">
+      <div class="documentwrapper">
+        <div class="bodywrapper">
+          <div class="body">
+            
+  <div class="section" id="faq-frequently-asked-questions">
+<span id="faq"></span><h1>FAQ - Frequently Asked Questions<a class="headerlink" href="#faq-frequently-asked-questions" title="Permalink to this headline">¶</a></h1>
+<p>Please have a look at our <a class="reference external" href="http://www.phpmyadmin.net/home_page/docs.php">Link section</a> on the official
+phpMyAdmin homepage for in-depth coverage of phpMyAdmin’s features and
+or interface.</p>
+<div class="section" id="server">
+<span id="faqserver"></span><h2>Server<a class="headerlink" href="#server" title="Permalink to this headline">¶</a></h2>
+<div class="section" id="my-server-is-crashing-each-time-a-specific-action-is-required-or-phpmyadmin-sends-a-blank-page-or-a-page-full-of-cryptic-characters-to-my-browser-what-can-i-do">
+<span id="faq1-1"></span><h3>1.1 My server is crashing each time a specific action is required or phpMyAdmin sends a blank page or a page full of cryptic characters to my browser, what can I do?<a class="headerlink" href="#my-server-is-crashing-each-time-a-specific-action-is-required-or-phpmyadmin-sends-a-blank-page-or-a-page-full-of-cryptic-characters-to-my-browser-what-can-i-do" title="Permalink to this headline">¶</a></h3>
+<p>Try to set the <span class="target" id="index-0"></span><a class="reference internal" href="config.html#cfg_OBGzip"><tt class="xref config config-option docutils literal"><span class="pre">$cfg['OBGzip']</span></tt></a>  directive to <tt class="docutils literal"><span class="pre">false</span></tt> in your
+<tt class="file docutils literal"><span class="pre">config.inc.php</span></tt> file and the <tt class="docutils literal"><span class="pre">zlib.output_compression</span></tt> directive to
+<tt class="docutils literal"><span class="pre">Off</span></tt> in your php configuration file.</p>
+</div>
+<div class="section" id="my-apache-server-crashes-when-using-phpmyadmin">
+<span id="faq1-2"></span><h3>1.2 My Apache server crashes when using phpMyAdmin.<a class="headerlink" href="#my-apache-server-crashes-when-using-phpmyadmin" title="Permalink to this headline">¶</a></h3>
+<p>You should first try the latest versions of Apache (and possibly MySQL). If
+your server keeps crashing, please ask for help in the various Apache support
+groups.</p>
+<div class="admonition-see-also admonition seealso">
+<p class="first admonition-title">See also</p>
+<p class="last"><a class="reference internal" href="#faq1-1"><em>1.1 My server is crashing each time a specific action is required or phpMyAdmin sends a blank page or a page full of cryptic characters to my browser, what can I do?</em></a></p>
+</div>
+</div>
+<div class="section" id="withdrawn">
+<span id="faq1-3"></span><h3>1.3 (withdrawn).<a class="headerlink" href="#withdrawn" title="Permalink to this headline">¶</a></h3>
+</div>
+<div class="section" id="using-phpmyadmin-on-iis-i-m-displayed-the-error-message-the-specified-cgi-application-misbehaved-by-not-returning-a-complete-set-of-http-headers">
+<span id="faq1-4"></span><h3>1.4 Using phpMyAdmin on IIS, I’m displayed the error message: “The specified CGI application misbehaved by not returning a complete set of HTTP headers ...”.<a class="headerlink" href="#using-phpmyadmin-on-iis-i-m-displayed-the-error-message-the-specified-cgi-application-misbehaved-by-not-returning-a-complete-set-of-http-headers" title="Permalink to this headline">¶</a></h3>
+<p>You just forgot to read the <em>install.txt</em> file from the PHP
+distribution. Have a look at the last message in this <a class="reference external" href="http://bugs.php.net/bug.php?id=12061">PHP bug report #12061</a> from the official PHP bug
+database.</p>
+</div>
+<div class="section" id="using-phpmyadmin-on-iis-i-m-facing-crashes-and-or-many-error-messages-with-the-http">
+<span id="faq1-5"></span><h3>1.5 Using phpMyAdmin on IIS, I’m facing crashes and/or many error messages with the HTTP.<a class="headerlink" href="#using-phpmyadmin-on-iis-i-m-facing-crashes-and-or-many-error-messages-with-the-http" title="Permalink to this headline">¶</a></h3>
+<p>This is a known problem with the PHP <a class="reference internal" href="glossary.html#term-isapi"><em class="xref std std-term">ISAPI</em></a> filter: it’s not so stable.
+Please use instead the cookie authentication mode.</p>
+</div>
+<div class="section" id="i-can-t-use-phpmyadmin-on-pws-nothing-is-displayed">
+<span id="faq1-6"></span><h3>1.6 I can’t use phpMyAdmin on PWS: nothing is displayed!<a class="headerlink" href="#i-can-t-use-phpmyadmin-on-pws-nothing-is-displayed" title="Permalink to this headline">¶</a></h3>
+<p>This seems to be a PWS bug. Filippo Simoncini found a workaround (at
+this time there is no better fix): remove or comment the <tt class="docutils literal"><span class="pre">DOCTYPE</span></tt>
+declarations (2 lines) from the scripts <tt class="file docutils literal"><span class="pre">libraries/Header.class.php</span></tt>
+and <tt class="file docutils literal"><span class="pre">index.php</span></tt>.</p>
+</div>
+<div class="section" id="how-can-i-gzip-or-bzip-a-dump-or-a-csv-export-it-does-not-seem-to-work">
+<span id="faq1-7"></span><h3>1.7 How can I GZip or Bzip a dump or a CSV export? It does not seem to work.<a class="headerlink" href="#how-can-i-gzip-or-bzip-a-dump-or-a-csv-export-it-does-not-seem-to-work" title="Permalink to this headline">¶</a></h3>
+<p>These features are based on the <tt class="docutils literal"><span class="pre">gzencode()</span></tt> and <tt class="docutils literal"><span class="pre">bzcompress()</span></tt>
+PHP functions to be more independent of the platform (Unix/Windows,
+Safe Mode or not, and so on). So, you must have Zlib/Bzip2 support
+(<tt class="docutils literal"><span class="pre">--with-zlib</span></tt> and <tt class="docutils literal"><span class="pre">--with-bz2</span></tt>).</p>
+</div>
+<div class="section" id="i-cannot-insert-a-text-file-in-a-table-and-i-get-an-error-about-safe-mode-being-in-effect">
+<span id="faq1-8"></span><h3>1.8 I cannot insert a text file in a table, and I get an error about safe mode being in effect.<a class="headerlink" href="#i-cannot-insert-a-text-file-in-a-table-and-i-get-an-error-about-safe-mode-being-in-effect" title="Permalink to this headline">¶</a></h3>
+<p>Your uploaded file is saved by PHP in the “upload dir”, as defined in
+<tt class="file docutils literal"><span class="pre">php.ini</span></tt> by the variable <tt class="docutils literal"><span class="pre">upload_tmp_dir</span></tt> (usually the system
+default is <em>/tmp</em>). We recommend the following setup for Apache
+servers running in safe mode, to enable uploads of files while being
+reasonably secure:</p>
+<ul class="simple">
+<li>create a separate directory for uploads: <strong class="command">mkdir /tmp/php</strong></li>
+<li>give ownership to the Apache server’s user.group: <strong class="command">chown
+apache.apache /tmp/php</strong></li>
+<li>give proper permission: <strong class="command">chmod 600 /tmp/php</strong></li>
+<li>put <tt class="docutils literal"><span class="pre">upload_tmp_dir</span> <span class="pre">=</span> <span class="pre">/tmp/php</span></tt> in <tt class="file docutils literal"><span class="pre">php.ini</span></tt></li>
+<li>restart Apache</li>
+</ul>
+</div>
+<div class="section" id="faq1-9">
+<span id="id1"></span><h3>1.9 (withdrawn).<a class="headerlink" href="#faq1-9" title="Permalink to this headline">¶</a></h3>
+</div>
+<div class="section" id="i-m-having-troubles-when-uploading-files-with-phpmyadmin-running-on-a-secure-server-my-browser-is-internet-explorer-and-i-m-using-the-apache-server">
+<span id="faq1-10"></span><h3>1.10 I’m having troubles when uploading files with phpMyAdmin running on a secure server. My browser is Internet Explorer and I’m using the Apache server.<a class="headerlink" href="#i-m-having-troubles-when-uploading-files-with-phpmyadmin-running-on-a-secure-server-my-browser-is-internet-explorer-and-i-m-using-the-apache-server" title="Permalink to this headline">¶</a></h3>
+<p>As suggested by “Rob M” in the phpWizard forum, add this line to your
+<em>httpd.conf</em>:</p>
+<div class="highlight-apache"><div class="highlight"><pre><span class="nb">SetEnvIf</span> <span class="k">User</span>-Agent <span class="s2">".*MSIE.*"</span> nokeepalive ssl-unclean-shutdown
+</pre></div>
+</div>
+<p>It seems to clear up many problems between Internet Explorer and SSL.</p>
+</div>
+<div class="section" id="i-get-an-open-basedir-restriction-while-uploading-a-file-from-the-query-box">
+<span id="faq1-11"></span><h3>1.11 I get an ‘open_basedir restriction’ while uploading a file from the query box.<a class="headerlink" href="#i-get-an-open-basedir-restriction-while-uploading-a-file-from-the-query-box" title="Permalink to this headline">¶</a></h3>
+<p>Since version 2.2.4, phpMyAdmin supports servers with open_basedir
+restrictions. However you need to create temporary directory and configure it
+as <span class="target" id="index-1"></span><a class="reference internal" href="config.html#cfg_TempDir"><tt class="xref config config-option docutils literal"><span class="pre">$cfg['TempDir']</span></tt></a>. The uploaded files will be moved there,
+and after execution of your <a class="reference internal" href="glossary.html#term-sql"><em class="xref std std-term">SQL</em></a> commands, removed.</p>
+</div>
+<div class="section" id="i-have-lost-my-mysql-root-password-what-can-i-do">
+<span id="faq1-12"></span><h3>1.12 I have lost my MySQL root password, what can I do?<a class="headerlink" href="#i-have-lost-my-mysql-root-password-what-can-i-do" title="Permalink to this headline">¶</a></h3>
+<p>The MySQL manual explains how to <a class="reference external" href="http://dev.mysql.com/doc/mysql/en/resetting-permissions.html">reset the permissions</a>.</p>
+</div>
+<div class="section" id="faq1-13">
+<span id="id2"></span><h3>1.13 (withdrawn).<a class="headerlink" href="#faq1-13" title="Permalink to this headline">¶</a></h3>
+</div>
+<div class="section" id="faq1-14">
+<span id="id3"></span><h3>1.14 (withdrawn).<a class="headerlink" href="#faq1-14" title="Permalink to this headline">¶</a></h3>
+</div>
+<div class="section" id="i-have-problems-with-mysql-user-column-names">
+<span id="faq1-15"></span><h3>1.15 I have problems with <em>mysql.user</em> column names.<a class="headerlink" href="#i-have-problems-with-mysql-user-column-names" title="Permalink to this headline">¶</a></h3>
+<p>In previous MySQL versions, the <tt class="docutils literal"><span class="pre">User</span></tt> and <tt class="docutils literal"><span class="pre">Password``columns</span> <span class="pre">were</span>
+<span class="pre">named</span> <span class="pre">``user</span></tt> and <tt class="docutils literal"><span class="pre">password</span></tt>. Please modify your column names to
+align with current standards.</p>
+</div>
+<div class="section" id="i-cannot-upload-big-dump-files-memory-http-or-timeout-problems">
+<span id="faq1-16"></span><h3>1.16 I cannot upload big dump files (memory, HTTP or timeout problems).<a class="headerlink" href="#i-cannot-upload-big-dump-files-memory-http-or-timeout-problems" title="Permalink to this headline">¶</a></h3>
+<p>Starting with version 2.7.0, the import engine has been re–written and
+these problems should not occur. If possible, upgrade your phpMyAdmin
+to the latest version to take advantage of the new import features.</p>
+<p>The first things to check (or ask your host provider to check) are the
+values of <tt class="docutils literal"><span class="pre">upload_max_filesize</span></tt>, <tt class="docutils literal"><span class="pre">memory_limit</span></tt> and
+<tt class="docutils literal"><span class="pre">post_max_size</span></tt> in the <tt class="file docutils literal"><span class="pre">php.ini</span></tt> configuration file. All of these
+three settings limit the maximum size of data that can be submitted
+and handled by PHP. One user also said that <tt class="docutils literal"><span class="pre">post_max_size</span></tt> and
+<tt class="docutils literal"><span class="pre">memory_limit</span></tt> need to be larger than <tt class="docutils literal"><span class="pre">upload_max_filesize</span></tt>.
+There exist several workarounds if your upload is too big or your
+hosting provider is unwilling to change the settings:</p>
+<ul>
+<li><p class="first">Look at the <span class="target" id="index-2"></span><a class="reference internal" href="config.html#cfg_UploadDir"><tt class="xref config config-option docutils literal"><span class="pre">$cfg['UploadDir']</span></tt></a> feature. This allows one to upload a file to the server
+via scp, ftp, or your favorite file transfer method. PhpMyAdmin is
+then able to import the files from the temporary directory. More
+information is available in the <a class="reference internal" href="config.html#config"><em>Configuration</em></a>  of this document.</p>
+</li>
+<li><p class="first">Using a utility (such as <a class="reference external" href="http://www.ozerov.de/bigdump.php">BigDump</a>) to split the files before
+uploading. We cannot support this or any third party applications, but
+are aware of users having success with it.</p>
+</li>
+<li><p class="first">If you have shell (command line) access, use MySQL to import the files
+directly. You can do this by issuing the “source” command from within
+MySQL:</p>
+<div class="highlight-mysql"><div class="highlight"><pre><span class="n">source</span> <span class="n">filename</span><span class="p">.</span><span class="k">sql</span><span class="p">;</span>
+</pre></div>
+</div>
+</li>
+</ul>
+</div>
+<div class="section" id="which-mysql-versions-does-phpmyadmin-support">
+<span id="faq1-17"></span><h3>1.17 Which MySQL versions does phpMyAdmin support?<a class="headerlink" href="#which-mysql-versions-does-phpmyadmin-support" title="Permalink to this headline">¶</a></h3>
+<p>Since phpMyAdmin 3.0.x, only MySQL 5.0.1 and newer are supported. For
+older MySQL versions, you need to use the latest 2.x branch.
+phpMyAdmin can connect to your MySQL server using PHP’s classic <a class="reference external" href="http://php.net/mysql">MySQL
+extension</a> as well as the <a class="reference external" href="http://php.net/mysqli">improved MySQL
+extension (MySQLi)</a> that is available in PHP
+5.0. The latter one should be used unless you have a good reason not
+to do so. When compiling PHP, we strongly recommend that you manually
+link the MySQL extension of your choice to a MySQL client library of
+at least the same minor version since the one that is bundled with
+some PHP distributions is rather old and might cause problems see
+<a class="reference internal" href="#faq1-17a"><em>1.17a I cannot connect to the MySQL server. It always returns the error message, “Client does not support authentication protocol requested by server; consider upgrading MySQL client”</em></a>. <a class="reference external" href="http://mariadb.org/">MariaDB</a> is also supported
+(versions 5.1 and 5.2 were tested).</p>
+<p class="versionchanged">
+<span class="versionmodified">Changed in version 3.5: </span>Since phpMyAdmin 3.5 <a class="reference external" href="http://www.drizzle.org/">Drizzle</a> is supported.</p>
+</div>
+<div class="section" id="a-i-cannot-connect-to-the-mysql-server-it-always-returns-the-error-message-client-does-not-support-authentication-protocol-requested-by-server-consider-upgrading-mysql-client">
+<span id="faq1-17a"></span><h3>1.17a I cannot connect to the MySQL server. It always returns the error message, “Client does not support authentication protocol requested by server; consider upgrading MySQL client”<a class="headerlink" href="#a-i-cannot-connect-to-the-mysql-server-it-always-returns-the-error-message-client-does-not-support-authentication-protocol-requested-by-server-consider-upgrading-mysql-client" title="Permalink to this headline">¶</a></h3>
+<p>You tried to access MySQL with an old MySQL client library. The
+version of your MySQL client library can be checked in your phpinfo()
+output. In general, it should have at least the same minor version as
+your server - as mentioned in <a class="reference internal" href="#faq1-17"><em>1.17 Which MySQL versions does phpMyAdmin support?</em></a>. This problem is
+generally caused by using MySQL version 4.1 or newer. MySQL changed
+the authentication hash and your PHP is trying to use the old method.
+The proper solution is to use the <a class="reference external" href="http://www.php.net/mysqli">mysqli extension</a> with the proper client library to match
+your MySQL installation. Your chosen extension is specified in
+<span class="target" id="index-3"></span><a class="reference internal" href="config.html#cfg_Servers_extension"><tt class="xref config config-option docutils literal"><span class="pre">$cfg['Servers'][$i]['extension']</span></tt></a>. More
+information (and several workarounds) are located in the <a class="reference external" href="http://dev.mysql.com/doc/mysql/en/old-client.html">MySQL
+Documentation</a>.</p>
+</div>
+<div class="section" id="faq1-18">
+<span id="id4"></span><h3>1.18 (withdrawn).<a class="headerlink" href="#faq1-18" title="Permalink to this headline">¶</a></h3>
+</div>
+<div class="section" id="i-can-t-run-the-display-relations-feature-because-the-script-seems-not-to-know-the-font-face-i-m-using">
+<span id="faq1-19"></span><h3>1.19 I can’t run the “display relations” feature because the script seems not to know the font face I’m using!<a class="headerlink" href="#i-can-t-run-the-display-relations-feature-because-the-script-seems-not-to-know-the-font-face-i-m-using" title="Permalink to this headline">¶</a></h3>
+<p>The <a class="reference internal" href="glossary.html#term-tcpdf"><em class="xref std std-term">TCPDF</em></a> library we’re using for this feature requires some special
+files to use font faces. Please refers to the <a class="reference external" href="http://www.tcpdf.org/">TCPDF manual</a> to build these files.</p>
+</div>
+<div class="section" id="i-receive-the-error-cannot-load-mysql-extension-please-check-php-configuration">
+<span id="faqmysql"></span><h3>1.20 I receive the error “cannot load MySQL extension, please check PHP Configuration”.<a class="headerlink" href="#i-receive-the-error-cannot-load-mysql-extension-please-check-php-configuration" title="Permalink to this headline">¶</a></h3>
+<p>To connect to a MySQL server, PHP needs a set of MySQL functions
+called “MySQL extension”. This extension may be part of the PHP
+distribution (compiled-in), otherwise it needs to be loaded
+dynamically. Its name is probably <em>mysql.so</em> or <em>php_mysql.dll</em>.
+phpMyAdmin tried to load the extension but failed. Usually, the
+problem is solved by installing a software package called “PHP-MySQL”
+or something similar.</p>
+</div>
+<div class="section" id="i-am-running-the-cgi-version-of-php-under-unix-and-i-cannot-log-in-using-cookie-auth">
+<span id="faq1-21"></span><h3>1.21 I am running the CGI version of PHP under Unix, and I cannot log in using cookie auth.<a class="headerlink" href="#i-am-running-the-cgi-version-of-php-under-unix-and-i-cannot-log-in-using-cookie-auth" title="Permalink to this headline">¶</a></h3>
+<p>In <tt class="file docutils literal"><span class="pre">php.ini</span></tt>, set <tt class="docutils literal"><span class="pre">mysql.max_links</span></tt> higher than 1.</p>
+</div>
+<div class="section" id="i-don-t-see-the-location-of-text-file-field-so-i-cannot-upload">
+<span id="faq1-22"></span><h3>1.22 I don’t see the “Location of text file” field, so I cannot upload.<a class="headerlink" href="#i-don-t-see-the-location-of-text-file-field-so-i-cannot-upload" title="Permalink to this headline">¶</a></h3>
+<p>This is most likely because in <tt class="file docutils literal"><span class="pre">php.ini</span></tt>, your <tt class="docutils literal"><span class="pre">file_uploads</span></tt>
+parameter is not set to “on”.</p>
+</div>
+<div class="section" id="i-m-running-mysql-on-a-win32-machine-each-time-i-create-a-new-table-the-table-and-column-names-are-changed-to-lowercase">
+<span id="faq1-23"></span><h3>1.23 I’m running MySQL on a Win32 machine. Each time I create a new table the table and column names are changed to lowercase!<a class="headerlink" href="#i-m-running-mysql-on-a-win32-machine-each-time-i-create-a-new-table-the-table-and-column-names-are-changed-to-lowercase" title="Permalink to this headline">¶</a></h3>
+<p>This happens because the MySQL directive <tt class="docutils literal"><span class="pre">lower_case_table_names</span></tt>
+defaults to 1 (<tt class="docutils literal"><span class="pre">ON</span></tt>) in the Win32 version of MySQL. You can change
+this behavior by simply changing the directive to 0 (<tt class="docutils literal"><span class="pre">OFF</span></tt>): Just
+edit your <tt class="docutils literal"><span class="pre">my.ini</span></tt> file that should be located in your Windows
+directory and add the following line to the group [mysqld]:</p>
+<div class="highlight-ini"><div class="highlight"><pre><span class="na">set-variable</span> <span class="o">=</span> <span class="s">lower_case_table_names=0</span>
+</pre></div>
+</div>
+<p>Next, save the file and restart the MySQL service. You can always
+check the value of this directive using the query</p>
+<div class="highlight-mysql"><div class="highlight"><pre><span class="k">SHOW</span> <span class="n">VARIABLES</span> <span class="k">LIKE</span> <span class="s1">'lower_case_table_names'</span><span class="p">;</span>
+</pre></div>
+</div>
+</div>
+<div class="section" id="faq1-24">
+<span id="id5"></span><h3>1.24 (withdrawn).<a class="headerlink" href="#faq1-24" title="Permalink to this headline">¶</a></h3>
+</div>
+<div class="section" id="i-am-running-apache-with-mod-gzip-1-3-26-1a-on-windows-xp-and-i-get-problems-such-as-undefined-variables-when-i-run-a-sql-query">
+<span id="faq1-25"></span><h3>1.25 I am running Apache with mod_gzip-1.3.26.1a on Windows XP, and I get problems, such as undefined variables when I run a SQL query.<a class="headerlink" href="#i-am-running-apache-with-mod-gzip-1-3-26-1a-on-windows-xp-and-i-get-problems-such-as-undefined-variables-when-i-run-a-sql-query" title="Permalink to this headline">¶</a></h3>
+<p>A tip from Jose Fandos: put a comment on the following two lines in
+httpd.conf, like this:</p>
+<div class="highlight-apache"><div class="highlight"><pre><span class="c"># mod_gzip_item_include file \.php$</span>
+<span class="c"># mod_gzip_item_include mime "application/x-httpd-php.*"</span>
+</pre></div>
+</div>
+<p>as this version of mod_gzip on Apache (Windows) has problems handling
+PHP scripts. Of course you have to restart Apache.</p>
+</div>
+<div class="section" id="i-just-installed-phpmyadmin-in-my-document-root-of-iis-but-i-get-the-error-no-input-file-specified-when-trying-to-run-phpmyadmin">
+<span id="faq1-26"></span><h3>1.26 I just installed phpMyAdmin in my document root of IIS but I get the error “No input file specified” when trying to run phpMyAdmin.<a class="headerlink" href="#i-just-installed-phpmyadmin-in-my-document-root-of-iis-but-i-get-the-error-no-input-file-specified-when-trying-to-run-phpmyadmin" title="Permalink to this headline">¶</a></h3>
+<p>This is a permission problem. Right-click on the phpmyadmin folder and
+choose properties. Under the tab Security, click on “Add” and select
+the user “IUSR_machine” from the list. Now set his permissions and it
+should work.</p>
+</div>
+<div class="section" id="i-get-empty-page-when-i-want-to-view-huge-page-eg-db-structure-php-with-plenty-of-tables">
+<span id="faq1-27"></span><h3>1.27 I get empty page when I want to view huge page (eg. db_structure.php with plenty of tables).<a class="headerlink" href="#i-get-empty-page-when-i-want-to-view-huge-page-eg-db-structure-php-with-plenty-of-tables" title="Permalink to this headline">¶</a></h3>
+<p>This was caused by a <a class="reference external" href="http://bugs.php.net/21079">PHP bug</a> that occur when
+GZIP output buffering is enabled. If you turn off it (by
+<span class="target" id="index-4"></span><a class="reference internal" href="config.html#cfg_OBGzip"><tt class="xref config config-option docutils literal"><span class="pre">$cfg['OBGzip']</span></tt></a> in <tt class="file docutils literal"><span class="pre">config.inc.php</span></tt>), it should work.
+This bug will has been fixed in PHP 5.0.0.</p>
+</div>
+<div class="section" id="my-mysql-server-sometimes-refuses-queries-and-returns-the-message-errorcode-13-what-does-this-mean">
+<span id="faq1-28"></span><h3>1.28 My MySQL server sometimes refuses queries and returns the message ‘Errorcode: 13’. What does this mean?<a class="headerlink" href="#my-mysql-server-sometimes-refuses-queries-and-returns-the-message-errorcode-13-what-does-this-mean" title="Permalink to this headline">¶</a></h3>
+<p>This can happen due to a MySQL bug when having database / table names
+with upper case characters although <tt class="docutils literal"><span class="pre">lower_case_table_names</span></tt> is
+set to 1. To fix this, turn off this directive, convert all database
+and table names to lower case and turn it on again. Alternatively,
+there’s a bug-fix available starting with MySQL 3.23.56 /
+4.0.11-gamma.</p>
+</div>
+<div class="section" id="when-i-create-a-table-or-modify-a-column-i-get-an-error-and-the-columns-are-duplicated">
+<span id="faq1-29"></span><h3>1.29 When I create a table or modify a column, I get an error and the columns are duplicated.<a class="headerlink" href="#when-i-create-a-table-or-modify-a-column-i-get-an-error-and-the-columns-are-duplicated" title="Permalink to this headline">¶</a></h3>
+<p>It is possible to configure Apache in such a way that PHP has problems
+interpreting .php files.</p>
+<p>The problems occur when two different (and conflicting) set of
+directives are used:</p>
+<div class="highlight-apache"><div class="highlight"><pre><span class="nb">SetOutputFilter</span> PHP
+<span class="nb">SetInputFilter</span> PHP
+</pre></div>
+</div>
+<p>and</p>
+<div class="highlight-apache"><div class="highlight"><pre><span class="nb">AddType</span> application/x-httpd-php .php
+</pre></div>
+</div>
+<p>In the case we saw, one set of directives was in
+<tt class="docutils literal"><span class="pre">/etc/httpd/conf/httpd.conf</span></tt>, while the other set was in
+<tt class="docutils literal"><span class="pre">/etc/httpd/conf/addon-modules/php.conf</span></tt>. The recommended way is
+with <tt class="docutils literal"><span class="pre">AddType</span></tt>, so just comment out the first set of lines and
+restart Apache:</p>
+<div class="highlight-apache"><div class="highlight"><pre><span class="c">#SetOutputFilter PHP</span>
+<span class="c">#SetInputFilter PHP</span>
+</pre></div>
+</div>
+</div>
+<div class="section" id="i-get-the-error-navigation-php-missing-hash">
+<span id="faq1-30"></span><h3>1.30 I get the error “navigation.php: Missing hash”.<a class="headerlink" href="#i-get-the-error-navigation-php-missing-hash" title="Permalink to this headline">¶</a></h3>
+<p>This problem is known to happen when the server is running Turck
+MMCache but upgrading MMCache to version 2.3.21 solves the problem.</p>
+</div>
+<div class="section" id="does-phpmyadmin-support-php-5">
+<span id="faq1-31"></span><h3>1.31 Does phpMyAdmin support PHP 5?<a class="headerlink" href="#does-phpmyadmin-support-php-5" title="Permalink to this headline">¶</a></h3>
+<p>Yes.</p>
+<p>Since release 3.0 only PHP 5.2 and newer. For older PHP versions, use
+phpMyAdmin 2.11.x.</p>
+</div>
+<div class="section" id="can-i-use-http-authentication-with-iis">
+<span id="faq1-32"></span><h3>1.32 Can I use HTTP authentication with IIS?<a class="headerlink" href="#can-i-use-http-authentication-with-iis" title="Permalink to this headline">¶</a></h3>
+<p>Yes. This procedure was tested with phpMyAdmin 2.6.1, PHP 4.3.9 in
+<a class="reference internal" href="glossary.html#term-isapi"><em class="xref std std-term">ISAPI</em></a> mode under <a class="reference internal" href="glossary.html#term-iis"><em class="xref std std-term">IIS</em></a> 5.1.</p>
+<ol class="arabic simple">
+<li>In your <tt class="file docutils literal"><span class="pre">php.ini</span></tt> file, set <tt class="docutils literal"><span class="pre">cgi.rfc2616_headers</span> <span class="pre">=</span> <span class="pre">0</span></tt></li>
+<li>In <tt class="docutils literal"><span class="pre">Web</span> <span class="pre">Site</span> <span class="pre">Properties</span> <span class="pre">-></span> <span class="pre">File/Directory</span> <span class="pre">Security</span> <span class="pre">-></span> <span class="pre">Anonymous</span>
+<span class="pre">Access</span></tt> dialog box, check the <tt class="docutils literal"><span class="pre">Anonymous</span> <span class="pre">access</span></tt> checkbox and
+uncheck any other checkboxes (i.e. uncheck <tt class="docutils literal"><span class="pre">Basic</span> <span class="pre">authentication</span></tt>,
+<tt class="docutils literal"><span class="pre">Integrated</span> <span class="pre">Windows</span> <span class="pre">authentication</span></tt>, and <tt class="docutils literal"><span class="pre">Digest</span></tt> if it’s
+enabled.) Click <tt class="docutils literal"><span class="pre">OK</span></tt>.</li>
+<li>In <tt class="docutils literal"><span class="pre">Custom</span> <span class="pre">Errors</span></tt>, select the range of <tt class="docutils literal"><span class="pre">401;1</span></tt> through <tt class="docutils literal"><span class="pre">401;5</span></tt>
+and click the <tt class="docutils literal"><span class="pre">Set</span> <span class="pre">to</span> <span class="pre">Default</span></tt> button.</li>
+</ol>
+<div class="admonition-see-also admonition seealso">
+<p class="first admonition-title">See also</p>
+<p class="last"><span class="target" id="index-5"></span><a class="rfc reference external" href="http://tools.ietf.org/html/rfc2616.html"><strong>RFC 2616</strong></a></p>
+</div>
+</div>
+<div class="section" id="faq1-33">
+<span id="id6"></span><h3>1.33 (withdrawn).<a class="headerlink" href="#faq1-33" title="Permalink to this headline">¶</a></h3>
+</div>
+<div class="section" id="can-i-access-directly-to-database-or-table-pages">
+<span id="faq1-34"></span><h3>1.34 Can I access directly to database or table pages?<a class="headerlink" href="#can-i-access-directly-to-database-or-table-pages" title="Permalink to this headline">¶</a></h3>
+<p>Yes. Out of the box, you can use <a class="reference internal" href="glossary.html#term-url"><em class="xref std std-term">URL</em></a> like <a class="reference external" href="http://server/phpMyAdmin/index.php?server=X&db=databas">http://server/phpMyAdmin/index.php?server=X&db=databas</a>
+e&table=table&target=script. For <tt class="docutils literal"><span class="pre">server</span></tt> you use the server number
+which refers to the order of the server paragraph in
+<tt class="file docutils literal"><span class="pre">config.inc.php</span></tt>. Table and script parts are optional. If you want
+<a class="reference external" href="http://server/phpMyAdmin/database[/table][/script">http://server/phpMyAdmin/database[/table][/script</a>] <a class="reference internal" href="glossary.html#term-url"><em class="xref std std-term">URL</em></a>, you need to do some configuration. Following
+lines apply only for <a class="reference external" href="http://httpd.apache.org">Apache</a> web server.
+First make sure, that you have enabled some features within global
+configuration. You need <tt class="docutils literal"><span class="pre">Options</span> <span class="pre">FollowSymLinks</span></tt> and <tt class="docutils literal"><span class="pre">AllowOverride</span>
+<span class="pre">FileInfo</span></tt> enabled for directory where phpMyAdmin is installed and you
+need mod_rewrite to be enabled. Then you just need to create
+following <a class="reference internal" href="glossary.html#term-htaccess"><em class="xref std std-term">.htaccess</em></a> file in root folder of phpMyAdmin installation (don’t
+forget to change directory name inside of it):</p>
+<div class="highlight-apache"><div class="highlight"><pre><span class="nb">RewriteEngine</span> <span class="k">On</span>
+<span class="nb">RewriteBase</span> <span class="sx">/path_to_phpMyAdmin</span>
+<span class="nb">RewriteRule</span> ^([a-zA-Z0-9_]+)/([a-zA-Z0-9_]+)/([a-z_]+\.php)$ index.php?db=$1&table=$2&target=$3 [R]
+<span class="nb">RewriteRule</span> ^([a-zA-Z0-9_]+)/([a-z_]+\.php)$ index.php?db=$1&target=$2 [R]
+<span class="nb">RewriteRule</span> ^([a-zA-Z0-9_]+)/([a-zA-Z0-9_]+)$ index.php?db=$1&table=$2 [R]
+<span class="nb">RewriteRule</span> ^([a-zA-Z0-9_]+)$ index.php?db=$1 [R]
+</pre></div>
+</div>
+</div>
+<div class="section" id="can-i-use-http-authentication-with-apache-cgi">
+<span id="faq1-35"></span><h3>1.35 Can I use HTTP authentication with Apache CGI?<a class="headerlink" href="#can-i-use-http-authentication-with-apache-cgi" title="Permalink to this headline">¶</a></h3>
+<p>Yes. However you need to pass authentication variable to <a class="reference internal" href="glossary.html#term-cgi"><em class="xref std std-term">CGI</em></a> using
+following rewrite rule:</p>
+<div class="highlight-apache"><div class="highlight"><pre><span class="nb">RewriteEngine</span> <span class="k">On</span>
+<span class="nb">RewriteRule</span> .* - [E=REMOTE_USER:%{HTTP:Authorization},L]
+</pre></div>
+</div>
+</div>
+<div class="section" id="i-get-an-error-500-internal-server-error">
+<span id="faq1-36"></span><h3>1.36 I get an error “500 Internal Server Error”.<a class="headerlink" href="#i-get-an-error-500-internal-server-error" title="Permalink to this headline">¶</a></h3>
+<p>There can be many explanations to this and a look at your server’s
+error log file might give a clue.</p>
+</div>
+<div class="section" id="i-run-phpmyadmin-on-cluster-of-different-machines-and-password-encryption-in-cookie-auth-doesn-t-work">
+<span id="faq1-37"></span><h3>1.37 I run phpMyAdmin on cluster of different machines and password encryption in cookie auth doesn’t work.<a class="headerlink" href="#i-run-phpmyadmin-on-cluster-of-different-machines-and-password-encryption-in-cookie-auth-doesn-t-work" title="Permalink to this headline">¶</a></h3>
+<p>If your cluster consist of different architectures, PHP code used for
+encryption/decryption won’t work correct. This is caused by use of
+pack/unpack functions in code. Only solution is to use mcrypt
+extension which works fine in this case.</p>
+</div>
+<div class="section" id="can-i-use-phpmyadmin-on-a-server-on-which-suhosin-is-enabled">
+<span id="faq1-38"></span><h3>1.38 Can I use phpMyAdmin on a server on which Suhosin is enabled?<a class="headerlink" href="#can-i-use-phpmyadmin-on-a-server-on-which-suhosin-is-enabled" title="Permalink to this headline">¶</a></h3>
+<p>Yes but the default configuration values of Suhosin are known to cause
+problems with some operations, for example editing a table with many
+columns and no primary key or with textual primary key.</p>
+<p>Suhosin configuration might lead to malfunction in some cases and it
+can not be fully avoided as phpMyAdmin is kind of application which
+needs to transfer big amounts of columns in single HTTP request, what
+is something what Suhosin tries to prevent. Generally all
+<tt class="docutils literal"><span class="pre">suhosin.request.*</span></tt>, <tt class="docutils literal"><span class="pre">suhosin.post.*</span></tt> and <tt class="docutils literal"><span class="pre">suhosin.get.*</span></tt>
+directives can have negative effect on phpMyAdmin usability. You can
+always find in your error logs which limit did cause dropping of
+variable, so you can diagnose the problem and adjust matching
+configuration variable.</p>
+<p>The default values for most Suhosin configuration options will work in
+most scenarios, however you might want to adjust at least following
+parameters:</p>
+<ul class="simple">
+<li><a class="reference external" href="http://www.hardened-php.net/suhosin/configuration.html#suhosin.request.max_vars">suhosin.request.max_vars</a> should
+be increased (eg. 2048)</li>
+<li><a class="reference external" href="http://www.hardened-php.net/suhosin/configuration.html#suhosin.post.max_vars">suhosin.post.max_vars</a> should be
+increased (eg. 2048)</li>
+<li><a class="reference external" href="http://www.hardened-php.net/suhosin/configuration.html#suhosin.request.max_array_index_length">suhosin.request.max_array_index_length</a>
+should be increased (eg. 256)</li>
+<li><a class="reference external" href="http://www.hardened-php.net/suhosin/configuration.html#suhosin.post.max_array_index_length">suhosin.post.max_array_index_length</a>
+should be increased (eg. 256)</li>
+<li><a class="reference external" href="http://www.hardened-php.net/suhosin/configuration.html#suhosin.request.max_totalname_length">suhosin.request.max_totalname_length</a>
+should be increased (eg. 8192)</li>
+<li><a class="reference external" href="http://www.hardened-php.net/suhosin/configuration.html#suhosin.post.max_totalname_length">suhosin.post.max_totalname_length</a> should be
+increased (eg. 8192)</li>
+<li><a class="reference external" href="http://www.hardened-php.net/suhosin/configuration.html#suhosin.get.max_value_length">suhosin.get.max_value_length</a>
+should be increased (eg. 1024)</li>
+<li><a class="reference external" href="http://www.hardened-php.net/suhosin/configuration.html#suhosin.sql.bailout_on_error">suhosin.sql.bailout_on_error</a>
+needs to be disabled (the default)</li>
+<li><a class="reference external" href="http://www.hardened-php.net/suhosin/configuration.html#logging_configuration">suhosin.log.*</a> should not
+include <a class="reference internal" href="glossary.html#term-sql"><em class="xref std std-term">SQL</em></a>, otherwise you get big
+slowdown</li>
+</ul>
+<p>You can also disable the warning using the <span class="target" id="index-6"></span><a class="reference internal" href="config.html#cfg_SuhosinDisableWarning"><tt class="xref config config-option docutils literal"><span class="pre">$cfg['SuhosinDisableWarning']</span></tt></a>.</p>
+</div>
+<div class="section" id="when-i-try-to-connect-via-https-i-can-log-in-but-then-my-connection-is-redirected-back-to-http-what-can-cause-this-behavior">
+<span id="faq1-39"></span><h3>1.39 When I try to connect via https, I can log in, but then my connection is redirected back to http. What can cause this behavior?<a class="headerlink" href="#when-i-try-to-connect-via-https-i-can-log-in-but-then-my-connection-is-redirected-back-to-http-what-can-cause-this-behavior" title="Permalink to this headline">¶</a></h3>
+<p>Be sure that you have enabled <tt class="docutils literal"><span class="pre">SSLOptions</span></tt> and <tt class="docutils literal"><span class="pre">StdEnvVars</span></tt> in
+your Apache configuration.</p>
+<div class="admonition-see-also admonition seealso">
+<p class="first admonition-title">See also</p>
+<p class="last"><<a class="reference external" href="http://httpd.apache.org/docs/2.0/mod/mod_ssl.html#ssloptions">http://httpd.apache.org/docs/2.0/mod/mod_ssl.html#ssloptions</a>></p>
+</div>
+</div>
+<div class="section" id="when-accessing-phpmyadmin-via-an-apache-reverse-proxy-cookie-login-does-not-work">
+<span id="faq1-40"></span><h3>1.40 When accessing phpMyAdmin via an Apache reverse proxy, cookie login does not work.<a class="headerlink" href="#when-accessing-phpmyadmin-via-an-apache-reverse-proxy-cookie-login-does-not-work" title="Permalink to this headline">¶</a></h3>
+<p>To be able to use cookie auth Apache must know that it has to rewrite
+the set-cookie headers. Example from the Apache 2.2 documentation:</p>
+<div class="highlight-apache"><div class="highlight"><pre><span class="nb">ProxyPass</span> <span class="sx">/mirror/foo/</span> http://backend.example.com/
+<span class="nb">ProxyPassReverse</span> <span class="sx">/mirror/foo/</span> http://backend.example.com/
+<span class="nb">ProxyPassReverseCookieDomain</span> backend.example.com public.example.com
+<span class="nb">ProxyPassReverseCookiePath</span> / <span class="sx">/mirror/foo/</span>
+</pre></div>
+</div>
+<p>Note: if the backend url looks like <a class="reference external" href="http://host/~user/phpmyadmin">http://host/~user/phpmyadmin</a>, the
+tilde (~) must be url encoded as %7E in the ProxyPassReverse* lines.
+This is not specific to phpmyadmin, it’s just the behavior of Apache.</p>
+<div class="highlight-apache"><div class="highlight"><pre><span class="nb">ProxyPass</span> <span class="sx">/mirror/foo/</span> http://backend.example.com/~user/phpmyadmin
+<span class="nb">ProxyPassReverse</span> <span class="sx">/mirror/foo/</span> http://backend.example.com/%7Euser/phpmyadmin
+<span class="nb">ProxyPassReverseCookiePath</span> /%7Euser/phpmyadmin <span class="sx">/mirror/foo</span>
+</pre></div>
+</div>
+<div class="admonition-see-also admonition seealso">
+<p class="first admonition-title">See also</p>
+<p class="last"><<a class="reference external" href="http://httpd.apache.org/docs/2.2/mod/mod_proxy.html">http://httpd.apache.org/docs/2.2/mod/mod_proxy.html</a>></p>
+</div>
+</div>
+<div class="section" id="when-i-view-a-database-and-ask-to-see-its-privileges-i-get-an-error-about-an-unknown-column">
+<span id="faq1-41"></span><h3>1.41 When I view a database and ask to see its privileges, I get an error about an unknown column.<a class="headerlink" href="#when-i-view-a-database-and-ask-to-see-its-privileges-i-get-an-error-about-an-unknown-column" title="Permalink to this headline">¶</a></h3>
+<p>The MySQL server’s privilege tables are not up to date, you need to
+run the <strong class="command">mysql_upgrade</strong> command on the server.</p>
+</div>
+<div class="section" id="how-can-i-prevent-robots-from-accessing-phpmyadmin">
+<span id="faq1-42"></span><h3>1.42 How can I prevent robots from accessing phpMyAdmin?<a class="headerlink" href="#how-can-i-prevent-robots-from-accessing-phpmyadmin" title="Permalink to this headline">¶</a></h3>
+<p>You can add various rules to <a class="reference internal" href="glossary.html#term-htaccess"><em class="xref std std-term">.htaccess</em></a> to filter access based on user agent
+field. This is quite easy to circumvent, but could prevent at least
+some robots accessing your installation.</p>
+<div class="highlight-apache"><div class="highlight"><pre><span class="nb">RewriteEngine</span> <span class="k">on</span>
+
+<span class="c"># Allow only GET and POST verbs</span>
+<span class="nb">RewriteCond</span> %{REQUEST_METHOD} !^(GET|POST)$ [NC,OR]
+
+<span class="c"># Ban Typical Vulnerability Scanners and others</span>
+<span class="c"># Kick out Script Kiddies</span>
+<span class="nb">RewriteCond</span> %{HTTP_USER_AGENT} ^(java|curl|wget).* [NC,OR]
+<span class="nb">RewriteCond</span> %{HTTP_USER_AGENT} ^.*(libwww-perl|curl|wget|python|nikto|wkito|pikto|scan|acunetix).* [NC,OR]
+<span class="nb">RewriteCond</span> %{HTTP_USER_AGENT} ^.*(winhttp|HTTrack|clshttp|archiver|loader|email|harvest|extract|grab|miner).* [NC,OR]
+
+<span class="c"># Ban Search Engines, Crawlers to your administrative panel</span>
+<span class="c"># No reasons to access from bots</span>
+<span class="c"># Ultimately Better than the useless robots.txt</span>
+<span class="c"># Did google respect robots.txt?</span>
+<span class="c"># Try google: intitle:phpMyAdmin intext:"Welcome to phpMyAdmin *.*.*" intext:"Log in" -wiki -forum -forums -questions intext:"Cookies must be enabled"</span>
+<span class="nb">RewriteCond</span> %{HTTP_USER_AGENT} ^.*(AdsBot-Google|ia_archiver|Scooter|Ask.Jeeves|Baiduspider|Exabot|FAST.Enterprise.Crawler|FAST-WebCrawler|www\.neomo\.de|Gigabot|Mediapartners-Google|Google.Desktop|Feedfetcher-Google|Googlebot|heise-IT-Markt-Crawler|heritrix|ibm.com\cs/crawler|ICCrawler|ichiro|MJ12bot|MetagerBot|msnbot-NewsBlogs|msnbot|msnbot-media|NG-Search|lucene.apache.org|NutchCVS|OmniExplorer_Bot|online.link.validator|psbot0|Seekbot|Sensis.Web.Crawler|SEO.sea [...]
+<span class="nb">RewriteRule</span> .* - [F]
+</pre></div>
+</div>
+</div>
+<div class="section" id="why-can-t-i-display-the-structure-of-my-table-containing-hundreds-of-columns">
+<span id="faq1-43"></span><h3>1.43 Why can’t I display the structure of my table containing hundreds of columns?<a class="headerlink" href="#why-can-t-i-display-the-structure-of-my-table-containing-hundreds-of-columns" title="Permalink to this headline">¶</a></h3>
+<p>Because your PHP’s <tt class="docutils literal"><span class="pre">memory_limit</span></tt> is too low; adjust it in <tt class="file docutils literal"><span class="pre">php.ini</span></tt>.</p>
+</div>
+</div>
+<div class="section" id="configuration">
+<span id="faqconfig"></span><h2>Configuration<a class="headerlink" href="#configuration" title="Permalink to this headline">¶</a></h2>
+<div class="section" id="the-error-message-warning-cannot-add-header-information-headers-already-sent-by-is-displayed-what-s-the-problem">
+<span id="faq2-1"></span><h3>2.1 The error message “Warning: Cannot add header information - headers already sent by ...” is displayed, what’s the problem?<a class="headerlink" href="#the-error-message-warning-cannot-add-header-information-headers-already-sent-by-is-displayed-what-s-the-problem" title="Permalink to this headline">¶</a></h3>
+<p>Edit your <tt class="file docutils literal"><span class="pre">config.inc.php</span></tt> file and ensure there is nothing (I.E. no
+blank lines, no spaces, no characters...) neither before the <tt class="docutils literal"><span class="pre"><?php</span></tt> tag at
+the beginning, neither after the <tt class="docutils literal"><span class="pre">?></span></tt> tag at the end. We also got a report
+from a user under <a class="reference internal" href="glossary.html#term-iis"><em class="xref std std-term">IIS</em></a>, that used a zipped distribution kit: the file
+<tt class="file docutils literal"><span class="pre">libraries/Config.class.php</span></tt> contained an end-of-line character (hex 0A)
+at the end; removing this character cleared his errors.</p>
+</div>
+<div class="section" id="phpmyadmin-can-t-connect-to-mysql-what-s-wrong">
+<span id="faq2-2"></span><h3>2.2 phpMyAdmin can’t connect to MySQL. What’s wrong?<a class="headerlink" href="#phpmyadmin-can-t-connect-to-mysql-what-s-wrong" title="Permalink to this headline">¶</a></h3>
+<p>Either there is an error with your PHP setup or your username/password
+is wrong. Try to make a small script which uses mysql_connect and see
+if it works. If it doesn’t, it may be you haven’t even compiled MySQL
+support into PHP.</p>
+</div>
+<div class="section" id="the-error-message-warning-mysql-connection-failed-can-t-connect-to-local-mysql-server-through-socket-tmp-mysql-sock-111-is-displayed-what-can-i-do">
+<span id="faq2-3"></span><h3>2.3 The error message “Warning: MySQL Connection Failed: Can’t connect to local MySQL server through socket ‘/tmp/mysql.sock’ (111) ...” is displayed. What can I do?<a class="headerlink" href="#the-error-message-warning-mysql-connection-failed-can-t-connect-to-local-mysql-server-through-socket-tmp-mysql-sock-111-is-displayed-what-can-i-do" title="Permalink to this headline">¶</a></h3>
+<p>For RedHat users, Harald Legner suggests this on the mailing list:</p>
+<p>On my RedHat-Box the socket of MySQL is <em>/var/lib/mysql/mysql.sock</em>.
+In your <tt class="file docutils literal"><span class="pre">php.ini</span></tt> you will find a line</p>
+<div class="highlight-ini"><div class="highlight"><pre><span class="na">mysql.default_socket</span> <span class="o">=</span> <span class="s">/tmp/mysql.sock</span>
+</pre></div>
+</div>
+<p>change it to</p>
+<div class="highlight-ini"><div class="highlight"><pre><span class="na">mysql.default_socket</span> <span class="o">=</span> <span class="s">/var/lib/mysql/mysql.sock</span>
+</pre></div>
+</div>
+<p>Then restart apache and it will work.</p>
+<p>Here is a fix suggested by Brad Ummer:</p>
+<ul class="simple">
+<li>First, you need to determine what socket is being used by MySQL. To do
+this, telnet to your server and go to the MySQL bin directory. In this
+directory there should be a file named <em>mysqladmin</em>. Type
+<tt class="docutils literal"><span class="pre">./mysqladmin</span> <span class="pre">variables</span></tt>, and this should give you a bunch of info
+about your MySQL server, including the socket (<em>/tmp/mysql.sock</em>, for
+example).</li>
+<li>Then, you need to tell PHP to use this socket. To do this in
+phpMyAdmin, you need to complete the socket information in the
+<tt class="file docutils literal"><span class="pre">config.inc.php</span></tt>. For example:
+<span class="target" id="index-7"></span><a class="reference internal" href="config.html#cfg_Servers_socket"><tt class="xref config config-option docutils literal"><span class="pre">$cfg['Servers'][$i]['socket']</span></tt></a>  Please also make sure that
+the permissions of this file allow to be readable by your webserver (i.e.
+‘0755’).</li>
+</ul>
+<p>Have also a look at the <a class="reference external" href="http://dev.mysql.com/doc/en/can-not-connect-to-server.html">corresponding section of the MySQL
+documentation</a>.</p>
+</div>
+<div class="section" id="nothing-is-displayed-by-my-browser-when-i-try-to-run-phpmyadmin-what-can-i-do">
+<span id="faq2-4"></span><h3>2.4 Nothing is displayed by my browser when I try to run phpMyAdmin, what can I do?<a class="headerlink" href="#nothing-is-displayed-by-my-browser-when-i-try-to-run-phpmyadmin-what-can-i-do" title="Permalink to this headline">¶</a></h3>
+<p>Try to set the <span class="target" id="index-8"></span><a class="reference internal" href="config.html#cfg_OBGzip"><tt class="xref config config-option docutils literal"><span class="pre">$cfg['OBGzip']</span></tt></a> directive to <tt class="docutils literal"><span class="pre">false</span></tt> in the phpMyAdmin configuration
+file. It helps sometime. Also have a look at your PHP version number:
+if it contains “b” or “alpha” it means you’re running a testing
+version of PHP. That’s not a so good idea, please upgrade to a plain
+revision.</p>
+</div>
+<div class="section" id="each-time-i-want-to-insert-or-change-a-row-or-drop-a-database-or-a-table-an-error-404-page-not-found-is-displayed-or-with-http-or-cookie-authentication-i-m-asked-to-log-in-again-what-s-wrong">
+<span id="faq2-5"></span><h3>2.5 Each time I want to insert or change a row or drop a database or a table, an error 404 (page not found) is displayed or, with HTTP or cookie authentication, I’m asked to log in again. What’s wrong?<a class="headerlink" href="#each-time-i-want-to-insert-or-change-a-row-or-drop-a-database-or-a-table-an-error-404-page-not-found-is-displayed-or-with-http-or-cookie-authentication-i-m-asked-to-log-in-again-what-s-wrong" title="Permalink to this head [...]
+<p>Check the value you set for the <span class="target" id="index-9"></span><a class="reference internal" href="config.html#cfg_PmaAbsoluteUri"><tt class="xref config config-option docutils literal"><span class="pre">$cfg['PmaAbsoluteUri']</span></tt></a> directive in the phpMyAdmin
+configuration file.</p>
+</div>
+<div class="section" id="i-get-an-access-denied-for-user-root-localhost-using-password-yes-error-when-trying-to-access-a-mysql-server-on-a-host-which-is-port-forwarded-for-my-localhost">
+<span id="faq2-6"></span><h3>2.6 I get an “Access denied for user: <a class="reference external" href="mailto:'root%40localhost">'root<span>@</span>localhost</a>‘ (Using password: YES)”-error when trying to access a MySQL-Server on a host which is port-forwarded for my localhost.<a class="headerlink" href="#i-get-an-access-denied-for-user-root-localhost-using-password-yes-error-when-trying-to-access-a-mysql-server-on-a-host-which-is-port-forwarded-for-my [...]
+<p>When you are using a port on your localhost, which you redirect via
+port-forwarding to another host, MySQL is not resolving the localhost
+as expected. Erik Wasser explains: The solution is: if your host is
+“localhost” MySQL (the command line tool <strong class="command">mysql</strong> as well) always
+tries to use the socket connection for speeding up things. And that
+doesn’t work in this configuration with port forwarding. If you enter
+“127.0.0.1” as hostname, everything is right and MySQL uses the
+<a class="reference internal" href="glossary.html#term-tcp"><em class="xref std std-term">TCP</em></a> connection.</p>
+</div>
+<div class="section" id="using-and-creating-themes">
+<span id="faqthemes"></span><h3>2.7 Using and creating themes<a class="headerlink" href="#using-and-creating-themes" title="Permalink to this headline">¶</a></h3>
+<p>Themes are configured with <span class="target" id="index-10"></span><a class="reference internal" href="config.html#cfg_ThemePath"><tt class="xref config config-option docutils literal"><span class="pre">$cfg['ThemePath']</span></tt></a>,
+<span class="target" id="index-11"></span><a class="reference internal" href="config.html#cfg_ThemeManager"><tt class="xref config config-option docutils literal"><span class="pre">$cfg['ThemeManager']</span></tt></a> and <span class="target" id="index-12"></span><a class="reference internal" href="config.html#cfg_ThemeDefault"><tt class="xref config config-option docutils literal"><span class="pre">$cfg['ThemeDefault']</span></tt></a>.
+Under <span class="target" id="index-13"></span><a class="reference internal" href="config.html#cfg_ThemePath"><tt class="xref config config-option docutils literal"><span class="pre">$cfg['ThemePath']</span></tt></a>, you should not delete the
+directory <tt class="docutils literal"><span class="pre">pmahomme</span></tt> or its underlying structure, because this is the
+system theme used by phpMyAdmin. <tt class="docutils literal"><span class="pre">pmahomme</span></tt> contains all images and
+styles, for backwards compatibility and for all themes that would not
+include images or css-files.  If <span class="target" id="index-14"></span><a class="reference internal" href="config.html#cfg_ThemeManager"><tt class="xref config config-option docutils literal"><span class="pre">$cfg['ThemeManager']</span></tt></a>
+is enabled, you can select your favorite theme on the main page. Your selected
+theme will be stored in a cookie.</p>
+<p>To create a theme:</p>
+<ul class="simple">
+<li>make a new subdirectory (for example “your_theme_name”) under <span class="target" id="index-15"></span><a class="reference internal" href="config.html#cfg_ThemePath"><tt class="xref config config-option docutils literal"><span class="pre">$cfg['ThemePath']</span></tt></a> (by
+default <tt class="docutils literal"><span class="pre">themes</span></tt>)</li>
+<li>copy the files and directories from <tt class="docutils literal"><span class="pre">pmahomme</span></tt> to “your_theme_name”</li>
+<li>edit the css-files in “your_theme_name/css”</li>
+<li>put your new images in “your_theme_name/img”</li>
+<li>edit <tt class="file docutils literal"><span class="pre">layout.inc.php</span></tt> in “your_theme_name”</li>
+<li>edit <tt class="file docutils literal"><span class="pre">info.inc.php</span></tt> in “your_theme_name” to contain your chosen
+theme name, that will be visible in user interface</li>
+<li>make a new screenshot of your theme and save it under
+“your_theme_name/screen.png”</li>
+</ul>
+<p>In theme directory there is file <tt class="file docutils literal"><span class="pre">info.inc.php</span></tt> which contains theme
+verbose name, theme generation and theme version. These versions and
+generations are enumerated from 1 and do not have any direct
+dependence on phpMyAdmin version. Themes within same generation should
+be backwards compatible - theme with version 2 should work in
+phpMyAdmin requiring version 1. Themes with different generation are
+incompatible.</p>
+<p>If you do not want to use your own symbols and buttons, remove the
+directory “img” in “your_theme_name”. phpMyAdmin will use the
+default icons and buttons (from the system-theme <tt class="docutils literal"><span class="pre">pmahomme</span></tt>).</p>
+</div>
+<div class="section" id="i-get-missing-parameters-errors-what-can-i-do">
+<span id="faqmissingparameters"></span><h3>2.8 I get “Missing parameters” errors, what can I do?<a class="headerlink" href="#i-get-missing-parameters-errors-what-can-i-do" title="Permalink to this headline">¶</a></h3>
+<p>Here are a few points to check:</p>
+<ul class="simple">
+<li>In <tt class="file docutils literal"><span class="pre">config.inc.php</span></tt>, try to leave the <span class="target" id="index-16"></span><a class="reference internal" href="config.html#cfg_PmaAbsoluteUri"><tt class="xref config config-option docutils literal"><span class="pre">$cfg['PmaAbsoluteUri']</span></tt></a> directive empty. See also
+<a class="reference internal" href="#faq4-7"><em>4.7 Authentication window is displayed more than once, why?</em></a>.</li>
+<li>Maybe you have a broken PHP installation or you need to upgrade your
+Zend Optimizer. See <<a class="reference external" href="http://bugs.php.net/bug.php?id=31134">http://bugs.php.net/bug.php?id=31134</a>>.</li>
+<li>If you are using Hardened PHP with the ini directive
+<tt class="docutils literal"><span class="pre">varfilter.max_request_variables</span></tt> set to the default (200) or
+another low value, you could get this error if your table has a high
+number of columns. Adjust this setting accordingly. (Thanks to Klaus
+Dorninger for the hint).</li>
+<li>In the <tt class="file docutils literal"><span class="pre">php.ini</span></tt> directive <tt class="docutils literal"><span class="pre">arg_separator.input</span></tt>, a value of ”;”
+will cause this error. Replace it with “&;”.</li>
+<li>If you are using <a class="reference external" href="http://www.hardened-php.net/">Hardened-PHP</a>, you
+might want to increase <a class="reference external" href="http://www.hardened-php.net/hphp/troubleshooting.html">request limits</a>.</li>
+<li>The directory specified in the <tt class="file docutils literal"><span class="pre">php.ini</span></tt> directive
+<tt class="docutils literal"><span class="pre">session.save_path</span></tt> does not exist or is read-only.</li>
+</ul>
+</div>
+<div class="section" id="seeing-an-upload-progress-bar">
+<span id="faq2-9"></span><h3>2.9 Seeing an upload progress bar<a class="headerlink" href="#seeing-an-upload-progress-bar" title="Permalink to this headline">¶</a></h3>
+<p>To be able to see a progress bar during your uploads, your server must
+have the <a class="reference external" href="http://pecl.php.net/package/APC">APC</a> extension, the
+<a class="reference external" href="http://pecl.php.net/package/uploadprogress">uploadprogress</a> one, or
+you must be running PHP 5.4.0 or higher. Moreover, the JSON extension
+has to be enabled in your PHP.</p>
+<p>If using APC, you must set <tt class="docutils literal"><span class="pre">apc.rfc1867</span></tt> to <tt class="docutils literal"><span class="pre">on</span></tt> in your <tt class="file docutils literal"><span class="pre">php.ini</span></tt>.</p>
+<p>If using PHP 5.4.0 or higher, you must set
+<tt class="docutils literal"><span class="pre">session.upload_progress.enabled</span></tt> to <tt class="docutils literal"><span class="pre">1</span></tt> in your <tt class="file docutils literal"><span class="pre">php.ini</span></tt>. However,
+starting from phpMyAdmin version 4.0.4, session-based upload progress has
+been temporarily deactivated due to its problematic behavior.</p>
+<div class="admonition-see-also admonition seealso">
+<p class="first admonition-title">See also</p>
+<p class="last"><span class="target" id="index-17"></span><a class="rfc reference external" href="http://tools.ietf.org/html/rfc1867.html"><strong>RFC 1867</strong></a></p>
+</div>
+</div>
+</div>
+<div class="section" id="known-limitations">
+<span id="faqlimitations"></span><h2>Known limitations<a class="headerlink" href="#known-limitations" title="Permalink to this headline">¶</a></h2>
+<div class="section" id="when-using-http-authentication-a-user-who-logged-out-can-not-log-in-again-in-with-the-same-nick">
+<span id="login-bug"></span><h3>3.1 When using HTTP authentication, a user who logged out can not log in again in with the same nick.<a class="headerlink" href="#when-using-http-authentication-a-user-who-logged-out-can-not-log-in-again-in-with-the-same-nick" title="Permalink to this headline">¶</a></h3>
+<p>This is related to the authentication mechanism (protocol) used by
+phpMyAdmin. To bypass this problem: just close all the opened browser
+windows and then go back to phpMyAdmin. You should be able to log in
+again.</p>
+</div>
+<div class="section" id="when-dumping-a-large-table-in-compressed-mode-i-get-a-memory-limit-error-or-a-time-limit-error">
+<span id="faq3-2"></span><h3>3.2 When dumping a large table in compressed mode, I get a memory limit error or a time limit error.<a class="headerlink" href="#when-dumping-a-large-table-in-compressed-mode-i-get-a-memory-limit-error-or-a-time-limit-error" title="Permalink to this headline">¶</a></h3>
+<p>Compressed dumps are built in memory and because of this are limited
+to php’s memory limit. For GZip/BZip2 exports this can be overcome
+since 2.5.4 using <span class="target" id="index-18"></span><a class="reference internal" href="config.html#cfg_CompressOnFly"><tt class="xref config config-option docutils literal"><span class="pre">$cfg['CompressOnFly']</span></tt></a> (enabled by default).
+Zip exports can not be handled this way, so if you need Zip files for larger
+dump, you have to use another way.</p>
+</div>
+<div class="section" id="with-innodb-tables-i-lose-foreign-key-relationships-when-i-rename-a-table-or-a-column">
+<span id="faq3-3"></span><h3>3.3 With InnoDB tables, I lose foreign key relationships when I rename a table or a column.<a class="headerlink" href="#with-innodb-tables-i-lose-foreign-key-relationships-when-i-rename-a-table-or-a-column" title="Permalink to this headline">¶</a></h3>
+<p>This is an InnoDB bug, see <<a class="reference external" href="http://bugs.mysql.com/bug.php?id=21704">http://bugs.mysql.com/bug.php?id=21704</a>>.</p>
+</div>
+<div class="section" id="i-am-unable-to-import-dumps-i-created-with-the-mysqldump-tool-bundled-with-the-mysql-server-distribution">
+<span id="faq3-4"></span><h3>3.4 I am unable to import dumps I created with the mysqldump tool bundled with the MySQL server distribution.<a class="headerlink" href="#i-am-unable-to-import-dumps-i-created-with-the-mysqldump-tool-bundled-with-the-mysql-server-distribution" title="Permalink to this headline">¶</a></h3>
+<p>The problem is that older versions of <tt class="docutils literal"><span class="pre">mysqldump</span></tt> created invalid
+comments like this:</p>
+<div class="highlight-mysql"><div class="highlight"><pre><span class="c1">-- MySQL dump 8.22</span>
+<span class="c1">--</span>
+<span class="c1">-- Host: localhost Database: database</span>
+<span class="o">-------------------------------------------------------</span><span class="c1">--</span>
+<span class="c1">-- Server version 3.23.54</span>
+</pre></div>
+</div>
+<p>The invalid part of the code is the horizontal line made of dashes
+that appears once in every dump created with mysqldump. If you want to
+run your dump you have to turn it into valid MySQL. This means, you
+have to add a whitespace after the first two dashes of the line or add
+a # before it:  <tt class="docutils literal"><span class="pre">--</span> <span class="pre">-------------------------------------------------------</span></tt> or
+<tt class="docutils literal"><span class="pre">#---------------------------------------------------------</span></tt></p>
+</div>
+<div class="section" id="when-using-nested-folders-multiple-hierarchies-are-displayed-in-a-wrong-manner">
+<span id="faq3-5"></span><h3>3.5 When using nested folders, multiple hierarchies are displayed in a wrong manner.<a class="headerlink" href="#when-using-nested-folders-multiple-hierarchies-are-displayed-in-a-wrong-manner" title="Permalink to this headline">¶</a></h3>
+<p>Please note that you should not use the separating string multiple
+times without any characters between them, or at the beginning/end of
+your table name. If you have to, think about using another
+TableSeparator or disabling that feature.</p>
+<div class="admonition-see-also admonition seealso">
+<p class="first admonition-title">See also</p>
+<p class="last"><span class="target" id="index-19"></span><a class="reference internal" href="config.html#cfg_NavigationTreeTableSeparator"><tt class="xref config config-option docutils literal"><span class="pre">$cfg['NavigationTreeTableSeparator']</span></tt></a></p>
+</div>
+</div>
+<div class="section" id="what-is-currently-not-supported-in-phpmyadmin-about-innodb">
+<span id="faq3-6"></span><h3>3.6 What is currently not supported in phpMyAdmin about InnoDB?<a class="headerlink" href="#what-is-currently-not-supported-in-phpmyadmin-about-innodb" title="Permalink to this headline">¶</a></h3>
+<p>In Relation view, being able to choose a table in another database, or
+having more than one index column in the foreign key. In Query-by-
+example (Query), automatic generation of the query LEFT JOIN from the
+foreign table.</p>
+</div>
+<div class="section" id="i-have-table-with-many-100-columns-and-when-i-try-to-browse-table-i-get-series-of-errors-like-warning-unable-to-parse-url-how-can-this-be-fixed">
+<span id="faq3-7"></span><h3>3.7 I have table with many (100+) columns and when I try to browse table I get series of errors like “Warning: unable to parse url”. How can this be fixed?<a class="headerlink" href="#i-have-table-with-many-100-columns-and-when-i-try-to-browse-table-i-get-series-of-errors-like-warning-unable-to-parse-url-how-can-this-be-fixed" title="Permalink to this headline">¶</a></h3>
+<p>Your table neither have a primary key nor an unique one, so we must
+use a long expression to identify this row. This causes problems to
+parse_url function. The workaround is to create a primary or unique
+key.</p>
+</div>
+<div class="section" id="i-cannot-use-clickable-html-forms-in-columns-where-i-put-a-mime-transformation-onto">
+<span id="faq3-8"></span><h3>3.8 I cannot use (clickable) HTML-forms in columns where I put a MIME-Transformation onto!<a class="headerlink" href="#i-cannot-use-clickable-html-forms-in-columns-where-i-put-a-mime-transformation-onto" title="Permalink to this headline">¶</a></h3>
+<p>Due to a surrounding form-container (for multi-row delete checkboxes),
+no nested forms can be put inside the table where phpMyAdmin displays
+the results. You can, however, use any form inside of a table if keep
+the parent form-container with the target to tbl_row_delete.php and
+just put your own input-elements inside. If you use a custom submit
+input field, the form will submit itself to the displaying page again,
+where you can validate the $HTTP_POST_VARS in a transformation. For
+a tutorial on how to effectively use transformations, see our <a class="reference external" href="http://www.phpmyadmin.net/home_page/docs.php">Link
+section</a> on the
+official phpMyAdmin-homepage.</p>
+</div>
+<div class="section" id="i-get-error-messages-when-using-sql-mode-ansi-for-the-mysql-server">
+<span id="faq3-9"></span><h3>3.9 I get error messages when using “–sql_mode=ANSI” for the MySQL server.<a class="headerlink" href="#i-get-error-messages-when-using-sql-mode-ansi-for-the-mysql-server" title="Permalink to this headline">¶</a></h3>
+<p>When MySQL is running in ANSI-compatibility mode, there are some major
+differences in how <a class="reference internal" href="glossary.html#term-sql"><em class="xref std std-term">SQL</em></a> is structured (see
+<<a class="reference external" href="http://dev.mysql.com/doc/mysql/en/ansi-mode.html">http://dev.mysql.com/doc/mysql/en/ansi-mode.html</a>>). Most important of all, the
+quote-character (”) is interpreted as an identifier quote character and not as
+a string quote character, which makes many internal phpMyAdmin operations into
+invalid <a class="reference internal" href="glossary.html#term-sql"><em class="xref std std-term">SQL</em></a> statements. There is no
+workaround to this behaviour.  News to this item will be posted in <a class="reference external" href="https://sourceforge.net/p/phpmyadmin/bugs/1013/">Bug report
+#1013</a>.</p>
+</div>
+<div class="section" id="homonyms-and-no-primary-key-when-the-results-of-a-select-display-more-that-one-column-with-the-same-value-for-example-select-lastname-from-employees-where-firstname-like-a-and-two-smith-values-are-displayed-if-i-click-edit-i-cannot-be-sure-that-i-am-editing-the-intended-row">
+<span id="faq3-10"></span><h3>3.10 Homonyms and no primary key: When the results of a SELECT display more that one column with the same value (for example <tt class="docutils literal"><span class="pre">SELECT</span> <span class="pre">lastname</span> <span class="pre">from</span> <span class="pre">employees</span> <span class="pre">where</span> <span class="pre">firstname</span> <span class="pre">like</span> <span class="pre">'A%'</span></tt> and two “Smith” values are display [...]
+<p>Please make sure that your table has a primary key, so that phpMyAdmin
+can use it for the Edit and Delete links.</p>
+</div>
+<div class="section" id="the-number-of-rows-for-innodb-tables-is-not-correct">
+<span id="faq3-11"></span><h3>3.11 The number of rows for InnoDB tables is not correct.<a class="headerlink" href="#the-number-of-rows-for-innodb-tables-is-not-correct" title="Permalink to this headline">¶</a></h3>
+<p>phpMyAdmin uses a quick method to get the row count, and this method only
+returns an approximate count in the case of InnoDB tables. See
+<span class="target" id="index-20"></span><a class="reference internal" href="config.html#cfg_MaxExactCount"><tt class="xref config config-option docutils literal"><span class="pre">$cfg['MaxExactCount']</span></tt></a> for a way to modify those results, but
+this could have a serious impact on performance.</p>
+</div>
+<div class="section" id="faq3-12">
+<span id="id8"></span><h3>3.12 (withdrawn).<a class="headerlink" href="#faq3-12" title="Permalink to this headline">¶</a></h3>
+</div>
+<div class="section" id="i-get-an-error-when-entering-use-followed-by-a-db-name-containing-an-hyphen">
+<span id="faq3-13"></span><h3>3.13 I get an error when entering <tt class="docutils literal"><span class="pre">USE</span></tt> followed by a db name containing an hyphen.<a class="headerlink" href="#i-get-an-error-when-entering-use-followed-by-a-db-name-containing-an-hyphen" title="Permalink to this headline">¶</a></h3>
+<p>The tests I have made with MySQL 5.1.49 shows that the API does not
+accept this syntax for the USE command.</p>
+</div>
+<div class="section" id="i-am-not-able-to-browse-a-table-when-i-don-t-have-the-right-to-select-one-of-the-columns">
+<span id="faq3-14"></span><h3>3.14 I am not able to browse a table when I don’t have the right to SELECT one of the columns.<a class="headerlink" href="#i-am-not-able-to-browse-a-table-when-i-don-t-have-the-right-to-select-one-of-the-columns" title="Permalink to this headline">¶</a></h3>
+<p>This has been a known limitation of phpMyAdmin since the beginning and
+it’s not likely to be solved in the future.</p>
+</div>
+<div class="section" id="faq3-15">
+<span id="id9"></span><h3>3.15 (withdrawn).<a class="headerlink" href="#faq3-15" title="Permalink to this headline">¶</a></h3>
+</div>
+<div class="section" id="faq3-16">
+<span id="id10"></span><h3>3.16 (withdrawn).<a class="headerlink" href="#faq3-16" title="Permalink to this headline">¶</a></h3>
+</div>
+<div class="section" id="faq3-17">
+<span id="id11"></span><h3>3.17 (withdrawn).<a class="headerlink" href="#faq3-17" title="Permalink to this headline">¶</a></h3>
+</div>
+<div class="section" id="when-i-import-a-csv-file-that-contains-multiple-tables-they-are-lumped-together-into-a-single-table">
+<span id="faq3-18"></span><h3>3.18 When I import a CSV file that contains multiple tables, they are lumped together into a single table.<a class="headerlink" href="#when-i-import-a-csv-file-that-contains-multiple-tables-they-are-lumped-together-into-a-single-table" title="Permalink to this headline">¶</a></h3>
+<p>There is no reliable way to differentiate tables in <a class="reference internal" href="glossary.html#term-csv"><em class="xref std std-term">CSV</em></a> format. For the
+time being, you will have to break apart <a class="reference internal" href="glossary.html#term-csv"><em class="xref std std-term">CSV</em></a> files containing multiple
+tables.</p>
+</div>
+<div class="section" id="when-i-import-a-file-and-have-phpmyadmin-determine-the-appropriate-data-structure-it-only-uses-int-decimal-and-varchar-types">
+<span id="faq3-19"></span><h3>3.19 When I import a file and have phpMyAdmin determine the appropriate data structure it only uses int, decimal, and varchar types.<a class="headerlink" href="#when-i-import-a-file-and-have-phpmyadmin-determine-the-appropriate-data-structure-it-only-uses-int-decimal-and-varchar-types" title="Permalink to this headline">¶</a></h3>
+<p>Currently, the import type-detection system can only assign these
+MySQL types to columns. In future, more will likely be added but for
+the time being you will have to edit the structure to your liking
+post-import.  Also, you should note the fact that phpMyAdmin will use
+the size of the largest item in any given column as the column size
+for the appropriate type. If you know you will be adding larger items
+to that column then you should manually adjust the column sizes
+accordingly. This is done for the sake of efficiency.</p>
+</div>
+</div>
+<div class="section" id="isps-multi-user-installations">
+<span id="faqmultiuser"></span><h2>ISPs, multi-user installations<a class="headerlink" href="#isps-multi-user-installations" title="Permalink to this headline">¶</a></h2>
+<div class="section" id="i-m-an-isp-can-i-setup-one-central-copy-of-phpmyadmin-or-do-i-need-to-install-it-for-each-customer">
+<span id="faq4-1"></span><h3>4.1 I’m an ISP. Can I setup one central copy of phpMyAdmin or do I need to install it for each customer?<a class="headerlink" href="#i-m-an-isp-can-i-setup-one-central-copy-of-phpmyadmin-or-do-i-need-to-install-it-for-each-customer" title="Permalink to this headline">¶</a></h3>
+<p>Since version 2.0.3, you can setup a central copy of phpMyAdmin for all your
+users. The development of this feature was kindly sponsored by NetCologne GmbH.
+This requires a properly setup MySQL user management and phpMyAdmin
+<a class="reference internal" href="glossary.html#term-http"><em class="xref std std-term">HTTP</em></a> or cookie authentication.</p>
+<div class="admonition-see-also admonition seealso">
+<p class="first admonition-title">See also</p>
+<p class="last"><a class="reference internal" href="setup.html#authentication-modes"><em>Using authentication modes</em></a></p>
+</div>
+</div>
+<div class="section" id="what-s-the-preferred-way-of-making-phpmyadmin-secure-against-evil-access">
+<span id="faq4-2"></span><h3>4.2 What’s the preferred way of making phpMyAdmin secure against evil access?<a class="headerlink" href="#what-s-the-preferred-way-of-making-phpmyadmin-secure-against-evil-access" title="Permalink to this headline">¶</a></h3>
+<p>This depends on your system. If you’re running a server which cannot be
+accessed by other people, it’s sufficient to use the directory protection
+bundled with your webserver (with Apache you can use <a class="reference internal" href="glossary.html#term-htaccess"><em class="xref std std-term">.htaccess</em></a> files,
+for example). If other people have telnet access to your server, you should use
+phpMyAdmin’s <a class="reference internal" href="glossary.html#term-http"><em class="xref std std-term">HTTP</em></a> or cookie authentication features.</p>
+<p>Suggestions:</p>
+<ul class="simple">
+<li>Your <tt class="file docutils literal"><span class="pre">config.inc.php</span></tt> file should be <tt class="docutils literal"><span class="pre">chmod</span> <span class="pre">660</span></tt>.</li>
+<li>All your phpMyAdmin files should be chown -R phpmy.apache, where phpmy
+is a user whose password is only known to you, and apache is the group
+under which Apache runs.</li>
+<li>Follow security recommendations for PHP and your webserver.</li>
+</ul>
+</div>
+<div class="section" id="i-get-errors-about-not-being-able-to-include-a-file-in-lang-or-in-libraries">
+<span id="faq4-3"></span><h3>4.3 I get errors about not being able to include a file in <em>/lang</em> or in <em>/libraries</em>.<a class="headerlink" href="#i-get-errors-about-not-being-able-to-include-a-file-in-lang-or-in-libraries" title="Permalink to this headline">¶</a></h3>
+<p>Check <tt class="file docutils literal"><span class="pre">php.ini</span></tt>, or ask your sysadmin to check it. The
+<tt class="docutils literal"><span class="pre">include_path</span></tt> must contain ”.” somewhere in it, and
+<tt class="docutils literal"><span class="pre">open_basedir</span></tt>, if used, must contain ”.” and ”./lang” to allow
+normal operation of phpMyAdmin.</p>
+</div>
+<div class="section" id="phpmyadmin-always-gives-access-denied-when-using-http-authentication">
+<span id="faq4-4"></span><h3>4.4 phpMyAdmin always gives “Access denied” when using HTTP authentication.<a class="headerlink" href="#phpmyadmin-always-gives-access-denied-when-using-http-authentication" title="Permalink to this headline">¶</a></h3>
+<p>This could happen for several reasons:</p>
+<ul class="simple">
+<li><span class="target" id="index-21"></span><a class="reference internal" href="config.html#cfg_Servers_controluser"><tt class="xref config config-option docutils literal"><span class="pre">$cfg['Servers'][$i]['controluser']</span></tt></a> and/or <span class="target" id="index-22"></span><a class="reference internal" href="config.html#cfg_Servers_controlpass"><tt class="xref config config-option docutils literal"><span class="pre">$cfg['Servers'][$i]['controlpass']</span></tt></a>  ar [...]
+<li>The username/password you specify in the login dialog are invalid.</li>
+<li>You have already setup a security mechanism for the phpMyAdmin-
+directory, eg. a <a class="reference internal" href="glossary.html#term-htaccess"><em class="xref std std-term">.htaccess</em></a> file. This would interfere with phpMyAdmin’s
+authentication, so remove it.</li>
+</ul>
+</div>
+<div class="section" id="is-it-possible-to-let-users-create-their-own-databases">
+<span id="faq4-5"></span><h3>4.5 Is it possible to let users create their own databases?<a class="headerlink" href="#is-it-possible-to-let-users-create-their-own-databases" title="Permalink to this headline">¶</a></h3>
+<p>Starting with 2.2.5, in the user management page, you can enter a
+wildcard database name for a user (for example “joe%”), and put the
+privileges you want. For example, adding <tt class="docutils literal"><span class="pre">SELECT,</span> <span class="pre">INSERT,</span> <span class="pre">UPDATE,</span>
+<span class="pre">DELETE,</span> <span class="pre">CREATE,</span> <span class="pre">DROP,</span> <span class="pre">INDEX,</span> <span class="pre">ALTER</span></tt> would let a user create/manage
+his/her database(s).</p>
+</div>
+<div class="section" id="how-can-i-use-the-host-based-authentication-additions">
+<span id="faq4-6"></span><h3>4.6 How can I use the Host-based authentication additions?<a class="headerlink" href="#how-can-i-use-the-host-based-authentication-additions" title="Permalink to this headline">¶</a></h3>
+<p>If you have existing rules from an old <a class="reference internal" href="glossary.html#term-htaccess"><em class="xref std std-term">.htaccess</em></a> file, you can take them and
+add a username between the <tt class="docutils literal"><span class="pre">'deny'</span></tt>/<tt class="docutils literal"><span class="pre">'allow'</span></tt> and <tt class="docutils literal"><span class="pre">'from'</span></tt>
+strings. Using the username wildcard of <tt class="docutils literal"><span class="pre">'%'</span></tt> would be a major
+benefit here if your installation is suited to using it. Then you can
+just add those updated lines into the
+<span class="target" id="index-23"></span><a class="reference internal" href="config.html#cfg_Servers_AllowDeny_rules"><tt class="xref config config-option docutils literal"><span class="pre">$cfg['Servers'][$i]['AllowDeny']['rules']</span></tt></a> array.</p>
+<p>If you want a pre-made sample, you can try this fragment. It stops the
+‘root’ user from logging in from any networks other than the private
+network <a class="reference internal" href="glossary.html#term-ip"><em class="xref std std-term">IP</em></a> blocks.</p>
+<div class="highlight-php"><div class="highlight"><pre><span class="x">//block root from logging in except from the private networks</span>
+<span class="x">$cfg['Servers'][$i]['AllowDeny']['order'] = 'deny,allow';</span>
+<span class="x">$cfg['Servers'][$i]['AllowDeny']['rules'] = array(</span>
+<span class="x">    'deny root from all',</span>
+<span class="x">    'allow root from localhost',</span>
+<span class="x">    'allow root from 10.0.0.0/8',</span>
+<span class="x">    'allow root from 192.168.0.0/16',</span>
+<span class="x">    'allow root from 172.16.0.0/12',</span>
+<span class="x">);</span>
+</pre></div>
+</div>
+</div>
+<div class="section" id="authentication-window-is-displayed-more-than-once-why">
+<span id="faq4-7"></span><h3>4.7 Authentication window is displayed more than once, why?<a class="headerlink" href="#authentication-window-is-displayed-more-than-once-why" title="Permalink to this headline">¶</a></h3>
+<p>This happens if you are using a <a class="reference internal" href="glossary.html#term-url"><em class="xref std std-term">URL</em></a> to start phpMyAdmin which is
+different than the one set in your <span class="target" id="index-24"></span><a class="reference internal" href="config.html#cfg_PmaAbsoluteUri"><tt class="xref config config-option docutils literal"><span class="pre">$cfg['PmaAbsoluteUri']</span></tt></a>. For
+example, a missing “www”, or entering with an <a class="reference internal" href="glossary.html#term-ip"><em class="xref std std-term">IP</em></a> address while a domain
+name is defined in the config file.</p>
+</div>
+<div class="section" id="which-parameters-can-i-use-in-the-url-that-starts-phpmyadmin">
+<span id="faq4-8"></span><h3>4.8 Which parameters can I use in the URL that starts phpMyAdmin?<a class="headerlink" href="#which-parameters-can-i-use-in-the-url-that-starts-phpmyadmin" title="Permalink to this headline">¶</a></h3>
+<p>When starting phpMyAdmin, you can use the <tt class="docutils literal"><span class="pre">db</span></tt>, <tt class="docutils literal"><span class="pre">pma_username</span></tt>,
+<tt class="docutils literal"><span class="pre">pma_password</span></tt> and <tt class="docutils literal"><span class="pre">server</span></tt> parameters. This last one can contain
+either the numeric host index (from <tt class="docutils literal"><span class="pre">$i</span></tt> of the configuration file)
+or one of the host names present in the configuration file. Using
+<tt class="docutils literal"><span class="pre">pma_username</span></tt> and <tt class="docutils literal"><span class="pre">pma_password</span></tt> has been tested along with the
+usage of ‘cookie’ <tt class="docutils literal"><span class="pre">auth_type</span></tt>.</p>
+</div>
+</div>
+<div class="section" id="browsers-or-client-os">
+<span id="faqbrowsers"></span><h2>Browsers or client OS<a class="headerlink" href="#browsers-or-client-os" title="Permalink to this headline">¶</a></h2>
+<div class="section" id="i-get-an-out-of-memory-error-and-my-controls-are-non-functional-when-trying-to-create-a-table-with-more-than-14-columns">
+<span id="faq5-1"></span><h3>5.1 I get an out of memory error, and my controls are non-functional, when trying to create a table with more than 14 columns.<a class="headerlink" href="#i-get-an-out-of-memory-error-and-my-controls-are-non-functional-when-trying-to-create-a-table-with-more-than-14-columns" title="Permalink to this headline">¶</a></h3>
+<p>We could reproduce this problem only under Win98/98SE. Testing under
+WinNT4 or Win2K, we could easily create more than 60 columns.  A
+workaround is to create a smaller number of columns, then come back to
+your table properties and add the other columns.</p>
+</div>
+<div class="section" id="with-xitami-2-5b4-phpmyadmin-won-t-process-form-fields">
+<span id="faq5-2"></span><h3>5.2 With Xitami 2.5b4, phpMyAdmin won’t process form fields.<a class="headerlink" href="#with-xitami-2-5b4-phpmyadmin-won-t-process-form-fields" title="Permalink to this headline">¶</a></h3>
+<p>This is not a phpMyAdmin problem but a Xitami known bug: you’ll face
+it with each script/website that use forms. Upgrade or downgrade your
+Xitami server.</p>
+</div>
+<div class="section" id="i-have-problems-dumping-tables-with-konqueror-phpmyadmin-2-2-2">
+<span id="faq5-3"></span><h3>5.3 I have problems dumping tables with Konqueror (phpMyAdmin 2.2.2).<a class="headerlink" href="#i-have-problems-dumping-tables-with-konqueror-phpmyadmin-2-2-2" title="Permalink to this headline">¶</a></h3>
+<p>With Konqueror 2.1.1: plain dumps, zip and GZip dumps work ok, except
+that the proposed file name for the dump is always ‘tbl_dump.php’.
+Bzip2 dumps don’t seem to work. With Konqueror 2.2.1: plain dumps
+work; zip dumps are placed into the user’s temporary directory, so
+they must be moved before closing Konqueror, or else they disappear.
+GZip dumps give an error message. Testing needs to be done for
+Konqueror 2.2.2.</p>
+</div>
+<div class="section" id="i-can-t-use-the-cookie-authentication-mode-because-internet-explorer-never-stores-the-cookies">
+<span id="faq5-4"></span><h3>5.4 I can’t use the cookie authentication mode because Internet Explorer never stores the cookies.<a class="headerlink" href="#i-can-t-use-the-cookie-authentication-mode-because-internet-explorer-never-stores-the-cookies" title="Permalink to this headline">¶</a></h3>
+<p>MS Internet Explorer seems to be really buggy about cookies, at least
+till version 6.</p>
+</div>
+<div class="section" id="in-internet-explorer-5-0-i-get-javascript-errors-when-browsing-my-rows">
+<span id="faq5-5"></span><h3>5.5 In Internet Explorer 5.0, I get JavaScript errors when browsing my rows.<a class="headerlink" href="#in-internet-explorer-5-0-i-get-javascript-errors-when-browsing-my-rows" title="Permalink to this headline">¶</a></h3>
+<p>Upgrade to at least Internet Explorer 5.5 SP2.</p>
+</div>
+<div class="section" id="in-internet-explorer-5-0-5-5-or-6-0-i-get-an-error-like-page-not-found-when-trying-to-modify-a-row-in-a-table-with-many-columns-or-with-a-text-column">
+<span id="faq5-6"></span><h3>5.6 In Internet Explorer 5.0, 5.5 or 6.0, I get an error (like “Page not found”) when trying to modify a row in a table with many columns, or with a text column.<a class="headerlink" href="#in-internet-explorer-5-0-5-5-or-6-0-i-get-an-error-like-page-not-found-when-trying-to-modify-a-row-in-a-table-with-many-columns-or-with-a-text-column" title="Permalink to this headline">¶</a></h3>
+<p>Your table neither have a primary key nor an unique one, so we must use a long
+<a class="reference internal" href="glossary.html#term-url"><em class="xref std std-term">URL</em></a> to identify this row. There is a limit on the length of the
+<a class="reference internal" href="glossary.html#term-url"><em class="xref std std-term">URL</em></a> in those browsers, and this not happen in Netscape, for example.
+The workaround is to create a primary or unique key, or use another browser.</p>
+</div>
+<div class="section" id="i-refresh-reload-my-browser-and-come-back-to-the-welcome-page">
+<span id="faq5-7"></span><h3>5.7 I refresh (reload) my browser, and come back to the welcome page.<a class="headerlink" href="#i-refresh-reload-my-browser-and-come-back-to-the-welcome-page" title="Permalink to this headline">¶</a></h3>
+<p>Some browsers support right-clicking into the frame you want to
+refresh, just do this in the right frame.</p>
+</div>
+<div class="section" id="with-mozilla-0-9-7-i-have-problems-sending-a-query-modified-in-the-query-box">
+<span id="faq5-8"></span><h3>5.8 With Mozilla 0.9.7 I have problems sending a query modified in the query box.<a class="headerlink" href="#with-mozilla-0-9-7-i-have-problems-sending-a-query-modified-in-the-query-box" title="Permalink to this headline">¶</a></h3>
+<p>Looks like a Mozilla bug: 0.9.6 was OK. We will keep an eye on future
+Mozilla versions.</p>
+</div>
+<div class="section" id="with-mozilla-0-9-to-1-0-and-netscape-7-0-pr1-i-can-t-type-a-whitespace-in-the-sql-query-edit-area-the-page-scrolls-down">
+<span id="faq5-9"></span><h3>5.9 With Mozilla 0.9.? to 1.0 and Netscape 7.0-PR1 I can’t type a whitespace in the SQL-Query edit area: the page scrolls down.<a class="headerlink" href="#with-mozilla-0-9-to-1-0-and-netscape-7-0-pr1-i-can-t-type-a-whitespace-in-the-sql-query-edit-area-the-page-scrolls-down" title="Permalink to this headline">¶</a></h3>
+<p>This is a Mozilla bug (see bug #26882 at <a class="reference external" href="http://bugzilla.mozilla.org/">BugZilla</a>).</p>
+</div>
+<div class="section" id="with-netscape-4-75-i-get-empty-rows-between-each-row-of-data-in-a-csv-exported-file">
+<span id="faq5-10"></span><h3>5.10 With Netscape 4.75 I get empty rows between each row of data in a CSV exported file.<a class="headerlink" href="#with-netscape-4-75-i-get-empty-rows-between-each-row-of-data-in-a-csv-exported-file" title="Permalink to this headline">¶</a></h3>
+<p>This is a known Netscape 4.75 bug: it adds some line feeds when
+exporting data in octet-stream mode. Since we can’t detect the
+specific Netscape version, we cannot workaround this bug.</p>
+</div>
+<div class="section" id="extended-ascii-characters-like-german-umlauts-are-displayed-wrong">
+<span id="faq5-11"></span><h3>5.11 Extended-ASCII characters like German umlauts are displayed wrong.<a class="headerlink" href="#extended-ascii-characters-like-german-umlauts-are-displayed-wrong" title="Permalink to this headline">¶</a></h3>
+<p>Please ensure that you have set your browser’s character set to the
+one of the language file you have selected on phpMyAdmin’s start page.
+Alternatively, you can try the auto detection mode that is supported
+by the recent versions of the most browsers.</p>
+</div>
+<div class="section" id="mac-os-x-safari-browser-changes-special-characters-to">
+<span id="faq5-12"></span><h3>5.12 Mac OS X Safari browser changes special characters to ”?”.<a class="headerlink" href="#mac-os-x-safari-browser-changes-special-characters-to" title="Permalink to this headline">¶</a></h3>
+<p>This issue has been reported by a <a class="reference internal" href="glossary.html#term-mac-os-x"><em class="xref std std-term">Mac OS X</em></a> user, who adds that Chimera,
+Netscape and Mozilla do not have this problem.</p>
+</div>
+<div class="section" id="with-internet-explorer-5-5-or-6-and-http-authentication-type-i-cannot-manage-two-servers-i-log-in-to-the-first-one-then-the-other-one-but-if-i-switch-back-to-the-first-i-have-to-log-in-on-each-operation">
+<span id="faq5-13"></span><h3>5.13 With Internet Explorer 5.5 or 6, and HTTP authentication type, I cannot manage two servers: I log in to the first one, then the other one, but if I switch back to the first, I have to log in on each operation.<a class="headerlink" href="#with-internet-explorer-5-5-or-6-and-http-authentication-type-i-cannot-manage-two-servers-i-log-in-to-the-first-one-then-the-other-one-but-if-i-switch-back-to-the-first-i-have-to-log-in-on-each-operation" title="Permalin [...]
+<p>This is a bug in Internet Explorer, other browsers do not behave this
+way.</p>
+</div>
+<div class="section" id="using-opera6-i-can-manage-to-get-to-the-authentication-but-nothing-happens-after-that-only-a-blank-screen">
+<span id="faq5-14"></span><h3>5.14 Using Opera6, I can manage to get to the authentication, but nothing happens after that, only a blank screen.<a class="headerlink" href="#using-opera6-i-can-manage-to-get-to-the-authentication-but-nothing-happens-after-that-only-a-blank-screen" title="Permalink to this headline">¶</a></h3>
+<p>Please upgrade to Opera7 at least.</p>
+</div>
+<div class="section" id="i-have-display-problems-with-safari">
+<span id="faq5-15"></span><h3>5.15 I have display problems with Safari.<a class="headerlink" href="#i-have-display-problems-with-safari" title="Permalink to this headline">¶</a></h3>
+<p>Please upgrade to at least version 1.2.3.</p>
+</div>
+<div class="section" id="with-internet-explorer-i-get-access-is-denied-javascript-errors-or-i-cannot-make-phpmyadmin-work-under-windows">
+<span id="faq5-16"></span><h3>5.16 With Internet Explorer, I get “Access is denied” Javascript errors. Or I cannot make phpMyAdmin work under Windows.<a class="headerlink" href="#with-internet-explorer-i-get-access-is-denied-javascript-errors-or-i-cannot-make-phpmyadmin-work-under-windows" title="Permalink to this headline">¶</a></h3>
+<p>Please check the following points:</p>
+<ul class="simple">
+<li>Maybe you have defined your <span class="target" id="index-25"></span><a class="reference internal" href="config.html#cfg_PmaAbsoluteUri"><tt class="xref config config-option docutils literal"><span class="pre">$cfg['PmaAbsoluteUri']</span></tt></a> setting in
+<tt class="file docutils literal"><span class="pre">config.inc.php</span></tt> to an <a class="reference internal" href="glossary.html#term-ip"><em class="xref std std-term">IP</em></a> address and you are starting phpMyAdmin
+with a <a class="reference internal" href="glossary.html#term-url"><em class="xref std std-term">URL</em></a> containing a domain name, or the reverse situation.</li>
+<li>Security settings in IE and/or Microsoft Security Center are too high,
+thus blocking scripts execution.</li>
+<li>The Windows Firewall is blocking Apache and MySQL. You must allow
+<a class="reference internal" href="glossary.html#term-http"><em class="xref std std-term">HTTP</em></a> ports (80 or 443) and MySQL
+port (usually 3306) in the “in” and “out” directions.</li>
+</ul>
+</div>
+<div class="section" id="with-firefox-i-cannot-delete-rows-of-data-or-drop-a-database">
+<span id="faq5-17"></span><h3>5.17 With Firefox, I cannot delete rows of data or drop a database.<a class="headerlink" href="#with-firefox-i-cannot-delete-rows-of-data-or-drop-a-database" title="Permalink to this headline">¶</a></h3>
+<p>Many users have confirmed that the Tabbrowser Extensions plugin they
+installed in their Firefox is causing the problem.</p>
+</div>
+<div class="section" id="with-konqueror-4-2-x-an-invalid-limit-clause-is-generated-when-i-browse-a-table">
+<span id="faq5-18"></span><h3>5.18 With Konqueror 4.2.x an invalid <tt class="docutils literal"><span class="pre">LIMIT</span></tt> clause is generated when I browse a table.<a class="headerlink" href="#with-konqueror-4-2-x-an-invalid-limit-clause-is-generated-when-i-browse-a-table" title="Permalink to this headline">¶</a></h3>
+<p>This happens only when both of these conditions are met: using the
+<tt class="docutils literal"><span class="pre">http</span></tt> authentication mode and <tt class="docutils literal"><span class="pre">register_globals</span></tt> being set to
+<tt class="docutils literal"><span class="pre">On</span></tt> on the server. It seems to be a browser-specific problem;
+meanwhile use the <tt class="docutils literal"><span class="pre">cookie</span></tt> authentication mode.</p>
+</div>
+<div class="section" id="i-get-javascript-errors-in-my-browser">
+<span id="faq5-19"></span><h3>5.19 I get JavaScript errors in my browser.<a class="headerlink" href="#i-get-javascript-errors-in-my-browser" title="Permalink to this headline">¶</a></h3>
+<p>Issues have been reported with some combinations of browser
+extensions. To troubleshoot, disable all extensions then clear your
+browser cache to see if the problem goes away.</p>
+</div>
+</div>
+<div class="section" id="using-phpmyadmin">
+<span id="faqusing"></span><h2>Using phpMyAdmin<a class="headerlink" href="#using-phpmyadmin" title="Permalink to this headline">¶</a></h2>
+<div class="section" id="i-can-t-insert-new-rows-into-a-table-i-can-t-create-a-table-mysql-brings-up-a-sql-error">
+<span id="faq6-1"></span><h3>6.1 I can’t insert new rows into a table / I can’t create a table - MySQL brings up a SQL error.<a class="headerlink" href="#i-can-t-insert-new-rows-into-a-table-i-can-t-create-a-table-mysql-brings-up-a-sql-error" title="Permalink to this headline">¶</a></h3>
+<p>Examine the <a class="reference internal" href="glossary.html#term-sql"><em class="xref std std-term">SQL</em></a> error with care.
+Often the problem is caused by specifying a wrong column-type. Common
+errors include:</p>
+<ul class="simple">
+<li>Using <tt class="docutils literal"><span class="pre">VARCHAR</span></tt> without a size argument</li>
+<li>Using <tt class="docutils literal"><span class="pre">TEXT</span></tt> or <tt class="docutils literal"><span class="pre">BLOB</span></tt> with a size argument</li>
+</ul>
+<p>Also, look at the syntax chapter in the MySQL manual to confirm that
+your syntax is correct.</p>
+</div>
+<div class="section" id="when-i-create-a-table-i-set-an-index-for-two-columns-and-phpmyadmin-generates-only-one-index-with-those-two-columns">
+<span id="faq6-2"></span><h3>6.2 When I create a table, I set an index for two columns and phpMyAdmin generates only one index with those two columns.<a class="headerlink" href="#when-i-create-a-table-i-set-an-index-for-two-columns-and-phpmyadmin-generates-only-one-index-with-those-two-columns" title="Permalink to this headline">¶</a></h3>
+<p>This is the way to create a multi-columns index. If you want two
+indexes, create the first one when creating the table, save, then
+display the table properties and click the Index link to create the
+other index.</p>
+</div>
+<div class="section" id="how-can-i-insert-a-null-value-into-my-table">
+<span id="faq6-3"></span><h3>6.3 How can I insert a null value into my table?<a class="headerlink" href="#how-can-i-insert-a-null-value-into-my-table" title="Permalink to this headline">¶</a></h3>
+<p>Since version 2.2.3, you have a checkbox for each column that can be
+null. Before 2.2.3, you had to enter “null”, without the quotes, as
+the column’s value. Since version 2.5.5, you have to use the checkbox
+to get a real NULL value, so if you enter “NULL” this means you want a
+literal NULL in the column, and not a NULL value (this works in PHP4).</p>
+</div>
+<div class="section" id="how-can-i-backup-my-database-or-table">
+<span id="faq6-4"></span><h3>6.4 How can I backup my database or table?<a class="headerlink" href="#how-can-i-backup-my-database-or-table" title="Permalink to this headline">¶</a></h3>
+<p>Click on a database or table name in the navigation panel, the properties will
+be displayed. Then on the menu, click “Export”, you can dump the structure, the
+data, or both. This will generate standard <a class="reference internal" href="glossary.html#term-sql"><em class="xref std std-term">SQL</em></a> statements that can be
+used to recreate your database/table.  You will need to choose “Save as file”,
+so that phpMyAdmin can transmit the resulting dump to your station.  Depending
+on your PHP configuration, you will see options to compress the dump. See also
+the <span class="target" id="index-26"></span><a class="reference internal" href="config.html#cfg_ExecTimeLimit"><tt class="xref config config-option docutils literal"><span class="pre">$cfg['ExecTimeLimit']</span></tt></a> configuration variable. For
+additional help on this subject, look for the word “dump” in this document.</p>
+</div>
+<div class="section" id="how-can-i-restore-upload-my-database-or-table-using-a-dump-how-can-i-run-a-sql-file">
+<span id="faq6-5"></span><h3>6.5 How can I restore (upload) my database or table using a dump? How can I run a ”.sql” file?<a class="headerlink" href="#how-can-i-restore-upload-my-database-or-table-using-a-dump-how-can-i-run-a-sql-file" title="Permalink to this headline">¶</a></h3>
+<p>Click on a database name in the navigation panel, the properties will
+be displayed. Select “Import” from the list of tabs in the right–hand
+frame (or “<a class="reference internal" href="glossary.html#term-sql"><em class="xref std std-term">SQL</em></a>” if your phpMyAdmin
+version is previous to 2.7.0). In the “Location of the text file”
+section, type in the path to your dump filename, or use the Browse
+button. Then click Go.  With version 2.7.0, the import engine has been
+re–written, if possible it is suggested that you upgrade to take
+advantage of the new features.  For additional help on this subject,
+look for the word “upload” in this document.</p>
+</div>
+<div class="section" id="how-can-i-use-the-relation-table-in-query-by-example">
+<span id="faq6-6"></span><h3>6.6 How can I use the relation table in Query-by-example?<a class="headerlink" href="#how-can-i-use-the-relation-table-in-query-by-example" title="Permalink to this headline">¶</a></h3>
+<p>Here is an example with the tables persons, towns and countries, all
+located in the database mydb. If you don’t have a <tt class="docutils literal"><span class="pre">pma__relation</span></tt>
+table, create it as explained in the configuration section. Then
+create the example tables:</p>
+<div class="highlight-mysql"><div class="highlight"><pre><span class="k">CREATE</span> <span class="k">TABLE</span> <span class="nf">REL_countries</span> <span class="p">(</span>
+<span class="n">country_code</span> <span class="kt">char</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span> <span class="k">NOT</span> <span class="no">NULL</span> <span class="k">default</span> <span class="s1">''</span><span class="p">,</span>
+<span class="n">description</span> <span class="kt">varchar</span><span class="p">(</span><span class="mi">10</span><span class="p">)</span> <span class="k">NOT</span> <span class="no">NULL</span> <span class="k">default</span> <span class="s1">''</span><span class="p">,</span>
+<span class="k">PRIMARY</span> <span class="k">KEY</span> <span class="p">(</span><span class="n">country_code</span><span class="p">)</span>
+<span class="p">)</span> <span class="n">TYPE</span><span class="o">=</span><span class="n">MyISAM</span><span class="p">;</span>
+
+<span class="k">INSERT</span> <span class="k">INTO</span> <span class="n">REL_countries</span> <span class="k">VALUES</span> <span class="p">(</span><span class="s1">'C'</span><span class="p">,</span> <span class="s1">'Canada'</span><span class="p">);</span>
+
+<span class="k">CREATE</span> <span class="k">TABLE</span> <span class="nf">REL_persons</span> <span class="p">(</span>
+<span class="n">id</span> <span class="kt">tinyint</span><span class="p">(</span><span class="mi">4</span><span class="p">)</span> <span class="k">NOT</span> <span class="no">NULL</span> <span class="kp">auto_increment</span><span class="p">,</span>
+<span class="n">person_name</span> <span class="kt">varchar</span><span class="p">(</span><span class="mi">32</span><span class="p">)</span> <span class="k">NOT</span> <span class="no">NULL</span> <span class="k">default</span> <span class="s1">''</span><span class="p">,</span>
+<span class="n">town_code</span> <span class="kt">varchar</span><span class="p">(</span><span class="mi">5</span><span class="p">)</span> <span class="k">default</span> <span class="s1">'0'</span><span class="p">,</span>
+<span class="n">country_code</span> <span class="kt">char</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span> <span class="k">NOT</span> <span class="no">NULL</span> <span class="k">default</span> <span class="s1">''</span><span class="p">,</span>
+<span class="k">PRIMARY</span> <span class="k">KEY</span> <span class="p">(</span><span class="n">id</span><span class="p">)</span>
+<span class="p">)</span> <span class="n">TYPE</span><span class="o">=</span><span class="n">MyISAM</span><span class="p">;</span>
+
+<span class="k">INSERT</span> <span class="k">INTO</span> <span class="n">REL_persons</span> <span class="k">VALUES</span> <span class="p">(</span><span class="mi">11</span><span class="p">,</span> <span class="s1">'Marc'</span><span class="p">,</span> <span class="s1">'S'</span><span class="p">,</span> <span class="s1">''</span><span class="p">);</span>
+<span class="k">INSERT</span> <span class="k">INTO</span> <span class="n">REL_persons</span> <span class="k">VALUES</span> <span class="p">(</span><span class="mi">15</span><span class="p">,</span> <span class="s1">'Paul'</span><span class="p">,</span> <span class="s1">'S'</span><span class="p">,</span> <span class="s1">'C'</span><span class="p">);</span>
+
+<span class="k">CREATE</span> <span class="k">TABLE</span> <span class="nf">REL_towns</span> <span class="p">(</span>
+<span class="n">town_code</span> <span class="kt">varchar</span><span class="p">(</span><span class="mi">5</span><span class="p">)</span> <span class="k">NOT</span> <span class="no">NULL</span> <span class="k">default</span> <span class="s1">'0'</span><span class="p">,</span>
+<span class="n">description</span> <span class="kt">varchar</span><span class="p">(</span><span class="mi">30</span><span class="p">)</span> <span class="k">NOT</span> <span class="no">NULL</span> <span class="k">default</span> <span class="s1">''</span><span class="p">,</span>
+<span class="k">PRIMARY</span> <span class="k">KEY</span> <span class="p">(</span><span class="n">town_code</span><span class="p">)</span>
+<span class="p">)</span> <span class="n">TYPE</span><span class="o">=</span><span class="n">MyISAM</span><span class="p">;</span>
+
+<span class="k">INSERT</span> <span class="k">INTO</span> <span class="n">REL_towns</span> <span class="k">VALUES</span> <span class="p">(</span><span class="s1">'S'</span><span class="p">,</span> <span class="s1">'Sherbrooke'</span><span class="p">);</span>
+<span class="k">INSERT</span> <span class="k">INTO</span> <span class="n">REL_towns</span> <span class="k">VALUES</span> <span class="p">(</span><span class="s1">'M'</span><span class="p">,</span> <span class="s1">'Montréal'</span><span class="p">);</span>
+</pre></div>
+</div>
+<p>To setup appropriate links and display information:</p>
+<ul class="simple">
+<li>on table “REL_persons” click Structure, then Relation view</li>
+<li>in Links, for “town_code” choose “REL_towns->code”</li>
+<li>in Links, for “country_code” choose “REL_countries->country_code”</li>
+<li>on table “REL_towns” click Structure, then Relation view</li>
+<li>in “Choose column to display”, choose “description”</li>
+<li>repeat the two previous steps for table “REL_countries”</li>
+</ul>
+<p>Then test like this:</p>
+<ul class="simple">
+<li>Click on your db name in the navigation panel</li>
+<li>Choose “Query”</li>
+<li>Use tables: persons, towns, countries</li>
+<li>Click “Update query”</li>
+<li>In the columns row, choose persons.person_name and click the “Show”
+tickbox</li>
+<li>Do the same for towns.description and countries.descriptions in the
+other 2 columns</li>
+<li>Click “Update query” and you will see in the query box that the
+correct joins have been generated</li>
+<li>Click “Submit query”</li>
+</ul>
+</div>
+<div class="section" id="how-can-i-use-the-display-column-feature">
+<span id="faqdisplay"></span><h3>6.7 How can I use the “display column” feature?<a class="headerlink" href="#how-can-i-use-the-display-column-feature" title="Permalink to this headline">¶</a></h3>
+<p>Starting from the previous example, create the <tt class="docutils literal"><span class="pre">pma__table_info</span></tt> as
+explained in the configuration section, then browse your persons
+table, and move the mouse over a town code or country code.  See also
+<a class="reference internal" href="#faq6-21"><em>6.21 In edit/insert mode, how can I see a list of possible values for a column, based on some foreign table?</em></a> for an additional feature that “display column”
+enables: drop-down list of possible values.</p>
+</div>
+<div class="section" id="how-can-i-produce-a-pdf-schema-of-my-database">
+<span id="faqpdf"></span><h3>6.8 How can I produce a PDF schema of my database?<a class="headerlink" href="#how-can-i-produce-a-pdf-schema-of-my-database" title="Permalink to this headline">¶</a></h3>
+<p>First the configuration variables “relation”, “table_coords” and
+“pdf_pages” have to be filled in.  Then you need to think about your
+schema layout. Which tables will go on which pages?</p>
+<ul class="simple">
+<li>Select your database in the navigation panel.</li>
+<li>Choose “Operations” in the navigation bar at the top.</li>
+<li>Choose “Edit <a class="reference internal" href="glossary.html#term-pdf"><em class="xref std std-term">PDF</em></a> Pages” near the
+bottom of the page.</li>
+<li>Enter a name for the first <a class="reference internal" href="glossary.html#term-pdf"><em class="xref std std-term">PDF</em></a> page
+and click Go. If you like, you can use the “automatic layout,” which
+will put all your linked tables onto the new page.</li>
+<li>Select the name of the new page (making sure the Edit radio button is
+selected) and click Go.</li>
+<li>Select a table from the list, enter its coordinates and click Save.
+Coordinates are relative; your diagram will be automatically scaled to
+fit the page. When initially placing tables on the page, just pick any
+coordinates – say, 50x50. After clicking Save, you can then use the
+<a class="reference internal" href="#wysiwyg"><em>6.28 How can I easily edit relational schema for export?</em></a> to position the element correctly.</li>
+<li>When you’d like to look at your <a class="reference internal" href="glossary.html#term-pdf"><em class="xref std std-term">PDF</em></a>, first be sure to click the Save
+button beneath the list of tables and coordinates, to save any changes you
+made there. Then scroll all the way down, select the <a class="reference internal" href="glossary.html#term-pdf"><em class="xref std std-term">PDF</em></a> options you
+want, and click Go.</li>
+<li>Internet Explorer for Windows may suggest an incorrect filename when
+you try to save a generated <a class="reference internal" href="glossary.html#term-pdf"><em class="xref std std-term">PDF</em></a>.
+When saving a generated <a class="reference internal" href="glossary.html#term-pdf"><em class="xref std std-term">PDF</em></a>, be
+sure that the filename ends in ”.pdf”, for example “schema.pdf”.
+Browsers on other operating systems, and other browsers on Windows, do
+not have this problem.</li>
+</ul>
+</div>
+<div class="section" id="phpmyadmin-is-changing-the-type-of-one-of-my-columns">
+<span id="faq6-9"></span><h3>6.9 phpMyAdmin is changing the type of one of my columns!<a class="headerlink" href="#phpmyadmin-is-changing-the-type-of-one-of-my-columns" title="Permalink to this headline">¶</a></h3>
+<p>No, it’s MySQL that is doing <a class="reference external" href="http://dev.mysql.com/doc/en/silent-column-changes.html">silent column type changing</a>.</p>
+</div>
+<div class="section" id="when-creating-a-privilege-what-happens-with-underscores-in-the-database-name">
+<span id="underscore"></span><h3>6.10 When creating a privilege, what happens with underscores in the database name?<a class="headerlink" href="#when-creating-a-privilege-what-happens-with-underscores-in-the-database-name" title="Permalink to this headline">¶</a></h3>
+<p>If you do not put a backslash before the underscore, this is a
+wildcard grant, and the underscore means “any character”. So, if the
+database name is “john_db”, the user would get rights to john1db,
+john2db ... If you put a backslash before the underscore, it means
+that the database name will have a real underscore.</p>
+</div>
+<div class="section" id="what-is-the-curious-symbol-o-in-the-statistics-pages">
+<span id="faq6-11"></span><h3>6.11 What is the curious symbol ø in the statistics pages?<a class="headerlink" href="#what-is-the-curious-symbol-o-in-the-statistics-pages" title="Permalink to this headline">¶</a></h3>
+<p>It means “average”.</p>
+</div>
+<div class="section" id="i-want-to-understand-some-export-options">
+<span id="faqexport"></span><h3>6.12 I want to understand some Export options.<a class="headerlink" href="#i-want-to-understand-some-export-options" title="Permalink to this headline">¶</a></h3>
+<p><strong>Structure:</strong></p>
+<ul class="simple">
+<li>“Add DROP TABLE” will add a line telling MySQL to <a class="reference external" href="http://dev.mysql.com/doc/mysql/en/drop-table.html">drop the table</a>, if it already
+exists during the import. It does NOT drop the table after your
+export, it only affects the import file.</li>
+<li>“If Not Exists” will only create the table if it doesn’t exist.
+Otherwise, you may get an error if the table name exists but has a
+different structure.</li>
+<li>“Add AUTO_INCREMENT value” ensures that AUTO_INCREMENT value (if
+any) will be included in backup.</li>
+<li>“Enclose table and column names with backquotes” ensures that column
+and table names formed with special characters are protected.</li>
+<li>“Add into comments” includes column comments, relations, and MIME
+types set in the pmadb in the dump as <a class="reference internal" href="glossary.html#term-sql"><em class="xref std std-term">SQL</em></a> comments
+(<em>/* xxx */</em>).</li>
+</ul>
+<p><strong>Data:</strong></p>
+<ul class="simple">
+<li>“Complete inserts” adds the column names on every INSERT command, for
+better documentation (but resulting file is bigger).</li>
+<li>“Extended inserts” provides a shorter dump file by using only once the
+INSERT verb and the table name.</li>
+<li>“Delayed inserts” are best explained in the <a class="reference external" href="http://dev.mysql.com/doc/mysql/en/insert-delayed.html">MySQL manual - INSERT DELAYED Syntax</a>.</li>
+<li>“Ignore inserts” treats errors as a warning instead. Again, more info
+is provided in the <a class="reference external" href="http://dev.mysql.com/doc/mysql/en/insert.html">MySQL manual - INSERT Syntax</a>, but basically with
+this selected, invalid values are adjusted and inserted rather than
+causing the entire statement to fail.</li>
+</ul>
+</div>
+<div class="section" id="i-would-like-to-create-a-database-with-a-dot-in-its-name">
+<span id="faq6-13"></span><h3>6.13 I would like to create a database with a dot in its name.<a class="headerlink" href="#i-would-like-to-create-a-database-with-a-dot-in-its-name" title="Permalink to this headline">¶</a></h3>
+<p>This is a bad idea, because in MySQL the syntax “database.table” is
+the normal way to reference a database and table name. Worse, MySQL
+will usually let you create a database with a dot, but then you cannot
+work with it, nor delete it.</p>
+</div>
+<div class="section" id="how-do-i-set-up-the-sql-validator">
+<span id="faqsqlvalidator"></span><h3>6.14 How do I set up the SQL Validator?<a class="headerlink" href="#how-do-i-set-up-the-sql-validator" title="Permalink to this headline">¶</a></h3>
+<p>To use SQL Validator, you need PHP with <a class="reference internal" href="glossary.html#term-xml"><em class="xref std std-term">XML</em></a>, <a class="reference internal" href="glossary.html#term-pcre"><em class="xref std std-term">PCRE</em></a> and
+<a class="reference internal" href="glossary.html#term-pear"><em class="xref std std-term">PEAR</em></a> support. In addition you need a <a class="reference internal" href="glossary.html#term-soap"><em class="xref std std-term">SOAP</em></a> support, either as a
+PHP extension or as a PEAR SOAP module.</p>
+<p>To install <a class="reference internal" href="glossary.html#term-pear"><em class="xref std std-term">PEAR</em></a> <a class="reference internal" href="glossary.html#term-soap"><em class="xref std std-term">SOAP</em></a> module, run <strong class="command">pear install
+Net_Socket Net_URL HTTP_Request Mail_Mime Net_DIME SOAP</strong> to get the necessary
+<a class="reference internal" href="glossary.html#term-pear"><em class="xref std std-term">PEAR</em></a> modules for usage.</p>
+<p>If you use the Validator, you should be aware that any <a class="reference internal" href="glossary.html#term-sql"><em class="xref std std-term">SQL</em></a> statement
+you submit will be stored anonymously (database/table/column names, strings,
+numbers replaced with generic values). The Mimer <a class="reference internal" href="glossary.html#term-sql"><em class="xref std std-term">SQL</em></a> Validator itself,
+is © 2001 Upright Database Technology. We utilize it as free SOAP service.</p>
+</div>
+<div class="section" id="i-want-to-add-a-blob-column-and-put-an-index-on-it-but-mysql-says-blob-column-used-in-key-specification-without-a-key-length">
+<span id="faq6-15"></span><h3>6.15 I want to add a BLOB column and put an index on it, but MySQL says “BLOB column ‘...’ used in key specification without a key length”.<a class="headerlink" href="#i-want-to-add-a-blob-column-and-put-an-index-on-it-but-mysql-says-blob-column-used-in-key-specification-without-a-key-length" title="Permalink to this headline">¶</a></h3>
+<p>The right way to do this, is to create the column without any indexes,
+then display the table structure and use the “Create an index” dialog.
+On this page, you will be able to choose your BLOB column, and set a
+size to the index, which is the condition to create an index on a BLOB
+column.</p>
+</div>
+<div class="section" id="how-can-i-simply-move-in-page-with-plenty-editing-fields">
+<span id="faq6-16"></span><h3>6.16 How can I simply move in page with plenty editing fields?<a class="headerlink" href="#how-can-i-simply-move-in-page-with-plenty-editing-fields" title="Permalink to this headline">¶</a></h3>
+<p>You can use <tt class="kbd docutils literal"><span class="pre">Ctrl+arrows</span></tt> (<tt class="kbd docutils literal"><span class="pre">Option+Arrows</span></tt> in Safari) for moving on
+most pages with many editing fields (table structure changes, row editing,
+etc.).</p>
+</div>
+<div class="section" id="transformations-i-can-t-enter-my-own-mimetype-wtf-is-this-feature-then-useful-for">
+<span id="faq6-17"></span><h3>6.17 Transformations: I can’t enter my own mimetype! WTF is this feature then useful for?<a class="headerlink" href="#transformations-i-can-t-enter-my-own-mimetype-wtf-is-this-feature-then-useful-for" title="Permalink to this headline">¶</a></h3>
+<p>Slow down :). Defining mimetypes is of no use, if you can’t put
+transformations on them. Otherwise you could just put a comment on the
+column. Because entering your own mimetype will cause serious syntax
+checking issues and validation, this introduces a high-risk false-
+user-input situation. Instead you have to initialize mimetypes using
+functions or empty mimetype definitions.</p>
+<p>Plus, you have a whole overview of available mimetypes. Who knows all those
+mimetypes by heart so he/she can enter it at will?</p>
+</div>
+<div class="section" id="bookmarks-where-can-i-store-bookmarks-why-can-t-i-see-any-bookmarks-below-the-query-box-what-is-this-variable-for">
+<span id="faqbookmark"></span><h3>6.18 Bookmarks: Where can I store bookmarks? Why can’t I see any bookmarks below the query box? What is this variable for?<a class="headerlink" href="#bookmarks-where-can-i-store-bookmarks-why-can-t-i-see-any-bookmarks-below-the-query-box-what-is-this-variable-for" title="Permalink to this headline">¶</a></h3>
+<p>Any query you have executed can be stored as a bookmark on the page
+where the results are displayed. You will find a button labeled
+‘Bookmark this query’ just at the end of the page. As soon as you have
+stored a bookmark, it is related to the database you run the query on.
+You can now access a bookmark dropdown on each page, the query box
+appears on for that database.</p>
+<p>You can also have, inside the query, a placeholder for a variable.
+This is done by inserting into the query a SQL comment between <tt class="docutils literal"><span class="pre">/*</span></tt> and
+<tt class="docutils literal"><span class="pre">*/</span></tt>. Inside the comment, the special string <tt class="docutils literal"><span class="pre">[VARIABLE]</span></tt> is used.
+Be aware that the whole query minus the SQL comment must be
+valid by itself, otherwise you won’t be able to store it as a bookmark.</p>
+<p>When you execute the bookmark, everything typed into the <em>value</em>
+input box on the query box page will replace the string <tt class="docutils literal"><span class="pre">/*[VARIABLE]*/</span></tt> in
+your stored query.</p>
+<p>Also remember, that everything else inside the <tt class="docutils literal"><span class="pre">/*[VARIABLE]*/</span></tt> string for
+your query will remain the way it is, but will be stripped of the <tt class="docutils literal"><span class="pre">/**/</span></tt>
+chars. So you can use:</p>
+<div class="highlight-mysql"><div class="highlight"><pre><span class="cm">/*, [VARIABLE] AS myname */</span>
+</pre></div>
+</div>
+<p>which will be expanded to</p>
+<div class="highlight-mysql"><div class="highlight"><pre><span class="p">,</span> <span class="n">VARIABLE</span> <span class="k">as</span> <span class="n">myname</span>
+</pre></div>
+</div>
+<p>in your query, where VARIABLE is the string you entered in the input box. If an
+empty string is provided, no replacements are made.</p>
+<p>A more complex example. Say you have stored
+this query:</p>
+<div class="highlight-mysql"><div class="highlight"><pre><span class="k">SELECT</span> <span class="n">Name</span><span class="p">,</span> <span class="n">Address</span> <span class="k">FROM</span> <span class="n">addresses</span> <span class="k">WHERE</span> <span class="mi">1</span> <span class="cm">/* AND Name LIKE '%[VARIABLE]%' */</span>
+</pre></div>
+</div>
+<p>Say, you now enter “phpMyAdmin” as the variable for the stored query, the full
+query will be:</p>
+<div class="highlight-mysql"><div class="highlight"><pre><span class="k">SELECT</span> <span class="n">Name</span><span class="p">,</span> <span class="n">Address</span> <span class="k">FROM</span> <span class="n">addresses</span> <span class="k">WHERE</span> <span class="mi">1</span> <span class="k">AND</span> <span class="n">Name</span> <span class="k">LIKE</span> <span class="s1">'%phpMyAdmin%'</span>
+</pre></div>
+</div>
+<p>You can use multiple occurrences of <tt class="docutils literal"><span class="pre">/*[VARIABLE]*/</span></tt> in a single query
+(that is, multiple occurrences of the <em>same</em> variable).</p>
+<p><strong>NOTE THE ABSENCE OF SPACES</strong> inside the <tt class="docutils literal"><span class="pre">/**/</span></tt> construct. Any spaces
+inserted there will be later also inserted as spaces in your query and may lead
+to unexpected results especially when using the variable expansion inside of a
+“LIKE ‘’” expression.</p>
+<p>Your initial query which is going to be stored as a bookmark has to yield at
+least one result row so you can store the bookmark. You may have that to work
+around using well positioned <tt class="docutils literal"><span class="pre">/**/</span></tt> comments.</p>
+</div>
+<div class="section" id="how-can-i-create-simple-latex-document-to-include-exported-table">
+<span id="faq6-19"></span><h3>6.19 How can I create simple LATEX document to include exported table?<a class="headerlink" href="#how-can-i-create-simple-latex-document-to-include-exported-table" title="Permalink to this headline">¶</a></h3>
+<p>You can simply include table in your LATEX documents,
+minimal sample document should look like following one (assuming you
+have table exported in file <tt class="file docutils literal"><span class="pre">table.tex</span></tt>):</p>
+<div class="highlight-latex"><div class="highlight"><pre><span class="k">\documentclass</span><span class="nb">{</span>article<span class="nb">}</span> <span class="c">% or any class you want</span>
+<span class="k">\usepackage</span><span class="nb">{</span>longtable<span class="nb">}</span>  <span class="c">% for displaying table</span>
+<span class="k">\begin</span><span class="nb">{</span>document<span class="nb">}</span>        <span class="c">% start of document</span>
+<span class="k">\include</span><span class="nb">{</span>table<span class="nb">}</span>         <span class="c">% including exported table</span>
+<span class="k">\end</span><span class="nb">{</span>document<span class="nb">}</span>          <span class="c">% end of document</span>
+</pre></div>
+</div>
+</div>
+<div class="section" id="i-see-a-lot-of-databases-which-are-not-mine-and-cannot-access-them">
+<span id="faq6-20"></span><h3>6.20 I see a lot of databases which are not mine, and cannot access them.<a class="headerlink" href="#i-see-a-lot-of-databases-which-are-not-mine-and-cannot-access-them" title="Permalink to this headline">¶</a></h3>
+<p>You have one of these global privileges: CREATE TEMPORARY TABLES, SHOW
+DATABASES, LOCK TABLES. Those privileges also enable users to see all the
+database names. So if your users do not need those privileges, you can remove
+them and their databases list will shorten.</p>
+<div class="admonition-see-also admonition seealso">
+<p class="first admonition-title">See also</p>
+<p class="last"><<a class="reference external" href="http://bugs.mysql.com/179">http://bugs.mysql.com/179</a>></p>
+</div>
+</div>
+<div class="section" id="in-edit-insert-mode-how-can-i-see-a-list-of-possible-values-for-a-column-based-on-some-foreign-table">
+<span id="faq6-21"></span><h3>6.21 In edit/insert mode, how can I see a list of possible values for a column, based on some foreign table?<a class="headerlink" href="#in-edit-insert-mode-how-can-i-see-a-list-of-possible-values-for-a-column-based-on-some-foreign-table" title="Permalink to this headline">¶</a></h3>
+<p>You have to setup appropriate links between the tables, and also setup
+the “display column” in the foreign table. See <a class="reference internal" href="#faq6-6"><em>6.6 How can I use the relation table in Query-by-example?</em></a> for an
+example. Then, if there are 100 values or less in the foreign table, a
+drop-down list of values will be available. You will see two lists of
+values, the first list containing the key and the display column, the
+second list containing the display column and the key. The reason for
+this is to be able to type the first letter of either the key or the
+display column. For 100 values or more, a distinct window will appear,
+to browse foreign key values and choose one. To change the default
+limit of 100, see <span class="target" id="index-27"></span><a class="reference internal" href="config.html#cfg_ForeignKeyMaxLimit"><tt class="xref config config-option docutils literal"><span class="pre">$cfg['ForeignKeyMaxLimit']</span></tt></a>.</p>
+</div>
+<div class="section" id="bookmarks-can-i-execute-a-default-bookmark-automatically-when-entering-browse-mode-for-a-table">
+<span id="faq6-22"></span><h3>6.22 Bookmarks: Can I execute a default bookmark automatically when entering Browse mode for a table?<a class="headerlink" href="#bookmarks-can-i-execute-a-default-bookmark-automatically-when-entering-browse-mode-for-a-table" title="Permalink to this headline">¶</a></h3>
+<p>Yes. If a bookmark has the same label as a table name and it’s not a
+public bookmark, it will be executed.</p>
+</div>
+<div class="section" id="export-i-heard-phpmyadmin-can-export-microsoft-excel-files">
+<span id="faq6-23"></span><h3>6.23 Export: I heard phpMyAdmin can export Microsoft Excel files?<a class="headerlink" href="#export-i-heard-phpmyadmin-can-export-microsoft-excel-files" title="Permalink to this headline">¶</a></h3>
+<p>You can use <a class="reference internal" href="glossary.html#term-csv"><em class="xref std std-term">CSV</em></a> for Microsoft Excel,
+which works out of the box.</p>
+<p class="versionchanged">
+<span class="versionmodified">Changed in version 3.4.5: </span>Since phpMyAdmin 3.4.5 support for direct export to Microsoft Excel version
+97 and newer was dropped.</p>
+</div>
+<div class="section" id="now-that-phpmyadmin-supports-native-mysql-4-1-x-column-comments-what-happens-to-my-column-comments-stored-in-pmadb">
+<span id="faq6-24"></span><h3>6.24 Now that phpMyAdmin supports native MySQL 4.1.x column comments, what happens to my column comments stored in pmadb?<a class="headerlink" href="#now-that-phpmyadmin-supports-native-mysql-4-1-x-column-comments-what-happens-to-my-column-comments-stored-in-pmadb" title="Permalink to this headline">¶</a></h3>
+<p>Automatic migration of a table’s pmadb-style column comments to the
+native ones is done whenever you enter Structure page for this table.</p>
+</div>
+<div class="section" id="faq6-25">
+<span id="id12"></span><h3>6.25 (withdrawn).<a class="headerlink" href="#faq6-25" title="Permalink to this headline">¶</a></h3>
+</div>
+<div class="section" id="how-can-i-select-a-range-of-rows">
+<span id="faq6-26"></span><h3>6.26 How can I select a range of rows?<a class="headerlink" href="#how-can-i-select-a-range-of-rows" title="Permalink to this headline">¶</a></h3>
+<p>Click the first row of the range, hold the shift key and click the
+last row of the range. This works everywhere you see rows, for example
+in Browse mode or on the Structure page.</p>
+</div>
+<div class="section" id="what-format-strings-can-i-use">
+<span id="faq6-27"></span><h3>6.27 What format strings can I use?<a class="headerlink" href="#what-format-strings-can-i-use" title="Permalink to this headline">¶</a></h3>
+<p>In all places where phpMyAdmin accepts format strings, you can use
+<tt class="docutils literal"><span class="pre">@VARIABLE@</span></tt> expansion and <a class="reference external" href="http://php.net/strftime">strftime</a>
+format strings. The expanded variables depend on a context (for
+example, if you haven’t chosen a table, you can not get the table
+name), but the following variables can be used:</p>
+<dl class="docutils">
+<dt><tt class="docutils literal"><span class="pre">@HTTP_HOST@</span></tt></dt>
+<dd>HTTP host that runs phpMyAdmin</dd>
+<dt><tt class="docutils literal"><span class="pre">@SERVER@</span></tt></dt>
+<dd>MySQL server name</dd>
+<dt><tt class="docutils literal"><span class="pre">@VERBOSE@</span></tt></dt>
+<dd>Verbose MySQL server name as defined in <span class="target" id="index-28"></span><a class="reference internal" href="config.html#cfg_Servers_verbose"><tt class="xref config config-option docutils literal"><span class="pre">$cfg['Servers'][$i]['verbose']</span></tt></a></dd>
+<dt><tt class="docutils literal"><span class="pre">@VSERVER@</span></tt></dt>
+<dd>Verbose MySQL server name if set, otherwise normal</dd>
+<dt><tt class="docutils literal"><span class="pre">@DATABASE@</span></tt></dt>
+<dd>Currently opened database</dd>
+<dt><tt class="docutils literal"><span class="pre">@TABLE@</span></tt></dt>
+<dd>Currently opened table</dd>
+<dt><tt class="docutils literal"><span class="pre">@COLUMNS@</span></tt></dt>
+<dd>Columns of the currently opened table</dd>
+<dt><tt class="docutils literal"><span class="pre">@PHPMYADMIN@</span></tt></dt>
+<dd>phpMyAdmin with version</dd>
+</dl>
+</div>
+<div class="section" id="how-can-i-easily-edit-relational-schema-for-export">
+<span id="wysiwyg"></span><h3>6.28 How can I easily edit relational schema for export?<a class="headerlink" href="#how-can-i-easily-edit-relational-schema-for-export" title="Permalink to this headline">¶</a></h3>
+<p>By clicking on the button ‘toggle scratchboard’ on the page where you
+edit x/y coordinates of those elements you can activate a scratchboard
+where all your elements are placed. By clicking on an element, you can
+move them around in the pre-defined area and the x/y coordinates will
+get updated dynamically. Likewise, when entering a new position
+directly into the input field, the new position in the scratchboard
+changes after your cursor leaves the input field.</p>
+<p>You have to click on the ‘OK’-button below the tables to save the new
+positions. If you want to place a new element, first add it to the
+table of elements and then you can drag the new element around.</p>
+<p>By changing the paper size and the orientation you can change the size
+of the scratchboard as well. You can do so by just changing the
+dropdown field below, and the scratchboard will resize automatically,
+without interfering with the current placement of the elements.</p>
+<p>If ever an element gets out of range you can either enlarge the paper
+size or click on the ‘reset’ button to place all elements below each
+other.</p>
+</div>
+<div class="section" id="why-can-t-i-get-a-chart-from-my-query-result-table">
+<span id="faq6-29"></span><h3>6.29 Why can’t I get a chart from my query result table?<a class="headerlink" href="#why-can-t-i-get-a-chart-from-my-query-result-table" title="Permalink to this headline">¶</a></h3>
+<p>Not every table can be put to the chart. Only tables with one, two or
+three columns can be visualised as a chart. Moreover the table must be
+in a special format for chart script to understand it. Currently
+supported formats can be found in the <a class="reference external" href="http://wiki.phpmyadmin.net/pma/Charts#Data_formats_for_query_results_chart">wiki</a>.</p>
+</div>
+<div class="section" id="import-how-can-i-import-esri-shapefiles">
+<span id="faq6-30"></span><h3>6.30 Import: How can I import ESRI Shapefiles<a class="headerlink" href="#import-how-can-i-import-esri-shapefiles" title="Permalink to this headline">¶</a></h3>
+<p>An ESRI Shapefile is actually a set of several files, where .shp file
+contains geometry data and .dbf file contains data related to those
+geometry data. To read data from .dbf file you need to have PHP
+compiled with the dBase extension (–enable-dbase). Otherwise only
+geometry data will be imported.</p>
+<p>To upload these set of files you can use either of the following
+methods:</p>
+<p>Configure upload directory with <span class="target" id="index-29"></span><a class="reference internal" href="config.html#cfg_UploadDir"><tt class="xref config config-option docutils literal"><span class="pre">$cfg['UploadDir']</span></tt></a>, upload both .shp and .dbf files with
+the same filename and chose the .shp file from the import page.</p>
+<p>Create a Zip archive with .shp and .dbf files and import it. For this
+to work, you need to set <span class="target" id="index-30"></span><a class="reference internal" href="config.html#cfg_TempDir"><tt class="xref config config-option docutils literal"><span class="pre">$cfg['TempDir']</span></tt></a> to a place where the web server user can
+write (for example <tt class="docutils literal"><span class="pre">'./tmp'</span></tt>).</p>
+<p>To create the temporary directory on a UNIX-based system, you can do:</p>
+<div class="highlight-sh"><div class="highlight"><pre><span class="nb">cd </span>phpMyAdmin
+mkdir tmp
+chmod o+rwx tmp
+</pre></div>
+</div>
+</div>
+<div class="section" id="how-do-i-create-a-relation-in-designer">
+<span id="faq6-31"></span><h3>6.31 How do I create a relation in designer?<a class="headerlink" href="#how-do-i-create-a-relation-in-designer" title="Permalink to this headline">¶</a></h3>
+<p>To select relation, click:  The display column is shown in pink. To
+set/unset a column as the display column, click the “Choose column to
+display” icon, then click on the appropriate column name.</p>
+</div>
+<div class="section" id="how-can-i-use-the-zoom-search-feature">
+<span id="faq6-32"></span><h3>6.32 How can I use the zoom search feature?<a class="headerlink" href="#how-can-i-use-the-zoom-search-feature" title="Permalink to this headline">¶</a></h3>
+<p>The Zoom search feature is an alternative to table search feature. It allows
+you to explore a table by representing its data in a scatter plot. You can
+locate this feature by selecting a table and clicking the <em class="guilabel">Search</em>
+tab. One of the sub-tabs in the <em class="guilabel">Table Search</em> page is
+<em class="guilabel">Zoom Search</em>.</p>
+<p>Consider the table REL_persons in <a class="reference internal" href="#faq6-6"><em>6.6 How can I use the relation table in Query-by-example?</em></a> for
+an example. To use zoom search, two columns need to be selected, for
+example, id and town_code. The id values will be represented on one
+axis and town_code values on the other axis. Each row will be
+represented as a point in a scatter plot based on its id and
+town_code. You can include two additional search criteria apart from
+the two fields to display.</p>
+<p>You can choose which field should be
+displayed as label for each point. If a display column has been set
+for the table (see <a class="reference internal" href="#faqdisplay"><em>6.7 How can I use the “display column” feature?</em></a>), it is taken as the label unless
+you specify otherwise. You can also select the maximum number of rows
+you want to be displayed in the plot by specifing it in the ‘Max rows
+to plot’ field. Once you have decided over your criteria, click ‘Go’
+to display the plot.</p>
+<p>After the plot is generated, you can use the
+mousewheel to zoom in and out of the plot. In addition, panning
+feature is enabled to navigate through the plot. You can zoom-in to a
+certail level of detail and use panning to locate your area of
+interest. Clicking on a point opens a dialogue box, displaying field
+values of the data row represented by the point. You can edit the
+values if required and click on submit to issue an update query. Basic
+instructions on how to use can be viewed by clicking the ‘How to use?’
+link located just above the plot.</p>
+</div>
+<div class="section" id="when-browsing-a-table-how-can-i-copy-a-column-name">
+<span id="faq6-33"></span><h3>6.33 When browsing a table, how can I copy a column name?<a class="headerlink" href="#when-browsing-a-table-how-can-i-copy-a-column-name" title="Permalink to this headline">¶</a></h3>
+<p>Selecting the name of the column within the browse table header cell
+for copying is difficult, as the columns support reordering by
+dragging the header cells as well as sorting by clicking on the linked
+column name. To copy a column name, double-click on the empty area
+next to the column name, when the tooltip tells you to do so. This
+will show you an input box with the column name. You may right-click
+the column name within this input box to copy it to your clipboard.</p>
+</div>
+</div>
+<div class="section" id="phpmyadmin-project">
+<span id="faqproject"></span><h2>phpMyAdmin project<a class="headerlink" href="#phpmyadmin-project" title="Permalink to this headline">¶</a></h2>
+<div class="section" id="i-have-found-a-bug-how-do-i-inform-developers">
+<span id="faq7-1"></span><h3>7.1 I have found a bug. How do I inform developers?<a class="headerlink" href="#i-have-found-a-bug-how-do-i-inform-developers" title="Permalink to this headline">¶</a></h3>
+<p>Our Bug Tracker is located at <<a class="reference external" href="http://sf.net/projects/phpmyadmin/">http://sf.net/projects/phpmyadmin/</a>> under the
+Bugs section. But please first discuss your bug with other users:
+<<a class="reference external" href="https://sourceforge.net/projects/phpmyadmin/forums">https://sourceforge.net/projects/phpmyadmin/forums</a>>.</p>
+</div>
+<div class="section" id="i-want-to-translate-the-messages-to-a-new-language-or-upgrade-an-existing-language-where-do-i-start">
+<span id="faq7-2"></span><h3>7.2 I want to translate the messages to a new language or upgrade an existing language, where do I start?<a class="headerlink" href="#i-want-to-translate-the-messages-to-a-new-language-or-upgrade-an-existing-language-where-do-i-start" title="Permalink to this headline">¶</a></h3>
+<p>Translations are very welcome and all you need to have are the
+language skills. The easiest way is to use our <a class="reference external" href="https://l10n.cihar.com/projects/phpmyadmin/">online translation
+service</a>. You can check
+out all the possibilities to translate in the <a class="reference external" href="http://www.phpmyadmin.net/home_page/translate.php">translate section on
+our website</a>.</p>
+</div>
+<div class="section" id="i-would-like-to-help-out-with-the-development-of-phpmyadmin-how-should-i-proceed">
+<span id="faq7-3"></span><h3>7.3 I would like to help out with the development of phpMyAdmin. How should I proceed?<a class="headerlink" href="#i-would-like-to-help-out-with-the-development-of-phpmyadmin-how-should-i-proceed" title="Permalink to this headline">¶</a></h3>
+<p>We welcome every contribution to the development of phpMyAdmin. You
+can check out all the possibilities to contribute in the <a class="reference external" href="http://www.phpmyadmin.net/home_page/improve.php">contribute
+section on our website</a>.</p>
+<div class="admonition-see-also admonition seealso">
+<p class="first admonition-title">See also</p>
+<p class="last"><a class="reference internal" href="developers.html#developers"><em>Developers Information</em></a></p>
+</div>
+</div>
+</div>
+<div class="section" id="security">
+<span id="faqsecurity"></span><h2>Security<a class="headerlink" href="#security" title="Permalink to this headline">¶</a></h2>
+<div class="section" id="where-can-i-get-information-about-the-security-alerts-issued-for-phpmyadmin">
+<span id="faq8-1"></span><h3>8.1 Where can I get information about the security alerts issued for phpMyAdmin?<a class="headerlink" href="#where-can-i-get-information-about-the-security-alerts-issued-for-phpmyadmin" title="Permalink to this headline">¶</a></h3>
+<p>Please refer to <<a class="reference external" href="http://www.phpmyadmin.net/home_page/security.php">http://www.phpmyadmin.net/home_page/security.php</a>>.</p>
+</div>
+<div class="section" id="how-can-i-protect-phpmyadmin-against-brute-force-attacks">
+<span id="faq8-2"></span><h3>8.2 How can I protect phpMyAdmin against brute force attacks?<a class="headerlink" href="#how-can-i-protect-phpmyadmin-against-brute-force-attacks" title="Permalink to this headline">¶</a></h3>
+<p>If you use Apache web server, phpMyAdmin exports information about
+authentication to the Apache environment and it can be used in Apache
+logs. Currently there are two variables available:</p>
+<dl class="docutils">
+<dt><tt class="docutils literal"><span class="pre">userID</span></tt></dt>
+<dd>User name of currently active user (he does not have to be logged in).</dd>
+<dt><tt class="docutils literal"><span class="pre">userStatus</span></tt></dt>
+<dd>Status of currently active user, one of <tt class="docutils literal"><span class="pre">ok</span></tt> (user is logged in),
+<tt class="docutils literal"><span class="pre">mysql-denied</span></tt> (MySQL denied user login), <tt class="docutils literal"><span class="pre">allow-denied</span></tt> (user denied
+by allow/deny rules), <tt class="docutils literal"><span class="pre">root-denied</span></tt> (root is denied in configuration),
+<tt class="docutils literal"><span class="pre">empty-denied</span></tt> (empty password is denied).</dd>
+</dl>
+<p><tt class="docutils literal"><span class="pre">LogFormat</span></tt> directive for Apache can look like following:</p>
+<div class="highlight-apache"><div class="highlight"><pre><span class="nb">LogFormat</span> <span class="s2">"%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\" %{userID}n %{userStatus}n"</span>   pma_combined
+</pre></div>
+</div>
+<p>You can then use any log analyzing tools to detect possible break-in
+attempts.</p>
+</div>
+</div>
+<div class="section" id="synchronization">
+<span id="faqsynchronization"></span><h2>Synchronization<a class="headerlink" href="#synchronization" title="Permalink to this headline">¶</a></h2>
+<div class="section" id="faq9-1">
+<span id="id13"></span><h3>9.1 (withdrawn).<a class="headerlink" href="#faq9-1" title="Permalink to this headline">¶</a></h3>
+</div>
+<div class="section" id="faq9-2">
+<span id="id14"></span><h3>9.2 (withdrawn).<a class="headerlink" href="#faq9-2" title="Permalink to this headline">¶</a></h3>
+</div>
+</div>
+</div>
+
+
+          </div>
+        </div>
+      </div>
+      <div class="sphinxsidebar">
+        <div class="sphinxsidebarwrapper">
+  <h3><a href="index.html">Table Of Contents</a></h3>
+  <ul>
+<li><a class="reference internal" href="#">FAQ - Frequently Asked Questions</a><ul>
+<li><a class="reference internal" href="#server">Server</a><ul>
+<li><a class="reference internal" href="#my-server-is-crashing-each-time-a-specific-action-is-required-or-phpmyadmin-sends-a-blank-page-or-a-page-full-of-cryptic-characters-to-my-browser-what-can-i-do">1.1 My server is crashing each time a specific action is required or phpMyAdmin sends a blank page or a page full of cryptic characters to my browser, what can I do?</a></li>
+<li><a class="reference internal" href="#my-apache-server-crashes-when-using-phpmyadmin">1.2 My Apache server crashes when using phpMyAdmin.</a></li>
+<li><a class="reference internal" href="#withdrawn">1.3 (withdrawn).</a></li>
+<li><a class="reference internal" href="#using-phpmyadmin-on-iis-i-m-displayed-the-error-message-the-specified-cgi-application-misbehaved-by-not-returning-a-complete-set-of-http-headers">1.4 Using phpMyAdmin on IIS, I’m displayed the error message: “The specified CGI application misbehaved by not returning a complete set of HTTP headers ...”.</a></li>
+<li><a class="reference internal" href="#using-phpmyadmin-on-iis-i-m-facing-crashes-and-or-many-error-messages-with-the-http">1.5 Using phpMyAdmin on IIS, I’m facing crashes and/or many error messages with the HTTP.</a></li>
+<li><a class="reference internal" href="#i-can-t-use-phpmyadmin-on-pws-nothing-is-displayed">1.6 I can’t use phpMyAdmin on PWS: nothing is displayed!</a></li>
+<li><a class="reference internal" href="#how-can-i-gzip-or-bzip-a-dump-or-a-csv-export-it-does-not-seem-to-work">1.7 How can I GZip or Bzip a dump or a CSV export? It does not seem to work.</a></li>
+<li><a class="reference internal" href="#i-cannot-insert-a-text-file-in-a-table-and-i-get-an-error-about-safe-mode-being-in-effect">1.8 I cannot insert a text file in a table, and I get an error about safe mode being in effect.</a></li>
+<li><a class="reference internal" href="#faq1-9">1.9 (withdrawn).</a></li>
+<li><a class="reference internal" href="#i-m-having-troubles-when-uploading-files-with-phpmyadmin-running-on-a-secure-server-my-browser-is-internet-explorer-and-i-m-using-the-apache-server">1.10 I’m having troubles when uploading files with phpMyAdmin running on a secure server. My browser is Internet Explorer and I’m using the Apache server.</a></li>
+<li><a class="reference internal" href="#i-get-an-open-basedir-restriction-while-uploading-a-file-from-the-query-box">1.11 I get an ‘open_basedir restriction’ while uploading a file from the query box.</a></li>
+<li><a class="reference internal" href="#i-have-lost-my-mysql-root-password-what-can-i-do">1.12 I have lost my MySQL root password, what can I do?</a></li>
+<li><a class="reference internal" href="#faq1-13">1.13 (withdrawn).</a></li>
+<li><a class="reference internal" href="#faq1-14">1.14 (withdrawn).</a></li>
+<li><a class="reference internal" href="#i-have-problems-with-mysql-user-column-names">1.15 I have problems with <em>mysql.user</em> column names.</a></li>
+<li><a class="reference internal" href="#i-cannot-upload-big-dump-files-memory-http-or-timeout-problems">1.16 I cannot upload big dump files (memory, HTTP or timeout problems).</a></li>
+<li><a class="reference internal" href="#which-mysql-versions-does-phpmyadmin-support">1.17 Which MySQL versions does phpMyAdmin support?</a></li>
+<li><a class="reference internal" href="#a-i-cannot-connect-to-the-mysql-server-it-always-returns-the-error-message-client-does-not-support-authentication-protocol-requested-by-server-consider-upgrading-mysql-client">1.17a I cannot connect to the MySQL server. It always returns the error message, “Client does not support authentication protocol requested by server; consider upgrading MySQL client”</a></li>
+<li><a class="reference internal" href="#faq1-18">1.18 (withdrawn).</a></li>
+<li><a class="reference internal" href="#i-can-t-run-the-display-relations-feature-because-the-script-seems-not-to-know-the-font-face-i-m-using">1.19 I can’t run the “display relations” feature because the script seems not to know the font face I’m using!</a></li>
+<li><a class="reference internal" href="#i-receive-the-error-cannot-load-mysql-extension-please-check-php-configuration">1.20 I receive the error “cannot load MySQL extension, please check PHP Configuration”.</a></li>
+<li><a class="reference internal" href="#i-am-running-the-cgi-version-of-php-under-unix-and-i-cannot-log-in-using-cookie-auth">1.21 I am running the CGI version of PHP under Unix, and I cannot log in using cookie auth.</a></li>
+<li><a class="reference internal" href="#i-don-t-see-the-location-of-text-file-field-so-i-cannot-upload">1.22 I don’t see the “Location of text file” field, so I cannot upload.</a></li>
+<li><a class="reference internal" href="#i-m-running-mysql-on-a-win32-machine-each-time-i-create-a-new-table-the-table-and-column-names-are-changed-to-lowercase">1.23 I’m running MySQL on a Win32 machine. Each time I create a new table the table and column names are changed to lowercase!</a></li>
+<li><a class="reference internal" href="#faq1-24">1.24 (withdrawn).</a></li>
+<li><a class="reference internal" href="#i-am-running-apache-with-mod-gzip-1-3-26-1a-on-windows-xp-and-i-get-problems-such-as-undefined-variables-when-i-run-a-sql-query">1.25 I am running Apache with mod_gzip-1.3.26.1a on Windows XP, and I get problems, such as undefined variables when I run a SQL query.</a></li>
+<li><a class="reference internal" href="#i-just-installed-phpmyadmin-in-my-document-root-of-iis-but-i-get-the-error-no-input-file-specified-when-trying-to-run-phpmyadmin">1.26 I just installed phpMyAdmin in my document root of IIS but I get the error “No input file specified” when trying to run phpMyAdmin.</a></li>
+<li><a class="reference internal" href="#i-get-empty-page-when-i-want-to-view-huge-page-eg-db-structure-php-with-plenty-of-tables">1.27 I get empty page when I want to view huge page (eg. db_structure.php with plenty of tables).</a></li>
+<li><a class="reference internal" href="#my-mysql-server-sometimes-refuses-queries-and-returns-the-message-errorcode-13-what-does-this-mean">1.28 My MySQL server sometimes refuses queries and returns the message ‘Errorcode: 13’. What does this mean?</a></li>
+<li><a class="reference internal" href="#when-i-create-a-table-or-modify-a-column-i-get-an-error-and-the-columns-are-duplicated">1.29 When I create a table or modify a column, I get an error and the columns are duplicated.</a></li>
+<li><a class="reference internal" href="#i-get-the-error-navigation-php-missing-hash">1.30 I get the error “navigation.php: Missing hash”.</a></li>
+<li><a class="reference internal" href="#does-phpmyadmin-support-php-5">1.31 Does phpMyAdmin support PHP 5?</a></li>
+<li><a class="reference internal" href="#can-i-use-http-authentication-with-iis">1.32 Can I use HTTP authentication with IIS?</a></li>
+<li><a class="reference internal" href="#faq1-33">1.33 (withdrawn).</a></li>
+<li><a class="reference internal" href="#can-i-access-directly-to-database-or-table-pages">1.34 Can I access directly to database or table pages?</a></li>
+<li><a class="reference internal" href="#can-i-use-http-authentication-with-apache-cgi">1.35 Can I use HTTP authentication with Apache CGI?</a></li>
+<li><a class="reference internal" href="#i-get-an-error-500-internal-server-error">1.36 I get an error “500 Internal Server Error”.</a></li>
+<li><a class="reference internal" href="#i-run-phpmyadmin-on-cluster-of-different-machines-and-password-encryption-in-cookie-auth-doesn-t-work">1.37 I run phpMyAdmin on cluster of different machines and password encryption in cookie auth doesn’t work.</a></li>
+<li><a class="reference internal" href="#can-i-use-phpmyadmin-on-a-server-on-which-suhosin-is-enabled">1.38 Can I use phpMyAdmin on a server on which Suhosin is enabled?</a></li>
+<li><a class="reference internal" href="#when-i-try-to-connect-via-https-i-can-log-in-but-then-my-connection-is-redirected-back-to-http-what-can-cause-this-behavior">1.39 When I try to connect via https, I can log in, but then my connection is redirected back to http. What can cause this behavior?</a></li>
+<li><a class="reference internal" href="#when-accessing-phpmyadmin-via-an-apache-reverse-proxy-cookie-login-does-not-work">1.40 When accessing phpMyAdmin via an Apache reverse proxy, cookie login does not work.</a></li>
+<li><a class="reference internal" href="#when-i-view-a-database-and-ask-to-see-its-privileges-i-get-an-error-about-an-unknown-column">1.41 When I view a database and ask to see its privileges, I get an error about an unknown column.</a></li>
+<li><a class="reference internal" href="#how-can-i-prevent-robots-from-accessing-phpmyadmin">1.42 How can I prevent robots from accessing phpMyAdmin?</a></li>
+<li><a class="reference internal" href="#why-can-t-i-display-the-structure-of-my-table-containing-hundreds-of-columns">1.43 Why can’t I display the structure of my table containing hundreds of columns?</a></li>
+</ul>
+</li>
+<li><a class="reference internal" href="#configuration">Configuration</a><ul>
+<li><a class="reference internal" href="#the-error-message-warning-cannot-add-header-information-headers-already-sent-by-is-displayed-what-s-the-problem">2.1 The error message “Warning: Cannot add header information - headers already sent by ...” is displayed, what’s the problem?</a></li>
+<li><a class="reference internal" href="#phpmyadmin-can-t-connect-to-mysql-what-s-wrong">2.2 phpMyAdmin can’t connect to MySQL. What’s wrong?</a></li>
+<li><a class="reference internal" href="#the-error-message-warning-mysql-connection-failed-can-t-connect-to-local-mysql-server-through-socket-tmp-mysql-sock-111-is-displayed-what-can-i-do">2.3 The error message “Warning: MySQL Connection Failed: Can’t connect to local MySQL server through socket ‘/tmp/mysql.sock’ (111) ...” is displayed. What can I do?</a></li>
+<li><a class="reference internal" href="#nothing-is-displayed-by-my-browser-when-i-try-to-run-phpmyadmin-what-can-i-do">2.4 Nothing is displayed by my browser when I try to run phpMyAdmin, what can I do?</a></li>
+<li><a class="reference internal" href="#each-time-i-want-to-insert-or-change-a-row-or-drop-a-database-or-a-table-an-error-404-page-not-found-is-displayed-or-with-http-or-cookie-authentication-i-m-asked-to-log-in-again-what-s-wrong">2.5 Each time I want to insert or change a row or drop a database or a table, an error 404 (page not found) is displayed or, with HTTP or cookie authentication, I’m asked to log in again. What’s wrong?</a></li>
+<li><a class="reference internal" href="#i-get-an-access-denied-for-user-root-localhost-using-password-yes-error-when-trying-to-access-a-mysql-server-on-a-host-which-is-port-forwarded-for-my-localhost">2.6 I get an “Access denied for user: ‘root@localhost‘ (Using password: YES)”-error when trying to access a MySQL-Server on a host which is port-forwarded for my localhost.</a></li>
+<li><a class="reference internal" href="#using-and-creating-themes">2.7 Using and creating themes</a></li>
+<li><a class="reference internal" href="#i-get-missing-parameters-errors-what-can-i-do">2.8 I get “Missing parameters” errors, what can I do?</a></li>
+<li><a class="reference internal" href="#seeing-an-upload-progress-bar">2.9 Seeing an upload progress bar</a></li>
+</ul>
+</li>
+<li><a class="reference internal" href="#known-limitations">Known limitations</a><ul>
+<li><a class="reference internal" href="#when-using-http-authentication-a-user-who-logged-out-can-not-log-in-again-in-with-the-same-nick">3.1 When using HTTP authentication, a user who logged out can not log in again in with the same nick.</a></li>
+<li><a class="reference internal" href="#when-dumping-a-large-table-in-compressed-mode-i-get-a-memory-limit-error-or-a-time-limit-error">3.2 When dumping a large table in compressed mode, I get a memory limit error or a time limit error.</a></li>
+<li><a class="reference internal" href="#with-innodb-tables-i-lose-foreign-key-relationships-when-i-rename-a-table-or-a-column">3.3 With InnoDB tables, I lose foreign key relationships when I rename a table or a column.</a></li>
+<li><a class="reference internal" href="#i-am-unable-to-import-dumps-i-created-with-the-mysqldump-tool-bundled-with-the-mysql-server-distribution">3.4 I am unable to import dumps I created with the mysqldump tool bundled with the MySQL server distribution.</a></li>
+<li><a class="reference internal" href="#when-using-nested-folders-multiple-hierarchies-are-displayed-in-a-wrong-manner">3.5 When using nested folders, multiple hierarchies are displayed in a wrong manner.</a></li>
+<li><a class="reference internal" href="#what-is-currently-not-supported-in-phpmyadmin-about-innodb">3.6 What is currently not supported in phpMyAdmin about InnoDB?</a></li>
+<li><a class="reference internal" href="#i-have-table-with-many-100-columns-and-when-i-try-to-browse-table-i-get-series-of-errors-like-warning-unable-to-parse-url-how-can-this-be-fixed">3.7 I have table with many (100+) columns and when I try to browse table I get series of errors like “Warning: unable to parse url”. How can this be fixed?</a></li>
+<li><a class="reference internal" href="#i-cannot-use-clickable-html-forms-in-columns-where-i-put-a-mime-transformation-onto">3.8 I cannot use (clickable) HTML-forms in columns where I put a MIME-Transformation onto!</a></li>
+<li><a class="reference internal" href="#i-get-error-messages-when-using-sql-mode-ansi-for-the-mysql-server">3.9 I get error messages when using “–sql_mode=ANSI” for the MySQL server.</a></li>
+<li><a class="reference internal" href="#homonyms-and-no-primary-key-when-the-results-of-a-select-display-more-that-one-column-with-the-same-value-for-example-select-lastname-from-employees-where-firstname-like-a-and-two-smith-values-are-displayed-if-i-click-edit-i-cannot-be-sure-that-i-am-editing-the-intended-row">3.10 Homonyms and no primary key: When the results of a SELECT display more that one column with the same value (for example <tt class="docutils literal"><span class="pre">SEL [...]
+<li><a class="reference internal" href="#the-number-of-rows-for-innodb-tables-is-not-correct">3.11 The number of rows for InnoDB tables is not correct.</a></li>
+<li><a class="reference internal" href="#faq3-12">3.12 (withdrawn).</a></li>
+<li><a class="reference internal" href="#i-get-an-error-when-entering-use-followed-by-a-db-name-containing-an-hyphen">3.13 I get an error when entering <tt class="docutils literal"><span class="pre">USE</span></tt> followed by a db name containing an hyphen.</a></li>
+<li><a class="reference internal" href="#i-am-not-able-to-browse-a-table-when-i-don-t-have-the-right-to-select-one-of-the-columns">3.14 I am not able to browse a table when I don’t have the right to SELECT one of the columns.</a></li>
+<li><a class="reference internal" href="#faq3-15">3.15 (withdrawn).</a></li>
+<li><a class="reference internal" href="#faq3-16">3.16 (withdrawn).</a></li>
+<li><a class="reference internal" href="#faq3-17">3.17 (withdrawn).</a></li>
+<li><a class="reference internal" href="#when-i-import-a-csv-file-that-contains-multiple-tables-they-are-lumped-together-into-a-single-table">3.18 When I import a CSV file that contains multiple tables, they are lumped together into a single table.</a></li>
+<li><a class="reference internal" href="#when-i-import-a-file-and-have-phpmyadmin-determine-the-appropriate-data-structure-it-only-uses-int-decimal-and-varchar-types">3.19 When I import a file and have phpMyAdmin determine the appropriate data structure it only uses int, decimal, and varchar types.</a></li>
+</ul>
+</li>
+<li><a class="reference internal" href="#isps-multi-user-installations">ISPs, multi-user installations</a><ul>
+<li><a class="reference internal" href="#i-m-an-isp-can-i-setup-one-central-copy-of-phpmyadmin-or-do-i-need-to-install-it-for-each-customer">4.1 I’m an ISP. Can I setup one central copy of phpMyAdmin or do I need to install it for each customer?</a></li>
+<li><a class="reference internal" href="#what-s-the-preferred-way-of-making-phpmyadmin-secure-against-evil-access">4.2 What’s the preferred way of making phpMyAdmin secure against evil access?</a></li>
+<li><a class="reference internal" href="#i-get-errors-about-not-being-able-to-include-a-file-in-lang-or-in-libraries">4.3 I get errors about not being able to include a file in <em>/lang</em> or in <em>/libraries</em>.</a></li>
+<li><a class="reference internal" href="#phpmyadmin-always-gives-access-denied-when-using-http-authentication">4.4 phpMyAdmin always gives “Access denied” when using HTTP authentication.</a></li>
+<li><a class="reference internal" href="#is-it-possible-to-let-users-create-their-own-databases">4.5 Is it possible to let users create their own databases?</a></li>
+<li><a class="reference internal" href="#how-can-i-use-the-host-based-authentication-additions">4.6 How can I use the Host-based authentication additions?</a></li>
+<li><a class="reference internal" href="#authentication-window-is-displayed-more-than-once-why">4.7 Authentication window is displayed more than once, why?</a></li>
+<li><a class="reference internal" href="#which-parameters-can-i-use-in-the-url-that-starts-phpmyadmin">4.8 Which parameters can I use in the URL that starts phpMyAdmin?</a></li>
+</ul>
+</li>
+<li><a class="reference internal" href="#browsers-or-client-os">Browsers or client OS</a><ul>
+<li><a class="reference internal" href="#i-get-an-out-of-memory-error-and-my-controls-are-non-functional-when-trying-to-create-a-table-with-more-than-14-columns">5.1 I get an out of memory error, and my controls are non-functional, when trying to create a table with more than 14 columns.</a></li>
+<li><a class="reference internal" href="#with-xitami-2-5b4-phpmyadmin-won-t-process-form-fields">5.2 With Xitami 2.5b4, phpMyAdmin won’t process form fields.</a></li>
+<li><a class="reference internal" href="#i-have-problems-dumping-tables-with-konqueror-phpmyadmin-2-2-2">5.3 I have problems dumping tables with Konqueror (phpMyAdmin 2.2.2).</a></li>
+<li><a class="reference internal" href="#i-can-t-use-the-cookie-authentication-mode-because-internet-explorer-never-stores-the-cookies">5.4 I can’t use the cookie authentication mode because Internet Explorer never stores the cookies.</a></li>
+<li><a class="reference internal" href="#in-internet-explorer-5-0-i-get-javascript-errors-when-browsing-my-rows">5.5 In Internet Explorer 5.0, I get JavaScript errors when browsing my rows.</a></li>
+<li><a class="reference internal" href="#in-internet-explorer-5-0-5-5-or-6-0-i-get-an-error-like-page-not-found-when-trying-to-modify-a-row-in-a-table-with-many-columns-or-with-a-text-column">5.6 In Internet Explorer 5.0, 5.5 or 6.0, I get an error (like “Page not found”) when trying to modify a row in a table with many columns, or with a text column.</a></li>
+<li><a class="reference internal" href="#i-refresh-reload-my-browser-and-come-back-to-the-welcome-page">5.7 I refresh (reload) my browser, and come back to the welcome page.</a></li>
+<li><a class="reference internal" href="#with-mozilla-0-9-7-i-have-problems-sending-a-query-modified-in-the-query-box">5.8 With Mozilla 0.9.7 I have problems sending a query modified in the query box.</a></li>
+<li><a class="reference internal" href="#with-mozilla-0-9-to-1-0-and-netscape-7-0-pr1-i-can-t-type-a-whitespace-in-the-sql-query-edit-area-the-page-scrolls-down">5.9 With Mozilla 0.9.? to 1.0 and Netscape 7.0-PR1 I can’t type a whitespace in the SQL-Query edit area: the page scrolls down.</a></li>
+<li><a class="reference internal" href="#with-netscape-4-75-i-get-empty-rows-between-each-row-of-data-in-a-csv-exported-file">5.10 With Netscape 4.75 I get empty rows between each row of data in a CSV exported file.</a></li>
+<li><a class="reference internal" href="#extended-ascii-characters-like-german-umlauts-are-displayed-wrong">5.11 Extended-ASCII characters like German umlauts are displayed wrong.</a></li>
+<li><a class="reference internal" href="#mac-os-x-safari-browser-changes-special-characters-to">5.12 Mac OS X Safari browser changes special characters to ”?”.</a></li>
+<li><a class="reference internal" href="#with-internet-explorer-5-5-or-6-and-http-authentication-type-i-cannot-manage-two-servers-i-log-in-to-the-first-one-then-the-other-one-but-if-i-switch-back-to-the-first-i-have-to-log-in-on-each-operation">5.13 With Internet Explorer 5.5 or 6, and HTTP authentication type, I cannot manage two servers: I log in to the first one, then the other one, but if I switch back to the first, I have to log in on each operation.</a></li>
+<li><a class="reference internal" href="#using-opera6-i-can-manage-to-get-to-the-authentication-but-nothing-happens-after-that-only-a-blank-screen">5.14 Using Opera6, I can manage to get to the authentication, but nothing happens after that, only a blank screen.</a></li>
+<li><a class="reference internal" href="#i-have-display-problems-with-safari">5.15 I have display problems with Safari.</a></li>
+<li><a class="reference internal" href="#with-internet-explorer-i-get-access-is-denied-javascript-errors-or-i-cannot-make-phpmyadmin-work-under-windows">5.16 With Internet Explorer, I get “Access is denied” Javascript errors. Or I cannot make phpMyAdmin work under Windows.</a></li>
+<li><a class="reference internal" href="#with-firefox-i-cannot-delete-rows-of-data-or-drop-a-database">5.17 With Firefox, I cannot delete rows of data or drop a database.</a></li>
+<li><a class="reference internal" href="#with-konqueror-4-2-x-an-invalid-limit-clause-is-generated-when-i-browse-a-table">5.18 With Konqueror 4.2.x an invalid <tt class="docutils literal"><span class="pre">LIMIT</span></tt> clause is generated when I browse a table.</a></li>
+<li><a class="reference internal" href="#i-get-javascript-errors-in-my-browser">5.19 I get JavaScript errors in my browser.</a></li>
+</ul>
+</li>
+<li><a class="reference internal" href="#using-phpmyadmin">Using phpMyAdmin</a><ul>
+<li><a class="reference internal" href="#i-can-t-insert-new-rows-into-a-table-i-can-t-create-a-table-mysql-brings-up-a-sql-error">6.1 I can’t insert new rows into a table / I can’t create a table - MySQL brings up a SQL error.</a></li>
+<li><a class="reference internal" href="#when-i-create-a-table-i-set-an-index-for-two-columns-and-phpmyadmin-generates-only-one-index-with-those-two-columns">6.2 When I create a table, I set an index for two columns and phpMyAdmin generates only one index with those two columns.</a></li>
+<li><a class="reference internal" href="#how-can-i-insert-a-null-value-into-my-table">6.3 How can I insert a null value into my table?</a></li>
+<li><a class="reference internal" href="#how-can-i-backup-my-database-or-table">6.4 How can I backup my database or table?</a></li>
+<li><a class="reference internal" href="#how-can-i-restore-upload-my-database-or-table-using-a-dump-how-can-i-run-a-sql-file">6.5 How can I restore (upload) my database or table using a dump? How can I run a ”.sql” file?</a></li>
+<li><a class="reference internal" href="#how-can-i-use-the-relation-table-in-query-by-example">6.6 How can I use the relation table in Query-by-example?</a></li>
+<li><a class="reference internal" href="#how-can-i-use-the-display-column-feature">6.7 How can I use the “display column” feature?</a></li>
+<li><a class="reference internal" href="#how-can-i-produce-a-pdf-schema-of-my-database">6.8 How can I produce a PDF schema of my database?</a></li>
+<li><a class="reference internal" href="#phpmyadmin-is-changing-the-type-of-one-of-my-columns">6.9 phpMyAdmin is changing the type of one of my columns!</a></li>
+<li><a class="reference internal" href="#when-creating-a-privilege-what-happens-with-underscores-in-the-database-name">6.10 When creating a privilege, what happens with underscores in the database name?</a></li>
+<li><a class="reference internal" href="#what-is-the-curious-symbol-o-in-the-statistics-pages">6.11 What is the curious symbol ø in the statistics pages?</a></li>
+<li><a class="reference internal" href="#i-want-to-understand-some-export-options">6.12 I want to understand some Export options.</a></li>
+<li><a class="reference internal" href="#i-would-like-to-create-a-database-with-a-dot-in-its-name">6.13 I would like to create a database with a dot in its name.</a></li>
+<li><a class="reference internal" href="#how-do-i-set-up-the-sql-validator">6.14 How do I set up the SQL Validator?</a></li>
+<li><a class="reference internal" href="#i-want-to-add-a-blob-column-and-put-an-index-on-it-but-mysql-says-blob-column-used-in-key-specification-without-a-key-length">6.15 I want to add a BLOB column and put an index on it, but MySQL says “BLOB column ‘...’ used in key specification without a key length”.</a></li>
+<li><a class="reference internal" href="#how-can-i-simply-move-in-page-with-plenty-editing-fields">6.16 How can I simply move in page with plenty editing fields?</a></li>
+<li><a class="reference internal" href="#transformations-i-can-t-enter-my-own-mimetype-wtf-is-this-feature-then-useful-for">6.17 Transformations: I can’t enter my own mimetype! WTF is this feature then useful for?</a></li>
+<li><a class="reference internal" href="#bookmarks-where-can-i-store-bookmarks-why-can-t-i-see-any-bookmarks-below-the-query-box-what-is-this-variable-for">6.18 Bookmarks: Where can I store bookmarks? Why can’t I see any bookmarks below the query box? What is this variable for?</a></li>
+<li><a class="reference internal" href="#how-can-i-create-simple-latex-document-to-include-exported-table">6.19 How can I create simple LATEX document to include exported table?</a></li>
+<li><a class="reference internal" href="#i-see-a-lot-of-databases-which-are-not-mine-and-cannot-access-them">6.20 I see a lot of databases which are not mine, and cannot access them.</a></li>
+<li><a class="reference internal" href="#in-edit-insert-mode-how-can-i-see-a-list-of-possible-values-for-a-column-based-on-some-foreign-table">6.21 In edit/insert mode, how can I see a list of possible values for a column, based on some foreign table?</a></li>
+<li><a class="reference internal" href="#bookmarks-can-i-execute-a-default-bookmark-automatically-when-entering-browse-mode-for-a-table">6.22 Bookmarks: Can I execute a default bookmark automatically when entering Browse mode for a table?</a></li>
+<li><a class="reference internal" href="#export-i-heard-phpmyadmin-can-export-microsoft-excel-files">6.23 Export: I heard phpMyAdmin can export Microsoft Excel files?</a></li>
+<li><a class="reference internal" href="#now-that-phpmyadmin-supports-native-mysql-4-1-x-column-comments-what-happens-to-my-column-comments-stored-in-pmadb">6.24 Now that phpMyAdmin supports native MySQL 4.1.x column comments, what happens to my column comments stored in pmadb?</a></li>
+<li><a class="reference internal" href="#faq6-25">6.25 (withdrawn).</a></li>
+<li><a class="reference internal" href="#how-can-i-select-a-range-of-rows">6.26 How can I select a range of rows?</a></li>
+<li><a class="reference internal" href="#what-format-strings-can-i-use">6.27 What format strings can I use?</a></li>
+<li><a class="reference internal" href="#how-can-i-easily-edit-relational-schema-for-export">6.28 How can I easily edit relational schema for export?</a></li>
+<li><a class="reference internal" href="#why-can-t-i-get-a-chart-from-my-query-result-table">6.29 Why can’t I get a chart from my query result table?</a></li>
+<li><a class="reference internal" href="#import-how-can-i-import-esri-shapefiles">6.30 Import: How can I import ESRI Shapefiles</a></li>
+<li><a class="reference internal" href="#how-do-i-create-a-relation-in-designer">6.31 How do I create a relation in designer?</a></li>
+<li><a class="reference internal" href="#how-can-i-use-the-zoom-search-feature">6.32 How can I use the zoom search feature?</a></li>
+<li><a class="reference internal" href="#when-browsing-a-table-how-can-i-copy-a-column-name">6.33 When browsing a table, how can I copy a column name?</a></li>
+</ul>
+</li>
+<li><a class="reference internal" href="#phpmyadmin-project">phpMyAdmin project</a><ul>
+<li><a class="reference internal" href="#i-have-found-a-bug-how-do-i-inform-developers">7.1 I have found a bug. How do I inform developers?</a></li>
+<li><a class="reference internal" href="#i-want-to-translate-the-messages-to-a-new-language-or-upgrade-an-existing-language-where-do-i-start">7.2 I want to translate the messages to a new language or upgrade an existing language, where do I start?</a></li>
+<li><a class="reference internal" href="#i-would-like-to-help-out-with-the-development-of-phpmyadmin-how-should-i-proceed">7.3 I would like to help out with the development of phpMyAdmin. How should I proceed?</a></li>
+</ul>
+</li>
+<li><a class="reference internal" href="#security">Security</a><ul>
+<li><a class="reference internal" href="#where-can-i-get-information-about-the-security-alerts-issued-for-phpmyadmin">8.1 Where can I get information about the security alerts issued for phpMyAdmin?</a></li>
+<li><a class="reference internal" href="#how-can-i-protect-phpmyadmin-against-brute-force-attacks">8.2 How can I protect phpMyAdmin against brute force attacks?</a></li>
+</ul>
+</li>
+<li><a class="reference internal" href="#synchronization">Synchronization</a><ul>
+<li><a class="reference internal" href="#faq9-1">9.1 (withdrawn).</a></li>
+<li><a class="reference internal" href="#faq9-2">9.2 (withdrawn).</a></li>
+</ul>
+</li>
+</ul>
+</li>
+</ul>
+
+  <h4>Previous topic</h4>
+  <p class="topless"><a href="other.html"
+                        title="previous chapter">Other sources of information</a></p>
+  <h4>Next topic</h4>
+  <p class="topless"><a href="developers.html"
+                        title="next chapter">Developers Information</a></p>
+  <h3>This Page</h3>
+  <ul class="this-page-menu">
+    <li><a href="_sources/faq.txt"
+           rel="nofollow">Show Source</a></li>
+  </ul>
+<div id="searchbox" style="display: none">
+  <h3>Quick search</h3>
+    <form class="search" action="search.html" method="get">
+      <input type="text" name="q" />
+      <input type="submit" value="Go" />
+      <input type="hidden" name="check_keywords" value="yes" />
+      <input type="hidden" name="area" value="default" />
+    </form>
+    <p class="searchtip" style="font-size: 90%">
+    Enter search terms or a module, class or function name.
+    </p>
+</div>
+<script type="text/javascript">$('#searchbox').show(0);</script>
+        </div>
+      </div>
+      <div class="clearer"></div>
+    </div>
+    <div class="related">
+      <h3>Navigation</h3>
+      <ul>
+        <li class="right" style="margin-right: 10px">
+          <a href="genindex.html" title="General Index"
+             >index</a></li>
+        <li class="right" >
+          <a href="developers.html" title="Developers Information"
+             >next</a> |</li>
+        <li class="right" >
+          <a href="other.html" title="Other sources of information"
+             >previous</a> |</li>
+        <li><a href="index.html">phpMyAdmin 4.0.4 documentation</a> »</li> 
+      </ul>
+    </div>
+    <div class="footer">
+        © <a href="copyright.html">Copyright</a> 2012 - 2013, The phpMyAdmin devel team.
+      Created using <a href="http://sphinx.pocoo.org/">Sphinx</a> 1.1.3.
+    </div>
+  </body>
+</html>
\ No newline at end of file
diff --git a/phpmyadmin/doc/html/genindex.html b/phpmyadmin/doc/html/genindex.html
new file mode 100644
index 0000000..0519e30
--- /dev/null
+++ b/phpmyadmin/doc/html/genindex.html
@@ -0,0 +1,3699 @@
+
+
+
+
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+
+
+<html xmlns="http://www.w3.org/1999/xhtml">
+  <head>
+    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+    
+    <title>Index — phpMyAdmin 4.0.4 documentation</title>
+    
+    <link rel="stylesheet" href="_static/default.css" type="text/css" />
+    <link rel="stylesheet" href="_static/pygments.css" type="text/css" />
+    
+    <script type="text/javascript">
+      var DOCUMENTATION_OPTIONS = {
+        URL_ROOT:    '',
+        VERSION:     '4.0.4',
+        COLLAPSE_INDEX: false,
+        FILE_SUFFIX: '.html',
+        HAS_SOURCE:  true
+      };
+    </script>
+    <script type="text/javascript" src="_static/jquery.js"></script>
+    <script type="text/javascript" src="_static/underscore.js"></script>
+    <script type="text/javascript" src="_static/doctools.js"></script>
+    <link rel="copyright" title="Copyright" href="copyright.html" />
+    <link rel="top" title="phpMyAdmin 4.0.4 documentation" href="index.html" /> 
+  </head>
+  <body>
+    <div class="related">
+      <h3>Navigation</h3>
+      <ul>
+        <li class="right" style="margin-right: 10px">
+          <a href="#" title="General Index"
+             accesskey="I">index</a></li>
+        <li><a href="index.html">phpMyAdmin 4.0.4 documentation</a> »</li> 
+      </ul>
+    </div>  
+
+    <div class="document">
+      <div class="documentwrapper">
+        <div class="bodywrapper">
+          <div class="body">
+            
+
+<h1 id="index">Index</h1>
+
+<div class="genindex-jumpbox">
+ <a href="#Symbols"><strong>Symbols</strong></a>
+ | <a href="#A"><strong>A</strong></a>
+ | <a href="#B"><strong>B</strong></a>
+ | <a href="#C"><strong>C</strong></a>
+ | <a href="#D"><strong>D</strong></a>
+ | <a href="#E"><strong>E</strong></a>
+ | <a href="#F"><strong>F</strong></a>
+ | <a href="#G"><strong>G</strong></a>
+ | <a href="#H"><strong>H</strong></a>
+ | <a href="#I"><strong>I</strong></a>
+ | <a href="#J"><strong>J</strong></a>
+ | <a href="#K"><strong>K</strong></a>
+ | <a href="#L"><strong>L</strong></a>
+ | <a href="#M"><strong>M</strong></a>
+ | <a href="#N"><strong>N</strong></a>
+ | <a href="#O"><strong>O</strong></a>
+ | <a href="#P"><strong>P</strong></a>
+ | <a href="#Q"><strong>Q</strong></a>
+ | <a href="#R"><strong>R</strong></a>
+ | <a href="#S"><strong>S</strong></a>
+ | <a href="#T"><strong>T</strong></a>
+ | <a href="#U"><strong>U</strong></a>
+ | <a href="#V"><strong>V</strong></a>
+ | <a href="#W"><strong>W</strong></a>
+ | <a href="#X"><strong>X</strong></a>
+ | <a href="#Z"><strong>Z</strong></a>
+ 
+</div>
+<h2 id="Symbols">Symbols</h2>
+<table style="width: 100%" class="indextable genindextable"><tr>
+  <td style="width: 33%" valign="top"><dl>
+      
+  <dt><a href="setup.html#index-9"><strong>$cfg['AllowArbitraryServer']</strong></a>, <a href="config.html#index-9"><strong>[1]</strong></a>, <a href="config.html#cfg_AllowArbitraryServer"><strong>[2]</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_AllowUserDropDatabase"><strong>$cfg['AllowUserDropDatabase']</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_AvailableCharsets"><strong>$cfg['AvailableCharsets']</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_BgOne"><strong>$cfg['BgOne']</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_BgTwo"><strong>$cfg['BgTwo']</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_blowfish_secret"><strong>$cfg['blowfish_secret']</strong></a>, <a href="config.html#index-59"><strong>[1]</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_Border"><strong>$cfg['Border']</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_BrowseMarkerBackground"><strong>$cfg['BrowseMarkerBackground']</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_BrowseMarkerColor"><strong>$cfg['BrowseMarkerColor']</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_BrowseMarkerEnable"><strong>$cfg['BrowseMarkerEnable']</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_BrowseMIME"><strong>$cfg['BrowseMIME']</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_BrowsePointerBackground"><strong>$cfg['BrowsePointerBackground']</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_BrowsePointerColor"><strong>$cfg['BrowsePointerColor']</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_BrowsePointerEnable"><strong>$cfg['BrowsePointerEnable']</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_BZipDump"><strong>$cfg['BZipDump']</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_CharEditing"><strong>$cfg['CharEditing']</strong></a>, <a href="config.html#index-70"><strong>[1]</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_CharTextareaCols"><strong>$cfg['CharTextareaCols']</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_CharTextareaRows"><strong>$cfg['CharTextareaRows']</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_CheckConfigurationPermissions"><strong>$cfg['CheckConfigurationPermissions']</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_CodemirrorEnable"><strong>$cfg['CodemirrorEnable']</strong></a>
+  </dt>
+
+      
+  <dt><a href="faq.html#index-18"><strong>$cfg['CompressOnFly']</strong></a>, <a href="config.html#cfg_CompressOnFly"><strong>[1]</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_Confirm"><strong>$cfg['Confirm']</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_CSPAllow"><strong>$cfg['CSPAllow']</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_DBG"><strong>$cfg['DBG']</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_DBG_sql"><strong>$cfg['DBG']['sql']</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_DefaultConnectionCollation"><strong>$cfg['DefaultConnectionCollation']</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_DefaultDisplay"><strong>$cfg['DefaultDisplay']</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_DefaultFunctions"><strong>$cfg['DefaultFunctions']</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_DefaultLang"><strong>$cfg['DefaultLang']</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_DefaultQueryDatabase"><strong>$cfg['DefaultQueryDatabase']</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_DefaultQueryTable"><strong>$cfg['DefaultQueryTable']</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_DefaultTabDatabase"><strong>$cfg['DefaultTabDatabase']</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_DefaultTabServer"><strong>$cfg['DefaultTabServer']</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_DefaultTabTable"><strong>$cfg['DefaultTabTable']</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_DisableMultiTableMaintenance"><strong>$cfg['DisableMultiTableMaintenance']</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_DisplayBinaryAsHex"><strong>$cfg['DisplayBinaryAsHex']</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_DisplayServersList"><strong>$cfg['DisplayServersList']</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_EditInWindow"><strong>$cfg['EditInWindow']</strong></a>, <a href="config.html#index-74"><strong>[1]</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_Error_Handler_display"><strong>$cfg['Error_Handler']['display']</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_Error_Handler_gather"><strong>$cfg['Error_Handler']['gather']</strong></a>
+  </dt>
+
+      
+  <dt><a href="faq.html#index-26"><strong>$cfg['ExecTimeLimit']</strong></a>, <a href="config.html#cfg_ExecTimeLimit"><strong>[1]</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_Export"><strong>$cfg['Export']</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#index-66"><strong>$cfg['Export']['charset']</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_Export_method"><strong>$cfg['Export']['method']</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_FilterLanguages"><strong>$cfg['FilterLanguages']</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_FontFamily"><strong>$cfg['FontFamily']</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_FontFamilyFixed"><strong>$cfg['FontFamilyFixed']</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_ForceSSL"><strong>$cfg['ForceSSL']</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#index-64"><strong>$cfg['ForeignKeyDropdownOrder']</strong></a>, <a href="config.html#cfg_ForeignKeyDropdownOrder"><strong>[1]</strong></a>
+  </dt>
+
+      
+  <dt><a href="faq.html#index-27"><strong>$cfg['ForeignKeyMaxLimit']</strong></a>, <a href="config.html#cfg_ForeignKeyMaxLimit"><strong>[1]</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_GD2Available"><strong>$cfg['GD2Available']</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_GridEditing"><strong>$cfg['GridEditing']</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_GZipDump"><strong>$cfg['GZipDump']</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_HeaderFlipType"><strong>$cfg['HeaderFlipType']</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_HideStructureActions"><strong>$cfg['HideStructureActions']</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_IconvExtraParams"><strong>$cfg['IconvExtraParams']</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_IgnoreMultiSubmitErrors"><strong>$cfg['IgnoreMultiSubmitErrors']</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_Import"><strong>$cfg['Import']</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#index-67"><strong>$cfg['Import']['charset']</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_InitialSlidersState"><strong>$cfg['InitialSlidersState']</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_InsertRows"><strong>$cfg['InsertRows']</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_Lang"><strong>$cfg['Lang']</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_LimitChars"><strong>$cfg['LimitChars']</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_LinkLengthLimit"><strong>$cfg['LinkLengthLimit']</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_LoginCookieDeleteAll"><strong>$cfg['LoginCookieDeleteAll']</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_LoginCookieRecall"><strong>$cfg['LoginCookieRecall']</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_LoginCookieStore"><strong>$cfg['LoginCookieStore']</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_LoginCookieValidity"><strong>$cfg['LoginCookieValidity']</strong></a>, <a href="config.html#index-60"><strong>[1]</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_LongtextDoubleTextarea"><strong>$cfg['LongtextDoubleTextarea']</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_MainBackground"><strong>$cfg['MainBackground']</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_MaxCharactersInDisplayedSQL"><strong>$cfg['MaxCharactersInDisplayedSQL']</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_MaxDbList"><strong>$cfg['MaxDbList']</strong></a>
+  </dt>
+
+      
+  <dt><a href="faq.html#index-20"><strong>$cfg['MaxExactCount']</strong></a>, <a href="config.html#cfg_MaxExactCount"><strong>[1]</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_MaxExactCountViews"><strong>$cfg['MaxExactCountViews']</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_MaxNavigationItems"><strong>$cfg['MaxNavigationItems']</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#index-63"><strong>$cfg['MaxRows']</strong></a>, <a href="config.html#cfg_MaxRows"><strong>[1]</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_MaxSizeForInputField"><strong>$cfg['MaxSizeForInputField']</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_MaxTableList"><strong>$cfg['MaxTableList']</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_McryptDisableWarning"><strong>$cfg['McryptDisableWarning']</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_MemoryLimit"><strong>$cfg['MemoryLimit']</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_MinSizeForInputField"><strong>$cfg['MinSizeForInputField']</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_MySQLManualBase"><strong>$cfg['MySQLManualBase']</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#index-65"><strong>$cfg['MySQLManualType']</strong></a>, <a href="config.html#cfg_MySQLManualType"><strong>[1]</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_NaturalOrder"><strong>$cfg['NaturalOrder']</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_NaviBackground"><strong>$cfg['NaviBackground']</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_NavigationBarIconic"><strong>$cfg['NavigationBarIconic']</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_NavigationDisplayLogo"><strong>$cfg['NavigationDisplayLogo']</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_NavigationDisplayServers"><strong>$cfg['NavigationDisplayServers']</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_NavigationLogoLink"><strong>$cfg['NavigationLogoLink']</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_NavigationLogoLinkWindow"><strong>$cfg['NavigationLogoLinkWindow']</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#index-61"><strong>$cfg['NavigationTreeDbSeparator']</strong></a>, <a href="config.html#cfg_NavigationTreeDbSeparator"><strong>[1]</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#index-34"><strong>$cfg['NavigationTreeDefaultTabTable']</strong></a>, <a href="config.html#cfg_NavigationTreeDefaultTabTable"><strong>[1]</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_NavigationTreeDisplayDbFilterMinimum"><strong>$cfg['NavigationTreeDisplayDbFilterMinimum']</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_NavigationTreeDisplayItemFilterMinimum"><strong>$cfg['NavigationTreeDisplayItemFilterMinimum']</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_NavigationTreeEnableGrouping"><strong>$cfg['NavigationTreeEnableGrouping']</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_NavigationTreePointerEnable"><strong>$cfg['NavigationTreePointerEnable']</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_NavigationTreeTableLevel"><strong>$cfg['NavigationTreeTableLevel']</strong></a>
+  </dt>
+
+      
+  <dt><a href="faq.html#index-19"><strong>$cfg['NavigationTreeTableSeparator']</strong></a>, <a href="config.html#cfg_NavigationTreeTableSeparator"><strong>[1]</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_NaviPointerBackground"><strong>$cfg['NaviPointerBackground']</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_NaviPointerColor"><strong>$cfg['NaviPointerColor']</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_NaviWidth"><strong>$cfg['NaviWidth']</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#index-33"><strong>$cfg['NumRecentTables']</strong></a>, <a href="config.html#cfg_NumRecentTables"><strong>[1]</strong></a>
+  </dt>
+
+      
+  <dt><a href="faq.html#index-0"><strong>$cfg['OBGzip']</strong></a>, <a href="faq.html#index-4"><strong>[1]</strong></a>, <a href="faq.html#index-8"><strong>[2]</strong></a>, <a href="config.html#cfg_OBGzip"><strong>[3]</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_Order"><strong>$cfg['Order']</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_PersistentConnections"><strong>$cfg['PersistentConnections']</strong></a>
+  </dt>
+
+      
+  <dt><a href="faq.html#index-9"><strong>$cfg['PmaAbsoluteUri']</strong></a>, <a href="faq.html#index-16"><strong>[1]</strong></a>, <a href="faq.html#index-24"><strong>[2]</strong></a>, <a href="faq.html#index-25"><strong>[3]</strong></a>, <a href="config.html#cfg_PmaAbsoluteUri"><strong>[4]</strong></a>, <a href="config.html#index-1"><strong>[5]</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_PmaNoRelation_DisableWarning"><strong>$cfg['PmaNoRelation_DisableWarning']</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_PropertiesIconic"><strong>$cfg['PropertiesIconic']</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_PropertiesNumColumns"><strong>$cfg['PropertiesNumColumns']</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_ProtectBinary"><strong>$cfg['ProtectBinary']</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_QueryHistoryDB"><strong>$cfg['QueryHistoryDB']</strong></a>, <a href="config.html#index-75"><strong>[1]</strong></a>, <a href="config.html#index-77"><strong>[2]</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#index-30"><strong>$cfg['QueryHistoryMax']</strong></a>, <a href="config.html#cfg_QueryHistoryMax"><strong>[1]</strong></a>, <a href="config.html#index-78"><strong>[2]</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_QueryWindowDefTab"><strong>$cfg['QueryWindowDefTab']</strong></a>, <a href="config.html#index-79"><strong>[1]</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_QueryWindowHeight"><strong>$cfg['QueryWindowHeight']</strong></a>, <a href="config.html#index-73"><strong>[1]</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_QueryWindowWidth"><strong>$cfg['QueryWindowWidth']</strong></a>, <a href="config.html#index-72"><strong>[1]</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_RecodingEngine"><strong>$cfg['RecodingEngine']</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#index-37"><strong>$cfg['RememberSorting']</strong></a>, <a href="config.html#cfg_RememberSorting"><strong>[1]</strong></a>
+  </dt>
+
+  </dl></td>
+  <td style="width: 33%" valign="top"><dl>
+      
+  <dt><a href="config.html#cfg_RepeatCells"><strong>$cfg['RepeatCells']</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_ReservedWordDisableWarning"><strong>$cfg['ReservedWordDisableWarning']</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_RetainQueryBox"><strong>$cfg['RetainQueryBox']</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_RowActionLinks"><strong>$cfg['RowActionLinks']</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_SaveCellsAtOnce"><strong>$cfg['SaveCellsAtOnce']</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_SaveDir"><strong>$cfg['SaveDir']</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_ServerDefault"><strong>$cfg['ServerDefault']</strong></a>, <a href="config.html#index-57"><strong>[1]</strong></a>, <a href="config.html#index-58"><strong>[2]</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_ServerLibraryDifference_DisableWarning"><strong>$cfg['ServerLibraryDifference_DisableWarning']</strong></a>
+  </dt>
+
+      
+  <dt><a href="setup.html#index-6"><strong>$cfg['Servers']</strong></a>, <a href="config.html#cfg_Servers"><strong>[1]</strong></a>, <a href="config.html#index-3"><strong>[2]</strong></a>, <a href="config.html#index-6"><strong>[3]</strong></a>
+  </dt>
+
+      
+  <dt><a href="setup.html#index-19"><strong>$cfg['Servers'][$i]['AllowDeny']['order']</strong></a>, <a href="config.html#cfg_Servers_AllowDeny_order"><strong>[1]</strong></a>, <a href="config.html#index-68"><strong>[2]</strong></a>
+  </dt>
+
+      
+  <dt><a href="setup.html#index-20"><strong>$cfg['Servers'][$i]['AllowDeny']['rules']</strong></a>, <a href="setup.html#index-23"><strong>[1]</strong></a>, <a href="faq.html#index-23"><strong>[2]</strong></a>, <a href="config.html#index-50"><strong>[3]</strong></a>, <a href="config.html#cfg_Servers_AllowDeny_rules"><strong>[4]</strong></a>, <a href="config.html#index-69"><strong>[5]</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_Servers_AllowNoPassword"><strong>$cfg['Servers'][$i]['AllowNoPassword']</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_Servers_AllowRoot"><strong>$cfg['Servers'][$i]['AllowRoot']</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_Servers_auth_http_realm"><strong>$cfg['Servers'][$i]['auth_http_realm']</strong></a>
+  </dt>
+
+      
+  <dt><a href="setup.html#index-22"><strong>$cfg['Servers'][$i]['auth_swekey_config']</strong></a>, <a href="config.html#cfg_Servers_auth_swekey_config"><strong>[1]</strong></a>
+  </dt>
+
+      
+  <dt><a href="setup.html#index-11"><strong>$cfg['Servers'][$i]['auth_type']</strong></a>, <a href="config.html#cfg_Servers_auth_type"><strong>[1]</strong></a>, <a href="config.html#index-15"><strong>[2]</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_Servers_bookmarktable"><strong>$cfg['Servers'][$i]['bookmarktable']</strong></a>, <a href="config.html#index-18"><strong>[1]</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#index-28"><strong>$cfg['Servers'][$i]['column_comments']</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_Servers_column_info"><strong>$cfg['Servers'][$i]['column_info']</strong></a>, <a href="config.html#index-27"><strong>[1]</strong></a>, <a href="config.html#index-29"><strong>[2]</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_Servers_compress"><strong>$cfg['Servers'][$i]['compress']</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_Servers_connect_type"><strong>$cfg['Servers'][$i]['connect_type']</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_Servers_controlhost"><strong>$cfg['Servers'][$i]['controlhost']</strong></a>
+  </dt>
+
+      
+  <dt><a href="setup.html#index-5"><strong>$cfg['Servers'][$i]['controlpass']</strong></a>, <a href="faq.html#index-22"><strong>[1]</strong></a>, <a href="config.html#cfg_Servers_controlpass"><strong>[2]</strong></a>
+  </dt>
+
+      
+  <dt><a href="setup.html#index-3"><strong>$cfg['Servers'][$i]['controluser']</strong></a>, <a href="setup.html#index-4"><strong>[1]</strong></a>, <a href="faq.html#index-21"><strong>[2]</strong></a>, <a href="config.html#cfg_Servers_controluser"><strong>[3]</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_Servers_designer_coords"><strong>$cfg['Servers'][$i]['designer_coords']</strong></a>, <a href="config.html#index-46"><strong>[1]</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_Servers_DisableIS"><strong>$cfg['Servers'][$i]['DisableIS']</strong></a>, <a href="config.html#index-55"><strong>[1]</strong></a>
+  </dt>
+
+      
+  <dt><a href="faq.html#index-3"><strong>$cfg['Servers'][$i]['extension']</strong></a>, <a href="config.html#cfg_Servers_extension"><strong>[1]</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_Servers_hide_db"><strong>$cfg['Servers'][$i]['hide_db']</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_Servers_history"><strong>$cfg['Servers'][$i]['history']</strong></a>, <a href="config.html#index-32"><strong>[1]</strong></a>, <a href="config.html#index-76"><strong>[2]</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#index-4"><strong>$cfg['Servers'][$i]['host']</strong></a>, <a href="config.html#index-5"><strong>[1]</strong></a>, <a href="config.html#cfg_Servers_host"><strong>[2]</strong></a>, <a href="config.html#index-7"><strong>[3]</strong></a>, <a href="config.html#index-14"><strong>[4]</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_Servers_LogoutURL"><strong>$cfg['Servers'][$i]['LogoutURL']</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_Servers_MaxTableUiprefs"><strong>$cfg['Servers'][$i]['MaxTableUiprefs']</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_Servers_nopassword"><strong>$cfg['Servers'][$i]['nopassword']</strong></a>
+  </dt>
+
+      
+  <dt><a href="setup.html#index-18"><strong>$cfg['Servers'][$i]['only_db']</strong></a>, <a href="config.html#cfg_Servers_only_db"><strong>[1]</strong></a>, <a href="config.html#index-52"><strong>[2]</strong></a>
+  </dt>
+
+      
+  <dt><a href="setup.html#index-17"><strong>$cfg['Servers'][$i]['password']</strong></a>, <a href="config.html#cfg_Servers_password"><strong>[1]</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_Servers_pdf_pages"><strong>$cfg['Servers'][$i]['pdf_pages']</strong></a>, <a href="config.html#index-25"><strong>[1]</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#index-2"><strong>$cfg['Servers'][$i]['pmadb']</strong></a>, <a href="config.html#index-8"><strong>[1]</strong></a>, <a href="config.html#cfg_Servers_pmadb"><strong>[2]</strong></a>, <a href="config.html#index-16"><strong>[3]</strong></a>, <a href="config.html#index-17"><strong>[4]</strong></a>, <a href="config.html#index-19"><strong>[5]</strong></a>, <a href="config.html#index-21"><strong>[6]</strong></a>, <a href="config.html#index-23"><strong> [...]
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_Servers_port"><strong>$cfg['Servers'][$i]['port']</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_Servers_recent"><strong>$cfg['Servers'][$i]['recent']</strong></a>, <a href="config.html#index-36"><strong>[1]</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_Servers_relation"><strong>$cfg['Servers'][$i]['relation']</strong></a>, <a href="config.html#index-20"><strong>[1]</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_Servers_ShowDatabasesCommand"><strong>$cfg['Servers'][$i]['ShowDatabasesCommand']</strong></a>
+  </dt>
+
+      
+  <dt><a href="setup.html#index-13"><strong>$cfg['Servers'][$i]['SignonScript']</strong></a>, <a href="config.html#index-11"><strong>[1]</strong></a>, <a href="config.html#cfg_Servers_SignonScript"><strong>[2]</strong></a>, <a href="config.html#index-53"><strong>[3]</strong></a>
+  </dt>
+
+      
+  <dt><a href="setup.html#index-12"><strong>$cfg['Servers'][$i]['SignonSession']</strong></a>, <a href="config.html#index-10"><strong>[1]</strong></a>, <a href="config.html#cfg_Servers_SignonSession"><strong>[2]</strong></a>
+  </dt>
+
+      
+  <dt><a href="setup.html#index-14"><strong>$cfg['Servers'][$i]['SignonURL']</strong></a>, <a href="config.html#index-12"><strong>[1]</strong></a>, <a href="config.html#cfg_Servers_SignonURL"><strong>[2]</strong></a>
+  </dt>
+
+      
+  <dt><a href="faq.html#index-7"><strong>$cfg['Servers'][$i]['socket']</strong></a>, <a href="config.html#cfg_Servers_socket"><strong>[1]</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_Servers_ssl"><strong>$cfg['Servers'][$i]['ssl']</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_Servers_StatusCacheDatabases"><strong>$cfg['Servers'][$i]['StatusCacheDatabases']</strong></a>, <a href="config.html#index-56"><strong>[1]</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#index-54"><strong>$cfg['Servers'][$i]['StatusCacheLifetime']</strong></a>, <a href="config.html#cfg_Servers_StatusCacheLifetime"><strong>[1]</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_Servers_table_coords"><strong>$cfg['Servers'][$i]['table_coords']</strong></a>, <a href="config.html#index-24"><strong>[1]</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_Servers_table_info"><strong>$cfg['Servers'][$i]['table_info']</strong></a>, <a href="config.html#index-22"><strong>[1]</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_Servers_table_uiprefs"><strong>$cfg['Servers'][$i]['table_uiprefs']</strong></a>, <a href="config.html#index-39"><strong>[1]</strong></a>, <a href="config.html#index-47"><strong>[2]</strong></a>, <a href="config.html#index-48"><strong>[3]</strong></a>, <a href="config.html#index-49"><strong>[4]</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_Servers_tracking"><strong>$cfg['Servers'][$i]['tracking']</strong></a>, <a href="config.html#index-41"><strong>[1]</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_Servers_tracking_add_drop_database"><strong>$cfg['Servers'][$i]['tracking_add_drop_database']</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_Servers_tracking_add_drop_table"><strong>$cfg['Servers'][$i]['tracking_add_drop_table']</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_Servers_tracking_add_drop_view"><strong>$cfg['Servers'][$i]['tracking_add_drop_view']</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_Servers_tracking_default_statements"><strong>$cfg['Servers'][$i]['tracking_default_statements']</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_Servers_tracking_version_auto_create"><strong>$cfg['Servers'][$i]['tracking_version_auto_create']</strong></a>
+  </dt>
+
+      
+  <dt><a href="setup.html#index-16"><strong>$cfg['Servers'][$i]['user']</strong></a>, <a href="config.html#cfg_Servers_user"><strong>[1]</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_Servers_userconfig"><strong>$cfg['Servers'][$i]['userconfig']</strong></a>, <a href="config.html#index-44"><strong>[1]</strong></a>
+  </dt>
+
+      
+  <dt><a href="faq.html#index-28"><strong>$cfg['Servers'][$i]['verbose']</strong></a>, <a href="config.html#index-13"><strong>[1]</strong></a>, <a href="config.html#cfg_Servers_verbose"><strong>[2]</strong></a>, <a href="config.html#index-62"><strong>[3]</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_SessionSavePath"><strong>$cfg['SessionSavePath']</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_ShowAll"><strong>$cfg['ShowAll']</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_ShowBrowseComments"><strong>$cfg['ShowBrowseComments']</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_ShowChgPassword"><strong>$cfg['ShowChgPassword']</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_ShowCreateDb"><strong>$cfg['ShowCreateDb']</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_ShowDbStructureCreation"><strong>$cfg['ShowDbStructureCreation']</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_ShowDbStructureLastCheck"><strong>$cfg['ShowDbStructureLastCheck']</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_ShowDbStructureLastUpdate"><strong>$cfg['ShowDbStructureLastUpdate']</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_ShowDisplayDirection"><strong>$cfg['ShowDisplayDirection']</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_ShowFieldTypesInDataEditView"><strong>$cfg['ShowFieldTypesInDataEditView']</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_ShowFunctionFields"><strong>$cfg['ShowFunctionFields']</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_ShowHint"><strong>$cfg['ShowHint']</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_ShowPhpInfo"><strong>$cfg['ShowPhpInfo']</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_ShowPropertyComments"><strong>$cfg['ShowPropertyComments']</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_ShowServerInfo"><strong>$cfg['ShowServerInfo']</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_ShowSQL"><strong>$cfg['ShowSQL']</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_ShowStats"><strong>$cfg['ShowStats']</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_ShowTooltip"><strong>$cfg['ShowTooltip']</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_SkipLockedTables"><strong>$cfg['SkipLockedTables']</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_SQLQuery_Edit"><strong>$cfg['SQLQuery']['Edit']</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_SQLQuery_Explain"><strong>$cfg['SQLQuery']['Explain']</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_SQLQuery_Refresh"><strong>$cfg['SQLQuery']['Refresh']</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_SQLQuery_ShowAsPHP"><strong>$cfg['SQLQuery']['ShowAsPHP']</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_SQLQuery_Validate"><strong>$cfg['SQLQuery']['Validate']</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#index-71"><strong>$cfg['SQLValidator']</strong></a>, <a href="config.html#cfg_SQLValidator"><strong>[1]</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_SQLValidator_password"><strong>$cfg['SQLValidator']['password']</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_SQLValidator_use"><strong>$cfg['SQLValidator']['use']</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_SQLValidator_username"><strong>$cfg['SQLValidator']['username']</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_SQP_fmtColor"><strong>$cfg['SQP']['fmtColor']</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_SQP_fmtInd"><strong>$cfg['SQP']['fmtInd']</strong></a>, <a href="config.html#index-81"><strong>[1]</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_SQP_fmtIndUnit"><strong>$cfg['SQP']['fmtIndUnit']</strong></a>, <a href="config.html#index-82"><strong>[1]</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_SQP_fmtType"><strong>$cfg['SQP']['fmtType']</strong></a>
+  </dt>
+
+      
+  <dt><a href="faq.html#index-6"><strong>$cfg['SuhosinDisableWarning']</strong></a>, <a href="config.html#cfg_SuhosinDisableWarning"><strong>[1]</strong></a>
+  </dt>
+
+      
+  <dt><a href="faq.html#index-1"><strong>$cfg['TempDir']</strong></a>, <a href="faq.html#index-30"><strong>[1]</strong></a>, <a href="config.html#cfg_TempDir"><strong>[2]</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_TextareaAutoSelect"><strong>$cfg['TextareaAutoSelect']</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_TextareaCols"><strong>$cfg['TextareaCols']</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_TextareaRows"><strong>$cfg['TextareaRows']</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_ThBackground"><strong>$cfg['ThBackground']</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_ThColor"><strong>$cfg['ThColor']</strong></a>
+  </dt>
+
+      
+  <dt><a href="faq.html#index-12"><strong>$cfg['ThemeDefault']</strong></a>, <a href="config.html#cfg_ThemeDefault"><strong>[1]</strong></a>
+  </dt>
+
+      
+  <dt><a href="faq.html#index-11"><strong>$cfg['ThemeManager']</strong></a>, <a href="faq.html#index-14"><strong>[1]</strong></a>, <a href="config.html#cfg_ThemeManager"><strong>[2]</strong></a>
+  </dt>
+
+      
+  <dt><a href="faq.html#index-10"><strong>$cfg['ThemePath']</strong></a>, <a href="faq.html#index-13"><strong>[1]</strong></a>, <a href="faq.html#index-15"><strong>[2]</strong></a>, <a href="config.html#cfg_ThemePath"><strong>[3]</strong></a>, <a href="config.html#index-80"><strong>[4]</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_ThemePerServer"><strong>$cfg['ThemePerServer']</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_TitleDatabase"><strong>$cfg['TitleDatabase']</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_TitleDefault"><strong>$cfg['TitleDefault']</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_TitleServer"><strong>$cfg['TitleServer']</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_TitleTable"><strong>$cfg['TitleTable']</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_TranslationWarningThreshold"><strong>$cfg['TranslationWarningThreshold']</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#index-51"><strong>$cfg['TrustedProxies']</strong></a>, <a href="config.html#cfg_TrustedProxies"><strong>[1]</strong></a>
+  </dt>
+
+      
+  <dt><a href="faq.html#index-2"><strong>$cfg['UploadDir']</strong></a>, <a href="faq.html#index-29"><strong>[1]</strong></a>, <a href="config.html#cfg_UploadDir"><strong>[2]</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_UseDbSearch"><strong>$cfg['UseDbSearch']</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_UserprefsDeveloperTab"><strong>$cfg['UserprefsDeveloperTab']</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_UserprefsDisallow"><strong>$cfg['UserprefsDisallow']</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_VersionCheck"><strong>$cfg['VersionCheck']</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_ZipDump"><strong>$cfg['ZipDump']</strong></a>
+  </dt>
+
+      
+  <dt><a href="glossary.html#term-htaccess"><strong>.htaccess</strong></a>
+  </dt>
+
+  </dl></td>
+</tr></table>
+
+<h2 id="A">A</h2>
+<table style="width: 100%" class="indextable genindextable"><tr>
+  <td style="width: 33%" valign="top"><dl>
+      
+  <dt><a href="glossary.html#term-acl"><strong>ACL</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_AllowArbitraryServer"><strong>AllowArbitraryServer</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_Servers_AllowDeny_order"><strong>AllowDeny, order</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_Servers_AllowDeny_rules"><strong>AllowDeny, rules</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_Servers_AllowNoPassword"><strong>AllowNoPassword</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_Servers_AllowRoot"><strong>AllowRoot</strong></a>
+  </dt>
+
+  </dl></td>
+  <td style="width: 33%" valign="top"><dl>
+      
+  <dt><a href="config.html#cfg_AllowUserDropDatabase"><strong>AllowUserDropDatabase</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_Servers_auth_http_realm"><strong>auth_http_realm</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_Servers_auth_swekey_config"><strong>auth_swekey_config</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_Servers_auth_type"><strong>auth_type</strong></a>
+  </dt>
+
+      
+  <dt><a href="setup.html#index-2">Authentication mode</a>
+  </dt>
+
+      <dd><dl>
+        
+  <dt><a href="setup.html#index-15">Config</a>
+  </dt>
+
+        
+  <dt><a href="setup.html#index-8">Cookie</a>
+  </dt>
+
+        
+  <dt><a href="setup.html#index-7">HTTP</a>
+  </dt>
+
+        
+  <dt><a href="setup.html#index-10">Signon</a>
+  </dt>
+
+        
+  <dt><a href="setup.html#index-21">Swekey</a>
+  </dt>
+
+      </dl></dd>
+      
+  <dt><a href="config.html#cfg_AvailableCharsets"><strong>AvailableCharsets</strong></a>
+  </dt>
+
+  </dl></td>
+</tr></table>
+
+<h2 id="B">B</h2>
+<table style="width: 100%" class="indextable genindextable"><tr>
+  <td style="width: 33%" valign="top"><dl>
+      
+  <dt><a href="config.html#cfg_BgOne"><strong>BgOne</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_BgTwo"><strong>BgTwo</strong></a>
+  </dt>
+
+      
+  <dt><a href="glossary.html#term-blowfish"><strong>Blowfish</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_blowfish_secret"><strong>blowfish_secret</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_Servers_bookmarktable"><strong>bookmarktable</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_Border"><strong>Border</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_BrowseMarkerBackground"><strong>BrowseMarkerBackground</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_BrowseMarkerColor"><strong>BrowseMarkerColor</strong></a>
+  </dt>
+
+  </dl></td>
+  <td style="width: 33%" valign="top"><dl>
+      
+  <dt><a href="config.html#cfg_BrowseMarkerEnable"><strong>BrowseMarkerEnable</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_BrowseMIME"><strong>BrowseMIME</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_BrowsePointerBackground"><strong>BrowsePointerBackground</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_BrowsePointerColor"><strong>BrowsePointerColor</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_BrowsePointerEnable"><strong>BrowsePointerEnable</strong></a>
+  </dt>
+
+      
+  <dt><a href="glossary.html#term-browser"><strong>Browser</strong></a>
+  </dt>
+
+      
+  <dt><a href="glossary.html#term-bzip2"><strong>bzip2</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_BZipDump"><strong>BZipDump</strong></a>
+  </dt>
+
+  </dl></td>
+</tr></table>
+
+<h2 id="C">C</h2>
+<table style="width: 100%" class="indextable genindextable"><tr>
+  <td style="width: 33%" valign="top"><dl>
+      
+  <dt><a href="glossary.html#term-cgi"><strong>CGI</strong></a>
+  </dt>
+
+      
+  <dt><a href="glossary.html#term-changelog"><strong>Changelog</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_CharEditing"><strong>CharEditing</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_CharTextareaCols"><strong>CharTextareaCols</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_CharTextareaRows"><strong>CharTextareaRows</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_CheckConfigurationPermissions"><strong>CheckConfigurationPermissions</strong></a>
+  </dt>
+
+      
+  <dt><a href="glossary.html#term-client"><strong>Client</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_CodemirrorEnable"><strong>CodemirrorEnable</strong></a>
+  </dt>
+
+      
+  <dt><a href="glossary.html#term-column"><strong>column</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_Servers_column_info"><strong>column_info</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_Servers_compress"><strong>compress</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_CompressOnFly"><strong>CompressOnFly</strong></a>
+  </dt>
+
+  </dl></td>
+  <td style="width: 33%" valign="top"><dl>
+      
+  <dt>
+    Config
+  </dt>
+
+      <dd><dl>
+        
+  <dt><a href="setup.html#index-15">Authentication mode</a>
+  </dt>
+
+      </dl></dd>
+      
+  <dt><a href="config.html#index-0">config.inc.php</a>
+  </dt>
+
+      
+  <dt>
+    configuration option
+  </dt>
+
+      <dd><dl>
+        
+  <dt><a href="setup.html#index-9"><strong>$cfg['AllowArbitraryServer']</strong></a>, <a href="config.html#index-9"><strong>[1]</strong></a>, <a href="config.html#cfg_AllowArbitraryServer"><strong>[2]</strong></a>
+  </dt>
+
+        
+  <dt><a href="config.html#cfg_AllowUserDropDatabase"><strong>$cfg['AllowUserDropDatabase']</strong></a>
+  </dt>
+
+        
+  <dt><a href="config.html#cfg_AvailableCharsets"><strong>$cfg['AvailableCharsets']</strong></a>
+  </dt>
+
+        
+  <dt><a href="config.html#cfg_BZipDump"><strong>$cfg['BZipDump']</strong></a>
+  </dt>
+
+        
+  <dt><a href="config.html#cfg_BgOne"><strong>$cfg['BgOne']</strong></a>
+  </dt>
+
+        
+  <dt><a href="config.html#cfg_BgTwo"><strong>$cfg['BgTwo']</strong></a>
+  </dt>
+
+        
+  <dt><a href="config.html#cfg_Border"><strong>$cfg['Border']</strong></a>
+  </dt>
+
+        
+  <dt><a href="config.html#cfg_BrowseMIME"><strong>$cfg['BrowseMIME']</strong></a>
+  </dt>
+
+        
+  <dt><a href="config.html#cfg_BrowseMarkerBackground"><strong>$cfg['BrowseMarkerBackground']</strong></a>
+  </dt>
+
+        
+  <dt><a href="config.html#cfg_BrowseMarkerColor"><strong>$cfg['BrowseMarkerColor']</strong></a>
+  </dt>
+
+        
+  <dt><a href="config.html#cfg_BrowseMarkerEnable"><strong>$cfg['BrowseMarkerEnable']</strong></a>
+  </dt>
+
+        
+  <dt><a href="config.html#cfg_BrowsePointerBackground"><strong>$cfg['BrowsePointerBackground']</strong></a>
+  </dt>
+
+        
+  <dt><a href="config.html#cfg_BrowsePointerColor"><strong>$cfg['BrowsePointerColor']</strong></a>
+  </dt>
+
+        
+  <dt><a href="config.html#cfg_BrowsePointerEnable"><strong>$cfg['BrowsePointerEnable']</strong></a>
+  </dt>
+
+        
+  <dt><a href="config.html#cfg_CSPAllow"><strong>$cfg['CSPAllow']</strong></a>
+  </dt>
+
+        
+  <dt><a href="config.html#cfg_CharEditing"><strong>$cfg['CharEditing']</strong></a>, <a href="config.html#index-70"><strong>[1]</strong></a>
+  </dt>
+
+        
+  <dt><a href="config.html#cfg_CharTextareaCols"><strong>$cfg['CharTextareaCols']</strong></a>
+  </dt>
+
+        
+  <dt><a href="config.html#cfg_CharTextareaRows"><strong>$cfg['CharTextareaRows']</strong></a>
+  </dt>
+
+        
+  <dt><a href="config.html#cfg_CheckConfigurationPermissions"><strong>$cfg['CheckConfigurationPermissions']</strong></a>
+  </dt>
+
+        
+  <dt><a href="config.html#cfg_CodemirrorEnable"><strong>$cfg['CodemirrorEnable']</strong></a>
+  </dt>
+
+        
+  <dt><a href="faq.html#index-18"><strong>$cfg['CompressOnFly']</strong></a>, <a href="config.html#cfg_CompressOnFly"><strong>[1]</strong></a>
+  </dt>
+
+        
+  <dt><a href="config.html#cfg_Confirm"><strong>$cfg['Confirm']</strong></a>
+  </dt>
+
+        
+  <dt><a href="config.html#cfg_DBG"><strong>$cfg['DBG']</strong></a>
+  </dt>
+
+        
+  <dt><a href="config.html#cfg_DBG_sql"><strong>$cfg['DBG']['sql']</strong></a>
+  </dt>
+
+        
+  <dt><a href="config.html#cfg_DefaultConnectionCollation"><strong>$cfg['DefaultConnectionCollation']</strong></a>
+  </dt>
+
+        
+  <dt><a href="config.html#cfg_DefaultDisplay"><strong>$cfg['DefaultDisplay']</strong></a>
+  </dt>
+
+        
+  <dt><a href="config.html#cfg_DefaultFunctions"><strong>$cfg['DefaultFunctions']</strong></a>
+  </dt>
+
+        
+  <dt><a href="config.html#cfg_DefaultLang"><strong>$cfg['DefaultLang']</strong></a>
+  </dt>
+
+        
+  <dt><a href="config.html#cfg_DefaultQueryDatabase"><strong>$cfg['DefaultQueryDatabase']</strong></a>
+  </dt>
+
+        
+  <dt><a href="config.html#cfg_DefaultQueryTable"><strong>$cfg['DefaultQueryTable']</strong></a>
+  </dt>
+
+        
+  <dt><a href="config.html#cfg_DefaultTabDatabase"><strong>$cfg['DefaultTabDatabase']</strong></a>
+  </dt>
+
+        
+  <dt><a href="config.html#cfg_DefaultTabServer"><strong>$cfg['DefaultTabServer']</strong></a>
+  </dt>
+
+        
+  <dt><a href="config.html#cfg_DefaultTabTable"><strong>$cfg['DefaultTabTable']</strong></a>
+  </dt>
+
+        
+  <dt><a href="config.html#cfg_DisableMultiTableMaintenance"><strong>$cfg['DisableMultiTableMaintenance']</strong></a>
+  </dt>
+
+        
+  <dt><a href="config.html#cfg_DisplayBinaryAsHex"><strong>$cfg['DisplayBinaryAsHex']</strong></a>
+  </dt>
+
+        
+  <dt><a href="config.html#cfg_DisplayServersList"><strong>$cfg['DisplayServersList']</strong></a>
+  </dt>
+
+        
+  <dt><a href="config.html#cfg_EditInWindow"><strong>$cfg['EditInWindow']</strong></a>, <a href="config.html#index-74"><strong>[1]</strong></a>
+  </dt>
+
+        
+  <dt><a href="config.html#cfg_Error_Handler_display"><strong>$cfg['Error_Handler']['display']</strong></a>
+  </dt>
+
+        
+  <dt><a href="config.html#cfg_Error_Handler_gather"><strong>$cfg['Error_Handler']['gather']</strong></a>
+  </dt>
+
+        
+  <dt><a href="faq.html#index-26"><strong>$cfg['ExecTimeLimit']</strong></a>, <a href="config.html#cfg_ExecTimeLimit"><strong>[1]</strong></a>
+  </dt>
+
+        
+  <dt><a href="config.html#cfg_Export"><strong>$cfg['Export']</strong></a>
+  </dt>
+
+        
+  <dt><a href="config.html#index-66"><strong>$cfg['Export']['charset']</strong></a>
+  </dt>
+
+        
+  <dt><a href="config.html#cfg_Export_method"><strong>$cfg['Export']['method']</strong></a>
+  </dt>
+
+        
+  <dt><a href="config.html#cfg_FilterLanguages"><strong>$cfg['FilterLanguages']</strong></a>
+  </dt>
+
+        
+  <dt><a href="config.html#cfg_FontFamily"><strong>$cfg['FontFamily']</strong></a>
+  </dt>
+
+        
+  <dt><a href="config.html#cfg_FontFamilyFixed"><strong>$cfg['FontFamilyFixed']</strong></a>
+  </dt>
+
+        
+  <dt><a href="config.html#cfg_ForceSSL"><strong>$cfg['ForceSSL']</strong></a>
+  </dt>
+
+        
+  <dt><a href="config.html#index-64"><strong>$cfg['ForeignKeyDropdownOrder']</strong></a>, <a href="config.html#cfg_ForeignKeyDropdownOrder"><strong>[1]</strong></a>
+  </dt>
+
+        
+  <dt><a href="faq.html#index-27"><strong>$cfg['ForeignKeyMaxLimit']</strong></a>, <a href="config.html#cfg_ForeignKeyMaxLimit"><strong>[1]</strong></a>
+  </dt>
+
+        
+  <dt><a href="config.html#cfg_GD2Available"><strong>$cfg['GD2Available']</strong></a>
+  </dt>
+
+        
+  <dt><a href="config.html#cfg_GZipDump"><strong>$cfg['GZipDump']</strong></a>
+  </dt>
+
+        
+  <dt><a href="config.html#cfg_GridEditing"><strong>$cfg['GridEditing']</strong></a>
+  </dt>
+
+        
+  <dt><a href="config.html#cfg_HeaderFlipType"><strong>$cfg['HeaderFlipType']</strong></a>
+  </dt>
+
+        
+  <dt><a href="config.html#cfg_HideStructureActions"><strong>$cfg['HideStructureActions']</strong></a>
+  </dt>
+
+        
+  <dt><a href="config.html#cfg_IconvExtraParams"><strong>$cfg['IconvExtraParams']</strong></a>
+  </dt>
+
+        
+  <dt><a href="config.html#cfg_IgnoreMultiSubmitErrors"><strong>$cfg['IgnoreMultiSubmitErrors']</strong></a>
+  </dt>
+
+        
+  <dt><a href="config.html#cfg_Import"><strong>$cfg['Import']</strong></a>
+  </dt>
+
+        
+  <dt><a href="config.html#index-67"><strong>$cfg['Import']['charset']</strong></a>
+  </dt>
+
+        
+  <dt><a href="config.html#cfg_InitialSlidersState"><strong>$cfg['InitialSlidersState']</strong></a>
+  </dt>
+
+        
+  <dt><a href="config.html#cfg_InsertRows"><strong>$cfg['InsertRows']</strong></a>
+  </dt>
+
+        
+  <dt><a href="config.html#cfg_Lang"><strong>$cfg['Lang']</strong></a>
+  </dt>
+
+        
+  <dt><a href="config.html#cfg_LimitChars"><strong>$cfg['LimitChars']</strong></a>
+  </dt>
+
+        
+  <dt><a href="config.html#cfg_LinkLengthLimit"><strong>$cfg['LinkLengthLimit']</strong></a>
+  </dt>
+
+        
+  <dt><a href="config.html#cfg_LoginCookieDeleteAll"><strong>$cfg['LoginCookieDeleteAll']</strong></a>
+  </dt>
+
+        
+  <dt><a href="config.html#cfg_LoginCookieRecall"><strong>$cfg['LoginCookieRecall']</strong></a>
+  </dt>
+
+        
+  <dt><a href="config.html#cfg_LoginCookieStore"><strong>$cfg['LoginCookieStore']</strong></a>
+  </dt>
+
+        
+  <dt><a href="config.html#cfg_LoginCookieValidity"><strong>$cfg['LoginCookieValidity']</strong></a>, <a href="config.html#index-60"><strong>[1]</strong></a>
+  </dt>
+
+        
+  <dt><a href="config.html#cfg_LongtextDoubleTextarea"><strong>$cfg['LongtextDoubleTextarea']</strong></a>
+  </dt>
+
+        
+  <dt><a href="config.html#cfg_MainBackground"><strong>$cfg['MainBackground']</strong></a>
+  </dt>
+
+        
+  <dt><a href="config.html#cfg_MaxCharactersInDisplayedSQL"><strong>$cfg['MaxCharactersInDisplayedSQL']</strong></a>
+  </dt>
+
+        
+  <dt><a href="config.html#cfg_MaxDbList"><strong>$cfg['MaxDbList']</strong></a>
+  </dt>
+
+        
+  <dt><a href="faq.html#index-20"><strong>$cfg['MaxExactCount']</strong></a>, <a href="config.html#cfg_MaxExactCount"><strong>[1]</strong></a>
+  </dt>
+
+        
+  <dt><a href="config.html#cfg_MaxExactCountViews"><strong>$cfg['MaxExactCountViews']</strong></a>
+  </dt>
+
+        
+  <dt><a href="config.html#cfg_MaxNavigationItems"><strong>$cfg['MaxNavigationItems']</strong></a>
+  </dt>
+
+        
+  <dt><a href="config.html#index-63"><strong>$cfg['MaxRows']</strong></a>, <a href="config.html#cfg_MaxRows"><strong>[1]</strong></a>
+  </dt>
+
+        
+  <dt><a href="config.html#cfg_MaxSizeForInputField"><strong>$cfg['MaxSizeForInputField']</strong></a>
+  </dt>
+
+        
+  <dt><a href="config.html#cfg_MaxTableList"><strong>$cfg['MaxTableList']</strong></a>
+  </dt>
+
+        
+  <dt><a href="config.html#cfg_McryptDisableWarning"><strong>$cfg['McryptDisableWarning']</strong></a>
+  </dt>
+
+        
+  <dt><a href="config.html#cfg_MemoryLimit"><strong>$cfg['MemoryLimit']</strong></a>
+  </dt>
+
+        
+  <dt><a href="config.html#cfg_MinSizeForInputField"><strong>$cfg['MinSizeForInputField']</strong></a>
+  </dt>
+
+        
+  <dt><a href="config.html#cfg_MySQLManualBase"><strong>$cfg['MySQLManualBase']</strong></a>
+  </dt>
+
+        
+  <dt><a href="config.html#index-65"><strong>$cfg['MySQLManualType']</strong></a>, <a href="config.html#cfg_MySQLManualType"><strong>[1]</strong></a>
+  </dt>
+
+        
+  <dt><a href="config.html#cfg_NaturalOrder"><strong>$cfg['NaturalOrder']</strong></a>
+  </dt>
+
+        
+  <dt><a href="config.html#cfg_NaviBackground"><strong>$cfg['NaviBackground']</strong></a>
+  </dt>
+
+        
+  <dt><a href="config.html#cfg_NaviPointerBackground"><strong>$cfg['NaviPointerBackground']</strong></a>
+  </dt>
+
+        
+  <dt><a href="config.html#cfg_NaviPointerColor"><strong>$cfg['NaviPointerColor']</strong></a>
+  </dt>
+
+        
+  <dt><a href="config.html#cfg_NaviWidth"><strong>$cfg['NaviWidth']</strong></a>
+  </dt>
+
+        
+  <dt><a href="config.html#cfg_NavigationBarIconic"><strong>$cfg['NavigationBarIconic']</strong></a>
+  </dt>
+
+        
+  <dt><a href="config.html#cfg_NavigationDisplayLogo"><strong>$cfg['NavigationDisplayLogo']</strong></a>
+  </dt>
+
+        
+  <dt><a href="config.html#cfg_NavigationDisplayServers"><strong>$cfg['NavigationDisplayServers']</strong></a>
+  </dt>
+
+        
+  <dt><a href="config.html#cfg_NavigationLogoLink"><strong>$cfg['NavigationLogoLink']</strong></a>
+  </dt>
+
+        
+  <dt><a href="config.html#cfg_NavigationLogoLinkWindow"><strong>$cfg['NavigationLogoLinkWindow']</strong></a>
+  </dt>
+
+        
+  <dt><a href="config.html#index-61"><strong>$cfg['NavigationTreeDbSeparator']</strong></a>, <a href="config.html#cfg_NavigationTreeDbSeparator"><strong>[1]</strong></a>
+  </dt>
+
+        
+  <dt><a href="config.html#index-34"><strong>$cfg['NavigationTreeDefaultTabTable']</strong></a>, <a href="config.html#cfg_NavigationTreeDefaultTabTable"><strong>[1]</strong></a>
+  </dt>
+
+        
+  <dt><a href="config.html#cfg_NavigationTreeDisplayDbFilterMinimum"><strong>$cfg['NavigationTreeDisplayDbFilterMinimum']</strong></a>
+  </dt>
+
+        
+  <dt><a href="config.html#cfg_NavigationTreeDisplayItemFilterMinimum"><strong>$cfg['NavigationTreeDisplayItemFilterMinimum']</strong></a>
+  </dt>
+
+        
+  <dt><a href="config.html#cfg_NavigationTreeEnableGrouping"><strong>$cfg['NavigationTreeEnableGrouping']</strong></a>
+  </dt>
+
+        
+  <dt><a href="config.html#cfg_NavigationTreePointerEnable"><strong>$cfg['NavigationTreePointerEnable']</strong></a>
+  </dt>
+
+        
+  <dt><a href="config.html#cfg_NavigationTreeTableLevel"><strong>$cfg['NavigationTreeTableLevel']</strong></a>
+  </dt>
+
+        
+  <dt><a href="faq.html#index-19"><strong>$cfg['NavigationTreeTableSeparator']</strong></a>, <a href="config.html#cfg_NavigationTreeTableSeparator"><strong>[1]</strong></a>
+  </dt>
+
+        
+  <dt><a href="config.html#index-33"><strong>$cfg['NumRecentTables']</strong></a>, <a href="config.html#cfg_NumRecentTables"><strong>[1]</strong></a>
+  </dt>
+
+        
+  <dt><a href="faq.html#index-0"><strong>$cfg['OBGzip']</strong></a>, <a href="faq.html#index-4"><strong>[1]</strong></a>, <a href="faq.html#index-8"><strong>[2]</strong></a>, <a href="config.html#cfg_OBGzip"><strong>[3]</strong></a>
+  </dt>
+
+        
+  <dt><a href="config.html#cfg_Order"><strong>$cfg['Order']</strong></a>
+  </dt>
+
+        
+  <dt><a href="config.html#cfg_PersistentConnections"><strong>$cfg['PersistentConnections']</strong></a>
+  </dt>
+
+        
+  <dt><a href="faq.html#index-9"><strong>$cfg['PmaAbsoluteUri']</strong></a>, <a href="faq.html#index-16"><strong>[1]</strong></a>, <a href="faq.html#index-24"><strong>[2]</strong></a>, <a href="faq.html#index-25"><strong>[3]</strong></a>, <a href="config.html#cfg_PmaAbsoluteUri"><strong>[4]</strong></a>, <a href="config.html#index-1"><strong>[5]</strong></a>
+  </dt>
+
+        
+  <dt><a href="config.html#cfg_PmaNoRelation_DisableWarning"><strong>$cfg['PmaNoRelation_DisableWarning']</strong></a>
+  </dt>
+
+        
+  <dt><a href="config.html#cfg_PropertiesIconic"><strong>$cfg['PropertiesIconic']</strong></a>
+  </dt>
+
+        
+  <dt><a href="config.html#cfg_PropertiesNumColumns"><strong>$cfg['PropertiesNumColumns']</strong></a>
+  </dt>
+
+        
+  <dt><a href="config.html#cfg_ProtectBinary"><strong>$cfg['ProtectBinary']</strong></a>
+  </dt>
+
+        
+  <dt><a href="config.html#cfg_QueryHistoryDB"><strong>$cfg['QueryHistoryDB']</strong></a>, <a href="config.html#index-75"><strong>[1]</strong></a>, <a href="config.html#index-77"><strong>[2]</strong></a>
+  </dt>
+
+        
+  <dt><a href="config.html#index-30"><strong>$cfg['QueryHistoryMax']</strong></a>, <a href="config.html#cfg_QueryHistoryMax"><strong>[1]</strong></a>, <a href="config.html#index-78"><strong>[2]</strong></a>
+  </dt>
+
+        
+  <dt><a href="config.html#cfg_QueryWindowDefTab"><strong>$cfg['QueryWindowDefTab']</strong></a>, <a href="config.html#index-79"><strong>[1]</strong></a>
+  </dt>
+
+        
+  <dt><a href="config.html#cfg_QueryWindowHeight"><strong>$cfg['QueryWindowHeight']</strong></a>, <a href="config.html#index-73"><strong>[1]</strong></a>
+  </dt>
+
+        
+  <dt><a href="config.html#cfg_QueryWindowWidth"><strong>$cfg['QueryWindowWidth']</strong></a>, <a href="config.html#index-72"><strong>[1]</strong></a>
+  </dt>
+
+        
+  <dt><a href="config.html#cfg_RecodingEngine"><strong>$cfg['RecodingEngine']</strong></a>
+  </dt>
+
+        
+  <dt><a href="config.html#index-37"><strong>$cfg['RememberSorting']</strong></a>, <a href="config.html#cfg_RememberSorting"><strong>[1]</strong></a>
+  </dt>
+
+        
+  <dt><a href="config.html#cfg_RepeatCells"><strong>$cfg['RepeatCells']</strong></a>
+  </dt>
+
+        
+  <dt><a href="config.html#cfg_ReservedWordDisableWarning"><strong>$cfg['ReservedWordDisableWarning']</strong></a>
+  </dt>
+
+        
+  <dt><a href="config.html#cfg_RetainQueryBox"><strong>$cfg['RetainQueryBox']</strong></a>
+  </dt>
+
+        
+  <dt><a href="config.html#cfg_RowActionLinks"><strong>$cfg['RowActionLinks']</strong></a>
+  </dt>
+
+        
+  <dt><a href="config.html#cfg_SQLQuery_Edit"><strong>$cfg['SQLQuery']['Edit']</strong></a>
+  </dt>
+
+        
+  <dt><a href="config.html#cfg_SQLQuery_Explain"><strong>$cfg['SQLQuery']['Explain']</strong></a>
+  </dt>
+
+        
+  <dt><a href="config.html#cfg_SQLQuery_Refresh"><strong>$cfg['SQLQuery']['Refresh']</strong></a>
+  </dt>
+
+        
+  <dt><a href="config.html#cfg_SQLQuery_ShowAsPHP"><strong>$cfg['SQLQuery']['ShowAsPHP']</strong></a>
+  </dt>
+
+        
+  <dt><a href="config.html#cfg_SQLQuery_Validate"><strong>$cfg['SQLQuery']['Validate']</strong></a>
+  </dt>
+
+        
+  <dt><a href="config.html#index-71"><strong>$cfg['SQLValidator']</strong></a>, <a href="config.html#cfg_SQLValidator"><strong>[1]</strong></a>
+  </dt>
+
+        
+  <dt><a href="config.html#cfg_SQLValidator_password"><strong>$cfg['SQLValidator']['password']</strong></a>
+  </dt>
+
+        
+  <dt><a href="config.html#cfg_SQLValidator_use"><strong>$cfg['SQLValidator']['use']</strong></a>
+  </dt>
+
+        
+  <dt><a href="config.html#cfg_SQLValidator_username"><strong>$cfg['SQLValidator']['username']</strong></a>
+  </dt>
+
+        
+  <dt><a href="config.html#cfg_SQP_fmtColor"><strong>$cfg['SQP']['fmtColor']</strong></a>
+  </dt>
+
+        
+  <dt><a href="config.html#cfg_SQP_fmtInd"><strong>$cfg['SQP']['fmtInd']</strong></a>, <a href="config.html#index-81"><strong>[1]</strong></a>
+  </dt>
+
+        
+  <dt><a href="config.html#cfg_SQP_fmtIndUnit"><strong>$cfg['SQP']['fmtIndUnit']</strong></a>, <a href="config.html#index-82"><strong>[1]</strong></a>
+  </dt>
+
+        
+  <dt><a href="config.html#cfg_SQP_fmtType"><strong>$cfg['SQP']['fmtType']</strong></a>
+  </dt>
+
+        
+  <dt><a href="config.html#cfg_SaveCellsAtOnce"><strong>$cfg['SaveCellsAtOnce']</strong></a>
+  </dt>
+
+        
+  <dt><a href="config.html#cfg_SaveDir"><strong>$cfg['SaveDir']</strong></a>
+  </dt>
+
+        
+  <dt><a href="config.html#cfg_ServerDefault"><strong>$cfg['ServerDefault']</strong></a>, <a href="config.html#index-57"><strong>[1]</strong></a>, <a href="config.html#index-58"><strong>[2]</strong></a>
+  </dt>
+
+        
+  <dt><a href="config.html#cfg_ServerLibraryDifference_DisableWarning"><strong>$cfg['ServerLibraryDifference_DisableWarning']</strong></a>
+  </dt>
+
+        
+  <dt><a href="setup.html#index-6"><strong>$cfg['Servers']</strong></a>, <a href="config.html#cfg_Servers"><strong>[1]</strong></a>, <a href="config.html#index-3"><strong>[2]</strong></a>, <a href="config.html#index-6"><strong>[3]</strong></a>
+  </dt>
+
+        
+  <dt><a href="setup.html#index-19"><strong>$cfg['Servers'][$i]['AllowDeny']['order']</strong></a>, <a href="config.html#cfg_Servers_AllowDeny_order"><strong>[1]</strong></a>, <a href="config.html#index-68"><strong>[2]</strong></a>
+  </dt>
+
+        
+  <dt><a href="setup.html#index-20"><strong>$cfg['Servers'][$i]['AllowDeny']['rules']</strong></a>, <a href="setup.html#index-23"><strong>[1]</strong></a>, <a href="faq.html#index-23"><strong>[2]</strong></a>, <a href="config.html#index-50"><strong>[3]</strong></a>, <a href="config.html#cfg_Servers_AllowDeny_rules"><strong>[4]</strong></a>, <a href="config.html#index-69"><strong>[5]</strong></a>
+  </dt>
+
+        
+  <dt><a href="config.html#cfg_Servers_AllowNoPassword"><strong>$cfg['Servers'][$i]['AllowNoPassword']</strong></a>
+  </dt>
+
+        
+  <dt><a href="config.html#cfg_Servers_AllowRoot"><strong>$cfg['Servers'][$i]['AllowRoot']</strong></a>
+  </dt>
+
+        
+  <dt><a href="config.html#cfg_Servers_DisableIS"><strong>$cfg['Servers'][$i]['DisableIS']</strong></a>, <a href="config.html#index-55"><strong>[1]</strong></a>
+  </dt>
+
+        
+  <dt><a href="config.html#cfg_Servers_LogoutURL"><strong>$cfg['Servers'][$i]['LogoutURL']</strong></a>
+  </dt>
+
+        
+  <dt><a href="config.html#cfg_Servers_MaxTableUiprefs"><strong>$cfg['Servers'][$i]['MaxTableUiprefs']</strong></a>
+  </dt>
+
+        
+  <dt><a href="config.html#cfg_Servers_ShowDatabasesCommand"><strong>$cfg['Servers'][$i]['ShowDatabasesCommand']</strong></a>
+  </dt>
+
+        
+  <dt><a href="setup.html#index-13"><strong>$cfg['Servers'][$i]['SignonScript']</strong></a>, <a href="config.html#index-11"><strong>[1]</strong></a>, <a href="config.html#cfg_Servers_SignonScript"><strong>[2]</strong></a>, <a href="config.html#index-53"><strong>[3]</strong></a>
+  </dt>
+
+        
+  <dt><a href="setup.html#index-12"><strong>$cfg['Servers'][$i]['SignonSession']</strong></a>, <a href="config.html#index-10"><strong>[1]</strong></a>, <a href="config.html#cfg_Servers_SignonSession"><strong>[2]</strong></a>
+  </dt>
+
+        
+  <dt><a href="setup.html#index-14"><strong>$cfg['Servers'][$i]['SignonURL']</strong></a>, <a href="config.html#index-12"><strong>[1]</strong></a>, <a href="config.html#cfg_Servers_SignonURL"><strong>[2]</strong></a>
+  </dt>
+
+        
+  <dt><a href="config.html#cfg_Servers_StatusCacheDatabases"><strong>$cfg['Servers'][$i]['StatusCacheDatabases']</strong></a>, <a href="config.html#index-56"><strong>[1]</strong></a>
+  </dt>
+
+        
+  <dt><a href="config.html#index-54"><strong>$cfg['Servers'][$i]['StatusCacheLifetime']</strong></a>, <a href="config.html#cfg_Servers_StatusCacheLifetime"><strong>[1]</strong></a>
+  </dt>
+
+        
+  <dt><a href="config.html#cfg_Servers_auth_http_realm"><strong>$cfg['Servers'][$i]['auth_http_realm']</strong></a>
+  </dt>
+
+        
+  <dt><a href="setup.html#index-22"><strong>$cfg['Servers'][$i]['auth_swekey_config']</strong></a>, <a href="config.html#cfg_Servers_auth_swekey_config"><strong>[1]</strong></a>
+  </dt>
+
+        
+  <dt><a href="setup.html#index-11"><strong>$cfg['Servers'][$i]['auth_type']</strong></a>, <a href="config.html#cfg_Servers_auth_type"><strong>[1]</strong></a>, <a href="config.html#index-15"><strong>[2]</strong></a>
+  </dt>
+
+        
+  <dt><a href="config.html#cfg_Servers_bookmarktable"><strong>$cfg['Servers'][$i]['bookmarktable']</strong></a>, <a href="config.html#index-18"><strong>[1]</strong></a>
+  </dt>
+
+        
+  <dt><a href="config.html#index-28"><strong>$cfg['Servers'][$i]['column_comments']</strong></a>
+  </dt>
+
+        
+  <dt><a href="config.html#cfg_Servers_column_info"><strong>$cfg['Servers'][$i]['column_info']</strong></a>, <a href="config.html#index-27"><strong>[1]</strong></a>, <a href="config.html#index-29"><strong>[2]</strong></a>
+  </dt>
+
+        
+  <dt><a href="config.html#cfg_Servers_compress"><strong>$cfg['Servers'][$i]['compress']</strong></a>
+  </dt>
+
+        
+  <dt><a href="config.html#cfg_Servers_connect_type"><strong>$cfg['Servers'][$i]['connect_type']</strong></a>
+  </dt>
+
+        
+  <dt><a href="config.html#cfg_Servers_controlhost"><strong>$cfg['Servers'][$i]['controlhost']</strong></a>
+  </dt>
+
+        
+  <dt><a href="setup.html#index-5"><strong>$cfg['Servers'][$i]['controlpass']</strong></a>, <a href="faq.html#index-22"><strong>[1]</strong></a>, <a href="config.html#cfg_Servers_controlpass"><strong>[2]</strong></a>
+  </dt>
+
+        
+  <dt><a href="setup.html#index-3"><strong>$cfg['Servers'][$i]['controluser']</strong></a>, <a href="setup.html#index-4"><strong>[1]</strong></a>, <a href="faq.html#index-21"><strong>[2]</strong></a>, <a href="config.html#cfg_Servers_controluser"><strong>[3]</strong></a>
+  </dt>
+
+        
+  <dt><a href="config.html#cfg_Servers_designer_coords"><strong>$cfg['Servers'][$i]['designer_coords']</strong></a>, <a href="config.html#index-46"><strong>[1]</strong></a>
+  </dt>
+
+        
+  <dt><a href="faq.html#index-3"><strong>$cfg['Servers'][$i]['extension']</strong></a>, <a href="config.html#cfg_Servers_extension"><strong>[1]</strong></a>
+  </dt>
+
+        
+  <dt><a href="config.html#cfg_Servers_hide_db"><strong>$cfg['Servers'][$i]['hide_db']</strong></a>
+  </dt>
+
+        
+  <dt><a href="config.html#cfg_Servers_history"><strong>$cfg['Servers'][$i]['history']</strong></a>, <a href="config.html#index-32"><strong>[1]</strong></a>, <a href="config.html#index-76"><strong>[2]</strong></a>
+  </dt>
+
+        
+  <dt><a href="config.html#index-4"><strong>$cfg['Servers'][$i]['host']</strong></a>, <a href="config.html#index-5"><strong>[1]</strong></a>, <a href="config.html#cfg_Servers_host"><strong>[2]</strong></a>, <a href="config.html#index-7"><strong>[3]</strong></a>, <a href="config.html#index-14"><strong>[4]</strong></a>
+  </dt>
+
+        
+  <dt><a href="config.html#cfg_Servers_nopassword"><strong>$cfg['Servers'][$i]['nopassword']</strong></a>
+  </dt>
+
+        
+  <dt><a href="setup.html#index-18"><strong>$cfg['Servers'][$i]['only_db']</strong></a>, <a href="config.html#cfg_Servers_only_db"><strong>[1]</strong></a>, <a href="config.html#index-52"><strong>[2]</strong></a>
+  </dt>
+
+        
+  <dt><a href="setup.html#index-17"><strong>$cfg['Servers'][$i]['password']</strong></a>, <a href="config.html#cfg_Servers_password"><strong>[1]</strong></a>
+  </dt>
+
+        
+  <dt><a href="config.html#cfg_Servers_pdf_pages"><strong>$cfg['Servers'][$i]['pdf_pages']</strong></a>, <a href="config.html#index-25"><strong>[1]</strong></a>
+  </dt>
+
+        
+  <dt><a href="config.html#index-2"><strong>$cfg['Servers'][$i]['pmadb']</strong></a>, <a href="config.html#index-8"><strong>[1]</strong></a>, <a href="config.html#cfg_Servers_pmadb"><strong>[2]</strong></a>, <a href="config.html#index-16"><strong>[3]</strong></a>, <a href="config.html#index-17"><strong>[4]</strong></a>, <a href="config.html#index-19"><strong>[5]</strong></a>, <a href="config.html#index-21"><strong>[6]</strong></a>, <a href="config.html#index-23"><strong> [...]
+  </dt>
+
+        
+  <dt><a href="config.html#cfg_Servers_port"><strong>$cfg['Servers'][$i]['port']</strong></a>
+  </dt>
+
+        
+  <dt><a href="config.html#cfg_Servers_recent"><strong>$cfg['Servers'][$i]['recent']</strong></a>, <a href="config.html#index-36"><strong>[1]</strong></a>
+  </dt>
+
+        
+  <dt><a href="config.html#cfg_Servers_relation"><strong>$cfg['Servers'][$i]['relation']</strong></a>, <a href="config.html#index-20"><strong>[1]</strong></a>
+  </dt>
+
+        
+  <dt><a href="faq.html#index-7"><strong>$cfg['Servers'][$i]['socket']</strong></a>, <a href="config.html#cfg_Servers_socket"><strong>[1]</strong></a>
+  </dt>
+
+        
+  <dt><a href="config.html#cfg_Servers_ssl"><strong>$cfg['Servers'][$i]['ssl']</strong></a>
+  </dt>
+
+        
+  <dt><a href="config.html#cfg_Servers_table_coords"><strong>$cfg['Servers'][$i]['table_coords']</strong></a>, <a href="config.html#index-24"><strong>[1]</strong></a>
+  </dt>
+
+        
+  <dt><a href="config.html#cfg_Servers_table_info"><strong>$cfg['Servers'][$i]['table_info']</strong></a>, <a href="config.html#index-22"><strong>[1]</strong></a>
+  </dt>
+
+        
+  <dt><a href="config.html#cfg_Servers_table_uiprefs"><strong>$cfg['Servers'][$i]['table_uiprefs']</strong></a>, <a href="config.html#index-39"><strong>[1]</strong></a>, <a href="config.html#index-47"><strong>[2]</strong></a>, <a href="config.html#index-48"><strong>[3]</strong></a>, <a href="config.html#index-49"><strong>[4]</strong></a>
+  </dt>
+
+        
+  <dt><a href="config.html#cfg_Servers_tracking"><strong>$cfg['Servers'][$i]['tracking']</strong></a>, <a href="config.html#index-41"><strong>[1]</strong></a>
+  </dt>
+
+        
+  <dt><a href="config.html#cfg_Servers_tracking_add_drop_database"><strong>$cfg['Servers'][$i]['tracking_add_drop_database']</strong></a>
+  </dt>
+
+        
+  <dt><a href="config.html#cfg_Servers_tracking_add_drop_table"><strong>$cfg['Servers'][$i]['tracking_add_drop_table']</strong></a>
+  </dt>
+
+        
+  <dt><a href="config.html#cfg_Servers_tracking_add_drop_view"><strong>$cfg['Servers'][$i]['tracking_add_drop_view']</strong></a>
+  </dt>
+
+        
+  <dt><a href="config.html#cfg_Servers_tracking_default_statements"><strong>$cfg['Servers'][$i]['tracking_default_statements']</strong></a>
+  </dt>
+
+        
+  <dt><a href="config.html#cfg_Servers_tracking_version_auto_create"><strong>$cfg['Servers'][$i]['tracking_version_auto_create']</strong></a>
+  </dt>
+
+        
+  <dt><a href="setup.html#index-16"><strong>$cfg['Servers'][$i]['user']</strong></a>, <a href="config.html#cfg_Servers_user"><strong>[1]</strong></a>
+  </dt>
+
+        
+  <dt><a href="config.html#cfg_Servers_userconfig"><strong>$cfg['Servers'][$i]['userconfig']</strong></a>, <a href="config.html#index-44"><strong>[1]</strong></a>
+  </dt>
+
+        
+  <dt><a href="faq.html#index-28"><strong>$cfg['Servers'][$i]['verbose']</strong></a>, <a href="config.html#index-13"><strong>[1]</strong></a>, <a href="config.html#cfg_Servers_verbose"><strong>[2]</strong></a>, <a href="config.html#index-62"><strong>[3]</strong></a>
+  </dt>
+
+        
+  <dt><a href="config.html#cfg_SessionSavePath"><strong>$cfg['SessionSavePath']</strong></a>
+  </dt>
+
+        
+  <dt><a href="config.html#cfg_ShowAll"><strong>$cfg['ShowAll']</strong></a>
+  </dt>
+
+        
+  <dt><a href="config.html#cfg_ShowBrowseComments"><strong>$cfg['ShowBrowseComments']</strong></a>
+  </dt>
+
+        
+  <dt><a href="config.html#cfg_ShowChgPassword"><strong>$cfg['ShowChgPassword']</strong></a>
+  </dt>
+
+        
+  <dt><a href="config.html#cfg_ShowCreateDb"><strong>$cfg['ShowCreateDb']</strong></a>
+  </dt>
+
+        
+  <dt><a href="config.html#cfg_ShowDbStructureCreation"><strong>$cfg['ShowDbStructureCreation']</strong></a>
+  </dt>
+
+        
+  <dt><a href="config.html#cfg_ShowDbStructureLastCheck"><strong>$cfg['ShowDbStructureLastCheck']</strong></a>
+  </dt>
+
+        
+  <dt><a href="config.html#cfg_ShowDbStructureLastUpdate"><strong>$cfg['ShowDbStructureLastUpdate']</strong></a>
+  </dt>
+
+        
+  <dt><a href="config.html#cfg_ShowDisplayDirection"><strong>$cfg['ShowDisplayDirection']</strong></a>
+  </dt>
+
+        
+  <dt><a href="config.html#cfg_ShowFieldTypesInDataEditView"><strong>$cfg['ShowFieldTypesInDataEditView']</strong></a>
+  </dt>
+
+        
+  <dt><a href="config.html#cfg_ShowFunctionFields"><strong>$cfg['ShowFunctionFields']</strong></a>
+  </dt>
+
+        
+  <dt><a href="config.html#cfg_ShowHint"><strong>$cfg['ShowHint']</strong></a>
+  </dt>
+
+        
+  <dt><a href="config.html#cfg_ShowPhpInfo"><strong>$cfg['ShowPhpInfo']</strong></a>
+  </dt>
+
+        
+  <dt><a href="config.html#cfg_ShowPropertyComments"><strong>$cfg['ShowPropertyComments']</strong></a>
+  </dt>
+
+        
+  <dt><a href="config.html#cfg_ShowSQL"><strong>$cfg['ShowSQL']</strong></a>
+  </dt>
+
+        
+  <dt><a href="config.html#cfg_ShowServerInfo"><strong>$cfg['ShowServerInfo']</strong></a>
+  </dt>
+
+        
+  <dt><a href="config.html#cfg_ShowStats"><strong>$cfg['ShowStats']</strong></a>
+  </dt>
+
+        
+  <dt><a href="config.html#cfg_ShowTooltip"><strong>$cfg['ShowTooltip']</strong></a>
+  </dt>
+
+        
+  <dt><a href="config.html#cfg_SkipLockedTables"><strong>$cfg['SkipLockedTables']</strong></a>
+  </dt>
+
+        
+  <dt><a href="faq.html#index-6"><strong>$cfg['SuhosinDisableWarning']</strong></a>, <a href="config.html#cfg_SuhosinDisableWarning"><strong>[1]</strong></a>
+  </dt>
+
+        
+  <dt><a href="faq.html#index-1"><strong>$cfg['TempDir']</strong></a>, <a href="faq.html#index-30"><strong>[1]</strong></a>, <a href="config.html#cfg_TempDir"><strong>[2]</strong></a>
+  </dt>
+
+        
+  <dt><a href="config.html#cfg_TextareaAutoSelect"><strong>$cfg['TextareaAutoSelect']</strong></a>
+  </dt>
+
+        
+  <dt><a href="config.html#cfg_TextareaCols"><strong>$cfg['TextareaCols']</strong></a>
+  </dt>
+
+        
+  <dt><a href="config.html#cfg_TextareaRows"><strong>$cfg['TextareaRows']</strong></a>
+  </dt>
+
+        
+  <dt><a href="config.html#cfg_ThBackground"><strong>$cfg['ThBackground']</strong></a>
+  </dt>
+
+        
+  <dt><a href="config.html#cfg_ThColor"><strong>$cfg['ThColor']</strong></a>
+  </dt>
+
+        
+  <dt><a href="faq.html#index-12"><strong>$cfg['ThemeDefault']</strong></a>, <a href="config.html#cfg_ThemeDefault"><strong>[1]</strong></a>
+  </dt>
+
+        
+  <dt><a href="faq.html#index-11"><strong>$cfg['ThemeManager']</strong></a>, <a href="faq.html#index-14"><strong>[1]</strong></a>, <a href="config.html#cfg_ThemeManager"><strong>[2]</strong></a>
+  </dt>
+
+        
+  <dt><a href="faq.html#index-10"><strong>$cfg['ThemePath']</strong></a>, <a href="faq.html#index-13"><strong>[1]</strong></a>, <a href="faq.html#index-15"><strong>[2]</strong></a>, <a href="config.html#cfg_ThemePath"><strong>[3]</strong></a>, <a href="config.html#index-80"><strong>[4]</strong></a>
+  </dt>
+
+        
+  <dt><a href="config.html#cfg_ThemePerServer"><strong>$cfg['ThemePerServer']</strong></a>
+  </dt>
+
+        
+  <dt><a href="config.html#cfg_TitleDatabase"><strong>$cfg['TitleDatabase']</strong></a>
+  </dt>
+
+        
+  <dt><a href="config.html#cfg_TitleDefault"><strong>$cfg['TitleDefault']</strong></a>
+  </dt>
+
+        
+  <dt><a href="config.html#cfg_TitleServer"><strong>$cfg['TitleServer']</strong></a>
+  </dt>
+
+        
+  <dt><a href="config.html#cfg_TitleTable"><strong>$cfg['TitleTable']</strong></a>
+  </dt>
+
+        
+  <dt><a href="config.html#cfg_TranslationWarningThreshold"><strong>$cfg['TranslationWarningThreshold']</strong></a>
+  </dt>
+
+        
+  <dt><a href="config.html#index-51"><strong>$cfg['TrustedProxies']</strong></a>, <a href="config.html#cfg_TrustedProxies"><strong>[1]</strong></a>
+  </dt>
+
+        
+  <dt><a href="faq.html#index-2"><strong>$cfg['UploadDir']</strong></a>, <a href="faq.html#index-29"><strong>[1]</strong></a>, <a href="config.html#cfg_UploadDir"><strong>[2]</strong></a>
+  </dt>
+
+        
+  <dt><a href="config.html#cfg_UseDbSearch"><strong>$cfg['UseDbSearch']</strong></a>
+  </dt>
+
+        
+  <dt><a href="config.html#cfg_UserprefsDeveloperTab"><strong>$cfg['UserprefsDeveloperTab']</strong></a>
+  </dt>
+
+        
+  <dt><a href="config.html#cfg_UserprefsDisallow"><strong>$cfg['UserprefsDisallow']</strong></a>
+  </dt>
+
+        
+  <dt><a href="config.html#cfg_VersionCheck"><strong>$cfg['VersionCheck']</strong></a>
+  </dt>
+
+        
+  <dt><a href="config.html#cfg_ZipDump"><strong>$cfg['ZipDump']</strong></a>
+  </dt>
+
+        
+  <dt><a href="config.html#cfg_blowfish_secret"><strong>$cfg['blowfish_secret']</strong></a>, <a href="config.html#index-59"><strong>[1]</strong></a>
+  </dt>
+
+      </dl></dd>
+      
+  <dt><a href="setup.html#index-1">Configuration storage</a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_Confirm"><strong>Confirm</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_Servers_connect_type"><strong>connect_type</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_Servers_controlhost"><strong>controlhost</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_Servers_controlpass"><strong>controlpass</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_Servers_controluser"><strong>controluser</strong></a>
+  </dt>
+
+      
+  <dt><a href="glossary.html#term-cookie"><strong>Cookie</strong></a>
+  </dt>
+
+      <dd><dl>
+        
+  <dt><a href="setup.html#index-8">Authentication mode</a>
+  </dt>
+
+      </dl></dd>
+      
+  <dt><a href="config.html#cfg_CSPAllow"><strong>CSPAllow</strong></a>
+  </dt>
+
+      
+  <dt><a href="glossary.html#term-csv"><strong>CSV</strong></a>
+  </dt>
+
+  </dl></td>
+</tr></table>
+
+<h2 id="D">D</h2>
+<table style="width: 100%" class="indextable genindextable"><tr>
+  <td style="width: 33%" valign="top"><dl>
+      
+  <dt><a href="glossary.html#term-database"><strong>database</strong></a>
+  </dt>
+
+      
+  <dt><a href="glossary.html#term-db"><strong>DB</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_DBG"><strong>DBG</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_DBG_sql"><strong>DBG, sql</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_DefaultConnectionCollation"><strong>DefaultConnectionCollation</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_DefaultDisplay"><strong>DefaultDisplay</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_DefaultFunctions"><strong>DefaultFunctions</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_DefaultLang"><strong>DefaultLang</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_DefaultQueryDatabase"><strong>DefaultQueryDatabase</strong></a>
+  </dt>
+
+  </dl></td>
+  <td style="width: 33%" valign="top"><dl>
+      
+  <dt><a href="config.html#cfg_DefaultQueryTable"><strong>DefaultQueryTable</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_DefaultTabDatabase"><strong>DefaultTabDatabase</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_DefaultTabServer"><strong>DefaultTabServer</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_DefaultTabTable"><strong>DefaultTabTable</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_Servers_designer_coords"><strong>designer_coords</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_Servers_DisableIS"><strong>DisableIS</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_DisableMultiTableMaintenance"><strong>DisableMultiTableMaintenance</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_DisplayBinaryAsHex"><strong>DisplayBinaryAsHex</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_DisplayServersList"><strong>DisplayServersList</strong></a>
+  </dt>
+
+  </dl></td>
+</tr></table>
+
+<h2 id="E">E</h2>
+<table style="width: 100%" class="indextable genindextable"><tr>
+  <td style="width: 33%" valign="top"><dl>
+      
+  <dt><a href="config.html#cfg_EditInWindow"><strong>EditInWindow</strong></a>
+  </dt>
+
+      
+  <dt><a href="glossary.html#term-engine"><strong>Engine</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_Error_Handler_display"><strong>Error_Handler, display</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_Error_Handler_gather"><strong>Error_Handler, gather</strong></a>
+  </dt>
+
+  </dl></td>
+  <td style="width: 33%" valign="top"><dl>
+      
+  <dt><a href="config.html#cfg_ExecTimeLimit"><strong>ExecTimeLimit</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_Export"><strong>Export</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_Export_method"><strong>Export, method</strong></a>
+  </dt>
+
+      
+  <dt><a href="glossary.html#term-extension"><strong>extension</strong></a>, <a href="config.html#cfg_Servers_extension"><strong>[1]</strong></a>
+  </dt>
+
+  </dl></td>
+</tr></table>
+
+<h2 id="F">F</h2>
+<table style="width: 100%" class="indextable genindextable"><tr>
+  <td style="width: 33%" valign="top"><dl>
+      
+  <dt><a href="glossary.html#term-faq"><strong>FAQ</strong></a>
+  </dt>
+
+      
+  <dt><a href="glossary.html#term-field"><strong>Field</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_FilterLanguages"><strong>FilterLanguages</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_FontFamily"><strong>FontFamily</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_FontFamilyFixed"><strong>FontFamilyFixed</strong></a>
+  </dt>
+
+  </dl></td>
+  <td style="width: 33%" valign="top"><dl>
+      
+  <dt><a href="config.html#cfg_ForceSSL"><strong>ForceSSL</strong></a>
+  </dt>
+
+      
+  <dt><a href="glossary.html#term-foreign-key"><strong>foreign key</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_ForeignKeyDropdownOrder"><strong>ForeignKeyDropdownOrder</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_ForeignKeyMaxLimit"><strong>ForeignKeyMaxLimit</strong></a>
+  </dt>
+
+      
+  <dt><a href="glossary.html#term-fpdf"><strong>FPDF</strong></a>
+  </dt>
+
+  </dl></td>
+</tr></table>
+
+<h2 id="G">G</h2>
+<table style="width: 100%" class="indextable genindextable"><tr>
+  <td style="width: 33%" valign="top"><dl>
+      
+  <dt><a href="glossary.html#term-gd"><strong>GD</strong></a>
+  </dt>
+
+      
+  <dt><a href="glossary.html#term-gd2"><strong>GD2</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_GD2Available"><strong>GD2Available</strong></a>
+  </dt>
+
+  </dl></td>
+  <td style="width: 33%" valign="top"><dl>
+      
+  <dt><a href="config.html#cfg_GridEditing"><strong>GridEditing</strong></a>
+  </dt>
+
+      
+  <dt><a href="glossary.html#term-gzip"><strong>gzip</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_GZipDump"><strong>GZipDump</strong></a>
+  </dt>
+
+  </dl></td>
+</tr></table>
+
+<h2 id="H">H</h2>
+<table style="width: 100%" class="indextable genindextable"><tr>
+  <td style="width: 33%" valign="top"><dl>
+      
+  <dt><a href="config.html#cfg_HeaderFlipType"><strong>HeaderFlipType</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_Servers_hide_db"><strong>hide_db</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_HideStructureActions"><strong>HideStructureActions</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_Servers_history"><strong>history</strong></a>
+  </dt>
+
+  </dl></td>
+  <td style="width: 33%" valign="top"><dl>
+      
+  <dt><a href="glossary.html#term-host"><strong>host</strong></a>, <a href="config.html#cfg_Servers_host"><strong>[1]</strong></a>
+  </dt>
+
+      
+  <dt><a href="glossary.html#term-hostname"><strong>hostname</strong></a>
+  </dt>
+
+      
+  <dt><a href="glossary.html#term-http"><strong>HTTP</strong></a>
+  </dt>
+
+      <dd><dl>
+        
+  <dt><a href="setup.html#index-7">Authentication mode</a>
+  </dt>
+
+      </dl></dd>
+      
+  <dt><a href="glossary.html#term-https"><strong>https</strong></a>
+  </dt>
+
+  </dl></td>
+</tr></table>
+
+<h2 id="I">I</h2>
+<table style="width: 100%" class="indextable genindextable"><tr>
+  <td style="width: 33%" valign="top"><dl>
+      
+  <dt><a href="config.html#cfg_IconvExtraParams"><strong>IconvExtraParams</strong></a>
+  </dt>
+
+      
+  <dt><a href="glossary.html#term-iec"><strong>IEC</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_IgnoreMultiSubmitErrors"><strong>IgnoreMultiSubmitErrors</strong></a>
+  </dt>
+
+      
+  <dt><a href="glossary.html#term-iis"><strong>IIS</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_Import"><strong>Import</strong></a>
+  </dt>
+
+      
+  <dt><a href="glossary.html#term-index"><strong>Index</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_InitialSlidersState"><strong>InitialSlidersState</strong></a>
+  </dt>
+
+  </dl></td>
+  <td style="width: 33%" valign="top"><dl>
+      
+  <dt><a href="config.html#cfg_InsertRows"><strong>InsertRows</strong></a>
+  </dt>
+
+      
+  <dt><a href="glossary.html#term-ip"><strong>IP</strong></a>
+  </dt>
+
+      
+  <dt><a href="glossary.html#term-ip-address"><strong>IP Address</strong></a>
+  </dt>
+
+      
+  <dt><a href="glossary.html#term-ipv6"><strong>IPv6</strong></a>
+  </dt>
+
+      
+  <dt><a href="glossary.html#term-isapi"><strong>ISAPI</strong></a>
+  </dt>
+
+      
+  <dt><a href="glossary.html#term-iso"><strong>ISO</strong></a>
+  </dt>
+
+      
+  <dt><a href="glossary.html#term-isp"><strong>ISP</strong></a>
+  </dt>
+
+  </dl></td>
+</tr></table>
+
+<h2 id="J">J</h2>
+<table style="width: 100%" class="indextable genindextable"><tr>
+  <td style="width: 33%" valign="top"><dl>
+      
+  <dt><a href="glossary.html#term-jpeg"><strong>JPEG</strong></a>
+  </dt>
+
+  </dl></td>
+  <td style="width: 33%" valign="top"><dl>
+      
+  <dt><a href="glossary.html#term-jpg"><strong>JPG</strong></a>
+  </dt>
+
+  </dl></td>
+</tr></table>
+
+<h2 id="K">K</h2>
+<table style="width: 100%" class="indextable genindextable"><tr>
+  <td style="width: 33%" valign="top"><dl>
+      
+  <dt><a href="glossary.html#term-key"><strong>Key</strong></a>
+  </dt>
+
+  </dl></td>
+</tr></table>
+
+<h2 id="L">L</h2>
+<table style="width: 100%" class="indextable genindextable"><tr>
+  <td style="width: 33%" valign="top"><dl>
+      
+  <dt><a href="config.html#cfg_Lang"><strong>Lang</strong></a>
+  </dt>
+
+      
+  <dt><a href="glossary.html#term-latex"><strong>LATEX</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_LimitChars"><strong>LimitChars</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_LinkLengthLimit"><strong>LinkLengthLimit</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_LoginCookieDeleteAll"><strong>LoginCookieDeleteAll</strong></a>
+  </dt>
+
+  </dl></td>
+  <td style="width: 33%" valign="top"><dl>
+      
+  <dt><a href="config.html#cfg_LoginCookieRecall"><strong>LoginCookieRecall</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_LoginCookieStore"><strong>LoginCookieStore</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_LoginCookieValidity"><strong>LoginCookieValidity</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_Servers_LogoutURL"><strong>LogoutURL</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_LongtextDoubleTextarea"><strong>LongtextDoubleTextarea</strong></a>
+  </dt>
+
+  </dl></td>
+</tr></table>
+
+<h2 id="M">M</h2>
+<table style="width: 100%" class="indextable genindextable"><tr>
+  <td style="width: 33%" valign="top"><dl>
+      
+  <dt><a href="glossary.html#term-mac"><strong>Mac</strong></a>
+  </dt>
+
+      
+  <dt><a href="glossary.html#term-mac-os-x"><strong>Mac OS X</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_MainBackground"><strong>MainBackground</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_MaxCharactersInDisplayedSQL"><strong>MaxCharactersInDisplayedSQL</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_MaxDbList"><strong>MaxDbList</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_MaxExactCount"><strong>MaxExactCount</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_MaxExactCountViews"><strong>MaxExactCountViews</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_MaxNavigationItems"><strong>MaxNavigationItems</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_MaxRows"><strong>MaxRows</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_MaxSizeForInputField"><strong>MaxSizeForInputField</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_MaxTableList"><strong>MaxTableList</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_Servers_MaxTableUiprefs"><strong>MaxTableUiprefs</strong></a>
+  </dt>
+
+  </dl></td>
+  <td style="width: 33%" valign="top"><dl>
+      
+  <dt><a href="glossary.html#term-mcrypt"><strong>MCrypt</strong></a>
+  </dt>
+
+      
+  <dt><a href="glossary.html#term-42"><strong>mcrypt</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_McryptDisableWarning"><strong>McryptDisableWarning</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_MemoryLimit"><strong>MemoryLimit</strong></a>
+  </dt>
+
+      
+  <dt><a href="glossary.html#term-mime"><strong>MIME</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_MinSizeForInputField"><strong>MinSizeForInputField</strong></a>
+  </dt>
+
+      
+  <dt><a href="glossary.html#term-module"><strong>module</strong></a>
+  </dt>
+
+      
+  <dt><a href="glossary.html#term-mysql"><strong>MySQL</strong></a>
+  </dt>
+
+      
+  <dt><a href="glossary.html#term-47"><strong>mysql</strong></a>
+  </dt>
+
+      
+  <dt><a href="glossary.html#term-mysqli"><strong>mysqli</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_MySQLManualBase"><strong>MySQLManualBase</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_MySQLManualType"><strong>MySQLManualType</strong></a>
+  </dt>
+
+  </dl></td>
+</tr></table>
+
+<h2 id="N">N</h2>
+<table style="width: 100%" class="indextable genindextable"><tr>
+  <td style="width: 33%" valign="top"><dl>
+      
+  <dt><a href="config.html#cfg_NaturalOrder"><strong>NaturalOrder</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_NaviBackground"><strong>NaviBackground</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_NavigationBarIconic"><strong>NavigationBarIconic</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_NavigationDisplayLogo"><strong>NavigationDisplayLogo</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_NavigationDisplayServers"><strong>NavigationDisplayServers</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_NavigationLogoLink"><strong>NavigationLogoLink</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_NavigationLogoLinkWindow"><strong>NavigationLogoLinkWindow</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_NavigationTreeDbSeparator"><strong>NavigationTreeDbSeparator</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_NavigationTreeDefaultTabTable"><strong>NavigationTreeDefaultTabTable</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_NavigationTreeDisplayDbFilterMinimum"><strong>NavigationTreeDisplayDbFilterMinimum</strong></a>
+  </dt>
+
+  </dl></td>
+  <td style="width: 33%" valign="top"><dl>
+      
+  <dt><a href="config.html#cfg_NavigationTreeDisplayItemFilterMinimum"><strong>NavigationTreeDisplayItemFilterMinimum</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_NavigationTreeEnableGrouping"><strong>NavigationTreeEnableGrouping</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_NavigationTreePointerEnable"><strong>NavigationTreePointerEnable</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_NavigationTreeTableLevel"><strong>NavigationTreeTableLevel</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_NavigationTreeTableSeparator"><strong>NavigationTreeTableSeparator</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_NaviPointerBackground"><strong>NaviPointerBackground</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_NaviPointerColor"><strong>NaviPointerColor</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_NaviWidth"><strong>NaviWidth</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_Servers_nopassword"><strong>nopassword</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_NumRecentTables"><strong>NumRecentTables</strong></a>
+  </dt>
+
+  </dl></td>
+</tr></table>
+
+<h2 id="O">O</h2>
+<table style="width: 100%" class="indextable genindextable"><tr>
+  <td style="width: 33%" valign="top"><dl>
+      
+  <dt><a href="config.html#cfg_OBGzip"><strong>OBGzip</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_Servers_only_db"><strong>only_db</strong></a>
+  </dt>
+
+      
+  <dt><a href="glossary.html#term-opendocument"><strong>OpenDocument</strong></a>
+  </dt>
+
+  </dl></td>
+  <td style="width: 33%" valign="top"><dl>
+      
+  <dt><a href="config.html#cfg_Order"><strong>Order</strong></a>
+  </dt>
+
+      
+  <dt><a href="glossary.html#term-os-x"><strong>OS X</strong></a>
+  </dt>
+
+  </dl></td>
+</tr></table>
+
+<h2 id="P">P</h2>
+<table style="width: 100%" class="indextable genindextable"><tr>
+  <td style="width: 33%" valign="top"><dl>
+      
+  <dt><a href="config.html#cfg_Servers_password"><strong>password</strong></a>
+  </dt>
+
+      
+  <dt><a href="glossary.html#term-pcre"><strong>PCRE</strong></a>
+  </dt>
+
+      
+  <dt><a href="glossary.html#term-pdf"><strong>PDF</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_Servers_pdf_pages"><strong>pdf_pages</strong></a>
+  </dt>
+
+      
+  <dt><a href="glossary.html#term-pear"><strong>PEAR</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_PersistentConnections"><strong>PersistentConnections</strong></a>
+  </dt>
+
+      
+  <dt><a href="glossary.html#term-php"><strong>PHP</strong></a>
+  </dt>
+
+      
+  <dt><a href="setup.html#index-1">phpMyAdmin configuration storage</a>
+  </dt>
+
+  </dl></td>
+  <td style="width: 33%" valign="top"><dl>
+      
+  <dt><a href="config.html#cfg_PmaAbsoluteUri"><strong>PmaAbsoluteUri</strong></a>
+  </dt>
+
+      
+  <dt><a href="setup.html#index-1">pmadb</a>, <a href="config.html#cfg_Servers_pmadb"><strong>[1]</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_PmaNoRelation_DisableWarning"><strong>PmaNoRelation_DisableWarning</strong></a>
+  </dt>
+
+      
+  <dt><a href="glossary.html#term-port"><strong>port</strong></a>, <a href="config.html#cfg_Servers_port"><strong>[1]</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_PropertiesIconic"><strong>PropertiesIconic</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_PropertiesNumColumns"><strong>PropertiesNumColumns</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_ProtectBinary"><strong>ProtectBinary</strong></a>
+  </dt>
+
+  </dl></td>
+</tr></table>
+
+<h2 id="Q">Q</h2>
+<table style="width: 100%" class="indextable genindextable"><tr>
+  <td style="width: 33%" valign="top"><dl>
+      
+  <dt><a href="config.html#cfg_QueryHistoryDB"><strong>QueryHistoryDB</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_QueryHistoryMax"><strong>QueryHistoryMax</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_QueryWindowDefTab"><strong>QueryWindowDefTab</strong></a>
+  </dt>
+
+  </dl></td>
+  <td style="width: 33%" valign="top"><dl>
+      
+  <dt><a href="config.html#cfg_QueryWindowHeight"><strong>QueryWindowHeight</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_QueryWindowWidth"><strong>QueryWindowWidth</strong></a>
+  </dt>
+
+  </dl></td>
+</tr></table>
+
+<h2 id="R">R</h2>
+<table style="width: 100%" class="indextable genindextable"><tr>
+  <td style="width: 33%" valign="top"><dl>
+      
+  <dt><a href="config.html#cfg_Servers_recent"><strong>recent</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_RecodingEngine"><strong>RecodingEngine</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_Servers_relation"><strong>relation</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_RememberSorting"><strong>RememberSorting</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_RepeatCells"><strong>RepeatCells</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_ReservedWordDisableWarning"><strong>ReservedWordDisableWarning</strong></a>
+  </dt>
+
+  </dl></td>
+  <td style="width: 33%" valign="top"><dl>
+      
+  <dt><a href="config.html#cfg_RetainQueryBox"><strong>RetainQueryBox</strong></a>
+  </dt>
+
+      
+  <dt><a href="glossary.html#term-rfc"><strong>RFC</strong></a>
+  </dt>
+
+      <dd><dl>
+        
+  <dt><a href="faq.html#index-17">RFC 1867</a>
+  </dt>
+
+        
+  <dt><a href="glossary.html#index-0">RFC 1952</a>
+  </dt>
+
+        
+  <dt><a href="faq.html#index-5">RFC 2616</a>
+  </dt>
+
+      </dl></dd>
+      
+  <dt><a href="glossary.html#term-rfc-1952"><strong>RFC 1952</strong></a>
+  </dt>
+
+      
+  <dt><a href="glossary.html#term-row-record-tuple"><strong>Row (record, tuple)</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_RowActionLinks"><strong>RowActionLinks</strong></a>
+  </dt>
+
+  </dl></td>
+</tr></table>
+
+<h2 id="S">S</h2>
+<table style="width: 100%" class="indextable genindextable"><tr>
+  <td style="width: 33%" valign="top"><dl>
+      
+  <dt><a href="config.html#cfg_SaveCellsAtOnce"><strong>SaveCellsAtOnce</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_SaveDir"><strong>SaveDir</strong></a>
+  </dt>
+
+      
+  <dt><a href="glossary.html#term-server"><strong>Server</strong></a>
+  </dt>
+
+      
+  <dt>
+    server configuration
+  </dt>
+
+      <dd><dl>
+        
+  <dt><a href="config.html#cfg_Servers_AllowDeny_order"><strong>AllowDeny, order</strong></a>
+  </dt>
+
+        
+  <dt><a href="config.html#cfg_Servers_AllowDeny_rules"><strong>AllowDeny, rules</strong></a>
+  </dt>
+
+        
+  <dt><a href="config.html#cfg_Servers_AllowNoPassword"><strong>AllowNoPassword</strong></a>
+  </dt>
+
+        
+  <dt><a href="config.html#cfg_Servers_AllowRoot"><strong>AllowRoot</strong></a>
+  </dt>
+
+        
+  <dt><a href="config.html#cfg_Servers_DisableIS"><strong>DisableIS</strong></a>
+  </dt>
+
+        
+  <dt><a href="config.html#cfg_Servers_LogoutURL"><strong>LogoutURL</strong></a>
+  </dt>
+
+        
+  <dt><a href="config.html#cfg_Servers_MaxTableUiprefs"><strong>MaxTableUiprefs</strong></a>
+  </dt>
+
+        
+  <dt><a href="config.html#cfg_Servers_ShowDatabasesCommand"><strong>ShowDatabasesCommand</strong></a>
+  </dt>
+
+        
+  <dt><a href="config.html#cfg_Servers_SignonScript"><strong>SignonScript</strong></a>
+  </dt>
+
+        
+  <dt><a href="config.html#cfg_Servers_SignonSession"><strong>SignonSession</strong></a>
+  </dt>
+
+        
+  <dt><a href="config.html#cfg_Servers_SignonURL"><strong>SignonURL</strong></a>
+  </dt>
+
+        
+  <dt><a href="config.html#cfg_Servers_StatusCacheDatabases"><strong>StatusCacheDatabases</strong></a>
+  </dt>
+
+        
+  <dt><a href="config.html#cfg_Servers_StatusCacheLifetime"><strong>StatusCacheLifetime</strong></a>
+  </dt>
+
+        
+  <dt><a href="config.html#cfg_Servers_auth_http_realm"><strong>auth_http_realm</strong></a>
+  </dt>
+
+        
+  <dt><a href="config.html#cfg_Servers_auth_swekey_config"><strong>auth_swekey_config</strong></a>
+  </dt>
+
+        
+  <dt><a href="config.html#cfg_Servers_auth_type"><strong>auth_type</strong></a>
+  </dt>
+
+        
+  <dt><a href="config.html#cfg_Servers_bookmarktable"><strong>bookmarktable</strong></a>
+  </dt>
+
+        
+  <dt><a href="config.html#cfg_Servers_column_info"><strong>column_info</strong></a>
+  </dt>
+
+        
+  <dt><a href="config.html#cfg_Servers_compress"><strong>compress</strong></a>
+  </dt>
+
+        
+  <dt><a href="config.html#cfg_Servers_connect_type"><strong>connect_type</strong></a>
+  </dt>
+
+        
+  <dt><a href="config.html#cfg_Servers_controlhost"><strong>controlhost</strong></a>
+  </dt>
+
+        
+  <dt><a href="config.html#cfg_Servers_controlpass"><strong>controlpass</strong></a>
+  </dt>
+
+        
+  <dt><a href="config.html#cfg_Servers_controluser"><strong>controluser</strong></a>
+  </dt>
+
+        
+  <dt><a href="config.html#cfg_Servers_designer_coords"><strong>designer_coords</strong></a>
+  </dt>
+
+        
+  <dt><a href="config.html#cfg_Servers_extension"><strong>extension</strong></a>
+  </dt>
+
+        
+  <dt><a href="config.html#cfg_Servers_hide_db"><strong>hide_db</strong></a>
+  </dt>
+
+        
+  <dt><a href="config.html#cfg_Servers_history"><strong>history</strong></a>
+  </dt>
+
+        
+  <dt><a href="config.html#cfg_Servers_host"><strong>host</strong></a>
+  </dt>
+
+        
+  <dt><a href="config.html#cfg_Servers_nopassword"><strong>nopassword</strong></a>
+  </dt>
+
+        
+  <dt><a href="config.html#cfg_Servers_only_db"><strong>only_db</strong></a>
+  </dt>
+
+        
+  <dt><a href="config.html#cfg_Servers_password"><strong>password</strong></a>
+  </dt>
+
+        
+  <dt><a href="config.html#cfg_Servers_pdf_pages"><strong>pdf_pages</strong></a>
+  </dt>
+
+        
+  <dt><a href="config.html#cfg_Servers_pmadb"><strong>pmadb</strong></a>
+  </dt>
+
+        
+  <dt><a href="config.html#cfg_Servers_port"><strong>port</strong></a>
+  </dt>
+
+        
+  <dt><a href="config.html#cfg_Servers_recent"><strong>recent</strong></a>
+  </dt>
+
+        
+  <dt><a href="config.html#cfg_Servers_relation"><strong>relation</strong></a>
+  </dt>
+
+        
+  <dt><a href="config.html#cfg_Servers_socket"><strong>socket</strong></a>
+  </dt>
+
+        
+  <dt><a href="config.html#cfg_Servers_ssl"><strong>ssl</strong></a>
+  </dt>
+
+        
+  <dt><a href="config.html#cfg_Servers_table_coords"><strong>table_coords</strong></a>
+  </dt>
+
+        
+  <dt><a href="config.html#cfg_Servers_table_info"><strong>table_info</strong></a>
+  </dt>
+
+        
+  <dt><a href="config.html#cfg_Servers_table_uiprefs"><strong>table_uiprefs</strong></a>
+  </dt>
+
+        
+  <dt><a href="config.html#cfg_Servers_tracking"><strong>tracking</strong></a>
+  </dt>
+
+        
+  <dt><a href="config.html#cfg_Servers_tracking_add_drop_database"><strong>tracking_add_drop_database</strong></a>
+  </dt>
+
+        
+  <dt><a href="config.html#cfg_Servers_tracking_add_drop_table"><strong>tracking_add_drop_table</strong></a>
+  </dt>
+
+        
+  <dt><a href="config.html#cfg_Servers_tracking_add_drop_view"><strong>tracking_add_drop_view</strong></a>
+  </dt>
+
+        
+  <dt><a href="config.html#cfg_Servers_tracking_default_statements"><strong>tracking_default_statements</strong></a>
+  </dt>
+
+        
+  <dt><a href="config.html#cfg_Servers_tracking_version_auto_create"><strong>tracking_version_auto_create</strong></a>
+  </dt>
+
+        
+  <dt><a href="config.html#cfg_Servers_user"><strong>user</strong></a>
+  </dt>
+
+        
+  <dt><a href="config.html#cfg_Servers_userconfig"><strong>userconfig</strong></a>
+  </dt>
+
+        
+  <dt><a href="config.html#cfg_Servers_verbose"><strong>verbose</strong></a>
+  </dt>
+
+      </dl></dd>
+      
+  <dt><a href="config.html#cfg_ServerDefault"><strong>ServerDefault</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_ServerLibraryDifference_DisableWarning"><strong>ServerLibraryDifference_DisableWarning</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_Servers"><strong>Servers</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_SessionSavePath"><strong>SessionSavePath</strong></a>
+  </dt>
+
+      
+  <dt><a href="setup.html#index-0">Setup script</a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_ShowAll"><strong>ShowAll</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_ShowBrowseComments"><strong>ShowBrowseComments</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_ShowChgPassword"><strong>ShowChgPassword</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_ShowCreateDb"><strong>ShowCreateDb</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_Servers_ShowDatabasesCommand"><strong>ShowDatabasesCommand</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_ShowDbStructureCreation"><strong>ShowDbStructureCreation</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_ShowDbStructureLastCheck"><strong>ShowDbStructureLastCheck</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_ShowDbStructureLastUpdate"><strong>ShowDbStructureLastUpdate</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_ShowDisplayDirection"><strong>ShowDisplayDirection</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_ShowFieldTypesInDataEditView"><strong>ShowFieldTypesInDataEditView</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_ShowFunctionFields"><strong>ShowFunctionFields</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_ShowHint"><strong>ShowHint</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_ShowPhpInfo"><strong>ShowPhpInfo</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_ShowPropertyComments"><strong>ShowPropertyComments</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_ShowServerInfo"><strong>ShowServerInfo</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_ShowSQL"><strong>ShowSQL</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_ShowStats"><strong>ShowStats</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_ShowTooltip"><strong>ShowTooltip</strong></a>
+  </dt>
+
+      
+  <dt>
+    Signon
+  </dt>
+
+      <dd><dl>
+        
+  <dt><a href="setup.html#index-10">Authentication mode</a>
+  </dt>
+
+      </dl></dd>
+  </dl></td>
+  <td style="width: 33%" valign="top"><dl>
+      
+  <dt><a href="config.html#cfg_Servers_SignonScript"><strong>SignonScript</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_Servers_SignonSession"><strong>SignonSession</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_Servers_SignonURL"><strong>SignonURL</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_SkipLockedTables"><strong>SkipLockedTables</strong></a>
+  </dt>
+
+      
+  <dt><a href="glossary.html#term-soap"><strong>SOAP</strong></a>
+  </dt>
+
+      
+  <dt><a href="glossary.html#term-socket"><strong>socket</strong></a>, <a href="config.html#cfg_Servers_socket"><strong>[1]</strong></a>
+  </dt>
+
+      
+  <dt><a href="glossary.html#term-sql"><strong>SQL</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_SQLQuery_Edit"><strong>SQLQuery, Edit</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_SQLQuery_Explain"><strong>SQLQuery, Explain</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_SQLQuery_Refresh"><strong>SQLQuery, Refresh</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_SQLQuery_ShowAsPHP"><strong>SQLQuery, ShowAsPHP</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_SQLQuery_Validate"><strong>SQLQuery, Validate</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_SQLValidator"><strong>SQLValidator</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_SQLValidator_password"><strong>SQLValidator, password</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_SQLValidator_use"><strong>SQLValidator, use</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_SQLValidator_username"><strong>SQLValidator, username</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_SQP_fmtColor"><strong>SQP, fmtColor</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_SQP_fmtInd"><strong>SQP, fmtInd</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_SQP_fmtIndUnit"><strong>SQP, fmtIndUnit</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_SQP_fmtType"><strong>SQP, fmtType</strong></a>
+  </dt>
+
+      
+  <dt><a href="glossary.html#term-ssl"><strong>SSL</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_Servers_ssl"><strong>ssl</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_Servers_StatusCacheDatabases"><strong>StatusCacheDatabases</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_Servers_StatusCacheLifetime"><strong>StatusCacheLifetime</strong></a>
+  </dt>
+
+      
+  <dt><a href="glossary.html#term-storage-engines"><strong>Storage Engines</strong></a>
+  </dt>
+
+      
+  <dt><a href="glossary.html#term-stored-procedure"><strong>Stored procedure</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_SuhosinDisableWarning"><strong>SuhosinDisableWarning</strong></a>
+  </dt>
+
+      
+  <dt>
+    Swekey
+  </dt>
+
+      <dd><dl>
+        
+  <dt><a href="setup.html#index-21">Authentication mode</a>
+  </dt>
+
+      </dl></dd>
+  </dl></td>
+</tr></table>
+
+<h2 id="T">T</h2>
+<table style="width: 100%" class="indextable genindextable"><tr>
+  <td style="width: 33%" valign="top"><dl>
+      
+  <dt><a href="glossary.html#term-table"><strong>table</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_Servers_table_coords"><strong>table_coords</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_Servers_table_info"><strong>table_info</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_Servers_table_uiprefs"><strong>table_uiprefs</strong></a>
+  </dt>
+
+      
+  <dt><a href="glossary.html#term-tar"><strong>tar</strong></a>
+  </dt>
+
+      
+  <dt><a href="glossary.html#term-tcp"><strong>TCP</strong></a>
+  </dt>
+
+      
+  <dt><a href="glossary.html#term-tcpdf"><strong>TCPDF</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_TempDir"><strong>TempDir</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_TextareaAutoSelect"><strong>TextareaAutoSelect</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_TextareaCols"><strong>TextareaCols</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_TextareaRows"><strong>TextareaRows</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_ThBackground"><strong>ThBackground</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_ThColor"><strong>ThColor</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_ThemeDefault"><strong>ThemeDefault</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_ThemeManager"><strong>ThemeManager</strong></a>
+  </dt>
+
+  </dl></td>
+  <td style="width: 33%" valign="top"><dl>
+      
+  <dt><a href="config.html#cfg_ThemePath"><strong>ThemePath</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_ThemePerServer"><strong>ThemePerServer</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_TitleDatabase"><strong>TitleDatabase</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_TitleDefault"><strong>TitleDefault</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_TitleServer"><strong>TitleServer</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_TitleTable"><strong>TitleTable</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_Servers_tracking"><strong>tracking</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_Servers_tracking_add_drop_database"><strong>tracking_add_drop_database</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_Servers_tracking_add_drop_table"><strong>tracking_add_drop_table</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_Servers_tracking_add_drop_view"><strong>tracking_add_drop_view</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_Servers_tracking_default_statements"><strong>tracking_default_statements</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_Servers_tracking_version_auto_create"><strong>tracking_version_auto_create</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_TranslationWarningThreshold"><strong>TranslationWarningThreshold</strong></a>
+  </dt>
+
+      
+  <dt><a href="glossary.html#term-trigger"><strong>trigger</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_TrustedProxies"><strong>TrustedProxies</strong></a>
+  </dt>
+
+  </dl></td>
+</tr></table>
+
+<h2 id="U">U</h2>
+<table style="width: 100%" class="indextable genindextable"><tr>
+  <td style="width: 33%" valign="top"><dl>
+      
+  <dt><a href="glossary.html#term-ufpdf"><strong>UFPDF</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_UploadDir"><strong>UploadDir</strong></a>
+  </dt>
+
+      
+  <dt><a href="glossary.html#term-url"><strong>URL</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_UseDbSearch"><strong>UseDbSearch</strong></a>
+  </dt>
+
+  </dl></td>
+  <td style="width: 33%" valign="top"><dl>
+      
+  <dt><a href="config.html#cfg_Servers_user"><strong>user</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_Servers_userconfig"><strong>userconfig</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_UserprefsDeveloperTab"><strong>UserprefsDeveloperTab</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_UserprefsDisallow"><strong>UserprefsDisallow</strong></a>
+  </dt>
+
+  </dl></td>
+</tr></table>
+
+<h2 id="V">V</h2>
+<table style="width: 100%" class="indextable genindextable"><tr>
+  <td style="width: 33%" valign="top"><dl>
+      
+  <dt><a href="config.html#cfg_Servers_verbose"><strong>verbose</strong></a>
+  </dt>
+
+  </dl></td>
+  <td style="width: 33%" valign="top"><dl>
+      
+  <dt><a href="config.html#cfg_VersionCheck"><strong>VersionCheck</strong></a>
+  </dt>
+
+  </dl></td>
+</tr></table>
+
+<h2 id="W">W</h2>
+<table style="width: 100%" class="indextable genindextable"><tr>
+  <td style="width: 33%" valign="top"><dl>
+      
+  <dt><a href="glossary.html#term-webserver"><strong>Webserver</strong></a>
+  </dt>
+
+  </dl></td>
+</tr></table>
+
+<h2 id="X">X</h2>
+<table style="width: 100%" class="indextable genindextable"><tr>
+  <td style="width: 33%" valign="top"><dl>
+      
+  <dt><a href="glossary.html#term-xml"><strong>XML</strong></a>
+  </dt>
+
+  </dl></td>
+</tr></table>
+
+<h2 id="Z">Z</h2>
+<table style="width: 100%" class="indextable genindextable"><tr>
+  <td style="width: 33%" valign="top"><dl>
+      
+  <dt><a href="glossary.html#term-zip"><strong>ZIP</strong></a>
+  </dt>
+
+      
+  <dt><a href="config.html#cfg_ZipDump"><strong>ZipDump</strong></a>
+  </dt>
+
+  </dl></td>
+  <td style="width: 33%" valign="top"><dl>
+      
+  <dt><a href="glossary.html#term-zlib"><strong>zlib</strong></a>
+  </dt>
+
+  </dl></td>
+</tr></table>
+
+
+
+          </div>
+        </div>
+      </div>
+      <div class="sphinxsidebar">
+        <div class="sphinxsidebarwrapper">
+
+   
+
+<div id="searchbox" style="display: none">
+  <h3>Quick search</h3>
+    <form class="search" action="search.html" method="get">
+      <input type="text" name="q" />
+      <input type="submit" value="Go" />
+      <input type="hidden" name="check_keywords" value="yes" />
+      <input type="hidden" name="area" value="default" />
+    </form>
+    <p class="searchtip" style="font-size: 90%">
+    Enter search terms or a module, class or function name.
+    </p>
+</div>
+<script type="text/javascript">$('#searchbox').show(0);</script>
+        </div>
+      </div>
+      <div class="clearer"></div>
+    </div>
+    <div class="related">
+      <h3>Navigation</h3>
+      <ul>
+        <li class="right" style="margin-right: 10px">
+          <a href="#" title="General Index"
+             >index</a></li>
+        <li><a href="index.html">phpMyAdmin 4.0.4 documentation</a> »</li> 
+      </ul>
+    </div>
+    <div class="footer">
+        © <a href="copyright.html">Copyright</a> 2012 - 2013, The phpMyAdmin devel team.
+      Created using <a href="http://sphinx.pocoo.org/">Sphinx</a> 1.1.3.
+    </div>
+  </body>
+</html>
\ No newline at end of file
diff --git a/phpmyadmin/doc/html/glossary.html b/phpmyadmin/doc/html/glossary.html
new file mode 100644
index 0000000..757eb49
--- /dev/null
+++ b/phpmyadmin/doc/html/glossary.html
@@ -0,0 +1,627 @@
+
+
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+
+
+<html xmlns="http://www.w3.org/1999/xhtml">
+  <head>
+    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+    
+    <title>Glossary — phpMyAdmin 4.0.4 documentation</title>
+    
+    <link rel="stylesheet" href="_static/default.css" type="text/css" />
+    <link rel="stylesheet" href="_static/pygments.css" type="text/css" />
+    
+    <script type="text/javascript">
+      var DOCUMENTATION_OPTIONS = {
+        URL_ROOT:    '',
+        VERSION:     '4.0.4',
+        COLLAPSE_INDEX: false,
+        FILE_SUFFIX: '.html',
+        HAS_SOURCE:  true
+      };
+    </script>
+    <script type="text/javascript" src="_static/jquery.js"></script>
+    <script type="text/javascript" src="_static/underscore.js"></script>
+    <script type="text/javascript" src="_static/doctools.js"></script>
+    <link rel="copyright" title="Copyright" href="copyright.html" />
+    <link rel="top" title="phpMyAdmin 4.0.4 documentation" href="index.html" />
+    <link rel="prev" title="Credits" href="credits.html" /> 
+  </head>
+  <body>
+    <div class="related">
+      <h3>Navigation</h3>
+      <ul>
+        <li class="right" style="margin-right: 10px">
+          <a href="genindex.html" title="General Index"
+             accesskey="I">index</a></li>
+        <li class="right" >
+          <a href="credits.html" title="Credits"
+             accesskey="P">previous</a> |</li>
+        <li><a href="index.html">phpMyAdmin 4.0.4 documentation</a> »</li> 
+      </ul>
+    </div>  
+
+    <div class="document">
+      <div class="documentwrapper">
+        <div class="bodywrapper">
+          <div class="body">
+            
+  <div class="section" id="glossary">
+<span id="id1"></span><h1>Glossary<a class="headerlink" href="#glossary" title="Permalink to this headline">¶</a></h1>
+<p>From Wikipedia, the free encyclopedia</p>
+<dl class="glossary docutils">
+<dt id="term-htaccess">.htaccess</dt>
+<dd><p class="first">the default name of Apache’s directory-level configuration file.</p>
+<div class="admonition-see-also last admonition seealso">
+<p class="first admonition-title">See also</p>
+<p class="last"><<a class="reference external" href="http://www.wikipedia.org/wiki/.htaccess">http://www.wikipedia.org/wiki/.htaccess</a>></p>
+</div>
+</dd>
+<dt id="term-acl">ACL</dt>
+<dd>Access Contol List</dd>
+<dt id="term-blowfish">Blowfish</dt>
+<dd><p class="first">a keyed, symmetric block cipher, designed in 1993 by Bruce Schneier.</p>
+<div class="admonition-see-also last admonition seealso">
+<p class="first admonition-title">See also</p>
+<p class="last"><<a class="reference external" href="http://www.wikipedia.org/wiki/Blowfish_(cipher)">http://www.wikipedia.org/wiki/Blowfish_(cipher)</a>></p>
+</div>
+</dd>
+<dt id="term-browser">Browser</dt>
+<dd><p class="first">a software application that enables a user to display and interact with text, images, and other information typically located on a web page at a website on the World Wide Web.</p>
+<div class="admonition-see-also last admonition seealso">
+<p class="first admonition-title">See also</p>
+<p class="last"><<a class="reference external" href="http://en.wikipedia.org/wiki/Web_browser">http://en.wikipedia.org/wiki/Web_browser</a>></p>
+</div>
+</dd>
+<dt id="term-bzip2">bzip2</dt>
+<dd><p class="first">a free software/open source data compression algorithm and program developed by Julian Seward.</p>
+<div class="admonition-see-also last admonition seealso">
+<p class="first admonition-title">See also</p>
+<p class="last"><<a class="reference external" href="http://www.wikipedia.org/wiki/Bzip2">http://www.wikipedia.org/wiki/Bzip2</a>></p>
+</div>
+</dd>
+<dt id="term-cgi">CGI</dt>
+<dd><p class="first">Common Gateway Interface is an important World Wide Web technology that
+enables a client web browser to request data from a program executed on
+the Web server.</p>
+<div class="admonition-see-also last admonition seealso">
+<p class="first admonition-title">See also</p>
+<p class="last"><<a class="reference external" href="http://www.wikipedia.org/wiki/CGI">http://www.wikipedia.org/wiki/CGI</a>></p>
+</div>
+</dd>
+<dt id="term-changelog">Changelog</dt>
+<dd><p class="first">a log or record of changes made to a project.</p>
+<div class="admonition-see-also last admonition seealso">
+<p class="first admonition-title">See also</p>
+<p class="last"><<a class="reference external" href="http://www.wikipedia.org/wiki/Changelog">http://www.wikipedia.org/wiki/Changelog</a>></p>
+</div>
+</dd>
+<dt id="term-client">Client</dt>
+<dd><p class="first">a computer system that accesses a (remote) service on another computer by some kind of network.</p>
+<div class="admonition-see-also last admonition seealso">
+<p class="first admonition-title">See also</p>
+<p class="last"><<a class="reference external" href="http://www.wikipedia.org/wiki/Client_(computing)">http://www.wikipedia.org/wiki/Client_(computing)</a>></p>
+</div>
+</dd>
+<dt id="term-column">column</dt>
+<dd><p class="first">a set of data values of a particular simple type, one for each row of the table.</p>
+<div class="admonition-see-also last admonition seealso">
+<p class="first admonition-title">See also</p>
+<p class="last"><<a class="reference external" href="http://www.wikipedia.org/wiki/Column_(database)">http://www.wikipedia.org/wiki/Column_(database)</a>></p>
+</div>
+</dd>
+<dt id="term-cookie">Cookie</dt>
+<dd><p class="first">a packet of information sent by a server to a World Wide Web browser and then sent back by the browser each time it accesses that server.</p>
+<div class="admonition-see-also last admonition seealso">
+<p class="first admonition-title">See also</p>
+<p class="last"><<a class="reference external" href="http://www.wikipedia.org/wiki/HTTP_cookie">http://www.wikipedia.org/wiki/HTTP_cookie</a>></p>
+</div>
+</dd>
+<dt id="term-csv">CSV</dt>
+<dd><p class="first">Comma- separated values</p>
+<div class="admonition-see-also last admonition seealso">
+<p class="first admonition-title">See also</p>
+<p class="last"><<a class="reference external" href="http://www.wikipedia.org/wiki/Comma-separated_values">http://www.wikipedia.org/wiki/Comma-separated_values</a>></p>
+</div>
+</dd>
+<dt id="term-db">DB</dt>
+<dd>look at <a class="reference internal" href="#term-database"><em class="xref std std-term">database</em></a></dd>
+<dt id="term-database">database</dt>
+<dd><p class="first">an organized collection of data.</p>
+<div class="admonition-see-also last admonition seealso">
+<p class="first admonition-title">See also</p>
+<p class="last"><<a class="reference external" href="http://www.wikipedia.org/wiki/Database">http://www.wikipedia.org/wiki/Database</a>></p>
+</div>
+</dd>
+<dt id="term-engine">Engine</dt>
+<dd>look at <a class="reference internal" href="#term-storage-engines"><em class="xref std std-term">storage engines</em></a></dd>
+<dt id="term-extension">extension</dt>
+<dd><p class="first">a PHP module that extends PHP with additional functionality.</p>
+<div class="admonition-see-also last admonition seealso">
+<p class="first admonition-title">See also</p>
+<p class="last"><<a class="reference external" href="http://www.wikipedia.org/wiki/extension">http://www.wikipedia.org/wiki/extension</a>></p>
+</div>
+</dd>
+<dt id="term-faq">FAQ</dt>
+<dd><p class="first">Frequently Asked Questions is a list of commonly asked question and there
+answers.</p>
+<div class="admonition-see-also last admonition seealso">
+<p class="first admonition-title">See also</p>
+<p class="last"><<a class="reference external" href="http://www.wikipedia.org/wiki/FAQ">http://www.wikipedia.org/wiki/FAQ</a>></p>
+</div>
+</dd>
+<dt id="term-field">Field</dt>
+<dd><p class="first">one part of divided data/columns.</p>
+<div class="admonition-see-also last admonition seealso">
+<p class="first admonition-title">See also</p>
+<p class="last"><<a class="reference external" href="http://www.wikipedia.org/wiki/Field_(computer_science)">http://www.wikipedia.org/wiki/Field_(computer_science)</a>></p>
+</div>
+</dd>
+<dt id="term-foreign-key">foreign key</dt>
+<dd><p class="first">a column or group of columns in a database row that point to a key column
+or group of columns forming a key of another database row in some
+(usually different) table.</p>
+<div class="admonition-see-also last admonition seealso">
+<p class="first admonition-title">See also</p>
+<p class="last"><<a class="reference external" href="http://www.wikipedia.org/wiki/Foreign_key">http://www.wikipedia.org/wiki/Foreign_key</a>></p>
+</div>
+</dd>
+<dt id="term-fpdf">FPDF</dt>
+<dd><p class="first">the free <a class="reference internal" href="#term-pdf"><em class="xref std std-term">PDF</em></a> library</p>
+<div class="admonition-see-also last admonition seealso">
+<p class="first admonition-title">See also</p>
+<p class="last"><<a class="reference external" href="http://www.fpdf.org/">http://www.fpdf.org/</a>></p>
+</div>
+</dd>
+<dt id="term-gd">GD</dt>
+<dd><p class="first">Graphics Library by Thomas Boutell and others for dynamically manipulating images.</p>
+<div class="admonition-see-also last admonition seealso">
+<p class="first admonition-title">See also</p>
+<p class="last"><<a class="reference external" href="http://www.wikipedia.org/wiki/GD_Graphics_Library">http://www.wikipedia.org/wiki/GD_Graphics_Library</a>></p>
+</div>
+</dd>
+<dt id="term-gd2">GD2</dt>
+<dd>look at <a class="reference internal" href="#term-gd"><em class="xref std std-term">gd</em></a></dd>
+<dt id="term-gzip">gzip</dt>
+<dd><p class="first">gzip is short for GNU zip, a GNU free software file compression program.</p>
+<div class="admonition-see-also last admonition seealso">
+<p class="first admonition-title">See also</p>
+<p class="last"><<a class="reference external" href="http://www.wikipedia.org/wiki/Gzip">http://www.wikipedia.org/wiki/Gzip</a>></p>
+</div>
+</dd>
+<dt id="term-host">host</dt>
+<dd><p class="first">any machine connected to a computer network, a node that has a hostname.</p>
+<div class="admonition-see-also last admonition seealso">
+<p class="first admonition-title">See also</p>
+<p class="last"><<a class="reference external" href="http://www.wikipedia.org/wiki/Host">http://www.wikipedia.org/wiki/Host</a>></p>
+</div>
+</dd>
+<dt id="term-hostname">hostname</dt>
+<dd><p class="first">the unique name by which a network attached device is known on a network.</p>
+<div class="admonition-see-also last admonition seealso">
+<p class="first admonition-title">See also</p>
+<p class="last"><<a class="reference external" href="http://www.wikipedia.org/wiki/Hostname">http://www.wikipedia.org/wiki/Hostname</a>></p>
+</div>
+</dd>
+<dt id="term-http">HTTP</dt>
+<dd><p class="first">HyperText Transfer Protocol is the primary method used to transfer or
+convey information on the World Wide Web.</p>
+<div class="admonition-see-also last admonition seealso">
+<p class="first admonition-title">See also</p>
+<p class="last"><<a class="reference external" href="http://www.wikipedia.org/wiki/HyperText_Transfer_Protocol">http://www.wikipedia.org/wiki/HyperText_Transfer_Protocol</a>></p>
+</div>
+</dd>
+<dt id="term-https">https</dt>
+<dd><p class="first">a <a class="reference internal" href="#term-http"><em class="xref std std-term">HTTP</em></a>-connection with additional security measures.</p>
+<div class="admonition-see-also last admonition seealso">
+<p class="first admonition-title">See also</p>
+<p class="last"><<a class="reference external" href="http://www.wikipedia.org/wiki/Https:_URI_scheme">http://www.wikipedia.org/wiki/Https:_URI_scheme</a>></p>
+</div>
+</dd>
+<dt id="term-iec">IEC</dt>
+<dd>International Electrotechnical Commission</dd>
+<dt id="term-iis">IIS</dt>
+<dd><p class="first">Internet Information Services is a set of Internet-based services for
+servers using Microsoft Windows.</p>
+<div class="admonition-see-also last admonition seealso">
+<p class="first admonition-title">See also</p>
+<p class="last"><<a class="reference external" href="http://www.wikipedia.org/wiki/Internet_Information_Services">http://www.wikipedia.org/wiki/Internet_Information_Services</a>></p>
+</div>
+</dd>
+<dt id="term-index">Index</dt>
+<dd><p class="first">a feature that allows quick access to the rows in a table.</p>
+<div class="admonition-see-also last admonition seealso">
+<p class="first admonition-title">See also</p>
+<p class="last"><<a class="reference external" href="http://www.wikipedia.org/wiki/Index_(database)">http://www.wikipedia.org/wiki/Index_(database)</a>></p>
+</div>
+</dd>
+<dt id="term-ip">IP</dt>
+<dd><p class="first">Internet Protocol is a data-oriented protocol used by source and
+destination hosts for communicating data across a packet-switched
+internetwork.</p>
+<div class="admonition-see-also last admonition seealso">
+<p class="first admonition-title">See also</p>
+<p class="last"><<a class="reference external" href="http://www.wikipedia.org/wiki/Internet_Protocol">http://www.wikipedia.org/wiki/Internet_Protocol</a>></p>
+</div>
+</dd>
+<dt id="term-ip-address">IP Address</dt>
+<dd><p class="first">a unique number that devices use in order to identify and communicate with each other on a network utilizing the Internet Protocol standard.</p>
+<div class="admonition-see-also last admonition seealso">
+<p class="first admonition-title">See also</p>
+<p class="last"><<a class="reference external" href="http://www.wikipedia.org/wiki/IP_Address">http://www.wikipedia.org/wiki/IP_Address</a>></p>
+</div>
+</dd>
+<dt id="term-ipv6">IPv6</dt>
+<dd><p class="first">IPv6 (Internet Protocol version 6) is the latest revision of the
+Internet Protocol (<a class="reference internal" href="#term-ip"><em class="xref std std-term">IP</em></a>), designed to deal with the
+long-anticipated problem of its precedessor IPv4 running out of addresses.</p>
+<div class="admonition-see-also last admonition seealso">
+<p class="first admonition-title">See also</p>
+<p class="last"><<a class="reference external" href="http://www.wikipedia.org/wiki/IPv6">http://www.wikipedia.org/wiki/IPv6</a>></p>
+</div>
+</dd>
+<dt id="term-isapi">ISAPI</dt>
+<dd><p class="first">Internet Server Application Programming Interface is the API of Internet Information Services (IIS).</p>
+<div class="admonition-see-also last admonition seealso">
+<p class="first admonition-title">See also</p>
+<p class="last"><<a class="reference external" href="http://www.wikipedia.org/wiki/ISAPI">http://www.wikipedia.org/wiki/ISAPI</a>></p>
+</div>
+</dd>
+<dt id="term-isp">ISP</dt>
+<dd><p class="first">Internet service provider is a business or organization that offers users
+access to the Internet and related services.</p>
+<div class="admonition-see-also last admonition seealso">
+<p class="first admonition-title">See also</p>
+<p class="last"><<a class="reference external" href="http://www.wikipedia.org/wiki/ISP">http://www.wikipedia.org/wiki/ISP</a>></p>
+</div>
+</dd>
+<dt id="term-iso">ISO</dt>
+<dd>International Standards Organisation</dd>
+<dt id="term-jpeg">JPEG</dt>
+<dd><p class="first">a most commonly used standard method of lossy compression for photographic images.</p>
+<div class="admonition-see-also last admonition seealso">
+<p class="first admonition-title">See also</p>
+<p class="last"><<a class="reference external" href="http://www.wikipedia.org/wiki/JPEG">http://www.wikipedia.org/wiki/JPEG</a>></p>
+</div>
+</dd>
+<dt id="term-jpg">JPG</dt>
+<dd>look at <a class="reference internal" href="#term-jpeg"><em class="xref std std-term">jpeg</em></a></dd>
+<dt id="term-key">Key</dt>
+<dd>look at <a class="reference internal" href="#term-index"><em class="xref std std-term">index</em></a></dd>
+<dt id="term-latex">LATEX</dt>
+<dd><p class="first">a document preparation system for the TEX typesetting program.</p>
+<div class="admonition-see-also last admonition seealso">
+<p class="first admonition-title">See also</p>
+<p class="last"><<a class="reference external" href="http://www.wikipedia.org/wiki/LaTeX">http://www.wikipedia.org/wiki/LaTeX</a>></p>
+</div>
+</dd>
+<dt id="term-mac">Mac</dt>
+<dd><p class="first">Apple Macintosh is line of personal computers is designed, developed, manufactured, and marketed by Apple Computer.</p>
+<p class="last">. seealso:: <<a class="reference external" href="http://www.wikipedia.org/wiki/Mac">http://www.wikipedia.org/wiki/Mac</a>></p>
+</dd>
+<dt id="term-mac-os-x">Mac OS X</dt>
+<dd><p class="first">the operating system which is included with all currently shipping Apple Macintosh computers in the consumer and professional markets.</p>
+<div class="admonition-see-also last admonition seealso">
+<p class="first admonition-title">See also</p>
+<p class="last"><<a class="reference external" href="http://www.wikipedia.org/wiki/Mac_OS_X">http://www.wikipedia.org/wiki/Mac_OS_X</a>></p>
+</div>
+</dd>
+<dt id="term-mcrypt">MCrypt</dt>
+<dd><p class="first">a cryptographic library.</p>
+<div class="admonition-see-also last admonition seealso">
+<p class="first admonition-title">See also</p>
+<p class="last"><<a class="reference external" href="http://www.wikipedia.org/wiki/MCrypt">http://www.wikipedia.org/wiki/MCrypt</a>></p>
+</div>
+</dd>
+<dt id="term-42">mcrypt</dt>
+<dd><p class="first">the MCrypt PHP extension.</p>
+<div class="admonition-see-also last admonition seealso">
+<p class="first admonition-title">See also</p>
+<p class="last"><<a class="reference external" href="http://php.net/mcrypt">http://php.net/mcrypt</a>></p>
+</div>
+</dd>
+<dt id="term-mime">MIME</dt>
+<dd><p class="first">Multipurpose Internet Mail Extensions is
+an Internet Standard for the format of e-mail.</p>
+<div class="admonition-see-also last admonition seealso">
+<p class="first admonition-title">See also</p>
+<p class="last"><<a class="reference external" href="http://www.wikipedia.org/wiki/MIME">http://www.wikipedia.org/wiki/MIME</a>></p>
+</div>
+</dd>
+<dt id="term-module">module</dt>
+<dd><p class="first">some sort of extension for the Apache Webserver.</p>
+<div class="admonition-see-also last admonition seealso">
+<p class="first admonition-title">See also</p>
+<p class="last"><<a class="reference external" href="http://www.wikipedia.org/wiki/module">http://www.wikipedia.org/wiki/module</a>></p>
+</div>
+</dd>
+<dt id="term-mysql">MySQL</dt>
+<dd><p class="first">a multithreaded, multi-user, SQL (Structured Query Language) Database Management System (DBMS).</p>
+<div class="admonition-see-also last admonition seealso">
+<p class="first admonition-title">See also</p>
+<p class="last"><<a class="reference external" href="http://www.wikipedia.org/wiki/MySQL">http://www.wikipedia.org/wiki/MySQL</a>></p>
+</div>
+</dd>
+<dt id="term-mysqli">mysqli</dt>
+<dd><p class="first">the improved MySQL client PHP extension.</p>
+<div class="admonition-see-also last admonition seealso">
+<p class="first admonition-title">See also</p>
+<p class="last"><<a class="reference external" href="http://php.net/mysqli">http://php.net/mysqli</a>></p>
+</div>
+</dd>
+<dt id="term-47">mysql</dt>
+<dd><p class="first">the MySQL client PHP extension.</p>
+<div class="admonition-see-also last admonition seealso">
+<p class="first admonition-title">See also</p>
+<p class="last"><<a class="reference external" href="http://php.net/mysql">http://php.net/mysql</a>></p>
+</div>
+</dd>
+<dt id="term-opendocument">OpenDocument</dt>
+<dd><p class="first">open standard for office documents.</p>
+<div class="admonition-see-also last admonition seealso">
+<p class="first admonition-title">See also</p>
+<p class="last"><<a class="reference external" href="http://www.wikipedia.org/wiki/OpenDocument">http://www.wikipedia.org/wiki/OpenDocument</a>></p>
+</div>
+</dd>
+<dt id="term-os-x">OS X</dt>
+<dd><p class="first">look at <a class="reference internal" href="#term-mac-os-x"><em class="xref std std-term">Mac OS X</em></a>.</p>
+<div class="admonition-see-also last admonition seealso">
+<p class="first admonition-title">See also</p>
+<p class="last"><<a class="reference external" href="http://www.wikipedia.org/wiki/OS_X">http://www.wikipedia.org/wiki/OS_X</a>></p>
+</div>
+</dd>
+<dt id="term-pdf">PDF</dt>
+<dd><p class="first">Portable Document Format is a file format developed by Adobe Systems for
+representing two dimensional documents in a device independent and
+resolution independent format.</p>
+<div class="admonition-see-also last admonition seealso">
+<p class="first admonition-title">See also</p>
+<p class="last"><<a class="reference external" href="http://www.wikipedia.org/wiki/Portable_Document_Format">http://www.wikipedia.org/wiki/Portable_Document_Format</a>></p>
+</div>
+</dd>
+<dt id="term-pear">PEAR</dt>
+<dd><p class="first">the PHP Extension and Application Repository.</p>
+<div class="admonition-see-also last admonition seealso">
+<p class="first admonition-title">See also</p>
+<p class="last"><<a class="reference external" href="http://pear.php.net/">http://pear.php.net/</a>></p>
+</div>
+</dd>
+<dt id="term-pcre">PCRE</dt>
+<dd><p class="first">Perl Compatible Regular Expressions is the perl-compatible regular
+expression functions for PHP</p>
+<div class="admonition-see-also last admonition seealso">
+<p class="first admonition-title">See also</p>
+<p class="last"><<a class="reference external" href="http://php.net/pcre">http://php.net/pcre</a>></p>
+</div>
+</dd>
+<dt id="term-php">PHP</dt>
+<dd><p class="first">short for “PHP: Hypertext Preprocessor”, is an open-source, reflective
+programming language used mainly for developing server-side applications
+and dynamic web content, and more recently, a broader range of software
+applications.</p>
+<div class="admonition-see-also last admonition seealso">
+<p class="first admonition-title">See also</p>
+<p class="last"><<a class="reference external" href="http://www.wikipedia.org/wiki/PHP">http://www.wikipedia.org/wiki/PHP</a>></p>
+</div>
+</dd>
+<dt id="term-port">port</dt>
+<dd><p class="first">a connection through which data is sent and received.</p>
+<div class="admonition-see-also last admonition seealso">
+<p class="first admonition-title">See also</p>
+<p class="last"><<a class="reference external" href="http://www.wikipedia.org/wiki/Port_(computing)">http://www.wikipedia.org/wiki/Port_(computing)</a>></p>
+</div>
+</dd>
+<dt id="term-rfc">RFC</dt>
+<dd><p class="first">Request for Comments (RFC) documents are a series of memoranda
+encompassing new research, innovations, and methodologies applicable to
+Internet technologies.</p>
+<div class="admonition-see-also last admonition seealso">
+<p class="first admonition-title">See also</p>
+<p class="last"><<a class="reference external" href="http://www.wikipedia.org/wiki/Request_for_Comments">http://www.wikipedia.org/wiki/Request_for_Comments</a>></p>
+</div>
+</dd>
+<dt id="term-rfc-1952">RFC 1952</dt>
+<dd><p class="first">GZIP file format specification version 4.3</p>
+<div class="admonition-see-also last admonition seealso">
+<p class="first admonition-title">See also</p>
+<p class="last"><span class="target" id="index-0"></span><a class="rfc reference external" href="http://tools.ietf.org/html/rfc1952.html"><strong>RFC 1952</strong></a></p>
+</div>
+</dd>
+<dt id="term-row-record-tuple">Row (record, tuple)</dt>
+<dd><p class="first">represents a single, implicitly structured data item in a table.</p>
+<div class="admonition-see-also last admonition seealso">
+<p class="first admonition-title">See also</p>
+<p class="last"><<a class="reference external" href="http://www.wikipedia.org/wiki/Row_(database)">http://www.wikipedia.org/wiki/Row_(database)</a>></p>
+</div>
+</dd>
+<dt id="term-server">Server</dt>
+<dd><p class="first">a computer system that provides services to other computing systems over a network.</p>
+<div class="admonition-see-also last admonition seealso">
+<p class="first admonition-title">See also</p>
+<p class="last"><<a class="reference external" href="http://www.wikipedia.org/wiki/Server_(computing)">http://www.wikipedia.org/wiki/Server_(computing)</a>></p>
+</div>
+</dd>
+<dt id="term-storage-engines">Storage Engines</dt>
+<dd><p class="first">handlers for different table types</p>
+<div class="admonition-see-also last admonition seealso">
+<p class="first admonition-title">See also</p>
+<p class="last"><<a class="reference external" href="http://dev.mysql.com/doc/en/storage-engines.html">http://dev.mysql.com/doc/en/storage-engines.html</a>></p>
+</div>
+</dd>
+<dt id="term-soap">SOAP</dt>
+<dd><p class="first">Simple Object Access Protocol is a protocol specification for exchanging
+structured information in the implementation of Web Services in computer
+networks.</p>
+<div class="admonition-see-also last admonition seealso">
+<p class="first admonition-title">See also</p>
+<p class="last"><<a class="reference external" href="http://en.wikipedia.org/wiki/SOAP">http://en.wikipedia.org/wiki/SOAP</a>></p>
+</div>
+</dd>
+<dt id="term-socket">socket</dt>
+<dd><p class="first">a form of inter-process communication.</p>
+<div class="admonition-see-also last admonition seealso">
+<p class="first admonition-title">See also</p>
+<p class="last"><<a class="reference external" href="http://www.wikipedia.org/wiki/Socket#Computer_sockets">http://www.wikipedia.org/wiki/Socket#Computer_sockets</a>></p>
+</div>
+</dd>
+<dt id="term-ssl">SSL</dt>
+<dd><p class="first">Secure Sockets Layer is a cryptographic protocol which provides secure
+communication on the Internet.</p>
+<div class="admonition-see-also last admonition seealso">
+<p class="first admonition-title">See also</p>
+<p class="last"><<a class="reference external" href="http://www.wikipedia.org/wiki/Secure_Sockets_Layer">http://www.wikipedia.org/wiki/Secure_Sockets_Layer</a>></p>
+</div>
+</dd>
+<dt id="term-stored-procedure">Stored procedure</dt>
+<dd><p class="first">a subroutine available to applications accessing a relational database system</p>
+<div class="admonition-see-also last admonition seealso">
+<p class="first admonition-title">See also</p>
+<p class="last"><<a class="reference external" href="http://en.wikipedia.org/wiki/Stored_procedure">http://en.wikipedia.org/wiki/Stored_procedure</a>></p>
+</div>
+</dd>
+<dt id="term-sql">SQL</dt>
+<dd><p class="first">Structured Query Language</p>
+<div class="admonition-see-also last admonition seealso">
+<p class="first admonition-title">See also</p>
+<p class="last"><<a class="reference external" href="http://www.wikipedia.org/wiki/SQL">http://www.wikipedia.org/wiki/SQL</a>></p>
+</div>
+</dd>
+<dt id="term-table">table</dt>
+<dd><p class="first">a set of data elements (cells) that is organized, defined and stored as
+horizontal rows and vertical columns where each item can be uniquely
+identified by a label or key or by it?s position in relation to other
+items.</p>
+<div class="admonition-see-also last admonition seealso">
+<p class="first admonition-title">See also</p>
+<p class="last"><<a class="reference external" href="http://www.wikipedia.org/wiki/Table_(database)">http://www.wikipedia.org/wiki/Table_(database)</a>></p>
+</div>
+</dd>
+<dt id="term-tar">tar</dt>
+<dd><p class="first">a type of archive file format: the Tape ARchive format.</p>
+<div class="admonition-see-also last admonition seealso">
+<p class="first admonition-title">See also</p>
+<p class="last"><<a class="reference external" href="http://www.wikipedia.org/wiki/Tar_(file_format)">http://www.wikipedia.org/wiki/Tar_(file_format)</a>></p>
+</div>
+</dd>
+<dt id="term-tcp">TCP</dt>
+<dd><p class="first">Transmission Control Protocol is one of the core protocols of the
+Internet protocol suite.</p>
+<div class="admonition-see-also last admonition seealso">
+<p class="first admonition-title">See also</p>
+<p class="last"><<a class="reference external" href="http://www.wikipedia.org/wiki/TCP">http://www.wikipedia.org/wiki/TCP</a>></p>
+</div>
+</dd>
+<dt id="term-tcpdf">TCPDF</dt>
+<dd><p class="first">Rewrite of <a class="reference internal" href="#term-ufpdf"><em class="xref std std-term">UFPDF</em></a> with various improvements.</p>
+<div class="admonition-see-also last admonition seealso">
+<p class="first admonition-title">See also</p>
+<p class="last"><<a class="reference external" href="http://www.tcpdf.org/">http://www.tcpdf.org/</a>></p>
+</div>
+</dd>
+<dt id="term-trigger">trigger</dt>
+<dd><p class="first">a procedural code that is automatically executed in response to certain events on a particular table or view in a database</p>
+<div class="admonition-see-also last admonition seealso">
+<p class="first admonition-title">See also</p>
+<p class="last"><<a class="reference external" href="http://en.wikipedia.org/wiki/Database_trigger">http://en.wikipedia.org/wiki/Database_trigger</a>></p>
+</div>
+</dd>
+<dt id="term-ufpdf">UFPDF</dt>
+<dd><p class="first">Unicode/UTF-8 extension for <a class="reference internal" href="#term-fpdf"><em class="xref std std-term">FPDF</em></a></p>
+<div class="admonition-see-also last admonition seealso">
+<p class="first admonition-title">See also</p>
+<p class="last"><<a class="reference external" href="http://www.acko.net/node/56">http://www.acko.net/node/56</a>></p>
+</div>
+</dd>
+<dt id="term-url">URL</dt>
+<dd><p class="first">Uniform Resource Locator is a sequence of characters, conforming to a
+standardized format, that is used for referring to resources, such as
+documents and images on the Internet, by their location.</p>
+<div class="admonition-see-also last admonition seealso">
+<p class="first admonition-title">See also</p>
+<p class="last"><<a class="reference external" href="http://www.wikipedia.org/wiki/URL">http://www.wikipedia.org/wiki/URL</a>></p>
+</div>
+</dd>
+<dt id="term-webserver">Webserver</dt>
+<dd><p class="first">A computer (program) that is responsible for accepting HTTP requests from clients and serving them Web pages.</p>
+<div class="admonition-see-also last admonition seealso">
+<p class="first admonition-title">See also</p>
+<p class="last"><<a class="reference external" href="http://www.wikipedia.org/wiki/Webserver">http://www.wikipedia.org/wiki/Webserver</a>></p>
+</div>
+</dd>
+<dt id="term-xml">XML</dt>
+<dd><p class="first">Extensible Markup Language is a W3C-recommended general- purpose markup
+language for creating special-purpose markup languages, capable of
+describing many different kinds of data.</p>
+<div class="admonition-see-also last admonition seealso">
+<p class="first admonition-title">See also</p>
+<p class="last"><<a class="reference external" href="http://www.wikipedia.org/wiki/XML">http://www.wikipedia.org/wiki/XML</a>></p>
+</div>
+</dd>
+<dt id="term-zip">ZIP</dt>
+<dd><p class="first">a popular data compression and archival format.</p>
+<div class="admonition-see-also last admonition seealso">
+<p class="first admonition-title">See also</p>
+<p class="last"><<a class="reference external" href="http://www.wikipedia.org/wiki/ZIP_(file_format)">http://www.wikipedia.org/wiki/ZIP_(file_format)</a>></p>
+</div>
+</dd>
+<dt id="term-zlib">zlib</dt>
+<dd><p class="first">an open-source, cross- platform data compression library by Jean-loup Gailly and Mark Adler.</p>
+<div class="admonition-see-also last admonition seealso">
+<p class="first admonition-title">See also</p>
+<p class="last"><<a class="reference external" href="http://www.wikipedia.org/wiki/Zlib">http://www.wikipedia.org/wiki/Zlib</a>></p>
+</div>
+</dd>
+</dl>
+</div>
+
+
+          </div>
+        </div>
+      </div>
+      <div class="sphinxsidebar">
+        <div class="sphinxsidebarwrapper">
+  <h4>Previous topic</h4>
+  <p class="topless"><a href="credits.html"
+                        title="previous chapter">Credits</a></p>
+  <h3>This Page</h3>
+  <ul class="this-page-menu">
+    <li><a href="_sources/glossary.txt"
+           rel="nofollow">Show Source</a></li>
+  </ul>
+<div id="searchbox" style="display: none">
+  <h3>Quick search</h3>
+    <form class="search" action="search.html" method="get">
+      <input type="text" name="q" />
+      <input type="submit" value="Go" />
+      <input type="hidden" name="check_keywords" value="yes" />
+      <input type="hidden" name="area" value="default" />
+    </form>
+    <p class="searchtip" style="font-size: 90%">
+    Enter search terms or a module, class or function name.
+    </p>
+</div>
+<script type="text/javascript">$('#searchbox').show(0);</script>
+        </div>
+      </div>
+      <div class="clearer"></div>
+    </div>
+    <div class="related">
+      <h3>Navigation</h3>
+      <ul>
+        <li class="right" style="margin-right: 10px">
+          <a href="genindex.html" title="General Index"
+             >index</a></li>
+        <li class="right" >
+          <a href="credits.html" title="Credits"
+             >previous</a> |</li>
+        <li><a href="index.html">phpMyAdmin 4.0.4 documentation</a> »</li> 
+      </ul>
+    </div>
+    <div class="footer">
+        © <a href="copyright.html">Copyright</a> 2012 - 2013, The phpMyAdmin devel team.
+      Created using <a href="http://sphinx.pocoo.org/">Sphinx</a> 1.1.3.
+    </div>
+  </body>
+</html>
\ No newline at end of file
diff --git a/phpmyadmin/doc/html/index.html b/phpmyadmin/doc/html/index.html
new file mode 100644
index 0000000..bb00688
--- /dev/null
+++ b/phpmyadmin/doc/html/index.html
@@ -0,0 +1,206 @@
+
+
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+
+
+<html xmlns="http://www.w3.org/1999/xhtml">
+  <head>
+    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+    
+    <title>Welcome to phpMyAdmin’s documentation! — phpMyAdmin 4.0.4 documentation</title>
+    
+    <link rel="stylesheet" href="_static/default.css" type="text/css" />
+    <link rel="stylesheet" href="_static/pygments.css" type="text/css" />
+    
+    <script type="text/javascript">
+      var DOCUMENTATION_OPTIONS = {
+        URL_ROOT:    '',
+        VERSION:     '4.0.4',
+        COLLAPSE_INDEX: false,
+        FILE_SUFFIX: '.html',
+        HAS_SOURCE:  true
+      };
+    </script>
+    <script type="text/javascript" src="_static/jquery.js"></script>
+    <script type="text/javascript" src="_static/underscore.js"></script>
+    <script type="text/javascript" src="_static/doctools.js"></script>
+    <link rel="copyright" title="Copyright" href="copyright.html" />
+    <link rel="top" title="phpMyAdmin 4.0.4 documentation" href="#" />
+    <link rel="next" title="Introduction" href="intro.html" /> 
+  </head>
+  <body>
+    <div class="related">
+      <h3>Navigation</h3>
+      <ul>
+        <li class="right" style="margin-right: 10px">
+          <a href="genindex.html" title="General Index"
+             accesskey="I">index</a></li>
+        <li class="right" >
+          <a href="intro.html" title="Introduction"
+             accesskey="N">next</a> |</li>
+        <li><a href="#">phpMyAdmin 4.0.4 documentation</a> »</li> 
+      </ul>
+    </div>  
+
+    <div class="document">
+      <div class="documentwrapper">
+        <div class="bodywrapper">
+          <div class="body">
+            
+  <div class="section" id="welcome-to-phpmyadmin-s-documentation">
+<h1>Welcome to phpMyAdmin’s documentation!<a class="headerlink" href="#welcome-to-phpmyadmin-s-documentation" title="Permalink to this headline">¶</a></h1>
+<p>Contents:</p>
+<div class="toctree-wrapper compound">
+<ul>
+<li class="toctree-l1"><a class="reference internal" href="intro.html">Introduction</a><ul>
+<li class="toctree-l2"><a class="reference internal" href="intro.html#supported-features">Supported features</a></li>
+<li class="toctree-l2"><a class="reference internal" href="intro.html#a-word-about-users">A word about users</a></li>
+</ul>
+</li>
+<li class="toctree-l1"><a class="reference internal" href="require.html">Requirements</a><ul>
+<li class="toctree-l2"><a class="reference internal" href="require.html#web-server">Web server</a></li>
+<li class="toctree-l2"><a class="reference internal" href="require.html#php">PHP</a></li>
+<li class="toctree-l2"><a class="reference internal" href="require.html#database">Database</a></li>
+<li class="toctree-l2"><a class="reference internal" href="require.html#web-browser">Web browser</a></li>
+</ul>
+</li>
+<li class="toctree-l1"><a class="reference internal" href="setup.html">Installation</a><ul>
+<li class="toctree-l2"><a class="reference internal" href="setup.html#quick-install">Quick Install</a></li>
+<li class="toctree-l2"><a class="reference internal" href="setup.html#phpmyadmin-configuration-storage">phpMyAdmin configuration storage</a></li>
+<li class="toctree-l2"><a class="reference internal" href="setup.html#upgrading-from-an-older-version">Upgrading from an older version</a></li>
+<li class="toctree-l2"><a class="reference internal" href="setup.html#using-authentication-modes">Using authentication modes</a></li>
+<li class="toctree-l2"><a class="reference internal" href="setup.html#securing-your-phpmyadmin-installation">Securing your phpMyAdmin installation</a></li>
+</ul>
+</li>
+<li class="toctree-l1"><a class="reference internal" href="config.html">Configuration</a><ul>
+<li class="toctree-l2"><a class="reference internal" href="config.html#basic-settings">Basic settings</a></li>
+<li class="toctree-l2"><a class="reference internal" href="config.html#server-connection-settings">Server connection settings</a></li>
+<li class="toctree-l2"><a class="reference internal" href="config.html#generic-settings">Generic settings</a></li>
+<li class="toctree-l2"><a class="reference internal" href="config.html#cookie-authentication-options">Cookie authentication options</a></li>
+<li class="toctree-l2"><a class="reference internal" href="config.html#navigation-panel-setup">Navigation panel setup</a></li>
+<li class="toctree-l2"><a class="reference internal" href="config.html#main-panel">Main panel</a></li>
+<li class="toctree-l2"><a class="reference internal" href="config.html#database-structure">Database structure</a></li>
+<li class="toctree-l2"><a class="reference internal" href="config.html#browse-mode">Browse mode</a></li>
+<li class="toctree-l2"><a class="reference internal" href="config.html#editing-mode">Editing mode</a></li>
+<li class="toctree-l2"><a class="reference internal" href="config.html#export-and-import-settings">Export and import settings</a></li>
+<li class="toctree-l2"><a class="reference internal" href="config.html#tabs-display-settings">Tabs display settings</a></li>
+<li class="toctree-l2"><a class="reference internal" href="config.html#documentation">Documentation</a></li>
+<li class="toctree-l2"><a class="reference internal" href="config.html#languages">Languages</a></li>
+<li class="toctree-l2"><a class="reference internal" href="config.html#web-server-settings">Web server settings</a></li>
+<li class="toctree-l2"><a class="reference internal" href="config.html#theme-settings">Theme settings</a></li>
+<li class="toctree-l2"><a class="reference internal" href="config.html#design-customization">Design customization</a></li>
+<li class="toctree-l2"><a class="reference internal" href="config.html#text-fields">Text fields</a></li>
+<li class="toctree-l2"><a class="reference internal" href="config.html#sql-query-box-settings">SQL query box settings</a></li>
+<li class="toctree-l2"><a class="reference internal" href="config.html#web-server-upload-save-import-directories">Web server upload/save/import directories</a></li>
+<li class="toctree-l2"><a class="reference internal" href="config.html#various-display-setting">Various display setting</a></li>
+<li class="toctree-l2"><a class="reference internal" href="config.html#page-titles">Page titles</a></li>
+<li class="toctree-l2"><a class="reference internal" href="config.html#theme-manager-settings">Theme manager settings</a></li>
+<li class="toctree-l2"><a class="reference internal" href="config.html#default-queries">Default queries</a></li>
+<li class="toctree-l2"><a class="reference internal" href="config.html#sql-parser-settings">SQL parser settings</a></li>
+<li class="toctree-l2"><a class="reference internal" href="config.html#sql-validator-settings">SQL validator settings</a></li>
+<li class="toctree-l2"><a class="reference internal" href="config.html#mysql-settings">MySQL settings</a></li>
+<li class="toctree-l2"><a class="reference internal" href="config.html#developer">Developer</a></li>
+</ul>
+</li>
+<li class="toctree-l1"><a class="reference internal" href="user.html">User Guide</a><ul>
+<li class="toctree-l2"><a class="reference internal" href="transformations.html">Transformations</a></li>
+<li class="toctree-l2"><a class="reference internal" href="privileges.html">User management</a></li>
+<li class="toctree-l2"><a class="reference internal" href="other.html">Other sources of information</a></li>
+</ul>
+</li>
+<li class="toctree-l1"><a class="reference internal" href="faq.html">FAQ - Frequently Asked Questions</a><ul>
+<li class="toctree-l2"><a class="reference internal" href="faq.html#server">Server</a></li>
+<li class="toctree-l2"><a class="reference internal" href="faq.html#configuration">Configuration</a></li>
+<li class="toctree-l2"><a class="reference internal" href="faq.html#known-limitations">Known limitations</a></li>
+<li class="toctree-l2"><a class="reference internal" href="faq.html#isps-multi-user-installations">ISPs, multi-user installations</a></li>
+<li class="toctree-l2"><a class="reference internal" href="faq.html#browsers-or-client-os">Browsers or client OS</a></li>
+<li class="toctree-l2"><a class="reference internal" href="faq.html#using-phpmyadmin">Using phpMyAdmin</a></li>
+<li class="toctree-l2"><a class="reference internal" href="faq.html#phpmyadmin-project">phpMyAdmin project</a></li>
+<li class="toctree-l2"><a class="reference internal" href="faq.html#security">Security</a></li>
+<li class="toctree-l2"><a class="reference internal" href="faq.html#synchronization">Synchronization</a></li>
+</ul>
+</li>
+<li class="toctree-l1"><a class="reference internal" href="developers.html">Developers Information</a></li>
+<li class="toctree-l1"><a class="reference internal" href="vendors.html">Distributing and packaging phpMyAdmin</a><ul>
+<li class="toctree-l2"><a class="reference internal" href="vendors.html#external-libraries">External libraries</a></li>
+</ul>
+</li>
+<li class="toctree-l1"><a class="reference internal" href="copyright.html">Copyright</a></li>
+<li class="toctree-l1"><a class="reference internal" href="credits.html">Credits</a><ul>
+<li class="toctree-l2"><a class="reference internal" href="credits.html#credits-in-chronological-order">Credits, in chronological order</a></li>
+<li class="toctree-l2"><a class="reference internal" href="credits.html#translators">Translators</a></li>
+<li class="toctree-l2"><a class="reference internal" href="credits.html#documentation-translators">Documentation translators</a></li>
+<li class="toctree-l2"><a class="reference internal" href="credits.html#original-credits-of-version-2-1-0">Original Credits of Version 2.1.0</a></li>
+</ul>
+</li>
+<li class="toctree-l1"><a class="reference internal" href="glossary.html">Glossary</a></li>
+</ul>
+</div>
+</div>
+<div class="section" id="indices-and-tables">
+<h1>Indices and tables<a class="headerlink" href="#indices-and-tables" title="Permalink to this headline">¶</a></h1>
+<ul class="simple">
+<li><a class="reference internal" href="genindex.html"><em>Index</em></a></li>
+<li><a class="reference internal" href="search.html"><em>Search Page</em></a></li>
+<li><a class="reference internal" href="glossary.html#glossary"><em>Glossary</em></a></li>
+</ul>
+</div>
+
+
+          </div>
+        </div>
+      </div>
+      <div class="sphinxsidebar">
+        <div class="sphinxsidebarwrapper">
+  <h3><a href="#">Table Of Contents</a></h3>
+  <ul>
+<li><a class="reference internal" href="#">Welcome to phpMyAdmin’s documentation!</a><ul>
+</ul>
+</li>
+<li><a class="reference internal" href="#indices-and-tables">Indices and tables</a></li>
+</ul>
+
+  <h4>Next topic</h4>
+  <p class="topless"><a href="intro.html"
+                        title="next chapter">Introduction</a></p>
+  <h3>This Page</h3>
+  <ul class="this-page-menu">
+    <li><a href="_sources/index.txt"
+           rel="nofollow">Show Source</a></li>
+  </ul>
+<div id="searchbox" style="display: none">
+  <h3>Quick search</h3>
+    <form class="search" action="search.html" method="get">
+      <input type="text" name="q" />
+      <input type="submit" value="Go" />
+      <input type="hidden" name="check_keywords" value="yes" />
+      <input type="hidden" name="area" value="default" />
+    </form>
+    <p class="searchtip" style="font-size: 90%">
+    Enter search terms or a module, class or function name.
+    </p>
+</div>
+<script type="text/javascript">$('#searchbox').show(0);</script>
+        </div>
+      </div>
+      <div class="clearer"></div>
+    </div>
+    <div class="related">
+      <h3>Navigation</h3>
+      <ul>
+        <li class="right" style="margin-right: 10px">
+          <a href="genindex.html" title="General Index"
+             >index</a></li>
+        <li class="right" >
+          <a href="intro.html" title="Introduction"
+             >next</a> |</li>
+        <li><a href="#">phpMyAdmin 4.0.4 documentation</a> »</li> 
+      </ul>
+    </div>
+    <div class="footer">
+        © <a href="copyright.html">Copyright</a> 2012 - 2013, The phpMyAdmin devel team.
+      Created using <a href="http://sphinx.pocoo.org/">Sphinx</a> 1.1.3.
+    </div>
+  </body>
+</html>
\ No newline at end of file
diff --git a/phpmyadmin/doc/html/intro.html b/phpmyadmin/doc/html/intro.html
new file mode 100644
index 0000000..5d3bfbe
--- /dev/null
+++ b/phpmyadmin/doc/html/intro.html
@@ -0,0 +1,182 @@
+
+
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+
+
+<html xmlns="http://www.w3.org/1999/xhtml">
+  <head>
+    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+    
+    <title>Introduction — phpMyAdmin 4.0.4 documentation</title>
+    
+    <link rel="stylesheet" href="_static/default.css" type="text/css" />
+    <link rel="stylesheet" href="_static/pygments.css" type="text/css" />
+    
+    <script type="text/javascript">
+      var DOCUMENTATION_OPTIONS = {
+        URL_ROOT:    '',
+        VERSION:     '4.0.4',
+        COLLAPSE_INDEX: false,
+        FILE_SUFFIX: '.html',
+        HAS_SOURCE:  true
+      };
+    </script>
+    <script type="text/javascript" src="_static/jquery.js"></script>
+    <script type="text/javascript" src="_static/underscore.js"></script>
+    <script type="text/javascript" src="_static/doctools.js"></script>
+    <link rel="copyright" title="Copyright" href="copyright.html" />
+    <link rel="top" title="phpMyAdmin 4.0.4 documentation" href="index.html" />
+    <link rel="next" title="Requirements" href="require.html" />
+    <link rel="prev" title="Welcome to phpMyAdmin’s documentation!" href="index.html" /> 
+  </head>
+  <body>
+    <div class="related">
+      <h3>Navigation</h3>
+      <ul>
+        <li class="right" style="margin-right: 10px">
+          <a href="genindex.html" title="General Index"
+             accesskey="I">index</a></li>
+        <li class="right" >
+          <a href="require.html" title="Requirements"
+             accesskey="N">next</a> |</li>
+        <li class="right" >
+          <a href="index.html" title="Welcome to phpMyAdmin’s documentation!"
+             accesskey="P">previous</a> |</li>
+        <li><a href="index.html">phpMyAdmin 4.0.4 documentation</a> »</li> 
+      </ul>
+    </div>  
+
+    <div class="document">
+      <div class="documentwrapper">
+        <div class="bodywrapper">
+          <div class="body">
+            
+  <div class="section" id="introduction">
+<span id="intro"></span><h1>Introduction<a class="headerlink" href="#introduction" title="Permalink to this headline">¶</a></h1>
+<p>phpMyAdmin can manage a whole MySQL server (needs a super-user) as
+well as a single database. To accomplish the latter you’ll need a
+properly set up MySQL user who can read/write only the desired
+database. It’s up to you to look up the appropriate part in the MySQL
+manual.</p>
+<div class="section" id="supported-features">
+<h2>Supported features<a class="headerlink" href="#supported-features" title="Permalink to this headline">¶</a></h2>
+<p>Currently phpMyAdmin can:</p>
+<ul class="simple">
+<li>browse and drop databases, tables, views, columns and indexes</li>
+<li>display multiple results sets through stored procedures or queries</li>
+<li>create, copy, drop, rename and alter databases, tables, columns and
+indexes</li>
+<li>maintenance server, databases and tables, with proposals on server
+configuration</li>
+<li>execute, edit and bookmark any <a class="reference internal" href="glossary.html#term-sql"><em class="xref std std-term">SQL</em></a>-statement, even batch-queries</li>
+<li>load text files into tables</li>
+<li>create <a class="footnote-reference" href="#f1" id="id1">[1]</a> and read dumps of tables</li>
+<li>export <a class="footnote-reference" href="#f1" id="id2">[1]</a> data to various formats: <a class="reference internal" href="glossary.html#term-csv"><em class="xref std std-term">CSV</em></a>, <a class="reference internal" href="glossary.html#term-xml"><em class="xref std std-term">XML</em></a>, <a class="reference internal" href="glossary.html#term-pdf"><em class="xref std std-term">PDF</em></a>,
+<a class="reference internal" href="glossary.html#term-iso"><em class="xref std std-term">ISO</em></a>/<a class="reference internal" href="glossary.html#term-iec"><em class="xref std std-term">IEC</em></a> 26300 - <a class="reference internal" href="glossary.html#term-opendocument"><em class="xref std std-term">OpenDocument</em></a> Text and Spreadsheet, Microsoft
+Word 2000, and LATEX formats</li>
+<li>import data and <a class="reference internal" href="glossary.html#term-47"><em class="xref std std-term">MySQL</em></a> structures from <a class="reference internal" href="glossary.html#term-opendocument"><em class="xref std std-term">OpenDocument</em></a> spreadsheets, as
+well as <a class="reference internal" href="glossary.html#term-xml"><em class="xref std std-term">XML</em></a>, <a class="reference internal" href="glossary.html#term-csv"><em class="xref std std-term">CSV</em></a>, and <a class="reference internal" href="glossary.html#term-sql"><em class="xref std std-term">SQL</em></a> files</li>
+<li>administer multiple servers</li>
+<li>manage MySQL users and privileges</li>
+<li>check referential integrity in MyISAM tables</li>
+<li>using Query-by-example (QBE), create complex queries automatically
+connecting required tables</li>
+<li>create <a class="reference internal" href="glossary.html#term-pdf"><em class="xref std std-term">PDF</em></a> graphics of your
+database layout</li>
+<li>search globally in a database or a subset of it</li>
+<li>transform stored data into any format using a set of predefined
+functions, like displaying BLOB-data as image or download-link</li>
+<li>track changes on databases, tables and views</li>
+<li>support InnoDB tables and foreign keys see <a class="reference internal" href="faq.html#faq3-6"><em>3.6 What is currently not supported in phpMyAdmin about InnoDB?</em></a></li>
+<li>support mysqli, the improved MySQL extension see <a class="reference internal" href="faq.html#faq1-17"><em>1.17 Which MySQL versions does phpMyAdmin support?</em></a></li>
+<li>create, edit, call, export and drop stored procedures and functions</li>
+<li>create, edit, export and drop events and triggers</li>
+<li>communicate in <a class="reference external" href="http://www.phpmyadmin.net/home_page/translations.php">62 different languages</a></li>
+</ul>
+</div>
+<div class="section" id="a-word-about-users">
+<h2>A word about users<a class="headerlink" href="#a-word-about-users" title="Permalink to this headline">¶</a></h2>
+<p>Many people have difficulty understanding the concept of user
+management with regards to phpMyAdmin. When a user logs in to
+phpMyAdmin, that username and password are passed directly to MySQL.
+phpMyAdmin does no account management on its own (other than allowing
+one to manipulate the MySQL user account information); all users must
+be valid MySQL users.</p>
+<p class="rubric">Footnotes</p>
+<table class="docutils footnote" frame="void" id="f1" rules="none">
+<colgroup><col class="label" /><col /></colgroup>
+<tbody valign="top">
+<tr><td class="label">[1]</td><td><em>(<a class="fn-backref" href="#id1">1</a>, <a class="fn-backref" href="#id2">2</a>)</em> phpMyAdmin can compress (<a class="reference internal" href="glossary.html#term-zip"><em class="xref std std-term">Zip</em></a>, <a class="reference internal" href="glossary.html#term-gzip"><em class="xref std std-term">GZip</em></a> <a class="reference internal" href="glossary.html#term-rfc-1952"><em class="xref std std-term">RFC 1952</em></a> or
+<a class="reference internal" href="glossary.html#term-bzip2"><em class="xref std std-term">Bzip2</em></a> formats) dumps and <a class="reference internal" href="glossary.html#term-csv"><em class="xref std std-term">CSV</em></a> exports if you use PHP with
+<a class="reference internal" href="glossary.html#term-zlib"><em class="xref std std-term">Zlib</em></a> support (<tt class="docutils literal"><span class="pre">--with-zlib</span></tt>) and/or <a class="reference internal" href="glossary.html#term-bzip2"><em class="xref std std-term">Bzip2</em></a> support
+(<tt class="docutils literal"><span class="pre">--with-bz2</span></tt>).  Proper support may also need changes in <tt class="file docutils literal"><span class="pre">php.ini</span></tt>.</td></tr>
+</tbody>
+</table>
+</div>
+</div>
+
+
+          </div>
+        </div>
+      </div>
+      <div class="sphinxsidebar">
+        <div class="sphinxsidebarwrapper">
+  <h3><a href="index.html">Table Of Contents</a></h3>
+  <ul>
+<li><a class="reference internal" href="#">Introduction</a><ul>
+<li><a class="reference internal" href="#supported-features">Supported features</a></li>
+<li><a class="reference internal" href="#a-word-about-users">A word about users</a></li>
+</ul>
+</li>
+</ul>
+
+  <h4>Previous topic</h4>
+  <p class="topless"><a href="index.html"
+                        title="previous chapter">Welcome to phpMyAdmin’s documentation!</a></p>
+  <h4>Next topic</h4>
+  <p class="topless"><a href="require.html"
+                        title="next chapter">Requirements</a></p>
+  <h3>This Page</h3>
+  <ul class="this-page-menu">
+    <li><a href="_sources/intro.txt"
+           rel="nofollow">Show Source</a></li>
+  </ul>
+<div id="searchbox" style="display: none">
+  <h3>Quick search</h3>
+    <form class="search" action="search.html" method="get">
+      <input type="text" name="q" />
+      <input type="submit" value="Go" />
+      <input type="hidden" name="check_keywords" value="yes" />
+      <input type="hidden" name="area" value="default" />
+    </form>
+    <p class="searchtip" style="font-size: 90%">
+    Enter search terms or a module, class or function name.
+    </p>
+</div>
+<script type="text/javascript">$('#searchbox').show(0);</script>
+        </div>
+      </div>
+      <div class="clearer"></div>
+    </div>
+    <div class="related">
+      <h3>Navigation</h3>
+      <ul>
+        <li class="right" style="margin-right: 10px">
+          <a href="genindex.html" title="General Index"
+             >index</a></li>
+        <li class="right" >
+          <a href="require.html" title="Requirements"
+             >next</a> |</li>
+        <li class="right" >
+          <a href="index.html" title="Welcome to phpMyAdmin’s documentation!"
+             >previous</a> |</li>
+        <li><a href="index.html">phpMyAdmin 4.0.4 documentation</a> »</li> 
+      </ul>
+    </div>
+    <div class="footer">
+        © <a href="copyright.html">Copyright</a> 2012 - 2013, The phpMyAdmin devel team.
+      Created using <a href="http://sphinx.pocoo.org/">Sphinx</a> 1.1.3.
+    </div>
+  </body>
+</html>
\ No newline at end of file
diff --git a/phpmyadmin/doc/html/objects.inv b/phpmyadmin/doc/html/objects.inv
new file mode 100644
index 0000000..5167891
Binary files /dev/null and b/phpmyadmin/doc/html/objects.inv differ
diff --git a/phpmyadmin/doc/html/other.html b/phpmyadmin/doc/html/other.html
new file mode 100644
index 0000000..9185e4b
--- /dev/null
+++ b/phpmyadmin/doc/html/other.html
@@ -0,0 +1,135 @@
+
+
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+
+
+<html xmlns="http://www.w3.org/1999/xhtml">
+  <head>
+    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+    
+    <title>Other sources of information — phpMyAdmin 4.0.4 documentation</title>
+    
+    <link rel="stylesheet" href="_static/default.css" type="text/css" />
+    <link rel="stylesheet" href="_static/pygments.css" type="text/css" />
+    
+    <script type="text/javascript">
+      var DOCUMENTATION_OPTIONS = {
+        URL_ROOT:    '',
+        VERSION:     '4.0.4',
+        COLLAPSE_INDEX: false,
+        FILE_SUFFIX: '.html',
+        HAS_SOURCE:  true
+      };
+    </script>
+    <script type="text/javascript" src="_static/jquery.js"></script>
+    <script type="text/javascript" src="_static/underscore.js"></script>
+    <script type="text/javascript" src="_static/doctools.js"></script>
+    <link rel="copyright" title="Copyright" href="copyright.html" />
+    <link rel="top" title="phpMyAdmin 4.0.4 documentation" href="index.html" />
+    <link rel="up" title="User Guide" href="user.html" />
+    <link rel="next" title="FAQ - Frequently Asked Questions" href="faq.html" />
+    <link rel="prev" title="User management" href="privileges.html" /> 
+  </head>
+  <body>
+    <div class="related">
+      <h3>Navigation</h3>
+      <ul>
+        <li class="right" style="margin-right: 10px">
+          <a href="genindex.html" title="General Index"
+             accesskey="I">index</a></li>
+        <li class="right" >
+          <a href="faq.html" title="FAQ - Frequently Asked Questions"
+             accesskey="N">next</a> |</li>
+        <li class="right" >
+          <a href="privileges.html" title="User management"
+             accesskey="P">previous</a> |</li>
+        <li><a href="index.html">phpMyAdmin 4.0.4 documentation</a> »</li>
+          <li><a href="user.html" accesskey="U">User Guide</a> »</li> 
+      </ul>
+    </div>  
+
+    <div class="document">
+      <div class="documentwrapper">
+        <div class="bodywrapper">
+          <div class="body">
+            
+  <div class="section" id="other-sources-of-information">
+<h1>Other sources of information<a class="headerlink" href="#other-sources-of-information" title="Permalink to this headline">¶</a></h1>
+<div class="section" id="printed-book">
+<h2>Printed Book<a class="headerlink" href="#printed-book" title="Permalink to this headline">¶</a></h2>
+<p>The definitive guide to using phpMyAdmin is the book Mastering phpMyAdmin for
+Effective MySQL Management by Marc Delisle. You can get information on that
+book and other officially endorsed <a class="reference external" href="http://www.phpmyadmin.net/home_page/docs.php?books">books at the phpMyAdmin site</a>.</p>
+</div>
+<div class="section" id="tutorials">
+<h2>Tutorials<a class="headerlink" href="#tutorials" title="Permalink to this headline">¶</a></h2>
+<p>Third party tutorials and articles are listed on our <a class="reference external" href="http://wiki.phpmyadmin.net/pma/Articles">wiki page</a>.</p>
+</div>
+</div>
+
+
+          </div>
+        </div>
+      </div>
+      <div class="sphinxsidebar">
+        <div class="sphinxsidebarwrapper">
+  <h3><a href="index.html">Table Of Contents</a></h3>
+  <ul>
+<li><a class="reference internal" href="#">Other sources of information</a><ul>
+<li><a class="reference internal" href="#printed-book">Printed Book</a></li>
+<li><a class="reference internal" href="#tutorials">Tutorials</a></li>
+</ul>
+</li>
+</ul>
+
+  <h4>Previous topic</h4>
+  <p class="topless"><a href="privileges.html"
+                        title="previous chapter">User management</a></p>
+  <h4>Next topic</h4>
+  <p class="topless"><a href="faq.html"
+                        title="next chapter">FAQ - Frequently Asked Questions</a></p>
+  <h3>This Page</h3>
+  <ul class="this-page-menu">
+    <li><a href="_sources/other.txt"
+           rel="nofollow">Show Source</a></li>
+  </ul>
+<div id="searchbox" style="display: none">
+  <h3>Quick search</h3>
+    <form class="search" action="search.html" method="get">
+      <input type="text" name="q" />
+      <input type="submit" value="Go" />
+      <input type="hidden" name="check_keywords" value="yes" />
+      <input type="hidden" name="area" value="default" />
+    </form>
+    <p class="searchtip" style="font-size: 90%">
+    Enter search terms or a module, class or function name.
+    </p>
+</div>
+<script type="text/javascript">$('#searchbox').show(0);</script>
+        </div>
+      </div>
+      <div class="clearer"></div>
+    </div>
+    <div class="related">
+      <h3>Navigation</h3>
+      <ul>
+        <li class="right" style="margin-right: 10px">
+          <a href="genindex.html" title="General Index"
+             >index</a></li>
+        <li class="right" >
+          <a href="faq.html" title="FAQ - Frequently Asked Questions"
+             >next</a> |</li>
+        <li class="right" >
+          <a href="privileges.html" title="User management"
+             >previous</a> |</li>
+        <li><a href="index.html">phpMyAdmin 4.0.4 documentation</a> »</li>
+          <li><a href="user.html" >User Guide</a> »</li> 
+      </ul>
+    </div>
+    <div class="footer">
+        © <a href="copyright.html">Copyright</a> 2012 - 2013, The phpMyAdmin devel team.
+      Created using <a href="http://sphinx.pocoo.org/">Sphinx</a> 1.1.3.
+    </div>
+  </body>
+</html>
\ No newline at end of file
diff --git a/phpmyadmin/doc/html/privileges.html b/phpmyadmin/doc/html/privileges.html
new file mode 100644
index 0000000..be20367
--- /dev/null
+++ b/phpmyadmin/doc/html/privileges.html
@@ -0,0 +1,169 @@
+
+
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+
+
+<html xmlns="http://www.w3.org/1999/xhtml">
+  <head>
+    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+    
+    <title>User management — phpMyAdmin 4.0.4 documentation</title>
+    
+    <link rel="stylesheet" href="_static/default.css" type="text/css" />
+    <link rel="stylesheet" href="_static/pygments.css" type="text/css" />
+    
+    <script type="text/javascript">
+      var DOCUMENTATION_OPTIONS = {
+        URL_ROOT:    '',
+        VERSION:     '4.0.4',
+        COLLAPSE_INDEX: false,
+        FILE_SUFFIX: '.html',
+        HAS_SOURCE:  true
+      };
+    </script>
+    <script type="text/javascript" src="_static/jquery.js"></script>
+    <script type="text/javascript" src="_static/underscore.js"></script>
+    <script type="text/javascript" src="_static/doctools.js"></script>
+    <link rel="copyright" title="Copyright" href="copyright.html" />
+    <link rel="top" title="phpMyAdmin 4.0.4 documentation" href="index.html" />
+    <link rel="up" title="User Guide" href="user.html" />
+    <link rel="next" title="Other sources of information" href="other.html" />
+    <link rel="prev" title="Transformations" href="transformations.html" /> 
+  </head>
+  <body>
+    <div class="related">
+      <h3>Navigation</h3>
+      <ul>
+        <li class="right" style="margin-right: 10px">
+          <a href="genindex.html" title="General Index"
+             accesskey="I">index</a></li>
+        <li class="right" >
+          <a href="other.html" title="Other sources of information"
+             accesskey="N">next</a> |</li>
+        <li class="right" >
+          <a href="transformations.html" title="Transformations"
+             accesskey="P">previous</a> |</li>
+        <li><a href="index.html">phpMyAdmin 4.0.4 documentation</a> »</li>
+          <li><a href="user.html" accesskey="U">User Guide</a> »</li> 
+      </ul>
+    </div>  
+
+    <div class="document">
+      <div class="documentwrapper">
+        <div class="bodywrapper">
+          <div class="body">
+            
+  <div class="section" id="user-management">
+<h1>User management<a class="headerlink" href="#user-management" title="Permalink to this headline">¶</a></h1>
+<p>User management is the process of controlling which users are allowed to
+connect to the MySQL server and what permissions they have on each database.
+phpMyAdmin does not handle user management, rather it passes the username and
+password on to MySQL, which then determines whether a user is permitted to
+perform a particular action. Within phpMyAdmin, administrators have full
+control over creating users, viewing and editing privileges for existing users,
+and removing users.</p>
+<p>Within phpMyAdmin, user management is controlled via the <em class="guilabel">Users</em> link
+from the main page. Users can be created, edited, and removed.</p>
+<div class="section" id="creating-a-new-user">
+<h2>Creating a new user<a class="headerlink" href="#creating-a-new-user" title="Permalink to this headline">¶</a></h2>
+<p>To create a new user, click the <em class="guilabel">Add a new user</em> link near the bottom
+of the <em class="guilabel">Users</em> page (you must be a “superuser”, e.g., user “root”).
+Use the textboxes and drop-downs to configure the user to your particular
+needs. You can then select whether to create a database for that user and grant
+specific global privileges. Once you’ve created the user (by clicking Go), you
+can define that user’s permissions on a specific database (don’t grant global
+privileges in that case). In general, users do not need any global privileges
+(other than USAGE), only permissions for their specific database.</p>
+</div>
+<div class="section" id="editing-an-existing-user">
+<h2>Editing an existing user<a class="headerlink" href="#editing-an-existing-user" title="Permalink to this headline">¶</a></h2>
+<p>To edit an existing user, simply click the pencil icon to the right of that
+user in the <em class="guilabel">Users</em> page. You can then edit their global- and
+database-specific privileges, change their password, or even copy those
+privileges to a new user.</p>
+</div>
+<div class="section" id="deleting-a-user">
+<h2>Deleting a user<a class="headerlink" href="#deleting-a-user" title="Permalink to this headline">¶</a></h2>
+<p>From the <em class="guilabel">Users</em> page, check the checkbox for the user you wish to
+remove, select whether or not to also remove any databases of the same name (if
+they exist), and click Go.</p>
+</div>
+<div class="section" id="assigning-privileges-to-user-for-a-specific-database">
+<h2>Assigning privileges to user for a specific database<a class="headerlink" href="#assigning-privileges-to-user-for-a-specific-database" title="Permalink to this headline">¶</a></h2>
+<p>Users are assigned to databases by editing the user record (from the
+<em class="guilabel">Users</em> link on the home page) not from within the <em class="guilabel">Users</em>
+link under the table. If you are creating a user specifically for a given table
+you will have to create the user first (with no global privileges) and then go
+back and edit that user to add the table and privileges for the individual
+table.</p>
+</div>
+</div>
+
+
+          </div>
+        </div>
+      </div>
+      <div class="sphinxsidebar">
+        <div class="sphinxsidebarwrapper">
+  <h3><a href="index.html">Table Of Contents</a></h3>
+  <ul>
+<li><a class="reference internal" href="#">User management</a><ul>
+<li><a class="reference internal" href="#creating-a-new-user">Creating a new user</a></li>
+<li><a class="reference internal" href="#editing-an-existing-user">Editing an existing user</a></li>
+<li><a class="reference internal" href="#deleting-a-user">Deleting a user</a></li>
+<li><a class="reference internal" href="#assigning-privileges-to-user-for-a-specific-database">Assigning privileges to user for a specific database</a></li>
+</ul>
+</li>
+</ul>
+
+  <h4>Previous topic</h4>
+  <p class="topless"><a href="transformations.html"
+                        title="previous chapter">Transformations</a></p>
+  <h4>Next topic</h4>
+  <p class="topless"><a href="other.html"
+                        title="next chapter">Other sources of information</a></p>
+  <h3>This Page</h3>
+  <ul class="this-page-menu">
+    <li><a href="_sources/privileges.txt"
+           rel="nofollow">Show Source</a></li>
+  </ul>
+<div id="searchbox" style="display: none">
+  <h3>Quick search</h3>
+    <form class="search" action="search.html" method="get">
+      <input type="text" name="q" />
+      <input type="submit" value="Go" />
+      <input type="hidden" name="check_keywords" value="yes" />
+      <input type="hidden" name="area" value="default" />
+    </form>
+    <p class="searchtip" style="font-size: 90%">
+    Enter search terms or a module, class or function name.
+    </p>
+</div>
+<script type="text/javascript">$('#searchbox').show(0);</script>
+        </div>
+      </div>
+      <div class="clearer"></div>
+    </div>
+    <div class="related">
+      <h3>Navigation</h3>
+      <ul>
+        <li class="right" style="margin-right: 10px">
+          <a href="genindex.html" title="General Index"
+             >index</a></li>
+        <li class="right" >
+          <a href="other.html" title="Other sources of information"
+             >next</a> |</li>
+        <li class="right" >
+          <a href="transformations.html" title="Transformations"
+             >previous</a> |</li>
+        <li><a href="index.html">phpMyAdmin 4.0.4 documentation</a> »</li>
+          <li><a href="user.html" >User Guide</a> »</li> 
+      </ul>
+    </div>
+    <div class="footer">
+        © <a href="copyright.html">Copyright</a> 2012 - 2013, The phpMyAdmin devel team.
+      Created using <a href="http://sphinx.pocoo.org/">Sphinx</a> 1.1.3.
+    </div>
+  </body>
+</html>
\ No newline at end of file
diff --git a/phpmyadmin/doc/html/require.html b/phpmyadmin/doc/html/require.html
new file mode 100644
index 0000000..b47afe5
--- /dev/null
+++ b/phpmyadmin/doc/html/require.html
@@ -0,0 +1,170 @@
+
+
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+
+
+<html xmlns="http://www.w3.org/1999/xhtml">
+  <head>
+    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+    
+    <title>Requirements — phpMyAdmin 4.0.4 documentation</title>
+    
+    <link rel="stylesheet" href="_static/default.css" type="text/css" />
+    <link rel="stylesheet" href="_static/pygments.css" type="text/css" />
+    
+    <script type="text/javascript">
+      var DOCUMENTATION_OPTIONS = {
+        URL_ROOT:    '',
+        VERSION:     '4.0.4',
+        COLLAPSE_INDEX: false,
+        FILE_SUFFIX: '.html',
+        HAS_SOURCE:  true
+      };
+    </script>
+    <script type="text/javascript" src="_static/jquery.js"></script>
+    <script type="text/javascript" src="_static/underscore.js"></script>
+    <script type="text/javascript" src="_static/doctools.js"></script>
+    <link rel="copyright" title="Copyright" href="copyright.html" />
+    <link rel="top" title="phpMyAdmin 4.0.4 documentation" href="index.html" />
+    <link rel="next" title="Installation" href="setup.html" />
+    <link rel="prev" title="Introduction" href="intro.html" /> 
+  </head>
+  <body>
+    <div class="related">
+      <h3>Navigation</h3>
+      <ul>
+        <li class="right" style="margin-right: 10px">
+          <a href="genindex.html" title="General Index"
+             accesskey="I">index</a></li>
+        <li class="right" >
+          <a href="setup.html" title="Installation"
+             accesskey="N">next</a> |</li>
+        <li class="right" >
+          <a href="intro.html" title="Introduction"
+             accesskey="P">previous</a> |</li>
+        <li><a href="index.html">phpMyAdmin 4.0.4 documentation</a> »</li> 
+      </ul>
+    </div>  
+
+    <div class="document">
+      <div class="documentwrapper">
+        <div class="bodywrapper">
+          <div class="body">
+            
+  <div class="section" id="requirements">
+<span id="require"></span><h1>Requirements<a class="headerlink" href="#requirements" title="Permalink to this headline">¶</a></h1>
+<div class="section" id="web-server">
+<h2>Web server<a class="headerlink" href="#web-server" title="Permalink to this headline">¶</a></h2>
+<p>Since, phpMyAdmin’s interface is based entirely in your browser, you’ll need a
+web server (such as Apache, <a class="reference internal" href="glossary.html#term-iis"><em class="xref std std-term">IIS</em></a>) to install phpMyAdmin’s files into.</p>
+</div>
+<div class="section" id="php">
+<h2>PHP<a class="headerlink" href="#php" title="Permalink to this headline">¶</a></h2>
+<ul class="simple">
+<li>You need PHP 5.2.0 or newer, with <tt class="docutils literal"><span class="pre">session</span></tt> support, the Standard PHP Library
+(SPL) extension and JSON support.</li>
+<li>To support uploading of ZIP files, you need the PHP <tt class="docutils literal"><span class="pre">zip</span></tt> extension.</li>
+<li>For proper support of multibyte strings (eg. UTF-8, which is currently
+the default), you should install the <tt class="docutils literal"><span class="pre">mbstring</span></tt> and <tt class="docutils literal"><span class="pre">ctype</span></tt> extensions.</li>
+<li>You need GD2 support in PHP to display inline thumbnails of JPEGs
+(“image/jpeg: inline”) with their original aspect ratio.</li>
+<li>When using the cookie authentication (the default), the <a class="reference external" href="http://www.php.net/mcrypt">mcrypt</a> extension is strongly suggested for most
+users and is <strong>required</strong> for 64–bit machines. Not using mcrypt will
+cause phpMyAdmin to load pages significantly slower.</li>
+<li>To support upload progress bars, see <a class="reference internal" href="faq.html#faq2-9"><em>2.9 Seeing an upload progress bar</em></a>.</li>
+<li>To support XML and Open Document Spreadsheet importing, you need PHP
+5.2.17 or newer and the <a class="reference external" href="http://www.php.net/libxml">libxml</a>
+extension.</li>
+</ul>
+<div class="admonition-see-also admonition seealso">
+<p class="first admonition-title">See also</p>
+<p class="last"><a class="reference internal" href="faq.html#faq1-31"><em>1.31 Does phpMyAdmin support PHP 5?</em></a>, <a class="reference internal" href="setup.html#authentication-modes"><em>Using authentication modes</em></a></p>
+</div>
+</div>
+<div class="section" id="database">
+<h2>Database<a class="headerlink" href="#database" title="Permalink to this headline">¶</a></h2>
+<p>phpMyAdmin support MySQL compatible databases.</p>
+<ul class="simple">
+<li>MySQL 5.0 or newer</li>
+<li>MariaDB 5.0 or newer</li>
+<li>Drizzle</li>
+</ul>
+<div class="admonition-see-also admonition seealso">
+<p class="first admonition-title">See also</p>
+<p class="last"><a class="reference internal" href="faq.html#faq1-17"><em>1.17 Which MySQL versions does phpMyAdmin support?</em></a></p>
+</div>
+</div>
+<div class="section" id="web-browser">
+<h2>Web browser<a class="headerlink" href="#web-browser" title="Permalink to this headline">¶</a></h2>
+<p>To access phpMyAdmin you need a web browser with cookies and javascript
+enabled.</p>
+</div>
+</div>
+
+
+          </div>
+        </div>
+      </div>
+      <div class="sphinxsidebar">
+        <div class="sphinxsidebarwrapper">
+  <h3><a href="index.html">Table Of Contents</a></h3>
+  <ul>
+<li><a class="reference internal" href="#">Requirements</a><ul>
+<li><a class="reference internal" href="#web-server">Web server</a></li>
+<li><a class="reference internal" href="#php">PHP</a></li>
+<li><a class="reference internal" href="#database">Database</a></li>
+<li><a class="reference internal" href="#web-browser">Web browser</a></li>
+</ul>
+</li>
+</ul>
+
+  <h4>Previous topic</h4>
+  <p class="topless"><a href="intro.html"
+                        title="previous chapter">Introduction</a></p>
+  <h4>Next topic</h4>
+  <p class="topless"><a href="setup.html"
+                        title="next chapter">Installation</a></p>
+  <h3>This Page</h3>
+  <ul class="this-page-menu">
+    <li><a href="_sources/require.txt"
+           rel="nofollow">Show Source</a></li>
+  </ul>
+<div id="searchbox" style="display: none">
+  <h3>Quick search</h3>
+    <form class="search" action="search.html" method="get">
+      <input type="text" name="q" />
+      <input type="submit" value="Go" />
+      <input type="hidden" name="check_keywords" value="yes" />
+      <input type="hidden" name="area" value="default" />
+    </form>
+    <p class="searchtip" style="font-size: 90%">
+    Enter search terms or a module, class or function name.
+    </p>
+</div>
+<script type="text/javascript">$('#searchbox').show(0);</script>
+        </div>
+      </div>
+      <div class="clearer"></div>
+    </div>
+    <div class="related">
+      <h3>Navigation</h3>
+      <ul>
+        <li class="right" style="margin-right: 10px">
+          <a href="genindex.html" title="General Index"
+             >index</a></li>
+        <li class="right" >
+          <a href="setup.html" title="Installation"
+             >next</a> |</li>
+        <li class="right" >
+          <a href="intro.html" title="Introduction"
+             >previous</a> |</li>
+        <li><a href="index.html">phpMyAdmin 4.0.4 documentation</a> »</li> 
+      </ul>
+    </div>
+    <div class="footer">
+        © <a href="copyright.html">Copyright</a> 2012 - 2013, The phpMyAdmin devel team.
+      Created using <a href="http://sphinx.pocoo.org/">Sphinx</a> 1.1.3.
+    </div>
+  </body>
+</html>
\ No newline at end of file
diff --git a/phpmyadmin/doc/html/search.html b/phpmyadmin/doc/html/search.html
new file mode 100644
index 0000000..83caa39
--- /dev/null
+++ b/phpmyadmin/doc/html/search.html
@@ -0,0 +1,100 @@
+
+
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+
+
+<html xmlns="http://www.w3.org/1999/xhtml">
+  <head>
+    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+    
+    <title>Search — phpMyAdmin 4.0.4 documentation</title>
+    
+    <link rel="stylesheet" href="_static/default.css" type="text/css" />
+    <link rel="stylesheet" href="_static/pygments.css" type="text/css" />
+    
+    <script type="text/javascript">
+      var DOCUMENTATION_OPTIONS = {
+        URL_ROOT:    '',
+        VERSION:     '4.0.4',
+        COLLAPSE_INDEX: false,
+        FILE_SUFFIX: '.html',
+        HAS_SOURCE:  true
+      };
+    </script>
+    <script type="text/javascript" src="_static/jquery.js"></script>
+    <script type="text/javascript" src="_static/underscore.js"></script>
+    <script type="text/javascript" src="_static/doctools.js"></script>
+    <script type="text/javascript" src="_static/searchtools.js"></script>
+    <link rel="copyright" title="Copyright" href="copyright.html" />
+    <link rel="top" title="phpMyAdmin 4.0.4 documentation" href="index.html" />
+  <script type="text/javascript">
+    jQuery(function() { Search.loadIndex("searchindex.js"); });
+  </script>
+   
+
+  </head>
+  <body>
+    <div class="related">
+      <h3>Navigation</h3>
+      <ul>
+        <li class="right" style="margin-right: 10px">
+          <a href="genindex.html" title="General Index"
+             accesskey="I">index</a></li>
+        <li><a href="index.html">phpMyAdmin 4.0.4 documentation</a> »</li> 
+      </ul>
+    </div>  
+
+    <div class="document">
+      <div class="documentwrapper">
+        <div class="bodywrapper">
+          <div class="body">
+            
+  <h1 id="search-documentation">Search</h1>
+  <div id="fallback" class="admonition warning">
+  <script type="text/javascript">$('#fallback').hide();</script>
+  <p>
+    Please activate JavaScript to enable the search
+    functionality.
+  </p>
+  </div>
+  <p>
+    From here you can search these documents. Enter your search
+    words into the box below and click "search". Note that the search
+    function will automatically search for all of the words. Pages
+    containing fewer words won't appear in the result list.
+  </p>
+  <form action="" method="get">
+    <input type="text" name="q" value="" />
+    <input type="submit" value="search" />
+    <span id="search-progress" style="padding-left: 10px"></span>
+  </form>
+  
+  <div id="search-results">
+  
+  </div>
+
+          </div>
+        </div>
+      </div>
+      <div class="sphinxsidebar">
+        <div class="sphinxsidebarwrapper">
+        </div>
+      </div>
+      <div class="clearer"></div>
+    </div>
+    <div class="related">
+      <h3>Navigation</h3>
+      <ul>
+        <li class="right" style="margin-right: 10px">
+          <a href="genindex.html" title="General Index"
+             >index</a></li>
+        <li><a href="index.html">phpMyAdmin 4.0.4 documentation</a> »</li> 
+      </ul>
+    </div>
+    <div class="footer">
+        © <a href="copyright.html">Copyright</a> 2012 - 2013, The phpMyAdmin devel team.
+      Created using <a href="http://sphinx.pocoo.org/">Sphinx</a> 1.1.3.
+    </div>
+  </body>
+</html>
\ No newline at end of file
diff --git a/phpmyadmin/doc/html/searchindex.js b/phpmyadmin/doc/html/searchindex.js
new file mode 100644
index 0000000..c4dfde2
--- /dev/null
+++ b/phpmyadmin/doc/html/searchindex.js
@@ -0,0 +1 @@
+Search.setIndex({objects:{"":{"$cfg['ExecTimeLimit']":[13,0,1,"cfg_ExecTimeLimit"],"$cfg['Servers'][$i]['SignonURL']":[13,0,1,"cfg_Servers_SignonURL"],"$cfg['UploadDir']":[13,0,1,"cfg_UploadDir"],"$cfg['Servers'][$i]['socket']":[13,0,1,"cfg_Servers_socket"],"$cfg['SkipLockedTables']":[13,0,1,"cfg_SkipLockedTables"],"$cfg['Servers'][$i]['AllowRoot']":[13,0,1,"cfg_Servers_AllowRoot"],"$cfg['Servers'][$i]['AllowDeny']['order']":[13,0,1,"cfg_Servers_AllowDeny_order"],"$cfg['GZipDump']":[13,0 [...]
\ No newline at end of file
diff --git a/phpmyadmin/doc/html/setup.html b/phpmyadmin/doc/html/setup.html
new file mode 100644
index 0000000..aec2ae1
--- /dev/null
+++ b/phpmyadmin/doc/html/setup.html
@@ -0,0 +1,481 @@
+
+
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+
+
+<html xmlns="http://www.w3.org/1999/xhtml">
+  <head>
+    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+    
+    <title>Installation — phpMyAdmin 4.0.4 documentation</title>
+    
+    <link rel="stylesheet" href="_static/default.css" type="text/css" />
+    <link rel="stylesheet" href="_static/pygments.css" type="text/css" />
+    
+    <script type="text/javascript">
+      var DOCUMENTATION_OPTIONS = {
+        URL_ROOT:    '',
+        VERSION:     '4.0.4',
+        COLLAPSE_INDEX: false,
+        FILE_SUFFIX: '.html',
+        HAS_SOURCE:  true
+      };
+    </script>
+    <script type="text/javascript" src="_static/jquery.js"></script>
+    <script type="text/javascript" src="_static/underscore.js"></script>
+    <script type="text/javascript" src="_static/doctools.js"></script>
+    <link rel="copyright" title="Copyright" href="copyright.html" />
+    <link rel="top" title="phpMyAdmin 4.0.4 documentation" href="index.html" />
+    <link rel="next" title="Configuration" href="config.html" />
+    <link rel="prev" title="Requirements" href="require.html" /> 
+  </head>
+  <body>
+    <div class="related">
+      <h3>Navigation</h3>
+      <ul>
+        <li class="right" style="margin-right: 10px">
+          <a href="genindex.html" title="General Index"
+             accesskey="I">index</a></li>
+        <li class="right" >
+          <a href="config.html" title="Configuration"
+             accesskey="N">next</a> |</li>
+        <li class="right" >
+          <a href="require.html" title="Requirements"
+             accesskey="P">previous</a> |</li>
+        <li><a href="index.html">phpMyAdmin 4.0.4 documentation</a> »</li> 
+      </ul>
+    </div>  
+
+    <div class="document">
+      <div class="documentwrapper">
+        <div class="bodywrapper">
+          <div class="body">
+            
+  <div class="section" id="installation">
+<span id="setup"></span><h1>Installation<a class="headerlink" href="#installation" title="Permalink to this headline">¶</a></h1>
+<p>phpMyAdmin does not apply any special security methods to the MySQL
+database server. It is still the system administrator’s job to grant
+permissions on the MySQL databases properly. phpMyAdmin’s <em class="guilabel">Users</em>
+page can be used for this.</p>
+<div class="admonition warning">
+<p class="first admonition-title">Warning</p>
+<p class="last"><a class="reference internal" href="glossary.html#term-mac"><em class="xref std std-term">Mac</em></a> users should note that if you are on a version before
+<a class="reference internal" href="glossary.html#term-mac-os-x"><em class="xref std std-term">Mac OS X</em></a>, StuffIt unstuffs with <a class="reference internal" href="glossary.html#term-mac"><em class="xref std std-term">Mac</em></a> formats. So you’ll have
+to resave as in BBEdit to Unix style ALL phpMyAdmin scripts before
+uploading them to your server, as PHP seems not to like <a class="reference internal" href="glossary.html#term-mac"><em class="xref std std-term">Mac</em></a>-style
+end of lines character (“<tt class="docutils literal"><span class="pre">\r</span></tt>”).</p>
+</div>
+<div class="section" id="quick-install">
+<span id="id1"></span><h2>Quick Install<a class="headerlink" href="#quick-install" title="Permalink to this headline">¶</a></h2>
+<ol class="arabic simple">
+<li>Choose an appropriate distribution kit from the phpmyadmin.net
+Downloads page. Some kits contain only the English messages, others
+contain all languages. We’ll assume you chose a kit whose name
+looks like <tt class="docutils literal"><span class="pre">phpMyAdmin-x.x.x</span> <span class="pre">-all-languages.tar.gz</span></tt>.</li>
+<li>Untar or unzip the distribution (be sure to unzip the subdirectories):
+<tt class="docutils literal"><span class="pre">tar</span> <span class="pre">-xzvf</span> <span class="pre">phpMyAdmin_x.x.x-all-languages.tar.gz</span></tt> in your
+webserver’s document root. If you don’t have direct access to your
+document root, put the files in a directory on your local machine,
+and, after step 4, transfer the directory on your web server using,
+for example, ftp.</li>
+<li>Ensure that all the scripts have the appropriate owner (if PHP is
+running in safe mode, having some scripts with an owner different from
+the owner of other scripts will be a problem). See <a class="reference internal" href="faq.html#faq4-2"><em>4.2 What’s the preferred way of making phpMyAdmin secure against evil access?</em></a> and
+<a class="reference internal" href="faq.html#faq1-26"><em>1.26 I just installed phpMyAdmin in my document root of IIS but I get the error “No input file specified” when trying to run phpMyAdmin.</em></a> for suggestions.</li>
+<li>Now you must configure your installation. There are two methods that
+can be used. Traditionally, users have hand-edited a copy of
+<tt class="file docutils literal"><span class="pre">config.inc.php</span></tt>, but now a wizard-style setup script is provided
+for those who prefer a graphical installation. Creating a
+<tt class="file docutils literal"><span class="pre">config.inc.php</span></tt> is still a quick way to get started and needed for
+some advanced features.</li>
+</ol>
+<div class="section" id="manualy-creating-file">
+<h3>Manualy creating file<a class="headerlink" href="#manualy-creating-file" title="Permalink to this headline">¶</a></h3>
+<p>To manually create the file, simply use your text editor to create the
+file <tt class="file docutils literal"><span class="pre">config.inc.php</span></tt> (you can copy <tt class="file docutils literal"><span class="pre">config.sample.inc.php</span></tt> to get
+minimal configuration file) in the main (top-level) phpMyAdmin
+directory (the one that contains <tt class="file docutils literal"><span class="pre">index.php</span></tt>). phpMyAdmin first
+loads <tt class="file docutils literal"><span class="pre">libraries/config.default.php</span></tt> and then overrides those values
+with anything found in <tt class="file docutils literal"><span class="pre">config.inc.php</span></tt>. If the default value is
+okay for a particular setting, there is no need to include it in
+<tt class="file docutils literal"><span class="pre">config.inc.php</span></tt>. You’ll need a few directives to get going, a
+simple configuration may look like this:</p>
+<div class="highlight-php"><div class="highlight"><pre><span class="cp"><?php</span>
+<span class="nv">$cfg</span><span class="p">[</span><span class="s1">'blowfish_secret'</span><span class="p">]</span> <span class="o">=</span> <span class="s1">'ba17c1ec07d65003'</span><span class="p">;</span>  <span class="c1">// use here a value of your choice</span>
+
+<span class="nv">$i</span><span class="o">=</span><span class="mi">0</span><span class="p">;</span>
+<span class="nv">$i</span><span class="o">++</span><span class="p">;</span>
+<span class="nv">$cfg</span><span class="p">[</span><span class="s1">'Servers'</span><span class="p">][</span><span class="nv">$i</span><span class="p">][</span><span class="s1">'auth_type'</span><span class="p">]</span>     <span class="o">=</span> <span class="s1">'cookie'</span><span class="p">;</span>
+<span class="cp">?></span><span class="x"></span>
+</pre></div>
+</div>
+<p>Or, if you prefer to not be prompted every time you log in:</p>
+<div class="highlight-php"><div class="highlight"><pre><span class="cp"><?php</span>
+
+<span class="nv">$i</span><span class="o">=</span><span class="mi">0</span><span class="p">;</span>
+<span class="nv">$i</span><span class="o">++</span><span class="p">;</span>
+<span class="nv">$cfg</span><span class="p">[</span><span class="s1">'Servers'</span><span class="p">][</span><span class="nv">$i</span><span class="p">][</span><span class="s1">'user'</span><span class="p">]</span>          <span class="o">=</span> <span class="s1">'root'</span><span class="p">;</span>
+<span class="nv">$cfg</span><span class="p">[</span><span class="s1">'Servers'</span><span class="p">][</span><span class="nv">$i</span><span class="p">][</span><span class="s1">'password'</span><span class="p">]</span>      <span class="o">=</span> <span class="s1">'cbb74bc'</span><span class="p">;</span> <span class="c1">// use here your password</span>
+<span class="nv">$cfg</span><span class="p">[</span><span class="s1">'Servers'</span><span class="p">][</span><span class="nv">$i</span><span class="p">][</span><span class="s1">'auth_type'</span><span class="p">]</span>     <span class="o">=</span> <span class="s1">'config'</span><span class="p">;</span>
+<span class="cp">?></span><span class="x"></span>
+</pre></div>
+</div>
+<p>For a full explanation of possible configuration values, see the
+<a class="reference internal" href="config.html#config"><em>Configuration</em></a> of this document.</p>
+</div>
+<div class="section" id="using-setup-script">
+<span id="setup-script"></span><span id="index-0"></span><h3>Using Setup script<a class="headerlink" href="#using-setup-script" title="Permalink to this headline">¶</a></h3>
+<p>Instead of manually editing <tt class="file docutils literal"><span class="pre">config.inc.php</span></tt>, you can use the <a class="reference external" href="setup/">Setup
+Script</a>. First you must manually create a folder <tt class="docutils literal"><span class="pre">config</span></tt>
+in the phpMyAdmin directory. This is a security measure. On a
+Linux/Unix system you can use the following commands:</p>
+<div class="highlight-sh"><div class="highlight"><pre><span class="nb">cd </span>phpMyAdmin
+mkdir config                        <span class="c"># create directory for saving</span>
+chmod o+rw config                   <span class="c"># give it world writable permissions</span>
+</pre></div>
+</div>
+<p>And to edit an existing configuration, copy it over first:</p>
+<div class="highlight-sh"><div class="highlight"><pre>cp config.inc.php config/           <span class="c"># copy current configuration for editing</span>
+chmod o+w config/config.inc.php     <span class="c"># give it world writable permissions</span>
+</pre></div>
+</div>
+<p>On other platforms, simply create the folder and ensure that your web
+server has read and write access to it. <a class="reference internal" href="faq.html#faq1-26"><em>1.26 I just installed phpMyAdmin in my document root of IIS but I get the error “No input file specified” when trying to run phpMyAdmin.</em></a> can help with
+this.</p>
+<p>Next, open <tt class="docutils literal"><span class="pre">setup/</span></tt> in your browser. Note that <strong>changes are
+not saved to disk until explicitly choose ``Save``</strong> from the
+<em>Configuration</em> area of the screen. Normally the script saves the new
+<tt class="file docutils literal"><span class="pre">config.inc.php</span></tt> to the <tt class="docutils literal"><span class="pre">config/</span></tt> directory, but if the webserver does
+not have the proper permissions you may see the error “Cannot load or
+save configuration.” Ensure that the <tt class="docutils literal"><span class="pre">config/</span></tt> directory exists and
+has the proper permissions - or use the <tt class="docutils literal"><span class="pre">Download</span></tt> link to save the
+config file locally and upload (via FTP or some similar means) to the
+proper location.</p>
+<p>Once the file has been saved, it must be moved out of the <tt class="docutils literal"><span class="pre">config/</span></tt>
+directory and the permissions must be reset, again as a security
+measure:</p>
+<div class="highlight-sh"><div class="highlight"><pre>mv config/config.inc.php .         <span class="c"># move file to current directory</span>
+chmod o-rw config.inc.php          <span class="c"># remove world read and write permissions</span>
+rm -rf config                      <span class="c"># remove not needed directory</span>
+</pre></div>
+</div>
+<p>Now the file is ready to be used. You can choose to review or edit the
+file with your favorite editor, if you prefer to set some advanced
+options which the setup script does not provide.</p>
+<ol class="arabic simple">
+<li>If you are using the <tt class="docutils literal"><span class="pre">auth_type</span></tt> “config”, it is suggested that you
+protect the phpMyAdmin installation directory because using config
+does not require a user to enter a password to access the phpMyAdmin
+installation. Use of an alternate authentication method is
+recommended, for example with HTTP–AUTH in a <a class="reference internal" href="glossary.html#term-htaccess"><em class="xref std std-term">.htaccess</em></a> file or switch to using
+<tt class="docutils literal"><span class="pre">auth_type</span></tt> cookie or http. See the <a class="reference internal" href="faq.html#faqmultiuser"><em>ISPs, multi-user installations</em></a>
+for additional information, especially <a class="reference internal" href="faq.html#faq4-4"><em>4.4 phpMyAdmin always gives “Access denied” when using HTTP authentication.</em></a>.</li>
+<li>Open the <a class="reference external" href="index.php">main phpMyAdmin directory</a> in your browser.
+phpMyAdmin should now display a welcome screen and your databases, or
+a login dialog if using <a class="reference internal" href="glossary.html#term-http"><em class="xref std std-term">HTTP</em></a> or
+cookie authentication mode.</li>
+<li>You should deny access to the <tt class="docutils literal"><span class="pre">./libraries</span></tt> and <tt class="docutils literal"><span class="pre">./setup/lib</span></tt>
+subfolders in your webserver configuration. For Apache you can use
+supplied <a class="reference internal" href="glossary.html#term-htaccess"><em class="xref std std-term">.htaccess</em></a>  file in that folder, for other webservers, you should
+configure this yourself. Such configuration prevents from possible
+path exposure and cross side scripting vulnerabilities that might
+happen to be found in that code.</li>
+<li>It is generally good idea to protect public phpMyAdmin installation
+against access by robots as they usually can not do anything good
+there. You can do this using <tt class="docutils literal"><span class="pre">robots.txt</span></tt> file in root of your
+webserver or limit access by web server configuration, see
+<a class="reference internal" href="faq.html#faq1-42"><em>1.42 How can I prevent robots from accessing phpMyAdmin?</em></a>.</li>
+</ol>
+</div>
+</div>
+<div class="section" id="phpmyadmin-configuration-storage">
+<span id="linked-tables"></span><span id="index-1"></span><h2>phpMyAdmin configuration storage<a class="headerlink" href="#phpmyadmin-configuration-storage" title="Permalink to this headline">¶</a></h2>
+<p>For a whole set of new features (bookmarks, comments, <a class="reference internal" href="glossary.html#term-sql"><em class="xref std std-term">SQL</em></a>-history,
+tracking mechanism, <a class="reference internal" href="glossary.html#term-pdf"><em class="xref std std-term">PDF</em></a>-generation, column contents transformation,
+etc.) you need to create a set of special tables.  Those tables can be located
+in your own database, or in a central database for a multi-user installation
+(this database would then be accessed by the controluser, so no other user
+should have rights to it).</p>
+<p>Please look at your <tt class="docutils literal"><span class="pre">./examples/</span></tt> directory, where you should find a
+file called <em>create_tables.sql</em>. (If you are using a Windows server,
+pay special attention to <a class="reference internal" href="faq.html#faq1-23"><em>1.23 I’m running MySQL on a Win32 machine. Each time I create a new table the table and column names are changed to lowercase!</em></a>).</p>
+<p>If you already had this infrastructure and upgraded to MySQL 4.1.2 or
+newer, please use <tt class="file docutils literal"><span class="pre">examples/upgrade_tables_mysql_4_1_2+.sql</span></tt>
+and then create new tables by importing
+<tt class="file docutils literal"><span class="pre">examples/create_tables.sql</span></tt>.</p>
+<p>You can use your phpMyAdmin to create the tables for you. Please be
+aware that you may need special (administrator) privileges to create
+the database and tables, and that the script may need some tuning,
+depending on the database name.</p>
+<p>After having imported the <tt class="file docutils literal"><span class="pre">examples/create_tables.sql</span></tt> file, you
+should specify the table names in your <tt class="file docutils literal"><span class="pre">config.inc.php</span></tt> file. The
+directives used for that can be found in the <a class="reference internal" href="config.html#config"><em>Configuration</em></a>. You will also need to
+have a controluser with the proper rights to those tables (see section
+<a class="reference internal" href="#authentication-modes"><em>Using authentication modes</em></a> below).</p>
+</div>
+<div class="section" id="upgrading-from-an-older-version">
+<span id="upgrading"></span><h2>Upgrading from an older version<a class="headerlink" href="#upgrading-from-an-older-version" title="Permalink to this headline">¶</a></h2>
+<p>Simply copy <tt class="file docutils literal"><span class="pre">config.inc.php</span></tt> from your previous installation into
+the newly unpacked one. Configuration files from old versions may
+require some tweaking as some options have been changed or removed.
+For compatibility with PHP 6, remove a
+<tt class="docutils literal"><span class="pre">set_magic_quotes_runtime(0);</span></tt> statement that you might find near
+the end of your configuration file.</p>
+<p>You should <strong>not</strong> copy <tt class="file docutils literal"><span class="pre">libraries/config.default.php</span></tt> over
+<tt class="file docutils literal"><span class="pre">config.inc.php</span></tt> because the default configuration file is version-
+specific.</p>
+<p>If you have upgraded your MySQL server from a version previous to 4.1.2 to
+version 5.x or newer and if you use the phpMyAdmin configuration storage, you
+should run the <a class="reference internal" href="glossary.html#term-sql"><em class="xref std std-term">SQL</em></a> script found in
+<tt class="file docutils literal"><span class="pre">examples/upgrade_tables_mysql_4_1_2+.sql</span></tt>.</p>
+</div>
+<div class="section" id="using-authentication-modes">
+<span id="authentication-modes"></span><span id="index-2"></span><h2>Using authentication modes<a class="headerlink" href="#using-authentication-modes" title="Permalink to this headline">¶</a></h2>
+<p><a class="reference internal" href="glossary.html#term-http"><em class="xref std std-term">HTTP</em></a> and cookie authentication modes are recommended in a <strong>multi-user
+environment</strong> where you want to give users access to their own database and
+don’t want them to play around with others. Nevertheless be aware that MS
+Internet Explorer seems to be really buggy about cookies, at least till version
+6. Even in a <strong>single-user environment</strong>, you might prefer to use <a class="reference internal" href="glossary.html#term-http"><em class="xref std std-term">HTTP</em></a>
+or cookie mode so that your user/password pair are not in clear in the
+configuration file.</p>
+<p><a class="reference internal" href="glossary.html#term-http"><em class="xref std std-term">HTTP</em></a> and cookie authentication
+modes are more secure: the MySQL login information does not need to be
+set in the phpMyAdmin configuration file (except possibly for the
+<span class="target" id="index-3"></span><a class="reference internal" href="config.html#cfg_Servers_controluser"><tt class="xref config config-option docutils literal"><span class="pre">$cfg['Servers'][$i]['controluser']</span></tt></a>).
+However, keep in mind that the password travels in plain text, unless
+you are using the HTTPS protocol. In cookie mode, the password is
+stored, encrypted with the blowfish algorithm, in a temporary cookie.</p>
+<p>For ‘<a class="reference internal" href="glossary.html#term-http"><em class="xref std std-term">HTTP</em></a>‘ and ‘cookie’ modes, phpMyAdmin needs a controluser that has
+<strong>only</strong> the <tt class="docutils literal"><span class="pre">SELECT</span></tt> privilege on the <em>`mysql`.`user` (all columns except
+`Password`)</em>, <em>`mysql`.`db` (all columns)</em>, <em>`mysql`.`host` (all columns)</em> and
+<em>`mysql`.`tables_priv` (all columns except `Grantor` and `Timestamp`)</em> tables.
+You must specify the details for the controluser in the <tt class="file docutils literal"><span class="pre">config.inc.php</span></tt>
+file under the <span class="target" id="index-4"></span><a class="reference internal" href="config.html#cfg_Servers_controluser"><tt class="xref config config-option docutils literal"><span class="pre">$cfg['Servers'][$i]['controluser']</span></tt></a> and
+<span class="target" id="index-5"></span><a class="reference internal" href="config.html#cfg_Servers_controlpass"><tt class="xref config config-option docutils literal"><span class="pre">$cfg['Servers'][$i]['controlpass']</span></tt></a> settings. The following
+example assumes you want to use <tt class="docutils literal"><span class="pre">pma</span></tt> as the controluser and <tt class="docutils literal"><span class="pre">pmapass</span></tt> as
+the controlpass, but <strong>this is only an example: use something else in your
+file!</strong> Input these statements from the phpMyAdmin <a class="reference internal" href="glossary.html#term-sql"><em class="xref std std-term">SQL</em></a> Query window or
+mysql command–line client. Of course you have to replace <tt class="docutils literal"><span class="pre">localhost</span></tt> with the
+webserver’s host if it’s not the same as the MySQL server’s one.</p>
+<p>If you want to use the many new relation and bookmark features:  (this of
+course requires that your <a class="reference internal" href="#linked-tables"><em>phpMyAdmin configuration storage</em></a> be set up).</p>
+<div class="highlight-mysql"><div class="highlight"><pre><span class="k">GRANT</span> <span class="k">USAGE</span> <span class="k">ON</span> <span class="n">mysql</span><span class="p">.</span><span class="o">*</span> <span class="k">TO</span> <span class="s1">'pma'</span><span class="o">@</span><span class="s1">'localhost'</span> <span class="n">IDENTIFIED</span> <span class="k">BY</span> <span class="s1">'pmapass'</span><span class="p">;</span>
+<span class="k">GRANT</span> <span class="k">SELECT</span> <span class="p">(</span>
+<span class="n">Host</span><span class="p">,</span> <span class="n">User</span><span class="p">,</span> <span class="n">Select_priv</span><span class="p">,</span> <span class="n">Insert_priv</span><span class="p">,</span> <span class="n">Update_priv</span><span class="p">,</span> <span class="n">Delete_priv</span><span class="p">,</span>
+<span class="n">Create_priv</span><span class="p">,</span> <span class="n">Drop_priv</span><span class="p">,</span> <span class="n">Reload_priv</span><span class="p">,</span> <span class="n">Shutdown_priv</span><span class="p">,</span> <span class="n">Process_priv</span><span class="p">,</span>
+<span class="n">File_priv</span><span class="p">,</span> <span class="n">Grant_priv</span><span class="p">,</span> <span class="n">References_priv</span><span class="p">,</span> <span class="n">Index_priv</span><span class="p">,</span> <span class="n">Alter_priv</span><span class="p">,</span>
+<span class="n">Show_db_priv</span><span class="p">,</span> <span class="n">Super_priv</span><span class="p">,</span> <span class="n">Create_tmp_table_priv</span><span class="p">,</span> <span class="n">Lock_tables_priv</span><span class="p">,</span>
+<span class="n">Execute_priv</span><span class="p">,</span> <span class="n">Repl_slave_priv</span><span class="p">,</span> <span class="n">Repl_client_priv</span>
+<span class="p">)</span> <span class="k">ON</span> <span class="n">mysql</span><span class="p">.</span><span class="n">user</span> <span class="k">TO</span> <span class="s1">'pma'</span><span class="o">@</span><span class="s1">'localhost'</span><span class="p">;</span>
+<span class="k">GRANT</span> <span class="k">SELECT</span> <span class="k">ON</span> <span class="n">mysql</span><span class="p">.</span><span class="n">db</span> <span class="k">TO</span> <span class="s1">'pma'</span><span class="o">@</span><span class="s1">'localhost'</span><span class="p">;</span>
+<span class="k">GRANT</span> <span class="k">SELECT</span> <span class="k">ON</span> <span class="n">mysql</span><span class="p">.</span><span class="n">host</span> <span class="k">TO</span> <span class="s1">'pma'</span><span class="o">@</span><span class="s1">'localhost'</span><span class="p">;</span>
+<span class="k">GRANT</span> <span class="k">SELECT</span> <span class="p">(</span><span class="n">Host</span><span class="p">,</span> <span class="n">Db</span><span class="p">,</span> <span class="n">User</span><span class="p">,</span> <span class="n">Table_name</span><span class="p">,</span> <span class="n">Table_priv</span><span class="p">,</span> <span class="n">Column_priv</span><span class="p">)</span>
+<span class="k">ON</span> <span class="n">mysql</span><span class="p">.</span><span class="n">tables_priv</span> <span class="k">TO</span> <span class="s1">'pma'</span><span class="o">@</span><span class="s1">'localhost'</span><span class="p">;</span>
+</pre></div>
+</div>
+<p>If you want to use the many new relation and bookmark features:</p>
+<div class="highlight-mysql"><div class="highlight"><pre><span class="k">GRANT</span> <span class="k">SELECT</span><span class="p">,</span> <span class="k">INSERT</span><span class="p">,</span> <span class="k">UPDATE</span><span class="p">,</span> <span class="k">DELETE</span> <span class="k">ON</span> <span class="o"><</span><span class="n">pma_db</span><span class="o">></span><span class="p">.</span><span class="o">*</span> <span class="k">TO</span> <span class="s1">'pma' [...]
+</pre></div>
+</div>
+<p>(this of course requires that your phpMyAdmin
+configuration storage be set up).</p>
+<p>Then each of the <em>true</em> users should be granted a set of privileges
+on a set of particular databases. Normally you shouldn’t give global
+privileges to an ordinary user, unless you understand the impact of those
+privileges (for example, you are creating a superuser).
+For example, to grant the user <em>real_user</em> with all privileges on
+the database <em>user_base</em>:</p>
+<div class="highlight-mysql"><div class="highlight"><pre><span class="k">GRANT</span> <span class="k">ALL</span> <span class="n">PRIVILEGES</span> <span class="k">ON</span> <span class="n">user_base</span><span class="p">.</span><span class="o">*</span> <span class="k">TO</span> <span class="s1">'real_user'</span><span class="o">@</span><span class="n">localhost</span> <span class="n">IDENTIFIED</span> <span class="k">BY</span> <span class="s1">'real_password'</span><span [...]
+</pre></div>
+</div>
+<p>What the user may now do is controlled entirely by the MySQL user management
+system. With HTTP or cookie authentication mode, you don’t need to fill the
+user/password fields inside the <span class="target" id="index-6"></span><a class="reference internal" href="config.html#cfg_Servers"><tt class="xref config config-option docutils literal"><span class="pre">$cfg['Servers']</span></tt></a>.</p>
+<div class="section" id="http-authentication-mode">
+<span id="index-7"></span><h3>HTTP authentication mode<a class="headerlink" href="#http-authentication-mode" title="Permalink to this headline">¶</a></h3>
+<ul class="simple">
+<li>Uses <a class="reference internal" href="glossary.html#term-http"><em class="xref std std-term">HTTP</em></a> Basic authentication
+method and allows you to log in as any valid MySQL user.</li>
+<li>Is supported with most PHP configurations. For <a class="reference internal" href="glossary.html#term-iis"><em class="xref std std-term">IIS</em></a> (<a class="reference internal" href="glossary.html#term-isapi"><em class="xref std std-term">ISAPI</em></a>)
+support using <a class="reference internal" href="glossary.html#term-cgi"><em class="xref std std-term">CGI</em></a> PHP see <a class="reference internal" href="faq.html#faq1-32"><em>1.32 Can I use HTTP authentication with IIS?</em></a>, for using with Apache
+<a class="reference internal" href="glossary.html#term-cgi"><em class="xref std std-term">CGI</em></a> see <a class="reference internal" href="faq.html#faq1-35"><em>1.35 Can I use HTTP authentication with Apache CGI?</em></a>.</li>
+<li>See also <a class="reference internal" href="faq.html#faq4-4"><em>4.4 phpMyAdmin always gives “Access denied” when using HTTP authentication.</em></a> about not using the <a class="reference internal" href="glossary.html#term-htaccess"><em class="xref std std-term">.htaccess</em></a> mechanism along with
+‘<a class="reference internal" href="glossary.html#term-http"><em class="xref std std-term">HTTP</em></a>‘ authentication mode.</li>
+</ul>
+</div>
+<div class="section" id="cookie-authentication-mode">
+<span id="cookie"></span><span id="index-8"></span><h3>Cookie authentication mode<a class="headerlink" href="#cookie-authentication-mode" title="Permalink to this headline">¶</a></h3>
+<ul class="simple">
+<li>You can use this method as a replacement for the <a class="reference internal" href="glossary.html#term-http"><em class="xref std std-term">HTTP</em></a> authentication
+(for example, if you’re running <a class="reference internal" href="glossary.html#term-iis"><em class="xref std std-term">IIS</em></a>).</li>
+<li>Obviously, the user must enable cookies in the browser, but this is
+now a requirement for all authentication modes.</li>
+<li>With this mode, the user can truly log out of phpMyAdmin and log in
+back with the same username.</li>
+<li>If you want to log in to arbitrary server see <span class="target" id="index-9"></span><a class="reference internal" href="config.html#cfg_AllowArbitraryServer"><tt class="xref config config-option docutils literal"><span class="pre">$cfg['AllowArbitraryServer']</span></tt></a> directive.</li>
+<li>As mentioned in the <a class="reference internal" href="require.html#require"><em>Requirements</em></a> section, having the <tt class="docutils literal"><span class="pre">mcrypt</span></tt> extension will
+speed up access considerably, but is not required.</li>
+</ul>
+</div>
+<div class="section" id="signon-authentication-mode">
+<span id="index-10"></span><h3>Signon authentication mode<a class="headerlink" href="#signon-authentication-mode" title="Permalink to this headline">¶</a></h3>
+<ul class="simple">
+<li>This mode is a convenient way of using credentials from another
+application to authenticate to phpMyAdmin.</li>
+<li>The other application has to store login information into session
+data.</li>
+</ul>
+<div class="admonition-see-also admonition seealso">
+<p class="first admonition-title">See also</p>
+<p class="last"><span class="target" id="index-11"></span><a class="reference internal" href="config.html#cfg_Servers_auth_type"><tt class="xref config config-option docutils literal"><span class="pre">$cfg['Servers'][$i]['auth_type']</span></tt></a>,
+<span class="target" id="index-12"></span><a class="reference internal" href="config.html#cfg_Servers_SignonSession"><tt class="xref config config-option docutils literal"><span class="pre">$cfg['Servers'][$i]['SignonSession']</span></tt></a>,
+<span class="target" id="index-13"></span><a class="reference internal" href="config.html#cfg_Servers_SignonScript"><tt class="xref config config-option docutils literal"><span class="pre">$cfg['Servers'][$i]['SignonScript']</span></tt></a>,
+<span class="target" id="index-14"></span><a class="reference internal" href="config.html#cfg_Servers_SignonURL"><tt class="xref config config-option docutils literal"><span class="pre">$cfg['Servers'][$i]['SignonURL']</span></tt></a></p>
+</div>
+</div>
+<div class="section" id="config-authentication-mode">
+<span id="index-15"></span><h3>Config authentication mode<a class="headerlink" href="#config-authentication-mode" title="Permalink to this headline">¶</a></h3>
+<ul class="simple">
+<li>This mode is the less secure one because it requires you to fill the
+<span class="target" id="index-16"></span><a class="reference internal" href="config.html#cfg_Servers_user"><tt class="xref config config-option docutils literal"><span class="pre">$cfg['Servers'][$i]['user']</span></tt></a> and
+<span class="target" id="index-17"></span><a class="reference internal" href="config.html#cfg_Servers_password"><tt class="xref config config-option docutils literal"><span class="pre">$cfg['Servers'][$i]['password']</span></tt></a>
+fields (and as a result, anyone who can read your <tt class="file docutils literal"><span class="pre">config.inc.php</span></tt>
+can discover your username and password).  But you don’t need to setup
+a “controluser” here: using the <span class="target" id="index-18"></span><a class="reference internal" href="config.html#cfg_Servers_only_db"><tt class="xref config config-option docutils literal"><span class="pre">$cfg['Servers'][$i]['only_db']</span></tt></a> might be enough.</li>
+<li>In the <a class="reference internal" href="faq.html#faqmultiuser"><em>ISPs, multi-user installations</em></a> section, there is an entry explaining how
+to protect your configuration file.</li>
+<li>For additional security in this mode, you may wish to consider the
+Host authentication <span class="target" id="index-19"></span><a class="reference internal" href="config.html#cfg_Servers_AllowDeny_order"><tt class="xref config config-option docutils literal"><span class="pre">$cfg['Servers'][$i]['AllowDeny']['order']</span></tt></a>
+and <span class="target" id="index-20"></span><a class="reference internal" href="config.html#cfg_Servers_AllowDeny_rules"><tt class="xref config config-option docutils literal"><span class="pre">$cfg['Servers'][$i]['AllowDeny']['rules']</span></tt></a> configuration directives.</li>
+<li>Unlike cookie and http, does not require a user to log in when first
+loading the phpMyAdmin site. This is by design but could allow any
+user to access your installation. Use of some restriction method is
+suggested, perhaps a <a class="reference internal" href="glossary.html#term-htaccess"><em class="xref std std-term">.htaccess</em></a> file with the HTTP-AUTH directive or disallowing
+incoming HTTP requests at one’s router or firewall will suffice (both
+of which are beyond the scope of this manual but easily searchable
+with Google).</li>
+</ul>
+</div>
+<div class="section" id="swekey-authentication-mode">
+<span id="swekey"></span><span id="index-21"></span><h3>Swekey authentication mode<a class="headerlink" href="#swekey-authentication-mode" title="Permalink to this headline">¶</a></h3>
+<p>The Swekey is a low cost authentication USB key that can be used in
+web applications. When Swekey authentication is activated, phpMyAdmin
+requires the users’s Swekey to be plugged before entering the login
+page (currently supported for cookie authentication mode only). Swekey
+Authentication is disabled by default. To enable it, add the following
+line to <tt class="file docutils literal"><span class="pre">config.inc.php</span></tt>:</p>
+<div class="highlight-php"><div class="highlight"><pre><span class="x">$cfg['Servers'][$i]['auth_swekey_config'] = '/etc/swekey.conf';</span>
+</pre></div>
+</div>
+<p>You then have to create the <tt class="docutils literal"><span class="pre">swekey.conf</span></tt> file that will associate
+each user with their Swekey Id. It is important to place this file
+outside of your web server’s document root (in the example, it is
+located in <tt class="docutils literal"><span class="pre">/etc</span></tt>). A self documented sample file is provided in the
+<tt class="docutils literal"><span class="pre">examples</span></tt> directory. Feel free to use it with your own users’
+information. If you want to purchase a Swekey please visit
+<a class="reference external" href="http://phpmyadmin.net/auth_key">http://phpmyadmin.net/auth_key</a>
+since this link provides funding for phpMyAdmin.</p>
+<div class="admonition-see-also admonition seealso">
+<p class="first admonition-title">See also</p>
+<p class="last"><span class="target" id="index-22"></span><a class="reference internal" href="config.html#cfg_Servers_auth_swekey_config"><tt class="xref config config-option docutils literal"><span class="pre">$cfg['Servers'][$i]['auth_swekey_config']</span></tt></a></p>
+</div>
+</div>
+</div>
+<div class="section" id="securing-your-phpmyadmin-installation">
+<h2>Securing your phpMyAdmin installation<a class="headerlink" href="#securing-your-phpmyadmin-installation" title="Permalink to this headline">¶</a></h2>
+<p>The phpMyAdmin team tries hardly to make the application secure, however there
+are always ways to make your installation more secure:</p>
+<ul class="simple">
+<li>remove <tt class="docutils literal"><span class="pre">setup</span></tt> directory from phpMyAdmin, you will probably not
+use it after initial setup</li>
+<li>prevent access to <tt class="docutils literal"><span class="pre">libraries</span></tt> directory from browser,
+as it is not needed, supplied <tt class="docutils literal"><span class="pre">.htaccess</span></tt> file does this</li>
+<li>properly choose authentication method - <a class="reference internal" href="#cookie"><em>Cookie authentication mode</em></a>
+is probably the best choice for shared hosting</li>
+<li>in case you don’t want all MySQL users to be able to access
+phpMyAdmin, you can use <span class="target" id="index-23"></span><a class="reference internal" href="config.html#cfg_Servers_AllowDeny_rules"><tt class="xref config config-option docutils literal"><span class="pre">$cfg['Servers'][$i]['AllowDeny']['rules']</span></tt></a> to limit them</li>
+<li>consider hiding phpMyAdmin behind authentication proxy, so that
+MySQL credentials are not all users need to login</li>
+</ul>
+</div>
+</div>
+
+
+          </div>
+        </div>
+      </div>
+      <div class="sphinxsidebar">
+        <div class="sphinxsidebarwrapper">
+  <h3><a href="index.html">Table Of Contents</a></h3>
+  <ul>
+<li><a class="reference internal" href="#">Installation</a><ul>
+<li><a class="reference internal" href="#quick-install">Quick Install</a><ul>
+<li><a class="reference internal" href="#manualy-creating-file">Manualy creating file</a></li>
+<li><a class="reference internal" href="#using-setup-script">Using Setup script</a></li>
+</ul>
+</li>
+<li><a class="reference internal" href="#phpmyadmin-configuration-storage">phpMyAdmin configuration storage</a></li>
+<li><a class="reference internal" href="#upgrading-from-an-older-version">Upgrading from an older version</a></li>
+<li><a class="reference internal" href="#using-authentication-modes">Using authentication modes</a><ul>
+<li><a class="reference internal" href="#http-authentication-mode">HTTP authentication mode</a></li>
+<li><a class="reference internal" href="#cookie-authentication-mode">Cookie authentication mode</a></li>
+<li><a class="reference internal" href="#signon-authentication-mode">Signon authentication mode</a></li>
+<li><a class="reference internal" href="#config-authentication-mode">Config authentication mode</a></li>
+<li><a class="reference internal" href="#swekey-authentication-mode">Swekey authentication mode</a></li>
+</ul>
+</li>
+<li><a class="reference internal" href="#securing-your-phpmyadmin-installation">Securing your phpMyAdmin installation</a></li>
+</ul>
+</li>
+</ul>
+
+  <h4>Previous topic</h4>
+  <p class="topless"><a href="require.html"
+                        title="previous chapter">Requirements</a></p>
+  <h4>Next topic</h4>
+  <p class="topless"><a href="config.html"
+                        title="next chapter">Configuration</a></p>
+  <h3>This Page</h3>
+  <ul class="this-page-menu">
+    <li><a href="_sources/setup.txt"
+           rel="nofollow">Show Source</a></li>
+  </ul>
+<div id="searchbox" style="display: none">
+  <h3>Quick search</h3>
+    <form class="search" action="search.html" method="get">
+      <input type="text" name="q" />
+      <input type="submit" value="Go" />
+      <input type="hidden" name="check_keywords" value="yes" />
+      <input type="hidden" name="area" value="default" />
+    </form>
+    <p class="searchtip" style="font-size: 90%">
+    Enter search terms or a module, class or function name.
+    </p>
+</div>
+<script type="text/javascript">$('#searchbox').show(0);</script>
+        </div>
+      </div>
+      <div class="clearer"></div>
+    </div>
+    <div class="related">
+      <h3>Navigation</h3>
+      <ul>
+        <li class="right" style="margin-right: 10px">
+          <a href="genindex.html" title="General Index"
+             >index</a></li>
+        <li class="right" >
+          <a href="config.html" title="Configuration"
+             >next</a> |</li>
+        <li class="right" >
+          <a href="require.html" title="Requirements"
+             >previous</a> |</li>
+        <li><a href="index.html">phpMyAdmin 4.0.4 documentation</a> »</li> 
+      </ul>
+    </div>
+    <div class="footer">
+        © <a href="copyright.html">Copyright</a> 2012 - 2013, The phpMyAdmin devel team.
+      Created using <a href="http://sphinx.pocoo.org/">Sphinx</a> 1.1.3.
+    </div>
+  </body>
+</html>
\ No newline at end of file
diff --git a/phpmyadmin/doc/html/transformations.html b/phpmyadmin/doc/html/transformations.html
new file mode 100644
index 0000000..887884e
--- /dev/null
+++ b/phpmyadmin/doc/html/transformations.html
@@ -0,0 +1,240 @@
+
+
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+
+
+<html xmlns="http://www.w3.org/1999/xhtml">
+  <head>
+    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+    
+    <title>Transformations — phpMyAdmin 4.0.4 documentation</title>
+    
+    <link rel="stylesheet" href="_static/default.css" type="text/css" />
+    <link rel="stylesheet" href="_static/pygments.css" type="text/css" />
+    
+    <script type="text/javascript">
+      var DOCUMENTATION_OPTIONS = {
+        URL_ROOT:    '',
+        VERSION:     '4.0.4',
+        COLLAPSE_INDEX: false,
+        FILE_SUFFIX: '.html',
+        HAS_SOURCE:  true
+      };
+    </script>
+    <script type="text/javascript" src="_static/jquery.js"></script>
+    <script type="text/javascript" src="_static/underscore.js"></script>
+    <script type="text/javascript" src="_static/doctools.js"></script>
+    <link rel="copyright" title="Copyright" href="copyright.html" />
+    <link rel="top" title="phpMyAdmin 4.0.4 documentation" href="index.html" />
+    <link rel="up" title="User Guide" href="user.html" />
+    <link rel="next" title="User management" href="privileges.html" />
+    <link rel="prev" title="User Guide" href="user.html" /> 
+  </head>
+  <body>
+    <div class="related">
+      <h3>Navigation</h3>
+      <ul>
+        <li class="right" style="margin-right: 10px">
+          <a href="genindex.html" title="General Index"
+             accesskey="I">index</a></li>
+        <li class="right" >
+          <a href="privileges.html" title="User management"
+             accesskey="N">next</a> |</li>
+        <li class="right" >
+          <a href="user.html" title="User Guide"
+             accesskey="P">previous</a> |</li>
+        <li><a href="index.html">phpMyAdmin 4.0.4 documentation</a> »</li>
+          <li><a href="user.html" accesskey="U">User Guide</a> »</li> 
+      </ul>
+    </div>  
+
+    <div class="document">
+      <div class="documentwrapper">
+        <div class="bodywrapper">
+          <div class="body">
+            
+  <div class="section" id="transformations">
+<span id="id1"></span><h1>Transformations<a class="headerlink" href="#transformations" title="Permalink to this headline">¶</a></h1>
+<div class="section" id="introduction">
+<span id="transformationsintro"></span><h2>Introduction<a class="headerlink" href="#introduction" title="Permalink to this headline">¶</a></h2>
+<p>To enable transformations, you have to setup the <tt class="docutils literal"><span class="pre">column_info</span></tt>
+table and the proper directives. Please see the <a class="reference internal" href="config.html#config"><em>Configuration</em></a> on how to do so.</p>
+<p>You can apply different transformations to the contents of each
+column. The transformation will take the content of each column and
+transform it with certain rules defined in the selected
+transformation.</p>
+<p>Say you have a column ‘filename’ which contains a filename. Normally
+you would see in phpMyAdmin only this filename. Using transformations
+you can transform that filename into a HTML link, so you can click
+inside of the phpMyAdmin structure on the column’s link and will see
+the file displayed in a new browser window. Using transformation
+options you can also specify strings to append/prepend to a string or
+the format you want the output stored in.</p>
+<p>For a general overview of all available transformations and their
+options, you can consult your <em><www.your-host.com>/<your-install-
+dir>/transformation_overview.php</em> installation.</p>
+<p>For a tutorial on how to effectively use transformations, see our
+<a class="reference external" href="http://www.phpmyadmin.net/home_page/docs.php">Link section</a> on the
+official phpMyAdmin homepage.</p>
+</div>
+<div class="section" id="usage">
+<span id="transformationshowto"></span><h2>Usage<a class="headerlink" href="#usage" title="Permalink to this headline">¶</a></h2>
+<p>Go to your <em>tbl_structure.php</em> page (i.e. reached through clicking on
+the ‘Structure’ link for a table). There click on “Change” (or change
+icon) and there you will see three new fields at the end of the line.
+They are called ‘MIME-type’, ‘Browser transformation’ and
+‘Transformation options’.</p>
+<ul class="simple">
+<li>The field ‘MIME-type’ is a drop-down field. Select the MIME-type that
+corresponds to the column’s contents. Please note that transformations
+are inactive as long as no MIME-type is selected.</li>
+<li>The field ‘Browser transformation’ is a drop-down field. You can
+choose from a hopefully growing amount of pre-defined transformations.
+See below for information on how to build your own transformation.
+There are global transformations and mimetype-bound transformations.
+Global transformations can be used for any mimetype. They will take
+the mimetype, if necessary, into regard. Mimetype-bound
+transformations usually only operate on a certain mimetype. There are
+transformations which operate on the main mimetype (like ‘image’),
+which will most likely take the subtype into regard, and those who
+only operate on a specific subtype (like ‘image/jpeg’). You can use
+transformations on mimetypes for which the function was not defined
+for. There is no security check for you selected the right
+transformation, so take care of what the output will be like.</li>
+<li>The field ‘Transformation options’ is a free-type textfield. You have
+to enter transform-function specific options here. Usually the
+transforms can operate with default options, but it is generally a
+good idea to look up the overview to see which options are necessary.
+Much like the ENUM/SET-Fields, you have to split up several options
+using the format ‘a’,’b’,’c’,...(NOTE THE MISSING BLANKS). This is
+because internally the options will be parsed as an array, leaving the
+first value the first element in the array, and so forth. If you want
+to specify a MIME character set you can define it in the
+transformation_options. You have to put that outside of the pre-
+defined options of the specific mime-transform, as the last value of
+the set. Use the format “’; charset=XXX’”. If you use a transform, for
+which you can specify 2 options and you want to append a character
+set, enter “‘first parameter’,’second parameter’,’charset=us-ascii’”.
+You can, however use the defaults for the parameters: “’‘,’‘,’charset
+=us-ascii’”.</li>
+</ul>
+</div>
+<div class="section" id="file-structure">
+<span id="transformationsfiles"></span><h2>File structure<a class="headerlink" href="#file-structure" title="Permalink to this headline">¶</a></h2>
+<p>All specific transformations for mimetypes are defined through class
+files in the directory ‘libraries/plugins/transformations/’. Each of
+them extends a certain transformation abstract class declared in
+libraries/plugins/transformations/abstract.</p>
+<p>They are stored in files to ease up customization and easy adding of
+new transformations.</p>
+<p>Because the user cannot enter own mimetypes, it is kept sure that
+transformations always work. It makes no sense to apply a
+transformation to a mimetype the transform-function doesn’t know to
+handle.</p>
+<p>There is a file called ‘<em>transformations.lib.php</em>‘ that provides some
+basic functions which can be included by any other transform function.</p>
+<p>The file name convention is <tt class="docutils literal"><span class="pre">[Mimetype]_[Subtype]_[Transformation</span>
+<span class="pre">Name].class.php</span></tt>, while the abtract class that it extends has the
+name <tt class="docutils literal"><span class="pre">[Transformation</span> <span class="pre">Name]TransformationsPlugin</span></tt>. All of the
+methods that have to be implemented by a transformations plug-in are:</p>
+<ol class="arabic simple">
+<li>getMIMEType() and getMIMESubtype() in the main class;</li>
+<li>getName(), getInfo() and applyTransformation() in the abstract class
+it extends.</li>
+</ol>
+<p>The getMIMEType(), getMIMESubtype() and getName() methods return the
+name of the MIME type, MIME Subtype and transformation accordingly.
+getInfo() returns the transformation’s description and possible
+options it may receive and applyTransformation() is the method that
+does the actual work of the transformation plug-in.</p>
+<p>Please see the libraries/plugins/transformations/TEMPLATE and
+libraries/plugins/transformations/TEMPLATE_ABSTRACT files for adding
+your own transformation plug-in. You can also generate a new
+transformation plug-in (with or without the abstract transformation
+class), by using
+<tt class="file docutils literal"><span class="pre">libraries/plugins/transformations/generator_plugin.sh</span></tt> or
+<tt class="file docutils literal"><span class="pre">libraries/plugins/transformations/generator_main_class.sh</span></tt>.</p>
+<p>The applyTransformation() method always gets passed three variables:</p>
+<ol class="arabic simple">
+<li><strong>$buffer</strong> - Contains the text inside of the column. This is the
+text, you want to transform.</li>
+<li><strong>$options</strong> - Contains any user-passed options to a transform
+function as an array.</li>
+<li><strong>$meta</strong> - Contains an object with information about your column. The
+data is drawn from the output of the <a class="reference external" href="http://www.php.net/mysql_fetch_field">mysql_fetch_field()</a> function. This means, all
+object properties described on the <a class="reference external" href="http://www.php.net/mysql_fetch_field">manual page</a> are available in this
+variable and can be used to transform a column accordingly to
+unsigned/zerofill/not_null/... properties. The $meta->mimetype
+variable contains the original MIME-type of the column (i.e.
+‘text/plain’, ‘image/jpeg’ etc.)</li>
+</ol>
+</div>
+</div>
+
+
+          </div>
+        </div>
+      </div>
+      <div class="sphinxsidebar">
+        <div class="sphinxsidebarwrapper">
+  <h3><a href="index.html">Table Of Contents</a></h3>
+  <ul>
+<li><a class="reference internal" href="#">Transformations</a><ul>
+<li><a class="reference internal" href="#introduction">Introduction</a></li>
+<li><a class="reference internal" href="#usage">Usage</a></li>
+<li><a class="reference internal" href="#file-structure">File structure</a></li>
+</ul>
+</li>
+</ul>
+
+  <h4>Previous topic</h4>
+  <p class="topless"><a href="user.html"
+                        title="previous chapter">User Guide</a></p>
+  <h4>Next topic</h4>
+  <p class="topless"><a href="privileges.html"
+                        title="next chapter">User management</a></p>
+  <h3>This Page</h3>
+  <ul class="this-page-menu">
+    <li><a href="_sources/transformations.txt"
+           rel="nofollow">Show Source</a></li>
+  </ul>
+<div id="searchbox" style="display: none">
+  <h3>Quick search</h3>
+    <form class="search" action="search.html" method="get">
+      <input type="text" name="q" />
+      <input type="submit" value="Go" />
+      <input type="hidden" name="check_keywords" value="yes" />
+      <input type="hidden" name="area" value="default" />
+    </form>
+    <p class="searchtip" style="font-size: 90%">
+    Enter search terms or a module, class or function name.
+    </p>
+</div>
+<script type="text/javascript">$('#searchbox').show(0);</script>
+        </div>
+      </div>
+      <div class="clearer"></div>
+    </div>
+    <div class="related">
+      <h3>Navigation</h3>
+      <ul>
+        <li class="right" style="margin-right: 10px">
+          <a href="genindex.html" title="General Index"
+             >index</a></li>
+        <li class="right" >
+          <a href="privileges.html" title="User management"
+             >next</a> |</li>
+        <li class="right" >
+          <a href="user.html" title="User Guide"
+             >previous</a> |</li>
+        <li><a href="index.html">phpMyAdmin 4.0.4 documentation</a> »</li>
+          <li><a href="user.html" >User Guide</a> »</li> 
+      </ul>
+    </div>
+    <div class="footer">
+        © <a href="copyright.html">Copyright</a> 2012 - 2013, The phpMyAdmin devel team.
+      Created using <a href="http://sphinx.pocoo.org/">Sphinx</a> 1.1.3.
+    </div>
+  </body>
+</html>
\ No newline at end of file
diff --git a/phpmyadmin/doc/html/user.html b/phpmyadmin/doc/html/user.html
new file mode 100644
index 0000000..8af33c0
--- /dev/null
+++ b/phpmyadmin/doc/html/user.html
@@ -0,0 +1,135 @@
+
+
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+
+
+<html xmlns="http://www.w3.org/1999/xhtml">
+  <head>
+    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+    
+    <title>User Guide — phpMyAdmin 4.0.4 documentation</title>
+    
+    <link rel="stylesheet" href="_static/default.css" type="text/css" />
+    <link rel="stylesheet" href="_static/pygments.css" type="text/css" />
+    
+    <script type="text/javascript">
+      var DOCUMENTATION_OPTIONS = {
+        URL_ROOT:    '',
+        VERSION:     '4.0.4',
+        COLLAPSE_INDEX: false,
+        FILE_SUFFIX: '.html',
+        HAS_SOURCE:  true
+      };
+    </script>
+    <script type="text/javascript" src="_static/jquery.js"></script>
+    <script type="text/javascript" src="_static/underscore.js"></script>
+    <script type="text/javascript" src="_static/doctools.js"></script>
+    <link rel="copyright" title="Copyright" href="copyright.html" />
+    <link rel="top" title="phpMyAdmin 4.0.4 documentation" href="index.html" />
+    <link rel="next" title="Transformations" href="transformations.html" />
+    <link rel="prev" title="Configuration" href="config.html" /> 
+  </head>
+  <body>
+    <div class="related">
+      <h3>Navigation</h3>
+      <ul>
+        <li class="right" style="margin-right: 10px">
+          <a href="genindex.html" title="General Index"
+             accesskey="I">index</a></li>
+        <li class="right" >
+          <a href="transformations.html" title="Transformations"
+             accesskey="N">next</a> |</li>
+        <li class="right" >
+          <a href="config.html" title="Configuration"
+             accesskey="P">previous</a> |</li>
+        <li><a href="index.html">phpMyAdmin 4.0.4 documentation</a> »</li> 
+      </ul>
+    </div>  
+
+    <div class="document">
+      <div class="documentwrapper">
+        <div class="bodywrapper">
+          <div class="body">
+            
+  <div class="section" id="user-guide">
+<h1>User Guide<a class="headerlink" href="#user-guide" title="Permalink to this headline">¶</a></h1>
+<div class="toctree-wrapper compound">
+<ul>
+<li class="toctree-l1"><a class="reference internal" href="transformations.html">Transformations</a><ul>
+<li class="toctree-l2"><a class="reference internal" href="transformations.html#introduction">Introduction</a></li>
+<li class="toctree-l2"><a class="reference internal" href="transformations.html#usage">Usage</a></li>
+<li class="toctree-l2"><a class="reference internal" href="transformations.html#file-structure">File structure</a></li>
+</ul>
+</li>
+<li class="toctree-l1"><a class="reference internal" href="privileges.html">User management</a><ul>
+<li class="toctree-l2"><a class="reference internal" href="privileges.html#creating-a-new-user">Creating a new user</a></li>
+<li class="toctree-l2"><a class="reference internal" href="privileges.html#editing-an-existing-user">Editing an existing user</a></li>
+<li class="toctree-l2"><a class="reference internal" href="privileges.html#deleting-a-user">Deleting a user</a></li>
+<li class="toctree-l2"><a class="reference internal" href="privileges.html#assigning-privileges-to-user-for-a-specific-database">Assigning privileges to user for a specific database</a></li>
+</ul>
+</li>
+<li class="toctree-l1"><a class="reference internal" href="other.html">Other sources of information</a><ul>
+<li class="toctree-l2"><a class="reference internal" href="other.html#printed-book">Printed Book</a></li>
+<li class="toctree-l2"><a class="reference internal" href="other.html#tutorials">Tutorials</a></li>
+</ul>
+</li>
+</ul>
+</div>
+</div>
+
+
+          </div>
+        </div>
+      </div>
+      <div class="sphinxsidebar">
+        <div class="sphinxsidebarwrapper">
+  <h4>Previous topic</h4>
+  <p class="topless"><a href="config.html"
+                        title="previous chapter">Configuration</a></p>
+  <h4>Next topic</h4>
+  <p class="topless"><a href="transformations.html"
+                        title="next chapter">Transformations</a></p>
+  <h3>This Page</h3>
+  <ul class="this-page-menu">
+    <li><a href="_sources/user.txt"
+           rel="nofollow">Show Source</a></li>
+  </ul>
+<div id="searchbox" style="display: none">
+  <h3>Quick search</h3>
+    <form class="search" action="search.html" method="get">
+      <input type="text" name="q" />
+      <input type="submit" value="Go" />
+      <input type="hidden" name="check_keywords" value="yes" />
+      <input type="hidden" name="area" value="default" />
+    </form>
+    <p class="searchtip" style="font-size: 90%">
+    Enter search terms or a module, class or function name.
+    </p>
+</div>
+<script type="text/javascript">$('#searchbox').show(0);</script>
+        </div>
+      </div>
+      <div class="clearer"></div>
+    </div>
+    <div class="related">
+      <h3>Navigation</h3>
+      <ul>
+        <li class="right" style="margin-right: 10px">
+          <a href="genindex.html" title="General Index"
+             >index</a></li>
+        <li class="right" >
+          <a href="transformations.html" title="Transformations"
+             >next</a> |</li>
+        <li class="right" >
+          <a href="config.html" title="Configuration"
+             >previous</a> |</li>
+        <li><a href="index.html">phpMyAdmin 4.0.4 documentation</a> »</li> 
+      </ul>
+    </div>
+    <div class="footer">
+        © <a href="copyright.html">Copyright</a> 2012 - 2013, The phpMyAdmin devel team.
+      Created using <a href="http://sphinx.pocoo.org/">Sphinx</a> 1.1.3.
+    </div>
+  </body>
+</html>
\ No newline at end of file
diff --git a/phpmyadmin/doc/html/vendors.html b/phpmyadmin/doc/html/vendors.html
new file mode 100644
index 0000000..a54f81d
--- /dev/null
+++ b/phpmyadmin/doc/html/vendors.html
@@ -0,0 +1,147 @@
+
+
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+
+
+<html xmlns="http://www.w3.org/1999/xhtml">
+  <head>
+    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+    
+    <title>Distributing and packaging phpMyAdmin — phpMyAdmin 4.0.4 documentation</title>
+    
+    <link rel="stylesheet" href="_static/default.css" type="text/css" />
+    <link rel="stylesheet" href="_static/pygments.css" type="text/css" />
+    
+    <script type="text/javascript">
+      var DOCUMENTATION_OPTIONS = {
+        URL_ROOT:    '',
+        VERSION:     '4.0.4',
+        COLLAPSE_INDEX: false,
+        FILE_SUFFIX: '.html',
+        HAS_SOURCE:  true
+      };
+    </script>
+    <script type="text/javascript" src="_static/jquery.js"></script>
+    <script type="text/javascript" src="_static/underscore.js"></script>
+    <script type="text/javascript" src="_static/doctools.js"></script>
+    <link rel="copyright" title="Copyright" href="copyright.html" />
+    <link rel="top" title="phpMyAdmin 4.0.4 documentation" href="index.html" />
+    <link rel="next" title="Copyright" href="copyright.html" />
+    <link rel="prev" title="Developers Information" href="developers.html" /> 
+  </head>
+  <body>
+    <div class="related">
+      <h3>Navigation</h3>
+      <ul>
+        <li class="right" style="margin-right: 10px">
+          <a href="genindex.html" title="General Index"
+             accesskey="I">index</a></li>
+        <li class="right" >
+          <a href="copyright.html" title="Copyright"
+             accesskey="N">next</a> |</li>
+        <li class="right" >
+          <a href="developers.html" title="Developers Information"
+             accesskey="P">previous</a> |</li>
+        <li><a href="index.html">phpMyAdmin 4.0.4 documentation</a> »</li> 
+      </ul>
+    </div>  
+
+    <div class="document">
+      <div class="documentwrapper">
+        <div class="bodywrapper">
+          <div class="body">
+            
+  <div class="section" id="distributing-and-packaging-phpmyadmin">
+<h1>Distributing and packaging phpMyAdmin<a class="headerlink" href="#distributing-and-packaging-phpmyadmin" title="Permalink to this headline">¶</a></h1>
+<p>This document is intended to give advices to people who want to
+redistribute phpMyAdmin inside other software package such as Linux
+distribution or some all in one package including web server and MySQL
+server.</p>
+<p>Generally you can customize some basic aspects (paths to some files and
+behavior) in <tt class="file docutils literal"><span class="pre">libraries/vendor_config.php</span></tt>.</p>
+<p>For example if you want setup script to generate config file in var, change
+<tt class="docutils literal"><span class="pre">SETUP_CONFIG_FILE</span></tt> to <tt class="file docutils literal"><span class="pre">/var/lib/phpmyadmin/config.inc.php</span></tt> and you
+will also probably want to skip directory writable check, so set
+<tt class="docutils literal"><span class="pre">SETUP_DIR_WRITABLE</span></tt> to false.</p>
+<div class="section" id="external-libraries">
+<h2>External libraries<a class="headerlink" href="#external-libraries" title="Permalink to this headline">¶</a></h2>
+<p>phpMyAdmin includes several external libraries, you might want to
+replace them with system ones if they are available, but please note
+that you should test whether version you provide is compatible with the
+one we ship.</p>
+<p>Currently known list of external libraries:</p>
+<dl class="docutils">
+<dt>js/jquery</dt>
+<dd>jQuery js framework and various jQuery based libraries.</dd>
+<dt>libraries/php-gettext</dt>
+<dd>php-gettext library</dd>
+<dt>libraries/tcpdf</dt>
+<dd>tcpdf library, stripped down of not needed files</dd>
+</dl>
+</div>
+</div>
+
+
+          </div>
+        </div>
+      </div>
+      <div class="sphinxsidebar">
+        <div class="sphinxsidebarwrapper">
+  <h3><a href="index.html">Table Of Contents</a></h3>
+  <ul>
+<li><a class="reference internal" href="#">Distributing and packaging phpMyAdmin</a><ul>
+<li><a class="reference internal" href="#external-libraries">External libraries</a></li>
+</ul>
+</li>
+</ul>
+
+  <h4>Previous topic</h4>
+  <p class="topless"><a href="developers.html"
+                        title="previous chapter">Developers Information</a></p>
+  <h4>Next topic</h4>
+  <p class="topless"><a href="copyright.html"
+                        title="next chapter">Copyright</a></p>
+  <h3>This Page</h3>
+  <ul class="this-page-menu">
+    <li><a href="_sources/vendors.txt"
+           rel="nofollow">Show Source</a></li>
+  </ul>
+<div id="searchbox" style="display: none">
+  <h3>Quick search</h3>
+    <form class="search" action="search.html" method="get">
+      <input type="text" name="q" />
+      <input type="submit" value="Go" />
+      <input type="hidden" name="check_keywords" value="yes" />
+      <input type="hidden" name="area" value="default" />
+    </form>
+    <p class="searchtip" style="font-size: 90%">
+    Enter search terms or a module, class or function name.
+    </p>
+</div>
+<script type="text/javascript">$('#searchbox').show(0);</script>
+        </div>
+      </div>
+      <div class="clearer"></div>
+    </div>
+    <div class="related">
+      <h3>Navigation</h3>
+      <ul>
+        <li class="right" style="margin-right: 10px">
+          <a href="genindex.html" title="General Index"
+             >index</a></li>
+        <li class="right" >
+          <a href="copyright.html" title="Copyright"
+             >next</a> |</li>
+        <li class="right" >
+          <a href="developers.html" title="Developers Information"
+             >previous</a> |</li>
+        <li><a href="index.html">phpMyAdmin 4.0.4 documentation</a> »</li> 
+      </ul>
+    </div>
+    <div class="footer">
+        © <a href="copyright.html">Copyright</a> 2012 - 2013, The phpMyAdmin devel team.
+      Created using <a href="http://sphinx.pocoo.org/">Sphinx</a> 1.1.3.
+    </div>
+  </body>
+</html>
\ No newline at end of file
diff --git a/phpmyadmin/doc/index.rst b/phpmyadmin/doc/index.rst
new file mode 100644
index 0000000..917ddf8
--- /dev/null
+++ b/phpmyadmin/doc/index.rst
@@ -0,0 +1,32 @@
+.. phpMyAdmin documentation master file, created by
+   sphinx-quickstart on Wed Sep 26 14:04:48 2012.
+   You can adapt this file completely to your liking, but it should at least
+   contain the root `toctree` directive.
+
+Welcome to phpMyAdmin's documentation!
+======================================
+
+Contents:
+
+.. toctree::
+    :maxdepth: 2
+
+    intro
+    require
+    setup
+    config
+    user
+    faq
+    developers
+    vendors
+    copyright
+    credits
+    glossary
+
+
+Indices and tables
+==================
+
+* :ref:`genindex`
+* :ref:`search`
+* :ref:`glossary`
diff --git a/phpmyadmin/doc/intro.rst b/phpmyadmin/doc/intro.rst
new file mode 100644
index 0000000..9d81e44
--- /dev/null
+++ b/phpmyadmin/doc/intro.rst
@@ -0,0 +1,68 @@
+.. _intro:
+
+Introduction
+============
+
+phpMyAdmin can manage a whole MySQL server (needs a super-user) as
+well as a single database. To accomplish the latter you'll need a
+properly set up MySQL user who can read/write only the desired
+database. It's up to you to look up the appropriate part in the MySQL
+manual.
+
+
+Supported features
+------------------
+
+Currently phpMyAdmin can:
+
+* browse and drop databases, tables, views, columns and indexes
+* display multiple results sets through stored procedures or queries
+* create, copy, drop, rename and alter databases, tables, columns and
+  indexes
+* maintenance server, databases and tables, with proposals on server
+  configuration
+* execute, edit and bookmark any :term:`SQL`-statement, even batch-queries
+* load text files into tables
+* create [#f1]_ and read dumps of tables
+* export [#f1]_ data to various formats: :term:`CSV`, :term:`XML`, :term:`PDF`, 
+  :term:`ISO`/:term:`IEC` 26300 - :term:`OpenDocument` Text and Spreadsheet, Microsoft 
+  Word 2000, and LATEX formats
+* import data and :term:`MySQL` structures from :term:`OpenDocument` spreadsheets, as
+  well as :term:`XML`, :term:`CSV`, and :term:`SQL` files
+* administer multiple servers
+* manage MySQL users and privileges
+* check referential integrity in MyISAM tables
+* using Query-by-example (QBE), create complex queries automatically
+  connecting required tables
+* create :term:`PDF` graphics of your
+  database layout
+* search globally in a database or a subset of it
+* transform stored data into any format using a set of predefined
+  functions, like displaying BLOB-data as image or download-link
+* track changes on databases, tables and views
+* support InnoDB tables and foreign keys see :ref:`faq3_6`
+* support mysqli, the improved MySQL extension see :ref:`faq1_17`
+* create, edit, call, export and drop stored procedures and functions
+* create, edit, export and drop events and triggers
+* communicate in `62 different languages
+  <http://www.phpmyadmin.net/home_page/translations.php>`_
+
+
+A word about users
+------------------
+
+Many people have difficulty understanding the concept of user
+management with regards to phpMyAdmin. When a user logs in to
+phpMyAdmin, that username and password are passed directly to MySQL.
+phpMyAdmin does no account management on its own (other than allowing
+one to manipulate the MySQL user account information); all users must
+be valid MySQL users.
+
+.. rubric:: Footnotes
+
+.. [#f1]
+
+    phpMyAdmin can compress (:term:`Zip`, :term:`GZip` :term:`RFC 1952` or
+    :term:`Bzip2` formats) dumps and :term:`CSV` exports if you use PHP with
+    :term:`Zlib` support (``--with-zlib``) and/or :term:`Bzip2` support
+    (``--with-bz2``).  Proper support may also need changes in :file:`php.ini`.
diff --git a/phpmyadmin/doc/make.bat b/phpmyadmin/doc/make.bat
new file mode 100644
index 0000000..19b6090
--- /dev/null
+++ b/phpmyadmin/doc/make.bat
@@ -0,0 +1,190 @@
+ at ECHO OFF
+
+REM Command file for Sphinx documentation
+
+if "%SPHINXBUILD%" == "" (
+	set SPHINXBUILD=sphinx-build
+)
+set BUILDDIR=_build
+set ALLSPHINXOPTS=-d %BUILDDIR%/doctrees %SPHINXOPTS% .
+set I18NSPHINXOPTS=%SPHINXOPTS% .
+if NOT "%PAPER%" == "" (
+	set ALLSPHINXOPTS=-D latex_paper_size=%PAPER% %ALLSPHINXOPTS%
+	set I18NSPHINXOPTS=-D latex_paper_size=%PAPER% %I18NSPHINXOPTS%
+)
+
+if "%1" == "" goto help
+
+if "%1" == "help" (
+	:help
+	echo.Please use `make ^<target^>` where ^<target^> is one of
+	echo.  html       to make standalone HTML files
+	echo.  dirhtml    to make HTML files named index.html in directories
+	echo.  singlehtml to make a single large HTML file
+	echo.  pickle     to make pickle files
+	echo.  json       to make JSON files
+	echo.  htmlhelp   to make HTML files and a HTML help project
+	echo.  qthelp     to make HTML files and a qthelp project
+	echo.  devhelp    to make HTML files and a Devhelp project
+	echo.  epub       to make an epub
+	echo.  latex      to make LaTeX files, you can set PAPER=a4 or PAPER=letter
+	echo.  text       to make text files
+	echo.  man        to make manual pages
+	echo.  texinfo    to make Texinfo files
+	echo.  gettext    to make PO message catalogs
+	echo.  changes    to make an overview over all changed/added/deprecated items
+	echo.  linkcheck  to check all external links for integrity
+	echo.  doctest    to run all doctests embedded in the documentation if enabled
+	goto end
+)
+
+if "%1" == "clean" (
+	for /d %%i in (%BUILDDIR%\*) do rmdir /q /s %%i
+	del /q /s %BUILDDIR%\*
+	goto end
+)
+
+if "%1" == "html" (
+	%SPHINXBUILD% -b html %ALLSPHINXOPTS% %BUILDDIR%/html
+	if errorlevel 1 exit /b 1
+	echo.
+	echo.Build finished. The HTML pages are in %BUILDDIR%/html.
+	goto end
+)
+
+if "%1" == "dirhtml" (
+	%SPHINXBUILD% -b dirhtml %ALLSPHINXOPTS% %BUILDDIR%/dirhtml
+	if errorlevel 1 exit /b 1
+	echo.
+	echo.Build finished. The HTML pages are in %BUILDDIR%/dirhtml.
+	goto end
+)
+
+if "%1" == "singlehtml" (
+	%SPHINXBUILD% -b singlehtml %ALLSPHINXOPTS% %BUILDDIR%/singlehtml
+	if errorlevel 1 exit /b 1
+	echo.
+	echo.Build finished. The HTML pages are in %BUILDDIR%/singlehtml.
+	goto end
+)
+
+if "%1" == "pickle" (
+	%SPHINXBUILD% -b pickle %ALLSPHINXOPTS% %BUILDDIR%/pickle
+	if errorlevel 1 exit /b 1
+	echo.
+	echo.Build finished; now you can process the pickle files.
+	goto end
+)
+
+if "%1" == "json" (
+	%SPHINXBUILD% -b json %ALLSPHINXOPTS% %BUILDDIR%/json
+	if errorlevel 1 exit /b 1
+	echo.
+	echo.Build finished; now you can process the JSON files.
+	goto end
+)
+
+if "%1" == "htmlhelp" (
+	%SPHINXBUILD% -b htmlhelp %ALLSPHINXOPTS% %BUILDDIR%/htmlhelp
+	if errorlevel 1 exit /b 1
+	echo.
+	echo.Build finished; now you can run HTML Help Workshop with the ^
+.hhp project file in %BUILDDIR%/htmlhelp.
+	goto end
+)
+
+if "%1" == "qthelp" (
+	%SPHINXBUILD% -b qthelp %ALLSPHINXOPTS% %BUILDDIR%/qthelp
+	if errorlevel 1 exit /b 1
+	echo.
+	echo.Build finished; now you can run "qcollectiongenerator" with the ^
+.qhcp project file in %BUILDDIR%/qthelp, like this:
+	echo.^> qcollectiongenerator %BUILDDIR%\qthelp\phpMyAdmin.qhcp
+	echo.To view the help file:
+	echo.^> assistant -collectionFile %BUILDDIR%\qthelp\phpMyAdmin.ghc
+	goto end
+)
+
+if "%1" == "devhelp" (
+	%SPHINXBUILD% -b devhelp %ALLSPHINXOPTS% %BUILDDIR%/devhelp
+	if errorlevel 1 exit /b 1
+	echo.
+	echo.Build finished.
+	goto end
+)
+
+if "%1" == "epub" (
+	%SPHINXBUILD% -b epub %ALLSPHINXOPTS% %BUILDDIR%/epub
+	if errorlevel 1 exit /b 1
+	echo.
+	echo.Build finished. The epub file is in %BUILDDIR%/epub.
+	goto end
+)
+
+if "%1" == "latex" (
+	%SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex
+	if errorlevel 1 exit /b 1
+	echo.
+	echo.Build finished; the LaTeX files are in %BUILDDIR%/latex.
+	goto end
+)
+
+if "%1" == "text" (
+	%SPHINXBUILD% -b text %ALLSPHINXOPTS% %BUILDDIR%/text
+	if errorlevel 1 exit /b 1
+	echo.
+	echo.Build finished. The text files are in %BUILDDIR%/text.
+	goto end
+)
+
+if "%1" == "man" (
+	%SPHINXBUILD% -b man %ALLSPHINXOPTS% %BUILDDIR%/man
+	if errorlevel 1 exit /b 1
+	echo.
+	echo.Build finished. The manual pages are in %BUILDDIR%/man.
+	goto end
+)
+
+if "%1" == "texinfo" (
+	%SPHINXBUILD% -b texinfo %ALLSPHINXOPTS% %BUILDDIR%/texinfo
+	if errorlevel 1 exit /b 1
+	echo.
+	echo.Build finished. The Texinfo files are in %BUILDDIR%/texinfo.
+	goto end
+)
+
+if "%1" == "gettext" (
+	%SPHINXBUILD% -b gettext %I18NSPHINXOPTS% %BUILDDIR%/locale
+	if errorlevel 1 exit /b 1
+	echo.
+	echo.Build finished. The message catalogs are in %BUILDDIR%/locale.
+	goto end
+)
+
+if "%1" == "changes" (
+	%SPHINXBUILD% -b changes %ALLSPHINXOPTS% %BUILDDIR%/changes
+	if errorlevel 1 exit /b 1
+	echo.
+	echo.The overview file is in %BUILDDIR%/changes.
+	goto end
+)
+
+if "%1" == "linkcheck" (
+	%SPHINXBUILD% -b linkcheck %ALLSPHINXOPTS% %BUILDDIR%/linkcheck
+	if errorlevel 1 exit /b 1
+	echo.
+	echo.Link check complete; look for any errors in the above output ^
+or in %BUILDDIR%/linkcheck/output.txt.
+	goto end
+)
+
+if "%1" == "doctest" (
+	%SPHINXBUILD% -b doctest %ALLSPHINXOPTS% %BUILDDIR%/doctest
+	if errorlevel 1 exit /b 1
+	echo.
+	echo.Testing of doctests in the sources finished, look at the ^
+results in %BUILDDIR%/doctest/output.txt.
+	goto end
+)
+
+:end
diff --git a/phpmyadmin/doc/other.rst b/phpmyadmin/doc/other.rst
new file mode 100644
index 0000000..aa95451
--- /dev/null
+++ b/phpmyadmin/doc/other.rst
@@ -0,0 +1,18 @@
+Other sources of information
+============================
+
+Printed Book
+------------
+
+The definitive guide to using phpMyAdmin is the book Mastering phpMyAdmin for
+Effective MySQL Management by Marc Delisle. You can get information on that
+book and other officially endorsed `books at the phpMyAdmin site`_.
+
+.. _books at the phpMyAdmin site: http://www.phpmyadmin.net/home_page/docs.php?books
+
+Tutorials
+---------
+
+Third party tutorials and articles are listed on our `wiki page`_.
+
+.. _wiki page: http://wiki.phpmyadmin.net/pma/Articles
diff --git a/phpmyadmin/doc/privileges.rst b/phpmyadmin/doc/privileges.rst
new file mode 100644
index 0000000..0c12932
--- /dev/null
+++ b/phpmyadmin/doc/privileges.rst
@@ -0,0 +1,50 @@
+User management
+===============
+
+User management is the process of controlling which users are allowed to
+connect to the MySQL server and what permissions they have on each database.
+phpMyAdmin does not handle user management, rather it passes the username and
+password on to MySQL, which then determines whether a user is permitted to
+perform a particular action. Within phpMyAdmin, administrators have full
+control over creating users, viewing and editing privileges for existing users,
+and removing users.
+
+Within phpMyAdmin, user management is controlled via the :guilabel:`Users` link
+from the main page. Users can be created, edited, and removed.  
+
+Creating a new user
+-------------------
+
+To create a new user, click the :guilabel:`Add a new user` link near the bottom
+of the :guilabel:`Users` page (you must be a "superuser", e.g., user "root").
+Use the textboxes and drop-downs to configure the user to your particular
+needs. You can then select whether to create a database for that user and grant
+specific global privileges. Once you've created the user (by clicking Go), you
+can define that user's permissions on a specific database (don't grant global
+privileges in that case). In general, users do not need any global privileges
+(other than USAGE), only permissions for their specific database.
+
+Editing an existing user
+------------------------
+
+To edit an existing user, simply click the pencil icon to the right of that
+user in the :guilabel:`Users` page. You can then edit their global- and
+database-specific privileges, change their password, or even copy those
+privileges to a new user.
+
+Deleting a user
+---------------
+
+From the :guilabel:`Users` page, check the checkbox for the user you wish to
+remove, select whether or not to also remove any databases of the same name (if
+they exist), and click Go.
+
+Assigning privileges to user for a specific database
+----------------------------------------------------
+
+Users are assigned to databases by editing the user record (from the
+:guilabel:`Users` link on the home page) not from within the :guilabel:`Users`
+link under the table. If you are creating a user specifically for a given table
+you will have to create the user first (with no global privileges) and then go
+back and edit that user to add the table and privileges for the individual
+table.
diff --git a/phpmyadmin/doc/require.rst b/phpmyadmin/doc/require.rst
new file mode 100644
index 0000000..1452ee3
--- /dev/null
+++ b/phpmyadmin/doc/require.rst
@@ -0,0 +1,55 @@
+.. _require:
+
+Requirements
+============
+
+Web server
+----------
+
+Since, phpMyAdmin's interface is based entirely in your browser, you'll need a
+web server (such as Apache, :term:`IIS`) to install phpMyAdmin's files into.
+
+PHP
+---
+
+* You need PHP 5.2.0 or newer, with ``session`` support, the Standard PHP Library 
+  (SPL) extension and JSON support.
+
+* To support uploading of ZIP files, you need the PHP ``zip`` extension.
+
+* For proper support of multibyte strings (eg. UTF-8, which is currently
+  the default), you should install the ``mbstring`` and ``ctype`` extensions.
+
+* You need GD2 support in PHP to display inline thumbnails of JPEGs
+  ("image/jpeg: inline") with their original aspect ratio.
+
+* When using the cookie authentication (the default), the `mcrypt
+  <http://www.php.net/mcrypt>`_ extension is strongly suggested for most
+  users and is **required** for 64–bit machines. Not using mcrypt will
+  cause phpMyAdmin to load pages significantly slower.
+
+* To support upload progress bars, see :ref:`faq2_9`.
+
+* To support XML and Open Document Spreadsheet importing, you need PHP
+  5.2.17 or newer and the `libxml <http://www.php.net/libxml>`_
+  extension.
+
+.. seealso:: :ref:`faq1_31`, :ref:`authentication_modes`
+
+Database
+--------
+
+phpMyAdmin support MySQL compatible databases. 
+
+* MySQL 5.0 or newer
+* MariaDB 5.0 or newer
+* Drizzle
+
+.. seealso:: :ref:`faq1_17`
+
+Web browser
+-----------
+
+To access phpMyAdmin you need a web browser with cookies and javascript
+enabled.
+
diff --git a/phpmyadmin/doc/setup.rst b/phpmyadmin/doc/setup.rst
new file mode 100644
index 0000000..850d67a
--- /dev/null
+++ b/phpmyadmin/doc/setup.rst
@@ -0,0 +1,424 @@
+.. _setup:
+
+Installation
+============
+
+phpMyAdmin does not apply any special security methods to the MySQL
+database server. It is still the system administrator's job to grant
+permissions on the MySQL databases properly. phpMyAdmin's :guilabel:`Users`
+page can be used for this.
+
+.. warning::
+
+    :term:`Mac` users should note that if you are on a version before
+    :term:`Mac OS X`, StuffIt unstuffs with :term:`Mac` formats. So you'll have
+    to resave as in BBEdit to Unix style ALL phpMyAdmin scripts before
+    uploading them to your server, as PHP seems not to like :term:`Mac`-style
+    end of lines character ("``\r``").
+
+.. _quick_install:
+
+Quick Install
++++++++++++++
+
+#. Choose an appropriate distribution kit from the phpmyadmin.net
+   Downloads page. Some kits contain only the English messages, others
+   contain all languages. We'll assume you chose a kit whose name 
+   looks like ``phpMyAdmin-x.x.x -all-languages.tar.gz``.
+#. Untar or unzip the distribution (be sure to unzip the subdirectories):
+   ``tar -xzvf phpMyAdmin_x.x.x-all-languages.tar.gz`` in your
+   webserver's document root. If you don't have direct access to your
+   document root, put the files in a directory on your local machine,
+   and, after step 4, transfer the directory on your web server using,
+   for example, ftp.
+#. Ensure that all the scripts have the appropriate owner (if PHP is
+   running in safe mode, having some scripts with an owner different from
+   the owner of other scripts will be a problem). See :ref:`faq4_2` and
+   :ref:`faq1_26` for suggestions.
+#. Now you must configure your installation. There are two methods that
+   can be used. Traditionally, users have hand-edited a copy of
+   :file:`config.inc.php`, but now a wizard-style setup script is provided
+   for those who prefer a graphical installation. Creating a
+   :file:`config.inc.php` is still a quick way to get started and needed for
+   some advanced features.
+
+
+Manualy creating file
+---------------------
+
+To manually create the file, simply use your text editor to create the
+file :file:`config.inc.php` (you can copy :file:`config.sample.inc.php` to get
+minimal configuration file) in the main (top-level) phpMyAdmin
+directory (the one that contains :file:`index.php`). phpMyAdmin first
+loads :file:`libraries/config.default.php` and then overrides those values
+with anything found in :file:`config.inc.php`. If the default value is
+okay for a particular setting, there is no need to include it in
+:file:`config.inc.php`. You'll need a few directives to get going, a
+simple configuration may look like this:
+
+.. code-block:: php
+
+    
+    <?php
+    $cfg['blowfish_secret'] = 'ba17c1ec07d65003';  // use here a value of your choice
+    
+    $i=0;
+    $i++;
+    $cfg['Servers'][$i]['auth_type']     = 'cookie';
+    ?>
+
+Or, if you prefer to not be prompted every time you log in:
+
+.. code-block:: php
+
+    
+    <?php
+    
+    $i=0;
+    $i++;
+    $cfg['Servers'][$i]['user']          = 'root';
+    $cfg['Servers'][$i]['password']      = 'cbb74bc'; // use here your password
+    $cfg['Servers'][$i]['auth_type']     = 'config';
+    ?>
+
+For a full explanation of possible configuration values, see the 
+:ref:`config` of this document.
+
+.. index:: Setup script
+
+.. _setup_script:
+
+Using Setup script
+------------------
+
+Instead of manually editing :file:`config.inc.php`, you can use the `Setup
+Script <setup/>`_. First you must manually create a folder ``config``
+in the phpMyAdmin directory. This is a security measure. On a
+Linux/Unix system you can use the following commands:
+
+.. code-block:: sh
+
+    
+    cd phpMyAdmin
+    mkdir config                        # create directory for saving
+    chmod o+rw config                   # give it world writable permissions
+
+And to edit an existing configuration, copy it over first:
+
+.. code-block:: sh
+
+    
+    cp config.inc.php config/           # copy current configuration for editing
+    chmod o+w config/config.inc.php     # give it world writable permissions
+
+On other platforms, simply create the folder and ensure that your web
+server has read and write access to it. :ref:`faq1_26` can help with
+this.
+
+Next, open ``setup/`` in your browser. Note that **changes are
+not saved to disk until explicitly choose ``Save``** from the
+*Configuration* area of the screen. Normally the script saves the new
+:file:`config.inc.php` to the ``config/`` directory, but if the webserver does
+not have the proper permissions you may see the error "Cannot load or
+save configuration." Ensure that the ``config/`` directory exists and
+has the proper permissions - or use the ``Download`` link to save the
+config file locally and upload (via FTP or some similar means) to the
+proper location.
+
+Once the file has been saved, it must be moved out of the ``config/``
+directory and the permissions must be reset, again as a security
+measure:
+
+.. code-block:: sh
+
+    
+    mv config/config.inc.php .         # move file to current directory
+    chmod o-rw config.inc.php          # remove world read and write permissions
+    rm -rf config                      # remove not needed directory
+
+Now the file is ready to be used. You can choose to review or edit the
+file with your favorite editor, if you prefer to set some advanced
+options which the setup script does not provide.
+
+#. If you are using the ``auth_type`` "config", it is suggested that you
+   protect the phpMyAdmin installation directory because using config
+   does not require a user to enter a password to access the phpMyAdmin
+   installation. Use of an alternate authentication method is
+   recommended, for example with HTTP–AUTH in a :term:`.htaccess` file or switch to using
+   ``auth_type`` cookie or http. See the :ref:`faqmultiuser`
+   for additional information, especially :ref:`faq4_4`.
+#. Open the `main phpMyAdmin directory <index.php>`_ in your browser.
+   phpMyAdmin should now display a welcome screen and your databases, or
+   a login dialog if using :term:`HTTP` or
+   cookie authentication mode.
+#. You should deny access to the ``./libraries`` and ``./setup/lib``
+   subfolders in your webserver configuration. For Apache you can use
+   supplied :term:`.htaccess`  file in that folder, for other webservers, you should
+   configure this yourself. Such configuration prevents from possible
+   path exposure and cross side scripting vulnerabilities that might
+   happen to be found in that code.
+#. It is generally good idea to protect public phpMyAdmin installation
+   against access by robots as they usually can not do anything good
+   there. You can do this using ``robots.txt`` file in root of your
+   webserver or limit access by web server configuration, see
+   :ref:`faq1_42`.
+
+.. index:: 
+    single: Configuration storage
+    single: phpMyAdmin configuration storage
+    single: pmadb
+
+.. _linked-tables:
+
+phpMyAdmin configuration storage
+++++++++++++++++++++++++++++++++
+
+For a whole set of new features (bookmarks, comments, :term:`SQL`-history,
+tracking mechanism, :term:`PDF`-generation, column contents transformation,
+etc.) you need to create a set of special tables.  Those tables can be located
+in your own database, or in a central database for a multi-user installation
+(this database would then be accessed by the controluser, so no other user
+should have rights to it).
+
+Please look at your ``./examples/`` directory, where you should find a
+file called *create\_tables.sql*. (If you are using a Windows server,
+pay special attention to :ref:`faq1_23`).
+
+If you already had this infrastructure and upgraded to MySQL 4.1.2 or
+newer, please use :file:`examples/upgrade_tables_mysql_4_1_2+.sql`
+and then create new tables by importing
+:file:`examples/create_tables.sql`.
+
+You can use your phpMyAdmin to create the tables for you. Please be
+aware that you may need special (administrator) privileges to create
+the database and tables, and that the script may need some tuning,
+depending on the database name.
+
+After having imported the :file:`examples/create_tables.sql` file, you
+should specify the table names in your :file:`config.inc.php` file. The
+directives used for that can be found in the :ref:`config`. You will also need to
+have a controluser with the proper rights to those tables (see section
+:ref:`authentication_modes` below).
+
+.. _upgrading:
+
+Upgrading from an older version
++++++++++++++++++++++++++++++++
+
+Simply copy :file:`config.inc.php` from your previous installation into
+the newly unpacked one. Configuration files from old versions may
+require some tweaking as some options have been changed or removed.
+For compatibility with PHP 6, remove a
+``set_magic_quotes_runtime(0);`` statement that you might find near
+the end of your configuration file.
+
+You should **not** copy :file:`libraries/config.default.php` over
+:file:`config.inc.php` because the default configuration file is version-
+specific.
+
+If you have upgraded your MySQL server from a version previous to 4.1.2 to
+version 5.x or newer and if you use the phpMyAdmin configuration storage, you
+should run the :term:`SQL` script found in
+:file:`examples/upgrade_tables_mysql_4_1_2+.sql`.
+
+.. index:: Authentication mode
+
+.. _authentication_modes:
+
+Using authentication modes
+++++++++++++++++++++++++++
+
+:term:`HTTP` and cookie authentication modes are recommended in a **multi-user
+environment** where you want to give users access to their own database and
+don't want them to play around with others. Nevertheless be aware that MS
+Internet Explorer seems to be really buggy about cookies, at least till version
+6. Even in a **single-user environment**, you might prefer to use :term:`HTTP`
+or cookie mode so that your user/password pair are not in clear in the
+configuration file.
+
+:term:`HTTP` and cookie authentication
+modes are more secure: the MySQL login information does not need to be
+set in the phpMyAdmin configuration file (except possibly for the 
+:config:option:`$cfg['Servers'][$i]['controluser']`).
+However, keep in mind that the password travels in plain text, unless
+you are using the HTTPS protocol. In cookie mode, the password is
+stored, encrypted with the blowfish algorithm, in a temporary cookie.
+
+.. note: 
+   
+    This section is only applicable if your MySQL server is running
+    with ``--skip-show-database``. 
+
+For ':term:`HTTP`' and 'cookie' modes, phpMyAdmin needs a controluser that has
+**only** the ``SELECT`` privilege on the *`mysql`.`user` (all columns except
+`Password`)*, *`mysql`.`db` (all columns)*, *`mysql`.`host` (all columns)* and
+*`mysql`.`tables\_priv` (all columns except `Grantor` and `Timestamp`)* tables.
+You must specify the details for the controluser in the :file:`config.inc.php`
+file under the :config:option:`$cfg['Servers'][$i]['controluser']` and
+:config:option:`$cfg['Servers'][$i]['controlpass']` settings. The following
+example assumes you want to use ``pma`` as the controluser and ``pmapass`` as
+the controlpass, but **this is only an example: use something else in your
+file!** Input these statements from the phpMyAdmin :term:`SQL` Query window or
+mysql command–line client. Of course you have to replace ``localhost`` with the
+webserver's host if it's not the same as the MySQL server's one. 
+
+If you want to use the many new relation and bookmark features:  (this of
+course requires that your :ref:`linked-tables` be set up).
+
+.. code-block:: mysql
+   
+   GRANT USAGE ON mysql.* TO 'pma'@'localhost' IDENTIFIED BY 'pmapass';
+   GRANT SELECT (
+   Host, User, Select_priv, Insert_priv, Update_priv, Delete_priv,
+   Create_priv, Drop_priv, Reload_priv, Shutdown_priv, Process_priv,
+   File_priv, Grant_priv, References_priv, Index_priv, Alter_priv,
+   Show_db_priv, Super_priv, Create_tmp_table_priv, Lock_tables_priv,
+   Execute_priv, Repl_slave_priv, Repl_client_priv
+   ) ON mysql.user TO 'pma'@'localhost';
+   GRANT SELECT ON mysql.db TO 'pma'@'localhost';
+   GRANT SELECT ON mysql.host TO 'pma'@'localhost';
+   GRANT SELECT (Host, Db, User, Table_name, Table_priv, Column_priv)
+   ON mysql.tables_priv TO 'pma'@'localhost';
+   
+If you want to use the many new relation and bookmark features:
+   
+.. code-block:: mysql
+   
+   GRANT SELECT, INSERT, UPDATE, DELETE ON <pma_db>.* TO 'pma'@'localhost';
+   
+(this of course requires that your phpMyAdmin
+configuration storage be set up).
+   
+Then each of the *true* users should be granted a set of privileges
+on a set of particular databases. Normally you shouldn't give global
+privileges to an ordinary user, unless you understand the impact of those
+privileges (for example, you are creating a superuser).
+For example, to grant the user *real_user* with all privileges on
+the database *user_base*:
+   
+.. code-block:: mysql
+   
+   GRANT ALL PRIVILEGES ON user_base.* TO 'real_user'@localhost IDENTIFIED BY 'real_password';
+   
+   
+What the user may now do is controlled entirely by the MySQL user management
+system. With HTTP or cookie authentication mode, you don't need to fill the
+user/password fields inside the :config:option:`$cfg['Servers']`.
+
+.. index:: pair: HTTP; Authentication mode
+
+HTTP authentication mode
+------------------------
+
+* Uses :term:`HTTP` Basic authentication
+  method and allows you to log in as any valid MySQL user.
+* Is supported with most PHP configurations. For :term:`IIS` (:term:`ISAPI`) 
+  support using :term:`CGI` PHP see :ref:`faq1_32`, for using with Apache 
+  :term:`CGI` see :ref:`faq1_35`.
+* See also :ref:`faq4_4` about not using the :term:`.htaccess` mechanism along with
+  ':term:`HTTP`' authentication mode.
+
+.. index:: pair: Cookie; Authentication mode
+
+.. _cookie:
+
+Cookie authentication mode
+--------------------------
+
+* You can use this method as a replacement for the :term:`HTTP` authentication 
+  (for example, if you're running :term:`IIS`).
+* Obviously, the user must enable cookies in the browser, but this is
+  now a requirement for all authentication modes.
+* With this mode, the user can truly log out of phpMyAdmin and log in
+  back with the same username.
+* If you want to log in to arbitrary server see :config:option:`$cfg['AllowArbitraryServer']` directive.
+* As mentioned in the :ref:`require` section, having the ``mcrypt`` extension will
+  speed up access considerably, but is not required.
+
+.. index:: pair: Signon; Authentication mode
+
+Signon authentication mode
+--------------------------
+
+* This mode is a convenient way of using credentials from another
+  application to authenticate to phpMyAdmin.
+* The other application has to store login information into session
+  data.
+
+.. seealso::
+    :config:option:`$cfg['Servers'][$i]['auth_type']`,
+    :config:option:`$cfg['Servers'][$i]['SignonSession']`,
+    :config:option:`$cfg['Servers'][$i]['SignonScript']`,
+    :config:option:`$cfg['Servers'][$i]['SignonURL']`
+
+
+.. index:: pair: Config; Authentication mode
+
+Config authentication mode
+--------------------------
+
+* This mode is the less secure one because it requires you to fill the
+  :config:option:`$cfg['Servers'][$i]['user']` and
+  :config:option:`$cfg['Servers'][$i]['password']`
+  fields (and as a result, anyone who can read your :file:`config.inc.php`
+  can discover your username and password).  But you don't need to setup
+  a "controluser" here: using the :config:option:`$cfg['Servers'][$i]['only_db']` might be enough.
+* In the :ref:`faqmultiuser` section, there is an entry explaining how
+  to protect your configuration file.
+* For additional security in this mode, you may wish to consider the
+  Host authentication :config:option:`$cfg['Servers'][$i]['AllowDeny']['order']`
+  and :config:option:`$cfg['Servers'][$i]['AllowDeny']['rules']` configuration directives.
+* Unlike cookie and http, does not require a user to log in when first
+  loading the phpMyAdmin site. This is by design but could allow any
+  user to access your installation. Use of some restriction method is
+  suggested, perhaps a :term:`.htaccess` file with the HTTP-AUTH directive or disallowing
+  incoming HTTP requests at one’s router or firewall will suffice (both
+  of which are beyond the scope of this manual but easily searchable
+  with Google).
+
+.. index:: pair: Swekey; Authentication mode
+
+.. _swekey:
+
+Swekey authentication mode
+--------------------------
+
+The Swekey is a low cost authentication USB key that can be used in
+web applications. When Swekey authentication is activated, phpMyAdmin
+requires the users's Swekey to be plugged before entering the login
+page (currently supported for cookie authentication mode only). Swekey
+Authentication is disabled by default. To enable it, add the following
+line to :file:`config.inc.php`:
+
+.. code-block:: php
+    
+    $cfg['Servers'][$i]['auth_swekey_config'] = '/etc/swekey.conf';
+
+You then have to create the ``swekey.conf`` file that will associate
+each user with their Swekey Id. It is important to place this file
+outside of your web server's document root (in the example, it is
+located in ``/etc``). A self documented sample file is provided in the
+``examples`` directory. Feel free to use it with your own users'
+information. If you want to purchase a Swekey please visit
+`http://phpmyadmin.net/auth\_key <http://phpmyadmin.net/auth_key>`_
+since this link provides funding for phpMyAdmin.
+
+.. seealso:: :config:option:`$cfg['Servers'][$i]['auth_swekey_config']`
+
+
+Securing your phpMyAdmin installation
++++++++++++++++++++++++++++++++++++++
+
+The phpMyAdmin team tries hardly to make the application secure, however there
+are always ways to make your installation more secure:
+
+* remove ``setup`` directory from phpMyAdmin, you will probably not 
+  use it after initial setup
+* prevent access to ``libraries`` directory from browser, 
+  as it is not needed, supplied ``.htaccess`` file does this
+* properly choose authentication method - :ref:`cookie`
+  is probably the best choice for shared hosting
+* in case you don't want all MySQL users to be able to access 
+  phpMyAdmin, you can use :config:option:`$cfg['Servers'][$i]['AllowDeny']['rules']` to limit them
+* consider hiding phpMyAdmin behind authentication proxy, so that 
+  MySQL credentials are not all users need to login
diff --git a/phpmyadmin/doc/transformations.rst b/phpmyadmin/doc/transformations.rst
new file mode 100644
index 0000000..4c3ce46
--- /dev/null
+++ b/phpmyadmin/doc/transformations.rst
@@ -0,0 +1,138 @@
+.. _transformations:
+
+Transformations
+===============
+
+.. _transformationsintro:
+
+Introduction
+++++++++++++
+
+To enable transformations, you have to setup the ``column_info``
+table and the proper directives. Please see the :ref:`config` on how to do so.
+
+You can apply different transformations to the contents of each
+column. The transformation will take the content of each column and
+transform it with certain rules defined in the selected
+transformation.
+
+Say you have a column 'filename' which contains a filename. Normally
+you would see in phpMyAdmin only this filename. Using transformations
+you can transform that filename into a HTML link, so you can click
+inside of the phpMyAdmin structure on the column's link and will see
+the file displayed in a new browser window. Using transformation
+options you can also specify strings to append/prepend to a string or
+the format you want the output stored in.
+
+For a general overview of all available transformations and their
+options, you can consult your *<www.your-host.com>/<your-install-
+dir>/transformation\_overview.php* installation.
+
+For a tutorial on how to effectively use transformations, see our
+`Link section <http://www.phpmyadmin.net/home_page/docs.php>`_ on the
+official phpMyAdmin homepage.
+
+.. _transformationshowto:
+
+Usage
++++++
+
+Go to your *tbl\_structure.php* page (i.e. reached through clicking on
+the 'Structure' link for a table). There click on "Change" (or change
+icon) and there you will see three new fields at the end of the line.
+They are called 'MIME-type', 'Browser transformation' and
+'Transformation options'.
+
+* The field 'MIME-type' is a drop-down field. Select the MIME-type that
+  corresponds to the column's contents. Please note that transformations
+  are inactive as long as no MIME-type is selected.
+* The field 'Browser transformation' is a drop-down field. You can
+  choose from a hopefully growing amount of pre-defined transformations.
+  See below for information on how to build your own transformation.
+  There are global transformations and mimetype-bound transformations.
+  Global transformations can be used for any mimetype. They will take
+  the mimetype, if necessary, into regard. Mimetype-bound
+  transformations usually only operate on a certain mimetype. There are
+  transformations which operate on the main mimetype (like 'image'),
+  which will most likely take the subtype into regard, and those who
+  only operate on a specific subtype (like 'image/jpeg'). You can use
+  transformations on mimetypes for which the function was not defined
+  for. There is no security check for you selected the right
+  transformation, so take care of what the output will be like.
+* The field 'Transformation options' is a free-type textfield. You have
+  to enter transform-function specific options here. Usually the
+  transforms can operate with default options, but it is generally a
+  good idea to look up the overview to see which options are necessary.
+  Much like the ENUM/SET-Fields, you have to split up several options
+  using the format 'a','b','c',...(NOTE THE MISSING BLANKS). This is
+  because internally the options will be parsed as an array, leaving the
+  first value the first element in the array, and so forth. If you want
+  to specify a MIME character set you can define it in the
+  transformation\_options. You have to put that outside of the pre-
+  defined options of the specific mime-transform, as the last value of
+  the set. Use the format "'; charset=XXX'". If you use a transform, for
+  which you can specify 2 options and you want to append a character
+  set, enter "'first parameter','second parameter','charset=us-ascii'".
+  You can, however use the defaults for the parameters: "'','','charset
+  =us-ascii'".
+
+.. _transformationsfiles:
+
+File structure
+++++++++++++++
+
+All specific transformations for mimetypes are defined through class
+files in the directory 'libraries/plugins/transformations/'. Each of
+them extends a certain transformation abstract class declared in
+libraries/plugins/transformations/abstract.
+
+They are stored in files to ease up customization and easy adding of
+new transformations.
+
+Because the user cannot enter own mimetypes, it is kept sure that
+transformations always work. It makes no sense to apply a
+transformation to a mimetype the transform-function doesn't know to
+handle.
+
+There is a file called '*transformations.lib.php*' that provides some
+basic functions which can be included by any other transform function.
+
+The file name convention is ``[Mimetype]_[Subtype]_[Transformation
+Name].class.php``, while the abtract class that it extends has the
+name ``[Transformation Name]TransformationsPlugin``. All of the
+methods that have to be implemented by a transformations plug-in are:
+
+#. getMIMEType() and getMIMESubtype() in the main class;
+#. getName(), getInfo() and applyTransformation() in the abstract class
+   it extends.
+
+The getMIMEType(), getMIMESubtype() and getName() methods return the
+name of the MIME type, MIME Subtype and transformation accordingly.
+getInfo() returns the transformation's description and possible
+options it may receive and applyTransformation() is the method that
+does the actual work of the transformation plug-in.
+
+Please see the libraries/plugins/transformations/TEMPLATE and
+libraries/plugins/transformations/TEMPLATE\_ABSTRACT files for adding
+your own transformation plug-in. You can also generate a new
+transformation plug-in (with or without the abstract transformation
+class), by using
+:file:`libraries/plugins/transformations/generator_plugin.sh` or
+:file:`libraries/plugins/transformations/generator_main_class.sh`.
+
+The applyTransformation() method always gets passed three variables:
+
+#. **$buffer** - Contains the text inside of the column. This is the
+   text, you want to transform.
+#. **$options** - Contains any user-passed options to a transform
+   function as an array.
+#. **$meta** - Contains an object with information about your column. The
+   data is drawn from the output of the `mysql\_fetch\_field()
+   <http://www.php.net/mysql_fetch_field>`_ function. This means, all
+   object properties described on the `manual page
+   <http://www.php.net/mysql_fetch_field>`_ are available in this
+   variable and can be used to transform a column accordingly to
+   unsigned/zerofill/not\_null/... properties. The $meta->mimetype
+   variable contains the original MIME-type of the column (i.e.
+   'text/plain', 'image/jpeg' etc.)
+
diff --git a/phpmyadmin/doc/user.rst b/phpmyadmin/doc/user.rst
new file mode 100644
index 0000000..ceaf723
--- /dev/null
+++ b/phpmyadmin/doc/user.rst
@@ -0,0 +1,9 @@
+User Guide
+==========
+
+.. toctree::
+    :maxdepth: 2
+
+    transformations
+    privileges
+    other
diff --git a/phpmyadmin/doc/vendors.rst b/phpmyadmin/doc/vendors.rst
new file mode 100644
index 0000000..13d7e55
--- /dev/null
+++ b/phpmyadmin/doc/vendors.rst
@@ -0,0 +1,34 @@
+Distributing and packaging phpMyAdmin
+=====================================
+
+This document is intended to give advices to people who want to
+redistribute phpMyAdmin inside other software package such as Linux
+distribution or some all in one package including web server and MySQL
+server.
+
+Generally you can customize some basic aspects (paths to some files and
+behavior) in :file:`libraries/vendor_config.php`.
+
+For example if you want setup script to generate config file in var, change
+``SETUP_CONFIG_FILE`` to :file:`/var/lib/phpmyadmin/config.inc.php` and you
+will also probably want to skip directory writable check, so set
+``SETUP_DIR_WRITABLE`` to false.
+
+External libraries
+------------------
+
+phpMyAdmin includes several external libraries, you might want to
+replace them with system ones if they are available, but please note
+that you should test whether version you provide is compatible with the
+one we ship.
+
+Currently known list of external libraries:
+
+js/jquery 
+    jQuery js framework and various jQuery based libraries.
+
+libraries/php-gettext 
+    php-gettext library
+libraries/tcpdf 
+    tcpdf library, stripped down of not needed files 
+
diff --git a/phpmyadmin/examples/config.manyhosts.inc.php b/phpmyadmin/examples/config.manyhosts.inc.php
new file mode 100644
index 0000000..ad29c3a
--- /dev/null
+++ b/phpmyadmin/examples/config.manyhosts.inc.php
@@ -0,0 +1,46 @@
+<?php
+
+/**
+ * This example configuration shows how to configure phpMyAdmin for
+ * many hosts that all have identical configuration otherwise. To add
+ * a new host, just drop it into $hosts below. Contributed by
+ * Matthew Hawkins.
+ */
+
+$i=0;
+$hosts = array (
+    "foo.example.com",
+    "bar.example.com",
+    "baz.example.com",
+    "quux.example.com",
+);
+
+foreach ($hosts as $host) {
+    $i++;
+    $cfg['Servers'][$i]['host']     = $host;
+    $cfg['Servers'][$i]['port']     = '';
+    $cfg['Servers'][$i]['socket']   = '';
+    $cfg['Servers'][$i]['connect_type']     = 'tcp';
+    $cfg['Servers'][$i]['extension']        = 'mysql';
+    $cfg['Servers'][$i]['compress'] = false;
+    $cfg['Servers'][$i]['controluser']      = 'pma';
+    $cfg['Servers'][$i]['controlpass']      = 'pmapass';
+    $cfg['Servers'][$i]['auth_type']        = 'cookie';
+    $cfg['Servers'][$i]['user']     = '';
+    $cfg['Servers'][$i]['password'] = '';
+    $cfg['Servers'][$i]['only_db']  = '';
+    $cfg['Servers'][$i]['verbose']  = '';
+    $cfg['Servers'][$i]['pmadb']    = 'phpmyadmin';
+    $cfg['Servers'][$i]['bookmarktable'] = 'pma__bookmark';
+    $cfg['Servers'][$i]['relation'] = 'pma__relation';
+    $cfg['Servers'][$i]['table_info'] = 'pma__table_info';
+    $cfg['Servers'][$i]['table_coords'] = 'pma__table_coords';
+    $cfg['Servers'][$i]['pdf_pages'] = 'pma__pdf_pages';
+    $cfg['Servers'][$i]['column_info'] = 'pma__column_info';
+    $cfg['Servers'][$i]['history'] = 'pma__history';
+    $cfg['Servers'][$i]['table_uiprefs'] = 'pma__table_uiprefs';
+    $cfg['Servers'][$i]['tracking'] = 'pma__tracking';
+    $cfg['Servers'][$i]['designer_coords'] = 'pma__designer_coords';
+    $cfg['Servers'][$i]['userconfig'] = 'pma__userconfig';
+    $cfg['Servers'][$i]['recent'] = 'pma__recent';
+}
diff --git a/phpmyadmin/examples/create_tables.sql b/phpmyadmin/examples/create_tables.sql
new file mode 100644
index 0000000..c3a62a2
--- /dev/null
+++ b/phpmyadmin/examples/create_tables.sql
@@ -0,0 +1,241 @@
+-- --------------------------------------------------------
+-- SQL Commands to set up the pmadb as described in the documentation.
+-- 
+-- This file is meant for use with MySQL 5 and above!
+-- 
+-- This script expects the user pma to already be existing. If we would put a
+-- line here to create him too many users might just use this script and end
+-- up with having the same password for the controluser.
+--                                                     
+-- This user "pma" must be defined in config.inc.php (controluser/controlpass)                         
+--                                                  
+-- Please don't forget to set up the tablenames in config.inc.php                                 
+-- 
+
+-- --------------------------------------------------------
+
+-- 
+-- Database : `phpmyadmin`
+-- 
+CREATE DATABASE IF NOT EXISTS `phpmyadmin`
+  DEFAULT CHARACTER SET utf8 COLLATE utf8_bin;
+USE phpmyadmin;
+
+-- --------------------------------------------------------
+
+-- 
+-- Privileges
+-- 
+-- (activate this statement if necessary)
+-- GRANT SELECT, INSERT, DELETE, UPDATE ON `phpmyadmin`.* TO
+--    'pma'@localhost;
+
+-- --------------------------------------------------------
+
+-- 
+-- Table structure for table `pma__bookmark`
+-- 
+
+CREATE TABLE IF NOT EXISTS `pma__bookmark` (
+  `id` int(11) NOT NULL auto_increment,
+  `dbase` varchar(255) NOT NULL default '',
+  `user` varchar(255) NOT NULL default '',
+  `label` varchar(255) COLLATE utf8_general_ci NOT NULL default '',
+  `query` text NOT NULL,
+  PRIMARY KEY  (`id`)
+)
+  ENGINE=MyISAM COMMENT='Bookmarks'
+  DEFAULT CHARACTER SET utf8 COLLATE utf8_bin;
+
+-- --------------------------------------------------------
+
+-- 
+-- Table structure for table `pma__column_info`
+-- 
+
+CREATE TABLE IF NOT EXISTS `pma__column_info` (
+  `id` int(5) unsigned NOT NULL auto_increment,
+  `db_name` varchar(64) NOT NULL default '',
+  `table_name` varchar(64) NOT NULL default '',
+  `column_name` varchar(64) NOT NULL default '',
+  `comment` varchar(255) COLLATE utf8_general_ci NOT NULL default '',
+  `mimetype` varchar(255) COLLATE utf8_general_ci NOT NULL default '',
+  `transformation` varchar(255) NOT NULL default '',
+  `transformation_options` varchar(255) NOT NULL default '',
+  PRIMARY KEY  (`id`),
+  UNIQUE KEY `db_name` (`db_name`,`table_name`,`column_name`)
+)
+  ENGINE=MyISAM COMMENT='Column information for phpMyAdmin'
+  DEFAULT CHARACTER SET utf8 COLLATE utf8_bin;
+
+-- --------------------------------------------------------
+
+-- 
+-- Table structure for table `pma__history`
+-- 
+
+CREATE TABLE IF NOT EXISTS `pma__history` (
+  `id` bigint(20) unsigned NOT NULL auto_increment,
+  `username` varchar(64) NOT NULL default '',
+  `db` varchar(64) NOT NULL default '',
+  `table` varchar(64) NOT NULL default '',
+  `timevalue` timestamp NOT NULL,
+  `sqlquery` text NOT NULL,
+  PRIMARY KEY  (`id`),
+  KEY `username` (`username`,`db`,`table`,`timevalue`)
+)
+  ENGINE=MyISAM COMMENT='SQL history for phpMyAdmin'
+  DEFAULT CHARACTER SET utf8 COLLATE utf8_bin;
+
+-- --------------------------------------------------------
+
+-- 
+-- Table structure for table `pma__pdf_pages`
+-- 
+
+CREATE TABLE IF NOT EXISTS `pma__pdf_pages` (
+  `db_name` varchar(64) NOT NULL default '',
+  `page_nr` int(10) unsigned NOT NULL auto_increment,
+  `page_descr` varchar(50) COLLATE utf8_general_ci NOT NULL default '',
+  PRIMARY KEY  (`page_nr`),
+  KEY `db_name` (`db_name`)
+)
+  ENGINE=MyISAM COMMENT='PDF relation pages for phpMyAdmin'
+  DEFAULT CHARACTER SET utf8 COLLATE utf8_bin;
+
+-- --------------------------------------------------------
+
+--
+-- Table structure for table `pma__recent`
+--
+
+CREATE TABLE IF NOT EXISTS `pma__recent` (
+  `username` varchar(64) NOT NULL,
+  `tables` text NOT NULL,
+  PRIMARY KEY (`username`)
+)
+  ENGINE=MyISAM COMMENT='Recently accessed tables'
+  DEFAULT CHARACTER SET utf8 COLLATE utf8_bin;
+
+-- --------------------------------------------------------
+
+--
+-- Table structure for table `pma__table_uiprefs`
+--
+
+CREATE TABLE IF NOT EXISTS `pma__table_uiprefs` (
+  `username` varchar(64) NOT NULL,
+  `db_name` varchar(64) NOT NULL,
+  `table_name` varchar(64) NOT NULL,
+  `prefs` text NOT NULL,
+  `last_update` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
+  PRIMARY KEY (`username`,`db_name`,`table_name`)
+)
+  ENGINE=MyISAM COMMENT='Tables'' UI preferences'
+  DEFAULT CHARACTER SET utf8 COLLATE utf8_bin;
+
+-- --------------------------------------------------------
+
+-- 
+-- Table structure for table `pma__relation`
+-- 
+
+CREATE TABLE IF NOT EXISTS `pma__relation` (
+  `master_db` varchar(64) NOT NULL default '',
+  `master_table` varchar(64) NOT NULL default '',
+  `master_field` varchar(64) NOT NULL default '',
+  `foreign_db` varchar(64) NOT NULL default '',
+  `foreign_table` varchar(64) NOT NULL default '',
+  `foreign_field` varchar(64) NOT NULL default '',
+  PRIMARY KEY  (`master_db`,`master_table`,`master_field`),
+  KEY `foreign_field` (`foreign_db`,`foreign_table`)
+)
+  ENGINE=MyISAM COMMENT='Relation table'
+  DEFAULT CHARACTER SET utf8 COLLATE utf8_bin;
+
+-- --------------------------------------------------------
+
+-- 
+-- Table structure for table `pma__table_coords`
+-- 
+
+CREATE TABLE IF NOT EXISTS `pma__table_coords` (
+  `db_name` varchar(64) NOT NULL default '',
+  `table_name` varchar(64) NOT NULL default '',
+  `pdf_page_number` int(11) NOT NULL default '0',
+  `x` float unsigned NOT NULL default '0',
+  `y` float unsigned NOT NULL default '0',
+  PRIMARY KEY  (`db_name`,`table_name`,`pdf_page_number`)
+)
+  ENGINE=MyISAM COMMENT='Table coordinates for phpMyAdmin PDF output'
+  DEFAULT CHARACTER SET utf8 COLLATE utf8_bin;
+
+-- --------------------------------------------------------
+
+-- 
+-- Table structure for table `pma__table_info`
+-- 
+
+CREATE TABLE IF NOT EXISTS `pma__table_info` (
+  `db_name` varchar(64) NOT NULL default '',
+  `table_name` varchar(64) NOT NULL default '',
+  `display_field` varchar(64) NOT NULL default '',
+  PRIMARY KEY  (`db_name`,`table_name`)
+)
+  ENGINE=MyISAM COMMENT='Table information for phpMyAdmin'
+  DEFAULT CHARACTER SET utf8 COLLATE utf8_bin;
+
+-- --------------------------------------------------------
+
+-- 
+-- Table structure for table `pma__designer_coords`
+-- 
+
+CREATE TABLE IF NOT EXISTS `pma__designer_coords` (
+  `db_name` varchar(64) NOT NULL default '',
+  `table_name` varchar(64) NOT NULL default '',
+  `x` INT,
+  `y` INT,
+  `v` TINYINT,
+  `h` TINYINT,
+  PRIMARY KEY (`db_name`,`table_name`)
+)
+  ENGINE=MyISAM COMMENT='Table coordinates for Designer'
+  DEFAULT CHARACTER SET utf8 COLLATE utf8_bin;
+
+-- --------------------------------------------------------
+
+-- 
+-- Table structure for table `pma__tracking`
+-- 
+
+CREATE TABLE IF NOT EXISTS `pma__tracking` (
+  `db_name` varchar(64) NOT NULL,
+  `table_name` varchar(64) NOT NULL,
+  `version` int(10) unsigned NOT NULL,
+  `date_created` datetime NOT NULL,
+  `date_updated` datetime NOT NULL,
+  `schema_snapshot` text NOT NULL,
+  `schema_sql` text,
+  `data_sql` longtext,
+  `tracking` set('UPDATE','REPLACE','INSERT','DELETE','TRUNCATE','CREATE DATABASE','ALTER DATABASE','DROP DATABASE','CREATE TABLE','ALTER TABLE','RENAME TABLE','DROP TABLE','CREATE INDEX','DROP INDEX','CREATE VIEW','ALTER VIEW','DROP VIEW') default NULL,
+  `tracking_active` int(1) unsigned NOT NULL default '1',
+  PRIMARY KEY  (`db_name`,`table_name`,`version`)
+)
+  ENGINE=MyISAM ROW_FORMAT=COMPACT COMMENT='Database changes tracking for phpMyAdmin'
+  DEFAULT CHARACTER SET utf8 COLLATE utf8_bin;
+
+-- --------------------------------------------------------
+
+--
+-- Table structure for table `pma__userconfig`
+--
+
+CREATE TABLE IF NOT EXISTS `pma__userconfig` (
+  `username` varchar(64) NOT NULL,
+  `timevalue` timestamp NOT NULL,
+  `config_data` text NOT NULL,
+  PRIMARY KEY  (`username`)
+)
+  ENGINE=MyISAM COMMENT='User preferences storage for phpMyAdmin'
+  DEFAULT CHARACTER SET utf8 COLLATE utf8_bin;
diff --git a/phpmyadmin/examples/create_tables_drizzle.sql b/phpmyadmin/examples/create_tables_drizzle.sql
new file mode 100644
index 0000000..21c24ca
--- /dev/null
+++ b/phpmyadmin/examples/create_tables_drizzle.sql
@@ -0,0 +1,228 @@
+-- --------------------------------------------------------
+-- SQL Commands to set up the pmadb as described in the documentation.
+-- 
+-- This file is meant for use with Drizzle 2011.03.13 and above!
+-- 
+-- This script expects that you take care of database permissions.
+--
+-- Please don't forget to set up the tablenames in config.inc.php
+-- 
+
+-- --------------------------------------------------------
+
+-- 
+-- Database : `phpmyadmin`
+-- 
+CREATE DATABASE IF NOT EXISTS `phpmyadmin`
+  COLLATE utf8_bin;
+USE phpmyadmin;
+
+-- --------------------------------------------------------
+
+-- 
+-- Table structure for table `pma__bookmark`
+-- 
+
+CREATE TABLE IF NOT EXISTS `pma__bookmark` (
+  `id` int(11) NOT NULL auto_increment,
+  `dbase` varchar(255) NOT NULL default '',
+  `user` varchar(255) NOT NULL default '',
+  `label` varchar(255) COLLATE utf8_general_ci NOT NULL default '',
+  `query` text NOT NULL,
+  PRIMARY KEY  (`id`)
+)
+  ENGINE=InnoDB COMMENT='Bookmarks'
+  COLLATE utf8_bin;
+
+-- --------------------------------------------------------
+
+-- 
+-- Table structure for table `pma__column_info`
+-- 
+
+CREATE TABLE IF NOT EXISTS `pma__column_info` (
+  `id` int(5) NOT NULL auto_increment,
+  `db_name` varchar(64) NOT NULL default '',
+  `table_name` varchar(64) NOT NULL default '',
+  `column_name` varchar(64) NOT NULL default '',
+  `comment` varchar(255) COLLATE utf8_general_ci NOT NULL default '',
+  `mimetype` varchar(255) COLLATE utf8_general_ci NOT NULL default '',
+  `transformation` varchar(255) NOT NULL default '',
+  `transformation_options` varchar(255) NOT NULL default '',
+  PRIMARY KEY  (`id`),
+  UNIQUE KEY `db_name` (`db_name`,`table_name`,`column_name`)
+)
+  ENGINE=InnoDB COMMENT='Column information for phpMyAdmin'
+  COLLATE utf8_bin;
+
+-- --------------------------------------------------------
+
+-- 
+-- Table structure for table `pma__history`
+-- 
+
+CREATE TABLE IF NOT EXISTS `pma__history` (
+  `id` bigint(20) NOT NULL auto_increment,
+  `username` varchar(64) NOT NULL default '',
+  `db` varchar(64) NOT NULL default '',
+  `table` varchar(64) NOT NULL default '',
+  `timevalue` timestamp NOT NULL,
+  `sqlquery` text NOT NULL,
+  PRIMARY KEY  (`id`),
+  KEY `username` (`username`,`db`,`table`,`timevalue`)
+)
+  ENGINE=InnoDB COMMENT='SQL history for phpMyAdmin'
+  COLLATE utf8_bin;
+
+-- --------------------------------------------------------
+
+-- 
+-- Table structure for table `pma__pdf_pages`
+-- 
+
+CREATE TABLE IF NOT EXISTS `pma__pdf_pages` (
+  `db_name` varchar(64) NOT NULL default '',
+  `page_nr` int(10) NOT NULL auto_increment,
+  `page_descr` varchar(50) COLLATE utf8_general_ci NOT NULL default '',
+  PRIMARY KEY  (`page_nr`),
+  KEY `db_name` (`db_name`)
+)
+  ENGINE=InnoDB COMMENT='PDF relation pages for phpMyAdmin'
+  COLLATE utf8_bin;
+
+-- --------------------------------------------------------
+
+--
+-- Table structure for table `pma__recent`
+--
+
+CREATE TABLE IF NOT EXISTS `pma__recent` (
+  `username` varchar(64) NOT NULL,
+  `tables` text NOT NULL,
+  PRIMARY KEY (`username`)
+)
+  ENGINE=InnoDB COMMENT='Recently accessed tables'
+  COLLATE utf8_bin;
+
+-- --------------------------------------------------------
+
+--
+-- Table structure for table `pma__table_uiprefs`
+--
+
+CREATE TABLE IF NOT EXISTS `pma__table_uiprefs` (
+  `username` varchar(64) NOT NULL,
+  `db_name` varchar(64) NOT NULL,
+  `table_name` varchar(64) NOT NULL,
+  `prefs` text NOT NULL,
+  `last_update` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
+  PRIMARY KEY (`username`,`db_name`,`table_name`)
+)
+  ENGINE=InnoDB COMMENT='Tables'' UI preferences'
+  COLLATE utf8_bin;
+
+-- --------------------------------------------------------
+
+-- 
+-- Table structure for table `pma__relation`
+-- 
+
+CREATE TABLE IF NOT EXISTS `pma__relation` (
+  `master_db` varchar(64) NOT NULL default '',
+  `master_table` varchar(64) NOT NULL default '',
+  `master_field` varchar(64) NOT NULL default '',
+  `foreign_db` varchar(64) NOT NULL default '',
+  `foreign_table` varchar(64) NOT NULL default '',
+  `foreign_field` varchar(64) NOT NULL default '',
+  PRIMARY KEY  (`master_db`,`master_table`,`master_field`),
+  KEY `foreign_field` (`foreign_db`,`foreign_table`)
+)
+  ENGINE=InnoDB COMMENT='Relation table'
+  COLLATE utf8_bin;
+
+-- --------------------------------------------------------
+
+-- 
+-- Table structure for table `pma__table_coords`
+-- 
+
+CREATE TABLE IF NOT EXISTS `pma__table_coords` (
+  `db_name` varchar(64) NOT NULL default '',
+  `table_name` varchar(64) NOT NULL default '',
+  `pdf_page_number` int(11) NOT NULL default '0',
+  `x` float NOT NULL default '0',
+  `y` float NOT NULL default '0',
+  PRIMARY KEY  (`db_name`,`table_name`,`pdf_page_number`)
+)
+  ENGINE=InnoDB COMMENT='Table coordinates for phpMyAdmin PDF output'
+  COLLATE utf8_bin;
+
+-- --------------------------------------------------------
+
+-- 
+-- Table structure for table `pma__table_info`
+-- 
+
+CREATE TABLE IF NOT EXISTS `pma__table_info` (
+  `db_name` varchar(64) NOT NULL default '',
+  `table_name` varchar(64) NOT NULL default '',
+  `display_field` varchar(64) NOT NULL default '',
+  PRIMARY KEY  (`db_name`,`table_name`)
+)
+  ENGINE=InnoDB COMMENT='Table information for phpMyAdmin'
+  COLLATE utf8_bin;
+
+-- --------------------------------------------------------
+
+-- 
+-- Table structure for table `pma__designer_coords`
+-- 
+
+CREATE TABLE IF NOT EXISTS `pma__designer_coords` (
+  `db_name` varchar(64) NOT NULL default '',
+  `table_name` varchar(64) NOT NULL default '',
+  `x` INT,
+  `y` INT,
+  `v` INT,
+  `h` INT,
+  PRIMARY KEY (`db_name`,`table_name`)
+)
+  ENGINE=InnoDB COMMENT='Table coordinates for Designer'
+  COLLATE utf8_bin;
+
+-- --------------------------------------------------------
+
+-- 
+-- Table structure for table `pma__tracking`
+-- 
+
+CREATE TABLE IF NOT EXISTS `pma__tracking` (
+  `db_name` varchar(64) NOT NULL,
+  `table_name` varchar(64) NOT NULL,
+  `version` int(10) NOT NULL,
+  `date_created` datetime NOT NULL,
+  `date_updated` datetime NOT NULL,
+  `schema_snapshot` text NOT NULL,
+  `schema_sql` text,
+  `data_sql` text,
+  `tracking` varchar(15) default NULL,
+  `tracking_active` int(1) NOT NULL default '1',
+  PRIMARY KEY  (`db_name`,`table_name`,`version`)
+)
+  ENGINE=InnoDB
+  COLLATE utf8_bin;
+
+-- --------------------------------------------------------
+
+--
+-- Table structure for table `pma__userconfig`
+--
+
+CREATE TABLE IF NOT EXISTS `pma__userconfig` (
+  `username` varchar(64) NOT NULL,
+  `timevalue` timestamp NOT NULL,
+  `config_data` text NOT NULL,
+  PRIMARY KEY  (`username`)
+)
+  ENGINE=InnoDB COMMENT='User preferences storage for phpMyAdmin'
+  COLLATE utf8_bin;
diff --git a/phpmyadmin/examples/openid.php b/phpmyadmin/examples/openid.php
new file mode 100644
index 0000000..563b230
--- /dev/null
+++ b/phpmyadmin/examples/openid.php
@@ -0,0 +1,158 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * Single signon for phpMyAdmin using OpenID
+ *
+ * This is just example how to use single signon with phpMyAdmin, it is
+ * not intended to be perfect code and look, only shows how you can
+ * integrate this functionality in your application.
+ *
+ * It uses OpenID pear package, see http://pear.php.net/package/OpenID
+ *
+ * User first authenticates using OpenID and based on content of $AUTH_MAP
+ * the login information is passed to phpMyAdmin in session data.
+ *
+ * @package    PhpMyAdmin
+ * @subpackage Example
+ */
+
+if (false === @include_once 'OpenID/RelyingParty.php') {
+    exit;
+}
+
+/**
+ * Map of authenticated users to MySQL user/password pairs.
+ */
+$AUTH_MAP = array(
+    'http://launchpad.net/~username' => array(
+        'user' => 'root',
+        'password' => '',
+        ),
+    );
+
+/**
+ * Simple function to show HTML page with given content.
+ *
+ * @return void
+ */
+function show_page($contents)
+{
+    header('Content-Type: text/html; charset=utf-8');
+    echo '<?xml version="1.0" encoding="utf-8"?>' . "\n";
+    ?>
+<!DOCTYPE HTML>
+<html lang="en" dir="ltr">
+<head>
+    <link rel="icon" href="../favicon.ico" type="image/x-icon" />
+    <link rel="shortcut icon" href="../favicon.ico" type="image/x-icon" />
+    <meta charset="utf-8" />
+    <title>phpMyAdmin OpenID signon example</title>
+</head>
+<body>
+<?php
+if (isset($_SESSION) && isset($_SESSION['PMA_single_signon_error_message'])) {
+    echo '<p class="error">' . $_SESSION['PMA_single_signon_message'] . '</p>';
+    unset($_SESSION['PMA_single_signon_message']);
+}
+echo $contents;
+?>
+</body>
+</html>
+<?php
+}
+
+/* Need to have cookie visible from parent directory */
+session_set_cookie_params(0, '/', '', 0);
+/* Create signon session */
+$session_name = 'SignonSession';
+session_name($session_name);
+session_start();
+
+// Determine realm and return_to
+$base = 'http';
+if (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] == 'on') {
+    $base .= 's';
+}
+$base .= '://' . $_SERVER['SERVER_NAME'] . ':' . $_SERVER['SERVER_PORT'];
+
+$realm = $base . '/';
+$returnTo = $base . dirname($_SERVER['PHP_SELF']);
+if ($returnTo[strlen($returnTo) - 1] != '/') {
+    $returnTo .= '/';
+}
+$returnTo .= 'openid.php';
+
+/* Display form */
+if (!count($_GET) && !count($_POST) || isset($_GET['phpMyAdmin'])) {
+    /* Show simple form */
+    $content = '<form action="openid.php" method="post">
+OpenID: <input type="text" name="identifier" /><br />
+<input type="submit" name="start" />
+</form>
+</body>
+</html>';
+    show_page($content);
+    exit;
+}
+
+/* Grab identifier */
+if (isset($_POST['identifier'])) {
+    $identifier = $_POST['identifier'];
+} else if (isset($_SESSION['identifier'])) {
+    $identifier = $_SESSION['identifier'];
+} else {
+    $identifier = null;
+}
+
+/* Create OpenID object */
+try {
+    $o = new OpenID_RelyingParty($returnTo, $realm, $identifier);
+} catch (OpenID_Exception $e) {
+    $contents = "<div class='relyingparty_results'>\n";
+    $contents .= "<pre>" . $e->getMessage() . "</pre>\n";
+    $contents .= "</div class='relyingparty_results'>";
+    show_page($contents);
+    exit;
+}
+
+/* Redirect to OpenID provider */
+if (isset($_POST['start'])) {
+    try {
+        $authRequest = $o->prepare();
+    } catch (OpenID_Exception $e) {
+        $contents = "<div class='relyingparty_results'>\n";
+        $contents .= "<pre>" . $e->getMessage() . "</pre>\n";
+        $contents .= "</div class='relyingparty_results'>";
+        show_page($contents);
+        exit;
+    }
+
+    $url = $authRequest->getAuthorizeURL();
+
+    header("Location: $url");
+    exit;
+} else {
+    /* Grab query string */
+    if (!count($_POST)) {
+        list(, $queryString) = explode('?', $_SERVER['REQUEST_URI']);
+    } else {
+        // I hate php sometimes
+        $queryString = file_get_contents('php://input');
+    }
+
+    /* Check reply */
+    $message = new OpenID_Message($queryString, OpenID_Message::FORMAT_HTTP);
+
+    $id = $message->get('openid.claimed_id');
+
+    if (!empty($id) && isset($AUTH_MAP[$id])) {
+        $_SESSION['PMA_single_signon_user'] = $AUTH_MAP[$id]['user'];
+        $_SESSION['PMA_single_signon_password'] = $AUTH_MAP[$id]['password'];
+        session_write_close();
+        /* Redirect to phpMyAdmin (should use absolute URL here!) */
+        header('Location: ../index.php');
+    } else {
+        show_page('<p>User not allowed!</p>');
+        exit;
+    }
+}
diff --git a/phpmyadmin/examples/signon-script.php b/phpmyadmin/examples/signon-script.php
new file mode 100644
index 0000000..0ef9734
--- /dev/null
+++ b/phpmyadmin/examples/signon-script.php
@@ -0,0 +1,29 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * Single signon for phpMyAdmin
+ *
+ * This is just example how to use script based single signon with
+ * phpMyAdmin, it is not intended to be perfect code and look, only
+ * shows how you can integrate this functionality in your application.
+ *
+ * @package    PhpMyAdmin
+ * @subpackage Example
+ */
+
+
+/**
+ * This function returns username and password.
+ *
+ * It can optionally use configured username as parameter.
+ *
+ * @param string $user
+ *
+ * @return array
+ */
+function get_login_credentials($user)
+{
+    return array('root', '');
+}
+
+?>
diff --git a/phpmyadmin/examples/signon.php b/phpmyadmin/examples/signon.php
new file mode 100644
index 0000000..6ab9e24
--- /dev/null
+++ b/phpmyadmin/examples/signon.php
@@ -0,0 +1,65 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * Single signon for phpMyAdmin
+ *
+ * This is just example how to use session based single signon with
+ * phpMyAdmin, it is not intended to be perfect code and look, only
+ * shows how you can integrate this functionality in your application.
+ *
+ * @package    PhpMyAdmin
+ * @subpackage Example
+ */
+
+/* Need to have cookie visible from parent directory */
+session_set_cookie_params(0, '/', '', 0);
+/* Create signon session */
+$session_name = 'SignonSession';
+session_name($session_name);
+session_start();
+
+/* Was data posted? */
+if (isset($_POST['user'])) {
+    /* Store there credentials */
+    $_SESSION['PMA_single_signon_user'] = $_POST['user'];
+    $_SESSION['PMA_single_signon_password'] = $_POST['password'];
+    $_SESSION['PMA_single_signon_host'] = $_POST['host'];
+    $_SESSION['PMA_single_signon_port'] = $_POST['port'];
+    /* Update another field of server configuration */
+    $_SESSION['PMA_single_signon_cfgupdate'] = array('verbose' => 'Signon test');
+    $id = session_id();
+    /* Close that session */
+    session_write_close();
+    /* Redirect to phpMyAdmin (should use absolute URL here!) */
+    header('Location: ../index.php');
+} else {
+    /* Show simple form */
+    header('Content-Type: text/html; charset=utf-8');
+    echo '<?xml version="1.0" encoding="utf-8"?>' . "\n";
+    ?>
+<!DOCTYPE HTML>
+<html lang="en" dir="ltr">
+<head>
+    <link rel="icon" href="../favicon.ico" type="image/x-icon" />
+    <link rel="shortcut icon" href="../favicon.ico" type="image/x-icon" />
+    <meta charset="utf-8" />
+    <title>phpMyAdmin single signon example</title>
+</head>
+<body>
+<?php
+if (isset($_SESSION['PMA_single_signon_error_message'])) {
+    echo '<p class="error">' . $_SESSION['PMA_single_signon_error_message'] . '</p>';
+}
+?>
+<form action="signon.php" method="post">
+Username: <input type="text" name="user" /><br />
+Password: <input type="password" name="password" /><br />
+Host: (will use the one from config.inc.php by default) <input type="text" name="host" /><br />
+Port: (will use the one from config.inc.php by default) <input type="text" name="port" /><br />
+<input type="submit" />
+</form>
+</body>
+</html>
+<?php
+}
+?>
diff --git a/phpmyadmin/examples/swekey.sample.conf b/phpmyadmin/examples/swekey.sample.conf
new file mode 100644
index 0000000..ebf1aed
--- /dev/null
+++ b/phpmyadmin/examples/swekey.sample.conf
@@ -0,0 +1,44 @@
+# This is a typical file used to enable Swekey hardware authentication.
+#
+# To activate the Swekey authentication add the following line to your config.inc.php file.
+#       $cfg['Servers'][$i]['auth_swekey_config'] = '/etc/swekey-pma.conf';
+# Then rename this file "swekey-pma.conf" and copy it to the /etc directory. 
+# Add all the Swekey ids you want to grant access to in the file.
+# After each Swekey id put the corresponding user name.
+#
+# If you don't know the id of a Swekey just visit http://www.swekey.com?sel=support 
+# while your Swekey is connected.
+#
+# If you need to purchase a Swekey please visit http://phpmyadmin.net/auth_key 
+# since this link provides funding to PhpMyAdmin.  
+#
+ 
+0000000000000000000000000000763A:root
+000000000000000000000000000089E4:steve
+0000000000000000000000000000231E:scott
+
+#
+# It is recommended to include the following lines to contact the
+# authentication servers in SSL mode.
+#
+
+SERVER_CHECK=https://auth-check-ssl.musbe.net
+SERVER_RNDTOKEN=https://auth-rnd-gen-ssl.musbe.net
+SERVER_STATUS=https://auth-status-ssl.musbe.net
+
+#
+# The path of the root certificate file used to ensure a secure
+# communication with the authentication servers in SSL mode. 
+# If not specified, will use musbe-ca.crt found in your
+# phpMyAdmin/libraries/auth/swekey.
+#
+
+#CA_FILE=/var/http-root/phpmyadmin/libraries/auth/swekey/musbe-ca.crt
+
+#
+# If your server receives many login requests, you can enable the random 
+# token caching to accelerate the authentication process.
+# Token caching is enabled by default.   
+#
+
+#ENABLE_TOKEN_CACHE=0
diff --git a/phpmyadmin/examples/upgrade_tables_mysql_4_1_2+.sql b/phpmyadmin/examples/upgrade_tables_mysql_4_1_2+.sql
new file mode 100644
index 0000000..df4046a
--- /dev/null
+++ b/phpmyadmin/examples/upgrade_tables_mysql_4_1_2+.sql
@@ -0,0 +1,144 @@
+-- -------------------------------------------------------------
+-- SQL Commands to upgrade pmadb for normal phpMyAdmin operation
+-- with MySQL 4.1.2 and above.
+--
+-- This file is meant for use with MySQL 4.1.2 and above!
+-- For older MySQL releases, please use create_tables.sql
+--
+-- If you are running one MySQL 4.1.0 or 4.1.1, please create the tables using
+-- create_tables.sql, then use this script.
+--
+-- Please don't forget to set up the tablenames in config.inc.php
+--
+
+-- --------------------------------------------------------
+
+--
+-- Database : `phpmyadmin`
+--
+ALTER DATABASE `phpmyadmin`
+  DEFAULT CHARACTER SET utf8 COLLATE utf8_bin;
+USE phpmyadmin;
+
+-- --------------------------------------------------------
+
+--
+-- Table structure for table `pma__bookmark`
+--
+ALTER TABLE `pma__bookmark`
+  DEFAULT CHARACTER SET utf8 COLLATE utf8_bin;
+
+ALTER TABLE `pma__bookmark`
+  CHANGE `dbase` `dbase` VARCHAR( 255 ) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL DEFAULT '';
+ALTER TABLE `pma__bookmark`
+  CHANGE `user` `user` VARCHAR( 255 ) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL DEFAULT '';
+ALTER TABLE `pma__bookmark`
+  CHANGE `label` `label` VARCHAR( 255 ) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '';
+ALTER TABLE `pma__bookmark`
+  CHANGE `query` `query` TEXT CHARACTER SET utf8 COLLATE utf8_bin NOT NULL;
+
+-- --------------------------------------------------------
+
+--
+-- Table structure for table `pma__column_info`
+--
+
+ALTER TABLE `pma__column_info`
+  DEFAULT CHARACTER SET utf8 COLLATE utf8_bin;
+
+ALTER TABLE `pma__column_info`
+  CHANGE `db_name` `db_name` VARCHAR(64) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL DEFAULT '';
+ALTER TABLE `pma__column_info`
+  CHANGE `table_name` `table_name` VARCHAR(64) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL DEFAULT '';
+ALTER TABLE `pma__column_info`
+  CHANGE `column_name` `column_name` VARCHAR(64) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL DEFAULT '';
+ALTER TABLE `pma__column_info`
+  CHANGE `comment` `comment` VARCHAR(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '';
+ALTER TABLE `pma__column_info`
+  CHANGE `mimetype` `mimetype` VARCHAR(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '';
+ALTER TABLE `pma__column_info`
+  CHANGE `transformation` `transformation` VARCHAR(255) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL DEFAULT '';
+ALTER TABLE `pma__column_info`
+  CHANGE `transformation_options` `transformation_options` VARCHAR(255) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL DEFAULT '';
+
+-- --------------------------------------------------------
+
+--
+-- Table structure for table `pma__history`
+--
+ALTER TABLE `pma__history`
+  DEFAULT CHARACTER SET utf8 COLLATE utf8_bin;
+
+ALTER TABLE `pma__history`
+  CHANGE `username` `username` VARCHAR(64) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL DEFAULT '';
+ALTER TABLE `pma__history`
+  CHANGE `db` `db` VARCHAR(64) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL DEFAULT '';
+ALTER TABLE `pma__history`
+  CHANGE `table` `table` VARCHAR(64) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL DEFAULT '';
+ALTER TABLE `pma__history`
+  CHANGE `sqlquery` `sqlquery` TEXT CHARACTER SET utf8 COLLATE utf8_bin NOT NULL;
+
+-- --------------------------------------------------------
+
+--
+-- Table structure for table `pma__pdf_pages`
+--
+
+ALTER TABLE `pma__pdf_pages`
+  DEFAULT CHARACTER SET utf8 COLLATE utf8_bin;
+
+ALTER TABLE `pma__pdf_pages`
+  CHANGE `db_name` `db_name` VARCHAR(64) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL DEFAULT '';
+ALTER TABLE `pma__pdf_pages`
+  CHANGE `page_descr` `page_descr` VARCHAR(50) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL default '';
+
+-- --------------------------------------------------------
+
+--
+-- Table structure for table `pma__relation`
+--
+ALTER TABLE `pma__relation`
+  DEFAULT CHARACTER SET utf8 COLLATE utf8_bin;
+
+ALTER TABLE `pma__relation`
+  CHANGE `master_db` `master_db` VARCHAR(64) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL DEFAULT '';
+ALTER TABLE `pma__relation`
+  CHANGE `master_table` `master_table` VARCHAR(64) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL DEFAULT '';
+ALTER TABLE `pma__relation`
+  CHANGE `master_field` `master_field` VARCHAR(64) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL DEFAULT '';
+ALTER TABLE `pma__relation`
+  CHANGE `foreign_db` `foreign_db` VARCHAR(64) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL DEFAULT '';
+ALTER TABLE `pma__relation`
+  CHANGE `foreign_table` `foreign_table` VARCHAR(64) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL DEFAULT '';
+ALTER TABLE `pma__relation`
+  CHANGE `foreign_field` `foreign_field` VARCHAR(64) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL DEFAULT '';
+
+-- --------------------------------------------------------
+
+--
+-- Table structure for table `pma__table_coords`
+--
+
+ALTER TABLE `pma__table_coords`
+  DEFAULT CHARACTER SET utf8 COLLATE utf8_bin;
+
+ALTER TABLE `pma__table_coords`
+  CHANGE `db_name` `db_name` VARCHAR(64) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL DEFAULT '';
+ALTER TABLE `pma__table_coords`
+  CHANGE `table_name` `table_name` VARCHAR(64) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL DEFAULT '';
+
+-- --------------------------------------------------------
+
+--
+-- Table structure for table `pma__table_info`
+--
+
+ALTER TABLE `pma__table_info`
+  DEFAULT CHARACTER SET utf8 COLLATE utf8_bin;
+
+ALTER TABLE `pma__table_info`
+  CHANGE `db_name` `db_name` VARCHAR(64) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL DEFAULT '';
+ALTER TABLE `pma__table_info`
+  CHANGE `table_name` `table_name` VARCHAR(64) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL DEFAULT '';
+ALTER TABLE `pma__table_info`
+  CHANGE `display_field` `display_field` VARCHAR(64) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL DEFAULT '';
diff --git a/phpmyadmin/export.php b/phpmyadmin/export.php
new file mode 100644
index 0000000..c2373e3
--- /dev/null
+++ b/phpmyadmin/export.php
@@ -0,0 +1,979 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * Main export handling code
+ *
+ * @package PhpMyAdmin
+ */
+
+/**
+ * Get the variables sent or posted to this script and a core script
+ */
+require_once 'libraries/common.inc.php';
+require_once 'libraries/zip.lib.php';
+require_once 'libraries/plugin_interface.lib.php';
+
+/**
+ * Sets globals from $_POST
+ *
+ * - Please keep the parameters in order of their appearance in the form
+ * - Some of these parameters are not used, as the code below directly
+ *   verifies from the superglobal $_POST or $_REQUEST
+ */
+$post_params = array(
+        'db',
+        'table',
+        'single_table',
+        'export_type',
+        'export_method',
+        'quick_or_custom',
+        'db_select',
+        'table_select',
+        'limit_to',
+        'limit_from',
+        'allrows',
+        'output_format',
+        'filename_template',
+        'remember_template',
+        'charset_of_file',
+        'compression',
+        'what',
+        'htmlword_structure_or_data',
+        'htmlword_null',
+        'htmlword_columns',
+        'mediawiki_structure_or_data',
+        'mediawiki_caption',
+        'pdf_report_title',
+        'pdf_structure_or_data',
+        'odt_structure_or_data',
+        'odt_relation',
+        'odt_comments',
+        'odt_mime',
+        'odt_columns',
+        'odt_null',
+        'codegen_structure_or_data',
+        'codegen_format',
+        'excel_null',
+        'excel_removeCRLF',
+        'excel_columns',
+        'excel_edition',
+        'excel_structure_or_data',
+        'yaml_structure_or_data',
+        'ods_null',
+        'ods_structure_or_data',
+        'ods_columns',
+        'json_structure_or_data',
+        'xml_structure_or_data',
+        'xml_export_functions',
+        'xml_export_procedures',
+        'xml_export_tables',
+        'xml_export_triggers',
+        'xml_export_views',
+        'xml_export_contents',
+        'texytext_structure_or_data',
+        'texytext_columns',
+        'texytext_null',
+        'phparray_structure_or_data',
+        'sql_include_comments',
+        'sql_header_comment',
+        'sql_dates',
+        'sql_relation',
+        'sql_mime',
+        'sql_use_transaction',
+        'sql_disable_fk',
+        'sql_compatibility',
+        'sql_structure_or_data',
+        'sql_drop_table',
+        'sql_procedure_function',
+        'sql_create_table_statements',
+        'sql_if_not_exists',
+        'sql_auto_increment',
+        'sql_backquotes',
+        'sql_truncate',
+        'sql_delayed',
+        'sql_ignore',
+        'sql_type',
+        'sql_insert_syntax',
+        'sql_max_query_size',
+        'sql_hex_for_blob',
+        'sql_utc_time',
+        'csv_separator',
+        'csv_enclosed',
+        'csv_escaped',
+        'csv_terminated',
+        'csv_null',
+        'csv_removeCRLF',
+        'csv_columns',
+        'csv_structure_or_data',
+        // csv_replace should have been here but we use it directly from $_POST
+        'latex_caption',
+        'latex_structure_or_data',
+        'latex_structure_caption',
+        'latex_structure_continued_caption',
+        'latex_structure_label',
+        'latex_relation',
+        'latex_comments',
+        'latex_mime',
+        'latex_columns',
+        'latex_data_caption',
+        'latex_data_continued_caption',
+        'latex_data_label',
+        'latex_null'
+);
+
+foreach ($post_params as $one_post_param) {
+    if (isset($_POST[$one_post_param])) {
+        $GLOBALS[$one_post_param] = $_POST[$one_post_param];
+    }
+}
+
+// sanitize this parameter which will be used below in a file inclusion
+$what = PMA_securePath($what);
+
+PMA_Util::checkParameters(array('what', 'export_type'));
+
+// export class instance, not array of properties, as before
+$export_plugin = PMA_getPlugin(
+    "export",
+    $what,
+    'libraries/plugins/export/',
+    array(
+        'export_type' => $export_type,
+        'single_table' => isset($single_table)
+    )
+);
+
+// Backward compatbility
+$type = $what;
+
+// Check export type
+if (! isset($export_plugin)) {
+    PMA_fatalError(__('Bad type!'));
+}
+
+/**
+ * valid compression methods
+ */
+$compression_methods = array(
+    'zip',
+    'gzip',
+    'bzip2',
+);
+
+/**
+ * init and variable checking
+ */
+$compression = false;
+$onserver = false;
+$save_on_server = false;
+$buffer_needed = false;
+
+// Is it a quick or custom export?
+if ($_REQUEST['quick_or_custom'] == 'quick') {
+    $quick_export = true;
+} else {
+    $quick_export = false;
+}
+
+if ($_REQUEST['output_format'] == 'astext') {
+    $asfile = false;
+} else {
+    $asfile = true;
+    if (in_array($_REQUEST['compression'], $compression_methods)) {
+        $compression = $_REQUEST['compression'];
+        $buffer_needed = true;
+    }
+    if (($quick_export && ! empty($_REQUEST['quick_export_onserver']))
+        || (! $quick_export && ! empty($_REQUEST['onserver']))
+    ) {
+        if ($quick_export) {
+            $onserver = $_REQUEST['quick_export_onserver'];
+        } else {
+            $onserver = $_REQUEST['onserver'];
+        }
+        // Will we save dump on server?
+        $save_on_server = ! empty($cfg['SaveDir']) && $onserver;
+    }
+}
+
+// Does export require to be into file?
+if ($export_plugin->getProperties()->getForceFile() != null && ! $asfile) {
+    $message = PMA_Message::error(
+        __('Selected export type has to be saved in file!')
+    );
+    if ($export_type == 'server') {
+        $active_page = 'server_export.php';
+        include 'server_export.php';
+    } elseif ($export_type == 'database') {
+        $active_page = 'db_export.php';
+        include 'db_export.php';
+    } else {
+        $active_page = 'tbl_export.php';
+        include 'tbl_export.php';
+    }
+    exit();
+}
+
+// Generate error url and check for needed variables
+if ($export_type == 'server') {
+    $err_url = 'server_export.php?' . PMA_generate_common_url();
+} elseif ($export_type == 'database' && strlen($db)) {
+    $err_url = 'db_export.php?' . PMA_generate_common_url($db);
+    // Check if we have something to export
+    if (isset($table_select)) {
+        $tables = $table_select;
+    } else {
+        $tables = array();
+    }
+} elseif ($export_type == 'table' && strlen($db) && strlen($table)) {
+    $err_url = 'tbl_export.php?' . PMA_generate_common_url($db, $table);
+} else {
+    PMA_fatalError(__('Bad parameters!'));
+}
+
+/**
+ * Increase time limit for script execution and initializes some variables
+ */
+ at set_time_limit($cfg['ExecTimeLimit']);
+if (! empty($cfg['MemoryLimit'])) {
+    @ini_set('memory_limit', $cfg['MemoryLimit']);
+}
+
+// Start with empty buffer
+$dump_buffer = '';
+$dump_buffer_len = 0;
+
+// We send fake headers to avoid browser timeout when buffering
+$time_start = time();
+
+
+/**
+ * Detect ob_gzhandler
+ *
+ * @return bool
+ */
+function PMA_isGzHandlerEnabled()
+{
+    return in_array('ob_gzhandler', ob_list_handlers());
+}
+
+/**
+ * Detect whether gzencode is needed; it might not be needed if
+ * the server is already compressing by itself 
+ *
+ * @return bool Whether gzencode is needed 
+ */
+function PMA_gzencodeNeeded()
+{
+    if (@function_exists('gzencode')
+        && ! @ini_get('zlib.output_compression')
+        // Here, we detect Apache's mod_deflate so we bet that
+        // this module is active for this instance of phpMyAdmin
+        // and therefore, will gzip encode the content
+        && ! (function_exists('apache_get_modules')
+            && in_array('mod_deflate', apache_get_modules()))
+        && ! PMA_isGzHandlerEnabled()
+    ) {
+        return true;
+    } else {
+        return false;
+    }
+}
+
+/**
+ * Output handler for all exports, if needed buffering, it stores data into
+ * $dump_buffer, otherwise it prints thems out.
+ *
+ * @param string $line the insert statement
+ *
+ * @return bool Whether output succeeded
+ */
+function PMA_exportOutputHandler($line)
+{
+    global $time_start, $dump_buffer, $dump_buffer_len, $save_filename;
+
+    // Kanji encoding convert feature
+    if ($GLOBALS['output_kanji_conversion']) {
+        $line = PMA_kanji_str_conv(
+            $line,
+            $GLOBALS['knjenc'],
+            isset($GLOBALS['xkana']) ? $GLOBALS['xkana'] : ''
+        );
+    }
+    // If we have to buffer data, we will perform everything at once at the end
+    if ($GLOBALS['buffer_needed']) {
+
+        $dump_buffer .= $line;
+        if ($GLOBALS['onfly_compression']) {
+
+            $dump_buffer_len += strlen($line);
+
+            if ($dump_buffer_len > $GLOBALS['memory_limit']) {
+                if ($GLOBALS['output_charset_conversion']) {
+                    $dump_buffer = PMA_convert_string(
+                        'utf-8',
+                        $GLOBALS['charset_of_file'],
+                        $dump_buffer
+                    );
+                }
+                // as bzipped
+                if ($GLOBALS['compression'] == 'bzip2'
+                    && @function_exists('bzcompress')
+                ) {
+                    $dump_buffer = bzcompress($dump_buffer);
+                } elseif ($GLOBALS['compression'] == 'gzip'
+                     && PMA_gzencodeNeeded() 
+                ) {
+                    // as a gzipped file
+                    // without the optional parameter level because it bugs
+                    $dump_buffer = gzencode($dump_buffer);
+                }
+                if ($GLOBALS['save_on_server']) {
+                    $write_result = @fwrite($GLOBALS['file_handle'], $dump_buffer);
+                    if (! $write_result || ($write_result != strlen($dump_buffer))) {
+                        $GLOBALS['message'] = PMA_Message::error(
+                            __('Insufficient space to save the file %s.')
+                        );
+                        $GLOBALS['message']->addParam($save_filename);
+                        return false;
+                    }
+                } else {
+                    echo $dump_buffer;
+                }
+                $dump_buffer = '';
+                $dump_buffer_len = 0;
+            }
+        } else {
+            $time_now = time();
+            if ($time_start >= $time_now + 30) {
+                $time_start = $time_now;
+                header('X-pmaPing: Pong');
+            } // end if
+        }
+    } else {
+        if ($GLOBALS['asfile']) {
+            if ($GLOBALS['output_charset_conversion']) {
+                $line = PMA_convert_string(
+                    'utf-8',
+                    $GLOBALS['charset_of_file'],
+                    $line
+                );
+            }
+            if ($GLOBALS['save_on_server'] && strlen($line) > 0) {
+                $write_result = @fwrite($GLOBALS['file_handle'], $line);
+                if (! $write_result || ($write_result != strlen($line))) {
+                    $GLOBALS['message'] = PMA_Message::error(
+                        __('Insufficient space to save the file %s.')
+                    );
+                    $GLOBALS['message']->addParam($save_filename);
+                    return false;
+                }
+                $time_now = time();
+                if ($time_start >= $time_now + 30) {
+                    $time_start = $time_now;
+                    header('X-pmaPing: Pong');
+                } // end if
+            } else {
+                // We export as file - output normally
+                echo $line;
+            }
+        } else {
+            // We export as html - replace special chars
+            echo htmlspecialchars($line);
+        }
+    }
+    return true;
+} // end of the 'PMA_exportOutputHandler()' function
+
+// Defines the default <CR><LF> format.
+// For SQL always use \n as MySQL wants this on all platforms.
+if ($what == 'sql') {
+    $crlf = "\n";
+} else {
+    $crlf = PMA_Util::whichCrlf();
+}
+
+$output_kanji_conversion = function_exists('PMA_kanji_str_conv') && $type != 'xls';
+
+// Do we need to convert charset?
+$output_charset_conversion = $asfile
+    && $GLOBALS['PMA_recoding_engine'] != PMA_CHARSET_NONE
+    && isset($charset_of_file) && $charset_of_file != 'utf-8'
+    && $type != 'xls';
+
+// Use on the fly compression?
+$onfly_compression = $GLOBALS['cfg']['CompressOnFly']
+    && ($compression == 'gzip' || $compression == 'bzip2');
+if ($onfly_compression) {
+    $memory_limit = trim(@ini_get('memory_limit'));
+    // 2 MB as default
+    if (empty($memory_limit)) {
+        $memory_limit = 2 * 1024 * 1024;
+    }
+
+    if (strtolower(substr($memory_limit, -1)) == 'm') {
+        $memory_limit = (int)substr($memory_limit, 0, -1) * 1024 * 1024;
+    } elseif (strtolower(substr($memory_limit, -1)) == 'k') {
+        $memory_limit = (int)substr($memory_limit, 0, -1) * 1024;
+    } elseif (strtolower(substr($memory_limit, -1)) == 'g') {
+        $memory_limit = (int)substr($memory_limit, 0, -1) * 1024 * 1024 * 1024;
+    } else {
+        $memory_limit = (int)$memory_limit;
+    }
+
+    // Some of memory is needed for other thins and as treshold.
+    // Nijel: During export I had allocated (see memory_get_usage function)
+    //        approx 1.2MB so this comes from that.
+    if ($memory_limit > 1500000) {
+        $memory_limit -= 1500000;
+    }
+
+    // Some memory is needed for compression, assume 1/3
+    $memory_limit /= 8;
+}
+
+// Generate filename and mime type if needed
+if ($asfile) {
+    $pma_uri_parts = parse_url($cfg['PmaAbsoluteUri']);
+    if ($export_type == 'server') {
+        if (isset($remember_template)) {
+            $GLOBALS['PMA_Config']->setUserValue(
+                'pma_server_filename_template',
+                'Export/file_template_server',
+                $filename_template
+            );
+        }
+    } elseif ($export_type == 'database') {
+        if (isset($remember_template)) {
+            $GLOBALS['PMA_Config']->setUserValue(
+                'pma_db_filename_template',
+                'Export/file_template_database',
+                $filename_template
+            );
+        }
+    } else {
+        if (isset($remember_template)) {
+            $GLOBALS['PMA_Config']->setUserValue(
+                'pma_table_filename_template',
+                'Export/file_template_table',
+                $filename_template
+            );
+        }
+    }
+    $filename = PMA_Util::expandUserString($filename_template);
+    // remove dots in filename (coming from either the template or already
+    // part of the filename) to avoid a remote code execution vulnerability
+    $filename = PMA_sanitizeFilename($filename, $replaceDots = true);
+
+    // Grab basic dump extension and mime type
+    // Check if the user already added extension;
+    // get the substring where the extension would be if it was included
+    $extension_start_pos = strlen($filename) - strlen(
+        $export_plugin->getProperties()->getExtension()
+    ) - 1;
+    $user_extension = substr($filename, $extension_start_pos, strlen($filename));
+    $required_extension = "." . $export_plugin->getProperties()->getExtension();
+    if (strtolower($user_extension) != $required_extension) {
+        $filename  .= $required_extension;
+    }
+    $mime_type  = $export_plugin->getProperties()->getMimeType();
+
+    // If dump is going to be compressed, set correct mime_type and add
+    // compression to extension
+    if ($compression == 'bzip2') {
+        $filename  .= '.bz2';
+        $mime_type = 'application/x-bzip2';
+    } elseif ($compression == 'gzip') {
+        $filename  .= '.gz';
+        $mime_type = 'application/x-gzip';
+    } elseif ($compression == 'zip') {
+        $filename  .= '.zip';
+        $mime_type = 'application/zip';
+    }
+}
+
+// Open file on server if needed
+if ($save_on_server) {
+    $save_filename = PMA_Util::userDir($cfg['SaveDir'])
+        . preg_replace('@[/\\\\]@', '_', $filename);
+    unset($message);
+    if (file_exists($save_filename)
+        && ((! $quick_export && empty($onserverover))
+        || ($quick_export
+        && $_REQUEST['quick_export_onserverover'] != 'saveitover'))
+    ) {
+        $message = PMA_Message::error(
+            __('File %s already exists on server, change filename or check overwrite option.')
+        );
+        $message->addParam($save_filename);
+    } else {
+        if (is_file($save_filename) && ! is_writable($save_filename)) {
+            $message = PMA_Message::error(
+                __('The web server does not have permission to save the file %s.')
+            );
+            $message->addParam($save_filename);
+        } else {
+            if (! $file_handle = @fopen($save_filename, 'w')) {
+                $message = PMA_Message::error(
+                    __('The web server does not have permission to save the file %s.')
+                );
+                $message->addParam($save_filename);
+            }
+        }
+    }
+    if (isset($message)) {
+        if ($export_type == 'server') {
+            $active_page = 'server_export.php';
+            include 'server_export.php';
+        } elseif ($export_type == 'database') {
+            $active_page = 'db_export.php';
+            include 'db_export.php';
+        } else {
+            $active_page = 'tbl_export.php';
+            include 'tbl_export.php';
+        }
+        exit();
+    }
+}
+
+/**
+ * Send headers depending on whether the user chose to download a dump file
+ * or not
+ */
+if (! $save_on_server) {
+    if ($asfile) {
+        // Download
+        // (avoid rewriting data containing HTML with anchors and forms;
+        // this was reported to happen under Plesk)
+        @ini_set('url_rewriter.tags', '');
+        $filename = PMA_sanitizeFilename($filename);
+
+        PMA_downloadHeader($filename, $mime_type);
+    } else {
+        // HTML
+        if ($export_type == 'database') {
+            $num_tables = count($tables);
+            if ($num_tables == 0) {
+                $message = PMA_Message::error(__('No tables found in database.'));
+                $active_page = 'db_export.php';
+                include 'db_export.php';
+                exit();
+            }
+        }
+        $backup_cfgServer = $cfg['Server'];
+        $cfg['Server'] = $backup_cfgServer;
+        unset($backup_cfgServer);
+        echo "\n" . '<div style="text-align: ' . $cell_align_left . '">' . "\n";
+        //echo '    <pre>' . "\n";
+
+        /**
+         * Displays a back button with all the $_REQUEST data in the URL
+         * (store in a variable to also display after the textarea)
+         */
+        $back_button = '<p>[ <a href="';
+        if ($export_type == 'server') {
+            $back_button .= 'server_export.php?' . PMA_generate_common_url();
+        } elseif ($export_type == 'database') {
+            $back_button .= 'db_export.php?' . PMA_generate_common_url($db);
+        } else {
+            $back_button .= 'tbl_export.php?' . PMA_generate_common_url($db, $table);
+        }
+
+        // Convert the multiple select elements from an array to a string
+        if ($export_type == 'server' && isset($_REQUEST['db_select'])) {
+            $_REQUEST['db_select'] = implode(",", $_REQUEST['db_select']);
+        } elseif ($export_type == 'database' && isset($_REQUEST['table_select'])) {
+            $_REQUEST['table_select'] = implode(",", $_REQUEST['table_select']);
+        }
+
+        foreach ($_REQUEST as $name => $value) {
+            $back_button .= '&' . urlencode($name) . '=' . urlencode($value);
+        }
+        $back_button .= '&repopulate=1">Back</a> ]</p>';
+
+        echo $back_button;
+        echo '    <form name="nofunction">' . "\n"
+           // remove auto-select for now: there is no way to select
+           // only a part of the text; anyway, it should obey
+           // $cfg['TextareaAutoSelect']
+           //. '        <textarea name="sqldump" cols="50" rows="30" onclick="this.select();" id="textSQLDUMP" wrap="OFF">' . "\n";
+           . '        <textarea name="sqldump" cols="50" rows="30" id="textSQLDUMP" wrap="OFF">' . "\n";
+    } // end download
+}
+
+// Fake loop just to allow skip of remain of this code by break, I'd really
+// need exceptions here :-)
+do {
+
+    // Add possibly some comments to export
+    if (! $export_plugin->exportHeader($db)) {
+        break;
+    }
+
+    // Will we need relation & co. setup?
+    $do_relation = isset($GLOBALS[$what . '_relation']);
+    $do_comments = isset($GLOBALS[$what . '_include_comments']);
+    $do_mime     = isset($GLOBALS[$what . '_mime']);
+    if ($do_relation || $do_comments || $do_mime) {
+        $cfgRelation = PMA_getRelationsParam();
+    }
+    if ($do_mime) {
+        include_once 'libraries/transformations.lib.php';
+    }
+
+    // Include dates in export?
+    $do_dates = isset($GLOBALS[$what . '_dates']);
+
+    /**
+     * Builds the dump
+     */
+    // Gets the number of tables if a dump of a database has been required
+    if ($export_type == 'server') {
+        if (isset($db_select)) {
+            $tmp_select = implode($db_select, '|');
+            $tmp_select = '|' . $tmp_select . '|';
+        }
+        // Walk over databases
+        foreach ($GLOBALS['pma']->databases as $current_db) {
+            if (isset($tmp_select)
+                && strpos(' ' . $tmp_select, '|' . $current_db . '|')
+            ) {
+                if (! $export_plugin->exportDBHeader($current_db)) {
+                    break 2;
+                }
+                if (! $export_plugin->exportDBCreate($current_db)) {
+                    break 2;
+                }
+                if (method_exists($export_plugin, 'exportRoutines')
+                    && strpos($GLOBALS['sql_structure_or_data'], 'structure') !== false
+                    && isset($GLOBALS['sql_procedure_function'])
+                ) {
+                    $export_plugin->exportRoutines($current_db);
+                }
+
+                $tables = PMA_DBI_get_tables($current_db);
+                $views = array();
+                foreach ($tables as $table) {
+                    // if this is a view, collect it for later;
+                    // views must be exported after the tables
+                    $is_view = PMA_Table::isView($current_db, $table);
+                    if ($is_view) {
+                        $views[] = $table;
+                    }
+                    if ($GLOBALS[$what . '_structure_or_data'] == 'structure'
+                        || $GLOBALS[$what . '_structure_or_data'] == 'structure_and_data'
+                    ) {
+                        // for a view, export a stand-in definition of the table
+                        // to resolve view dependencies
+                        if (! $export_plugin->exportStructure(
+                            $current_db, $table, $crlf, $err_url,
+                            $is_view ? 'stand_in' : 'create_table', $export_type,
+                            $do_relation, $do_comments, $do_mime, $do_dates
+                        )) {
+                            break 3;
+                        }
+                    }
+                    // if this is a view or a merge table, don't export data
+                    if (($GLOBALS[$what . '_structure_or_data'] == 'data'
+                        || $GLOBALS[$what . '_structure_or_data'] == 'structure_and_data')
+                        && ! ($is_view || PMA_Table::isMerge($current_db, $table))
+                    ) {
+                        $local_query  = 'SELECT * FROM ' . PMA_Util::backquote($current_db)
+                            . '.' . PMA_Util::backquote($table);
+                        if (! $export_plugin->exportData($current_db, $table, $crlf, $err_url, $local_query)) {
+                            break 3;
+                        }
+                    }
+                    // now export the triggers (needs to be done after the data
+                    // because triggers can modify already imported tables)
+                    if ($GLOBALS[$what . '_structure_or_data'] == 'structure'
+                        || $GLOBALS[$what . '_structure_or_data'] == 'structure_and_data'
+                    ) {
+                        if (! $export_plugin->exportStructure(
+                            $current_db, $table, $crlf, $err_url,
+                            'triggers', $export_type,
+                            $do_relation, $do_comments, $do_mime, $do_dates
+                        )) {
+                            break 2;
+                        }
+                    }
+                }
+                foreach ($views as $view) {
+                    // no data export for a view
+                    if ($GLOBALS[$what . '_structure_or_data'] == 'structure'
+                        || $GLOBALS[$what . '_structure_or_data'] == 'structure_and_data'
+                    ) {
+                        if (! $export_plugin->exportStructure(
+                            $current_db, $view, $crlf, $err_url,
+                            'create_view', $export_type,
+                            $do_relation, $do_comments, $do_mime, $do_dates
+                        )) {
+                            break 3;
+                        }
+                    }
+                }
+                if (! $export_plugin->exportDBFooter($current_db)) {
+                    break 2;
+                }
+            }
+        }
+    } elseif ($export_type == 'database') {
+        if (! $export_plugin->exportDBHeader($db)) {
+            break;
+        }
+        if (! $export_plugin->exportDBCreate($db)) {
+            break;
+        }
+
+        if (method_exists($export_plugin, 'exportRoutines')
+            && strpos($GLOBALS['sql_structure_or_data'], 'structure') !== false
+            && isset($GLOBALS['sql_procedure_function'])
+        ) {
+            $export_plugin->exportRoutines($db);
+        }
+
+        $i = 0;
+        $views = array();
+        // $tables contains the choices from the user (via $table_select)
+        foreach ($tables as $table) {
+            // if this is a view, collect it for later; views must be exported after
+            // the tables
+            $is_view = PMA_Table::isView($db, $table);
+            if ($is_view) {
+                $views[] = $table;
+            }
+            if ($GLOBALS[$what . '_structure_or_data'] == 'structure'
+                || $GLOBALS[$what . '_structure_or_data'] == 'structure_and_data'
+            ) {
+                // for a view, export a stand-in definition of the table
+                // to resolve view dependencies
+                if (! $export_plugin->exportStructure(
+                    $db, $table, $crlf, $err_url,
+                    $is_view ? 'stand_in' : 'create_table', $export_type,
+                    $do_relation, $do_comments, $do_mime, $do_dates
+                )) {
+                    break 2;
+                }
+            }
+            // if this is a view or a merge table, don't export data
+            if (($GLOBALS[$what . '_structure_or_data'] == 'data'
+                || $GLOBALS[$what . '_structure_or_data'] == 'structure_and_data')
+                && ! ($is_view || PMA_Table::isMerge($db, $table))
+            ) {
+                $local_query  = 'SELECT * FROM ' . PMA_Util::backquote($db)
+                    . '.' . PMA_Util::backquote($table);
+                if (! $export_plugin->exportData($db, $table, $crlf, $err_url, $local_query)) {
+                    break 2;
+                }
+            }
+            // now export the triggers (needs to be done after the data because
+            // triggers can modify already imported tables)
+            if ($GLOBALS[$what . '_structure_or_data'] == 'structure'
+                || $GLOBALS[$what . '_structure_or_data'] == 'structure_and_data'
+            ) {
+                if (! $export_plugin->exportStructure(
+                    $db, $table, $crlf, $err_url,
+                    'triggers', $export_type,
+                    $do_relation, $do_comments, $do_mime, $do_dates
+                )) {
+                    break 2;
+                }
+            }
+        }
+        foreach ($views as $view) {
+            // no data export for a view
+            if ($GLOBALS[$what . '_structure_or_data'] == 'structure'
+                || $GLOBALS[$what . '_structure_or_data'] == 'structure_and_data'
+            ) {
+                if (! $export_plugin->exportStructure(
+                    $db, $view, $crlf, $err_url,
+                    'create_view', $export_type,
+                    $do_relation, $do_comments, $do_mime, $do_dates
+                )) {
+                    break 2;
+                }
+            }
+        }
+
+        if (! $export_plugin->exportDBFooter($db)) {
+            break;
+        }
+    } else {
+        if (! $export_plugin->exportDBHeader($db)) {
+            break;
+        }
+        // We export just one table
+        // $allrows comes from the form when "Dump all rows" has been selected
+        if (isset($allrows) && $allrows == '0' && $limit_to > 0 && $limit_from >= 0) {
+            $add_query  = ' LIMIT '
+                        . (($limit_from > 0) ? $limit_from . ', ' : '')
+                        . $limit_to;
+        } else {
+            $add_query  = '';
+        }
+
+        $is_view = PMA_Table::isView($db, $table);
+        if ($GLOBALS[$what . '_structure_or_data'] == 'structure'
+            || $GLOBALS[$what . '_structure_or_data'] == 'structure_and_data'
+        ) {
+            if (! $export_plugin->exportStructure(
+                $db, $table, $crlf, $err_url,
+                $is_view ? 'create_view' : 'create_table', $export_type,
+                $do_relation, $do_comments, $do_mime, $do_dates
+            )) {
+                break;
+            }
+        }
+        // If this is an export of a single view, we have to export data;
+        // for example, a PDF report
+        // if it is a merge table, no data is exported
+        if (($GLOBALS[$what . '_structure_or_data'] == 'data'
+            || $GLOBALS[$what . '_structure_or_data'] == 'structure_and_data')
+            && ! PMA_Table::isMerge($db, $table)
+        ) {
+            if (! empty($sql_query)) {
+                // only preg_replace if needed
+                if (! empty($add_query)) {
+                    // remove trailing semicolon before adding a LIMIT
+                    $sql_query = preg_replace('%;\s*$%', '', $sql_query);
+                }
+                $local_query = $sql_query . $add_query;
+                PMA_DBI_select_db($db);
+            } else {
+                $local_query  = 'SELECT * FROM ' . PMA_Util::backquote($db)
+                    . '.' . PMA_Util::backquote($table) . $add_query;
+            }
+            if (! $export_plugin->exportData($db, $table, $crlf, $err_url, $local_query)) {
+                break;
+            }
+        }
+        // now export the triggers (needs to be done after the data because
+        // triggers can modify already imported tables)
+        if ($GLOBALS[$what . '_structure_or_data'] == 'structure'
+            || $GLOBALS[$what . '_structure_or_data'] == 'structure_and_data'
+        ) {
+            if (! $export_plugin->exportStructure(
+                $db, $table, $crlf, $err_url,
+                'triggers', $export_type,
+                $do_relation, $do_comments, $do_mime, $do_dates
+            )) {
+                break 2;
+            }
+        }
+        if (! $export_plugin->exportDBFooter($db)) {
+            break;
+        }
+    }
+    if (! $export_plugin->exportFooter()) {
+        break;
+    }
+
+} while (false);
+// End of fake loop
+
+if ($save_on_server && isset($message)) {
+    if ($export_type == 'server') {
+        $active_page = 'server_export.php';
+        include 'server_export.php';
+    } elseif ($export_type == 'database') {
+        $active_page = 'db_export.php';
+        include 'db_export.php';
+    } else {
+        $active_page = 'tbl_export.php';
+        include 'tbl_export.php';
+    }
+    exit();
+}
+
+/**
+ * Send the dump as a file...
+ */
+if (! empty($asfile)) {
+    // Convert the charset if required.
+    if ($output_charset_conversion) {
+        $dump_buffer = PMA_convert_string(
+            'utf-8',
+            $GLOBALS['charset_of_file'],
+            $dump_buffer
+        );
+    }
+
+    // Do the compression
+    // 1. as a zipped file
+    if ($compression == 'zip') {
+        if (@function_exists('gzcompress')) {
+            $zipfile = new ZipFile();
+            $zipfile->addFile($dump_buffer, substr($filename, 0, -4));
+            $dump_buffer = $zipfile->file();
+        }
+    } elseif ($compression == 'bzip2') {
+        // 2. as a bzipped file
+        if (@function_exists('bzcompress')) {
+            $dump_buffer = bzcompress($dump_buffer);
+        }
+    } elseif ($compression == 'gzip' && PMA_gzencodeNeeded()) {
+        // 3. as a gzipped file
+        // without the optional parameter level because it bugs
+            $dump_buffer = gzencode($dump_buffer);
+    }
+
+    /* If we saved on server, we have to close file now */
+    if ($save_on_server) {
+        $write_result = @fwrite($file_handle, $dump_buffer);
+        fclose($file_handle);
+        if (strlen($dump_buffer) > 0
+            && (! $write_result || ($write_result != strlen($dump_buffer)))
+        ) {
+            $message = new PMA_Message(
+                __('Insufficient space to save the file %s.'),
+                PMA_Message::ERROR,
+                $save_filename
+            );
+        } else {
+            $message = new PMA_Message(
+                __('Dump has been saved to file %s.'),
+                PMA_Message::SUCCESS,
+                $save_filename
+            );
+        }
+
+        if ($export_type == 'server') {
+            $active_page = 'server_export.php';
+            include_once 'server_export.php';
+        } elseif ($export_type == 'database') {
+            $active_page = 'db_export.php';
+            include_once 'db_export.php';
+        } else {
+            $active_page = 'tbl_export.php';
+            include_once 'tbl_export.php';
+        }
+        exit();
+    } else {
+        PMA_Response::getInstance()->disable();
+        echo $dump_buffer;
+    }
+} else {
+    /**
+     * Displays the dump...
+     *
+     * Close the html tags and add the footers if dump is displayed on screen
+     */
+    echo '</textarea>' . "\n"
+       . '    </form>' . "\n";
+    echo $back_button;
+
+    echo "\n";
+    echo '</div>' . "\n";
+    echo "\n";
+?>
+<script type="text/javascript">
+//<![CDATA[
+    var $body = $("body");
+    $("#textSQLDUMP")
+        .width($body.width() - 50)
+        .height($body.height() - 100);
+//]]>
+</script>
+<?php
+} // end if
+?>
diff --git a/phpmyadmin/favicon.ico b/phpmyadmin/favicon.ico
new file mode 100644
index 0000000..2352b5f
Binary files /dev/null and b/phpmyadmin/favicon.ico differ
diff --git a/phpmyadmin/file_echo.php b/phpmyadmin/file_echo.php
new file mode 100644
index 0000000..d910b74
--- /dev/null
+++ b/phpmyadmin/file_echo.php
@@ -0,0 +1,71 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * "Echo" service to allow force downloading of exported charts (png or svg)
+ * and server status monitor settings
+ *
+ * @package PhpMyAdmin
+ */
+
+define('PMA_MINIMUM_COMMON', true);
+require_once 'libraries/common.inc.php';
+
+/* For chart exporting */
+if (isset($_REQUEST['filename']) && isset($_REQUEST['image'])) {
+    $allowed = array(
+        'image/png'     => 'png',
+        'image/svg+xml' => 'svg',
+    );
+
+    /* Check whether MIME type is allowed */
+    if (! isset($allowed[$_REQUEST['type']])) {
+        PMA_fatalError(__('Invalid export type'));
+    }
+
+    /*
+     * Check file name to match mime type and not contain new lines
+     * to prevent response splitting.
+     */
+    $extension = $allowed[$_REQUEST['type']];
+    $valid_match = '/^[^\n\r]*\.' . $extension . '$/';
+    if (! preg_match($valid_match, $_REQUEST['filename'])) {
+        if (! preg_match('/^[^\n\r]*$/', $_REQUEST['filename'])) {
+            /* Filename is unsafe, discard it */
+            $filename = 'download.' . $extension;
+        } else {
+            /* Add extension */
+            $filename = $_REQUEST['filename'] . '.' . $extension;
+        }
+    } else {
+        /* Filename from request should be safe here */
+        $filename = $_REQUEST['filename'];
+    }
+
+    /* Decode data */
+    if ($extension != 'svg') {
+        $data = substr($_REQUEST['image'], strpos($_REQUEST['image'], ',') + 1);
+        $data = base64_decode($data);
+    } else {
+        $data = $_REQUEST['image'];
+    }
+
+    /* Send download header */
+    PMA_downloadHeader($filename, $_REQUEST['type'], strlen($data));
+
+    /* Send data */
+    echo $data;
+
+} else if (isset($_REQUEST['monitorconfig'])) {
+    /* For monitor chart config export */
+    PMA_downloadHeader('monitor.cfg', 'application/force-download');
+    echo urldecode($_REQUEST['monitorconfig']);
+
+} else if (isset($_REQUEST['import'])) {
+    /* For monitor chart config import */
+    header('Content-type: text/plain');
+    if (!file_exists($_FILES['file']['tmp_name'])) {
+        exit();
+    }
+    echo file_get_contents($_FILES['file']['tmp_name']);
+}
+?>
diff --git a/phpmyadmin/gis_data_editor.php b/phpmyadmin/gis_data_editor.php
new file mode 100644
index 0000000..229e36b
--- /dev/null
+++ b/phpmyadmin/gis_data_editor.php
@@ -0,0 +1,416 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * Editor for Geometry data types.
+ *
+ * @package PhpMyAdmin
+ */
+
+/**
+ * Escapes special characters if the variable is set.
+ * Returns an empty string otherwise.
+ *
+ * @param string $variable variable to be escaped
+ *
+ * @return escaped variable
+ */
+function escape($variable)
+{
+    return isset($variable) ? htmlspecialchars($variable) : '';
+}
+
+require_once 'libraries/common.inc.php';
+require_once 'libraries/gis/pma_gis_factory.php';
+require_once 'libraries/gis_visualization.lib.php';
+
+// Get data if any posted
+$gis_data = array();
+if (PMA_isValid($_REQUEST['gis_data'], 'array')) {
+    $gis_data = $_REQUEST['gis_data'];
+}
+
+$gis_types = array(
+    'POINT',
+    'MULTIPOINT',
+    'LINESTRING',
+    'MULTILINESTRING',
+    'POLYGON',
+    'MULTIPOLYGON',
+    'GEOMETRYCOLLECTION'
+);
+
+// Extract type from the initial call and make sure that it's a valid one.
+// Extract from field's values if availbale, if not use the column type passed.
+if (! isset($gis_data['gis_type'])) {
+    if (isset($_REQUEST['type']) && $_REQUEST['type'] != '') {
+        $gis_data['gis_type'] = strtoupper($_REQUEST['type']);
+    }
+    if (isset($_REQUEST['value']) && trim($_REQUEST['value']) != '') {
+        $start = (substr($_REQUEST['value'], 0, 1) == "'") ? 1 : 0;
+        $gis_data['gis_type'] = substr(
+            $_REQUEST['value'], $start, strpos($_REQUEST['value'], "(") - $start
+        );
+    }
+    if ((! isset($gis_data['gis_type']))
+        || (! in_array($gis_data['gis_type'], $gis_types))
+    ) {
+        $gis_data['gis_type'] = $gis_types[0];
+    }
+}
+$geom_type = $gis_data['gis_type'];
+
+// Generate parameters from value passed.
+$gis_obj = PMA_GIS_Factory::factory($geom_type);
+if (isset($_REQUEST['value'])) {
+    $gis_data = array_merge(
+        $gis_data, $gis_obj->generateParams($_REQUEST['value'])
+    );
+}
+
+// Generate Well Known Text
+$srid = (isset($gis_data['srid']) && $gis_data['srid'] != '')
+    ? htmlspecialchars($gis_data['srid']) : 0;
+$wkt = $gis_obj->generateWkt($gis_data, 0);
+$wkt_with_zero = $gis_obj->generateWkt($gis_data, 0, '0');
+$result = "'" . $wkt . "'," . $srid;
+
+// Generate PNG or SVG based visualization
+$format = (PMA_USR_BROWSER_AGENT == 'IE' && PMA_USR_BROWSER_VER <= 8)
+    ? 'png' : 'svg';
+$visualizationSettings = array(
+    'width' => 450,
+    'height' => 300,
+    'spatialColumn' => 'wkt'
+);
+$data = array(array('wkt' => $wkt_with_zero, 'srid' => $srid));
+$visualization = PMA_GIS_visualizationResults(
+    $data, $visualizationSettings, $format
+);
+$open_layers = PMA_GIS_visualizationResults($data, $visualizationSettings, 'ol');
+
+// If the call is to update the WKT and visualization make an AJAX response
+if (isset($_REQUEST['generate']) && $_REQUEST['generate'] == true) {
+    $extra_data = array(
+        'result'        => $result,
+        'visualization' => $visualization,
+        'openLayers'    => $open_layers,
+    );
+    $response = PMA_Response::getInstance();
+    $response->addJSON($extra_data);
+    exit;
+}
+
+ob_start();
+
+echo '<form id="gis_data_editor_form" action="gis_data_editor.php" method="post">';
+echo '<input type="hidden" id="pmaThemeImage"'
+    . ' value="' . $GLOBALS['pmaThemeImage'] . '" />';
+echo '<div id="gis_data_editor">';
+
+echo '<h3>';
+printf(
+    __('Value for the column "%s"'),
+    htmlspecialchars($_REQUEST['field'])
+);
+echo '</h3>';
+
+echo '<input type="hidden" name="field" value="'
+    . htmlspecialchars($_REQUEST['field']) . '" />';
+// The input field to which the final result should be added
+// and corresponding null checkbox
+if (isset($_REQUEST['input_name'])) {
+    echo '<input type="hidden" name="input_name" value="'
+        . htmlspecialchars($_REQUEST['input_name']) . '" />';
+}
+echo PMA_generate_common_hidden_inputs();
+
+echo '<!-- Visualization section -->';
+echo '<div id="placeholder" style="width:450px;height:300px;'
+    . ($srid != 0 ? 'display:none;' : '') . '">';
+echo $visualization;
+echo '</div>';
+
+echo '<div id="openlayersmap" style="width:450px;height:300px;'
+    . ($srid == 0 ? 'display:none;' : '') . '">';
+echo '</div>';
+
+echo '<div class="choice" style="float:right;clear:right;">';
+echo '<input type="checkbox" id="choice" value="useBaseLayer"'
+    . ($srid != 0 ? ' checked="checked"' : '') . '/>';
+echo '<label for="choice">' .  __("Use OpenStreetMaps as Base Layer") . '</label>';
+echo '</div>';
+
+echo '<script language="javascript" type="text/javascript">';
+echo $open_layers;
+echo '</script>';
+echo '<!-- End of visualization section -->';
+
+
+echo '<!-- Header section - Inclueds GIS type selector and input field for SRID -->';
+echo '<div id="gis_data_header">';
+echo '<select name="gis_data[gis_type]" class="gis_type">';
+foreach ($gis_types as $gis_type) {
+    echo '<option value="' . $gis_type . '"';
+    if ($geom_type == $gis_type) {
+        echo ' selected="selected"';
+    }
+    echo '>' . $gis_type . '</option>';
+}
+echo '</select>';
+echo '    ';
+echo '<label for="srid">' .  __("SRID") . ':</label>';
+echo '<input name="gis_data[srid]" type="text" value="' . $srid . '" />';
+echo '</div>';
+echo '<!-- End of header section -->';
+
+echo '<!-- Data section -->';
+echo '<div id="gis_data">';
+
+$geom_count = 1;
+if ($geom_type == 'GEOMETRYCOLLECTION') {
+    $geom_count = (isset($gis_data[$geom_type]['geom_count']))
+        ? $gis_data[$geom_type]['geom_count'] : 1;
+    if (isset($gis_data[$geom_type]['add_geom'])) {
+        $geom_count++;
+    }
+    echo '<input type="hidden" name="gis_data[GEOMETRYCOLLECTION][geom_count]"'
+        . ' value="' . $geom_count . '" />';
+}
+
+for ($a = 0; $a < $geom_count; $a++) {
+
+    if ($geom_type == 'GEOMETRYCOLLECTION') {
+        echo '<br/><br/>';
+        echo __("Geometry") . ' ' . ($a + 1) . ': ';
+        echo '<br/>';
+        if (isset($gis_data[$a]['gis_type'])) {
+            $type = $gis_data[$a]['gis_type'];
+        } else {
+            $type = $gis_types[0];
+        }
+        echo '<select name="gis_data[' . $a . '][gis_type]" class="gis_type">';
+        foreach (array_slice($gis_types, 0, 6) as $gis_type) {
+            echo '<option value="' . $gis_type . '"';
+            if ($type == $gis_type) {
+                echo ' selected="selected"';
+            }
+            echo '>' . $gis_type . '</option>';
+        }
+        echo '</select>';
+    } else {
+        $type = $geom_type;
+    }
+
+    if ($type == 'POINT') {
+        echo '<br/>';
+        echo __("Point") . ': ';
+        echo '<label for="x">' . __("X") . '</label>';
+        echo '<input name="gis_data[' . $a . '][POINT][x]" type="text"'
+            . ' value="' . escape($gis_data[$a]['POINT']['x']) . '" />';
+        echo '<label for="y">' . __("Y") . '</label>';
+        echo '<input name="gis_data[' . $a . '][POINT][y]" type="text"'
+            . ' value="' . escape($gis_data[$a]['POINT']['y']) . '" />';
+
+    } elseif ($type == 'MULTIPOINT' || $type == 'LINESTRING') {
+        $no_of_points = isset($gis_data[$a][$type]['no_of_points'])
+            ? $gis_data[$a][$type]['no_of_points'] : 1;
+        if ($type == 'LINESTRING' && $no_of_points < 2) {
+            $no_of_points = 2;
+        }
+        if ($type == 'MULTIPOINT' && $no_of_points < 1) {
+            $no_of_points = 1;
+        }
+
+        if (isset($gis_data[$a][$type]['add_point'])) {
+            $no_of_points++;
+        }
+        echo '<input type="hidden" value="' . $no_of_points . '"'
+            . ' name="gis_data[' . $a . '][' . $type . '][no_of_points]" />';
+
+        for ($i = 0; $i < $no_of_points; $i++) {
+            echo '<br/>';
+            printf(__('Point %d'), $i + 1);
+            echo ': ';
+            echo '<label for="x">' .  __("X") . '</label>';
+            echo '<input type="text"'
+                . ' name="gis_data[' . $a . '][' . $type . '][' . $i . '][x]"'
+                . ' value="' . escape($gis_data[$a][$type][$i]['x']) . '" />';
+            echo '<label for="y">' . __("Y") . '</label>';
+            echo '<input type="text"'
+                . ' name="gis_data[' . $a . '][' . $type . '][' . $i . '][y]"'
+                . ' value="' . escape($gis_data[$a][$type][$i]['y']). '" />';
+        }
+        echo '<input type="submit"'
+            . ' name="gis_data[' . $a . '][' . $type . '][add_point]"'
+            . ' class="add addPoint" value="' . __("Add a point") . '" />';
+
+    } elseif ($type == 'MULTILINESTRING' || $type == 'POLYGON') {
+        $no_of_lines = isset($gis_data[$a][$type]['no_of_lines'])
+            ? $gis_data[$a][$type]['no_of_lines'] : 1;
+        if ($no_of_lines < 1) {
+            $no_of_lines = 1;
+        }
+        if (isset($gis_data[$a][$type]['add_line'])) {
+            $no_of_lines++;
+        }
+        echo '<input type="hidden" value="' . $no_of_lines . '"'
+            . ' name="gis_data[' . $a . '][' . $type . '][no_of_lines]" />';
+
+        for ($i = 0; $i < $no_of_lines; $i++) {
+            echo '<br/>';
+            if ($type == 'MULTILINESTRING') {
+                echo __("Linestring") . ' ' . ($i + 1) . ':';
+            } else {
+                if ($i == 0) {
+                    echo __("Outer Ring") . ':';
+                } else {
+                    echo __("Inner Ring") . ' ' . $i . ':';
+                }
+            }
+
+            $no_of_points = isset($gis_data[$a][$type][$i]['no_of_points'])
+                ? $gis_data[$a][$type][$i]['no_of_points'] : 2;
+            if ($type == 'MULTILINESTRING' && $no_of_points < 2) {
+                $no_of_points = 2;
+            }
+            if ($type == 'POLYGON' && $no_of_points < 4) {
+                $no_of_points = 4;
+            }
+            if (isset($gis_data[$a][$type][$i]['add_point'])) {
+                $no_of_points++;
+            }
+            echo '<input type="hidden" value="' . $no_of_points . '"'
+               . ' name="gis_data[' . $a . '][' . $type . '][' . $i . '][no_of_points]" />';
+
+            for ($j = 0; $j < $no_of_points; $j++) {
+                echo('<br/>');
+                printf(__('Point %d'), $j + 1);
+                echo ': ';
+                echo '<label for="x">' .  __("X") . '</label>';
+                echo '<input type="text"'
+                    . ' name="gis_data[' . $a . '][' . $type . '][' . $i . '][' . $j . '][x]"'
+                    . ' value="' . escape($gis_data[$a][$type][$i][$j]['x']) . '" />';
+                echo '<label for="y">' . __("Y") . '</label>';
+                echo '<input type="text"'
+                    . ' name="gis_data[' . $a . '][' . $type . '][' . $i . '][' . $j . '][y]"'
+                    . ' value="' . escape($gis_data[$a][$type][$i][$j]['x']) . '" />';
+            }
+            echo '<input type="submit"'
+                . ' name="gis_data[' . $a . '][' . $type . '][' . $i . '][add_point]"'
+                . ' class="add addPoint" value="' . __("Add a point") . '" />';
+        }
+        $caption = ($type == 'MULTILINESTRING')
+            ? __('Add a linestring')
+            : __('Add an inner ring');
+        echo '<br/>';
+        echo '<input type="submit"'
+            . ' name="gis_data[' . $a . '][' . $type . '][add_line]"'
+            . ' class="add addLine" value="' . $caption . '" />';
+
+    } elseif ($type == 'MULTIPOLYGON') {
+        $no_of_polygons = isset($gis_data[$a][$type]['no_of_polygons'])
+            ? $gis_data[$a][$type]['no_of_polygons'] : 1;
+        if ($no_of_polygons < 1) {
+            $no_of_polygons = 1;
+        }
+        if (isset($gis_data[$a][$type]['add_polygon'])) {
+            $no_of_polygons++;
+        }
+        echo '<input type="hidden"'
+            . ' name="gis_data[' . $a . '][' . $type . '][no_of_polygons]"'
+            . ' value="' . $no_of_polygons . '" />';
+
+        for ($k = 0; $k < $no_of_polygons; $k++) {
+            echo '<br/>';
+            echo __("Polygon") . ' ' . ($k + 1) . ':';
+            $no_of_lines = isset($gis_data[$a][$type][$k]['no_of_lines'])
+                ? $gis_data[$a][$type][$k]['no_of_lines'] : 1;
+            if ($no_of_lines < 1) {
+                $no_of_lines = 1;
+            }
+            if (isset($gis_data[$a][$type][$k]['add_line'])) {
+                $no_of_lines++;
+            }
+            echo '<input type="hidden"'
+                . ' name="gis_data[' . $a . '][' . $type . '][' . $k . '][no_of_lines]"'
+                . ' value="' . $no_of_lines . '" />';
+
+            for ($i = 0; $i < $no_of_lines; $i++) {
+                echo '<br/><br/>';
+                if ($i == 0) {
+                    echo __("Outer Ring") . ':';
+                } else {
+                    echo __("Inner Ring") . ' ' . $i . ':';
+                }
+
+                $no_of_points = isset($gis_data[$a][$type][$k][$i]['no_of_points'])
+                    ? $gis_data[$a][$type][$k][$i]['no_of_points'] : 4;
+                if ($no_of_points < 4) {
+                    $no_of_points = 4;
+                }
+                if (isset($gis_data[$a][$type][$k][$i]['add_point'])) {
+                    $no_of_points++;
+                }
+                echo '<input type="hidden"'
+                    . ' name="gis_data[' . $a . '][' . $type . '][' . $k . '][' . $i . '][no_of_points]"'
+                    . ' value="' . $no_of_points . '" />';
+
+                for ($j = 0; $j < $no_of_points; $j++) {
+                    echo '<br/>';
+                    printf(__('Point %d'), $j + 1);
+                    echo ': ';
+                    echo '<label for="x">' .  __("X") . '</label>';
+                    echo '<input type="text"'
+                        . ' name="gis_data[' . $a . '][' . $type . '][' . $k . '][' . $i . '][' . $j . '][x]"'
+                        . ' value="' . escape($gis_data[$a][$type][$k][$i][$j]['x']). '" />';
+                    echo '<label for="y">' . __("Y") . '</label>';
+                    echo '<input type="text"'
+                        . ' name="gis_data[' . $a . '][' . $type . '][' . $k . '][' . $i . '][' . $j . '][y]"'
+                        . ' value="' . escape($gis_data[$a][$type][$k][$i][$j]['y']) . '" />';
+                }
+                echo '<input type="submit"'
+                    . ' name="gis_data[' . $a . '][' . $type . '][' . $k . '][' . $i . '][add_point]"'
+                    . ' class="add addPoint" value="' . __("Add a point") . '" />';
+            }
+            echo '<br/>';
+            echo '<input type="submit"'
+                . ' name="gis_data[' . $a . '][' . $type . '][' . $k . '][add_line]"'
+                . ' class="add addLine" value="' . __('Add an inner ring'). '" />';
+            echo '<br/>';
+        }
+        echo '<br/>';
+        echo '<input type="submit"'
+            . ' name="gis_data[' . $a . '][' . $type . '][add_polygon]"'
+            . ' class="add addPolygon" value="' .  __('Add a polygon') . '" />';
+    }
+}
+if ($geom_type == 'GEOMETRYCOLLECTION') {
+    echo '<br/><br/>';
+    echo '<input type="submit" name="gis_data[GEOMETRYCOLLECTION][add_geom]"'
+        . 'class="add addGeom" value="' . __("Add geometry") . '" />';
+}
+echo '</div>';
+echo '<!-- End of data section -->';
+
+echo '<br/>';
+echo '<input type="submit" name="gis_data[save]" value="' . __('Go') . '" />';
+
+echo '<div id="gis_data_output">';
+echo '<h3>' . __('Output') . '</h3>';
+echo '<p>';
+echo __(
+    'Choose "GeomFromText" from the "Function" column and paste the'
+    . ' string below into the "Value" field'
+);
+echo '</p>';
+echo '<textarea id="gis_data_textarea" cols="95" rows="5">';
+echo $result;
+echo '</textarea>';
+echo '</div>';
+
+echo '</div>';
+echo '</form>';
+
+PMA_Response::getInstance()->addJSON('gis_editor', ob_get_contents());
+ob_end_clean();
+?>
diff --git a/phpmyadmin/import.php b/phpmyadmin/import.php
new file mode 100644
index 0000000..6075d5d
--- /dev/null
+++ b/phpmyadmin/import.php
@@ -0,0 +1,619 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * Core script for import, this is just the glue around all other stuff
+ *
+ * @package PhpMyAdmin
+ */
+
+/**
+ * Get the variables sent or posted to this script and a core script
+ */
+require_once 'libraries/common.inc.php';
+//require_once 'libraries/display_import_functions.lib.php';
+
+if (isset($_REQUEST['show_as_php'])) {
+    $GLOBALS['show_as_php'] = $_REQUEST['show_as_php'];
+}
+
+/**
+ * Sets globals from $_POST
+ */
+$post_params = array(
+    'action_bookmark',
+    'allow_interrupt',
+    'bkm_label',
+    'bookmark_variable',
+    'charset_of_file',
+    'format',
+    'id_bookmark',
+    'import_type',
+    'is_js_confirmed',
+    'MAX_FILE_SIZE',
+    'message_to_show',
+    'noplugin',
+    'skip_queries',
+    'local_import_file'
+);
+
+// TODO: adapt full list of allowed parameters, as in export.php
+foreach ($post_params as $one_post_param) {
+    if (isset($_POST[$one_post_param])) {
+        $GLOBALS[$one_post_param] = $_POST[$one_post_param];
+    }
+}
+
+// reset import messages for ajax request
+$_SESSION['Import_message']['message'] = null;
+$_SESSION['Import_message']['go_back_url'] = null;
+// default values
+$GLOBALS['reload'] = false;
+
+// Use to identify curren cycle is executing
+// a multiquery statement or stored routine
+if (!isset($_SESSION['is_multi_query'])) {
+    $_SESSION['is_multi_query'] = false;
+}
+
+// Are we just executing plain query or sql file?
+// (eg. non import, but query box/window run)
+if (! empty($sql_query)) {
+    // run SQL query
+    $import_text = $sql_query;
+    $import_type = 'query';
+    $format = 'sql';
+
+    // refresh navigation and main panels
+    if (preg_match('/^(DROP)\s+(VIEW|TABLE|DATABASE|SCHEMA)\s+/i', $sql_query)) {
+        $GLOBALS['reload'] = true;
+    }
+
+    // refresh navigation panel only
+    if (preg_match('/^(CREATE|ALTER)\s+(VIEW|TABLE|DATABASE|SCHEMA)\s+/i', $sql_query)) {
+        $ajax_reload['reload'] = true;
+    }
+
+    // do a dynamic reload if table is RENAMED
+    // (by sending the instruction to the AJAX response handler)
+    if (preg_match('/^RENAME\s+TABLE\s+(.*?)\s+TO\s+(.*?)($|;|\s)/i', $sql_query, $rename_table_names)) {
+        $ajax_reload['table_name'] = PMA_Util::unQuote($rename_table_names[2]);
+        $ajax_reload['reload'] = true;
+    }
+
+    $sql_query = '';
+} elseif (! empty($sql_localfile)) {
+    // run SQL file on server
+    $local_import_file = $sql_localfile;
+    $import_type = 'queryfile';
+    $format = 'sql';
+    unset($sql_localfile);
+} elseif (! empty($sql_file)) {
+    // run uploaded SQL file
+    $import_file = $sql_file;
+    $import_type = 'queryfile';
+    $format = 'sql';
+    unset($sql_file);
+} elseif (! empty($id_bookmark)) {
+    // run bookmark
+    $import_type = 'query';
+    $format = 'sql';
+}
+
+// If we didn't get any parameters, either user called this directly, or
+// upload limit has been reached, let's assume the second possibility.
+;
+if ($_POST == array() && $_GET == array()) {
+    $message = PMA_Message::error(
+        __('You probably tried to upload a file that is too large. Please refer to %sdocumentation%s for a workaround for this limit.')
+    );
+    $message->addParam('[doc at faq1-16]');
+    $message->addParam('[/doc]');
+
+    // so we can obtain the message
+    $_SESSION['Import_message']['message'] = $message->getDisplay();
+    $_SESSION['Import_message']['go_back_url'] = $goto;
+
+    $message->display();
+    exit; // the footer is displayed automatically
+}
+
+/**
+ * Sets globals from $_POST patterns, for import plugins
+ * We only need to load the selected plugin
+ */
+
+if (! in_array(
+    $format, 
+    array(
+        'csv',
+        'ldi',
+        'mediawiki',
+        'ods',
+        'shp',
+        'sql',
+        'xml'
+    )
+)
+) {
+    // this should not happen for a normal user
+    // but only during an attack
+    PMA_fatalError('Incorrect format parameter');
+}
+
+$post_patterns = array(
+    '/^force_file_/',
+    '/^'. $format . '_/'
+);
+foreach (array_keys($_POST) as $post_key) {
+    foreach ($post_patterns as $one_post_pattern) {
+        if (preg_match($one_post_pattern, $post_key)) {
+            $GLOBALS[$post_key] = $_POST[$post_key];
+        }
+    }
+}
+
+// Check needed parameters
+PMA_Util::checkParameters(array('import_type', 'format'));
+
+// We don't want anything special in format
+$format = PMA_securePath($format);
+
+// Import functions
+require_once 'libraries/import.lib.php';
+
+// Create error and goto url
+if ($import_type == 'table') {
+    $err_url = 'tbl_import.php?' . PMA_generate_common_url($db, $table);
+    $_SESSION['Import_message']['go_back_url'] = $err_url;
+    $goto = 'tbl_import.php';
+} elseif ($import_type == 'database') {
+    $err_url = 'db_import.php?' . PMA_generate_common_url($db);
+    $_SESSION['Import_message']['go_back_url'] = $err_url;
+    $goto = 'db_import.php';
+} elseif ($import_type == 'server') {
+    $err_url = 'server_import.php?' . PMA_generate_common_url();
+    $_SESSION['Import_message']['go_back_url'] = $err_url;
+    $goto = 'server_import.php';
+} else {
+    if (empty($goto) || !preg_match('@^(server|db|tbl)(_[a-z]*)*\.php$@i', $goto)) {
+        if (strlen($table) && strlen($db)) {
+            $goto = 'tbl_structure.php';
+        } elseif (strlen($db)) {
+            $goto = 'db_structure.php';
+        } else {
+            $goto = 'server_sql.php';
+        }
+    }
+    if (strlen($table) && strlen($db)) {
+        $common = PMA_generate_common_url($db, $table);
+    } elseif (strlen($db)) {
+        $common = PMA_generate_common_url($db);
+    } else {
+        $common = PMA_generate_common_url();
+    }
+    $err_url  = $goto . '?' . $common
+        . (preg_match('@^tbl_[a-z]*\.php$@', $goto)
+            ? '&table=' . htmlspecialchars($table)
+            : '');
+    $_SESSION['Import_message']['go_back_url'] = $err_url;
+}
+
+
+if (strlen($db)) {
+    PMA_DBI_select_db($db);
+}
+
+ at set_time_limit($cfg['ExecTimeLimit']);
+if (! empty($cfg['MemoryLimit'])) {
+    @ini_set('memory_limit', $cfg['MemoryLimit']);
+}
+
+$timestamp = time();
+if (isset($allow_interrupt)) {
+    $maximum_time = ini_get('max_execution_time');
+} else {
+    $maximum_time = 0;
+}
+
+// set default values
+$timeout_passed = false;
+$error = false;
+$read_multiply = 1;
+$finished = false;
+$offset = 0;
+$max_sql_len = 0;
+$file_to_unlink = '';
+$sql_query = '';
+$sql_query_disabled = false;
+$go_sql = false;
+$executed_queries = 0;
+$run_query = true;
+$charset_conversion = false;
+$reset_charset = false;
+$bookmark_created = false;
+
+// Bookmark Support: get a query back from bookmark if required
+if (! empty($id_bookmark)) {
+    $id_bookmark = (int)$id_bookmark;
+    include_once 'libraries/bookmark.lib.php';
+    switch ($action_bookmark) {
+    case 0: // bookmarked query that have to be run
+        $import_text = PMA_Bookmark_get(
+            $db,
+            $id_bookmark,
+            'id',
+            isset($action_bookmark_all)
+        );
+        if (isset($bookmark_variable) && ! empty($bookmark_variable)) {
+            $import_text = preg_replace(
+                '|/\*(.*)\[VARIABLE\](.*)\*/|imsU',
+                '${1}' . PMA_Util::sqlAddSlashes($bookmark_variable) . '${2}',
+                $import_text
+            );
+        }
+
+        // refresh navigation and main panels
+        if (preg_match('/^(DROP)\s+(VIEW|TABLE|DATABASE|SCHEMA)\s+/i', $import_text)) {
+            $GLOBALS['reload'] = true;
+        }
+
+        // refresh navigation panel only
+        if (preg_match('/^(CREATE|ALTER)\s+(VIEW|TABLE|DATABASE|SCHEMA)\s+/i', $import_text)) {
+            $ajax_reload['reload'] = true;
+        }
+        break;
+    case 1: // bookmarked query that have to be displayed
+        $import_text = PMA_Bookmark_get($db, $id_bookmark);
+        if ($GLOBALS['is_ajax_request'] == true) {
+            $message = PMA_Message::success(__('Showing bookmark'));
+            $response = PMA_Response::getInstance();
+            $response->isSuccess($message->isSuccess());
+            $response->addJSON('message', $message);
+            $response->addJSON('sql_query', $import_text);
+            $response->addJSON('action_bookmark', $action_bookmark);
+            exit;
+        } else {
+            $run_query = false;
+        }
+        break;
+    case 2: // bookmarked query that have to be deleted
+        $import_text = PMA_Bookmark_get($db, $id_bookmark);
+        PMA_Bookmark_delete($db, $id_bookmark);
+        if ($GLOBALS['is_ajax_request'] == true) {
+            $message = PMA_Message::success(__('The bookmark has been deleted.'));
+            $response = PMA_Response::getInstance();
+            $response->isSuccess($message->isSuccess());
+            $response->addJSON('message', $message);
+            $response->addJSON('action_bookmark', $action_bookmark);
+            $response->addJSON('id_bookmark', $id_bookmark);
+            exit;
+        } else {
+            $run_query = false;
+            $error = true; // this is kind of hack to skip processing the query
+        }
+        break;
+    }
+} // end bookmarks reading
+
+// Do no run query if we show PHP code
+if (isset($GLOBALS['show_as_php'])) {
+    $run_query = false;
+    $go_sql = true;
+}
+
+// We can not read all at once, otherwise we can run out of memory
+$memory_limit = trim(@ini_get('memory_limit'));
+// 2 MB as default
+if (empty($memory_limit)) {
+    $memory_limit = 2 * 1024 * 1024;
+}
+// In case no memory limit we work on 10MB chunks
+if ($memory_limit == -1) {
+    $memory_limit = 10 * 1024 * 1024;
+}
+
+// Calculate value of the limit
+if (strtolower(substr($memory_limit, -1)) == 'm') {
+    $memory_limit = (int)substr($memory_limit, 0, -1) * 1024 * 1024;
+} elseif (strtolower(substr($memory_limit, -1)) == 'k') {
+    $memory_limit = (int)substr($memory_limit, 0, -1) * 1024;
+} elseif (strtolower(substr($memory_limit, -1)) == 'g') {
+    $memory_limit = (int)substr($memory_limit, 0, -1) * 1024 * 1024 * 1024;
+} else {
+    $memory_limit = (int)$memory_limit;
+}
+
+// Just to be sure, there might be lot of memory needed for uncompression
+$read_limit = $memory_limit / 8;
+
+// handle filenames
+if (isset($_FILES['import_file'])) {
+    $import_file = $_FILES['import_file']['tmp_name'];
+}
+if (! empty($local_import_file) && ! empty($cfg['UploadDir'])) {
+
+    // sanitize $local_import_file as it comes from a POST
+    $local_import_file = PMA_securePath($local_import_file);
+
+    $import_file = PMA_Util::userDir($cfg['UploadDir'])
+        . $local_import_file;
+
+} elseif (empty($import_file) || ! is_uploaded_file($import_file)) {
+    $import_file  = 'none';
+}
+
+// Do we have file to import?
+
+if ($import_file != 'none' && ! $error) {
+    // work around open_basedir and other limitations
+    $open_basedir = @ini_get('open_basedir');
+
+    // If we are on a server with open_basedir, we must move the file
+    // before opening it. The doc explains how to create the "./tmp"
+    // directory
+
+    if (! empty($open_basedir)) {
+
+        $tmp_subdir = (PMA_IS_WINDOWS ? '.\\tmp\\' : 'tmp/');
+
+        if (is_writable($tmp_subdir)) {
+
+
+            $import_file_new = $tmp_subdir . basename($import_file) . uniqid();
+            if (move_uploaded_file($import_file, $import_file_new)) {
+                $import_file = $import_file_new;
+                $file_to_unlink = $import_file_new;
+            }
+
+            $size = filesize($import_file);
+        }
+    }
+
+    /**
+     *  Handle file compression
+     * @todo duplicate code exists in File.class.php
+     */
+    $compression = PMA_detectCompression($import_file);
+    if ($compression === false) {
+        $message = PMA_Message::error(__('File could not be read'));
+        $error = true;
+    } else {
+        switch ($compression) {
+        case 'application/bzip2':
+            if ($cfg['BZipDump'] && @function_exists('bzopen')) {
+                $import_handle = @bzopen($import_file, 'r');
+            } else {
+                $message = PMA_Message::error(
+                    __('You attempted to load file with unsupported compression (%s). Either support for it is not implemented or disabled by your configuration.')
+                );
+                $message->addParam($compression);
+                $error = true;
+            }
+            break;
+        case 'application/gzip':
+            if ($cfg['GZipDump'] && @function_exists('gzopen')) {
+                $import_handle = @gzopen($import_file, 'r');
+            } else {
+                $message = PMA_Message::error(
+                    __('You attempted to load file with unsupported compression (%s). Either support for it is not implemented or disabled by your configuration.')
+                );
+                $message->addParam($compression);
+                $error = true;
+            }
+            break;
+        case 'application/zip':
+            if ($cfg['ZipDump'] && @function_exists('zip_open')) {
+                /**
+                 * Load interface for zip extension.
+                 */
+                include_once 'libraries/zip_extension.lib.php';
+                $result = PMA_getZipContents($import_file);
+                if (! empty($result['error'])) {
+                    $message = PMA_Message::rawError($result['error']);
+                    $error = true;
+                } else {
+                    $import_text = $result['data'];
+                }
+            } else {
+                $message = PMA_Message::error(
+                    __('You attempted to load file with unsupported compression (%s). Either support for it is not implemented or disabled by your configuration.')
+                );
+                $message->addParam($compression);
+                $error = true;
+            }
+            break;
+        case 'none':
+            $import_handle = @fopen($import_file, 'r');
+            break;
+        default:
+            $message = PMA_Message::error(
+                __('You attempted to load file with unsupported compression (%s). Either support for it is not implemented or disabled by your configuration.')
+            );
+            $message->addParam($compression);
+            $error = true;
+            break;
+        }
+    }
+    // use isset() because zip compression type does not use a handle
+    if (! $error && isset($import_handle) && $import_handle === false) {
+        $message = PMA_Message::error(__('File could not be read'));
+        $error = true;
+    }
+} elseif (! $error) {
+    if (! isset($import_text) || empty($import_text)) {
+        $message = PMA_Message::error(
+            __('No data was received to import. Either no file name was submitted, or the file size exceeded the maximum size permitted by your PHP configuration. See [doc at faq1-16]FAQ 1.16[/doc].')
+        );
+        $error = true;
+    }
+}
+
+// so we can obtain the message
+//$_SESSION['Import_message'] = $message->getDisplay();
+
+// Convert the file's charset if necessary
+if ($GLOBALS['PMA_recoding_engine'] != PMA_CHARSET_NONE && isset($charset_of_file)) {
+    if ($charset_of_file != 'utf-8') {
+        $charset_conversion = true;
+    }
+} elseif (isset($charset_of_file) && $charset_of_file != 'utf8') {
+    if (PMA_DRIZZLE) {
+        // Drizzle doesn't support other character sets,
+        // so we can't fallback to SET NAMES - throw an error
+        $error = true;
+        $message = PMA_Message::error(
+            __('Cannot convert file\'s character set without character set conversion library')
+        );
+    } else {
+        PMA_DBI_query('SET NAMES \'' . $charset_of_file . '\'');
+        // We can not show query in this case, it is in different charset
+        $sql_query_disabled = true;
+        $reset_charset = true;
+    }
+}
+
+// Something to skip?
+if (! $error && isset($skip)) {
+    $original_skip = $skip;
+    while ($skip > 0) {
+        PMA_importGetNextChunk($skip < $read_limit ? $skip : $read_limit);
+        // Disable read progresivity, otherwise we eat all memory!
+        $read_multiply = 1;
+        $skip -= $read_limit;
+    }
+    unset($skip);
+}
+
+// This array contain the data like numberof valid sql queries in the statement
+// and complete valid sql statement (which affected for rows)
+$sql_data = array('valid_sql' => array(), 'valid_queries' => 0);
+
+if (! $error) {
+    // Check for file existance
+    include_once "libraries/plugin_interface.lib.php";
+    $import_plugin = PMA_getPlugin(
+        "import",
+        $format,
+        'libraries/plugins/import/',
+        $import_type
+    );
+    if ($import_plugin == null) {
+        $error = true;
+        $message = PMA_Message::error(
+            __('Could not load import plugins, please check your installation!')
+        );
+    } else {
+        // Do the real import
+        $import_plugin->doImport($sql_data);
+    }
+}
+
+if (! $error && false !== $import_handle && null !== $import_handle) {
+    fclose($import_handle);
+}
+
+// Cleanup temporary file
+if ($file_to_unlink != '') {
+    unlink($file_to_unlink);
+}
+
+// Reset charset back, if we did some changes
+if ($reset_charset) {
+    PMA_DBI_query('SET CHARACTER SET utf8');
+    PMA_DBI_query(
+        'SET SESSION collation_connection =\'' . $collation_connection . '\''
+    );
+}
+
+// Show correct message
+if (! empty($id_bookmark) && $action_bookmark == 2) {
+    $message = PMA_Message::success(__('The bookmark has been deleted.'));
+    $display_query = $import_text;
+    $error = false; // unset error marker, it was used just to skip processing
+} elseif (! empty($id_bookmark) && $action_bookmark == 1) {
+    $message = PMA_Message::notice(__('Showing bookmark'));
+} elseif ($bookmark_created) {
+    $special_message = '[br]'  . sprintf(
+        __('Bookmark %s created'),
+        htmlspecialchars($bkm_label)
+    );
+} elseif ($finished && ! $error) {
+    if ($import_type == 'query') {
+        $message = PMA_Message::success();
+    } else {
+        if ($import_notice) {
+            $message = PMA_Message::success(
+                '<em>' . __('Import has been successfully finished, %d queries executed.') . '</em>'
+            );
+            $message->addParam($executed_queries);
+
+            $message->addString($import_notice);
+            if (isset($local_import_file)) {
+                $message->addString('(' . $local_import_file . ')');
+            } else {
+                $message->addString('(' . $_FILES['import_file']['name'] . ')');
+            }
+        } else {
+            $message = PMA_Message::success(
+                __('Import has been successfully finished, %d queries executed.')
+            );
+            $message->addParam($executed_queries);
+            if (isset($local_import_file)) {
+                $message->addString('(' . $local_import_file . ')');
+            } else {
+                $message->addString('(' . $_FILES['import_file']['name'] . ')');
+            }
+        }
+    }
+}
+
+// Did we hit timeout? Tell it user.
+if ($timeout_passed) {
+    $message = PMA_Message::error(
+        __('Script timeout passed, if you want to finish import, please resubmit same file and import will resume.')
+    );
+    if ($offset == 0 || (isset($original_skip) && $original_skip == $offset)) {
+        $message->addString(
+            __('However on last run no data has been parsed, this usually means phpMyAdmin won\'t be able to finish this import unless you increase php time limits.')
+        );
+    }
+}
+
+// if there is any message, copy it into $_SESSION as well,
+// so we can obtain it by AJAX call
+if (isset($message)) {
+    $_SESSION['Import_message']['message'] = $message->getDisplay();
+}
+// Parse and analyze the query, for correct db and table name
+// in case of a query typed in the query window
+// (but if the query is too large, in case of an imported file, the parser
+//  can choke on it so avoid parsing)
+if (strlen($sql_query) <= $GLOBALS['cfg']['MaxCharactersInDisplayedSQL']) {
+    include_once 'libraries/parse_analyze.lib.php';
+}
+
+// There was an error?
+if (isset($my_die)) {
+    foreach ($my_die AS $key => $die) {
+        PMA_Util::mysqlDie(
+            $die['error'], $die['sql'], '', $err_url, $error
+        );
+    }
+}
+
+// we want to see the results of the last query that returned at least a row
+if (! empty($last_query_with_results)) {
+    // but we want to show intermediate results too
+    $disp_query = $sql_query;
+    $disp_message = __('Your SQL query has been executed successfully');
+    $sql_query = $last_query_with_results;
+    $go_sql = true;
+}
+
+if ($go_sql) {
+    include 'sql.php';
+} else {
+    $active_page = $goto;
+    include '' . $goto;
+}
+?>
diff --git a/phpmyadmin/import_status.php b/phpmyadmin/import_status.php
new file mode 100644
index 0000000..9b79f3f
--- /dev/null
+++ b/phpmyadmin/import_status.php
@@ -0,0 +1,105 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ *
+ * @package PhpMyAdmin
+ */
+
+/* PHP 5.4 stores upload progress data only in the default session.
+ * After calling session_name(), we won't find the progress data anymore.
+ *
+ * https://bugs.php.net/bug.php?id=64075
+ *
+ * The bug should be somewhere in
+ * https://github.com/php/php-src/blob/master/ext/session/session.c#L2342
+ *
+ * Until this is fixed, we need to load the default session to load the data,
+ * export the upload progress information from there,
+ * and re-import after switching to our session.
+ */
+
+if (version_compare(PHP_VERSION, '5.4.0', '>=')
+    && ini_get('session.upload_progress.enabled')
+) {
+
+    $sessionupload = array();
+    define('UPLOAD_PREFIX', ini_get('session.upload_progress.prefix'));
+
+    session_start();
+    foreach ($_SESSION as $key => $value) {
+        // only copy session-prefixed data
+        if (substr($key, 0, strlen(UPLOAD_PREFIX)) == UPLOAD_PREFIX) {
+            $sessionupload[$key] = $value;
+        }
+    }
+    // PMA will kill all variables, so let's use a constant
+    define('SESSIONUPLOAD', serialize($sessionupload));
+    session_write_close();
+
+    session_name('phpMyAdmin');
+    session_id($_COOKIE['phpMyAdmin']);
+}
+
+define('PMA_MINIMUM_COMMON', 1);
+
+require_once 'libraries/common.inc.php';
+require_once 'libraries/display_import_ajax.lib.php';
+
+if (defined('SESSIONUPLOAD')) {
+    // write sessionupload back into the loaded PMA session
+
+    $sessionupload = unserialize(SESSIONUPLOAD);
+    foreach ($sessionupload as $key => $value) {
+        $_SESSION[$key] = $value;
+    }
+
+    // remove session upload data that are not set anymore
+    foreach ($_SESSION as $key => $value) {
+        if (substr($key, 0, strlen(UPLOAD_PREFIX)) == UPLOAD_PREFIX
+            && ! isset($sessionupload[$key])
+        ) {
+            unset($_SESSION[$key]);
+        }
+    }
+}
+
+/**
+ * Sets globals from $_GET
+ */
+$get_params = array(
+    'message',
+    'id'
+);
+foreach ($get_params as $one_get_param) {
+    if (isset($_GET[$one_get_param])) {
+        $GLOBALS[$one_get_param] = $_GET[$one_get_param];
+    }
+}
+
+// AJAX requests can't be cached!
+PMA_noCacheHeader();
+
+// $GLOBALS["message"] is used for asking for an import message
+if (isset($GLOBALS["message"]) && $GLOBALS["message"]) {
+
+    header('Content-type: text/html');
+
+    // wait 0.3 sec before we check for $_SESSION variable,
+    // which is set inside import.php
+    usleep(300000);
+
+    // wait until message is available
+    while ($_SESSION['Import_message']['message'] == null) {
+        usleep(250000); // 0.25 sec
+    }
+
+    echo $_SESSION['Import_message']['message'];
+    echo '<fieldset class="tblFooters">' . "\n";
+    echo '    [ <a href="' . $_SESSION['Import_message']['go_back_url']
+        . '">' . __('Back') . '</a> ]' . "\n";
+    echo '</fieldset>'."\n";
+
+} else {
+    PMA_importAjaxStatus($GLOBALS["id"]);
+}
+?>
diff --git a/phpmyadmin/index.php b/phpmyadmin/index.php
new file mode 100644
index 0000000..0e87ccd
--- /dev/null
+++ b/phpmyadmin/index.php
@@ -0,0 +1,616 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ *
+ * @package PhpMyAdmin
+ */
+
+/**
+ * Gets some core libraries and displays a top message if required
+ */
+require_once 'libraries/common.inc.php';
+
+/**
+ * display Git revision if requested
+ */
+require_once 'libraries/display_git_revision.lib.php';
+
+/**
+ * pass variables to child pages
+ */
+$drops = array(
+    'lang',
+    'server',
+    'collation_connection',
+    'db',
+    'table'
+);
+foreach ($drops as $each_drop) {
+    if (array_key_exists($each_drop, $_GET)) {
+        unset($_GET[$each_drop]);
+    }
+}
+unset($drops, $each_drop);
+
+// If we have a valid target, let's load that script instead
+if (! empty($_REQUEST['target'])
+    && is_string($_REQUEST['target'])
+    && ! preg_match('/^index/', $_REQUEST['target'])
+    && in_array($_REQUEST['target'], $goto_whitelist)
+) {
+    include $_REQUEST['target'];
+    exit;
+}
+
+/**
+ * Check if it is an ajax request to reload the recent tables list.
+ */
+require_once 'libraries/RecentTable.class.php';
+if ($GLOBALS['is_ajax_request'] && ! empty($_REQUEST['recent_table'])) {
+    $response = PMA_Response::getInstance();
+    $response->addJSON(
+        'options',
+        PMA_RecentTable::getInstance()->getHtmlSelectOption()
+    );
+    exit;
+}
+
+if ($GLOBALS['PMA_Config']->isGitRevision()) {
+    if (isset($_REQUEST['git_revision']) && $GLOBALS['is_ajax_request'] == true) {
+        PMA_printGitRevision();
+        exit;
+    }
+    echo '<div id="is_git_revision"></div>';
+}
+
+// Handles some variables that may have been sent by the calling script
+$GLOBALS['db'] = '';
+$GLOBALS['table'] = '';
+$show_query = '1';
+
+// Any message to display?
+if (! empty($message)) {
+    echo PMA_Util::getMessage($message);
+    unset($message);
+}
+
+$common_url_query =  PMA_generate_common_url('', '');
+
+// when $server > 0, a server has been chosen so we can display
+// all MySQL-related information
+if ($server > 0) {
+    include 'libraries/server_common.inc.php';
+    include 'libraries/StorageEngine.class.php';
+
+    // Use the verbose name of the server instead of the hostname
+    // if a value is set
+    $server_info = '';
+    if (! empty($cfg['Server']['verbose'])) {
+        $server_info .= htmlspecialchars($cfg['Server']['verbose']);
+        if ($GLOBALS['cfg']['ShowServerInfo']) {
+            $server_info .= ' (';
+        }
+    }
+    if ($GLOBALS['cfg']['ShowServerInfo'] || empty($cfg['Server']['verbose'])) {
+        $server_info .= PMA_DBI_get_host_info();
+    }
+    if (! empty($cfg['Server']['verbose']) && $GLOBALS['cfg']['ShowServerInfo']) {
+        $server_info .= ')';
+    }
+    $mysql_cur_user_and_host = PMA_DBI_fetch_value('SELECT USER();');
+
+    // should we add the port info here?
+    $short_server_info = (!empty($GLOBALS['cfg']['Server']['verbose'])
+                ? $GLOBALS['cfg']['Server']['verbose']
+                : $GLOBALS['cfg']['Server']['host']);
+}
+
+echo '<div id="maincontainer">' . "\n";
+echo '<div id="main_pane_left">';
+if ($server > 0 || count($cfg['Servers']) > 1
+) {
+    echo '<div class="group">';
+    echo '<h2>' . __('General Settings') . '</h2>';
+    echo '<ul>';
+
+    /**
+     * Displays the MySQL servers choice form
+     */
+    if ($cfg['ServerDefault'] == 0 
+        || (! $cfg['NavigationDisplayServers']
+            && (count($cfg['Servers']) > 1 
+                || ($server == 0 && count($cfg['Servers']) == 1)
+            )
+        )
+    ) {
+        echo '<li id="li_select_server" class="no_bullets" >';
+        include_once 'libraries/select_server.lib.php';
+        echo PMA_Util::getImage('s_host.png') . " " . PMA_selectServer(true, true);
+        echo '</li>';
+    }
+
+    /**
+     * Displays the mysql server related links
+     */
+    if ($server > 0 && ! PMA_DRIZZLE) {
+        include_once 'libraries/check_user_privileges.lib.php';
+
+        // Logout for advanced authentication
+        if ($cfg['Server']['auth_type'] != 'config') {
+            if ($cfg['ShowChgPassword']) {
+                $conditional_class = 'ajax';
+                PMA_printListItem(
+                    PMA_Util::getImage('s_passwd.png') . " " . __('Change password'),
+                    'li_change_password',
+                    'user_password.php?' . $common_url_query,
+                    null,
+                    null,
+                    'change_password_anchor',
+                    "no_bullets",
+                    $conditional_class
+                );
+            }
+        } // end if
+        echo '    <li id="li_select_mysql_collation" class="no_bullets" >';
+        echo '        <form method="post" action="index.php">' . "\n"
+           . PMA_generate_common_hidden_inputs(null, null, 4, 'collation_connection')
+           . '            <label for="select_collation_connection">' . "\n"
+           . '                '. PMA_Util::getImage('s_asci.png') . " " 
+                               . __('Server connection collation') . "\n"
+           // put the doc link in the form so that it appears on the same line
+           . PMA_Util::showMySQLDocu(
+               'MySQL_Database_Administration',
+               'Charset-connection'
+           )
+           . ': ' .  "\n"
+           . '            </label>' . "\n"
+
+           . PMA_generateCharsetDropdownBox(
+               PMA_CSDROPDOWN_COLLATION,
+               'collation_connection',
+               'select_collation_connection',
+               $collation_connection,
+               true,
+               4,
+               true
+           )
+           . '        </form>' . "\n"
+           . '    </li>' . "\n";
+    } // end of if ($server > 0 && !PMA_DRIZZLE)
+    echo '</ul>';
+    echo '</div>';
+}
+
+echo '<div class="group">';
+echo '<h2>' . __('Appearance Settings') . '</h2>';
+echo '  <ul>';
+
+// Displays language selection combo
+if (empty($cfg['Lang']) && count($GLOBALS['available_languages']) > 1) {
+    echo '<li id="li_select_lang" class="no_bullets">';
+    include_once 'libraries/display_select_lang.lib.php';
+    echo PMA_Util::getImage('s_lang.png') . " " . PMA_getLanguageSelectorHtml();
+    echo '</li>';
+}
+
+// ThemeManager if available
+
+if ($GLOBALS['cfg']['ThemeManager']) {
+    echo '<li id="li_select_theme" class="no_bullets">';
+    echo PMA_Util::getImage('s_theme.png') . " "
+            .  $_SESSION['PMA_Theme_Manager']->getHtmlSelectBox();
+    echo '</li>';
+}
+echo '<li id="li_select_fontsize">';
+echo PMA_Config::getFontsizeForm();
+echo '</li>';
+
+echo '</ul>';
+
+// User preferences
+
+if ($server > 0) {
+    echo '<ul>';
+    PMA_printListItem(
+        PMA_Util::getImage('b_tblops.png')." " .__('More settings'),
+        'li_user_preferences',
+        'prefs_manage.php?' . $common_url_query,
+        null,
+        null,
+        null,
+        "no_bullets"
+    );
+    echo '</ul>';
+}
+
+echo '</div>';
+
+
+echo '</div>';
+echo '<div id="main_pane_right">';
+
+
+if ($server > 0 && $GLOBALS['cfg']['ShowServerInfo']) {
+
+    echo '<div class="group">';
+    echo '<h2>' . __('Database server') . '</h2>';
+    echo '<ul>' . "\n";
+    PMA_printListItem(
+        __('Server') . ': ' . $server_info,
+        'li_server_info'
+    );
+    PMA_printListItem(
+        __('Server type') . ': ' . PMA_Util::getServerType(),
+        'li_server_type'
+    );
+    PMA_printListItem(
+        __('Server version') . ': ' . PMA_MYSQL_STR_VERSION . ' - ' . PMA_MYSQL_VERSION_COMMENT,
+        'li_server_version'
+    );
+    PMA_printListItem(
+        __('Protocol version') . ': ' . PMA_DBI_get_proto_info(),
+        'li_mysql_proto'
+    );
+    PMA_printListItem(
+        __('User') . ': ' . htmlspecialchars($mysql_cur_user_and_host),
+        'li_user_info'
+    );
+
+    echo '    <li id="li_select_mysql_charset">';
+    echo '        ' . __('Server charset') . ': '
+       . '        <span lang="en" dir="ltr">'
+       . '           ' . $mysql_charsets_descriptions[$mysql_charset_map['utf-8']] . "\n"
+       . '           (' . $mysql_charset_map['utf-8'] . ')' . "\n"
+       . '        </span>' . "\n"
+       . '    </li>' . "\n";
+    echo '  </ul>';
+    echo ' </div>';
+}
+
+if ($GLOBALS['cfg']['ShowServerInfo'] || $GLOBALS['cfg']['ShowPhpInfo']) {
+    echo '<div class="group">';
+    echo '<h2>' . __('Web server') . '</h2>';
+    echo '<ul>';
+    if ($GLOBALS['cfg']['ShowServerInfo']) {
+        PMA_printListItem($_SERVER['SERVER_SOFTWARE'], 'li_web_server_software');
+
+        if ($server > 0) {
+            $client_version_str = PMA_DBI_get_client_info();
+            if (preg_match('#\d+\.\d+\.\d+#', $client_version_str)
+                && in_array($GLOBALS['cfg']['Server']['extension'], array('mysql', 'mysqli'))
+            ) {
+                $client_version_str = 'libmysql - ' . $client_version_str;
+            }
+            PMA_printListItem(
+                __('Database client version') . ': ' . $client_version_str,
+                'li_mysql_client_version'
+            );
+
+            $php_ext_string = __('PHP extension') . ': '
+                . $GLOBALS['cfg']['Server']['extension'] . ' '
+                . PMA_Util::showPHPDocu(
+                    'book.' . $GLOBALS['cfg']['Server']['extension'] . '.php'
+                );
+            PMA_printListItem(
+                $php_ext_string,
+                'li_used_php_extension'
+            );
+        }
+    }
+
+    if ($cfg['ShowPhpInfo']) {
+        PMA_printListItem(
+            __('Show PHP information'),
+            'li_phpinfo',
+            'phpinfo.php?' . $common_url_query,
+            null,
+            '_blank'
+        );
+    }
+    echo '  </ul>';
+    echo ' </div>';
+}
+
+echo '<div class="group pmagroup">';
+echo '<h2>phpMyAdmin</h2>';
+echo '<ul>';
+$class = null;
+// We rely on CSP to allow access to http://www.phpmyadmin.net, but IE lacks
+// support here and does not allow request to http once using https.
+if ($GLOBALS['cfg']['VersionCheck']
+    && (! $GLOBALS['PMA_Config']->get('is_https') || PMA_USR_BROWSER_AGENT != 'IE')
+) {
+    $class = 'jsversioncheck';
+}
+PMA_printListItem(
+    __('Version information') . ': ' . PMA_VERSION,
+    'li_pma_version',
+    null,
+    null,
+    null,
+    null,
+    $class
+);
+PMA_printListItem(
+    __('Documentation'),
+    'li_pma_docs',
+    PMA_Util::getDocuLink('index'),
+    null,
+    '_blank'
+);
+PMA_printListItem(
+    __('Wiki'),
+    'li_pma_wiki',
+    PMA_linkURL('http://wiki.phpmyadmin.net/'),
+    null,
+    '_blank'
+);
+
+// does not work if no target specified, don't know why
+PMA_printListItem(
+    __('Official Homepage'),
+    'li_pma_homepage',
+    PMA_linkURL('http://www.phpMyAdmin.net/'),
+    null,
+    '_blank'
+);
+PMA_printListItem(
+    __('Contribute'),
+    'li_pma_contribute',
+    PMA_linkURL('http://www.phpmyadmin.net/home_page/improve.php'),
+    null,
+    '_blank'
+);
+PMA_printListItem(
+    __('Get support'),
+    'li_pma_support',
+    PMA_linkURL('http://www.phpmyadmin.net/home_page/support.php'),
+    null,
+    '_blank'
+);
+PMA_printListItem(
+    __('List of changes'),
+    'li_pma_changes',
+    PMA_linkURL('changelog.php'),
+    null,
+    '_blank'
+);
+?>
+    </ul>
+ </div>
+
+</div>
+
+</div>
+
+<?php
+/**
+ * Warning if using the default MySQL privileged account
+ */
+if ($server != 0
+    && $cfg['Server']['user'] == 'root'
+    && $cfg['Server']['password'] == ''
+) {
+    trigger_error(
+        __('Your configuration file contains settings (root with no password) that correspond to the default MySQL privileged account. Your MySQL server is running with this default, is open to intrusion, and you really should fix this security hole by setting a password for user \'root\'.'),
+        E_USER_WARNING
+    );
+}
+
+/**
+ * Nijel: As we try to handle charsets by ourself, mbstring overloads just
+ * break it, see bug 1063821.
+ */
+if (@extension_loaded('mbstring') && @ini_get('mbstring.func_overload') > 1) {
+    trigger_error(
+        __('You have enabled mbstring.func_overload in your PHP configuration. This option is incompatible with phpMyAdmin and might cause some data to be corrupted!'),
+        E_USER_WARNING
+    );
+}
+
+/**
+ * Nijel: mbstring is used for handling multibyte inside parser, so it is good
+ * to tell user something might be broken without it, see bug #1063149.
+ */
+if (! @extension_loaded('mbstring')) {
+    trigger_error(
+        __('The mbstring PHP extension was not found and you seem to be using a multibyte charset. Without the mbstring extension phpMyAdmin is unable to split strings correctly and it may result in unexpected results.'),
+        E_USER_WARNING
+    );
+}
+
+/**
+ * Check whether session.gc_maxlifetime limits session validity.
+ */
+$gc_time = (int)@ini_get('session.gc_maxlifetime');
+if ($gc_time < $GLOBALS['cfg']['LoginCookieValidity'] ) {
+    trigger_error(
+        __('Your PHP parameter [a at http://php.net/manual/en/session.configuration.php#ini.session.gc-maxlifetime at _blank]session.gc_maxlifetime[/a] is lower than cookie validity configured in phpMyAdmin, because of this, your login will expire sooner than configured in phpMyAdmin.'),
+        E_USER_WARNING
+    );
+}
+
+/**
+ * Check whether LoginCookieValidity is limited by LoginCookieStore.
+ */
+if ($GLOBALS['cfg']['LoginCookieStore'] != 0
+    && $GLOBALS['cfg']['LoginCookieStore'] < $GLOBALS['cfg']['LoginCookieValidity']
+) {
+    trigger_error(
+        __('Login cookie store is lower than cookie validity configured in phpMyAdmin, because of this, your login will expire sooner than configured in phpMyAdmin.'),
+        E_USER_WARNING
+    );
+}
+
+/**
+ * Check if user does not have defined blowfish secret and it is being used.
+ */
+if (! empty($_SESSION['auto_blowfish_secret'])
+    && empty($GLOBALS['cfg']['blowfish_secret'])
+) {
+    trigger_error(
+        __('The configuration file now needs a secret passphrase (blowfish_secret).'),
+        E_USER_WARNING
+    );
+}
+
+/**
+ * Check for existence of config directory which should not exist in
+ * production environment.
+ */
+if (file_exists('config')) {
+    trigger_error(
+        __('Directory [code]config[/code], which is used by the setup script, still exists in your phpMyAdmin directory. You should remove it once phpMyAdmin has been configured.'),
+        E_USER_WARNING
+    );
+}
+
+if ($server > 0) {
+    $cfgRelation = PMA_getRelationsParam();
+    if (! $cfgRelation['allworks']
+        && $cfg['PmaNoRelation_DisableWarning'] == false
+    ) {
+        $msg = PMA_Message::notice(__('The phpMyAdmin configuration storage is not completely configured, some extended features have been deactivated. To find out why click %shere%s.'));
+        $msg->addParam(
+            '<a href="' . $cfg['PmaAbsoluteUri'] . 'chk_rel.php?' . $common_url_query . '">',
+            false
+        );
+        $msg->addParam('</a>', false);
+        /* Show error if user has configured something, notice elsewhere */
+        if (!empty($cfg['Servers'][$server]['pmadb'])) {
+            $msg->isError(true);
+        }
+        $msg->display();
+    } // end if
+}
+
+/**
+ * Warning about different MySQL library and server version
+ * (a difference on the third digit does not count).
+ * If someday there is a constant that we can check about mysqlnd,
+ * we can use it instead of strpos().
+ * If no default server is set, PMA_DBI_get_client_info() is not defined yet.
+ * Drizzle can speak MySQL protocol, so don't warn about version mismatch for
+ * Drizzle servers.
+ */
+if (function_exists('PMA_DBI_get_client_info') && !PMA_DRIZZLE) {
+    $_client_info = PMA_DBI_get_client_info();
+    if ($server > 0
+        && strpos($_client_info, 'mysqlnd') === false
+        && substr(PMA_MYSQL_CLIENT_API, 0, 3) != substr(PMA_MYSQL_INT_VERSION, 0, 3)
+    ) {
+        trigger_error(
+            PMA_sanitize(
+                sprintf(
+                    __('Your PHP MySQL library version %s differs from your MySQL server version %s. This may cause unpredictable behavior.'),
+                    $_client_info,
+                    substr(
+                        PMA_MYSQL_STR_VERSION,
+                        0,
+                        strpos(PMA_MYSQL_STR_VERSION . '-', '-')
+                    )
+                )
+            ),
+            E_USER_NOTICE
+        );
+    }
+    unset($_client_info);
+}
+
+/**
+ * Warning about Suhosin
+ */
+if ($cfg['SuhosinDisableWarning'] == false
+    && @ini_get('suhosin.request.max_value_length')
+    // warn about Suhosin only if its simulation mode is not enabled
+    && @ini_get('suhosin.simulation') == '0'
+) {
+    trigger_error(
+        sprintf(
+            __('Server running with Suhosin. Please refer to %sdocumentation%s for possible issues.'),
+            '[doc at faq1-38]',
+            '[/doc]'
+        ),
+        E_USER_WARNING
+    );
+}
+
+/**
+ * Warning about mcrypt.
+ */
+if (! function_exists('mcrypt_encrypt')
+    && ! $GLOBALS['cfg']['McryptDisableWarning']
+) {
+    PMA_warnMissingExtension('mcrypt');
+}
+
+/**
+ * Warning about incomplete translations.
+ *
+ * The data file is created while creating release by ./scripts/remove-incomplete-mo
+ */
+if (file_exists('libraries/language_stats.inc.php')) {
+    include 'libraries/language_stats.inc.php';
+    /*
+     * This message is intentionally not translated, because we're
+     * handling incomplete translations here and focus on english
+     * speaking users.
+     */
+    if (isset($GLOBALS['language_stats'][$lang])
+        && $GLOBALS['language_stats'][$lang] < $cfg['TranslationWarningThreshold']
+    ) {
+        trigger_error(
+            'You are using an incomplete translation, please help to make it better by <a href="http://www.phpmyadmin.net/home_page/improve.php#translate" target="_blank">contributing</a>.',
+            E_USER_NOTICE
+        );
+    }
+}
+
+/**
+ * prints list item for main page
+ *
+ * @param string $name            displayed text
+ * @param string $id              id, used for css styles
+ * @param string $url             make item as link with $url as target
+ * @param string $mysql_help_page display a link to MySQL's manual
+ * @param string $target          special target for $url
+ * @param string $a_id            id for the anchor,
+ *                                used for jQuery to hook in functions
+ * @param string $class           class for the li element
+ * @param string $a_class         class for the anchor element
+ *
+ * @return void
+ */
+function PMA_printListItem($name, $id = null, $url = null, $mysql_help_page = null,
+    $target = null, $a_id = null, $class = null, $a_class = null
+) {
+    echo '<li id="' . $id . '"';
+    if (null !== $class) {
+        echo ' class="' . $class . '"';
+    }
+    echo '>';
+    if (null !== $url) {
+        echo '<a href="' . $url . '"';
+        if (null !== $target) {
+            echo ' target="' . $target . '"';
+        }
+        if (null != $a_id) {
+            echo ' id="' . $a_id .'"';
+        }
+        if (null != $a_class) {
+            echo ' class="' . $a_class .'"';
+        }
+        echo '>';
+    }
+
+    echo $name;
+
+    if (null !== $url) {
+        echo '</a>' . "\n";
+    }
+    if (null !== $mysql_help_page) {
+        echo PMA_Util::showMySQLDocu('', $mysql_help_page);
+    }
+    echo '</li>';
+}
+?>
diff --git a/phpmyadmin/js/OpenStreetMap.js b/phpmyadmin/js/OpenStreetMap.js
new file mode 100644
index 0000000..dbef7b0
--- /dev/null
+++ b/phpmyadmin/js/OpenStreetMap.js
@@ -0,0 +1 @@
+OpenLayers.Util.OSM={};OpenLayers.Util.OSM.MISSING_TILE_URL="http://www.openstreetmap.org/openlayers/img/404.png";OpenLayers.Util.OSM.originalOnImageLoadError=OpenLayers.Util.onImageLoadError;OpenLayers.Util.onImageLoadError=function(){if(this.src.match(/^http:\/\/[abc]\.[a-z]+\.openstreetmap\.org\//)){this.src=OpenLayers.Util.OSM.MISSING_TILE_URL}else{if(this.src.match(/^http:\/\/[def]\.tah\.openstreetmap\.org\//)){}else{OpenLayers.Util.OSM.originalOnImageLoadError}}};OpenLayers.Layer.O [...]
\ No newline at end of file
diff --git a/phpmyadmin/js/ajax.js b/phpmyadmin/js/ajax.js
new file mode 100644
index 0000000..a4d659f
--- /dev/null
+++ b/phpmyadmin/js/ajax.js
@@ -0,0 +1 @@
+var AJAX={active:false,source:null,_callback:function(){},_debug:false,$msgbox:null,hash:function(c){c+="";var a=c.length,d=0,b=0;for(;b<a;++b){d+=c.charCodeAt(b);d+=(d<<10);d^=(d>>6)}d+=(d<<3);d^=(d>>11);d+=(d<<15);return Math.abs(d)},registerOnload:function(b,c){var a="onload_"+AJAX.hash(b);$(document).bind(a,c);this._debug&&console.log("Registered event "+a+" for file "+b);return this},registerTeardown:function(b,c){var a="teardown_"+AJAX.hash(b);$(document).bind(a,c);this._debug&&con [...]
\ No newline at end of file
diff --git a/phpmyadmin/js/canvg/MIT-LICENSE.txt b/phpmyadmin/js/canvg/MIT-LICENSE.txt
new file mode 100644
index 0000000..40f19bd
--- /dev/null
+++ b/phpmyadmin/js/canvg/MIT-LICENSE.txt
@@ -0,0 +1,22 @@
+Copyright (c) 2010-2011 Gabe Lerner (gabelerner at gmail.com) - http://code.google.com/p/canvg/
+
+ Permission is hereby granted, free of charge, to any person
+ obtaining a copy of this software and associated documentation
+ files (the "Software"), to deal in the Software without
+ restriction, including without limitation the rights to use,
+ copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the
+ Software is furnished to do so, subject to the following
+ conditions:
+
+ The above copyright notice and this permission notice shall be
+ included in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ OTHER DEALINGS IN THE SOFTWARE.
\ No newline at end of file
diff --git a/phpmyadmin/js/canvg/canvg.js b/phpmyadmin/js/canvg/canvg.js
new file mode 100644
index 0000000..fcea2ec
--- /dev/null
+++ b/phpmyadmin/js/canvg/canvg.js
@@ -0,0 +1 @@
+if(!window.console){window.console={};window.console.log=function(a){};window.console.dir=function(a){}}if(!Array.indexOf){Array.prototype.indexOf=function(b){for(var a=0;a<this.length;a++){if(this[a]==b){return a}}return -1}}(function(){this.canvg=function(j,m,b){if(j==null&&m==null&&b==null){var e=document.getElementsByTagName("svg");for(var g=0;g<e.length;g++){var f=e[g];var k=document.createElement("canvas");k.width=f.clientWidth;k.height=f.clientHeight;f.parentNode.insertBefore(k,f) [...]
\ No newline at end of file
diff --git a/phpmyadmin/js/canvg/flashcanvas.js b/phpmyadmin/js/canvg/flashcanvas.js
new file mode 100644
index 0000000..4ae4f5b
--- /dev/null
+++ b/phpmyadmin/js/canvg/flashcanvas.js
@@ -0,0 +1 @@
+if(window.ActiveXObject&&!window.CanvasRenderingContext2D){(function(window,document,undefined){var NULL=null;var CANVAS="canvas";var CANVAS_RENDERING_CONTEXT_2D="CanvasRenderingContext2D";var CANVAS_GRADIENT="CanvasGradient";var CANVAS_PATTERN="CanvasPattern";var FLASH_CANVAS="FlashCanvas";var G_VML_CANVAS_MANAGER="G_vmlCanvasManager";var OBJECT_ID_PREFIX="external";var ON_FOCUS="onfocus";var ON_PROPERTY_CHANGE="onpropertychange";var ON_READY_STATE_CHANGE="onreadystatechange";var ON_UNL [...]
\ No newline at end of file
diff --git a/phpmyadmin/js/canvg/flashcanvas.swf b/phpmyadmin/js/canvg/flashcanvas.swf
new file mode 100644
index 0000000..66ff213
Binary files /dev/null and b/phpmyadmin/js/canvg/flashcanvas.swf differ
diff --git a/phpmyadmin/js/chart.js b/phpmyadmin/js/chart.js
new file mode 100644
index 0000000..6192c58
--- /dev/null
+++ b/phpmyadmin/js/chart.js
@@ -0,0 +1 @@
+var ChartType={LINE:"line",SPLINE:"spline",AREA:"area",BAR:"bar",COLUMN:"column",PIE:"pie",TIMELINE:"timeline"};var ChartFactory=function(){};ChartFactory.prototype={createChart:function(b,a){throw new Error("createChart must be implemented by a subclass")}};var Chart=function(a){this.elementId=a};Chart.prototype={draw:function(b,a){throw new Error("draw must be implemented by a subclass")},redraw:function(a){throw new Error("redraw must be implemented by a subclass")},destroy:function() [...]
\ No newline at end of file
diff --git a/phpmyadmin/js/codemirror/LICENSE b/phpmyadmin/js/codemirror/LICENSE
new file mode 100644
index 0000000..3f7c0bb
--- /dev/null
+++ b/phpmyadmin/js/codemirror/LICENSE
@@ -0,0 +1,19 @@
+Copyright (C) 2011 by Marijn Haverbeke <marijnh at gmail.com>
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
diff --git a/phpmyadmin/js/codemirror/lib/codemirror.js b/phpmyadmin/js/codemirror/lib/codemirror.js
new file mode 100644
index 0000000..5188f16
--- /dev/null
+++ b/phpmyadmin/js/codemirror/lib/codemirror.js
@@ -0,0 +1 @@
+window.CodeMirror=(function(){function r(a9,a5){var ct={},bG=r.defaults;for(var aX in bG){if(bG.hasOwnProperty(aX)){ct[aX]=(a5&&a5.hasOwnProperty(aX)?a5:bG)[aX]}}var bJ=ak("textarea",null,null,"position: absolute; padding: 0; width: 1px; height: 1em");bJ.setAttribute("wrap","off");bJ.setAttribute("autocorrect","off");bJ.setAttribute("autocapitalize","off");var cp=ak("div",[bJ],null,"overflow: hidden; position: relative; width: 3px; height: 0px;");var cR=ak("div",null,"CodeMirror-scrollba [...]
\ No newline at end of file
diff --git a/phpmyadmin/js/codemirror/mode/mysql/mysql.js b/phpmyadmin/js/codemirror/mode/mysql/mysql.js
new file mode 100644
index 0000000..029094c
--- /dev/null
+++ b/phpmyadmin/js/codemirror/mode/mysql/mysql.js
@@ -0,0 +1 @@
+CodeMirror.defineMode("mysql",function(b){var e=b.indentUnit;var l;function g(n){return new RegExp("^(?:"+n.join("|")+")$","i")}var a=g(["str","lang","langmatches","datatype","bound","sameterm","isiri","isuri","isblank","isliteral","union","a"]);var d=g([("ACCESSIBLE"),("ALTER"),("AS"),("BEFORE"),("BINARY"),("BY"),("CASE"),("CHARACTER"),("COLUMN"),("CONTINUE"),("CROSS"),("CURRENT_TIMESTAMP"),("DATABASE"),("DAY_MICROSECOND"),("DEC"),("DEFAULT"),("DESC"),("DISTINCT"),("DOUBLE"),("EACH"),(" [...]
\ No newline at end of file
diff --git a/phpmyadmin/js/common.js b/phpmyadmin/js/common.js
new file mode 100644
index 0000000..ca3343e
--- /dev/null
+++ b/phpmyadmin/js/common.js
@@ -0,0 +1 @@
+$(function(){$("#pma_open_querywindow").click(function(a){a.preventDefault();PMA_querywindow.focus()})});var PMA_commonParams=(function(){var a={};return{setAll:function(d){var c=false;for(var b in d){if(a[b]!==undefined&&a[b]!==d[b]){c=true}a[b]=d[b]}if(c){PMA_querywindow.refresh()}},get:function(b){return a[b]||""},set:function(b,c){if(a[b]!==undefined&&a[b]!==c){PMA_querywindow.refresh();PMA_reloadNavigation()}a[b]=c;return this},getUrlQuery:function(){return $.sprintf("?%s&server=%s& [...]
\ No newline at end of file
diff --git a/phpmyadmin/js/config.js b/phpmyadmin/js/config.js
new file mode 100644
index 0000000..fafd121
--- /dev/null
+++ b/phpmyadmin/js/config.js
@@ -0,0 +1 @@
+AJAX.registerTeardown("config.js",function(){$("input[id], select[id], textarea[id]").unbind("change").unbind("keyup");$("input[type=button][name=submit_reset]").unbind("click");$("div.tabs_contents").undelegate();$("#import_local_storage, #export_local_storage").unbind("click");$("form.prefs-form").unbind("change").unbind("submit");$("div.click-hide-message").die("click");$("#prefs_autoload").find("a").unbind("click")});AJAX.registerOnload("config.js",function(){$("#topmenu2").find("li. [...]
\ No newline at end of file
diff --git a/phpmyadmin/js/date.js b/phpmyadmin/js/date.js
new file mode 100644
index 0000000..367a42a
--- /dev/null
+++ b/phpmyadmin/js/date.js
@@ -0,0 +1 @@
+var MONTH_NAMES=new Array("January","February","March","April","May","June","July","August","September","October","November","December","Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec");var DAY_NAMES=new Array("Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday","Sun","Mon","Tue","Wed","Thu","Fri","Sat");function LZ(a){return(a<0||a>9?"":"0")+a}function isDate(c,b){var a=getDateFromFormat(c,b);if(a==0){return false}return true}function compareDate [...]
\ No newline at end of file
diff --git a/phpmyadmin/js/db_operations.js b/phpmyadmin/js/db_operations.js
new file mode 100644
index 0000000..2885532
--- /dev/null
+++ b/phpmyadmin/js/db_operations.js
@@ -0,0 +1 @@
+AJAX.registerTeardown("db_operations.js",function(){$("#rename_db_form.ajax").die("submit");$("#copy_db_form.ajax").die("submit");$("#change_db_charset_form.ajax").die("submit")});AJAX.registerOnload("db_operations.js",function(){$("#rename_db_form.ajax").live("submit",function(c){c.preventDefault();var b=$(this);var a=escapeHtml("CREATE DATABASE "+$("#new_db_name").val()+" / DROP DATABASE "+PMA_commonParams.get("db"));PMA_prepareForAjaxRequest(b);b.PMA_confirm(a,b.attr("action"),functio [...]
\ No newline at end of file
diff --git a/phpmyadmin/js/db_search.js b/phpmyadmin/js/db_search.js
new file mode 100644
index 0000000..7b16ed3
--- /dev/null
+++ b/phpmyadmin/js/db_search.js
@@ -0,0 +1 @@
+AJAX.registerTeardown("db_search.js",function(){$("#buttonGo").unbind("click");$("#togglesearchresultlink").unbind("click");$("#togglequerybox").unbind("click");$("#togglesearchformlink").unbind("click");$("#db_search_form.ajax").die("submit")});function loadResult(c,a,b){$(function(){var d=PMA_ajaxShowMessage(PMA_messages.strBrowsing,false);$("#sqlqueryform").hide();$("#togglequerybox").hide();$("#table-info").show();$("#table-link").attr({href:"sql.php?"+b}).text(a);var e=c+" #sqlquery [...]
\ No newline at end of file
diff --git a/phpmyadmin/js/db_structure.js b/phpmyadmin/js/db_structure.js
new file mode 100644
index 0000000..7fd952b
--- /dev/null
+++ b/phpmyadmin/js/db_structure.js
@@ -0,0 +1 @@
+AJAX.registerTeardown("db_structure.js",function(){$("span.fkc_switch").unbind("click");$("#fkc_checkbox").unbind("change");$("a.truncate_table_anchor.ajax").die("click");$("a.drop_table_anchor.ajax").die("click");$("a.drop_tracking_anchor.ajax").die("click");$("#real_end_input").die("click")});function PMA_adjustTotals(){var a=new Array(PMA_messages.strB,PMA_messages.strKiB,PMA_messages.strMiB,PMA_messages.strGiB,PMA_messages.strTiB,PMA_messages.strPiB,PMA_messages.strEiB);var g=$("#tab [...]
\ No newline at end of file
diff --git a/phpmyadmin/js/export.js b/phpmyadmin/js/export.js
new file mode 100644
index 0000000..d2bece3
--- /dev/null
+++ b/phpmyadmin/js/export.js
@@ -0,0 +1 @@
+AJAX.registerTeardown("export.js",function(){$("#plugins").unbind("change");$("input[type='radio'][name='sql_structure_or_data']").unbind("change");$("input[type='radio'][name='latex_structure_or_data']").unbind("change");$("input[type='radio'][name='odt_structure_or_data']").unbind("change");$("input[type='radio'][name='texytext_structure_or_data']").unbind("change");$("input[type='radio'][name='htmlword_structure_or_data']").unbind("change");$("input[type='radio'][name='sql_structure_o [...]
\ No newline at end of file
diff --git a/phpmyadmin/js/functions.js b/phpmyadmin/js/functions.js
new file mode 100644
index 0000000..aa663d4
--- /dev/null
+++ b/phpmyadmin/js/functions.js
@@ -0,0 +1 @@
+var $table_clone=false;var sql_box_locked=false;var only_once_elements=[];var ajax_message_count=0;var codemirror_editor=false;var codemirror_inline_editor=false;var chart_activeTimeouts={};$.ajaxPrefilter(function(a,d,c){var b=new Date().getTime()+""+Math.floor(Math.random()*1000000);if(typeof a.data=="string"){a.data+="&_nocache="+b}else{if(typeof a.data=="object"){a.data=$.extend(d.data,{_nocache:b})}}});function PMA_prepareForAjaxRequest(a){if(!a.find("input:hidden").is("#ajax_reques [...]
\ No newline at end of file
diff --git a/phpmyadmin/js/get_image.js.php b/phpmyadmin/js/get_image.js.php
new file mode 100644
index 0000000..0861fa3
--- /dev/null
+++ b/phpmyadmin/js/get_image.js.php
@@ -0,0 +1,138 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * Provides the functionality for retreiving images
+ * which may be actual images or an icon from a sprite
+ *
+ * @package PhpMyAdmin
+ */
+chdir('..');
+
+// Send correct type:
+header('Content-Type: text/javascript; charset=UTF-8');
+header('Expires: ' . gmdate('D, d M Y H:i:s', time() + 3600) . ' GMT');
+
+// Avoid loading the full common.inc.php because this would add many
+// non-js-compatible stuff like DOCTYPE
+define('PMA_MINIMUM_COMMON', true);
+require_once './libraries/common.inc.php';
+
+// Get the data for the sprites, if it's available
+if (is_readable($_SESSION['PMA_Theme']->getPath() . '/sprites.lib.php')) {
+    include $_SESSION['PMA_Theme']->getPath() . '/sprites.lib.php';
+}
+$sprites = array();
+if (function_exists('PMA_sprites')) {
+    $sprites = PMA_sprites();
+}
+// We only need the keys from the array of sprites data,
+// since they contain the (partial) class names
+$keys = array();
+foreach ($sprites as $key => $value) {
+    $keys[] = "'$key'";
+}
+
+?>
+/**
+ * Returns an HTML IMG tag for a particular image from a theme,
+ * which may be an actual file or an icon from a sprite
+ *
+ * @param string image      The name of the file to get
+ * @param string alternate  Used to set 'alt' and 'title' attributes of the image
+ * @param object attributes An associative array of other attributes
+ *
+ * @return Object The requested image, this object has two methods:
+ *                  .toString()        - Returns the IMG tag for the requested image
+ *                  .attr(name)        - Returns a particular attribute of the IMG
+ *                                       tag given it's name
+ *                  .attr(name, value) - Sets a particular attribute of the IMG
+ *                                       tag to the given value
+ *                And one property:
+ *                  .isSprite          - Whether the image is a sprite or not
+ */
+function PMA_getImage(image, alternate, attributes) {
+    var in_array = function (needle, haystack) {
+        for (var i in haystack) {
+            if (haystack[i] == needle) {
+                return true;
+            }
+        }
+        return false;
+    };
+    var sprites = [
+        <?php echo implode($keys, ",\n        ") . "\n"; ?>
+    ];
+    // custom image object, it will eventually be returned by this functions
+    var retval = {
+        data: {
+            // this is private
+            alt: '',
+            title: '',
+            src: (typeof PMA_TEST_THEME == 'undefined' ? '' : '../')
+                + 'themes/dot.gif'
+        },
+        isSprite: true,
+        attr: function (name, value) {
+            if (value == undefined) {
+                if (this.data[name] == undefined) {
+                    return '';
+                } else {
+                    return this.data[name];
+                }
+            } else {
+                this.data[name] = value;
+            }
+        },
+        toString: function () {
+            var retval = '<' + 'img';
+            for (var i in this.data) {
+                retval += ' ' + i + '="' + this.data[i] + '"';
+            }
+            retval += ' /' + '>';
+            return retval;
+        }
+    };
+    // initialise missing parameters
+    if (attributes == undefined) {
+        attributes = {};
+    }
+    if (alternate == undefined) {
+        alternate = '';
+    }
+    // set alt
+    if (attributes.alt != undefined) {
+        retval.attr('alt', attributes.alt);
+    } else {
+        retval.attr('alt', alternate);
+    }
+    // set title
+    if (attributes.title != undefined) {
+        retval.attr('title', attributes.title);
+    } else {
+        retval.attr('title', alternate);
+    }
+    // set src
+    var klass = image.replace('.gif', '').replace('.png', '');
+    if (in_array(klass, sprites)) {
+        // it's an icon from a sprite
+        retval.attr('class', 'icon ic_' + klass);
+    } else {
+        // it's an image file
+        retval.isSprite = false;
+        retval.attr('src', "<?php echo $_SESSION['PMA_Theme']->getImgPath(); ?>" + image);
+    }
+    // set all other attrubutes
+    for (var i in attributes) {
+        if (i == 'src') {
+            // do not allow to override the 'src' attribute
+            continue;
+        } else if (i == 'class') {
+            retval.attr(i, retval.attr('class') + ' ' + attributes[i]);
+        } else {
+            retval.attr(i, attributes[i]);
+        }
+    }
+
+    return retval;
+}
+//
\ No newline at end of file
diff --git a/phpmyadmin/js/get_scripts.js.php b/phpmyadmin/js/get_scripts.js.php
new file mode 100644
index 0000000..564fda7
--- /dev/null
+++ b/phpmyadmin/js/get_scripts.js.php
@@ -0,0 +1,38 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * Concatenates reveral js files to reduce the number of
+ * http requests sent to the server
+ *
+ * @package PhpMyAdmin
+ */
+chdir('..');
+
+// Send correct type
+header('Content-Type: text/javascript; charset=UTF-8');
+// Enable browser cache for 1 hour
+header('Expires: ' . gmdate('D, d M Y H:i:s', time() + 3600) . ' GMT');
+
+if (! empty($_GET['scripts']) && is_array($_GET['scripts'])) {
+    foreach ($_GET['scripts'] as $script) {
+        // Sanitise filename
+        $script_name = 'js';
+        $path = explode("/", $script);
+        foreach ($path as $index => $filename) {
+            if (! preg_match("@^\.+$@", $filename)
+                && preg_match("@^[\w\.-]+$@", $filename)
+            ) {
+                // Disallow "." and ".." alone
+                // Allow alphanumeric, "." and "-" chars only
+                $script_name .= DIRECTORY_SEPARATOR . $filename;
+            }
+        }
+        // Output file contents
+        if (preg_match("@\.js$@", $script_name) && is_readable($script_name)) {
+            readfile($script_name);
+            echo ";\n\n";
+        }
+    }
+}
+
+?>
diff --git a/phpmyadmin/js/gis_data_editor.js b/phpmyadmin/js/gis_data_editor.js
new file mode 100644
index 0000000..233df5e
--- /dev/null
+++ b/phpmyadmin/js/gis_data_editor.js
@@ -0,0 +1 @@
+var gisEditorLoaded=false;function closeGISEditor(){$("#popup_background").fadeOut("fast");$("#gis_editor").fadeOut("fast",function(){$(this).empty()})}function prepareJSVersion(){$("#gis_editor input[name='gis_data[save]']").val(PMA_messages.strCopy).insertAfter($("#gis_data_textarea")).before("<br/><br/>");$("#gis_data_editor").prepend('<a class="close_gis_editor" href="#">'+PMA_messages.strClose+"</a>");$('<a class="cancel_gis_editor" href="#"> '+PMA_messages.strCancel+"</a>").insertA [...]
\ No newline at end of file
diff --git a/phpmyadmin/js/import.js b/phpmyadmin/js/import.js
new file mode 100644
index 0000000..c250bae
--- /dev/null
+++ b/phpmyadmin/js/import.js
@@ -0,0 +1 @@
+function changePluginOpts(){$("#format_specific_opts div.format_specific_options").each(function(){$(this).hide()});var a=$("#plugins option:selected").val();$("#"+a+"_options").fadeIn("slow");if(a=="csv"){$("#import_notification").text(PMA_messages.strImportCSV)}else{$("#import_notification").text("")}}function matchFile(d){var b=d.toLowerCase().split(".");var a=b.length;if(a!=0){var c=b[a-1];if(c=="gz"||c=="bz2"||c=="zip"){a--}if($("select[name='format'] option").filterByValue(b[a-1]). [...]
\ No newline at end of file
diff --git a/phpmyadmin/js/indexes.js b/phpmyadmin/js/indexes.js
new file mode 100644
index 0000000..ec86dc5
--- /dev/null
+++ b/phpmyadmin/js/indexes.js
@@ -0,0 +1 @@
+function checkIndexType(){$select_index_type=$("#select_index_type");$size_header=$("#index_columns thead tr th:nth-child(2)");$column_inputs=$('select[name="index[columns][names][]"]');$size_inputs=$('input[name="index[columns][sub_parts][]"]');$add_more=$("#index_frm .tblFooters");if($select_index_type.val()=="SPATIAL"){$size_header.hide();$size_inputs.each(function(){$(this).prop("disabled",true).parent("td").hide()});var a=true;$column_inputs.each(function(){$column_input=$(this);if( [...]
\ No newline at end of file
diff --git a/phpmyadmin/js/jqplot/excanvas.js b/phpmyadmin/js/jqplot/excanvas.js
new file mode 100644
index 0000000..f583bbb
--- /dev/null
+++ b/phpmyadmin/js/jqplot/excanvas.js
@@ -0,0 +1 @@
+if(!document.createElement("canvas").getContext){(function(){var ab=Math;var n=ab.round;var l=ab.sin;var A=ab.cos;var H=ab.abs;var N=ab.sqrt;var d=10;var f=d/2;var z=+navigator.userAgent.match(/MSIE ([\d.]+)?/)[1];function y(){return this.context_||(this.context_=new D(this))}var t=Array.prototype.slice;function g(j,m,p){var i=t.call(arguments,2);return function(){return j.apply(m,i.concat(t.call(arguments)))}}function af(i){return String(i).replace(/&/g,"&").replace(/"/g,""")}f [...]
\ No newline at end of file
diff --git a/phpmyadmin/js/jqplot/jquery.jqplot.js b/phpmyadmin/js/jqplot/jquery.jqplot.js
new file mode 100644
index 0000000..b7aee65
--- /dev/null
+++ b/phpmyadmin/js/jqplot/jquery.jqplot.js
@@ -0,0 +1 @@
+(function(H){var r;H.fn.emptyForce=function(){for(var ab=0,ac;(ac=H(this)[ab])!=null;ab++){if(ac.nodeType===1){H.cleanData(ac.getElementsByTagName("*"))}if(H.jqplot.use_excanvas){ac.outerHTML=""}else{while(ac.firstChild){ac.removeChild(ac.firstChild)}}ac=null}return H(this)};H.fn.removeChildForce=function(ab){while(ab.firstChild){this.removeChildForce(ab.firstChild);ab.removeChild(ab.firstChild)}};H.fn.jqplot=function(){var ab=[];var ad=[];for(var ae=0,ac=arguments.length;ae<ac;ae++){if( [...]
\ No newline at end of file
diff --git a/phpmyadmin/js/jqplot/plugins/jqplot.barRenderer.js b/phpmyadmin/js/jqplot/plugins/jqplot.barRenderer.js
new file mode 100644
index 0000000..f97ca61
--- /dev/null
+++ b/phpmyadmin/js/jqplot/plugins/jqplot.barRenderer.js
@@ -0,0 +1 @@
+(function(d){d.jqplot.BarRenderer=function(){d.jqplot.LineRenderer.call(this)};d.jqplot.BarRenderer.prototype=new d.jqplot.LineRenderer();d.jqplot.BarRenderer.prototype.constructor=d.jqplot.BarRenderer;d.jqplot.BarRenderer.prototype.init=function(o,q){this.barPadding=8;this.barMargin=10;this.barDirection="vertical";this.barWidth=null;this.shadowOffset=2;this.shadowDepth=5;this.shadowAlpha=0.08;this.waterfall=false;this.groups=1;this.varyBarColor=false;this.highlightMouseOver=true;this.hi [...]
\ No newline at end of file
diff --git a/phpmyadmin/js/jqplot/plugins/jqplot.byteFormatter.js b/phpmyadmin/js/jqplot/plugins/jqplot.byteFormatter.js
new file mode 100644
index 0000000..9525bd1
--- /dev/null
+++ b/phpmyadmin/js/jqplot/plugins/jqplot.byteFormatter.js
@@ -0,0 +1 @@
+(function(b){var a=function(f,d){var c=[PMA_messages.strB,PMA_messages.strKiB,PMA_messages.strMiB,PMA_messages.strGiB,PMA_messages.strTiB,PMA_messages.strPiB,PMA_messages.strEiB];while(f>=1024&&d<=6){f/=1024;d++}var e="%.1f";if(Math.floor(f)===f){e="%.0f"}return b.jqplot.sprintf(e+" "+c[d],f)};b.jqplot.byteFormatter=function(c){c=c||0;return function(d,e){if(typeof e==="number"){e=parseFloat(e)||0;return a(e,c)}else{return String(e)}}}})(jQuery);
\ No newline at end of file
diff --git a/phpmyadmin/js/jqplot/plugins/jqplot.canvasAxisLabelRenderer.js b/phpmyadmin/js/jqplot/plugins/jqplot.canvasAxisLabelRenderer.js
new file mode 100644
index 0000000..5c72b7e
--- /dev/null
+++ b/phpmyadmin/js/jqplot/plugins/jqplot.canvasAxisLabelRenderer.js
@@ -0,0 +1 @@
+(function(a){a.jqplot.CanvasAxisLabelRenderer=function(b){this.angle=0;this.axis;this.show=true;this.showLabel=true;this.label="";this.fontFamily='"Trebuchet MS", Arial, Helvetica, sans-serif';this.fontSize="11pt";this.fontWeight="normal";this.fontStretch=1;this.textColor="#666666";this.enableFontSupport=true;this.pt2px=null;this._elem;this._ctx;this._plotWidth;this._plotHeight;this._plotDimensions={height:null,width:null};a.extend(true,this,b);if(b.angle==null&&this.axis!="xaxis"&&this. [...]
\ No newline at end of file
diff --git a/phpmyadmin/js/jqplot/plugins/jqplot.canvasTextRenderer.js b/phpmyadmin/js/jqplot/plugins/jqplot.canvasTextRenderer.js
new file mode 100644
index 0000000..0bbe5c0
--- /dev/null
+++ b/phpmyadmin/js/jqplot/plugins/jqplot.canvasTextRenderer.js
@@ -0,0 +1 @@
+(function(a){a.jqplot.CanvasTextRenderer=function(b){this.fontStyle="normal";this.fontVariant="normal";this.fontWeight="normal";this.fontSize="10px";this.fontFamily="sans-serif";this.fontStretch=1;this.fillStyle="#666666";this.angle=0;this.textAlign="start";this.textBaseline="alphabetic";this.text;this.width;this.height;this.pt2px=1.28;a.extend(true,this,b);this.normalizedFontSize=this.normalizeFontSize(this.fontSize);this.setHeight()};a.jqplot.CanvasTextRenderer.prototype.init=function( [...]
\ No newline at end of file
diff --git a/phpmyadmin/js/jqplot/plugins/jqplot.categoryAxisRenderer.js b/phpmyadmin/js/jqplot/plugins/jqplot.categoryAxisRenderer.js
new file mode 100644
index 0000000..b0fa03c
--- /dev/null
+++ b/phpmyadmin/js/jqplot/plugins/jqplot.categoryAxisRenderer.js
@@ -0,0 +1 @@
+(function(a){a.jqplot.CategoryAxisRenderer=function(b){a.jqplot.LinearAxisRenderer.call(this);this.sortMergedLabels=false};a.jqplot.CategoryAxisRenderer.prototype=new a.jqplot.LinearAxisRenderer();a.jqplot.CategoryAxisRenderer.prototype.constructor=a.jqplot.CategoryAxisRenderer;a.jqplot.CategoryAxisRenderer.prototype.init=function(e){this.groups=1;this.groupLabels=[];this._groupLabels=[];this._grouped=false;this._barsPerGroup=null;this.reverse=false;a.extend(true,this,{tickOptions:{forma [...]
\ No newline at end of file
diff --git a/phpmyadmin/js/jqplot/plugins/jqplot.cursor.js b/phpmyadmin/js/jqplot/plugins/jqplot.cursor.js
new file mode 100644
index 0000000..8f28bb7
--- /dev/null
+++ b/phpmyadmin/js/jqplot/plugins/jqplot.cursor.js
@@ -0,0 +1 @@
+(function(j){j.jqplot.Cursor=function(q){this.style="crosshair";this.previousCursor="auto";this.show=j.jqplot.config.enablePlugins;this.showTooltip=true;this.followMouse=false;this.tooltipLocation="se";this.tooltipOffset=6;this.showTooltipGridPosition=false;this.showTooltipUnitPosition=true;this.showTooltipDataPosition=false;this.tooltipFormatString="%.4P, %.4P";this.useAxesFormatters=true;this.tooltipAxisGroups=[];this.zoom=false;this.zoomProxy=false;this.zoomTarget=false;this.looseZoom [...]
\ No newline at end of file
diff --git a/phpmyadmin/js/jqplot/plugins/jqplot.dateAxisRenderer.js b/phpmyadmin/js/jqplot/plugins/jqplot.dateAxisRenderer.js
new file mode 100644
index 0000000..86d52c5
--- /dev/null
+++ b/phpmyadmin/js/jqplot/plugins/jqplot.dateAxisRenderer.js
@@ -0,0 +1 @@
+(function(h){h.jqplot.DateAxisRenderer=function(){h.jqplot.LinearAxisRenderer.call(this);this.date=new h.jsDate()};var c=1000;var e=60*c;var f=60*e;var l=24*f;var b=7*l;var j=30.4368499*l;var k=365.242199*l;var g=[31,28,31,30,31,30,31,30,31,30,31,30];var i=["%M:%S.%#N","%M:%S.%#N","%M:%S.%#N","%M:%S","%M:%S","%M:%S","%M:%S","%H:%M:%S","%H:%M:%S","%H:%M","%H:%M","%H:%M","%H:%M","%H:%M","%H:%M","%a %H:%M","%a %H:%M","%b %e %H:%M","%b %e %H:%M","%b %e %H:%M","%b %e %H:%M","%v","%v","%v","%v [...]
\ No newline at end of file
diff --git a/phpmyadmin/js/jqplot/plugins/jqplot.highlighter.js b/phpmyadmin/js/jqplot/plugins/jqplot.highlighter.js
new file mode 100644
index 0000000..a26f9f9
--- /dev/null
+++ b/phpmyadmin/js/jqplot/plugins/jqplot.highlighter.js
@@ -0,0 +1 @@
+(function(d){d.jqplot.eventListenerHooks.push(["jqplotMouseMove",f]);d.jqplot.Highlighter=function(h){this.show=d.jqplot.config.enablePlugins;this.markerRenderer=new d.jqplot.MarkerRenderer({shadow:false});this.showMarker=true;this.lineWidthAdjust=2.5;this.sizeAdjust=5;this.showTooltip=true;this.tooltipLocation="nw";this.fadeTooltip=true;this.tooltipFadeSpeed="fast";this.tooltipOffset=2;this.tooltipAxes="both";this.tooltipSeparator=", ";this.tooltipContentEditor=null;this.useAxesFormatte [...]
\ No newline at end of file
diff --git a/phpmyadmin/js/jqplot/plugins/jqplot.pieRenderer.js b/phpmyadmin/js/jqplot/plugins/jqplot.pieRenderer.js
new file mode 100644
index 0000000..714a98a
--- /dev/null
+++ b/phpmyadmin/js/jqplot/plugins/jqplot.pieRenderer.js
@@ -0,0 +1 @@
+(function(e){e.jqplot.PieRenderer=function(){e.jqplot.LineRenderer.call(this)};e.jqplot.PieRenderer.prototype=new e.jqplot.LineRenderer();e.jqplot.PieRenderer.prototype.constructor=e.jqplot.PieRenderer;e.jqplot.PieRenderer.prototype.init=function(q,u){this.diameter=null;this.padding=20;this.sliceMargin=0;this.fill=true;this.shadowOffset=2;this.shadowAlpha=0.07;this.shadowDepth=5;this.highlightMouseOver=true;this.highlightMouseDown=false;this.highlightColors=[];this.dataLabels="percent";t [...]
\ No newline at end of file
diff --git a/phpmyadmin/js/jqplot/plugins/jqplot.pointLabels.js b/phpmyadmin/js/jqplot/plugins/jqplot.pointLabels.js
new file mode 100644
index 0000000..4bfe331
--- /dev/null
+++ b/phpmyadmin/js/jqplot/plugins/jqplot.pointLabels.js
@@ -0,0 +1 @@
+(function(c){c.jqplot.PointLabels=function(e){this.show=c.jqplot.config.enablePlugins;this.location="n";this.labelsFromSeries=false;this.seriesLabelIndex=null;this.labels=[];this._labels=[];this.stackedValue=false;this.ypadding=6;this.xpadding=6;this.escapeHTML=true;this.edgeTolerance=-5;this.formatter=c.jqplot.DefaultTickFormatter;this.formatString="";this.hideZeros=false;this._elems=[];c.extend(true,this,e)};var a=["nw","n","ne","e","se","s","sw","w"];var d={nw:0,n:1,ne:2,e:3,se:4,s:5, [...]
\ No newline at end of file
diff --git a/phpmyadmin/js/jquery/jquery-1.8.3.js b/phpmyadmin/js/jquery/jquery-1.8.3.js
new file mode 100644
index 0000000..3f4b546
--- /dev/null
+++ b/phpmyadmin/js/jquery/jquery-1.8.3.js
@@ -0,0 +1,21 @@
+/*!
+ * jQuery JavaScript Library v1.8.3
+ * http://jquery.com/
+ *
+ * Includes Sizzle.js
+ * http://sizzlejs.com/
+ *
+ * Copyright 2012 jQuery Foundation and other contributors
+ * Released under the MIT license
+ * http://jquery.org/license
+ *
+ * Date: Tue Nov 13 2012 08:20:33 GMT-0500 (Eastern Standard Time)
+ */
+(function(a2,aB){var w,af,o=a2.document,aI=a2.location,d=a2.navigator,bg=a2.jQuery,I=a2.$,am=Array.prototype.push,a4=Array.prototype.slice,aK=Array.prototype.indexOf,z=Object.prototype.toString,V=Object.prototype.hasOwnProperty,aO=String.prototype.trim,bG=function(e,bZ){return new bG.fn.init(e,bZ,w)},bx=/[\-+]?(?:\d*\.|)\d+(?:[eE][\-+]?\d+|)/.source,aa=/\S/,aV=/\s+/,C=/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,bo=/^(?:[^#<]*(<[\w\W]+>)[^>]*$|#([\w\-]*)$)/,a=/^<(\w+)\s*\/?>(?:<\/\1>|)$/,bf=/^[\ [...]
+/*!
+ * Sizzle CSS Selector Engine
+ * Copyright 2012 jQuery Foundation and other contributors
+ * Released under the MIT license
+ * http://sizzlejs.com/
+ */
+(function(cS,ch){var cX,ca,cL,b0,cm,cA,cd,cg,cc,cJ,b9=true,cu="undefined",cZ=("sizcache"+Math.random()).replace(".",""),b4=String,b8=cS.document,cb=b8.documentElement,cr=0,cf=0,cE=[].pop,cW=[].push,cl=[].slice,co=[].indexOf||function(c8){var c7=0,e=this.length;for(;c7<e;c7++){if(this[c7]===c8){return c7}}return -1},c1=function(e,c7){e[cZ]=c7==null||c7;return e},c5=function(){var e={},c7=[];return c1(function(c8,c9){if(c7.push(c8)>cL.cacheLength){delete e[c7.shift()]}return(e[c8+" "]=c9)} [...]
\ No newline at end of file
diff --git a/phpmyadmin/js/jquery/jquery-ui-1.9.2.custom.js b/phpmyadmin/js/jquery/jquery-ui-1.9.2.custom.js
new file mode 100644
index 0000000..a2f24a0
--- /dev/null
+++ b/phpmyadmin/js/jquery/jquery-ui-1.9.2.custom.js
@@ -0,0 +1,16 @@
+/*! jQuery UI - v1.9.2 - 2012-12-19
+* http://jqueryui.com
+* Includes: jquery.ui.core.js, jquery.ui.widget.js, jquery.ui.mouse.js, jquery.ui.position.js, jquery.ui.draggable.js, jquery.ui.droppable.js, jquery.ui.resizable.js, jquery.ui.selectable.js, jquery.ui.sortable.js, jquery.ui.accordion.js, jquery.ui.autocomplete.js, jquery.ui.button.js, jquery.ui.datepicker.js, jquery.ui.dialog.js, jquery.ui.menu.js, jquery.ui.progressbar.js, jquery.ui.slider.js, jquery.ui.spinner.js, jquery.ui.tabs.js, jquery.ui.tooltip.js, jquery.ui.effect.js, jquery.ui [...]
+* Copyright (c) 2012 jQuery Foundation and other contributors Licensed MIT */
+(function(b,f){var a=0,e=/^ui-id-\d+$/;b.ui=b.ui||{};if(b.ui.version){return}b.extend(b.ui,{version:"1.9.2",keyCode:{BACKSPACE:8,COMMA:188,DELETE:46,DOWN:40,END:35,ENTER:13,ESCAPE:27,HOME:36,LEFT:37,NUMPAD_ADD:107,NUMPAD_DECIMAL:110,NUMPAD_DIVIDE:111,NUMPAD_ENTER:108,NUMPAD_MULTIPLY:106,NUMPAD_SUBTRACT:109,PAGE_DOWN:34,PAGE_UP:33,PERIOD:190,RIGHT:39,SPACE:32,TAB:9,UP:38}});b.fn.extend({_focus:b.fn.focus,focus:function(g,h){return typeof g==="number"?this.each(function(){var i=this;setTim [...]
+/*!
+ * jQuery Color Animations v2.0.0
+ * http://jquery.com/
+ *
+ * Copyright 2012 jQuery Foundation and other contributors
+ * Released under the MIT license.
+ * http://jquery.org/license
+ *
+ * Date: Mon Aug 13 13:41:02 2012 -0500
+ */
+(function(s,h){var o="backgroundColor borderBottomColor borderLeftColor borderRightColor borderTopColor color columnRuleColor outlineColor textDecorationColor textEmphasisColor".split(" "),l=/^([\-+])=\s*(\d+\.?\d*)/,k=[{re:/rgba?\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*(?:,\s*(\d+(?:\.\d+)?)\s*)?\)/,parse:function(t){return[t[1],t[2],t[3],t[4]]}},{re:/rgba?\(\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d+(?:\.\d+)?)\s*)?\)/,parse:function(t){re [...]
\ No newline at end of file
diff --git a/phpmyadmin/js/jquery/jquery-ui-timepicker-addon.js b/phpmyadmin/js/jquery/jquery-ui-timepicker-addon.js
new file mode 100644
index 0000000..55f9dc8
--- /dev/null
+++ b/phpmyadmin/js/jquery/jquery-ui-timepicker-addon.js
@@ -0,0 +1 @@
+(function($){$.ui.timepicker=$.ui.timepicker||{};if($.ui.timepicker.version){return}$.extend($.ui,{timepicker:{version:"1.1.1"}});function Timepicker(){this.regional=[];this.regional[""]={currentText:"Now",closeText:"Done",amNames:["AM","A"],pmNames:["PM","P"],timeFormat:"HH:mm",timeSuffix:"",timeOnlyTitle:"Choose Time",timeText:"Time",hourText:"Hour",minuteText:"Minute",secondText:"Second",millisecText:"Millisecond",timezoneText:"Time Zone",isRTL:false};this._defaults={showButtonPanel:t [...]
\ No newline at end of file
diff --git a/phpmyadmin/js/jquery/jquery.ba-hashchange-1.3.js b/phpmyadmin/js/jquery/jquery.ba-hashchange-1.3.js
new file mode 100644
index 0000000..1467f47
--- /dev/null
+++ b/phpmyadmin/js/jquery/jquery.ba-hashchange-1.3.js
@@ -0,0 +1,9 @@
+/*!
+ * jQuery hashchange event - v1.3 - 7/21/2010
+ * http://benalman.com/projects/jquery-hashchange-plugin/
+ * 
+ * Copyright (c) 2010 "Cowboy" Ben Alman
+ * Dual licensed under the MIT and GPL licenses.
+ * http://benalman.com/about/license/
+ */
+(function($,e,b){var c="hashchange",h=document,f,g=$.event.special,i=h.documentMode,d="on"+c in e&&(i===b||i>7);function a(j){j=j||location.href;return"#"+j.replace(/^[^#]*#?(.*)$/,"$1")}$.fn[c]=function(j){return j?this.bind(c,j):this.trigger(c)};$.fn[c].delay=50;g[c]=$.extend(g[c],{setup:function(){if(d){return false}$(f.start)},teardown:function(){if(d){return false}$(f.stop)}});f=(function(){var j={},p,m=a(),k=function(q){return q},l=k,o=k;j.start=function(){p||n()};j.stop=function() [...]
\ No newline at end of file
diff --git a/phpmyadmin/js/jquery/jquery.cookie.js b/phpmyadmin/js/jquery/jquery.cookie.js
new file mode 100644
index 0000000..2a046b5
--- /dev/null
+++ b/phpmyadmin/js/jquery/jquery.cookie.js
@@ -0,0 +1 @@
+jQuery.cookie=function(d,e,b){if(arguments.length>1&&String(e)!=="[object Object]"){b=jQuery.extend({},b);if(e===null||e===undefined){b.expires=-1}if(typeof b.expires==="number"){var g=b.expires,c=b.expires=new Date();c.setDate(c.getDate()+g)}e=String(e);return(document.cookie=[encodeURIComponent(d),"=",b.raw?e:encodeURIComponent(e),b.expires?"; expires="+b.expires.toUTCString():"",b.path?"; path="+b.path:"",b.domain?"; domain="+b.domain:"",b.secure?"; secure":""].join(""))}b=e||{};var a [...]
\ No newline at end of file
diff --git a/phpmyadmin/js/jquery/jquery.debounce-1.0.5.js b/phpmyadmin/js/jquery/jquery.debounce-1.0.5.js
new file mode 100644
index 0000000..f8b05cf
--- /dev/null
+++ b/phpmyadmin/js/jquery/jquery.debounce-1.0.5.js
@@ -0,0 +1 @@
+(function(a){a.extend({debounce:function(c,d,e,b){if(arguments.length==3&&typeof e!="boolean"){b=e;e=false}var f;return function(){var g=arguments;b=b||this;e&&!f&&c.apply(b,g);clearTimeout(f);f=setTimeout(function(){!e&&c.apply(b,g);f=null},d)}},throttle:function(e,f,b){var g,d,c;return function(){d=arguments;c=true;b=b||this;if(!g){(function(){if(c){e.apply(b,d);c=false;g=setTimeout(arguments.callee,f)}else{g=null}})()}}}})})(jQuery);
\ No newline at end of file
diff --git a/phpmyadmin/js/jquery/jquery.event.drag-2.2.js b/phpmyadmin/js/jquery/jquery.event.drag-2.2.js
new file mode 100644
index 0000000..b22542f
--- /dev/null
+++ b/phpmyadmin/js/jquery/jquery.event.drag-2.2.js
@@ -0,0 +1,6 @@
+/*! 
+ * jquery.event.drag - v 2.2
+ * Copyright (c) 2010 Three Dub Media - http://threedubmedia.com
+ * Open Source MIT License - http://threedubmedia.com/code/license
+ */
+(function(e){e.fn.drag=function(k,g,j){var i=typeof k=="string"?k:"",h=e.isFunction(k)?k:e.isFunction(g)?g:null;if(i.indexOf("drag")!==0){i="drag"+i}j=(k==h?g:j)||{};return h?this.bind(i,j,h):this.trigger(i)};var b=e.event,a=b.special,d=a.drag={defaults:{which:1,distance:0,not:":input",handle:null,relative:false,drop:true,click:false},datakey:"dragdata",noBubble:true,add:function(i){var h=e.data(this,d.datakey),g=i.data||{};h.related+=1;e.each(d.defaults,function(j,k){if(g[j]!==undefined [...]
\ No newline at end of file
diff --git a/phpmyadmin/js/jquery/jquery.fullscreen.js b/phpmyadmin/js/jquery/jquery.fullscreen.js
new file mode 100644
index 0000000..73b7bd4
--- /dev/null
+++ b/phpmyadmin/js/jquery/jquery.fullscreen.js
@@ -0,0 +1 @@
+(function(h){function b(){return document[!f?"fullScreen":"webkit"===f?"webkitIsFullScreen":f+"FullScreen"]}function d(){return document[f?f+"CancelFullScreen":"cancelFullScreen"]()}var a=typeof document.cancelFullScreen!=="undefined",g=["webkit","moz","o","ms","khtml"],f="",e=function(){},c;if(!a){for(c=0;f=g[c];c++){if(typeof document[f+"CancelFullScreen"]!=="undefined"){a=true;break}}}if(a){h.fn.requestFullScreen=function(){return this.each(function(){return this[f?f+"RequestFullScree [...]
\ No newline at end of file
diff --git a/phpmyadmin/js/jquery/jquery.json-2.4.js b/phpmyadmin/js/jquery/jquery.json-2.4.js
new file mode 100644
index 0000000..7c357ea
--- /dev/null
+++ b/phpmyadmin/js/jquery/jquery.json-2.4.js
@@ -0,0 +1 @@
+(function($){var escape=/["\\\x00-\x1f\x7f-\x9f]/g,meta={"\b":"\\b","\t":"\\t","\n":"\\n","\f":"\\f","\r":"\\r",'"':'\\"',"\\":"\\\\"},hasOwn=Object.prototype.hasOwnProperty;$.toJSON=typeof JSON==="object"&&JSON.stringify?JSON.stringify:function(o){if(o===null){return"null"}var pairs,k,name,val,type=$.type(o);if(type==="undefined"){return undefined}if(type==="number"||type==="boolean"){return String(o)}if(type==="string"){return $.quoteString(o)}if(typeof o.toJSON==="function"){return $. [...]
\ No newline at end of file
diff --git a/phpmyadmin/js/jquery/jquery.menuResizer-1.0.js b/phpmyadmin/js/jquery/jquery.menuResizer-1.0.js
new file mode 100644
index 0000000..9ddee5a
--- /dev/null
+++ b/phpmyadmin/js/jquery/jquery.menuResizer-1.0.js
@@ -0,0 +1 @@
+(function(c){function b(h,i){var f=this;f.$container=h;f.widthCalculator=i;var g=c("<a />",{href:"#","class":"tab nowrap"}).text(PMA_messages.strMore).bind("click",false);var e=h.find("li img");if(e.length){c(PMA_getImage("b_more.png").toString()).prependTo(g)}var d=c("<li />",{"class":"submenu"}).append(g).append(c("<ul />")).mouseenter(function(){if(c(this).find("ul .tabactive").length==0){c(this).addClass("submenuhover").find("> a").addClass("tabactive")}}).mouseleave(function(){if(c( [...]
\ No newline at end of file
diff --git a/phpmyadmin/js/jquery/jquery.mousewheel.js b/phpmyadmin/js/jquery/jquery.mousewheel.js
new file mode 100644
index 0000000..9d815f0
--- /dev/null
+++ b/phpmyadmin/js/jquery/jquery.mousewheel.js
@@ -0,0 +1,12 @@
+/*! Copyright (c) 2011 Brandon Aaron (http://brandonaaron.net)
+ * Licensed under the MIT License (LICENSE.txt).
+ *
+ * Thanks to: http://adomas.org/javascript-mouse-wheel/ for some pointers.
+ * Thanks to: Mathias Bank(http://www.mathias-bank.de) for a scope bug fix.
+ * Thanks to: Seamus Leahy for adding deltaX and deltaY
+ *
+ * Version: 3.0.6
+ * 
+ * Requires: 1.2.2+
+ */
+(function(d){var b=["DOMMouseScroll","mousewheel"];if(d.event.fixHooks){for(var a=b.length;a;){d.event.fixHooks[b[--a]]=d.event.mouseHooks}}d.event.special.mousewheel={setup:function(){if(this.addEventListener){for(var e=b.length;e;){this.addEventListener(b[--e],c,false)}}else{this.onmousewheel=c}},teardown:function(){if(this.removeEventListener){for(var e=b.length;e;){this.removeEventListener(b[--e],c,false)}}else{this.onmousewheel=null}}};d.fn.extend({mousewheel:function(e){return e?th [...]
\ No newline at end of file
diff --git a/phpmyadmin/js/jquery/jquery.sortableTable.js b/phpmyadmin/js/jquery/jquery.sortableTable.js
new file mode 100644
index 0000000..27cf294
--- /dev/null
+++ b/phpmyadmin/js/jquery/jquery.sortableTable.js
@@ -0,0 +1 @@
+(function(a){jQuery.fn.sortableTable=function(d){var b={init:function(f){var e=new c(this,f);e.init();a(this).data("sortableTable",e)},refresh:function(){a(this).data("sortableTable").refresh()},destroy:function(){a(this).data("sortableTable").destroy()}};if(b[d]){return b[d].apply(this,Array.prototype.slice.call(arguments,1))}else{if(typeof d==="object"||!d){return b.init.apply(this,arguments)}else{a.error("Method "+d+" does not exist on jQuery.sortableTable")}}function c(t,u){var p=fal [...]
\ No newline at end of file
diff --git a/phpmyadmin/js/jquery/jquery.sprintf.js b/phpmyadmin/js/jquery/jquery.sprintf.js
new file mode 100644
index 0000000..b0e3a63
--- /dev/null
+++ b/phpmyadmin/js/jquery/jquery.sprintf.js
@@ -0,0 +1 @@
+(function(d){var a={b:function(e){return parseInt(e,10).toString(2)},c:function(e){return String.fromCharCode(parseInt(e,10))},d:function(e){return parseInt(e,10)},u:function(e){return Math.abs(e)},f:function(f,e){e=parseInt(e,10);f=parseFloat(f);if(isNaN(e&&f)){return NaN}return e&&f.toFixed(e)||f},o:function(e){return parseInt(e,10).toString(8)},s:function(e){return e},x:function(e){return(""+parseInt(e,10).toString(16)).toLowerCase()},X:function(e){return(""+parseInt(e,10).toString(16 [...]
\ No newline at end of file
diff --git a/phpmyadmin/js/jquery/jquery.svg.js b/phpmyadmin/js/jquery/jquery.svg.js
new file mode 100644
index 0000000..dca0984
--- /dev/null
+++ b/phpmyadmin/js/jquery/jquery.svg.js
@@ -0,0 +1 @@
+(function(e){function d(){this._settings=[];this._extensions=[];this.regional=[];this.regional[""]={errorLoadingText:"Error loading",notSupportedText:"This browser does not support SVG"};this.local=this.regional[""];this._uuid=new Date().getTime();this._renesis=c("RenesisX.RenesisCtrl")}function c(i){try{return !!(window.ActiveXObject&&new ActiveXObject(i))}catch(j){return false}}var g="svgwrapper";e.extend(d.prototype,{markerClassName:"hasSVG",svgNS:"http://www.w3.org/2000/svg",xlinkNS: [...]
\ No newline at end of file
diff --git a/phpmyadmin/js/jquery/jquery.tablesorter.js b/phpmyadmin/js/jquery/jquery.tablesorter.js
new file mode 100644
index 0000000..771f975
--- /dev/null
+++ b/phpmyadmin/js/jquery/jquery.tablesorter.js
@@ -0,0 +1 @@
+(function($){$.extend({tablesorter:new function(){var parsers=[],widgets=[];this.defaults={cssHeader:"header",cssAsc:"headerSortUp",cssDesc:"headerSortDown",cssChildRow:"expand-child",sortInitialOrder:"asc",sortMultiSortKey:"shiftKey",sortForce:null,sortAppend:null,sortLocaleCompare:true,textExtraction:"simple",parsers:{},widgets:[],widgetZebra:{css:["even","odd"]},headers:{},widthFixed:false,cancelSelection:true,sortList:[],headerList:[],dateFormat:"us",decimal:"/.|,/g",onRenderHeader:n [...]
\ No newline at end of file
diff --git a/phpmyadmin/js/keyhandler.js b/phpmyadmin/js/keyhandler.js
new file mode 100644
index 0000000..9b6120a
--- /dev/null
+++ b/phpmyadmin/js/keyhandler.js
@@ -0,0 +1 @@
+AJAX.registerTeardown("keyhandler.js",function(){$("#table_columns").die("keydown keyup");$("table.insertRowTable").die("keydown keyup")});AJAX.registerOnload("keyhandler.js",function(){$("#table_columns").live("keydown keyup",function(a){onKeyDownArrowsHandler(a.originalEvent)});$("table.insertRowTable").live("keydown keyup",function(a){onKeyDownArrowsHandler(a.originalEvent)})});function onKeyDownArrowsHandler(d){d=d||window.event;var f=(d.srcElement||d.target);if(!f){return}if(f.tagNa [...]
\ No newline at end of file
diff --git a/phpmyadmin/js/makegrid.js b/phpmyadmin/js/makegrid.js
new file mode 100644
index 0000000..4aab136
--- /dev/null
+++ b/phpmyadmin/js/makegrid.js
@@ -0,0 +1 @@
+function PMA_makegrid(b,f,d,e,a){var c={minColWidth:15,actionSpan:5,tableCreateTime:null,colOrder:[],colVisib:[],showAllColText:"",visibleHeadersCount:0,reorderHint:"",sortHint:"",markHint:"",copyHint:"",showReorderHint:false,showSortHint:false,showMarkHint:false,isCellEditActive:false,isEditCellTextEditable:false,currentEditCell:null,cellEditHint:"",gotoLinkText:"",wasEditedCellNull:false,maxTruncatedLen:0,saveCellsAtOnce:false,isCellEdited:false,saveCellWarning:"",lastXHR:null,isSaving [...]
\ No newline at end of file
diff --git a/phpmyadmin/js/messages.php b/phpmyadmin/js/messages.php
new file mode 100644
index 0000000..4a0df52
--- /dev/null
+++ b/phpmyadmin/js/messages.php
@@ -0,0 +1,530 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * Exporting of translated messages from PHP to Javascript
+ *
+ * @package PhpMyAdmin
+ */
+
+chdir('..');
+
+// Send correct type:
+header('Content-Type: text/javascript; charset=UTF-8');
+
+// Cache output in client - the nocache query parameter makes sure that this
+// file is reloaded when config changes
+header('Expires: ' . gmdate('D, d M Y H:i:s', time() + 3600) . ' GMT');
+
+// Avoid loading the full common.inc.php because this would add many
+// non-js-compatible stuff like DOCTYPE
+define('PMA_MINIMUM_COMMON', true);
+require_once './libraries/common.inc.php';
+// Close session early as we won't write anything there
+session_write_close();
+// But this one is needed for PMA_escapeJsString()
+require_once './libraries/js_escape.lib.php';
+
+$js_messages['strNoDropDatabases'] = $cfg['AllowUserDropDatabase'] ? '' : __('"DROP DATABASE" statements are disabled.');
+
+/* For confirmations */
+$js_messages['strDoYouReally'] = __('Do you really want to execute "%s"?');
+$js_messages['strDropDatabaseStrongWarning'] = __('You are about to DESTROY a complete database!');
+$js_messages['strDropTableStrongWarning'] = __('You are about to DESTROY a complete table!');
+$js_messages['strTruncateTableStrongWarning'] = __('You are about to TRUNCATE a complete table!');
+$js_messages['strDeleteTrackingData'] = __('Delete tracking data for this table');
+$js_messages['strDeletingTrackingData'] = __('Deleting tracking data');
+$js_messages['strDroppingPrimaryKeyIndex'] = __('Dropping Primary Key/Index');
+$js_messages['strOperationTakesLongTime'] = __('This operation could take a long time. Proceed anyway?');
+
+/* For indexes */
+$js_messages['strFormEmpty'] = __('Missing value in the form!');
+$js_messages['strNotNumber'] = __('This is not a number!');
+$js_messages['strAddIndex'] = __('Add Index');
+$js_messages['strEditIndex'] = __('Edit Index');
+$js_messages['strAddToIndex'] = __('Add %s column(s) to index');
+
+/* Charts */
+/* l10n: Default label for the y-Axis of Charts */
+$js_messages['strYValues'] = __('Y Values');
+
+/* For server_privileges.js */
+$js_messages['strHostEmpty'] = __('The host name is empty!');
+$js_messages['strUserEmpty'] = __('The user name is empty!');
+$js_messages['strPasswordEmpty'] = __('The password is empty!');
+$js_messages['strPasswordNotSame'] = __('The passwords aren\'t the same!');
+$js_messages['strAddUser'] = __('Add user');
+$js_messages['strReloadingPrivileges'] = __('Reloading Privileges');
+$js_messages['strRemovingSelectedUsers'] = __('Removing Selected Users');
+$js_messages['strClose'] = __('Close');
+
+/* for server_status.js */
+$js_messages['strEdit'] = __('Edit');
+$js_messages['strLiveTrafficChart'] = __('Live traffic chart');
+$js_messages['strLiveConnChart'] = __('Live conn./process chart');
+$js_messages['strLiveQueryChart'] = __('Live query chart');
+
+$js_messages['strStaticData'] = __('Static data');
+/* l10n: Total number of queries */
+$js_messages['strTotal'] = __('Total');
+/* l10n: Other, small valued, queries */
+$js_messages['strOther'] = __('Other');
+/* l10n: Thousands separator */
+$js_messages['strThousandsSeparator'] = __(',');
+/* l10n: Decimal separator */
+$js_messages['strDecimalSeparator'] = __('.');
+
+$js_messages['strChartConnectionsTitle'] = __('Connections / Processes');
+
+/* server status monitor */
+$js_messages['strIncompatibleMonitorConfig'] = __('Local monitor configuration incompatible');
+$js_messages['strIncompatibleMonitorConfigDescription'] = __('The chart arrangement configuration in your browsers local storage is not compatible anymore to the newer version of the monitor dialog. It is very likely that your current configuration will not work anymore. Please reset your configuration to default in the <i>Settings</i> menu.');
+
+$js_messages['strQueryCacheEfficiency'] = __('Query cache efficiency');
+$js_messages['strQueryCacheUsage'] = __('Query cache usage');
+$js_messages['strQueryCacheUsed'] = __('Query cache used');
+
+$js_messages['strSystemCPUUsage'] = __('System CPU Usage');
+$js_messages['strSystemMemory'] = __('System memory');
+$js_messages['strSystemSwap'] = __('System swap');
+
+$js_messages['strAverageLoad'] = __('Average load');
+$js_messages['strTotalMemory'] = __('Total memory');
+$js_messages['strCachedMemory'] = __('Cached memory');
+$js_messages['strBufferedMemory'] = __('Buffered memory');
+$js_messages['strFreeMemory'] = __('Free memory');
+$js_messages['strUsedMemory'] = __('Used memory');
+
+$js_messages['strTotalSwap'] = __('Total Swap');
+$js_messages['strCachedSwap'] = __('Cached Swap');
+$js_messages['strUsedSwap'] = __('Used Swap');
+$js_messages['strFreeSwap'] = __('Free Swap');
+
+$js_messages['strBytesSent'] = __('Bytes sent');
+$js_messages['strBytesReceived'] = __('Bytes received');
+$js_messages['strConnections'] = __('Connections');
+$js_messages['strProcesses'] = __('Processes');
+
+/* summary row */
+$js_messages['strB'] = __('B');
+$js_messages['strKiB'] = __('KiB');
+$js_messages['strMiB'] = __('MiB');
+$js_messages['strGiB'] = __('GiB');
+$js_messages['strTiB'] = __('TiB');
+$js_messages['strPiB'] = __('PiB');
+$js_messages['strEiB'] = __('EiB');
+$js_messages['strTables'] = __('%d table(s)');
+
+/* l10n: Questions is the name of a MySQL Status variable */
+$js_messages['strQuestions'] = __('Questions');
+$js_messages['strTraffic'] = __('Traffic');
+$js_messages['strSettings'] = __('Settings');
+$js_messages['strRemoveChart'] = __('Remove chart');
+$js_messages['strEditChart'] = __('Edit title and labels');
+$js_messages['strAddChart'] = __('Add chart to grid');
+$js_messages['strClose'] = __('Close');
+$js_messages['strAddOneSeriesWarning'] = __('Please add at least one variable to the series');
+$js_messages['strNone'] = __('None');
+$js_messages['strResumeMonitor'] = __('Resume monitor');
+$js_messages['strPauseMonitor'] = __('Pause monitor');
+/* Monitor: Instructions Dialog */
+$js_messages['strBothLogOn'] = __('general_log and slow_query_log are enabled.');
+$js_messages['strGenLogOn'] = __('general_log is enabled.');
+$js_messages['strSlowLogOn'] = __('slow_query_log is enabled.');
+$js_messages['strBothLogOff'] = __('slow_query_log and general_log are disabled.');
+$js_messages['strLogOutNotTable'] = __('log_output is not set to TABLE.');
+$js_messages['strLogOutIsTable'] = __('log_output is set to TABLE.');
+$js_messages['strSmallerLongQueryTimeAdvice'] = __('slow_query_log is enabled, but the server logs only queries that take longer than %d seconds. It is advisable to set this long_query_time 0-2 seconds, depending on your system.');
+$js_messages['strLongQueryTimeSet'] = __('long_query_time is set to %d second(s).');
+$js_messages['strSettingsAppliedGlobal'] = __('Following settings will be applied globally and reset to default on server restart:');
+/* l10n: %s is FILE or TABLE */
+$js_messages['strSetLogOutput'] = __('Set log_output to %s');
+/* l10n: Enable in this context means setting a status variable to ON */
+$js_messages['strEnableVar'] = __('Enable %s');
+/* l10n: Disable in this context means setting a status variable to OFF */
+$js_messages['strDisableVar'] = __('Disable %s');
+/* l10n: %d seconds */
+$js_messages['setSetLongQueryTime'] = __('Set long_query_time to %ds');
+$js_messages['strNoSuperUser'] = __('You can\'t change these variables. Please log in as root or contact your database administrator.');
+$js_messages['strChangeSettings'] = __('Change settings');
+$js_messages['strCurrentSettings'] = __('Current settings');
+
+$js_messages['strChartTitle'] = __('Chart Title');
+/* l10n: As in differential values */
+$js_messages['strDifferential'] = __('Differential');
+$js_messages['strDividedBy'] = __('Divided by %s');
+$js_messages['strUnit'] = __('Unit');
+
+$js_messages['strFromSlowLog'] = __('From slow log');
+$js_messages['strFromGeneralLog'] = __('From general log');
+$js_messages['strAnalysingLogsTitle'] = __('Analysing logs');
+$js_messages['strAnalysingLogs'] = __('Analysing & loading logs. This may take a while.');
+$js_messages['strCancelRequest'] = __('Cancel request');
+$js_messages['strCountColumnExplanation'] = __('This column shows the amount of identical queries that are grouped together. However only the SQL query itself has been used as a grouping criteria, so the other attributes of queries, such as start time, may differ.');
+$js_messages['strMoreCountColumnExplanation'] = __('Since grouping of INSERTs queries has been selected, INSERT queries into the same table are also being grouped together, disregarding of the inserted data.');
+$js_messages['strLogDataLoaded'] = __('Log data loaded. Queries executed in this time span:');
+
+$js_messages['strJumpToTable'] = __('Jump to Log table');
+$js_messages['strNoDataFoundTitle'] = __('No data found');
+$js_messages['strNoDataFound'] = __('Log analysed, but no data found in this time span.');
+
+$js_messages['strAnalyzing'] = __('Analyzing…');
+$js_messages['strExplainOutput'] = __('Explain output');
+$js_messages['strStatus'] = __('Status');
+$js_messages['strTime'] = __('Time');
+$js_messages['strTotalTime'] = __('Total time:');
+$js_messages['strProfilingResults'] = __('Profiling results');
+$js_messages['strTable'] = _pgettext('Display format', 'Table');
+$js_messages['strChart'] = __('Chart');
+$js_messages['strChartEdit'] = __('Edit chart');
+$js_messages['strSeries'] = __('Series');
+
+/* l10n: A collection of available filters */
+$js_messages['strFiltersForLogTable'] = __('Log table filter options');
+/* l10n: Filter as in "Start Filtering" */
+$js_messages['strFilter'] = __('Filter');
+$js_messages['strFilterByWordRegexp'] = __('Filter queries by word/regexp:');
+$js_messages['strIgnoreWhereAndGroup'] = __('Group queries, ignoring variable data in WHERE clauses');
+$js_messages['strSumRows'] = __('Sum of grouped rows:');
+$js_messages['strTotal'] = __('Total:');
+
+$js_messages['strLoadingLogs'] = __('Loading logs');
+$js_messages['strRefreshFailed'] = __('Monitor refresh failed');
+$js_messages['strInvalidResponseExplanation'] = __('While requesting new chart data the server returned an invalid response. This is most likely because your session expired. Reloading the page and reentering your credentials should help.');
+$js_messages['strReloadPage'] = __('Reload page');
+
+$js_messages['strAffectedRows'] = __('Affected rows:');
+
+$js_messages['strFailedParsingConfig'] = __('Failed parsing config file. It doesn\'t seem to be valid JSON code.');
+$js_messages['strFailedBuildingGrid'] = __('Failed building chart grid with imported config. Resetting to default config…');
+$js_messages['strImport'] = __('Import');
+$js_messages['strImportDialogTitle'] = __('Import monitor configuration');
+$js_messages['strImportDialogMessage'] = __('Please select the file you want to import');
+
+$js_messages['strAnalyzeQuery'] = __('Analyse Query');
+
+/* Server status advisor */
+
+$js_messages['strAdvisorSystem'] = __('Advisor system');
+$js_messages['strPerformanceIssues'] = __('Possible performance issues');
+$js_messages['strIssuse'] = __('Issue');
+$js_messages['strRecommendation'] = __('Recommendation');
+$js_messages['strRuleDetails'] = __('Rule details');
+$js_messages['strJustification'] = __('Justification');
+$js_messages['strFormula'] = __('Used variable / formula');
+$js_messages['strTest'] = __('Test');
+
+
+/* For inline query editing */
+$js_messages['strGo'] = __('Go');
+$js_messages['strCancel'] = __('Cancel');
+
+/* For Ajax Notifications */
+$js_messages['strLoading'] = __('Loading');
+$js_messages['strProcessingRequest'] = __('Processing Request');
+$js_messages['strErrorProcessingRequest'] = __('Error in Processing Request');
+$js_messages['strErrorCode'] = __('Error code: %s');
+$js_messages['strErrorText'] = __('Error text: %s');
+$js_messages['strNoDatabasesSelected'] = __('No databases selected.');
+$js_messages['strDroppingColumn'] = __('Dropping Column');
+$js_messages['strAddingPrimaryKey'] = __('Adding Primary Key');
+$js_messages['strOK'] = __('OK');
+$js_messages['strDismiss'] = __('Click to dismiss this notification');
+
+/* For db_operations.js */
+$js_messages['strRenamingDatabases'] = __('Renaming Databases');
+$js_messages['strReloadDatabase'] = __('Reload Database');
+$js_messages['strCopyingDatabase'] = __('Copying Database');
+$js_messages['strChangingCharset'] = __('Changing Charset');
+$js_messages['strTableMustHaveAtleastOneColumn'] = __('Table must have at least one column');
+$js_messages['strYes'] = __('Yes');
+$js_messages['strNo'] = __('No');
+
+/* For db_stucture.js */
+$js_messages['strInsertTable'] = __('Insert Table');
+$js_messages['strHideIndexes'] = __('Hide indexes');
+$js_messages['strShowIndexes'] = __('Show indexes');
+$js_messages['strForeignKeyCheck'] = __('Foreign key check:');
+$js_messages['strForeignKeyCheckEnabled'] = __('(Enabled)');
+$js_messages['strForeignKeyCheckDisabled'] = __('(Disabled)');
+
+/* For db_search.js */
+$js_messages['strSearching'] = __('Searching');
+$js_messages['strHideSearchResults'] = __('Hide search results');
+$js_messages['strShowSearchResults'] = __('Show search results');
+$js_messages['strBrowsing'] = __('Browsing');
+$js_messages['strDeleting'] = __('Deleting');
+
+/* For db_routines.js */
+$js_messages['MissingReturn'] = __('The definition of a stored function must contain a RETURN statement!');
+
+/* For ENUM/SET editor*/
+$js_messages['enum_editor'] = __('ENUM/SET editor');
+$js_messages['enum_columnVals'] =__('Values for column %s');
+$js_messages['enum_newColumnVals'] = __('Values for a new column');
+$js_messages['enum_hint'] =__('Enter each value in a separate field');
+$js_messages['enum_addValue'] =__('Add %d value(s)');
+
+/* For import.js */
+$js_messages['strImportCSV'] = __('Note: If the file contains multiple tables, they will be combined into one');
+
+/* For sql.js */
+$js_messages['strHideQueryBox'] = __('Hide query box');
+$js_messages['strShowQueryBox'] = __('Show query box');
+$js_messages['strEdit'] = __('Edit');
+$js_messages['strNoRowSelected'] = __('No rows selected');
+$js_messages['strChangeTbl'] = __('Change');
+$js_messages['strQueryExecutionTime'] = __('Query execution time');
+$js_messages['strNotValidRowNumber'] = __('%d is not valid row number.');
+
+/* For server_variables.js */
+$js_messages['strSave'] = __('Save');
+
+/* For tbl_select.js */
+$js_messages['strHideSearchCriteria'] = __('Hide search criteria');
+$js_messages['strShowSearchCriteria'] = __('Show search criteria');
+
+/* For tbl_zoom_plot_jqplot.js */
+$js_messages['strZoomSearch'] = __('Zoom Search');
+$js_messages['strDisplayHelp'] = '<ul><li>'
+    . __('Each point represents a data row.')
+    . '</li><li>'
+    . __('Hovering over a point will show its label.')
+    . '</li><li>'
+    . __('To zoom in, select a section of the plot with the mouse.')
+    . '</li><li>'
+    . __('Click reset zoom button to come back to original state.')
+    . '</li><li>'
+    . __('Click a data point to view and possibly edit the data row.')
+    . '</li><li>'
+    . __('The plot can be resized by dragging it along the bottom right corner.')
+    . '</li></ul>';
+$js_messages['strInputNull'] = '<strong>' . __('Select two columns') . '</strong>';
+$js_messages['strSameInputs'] = '<strong>' . __('Select two different columns') . '</strong>';
+$js_messages['strQueryResults'] = __('Query results');
+$js_messages['strDataPointContent'] = __('Data point content');
+
+/* For tbl_change.js */
+$js_messages['strIgnore'] = __('Ignore');
+$js_messages['strCopy'] = __('Copy');
+$js_messages['strX'] = __('X');
+$js_messages['strY'] = __('Y');
+$js_messages['strPoint'] = __('Point');
+$js_messages['strPointN'] = __('Point %d');
+$js_messages['strLineString'] = __('Linestring');
+$js_messages['strPolygon'] = __('Polygon');
+$js_messages['strGeometry'] = __('Geometry');
+$js_messages['strInnerRing'] = __('Inner Ring');
+$js_messages['strOuterRing'] = __('Outer Ring');
+$js_messages['strAddPoint'] = __('Add a point');
+$js_messages['strAddInnerRing'] = __('Add an inner ring');
+$js_messages['strAddPolygon'] = __('Add a polygon');
+
+/* For tbl_structure.js */
+$js_messages['strAddColumns'] = __('Add columns');
+
+/* Designer (js/pmd/move.js) */
+$js_messages['strSelectReferencedKey'] = __('Select referenced key');
+$js_messages['strSelectForeignKey'] = __('Select Foreign Key');
+$js_messages['strPleaseSelectPrimaryOrUniqueKey'] = __('Please select the primary key or a unique key');
+$js_messages['strChangeDisplay'] = __('Choose column to display');
+$js_messages['strLeavingDesigner'] = __('You haven\'t saved the changes in the layout. They will be lost if you don\'t save them. Do you want to continue?');
+
+/* Visual query builder (js/pmd/move.js) */
+$js_messages['strAddOption'] = __('Add an option for column ');
+$js_messages['strObjectsCreated'] = __('%d object(s) created');
+
+/* For makegrid.js (column reordering, show/hide column, grid editing) */
+$js_messages['strCellEditHint'] = __('Press escape to cancel editing');
+$js_messages['strSaveCellWarning'] = __('You have edited some data and they have not been saved. Are you sure you want to leave this page before saving the data?');
+$js_messages['strColOrderHint'] = __('Drag to reorder');
+$js_messages['strSortHint'] = __('Click to sort');
+$js_messages['strColMarkHint'] = __('Click to mark/unmark');
+$js_messages['strColNameCopyHint'] = __('Double-click to copy column name');
+$js_messages['strColVisibHint'] = __('Click the drop-down arrow<br />to toggle column\'s visibility');
+$js_messages['strShowAllCol'] = __('Show all');
+$js_messages['strAlertNonUnique'] = __('This table does not contain a unique column. Features related to the grid edit, checkbox, Edit, Copy and Delete links may not work after saving.');
+
+// this approach does not work when the parameter is changed via user prefs
+switch ($GLOBALS['cfg']['GridEditing']) {
+case 'double-click':
+    $js_messages['strGridEditFeatureHint'] = __('You can also edit most values<br />by double-clicking directly on them.');
+    break;
+case 'click':
+    $js_messages['strGridEditFeatureHint'] = __('You can also edit most values<br />by clicking directly on them.');
+    break;
+default:
+    break;
+}
+$js_messages['strGoToLink'] = __('Go to link');
+$js_messages['strColNameCopyTitle'] = __('Copy column name');
+$js_messages['strColNameCopyText'] = __('Right-click the column name to copy it to your clipboard.');
+$js_messages['strShowDataRowLink'] = __('Show data row(s)');
+
+/* password generation */
+$js_messages['strGeneratePassword'] = __('Generate password');
+$js_messages['strGenerate'] = __('Generate');
+$js_messages['strChangePassword'] = __('Change Password');
+
+/* navigation tabs */
+$js_messages['strMore'] = __('More');
+
+/* navigation panel */
+$js_messages['strShowPanel'] = __('Show Panel');
+$js_messages['strHidePanel'] = __('Hide Panel');
+
+/* microhistory */
+$js_messages['strInvalidPage'] = __('The requested page was not found in the history, it may have expired.');
+
+/* update */
+$js_messages['strNewerVersion'] = __('A newer version of phpMyAdmin is available and you should consider upgrading. The newest version is %s, released on %s.');
+/* l10n: Latest available phpMyAdmin version */
+$js_messages['strLatestAvailable'] = __(', latest stable version:');
+$js_messages['strUpToDate'] = __('up to date');
+
+
+echo "var PMA_messages = new Array();\n";
+foreach ($js_messages as $name => $js_message) {
+    PMA_printJsValue("PMA_messages['" . $name . "']", $js_message);
+}
+
+/* Calendar */
+echo "var themeCalendarImage = '" . $GLOBALS['pmaThemeImage'] . 'b_calendar.png' . "';\n";
+
+/* Image path */
+echo "var pmaThemeImage = '" . $GLOBALS['pmaThemeImage'] . "';\n";
+
+/* Version */
+echo "var pmaversion = '" . PMA_VERSION . "';\n";
+
+echo "if ($.datepicker) {\n";
+/* l10n: Display text for calendar close link */
+PMA_printJsValue("$.datepicker.regional['']['closeText']", __('Done'));
+/* l10n: Display text for previous month link in calendar */
+PMA_printJsValue(
+    "$.datepicker.regional['']['prevText']",
+    _pgettext('Previous month', 'Prev')
+);
+/* l10n: Display text for next month link in calendar */
+PMA_printJsValue(
+    "$.datepicker.regional['']['nextText']",
+    _pgettext('Next month', 'Next')
+);
+/* l10n: Display text for current month link in calendar */
+PMA_printJsValue("$.datepicker.regional['']['currentText']", __('Today'));
+PMA_printJsValue(
+    "$.datepicker.regional['']['monthNames']",
+    array(
+        __('January'),
+        __('February'),
+        __('March'),
+        __('April'),
+        __('May'),
+        __('June'),
+        __('July'),
+        __('August'),
+        __('September'),
+        __('October'),
+        __('November'),
+        __('December')
+    )
+);
+PMA_printJsValue(
+    "$.datepicker.regional['']['monthNamesShort']",
+    array(
+/* l10n: Short month name */
+        __('Jan'),
+/* l10n: Short month name */
+        __('Feb'),
+/* l10n: Short month name */
+        __('Mar'),
+/* l10n: Short month name */
+        __('Apr'),
+/* l10n: Short month name */
+        _pgettext('Short month name', 'May'),
+/* l10n: Short month name */
+        __('Jun'),
+/* l10n: Short month name */
+        __('Jul'),
+/* l10n: Short month name */
+        __('Aug'),
+/* l10n: Short month name */
+        __('Sep'),
+/* l10n: Short month name */
+        __('Oct'),
+/* l10n: Short month name */
+        __('Nov'),
+/* l10n: Short month name */
+        __('Dec')
+    )
+);
+PMA_printJsValue(
+    "$.datepicker.regional['']['dayNames']",
+    array(
+        __('Sunday'),
+        __('Monday'),
+        __('Tuesday'),
+        __('Wednesday'),
+        __('Thursday'),
+        __('Friday'),
+        __('Saturday')
+    )
+);
+PMA_printJsValue(
+    "$.datepicker.regional['']['dayNamesShort']",
+    array(
+/* l10n: Short week day name */
+        __('Sun'),
+/* l10n: Short week day name */
+        __('Mon'),
+/* l10n: Short week day name */
+        __('Tue'),
+/* l10n: Short week day name */
+        __('Wed'),
+/* l10n: Short week day name */
+        __('Thu'),
+/* l10n: Short week day name */
+        __('Fri'),
+/* l10n: Short week day name */
+        __('Sat')
+    )
+);
+PMA_printJsValue(
+    "$.datepicker.regional['']['dayNamesMin']",
+    array(
+/* l10n: Minimal week day name */
+        __('Su'),
+/* l10n: Minimal week day name */
+        __('Mo'),
+/* l10n: Minimal week day name */
+        __('Tu'),
+/* l10n: Minimal week day name */
+        __('We'),
+/* l10n: Minimal week day name */
+        __('Th'),
+/* l10n: Minimal week day name */
+        __('Fr'),
+/* l10n: Minimal week day name */
+        __('Sa')
+    )
+);
+/* l10n: Column header for week of the year in calendar */
+PMA_printJsValue("$.datepicker.regional['']['weekHeader']", __('Wk'));
+
+/* l10n: Month-year order for calendar, use either "calendar-month-year" or "calendar-year-month". */
+PMA_printJsValue("$.datepicker.regional['']['showMonthAfterYear']", (__('calendar-month-year') == 'calendar-year-month'));
+/* l10n: Year suffix for calendar, "none" is empty. */
+$year_suffix = _pgettext('Year suffix', 'none');
+PMA_printJsValue("$.datepicker.regional['']['yearSuffix']", ($year_suffix == 'none' ? '' : $year_suffix));
+?>
+$.extend($.datepicker._defaults, $.datepicker.regional['']);
+} /* if ($.datepicker) */
+
+<?php
+echo "if ($.timepicker) {\n";
+PMA_printJsValue("$.timepicker.regional['']['timeText']", __('Time'));
+PMA_printJsValue("$.timepicker.regional['']['hourText']", __('Hour'));
+PMA_printJsValue("$.timepicker.regional['']['minuteText']", __('Minute'));
+PMA_printJsValue("$.timepicker.regional['']['secondText']", __('Second'));
+?>
+$.extend($.timepicker._defaults, $.timepicker.regional['']);
+} /* if ($.timepicker) */
diff --git a/phpmyadmin/js/navigation.js b/phpmyadmin/js/navigation.js
new file mode 100644
index 0000000..49a2978
--- /dev/null
+++ b/phpmyadmin/js/navigation.js
@@ -0,0 +1 @@
+$(function(){if(!$("#pma_navigation").length){return}new ResizeHandler();$("#pma_navigation_tree a.expander").live("click",function(b){b.preventDefault();b.stopImmediatePropagation();var h=$(this);var i=h.closest("li").children("div.list_container");var g=h.find("img");if(h.hasClass("loaded")){if(g.is(".ic_b_plus")){g.removeClass("ic_b_plus").addClass("ic_b_minus");i.show("fast")}else{g.removeClass("ic_b_minus").addClass("ic_b_plus");i.hide("fast")}}else{var f=h.closest("li");var c=$("#p [...]
\ No newline at end of file
diff --git a/phpmyadmin/js/openlayers/OpenLayers.js b/phpmyadmin/js/openlayers/OpenLayers.js
new file mode 100644
index 0000000..f38241c
--- /dev/null
+++ b/phpmyadmin/js/openlayers/OpenLayers.js
@@ -0,0 +1 @@
+var OpenLayers={singleFile:true};(function(){var j=(typeof OpenLayers=="object"&&OpenLayers.singleFile);var a="js/openlayers/";window.OpenLayers={_scriptName:(!j)?"lib/OpenLayers.js":"OpenLayers.js",_getScriptLocation:function(){if(a!=undefined){return a}a="";var r=new RegExp("(^|(.*?\\/))("+OpenLayers._scriptName+")(\\?|$)");var n=document.getElementsByTagName("script");for(var p=0,h=n.length;p<h;p++){var q=n[p].getAttribute("src");if(q){var o=q.match(r);if(o){a=o[1];break}}}return a}}; [...]
\ No newline at end of file
diff --git a/phpmyadmin/js/openlayers/img/blank.gif b/phpmyadmin/js/openlayers/img/blank.gif
new file mode 100644
index 0000000..4bcc753
Binary files /dev/null and b/phpmyadmin/js/openlayers/img/blank.gif differ
diff --git a/phpmyadmin/js/openlayers/img/cloud-popup-relative.png b/phpmyadmin/js/openlayers/img/cloud-popup-relative.png
new file mode 100644
index 0000000..1215a36
Binary files /dev/null and b/phpmyadmin/js/openlayers/img/cloud-popup-relative.png differ
diff --git a/phpmyadmin/js/openlayers/img/drag-rectangle-off.png b/phpmyadmin/js/openlayers/img/drag-rectangle-off.png
new file mode 100644
index 0000000..fc6daf4
Binary files /dev/null and b/phpmyadmin/js/openlayers/img/drag-rectangle-off.png differ
diff --git a/phpmyadmin/js/openlayers/img/drag-rectangle-on.png b/phpmyadmin/js/openlayers/img/drag-rectangle-on.png
new file mode 100644
index 0000000..7f783ce
Binary files /dev/null and b/phpmyadmin/js/openlayers/img/drag-rectangle-on.png differ
diff --git a/phpmyadmin/js/openlayers/img/east-mini.png b/phpmyadmin/js/openlayers/img/east-mini.png
new file mode 100644
index 0000000..0707567
Binary files /dev/null and b/phpmyadmin/js/openlayers/img/east-mini.png differ
diff --git a/phpmyadmin/js/openlayers/img/layer-switcher-maximize.png b/phpmyadmin/js/openlayers/img/layer-switcher-maximize.png
new file mode 100644
index 0000000..8d7bb16
Binary files /dev/null and b/phpmyadmin/js/openlayers/img/layer-switcher-maximize.png differ
diff --git a/phpmyadmin/js/openlayers/img/layer-switcher-minimize.png b/phpmyadmin/js/openlayers/img/layer-switcher-minimize.png
new file mode 100644
index 0000000..e80bf21
Binary files /dev/null and b/phpmyadmin/js/openlayers/img/layer-switcher-minimize.png differ
diff --git a/phpmyadmin/js/openlayers/img/marker-blue.png b/phpmyadmin/js/openlayers/img/marker-blue.png
new file mode 100644
index 0000000..83a90b4
Binary files /dev/null and b/phpmyadmin/js/openlayers/img/marker-blue.png differ
diff --git a/phpmyadmin/js/openlayers/img/marker-gold.png b/phpmyadmin/js/openlayers/img/marker-gold.png
new file mode 100644
index 0000000..2ff9ec5
Binary files /dev/null and b/phpmyadmin/js/openlayers/img/marker-gold.png differ
diff --git a/phpmyadmin/js/openlayers/img/marker-green.png b/phpmyadmin/js/openlayers/img/marker-green.png
new file mode 100644
index 0000000..17168f1
Binary files /dev/null and b/phpmyadmin/js/openlayers/img/marker-green.png differ
diff --git a/phpmyadmin/js/openlayers/img/marker.png b/phpmyadmin/js/openlayers/img/marker.png
new file mode 100644
index 0000000..ccd1913
Binary files /dev/null and b/phpmyadmin/js/openlayers/img/marker.png differ
diff --git a/phpmyadmin/js/openlayers/img/measuring-stick-off.png b/phpmyadmin/js/openlayers/img/measuring-stick-off.png
new file mode 100644
index 0000000..70c2dff
Binary files /dev/null and b/phpmyadmin/js/openlayers/img/measuring-stick-off.png differ
diff --git a/phpmyadmin/js/openlayers/img/measuring-stick-on.png b/phpmyadmin/js/openlayers/img/measuring-stick-on.png
new file mode 100644
index 0000000..cdb8f34
Binary files /dev/null and b/phpmyadmin/js/openlayers/img/measuring-stick-on.png differ
diff --git a/phpmyadmin/js/openlayers/img/north-mini.png b/phpmyadmin/js/openlayers/img/north-mini.png
new file mode 100644
index 0000000..a8a0b40
Binary files /dev/null and b/phpmyadmin/js/openlayers/img/north-mini.png differ
diff --git a/phpmyadmin/js/openlayers/img/panning-hand-off.png b/phpmyadmin/js/openlayers/img/panning-hand-off.png
new file mode 100644
index 0000000..4c912ac
Binary files /dev/null and b/phpmyadmin/js/openlayers/img/panning-hand-off.png differ
diff --git a/phpmyadmin/js/openlayers/img/panning-hand-on.png b/phpmyadmin/js/openlayers/img/panning-hand-on.png
new file mode 100644
index 0000000..6094c64
Binary files /dev/null and b/phpmyadmin/js/openlayers/img/panning-hand-on.png differ
diff --git a/phpmyadmin/js/openlayers/img/slider.png b/phpmyadmin/js/openlayers/img/slider.png
new file mode 100644
index 0000000..23afd57
Binary files /dev/null and b/phpmyadmin/js/openlayers/img/slider.png differ
diff --git a/phpmyadmin/js/openlayers/img/south-mini.png b/phpmyadmin/js/openlayers/img/south-mini.png
new file mode 100644
index 0000000..6c4ac8a
Binary files /dev/null and b/phpmyadmin/js/openlayers/img/south-mini.png differ
diff --git a/phpmyadmin/js/openlayers/img/west-mini.png b/phpmyadmin/js/openlayers/img/west-mini.png
new file mode 100644
index 0000000..db5f420
Binary files /dev/null and b/phpmyadmin/js/openlayers/img/west-mini.png differ
diff --git a/phpmyadmin/js/openlayers/img/zoom-minus-mini.png b/phpmyadmin/js/openlayers/img/zoom-minus-mini.png
new file mode 100644
index 0000000..f9b63ab
Binary files /dev/null and b/phpmyadmin/js/openlayers/img/zoom-minus-mini.png differ
diff --git a/phpmyadmin/js/openlayers/img/zoom-plus-mini.png b/phpmyadmin/js/openlayers/img/zoom-plus-mini.png
new file mode 100644
index 0000000..eecf2eb
Binary files /dev/null and b/phpmyadmin/js/openlayers/img/zoom-plus-mini.png differ
diff --git a/phpmyadmin/js/openlayers/img/zoom-world-mini.png b/phpmyadmin/js/openlayers/img/zoom-world-mini.png
new file mode 100644
index 0000000..2159dde
Binary files /dev/null and b/phpmyadmin/js/openlayers/img/zoom-world-mini.png differ
diff --git a/phpmyadmin/js/openlayers/img/zoombar.png b/phpmyadmin/js/openlayers/img/zoombar.png
new file mode 100644
index 0000000..959f01a
Binary files /dev/null and b/phpmyadmin/js/openlayers/img/zoombar.png differ
diff --git a/phpmyadmin/js/openlayers/theme/default/framedCloud.css b/phpmyadmin/js/openlayers/theme/default/framedCloud.css
new file mode 100644
index 0000000..e69de29
diff --git a/phpmyadmin/js/openlayers/theme/default/google.css b/phpmyadmin/js/openlayers/theme/default/google.css
new file mode 100644
index 0000000..3c1c187
--- /dev/null
+++ b/phpmyadmin/js/openlayers/theme/default/google.css
@@ -0,0 +1,10 @@
+.olLayerGoogleCopyright {
+    right: 3px;
+    bottom: 2px;
+    left: auto;  
+}
+.olLayerGooglePoweredBy {
+    left: 2px;
+    bottom: 2px;   
+}
+
diff --git a/phpmyadmin/js/openlayers/theme/default/ie6-style.css b/phpmyadmin/js/openlayers/theme/default/ie6-style.css
new file mode 100644
index 0000000..65f6b19
--- /dev/null
+++ b/phpmyadmin/js/openlayers/theme/default/ie6-style.css
@@ -0,0 +1,7 @@
+.olControlZoomPanel div {
+    background-image: url(img/zoom-panel-NOALPHA.png);
+}
+.olControlPanPanel div {
+    background-image: url(img/pan-panel-NOALPHA.png);
+}
+
diff --git a/phpmyadmin/js/openlayers/theme/default/img/add_point_off.png b/phpmyadmin/js/openlayers/theme/default/img/add_point_off.png
new file mode 100644
index 0000000..aefd09c
Binary files /dev/null and b/phpmyadmin/js/openlayers/theme/default/img/add_point_off.png differ
diff --git a/phpmyadmin/js/openlayers/theme/default/img/add_point_on.png b/phpmyadmin/js/openlayers/theme/default/img/add_point_on.png
new file mode 100644
index 0000000..1294a2c
Binary files /dev/null and b/phpmyadmin/js/openlayers/theme/default/img/add_point_on.png differ
diff --git a/phpmyadmin/js/openlayers/theme/default/img/blank.gif b/phpmyadmin/js/openlayers/theme/default/img/blank.gif
new file mode 100644
index 0000000..4bcc753
Binary files /dev/null and b/phpmyadmin/js/openlayers/theme/default/img/blank.gif differ
diff --git a/phpmyadmin/js/openlayers/theme/default/img/close.gif b/phpmyadmin/js/openlayers/theme/default/img/close.gif
new file mode 100644
index 0000000..a8958de
Binary files /dev/null and b/phpmyadmin/js/openlayers/theme/default/img/close.gif differ
diff --git a/phpmyadmin/js/openlayers/theme/default/img/drag-rectangle-off.png b/phpmyadmin/js/openlayers/theme/default/img/drag-rectangle-off.png
new file mode 100644
index 0000000..fc6daf4
Binary files /dev/null and b/phpmyadmin/js/openlayers/theme/default/img/drag-rectangle-off.png differ
diff --git a/phpmyadmin/js/openlayers/theme/default/img/drag-rectangle-on.png b/phpmyadmin/js/openlayers/theme/default/img/drag-rectangle-on.png
new file mode 100644
index 0000000..7f783ce
Binary files /dev/null and b/phpmyadmin/js/openlayers/theme/default/img/drag-rectangle-on.png differ
diff --git a/phpmyadmin/js/openlayers/theme/default/img/draw_line_off.png b/phpmyadmin/js/openlayers/theme/default/img/draw_line_off.png
new file mode 100644
index 0000000..7f15612
Binary files /dev/null and b/phpmyadmin/js/openlayers/theme/default/img/draw_line_off.png differ
diff --git a/phpmyadmin/js/openlayers/theme/default/img/draw_line_on.png b/phpmyadmin/js/openlayers/theme/default/img/draw_line_on.png
new file mode 100644
index 0000000..ba09186
Binary files /dev/null and b/phpmyadmin/js/openlayers/theme/default/img/draw_line_on.png differ
diff --git a/phpmyadmin/js/openlayers/theme/default/img/draw_point_off.png b/phpmyadmin/js/openlayers/theme/default/img/draw_point_off.png
new file mode 100644
index 0000000..fde94bd
Binary files /dev/null and b/phpmyadmin/js/openlayers/theme/default/img/draw_point_off.png differ
diff --git a/phpmyadmin/js/openlayers/theme/default/img/draw_point_on.png b/phpmyadmin/js/openlayers/theme/default/img/draw_point_on.png
new file mode 100644
index 0000000..8804221
Binary files /dev/null and b/phpmyadmin/js/openlayers/theme/default/img/draw_point_on.png differ
diff --git a/phpmyadmin/js/openlayers/theme/default/img/draw_polygon_off.png b/phpmyadmin/js/openlayers/theme/default/img/draw_polygon_off.png
new file mode 100644
index 0000000..53ce9d7
Binary files /dev/null and b/phpmyadmin/js/openlayers/theme/default/img/draw_polygon_off.png differ
diff --git a/phpmyadmin/js/openlayers/theme/default/img/draw_polygon_on.png b/phpmyadmin/js/openlayers/theme/default/img/draw_polygon_on.png
new file mode 100644
index 0000000..2a33376
Binary files /dev/null and b/phpmyadmin/js/openlayers/theme/default/img/draw_polygon_on.png differ
diff --git a/phpmyadmin/js/openlayers/theme/default/img/editing_tool_bar.png b/phpmyadmin/js/openlayers/theme/default/img/editing_tool_bar.png
new file mode 100644
index 0000000..464340e
Binary files /dev/null and b/phpmyadmin/js/openlayers/theme/default/img/editing_tool_bar.png differ
diff --git a/phpmyadmin/js/openlayers/theme/default/img/move_feature_off.png b/phpmyadmin/js/openlayers/theme/default/img/move_feature_off.png
new file mode 100644
index 0000000..9f588db
Binary files /dev/null and b/phpmyadmin/js/openlayers/theme/default/img/move_feature_off.png differ
diff --git a/phpmyadmin/js/openlayers/theme/default/img/move_feature_on.png b/phpmyadmin/js/openlayers/theme/default/img/move_feature_on.png
new file mode 100644
index 0000000..072f066
Binary files /dev/null and b/phpmyadmin/js/openlayers/theme/default/img/move_feature_on.png differ
diff --git a/phpmyadmin/js/openlayers/theme/default/img/navigation_history.png b/phpmyadmin/js/openlayers/theme/default/img/navigation_history.png
new file mode 100644
index 0000000..053d1e0
Binary files /dev/null and b/phpmyadmin/js/openlayers/theme/default/img/navigation_history.png differ
diff --git a/phpmyadmin/js/openlayers/theme/default/img/overview_replacement.gif b/phpmyadmin/js/openlayers/theme/default/img/overview_replacement.gif
new file mode 100644
index 0000000..a82cf5f
Binary files /dev/null and b/phpmyadmin/js/openlayers/theme/default/img/overview_replacement.gif differ
diff --git a/phpmyadmin/js/openlayers/theme/default/img/pan-panel-NOALPHA.png b/phpmyadmin/js/openlayers/theme/default/img/pan-panel-NOALPHA.png
new file mode 100644
index 0000000..2740d8b
Binary files /dev/null and b/phpmyadmin/js/openlayers/theme/default/img/pan-panel-NOALPHA.png differ
diff --git a/phpmyadmin/js/openlayers/theme/default/img/pan-panel.png b/phpmyadmin/js/openlayers/theme/default/img/pan-panel.png
new file mode 100644
index 0000000..9910121
Binary files /dev/null and b/phpmyadmin/js/openlayers/theme/default/img/pan-panel.png differ
diff --git a/phpmyadmin/js/openlayers/theme/default/img/pan_off.png b/phpmyadmin/js/openlayers/theme/default/img/pan_off.png
new file mode 100644
index 0000000..30b2aed
Binary files /dev/null and b/phpmyadmin/js/openlayers/theme/default/img/pan_off.png differ
diff --git a/phpmyadmin/js/openlayers/theme/default/img/pan_on.png b/phpmyadmin/js/openlayers/theme/default/img/pan_on.png
new file mode 100644
index 0000000..d73e7dd
Binary files /dev/null and b/phpmyadmin/js/openlayers/theme/default/img/pan_on.png differ
diff --git a/phpmyadmin/js/openlayers/theme/default/img/panning-hand-off.png b/phpmyadmin/js/openlayers/theme/default/img/panning-hand-off.png
new file mode 100644
index 0000000..4c912ac
Binary files /dev/null and b/phpmyadmin/js/openlayers/theme/default/img/panning-hand-off.png differ
diff --git a/phpmyadmin/js/openlayers/theme/default/img/panning-hand-on.png b/phpmyadmin/js/openlayers/theme/default/img/panning-hand-on.png
new file mode 100644
index 0000000..6094c64
Binary files /dev/null and b/phpmyadmin/js/openlayers/theme/default/img/panning-hand-on.png differ
diff --git a/phpmyadmin/js/openlayers/theme/default/img/remove_point_off.png b/phpmyadmin/js/openlayers/theme/default/img/remove_point_off.png
new file mode 100644
index 0000000..76c8606
Binary files /dev/null and b/phpmyadmin/js/openlayers/theme/default/img/remove_point_off.png differ
diff --git a/phpmyadmin/js/openlayers/theme/default/img/remove_point_on.png b/phpmyadmin/js/openlayers/theme/default/img/remove_point_on.png
new file mode 100644
index 0000000..0ff28fc
Binary files /dev/null and b/phpmyadmin/js/openlayers/theme/default/img/remove_point_on.png differ
diff --git a/phpmyadmin/js/openlayers/theme/default/img/ruler.png b/phpmyadmin/js/openlayers/theme/default/img/ruler.png
new file mode 100644
index 0000000..aa4883b
Binary files /dev/null and b/phpmyadmin/js/openlayers/theme/default/img/ruler.png differ
diff --git a/phpmyadmin/js/openlayers/theme/default/img/save_features_off.png b/phpmyadmin/js/openlayers/theme/default/img/save_features_off.png
new file mode 100644
index 0000000..2bf2906
Binary files /dev/null and b/phpmyadmin/js/openlayers/theme/default/img/save_features_off.png differ
diff --git a/phpmyadmin/js/openlayers/theme/default/img/save_features_on.png b/phpmyadmin/js/openlayers/theme/default/img/save_features_on.png
new file mode 100644
index 0000000..93c8f08
Binary files /dev/null and b/phpmyadmin/js/openlayers/theme/default/img/save_features_on.png differ
diff --git a/phpmyadmin/js/openlayers/theme/default/img/view_next_off.png b/phpmyadmin/js/openlayers/theme/default/img/view_next_off.png
new file mode 100644
index 0000000..23c5ac1
Binary files /dev/null and b/phpmyadmin/js/openlayers/theme/default/img/view_next_off.png differ
diff --git a/phpmyadmin/js/openlayers/theme/default/img/view_next_on.png b/phpmyadmin/js/openlayers/theme/default/img/view_next_on.png
new file mode 100644
index 0000000..e41fb7b
Binary files /dev/null and b/phpmyadmin/js/openlayers/theme/default/img/view_next_on.png differ
diff --git a/phpmyadmin/js/openlayers/theme/default/img/view_previous_off.png b/phpmyadmin/js/openlayers/theme/default/img/view_previous_off.png
new file mode 100644
index 0000000..b9c230f
Binary files /dev/null and b/phpmyadmin/js/openlayers/theme/default/img/view_previous_off.png differ
diff --git a/phpmyadmin/js/openlayers/theme/default/img/view_previous_on.png b/phpmyadmin/js/openlayers/theme/default/img/view_previous_on.png
new file mode 100644
index 0000000..c009c25
Binary files /dev/null and b/phpmyadmin/js/openlayers/theme/default/img/view_previous_on.png differ
diff --git a/phpmyadmin/js/openlayers/theme/default/img/zoom-panel-NOALPHA.png b/phpmyadmin/js/openlayers/theme/default/img/zoom-panel-NOALPHA.png
new file mode 100644
index 0000000..cdde6fc
Binary files /dev/null and b/phpmyadmin/js/openlayers/theme/default/img/zoom-panel-NOALPHA.png differ
diff --git a/phpmyadmin/js/openlayers/theme/default/img/zoom-panel.png b/phpmyadmin/js/openlayers/theme/default/img/zoom-panel.png
new file mode 100644
index 0000000..f2c7c51
Binary files /dev/null and b/phpmyadmin/js/openlayers/theme/default/img/zoom-panel.png differ
diff --git a/phpmyadmin/js/openlayers/theme/default/style.css b/phpmyadmin/js/openlayers/theme/default/style.css
new file mode 100644
index 0000000..0627f0e
--- /dev/null
+++ b/phpmyadmin/js/openlayers/theme/default/style.css
@@ -0,0 +1,397 @@
+div.olMap {
+    z-index: 0;
+    padding: 0px!important;
+    margin: 0px!important;
+    cursor: default;
+}
+
+div.olMapViewport {
+    text-align: left;
+}
+
+div.olLayerDiv {
+   -moz-user-select: none;
+}
+
+.olLayerGoogleCopyright {
+    left: 2px;
+    bottom: 2px;  
+}
+.olLayerGooglePoweredBy {
+    left: 2px;
+    bottom: 15px;   
+}
+.olControlAttribution {
+    font-size: smaller; 
+    right: 3px; 
+    bottom: 4.5em; 
+    position: absolute; 
+    display: block;
+}
+.olControlScale {
+    right: 3px;
+    bottom: 3em;
+    display: block;
+    position: absolute;
+    font-size: smaller;
+}
+.olControlScaleLine {
+   display: block;
+   position: absolute;
+   left: 10px;
+   bottom: 15px;
+   font-size: xx-small;
+}
+.olControlScaleLineBottom {
+   border: solid 2px black;
+   border-bottom: none;
+   margin-top:-2px;
+   text-align: center;
+}
+.olControlScaleLineTop {
+   border: solid 2px black;
+   border-top: none;
+   text-align: center;
+}
+
+.olControlPermalink {
+    right: 3px;
+    bottom: 1.5em;
+    display: block;
+    position: absolute;
+    font-size: smaller;
+} 
+
+div.olControlMousePosition {
+    bottom: 0em;
+    right: 3px;
+    display: block;
+    position: absolute;
+    font-family: Arial;
+    font-size: smaller;
+}
+
+.olControlOverviewMapContainer {
+    position: absolute;
+    bottom: 0px;
+    right: 0px;
+}
+
+.olControlOverviewMapElement {
+    padding: 10px 18px 10px 10px;
+    background-color: #00008B;
+    -moz-border-radius: 1em 0 0 0;
+}
+
+.olControlOverviewMapMinimizeButton {
+    right: 0px;
+    bottom: 80px;
+}    
+
+.olControlOverviewMapMaximizeButton {
+    right: 0px;
+    bottom: 80px;
+}
+
+.olControlOverviewMapExtentRectangle {
+    overflow: hidden;
+    background-image: url("img/blank.gif");
+    cursor: move;
+    border: 2px dotted red;
+}
+.olControlOverviewMapRectReplacement {
+    overflow: hidden;
+    cursor: move;
+    background-image: url("img/overview_replacement.gif");
+    background-repeat: no-repeat;
+    background-position: center;
+}
+
+.olLayerGeoRSSDescription {
+    float:left;
+    width:100%;
+    overflow:auto;
+    font-size:1.0em;
+}
+.olLayerGeoRSSClose {
+    float:right;
+    color:gray;
+    font-size:1.2em;
+    margin-right:6px;
+    font-family:sans-serif;
+}
+.olLayerGeoRSSTitle {
+    float:left;font-size:1.2em;
+}
+
+.olPopupContent {
+    padding:5px;
+    overflow: auto;
+}    
+.olControlNavToolbar { 
+    width:0px;
+    height:0px;
+}    
+.olControlNavToolbar div { 
+  display:block;
+  width:  28px;
+  height: 28px;
+  top: 300px;
+  left: 6px;
+  position: relative;
+}
+
+.olControlNavigationHistory {
+   background-image: url("img/navigation_history.png");
+   background-repeat: no-repeat;
+   width:  24px;
+   height: 24px;
+
+}
+.olControlNavigationHistoryPreviousItemActive { 
+  background-position: 0px 0px;
+}
+.olControlNavigationHistoryPreviousItemInactive { 
+   background-position: 0px -24px;
+}
+.olControlNavigationHistoryNextItemActive { 
+   background-position: -24px 0px;
+}
+.olControlNavigationHistoryNextItemInactive { 
+   background-position: -24px -24px;
+}
+
+.olControlNavToolbar .olControlNavigationItemActive { 
+  background-image: url("img/panning-hand-on.png");
+  background-repeat: no-repeat;
+}
+.olControlNavToolbar .olControlNavigationItemInactive { 
+  background-image: url("img/panning-hand-off.png");
+  background-repeat: no-repeat;
+}
+.olControlNavToolbar .olControlZoomBoxItemActive { 
+  background-image: url("img/drag-rectangle-on.png");
+  background-color: orange;
+  background-repeat: no-repeat;
+}
+.olControlNavToolbar .olControlZoomBoxItemInactive { 
+  background-image: url("img/drag-rectangle-off.png");
+  background-repeat: no-repeat;
+}
+.olControlEditingToolbar  {
+    float:right;
+    right: 0px;
+    height: 30px; 
+    width: 200px;
+}
+.olControlEditingToolbar div { 
+  background-image: url("img/editing_tool_bar.png");
+  background-repeat: no-repeat;
+  float:right;
+  width:  24px;
+  height: 24px;
+  margin: 5px;
+}
+.olControlEditingToolbar .olControlNavigationItemActive { 
+  background-position: -103px -23px; 
+}
+.olControlEditingToolbar .olControlNavigationItemInactive { 
+  background-position: -103px -0px; 
+}
+.olControlEditingToolbar .olControlDrawFeaturePointItemActive { 
+  background-position: -77px -23px; 
+}
+.olControlEditingToolbar .olControlDrawFeaturePointItemInactive { 
+  background-position: -77px -0px; 
+}
+.olControlEditingToolbar .olControlDrawFeaturePathItemInactive { 
+  background-position: -51px 0px; 
+}
+.olControlEditingToolbar .olControlDrawFeaturePathItemActive { 
+  background-position: -51px -23px; 
+}
+.olControlEditingToolbar .olControlDrawFeaturePolygonItemInactive { 
+  background-position: -26px 0px; 
+}
+.olControlEditingToolbar .olControlDrawFeaturePolygonItemActive { 
+  background-position: -26px -23px ;                                                                   
+}
+div.olControlSaveFeaturesItemActive { 
+    background-image: url(img/save_features_on.png);
+    background-repeat: no-repeat;
+    background-position: 0px 1px;
+}
+div.olControlSaveFeaturesItemInactive { 
+    background-image: url(img/save_features_off.png);
+    background-repeat: no-repeat;
+    background-position: 0px 1px;
+}
+
+.olHandlerBoxZoomBox {
+    border: 2px solid red;
+    position: absolute;
+    background-color: white;
+    opacity: 0.50;
+    font-size: 1px;
+    filter: alpha(opacity=50);
+}
+.olHandlerBoxSelectFeature {
+    border: 2px solid blue;
+    position: absolute;
+    background-color: white;
+    opacity: 0.50;
+    font-size: 1px;
+    filter: alpha(opacity=50);
+}   
+
+.olControlPanPanel {
+    top: 10px;
+    left: 5px;
+}  
+
+.olControlPanPanel div {
+    background-image: url(img/pan-panel.png);
+    height: 18px;
+    width: 18px;
+    cursor: pointer;
+    position: absolute;
+}
+
+.olControlPanPanel .olControlPanNorthItemInactive {
+    top: 0px;
+    left: 9px;
+    background-position: 0px 0px;
+}
+.olControlPanPanel .olControlPanSouthItemInactive {
+    top: 36px;
+    left: 9px;
+    background-position: 18px 0px;
+}
+.olControlPanPanel .olControlPanWestItemInactive {
+    position: absolute;
+    top: 18px;
+    left: 0px;
+    background-position: 0px 18px;
+}
+.olControlPanPanel .olControlPanEastItemInactive {
+    top: 18px;
+    left: 18px;
+    background-position: 18px 18px;
+}
+
+.olControlZoomPanel {
+    top: 71px;
+    left: 14px;
+} 
+
+.olControlZoomPanel div {
+    background-image: url(img/zoom-panel.png);
+    position: absolute;
+    height: 18px;
+    width: 18px;
+    cursor: pointer;
+}
+
+.olControlZoomPanel .olControlZoomInItemInactive {
+    top: 0px;
+    left: 0px;
+    background-position: 0px 0px;
+}
+
+.olControlZoomPanel .olControlZoomToMaxExtentItemInactive {
+    top: 18px;
+    left: 0px;
+    background-position: 0px -18px;
+}
+
+.olControlZoomPanel .olControlZoomOutItemInactive {
+    top: 36px;
+    left: 0px;
+    background-position: 0px 18px;
+}
+
+.olPopupCloseBox {
+  background: url("img/close.gif") no-repeat;
+  cursor: pointer;
+}
+
+.olFramedCloudPopupContent {
+    padding: 5px;
+    overflow: auto;
+}
+
+.olControlNoSelect {
+ -moz-user-select: none;
+}
+
+.olImageLoadError {
+    background-color: pink;
+    opacity: 0.5;
+    filter: alpha(opacity=50); /* IE */
+}
+
+/**
+ * Cursor styles
+ */
+
+.olCursorWait {
+    cursor: wait;
+}
+.olDragDown {
+    cursor: move;
+}
+.olDrawBox {
+    cursor: crosshair;
+}
+.olControlDragFeatureOver {
+    cursor: move;
+}
+.olControlDragFeatureActive.olControlDragFeatureOver.olDragDown {
+    cursor: -moz-grabbing;
+}
+
+/**
+ * Layer switcher
+ */
+.olControlLayerSwitcher {
+    position: absolute;
+    top: 25px;
+    right: 0px;
+    width: 20em;
+    font-family: sans-serif;
+    font-weight: bold;
+    margin-top: 3px;
+    margin-left: 3px;
+    margin-bottom: 3px;
+    font-size: smaller;
+    color: white;
+    background-color: transparent;
+}
+
+.olControlLayerSwitcher .layersDiv {
+    padding-top: 5px;
+    padding-left: 10px;
+    padding-bottom: 5px;
+    padding-right: 75px;
+    background-color: darkblue;
+    width: 100%;
+    height: 100%;
+}
+
+.olControlLayerSwitcher .layersDiv .baseLbl,
+.olControlLayerSwitcher .layersDiv .dataLbl {
+    margin-top: 3px;
+    margin-left: 3px;
+    margin-bottom: 3px;
+}
+
+.olControlLayerSwitcher .layersDiv .baseLayersDiv,
+.olControlLayerSwitcher .layersDiv .dataLayersDiv {
+    padding-left: 10px;
+}
+
+.olControlLayerSwitcher .maximizeDiv,
+.olControlLayerSwitcher .minimizeDiv {
+    top: 5px;
+    right: 0px;
+}
diff --git a/phpmyadmin/js/pmd/ajax.js b/phpmyadmin/js/pmd/ajax.js
new file mode 100644
index 0000000..3efbf0f
--- /dev/null
+++ b/phpmyadmin/js/pmd/ajax.js
@@ -0,0 +1 @@
+function makeRequest(b,c){var a=PMA_ajaxShowMessage();$.post(b,c,function(d){PMA_ajaxRemoveMessage(a);PrintXML(d)});return true}function PrintXML(c){var j=$(c).find("root");if(j.length==0){var h=window.open("","Report","width=400, height=250, resizable=1, scrollbars=1, status=1");var d=h.document;d.write(c);d.close()}else{if(j.attr("act")=="save_pos"){PMA_ajaxShowMessage(j.attr("return"))}else{if(j.attr("act")=="relation_upd"){PMA_ajaxShowMessage(j.attr("return"));if(j.attr("b")=="1"){co [...]
\ No newline at end of file
diff --git a/phpmyadmin/js/pmd/history.js b/phpmyadmin/js/pmd/history.js
new file mode 100644
index 0000000..0024d40
--- /dev/null
+++ b/phpmyadmin/js/pmd/history.js
@@ -0,0 +1 @@
+var history_array=[];var select_field=[];var g_index;function panel(a){if(!a){$(".toggle_container").hide()}$("h2.tiger").click(function(){$(this).toggleClass("active").next().slideToggle("slow")})}function display(h,f){var g,e,d,c,a;for(e=h;e<f;e++){a=history_array[e];var b=history_array[e].get_tab();for(d=0;d<e;d++){if(b>(history_array[d].get_tab())){for(c=e;c>d;c--){history_array[c]=history_array[c-1]}history_array[d]=a;break}}}g="";for(var e=0;e<history_array.length;e++){var b=histor [...]
\ No newline at end of file
diff --git a/phpmyadmin/js/pmd/iecanvas.js b/phpmyadmin/js/pmd/iecanvas.js
new file mode 100644
index 0000000..7d74107
--- /dev/null
+++ b/phpmyadmin/js/pmd/iecanvas.js
@@ -0,0 +1 @@
+if(!window.all){document.attachEvent("onreadystatechange",function(){if(document.readyState=="complete"){var a=document.getElementById("canvas");var c=a.outerHTML;var b=document.createElement(c);a.parentNode.replaceChild(b,a);a=b;a.getContext=function(){if(this.cont){return this.cont}return this.cont=new PMD_2D(this)};a.style.width=a.attributes.width.nodeValue+"px";a.style.height=a.attributes.height.nodeValue+"px"}});function convert_style(c){var a=[];a=c.match(/.*\((\d*),(\d*),(\d*),(\d [...]
\ No newline at end of file
diff --git a/phpmyadmin/js/pmd/init.js b/phpmyadmin/js/pmd/init.js
new file mode 100644
index 0000000..899b900
--- /dev/null
+++ b/phpmyadmin/js/pmd/init.js
@@ -0,0 +1 @@
+var j_tabs,h_tabs,contr,server,db,token;AJAX.registerTeardown("pmd/init.js",function(){$(".trigger").unbind("click")});AJAX.registerOnload("pmd/init.js",function(){$(".trigger").click(function(){$(".panel").toggle("fast");$(this).toggleClass("active");return false});var a=$.parseJSON($("#script_tables").html());j_tabs=a.j_tabs;h_tabs=a.h_tabs;contr=$.parseJSON($("#script_contr").html());display_field=$.parseJSON($("#script_display_field").html());server=$("#script_server").html();db=$("# [...]
\ No newline at end of file
diff --git a/phpmyadmin/js/pmd/move.js b/phpmyadmin/js/pmd/move.js
new file mode 100644
index 0000000..0fce80f
--- /dev/null
+++ b/phpmyadmin/js/pmd/move.js
@@ -0,0 +1 @@
+var _change=0;var _staying=0;var show_relation_lines=true;AJAX.registerTeardown("pmd/move.js",function(){if($.FullScreen.supported){$(document).unbind($.FullScreen.prefix+"fullscreenchange")}});AJAX.registerOnload("pmd/move.js",function(){$("#page_content").css({"margin-left":"3px"});$("#exitFullscreen").hide();if($.FullScreen.supported){$(document).fullScreenChange(function(){if(!$.FullScreen.isFullScreen()){$("#page_content").removeClass("content_fullscreen").css({width:"auto",height:" [...]
\ No newline at end of file
diff --git a/phpmyadmin/js/querywindow.js b/phpmyadmin/js/querywindow.js
new file mode 100644
index 0000000..c50171c
--- /dev/null
+++ b/phpmyadmin/js/querywindow.js
@@ -0,0 +1 @@
+function PMA_queryAutoCommit(){var a=document.getElementById("sqlqueryform");a.target=window.opener.frame_content.name;a.submit();return}function PMA_querywindowCommit(b){var a=$("#hiddenqueryform");a.find("input[name='querydisplay_tab']").val(b);a.addClass("disableAjax").submit();return false}function PMA_querywindowSetFocus(){$("#sqlquery").focus()}$(function(){$("#topmenucontainer").css("padding",0)});
\ No newline at end of file
diff --git a/phpmyadmin/js/replication.js b/phpmyadmin/js/replication.js
new file mode 100644
index 0000000..b8a802d
--- /dev/null
+++ b/phpmyadmin/js/replication.js
@@ -0,0 +1 @@
+var random_server_id=Math.floor(Math.random()*10000000);var conf_prefix="server-id="+random_server_id+"\nlog_bin=mysql-bin\nlog_error=mysql-bin.err\n";function update_config(){var a="binlog_ignore_db=";var b="binlog_do_db=";var c="";if($("#db_select option:selected").size()==0){$("#rep").text(conf_prefix)}else{if($("#db_type option:selected").val()=="all"){$("#db_select option:selected").each(function(){c+=a+$(this).val()+"\n"});$("#rep").text(conf_prefix+c)}else{$("#db_select option:sel [...]
\ No newline at end of file
diff --git a/phpmyadmin/js/rte.js b/phpmyadmin/js/rte.js
new file mode 100644
index 0000000..bd4a0e1
--- /dev/null
+++ b/phpmyadmin/js/rte.js
@@ -0,0 +1 @@
+var RTE={object:function(a){$.extend(this,RTE.COMMON);switch(a){case"routine":$.extend(this,RTE.ROUTINE);break;case"trigger":break;case"event":$.extend(this,RTE.EVENT);break;default:break}},param_template:""};RTE.COMMON={$ajaxDialog:null,syntaxHiglighter:null,buttonOptions:{},validate:function(){var a=null;a=$("table.rte_table").last().find("input[name=item_name]");if(a.val()===""){a.focus();alert(PMA_messages.strFormEmpty);return false}a=$("table.rte_table").find("textarea[name=item_def [...]
\ No newline at end of file
diff --git a/phpmyadmin/js/server_databases.js b/phpmyadmin/js/server_databases.js
new file mode 100644
index 0000000..6f5a9c0
--- /dev/null
+++ b/phpmyadmin/js/server_databases.js
@@ -0,0 +1 @@
+AJAX.registerTeardown("server_databases.js",function(){$("#dbStatsForm").die("submit");$("#create_database_form.ajax").die("submit")});AJAX.registerOnload("server_databases.js",function(){$("#dbStatsForm").live("submit",function(d){d.preventDefault();var b=$(this);var c=[];b.find("input:checkbox:checked:not(#checkall)").each(function(){$(this).closest("tr").addClass("removeMe");c[c.length]="DROP DATABASE `"+escapeHtml($(this).val())+"`;"});if(!c.length){PMA_ajaxShowMessage($('<div class= [...]
\ No newline at end of file
diff --git a/phpmyadmin/js/server_plugins.js b/phpmyadmin/js/server_plugins.js
new file mode 100644
index 0000000..89b30aa
--- /dev/null
+++ b/phpmyadmin/js/server_plugins.js
@@ -0,0 +1 @@
+var pma_theme_image;AJAX.registerOnload("server_plugins.js",function(){$("#pluginsTabs").tabs({cookie:{name:"pma_serverStatusTabs",expires:1},show:function(b,c){$("#topmenu").menuResizer("resize");$(c.panel).closest(".ui-tabs").find("> div").not(c.panel).css("display","none");$(c.panel).css("display","block")}});var a=$("#plugins_plugins table:has(tbody tr + tr)");a.tablesorter({sortList:[[0,0]],widgets:["zebra"]});a.find("thead th").append('<img class="sortableIcon" src="'+pma_theme_ima [...]
\ No newline at end of file
diff --git a/phpmyadmin/js/server_privileges.js b/phpmyadmin/js/server_privileges.js
new file mode 100644
index 0000000..f526118
--- /dev/null
+++ b/phpmyadmin/js/server_privileges.js
@@ -0,0 +1 @@
+function checkAddUser(a){if(a.elements.pred_hostname.value=="userdefined"&&a.elements.hostname.value==""){alert(PMA_messages.strHostEmpty);a.elements.hostname.focus();return false}if(a.elements.pred_username.value=="userdefined"&&a.elements.username.value==""){alert(PMA_messages.strUserEmpty);a.elements.username.focus();return false}return PMA_checkPassword($(a))}function appendNewUser(j,e,l){var b=$("#usersForm").find("tbody").find("tr:last");var h=$("#usersForm").find("tbody").find("tr [...]
\ No newline at end of file
diff --git a/phpmyadmin/js/server_status.js b/phpmyadmin/js/server_status.js
new file mode 100644
index 0000000..0ba28bc
--- /dev/null
+++ b/phpmyadmin/js/server_status.js
@@ -0,0 +1 @@
+var pma_token,url_query,server_time_diff,server_os,is_superuser,server_db_isLocal;AJAX.registerOnload("server_status.js",function(){var $js_data_form=$("#js_data");pma_token=$js_data_form.find("input[name=pma_token]").val();url_query=$js_data_form.find("input[name=url_query]").val();server_time_diff=eval($js_data_form.find("input[name=server_time_diff]").val());server_os=$js_data_form.find("input[name=server_os]").val();is_superuser=$js_data_form.find("input[name=is_superuser]").val();se [...]
\ No newline at end of file
diff --git a/phpmyadmin/js/server_status_advisor.js b/phpmyadmin/js/server_status_advisor.js
new file mode 100644
index 0000000..c256be9
--- /dev/null
+++ b/phpmyadmin/js/server_status_advisor.js
@@ -0,0 +1 @@
+AJAX.registerTeardown("server_status_advisor.js",function(){$('a[href="#openAdvisorInstructions"]').unbind("click");$("#statustabs_advisor").html("");$("#advisorDialog").remove();$("#instructionsDialog").remove()});AJAX.registerOnload("server_status_advisor.js",function(){var d=$("<div />").attr("id","advisorDialog");var h=$("<div />").attr("id","instructionsDialog").html($("#advisorInstructionsDialog").html());$('a[href="#openAdvisorInstructions"]').click(function(){var i={};i[PMA_messa [...]
\ No newline at end of file
diff --git a/phpmyadmin/js/server_status_monitor.js b/phpmyadmin/js/server_status_monitor.js
new file mode 100644
index 0000000..3ed5356
--- /dev/null
+++ b/phpmyadmin/js/server_status_monitor.js
@@ -0,0 +1 @@
+var runtime={},server_time_diff,server_os,is_superuser,server_db_isLocal;AJAX.registerOnload("server_status_monitor.js",function(){var a=$("#js_data");server_time_diff=new Date().getTime()-a.find("input[name=server_time]").val();server_os=a.find("input[name=server_os]").val();is_superuser=a.find("input[name=is_superuser]").val();server_db_isLocal=a.find("input[name=server_db_isLocal]").val()});AJAX.registerTeardown("server_status_monitor.js",function(){$("#emptyDialog").remove();$("#addC [...]
\ No newline at end of file
diff --git a/phpmyadmin/js/server_status_queries.js b/phpmyadmin/js/server_status_queries.js
new file mode 100644
index 0000000..b6b6f16
--- /dev/null
+++ b/phpmyadmin/js/server_status_queries.js
@@ -0,0 +1 @@
+AJAX.registerTeardown("server_status_queries.js",function(){var a=$("#serverstatusquerieschart").data("queryPieChart");if(a){a.destroy()}});AJAX.registerOnload("server_status_queries.js",function(){var b=[];try{$.each(jQuery.parseJSON($("#serverstatusquerieschart_data").text()),function(c,d){b.push([c,parseInt(d)])});$("#serverstatusquerieschart").data("queryPieChart",PMA_createProfilingChartJqplot("serverstatusquerieschart",b))}catch(a){}PMA_tooltip($("table.sortable>thead>tr:first").fi [...]
\ No newline at end of file
diff --git a/phpmyadmin/js/server_status_sorter.js b/phpmyadmin/js/server_status_sorter.js
new file mode 100644
index 0000000..8130240
--- /dev/null
+++ b/phpmyadmin/js/server_status_sorter.js
@@ -0,0 +1 @@
+function initTableSorter(a){var b,c;switch(a){case"statustabs_queries":b=$("#serverstatusqueriesdetails");c={sortList:[[3,1]],widgets:["fast-zebra"],headers:{1:{sorter:"fancyNumber"},2:{sorter:"fancyNumber"}}};break;case"statustabs_allvars":b=$("#serverstatusvariables");c={sortList:[[0,0]],widgets:["fast-zebra"],headers:{1:{sorter:"withinSpanNumber"}}};break}b.tablesorter(c);b.find("tr:first th").append('<img class="icon sortableIcon" src="themes/dot.gif" alt="">')}$(function(){$.tableso [...]
\ No newline at end of file
diff --git a/phpmyadmin/js/server_status_variables.js b/phpmyadmin/js/server_status_variables.js
new file mode 100644
index 0000000..75bb7ee
--- /dev/null
+++ b/phpmyadmin/js/server_status_variables.js
@@ -0,0 +1 @@
+AJAX.registerTeardown("server_status_variables.js",function(){$("#filterAlert").unbind("change");$("#filterText").unbind("keyup");$("#filterCategory").unbind("change");$("#dontFormat").unbind("change")});AJAX.registerOnload("server_status_variables.js",function(){PMA_tooltip($("table.sortable>thead>tr:first").find("th"),"th",PMA_messages.strSortHint);initTableSorter("statustabs_allvars");var d=null;var c=$("#filterAlert").prop("checked");var b=$("#filterCategory").find(":selected").val() [...]
\ No newline at end of file
diff --git a/phpmyadmin/js/server_variables.js b/phpmyadmin/js/server_variables.js
new file mode 100644
index 0000000..07ea3e9
--- /dev/null
+++ b/phpmyadmin/js/server_variables.js
@@ -0,0 +1 @@
+AJAX.registerTeardown("server_variables.js",function(){$("#serverVariables .var-row").unbind("hover");$("#filterText").unbind("keyup");$("a.editLink").die("click");$("#serverVariables").find(".var-name").find("a img").remove()});AJAX.registerOnload("server_variables.js",function(){var c=$("a.editLink");var e=$("a.saveLink");var b=$("a.cancelLink");var d=$("#filterText");$("#serverVariables").delegate(".var-row","hover",function(h){if(h.type==="mouseenter"){var g=$(this).find(".var-value" [...]
\ No newline at end of file
diff --git a/phpmyadmin/js/sql.js b/phpmyadmin/js/sql.js
new file mode 100644
index 0000000..f03688a
--- /dev/null
+++ b/phpmyadmin/js/sql.js
@@ -0,0 +1 @@
+var $data_a;function PMA_urldecode(a){return decodeURIComponent(a.replace(/\+/g,"%20"))}function PMA_urlencode(a){return encodeURIComponent(a).replace(/\%20/g,"+")}function getFieldName(c){var b=c.index();var a=!$("#table_results").find("th:first").hasClass("draggable");var f=a?$("#table_results").find("th:first").attr("colspan")-1:0;var e=$("#table_results").find("thead").find("th:eq("+(b-f)+") a").text();if(""==e){var d=$("#table_results").find("thead").find("th:eq("+(b-f)+")").childre [...]
\ No newline at end of file
diff --git a/phpmyadmin/js/tbl_change.js b/phpmyadmin/js/tbl_change.js
new file mode 100644
index 0000000..dcc8e46
--- /dev/null
+++ b/phpmyadmin/js/tbl_change.js
@@ -0,0 +1 @@
+function nullify(f,h,c,g){var d=document.forms.insertForm;if(typeof(d.elements["funcs"+g+"["+c+"]"])!="undefined"){d.elements["funcs"+g+"["+c+"]"].selectedIndex=-1}if(f==1){d.elements["fields"+g+"["+c+"]"][1].selectedIndex=-1}else{if(f==2){var e=d.elements["fields"+g+"["+c+"]"];if(e.checked){e.checked=false}else{var a=e.length;for(var b=0;b<a;b++){e[b].checked=false}}}else{if(f==3){d.elements["fields"+g+"["+c+"][]"].selectedIndex=-1}else{if(f==4){d.elements["fields"+g+"["+c+"]"].selected [...]
\ No newline at end of file
diff --git a/phpmyadmin/js/tbl_chart.js b/phpmyadmin/js/tbl_chart.js
new file mode 100644
index 0000000..6d6082a
--- /dev/null
+++ b/phpmyadmin/js/tbl_chart.js
@@ -0,0 +1 @@
+var chart_data={};var temp_chart_title;var currentChart=null;var currentSettings=null;AJAX.registerTeardown("tbl_chart.js",function(){$('input[name="chartType"]').unbind("click");$('input[name="barStacked"]').unbind("click");$('input[name="chartTitle"]').unbind("focus").unbind("keyup").unbind("blur");$('select[name="chartXAxis"]').unbind("change");$('select[name="chartSeries"]').unbind("change");$('input[name="xaxis_label"]').unbind("keyup");$('input[name="yaxis_label"]').unbind("keyup") [...]
\ No newline at end of file
diff --git a/phpmyadmin/js/tbl_gis_visualization.js b/phpmyadmin/js/tbl_gis_visualization.js
new file mode 100644
index 0000000..41b356d
--- /dev/null
+++ b/phpmyadmin/js/tbl_gis_visualization.js
@@ -0,0 +1 @@
+var zoomFactor=1.5;var defaultX=0;var defaultY=0;var x;var y;var scale;var svg;function zoomAndPan(){var c=svg.getElementById("groupPanel");c.setAttribute("transform","translate("+x+", "+y+") scale("+scale+")");var e;var d;$("circle.vector").each(function(){e=$(this).attr("id");d=svg.getElementById(e);svg.change(d,{r:(3/scale),"stroke-width":(2/scale)})});var a;$("polyline.vector").each(function(){e=$(this).attr("id");a=svg.getElementById(e);svg.change(a,{"stroke-width":(2/scale)})});var [...]
\ No newline at end of file
diff --git a/phpmyadmin/js/tbl_relation.js b/phpmyadmin/js/tbl_relation.js
new file mode 100644
index 0000000..49b3d17
--- /dev/null
+++ b/phpmyadmin/js/tbl_relation.js
@@ -0,0 +1 @@
+function show_hide_clauses(a){if(a.val()!=""){a.parent().nextAll("span").show()}else{a.parent().nextAll("span").hide()}}AJAX.registerTeardown("tbl_relation.js",function(){$("select.referenced_column_dropdown").unbind("change")});AJAX.registerOnload("tbl_relation.js",function(){$("select.referenced_column_dropdown").each(function(a,b){show_hide_clauses($(b))});$("select.referenced_column_dropdown").change(function(){show_hide_clauses($(this))})});
\ No newline at end of file
diff --git a/phpmyadmin/js/tbl_select.js b/phpmyadmin/js/tbl_select.js
new file mode 100644
index 0000000..5c93bd9
--- /dev/null
+++ b/phpmyadmin/js/tbl_select.js
@@ -0,0 +1 @@
+AJAX.registerTeardown("tbl_select.js",function(){$("#togglesearchformlink").unbind("click");$("#tbl_search_form.ajax").die("submit");$("select.geom_func").unbind("change");$("span.open_search_gis_editor").die("click")});AJAX.registerOnload("tbl_select.js",function(){$('<div id="togglesearchformdiv"><a id="togglesearchformlink"></a></div>').insertAfter("#tbl_search_form").hide();$("#togglesearchformlink").html(PMA_messages.strShowSearchCriteria).bind("click",function(){var a=$(this);$("#t [...]
\ No newline at end of file
diff --git a/phpmyadmin/js/tbl_structure.js b/phpmyadmin/js/tbl_structure.js
new file mode 100644
index 0000000..b7ba163
--- /dev/null
+++ b/phpmyadmin/js/tbl_structure.js
@@ -0,0 +1 @@
+AJAX.registerTeardown("tbl_structure.js",function(){$("a.change_column_anchor.ajax").die("click");$("button.change_columns_anchor.ajax, input.change_columns_anchor.ajax").die("click");$("a.drop_column_anchor.ajax").die("click");$("a.add_primary_key_anchor.ajax").die("click");$("#move_columns_anchor").die("click");$(".append_fields_form.ajax").unbind("submit")});AJAX.registerOnload("tbl_structure.js",function(){$(".append_fields_form.ajax").die().live("submit",function(b){b.preventDefault [...]
\ No newline at end of file
diff --git a/phpmyadmin/js/tbl_zoom_plot_jqplot.js b/phpmyadmin/js/tbl_zoom_plot_jqplot.js
new file mode 100644
index 0000000..dffee46
--- /dev/null
+++ b/phpmyadmin/js/tbl_zoom_plot_jqplot.js
@@ -0,0 +1 @@
+function displayHelp(){PMA_ajaxShowMessage(PMA_messages.strDisplayHelp,10000)}Array.max=function(a){return Math.max.apply(Math,a)};Array.min=function(a){return Math.min.apply(Math,a)};function isNumeric(a){return !isNaN(parseFloat(a))&&isFinite(a)}function isEmpty(b){var a;for(a in b){return false}return true}function getTimeStamp(b,a){if(a.toString().search(/datetime/i)!=-1||a.toString().search(/timestamp/i)!=-1){return getDateFromFormat(b,"yyyy-MM-dd HH:mm:ss")}else{if(a.toString().sea [...]
\ No newline at end of file
diff --git a/phpmyadmin/libraries/.htaccess b/phpmyadmin/libraries/.htaccess
new file mode 100644
index 0000000..56baee6
--- /dev/null
+++ b/phpmyadmin/libraries/.htaccess
@@ -0,0 +1,3 @@
+# This folder does not require access over HTTP
+# (the following directive denies access by default)
+Order allow,deny
diff --git a/phpmyadmin/libraries/Advisor.class.php b/phpmyadmin/libraries/Advisor.class.php
new file mode 100644
index 0000000..91c8bf2
--- /dev/null
+++ b/phpmyadmin/libraries/Advisor.class.php
@@ -0,0 +1,509 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * A simple rules engine, that parses and executes the rules in advisory_rules.txt.
+ * Adjusted to phpMyAdmin.
+ *
+ * @package PhpMyAdmin
+ */
+if (! defined('PHPMYADMIN')) {
+    exit;
+}
+
+/**
+ * Advisor class
+ *
+ * @package PhpMyAdmin
+ */
+class Advisor
+{
+    var $variables;
+    var $parseResult;
+    var $runResult;
+
+    /**
+     * Parses and executes advisor rules
+     *
+     * @return array with run and parse results
+     */
+    function run()
+    {
+        // HowTo: A simple Advisory system in 3 easy steps.
+
+        // Step 1: Get some variables to evaluate on
+        $this->variables = array_merge(
+            PMA_DBI_fetch_result('SHOW GLOBAL STATUS', 0, 1),
+            PMA_DBI_fetch_result('SHOW GLOBAL VARIABLES', 0, 1)
+        );
+        if (PMA_DRIZZLE) {
+            $this->variables = array_merge(
+                $this->variables,
+                PMA_DBI_fetch_result(
+                    "SELECT concat('Com_', variable_name), variable_value
+                    FROM data_dictionary.GLOBAL_STATEMENTS", 0, 1
+                )
+            );
+        }
+        // Add total memory to variables as well
+        include_once 'libraries/sysinfo.lib.php';
+        $sysinfo = PMA_getSysInfo();
+        $memory  = $sysinfo->memory();
+        $this->variables['system_memory'] = $memory['MemTotal'];
+
+        // Step 2: Read and parse the list of rules
+        $this->parseResult = $this->parseRulesFile();
+        // Step 3: Feed the variables to the rules and let them fire. Sets
+        // $runResult
+        $this->runRules();
+
+        return array(
+            'parse' => array('errors' => $this->parseResult['errors']),
+            'run'   => $this->runResult
+        );
+    }
+
+    /**
+     * Stores current error in run results.
+     *
+     * @param string $description description of an error.
+     * @param object $exception   exception raised
+     *
+     * @return void
+     */
+    function storeError($description, $exception)
+    {
+        $this->runResult['errors'][] = $description
+            . ' '
+            . sprintf(__('PHP threw following error: %s'), $exception->getMessage());
+    }
+
+    /**
+     * Executes advisor rules
+     *
+     * @return void
+     */
+    function runRules()
+    {
+        $this->runResult = array(
+            'fired' => array(),
+            'notfired' => array(),
+            'unchecked'=> array(),
+            'errors' => array()
+        );
+
+        foreach ($this->parseResult['rules'] as $rule) {
+            $this->variables['value'] = 0;
+            $precond = true;
+
+            if (isset($rule['precondition'])) {
+                try {
+                     $precond = $this->ruleExprEvaluate($rule['precondition']);
+                } catch (Exception $e) {
+                    $this->storeError(
+                        sprintf(
+                            __('Failed evaluating precondition for rule \'%s\''),
+                            $rule['name']
+                        ),
+                        $e
+                    );
+                    continue;
+                }
+            }
+
+            if (! $precond) {
+                $this->addRule('unchecked', $rule);
+            } else {
+                try {
+                    $value = $this->ruleExprEvaluate($rule['formula']);
+                } catch(Exception $e) {
+                    $this->storeError(
+                        sprintf(
+                            __('Failed calculating value for rule \'%s\''),
+                            $rule['name']
+                        ),
+                        $e
+                    );
+                    continue;
+                }
+
+                $this->variables['value'] = $value;
+
+                try {
+                    if ($this->ruleExprEvaluate($rule['test'])) {
+                        $this->addRule('fired', $rule);
+                    } else {
+                        $this->addRule('notfired', $rule);
+                    }
+                }  catch(Exception $e) {
+                    $this->storeError(
+                        sprintf(
+                            __('Failed running test for rule \'%s\''),
+                            $rule['name']
+                        ),
+                        $e
+                    );
+                }
+            }
+        }
+
+        return true;
+    }
+
+    /**
+     * Escapes percent string to be used in format string.
+     *
+     * @param string $str string to escape
+     *
+     * @return string
+     */
+    static function escapePercent($str)
+    {
+        return preg_replace('/%( |,|\.|$|\(|\)|<|>)/', '%%\1', $str);
+    }
+
+    /**
+     * Wrapper function for translating.
+     *
+     * @param string $str   the string
+     * @param mixed  $param the parameters
+     *
+     * @return string
+     */
+    function translate($str, $param = null)
+    {
+        if (is_null($param)) {
+            return sprintf(_gettext(Advisor::escapePercent($str)));
+        } else {
+            $printf = 'sprintf("' . _gettext(Advisor::escapePercent($str)) . '",';
+            return $this->ruleExprEvaluate(
+                $printf . $param . ')',
+                strlen($printf)
+            );
+        }
+    }
+
+    /**
+     * Splits justification to text and formula.
+     *
+     * @param string $rule the rule
+     *
+     * @return array
+     */
+    static function splitJustification($rule)
+    {
+        $jst = preg_split('/\s*\|\s*/', $rule['justification'], 2);
+        if (count($jst) > 1) {
+            return array($jst[0], $jst[1]);
+        }
+        return array($rule['justification']);
+    }
+
+    /**
+     * Adds a rule to the result list
+     *
+     * @param string $type type of rule
+     * @param array  $rule rule itslef
+     *
+     * @return void
+     */
+    function addRule($type, $rule)
+    {
+        switch($type) {
+        case 'notfired':
+        case 'fired':
+            $jst = Advisor::splitJustification($rule);
+            if (count($jst) > 1) {
+                try {
+                    /* Translate */
+                    $str = $this->translate($jst[0], $jst[1]);
+                } catch (Exception $e) {
+                    $this->storeError(
+                        sprintf(
+                            __('Failed formatting string for rule \'%s\'.'),
+                            $rule['name']
+                        ),
+                        $e
+                    );
+                    return;
+                }
+
+                $rule['justification'] = $str;
+            } else {
+                $rule['justification'] = $this->translate($rule['justification']);
+            }
+            $rule['id'] = $rule['name'];
+            $rule['name'] = $this->translate($rule['name']);
+            $rule['issue'] = $this->translate($rule['issue']);
+
+            // Replaces {server_variable} with 'server_variable'
+            // linking to server_variables.php
+            $rule['recommendation'] = preg_replace(
+                '/\{([a-z_0-9]+)\}/Ui',
+                '<a href="server_variables.php?' . PMA_generate_common_url() . '&filter=\1">\1</a>',
+                $this->translate($rule['recommendation'])
+            );
+
+            // Replaces external Links with PMA_linkURL() generated links
+            $rule['recommendation'] = preg_replace_callback(
+                '#href=("|\')(https?://[^\1]+)\1#i',
+                array($this, '_replaceLinkURL'),
+                $rule['recommendation']
+            );
+            break;
+        }
+
+        $this->runResult[$type][] = $rule;
+    }
+
+    /**
+     * Callback for wrapping links with PMA_linkURL
+     *
+     * @param array $matches List of matched elements form preg_replace_callback
+     *
+     * @return Replacement value
+     */
+    private function _replaceLinkURL($matches)
+    {
+        return 'href="' . PMA_linkURL($matches[2]) . '"';
+    }
+
+    /**
+     * Callback for evaluating fired() condition.
+     *
+     * @param array $matches List of matched elements form preg_replace_callback
+     *
+     * @return Replacement value
+     */
+    private function _ruleExprEvaluateFired($matches)
+    {
+        // No list of fired rules
+        if (!isset($this->runResult['fired'])) {
+            return '0';
+        }
+
+        // Did matching rule fire?
+        foreach ($this->runResult['fired'] as $rule) {
+            if ($rule['id'] == $matches[2]) {
+                return '1';
+            }
+        }
+
+        return '0';
+    }
+
+    /**
+     * Callback for evaluating variables in expression.
+     *
+     * @param array $matches List of matched elements form preg_replace_callback
+     *
+     * @return Replacement value
+     */
+    private function _ruleExprEvaluateVariable($matches)
+    {
+        return isset($this->variables[$matches[1]])
+            ? (is_numeric($this->variables[$matches[1]])
+                ? $this->variables[$matches[1]]
+                : '"'.$this->variables[$matches[1]].'"')
+            : $matches[1];
+    }
+
+    /**
+     * Runs a code expression, replacing variable names with their respective
+     * values
+     *
+     * @param string $expr        expression to evaluate
+     * @param int    $ignoreUntil if > 0, it doesn't replace any variables until
+     *                            that string position, but still evaluates the
+     *                            whole expr
+     *
+     * @return result of evaluated expression
+     */
+    function ruleExprEvaluate($expr, $ignoreUntil = 0)
+    {
+        if ($ignoreUntil > 0) {
+            $exprIgnore = substr($expr, 0, $ignoreUntil);
+            $expr = substr($expr, $ignoreUntil);
+        }
+        // Evaluate fired() conditions
+        $expr = preg_replace_callback(
+            '/fired\s*\(\s*(\'|")(.*)\1\s*\)/Ui',
+            array($this, '_ruleExprEvaluateFired'),
+            $expr
+        );
+        // Evaluate variables
+        $expr = preg_replace_callback(
+            '/\b(\w+)\b/',
+            array($this, '_ruleExprEvaluateVariable'),
+            $expr
+        );
+        if ($ignoreUntil > 0) {
+            $expr = $exprIgnore . $expr;
+        }
+        $value = 0;
+        $err = 0;
+
+        // Actually evaluate the code
+        ob_start();
+        eval('$value = ' . $expr . ';');
+        $err = ob_get_contents();
+        ob_end_clean();
+
+        // Error handling
+        if ($err) {
+            throw new Exception(
+                strip_tags($err) . '<br />Executed code: $value = ' . htmlspecialchars($expr) . ';'
+            );
+        }
+        return $value;
+    }
+
+    /**
+     * Reads the rule file into an array, throwing errors messages on syntax
+     * errors.
+     *
+     * @return array with parsed data
+     */
+    static function parseRulesFile()
+    {
+        $file = file('libraries/advisory_rules.txt', FILE_IGNORE_NEW_LINES);
+        $errors = array();
+        $rules = array();
+        $lines = array();
+        $ruleSyntax = array(
+            'name', 'formula', 'test', 'issue', 'recommendation', 'justification'
+        );
+        $numRules = count($ruleSyntax);
+        $numLines = count($file);
+        $ruleNo = -1;
+        $ruleLine = -1;
+
+        for ($i = 0; $i < $numLines; $i++) {
+            $line = $file[$i];
+            if ($line == "" || $line[0] == '#') {
+                continue;
+            }
+
+            // Reading new rule
+            if (substr($line, 0, 4) == 'rule') {
+                if ($ruleLine > 0) {
+                    $errors[] = sprintf(
+                        __('Invalid rule declaration on line %1$s, expected line %2$s of previous rule'),
+                        $i + 1,
+                        $ruleSyntax[$ruleLine++]
+                    );
+                    continue;
+                }
+                if (preg_match("/rule\s'(.*)'( \[(.*)\])?$/", $line, $match)) {
+                    $ruleLine = 1;
+                    $ruleNo++;
+                    $rules[$ruleNo] = array('name' => $match[1]);
+                    $lines[$ruleNo] = array('name' => $i + 1);
+                    if (isset($match[3])) {
+                        $rules[$ruleNo]['precondition'] = $match[3];
+                        $lines[$ruleNo]['precondition'] = $i + 1;
+                    }
+                } else {
+                    $errors[] = sprintf(
+                        __('Invalid rule declaration on line %s'),
+                        $i + 1
+                    );
+                }
+                continue;
+            } else {
+                if ($ruleLine == -1) {
+                    $errors[] = sprintf(
+                        __('Unexpected characters on line %s'),
+                        $i + 1
+                    );
+                }
+            }
+
+            // Reading rule lines
+            if ($ruleLine > 0) {
+                if (!isset($line[0])) {
+                    continue; // Empty lines are ok
+                }
+                // Non tabbed lines are not
+                if ($line[0] != "\t") {
+                    $errors[] = sprintf(
+                        __('Unexpected character on line %1$s. Expected tab, but found "%2$s"'),
+                        $i + 1,
+                        $line[0]
+                    );
+                    continue;
+                }
+                $rules[$ruleNo][$ruleSyntax[$ruleLine]] = chop(substr($line, 1));
+                $lines[$ruleNo][$ruleSyntax[$ruleLine]] = $i + 1;
+                $ruleLine += 1;
+            }
+
+            // Rule complete
+            if ($ruleLine == $numRules) {
+                $ruleLine = -1;
+            }
+        }
+
+        return array('rules' => $rules, 'lines' => $lines, 'errors' => $errors);
+    }
+}
+
+/**
+ * Formats interval like 10 per hour
+ *
+ * @param integer $num       number to format
+ * @param intefer $precision required precision
+ *
+ * @return formatted string
+ */
+function ADVISOR_bytime($num, $precision)
+{
+    $per = '';
+    if ($num >= 1) { // per second
+        $per = __('per second');
+    } elseif ($num * 60 >= 1) { // per minute
+        $num = $num * 60;
+        $per = __('per minute');
+    } elseif ($num * 60 * 60 >= 1 ) { // per hour
+        $num = $num * 60 * 60;
+        $per = __('per hour');
+    } else {
+        $num = $num * 60 * 60 * 24;
+        $per = __('per day');
+    }
+
+    $num = round($num, $precision);
+
+    if ($num == 0) {
+        $num = '<' . PMA_Util::pow(10, -$precision);
+    }
+
+    return "$num $per";
+}
+
+/**
+ * Wrapper for PMA_Util::timespanFormat
+ *
+ * @param int $seconds the timespan
+ *
+ * @return string  the formatted value
+ */
+function ADVISOR_timespanFormat($seconds)
+{
+    return PMA_Util::timespanFormat($seconds);
+}
+
+/**
+ * Wrapper around PMA_Util::formatByteDown
+ *
+ * @param double $value the value to format
+ * @param int    $limes the sensitiveness
+ * @param int    $comma the number of decimals to retain
+ *
+ * @return array    the formatted value and its unit
+ */
+function ADVISOR_formatByteDown($value, $limes = 6, $comma = 0)
+{
+    return PMA_Util::formatByteDown($value, $limes, $comma);
+}
+
+?>
diff --git a/phpmyadmin/libraries/Config.class.php b/phpmyadmin/libraries/Config.class.php
new file mode 100644
index 0000000..57b643e
--- /dev/null
+++ b/phpmyadmin/libraries/Config.class.php
@@ -0,0 +1,1829 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * Configuration handling.
+ *
+ * @package PhpMyAdmin
+ */
+if (! defined('PHPMYADMIN')) {
+    exit;
+}
+
+/**
+ * Load vendor configuration.
+ */
+require_once './libraries/vendor_config.php';
+
+/**
+ * Configuration class
+ *
+ * @package PhpMyAdmin
+ */
+class PMA_Config
+{
+    /**
+     * @var string  default config source
+     */
+    var $default_source = './libraries/config.default.php';
+
+    /**
+     * @var array   default configuration settings
+     */
+    var $default = array();
+
+    /**
+     * @var array   configuration settings
+     */
+    var $settings = array();
+
+    /**
+     * @var string  config source
+     */
+    var $source = '';
+
+    /**
+     * @var int     source modification time
+     */
+    var $source_mtime = 0;
+    var $default_source_mtime = 0;
+    var $set_mtime = 0;
+
+    /**
+     * @var boolean
+     */
+    var $error_config_file = false;
+
+    /**
+     * @var boolean
+     */
+    var $error_config_default_file = false;
+
+    /**
+     * @var boolean
+     */
+    var $error_pma_uri = false;
+
+    /**
+     * @var array
+     */
+    var $default_server = array();
+
+    /**
+     * @var boolean whether init is done or not
+     * set this to false to force some initial checks
+     * like checking for required functions
+     */
+    var $done = false;
+
+    /**
+     * constructor
+     *
+     * @param string $source source to read config from
+     */
+    function __construct($source = null)
+    {
+        $this->settings = array();
+
+        // functions need to refresh in case of config file changed goes in
+        // PMA_Config::load()
+        $this->load($source);
+
+        // other settings, independent from config file, comes in
+        $this->checkSystem();
+
+        $this->checkIsHttps();
+    }
+
+    /**
+     * sets system and application settings
+     *
+     * @return void
+     */
+    function checkSystem()
+    {
+        $this->set('PMA_VERSION', '4.0.4');
+        /**
+         * @deprecated
+         */
+        $this->set('PMA_THEME_VERSION', 2);
+        /**
+         * @deprecated
+         */
+        $this->set('PMA_THEME_GENERATION', 2);
+
+        $this->checkPhpVersion();
+        $this->checkWebServerOs();
+        $this->checkWebServer();
+        $this->checkGd2();
+        $this->checkClient();
+        $this->checkUpload();
+        $this->checkUploadSize();
+        $this->checkOutputCompression();
+    }
+
+    /**
+     * whether to use gzip output compression or not
+     *
+     * @return void
+     */
+    function checkOutputCompression()
+    {
+        // If zlib output compression is set in the php configuration file, no
+        // output buffering should be run
+        if (@ini_get('zlib.output_compression')) {
+            $this->set('OBGzip', false);
+        }
+
+        // disable output-buffering (if set to 'auto') for IE6, else enable it.
+        if (strtolower($this->get('OBGzip')) == 'auto') {
+            if ($this->get('PMA_USR_BROWSER_AGENT') == 'IE'
+                && $this->get('PMA_USR_BROWSER_VER') >= 6
+                && $this->get('PMA_USR_BROWSER_VER') < 7
+            ) {
+                $this->set('OBGzip', false);
+            } else {
+                $this->set('OBGzip', true);
+            }
+        }
+    }
+
+    /**
+     * Determines platform (OS), browser and version of the user
+     * Based on a phpBuilder article:
+     *
+     * @see http://www.phpbuilder.net/columns/tim20000821.php
+     *
+     * @return void
+     */
+    function checkClient()
+    {
+        if (PMA_getenv('HTTP_USER_AGENT')) {
+            $HTTP_USER_AGENT = PMA_getenv('HTTP_USER_AGENT');
+        } else {
+            $HTTP_USER_AGENT = '';
+        }
+
+        // 1. Platform
+        if (strstr($HTTP_USER_AGENT, 'Win')) {
+            $this->set('PMA_USR_OS', 'Win');
+        } elseif (strstr($HTTP_USER_AGENT, 'Mac')) {
+            $this->set('PMA_USR_OS', 'Mac');
+        } elseif (strstr($HTTP_USER_AGENT, 'Linux')) {
+            $this->set('PMA_USR_OS', 'Linux');
+        } elseif (strstr($HTTP_USER_AGENT, 'Unix')) {
+            $this->set('PMA_USR_OS', 'Unix');
+        } elseif (strstr($HTTP_USER_AGENT, 'OS/2')) {
+            $this->set('PMA_USR_OS', 'OS/2');
+        } else {
+            $this->set('PMA_USR_OS', 'Other');
+        }
+
+        // 2. browser and version
+        // (must check everything else before Mozilla)
+
+        if (preg_match(
+            '@Opera(/| )([0-9].[0-9]{1,2})@',
+            $HTTP_USER_AGENT,
+            $log_version
+        )) {
+            $this->set('PMA_USR_BROWSER_VER', $log_version[2]);
+            $this->set('PMA_USR_BROWSER_AGENT', 'OPERA');
+        } elseif (preg_match(
+            '@MSIE ([0-9].[0-9]{1,2})@',
+            $HTTP_USER_AGENT,
+            $log_version
+        )) {
+            $this->set('PMA_USR_BROWSER_VER', $log_version[1]);
+            $this->set('PMA_USR_BROWSER_AGENT', 'IE');
+        } elseif (preg_match(
+            '@OmniWeb/([0-9].[0-9]{1,2})@',
+            $HTTP_USER_AGENT,
+            $log_version
+        )) {
+            $this->set('PMA_USR_BROWSER_VER', $log_version[1]);
+            $this->set('PMA_USR_BROWSER_AGENT', 'OMNIWEB');
+            // Konqueror 2.2.2 says Konqueror/2.2.2
+            // Konqueror 3.0.3 says Konqueror/3
+        } elseif (preg_match(
+            '@(Konqueror/)(.*)(;)@',
+            $HTTP_USER_AGENT,
+            $log_version
+        )) {
+            $this->set('PMA_USR_BROWSER_VER', $log_version[2]);
+            $this->set('PMA_USR_BROWSER_AGENT', 'KONQUEROR');
+            // must check Chrome before Safari
+        } elseif (preg_match(
+            '@Mozilla/([0-9].[0-9]{1,2})@',
+            $HTTP_USER_AGENT,
+            $log_version)
+            && preg_match('@Chrome/([0-9]*)@', $HTTP_USER_AGENT, $log_version2)
+        ) {
+            $this->set('PMA_USR_BROWSER_VER', $log_version[1] . '.' . $log_version2[1]);
+            $this->set('PMA_USR_BROWSER_AGENT', 'CHROME');
+            // newer Safari
+        } elseif (preg_match(
+            '@Mozilla/([0-9].[0-9]{1,2})@',
+            $HTTP_USER_AGENT,
+            $log_version)
+            && preg_match('@Version/(.*) Safari@', $HTTP_USER_AGENT, $log_version2)
+        ) {
+            $this->set(
+                'PMA_USR_BROWSER_VER', $log_version2[1]
+            );
+            $this->set('PMA_USR_BROWSER_AGENT', 'SAFARI');
+            // older Safari
+        } elseif (preg_match(
+            '@Mozilla/([0-9].[0-9]{1,2})@',
+            $HTTP_USER_AGENT,
+            $log_version)
+            && preg_match('@Safari/([0-9]*)@', $HTTP_USER_AGENT, $log_version2)
+        ) {
+            $this->set(
+                'PMA_USR_BROWSER_VER', $log_version[1] . '.' . $log_version2[1]
+            );
+            $this->set('PMA_USR_BROWSER_AGENT', 'SAFARI');
+        } elseif (preg_match('@rv:1.9(.*)Gecko@', $HTTP_USER_AGENT)) {
+            $this->set('PMA_USR_BROWSER_VER', '1.9');
+            $this->set('PMA_USR_BROWSER_AGENT', 'GECKO');
+        } elseif (preg_match('@Mozilla/([0-9].[0-9]{1,2})@', $HTTP_USER_AGENT, $log_version)) {
+            $this->set('PMA_USR_BROWSER_VER', $log_version[1]);
+            $this->set('PMA_USR_BROWSER_AGENT', 'MOZILLA');
+        } else {
+            $this->set('PMA_USR_BROWSER_VER', 0);
+            $this->set('PMA_USR_BROWSER_AGENT', 'OTHER');
+        }
+    }
+
+    /**
+     * Whether GD2 is present
+     *
+     * @return void
+     */
+    function checkGd2()
+    {
+        if ($this->get('GD2Available') == 'yes') {
+            $this->set('PMA_IS_GD2', 1);
+        } elseif ($this->get('GD2Available') == 'no') {
+            $this->set('PMA_IS_GD2', 0);
+        } else {
+            if (!@function_exists('imagecreatetruecolor')) {
+                $this->set('PMA_IS_GD2', 0);
+            } else {
+                if (@function_exists('gd_info')) {
+                    $gd_nfo = gd_info();
+                    if (strstr($gd_nfo["GD Version"], '2.')) {
+                        $this->set('PMA_IS_GD2', 1);
+                    } else {
+                        $this->set('PMA_IS_GD2', 0);
+                    }
+                } else {
+                    $this->set('PMA_IS_GD2', 0);
+                }
+            }
+        }
+    }
+
+    /**
+     * Whether the Web server php is running on is IIS
+     *
+     * @return void
+     */
+    function checkWebServer()
+    {
+        // some versions return Microsoft-IIS, some Microsoft/IIS
+        // we could use a preg_match() but it's slower
+        if (PMA_getenv('SERVER_SOFTWARE')
+            && stristr(PMA_getenv('SERVER_SOFTWARE'), 'Microsoft')
+            && stristr(PMA_getenv('SERVER_SOFTWARE'), 'IIS')
+        ) {
+            $this->set('PMA_IS_IIS', 1);
+        } else {
+            $this->set('PMA_IS_IIS', 0);
+        }
+    }
+
+    /**
+     * Whether the os php is running on is windows or not
+     *
+     * @return void
+     */
+    function checkWebServerOs()
+    {
+        // Default to Unix or Equiv
+        $this->set('PMA_IS_WINDOWS', 0);
+        // If PHP_OS is defined then continue
+        if (defined('PHP_OS')) {
+            if (stristr(PHP_OS, 'win')) {
+                // Is it some version of Windows
+                $this->set('PMA_IS_WINDOWS', 1);
+            } elseif (stristr(PHP_OS, 'OS/2')) {
+                // Is it OS/2 (No file permissions like Windows)
+                $this->set('PMA_IS_WINDOWS', 1);
+            }
+        }
+    }
+
+    /**
+     * detects PHP version
+     *
+     * @return void
+     */
+    function checkPhpVersion()
+    {
+        $match = array();
+        if (! preg_match(
+            '@([0-9]{1,2}).([0-9]{1,2}).([0-9]{1,2})@',
+            phpversion(),
+            $match
+        )) {
+            preg_match(
+                '@([0-9]{1,2}).([0-9]{1,2})@',
+                phpversion(),
+                $match
+            );
+        }
+        if (isset($match) && ! empty($match[1])) {
+            if (! isset($match[2])) {
+                $match[2] = 0;
+            }
+            if (! isset($match[3])) {
+                $match[3] = 0;
+            }
+            $this->set(
+                'PMA_PHP_INT_VERSION',
+                (int) sprintf('%d%02d%02d', $match[1], $match[2], $match[3])
+            );
+        } else {
+            $this->set('PMA_PHP_INT_VERSION', 0);
+        }
+        $this->set('PMA_PHP_STR_VERSION', phpversion());
+    }
+
+    /**
+     * detects if Git revision
+     *
+     * @return boolean
+     */
+    function isGitRevision()
+    {
+        // caching
+        if (isset($_SESSION['is_git_revision'])) {
+            if ($_SESSION['is_git_revision']) {
+                $this->set('PMA_VERSION_GIT', 1);
+            }
+            return $_SESSION['is_git_revision'];
+        }
+        // find out if there is a .git folder
+        $git_folder = '.git';
+        if (! @file_exists($git_folder)
+            || ! @file_exists($git_folder . '/config')
+        ) {
+            $_SESSION['is_git_revision'] = false;
+            return false;
+        }
+        $_SESSION['is_git_revision'] = true;
+        return true;
+    }
+
+    /**
+     * detects Git revision, if running inside repo
+     *
+     * @return void
+     */
+    function checkGitRevision()
+    {
+        // find out if there is a .git folder
+        $git_folder = '.git';
+        if (! $this->isGitRevision()) {
+            return;
+        }
+
+        if (! $ref_head = @file_get_contents($git_folder . '/HEAD')) {
+            return;
+        }
+        $branch = false;
+        // are we on any branch?
+        if (strstr($ref_head, '/')) {
+            $ref_head = substr(trim($ref_head), 5);
+            if (substr($ref_head, 0, 11) === 'refs/heads/') {
+                $branch = substr($ref_head, 11);
+            } else {
+                $branch = basename($ref_head);
+            }
+
+            $ref_file = $git_folder . '/' . $ref_head;
+            if (@file_exists($ref_file)) {
+                if (! $hash = @file_get_contents($ref_file)) {
+                    return;
+                }
+                $hash = trim($hash);
+            } else {
+                // deal with packed refs
+                if (! $packed_refs = @file_get_contents($git_folder . '/packed-refs')) {
+                    return;
+                }
+                // split file to lines
+                $ref_lines = explode("\n", $packed_refs);
+                foreach ($ref_lines as $line) {
+                    // skip comments
+                    if ($line[0] == '#') {
+                        continue;
+                    }
+                    // parse line
+                    $parts = explode(' ', $line);
+                    // care only about named refs
+                    if (count($parts) != 2) {
+                        continue;
+                    }
+                    // have found our ref?
+                    if ($parts[1] == $ref_head) {
+                        $hash = $parts[0];
+                        break;
+                    }
+                }
+                if (! isset($hash)) {
+                    // Could not find ref
+                    return;
+                }
+            }
+        } else {
+            $hash = trim($ref_head);
+        }
+
+        $commit = false;
+        if ( !isset($_SESSION['PMA_VERSION_COMMITDATA_' . $hash])) {
+            $git_file_name = $git_folder . '/objects/' . substr($hash, 0, 2)
+                    . '/' . substr($hash, 2);
+            if (file_exists($git_file_name) ) {
+                if (! $commit = @file_get_contents($git_file_name)) {
+                    return;
+                }
+                $commit = explode("\0", gzuncompress($commit), 2);
+                $commit = explode("\n", $commit[1]);
+                $_SESSION['PMA_VERSION_COMMITDATA_' . $hash] = $commit;
+            } else {
+                $pack_names = array();
+                // work with packed data
+                if ($packs = @file_get_contents($git_folder . '/objects/info/packs')) {
+                    // File exists. Read it, parse the file to get the names of the
+                    // packs. (to look for them in .git/object/pack directory later)
+                    foreach (explode("\n", $packs) as $line) {
+                        // skip blank lines
+                        if (strlen(trim($line)) == 0) {
+                            continue;
+                        }
+                        // skip non pack lines
+                        if ($line[0] != 'P') {
+                            continue;
+                        }
+                        // parse names
+                        $pack_names[] = substr($line, 2);
+                    }
+                } else {
+                    // '.git/objects/info/packs' file can be missing
+                    // (atlease in mysGit)
+                    // File missing. May be we can look in the .git/object/pack
+                    // directory for all the .pack files and use that list of
+                    // files instead
+                    $it = new DirectoryIterator($git_folder . '/objects/pack');
+                    foreach ($it as $file_info) {
+                        $file_name = $file_info->getFilename();
+                        // if this is a .pack file
+                        if ($file_info->isFile()
+                            && substr($file_name, -5) == '.pack'
+                        ) {
+                            $pack_names[] = $file_name;
+                        }
+                    }
+                }
+                $hash = strtolower($hash);
+                foreach ($pack_names as $pack_name) {
+                    $index_name = str_replace('.pack', '.idx', $pack_name);
+
+                    // load index
+                    if (! $index_data = @file_get_contents($git_folder . '/objects/pack/' . $index_name)) {
+                        continue;
+                    }
+                    // check format
+                    if (substr($index_data, 0, 4) != "\377tOc") {
+                        continue;
+                    }
+                    // check version
+                    $version = unpack('N', substr($index_data, 4, 4));
+                    if ($version[1] != 2) {
+                        continue;
+                    }
+                    // parse fanout table
+                    $fanout = unpack("N*", substr($index_data, 8, 256 * 4));
+
+                    // find where we should search
+                    $firstbyte = intval(substr($hash, 0, 2), 16);
+                    // array is indexed from 1 and we need to get
+                    // previous entry for start
+                    if ($firstbyte == 0) {
+                        $start = 0;
+                    } else {
+                        $start = $fanout[$firstbyte];
+                    }
+                    $end = $fanout[$firstbyte + 1];
+
+                    // stupid linear search for our sha
+                    $position = $start;
+                    $found = false;
+                    $offset = 8 + (256 * 4);
+                    for ($position = $start; $position < $end; $position++) {
+                        $sha = strtolower(
+                            bin2hex(
+                                substr(
+                                    $index_data, $offset + ($position * 20), 20
+                                )
+                            )
+                        );
+                        if ($sha == $hash) {
+                            $found = true;
+                            break;
+                        }
+                    }
+                    if (! $found) {
+                        continue;
+                    }
+                    // read pack offset
+                    $offset = 8 + (256 * 4) + (24 * $fanout[256]);
+                    $pack_offset = unpack(
+                        'N', substr($index_data, $offset + ($position * 4), 4)
+                    );
+                    $pack_offset = $pack_offset[1];
+
+                    // open pack file
+                    $pack_file = fopen(
+                        $git_folder . '/objects/pack/' . $pack_name, 'rb'
+                    );
+                    if ($pack_file === false) {
+                        continue;
+                    }
+                    // seek to start
+                    fseek($pack_file, $pack_offset);
+
+                    // parse header
+                    $header = ord(fread($pack_file, 1));
+                    $type = ($header >> 4) & 7;
+                    $hasnext = ($header & 128) >> 7;
+                    $size = $header & 0xf;
+                    $offset = 4;
+
+                    while ($hasnext) {
+                        $byte = ord(fread($pack_file, 1));
+                        $size |= ($byte & 0x7f) << $offset;
+                        $hasnext = ($byte & 128) >> 7;
+                        $offset += 7;
+                    }
+
+                    // we care only about commit objects
+                    if ($type != 1) {
+                        continue;
+                    }
+
+                    // read data
+                    $commit = fread($pack_file, $size);
+                    $commit = gzuncompress($commit);
+                    $commit = explode("\n", $commit);
+                    $_SESSION['PMA_VERSION_COMMITDATA_' . $hash] = $commit;
+                    fclose($pack_file);
+                }
+            }
+        } else {
+            $commit = $_SESSION['PMA_VERSION_COMMITDATA_' . $hash];
+        }
+
+        // check if commit exists in Github
+        $is_remote_commit = false;
+        if ($commit !== false
+            && isset($_SESSION['PMA_VERSION_REMOTECOMMIT_' . $hash])
+        ) {
+            $is_remote_commit = $_SESSION['PMA_VERSION_REMOTECOMMIT_' . $hash];
+        } else {
+            $link = 'https://api.github.com/repos/phpmyadmin/phpmyadmin/git/commits/'
+                . $hash;
+            $is_found = $this->checkHTTP($link, !$commit);
+            switch($is_found) {
+            case false:
+                $is_remote_commit = false;
+                $_SESSION['PMA_VERSION_REMOTECOMMIT_' . $hash] = false;
+                break;
+            case null:
+                // no remote link for now, but don't cache this as Github is down
+                $is_remote_commit = false;
+                break;
+            default:
+                $is_remote_commit = true;
+                $_SESSION['PMA_VERSION_REMOTECOMMIT_' . $hash] = true;
+                if ($commit === false) {
+                    // if no local commit data, try loading from Github
+                    $commit_json = json_decode($is_found);
+                }
+                break;
+            }
+        }
+
+        $is_remote_branch = false;
+        if ($is_remote_commit && $branch !== false) {
+            // check if branch exists in Github
+            if (isset($_SESSION['PMA_VERSION_REMOTEBRANCH_' . $hash])) {
+                $is_remote_branch = $_SESSION['PMA_VERSION_REMOTEBRANCH_' . $hash];
+            } else {
+                $link = 'https://api.github.com/repos/phpmyadmin/phpmyadmin'
+                    . '/git/trees/' . $branch;
+                $is_found = $this->checkHTTP($link);
+                switch($is_found) {
+                case true:
+                    $is_remote_branch = true;
+                    $_SESSION['PMA_VERSION_REMOTEBRANCH_' . $hash] = true;
+                    break;
+                case false:
+                    $is_remote_branch = false;
+                    $_SESSION['PMA_VERSION_REMOTEBRANCH_' . $hash] = false;
+                    break;
+                case null:
+                    // no remote link for now, but don't cache this as Github is down
+                    $is_remote_branch = false;
+                    break;
+                }
+            }
+        }
+
+        if ($commit !== false) {
+            $author = array('name' => '', 'email' => '', 'date' => '');
+            $committer = array('name' => '', 'email' => '', 'date' => '');
+
+            do {
+                $dataline = array_shift($commit);
+                $datalinearr = explode(' ', $dataline, 2);
+                $linetype = $datalinearr[0];
+                if (in_array($linetype, array('author', 'committer'))) {
+                    $user = $datalinearr[1];
+                    preg_match('/([^<]+)<([^>]+)> ([0-9]+)( [^ ]+)?/', $user, $user);
+                    $user2 = array(
+                        'name' => trim($user[1]),
+                        'email' => trim($user[2]),
+                        'date' => date('Y-m-d H:i:s', $user[3]));
+                    if (isset($user[4])) {
+                        $user2['date'] .= $user[4];
+                    }
+                    $$linetype = $user2;
+                }
+            } while ($dataline != '');
+            $message = trim(implode(' ', $commit));
+
+        } elseif (isset($commit_json)) {
+            $author = array(
+                'name' => $commit_json->author->name,
+                'email' => $commit_json->author->email,
+                'date' => $commit_json->author->date);
+            $committer = array(
+                'name' => $commit_json->committer->name,
+                'email' => $commit_json->committer->email,
+                'date' => $commit_json->committer->date);
+            $message = trim($commit_json->message);
+        } else {
+            return;
+        }
+
+        $this->set('PMA_VERSION_GIT', 1);
+        $this->set('PMA_VERSION_GIT_COMMITHASH', $hash);
+        $this->set('PMA_VERSION_GIT_BRANCH', $branch);
+        $this->set('PMA_VERSION_GIT_MESSAGE', $message);
+        $this->set('PMA_VERSION_GIT_AUTHOR', $author);
+        $this->set('PMA_VERSION_GIT_COMMITTER', $committer);
+        $this->set('PMA_VERSION_GIT_ISREMOTECOMMIT', $is_remote_commit);
+        $this->set('PMA_VERSION_GIT_ISREMOTEBRANCH', $is_remote_branch);
+    }
+
+    /**
+     * Checks if given URL is 200 or 404, optionally returns data
+     *
+     * @param mixed   $link     curl link
+     * @param boolean $get_body whether to retrieve body of document
+     *
+     * @return test result or data
+     */
+    function checkHTTP($link, $get_body = false)
+    {
+        if (! function_exists('curl_init')) {
+            return null;
+        }
+        $ch = curl_init($link);
+        curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 0);
+        curl_setopt($ch, CURLOPT_HEADER, 1);
+        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
+        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
+        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
+        curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 5);
+        curl_setopt($ch, CURLOPT_USERAGENT, 'phpMyAdmin/' . PMA_VERSION);
+        curl_setopt($ch, CURLOPT_TIMEOUT, 5);
+        $data = @curl_exec($ch);
+        if ($data === false) {
+            return null;
+        }
+        $ok = 'HTTP/1.1 200 OK';
+        $notfound = 'HTTP/1.1 404 Not Found';
+        if (substr($data, 0, strlen($ok)) === $ok) {
+            return $get_body ? substr($data, strpos($data, "\r\n\r\n") + 4) : true;
+        } elseif (substr($data, 0, strlen($notfound)) === $notfound) {
+            return false;
+        }
+        return null;
+    }
+
+    /**
+     * loads default values from default source
+     *
+     * @return boolean     success
+     */
+    function loadDefaults()
+    {
+        $cfg = array();
+        if (! file_exists($this->default_source)) {
+            $this->error_config_default_file = true;
+            return false;
+        }
+        include $this->default_source;
+
+        $this->default_source_mtime = filemtime($this->default_source);
+
+        $this->default_server = $cfg['Servers'][1];
+        unset($cfg['Servers']);
+
+        $this->default = $cfg;
+        $this->settings = PMA_arrayMergeRecursive($this->settings, $cfg);
+
+        $this->error_config_default_file = false;
+
+        return true;
+    }
+
+    /**
+     * loads configuration from $source, usally the config file
+     * should be called on object creation
+     *
+     * @param string $source config file
+     *
+     * @return bool
+     */
+    function load($source = null)
+    {
+        $this->loadDefaults();
+
+        if (null !== $source) {
+            $this->setSource($source);
+        }
+
+        if (! $this->checkConfigSource()) {
+            return false;
+        }
+
+        $cfg = array();
+
+        /**
+         * Parses the configuration file, the eval is used here to avoid
+         * problems with trailing whitespace, what is often a problem.
+         */
+        $old_error_reporting = error_reporting(0);
+        $eval_result = eval('?' . '>' . trim(file_get_contents($this->getSource())));
+        error_reporting($old_error_reporting);
+
+        if ($eval_result === false) {
+            $this->error_config_file = true;
+        } else {
+            $this->error_config_file = false;
+            $this->source_mtime = filemtime($this->getSource());
+        }
+
+        /**
+         * Backward compatibility code
+         */
+        if (!empty($cfg['DefaultTabTable'])) {
+            $cfg['DefaultTabTable'] = str_replace(
+                '_properties',
+                '',
+                str_replace(
+                    'tbl_properties.php',
+                    'tbl_sql.php',
+                    $cfg['DefaultTabTable']
+                )
+            );
+        }
+        if (!empty($cfg['DefaultTabDatabase'])) {
+            $cfg['DefaultTabDatabase'] = str_replace(
+                '_details',
+                '',
+                str_replace(
+                    'db_details.php',
+                    'db_sql.php',
+                    $cfg['DefaultTabDatabase']
+                )
+            );
+        }
+
+        $this->settings = PMA_arrayMergeRecursive($this->settings, $cfg);
+        $this->checkPmaAbsoluteUri();
+        $this->checkFontsize();
+
+        // Handling of the collation must be done after merging of $cfg
+        // (from config.inc.php) so that $cfg['DefaultConnectionCollation']
+        // can have an effect. Note that the presence of collation
+        // information in a cookie has priority over what is defined
+        // in the default or user's config files.
+        /**
+         * @todo check validity of $_COOKIE['pma_collation_connection']
+         */
+        if (! empty($_COOKIE['pma_collation_connection'])) {
+            $this->set(
+                'collation_connection',
+                strip_tags($_COOKIE['pma_collation_connection'])
+            );
+        } else {
+            $this->set(
+                'collation_connection',
+                $this->get('DefaultConnectionCollation')
+            );
+        }
+        // Now, a collation information could come from REQUEST
+        // (an example of this: the collation selector in index.php)
+        // so the following handles the setting of collation_connection
+        // and later, in common.inc.php, the cookie will be set
+        // according to this.
+        $this->checkCollationConnection();
+
+        return true;
+    }
+
+    /**
+     * Loads user preferences and merges them with current config
+     * must be called after control connection has been estabilished
+     *
+     * @return boolean
+     */
+    function loadUserPreferences()
+    {
+        // index.php should load these settings, so that phpmyadmin.css.php
+        // will have everything avaiable in session cache
+        $server = isset($GLOBALS['server'])
+            ? $GLOBALS['server']
+            : (!empty($GLOBALS['cfg']['ServerDefault'])
+                ? $GLOBALS['cfg']['ServerDefault']
+                : 0);
+        $cache_key = 'server_' . $server;
+        if ($server > 0 && !defined('PMA_MINIMUM_COMMON')) {
+            $config_mtime = max($this->default_source_mtime, $this->source_mtime);
+            // cache user preferences, use database only when needed
+            if (! isset($_SESSION['cache'][$cache_key]['userprefs'])
+                || $_SESSION['cache'][$cache_key]['config_mtime'] < $config_mtime
+            ) {
+                // load required libraries
+                include_once './libraries/user_preferences.lib.php';
+                $prefs = PMA_loadUserprefs();
+                $_SESSION['cache'][$cache_key]['userprefs']
+                    = PMA_applyUserprefs($prefs['config_data']);
+                $_SESSION['cache'][$cache_key]['userprefs_mtime'] = $prefs['mtime'];
+                $_SESSION['cache'][$cache_key]['userprefs_type'] = $prefs['type'];
+                $_SESSION['cache'][$cache_key]['config_mtime'] = $config_mtime;
+            }
+        } elseif ($server == 0
+            || ! isset($_SESSION['cache'][$cache_key]['userprefs'])
+        ) {
+            $this->set('user_preferences', false);
+            return;
+        }
+        $config_data = $_SESSION['cache'][$cache_key]['userprefs'];
+        // type is 'db' or 'session'
+        $this->set(
+            'user_preferences',
+            $_SESSION['cache'][$cache_key]['userprefs_type']
+        );
+        $this->set(
+            'user_preferences_mtime',
+            $_SESSION['cache'][$cache_key]['userprefs_mtime']
+        );
+
+        // backup some settings
+        $org_fontsize = '';
+        if (isset($this->settings['fontsize'])) {
+            $org_fontsize = $this->settings['fontsize'];
+        }
+        // load config array
+        $this->settings = PMA_arrayMergeRecursive($this->settings, $config_data);
+        $GLOBALS['cfg'] = PMA_arrayMergeRecursive($GLOBALS['cfg'], $config_data);
+        if (defined('PMA_MINIMUM_COMMON')) {
+            return;
+        }
+
+        // settings below start really working on next page load, but
+        // changes are made only in index.php so everything is set when
+        // in frames
+
+        // save theme
+        $tmanager = $_SESSION['PMA_Theme_Manager'];
+        if ($tmanager->getThemeCookie() || isset($_REQUEST['set_theme'])) {
+            if ((! isset($config_data['ThemeDefault'])
+                && $tmanager->theme->getId() != 'original')
+                || isset($config_data['ThemeDefault'])
+                && $config_data['ThemeDefault'] != $tmanager->theme->getId()
+            ) {
+                // new theme was set in common.inc.php
+                $this->setUserValue(
+                    null,
+                    'ThemeDefault',
+                    $tmanager->theme->getId(),
+                    'original'
+                );
+            }
+        } else {
+            // no cookie - read default from settings
+            if ($this->settings['ThemeDefault'] != $tmanager->theme->getId()
+                && $tmanager->checkTheme($this->settings['ThemeDefault'])
+            ) {
+                $tmanager->setActiveTheme($this->settings['ThemeDefault']);
+                $tmanager->setThemeCookie();
+            }
+        }
+
+        // save font size
+        if ((! isset($config_data['fontsize'])
+            && $org_fontsize != '82%')
+            || isset($config_data['fontsize'])
+            && $org_fontsize != $config_data['fontsize']
+        ) {
+            $this->setUserValue(null, 'fontsize', $org_fontsize, '82%');
+        }
+
+        // save language
+        if (isset($_COOKIE['pma_lang']) || isset($_POST['lang'])) {
+            if ((! isset($config_data['lang'])
+                && $GLOBALS['lang'] != 'en')
+                || isset($config_data['lang'])
+                && $GLOBALS['lang'] != $config_data['lang']
+            ) {
+                $this->setUserValue(null, 'lang', $GLOBALS['lang'], 'en');
+            }
+        } else {
+            // read language from settings
+            if (isset($config_data['lang']) && PMA_langSet($config_data['lang'])) {
+                $this->setCookie('pma_lang', $GLOBALS['lang']);
+            }
+        }
+
+        // save connection collation
+        if (isset($_COOKIE['pma_collation_connection'])
+            || isset($_POST['collation_connection'])
+        ) {
+            if ((! isset($config_data['collation_connection'])
+                && $GLOBALS['collation_connection'] != 'utf8_general_ci')
+                || isset($config_data['collation_connection'])
+                && $GLOBALS['collation_connection'] != $config_data['collation_connection']
+            ) {
+                $this->setUserValue(
+                    null,
+                    'collation_connection',
+                    $GLOBALS['collation_connection'],
+                    'utf8_general_ci'
+                );
+            }
+        } else {
+            // read collation from settings
+            if (isset($config_data['collation_connection'])) {
+                $GLOBALS['collation_connection']
+                    = $config_data['collation_connection'];
+                $this->setCookie(
+                    'pma_collation_connection',
+                    $GLOBALS['collation_connection']
+                );
+            }
+        }
+    }
+
+    /**
+     * Sets config value which is stored in user preferences (if available)
+     * or in a cookie.
+     *
+     * If user preferences are not yet initialized, option is applied to
+     * global config and added to a update queue, which is processed
+     * by {@link loadUserPreferences()}
+     *
+     * @param string $cookie_name   can be null
+     * @param string $cfg_path      configuration path
+     * @param mixed  $new_cfg_value new value
+     * @param mixed  $default_value default value
+     *
+     * @return void
+     */
+    function setUserValue($cookie_name, $cfg_path, $new_cfg_value,
+        $default_value = null
+    ) {
+        // use permanent user preferences if possible
+        $prefs_type = $this->get('user_preferences');
+        if ($prefs_type) {
+            include_once './libraries/user_preferences.lib.php';
+            if ($default_value === null) {
+                $default_value = PMA_arrayRead($cfg_path, $this->default);
+            }
+            PMA_persistOption($cfg_path, $new_cfg_value, $default_value);
+        }
+        if ($prefs_type != 'db' && $cookie_name) {
+            // fall back to cookies
+            if ($default_value === null) {
+                $default_value = PMA_arrayRead($cfg_path, $this->settings);
+            }
+            $this->setCookie($cookie_name, $new_cfg_value, $default_value);
+        }
+        PMA_arrayWrite($cfg_path, $GLOBALS['cfg'], $new_cfg_value);
+        PMA_arrayWrite($cfg_path, $this->settings, $new_cfg_value);
+    }
+
+    /**
+     * Reads value stored by {@link setUserValue()}
+     *
+     * @param string $cookie_name cookie name
+     * @param mixed  $cfg_value   config value
+     *
+     * @return mixed
+     */
+    function getUserValue($cookie_name, $cfg_value)
+    {
+        $cookie_exists = isset($_COOKIE) && !empty($_COOKIE[$cookie_name]);
+        $prefs_type = $this->get('user_preferences');
+        if ($prefs_type == 'db') {
+            // permanent user preferences value exists, remove cookie
+            if ($cookie_exists) {
+                $this->removeCookie($cookie_name);
+            }
+        } else if ($cookie_exists) {
+            return $_COOKIE[$cookie_name];
+        }
+        // return value from $cfg array
+        return $cfg_value;
+    }
+
+    /**
+     * set source
+     *
+     * @param string $source source
+     *
+     * @return void
+     */
+    function setSource($source)
+    {
+        $this->source = trim($source);
+    }
+
+    /**
+     * check config source
+     *
+     * @return boolean whether source is valid or not
+     */
+    function checkConfigSource()
+    {
+        if (! $this->getSource()) {
+            // no configuration file set at all
+            return false;
+        }
+
+        if (! file_exists($this->getSource())) {
+            $this->source_mtime = 0;
+            return false;
+        }
+
+        if (! is_readable($this->getSource())) {
+            // manually check if file is readable
+            // might be bug #3059806 Supporting running from CIFS/Samba shares
+
+            $contents = false;
+            $handle = @fopen($this->getSource(), 'r');
+            if ($handle !== false) {
+                $contents = @fread($handle, 1); // reading 1 byte is enough to test
+                @fclose($handle);
+            }
+            if ($contents === false) {
+                $this->source_mtime = 0;
+                PMA_fatalError(
+                    sprintf(
+                        function_exists('__')
+                        ? __('Existing configuration file (%s) is not readable.')
+                        : 'Existing configuration file (%s) is not readable.',
+                        $this->getSource()
+                    )
+                );
+                return false;
+            }
+        }
+
+        return true;
+    }
+
+    /**
+     * verifies the permissions on config file (if asked by configuration)
+     * (must be called after config.inc.php has been merged)
+     *
+     * @return void
+     */
+    function checkPermissions()
+    {
+        // Check for permissions (on platforms that support it):
+        if ($this->get('CheckConfigurationPermissions')) {
+            $perms = @fileperms($this->getSource());
+            if (!($perms === false) && ($perms & 2)) {
+                // This check is normally done after loading configuration
+                $this->checkWebServerOs();
+                if ($this->get('PMA_IS_WINDOWS') == 0) {
+                    $this->source_mtime = 0;
+                    /* Gettext is possibly still not loaded */
+                    if (function_exists('__')) {
+                        $msg = __('Wrong permissions on configuration file, should not be world writable!');
+                    } else {
+                        $msg = 'Wrong permissions on configuration file, should not be world writable!';
+                    }
+                    PMA_fatalError($msg);
+                }
+            }
+        }
+    }
+
+    /**
+     * returns specific config setting
+     *
+     * @param string $setting config setting
+     *
+     * @return mixed value
+     */
+    function get($setting)
+    {
+        if (isset($this->settings[$setting])) {
+            return $this->settings[$setting];
+        }
+        return null;
+    }
+
+    /**
+     * sets configuration variable
+     *
+     * @param string $setting configuration option
+     * @param string $value   new value for configuration option
+     *
+     * @return void
+     */
+    function set($setting, $value)
+    {
+        if (! isset($this->settings[$setting])
+            || $this->settings[$setting] != $value
+        ) {
+            $this->settings[$setting] = $value;
+            $this->set_mtime = time();
+        }
+    }
+
+    /**
+     * returns source for current config
+     *
+     * @return string  config source
+     */
+    function getSource()
+    {
+        return $this->source;
+    }
+
+    /**
+     * returns a unique value to force a CSS reload if either the config
+     * or the theme changes
+     * must also check the pma_fontsize cookie in case there is no
+     * config file
+     *
+     * @return int Summary of unix timestamps and fontsize,
+     * to be unique on theme parameters change
+     */
+    function getThemeUniqueValue()
+    {
+        if (null !== $this->get('fontsize')) {
+            $fontsize = intval($this->get('fontsize'));
+        } elseif (isset($_COOKIE['pma_fontsize'])) {
+            $fontsize = intval($_COOKIE['pma_fontsize']);
+        } else {
+            $fontsize = 0;
+        }
+        return (
+            $fontsize +
+            $this->source_mtime +
+            $this->default_source_mtime +
+            $this->get('user_preferences_mtime') +
+            $_SESSION['PMA_Theme']->mtime_info +
+            $_SESSION['PMA_Theme']->filesize_info);
+    }
+
+    /**
+     * $cfg['PmaAbsoluteUri'] is a required directive else cookies won't be
+     * set properly and, depending on browsers, inserting or updating a
+     * record might fail
+     *
+     * @return bool
+     */
+    function checkPmaAbsoluteUri()
+    {
+        // Setup a default value to let the people and lazy sysadmins work anyway,
+        // they'll get an error if the autodetect code doesn't work
+        $pma_absolute_uri = $this->get('PmaAbsoluteUri');
+        $is_https = $this->detectHttps();
+
+        if (strlen($pma_absolute_uri) < 5) {
+            $url = array();
+
+            // If we don't have scheme, we didn't have full URL so we need to
+            // dig deeper
+            if (empty($url['scheme'])) {
+                // Scheme
+                if ($is_https) {
+                    $url['scheme'] = 'https';
+                } else {
+                    $url['scheme'] = 'http';
+                }
+
+                // Host and port
+                if (PMA_getenv('HTTP_HOST')) {
+                    // Prepend the scheme before using parse_url() since this
+                    // is not part of the RFC2616 Host request-header
+                    $parsed_url = parse_url(
+                        $url['scheme'] . '://' . PMA_getenv('HTTP_HOST')
+                    );
+                    if (!empty($parsed_url['host'])) {
+                        $url = $parsed_url;
+                    } else {
+                        $url['host'] = PMA_getenv('HTTP_HOST');
+                    }
+                } elseif (PMA_getenv('SERVER_NAME')) {
+                    $url['host'] = PMA_getenv('SERVER_NAME');
+                } else {
+                    $this->error_pma_uri = true;
+                    return false;
+                }
+
+                // If we didn't set port yet...
+                if (empty($url['port']) && PMA_getenv('SERVER_PORT')) {
+                    $url['port'] = PMA_getenv('SERVER_PORT');
+                }
+
+                // And finally the path could be already set from REQUEST_URI
+                if (empty($url['path'])) {
+                    $path = parse_url($GLOBALS['PMA_PHP_SELF']);
+                    $url['path'] = $path['path'];
+                }
+            }
+
+            // Make url from parts we have
+            $pma_absolute_uri = $url['scheme'] . '://';
+            // Was there user information?
+            if (!empty($url['user'])) {
+                $pma_absolute_uri .= $url['user'];
+                if (!empty($url['pass'])) {
+                    $pma_absolute_uri .= ':' . $url['pass'];
+                }
+                $pma_absolute_uri .= '@';
+            }
+            // Add hostname
+            $pma_absolute_uri .= $url['host'];
+            // Add port, if it not the default one
+            if (! empty($url['port'])
+                && (($url['scheme'] == 'http' && $url['port'] != 80)
+                || ($url['scheme'] == 'https' && $url['port'] != 443))
+            ) {
+                $pma_absolute_uri .= ':' . $url['port'];
+            }
+            // And finally path, without script name, the 'a' is there not to
+            // strip our directory, when path is only /pmadir/ without filename.
+            // Backslashes returned by Windows have to be changed.
+            // Only replace backslashes by forward slashes if on Windows,
+            // as the backslash could be valid on a non-Windows system.
+            $this->checkWebServerOs();
+            if ($this->get('PMA_IS_WINDOWS') == 1) {
+                $path = str_replace("\\", "/", dirname($url['path'] . 'a'));
+            } else {
+                $path = dirname($url['path'] . 'a');
+            }
+
+            // To work correctly within transformations overview:
+            if (defined('PMA_PATH_TO_BASEDIR') && PMA_PATH_TO_BASEDIR == '../../') {
+                if ($this->get('PMA_IS_WINDOWS') == 1) {
+                    $path = str_replace("\\", "/", dirname(dirname($path)));
+                } else {
+                    $path = dirname(dirname($path));
+                }
+            }
+
+            // PHP's dirname function would have returned a dot
+            // when $path contains no slash
+            if ($path == '.') {
+                $path = '';
+            }
+            // in vhost situations, there could be already an ending slash
+            if (substr($path, -1) != '/') {
+                $path .= '/';
+            }
+            $pma_absolute_uri .= $path;
+
+            // We used to display a warning if PmaAbsoluteUri wasn't set, but now
+            // the autodetect code works well enough that we don't display the
+            // warning at all. The user can still set PmaAbsoluteUri manually.
+
+        } else {
+            // The URI is specified, however users do often specify this
+            // wrongly, so we try to fix this.
+
+            // Adds a trailing slash et the end of the phpMyAdmin uri if it
+            // does not exist.
+            if (substr($pma_absolute_uri, -1) != '/') {
+                $pma_absolute_uri .= '/';
+            }
+
+            // If URI doesn't start with http:// or https://, we will add
+            // this.
+            if (substr($pma_absolute_uri, 0, 7) != 'http://'
+                && substr($pma_absolute_uri, 0, 8) != 'https://'
+            ) {
+                $pma_absolute_uri
+                    = ($is_https ? 'https' : 'http')
+                    . ':' . (substr($pma_absolute_uri, 0, 2) == '//' ? '' : '//')
+                    . $pma_absolute_uri;
+            }
+        }
+        $this->set('PmaAbsoluteUri', $pma_absolute_uri);
+    }
+
+    /**
+     * Converts currently used PmaAbsoluteUri to SSL based variant.
+     *
+     * @return String witch adjusted URI
+     */
+    function getSSLUri()
+    {
+        // grab current URL
+        $url = $this->get('PmaAbsoluteUri');
+        // Parse current URL
+        $parsed = parse_url($url);
+        // In case parsing has failed do stupid string replacement
+        if ($parsed === false) {
+            // Replace http protocol
+            return preg_replace('@^http:@', 'https:', $url);
+        }
+
+        // Reconstruct URL using parsed parts
+        if ($this->get('SSLPort')) {
+            $port_number = $this->get('SSLPort');
+        } else {
+            $port_number = 443;
+        }
+        return 'https://' . $parsed['host'] . ':' . $port_number . $parsed['path'];
+    }
+
+    /**
+     * check selected collation_connection
+     *
+     * @todo check validity of $_REQUEST['collation_connection']
+     *
+     * @return void
+     */
+    function checkCollationConnection()
+    {
+        if (! empty($_REQUEST['collation_connection'])) {
+            $this->set(
+                'collation_connection',
+                strip_tags($_REQUEST['collation_connection'])
+            );
+        }
+    }
+
+    /**
+     * checks for font size configuration, and sets font size as requested by user
+     *
+     * @return void
+     */
+    function checkFontsize()
+    {
+        $new_fontsize = '';
+
+        if (isset($_GET['set_fontsize'])) {
+            $new_fontsize = $_GET['set_fontsize'];
+        } elseif (isset($_POST['set_fontsize'])) {
+            $new_fontsize = $_POST['set_fontsize'];
+        } elseif (isset($_COOKIE['pma_fontsize'])) {
+            $new_fontsize = $_COOKIE['pma_fontsize'];
+        }
+
+        if (preg_match('/^[0-9.]+(px|em|pt|\%)$/', $new_fontsize)) {
+            $this->set('fontsize', $new_fontsize);
+        } elseif (! $this->get('fontsize')) {
+            // 80% would correspond to the default browser font size
+            // of 16, but use 82% to help read the monoface font
+            $this->set('fontsize', '82%');
+        }
+
+        $this->setCookie('pma_fontsize', $this->get('fontsize'), '82%');
+    }
+
+    /**
+     * checks if upload is enabled
+     *
+     * @return void
+     */
+    function checkUpload()
+    {
+        if (ini_get('file_uploads')) {
+            $this->set('enable_upload', true);
+            // if set "php_admin_value file_uploads Off" in httpd.conf
+            // ini_get() also returns the string "Off" in this case:
+            if ('off' == strtolower(ini_get('file_uploads'))) {
+                $this->set('enable_upload', false);
+            }
+        } else {
+            $this->set('enable_upload', false);
+        }
+    }
+
+    /**
+     * Maximum upload size as limited by PHP
+     * Used with permission from Moodle (http://moodle.org) by Martin Dougiamas
+     *
+     * this section generates $max_upload_size in bytes
+     *
+     * @return void
+     */
+    function checkUploadSize()
+    {
+        if (! $filesize = ini_get('upload_max_filesize')) {
+            $filesize = "5M";
+        }
+
+        if ($postsize = ini_get('post_max_size')) {
+            $this->set(
+                'max_upload_size',
+                min(PMA_getRealSize($filesize), PMA_getRealSize($postsize))
+            );
+        } else {
+            $this->set('max_upload_size', PMA_getRealSize($filesize));
+        }
+    }
+
+    /**
+     * check for https
+     *
+     * @return void
+     */
+    function checkIsHttps()
+    {
+        $this->set('is_https', $this->isHttps());
+    }
+
+    /**
+     * Checks if protocol is https
+     *
+     * This function checks if the https protocol is used in the PmaAbsoluteUri
+     * configuration setting, as opposed to detectHttps() which checks if the
+     * https protocol is used on the active connection.
+     *
+     * @return bool
+     */
+    public function isHttps()
+    {
+        static $is_https = null;
+
+        if (null !== $is_https) {
+            return $is_https;
+        }
+
+        $url = parse_url($this->get('PmaAbsoluteUri'));
+
+        if (isset($url['scheme']) && $url['scheme'] == 'https') {
+            $is_https = true;
+        } else {
+            $is_https = false;
+        }
+
+        return $is_https;
+    }
+
+    /**
+     * Detects whether https appears to be used.
+     *
+     * This function checks if the https protocol is used in the current connection
+     * with the webserver, based on environment variables.
+     * Please note that this just detects what we see, so
+     * it completely ignores things like reverse proxies.
+     *
+     * @return bool
+     */
+    function detectHttps()
+    {
+        $is_https = false;
+
+        $url = array();
+
+        // At first we try to parse REQUEST_URI, it might contain full URL,
+        if (PMA_getenv('REQUEST_URI')) {
+            // produces E_WARNING if it cannot get parsed, e.g. '/foobar:/'
+            $url = @parse_url(PMA_getenv('REQUEST_URI'));
+            if ($url === false) {
+                $url = array();
+            }
+        }
+
+        // If we don't have scheme, we didn't have full URL so we need to
+        // dig deeper
+        if (empty($url['scheme'])) {
+            // Scheme
+            if (PMA_getenv('HTTP_SCHEME')) {
+                $url['scheme'] = PMA_getenv('HTTP_SCHEME');
+            } elseif (PMA_getenv('HTTPS')
+                && strtolower(PMA_getenv('HTTPS')) == 'on'
+            ) {
+                $url['scheme'] = 'https';
+            } elseif (PMA_getenv('HTTP_X_FORWARDED_PROTO')) {
+                $url['scheme'] = strtolower(PMA_getenv('HTTP_X_FORWARDED_PROTO'));
+            } elseif (PMA_getenv('HTTP_FRONT_END_HTTPS')
+                && strtolower(PMA_getenv('HTTP_FRONT_END_HTTPS')) == 'on'
+            ) {
+                $url['scheme'] = 'https';
+            } else {
+                $url['scheme'] = 'http';
+            }
+        }
+
+        if (isset($url['scheme']) && $url['scheme'] == 'https') {
+            $is_https = true;
+        } else {
+            $is_https = false;
+        }
+
+        return $is_https;
+    }
+
+    /**
+     * detect correct cookie path
+     *
+     * @return void
+     */
+    function checkCookiePath()
+    {
+        $this->set('cookie_path', $this->getCookiePath());
+    }
+
+    /**
+     * Get cookie path
+     *
+     * @return string
+     */
+    public function getCookiePath()
+    {
+        static $cookie_path = null;
+
+        if (null !== $cookie_path && !defined('TESTSUITE')) {
+            return $cookie_path;
+        }
+
+        $parsed_url = parse_url($this->get('PmaAbsoluteUri'));
+
+        $cookie_path   = $parsed_url['path'];
+
+        return $cookie_path;
+    }
+
+    /**
+     * enables backward compatibility
+     *
+     * @return void
+     */
+    function enableBc()
+    {
+        $GLOBALS['cfg']             = $this->settings;
+        $GLOBALS['default_server']  = $this->default_server;
+        unset($this->default_server);
+        $GLOBALS['collation_connection'] = $this->get('collation_connection');
+        $GLOBALS['is_upload']       = $this->get('enable_upload');
+        $GLOBALS['max_upload_size'] = $this->get('max_upload_size');
+        $GLOBALS['cookie_path']     = $this->get('cookie_path');
+        $GLOBALS['is_https']        = $this->get('is_https');
+
+        $defines = array(
+            'PMA_VERSION',
+            'PMA_THEME_VERSION',
+            'PMA_THEME_GENERATION',
+            'PMA_PHP_STR_VERSION',
+            'PMA_PHP_INT_VERSION',
+            'PMA_IS_WINDOWS',
+            'PMA_IS_IIS',
+            'PMA_IS_GD2',
+            'PMA_USR_OS',
+            'PMA_USR_BROWSER_VER',
+            'PMA_USR_BROWSER_AGENT'
+            );
+
+        foreach ($defines as $define) {
+            if (! defined($define)) {
+                define($define, $this->get($define));
+            }
+        }
+    }
+
+    /**
+     * returns options for font size selection
+     *
+     * @param string $current_size current selected font size with unit
+     *
+     * @return array selectable font sizes
+     *
+     * @static
+     */
+    static protected function getFontsizeOptions($current_size = '82%')
+    {
+        $unit = preg_replace('/[0-9.]*/', '', $current_size);
+        $value = preg_replace('/[^0-9.]*/', '', $current_size);
+
+        $factors = array();
+        $options = array();
+        $options["$value"] = $value . $unit;
+
+        if ($unit === '%') {
+            $factors[] = 1;
+            $factors[] = 5;
+            $factors[] = 10;
+        } elseif ($unit === 'em') {
+            $factors[] = 0.05;
+            $factors[] = 0.2;
+            $factors[] = 1;
+        } elseif ($unit === 'pt') {
+            $factors[] = 0.5;
+            $factors[] = 2;
+        } elseif ($unit === 'px') {
+            $factors[] = 1;
+            $factors[] = 5;
+            $factors[] = 10;
+        } else {
+            //unknown font size unit
+            $factors[] = 0.05;
+            $factors[] = 0.2;
+            $factors[] = 1;
+            $factors[] = 5;
+            $factors[] = 10;
+        }
+
+        foreach ($factors as $key => $factor) {
+            $option_inc = $value + $factor;
+            $option_dec = $value - $factor;
+            while (count($options) < 21) {
+                $options["$option_inc"] = $option_inc . $unit;
+                if ($option_dec > $factors[0]) {
+                    $options["$option_dec"] = $option_dec . $unit;
+                }
+                $option_inc += $factor;
+                $option_dec -= $factor;
+                if (isset($factors[$key + 1])
+                    && $option_inc >= $value + $factors[$key + 1]
+                ) {
+                    break;
+                }
+            }
+        }
+        ksort($options);
+        return $options;
+    }
+
+    /**
+     * returns html selectbox for font sizes
+     *
+     * @static
+     *
+     * @return string html selectbox
+     */
+    static protected function getFontsizeSelection()
+    {
+        $current_size = $GLOBALS['PMA_Config']->get('fontsize');
+        // for the case when there is no config file (this is supported)
+        if (empty($current_size)) {
+            if (isset($_COOKIE['pma_fontsize'])) {
+                $current_size = $_COOKIE['pma_fontsize'];
+            } else {
+                $current_size = '82%';
+            }
+        }
+        $options = PMA_Config::getFontsizeOptions($current_size);
+
+        $return = '<label for="select_fontsize">' . __('Font size')
+            . ':</label>' . "\n"
+            . '<select name="set_fontsize" id="select_fontsize"'
+            . ' class="autosubmit">' . "\n";
+        foreach ($options as $option) {
+            $return .= '<option value="' . $option . '"';
+            if ($option == $current_size) {
+                $return .= ' selected="selected"';
+            }
+            $return .= '>' . $option . '</option>' . "\n";
+        }
+        $return .= '</select>';
+
+        return $return;
+    }
+
+    /**
+     * return complete font size selection form
+     *
+     * @static
+     *
+     * @return string html selectbox
+     */
+    static public function getFontsizeForm()
+    {
+        return '<form name="form_fontsize_selection" id="form_fontsize_selection"'
+            . ' method="get" action="index.php" class="disableAjax">' . "\n"
+            . PMA_generate_common_hidden_inputs() . "\n"
+            . PMA_Config::getFontsizeSelection() . "\n"
+            . '</form>';
+    }
+
+    /**
+     * removes cookie
+     *
+     * @param string $cookie name of cookie to remove
+     *
+     * @return boolean result of setcookie()
+     */
+    function removeCookie($cookie)
+    {
+        if (defined('TESTSUITE')) {
+            if (isset($_COOKIE[$cookie])) {
+                unset($_COOKIE[$cookie]);
+            }
+            return true;
+        }
+        return setcookie(
+            $cookie,
+            '',
+            time() - 3600,
+            $this->getCookiePath(),
+            '',
+            $this->isHttps()
+        );
+    }
+
+    /**
+     * sets cookie if value is different from current cookie value,
+     * or removes if value is equal to default
+     *
+     * @param string $cookie   name of cookie to remove
+     * @param mixed  $value    new cookie value
+     * @param string $default  default value
+     * @param int    $validity validity of cookie in seconds (default is one month)
+     * @param bool   $httponly whether cookie is only for HTTP (and not for scripts)
+     *
+     * @return boolean result of setcookie()
+     */
+    function setCookie($cookie, $value, $default = null, $validity = null,
+        $httponly = true
+    ) {
+        if (strlen($value) && null !== $default && $value === $default) {
+            // default value is used
+            if (isset($_COOKIE[$cookie])) {
+                // remove cookie
+                return $this->removeCookie($cookie);
+            }
+            return false;
+        }
+
+        if (! strlen($value) && isset($_COOKIE[$cookie])) {
+            // remove cookie, value is empty
+            return $this->removeCookie($cookie);
+        }
+
+        if (! isset($_COOKIE[$cookie]) || $_COOKIE[$cookie] !== $value) {
+            // set cookie with new value
+            /* Calculate cookie validity */
+            if ($validity === null) {
+                $validity = time() + 2592000;
+            } elseif ($validity == 0) {
+                $validity = 0;
+            } else {
+                $validity = time() + $validity;
+            }
+            if (defined('TESTSUITE')) {
+                $_COOKIE[$cookie] = $value;
+                return true;
+            }
+            return setcookie(
+                $cookie,
+                $value,
+                $validity,
+                $this->getCookiePath(),
+                '',
+                $this->isHttps(),
+                $httponly
+            );
+        }
+
+        // cookie has already $value as value
+        return true;
+    }
+}
+?>
diff --git a/phpmyadmin/libraries/DBQbe.class.php b/phpmyadmin/libraries/DBQbe.class.php
new file mode 100644
index 0000000..6213dd7
--- /dev/null
+++ b/phpmyadmin/libraries/DBQbe.class.php
@@ -0,0 +1,1343 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * Handles DB QBE search
+ *
+ * @package PhpMyAdmin
+ */
+if (! defined('PHPMYADMIN')) {
+    exit;
+}
+
+/**
+ * Class to handle database QBE search
+ *
+ * @package PhpMyAdmin
+ */
+class PMA_DbQbe
+{
+    /**
+     * Database name
+     *
+     * @access private
+     * @var string
+     */
+    private $_db;
+    /**
+     * Table Names (selected/non-selected)
+     *
+     * @access private
+     * @var array
+     */
+    private $_criteriaTables;
+    /**
+     * Column Names
+     *
+     * @access private
+     * @var array
+     */
+    private $_columnNames;
+    /**
+     * Number of columns
+     *
+     * @access private
+     * @var integer
+     */
+    private $_criteria_column_count;
+    /**
+     * Number of Rows
+     *
+     * @access private
+     * @var integer
+     */
+    private $_criteria_row_count;
+    /**
+     * Whether to insert a new column
+     *
+     * @access private
+     * @var array
+     */
+    private $_criteriaColumnInsert;
+    /**
+     * Whether to delete a column
+     *
+     * @access private
+     * @var array
+     */
+    private $_criteriaColumnDelete;
+    /**
+     * Whether to insert a new row
+     *
+     * @access private
+     * @var array
+     */
+    private $_criteriaRowInsert;
+    /**
+     * Already set criteria values
+     *
+     * @access private
+     * @var array
+     */
+    private $_criteria;
+    /**
+     * Previously set criteria values
+     *
+     * @access private
+     * @var array
+     */
+    private $_prev_criteria;
+    /**
+     * AND/OR relation b/w criteria columns
+     *
+     * @access private
+     * @var array
+     */
+    private $_criteriaAndOrColumn;
+    /**
+     * AND/OR relation b/w criteria rows
+     *
+     * @access private
+     * @var array
+     */
+    private $_criteriaAndOrRow;
+    /**
+     * Larget width of a column
+     *
+     * @access private
+     * @var string
+     */
+    private $_realwidth;
+    /**
+     * Minimum width of a column
+     *
+     * @access private
+     * @var string
+     */
+    private $_form_column_width;
+    /**
+     * Current criteria field
+     *
+     * @access private
+     * @var array
+     */
+    private $_curField;
+    /**
+     * Current criteria Sort options
+     *
+     * @access private
+     * @var array
+     */
+    private $_curSort;
+    /**
+     * Current criteria Show options
+     *
+     * @access private
+     * @var array
+     */
+    private $_curShow;
+    /**
+     * Current criteria values
+     *
+     * @access private
+     * @var array
+     */
+    private $_curCriteria;
+    /**
+     * Current criteria AND/OR column realtions
+     *
+     * @access private
+     * @var array
+     */
+    private $_curAndOrCol;
+    /**
+     * New column count in case of add/delete
+     *
+     * @access private
+     * @var integer
+     */
+    private $_new_column_count;
+    /**
+     * New row count in case of add/delete
+     *
+     * @access private
+     * @var integer
+     */
+    private $_new_row_count;
+
+    /**
+     * Public Constructor
+     *
+     * @param string $db Database name
+     */
+    public function __construct($db)
+    {
+        $this->_db = $db;
+        // Sets criteria parameters
+        $this->_setSearchParams();
+        $this->_setCriteriaTablesAndColumns();
+    }
+
+    /**
+     * Sets search parameters
+     *
+     * @return void
+     */
+    private function _setSearchParams()
+    {
+        // sets column count
+        $criteriaColumnCount = PMA_ifSetOr(
+            $_REQUEST['criteriaColumnCount'],
+            3,
+            'numeric'
+        );
+        $criteriaColumnAdd = PMA_ifSetOr(
+            $_REQUEST['criteriaColumnAdd'],
+            0,
+            'numeric'
+        );
+        $this->_criteria_column_count = max(
+            $criteriaColumnCount + $criteriaColumnAdd,
+            0
+        );
+
+        // sets row count
+        $rows = PMA_ifSetOr($_REQUEST['rows'],    0, 'numeric');
+        $criteriaRowAdd = PMA_ifSetOr($_REQUEST['criteriaRowAdd'], 0, 'numeric');
+        $this->_criteria_row_count = max($rows + $criteriaRowAdd, 0);
+
+        $this->_criteriaColumnInsert = PMA_ifSetOr(
+            $_REQUEST['criteriaColumnInsert'],
+            null,
+            'array'
+        );
+        $this->_criteriaColumnDelete = PMA_ifSetOr(
+            $_REQUEST['criteriaColumnDelete'],
+            null,
+            'array'
+        );
+
+        $this->_prev_criteria = isset($_REQUEST['prev_criteria'])
+            ? $_REQUEST['prev_criteria']
+            : array();
+        $this->_criteria = isset($_REQUEST['criteria'])
+            ? $_REQUEST['criteria']
+            : array_fill(0, $criteriaColumnCount, '');
+
+        $this->_criteriaRowInsert = isset($_REQUEST['criteriaRowInsert'])
+            ? $_REQUEST['criteriaRowInsert']
+            : array_fill(0, $criteriaColumnCount, '');
+        $this->_criteriaRowDelete = isset($_REQUEST['criteriaRowDelete'])
+            ? $_REQUEST['criteriaRowDelete']
+            : array_fill(0, $criteriaColumnCount, '');
+        $this->_criteriaAndOrRow = isset($_REQUEST['criteriaAndOrRow'])
+            ? $_REQUEST['criteriaAndOrRow']
+            : array_fill(0, $criteriaColumnCount, '');
+        $this->_criteriaAndOrColumn = isset($_REQUEST['criteriaAndOrColumn'])
+            ? $_REQUEST['criteriaAndOrColumn']
+            : array_fill(0, $criteriaColumnCount, '');
+        // sets minimum width
+        $this->_form_column_width = 12;
+        $this->_curField = array();
+        $this->_curSort = array();
+        $this->_curShow = array();
+        $this->_curCriteria = array();
+        $this->_curAndOrRow = array();
+        $this->_curAndOrCol = array();
+    }
+
+    /**
+     * Sets criteria tables and columns
+     *
+     * @return void
+     */
+    private function _setCriteriaTablesAndColumns()
+    {
+        // The tables list sent by a previously submitted form
+        if (PMA_isValid($_REQUEST['TableList'], 'array')) {
+            foreach ($_REQUEST['TableList'] as $each_table) {
+                $this->_criteriaTables[$each_table] = ' selected="selected"';
+            }
+        } // end if
+        $all_tables = PMA_DBI_query(
+            'SHOW TABLES FROM ' . PMA_Util::backquote($this->_db) . ';',
+            null,
+            PMA_DBI_QUERY_STORE
+        );
+        $all_tables_count = PMA_DBI_num_rows($all_tables);
+        if (0 == $all_tables_count) {
+            PMA_Message::error(__('No tables found in database.'))->display();
+            exit;
+        }
+        // The tables list gets from MySQL
+        while (list($table) = PMA_DBI_fetch_row($all_tables)) {
+            $columns = PMA_DBI_get_columns($this->_db, $table);
+
+            if (empty($this->_criteriaTables[$table])
+                && ! empty($_REQUEST['TableList'])
+            ) {
+                $this->_criteriaTables[$table] = '';
+            } else {
+                $this->_criteriaTables[$table] = ' selected="selected"';
+            } //  end if
+
+            // The fields list per selected tables
+            if ($this->_criteriaTables[$table] == ' selected="selected"') {
+                $each_table = PMA_Util::backquote($table);
+                $this->_columnNames[]  = $each_table . '.*';
+                foreach ($columns as $each_column) {
+                    $each_column = $each_table . '.'
+                        . PMA_Util::backquote($each_column['Field']);
+                    $this->_columnNames[] = $each_column;
+                    // increase the width if necessary
+                    $this->_form_column_width = max(
+                        strlen($each_column),
+                        $this->_form_column_width
+                    );
+                } // end foreach
+            } // end if
+        } // end while
+        PMA_DBI_free_result($all_tables);
+
+        // sets the largest width found
+        $this->_realwidth = $this->_form_column_width . 'ex';
+    }
+    /**
+     * Provides select options list containing column names
+     *
+     * @param integer $column_number Column Number (0,1,2) or more
+     * @param string  $selected      Selected criteria column name
+     *
+     * @return HTML for select options
+     */
+    private function _showColumnSelectCell($column_number, $selected = '')
+    {
+        $html_output = '';
+        $html_output .= '<td class="center">';
+        $html_output .= '<select name="criteriaColumn[' . $column_number . ']" size="1">';
+        $html_output .= '<option value=""> </option>';
+        foreach ($this->_columnNames as $column) {
+            $html_output .= '<option value="' . htmlspecialchars($column) . '"'
+                . (($column === $selected) ? ' selected="selected"' : '') . '>'
+                . str_replace(' ', ' ', htmlspecialchars($column))
+                . '</option>';
+        }
+        $html_output .= '</select>';
+        $html_output .= '</td>';
+        return $html_output;
+    }
+
+    /**
+     * Provides select options list containing sort options (ASC/DESC)
+     *
+     * @param integer $column_number Column Number (0,1,2) or more
+     * @param string  $asc_selected  Selected criteria 'Ascending'
+     * @param string  $desc_selected Selected criteria 'Descending'
+     *
+     * @return HTML for select options
+     */
+    private function _getSortSelectCell($column_number, $asc_selected = '',
+        $desc_selected = ''
+    ) {
+        $html_output = '<td class="center">';
+        $html_output .= '<select style="width: ' . $this->_realwidth
+            . '" name="criteriaSort[' . $column_number . ']" size="1">';
+        $html_output .= '<option value=""> </option>';
+        $html_output .= '<option value="ASC"' . $asc_selected . '>'
+            . __('Ascending')
+            . '</option>';
+        $html_output .= '<option value="DESC"' . $desc_selected . '>'
+            . __('Descending')
+            . '</option>';
+        $html_output .= '</select>';
+        $html_output .= '</td>';
+        return $html_output;
+    }
+
+    /**
+     * Provides search form's row containing column select options
+     *
+     * @return HTML for search table's row
+     */
+    private function _getColumnNamesRow()
+    {
+        $html_output = '<tr class="odd noclick">';
+        $html_output .= '<th>' . __('Column') . ':</th>';
+        $new_column_count = 0;
+        for ($column_index = 0; $column_index < $this->_criteria_column_count; $column_index++) {
+            if (isset($this->_criteriaColumnInsert[$column_index])
+                && $this->_criteriaColumnInsert[$column_index] == 'on'
+            ) {
+                $html_output .= $this->_showColumnSelectCell(
+                    $new_column_count
+                );
+                $new_column_count++;
+            }
+            if (! empty($this->_criteriaColumnDelete)
+                && isset($this->_criteriaColumnDelete[$column_index])
+                && $this->_criteriaColumnDelete[$column_index] == 'on'
+            ) {
+                continue;
+            }
+            $selected = '';
+            if (isset($_REQUEST['criteriaColumn'][$column_index])) {
+                $selected = $_REQUEST['criteriaColumn'][$column_index];
+                $this->_curField[$new_column_count]
+                    = $_REQUEST['criteriaColumn'][$column_index];
+            }
+            $html_output .= $this->_showColumnSelectCell(
+                $new_column_count,
+                $selected
+            );
+            $new_column_count++;
+        } // end for
+        $this->_new_column_count = $new_column_count;
+        $html_output .= '</tr>';
+        return $html_output;
+    }
+
+    /**
+     * Provides search form's row containing sort(ASC/DESC) select options
+     *
+     * @return HTML for search table's row
+     */
+    private function _getSortRow()
+    {
+        $html_output = '<tr class="even noclick">';
+        $html_output .= '<th>' . __('Sort') . ':</th>';
+        $new_column_count = 0;
+        for ($column_index = 0; $column_index < $this->_criteria_column_count; $column_index++) {
+            if (! empty($this->_criteriaColumnInsert)
+                && isset($this->_criteriaColumnInsert[$column_index])
+                && $this->_criteriaColumnInsert[$column_index] == 'on'
+            ) {
+                $html_output .= $this->_getSortSelectCell($new_column_count);
+                $new_column_count++;
+            } // end if
+
+            if (! empty($this->_criteriaColumnDelete)
+                && isset($this->_criteriaColumnDelete[$column_index])
+                && $this->_criteriaColumnDelete[$column_index] == 'on'
+            ) {
+                continue;
+            }
+            // If they have chosen all fields using the * selector,
+            // then sorting is not available, Fix for Bug #570698
+            if (isset($_REQUEST['criteriaSort'][$column_index])
+                && isset($_REQUEST['criteriaColumn'][$column_index])
+                && substr($_REQUEST['criteriaColumn'][$column_index], -2) == '.*'
+            ) {
+                $_REQUEST['criteriaSort'][$column_index] = '';
+            } //end if
+            // Set asc_selected
+            if (isset($_REQUEST['criteriaSort'][$column_index])
+                && $_REQUEST['criteriaSort'][$column_index] == 'ASC'
+            ) {
+                $this->_curSort[$new_column_count]
+                    = $_REQUEST['criteriaSort'][$column_index];
+                $asc_selected = ' selected="selected"';
+            } else {
+                $asc_selected = '';
+            } // end if
+            // Set desc selected
+            if (isset($_REQUEST['criteriaSort'][$column_index])
+                && $_REQUEST['criteriaSort'][$column_index] == 'DESC'
+            ) {
+                $this->_curSort[$new_column_count]
+                    = $_REQUEST['criteriaSort'][$column_index];
+                $desc_selected = ' selected="selected"';
+            } else {
+                $desc_selected = '';
+            } // end if
+            $html_output .= $this->_getSortSelectCell(
+                $new_column_count, $asc_selected, $desc_selected
+            );
+            $new_column_count++;
+        } // end for
+        $html_output .= '</tr>';
+        return $html_output;
+    }
+
+    /**
+     * Provides search form's row containing SHOW checkboxes
+     *
+     * @return HTML for search table's row
+     */
+    private function _getShowRow()
+    {
+        $html_output = '<tr class="odd noclick">';
+        $html_output .= '<th>' . __('Show') . ':</th>';
+        $new_column_count = 0;
+        for ($column_index = 0; $column_index < $this->_criteria_column_count; $column_index++) {
+            if (! empty($this->_criteriaColumnInsert)
+                && isset($this->_criteriaColumnInsert[$column_index])
+                && $this->_criteriaColumnInsert[$column_index] == 'on'
+            ) {
+                $html_output .= '<td class="center">';
+                $html_output .= '<input type="checkbox"'
+                    . ' name="criteriaShow[' . $new_column_count . ']" />';
+                $html_output .= '</td>';
+                $new_column_count++;
+            } // end if
+            if (! empty($this->_criteriaColumnDelete)
+                && isset($this->_criteriaColumnDelete[$column_index])
+                && $this->_criteriaColumnDelete[$column_index] == 'on'
+            ) {
+                continue;
+            }
+            if (isset($_REQUEST['criteriaShow'][$column_index])) {
+                $checked_options = ' checked="checked"';
+                $this->_curShow[$new_column_count]
+                    = $_REQUEST['criteriaShow'][$column_index];
+            } else {
+                $checked_options = '';
+            }
+            $html_output .= '<td class="center">';
+            $html_output .= '<input type="checkbox"'
+                . ' name="criteriaShow[' . $new_column_count . ']"'
+                . $checked_options . ' />';
+            $html_output .= '</td>';
+            $new_column_count++;
+        } // end for
+        $html_output .= '</tr>';
+        return $html_output;
+    }
+
+    /**
+     * Provides search form's row containing criteria Inputboxes
+     *
+     * @return HTML for search table's row
+     */
+    private function _getCriteriaInputboxRow()
+    {
+        $html_output = '<tr class="even noclick">';
+        $html_output .= '<th>' . __('Criteria') . ':</th>';
+        $new_column_count = 0;
+        for ($column_index = 0; $column_index < $this->_criteria_column_count; $column_index++) {
+            if (! empty($this->_criteriaColumnInsert)
+                && isset($this->_criteriaColumnInsert[$column_index])
+                && $this->_criteriaColumnInsert[$column_index] == 'on'
+            ) {
+                $html_output .= '<td class="center">';
+                $html_output .= '<input type="text"'
+                    . ' name="criteria[' . $new_column_count . ']"'
+                    . ' value=""'
+                    . ' class="textfield"'
+                    . ' style="width: ' . $this->_realwidth . '"'
+                    . ' size="20" />';
+                $html_output .= '</td>';
+                $new_column_count++;
+            } // end if
+            if (! empty($this->_criteriaColumnDelete)
+                && isset($this->_criteriaColumnDelete[$column_index])
+                && $this->_criteriaColumnDelete[$column_index] == 'on'
+            ) {
+                continue;
+            }
+            if (isset($this->_criteria[$column_index])) {
+                $tmp_criteria = $this->_criteria[$column_index];
+            }
+            if ((empty($this->_prev_criteria)
+                || ! isset($this->_prev_criteria[$column_index]))
+                || $this->_prev_criteria[$column_index] != htmlspecialchars($tmp_criteria)
+            ) {
+                $this->_curCriteria[$new_column_count] = $tmp_criteria;
+            } else {
+                $this->_curCriteria[$new_column_count]
+                    = $this->_prev_criteria[$column_index];
+            }
+            $html_output .= '<td class="center">';
+            $html_output .= '<input type="hidden"'
+                . ' name="prev_criteria[' . $new_column_count . ']"'
+                . ' value="' . htmlspecialchars($this->_curCriteria[$new_column_count]) . '" />';
+            $html_output .= '<input type="text"'
+                . ' name="criteria[' . $new_column_count . ']"'
+                . ' value="' . htmlspecialchars($tmp_criteria) . '"'
+                . ' class="textfield"'
+                . ' style="width: ' . $this->_realwidth . '"'
+                . ' size="20" />';
+            $html_output .= '</td>';
+            $new_column_count++;
+        } // end for
+        $html_output .= '</tr>';
+        return $html_output;
+    }
+
+    /**
+     * Provides footer options for adding/deleting row/columns
+     *
+     * @param string $type Whether row or column
+     *
+     * @return HTML for footer options
+     */
+    private function _getFootersOptions($type)
+    {
+        $html_output = '<div class="floatleft">';
+        $html_output .= (($type == 'row')
+            ? __('Add/Delete criteria rows') : __('Add/Delete columns'));
+        $html_output .= ':<select size="1" name="'
+            . (($type == 'row') ? 'criteriaRowAdd' : 'criteriaColumnAdd') . '">';
+        $html_output .= '<option value="-3">-3</option>';
+        $html_output .= '<option value="-2">-2</option>';
+        $html_output .= '<option value="-1">-1</option>';
+        $html_output .= '<option value="0" selected="selected">0</option>';
+        $html_output .= '<option value="1">1</option>';
+        $html_output .= '<option value="2">2</option>';
+        $html_output .= '<option value="3">3</option>';
+        $html_output .= '</select>';
+        $html_output .= '</div>';
+        return $html_output;
+    }
+
+    /**
+     * Provides search form table's footer options
+     *
+     * @return HTML for table footer
+     */
+    private function _getTableFooters()
+    {
+        $html_output = '<fieldset class="tblFooters">';
+        $html_output .= $this->_getFootersOptions("row");
+        $html_output .= $this->_getFootersOptions("column");
+        $html_output .= '<div class="floatleft">';
+        $html_output .= '<input type="submit" name="modify"'
+            . 'value="' . __('Update Query') . '" />';
+        $html_output .= '</div>';
+        $html_output .= '</fieldset>';
+        return $html_output;
+    }
+
+    /**
+     * Provides a select list of database tables
+     *
+     * @return HTML for table select list
+     */
+    private function _getTablesList()
+    {
+        $html_output = '<div class="floatleft">';
+        $html_output .= '<fieldset>';
+        $html_output .= '<legend>' . __('Use Tables') . '</legend>';
+        // Build the options list for each table name
+        $options = '';
+        $numTableListOptions = 0;
+        foreach ($this->_criteriaTables as $key => $val) {
+            $options .= '<option value="' . htmlspecialchars($key) . '"' . $val . '>'
+                . (str_replace(' ', ' ', htmlspecialchars($key))) . '</option>';
+            $numTableListOptions++;
+        }
+        $html_output .= '<select name="TableList[]"'
+            . ' multiple="multiple" id="listTable"'
+            . ' size="' . (($numTableListOptions > 30) ? '15' : '7') . '">';
+        $html_output .= $options;
+        $html_output .= '</select>';
+        $html_output .= '</fieldset>';
+        $html_output .= '<fieldset class="tblFooters">';
+        $html_output .= '<input type="submit" name="modify" value="'
+            . __('Update Query') . '" />';
+        $html_output .= '</fieldset>';
+        $html_output .= '</div>';
+        return $html_output;
+    }
+
+    /**
+     * Provides And/Or modification cell along with Insert/Delete options
+     * (For modifying search form's table columns)
+     *
+     * @param integer $column_number Column Number (0,1,2) or more
+     * @param array   $selected      Selected criteria column name
+     *
+     * @return HTML for modification cell
+     */
+    private function _getAndOrColCell($column_number, $selected = null)
+    {
+        $html_output = '<td class="center">';
+        $html_output .= '<strong>' . __('Or') . ':</strong>';
+        $html_output .= '<input type="radio"'
+            . ' name="criteriaAndOrColumn[' . $column_number . ']"'
+            . ' value="or"' . $selected['or'] . ' />';
+        $html_output .= '  <strong>' . __('And') . ':</strong>';
+        $html_output .= '<input type="radio"'
+            . ' name="criteriaAndOrColumn[' . $column_number . ']"'
+            . ' value="and"' . $selected['and'] . ' />';
+        $html_output .= '<br />' . __('Ins');
+        $html_output .= '<input type="checkbox"'
+            . ' name="criteriaColumnInsert[' . $column_number . ']" />';
+        $html_output .= '  ' . __('Del');
+        $html_output .= '<input type="checkbox"'
+            . ' name="criteriaColumnDelete[' . $column_number . ']" />';
+        $html_output .= '</td>';
+        return $html_output;
+    }
+
+    /**
+     * Provides search form's row containing column modifications options
+     * (For modifying search form's table columns)
+     *
+     * @return HTML for search table's row
+     */
+    private function _getModifyColumnsRow()
+    {
+        $html_output = '<tr class="even noclick">';
+        $html_output .= '<th>' . __('Modify') . ':</th>';
+        $new_column_count = 0;
+        for ($column_index = 0; $column_index < $this->_criteria_column_count; $column_index++) {
+            if (! empty($this->_criteriaColumnInsert)
+                && isset($this->_criteriaColumnInsert[$column_index])
+                && $this->_criteriaColumnInsert[$column_index] == 'on'
+            ) {
+                $html_output .= $this->_getAndOrColCell($new_column_count);
+                $new_column_count++;
+            } // end if
+
+            if (! empty($this->_criteriaColumnDelete)
+                && isset($this->_criteriaColumnDelete[$column_index])
+                && $this->_criteriaColumnDelete[$column_index] == 'on'
+            ) {
+                continue;
+            }
+
+            if (isset($this->_criteriaAndOrColumn[$column_index])) {
+                $this->_curAndOrCol[$new_column_count]
+                    = $this->_criteriaAndOrColumn[$column_index];
+            }
+            if (isset($this->_criteriaAndOrColumn[$column_index])
+                && $this->_criteriaAndOrColumn[$column_index] == 'or'
+            ) {
+                $checked_options['or']  = ' checked="checked"';
+                $checked_options['and'] = '';
+            } else {
+                $checked_options['and'] = ' checked="checked"';
+                $checked_options['or']  = '';
+            }
+            $html_output .= $this->_getAndOrColCell(
+                $new_column_count,
+                $checked_options
+            );
+            $new_column_count++;
+        } // end for
+        $html_output .= '</tr>';
+        return $html_output;
+    }
+
+    /**
+     * Provides Insert/Delete options for criteria inputbox
+     * with AND/OR relationship modification options
+     *
+     * @param integer $row_index       Number of criteria row
+     * @param string  $checked_options If checked
+     *
+     * @return HTML
+     */
+    private function _getInsDelAndOrCell($row_index, $checked_options)
+    {
+        $html_output = '<td class="' . $GLOBALS['cell_align_right'] . ' nowrap">';
+        $html_output .= '<!-- Row controls -->';
+        $html_output .= '<table class="nospacing nopadding">';
+        $html_output .= '<tr>';
+        $html_output .= '<td class="' . $GLOBALS['cell_align_right'] . ' nowrap">';
+        $html_output .= '<small>' . __('Ins') . ':</small>';
+        $html_output .= '<input type="checkbox"'
+            . ' name="criteriaRowInsert[' . $row_index . ']" />';
+        $html_output .= '</td>';
+        $html_output .= '<td class="' . $GLOBALS['cell_align_right'] . '">';
+        $html_output .= '<strong>' . __('And') . ':</strong>';
+        $html_output .= '</td>';
+        $html_output .= '<td>';
+        $html_output .= '<input type="radio"'
+            . ' name="criteriaAndOrRow[' . $row_index . ']" value="and"'
+            . $checked_options['and'] . ' />';
+        $html_output .= '</td>';
+        $html_output .= '</tr>';
+        $html_output .= '<tr>';
+        $html_output .= '<td class="' . $GLOBALS['cell_align_right'] . ' nowrap">';
+        $html_output .= '<small>' . __('Del') . ':</small>';
+        $html_output .= '<input type="checkbox"'
+            . ' name="criteriaRowDelete[' . $row_index . ']" />';
+        $html_output .= '</td>';
+        $html_output .= '<td class="' . $GLOBALS['cell_align_right'] . '">';
+        $html_output .= '<strong>' . __('Or') . ':</strong>';
+        $html_output .= '</td>';
+        $html_output .= '<td>';
+        $html_output .= '<input type="radio"'
+            . ' name="criteriaAndOrRow[' . $row_index . ']"'
+            . ' value="or"' . $checked_options['or'] . ' />';
+        $html_output .= '</td>';
+        $html_output .= '</tr>';
+        $html_output .= '</table>';
+        $html_output .= '</td>';
+        return $html_output;
+    }
+
+    /**
+     * Provides rows for criteria inputbox Insert/Delete options
+     * with AND/OR relationship modification options
+     *
+     * @param integer $new_row_index New row index if rows are added/deleted
+     * @param integer $row_index     Row index
+     *
+     * @return HTML table rows
+     */
+    private function _getInputboxRow($new_row_index, $row_index)
+    {
+        $html_output = '';
+        $new_column_count = 0;
+        for ($column_index = 0; $column_index < $this->_criteria_column_count; $column_index++) {
+            if (! empty($this->_criteriaColumnInsert)
+                && isset($this->_criteriaColumnInsert[$column_index])
+                && $this->_criteriaColumnInsert[$column_index] == 'on'
+            ) {
+                $or = 'Or' . $new_row_index . '[' . $new_column_count . ']';
+                $html_output .= '<td class="center">';
+                $html_output .= '<input type="text"'
+                    . ' name="Or' . $or . '" class="textfield"'
+                    . ' style="width: ' . $this->_realwidth . '" size="20" />';
+                $html_output .= '</td>';
+                $new_column_count++;
+            } // end if
+            if (! empty($this->_criteriaColumnDelete)
+                && isset($this->_criteriaColumnDelete[$column_index])
+                && $this->_criteriaColumnDelete[$column_index] == 'on'
+            ) {
+                continue;
+            }
+            $or = 'Or' . $new_row_index;
+            if (! empty($_POST[$or]) && isset($_POST[$or][$column_index])) {
+                $tmp_or = $_POST[$or][$column_index];
+            } else {
+                $tmp_or     = '';
+            }
+            $html_output .= '<td class="center">';
+            $html_output .= '<input type="text"'
+                . ' name="Or' . $new_row_index . '[' . $new_column_count . ']' . '"'
+                . ' value="' . htmlspecialchars($tmp_or) . '" class="textfield"'
+                . ' style="width: ' . $this->_realwidth . '" size="20" />';
+            $html_output .= '</td>';
+            if (! empty(${$or}) && isset(${$or}[$column_index])) {
+                $GLOBALS[${'cur' . $or}][$new_column_count] = ${$or}[$column_index];
+            }
+            $new_column_count++;
+        } // end for
+        return $html_output;
+    }
+
+    /**
+     * Provides rows for criteria inputbox Insert/Delete options
+     * with AND/OR relationship modification options
+     *
+     * @return HTML table rows
+     */
+    private function _getInsDelAndOrCriteriaRows()
+    {
+        $html_output = '';
+        $new_row_count = 0;
+        $odd_row = true;
+        for ($row_index = 0; $row_index <= $this->_criteria_row_count; $row_index++) {
+            if (isset($this->_criteriaRowInsert[$row_index])
+                && $this->_criteriaRowInsert[$row_index] == 'on'
+            ) {
+                $checked_options['or']  = ' checked="checked"';
+                $checked_options['and'] = '';
+                $html_output .= '<tr class="' . ($odd_row ? 'odd' : 'even') . ' noclick">';
+                $html_output .= $this->_getInsDelAndOrCell(
+                    $new_row_count, $checked_options
+                );
+                $html_output .= $this->_getInputboxRow(
+                    $new_row_count, $row_index
+                );
+                $new_row_count++;
+                $html_output .= '</tr>';
+                $odd_row =! $odd_row;
+            } // end if
+            if (isset($this->_criteriaRowDelete[$row_index])
+                && $this->_criteriaRowDelete[$row_index] == 'on'
+            ) {
+                continue;
+            }
+            if (isset($this->_criteriaAndOrRow[$row_index])) {
+                $this->_curAndOrRow[$new_row_count]
+                    = $this->_criteriaAndOrRow[$row_index];
+            }
+            if (isset($this->_criteriaAndOrRow[$row_index])
+                && $this->_criteriaAndOrRow[$row_index] == 'and'
+            ) {
+                $checked_options['and'] =  ' checked="checked"';
+                $checked_options['or']  =  '';
+            } else {
+                $checked_options['or']  =  ' checked="checked"';
+                $checked_options['and'] =  '';
+            }
+            $html_output .= '<tr class="' . ($odd_row ? 'odd' : 'even') . ' noclick">';
+            $html_output .= $this->_getInsDelAndOrCell(
+                $new_row_count, $checked_options
+            );
+            $html_output .= $this->_getInputboxRow(
+                $new_row_count, $row_index
+            );
+            $new_row_count++;
+            $html_output .= '</tr>';
+            $odd_row =! $odd_row;
+        } // end for
+        $this->_new_row_count = $new_row_count;
+        return $html_output;
+    }
+
+    /**
+     * Provides SELECT clause for building SQL query
+     *
+     * @return Select clause
+     */
+    private function _getSelectClause()
+    {
+        $select_clause = '';
+        $select_clauses = array();
+        for ($column_index = 0; $column_index < $this->_criteria_column_count; $column_index++) {
+            if (! empty($this->_curField[$column_index])
+                && isset($this->_curShow[$column_index])
+                && $this->_curShow[$column_index] == 'on'
+            ) {
+                $select_clauses[] = $this->_curField[$column_index];
+            }
+        } // end for
+        if ($select_clauses) {
+            $select_clause = 'SELECT '
+                . htmlspecialchars(implode(", ", $select_clauses)) . "\n";
+        }
+        return $select_clause;
+    }
+
+    /**
+     * Provides WHERE clause for building SQL query
+     *
+     * @return Where clause
+     */
+    private function _getWhereClause()
+    {
+        $where_clause = '';
+        $criteria_cnt = 0;
+        for ($column_index = 0; $column_index < $this->_criteria_column_count; $column_index++) {
+            if (! empty($this->_curField[$column_index])
+                && ! empty($this->_curCriteria[$column_index])
+                && $column_index
+                && isset($last_where)
+                && isset($this->_curAndOrCol)
+            ) {
+                $where_clause .= ' ' . strtoupper($this->_curAndOrCol[$last_where]) . ' ';
+            }
+            if (! empty($this->_curField[$column_index])
+                && ! empty($this->_curCriteria[$column_index])
+            ) {
+                $where_clause .= '(' . $this->_curField[$column_index] . ' '
+                    . $this->_curCriteria[$column_index] . ')';
+                $last_where = $column_index;
+                $criteria_cnt++;
+            }
+        } // end for
+        if ($criteria_cnt > 1) {
+            $where_clause = '(' . $where_clause . ')';
+        }
+        // OR rows ${'cur' . $or}[$column_index]
+        if (! isset($this->_curAndOrRow)) {
+            $this->_curAndOrRow = array();
+        }
+        for ($row_index = 0; $row_index <= $this->_criteria_row_count; $row_index++) {
+            $criteria_cnt = 0;
+            $qry_orwhere = '';
+            $last_orwhere = '';
+            for ($column_index = 0; $column_index < $this->_criteria_column_count; $column_index++) {
+                if (! empty($this->_curField[$column_index])
+                    && ! empty(${'curOr' . $row_index}[$column_index])
+                    && $column_index
+                ) {
+                    $qry_orwhere .= ' ' . strtoupper($this->_curAndOrCol[$last_orwhere]) . ' ';
+                }
+                if (! empty($this->_curField[$column_index])
+                    && ! empty(${'curOr' . $row_index}[$column_index])
+                ) {
+                    $qry_orwhere .= '(' . $this->_curField[$column_index]
+                        .  ' '
+                        .  ${'curOr' . $row_index}[$column_index]
+                        .  ')';
+                    $last_orwhere = $column_index;
+                    $criteria_cnt++;
+                }
+            } // end for
+            if ($criteria_cnt > 1) {
+                $qry_orwhere      = '(' . $qry_orwhere . ')';
+            }
+            if (! empty($qry_orwhere)) {
+                $where_clause .= "\n"
+                    .  strtoupper(
+                        isset($this->_curAndOrRow[$row_index])
+                        ? $this->_curAndOrRow[$row_index] . ' '
+                        : ''
+                    )
+                    .  $qry_orwhere;
+            } // end if
+        } // end for
+
+        if (! empty($where_clause) && $where_clause != '()') {
+            $where_clause = 'WHERE ' . htmlspecialchars($where_clause) . "\n";
+        } // end if
+        return $where_clause;
+    }
+
+    /**
+     * Provides ORDER BY clause for building SQL query
+     *
+     * @return Order By clause
+     */
+    private function _getOrderByClause()
+    {
+        $orderby_clause = '';
+        $orderby_clauses = array();
+        for ($column_index = 0; $column_index < $this->_criteria_column_count; $column_index++) {
+            // if all columns are chosen with * selector,
+            // then sorting isn't available
+            // Fix for Bug #570698
+            if (! empty($this->_curField[$column_index])
+                && ! empty($this->_curSort[$column_index])
+            ) {
+                if (substr($this->_curField[$column_index], -2) == '.*') {
+                    continue;
+                }
+                $orderby_clauses[] = $this->_curField[$column_index] . ' '
+                    . $this->_curSort[$column_index];
+            }
+        } // end for
+        if ($orderby_clauses) {
+            $orderby_clause = 'ORDER BY '
+                . htmlspecialchars(implode(", ", $orderby_clauses)) . "\n";
+        }
+        return $orderby_clause;
+    }
+
+    /**
+     * Provides UNIQUE columns and INDEX columns present in criteria tables
+     *
+     * @param array $all_tables           Tables involved in the search
+     * @param array $all_columns          Columns involved in the search
+     * @param array $where_clause_columns Columns having criteria where clause
+     *
+     * @return array having UNIQUE and INDEX columns
+     */
+    private function _getIndexes($all_tables, $all_columns,
+        $where_clause_columns
+    ) {
+        $unique_columns = array();
+        $index_columns = array();
+
+        foreach ($all_tables as $table) {
+            $indexes = PMA_DBI_get_table_indexes($this->_db, $table);
+            foreach ($indexes as $index) {
+                $column = $table . '.' . $index['Column_name'];
+                if (isset($all_columns[$column])) {
+                    if ($index['Non_unique'] == 0) {
+                        if (isset($where_clause_columns[$column])) {
+                            $unique_columns[$column] = 'Y';
+                        } else {
+                            $unique_columns[$column] = 'N';
+                        }
+                    } else {
+                        if (isset($where_clause_columns[$column])) {
+                            $index_columns[$column] = 'Y';
+                        } else {
+                            $index_columns[$column] = 'N';
+                        }
+                    }
+                }
+            } // end while (each index of a table)
+        } // end while (each table)
+
+        return array(
+            'unique' => $unique_columns,
+            'index' => $index_columns
+        );
+    }
+
+    /**
+     * Provides UNIQUE columns and INDEX columns present in criteria tables
+     *
+     * @param array $all_tables           Tables involved in the search
+     * @param array $all_columns          Columns involved in the search
+     * @param array $where_clause_columns Columns having criteria where clause
+     *
+     * @return array having UNIQUE and INDEX columns
+     */
+    private function _getLeftJoinColumnCandidates($all_tables, $all_columns,
+        $where_clause_columns
+    ) {
+        PMA_DBI_select_db($this->_db);
+        $candidate_columns = array();
+
+        // Get unique columns and index columns
+        $indexes = $this->_getIndexes(
+            $all_tables, $all_columns, $where_clause_columns
+        );
+        $unique_columns = $indexes['unique'];
+        $index_columns = $indexes['index'];
+
+        // now we want to find the best.
+        if (isset($unique_columns) && count($unique_columns) > 0) {
+            $candidate_columns = $unique_columns;
+            $needsort = 1;
+        } elseif (isset($index_columns) && count($index_columns) > 0) {
+            $candidate_columns = $index_columns;
+            $needsort = 1;
+        } elseif (isset($where_clause_columns) && count($where_clause_columns) > 0) {
+            $candidate_columns = $where_clause_columns;
+            $needsort = 0;
+        } else {
+            $candidate_columns = $all_tables;
+            $needsort = 0;
+        }
+
+        // If we came up with $unique_columns (very good) or $index_columns (still
+        // good) as $candidate_columns we want to check if we have any 'Y' there
+        // (that would mean that they were also found in the whereclauses
+        // which would be great). if yes, we take only those
+        if ($needsort == 1) {
+            foreach ($candidate_columns as $column => $is_where) {
+                $table = explode('.', $column);
+                $table = $table[0];
+                if ($is_where == 'Y') {
+                    $vg[$column] = $table;
+                } else {
+                    $sg[$column] = $table;
+                }
+            }
+            if (isset($vg)) {
+                $candidate_columns = $vg;
+                // Candidates restricted in index+where
+            } else {
+                $candidate_columns = $sg;
+                // None of the candidates where in a where-clause
+            }
+        }
+
+        return $candidate_columns;
+    }
+
+    /**
+     * Provides the main table to form the LEFT JOIN clause
+     *
+     * @param array $all_tables           Tables involved in the search
+     * @param array $all_columns          Columns involved in the search
+     * @param array $where_clause_columns Columns having criteria where clause
+     * @param array $where_clause_tables  Tables having criteria where clause
+     *
+     * @return string table name
+     */
+    private function _getMasterTable($all_tables, $all_columns,
+        $where_clause_columns, $where_clause_tables
+    ) {
+        $master = '';
+        if (count($where_clause_tables) == 1) {
+            // If there is exactly one column that has a decent where-clause
+            // we will just use this
+            $master = key($where_clause_tables);
+        } else {
+            // Now let's find out which of the tables has an index
+            // (When the control user is the same as the normal user
+            // because he is using one of his databases as pmadb,
+            // the last db selected is not always the one where we need to work)
+            $candidate_columns = $this->_getLeftJoinColumnCandidates(
+                $all_tables, $all_columns, $where_clause_columns
+            );
+            // If our array of candidates has more than one member we'll just
+            // find the smallest table.
+            // Of course the actual query would be faster if we check for
+            // the Criteria which gives the smallest result set in its table,
+            // but it would take too much time to check this
+            if (count($candidate_columns) > 1) {
+                // Of course we only want to check each table once
+                $checked_tables = $candidate_columns;
+                foreach ($candidate_columns as $table) {
+                    if ($checked_tables[$table] != 1) {
+                        $tsize[$table] = PMA_Table::countRecords(
+                            $this->_db,
+                            $table,
+                            false
+                        );
+                        $checked_tables[$table] = 1;
+                    }
+                    $csize[$table] = $tsize[$table];
+                }
+                asort($csize);
+                reset($csize);
+                $master = key($csize); // Smallest
+            } else {
+                reset($candidate_columns);
+                $master = current($candidate_columns); // Only one single candidate
+            }
+        } // end if (exactly one where clause)
+        return $master;
+    }
+
+    /**
+     * Provides columns and tables that have valid where clause criteria
+     *
+     * @return array
+     */
+    private function _getWhereClauseTablesAndColumns()
+    {
+        $where_clause_columns = array();
+        $where_clause_tables = array();
+        // Now we need all tables that we have in the where clause
+        for ($column_index = 0; $column_index < count($this->_criteria); $column_index++) {
+            $current_table = explode('.', $_POST['criteriaColumn'][$column_index]);
+            if (empty($current_table[0]) || empty($current_table[1])) {
+                continue;
+            } // end if
+            $table = str_replace('`', '', $current_table[0]);
+            $column = str_replace('`', '', $current_table[1]);
+            $column = $table . '.' . $column;
+            // Now we know that our array has the same numbers as $criteria
+            // we can check which of our columns has a where clause
+            if (! empty($this->_criteria[$column_index])) {
+                if (substr($this->_criteria[$column_index], 0, 1) == '='
+                    || stristr($this->_criteria[$column_index], 'is')
+                ) {
+                    $where_clause_columns[$column] = $column;
+                    $where_clause_tables[$table]  = $table;
+                }
+            } // end if
+        } // end for
+        return array(
+            'where_clause_tables' => $where_clause_tables,
+            'where_clause_columns' => $where_clause_columns
+        );
+    }
+
+    /**
+     * Provides FROM clause for building SQL query
+     *
+     * @param string $cfgRelation Relation Settings
+     *
+     * @return FROM clause
+     */
+    private function _getFromClause($cfgRelation)
+    {
+        $from_clause = '';
+        if (isset($_POST['criteriaColumn']) && count($_POST['criteriaColumn']) > 0) {
+            // Initialize some variables
+            $all_tables = $all_columns = $known_tables = $remaining_tables = array();
+            $left_join = '';
+
+            // We only start this if we have fields, otherwise it would be dumb
+            foreach ($_POST['criteriaColumn'] as $value) {
+                $parts = explode('.', $value);
+                if (! empty($parts[0]) && ! empty($parts[1])) {
+                    $table = str_replace('`', '', $parts[0]);
+                    $all_tables[$table] = $table;
+                    $all_columns[] = $table . '.' . str_replace('`', '', $parts[1]);
+                }
+            } // end while
+
+            // Create LEFT JOINS out of Relations
+            if ($cfgRelation['relwork'] && count($all_tables) > 0) {
+                // Get tables and columns with valid where clauses
+                $valid_where_clauses = $this->_getWhereClauseTablesAndColumns();
+                $where_clause_tables = $valid_where_clauses['where_clause_tables'];
+                $where_clause_columns = $valid_where_clauses['where_clause_columns'];
+                // Get master table
+                $master = $this->_getMasterTable(
+                    $all_tables, $all_columns,
+                    $where_clause_columns, $where_clause_tables
+                );
+                $from_clause = PMA_Util::backquote($master)
+                    . PMA_getRelatives($all_tables, $master);
+
+            } // end if ($cfgRelation['relwork'] && count($all_tables) > 0)
+        } // end count($_POST['criteriaColumn']) > 0
+
+        // In case relations are not defined, just generate the FROM clause
+        // from the list of tables, however we don't generate any JOIN
+        if (empty($from_clause) && isset($all_tables)) {
+            $from_clause = implode(', ', $all_tables);
+        }
+        return $from_clause;
+    }
+
+    /**
+     * Provides the generated SQL query
+     *
+     * @param string $cfgRelation Relation Settings
+     *
+     * @return string SQL query
+     */
+    private function _getSQLQuery($cfgRelation)
+    {
+        $sql_query = '';
+        // get SELECT clause
+        $sql_query .= $this->_getSelectClause();
+        // get FROM clause
+        $from_clause = $this->_getFromClause($cfgRelation);
+        if (! empty($from_clause)) {
+            $sql_query .= 'FROM ' . htmlspecialchars($from_clause) . "\n";
+        }
+        // get WHERE clause
+        $sql_query .= $this->_getWhereClause();
+        // get ORDER BY clause
+        $sql_query .= $this->_getOrderByClause();
+        return $sql_query;
+    }
+
+    /**
+     * Provides the generated QBE form
+     *
+     * @param string $cfgRelation Relation Settings
+     *
+     * @return string QBE form
+     */
+    public function getSelectionForm($cfgRelation)
+    {
+        $html_output = '<form action="db_qbe.php" method="post">';
+        $html_output .= '<fieldset>';
+        $html_output .= '<table class="data" style="width: 100%;">';
+        // Get table's <tr> elements
+        $html_output .= $this->_getColumnNamesRow();
+        $html_output .= $this->_getSortRow();
+        $html_output .= $this->_getShowRow();
+        $html_output .= $this->_getCriteriaInputboxRow();
+        $html_output .= $this->_getInsDelAndOrCriteriaRows();
+        $html_output .= $this->_getModifyColumnsRow();
+        $html_output .= '</table>';
+        $this->_new_row_count--;
+        $url_params['db'] = $this->_db;
+        $url_params['criteriaColumnCount'] = $this->_new_column_count;
+        $url_params['rows'] = $this->_new_row_count;
+        $html_output .= PMA_generate_common_hidden_inputs($url_params);
+        $html_output .= '</fieldset>';
+        // get footers
+        $html_output .= $this->_getTableFooters();
+        // get tables select list
+        $html_output .= $this->_getTablesList();
+        $html_output .= '</form>';
+        $html_output .= '<form action="db_qbe.php" method="post">';
+        $html_output .= PMA_generate_common_hidden_inputs(array('db' => $this->_db));
+        // get SQL query
+        $html_output .= '<div class="floatleft">';
+        $html_output .= '<fieldset>';
+        $html_output .= '<legend>'
+            . sprintf(
+                __('SQL query on database <b>%s</b>:'),
+                PMA_Util::getDbLink($this->_db)
+            );
+        $html_output .= '</legend>';
+        $text_dir = 'ltr';
+        $html_output .= '<textarea cols="80" name="sql_query" id="textSqlquery"'
+            . ' rows="' . ((count($this->_criteriaTables) > 30) ? '15' : '7') . '"'
+            . ' dir="' . $text_dir . '">';
+        $html_output .= $this->_getSQLQuery($cfgRelation);
+        $html_output .= '</textarea>';
+        $html_output .= '</fieldset>';
+        // displays form's footers
+        $html_output .= '<fieldset class="tblFooters">';
+        $html_output .= '<input type="hidden" name="submit_sql" value="1" />';
+        $html_output .= '<input type="submit" value="' . __('Submit Query') . '" />';
+        $html_output .= '</fieldset>';
+        $html_output .= '</div>';
+        $html_output .= '</form>';
+        return $html_output;
+    }
+}
+?>
diff --git a/phpmyadmin/libraries/DbSearch.class.php b/phpmyadmin/libraries/DbSearch.class.php
new file mode 100644
index 0000000..9ffd1d8
--- /dev/null
+++ b/phpmyadmin/libraries/DbSearch.class.php
@@ -0,0 +1,489 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * Handles Database Search
+ *
+ * @package PhpMyAdmin
+ */
+if (! defined('PHPMYADMIN')) {
+    exit;
+}
+
+/**
+ * Class to handle database search
+ *
+ * @package PhpMyAdmin
+ */
+class PMA_DbSearch
+{
+    /**
+     * Database name
+     *
+     * @access private
+     * @var string
+     */
+    private $_db;
+    /**
+     * Table Names
+     *
+     * @access private
+     * @var array
+     */
+    private $_tables_names_only;
+    /**
+     * Type of search
+     *
+     * @access private
+     * @var array
+     */
+    private $_searchTypes;
+    /**
+     * Already set search type
+     *
+     * @access private
+     * @var integer
+     */
+    private $_criteriaSearchType;
+    /**
+     * Already set search type's description
+     *
+     * @access private
+     * @var string
+     */
+    private $_searchTypeDescription;
+    /**
+     * Search string/regexp
+     *
+     * @access private
+     * @var string
+     */
+    private $_criteriaSearchString;
+    /**
+     * Criteria Tables to search in
+     *
+     * @access private
+     * @var array
+     */
+    private $_criteriaTables;
+    /**
+     * Restrict the search to this column
+     *
+     * @access private
+     * @var string
+     */
+    private $_criteriaColumnName;
+
+    /**
+     * Public Constructor
+     *
+     * @param string $db Database name
+     */
+    public function __construct($db)
+    {
+        $this->_db = $db;
+        // Sets criteria parameters
+        $this->_setSearchParams();
+    }
+
+    /**
+     * Sets search parameters
+     *
+     * @return void
+     */
+    private function _setSearchParams()
+    {
+        $this->_tables_names_only = PMA_DBI_get_tables($this->_db);
+
+        $this->_searchTypes = array(
+            '1' => __('at least one of the words'),
+            '2' => __('all words'),
+            '3' => __('the exact phrase'),
+            '4' => __('as regular expression'),
+        );
+
+        if (empty($_REQUEST['criteriaSearchType'])
+            || ! is_string($_REQUEST['criteriaSearchType'])
+            || ! array_key_exists($_REQUEST['criteriaSearchType'], $this->_searchTypes)
+        ) {
+            $this->_criteriaSearchType = 1;
+            unset($_REQUEST['submit_search']);
+        } else {
+            $this->_criteriaSearchType = (int) $_REQUEST['criteriaSearchType'];
+            $this->_searchTypeDescription
+                = $this->_searchTypes[$_REQUEST['criteriaSearchType']];
+        }
+
+        if (empty($_REQUEST['criteriaSearchString'])
+            || ! is_string($_REQUEST['criteriaSearchString'])
+        ) {
+            $this->_criteriaSearchString = '';
+            unset($_REQUEST['submit_search']);
+        } else {
+            $this->_criteriaSearchString = $_REQUEST['criteriaSearchString'];
+        }
+
+        $this->_criteriaTables = array();
+        if (empty($_REQUEST['criteriaTables'])
+            || ! is_array($_REQUEST['criteriaTables'])
+        ) {
+            unset($_REQUEST['submit_search']);
+        } else {
+            $this->_criteriaTables = array_intersect(
+                $_REQUEST['criteriaTables'], $this->_tables_names_only
+            );
+        }
+
+        if (empty($_REQUEST['criteriaColumnName'])
+            || ! is_string($_REQUEST['criteriaColumnName'])
+        ) {
+            unset($this->_criteriaColumnName);
+        } else {
+            $this->_criteriaColumnName = PMA_Util::sqlAddSlashes(
+                $_REQUEST['criteriaColumnName'], true
+            );
+        }
+    }
+
+    /**
+     * Builds the SQL search query
+     *
+     * @param string $table The table name
+     *
+     * @return array 3 SQL querys (for count, display and delete results)
+     *
+     * @todo    can we make use of fulltextsearch IN BOOLEAN MODE for this?
+     * PMA_backquote
+     * PMA_DBI_free_result
+     * PMA_DBI_fetch_assoc
+     * $GLOBALS['db']
+     * explode
+     * count
+     * strlen
+     */
+    private function _getSearchSqls($table)
+    {
+        // Statement types
+        $sqlstr_select = 'SELECT';
+        $sqlstr_delete = 'DELETE';
+        // Table to use
+        $sqlstr_from = ' FROM '
+            . PMA_Util::backquote($GLOBALS['db']) . '.'
+            . PMA_Util::backquote($table);
+        // Gets where clause for the query
+        $where_clause = $this->_getWhereClause($table);
+        // Builds complete queries
+        $sql['select_columns'] = $sqlstr_select . ' * ' . $sqlstr_from . $where_clause;
+        // here, I think we need to still use the COUNT clause, even for
+        // VIEWs, anyway we have a WHERE clause that should limit results
+        $sql['select_count']  = $sqlstr_select . ' COUNT(*) AS `count`'
+            . $sqlstr_from . $where_clause;
+        $sql['delete']        = $sqlstr_delete . $sqlstr_from . $where_clause;
+
+        return $sql;
+    }
+
+    /**
+     * Provides where clause for bulding SQL query
+     *
+     * @param string $table The table name
+     *
+     * @return string The generated where clause
+     */
+    private function _getWhereClause($table)
+    {
+        $where_clause = '';
+        // Columns to select
+        $allColumns = PMA_DBI_get_columns($GLOBALS['db'], $table);
+        $likeClauses = array();
+        // Based on search type, decide like/regex & '%'/''
+        $like_or_regex   = (($this->_criteriaSearchType == 4) ? 'REGEXP' : 'LIKE');
+        $automatic_wildcard   = (($this->_criteriaSearchType < 3) ? '%' : '');
+        // For "as regular expression" (search option 4), LIKE won't be used
+        // Usage example: If user is seaching for a literal $ in a regexp search,
+        // he should enter \$ as the value.
+        $this->_criteriaSearchString = PMA_Util::sqlAddSlashes(
+            $this->_criteriaSearchString,
+            ($this->_criteriaSearchType == 4 ? false : true)
+        );
+        // Extract search words or pattern
+        $search_words = (($this->_criteriaSearchType > 2)
+            ? array($this->_criteriaSearchString)
+            : explode(' ', $this->_criteriaSearchString));
+
+        foreach ($search_words as $search_word) {
+            // Eliminates empty values
+            if (strlen($search_word) === 0) {
+                continue;
+            }
+            $likeClausesPerColumn = array();
+            // for each column in the table
+            foreach ($allColumns as $column) {
+                if (! isset($this->_criteriaColumnName)
+                    || strlen($this->_criteriaColumnName) == 0
+                    || $column['Field'] == $this->_criteriaColumnName
+                ) {
+                    // Drizzle has no CONVERT and all text columns are UTF-8
+                    $column = ((PMA_DRIZZLE)
+                        ? PMA_Util::backquote($column['Field'])
+                        : 'CONVERT(' . PMA_Util::backquote($column['Field'])
+                            . ' USING utf8)');
+                    $likeClausesPerColumn[] = $column . ' ' . $like_or_regex . ' '
+                        . "'"
+                        . $automatic_wildcard . $search_word . $automatic_wildcard
+                        . "'";
+                }
+            } // end for
+            if (count($likeClausesPerColumn) > 0) {
+                $likeClauses[] = implode(' OR ', $likeClausesPerColumn);
+            }
+        } // end for
+        // Use 'OR' if 'at least one word' is to be searched, else use 'AND'
+        $implode_str  = ($this->_criteriaSearchType == 1 ? ' OR ' : ' AND ');
+        if ( empty($likeClauses)) {
+            // this could happen when the "inside column" does not exist
+            // in any selected tables
+            $where_clause = ' WHERE FALSE';
+        } else {
+            $where_clause = ' WHERE ('
+                . implode(') ' . $implode_str . ' (', $likeClauses)
+                . ')';
+        }
+        return $where_clause;
+    }
+
+    /**
+     * Displays database search results
+     *
+     * @return string HTML for search results
+     */
+    public function getSearchResults()
+    {
+        $html_output = '';
+        // Displays search string
+        $html_output .= '<br />'
+            . '<table class="data">'
+            . '<caption class="tblHeaders">'
+            . sprintf(
+                __('Search results for "<i>%s</i>" %s:'),
+                htmlspecialchars($this->_criteriaSearchString),
+                $this->_searchTypeDescription
+            )
+            . '</caption>';
+
+        $num_search_result_total = 0;
+        $odd_row = true;
+        // For each table selected as search criteria
+        foreach ($this->_criteriaTables as $each_table) {
+            // Gets the SQL statements
+            $newsearchsqls = $this->_getSearchSqls($each_table);
+            // Executes the "COUNT" statement
+            $res_cnt = PMA_DBI_fetch_value($newsearchsqls['select_count']);
+            $num_search_result_total += $res_cnt;
+            // Gets the result row's HTML for a table
+            $html_output .= $this->_getResultsRow(
+                $each_table, $newsearchsqls, $odd_row, $res_cnt
+            );
+            $odd_row = ! $odd_row;
+        } // end for
+        $html_output .= '</table>';
+        // Displays total number of matches
+        if (count($this->_criteriaTables) > 1) {
+            $html_output .= '<p>';
+            $html_output .= sprintf(
+                _ngettext(
+                    '<b>Total:</b> <i>%s</i> match',
+                    '<b>Total:</b> <i>%s</i> matches',
+                    $num_search_result_total
+                ),
+                $num_search_result_total
+            );
+            $html_output .= '</p>';
+        }
+        return $html_output;
+    }
+
+    /**
+     * Provides search results row with browse/delete links.
+     * (for a table)
+     *
+     * @param string  $each_table    One of the tables on which search was performed
+     * @param array   $newsearchsqls Contains SQL queries
+     * @param bool    $odd_row       For displaying contrasting table rows
+     * @param integer $res_cnt       Number of results found
+     *
+     * @return string HTML row
+     */
+    private function _getResultsRow($each_table, $newsearchsqls, $odd_row, $res_cnt)
+    {
+        $this_url_params = array(
+            'db'    => $GLOBALS['db'],
+            'table' => $each_table,
+            'goto'  => 'db_sql.php',
+            'pos'   => 0,
+            'is_js_confirmed' => 0,
+        );
+        // Start forming search results row
+        $html_output = '<tr class="noclick ' . ($odd_row ? 'odd' : 'even') . '">';
+        // Displays results count for a table
+        $html_output .= '<td>';
+        $html_output .= sprintf(
+            _ngettext(
+                '%1$s match in <strong>%2$s</strong>',
+                '%1$s matches in <strong>%2$s</strong>', $res_cnt
+            ),
+            $res_cnt, htmlspecialchars($each_table)
+        );
+        $html_output .= '</td>';
+        // Displays browse/delete link if result count > 0
+        if ($res_cnt > 0) {
+            $this_url_params['sql_query'] = $newsearchsqls['select_columns'];
+            $browse_result_path = 'sql.php' . PMA_generate_common_url($this_url_params);
+            $html_output .= '<td><a name="browse_search" href="'
+                . $browse_result_path . '" onclick="loadResult(\''
+                . $browse_result_path . '\',\'' . $each_table . '\',\''
+                . PMA_generate_common_url($GLOBALS['db'], $each_table) . '\''
+                . ');return false;" >'
+                . __('Browse') . '</a></td>';
+            $this_url_params['sql_query'] = $newsearchsqls['delete'];
+            $delete_result_path = 'sql.php' . PMA_generate_common_url($this_url_params);
+            $html_output .= '<td><a name="delete_search" href="'
+                . $delete_result_path . '" onclick="deleteResult(\''
+                . $delete_result_path . '\' , \''
+                . sprintf(
+                    __('Delete the matches for the %s table?'),
+                    htmlspecialchars($each_table)
+                )
+                . '\');return false;">'
+                . __('Delete') . '</a></td>';
+        } else {
+            $html_output .= '<td> </td>'
+                .'<td> </td>';
+        }// end if else
+        $html_output .= '</tr>';
+        return $html_output;
+    }
+
+    /**
+     * Provides the main search form's html
+     *
+     * @param array $url_params URL parameters
+     *
+     * @return string HTML for selection form
+     */
+    public function getSelectionForm($url_params)
+    {
+        $html_output = '<a id="db_search"></a>';
+        $html_output .= '<form id="db_search_form"'
+            . ' class="ajax"'
+            . ' method="post" action="db_search.php" name="db_search">';
+        $html_output .= PMA_generate_common_hidden_inputs($GLOBALS['db']);
+        $html_output .= '<fieldset>';
+        // set legend caption
+        $html_output .= '<legend>' . __('Search in database') . '</legend>';
+        $html_output .= '<table class="formlayout">';
+        // inputbox for search phrase
+        $html_output .= '<tr>';
+        $html_output .= '<td>' . __('Words or values to search for (wildcard: "%"):')
+            . '</td>';
+        $html_output .= '<td><input type="text"'
+            . ' name="criteriaSearchString" size="60"'
+            . ' value="' . htmlspecialchars($this->_criteriaSearchString) . '" />';
+        $html_output .= '</td>';
+        $html_output .= '</tr>';
+        // choices for types of search
+        $html_output .= '<tr>';
+        $html_output .= '<td class="right vtop">' . __('Find:') . '</td>';
+        $html_output .= '<td>';
+        $choices = array(
+            '1' => __('at least one of the words')
+                . PMA_Util::showHint(
+                    __('Words are separated by a space character (" ").')
+                ),
+            '2' => __('all words')
+                . PMA_Util::showHint(
+                    __('Words are separated by a space character (" ").')
+                ),
+            '3' => __('the exact phrase'),
+            '4' => __('as regular expression') . ' '
+                . PMA_Util::showMySQLDocu('Regexp', 'Regexp')
+        );
+        // 4th parameter set to true to add line breaks
+        // 5th parameter set to false to avoid htmlspecialchars() escaping
+        // in the label since we have some HTML in some labels
+        $html_output .= PMA_Util::getRadioFields(
+            'criteriaSearchType', $choices, $this->_criteriaSearchType, true, false
+        );
+        $html_output .= '</td></tr>';
+        // displays table names as select options
+        $html_output .= '<tr>';
+        $html_output .= '<td class="right vtop">' . __('Inside tables:') . '</td>';
+        $html_output .= '<td rowspan="2">';
+        $html_output .= '<select name="criteriaTables[]" size="6" multiple="multiple">';
+        foreach ($this->_tables_names_only as $each_table) {
+            if (in_array($each_table, $this->_criteriaTables)) {
+                $is_selected = ' selected="selected"';
+            } else {
+                $is_selected = '';
+            }
+            $html_output .= '<option value="' . htmlspecialchars($each_table) . '"'
+                . $is_selected . '>'
+                . str_replace(' ', ' ', htmlspecialchars($each_table))
+                . '</option>';
+        } // end for
+        $html_output .= '</select>';
+        $html_output .= '</td></tr>';
+        // Displays 'select all' and 'unselect all' links
+        $alter_select = '<a href="#" '
+            . 'onclick="setSelectOptions(\'db_search\', \'criteriaTables[]\', true); return false;">'
+            . __('Select All') . '</a>  / ';
+        $alter_select .= '<a href="#" '
+            . 'onclick="setSelectOptions(\'db_search\', \'criteriaTables[]\', false); return false;">'
+            . __('Unselect All') . '</a>';
+        $html_output .= '<tr><td class="right vbottom">' . $alter_select . '</td></tr>';
+        // Inputbox for column name entry
+        $html_output .= '<tr>';
+        $html_output .= '<td class="right">' . __('Inside column:') . '</td>';
+        $html_output .= '<td><input type="text" name="criteriaColumnName" size="60"'
+            . 'value="'
+            . (! empty($this->_criteriaColumnName) ? htmlspecialchars($this->_criteriaColumnName) : '')
+            . '" /></td>';
+        $html_output .= '</tr>';
+        $html_output .= '</table>';
+        $html_output .= '</fieldset>';
+        $html_output .= '<fieldset class="tblFooters">';
+        $html_output .= '<input type="submit" name="submit_search" value="'
+            . __('Go') . '" id="buttonGo" />';
+        $html_output .= '</fieldset>';
+        $html_output .= '</form>';
+        $html_output .= $this->_getResultDivs();
+
+        return $html_output;
+    }
+
+    /**
+     * Provides div tags for browsing search results and sql query form.
+     *
+     * @return string div tags
+     */
+    private function _getResultDivs()
+    {
+        $html_output = '<!-- These two table-image and table-link elements display'
+            . ' the table name in browse search results  -->';
+        $html_output .= '<div id="table-info">';
+        $html_output .= '<a class="item" id="table-link" ></a>';
+        $html_output .= '</div>';
+        // div for browsing results
+        $html_output .= '<div id="browse-results">';
+        $html_output .= '<!-- this browse-results div is used to load the browse'
+            . ' and delete results in the db search -->';
+        $html_output .= '</div>';
+        $html_output .= '<br class="clearfloat" />';
+        $html_output .= '<div id="sqlqueryform">';
+        $html_output .= '<!-- this sqlqueryform div is used to load the delete form in'
+            . ' the db search -->';
+        $html_output .= '</div>';
+        $html_output .= '<!--  toggle query box link-->';
+        $html_output .= '<a id="togglequerybox"></a>';
+        return $html_output;
+    }
+}
diff --git a/phpmyadmin/libraries/DisplayResults.class.php b/phpmyadmin/libraries/DisplayResults.class.php
new file mode 100644
index 0000000..35dd112
--- /dev/null
+++ b/phpmyadmin/libraries/DisplayResults.class.php
@@ -0,0 +1,5967 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * Hold the PMA_DisplayResults class
+ *
+ * @package PhpMyAdmin
+ */
+if (! defined('PHPMYADMIN')) {
+    exit;
+}
+
+/**
+ * Handle all the functionalities related to displaying results
+ * of sql queries, stored procedure, browsing sql processes or
+ * displaying binary log.
+ *
+ * @package PhpMyAdmin
+ */
+class PMA_DisplayResults
+{
+
+    // Define constants
+    const NO_EDIT_OR_DELETE = 'nn';
+    const UPDATE_ROW = 'ur';
+    const DELETE_ROW = 'dr';
+    const KILL_PROCESS = 'kp';
+
+    const POSITION_LEFT = 'left';
+    const POSITION_RIGHT = 'right';
+    const POSITION_BOTH = 'both';
+    const POSITION_NONE = 'none';
+
+    const PLACE_TOP_DIRECTION_DROPDOWN = 'top_direction_dropdown';
+    const PLACE_BOTTOM_DIRECTION_DROPDOWN = 'bottom_direction_dropdown';
+
+    const DISP_DIR_HORIZONTAL = 'horizontal';
+    const DISP_DIR_HORIZONTAL_FLIPPED = 'horizontalflipped';
+    const DISP_DIR_VERTICAL = 'vertical';
+
+    const DISPLAY_FULL_TEXT = 'F';
+    const DISPLAY_PARTIAL_TEXT = 'P';
+
+    const HEADER_FLIP_TYPE_AUTO = 'auto';
+    const HEADER_FLIP_TYPE_CSS = 'css';
+    const HEADER_FLIP_TYPE_FAKE = 'fake';
+
+    const DATE_FIELD = 'date';
+    const DATETIME_FIELD = 'datetime';
+    const TIMESTAMP_FIELD = 'timestamp';
+    const STRING_FIELD = 'string';
+    const GEOMETRY_FIELD = 'geometry';
+    const BLOB_FIELD = 'BLOB';
+    const BINARY_FIELD = 'BINARY';
+
+    const RELATIONAL_KEY = 'K';
+    const RELATIONAL_DISPLAY_COLUMN = 'D';
+
+    const GEOMETRY_DISP_GEOM = 'GEOM';
+    const GEOMETRY_DISP_WKT = 'WKT';
+    const GEOMETRY_DISP_WKB = 'WKB';
+
+    const SMART_SORT_ORDER = 'SMART';
+    const ASCENDING_SORT_DIR = 'ASC';
+    const DESCENDING_SORT_DIR = 'DESC';
+
+    const TABLE_TYPE_INNO_DB = 'InnoDB';
+    const ALL_ROWS = 'all';
+    const QUERY_TYPE_SELECT = 'SELECT';
+
+    const ROUTINE_PROCEDURE = 'procedure';
+    const ROUTINE_FUNCTION = 'function';
+
+
+    // Declare global fields
+
+    /** array with properties of the class */
+    private $_property_array = array(
+
+        /** string Database name */
+        'db' => null,
+
+        /** string Table name */
+        'table' => null,
+
+        /** string the URL to go back in case of errors */
+        'goto' => null,
+
+        /** string the SQL query */
+        'sql_query' => null,
+
+        /**
+         * integer the total number of rows returned by the SQL query without any
+         *         appended "LIMIT" clause programmatically
+         */
+        'unlim_num_rows' => null,
+
+        /** array meta information about fields */
+        'fields_meta' => null,
+
+        /** boolean */
+        'is_count' => null,
+
+        /** integer */
+        'is_export' => null,
+
+        /** boolean */
+        'is_func' => null,
+
+        /** integer */
+        'is_analyse' => null,
+
+        /** integer the total number of rows returned by the SQL query */
+        'num_rows' => null,
+
+        /** integer the total number of fields returned by the SQL query */
+        'fields_cnt' => null,
+
+        /** double time taken for execute the SQL query */
+        'querytime' => null,
+
+        /** string path for theme images directory */
+        'pma_theme_image' => null,
+
+        /** string */
+        'text_dir' => null,
+
+        /** boolean */
+        'is_maint' => null,
+
+        /** boolean */
+        'is_explain' => null,
+
+        /** boolean */
+        'is_show' => null,
+
+        /** array table definitions */
+        'showtable' => null,
+
+        /** string */
+        'printview' => null,
+
+        /** string URL query */
+        'url_query' => null,
+
+        /** array column names to highlight */
+        'highlight_columns' => null,
+
+        /** array informations used with vertical display mode */
+        'vertical_display' => null,
+
+        /** array mime types information of fields */
+        'mime_map' => null,
+
+        /** boolean */
+        'editable' => null
+    );
+
+    /**
+     * This global variable represent the columns which needs to be syntax
+     * highlighted in each database tables
+     * One element of this array represent all relavant columns in all tables in
+     * one specific database
+     */
+    public $syntax_highlighting_column_info;
+
+
+    /**
+     * Get any property of this class
+     *
+     * @param string $property name of the property
+     *
+     * @return if property exist, value of the relavant property
+     */
+    public function __get($property)
+    {
+        if (array_key_exists($property, $this->_property_array)) {
+            return $this->_property_array[$property];
+        }
+    }
+
+
+    /**
+     * Set values for any property of this class
+     *
+     * @param string $property name of the property
+     * @param any    $value    value to set
+     *
+     * @return void
+     */
+    public function __set($property, $value)
+    {
+        if (array_key_exists($property, $this->_property_array)) {
+            $this->_property_array[$property] = $value;
+        }
+    }
+
+
+    /**
+     * Constructor for PMA_DisplayResults class
+     *
+     * @param string $db        the database name
+     * @param string $table     the table name
+     * @param string $goto      the URL to go back in case of errors
+     * @param string $sql_query the SQL query
+     *
+     * @access  public
+     */
+    public function __construct($db, $table, $goto, $sql_query)
+    {
+        $this->syntax_highlighting_column_info = array(
+            'information_schema' => array(
+                'processlist' => array(
+                    'info' => array(
+                        'libraries/plugins/transformations/'
+                            . 'Text_Plain_Formatted.class.php',
+                        'Text_Plain_Formatted',
+                        'Text_Plain'
+                    )
+                )
+            )
+        );
+
+        $this->__set('db', $db);
+        $this->__set('table', $table);
+        $this->__set('goto', $goto);
+        $this->__set('sql_query', $sql_query);
+    }
+
+
+    /**
+     * Set properties which were not initialized at the constructor
+     *
+     * @param type $unlim_num_rows integer the total number of rows returned by
+     *                                     the SQL query without any appended
+     *                                     "LIMIT" clause programmatically
+     * @param type $fields_meta    array   meta information about fields
+     * @param type $is_count       boolean
+     * @param type $is_export      integer
+     * @param type $is_func        boolean
+     * @param type $is_analyse     integer
+     * @param type $num_rows       integer total no. of rows returned by SQL query
+     * @param type $fields_cnt     integer total no.of fields returned by SQL query
+     * @param type $querytime      double  time taken for execute the SQL query
+     * @param type $pmaThemeImage  string  path for theme images directory
+     * @param type $text_dir       string
+     * @param type $is_maint       boolean
+     * @param type $is_explain     boolean
+     * @param type $is_show        boolean
+     * @param type $showtable      array   table definitions
+     * @param type $printview      string
+     * @param type $url_query      string  URL query
+     * @param type $editable       boolean whether the resutls set is editable
+     *
+     * @return  void
+     *
+     * @see     sql.php
+     */
+    public function setProperties(
+        $unlim_num_rows, $fields_meta, $is_count, $is_export, $is_func,
+        $is_analyse, $num_rows, $fields_cnt, $querytime, $pmaThemeImage, $text_dir,
+        $is_maint, $is_explain, $is_show, $showtable, $printview, $url_query,
+        $editable
+    ) {
+
+        $this->__set('unlim_num_rows', $unlim_num_rows);
+        $this->__set('fields_meta', $fields_meta);
+        $this->__set('is_count', $is_count);
+        $this->__set('is_export', $is_export);
+        $this->__set('is_func', $is_func);
+        $this->__set('is_analyse', $is_analyse);
+        $this->__set('num_rows', $num_rows);
+        $this->__set('fields_cnt', $fields_cnt);
+        $this->__set('querytime', $querytime);
+        $this->__set('pma_theme_image', $pmaThemeImage);
+        $this->__set('text_dir', $text_dir);
+        $this->__set('is_maint', $is_maint);
+        $this->__set('is_explain', $is_explain);
+        $this->__set('is_show', $is_show);
+        $this->__set('showtable', $showtable);
+        $this->__set('printview', $printview);
+        $this->__set('url_query', $url_query);
+        $this->__set('editable', $editable);
+
+    } // end of the 'setProperties()' function
+
+
+    /**
+     * Defines the display mode to use for the results of a SQL query
+     *
+     * It uses a synthetic string that contains all the required informations.
+     * In this string:
+     *   - the first two characters stand for the action to do while
+     *     clicking on the "edit" link (e.g. 'ur' for update a row, 'nn' for no
+     *     edit link...);
+     *   - the next two characters stand for the action to do while
+     *     clicking on the "delete" link (e.g. 'kp' for kill a process, 'nn' for
+     *     no delete link...);
+     *   - the next characters are boolean values (1/0) and respectively stand
+     *     for sorting links, navigation bar, "insert a new row" link, the
+     *     bookmark feature, the expand/collapse text/blob fields button and
+     *     the "display printable view" option.
+     *     Of course '0'/'1' means the feature won't/will be enabled.
+     *
+     * @param string  &$the_disp_mode the synthetic value for display_mode (see a few
+     *                                lines above for explanations)
+     * @param integer &$the_total     the total number of rows returned by the SQL
+     *                                 query without any programmatically appended
+     *                                 LIMIT clause
+     *                                 (just a copy of $unlim_num_rows if it exists,
+     *                                 elsecomputed inside this function)
+     *
+     * @return array    an array with explicit indexes for all the display
+     *                   elements
+     *
+     * @access  private
+     *
+     * @see     getTable()
+     */
+    private function _setDisplayMode(&$the_disp_mode, &$the_total)
+    {
+
+        // Following variables are needed for use in isset/empty or
+        // use with array indexes or safe use in foreach
+        $db = $this->__get('db');
+        $table = $this->__get('table');
+        $unlim_num_rows = $this->__get('unlim_num_rows');
+        $fields_meta = $this->__get('fields_meta');
+        $printview = $this->__get('printview');
+
+        // 1. Initializes the $do_display array
+        $do_display              = array();
+        $do_display['edit_lnk']  = $the_disp_mode[0] . $the_disp_mode[1];
+        $do_display['del_lnk']   = $the_disp_mode[2] . $the_disp_mode[3];
+        $do_display['sort_lnk']  = (string) $the_disp_mode[4];
+        $do_display['nav_bar']   = (string) $the_disp_mode[5];
+        $do_display['ins_row']   = (string) $the_disp_mode[6];
+        $do_display['bkm_form']  = (string) $the_disp_mode[7];
+        $do_display['text_btn']  = (string) $the_disp_mode[8];
+        $do_display['pview_lnk'] = (string) $the_disp_mode[9];
+
+        // 2. Display mode is not "false for all elements" -> updates the
+        // display mode
+        if ($the_disp_mode != 'nnnn000000') {
+
+            if (isset($printview) && ($printview == '1')) {
+                // 2.0 Print view -> set all elements to false!
+                $do_display['edit_lnk']  = self::NO_EDIT_OR_DELETE; // no edit link
+                $do_display['del_lnk']   = self::NO_EDIT_OR_DELETE; // no delete link
+                $do_display['sort_lnk']  = (string) '0';
+                $do_display['nav_bar']   = (string) '0';
+                $do_display['ins_row']   = (string) '0';
+                $do_display['bkm_form']  = (string) '0';
+                $do_display['text_btn']  = (string) '0';
+                $do_display['pview_lnk'] = (string) '0';
+
+            } elseif ($this->__get('is_count') || $this->__get('is_analyse')
+                || $this->__get('is_maint') || $this->__get('is_explain')
+            ) {
+                // 2.1 Statement is a "SELECT COUNT", a
+                //     "CHECK/ANALYZE/REPAIR/OPTIMIZE", an "EXPLAIN" one or
+                //     contains a "PROC ANALYSE" part
+                $do_display['edit_lnk']  = self::NO_EDIT_OR_DELETE; // no edit link
+                $do_display['del_lnk']   = self::NO_EDIT_OR_DELETE; // no delete link
+                $do_display['sort_lnk']  = (string) '0';
+                $do_display['nav_bar']   = (string) '0';
+                $do_display['ins_row']   = (string) '0';
+                $do_display['bkm_form']  = (string) '1';
+
+                if ($this->__get('is_maint')) {
+                    $do_display['text_btn']  = (string) '1';
+                } else {
+                    $do_display['text_btn']  = (string) '0';
+                }
+                $do_display['pview_lnk'] = (string) '1';
+
+            } elseif ($this->__get('is_show')) {
+                // 2.2 Statement is a "SHOW..."
+                /**
+                 * 2.2.1
+                 * @todo defines edit/delete links depending on show statement
+                 */
+                $tmp = preg_match(
+                    '@^SHOW[[:space:]]+(VARIABLES|(FULL[[:space:]]+)?'
+                    . 'PROCESSLIST|STATUS|TABLE|GRANTS|CREATE|LOGS|DATABASES|FIELDS'
+                    . ')@i',
+                    $this->__get('sql_query'), $which
+                );
+                if (isset($which[1])
+                    && (strpos(' ' . strtoupper($which[1]), 'PROCESSLIST') > 0)
+                ) {
+                    // no edit link
+                    $do_display['edit_lnk'] = self::NO_EDIT_OR_DELETE;
+                    // "kill process" type edit link
+                    $do_display['del_lnk']  = self::KILL_PROCESS;
+                } else {
+                    // Default case -> no links
+                    // no edit link
+                    $do_display['edit_lnk'] = self::NO_EDIT_OR_DELETE;
+                    // no delete link
+                    $do_display['del_lnk']  = self::NO_EDIT_OR_DELETE;
+                }
+                // 2.2.2 Other settings
+                $do_display['sort_lnk']  = (string) '0';
+                $do_display['nav_bar']   = (string) '0';
+                $do_display['ins_row']   = (string) '0';
+                $do_display['bkm_form']  = (string) '1';
+                $do_display['text_btn']  = (string) '1';
+                $do_display['pview_lnk'] = (string) '1';
+
+            } else {
+                // 2.3 Other statements (ie "SELECT" ones) -> updates
+                //     $do_display['edit_lnk'], $do_display['del_lnk'] and
+                //     $do_display['text_btn'] (keeps other default values)
+                $prev_table = $fields_meta[0]->table;
+                $do_display['text_btn']  = (string) '1';
+
+                for ($i = 0; $i < $this->__get('fields_cnt'); $i++) {
+
+                    $is_link = ($do_display['edit_lnk'] != self::NO_EDIT_OR_DELETE)
+                        || ($do_display['del_lnk'] != self::NO_EDIT_OR_DELETE)
+                        || ($do_display['sort_lnk'] != '0')
+                        || ($do_display['ins_row'] != '0');
+
+                    // 2.3.2 Displays edit/delete/sort/insert links?
+                    if ($is_link
+                        && (($fields_meta[$i]->table == '')
+                        || ($fields_meta[$i]->table != $prev_table))
+                    ) {
+                        // don't display links
+                        $do_display['edit_lnk'] = self::NO_EDIT_OR_DELETE;
+                        $do_display['del_lnk']  = self::NO_EDIT_OR_DELETE;
+                        /**
+                         * @todo May be problematic with same field names
+                         * in two joined table.
+                         */
+                        // $do_display['sort_lnk'] = (string) '0';
+                        $do_display['ins_row']  = (string) '0';
+                        if ($do_display['text_btn'] == '1') {
+                            break;
+                        }
+                    } // end if (2.3.2)
+
+                    // 2.3.3 Always display print view link
+                    $do_display['pview_lnk']    = (string) '1';
+                    $prev_table = $fields_meta[$i]->table;
+
+                } // end for
+            } // end if..elseif...else (2.1 -> 2.3)
+        } // end if (2)
+
+        // 3. Gets the total number of rows if it is unknown
+        if (isset($unlim_num_rows) && $unlim_num_rows != '') {
+            $the_total = $unlim_num_rows;
+        } elseif ((($do_display['nav_bar'] == '1')
+            || ($do_display['sort_lnk'] == '1'))
+            && (strlen($db) && !empty($table))
+        ) {
+            $the_total   = PMA_Table::countRecords($db, $table);
+        }
+
+        // 4. If navigation bar or sorting fields names URLs should be
+        //    displayed but there is only one row, change these settings to
+        //    false
+        if ($do_display['nav_bar'] == '1' || $do_display['sort_lnk'] == '1') {
+
+            // - Do not display sort links if less than 2 rows.
+            // - For a VIEW we (probably) did not count the number of rows
+            //   so don't test this number here, it would remove the possibility
+            //   of sorting VIEW results.
+            if (isset($unlim_num_rows)
+                && ($unlim_num_rows < 2)
+                && ! PMA_Table::isView($db, $table)
+            ) {
+                // force display of navbar for vertical/horizontal display-choice.
+                // $do_display['nav_bar']  = (string) '0';
+                $do_display['sort_lnk'] = (string) '0';
+            }
+        } // end if (3)
+
+        // 5. Updates the synthetic var
+        $the_disp_mode = join('', $do_display);
+
+        return $do_display;
+
+    } // end of the 'setDisplayMode()' function
+
+
+    /**
+     * Return true if we are executing a query in the form of
+     * "SELECT * FROM <a table> ..."
+     *
+     * @param array $analyzed_sql the analyzed query
+     *
+     * @return boolean
+     *
+     * @access  private
+     *
+     * @see     _getTableHeaders(), _getColumnParams()
+     */
+    private function _isSelect($analyzed_sql)
+    {
+        if (!isset($analyzed_sql[0]['select_expr'])) {
+            $analyzed_sql[0]['select_expr'] = 0;
+        }
+
+        return ! ($this->__get('is_count') || $this->__get('is_export')
+            || $this->__get('is_func') || $this->__get('is_analyse'))
+            && (count($analyzed_sql[0]['select_expr']) == 0)
+            && isset($analyzed_sql[0]['queryflags']['select_from'])
+            && (count($analyzed_sql[0]['table_ref']) == 1);
+    }
+
+
+    /**
+     * Get a navigation button
+     *
+     * @param string  $caption            iconic caption for button
+     * @param string  $title              text for button
+     * @param integer $pos                position for next query
+     * @param string  $html_sql_query     query ready for display
+     * @param string  $onsubmit           optional onsubmit clause
+     * @param string  $input_for_real_end optional hidden field for special treatment
+     * @param string  $onclick            optional onclick clause
+     *
+     * @return string                     html content
+     *
+     * @access  private
+     *
+     * @see     _getMoveBackwardButtonsForTableNavigation(),
+     *          _getMoveForwardButtonsForTableNavigation()
+     */
+    private function _getTableNavigationButton(
+        $caption, $title, $pos, $html_sql_query, $onsubmit = '',
+        $input_for_real_end = '', $onclick = ''
+    ) {
+
+        $caption_output = '';
+        // for true or 'both'
+        if ($GLOBALS['cfg']['NavigationBarIconic']) {
+            $caption_output .= $caption;
+        }
+
+        // for false or 'both'
+        if (($GLOBALS['cfg']['NavigationBarIconic'] === false)
+            || ($GLOBALS['cfg']['NavigationBarIconic'] === self::POSITION_BOTH)
+        ) {
+            $caption_output .= ' ' . $title;
+        }
+        $title_output = ' title="' . $title . '"';
+
+        return '<td>'
+            . '<form action="sql.php" method="post" ' . $onsubmit . '>'
+            . PMA_generate_common_hidden_inputs(
+                $this->__get('db'), $this->__get('table')
+            )
+            . '<input type="hidden" name="sql_query" value="'
+            . $html_sql_query . '" />'
+            . '<input type="hidden" name="pos" value="' . $pos . '" />'
+            . '<input type="hidden" name="goto" value="' . $this->__get('goto')
+            . '" />'
+            . $input_for_real_end
+            . '<input type="submit" name="navig"'
+            . ' class="ajax" '
+            . 'value="' . $caption_output . '" ' . $title_output . $onclick . ' />'
+            . '</form>'
+            . '</td>';
+
+    } // end function _getTableNavigationButton()
+
+
+    /**
+     * Get a navigation bar to browse among the results of a SQL query
+     *
+     * @param integer $pos_next                  the offset for the "next" page
+     * @param integer $pos_prev                  the offset for the "previous" page
+     * @param string  $id_for_direction_dropdown the id for the direction dropdown
+     * @param boolean $is_innodb                 whether its InnoDB or not
+     *
+     * @return string                            html content
+     *
+     * @access  private
+     *
+     * @see     _getTable()
+     */
+    private function _getTableNavigation(
+        $pos_next, $pos_prev, $id_for_direction_dropdown, $is_innodb
+    ) {
+
+        $table_navigation_html = '';
+        $showtable = $this->__get('showtable'); // To use in isset
+
+        // here, using htmlentities() would cause problems if the query
+        // contains accented characters
+        $html_sql_query = htmlspecialchars($this->__get('sql_query'));
+
+        /**
+         * @todo move this to a central place
+         * @todo for other future table types
+         */
+        $is_innodb = (isset($showtable['Type'])
+            && $showtable['Type'] == self::TABLE_TYPE_INNO_DB);
+
+        // Navigation bar
+        $table_navigation_html .= '<table class="navigation nospacing nopadding">'
+            . '<tr>'
+            . '<td class="navigation_separator"></td>';
+
+        // Move to the beginning or to the previous page
+        if ($_SESSION['tmp_user_values']['pos']
+            && ($_SESSION['tmp_user_values']['max_rows'] != self::ALL_ROWS)
+        ) {
+
+            $table_navigation_html
+                .= $this->_getMoveBackwardButtonsForTableNavigation(
+                    $html_sql_query, $pos_prev
+                );
+
+        } // end move back
+
+        $nbTotalPage = 1;
+        //page redirection
+        // (unless we are showing all records)
+        if ($_SESSION['tmp_user_values']['max_rows'] != self::ALL_ROWS) { //if1
+
+            $pageNow = @floor(
+                $_SESSION['tmp_user_values']['pos']
+                / $_SESSION['tmp_user_values']['max_rows']
+            ) + 1;
+
+            $nbTotalPage = @ceil(
+                $this->__get('unlim_num_rows')
+                / $_SESSION['tmp_user_values']['max_rows']
+            );
+
+            if ($nbTotalPage > 1) { //if2
+
+                $table_navigation_html .= '<td>';
+                $_url_params = array(
+                    'db'        => $this->__get('db'),
+                    'table'     => $this->__get('table'),
+                    'sql_query' => $this->__get('sql_query'),
+                    'goto'      => $this->__get('goto'),
+                );
+
+                //<form> to keep the form alignment of button < and <<
+                // and also to know what to execute when the selector changes
+                $table_navigation_html .= '<form action="sql.php'
+                    . PMA_generate_common_url($_url_params)
+                    . '" method="post">';
+
+                $table_navigation_html .= PMA_Util::pageselector(
+                    'pos',
+                    $_SESSION['tmp_user_values']['max_rows'],
+                    $pageNow, $nbTotalPage, 200, 5, 5, 20, 10
+                );
+
+                $table_navigation_html .= '</form>'
+                    . '</td>';
+            } //_if2
+        } //_if1
+
+        // Display the "Show all" button if allowed
+        if (($this->__get('num_rows') < $this->__get('unlim_num_rows'))
+            && ($GLOBALS['cfg']['ShowAll']
+            || ($GLOBALS['cfg']['MaxRows'] * 5 >= $this->__get('unlim_num_rows')))
+        ) {
+
+            $table_navigation_html .= $this->_getShowAllButtonForTableNavigation(
+                $html_sql_query
+            );
+
+        } // end show all
+
+        // Move to the next page or to the last one
+        $endpos = $_SESSION['tmp_user_values']['pos']
+            + $_SESSION['tmp_user_values']['max_rows'];
+
+        if (($endpos < $this->__get('unlim_num_rows'))
+            && ($this->__get('num_rows') >= $_SESSION['tmp_user_values']['max_rows'])
+            && ($_SESSION['tmp_user_values']['max_rows'] != self::ALL_ROWS)
+        ) {
+
+            $table_navigation_html
+                .= $this->_getMoveForwardButtonsForTableNavigation(
+                    $html_sql_query, $pos_next, $is_innodb
+                );
+
+        } // end move toward
+
+        // show separator if pagination happen
+        if ($nbTotalPage > 1) {
+            $table_navigation_html
+                .= '<td><div class="navigation_separator">|</div></td>';
+        }
+
+        $table_navigation_html .= '<td>'
+            . '<div class="save_edited hide">'
+            . '<input type="submit" value="' . __('Save edited data') . '" />'
+            . '<div class="navigation_separator">|</div>'
+            . '</div>'
+            . '</td>'
+            . '<td>'
+            . '<div class="restore_column hide">'
+            . '<input type="submit" value="' . __('Restore column order') . '" />'
+            . '<div class="navigation_separator">|</div>'
+            . '</div>'
+            . '</td>';
+
+        // if displaying a VIEW, $unlim_num_rows could be zero because
+        // of $cfg['MaxExactCountViews']; in this case, avoid passing
+        // the 5th parameter to checkFormElementInRange()
+        // (this means we can't validate the upper limit
+        $table_navigation_html .= '<td class="navigation_goto">';
+
+        $table_navigation_html .= '<form action="sql.php" method="post" '
+            . 'onsubmit="return '
+                . '(checkFormElementInRange('
+                    . 'this, '
+                    . '\'session_max_rows\', '
+                    . '\''
+                    . str_replace('\'', '\\\'', __('%d is not valid row number.'))
+                    . '\', '
+                    . '1)'
+                . ' && '
+                . 'checkFormElementInRange('
+                    . 'this, '
+                    . '\'pos\', '
+                    . '\''
+                    . str_replace('\'', '\\\'', __('%d is not valid row number.'))
+                    . '\', '
+                    . '0'
+                    . (($this->__get('unlim_num_rows') > 0)
+                        ? ', ' . ($this->__get('unlim_num_rows') - 1)
+                        : ''
+                    )
+                    . ')'
+                . ')'
+            .'">';
+
+        $table_navigation_html .= PMA_generate_common_hidden_inputs(
+            $this->__get('db'), $this->__get('table')
+        );
+
+        $table_navigation_html .= $this->_getAdditionalFieldsForTableNavigation(
+            $html_sql_query, $pos_next, $id_for_direction_dropdown
+        );
+
+        $table_navigation_html .= '</form>'
+            . '</td>'
+            . '<td class="navigation_separator"></td>'
+            . '</tr>'
+            . '</table>';
+
+        return $table_navigation_html;
+
+    } // end of the '_getTableNavigation()' function
+
+
+    /**
+     * Prepare move backward buttons - previous and first
+     *
+     * @param string  $html_sql_query the sql encoded by html special characters
+     * @param integer $pos_prev       the offset for the "previous" page
+     *
+     * @return  string                  html content
+     *
+     * @access  private
+     *
+     * @see     _getTableNavigation()
+     */
+    private function _getMoveBackwardButtonsForTableNavigation(
+        $html_sql_query, $pos_prev
+    ) {
+        return $this->_getTableNavigationButton(
+            '<<', _pgettext('First page', 'Begin'), 0, $html_sql_query
+        )
+        . $this->_getTableNavigationButton(
+            '<', _pgettext('Previous page', 'Previous'), $pos_prev,
+            $html_sql_query
+        );
+    } // end of the '_getMoveBackwardButtonsForTableNavigation()' function
+
+
+    /**
+     * Prepare Show All button for table navigation
+     *
+     * @param string $html_sql_query the sql encoded by html special characters
+     *
+     * @return  string                          html content
+     *
+     * @access  private
+     *
+     * @see     _getTableNavigation()
+     */
+    private function _getShowAllButtonForTableNavigation($html_sql_query)
+    {
+        return "\n"
+            . '<td>'
+            . '<form action="sql.php" method="post">'
+            . PMA_generate_common_hidden_inputs(
+                $this->__get('db'), $this->__get('table')
+            )
+            . '<input type="hidden" name="sql_query" value="'
+            . $html_sql_query . '" />'
+            . '<input type="hidden" name="pos" value="0" />'
+            . '<input type="hidden" name="session_max_rows" value="all" />'
+            . '<input type="hidden" name="goto" value="' . $this->__get('goto')
+            . '" />'
+            . '<input type="submit" name="navig" value="' . __('Show all') . '" />'
+            . '</form>'
+            . '</td>';
+    } // end of the '_getShowAllButtonForTableNavigation()' function
+
+
+    /**
+     * Prepare move farward buttons - next and last
+     *
+     * @param string  $html_sql_query the sql encoded by html special characters
+     * @param integer $pos_next       the offset for the "next" page
+     * @param boolean $is_innodb      whether its InnoDB or not
+     *
+     * @return  string  $buttons_html   html content
+     *
+     * @access  private
+     *
+     * @see     _getTableNavigation()
+     */
+    private function _getMoveForwardButtonsForTableNavigation(
+        $html_sql_query, $pos_next, $is_innodb
+    ) {
+
+        // display the Next button
+        $buttons_html = $this->_getTableNavigationButton(
+            '>',
+            _pgettext('Next page', 'Next'),
+            $pos_next,
+            $html_sql_query
+        );
+
+        // prepare some options for the End button
+        if ($is_innodb
+            && $this->__get('unlim_num_rows') > $GLOBALS['cfg']['MaxExactCount']
+        ) {
+            $input_for_real_end = '<input id="real_end_input" type="hidden" '
+                . 'name="find_real_end" value="1" />';
+            // no backquote around this message
+            $onclick = '';
+        } else {
+            $input_for_real_end = $onclick = '';
+        }
+
+        $onsubmit = 'onsubmit="return '
+            . ($_SESSION['tmp_user_values']['pos']
+                + $_SESSION['tmp_user_values']['max_rows']
+                < $this->__get('unlim_num_rows')
+                && $this->__get('num_rows') >= $_SESSION['tmp_user_values']['max_rows'])
+            ? 'true'
+            : 'false' . '"';
+
+        // display the End button
+        $buttons_html .= $this->_getTableNavigationButton(
+            '>>',
+            _pgettext('Last page', 'End'),
+            @((ceil(
+                $this->__get('unlim_num_rows')
+                / $_SESSION['tmp_user_values']['max_rows']
+            )- 1) * $_SESSION['tmp_user_values']['max_rows']),
+            $html_sql_query, $onsubmit, $input_for_real_end, $onclick
+        );
+
+        return $buttons_html;
+
+    } // end of the '_getMoveForwardButtonsForTableNavigation()' function
+
+
+    /**
+     * Prepare feilds followed by Show button for table navigation
+     * Start row, Number of rows, Headers every
+     *
+     * @param string  $html_sql_query            the sql encoded by html special
+     *                                           characters
+     * @param integer $pos_next                  the offset for the "next" page
+     * @param string  $id_for_direction_dropdown the id for the direction dropdown
+     *
+     * @return  string  $additional_fields_html html content
+     *
+     * @access  private
+     *
+     * @see     _getTableNavigation()
+     */
+    private function _getAdditionalFieldsForTableNavigation(
+        $html_sql_query, $pos_next, $id_for_direction_dropdown
+    ) {
+
+        $additional_fields_html = '';
+
+        $additional_fields_html .= '<input type="hidden" name="sql_query" '
+            . 'value="' . $html_sql_query . '" />'
+            . '<input type="hidden" name="goto" value="' . $this->__get('goto')
+            . '" />'
+            . '<input type="submit" name="navig"'
+            . ' class="ajax"'
+            . ' value="' . __('Show') . ' :" />'
+            . __('Start row') . ': ' . "\n"
+            . '<input type="text" name="pos" size="3" value="'
+            . (($pos_next >= $this->__get('unlim_num_rows')) ? 0 : $pos_next)
+            . '" class="textfield" onfocus="this.select()" />'
+            . __('Number of rows') . ': ' . "\n"
+            . '<input type="text" name="session_max_rows" size="3" value="'
+            . (($_SESSION['tmp_user_values']['max_rows'] != self::ALL_ROWS)
+                ? $_SESSION['tmp_user_values']['max_rows']
+                : $GLOBALS['cfg']['MaxRows'])
+            . '" class="textfield" onfocus="this.select()" />';
+
+        if ($GLOBALS['cfg']['ShowDisplayDirection']) {
+            // Display mode (horizontal/vertical and repeat headers)
+            $additional_fields_html .= __('Mode') . ': ' . "\n";
+            $choices = array(
+                    'horizontal'        => __('horizontal'),
+                    'horizontalflipped' => __('horizontal (rotated headers)'),
+                    'vertical'          => __('vertical')
+                );
+
+            $additional_fields_html .= PMA_Util::getDropdown(
+                'disp_direction', $choices,
+                $_SESSION['tmp_user_values']['disp_direction'],
+                $id_for_direction_dropdown
+            );
+            unset($choices);
+        }
+
+        $additional_fields_html .= sprintf(
+            __('Headers every %s rows'),
+            '<input type="text" size="3" name="repeat_cells" value="'
+            . $_SESSION['tmp_user_values']['repeat_cells']
+            . '" class="textfield" /> '
+        );
+
+        return $additional_fields_html;
+
+    } // end of the '_getAdditionalFieldsForTableNavigation()' function
+
+
+    /**
+     * Get the headers of the results table
+     *
+     * @param array   &$is_display                 which elements to display
+     * @param array   $analyzed_sql                the analyzed query
+     * @param string  $sort_expression             sort expression
+     * @param string  $sort_expression_nodirection sort expression without direction
+     * @param string  $sort_direction              sort direction
+     * @param boolean $is_limited_display          with limited operations or not
+     *
+     * @return string                      html content
+     *
+     * @access  private
+     *
+     * @see     getTable()
+     */
+    private function _getTableHeaders(
+        &$is_display, $analyzed_sql = '',
+        $sort_expression = '', $sort_expression_nodirection = '',
+        $sort_direction = '', $is_limited_display = false
+    ) {
+
+        $table_headers_html = '';
+        // Following variable are needed for use in isset/empty or
+        // use with array indexes/safe use in foreach
+        $fields_meta = $this->__get('fields_meta');
+        $highlight_columns = $this->__get('highlight_columns');
+        $printview = $this->__get('printview');
+        $vertical_display = $this->__get('vertical_display');
+
+        // required to generate sort links that will remember whether the
+        // "Show all" button has been clicked
+        $sql_md5 = md5($this->__get('sql_query'));
+        $session_max_rows = $is_limited_display
+            ? 0
+            : $_SESSION['tmp_user_values']['query'][$sql_md5]['max_rows'];
+
+        $direction = isset($_SESSION['tmp_user_values']['disp_direction'])
+            ? $_SESSION['tmp_user_values']['disp_direction']
+            : '';
+
+        if ($analyzed_sql == '') {
+            $analyzed_sql = array();
+        }
+
+        $directionCondition = ($direction == self::DISP_DIR_HORIZONTAL)
+            || ($direction == self::DISP_DIR_HORIZONTAL_FLIPPED);
+
+        // can the result be sorted?
+        if ($is_display['sort_lnk'] == '1') {
+
+            list($unsorted_sql_query, $drop_down_html)
+                = $this->_getUnsortedSqlAndSortByKeyDropDown(
+                    $analyzed_sql, $sort_expression
+                );
+
+            $table_headers_html .= $drop_down_html;
+
+        }
+
+        // Output data needed for grid editing
+        $table_headers_html .= '<input id="save_cells_at_once" type="hidden" value="'
+            . $GLOBALS['cfg']['SaveCellsAtOnce'] . '" />'
+            . '<div class="common_hidden_inputs">'
+            . PMA_generate_common_hidden_inputs(
+                $this->__get('db'), $this->__get('table')
+            )
+            . '</div>';
+
+        // Output data needed for column reordering and show/hide column
+        if ($this->_isSelect($analyzed_sql)) {
+            $table_headers_html .= $this->_getDataForResettingColumnOrder();
+        }
+
+        $vertical_display['emptypre']   = 0;
+        $vertical_display['emptyafter'] = 0;
+        $vertical_display['textbtn']    = '';
+        $full_or_partial_text_link = null;
+
+        $this->__set('vertical_display', $vertical_display);
+
+        // Display options (if we are not in print view)
+        if (! (isset($printview) && ($printview == '1')) && ! $is_limited_display) {
+
+            $table_headers_html .= $this->_getOptionsBlock();
+
+            // prepare full/partial text button or link
+            $full_or_partial_text_link = $this->_getFullOrPartialTextButtonOrLink();
+        }
+
+        // Start of form for multi-rows edit/delete/export
+        $table_headers_html .= $this->_getFormForMultiRowOperations(
+            $is_display['del_lnk']
+        );
+
+        // 1. Set $colspan or $rowspan and generate html with full/partial
+        // text button or link
+        list($colspan, $rowspan, $button_html)
+            = $this->_getFieldVisibilityParams(
+                $directionCondition, $is_display, $full_or_partial_text_link
+            );
+
+        $table_headers_html .= $button_html;
+
+        // 2. Displays the fields' name
+        // 2.0 If sorting links should be used, checks if the query is a "JOIN"
+        //     statement (see 2.1.3)
+
+        // 2.0.1 Prepare Display column comments if enabled
+        //       ($GLOBALS['cfg']['ShowBrowseComments']).
+        //       Do not show comments, if using horizontalflipped mode,
+        //       because of space usage
+        $comments_map = $this->_getTableCommentsArray($direction, $analyzed_sql);
+
+        if ($GLOBALS['cfgRelation']['commwork']
+            && $GLOBALS['cfgRelation']['mimework']
+            && $GLOBALS['cfg']['BrowseMIME']
+            && ! $_SESSION['tmp_user_values']['hide_transformation']
+        ) {
+            include_once './libraries/transformations.lib.php';
+            $this->__set(
+                'mime_map',
+                PMA_getMIME($this->__get('db'), $this->__get('table'))
+            );
+        }
+
+        // See if we have to highlight any header fields of a WHERE query.
+        // Uses SQL-Parser results.
+        $this->_setHighlightedColumnGlobalField($analyzed_sql);
+
+        list($col_order, $col_visib) = $this->_getColumnParams($analyzed_sql);
+
+        for ($j = 0; $j < $this->__get('fields_cnt'); $j++) {
+
+            // assign $i with appropriate column order
+            $i = $col_order ? $col_order[$j] : $j;
+
+            //  See if this column should get highlight because it's used in the
+            //  where-query.
+            $condition_field = (isset($highlight_columns[$fields_meta[$i]->name])
+                || isset($highlight_columns[PMA_Util::backquote($fields_meta[$i]->name)]))
+                ? true
+                : false;
+
+            // 2.0 Prepare comment-HTML-wrappers for each row, if defined/enabled.
+            $comments = $this->_getCommentForRow($comments_map, $fields_meta[$i]);
+
+            $vertical_display = $this->__get('vertical_display');
+
+            if (($is_display['sort_lnk'] == '1') && ! $is_limited_display) {
+
+                list($order_link, $sorted_headrer_html)
+                    = $this->_getOrderLinkAndSortedHeaderHtml(
+                        $fields_meta[$i], $sort_expression,
+                        $sort_expression_nodirection, $i, $unsorted_sql_query,
+                        $session_max_rows, $direction, $comments,
+                        $sort_direction, $directionCondition, $col_visib,
+                        $col_visib[$j], $condition_field
+                    );
+
+                $table_headers_html .= $sorted_headrer_html;
+
+                $vertical_display['desc'][] = '    <th '
+                    . 'class="draggable'
+                    . ($condition_field ? ' condition' : '')
+                    . '" data-column="' . htmlspecialchars($fields_meta[$i]->name)
+                    . '">' . "\n" . $order_link . $comments . '    </th>' . "\n";
+            } else {
+                // 2.2 Results can't be sorted
+
+                if ($directionCondition) {
+                    $table_headers_html
+                        .= $this->_getDraggableClassForNonSortableColumns(
+                            $col_visib, $col_visib[$j], $condition_field,
+                            $direction, $fields_meta[$i], $comments
+                        );
+                }
+
+                $vertical_display['desc'][] = '    <th '
+                    . 'class="draggable'
+                    . ($condition_field ? ' condition"' : '')
+                    . '" data-column="' . htmlspecialchars($fields_meta[$i]->name)
+                    . '">' . "\n" . '        '
+                    . htmlspecialchars($fields_meta[$i]->name)
+                    . "\n" . $comments . '    </th>';
+            } // end else (2.2)
+
+            $this->__set('vertical_display', $vertical_display);
+
+        } // end for
+
+        // Display column at rightside - checkboxes or empty column
+        $table_headers_html .= $this->_getColumnAtRightSide(
+            $is_display, $directionCondition, $full_or_partial_text_link,
+            $colspan, $rowspan
+        );
+
+        if ($directionCondition) {
+            $table_headers_html .= '</tr>'
+                . '</thead>';
+        }
+
+        return $table_headers_html;
+
+    } // end of the '_getTableHeaders()' function
+
+
+    /**
+     * Prepare unsorted sql query and sort by key drop down
+     *
+     * @param array  $analyzed_sql    the analyzed query
+     * @param string $sort_expression sort expression
+     *
+     * @return  array   two element array - $unsorted_sql_query, $drop_down_html
+     *
+     * @access  private
+     *
+     * @see     _getTableHeaders()
+     */
+    private function _getUnsortedSqlAndSortByKeyDropDown(
+        $analyzed_sql, $sort_expression
+    ) {
+
+        $drop_down_html = '';
+
+        // Just as fallback
+        $unsorted_sql_query     = $this->__get('sql_query');
+        if (isset($analyzed_sql[0]['unsorted_query'])) {
+            $unsorted_sql_query = $analyzed_sql[0]['unsorted_query'];
+        }
+        // Handles the case of multiple clicks on a column's header
+        // which would add many spaces before "ORDER BY" in the
+        // generated query.
+        $unsorted_sql_query = trim($unsorted_sql_query);
+
+        // sorting by indexes, only if it makes sense (only one table ref)
+        if (isset($analyzed_sql)
+            && isset($analyzed_sql[0])
+            && isset($analyzed_sql[0]['querytype'])
+            && ($analyzed_sql[0]['querytype'] == self::QUERY_TYPE_SELECT)
+            && isset($analyzed_sql[0]['table_ref'])
+            && (count($analyzed_sql[0]['table_ref']) == 1)
+        ) {
+            // grab indexes data:
+            $indexes = PMA_Index::getFromTable(
+                $this->__get('table'),
+                $this->__get('db')
+            );
+
+            // do we have any index?
+            if ($indexes) {
+                $drop_down_html = $this->_getSortByKeyDropDown(
+                    $indexes, $sort_expression,
+                    $unsorted_sql_query
+                );
+            }
+        }
+
+        return array($unsorted_sql_query, $drop_down_html);
+
+    } // end of the '_getUnsortedSqlAndSortByKeyDropDown()' function
+
+
+    /**
+     * Prepare sort by key dropdown - html code segment
+     *
+     * @param array  $indexes            the indexes of the table for sort criteria
+     * @param string $sort_expression    the sort expression
+     * @param string $unsorted_sql_query the unsorted sql query
+     *
+     * @return  string  $drop_down_html         html content
+     *
+     * @access  private
+     *
+     * @see     _getTableHeaders()
+     */
+    private function _getSortByKeyDropDown(
+        $indexes, $sort_expression, $unsorted_sql_query
+    ) {
+
+        $drop_down_html = '';
+
+        $drop_down_html .= '<form action="sql.php" method="post">' . "\n"
+            . PMA_generate_common_hidden_inputs(
+                $this->__get('db'), $this->__get('table')
+            )
+            . __('Sort by key')
+            . ': <select name="sql_query" class="autosubmit">' . "\n";
+
+        $used_index = false;
+        $local_order = (isset($sort_expression) ? $sort_expression : '');
+
+        foreach ($indexes as $index) {
+
+            $asc_sort = '`'
+                . implode('` ASC, `', array_keys($index->getColumns()))
+                . '` ASC';
+
+            $desc_sort = '`'
+                . implode('` DESC, `', array_keys($index->getColumns()))
+                . '` DESC';
+
+            $used_index = $used_index
+                || ($local_order == $asc_sort)
+                || ($local_order == $desc_sort);
+
+            if (preg_match(
+                '@(.*)([[:space:]](LIMIT (.*)|PROCEDURE (.*)|'
+                . 'FOR UPDATE|LOCK IN SHARE MODE))@is',
+                $unsorted_sql_query, $my_reg
+            )) {
+                $unsorted_sql_query_first_part = $my_reg[1];
+                $unsorted_sql_query_second_part = $my_reg[2];
+            } else {
+                $unsorted_sql_query_first_part = $unsorted_sql_query;
+                $unsorted_sql_query_second_part = '';
+            }
+
+            $drop_down_html .= '<option value="'
+                . htmlspecialchars(
+                    $unsorted_sql_query_first_part  . "\n"
+                    . ' ORDER BY ' . $asc_sort
+                    . $unsorted_sql_query_second_part
+                )
+                . '"' . ($local_order == $asc_sort
+                    ? ' selected="selected"'
+                    : '')
+                . '>' . htmlspecialchars($index->getName()) . ' ('
+                . __('Ascending') . ')</option>';
+
+            $drop_down_html .= '<option value="'
+                . htmlspecialchars(
+                    $unsorted_sql_query_first_part . "\n"
+                    . ' ORDER BY ' . $desc_sort
+                    . $unsorted_sql_query_second_part
+                )
+                . '"' . ($local_order == $desc_sort
+                    ? ' selected="selected"'
+                    : '')
+                . '>' . htmlspecialchars($index->getName()) . ' ('
+                . __('Descending') . ')</option>';
+        }
+
+        $drop_down_html .= '<option value="' . htmlspecialchars($unsorted_sql_query)
+            . '"' . ($used_index ? '' : ' selected="selected"') . '>' . __('None')
+            . '</option>'
+            . '</select>' . "\n"
+            . '</form>' . "\n";
+
+        return $drop_down_html;
+
+    } // end of the '_getSortByKeyDropDown()' function
+
+
+    /**
+     * Set column span, row span and prepare html with full/partial
+     * text button or link
+     *
+     * @param boolean $directionCondition        display direction horizontal or
+     *                                           horizontalflipped
+     * @param array   &$is_display               which elements to display
+     * @param string  $full_or_partial_text_link full/partial link or text button
+     *
+     * @return  array   3 element array - $colspan, $rowspan, $button_html
+     *
+     * @access  private
+     *
+     * @see     _getTableHeaders()
+     */
+    private function _getFieldVisibilityParams(
+        $directionCondition, &$is_display, $full_or_partial_text_link
+    ) {
+
+        $button_html = '';
+        $colspan = $rowspan = null;
+        $vertical_display = $this->__get('vertical_display');
+
+        // 1. Displays the full/partial text button (part 1)...
+        if ($directionCondition) {
+
+            $button_html .= '<thead><tr>' . "\n";
+
+            $colspan = (($is_display['edit_lnk'] != self::NO_EDIT_OR_DELETE)
+                && ($is_display['del_lnk'] != self::NO_EDIT_OR_DELETE))
+                ? ' colspan="4"'
+                : '';
+
+        } else {
+            $rowspan = (($is_display['edit_lnk'] != self::NO_EDIT_OR_DELETE)
+                && ($is_display['del_lnk'] != self::NO_EDIT_OR_DELETE))
+                ? ' rowspan="4"'
+                : '';
+        }
+
+        //     ... before the result table
+        if ((($is_display['edit_lnk'] == self::NO_EDIT_OR_DELETE)
+            && ($is_display['del_lnk'] == self::NO_EDIT_OR_DELETE))
+            && ($is_display['text_btn'] == '1')
+        ) {
+
+            $vertical_display['emptypre']
+                = (($is_display['edit_lnk'] != self::NO_EDIT_OR_DELETE)
+                && ($is_display['del_lnk'] != self::NO_EDIT_OR_DELETE)) ? 4 : 0;
+
+            if ($directionCondition) {
+
+                $button_html .= '<th colspan="' . $this->__get('fields_cnt') . '">'
+                    . '</th>'
+                    . '</tr>'
+                    . '<tr>';
+
+                // end horizontal/horizontalflipped mode
+            } else {
+
+                $span = $this->__get('num_rows') + 1 + floor(
+                    $this->__get('num_rows')
+                    / $_SESSION['tmp_user_values']['repeat_cells']
+                );
+                $button_html .= '<tr><th colspan="' . $span . '"></th></tr>';
+
+            } // end vertical mode
+
+        } elseif ((($GLOBALS['cfg']['RowActionLinks'] == self::POSITION_LEFT)
+            || ($GLOBALS['cfg']['RowActionLinks'] == self::POSITION_BOTH))
+            && ($is_display['text_btn'] == '1')
+        ) {
+            //     ... at the left column of the result table header if possible
+            //     and required
+
+            $vertical_display['emptypre']
+                = (($is_display['edit_lnk'] != self::NO_EDIT_OR_DELETE)
+                && ($is_display['del_lnk'] != self::NO_EDIT_OR_DELETE)) ? 4 : 0;
+
+            if ($directionCondition) {
+
+                $button_html .= '<th ' . $colspan . '>'
+                    . $full_or_partial_text_link . '</th>';
+                // end horizontal/horizontalflipped mode
+
+            } else {
+
+                $vertical_display['textbtn']
+                    = '    <th ' . $rowspan . ' class="vmiddle">' . "\n"
+                    . '        ' . "\n"
+                    . '    </th>' . "\n";
+            } // end vertical mode
+
+        } elseif ((($GLOBALS['cfg']['RowActionLinks'] == self::POSITION_LEFT)
+            || ($GLOBALS['cfg']['RowActionLinks'] == self::POSITION_BOTH))
+            && (($is_display['edit_lnk'] != self::NO_EDIT_OR_DELETE)
+            || ($is_display['del_lnk'] != self::NO_EDIT_OR_DELETE))
+        ) {
+            //     ... elseif no button, displays empty(ies) col(s) if required
+
+            $vertical_display['emptypre']
+                = (($is_display['edit_lnk'] != self::NO_EDIT_OR_DELETE)
+                && ($is_display['del_lnk'] != self::NO_EDIT_OR_DELETE)) ? 4 : 0;
+
+            if ($directionCondition) {
+
+                $button_html .= '<td ' . $colspan . '></td>';
+
+                // end horizontal/horizontalfipped mode
+            } else {
+                $vertical_display['textbtn'] = '    <td' . $rowspan .
+                    '></td>' . "\n";
+            } // end vertical mode
+
+        } elseif (($GLOBALS['cfg']['RowActionLinks'] == self::POSITION_NONE)
+            && ($directionCondition)
+        ) {
+            // ... elseif display an empty column if the actions links are
+            //  disabled to match the rest of the table
+            $button_html .= '<th></th>';
+        }
+
+        $this->__set('vertical_display', $vertical_display);
+
+        return array($colspan, $rowspan, $button_html);
+
+    } // end of the '_getFieldVisibilityParams()' function
+
+
+    /**
+     * Get table comments as array
+     *
+     * @param boolean $direction    display direction, horizontal
+     *                              or horizontalflipped
+     * @param array   $analyzed_sql the analyzed query
+     *
+     * @return  array $comments_map table comments when condition true
+     *          null                when condition falls
+     *
+     * @access  private
+     *
+     * @see     _getTableHeaders()
+     */
+    private function _getTableCommentsArray($direction, $analyzed_sql)
+    {
+
+        $comments_map = null;
+
+        if ($GLOBALS['cfg']['ShowBrowseComments']
+            && ($direction != self::DISP_DIR_HORIZONTAL_FLIPPED)
+        ) {
+            $comments_map = array();
+            if (isset($analyzed_sql[0])
+                && is_array($analyzed_sql[0])
+                && isset($analyzed_sql[0]['table_ref'])
+            ) {
+                foreach ($analyzed_sql[0]['table_ref'] as $tbl) {
+                    $tb = $tbl['table_true_name'];
+                    $comments_map[$tb] = PMA_getComments($this->__get('db'), $tb);
+                    unset($tb);
+                }
+            }
+        }
+
+        return $comments_map;
+
+    } // end of the '_getTableCommentsArray()' function
+
+
+    /**
+     * Set global array for store highlighted header fields
+     *
+     * @param array $analyzed_sql the analyzed query
+     *
+     * @return  void
+     *
+     * @access  private
+     *
+     * @see     _getTableHeaders()
+     */
+    private function _setHighlightedColumnGlobalField($analyzed_sql)
+    {
+
+        $highlight_columns = array();
+        if (isset($analyzed_sql) && isset($analyzed_sql[0])
+            && isset($analyzed_sql[0]['where_clause_identifiers'])
+        ) {
+
+            $wi = 0;
+            if (isset($analyzed_sql[0]['where_clause_identifiers'])
+                && is_array($analyzed_sql[0]['where_clause_identifiers'])
+            ) {
+                foreach ($analyzed_sql[0]['where_clause_identifiers']
+                    as $wci_nr => $wci
+                ) {
+                    $highlight_columns[$wci] = 'true';
+                }
+            }
+        }
+
+        $this->__set('highlight_columns', $highlight_columns);
+
+    } // end of the '_setHighlightedColumnGlobalField()' function
+
+
+    /**
+     * Prepare data for column restoring and show/hide
+     *
+     * @return  string  $data_html      html content
+     *
+     * @access  private
+     *
+     * @see     _getTableHeaders()
+     */
+    private function _getDataForResettingColumnOrder()
+    {
+
+        $data_html = '';
+
+        // generate the column order, if it is set
+        $pmatable = new PMA_Table($this->__get('table'), $this->__get('db'));
+        $col_order = $pmatable->getUiProp(PMA_Table::PROP_COLUMN_ORDER);
+
+        if ($col_order) {
+            $data_html .= '<input id="col_order" type="hidden" value="'
+                . implode(',', $col_order) . '" />';
+        }
+
+        $col_visib = $pmatable->getUiProp(PMA_Table::PROP_COLUMN_VISIB);
+
+        if ($col_visib) {
+            $data_html .= '<input id="col_visib" type="hidden" value="'
+                . implode(',', $col_visib) . '" />';
+        }
+
+        // generate table create time
+        if (! PMA_Table::isView($this->__get('db'), $this->__get('table'))) {
+            $data_html .= '<input id="table_create_time" type="hidden" value="'
+                . PMA_Table::sGetStatusInfo(
+                    $this->__get('db'), $this->__get('table'), 'Create_time'
+                ) . '" />';
+        }
+
+        return $data_html;
+
+    } // end of the '_getDataForResettingColumnOrder()' function
+
+
+    /**
+     * Prepare option fields block
+     *
+     * @return  string  $options_html   html content
+     *
+     * @access  private
+     *
+     * @see     _getTableHeaders()
+     */
+    private function  _getOptionsBlock()
+    {
+
+        $options_html = '';
+
+        $options_html .= '<form method="post" action="sql.php" '
+            . 'name="displayOptionsForm" '
+            . 'id="displayOptionsForm"';
+
+        $options_html .= ' class="ajax" ';
+
+        $options_html .= '>';
+        $url_params = array(
+            'db' => $this->__get('db'),
+            'table' => $this->__get('table'),
+            'sql_query' => $this->__get('sql_query'),
+            'goto' => $this->__get('goto'),
+            'display_options_form' => 1
+        );
+
+        $options_html .= PMA_generate_common_hidden_inputs($url_params)
+            . '<br />'
+            . PMA_Util::getDivForSliderEffect(
+                'displayoptions', __('Options')
+            )
+            . '<fieldset>';
+
+        $options_html .= '<div class="formelement">';
+        $choices = array(
+            'P'   => __('Partial texts'),
+            'F'   => __('Full texts')
+        );
+
+        $options_html .= PMA_Util::getRadioFields(
+            'display_text', $choices,
+            $_SESSION['tmp_user_values']['display_text']
+        )
+        . '</div>';
+
+        if ($GLOBALS['cfgRelation']['relwork']
+            && $GLOBALS['cfgRelation']['displaywork']
+        ) {
+            $options_html .= '<div class="formelement">';
+            $choices = array(
+                'K'   => __('Relational key'),
+                'D'   => __('Relational display column')
+            );
+
+            $options_html .= PMA_Util::getRadioFields(
+                'relational_display', $choices,
+                $_SESSION['tmp_user_values']['relational_display']
+            )
+            . '</div>';
+        }
+
+        $options_html .= '<div class="formelement">'
+            . PMA_Util::getCheckbox(
+                'display_binary', __('Show binary contents'),
+                ! empty($_SESSION['tmp_user_values']['display_binary']), false
+            )
+            . '<br />'
+            . PMA_Util::getCheckbox(
+                'display_blob', __('Show BLOB contents'),
+                ! empty($_SESSION['tmp_user_values']['display_blob']), false
+            )
+            . '<br />'
+            . PMA_Util::getCheckbox(
+                'display_binary_as_hex', __('Show binary contents as HEX'),
+                ! empty($_SESSION['tmp_user_values']['display_binary_as_hex']), false
+            )
+            . '</div>';
+
+        // I would have preferred to name this "display_transformation".
+        // This is the only way I found to be able to keep this setting sticky
+        // per SQL query, and at the same time have a default that displays
+        // the transformations.
+        $options_html .= '<div class="formelement">'
+            . PMA_Util::getCheckbox(
+                'hide_transformation', __('Hide browser transformation'),
+                ! empty($_SESSION['tmp_user_values']['hide_transformation']), false
+            )
+            . '</div>';
+
+        if (! PMA_DRIZZLE) {
+            $options_html .= '<div class="formelement">';
+            $choices = array(
+                'GEOM'  => __('Geometry'),
+                'WKT'   => __('Well Known Text'),
+                'WKB'   => __('Well Known Binary')
+            );
+
+            $options_html .= PMA_Util::getRadioFields(
+                'geometry_display', $choices,
+                $_SESSION['tmp_user_values']['geometry_display']
+            )
+                . '</div>';
+        }
+
+        $options_html .= '<div class="clearfloat"></div>'
+            . '</fieldset>';
+
+        $options_html .= '<fieldset class="tblFooters">'
+            . '<input type="submit" value="' . __('Go') . '" />'
+            . '</fieldset>'
+            . '</div>'
+            . '</form>';
+
+        return $options_html;
+
+    } // end of the '_getOptionsBlock()' function
+
+
+    /**
+     * Get full/partial text button or link
+     *
+     * @return string html content
+     *
+     * @access  private
+     *
+     * @see     _getTableHeaders()
+     */
+    private function _getFullOrPartialTextButtonOrLink()
+    {
+
+        $url_params_full_text = array(
+            'db' => $this->__get('db'),
+            'table' => $this->__get('table'),
+            'sql_query' => $this->__get('sql_query'),
+            'goto' => $this->__get('goto'),
+            'full_text_button' => 1
+        );
+
+        if ($_SESSION['tmp_user_values']['display_text'] == self::DISPLAY_FULL_TEXT) {
+            // currently in fulltext mode so show the opposite link
+            $tmp_image_file = $this->__get('pma_theme_image') . 's_partialtext.png';
+            $tmp_txt = __('Partial texts');
+            $url_params_full_text['display_text'] = self::DISPLAY_PARTIAL_TEXT;
+        } else {
+            $tmp_image_file = $this->__get('pma_theme_image') . 's_fulltext.png';
+            $tmp_txt = __('Full texts');
+            $url_params_full_text['display_text'] = self::DISPLAY_FULL_TEXT;
+        }
+
+        $tmp_image = '<img class="fulltext" src="' . $tmp_image_file . '" alt="'
+                     . $tmp_txt . '" title="' . $tmp_txt . '" />';
+        $tmp_url = 'sql.php' . PMA_generate_common_url($url_params_full_text);
+
+        return PMA_Util::linkOrButton(
+            $tmp_url, $tmp_image, array(), false
+        );
+
+    } // end of the '_getFullOrPartialTextButtonOrLink()' function
+
+
+    /**
+     * Prepare html form for multi row operations
+     *
+     * @param string $del_lnk the delete link of current row
+     *
+     * @return  string  $form_html          html content
+     *
+     * @access  private
+     *
+     * @see     _getTableHeaders()
+     */
+    private function _getFormForMultiRowOperations($del_lnk)
+    {
+
+        $form_html = '';
+
+        if (($del_lnk == self::DELETE_ROW) || ($del_lnk == self::KILL_PROCESS)) {
+
+            $form_html .= '<form method="post" action="tbl_row_action.php" '
+                . 'name="resultsForm" id="resultsForm"';
+
+            $form_html .= ' class="ajax" ';
+
+            $form_html .= '>'
+                . PMA_generate_common_hidden_inputs(
+                    $this->__get('db'), $this->__get('table'), 1
+                )
+                . '<input type="hidden" name="goto" value="sql.php" />';
+        }
+
+        $form_html .= '<table id="table_results" class="data';
+        $form_html .= ' ajax';
+        $form_html .= '">';
+
+        return $form_html;
+
+    } // end of the '_getFormForMultiRowOperations()' function
+
+
+    /**
+     * Get comment for row
+     *
+     * @param array $comments_map comments array
+     * @param array $fields_meta  set of field properties
+     *
+     * @return  string  $comment        html content
+     *
+     * @access  private
+     *
+     * @see     _getTableHeaders()
+     */
+    private function _getCommentForRow($comments_map, $fields_meta)
+    {
+        $comments = '';
+        if (isset($comments_map)
+            && isset($comments_map[$fields_meta->table])
+            && isset($comments_map[$fields_meta->table][$fields_meta->name])
+        ) {
+            $comments = '<span class="tblcomment">'
+                . htmlspecialchars(
+                    $comments_map[$fields_meta->table][$fields_meta->name]
+                )
+                . '</span>';
+        }
+        return $comments;
+    } // end of the '_getCommentForRow()' function
+
+
+    /**
+     * Prepare parameters and html for sorted table header fields
+     *
+     * @param array   $fields_meta                 set of field properties
+     * @param string  $sort_expression             sort expression
+     * @param string  $sort_expression_nodirection sort expression without direction
+     * @param integer $column_index                the index of the column
+     * @param string  $unsorted_sql_query          the unsorted sql query
+     * @param integer $session_max_rows            maximum rows resulted by sql
+     * @param string  $direction                   the display direction
+     * @param string  $comments                    comment for row
+     * @param string  $sort_direction              sort direction
+     * @param boolean $directionCondition          display direction horizontal
+     *                                             or horizontalflipped
+     * @param boolean $col_visib                   column is visible(false)
+     *        array                                column isn't visible(string array)
+     * @param string  $col_visib_j                 element of $col_visib array
+     * @param boolean $condition_field             whether the column is a part of
+     *                                             the where clause
+     *
+     * @return  array   2 element array - $order_link, $sorted_header_html
+     *
+     * @access  private
+     *
+     * @see     _getTableHeaders()
+     */
+    private function _getOrderLinkAndSortedHeaderHtml(
+        $fields_meta, $sort_expression, $sort_expression_nodirection,
+        $column_index, $unsorted_sql_query, $session_max_rows, $direction,
+        $comments, $sort_direction, $directionCondition, $col_visib,
+        $col_visib_j, $condition_field
+    ) {
+
+        $sorted_header_html = '';
+
+        // Checks if the table name is required; it's the case
+        // for a query with a "JOIN" statement and if the column
+        // isn't aliased, or in queries like
+        // SELECT `1`.`master_field` , `2`.`master_field`
+        // FROM `PMA_relation` AS `1` , `PMA_relation` AS `2`
+
+        $sort_tbl = (isset($fields_meta->table)
+            && strlen($fields_meta->table))
+            ? PMA_Util::backquote(
+                $fields_meta->table
+            ) . '.'
+            : '';
+
+        // Checks if the current column is used to sort the
+        // results
+        // the orgname member does not exist for all MySQL versions
+        // but if found, it's the one on which to sort
+        $name_to_use_in_sort = $fields_meta->name;
+        $is_orgname = false;
+        if (isset($fields_meta->orgname)
+            && strlen($fields_meta->orgname)
+        ) {
+            $name_to_use_in_sort = $fields_meta->orgname;
+            $is_orgname = true;
+        }
+
+        // $name_to_use_in_sort might contain a space due to
+        // formatting of function expressions like "COUNT(name )"
+        // so we remove the space in this situation
+        $name_to_use_in_sort = str_replace(' )', ')', $name_to_use_in_sort);
+
+        $is_in_sort = $this->_isInSorted(
+            $sort_expression, $sort_expression_nodirection,
+            $sort_tbl, $name_to_use_in_sort
+        );
+
+        // Check the field name for a bracket.
+        // If it contains one, it's probably a function column
+        // like 'COUNT(`field`)'
+        // It still might be a column name of a view. See bug #3383711
+        // Check is_orgname.
+        if ((strpos($name_to_use_in_sort, '(') !== false) && ! $is_orgname) {
+            $sort_order = "\n" . 'ORDER BY ' . $name_to_use_in_sort . ' ';
+        } else {
+            $sort_order = "\n" . 'ORDER BY ' . $sort_tbl
+                . PMA_Util::backquote(
+                    $name_to_use_in_sort
+                ) . ' ';
+        }
+        unset($name_to_use_in_sort);
+        unset($is_orgname);
+
+        // Do define the sorting URL
+
+        list($sort_order, $order_img) = $this->_getSortingUrlParams(
+            $is_in_sort, $sort_direction, $fields_meta,
+            $sort_order, $column_index
+        );
+
+        if (preg_match(
+            '@(.*)([[:space:]](LIMIT (.*)|PROCEDURE (.*)|FOR UPDATE|'
+            . 'LOCK IN SHARE MODE))@is',
+            $unsorted_sql_query, $regs3
+        )) {
+            $sorted_sql_query = $regs3[1] . $sort_order . $regs3[2];
+        } else {
+            $sorted_sql_query = $unsorted_sql_query . $sort_order;
+        }
+
+        $_url_params = array(
+            'db'                => $this->__get('db'),
+            'table'             => $this->__get('table'),
+            'sql_query'         => $sorted_sql_query,
+            'session_max_rows'  => $session_max_rows
+        );
+        $order_url  = 'sql.php' . PMA_generate_common_url($_url_params);
+
+        // Displays the sorting URL
+        // enable sort order swapping for image
+        $order_link = $this->_getSortOrderLink(
+            $order_img, $column_index, $direction,
+            $fields_meta, $order_url
+        );
+
+        if ($directionCondition) {
+            $sorted_header_html .= $this->_getDraggableClassForSortableColumns(
+                $col_visib, $col_visib_j, $condition_field, $direction,
+                $fields_meta, $order_link, $comments
+            );
+        }
+
+        return array($order_link, $sorted_header_html);
+
+    } // end of the '_getOrderLinkAndSortedHeaderHtml()' function
+
+
+    /**
+     * Check whether the column is sorted
+     *
+     * @param string $sort_expression             sort expression
+     * @param string $sort_expression_nodirection sort expression without direction
+     * @param string $sort_tbl                    the table name
+     * @param string $name_to_use_in_sort         the sorting column name
+     *
+     * @return boolean $is_in_sort                   the column sorted or not
+     *
+     * @access  private
+     *
+     * @see     _getTableHeaders()
+     */
+    private function _isInSorted(
+        $sort_expression, $sort_expression_nodirection, $sort_tbl,
+        $name_to_use_in_sort
+    ) {
+
+        if (empty($sort_expression)) {
+            $is_in_sort = false;
+        } else {
+            // Field name may be preceded by a space, or any number
+            // of characters followed by a dot (tablename.fieldname)
+            // so do a direct comparison for the sort expression;
+            // this avoids problems with queries like
+            // "SELECT id, count(id)..." and clicking to sort
+            // on id or on count(id).
+            // Another query to test this:
+            // SELECT p.*, FROM_UNIXTIME(p.temps) FROM mytable AS p
+            // (and try clicking on each column's header twice)
+            if (! empty($sort_tbl)
+                && strpos($sort_expression_nodirection, $sort_tbl) === false
+                && strpos($sort_expression_nodirection, '(') === false
+            ) {
+                $new_sort_expression_nodirection = $sort_tbl
+                    . $sort_expression_nodirection;
+            } else {
+                $new_sort_expression_nodirection = $sort_expression_nodirection;
+            }
+
+            $is_in_sort = false;
+            $sort_name = str_replace('`', '', $sort_tbl) . $name_to_use_in_sort;
+
+            if ($sort_name == str_replace('`', '', $new_sort_expression_nodirection)
+                || $sort_name == str_replace('`', '', $sort_expression_nodirection)
+            ) {
+                $is_in_sort = true;
+            }
+        }
+
+        return $is_in_sort;
+
+    } // end of the '_isInSorted()' function
+
+
+    /**
+     * Get sort url paramaeters - sort order and order image
+     *
+     * @param boolean $is_in_sort     the column sorted or not
+     * @param string  $sort_direction the sort direction
+     * @param array   $fields_meta    set of field properties
+     * @param string  $sort_order     the sorting order
+     * @param integer $column_index   the index of the column
+     *
+     * @return  array                       2 element array - $sort_order, $order_img
+     *
+     * @access  private
+     *
+     * @see     _getTableHeaders()
+     */
+    private function _getSortingUrlParams(
+        $is_in_sort, $sort_direction, $fields_meta, $sort_order, $column_index
+    ) {
+
+        if (! $is_in_sort) {
+
+            // patch #455484 ("Smart" order)
+            $GLOBALS['cfg']['Order'] = strtoupper($GLOBALS['cfg']['Order']);
+
+            if ($GLOBALS['cfg']['Order'] === self::SMART_SORT_ORDER) {
+                $sort_order .= (preg_match(
+                    '@time|date at i',
+                    $fields_meta->type
+                )) ? self::DESCENDING_SORT_DIR : self::ASCENDING_SORT_DIR;
+            } else {
+                $sort_order .= $GLOBALS['cfg']['Order'];
+            }
+            $order_img   = '';
+
+        } elseif ($sort_direction == self::DESCENDING_SORT_DIR) {
+
+            $sort_order .= ' ASC';
+            $order_img   = ' ' . PMA_Util::getImage(
+                's_desc.png', __('Descending'),
+                array('class' => "soimg$column_index", 'title' => '')
+            );
+
+            $order_img  .= ' ' . PMA_Util::getImage(
+                's_asc.png', __('Ascending'),
+                array('class' => "soimg$column_index hide", 'title' => '')
+            );
+
+        } else {
+
+            $sort_order .= ' DESC';
+            $order_img   = ' ' . PMA_Util::getImage(
+                's_asc.png', __('Ascending'),
+                array('class' => "soimg$column_index", 'title' => '')
+            );
+
+            $order_img  .= ' ' . PMA_Util::getImage(
+                's_desc.png', __('Descending'),
+                array('class' => "soimg$column_index hide", 'title' => '')
+            );
+        }
+
+        return array($sort_order, $order_img);
+
+    } // end of the '_getSortingUrlParams()' function
+
+
+    /**
+     * Get sort order link
+     *
+     * @param string  $order_img   the sort order image
+     * @param integer $col_index   the index of the column
+     * @param string  $direction   the display direction
+     * @param array   $fields_meta set of field properties
+     * @param string  $order_url   the url for sort
+     *
+     * @return  string                      the sort order link
+     *
+     * @access  private
+     *
+     * @see     _getTableHeaders()
+     */
+    private function _getSortOrderLink(
+        $order_img, $col_index, $direction, $fields_meta, $order_url
+    ) {
+
+        $order_link_params = array();
+
+        if (isset($order_img) && ($order_img != '')) {
+            if (strstr($order_img, 'asc')) {
+                $order_link_params['onmouseover'] = "$('.soimg$col_index').toggle()";
+                $order_link_params['onmouseout']  = "$('.soimg$col_index').toggle()";
+            } elseif (strstr($order_img, 'desc')) {
+                $order_link_params['onmouseover'] = "$('.soimg$col_index').toggle()";
+                $order_link_params['onmouseout']  = "$('.soimg$col_index').toggle()";
+            }
+        }
+
+        if ($GLOBALS['cfg']['HeaderFlipType'] == self::HEADER_FLIP_TYPE_AUTO) {
+
+            $GLOBALS['cfg']['HeaderFlipType']
+                = (PMA_USR_BROWSER_AGENT == 'IE')
+                ? self::HEADER_FLIP_TYPE_CSS
+                : self::HEADER_FLIP_TYPE_FAKE;
+        }
+
+        if ($direction == self::DISP_DIR_HORIZONTAL_FLIPPED
+            && $GLOBALS['cfg']['HeaderFlipType'] == self::HEADER_FLIP_TYPE_CSS
+        ) {
+            $order_link_params['style'] = 'direction: ltr; writing-mode: tb-rl;';
+        }
+
+        $order_link_content = (($direction == self::DISP_DIR_HORIZONTAL_FLIPPED)
+            && ($GLOBALS['cfg']['HeaderFlipType'] == self::HEADER_FLIP_TYPE_FAKE))
+            ? PMA_Util::flipstring(
+                htmlspecialchars($fields_meta->name),
+                "<br />\n"
+            )
+            : htmlspecialchars($fields_meta->name);
+
+        return PMA_Util::linkOrButton(
+            $order_url, $order_link_content . $order_img,
+            $order_link_params, false, true
+        );
+
+    } // end of the '_getSortOrderLink()' function
+
+
+    /**
+     * Prepare columns to draggable effect for sortable columns
+     *
+     * @param boolean $col_visib       the column is visible (false)
+     *        array                    the column is not visible (string array)
+     * @param string  $col_visib_j     element of $col_visib array
+     * @param boolean $condition_field whether to add CSS class condition
+     * @param string  $direction       the display direction
+     * @param array   $fields_meta     set of field properties
+     * @param string  $order_link      the order link
+     * @param string  $comments        the comment for the column
+     *
+     * @return  string  $draggable_html     html content
+     *
+     * @access  private
+     *
+     * @see     _getTableHeaders()
+     */
+    private function _getDraggableClassForSortableColumns(
+        $col_visib, $col_visib_j, $condition_field, $direction, $fields_meta,
+        $order_link, $comments
+    ) {
+
+        $draggable_html = '<th';
+        $th_class = array();
+        $th_class[] = 'draggable';
+
+        if ($col_visib && !$col_visib_j) {
+            $th_class[] = 'hide';
+        }
+
+        if ($condition_field) {
+            $th_class[] = 'condition';
+        }
+
+        $th_class[] = 'column_heading';
+        if ($GLOBALS['cfg']['BrowsePointerEnable'] == true) {
+            $th_class[] = 'pointer';
+        }
+
+        if ($GLOBALS['cfg']['BrowseMarkerEnable'] == true) {
+            $th_class[] = 'marker';
+        }
+
+        $draggable_html .= ' class="' . implode(' ', $th_class);
+
+        if ($direction == self::DISP_DIR_HORIZONTAL_FLIPPED) {
+            $draggable_html .= ' vbottom';
+        }
+
+        $draggable_html .= '" data-column="' . htmlspecialchars($fields_meta->name)
+            . '">' . $order_link . $comments . '</th>';
+
+        return $draggable_html;
+
+    } // end of the '_getDraggableClassForSortableColumns()' function
+
+
+    /**
+     * Prepare columns to draggable effect for non sortable columns
+     *
+     * @param boolean $col_visib       the column is visible (false)
+     *        array                    the column is not visible (string array)
+     * @param string  $col_visib_j     element of $col_visib array
+     * @param boolean $condition_field whether to add CSS class condition
+     * @param string  $direction       the display direction
+     * @param array   $fields_meta     set of field properties
+     * @param string  $comments        the comment for the column
+     *
+     * @return  string  $draggable_html         html content
+     *
+     * @access  private
+     *
+     * @see     _getTableHeaders()
+     */
+    private function _getDraggableClassForNonSortableColumns(
+        $col_visib, $col_visib_j, $condition_field,
+        $direction, $fields_meta, $comments
+    ) {
+
+        $draggable_html = '<th';
+        $th_class = array();
+        $th_class[] = 'draggable';
+
+        if ($col_visib && !$col_visib_j) {
+            $th_class[] = 'hide';
+        }
+
+        if ($condition_field) {
+            $th_class[] = 'condition';
+        }
+
+        $draggable_html .= ' class="' . implode(' ', $th_class);
+        if ($direction == self::DISP_DIR_HORIZONTAL_FLIPPED) {
+            $draggable_html .= ' vbottom';
+        }
+
+        $draggable_html .= '"';
+        if (($direction == self::DISP_DIR_HORIZONTAL_FLIPPED)
+            && ($GLOBALS['cfg']['HeaderFlipType'] == self::HEADER_FLIP_TYPE_CSS)
+        ) {
+            $draggable_html .= ' style="direction: ltr; writing-mode: tb-rl;"';
+        }
+
+        $draggable_html .= ' data-column="'
+            . htmlspecialchars($fields_meta->name) . '">';
+
+        if (($direction == self::DISP_DIR_HORIZONTAL_FLIPPED)
+            && ($GLOBALS['cfg']['HeaderFlipType'] == self::HEADER_FLIP_TYPE_FAKE)
+        ) {
+
+            $draggable_html .= PMA_Util::flipstring(
+                htmlspecialchars($fields_meta->name), '<br />'
+            );
+
+        } else {
+            $draggable_html .= htmlspecialchars($fields_meta->name);
+        }
+
+        $draggable_html .= "\n" . $comments . '</th>';
+
+        return $draggable_html;
+
+    } // end of the '_getDraggableClassForNonSortableColumns()' function
+
+
+    /**
+     * Prepare column to show at right side - check boxes or empty column
+     *
+     * @param array   &$is_display               which elements to display
+     * @param boolean $directionCondition        display direction horizontal
+     *                                           or horizontalflipped
+     * @param string  $full_or_partial_text_link full/partial link or text button
+     * @param string  $colspan                   column span of table header
+     * @param string  $rowspan                   row span of table header
+     *
+     * @return  string  html content
+     *
+     * @access  private
+     *
+     * @see     _getTableHeaders()
+     */
+    private function _getColumnAtRightSide(
+        &$is_display, $directionCondition, $full_or_partial_text_link,
+        $colspan, $rowspan
+    ) {
+
+        $right_column_html = '';
+        $vertical_display = $this->__get('vertical_display');
+
+        // Displays the needed checkboxes at the right
+        // column of the result table header if possible and required...
+        if ((($GLOBALS['cfg']['RowActionLinks'] == self::POSITION_RIGHT)
+            || ($GLOBALS['cfg']['RowActionLinks'] == self::POSITION_BOTH))
+            && (($is_display['edit_lnk'] != self::NO_EDIT_OR_DELETE)
+            || ($is_display['del_lnk'] != self::NO_EDIT_OR_DELETE))
+            && ($is_display['text_btn'] == '1')
+        ) {
+
+            $vertical_display['emptyafter']
+                = (($is_display['edit_lnk'] != self::NO_EDIT_OR_DELETE)
+                && ($is_display['del_lnk'] != self::NO_EDIT_OR_DELETE)) ? 4 : 1;
+
+            if ($directionCondition) {
+                $right_column_html .= "\n"
+                    . '<th ' . $colspan . '>' . $full_or_partial_text_link
+                    . '</th>';
+
+                // end horizontal/horizontalflipped mode
+            } else {
+                $vertical_display['textbtn'] = '    <th ' . $rowspan
+                    . ' class="vmiddle">' . "\n"
+                    . '        ' . "\n"
+                    . '    </th>' . "\n";
+            } // end vertical mode
+        } elseif ((($GLOBALS['cfg']['RowActionLinks'] == self::POSITION_LEFT)
+            || ($GLOBALS['cfg']['RowActionLinks'] == self::POSITION_BOTH))
+            && (($is_display['edit_lnk'] == self::NO_EDIT_OR_DELETE)
+            && ($is_display['del_lnk'] == self::NO_EDIT_OR_DELETE))
+            && (! isset($GLOBALS['is_header_sent']) || ! $GLOBALS['is_header_sent'])
+        ) {
+            //     ... elseif no button, displays empty columns if required
+            // (unless coming from Browse mode print view)
+
+            $vertical_display['emptyafter']
+                = (($is_display['edit_lnk'] != self::NO_EDIT_OR_DELETE)
+                && ($is_display['del_lnk'] != self::NO_EDIT_OR_DELETE)) ? 4 : 1;
+
+            if ($directionCondition) {
+                $right_column_html .= "\n"
+                    . '<td ' . $colspan . '></td>';
+
+                // end horizontal/horizontalflipped mode
+            } else {
+                $vertical_display['textbtn'] = '    <td' . $rowspan
+                    . '></td>' . "\n";
+            } // end vertical mode
+        }
+
+        $this->__set('vertical_display', $vertical_display);
+
+        return $right_column_html;
+
+    } // end of the '_getColumnAtRightSide()' function
+
+
+    /**
+     * Prepares the display for a value
+     *
+     * @param string $class           class of table cell
+     * @param bool   $condition_field whether to add CSS class condition
+     * @param string $value           value to display
+     *
+     * @return string  the td
+     *
+     * @access  private
+     *
+     * @see     _getDataCellForBlobColumns(), _getDataCellForGeometryColumns(),
+     *          _getDataCellForNonNumericAndNonBlobColumns()
+     */
+    private function _buildValueDisplay($class, $condition_field, $value)
+    {
+        return '<td class="left ' . $class . ($condition_field ? ' condition' : '')
+            . '">' . $value . '</td>';
+    } // end of the '_buildValueDisplay()' function
+
+
+    /**
+     * Prepares the display for a null value
+     *
+     * @param string $class           class of table cell
+     * @param bool   $condition_field whether to add CSS class condition
+     * @param object $meta            the meta-information about this field
+     * @param string $align           cell allignment
+     *
+     * @return string  the td
+     *
+     * @access  private
+     *
+     * @see     _getDataCellForNumericColumns(), _getDataCellForBlobColumns(),
+     *          _getDataCellForGeometryColumns(),
+     *          _getDataCellForNonNumericAndNonBlobColumns()
+     */
+    private function _buildNullDisplay($class, $condition_field, $meta, $align = '')
+    {
+        // the null class is needed for grid editing
+        return '<td ' . $align . ' class="'
+            . $this->_addClass(
+                $class, $condition_field, $meta, ''
+            )
+            . ' null"><i>NULL</i></td>';
+    } // end of the '_buildNullDisplay()' function
+
+
+    /**
+     * Prepares the display for an empty value
+     *
+     * @param string $class           class of table cell
+     * @param bool   $condition_field whether to add CSS class condition
+     * @param object $meta            the meta-information about this field
+     * @param string $align           cell allignment
+     *
+     * @return string  the td
+     *
+     * @access  private
+     *
+     * @see     _getDataCellForNumericColumns(), _getDataCellForBlobColumns(),
+     *          _getDataCellForGeometryColumns(),
+     *          _getDataCellForNonNumericAndNonBlobColumns()
+     */
+    private function _buildEmptyDisplay($class, $condition_field, $meta, $align = '')
+    {
+        return '<td ' . $align . ' class="'
+            . $this->_addClass(
+                $class, $condition_field, $meta, ' nowrap'
+            )
+            . '"></td>';
+    } // end of the '_buildEmptyDisplay()' function
+
+
+    /**
+     * Adds the relavant classes.
+     *
+     * @param string $class                 class of table cell
+     * @param bool   $condition_field       whether to add CSS class condition
+     * @param object $meta                  the meta-information about the field
+     * @param string $nowrap                avoid wrapping
+     * @param bool   $is_field_truncated    is field truncated (display ...)
+     * @param string $transformation_plugin transformation plugin.
+     *                                      Can also be the default function:
+     *                                      PMA_mimeDefaultFunction
+     * @param string $default_function      default transformation function
+     *
+     * @return string the list of classes
+     *
+     * @access  private
+     *
+     * @see     _buildNullDisplay(), _getRowData()
+     */
+    private function _addClass(
+        $class, $condition_field, $meta, $nowrap, $is_field_truncated = false,
+        $transformation_plugin = '', $default_function = ''
+    ) {
+
+        // Define classes to be added to this data field based on the type of data
+        $enum_class = '';
+        if (strpos($meta->flags, 'enum') !== false) {
+            $enum_class = ' enum';
+        }
+
+        $set_class = '';
+        if (strpos($meta->flags, 'set') !== false) {
+            $set_class = ' set';
+        }
+
+        $bit_class = '';
+        if (strpos($meta->type, 'bit') !== false) {
+            $bit_class = ' bit';
+        }
+
+        $mime_type_class = '';
+        if (isset($meta->mimetype)) {
+            $mime_type_class = ' ' . preg_replace('/\//', '_', $meta->mimetype);
+        }
+
+        return $class . ($condition_field ? ' condition' : '') . $nowrap
+            . ' ' . ($is_field_truncated ? ' truncated' : '')
+            . ($transformation_plugin != $default_function ? ' transformed' : '')
+            . $enum_class . $set_class . $bit_class . $mime_type_class;
+
+    } // end of the '_addClass()' function
+
+
+    /**
+     * Prepare the body of the results table
+     *
+     * @param integer &$dt_result         the link id associated to the query
+     *                                    which results have to be displayed
+     * @param array   &$is_display        which elements to display
+     * @param array   $map                the list of relations
+     * @param array   $analyzed_sql       the analyzed query
+     * @param boolean $is_limited_display with limited operations or not
+     *
+     * @return string $table_body_html  html content
+     *
+     * @global array   $row             current row data
+     *
+     * @access  private
+     *
+     * @see     getTable()
+     */
+    private function _getTableBody(
+        &$dt_result, &$is_display, $map, $analyzed_sql, $is_limited_display = false
+    ) {
+
+        global $row; // mostly because of browser transformations,
+                     // to make the row-data accessible in a plugin
+
+        $table_body_html = '';
+
+        // query without conditions to shorten URLs when needed, 200 is just
+        // guess, it should depend on remaining URL length
+        $url_sql_query = $this->_getUrlSqlQuery($analyzed_sql);
+
+        $vertical_display = $this->__get('vertical_display');
+
+        if (! is_array($map)) {
+            $map = array();
+        }
+
+        $row_no                         = 0;
+        $vertical_display['edit']       = array();
+        $vertical_display['copy']       = array();
+        $vertical_display['delete']     = array();
+        $vertical_display['data']       = array();
+        $vertical_display['row_delete'] = array();
+        $this->__set('vertical_display', $vertical_display);
+
+        // name of the class added to all grid editable elements;
+        // if we don't have all the columns of a unique key in the result set,
+        //  do not permit grid editing
+        if ($is_limited_display || ! $this->__get('editable')) {
+            $grid_edit_class = '';
+        } else {
+            switch ($GLOBALS['cfg']['GridEditing']) {
+            case 'double-click':
+                // trying to reduce generated HTML by using shorter
+                // classes like click1 and click2
+                $grid_edit_class = 'grid_edit click2';
+                break;
+            case 'click':
+                $grid_edit_class = 'grid_edit click1';
+                break;
+            case 'disabled':
+                $grid_edit_class = '';
+                break;
+            }
+        }
+
+        // prepare to get the column order, if available
+        list($col_order, $col_visib) = $this->_getColumnParams($analyzed_sql);
+
+        // Correction University of Virginia 19991216 in the while below
+        // Previous code assumed that all tables have keys, specifically that
+        // the phpMyAdmin GUI should support row delete/edit only for such
+        // tables.
+        // Although always using keys is arguably the prescribed way of
+        // defining a relational table, it is not required. This will in
+        // particular be violated by the novice.
+        // We want to encourage phpMyAdmin usage by such novices. So the code
+        // below has been changed to conditionally work as before when the
+        // table being displayed has one or more keys; but to display
+        // delete/edit options correctly for tables without keys.
+
+        $odd_row = true;
+        $directionCondition
+            = ($_SESSION['tmp_user_values']['disp_direction']
+                == self::DISP_DIR_HORIZONTAL)
+            || ($_SESSION['tmp_user_values']['disp_direction']
+                == self::DISP_DIR_HORIZONTAL_FLIPPED);
+
+        while ($row = PMA_DBI_fetch_row($dt_result)) {
+
+            // "vertical display" mode stuff
+            $table_body_html .= $this->_getVerticalDisplaySupportSegments(
+                $vertical_display, $row_no, $directionCondition
+            );
+
+            $alternating_color_class = ($odd_row ? 'odd' : 'even');
+            $odd_row = ! $odd_row;
+
+            if ($directionCondition) {
+                // pointer code part
+                $table_body_html .= '<tr class="' . $alternating_color_class . '">';
+            }
+
+            // 1. Prepares the row
+            // 1.1 Results from a "SELECT" statement -> builds the
+            //     WHERE clause to use in links (a unique key if possible)
+            /**
+             * @todo $where_clause could be empty, for example a table
+             *       with only one field and it's a BLOB; in this case,
+             *       avoid to display the delete and edit links
+             */
+            list($where_clause, $clause_is_unique, $condition_array)
+                = PMA_Util::getUniqueCondition(
+                    $dt_result,
+                    $this->__get('fields_cnt'),
+                    $this->__get('fields_meta'),
+                    $row
+                );
+            $where_clause_html = urlencode($where_clause);
+
+            // In print view these variable needs toinitialized
+            $del_url = $del_query = $del_str = $edit_anchor_class
+                = $edit_str = $js_conf = $copy_url = $copy_str = $edit_url = null;
+
+            // 1.2 Defines the URLs for the modify/delete link(s)
+
+            if (($is_display['edit_lnk'] != self::NO_EDIT_OR_DELETE)
+                || ($is_display['del_lnk'] != self::NO_EDIT_OR_DELETE)
+            ) {
+                // We need to copy the value
+                // or else the == 'both' check will always return true
+
+                if ($GLOBALS['cfg']['PropertiesIconic'] === self::POSITION_BOTH) {
+                    $iconic_spacer = '<div class="nowrap">';
+                } else {
+                    $iconic_spacer = '';
+                }
+
+                // 1.2.1 Modify link(s) - update row case
+                if ($is_display['edit_lnk'] == self::UPDATE_ROW) {
+
+                    list($edit_url, $copy_url, $edit_str, $copy_str,
+                        $edit_anchor_class)
+                            = $this->_getModifiedLinks(
+                                $where_clause,
+                                $clause_is_unique, $url_sql_query
+                            );
+
+                } // end if (1.2.1)
+
+                // 1.2.2 Delete/Kill link(s)
+                if (($is_display['del_lnk'] == self::DELETE_ROW)
+                    || ($is_display['del_lnk'] == self::KILL_PROCESS)
+                ) {
+
+                    list($del_query, $del_url, $del_str, $js_conf)
+                        = $this->_getDeleteAndKillLinks(
+                            $where_clause, $clause_is_unique,
+                            $url_sql_query, $is_display['del_lnk'],
+                            $row
+                        );
+
+                } // end if (1.2.2)
+
+                // 1.3 Displays the links at left if required
+                if ((($GLOBALS['cfg']['RowActionLinks'] == self::POSITION_LEFT)
+                    || ($GLOBALS['cfg']['RowActionLinks'] == self::POSITION_BOTH))
+                    && $directionCondition
+                ) {
+
+                    $table_body_html .= $this->_getPlacedLinks(
+                        self::POSITION_LEFT, $del_url, $is_display, $row_no,
+                        $where_clause, $where_clause_html, $condition_array,
+                        $del_query, 'l', $edit_url, $copy_url, $edit_anchor_class,
+                        $edit_str, $copy_str, $del_str, $js_conf
+                    );
+
+                } elseif (($GLOBALS['cfg']['RowActionLinks'] == self::POSITION_NONE)
+                    && $directionCondition
+                ) {
+
+                    $table_body_html .= $this->_getPlacedLinks(
+                        self::POSITION_NONE, $del_url, $is_display, $row_no,
+                        $where_clause, $where_clause_html, $condition_array,
+                        $del_query, 'l', $edit_url, $copy_url, $edit_anchor_class,
+                        $edit_str, $copy_str, $del_str, $js_conf
+                    );
+
+                } // end if (1.3)
+            } // end if (1)
+
+            // 2. Displays the rows' values
+            $table_body_html .= $this->_getRowValues(
+                $dt_result, $row, $row_no, $col_order, $map,
+                $grid_edit_class, $col_visib, $where_clause,
+                $url_sql_query, $analyzed_sql, $directionCondition
+            );
+
+            // 3. Displays the modify/delete links on the right if required
+            if ((($GLOBALS['cfg']['RowActionLinks'] == self::POSITION_RIGHT)
+                || ($GLOBALS['cfg']['RowActionLinks'] == self::POSITION_BOTH))
+                && $directionCondition
+            ) {
+
+                $table_body_html .= $this->_getPlacedLinks(
+                    self::POSITION_RIGHT, $del_url, $is_display, $row_no,
+                    $where_clause, $where_clause_html, $condition_array,
+                    $del_query, 'r', $edit_url, $copy_url, $edit_anchor_class,
+                    $edit_str, $copy_str, $del_str, $js_conf
+                );
+
+            } // end if (3)
+
+            if ($directionCondition) {
+                $table_body_html .= '</tr>';
+            } // end if
+
+            // 4. Gather links of del_urls and edit_urls in an array for later
+            //    output
+            $this->_gatherLinksForLaterOutputs(
+                $row_no, $is_display, $where_clause, $where_clause_html, $js_conf,
+                $del_url, $del_query, $del_str, $edit_anchor_class, $edit_url,
+                $edit_str, $copy_url, $copy_str, $alternating_color_class,
+                $condition_array
+            );
+
+            $table_body_html .= $directionCondition ? "\n" : '';
+            $row_no++;
+
+        } // end while
+
+        return $table_body_html;
+
+    } // end of the '_getTableBody()' function
+
+
+    /**
+     * Get the values for one data row 
+     *
+     * @param integer &$dt_result         the link id associated to the query
+     *                                    which results have to be displayed
+     * @param array   $row                current row data
+     * @param integer $row_no             the index of current row
+     * @param array   $col_order          the column order
+     *                                    false when a property not found
+     * @param array   $map                the list of relations
+     * @param string  $grid_edit_class    the class for all editable columns
+     * @param boolean $col_visib          column is visible(false)
+     *        array                       column isn't visible(string array)
+     * @param string  $where_clause       where clause
+     * @param string  $url_sql_query      the analyzed sql query
+     * @param array   $analyzed_sql       the analyzed query
+     * @param boolean $directionCondition the directional condition
+     *
+     * @return  string $row_values_html  html content
+     *
+     * @access  private
+     *
+     * @see     _getTableBody()
+     */
+    private function _getRowValues(
+        &$dt_result, $row, $row_no, $col_order, $map,
+        $grid_edit_class, $col_visib, $where_clause,
+        $url_sql_query, $analyzed_sql, $directionCondition
+    ) {
+
+        $row_values_html = '';
+
+        // Following variable are needed for use in isset/empty or
+        // use with array indexes/safe use in foreach
+        $sql_query = $this->__get('sql_query');
+        $fields_meta = $this->__get('fields_meta');
+        $highlight_columns = $this->__get('highlight_columns');
+        $mime_map = $this->__get('mime_map');
+
+        $row_info = $this->_getRowInfoForSpecialLinks($row, $col_order);
+
+        for ($currentColumn = 0; 
+                $currentColumn < $this->__get('fields_cnt'); 
+                ++$currentColumn) {
+
+            // assign $i with appropriate column order
+            $i = $col_order ? $col_order[$currentColumn] : $currentColumn;
+
+            $meta    = $fields_meta[$i];
+            $not_null_class = $meta->not_null ? 'not_null' : '';
+            $relation_class = isset($map[$meta->name]) ? 'relation' : '';
+            $hide_class = ($col_visib && ! $col_visib[$currentColumn]
+                // hide per <td> only if the display dir is not vertical
+                && ($_SESSION['tmp_user_values']['disp_direction']
+                    != self::DISP_DIR_VERTICAL))
+                ? 'hide'
+                : '';
+
+            // handle datetime-related class, for grid editing
+            $field_type_class
+                = $this->_getClassForDateTimeRelatedFields($meta->type);
+
+            $is_field_truncated = false;
+            // combine all the classes applicable to this column's value
+            $class = $this->_getClassesForColumn(
+                $grid_edit_class, $not_null_class, $relation_class,
+                $hide_class, $field_type_class, $row_no
+            );
+
+            //  See if this column should get highlight because it's used in the
+            //  where-query.
+            $condition_field = (isset($highlight_columns)
+                && (isset($highlight_columns[$meta->name])
+                || isset($highlight_columns[PMA_Util::backquote($meta->name)])))
+                ? true
+                : false;
+
+            // Wrap MIME-transformations. [MIME]
+            $default_function = '_mimeDefaultFunction'; // default_function
+            $transformation_plugin = $default_function;
+            $transform_options = array();
+
+            if ($GLOBALS['cfgRelation']['mimework']
+                && $GLOBALS['cfg']['BrowseMIME']
+            ) {
+
+                if (isset($mime_map[$meta->name]['mimetype'])
+                    && isset($mime_map[$meta->name]['transformation'])
+                    && !empty($mime_map[$meta->name]['transformation'])
+                ) {
+
+                    $file = $mime_map[$meta->name]['transformation'];
+                    $include_file = 'libraries/plugins/transformations/' . $file;
+
+                    if (file_exists($include_file)) {
+
+                        include_once $include_file;
+                        $class_name = str_replace('.class.php', '', $file);
+                        // todo add $plugin_manager
+                        $plugin_manager = null;
+                        $transformation_plugin = new $class_name(
+                            $plugin_manager
+                        );
+
+                        $transform_options  = PMA_transformation_getOptions(
+                            isset($mime_map[$meta->name]
+                                ['transformation_options']
+                            )
+                            ? $mime_map[$meta->name]
+                            ['transformation_options']
+                            : ''
+                        );
+
+                        $meta->mimetype = str_replace(
+                            '_', '/',
+                            $mime_map[$meta->name]['mimetype']
+                        );
+
+                    } // end if file_exists
+                } // end if transformation is set
+            } // end if mime/transformation works.
+
+            $_url_params = array(
+                'db'            => $this->__get('db'),
+                'table'         => $this->__get('table'),
+                'where_clause'  => $where_clause,
+                'transform_key' => $meta->name,
+            );
+
+            if (! empty($sql_query)) {
+                $_url_params['sql_query'] = $url_sql_query;
+            }
+
+            $transform_options['wrapper_link']
+                = PMA_generate_common_url($_url_params);
+
+            $vertical_display = $this->__get('vertical_display');
+
+            // Check whether the field needs to display with syntax highlighting
+
+            if ($this->_isNeedToSyntaxHighlight($meta->name)
+                && (trim($row[$i]) != '')
+            ) {
+
+                $parsed_sql = PMA_SQP_parse($row[$i]);
+                $row[$i] = PMA_Util::formatSql(
+                    $parsed_sql, $row[$i]
+                );
+                include_once $this->syntax_highlighting_column_info[strtolower($this->__get('db'))][strtolower($this->__get('table'))][strtolower($meta->name)][0];
+                $transformation_plugin = new $this->syntax_highlighting_column_info[strtolower($this->__get('db'))][strtolower($this->__get('table'))][strtolower($meta->name)][1](null);
+
+                $transform_options  = PMA_transformation_getOptions(
+                    isset($mime_map[$meta->name]['transformation_options'])
+                    ? $mime_map[$meta->name]['transformation_options']
+                    : ''
+                );
+
+                $meta->mimetype = str_replace(
+                    '_', '/',
+                    $this->syntax_highlighting_column_info[strtolower($this->__get('db'))][strtolower($this->__get('table'))][strtolower($meta->name)][2]
+                );
+
+            }
+
+            // Check for the predefined fields need to show as link in schemas
+            include_once 'libraries/special_schema_links.lib.php';
+
+            if (isset($GLOBALS['special_schema_links'])
+                && ($this->_isFieldNeedToLink(strtolower($meta->name)))
+            ) {
+
+                $linking_url = $this->_getSpecialLinkUrl(
+                    $row[$i], $row_info, strtolower($meta->name)
+                );
+                include_once "libraries/plugins/transformations/Text_Plain_Link.class.php";
+                $transformation_plugin = new Text_Plain_Link(null);
+
+                $transform_options  = array(
+                    0 => $linking_url,
+                    2 => true
+                );
+
+                $meta->mimetype = str_replace(
+                    '_', '/',
+                    'Text/Plain'
+                );
+
+            }
+
+            if ($meta->numeric == 1) {
+                // n u m e r i c
+
+                $vertical_display['data'][$row_no][$i]
+                    = $this->_getDataCellForNumericColumns(
+                        $row[$i], $class, $condition_field, $meta, $map,
+                        $is_field_truncated, $analyzed_sql,
+                        $transformation_plugin, $default_function,
+                        $transform_options
+                    );
+
+            } elseif (stristr($meta->type, self::BLOB_FIELD)) {
+                //  b l o b
+
+                // PMA_mysql_fetch_fields returns BLOB in place of
+                // TEXT fields type so we have to ensure it's really a BLOB
+                $field_flags = PMA_DBI_field_flags($dt_result, $i);
+
+                $vertical_display['data'][$row_no][$i]
+                    = $this->_getDataCellForBlobColumns(
+                        $row[$i], $class, $meta, $_url_params, $field_flags,
+                        $transformation_plugin, $default_function,
+                        $transform_options, $condition_field, $is_field_truncated
+                    );
+
+            } elseif ($meta->type == self::GEOMETRY_FIELD) {
+                // g e o m e t r y
+
+                // Remove 'grid_edit' from $class as we do not allow to
+                // inline-edit geometry data.
+                $class = str_replace('grid_edit', '', $class);
+
+                $vertical_display['data'][$row_no][$i]
+                    = $this->_getDataCellForGeometryColumns(
+                        $row[$i], $class, $meta, $map, $_url_params,
+                        $condition_field, $transformation_plugin,
+                        $default_function, $transform_options,
+                        $is_field_truncated, $analyzed_sql
+                    );
+
+            } else {
+                // n o t   n u m e r i c   a n d   n o t   B L O B
+
+                $vertical_display['data'][$row_no][$i]
+                    = $this->_getDataCellForNonNumericAndNonBlobColumns(
+                        $row[$i], $class, $meta, $map, $_url_params,
+                        $condition_field, $transformation_plugin,
+                        $default_function, $transform_options,
+                        $is_field_truncated, $analyzed_sql, $dt_result, $i
+                    );
+
+            }
+
+            // output stored cell
+            if ($directionCondition) {
+                $row_values_html
+                    .= $vertical_display['data'][$row_no][$i];
+            }
+
+            if (isset($vertical_display['rowdata'][$i][$row_no])) {
+                $vertical_display['rowdata'][$i][$row_no]
+                    .= $vertical_display['data'][$row_no][$i];
+            } else {
+                $vertical_display['rowdata'][$i][$row_no]
+                    = $vertical_display['data'][$row_no][$i];
+            }
+
+            $this->__set('vertical_display', $vertical_display);
+
+        } // end for
+
+        return $row_values_html;
+
+    } // end of the '_getRowValues()' function
+
+
+    /**
+     * Gather delete/edit url links for further outputs
+     *
+     * @param integer $row_no                  the index of current row
+     * @param array   $is_display              which elements to display
+     * @param string  $where_clause            where clause
+     * @param string  $where_clause_html       the html encoded where clause
+     * @param string  $js_conf                 text for the JS confirmation
+     * @param string  $del_url                 the url for delete row
+     * @param string  $del_query               the query for delete row
+     * @param string  $del_str                 the label for delete row
+     * @param string  $edit_anchor_class       the class for html element for edit
+     * @param string  $edit_url                the url for edit row
+     * @param string  $edit_str                the label for edit row
+     * @param string  $copy_url                the url for copy row
+     * @param string  $copy_str                the label for copy row
+     * @param string  $alternating_color_class class for display two colors in rows
+     * @param array   $condition_array         array of keys
+     *                                         (primary,unique,condition)
+     *
+     * @return  void
+     *
+     * @access  private
+     *
+     * @see     _getTableBody()
+     */
+    private function _gatherLinksForLaterOutputs(
+        $row_no, $is_display, $where_clause, $where_clause_html, $js_conf,
+        $del_url, $del_query, $del_str, $edit_anchor_class, $edit_url, $edit_str,
+        $copy_url, $copy_str, $alternating_color_class, $condition_array
+    ) {
+
+        $vertical_display = $this->__get('vertical_display');
+
+        if (! isset($vertical_display['edit'][$row_no])) {
+            $vertical_display['edit'][$row_no]       = '';
+            $vertical_display['copy'][$row_no]       = '';
+            $vertical_display['delete'][$row_no]     = '';
+            $vertical_display['row_delete'][$row_no] = '';
+        }
+
+        $vertical_class = ' row_' . $row_no;
+        if ($GLOBALS['cfg']['BrowsePointerEnable'] == true) {
+            $vertical_class .= ' vpointer';
+        }
+
+        if ($GLOBALS['cfg']['BrowseMarkerEnable'] == true) {
+            $vertical_class .= ' vmarker';
+        }
+
+        if (!empty($del_url)
+            && ($is_display['del_lnk'] != self::KILL_PROCESS)
+        ) {
+
+            $vertical_display['row_delete'][$row_no]
+                .= $this->_getCheckboxForMultiRowSubmissions(
+                    $del_url, $is_display, $row_no, $where_clause_html,
+                    $condition_array, $del_query, '[%_PMA_CHECKBOX_DIR_%]',
+                    $alternating_color_class . $vertical_class
+                );
+
+        } else {
+            unset($vertical_display['row_delete'][$row_no]);
+        }
+
+        if (isset($edit_url)) {
+
+            $vertical_display['edit'][$row_no] .= $this->_getEditLink(
+                $edit_url,
+                $alternating_color_class . ' ' . $edit_anchor_class
+                . $vertical_class, $edit_str,
+                $where_clause,
+                $where_clause_html
+            );
+
+        } else {
+            unset($vertical_display['edit'][$row_no]);
+        }
+
+        if (isset($copy_url)) {
+
+            $vertical_display['copy'][$row_no] .= $this->_getCopyLink(
+                $copy_url, $copy_str, $where_clause, $where_clause_html,
+                $alternating_color_class . $vertical_class
+            );
+
+        } else {
+            unset($vertical_display['copy'][$row_no]);
+        }
+
+        if (isset($del_url)) {
+
+            if (! isset($js_conf)) {
+                $js_conf = '';
+            }
+
+            $vertical_display['delete'][$row_no]
+                .= $this->_getDeleteLink(
+                    $del_url, $del_str, $js_conf,
+                    $alternating_color_class . $vertical_class
+                );
+
+        } else {
+            unset($vertical_display['delete'][$row_no]);
+        }
+
+        $this->__set('vertical_display', $vertical_display);
+
+    } // end of the '_gatherLinksForLaterOutputs()' function
+
+
+    /**
+     * Check whether any field is marked as need to syntax highlight
+     *
+     * @param string $field field to check
+     *
+     * @return boolean
+     */
+    private function _isNeedToSyntaxHighlight($field)
+    {
+        if (! empty($this->syntax_highlighting_column_info[strtolower($this->__get('db'))][strtolower($this->__get('table'))][strtolower($field)])) {
+            return true;
+        }
+        return false;
+    }
+
+    /**
+     * Check whether the field needs to be link
+     *
+     * @param string $field field to check
+     *
+     * @return boolean
+     */
+    private function _isFieldNeedToLink($field)
+    {
+        if (! empty($GLOBALS['special_schema_links'][strtolower($this->__get('db'))][strtolower($this->__get('table'))][$field])) {
+            return true;
+        }
+        return false;
+    }
+
+
+    /**
+     * Get link for display special schema links
+     *
+     * @param string $column_value column value
+     * @param array  $row_info     information about row
+     * @param string $field_name   column name
+     *
+     * @return string generated link
+     */
+    private function _getSpecialLinkUrl($column_value, $row_info, $field_name)
+    {
+
+        $linking_url_params = array();
+        $link_relations = $GLOBALS['special_schema_links']
+            [strtolower($this->__get('db'))]
+            [strtolower($this->__get('table'))]
+            [$field_name];
+
+        if (! is_array($link_relations['link_param'])) {
+            $linking_url_params[$link_relations['link_param']] = $column_value;
+        } else {
+            // Consider only the case of creating link for column field
+            // sql query need to be pass as url param
+            $sql = 'SELECT `'.$column_value.'` FROM `'
+                . $row_info[$link_relations['link_param'][1]] .'`.`'
+                . $row_info[$link_relations['link_param'][2]] .'`';
+            $linking_url_params[$link_relations['link_param'][0]] = $sql;
+        }
+
+
+        if (! empty($link_relations['link_dependancy_params'])) {
+
+            foreach ($link_relations['link_dependancy_params'] as $new_param) {
+
+                // If param_info is an array, set the key and value
+                // from that array
+                if (is_array($new_param['param_info'])) {
+                    $linking_url_params[$new_param['param_info'][0]]
+                        = $new_param['param_info'][1];
+                } else {
+
+                    $linking_url_params[$new_param['param_info']]
+                        = $row_info[strtolower($new_param['column_name'])];
+
+                    // Special case 1 - when executing routines, according
+                    // to the type of the routine, url param changes
+                    if (!empty($row_info['routine_type'])) {
+                        if (strtolower($row_info['routine_type']) == self::ROUTINE_PROCEDURE) {
+                            $linking_url_params['execute_routine'] = 1;
+                        } else if (strtolower($row_info['routine_type']) == self::ROUTINE_FUNCTION) {
+                            $linking_url_params['execute_dialog'] = 1;
+                        }
+                    }
+                }
+
+            }
+
+        }
+
+        return $link_relations['default_page']
+            . PMA_generate_common_url($linking_url_params);
+
+    }
+
+
+    /**
+     * Prepare row information for display special links
+     *
+     * @param array $row       current row data
+     * @param array $col_order the column order
+     *
+     * @return array $row_info associative array with column nama -> value
+     */
+    private function _getRowInfoForSpecialLinks($row, $col_order)
+    {
+
+        $row_info = array();
+        $fields_meta = $this->__get('fields_meta');
+
+        for ($n = 0; $n < $this->__get('fields_cnt'); ++$n) {
+            $m = $col_order ? $col_order[$n] : $n;
+            $row_info[strtolower($fields_meta[$m]->name)] = $row[$m];
+        }
+
+        return $row_info;
+
+    }
+
+
+    /**
+     * Get url sql query without conditions to shorten URLs
+     *
+     * @param array $analyzed_sql analyzed query
+     *
+     * @return  string  $url_sql        analyzed sql query
+     *
+     * @access  private
+     *
+     * @see     _getTableBody()
+     */
+    private function _getUrlSqlQuery($analyzed_sql)
+    {
+
+        if (isset($analyzed_sql)
+            && isset($analyzed_sql[0])
+            && isset($analyzed_sql[0]['querytype'])
+            && ($analyzed_sql[0]['querytype'] == self::QUERY_TYPE_SELECT)
+            && (strlen($this->__get('sql_query')) > 200)
+        ) {
+
+            $url_sql_query = 'SELECT ';
+            if (isset($analyzed_sql[0]['queryflags']['distinct'])) {
+                $url_sql_query .= ' DISTINCT ';
+            }
+
+            $url_sql_query .= $analyzed_sql[0]['select_expr_clause'];
+            if (!empty($analyzed_sql[0]['from_clause'])) {
+                $url_sql_query .= ' FROM ' . $analyzed_sql[0]['from_clause'];
+            }
+
+            return $url_sql_query;
+        }
+
+        return $this->__get('sql_query');
+
+    } // end of the '_getUrlSqlQuery()' function
+
+
+    /**
+     * Get column order and column visibility
+     *
+     * @param array $analyzed_sql the analyzed query
+     *
+     * @return  array           2 element array - $col_order, $col_visib
+     *
+     * @access  private
+     *
+     * @see     _getTableBody()
+     */
+    private function _getColumnParams($analyzed_sql)
+    {
+        if ($this->_isSelect($analyzed_sql)) {
+            $pmatable = new PMA_Table($this->__get('table'), $this->__get('db'));
+            $col_order = $pmatable->getUiProp(PMA_Table::PROP_COLUMN_ORDER);
+            $col_visib = $pmatable->getUiProp(PMA_Table::PROP_COLUMN_VISIB);
+        } else {
+            $col_order = false;
+            $col_visib = false;
+        }
+
+        return array($col_order, $col_visib);
+    } // end of the '_getColumnParams()' function
+
+
+    /**
+     * Prepare vertical display mode necessay HTML stuff
+     *
+     * @param array   $vertical_display   informations used with vertical
+     *                                    display mode
+     * @param integer $row_no             the index of current row
+     * @param boolean $directionCondition the directional condition
+     *
+     * @return  string  $vertical_disp_html     html content
+     *
+     * @access  private
+     *
+     * @see     _getTableBody()
+     */
+    private function _getVerticalDisplaySupportSegments(
+        $vertical_display, $row_no, $directionCondition
+    ) {
+
+        $support_html = '';
+
+        if ((($row_no != 0) && ($_SESSION['tmp_user_values']['repeat_cells'] != 0))
+            && !($row_no % $_SESSION['tmp_user_values']['repeat_cells'])
+            && $directionCondition
+        ) {
+
+            $support_html .= '<tr>' . "\n";
+
+            if ($vertical_display['emptypre'] > 0) {
+
+                $support_html .= '    <th colspan="'
+                    . $vertical_display['emptypre'] . '">'
+                    . "\n".'         </th>' . "\n";
+
+            } else if ($GLOBALS['cfg']['RowActionLinks'] == self::POSITION_NONE) {
+                $support_html .= '    <th></th>' . "\n";
+            }
+
+            foreach ($vertical_display['desc'] as $val) {
+                $support_html .= $val;
+            }
+
+            if ($vertical_display['emptyafter'] > 0) {
+                $support_html
+                    .= '    <th colspan="' . $vertical_display['emptyafter']
+                    . '">'
+                    . "\n" . '         </th>' . "\n";
+            }
+            $support_html .= '</tr>' . "\n";
+        } // end if
+
+        return $support_html;
+
+    } // end of the '_getVerticalDisplaySupportSegments()' function
+
+
+    /**
+     * Get modified links
+     *
+     * @param string  $where_clause     the where clause of the sql
+     * @param boolean $clause_is_unique the unique condition of clause
+     * @param string  $url_sql_query    the analyzed sql query
+     *
+     * @return  array                   5 element array - $edit_url, $copy_url,
+     *                                  $edit_str, $copy_str, $edit_anchor_class
+     *
+     * @access  private
+     *
+     * @see     _getTableBody()
+     */
+    private function _getModifiedLinks(
+        $where_clause, $clause_is_unique, $url_sql_query
+    ) {
+
+        $_url_params = array(
+                'db'               => $this->__get('db'),
+                'table'            => $this->__get('table'),
+                'where_clause'     => $where_clause,
+                'clause_is_unique' => $clause_is_unique,
+                'sql_query'        => $url_sql_query,
+                'goto'             => 'sql.php',
+            );
+
+        $edit_url = 'tbl_change.php'
+            . PMA_generate_common_url(
+                $_url_params + array('default_action' => 'update')
+            );
+
+        $copy_url = 'tbl_change.php'
+            . PMA_generate_common_url(
+                $_url_params + array('default_action' => 'insert')
+            );
+
+        $edit_str = PMA_Util::getIcon(
+            'b_edit.png', __('Edit')
+        );
+        $copy_str = PMA_Util::getIcon(
+            'b_insrow.png', __('Copy')
+        );
+
+        // Class definitions required for grid editing jQuery scripts
+        $edit_anchor_class = "edit_row_anchor";
+        if ( $clause_is_unique == 0) {
+            $edit_anchor_class .= ' nonunique';
+        }
+
+        return array($edit_url, $copy_url, $edit_str, $copy_str, $edit_anchor_class);
+
+    } // end of the '_getModifiedLinks()' function
+
+
+    /**
+     * Get delete and kill links
+     *
+     * @param string  $where_clause     the where clause of the sql
+     * @param boolean $clause_is_unique the unique condition of clause
+     * @param string  $url_sql_query    the analyzed sql query
+     * @param string  $del_lnk          the delete link of current row
+     * @param array   $row              the current row
+     *
+     * @return  array                       4 element array - $del_query,
+     *                                      $del_url, $del_str, $js_conf
+     *
+     * @access  private
+     *
+     * @see     _getTableBody()
+     */
+    private function _getDeleteAndKillLinks(
+        $where_clause, $clause_is_unique, $url_sql_query, $del_lnk, $row
+    ) {
+
+        $goto = $this->__get('goto');
+
+        if ($del_lnk == self::DELETE_ROW) { // delete row case
+
+            $_url_params = array(
+                'db'        => $this->__get('db'),
+                'table'     => $this->__get('table'),
+                'sql_query' => $url_sql_query,
+                'message_to_show' => __('The row has been deleted'),
+                'goto'      => (empty($goto) ? 'tbl_sql.php' : $goto),
+            );
+
+            $lnk_goto = 'sql.php' . PMA_generate_common_url($_url_params, 'text');
+
+            $del_query = 'DELETE FROM '
+                . PMA_Util::backquote($this->__get('db')) . '.'
+                . PMA_Util::backquote($this->__get('table'))
+                . ' WHERE ' . $where_clause .
+                ($clause_is_unique ? '' : ' LIMIT 1');
+
+            $_url_params = array(
+                    'db'        => $this->__get('db'),
+                    'table'     => $this->__get('table'),
+                    'sql_query' => $del_query,
+                    'message_to_show' => __('The row has been deleted'),
+                    'goto'      => $lnk_goto,
+                );
+            $del_url  = 'sql.php' . PMA_generate_common_url($_url_params);
+
+            $js_conf  = 'DELETE FROM ' . PMA_jsFormat($this->__get('db')) . '.'
+                . PMA_jsFormat($this->__get('table'))
+                . ' WHERE ' . PMA_jsFormat($where_clause, false)
+                . ($clause_is_unique ? '' : ' LIMIT 1');
+
+            $del_str = PMA_Util::getIcon(
+                'b_drop.png', __('Delete')
+            );
+
+        } elseif ($del_lnk == self::KILL_PROCESS) { // kill process case
+
+            $_url_params = array(
+                    'db'        => $this->__get('db'),
+                    'table'     => $this->__get('table'),
+                    'sql_query' => $url_sql_query,
+                    'goto'      => 'index.php',
+                );
+
+            $lnk_goto = 'sql.php'
+                . PMA_generate_common_url(
+                    $_url_params, 'text'
+                );
+
+            $_url_params = array(
+                    'db'        => 'mysql',
+                    'sql_query' => 'KILL ' . $row[0],
+                    'goto'      => $lnk_goto,
+                );
+
+            $del_url  = 'sql.php' . PMA_generate_common_url($_url_params);
+            $del_query = 'KILL ' . $row[0];
+            $js_conf  = 'KILL ' . $row[0];
+            $del_str = PMA_Util::getIcon(
+                'b_drop.png', __('Kill')
+            );
+        }
+
+        return array($del_query, $del_url, $del_str, $js_conf);
+
+    } // end of the '_getDeleteAndKillLinks()' function
+
+
+    /**
+     * Prepare placed links
+     *
+     * @param string  $dir               the direction of links should place
+     * @param string  $del_url           the url for delete row
+     * @param array   $is_display        which elements to display
+     * @param integer $row_no            the index of current row
+     * @param string  $where_clause      the where clause of the sql
+     * @param string  $where_clause_html the html encoded where clause
+     * @param array   $condition_array   array of keys (primary, unique, condition)
+     * @param string  $del_query         the query for delete row
+     * @param string  $dir_letter        the letter denoted the direction
+     * @param string  $edit_url          the url for edit row
+     * @param string  $copy_url          the url for copy row
+     * @param string  $edit_anchor_class the class for html element for edit
+     * @param string  $edit_str          the label for edit row
+     * @param string  $copy_str          the label for copy row
+     * @param string  $del_str           the label for delete row
+     * @param string  $js_conf           text for the JS confirmation
+     *
+     * @return  string                      html content
+     *
+     * @access  private
+     *
+     * @see     _getTableBody()
+     */
+    private function _getPlacedLinks(
+        $dir, $del_url, $is_display, $row_no, $where_clause, $where_clause_html,
+        $condition_array, $del_query, $dir_letter, $edit_url, $copy_url,
+        $edit_anchor_class, $edit_str, $copy_str, $del_str, $js_conf
+    ) {
+
+        if (! isset($js_conf)) {
+            $js_conf = '';
+        }
+
+        return $this->_getCheckboxAndLinks(
+            $dir, $del_url, $is_display,
+            $row_no, $where_clause, $where_clause_html, $condition_array,
+            $del_query, 'l', $edit_url, $copy_url, $edit_anchor_class,
+            $edit_str, $copy_str, $del_str, $js_conf
+        );
+
+    } // end of the '_getPlacedLinks()' function
+
+
+    /**
+     * Get the combined classes for a column 
+     *
+     * @param string  $grid_edit_class  the class for all editable columns
+     * @param string  $not_null_class   the class for not null columns
+     * @param string  $relation_class   the class for relations in a column
+     * @param string  $hide_class       the class for visibility of a column
+     * @param string  $field_type_class the class related to type of the field
+     * @param integer $row_no           the row index
+     *
+     * @return string $class the combined classes
+     *
+     * @access  private
+     *
+     * @see     _getTableBody()
+     */
+    private function _getClassesForColumn(
+        $grid_edit_class, $not_null_class, $relation_class,
+        $hide_class, $field_type_class, $row_no
+    ) {
+
+        $printview = $this->__get('printview');
+
+        $class = 'data ' . $grid_edit_class . ' ' . $not_null_class . ' '
+            . $relation_class . ' ' . $hide_class . ' ' . $field_type_class;
+
+        if (($_SESSION['tmp_user_values']['disp_direction'] == self::DISP_DIR_VERTICAL)
+            && (! isset($printview) || ($printview != '1'))
+        ) {
+            // the row number corresponds to a data row, not HTML table row
+            $class .= ' row_' . $row_no;
+            if ($GLOBALS['cfg']['BrowsePointerEnable'] == true) {
+                $class .= ' vpointer';
+            }
+
+            if ($GLOBALS['cfg']['BrowseMarkerEnable'] == true) {
+                $class .= ' vmarker';
+            }
+        }
+
+        return $class;
+
+    } // end of the '_getClassesForColumn()' function
+
+
+    /**
+     * Get class for datetime related fields
+     *
+     * @param string $type the type of the column field
+     *
+     * @return  string  $field_type_class   the class for the column
+     *
+     * @access  private
+     *
+     * @see     _getTableBody()
+     */
+    private function _getClassForDateTimeRelatedFields($type)
+    {
+        if ((substr($type, 0, 9) == self::TIMESTAMP_FIELD)
+            || ($type == self::DATETIME_FIELD)
+        ) {
+            $field_type_class = 'datetimefield';
+        } else if ($type == self::DATE_FIELD) {
+            $field_type_class = 'datefield';
+        } else {
+            $field_type_class = '';
+        }
+        return $field_type_class;
+    } // end of the '_getClassForDateTimeRelatedFields()' function
+
+
+    /**
+     * Prepare data cell for numeric type fields
+     *
+     * @param string  $column                the relavent column in data row
+     * @param string  $class                 the html class for column
+     * @param boolean $condition_field       the column should highlighted
+     *                                       or not
+     * @param object  $meta                  the meta-information about this
+     *                                       field
+     * @param array   $map                   the list of relations
+     * @param boolean $is_field_truncated    the condition for blob data
+     *                                       replacements
+     * @param array   $analyzed_sql          the analyzed query
+     * @param string  $transformation_plugin the name of transformation plugin
+     * @param string  $default_function      the default transformation function
+     * @param string  $transform_options     the transformation parameters
+     *
+     * @return  string  $cell               the prepared cell, html content
+     *
+     * @access  private
+     *
+     * @see     _getTableBody()
+     */
+    private function _getDataCellForNumericColumns(
+        $column, $class, $condition_field, $meta, $map, $is_field_truncated,
+        $analyzed_sql, $transformation_plugin, $default_function,
+        $transform_options
+    ) {
+
+        if (! isset($column) || is_null($column)) {
+
+            $cell = $this->_buildNullDisplay(
+                'right '.$class, $condition_field, $meta, ''
+            );
+
+        } elseif ($column != '') {
+
+            $nowrap = ' nowrap';
+            $where_comparison = ' = ' . $column;
+
+            $cell = $this->_getRowData(
+                'right '.$class, $condition_field,
+                $analyzed_sql, $meta, $map, $column,
+                $transformation_plugin, $default_function, $nowrap,
+                $where_comparison, $transform_options,
+                $is_field_truncated
+            );
+        } else {
+
+            $cell = $this->_buildEmptyDisplay(
+                'right '.$class, $condition_field, $meta, ''
+            );
+        }
+
+        return $cell;
+
+    } // end of the '_getDataCellForNumericColumns()' function
+
+
+    /**
+     * Get data cell for blob type fields
+     *
+     * @param string  $column                the relavent column in data row
+     * @param string  $class                 the html class for column
+     * @param object  $meta                  the meta-information about this
+     *                                       field
+     * @param array   $_url_params           the parameters for generate url
+     * @param string  $field_flags           field flags for column(blob,
+     *                                       primary etc)
+     * @param string  $transformation_plugin the name of transformation function
+     * @param string  $default_function      the default transformation function
+     * @param string  $transform_options     the transformation parameters
+     * @param boolean $condition_field       the column should highlighted
+     *                                       or not
+     * @param boolean $is_field_truncated    the condition for blob data
+     *                                       replacements
+     *
+     * @return  string  $cell                the prepared cell, html content
+     *
+     * @access  private
+     *
+     * @see     _getTableBody()
+     */
+    private function _getDataCellForBlobColumns(
+        $column, $class, $meta, $_url_params, $field_flags, $transformation_plugin,
+        $default_function, $transform_options, $condition_field, $is_field_truncated
+    ) {
+
+        if (stristr($field_flags, self::BINARY_FIELD)) {
+
+            // remove 'grid_edit' from $class as we can't edit binary data.
+            $class = str_replace('grid_edit', '', $class);
+
+            if (! isset($column) || is_null($column)) {
+
+                $cell = $this->_buildNullDisplay($class, $condition_field, $meta);
+
+            } else {
+
+                $blobtext = $this->_handleNonPrintableContents(
+                    self::BLOB_FIELD, (isset($column) ? $column : ''),
+                    $transformation_plugin, $transform_options,
+                    $default_function, $meta, $_url_params
+                );
+
+                $cell = $this->_buildValueDisplay(
+                    $class, $condition_field, $blobtext
+                );
+                unset($blobtext);
+            }
+        } else {
+            // not binary:
+
+            if (! isset($column) || is_null($column)) {
+
+                $cell = $this->_buildNullDisplay($class, $condition_field, $meta);
+
+            } elseif ($column != '') {
+
+                // if a transform function for blob is set, none of these
+                // replacements will be made
+                if ((PMA_strlen($column) > $GLOBALS['cfg']['LimitChars'])
+                    && ($_SESSION['tmp_user_values']['display_text'] == self::DISPLAY_PARTIAL_TEXT)
+                    && ! $this->_isNeedToSyntaxHighlight(strtolower($meta->name))
+                ) {
+                    $column = PMA_substr($column, 0, $GLOBALS['cfg']['LimitChars'])
+                        . '...';
+                    $is_field_truncated = true;
+                }
+
+                // displays all space characters, 4 space
+                // characters for tabulations and <cr>/<lf>
+                $column = ($default_function != $transformation_plugin)
+                    ? $transformation_plugin->applyTransformation(
+                        $column,
+                        $transform_options,
+                        $meta
+                    )
+                    : $this->$default_function($column, array(), $meta);
+
+                if ($is_field_truncated) {
+                    $class .= ' truncated';
+                }
+
+                $cell = $this->_buildValueDisplay($class, $condition_field, $column);
+
+            } else {
+                $cell = $this->_buildEmptyDisplay($class, $condition_field, $meta);
+            }
+        }
+
+        return $cell;
+
+    } // end of the '_getDataCellForBlobColumns()' function
+
+
+    /**
+     * Get data cell for geometry type fields
+     *
+     * @param string  $column                the relavent column in data row
+     * @param string  $class                 the html class for column
+     * @param object  $meta                  the meta-information about this field
+     * @param array   $map                   the list of relations
+     * @param array   $_url_params           the parameters for generate url
+     * @param boolean $condition_field       the column should highlighted or not
+     * @param string  $transformation_plugin the name of transformation function
+     * @param string  $default_function      the default transformation function
+     * @param string  $transform_options     the transformation parameters
+     * @param boolean $is_field_truncated    the condition for blob data replacements
+     * @param array   $analyzed_sql          the analyzed query
+     *
+     * @return  string  $cell                  the prepared data cell, html content
+     *
+     * @access  private
+     *
+     * @see     _getTableBody()
+     */
+    private function _getDataCellForGeometryColumns(
+        $column, $class, $meta, $map, $_url_params, $condition_field,
+        $transformation_plugin, $default_function, $transform_options,
+        $is_field_truncated, $analyzed_sql
+    ) {
+
+        if (! isset($column) || is_null($column)) {
+
+            $cell = $this->_buildNullDisplay($class, $condition_field, $meta);
+
+        } elseif ($column != '') {
+
+            // Display as [GEOMETRY - (size)]
+            if ($_SESSION['tmp_user_values']['geometry_display'] == self::GEOMETRY_DISP_GEOM) {
+
+                $geometry_text = $this->_handleNonPrintableContents(
+                    strtoupper(self::GEOMETRY_FIELD),
+                    (isset($column) ? $column : ''), $transformation_plugin,
+                    $transform_options, $default_function, $meta
+                );
+
+                $cell = $this->_buildValueDisplay(
+                    $class, $condition_field, $geometry_text
+                );
+
+            } elseif ($_SESSION['tmp_user_values']['geometry_display']
+                == self::GEOMETRY_DISP_WKT
+            ) {
+                // Prepare in Well Known Text(WKT) format.
+
+                $where_comparison = ' = ' . $column;
+
+                // Convert to WKT format
+                $wktval = PMA_Util::asWKT($column);
+
+                if ((PMA_strlen($wktval) > $GLOBALS['cfg']['LimitChars'])
+                    && ($_SESSION['tmp_user_values']['display_text'] == self::DISPLAY_PARTIAL_TEXT)
+                ) {
+                    $wktval = PMA_substr($wktval, 0, $GLOBALS['cfg']['LimitChars'])
+                        . '...';
+                    $is_field_truncated = true;
+                }
+
+                $cell = $this->_getRowData(
+                    $class, $condition_field, $analyzed_sql, $meta, $map,
+                    $wktval, $transformation_plugin, $default_function, '',
+                    $where_comparison, $transform_options,
+                    $is_field_truncated
+                );
+
+            } else {
+                // Prepare in  Well Known Binary (WKB) format.
+
+                if ($_SESSION['tmp_user_values']['display_binary']) {
+
+                    $where_comparison = ' = ' . $column;
+
+                    $wkbval = $this->_displayBinaryAsPrintable($column, 'binary', 8);
+
+                    if ((PMA_strlen($wkbval) > $GLOBALS['cfg']['LimitChars'])
+                        && ($_SESSION['tmp_user_values']['display_text'] == self::DISPLAY_PARTIAL_TEXT)
+                    ) {
+                        $wkbval
+                            = PMA_substr($wkbval, 0, $GLOBALS['cfg']['LimitChars'])
+                            . '...';
+                        $is_field_truncated = true;
+                    }
+
+                    $cell = $this->_getRowData(
+                        $class, $condition_field,
+                        $analyzed_sql, $meta, $map, $wkbval,
+                        $transformation_plugin, $default_function, '',
+                        $where_comparison, $transform_options,
+                        $is_field_truncated
+                    );
+
+                } else {
+                    $wkbval = $this->_handleNonPrintableContents(
+                        self::BINARY_FIELD, $column, $transformation_plugin,
+                        $transform_options, $default_function, $meta,
+                        $_url_params
+                    );
+
+                    $cell = $this->_buildValueDisplay(
+                        $class, $condition_field, $wkbval
+                    );
+                }
+            }
+        } else {
+            $cell = $this->_buildEmptyDisplay($class, $condition_field, $meta);
+        }
+
+        return $cell;
+
+    } // end of the '_getDataCellForGeometryColumns()' function
+
+
+    /**
+     * Get data cell for non numeric and non blob type fields
+     *
+     * @param string  $column                the relavent column in data row
+     * @param string  $class                 the html class for column
+     * @param object  $meta                  the meta-information about the field
+     * @param array   $map                   the list of relations
+     * @param array   $_url_params           the parameters for generate url
+     * @param boolean $condition_field       the column should highlighted
+     *                                       or not
+     * @param string  $transformation_plugin the name of transformation function
+     * @param string  $default_function      the default transformation function
+     * @param string  $transform_options     the transformation parameters
+     * @param boolean $is_field_truncated    the condition for blob data
+     *                                       replacements
+     * @param array   $analyzed_sql          the analyzed query
+     * @param integer &$dt_result            the link id associated to the query
+     *                                        which results have to be displayed
+     * @param integer $col_index             the column index
+     *
+     * @return  string  $cell               the prepared data cell, html content
+     *
+     * @access  private
+     *
+     * @see     _getTableBody()
+     */
+    private function _getDataCellForNonNumericAndNonBlobColumns(
+        $column, $class, $meta, $map, $_url_params, $condition_field,
+        $transformation_plugin, $default_function, $transform_options,
+        $is_field_truncated, $analyzed_sql, &$dt_result, $col_index
+    ) {
+
+        $is_analyse = $this->__get('is_analyse');
+        $field_flags = PMA_DBI_field_flags($dt_result, $col_index);
+        if (stristr($field_flags, self::BINARY_FIELD)
+            && ($GLOBALS['cfg']['ProtectBinary'] == 'all'
+            || $GLOBALS['cfg']['ProtectBinary'] == 'noblob')
+        ) {
+            $class = str_replace('grid_edit', '', $class);
+        }
+
+        if (! isset($column) || is_null($column)) {
+
+            $cell = $this->_buildNullDisplay($class, $condition_field, $meta);
+
+        } elseif ($column != '') {
+
+            // Cut all fields to $GLOBALS['cfg']['LimitChars']
+            // (unless it's a link-type transformation)
+            if (PMA_strlen($column) > $GLOBALS['cfg']['LimitChars']
+                && ($_SESSION['tmp_user_values']['display_text'] == self::DISPLAY_PARTIAL_TEXT)
+                && gettype($transformation_plugin) == "object"
+                && ! strpos($transformation_plugin->getName(), 'Link') === true
+            ) {
+                $column = PMA_substr($column, 0, $GLOBALS['cfg']['LimitChars'])
+                    . '...';
+                $is_field_truncated = true;
+            }
+
+            $formatted = false;
+            if (isset($meta->_type) && $meta->_type === MYSQLI_TYPE_BIT) {
+
+                $column = PMA_Util::printableBitValue(
+                    $column, $meta->length
+                );
+
+                // some results of PROCEDURE ANALYSE() are reported as
+                // being BINARY but they are quite readable,
+                // so don't treat them as BINARY
+            } elseif (stristr($field_flags, self::BINARY_FIELD)
+                && ($meta->type == self::STRING_FIELD)
+                && !(isset($is_analyse) && $is_analyse)
+            ) {
+
+                if ($_SESSION['tmp_user_values']['display_binary']) {
+
+                    // user asked to see the real contents of BINARY
+                    // fields
+                    $column = $this->_displayBinaryAsPrintable($column, 'binary');
+
+                } else {
+                    // we show the BINARY message and field's size
+                    // (or maybe use a transformation)
+                    $column = $this->_handleNonPrintableContents(
+                        self::BINARY_FIELD, $column, $transformation_plugin,
+                        $transform_options, $default_function,
+                        $meta, $_url_params
+                    );
+                    $formatted = true;
+                }
+            }
+
+            if ($formatted) {
+
+                $cell = $this->_buildValueDisplay(
+                    $class, $condition_field, $column
+                );
+
+            } else {
+
+                // transform functions may enable no-wrapping:
+                $function_nowrap = 'applyTransformationNoWrap';
+
+                $bool_nowrap = (($default_function != $transformation_plugin)
+                    && function_exists($transformation_plugin->$function_nowrap()))
+                    ? $transformation_plugin->$function_nowrap($transform_options)
+                    : false;
+
+                // do not wrap if date field type
+                $nowrap = (preg_match('@DATE|TIME at i', $meta->type)
+                    || $bool_nowrap) ? ' nowrap' : '';
+
+                $where_comparison = ' = \''
+                    . PMA_Util::sqlAddSlashes($column)
+                    . '\'';
+
+                $cell = $this->_getRowData(
+                    $class, $condition_field,
+                    $analyzed_sql, $meta, $map, $column,
+                    $transformation_plugin, $default_function, $nowrap,
+                    $where_comparison, $transform_options,
+                    $is_field_truncated
+                );
+            }
+
+        } else {
+            $cell = $this->_buildEmptyDisplay($class, $condition_field, $meta);
+        }
+
+        return $cell;
+
+    } // end of the '_getDataCellForNonNumericAndNonBlobColumns()' function
+
+
+    /**
+     * Get the resulted table with the vertical direction mode.
+     *
+     * @param array $analyzed_sql the analyzed query
+     * @param array $is_display display mode
+     *
+     * @return string       html content
+     *
+     * @access  private
+     *
+     * @see     _getTable()
+     */
+    private function _getVerticalTable($analyzed_sql, $is_display)
+    {
+
+        $vertical_table_html = '';
+        $vertical_display = $this->__get('vertical_display');
+
+        // Prepares "multi row delete" link at top if required
+        if (($GLOBALS['cfg']['RowActionLinks'] != self::POSITION_RIGHT)
+            && is_array($vertical_display['row_delete'])
+            && ((count($vertical_display['row_delete']) > 0)
+            || !empty($vertical_display['textbtn']))
+        ) {
+
+            $vertical_table_html .= '<tr>' . "\n";
+            if ($GLOBALS['cfg']['RowActionLinks'] == self::POSITION_NONE) {
+                // if we are not showing the RowActionLinks, then we need to show
+                // the Multi-Row-Action checkboxes
+                $vertical_table_html .= '<th></th>' . "\n";
+            }
+
+            $vertical_table_html .= $vertical_display['textbtn']
+                . $this->_getCheckBoxesForMultipleRowOperations('_left', $is_display)
+                . '</tr>' . "\n";
+        } // end if
+
+        // Prepares "edit" link at top if required
+        if ((($GLOBALS['cfg']['RowActionLinks'] == self::POSITION_LEFT)
+            || ($GLOBALS['cfg']['RowActionLinks'] == self::POSITION_BOTH))
+            && is_array($vertical_display['edit'])
+            && ((count($vertical_display['edit']) > 0)
+            || !empty($vertical_display['textbtn']))
+        ) {
+            $vertical_table_html .= $this->_getOperationLinksForVerticleTable(
+                'edit'
+            );
+        } // end if
+
+        // Prepares "copy" link at top if required
+        if ((($GLOBALS['cfg']['RowActionLinks'] == self::POSITION_LEFT)
+            || ($GLOBALS['cfg']['RowActionLinks'] == self::POSITION_BOTH))
+            && is_array($vertical_display['copy'])
+            && ((count($vertical_display['copy']) > 0)
+            || !empty($vertical_display['textbtn']))
+        ) {
+            $vertical_table_html .= $this->_getOperationLinksForVerticleTable(
+                'copy'
+            );
+        } // end if
+
+        // Prepares "delete" link at top if required
+        if ((($GLOBALS['cfg']['RowActionLinks'] == self::POSITION_LEFT)
+            || ($GLOBALS['cfg']['RowActionLinks'] == self::POSITION_BOTH))
+            && is_array($vertical_display['delete'])
+            && ((count($vertical_display['delete']) > 0)
+            || !empty($vertical_display['textbtn']))
+        ) {
+            $vertical_table_html .= $this->_getOperationLinksForVerticleTable(
+                'delete'
+            );
+        } // end if
+
+        list($col_order, $col_visib) = $this->_getColumnParams($analyzed_sql);
+
+        // Prepares data
+        foreach ($vertical_display['desc'] AS $j => $val) {
+
+            // assign appropriate key with current column order
+            $key = $col_order ? $col_order[$j] : $j;
+
+            $vertical_table_html .= '<tr'
+                . (($col_visib && !$col_visib[$j]) ? ' class="hide"' : '')
+                . '>' . "\n"
+                . $val;
+
+            $cell_displayed = 0;
+            foreach ($vertical_display['rowdata'][$key] as $subval) {
+
+                if (($cell_displayed != 0)
+                    && ($_SESSION['tmp_user_values']['repeat_cells'] != 0)
+                    && ! ($cell_displayed % $_SESSION['tmp_user_values']['repeat_cells'])
+                ) {
+                    $vertical_table_html .= $val;
+                }
+
+                $vertical_table_html .= $subval;
+                $cell_displayed++;
+
+            } // end while
+
+            $vertical_table_html .= '</tr>' . "\n";
+        } // end while
+
+        // Prepares "multi row delete" link at bottom if required
+        if ((($GLOBALS['cfg']['RowActionLinks'] == self::POSITION_RIGHT)
+            || ($GLOBALS['cfg']['RowActionLinks'] == self::POSITION_BOTH))
+            && is_array($vertical_display['row_delete'])
+            && ((count($vertical_display['row_delete']) > 0)
+            || !empty($vertical_display['textbtn']))
+        ) {
+
+            $vertical_table_html .= '<tr>' . "\n"
+                . $vertical_display['textbtn']
+                . $this->_getCheckBoxesForMultipleRowOperations('_right', $is_display)
+                . '</tr>' . "\n";
+        } // end if
+
+        // Prepares "edit" link at bottom if required
+        if ((($GLOBALS['cfg']['RowActionLinks'] == self::POSITION_RIGHT)
+            || ($GLOBALS['cfg']['RowActionLinks'] == self::POSITION_BOTH))
+            && is_array($vertical_display['edit'])
+            && ((count($vertical_display['edit']) > 0)
+            || !empty($vertical_display['textbtn']))
+        ) {
+            $vertical_table_html .= $this->_getOperationLinksForVerticleTable(
+                'edit'
+            );
+        } // end if
+
+        // Prepares "copy" link at bottom if required
+        if ((($GLOBALS['cfg']['RowActionLinks'] == self::POSITION_RIGHT)
+            || ($GLOBALS['cfg']['RowActionLinks'] == self::POSITION_BOTH))
+            && is_array($vertical_display['copy'])
+            && ((count($vertical_display['copy']) > 0)
+            || !empty($vertical_display['textbtn']))
+        ) {
+            $vertical_table_html .= $this->_getOperationLinksForVerticleTable(
+                'copy'
+            );
+        } // end if
+
+        // Prepares "delete" link at bottom if required
+        if ((($GLOBALS['cfg']['RowActionLinks'] == self::POSITION_RIGHT)
+            || ($GLOBALS['cfg']['RowActionLinks'] == self::POSITION_BOTH))
+            && is_array($vertical_display['delete'])
+            && ((count($vertical_display['delete']) > 0)
+            || !empty($vertical_display['textbtn']))
+        ) {
+            $vertical_table_html .= $this->_getOperationLinksForVerticleTable(
+                'delete'
+            );
+        }
+
+        return $vertical_table_html;
+
+    } // end of the '_getVerticalTable' function
+
+
+    /**
+     * Prepare edit, copy and delete links for verticle table
+     *
+     * @param string $operation edit/copy/delete
+     *
+     * @return  string  $links_html  html content
+     *
+     * @access  private
+     *
+     * @see     _getVerticalTable()
+     */
+    private function _getOperationLinksForVerticleTable($operation)
+    {
+
+        $link_html = '<tr>' . "\n";
+        $vertical_display = $this->__get('vertical_display');
+
+        if (! is_array($vertical_display['row_delete'])) {
+
+            if (($operation == 'edit') || ($operation == 'copy')) {
+                $link_html .= $vertical_display['textbtn'];
+
+            } elseif ($operation == 'delete') {
+
+                if (! is_array($vertical_display['edit'])) {
+                    $link_html .= $vertical_display['textbtn'];
+                }
+            }
+        }
+
+        foreach ($vertical_display[$operation] as $val) {
+            $link_html .= $val;
+        } // end while
+
+        $link_html .= '</tr>' . "\n";
+
+        return $link_html;
+
+    } // end of the '_getOperationLinksForVerticleTable' function
+
+
+    /**
+     * Get checkboxes for multiple row data operations
+     *
+     * @param string $dir _left / _right
+     * @param array $is_display display mode
+     *
+     * @return  $checkBoxes_html html content
+     *
+     * @access  private
+     *
+     * @see     _getVerticalTable()
+     */
+    private function _getCheckBoxesForMultipleRowOperations($dir, $is_display)
+    {
+
+        $checkBoxes_html = '';
+        $cell_displayed = 0;
+        $vertical_display = $this->__get('vertical_display');
+
+        foreach ($vertical_display['row_delete'] as $val) {
+
+            if (($cell_displayed != 0)
+                && ($_SESSION['tmp_user_values']['repeat_cells'] != 0)
+                && !($cell_displayed % $_SESSION['tmp_user_values']['repeat_cells'])
+            ) {
+
+                $checkBoxes_html .= '<th'
+                    . (($is_display['edit_lnk'] != self::NO_EDIT_OR_DELETE)
+                        && ($is_display['del_lnk'] != self::NO_EDIT_OR_DELETE))
+                        ? ' rowspan="4"'
+                        : ''
+                    . '></th>' . "\n";
+
+            }
+
+            $checkBoxes_html .= str_replace('[%_PMA_CHECKBOX_DIR_%]', $dir, $val);
+            $cell_displayed++;
+        } // end while
+
+        return $checkBoxes_html;
+
+    } // end of the '_getCheckBoxesForMultipleRowOperations' function
+
+
+    /**
+     * Checks the posted options for viewing query resutls
+     * and sets appropriate values in the session.
+     *
+     * @todo    make maximum remembered queries configurable
+     * @todo    move/split into SQL class!?
+     * @todo    currently this is called twice unnecessary
+     * @todo    ignore LIMIT and ORDER in query!?
+     *
+     * @return void
+     *
+     * @access  public
+     *
+     * @see     sql.php file
+     */
+    public function setConfigParamsForDisplayTable()
+    {
+
+        $sql_md5 = md5($this->__get('sql_query'));
+
+        $_SESSION['tmp_user_values']['query'][$sql_md5]['sql']
+            = $this->__get('sql_query');
+
+        $valid_disp_dir = PMA_isValid(
+            $_REQUEST['disp_direction'],
+            array(self::DISP_DIR_HORIZONTAL, self::DISP_DIR_VERTICAL,
+                self::DISP_DIR_HORIZONTAL_FLIPPED
+            )
+        );
+
+        if ($valid_disp_dir) {
+            $_SESSION['tmp_user_values']['query'][$sql_md5]['disp_direction']
+                = $_REQUEST['disp_direction'];
+            unset($_REQUEST['disp_direction']);
+        } elseif (
+            empty($_SESSION['tmp_user_values']['query'][$sql_md5]['disp_direction'])
+        ) {
+            $_SESSION['tmp_user_values']['query'][$sql_md5]['disp_direction']
+                = $GLOBALS['cfg']['DefaultDisplay'];
+        }
+
+        if (PMA_isValid($_REQUEST['repeat_cells'], 'numeric')) {
+            $_SESSION['tmp_user_values']['query'][$sql_md5]['repeat_cells']
+                = $_REQUEST['repeat_cells'];
+            unset($_REQUEST['repeat_cells']);
+        } elseif (
+            empty($_SESSION['tmp_user_values']['query'][$sql_md5]['repeat_cells'])
+        ) {
+            $_SESSION['tmp_user_values']['query'][$sql_md5]['repeat_cells']
+                = $GLOBALS['cfg']['RepeatCells'];
+        }
+
+        // as this is a form value, the type is always string so we cannot
+        // use PMA_isValid($_REQUEST['session_max_rows'], 'integer')
+        if ((PMA_isValid($_REQUEST['session_max_rows'], 'numeric')
+            && ((int) $_REQUEST['session_max_rows'] == $_REQUEST['session_max_rows']))
+            || ($_REQUEST['session_max_rows'] == self::ALL_ROWS)
+        ) {
+            $_SESSION['tmp_user_values']['query'][$sql_md5]['max_rows']
+                = $_REQUEST['session_max_rows'];
+            unset($_REQUEST['session_max_rows']);
+        } elseif (empty($_SESSION['tmp_user_values']['query'][$sql_md5]['max_rows'])) {
+            $_SESSION['tmp_user_values']['query'][$sql_md5]['max_rows']
+                = $GLOBALS['cfg']['MaxRows'];
+        }
+
+        if (PMA_isValid($_REQUEST['pos'], 'numeric')) {
+            $_SESSION['tmp_user_values']['query'][$sql_md5]['pos']
+                = $_REQUEST['pos'];
+            unset($_REQUEST['pos']);
+        } elseif (empty($_SESSION['tmp_user_values']['query'][$sql_md5]['pos'])) {
+            $_SESSION['tmp_user_values']['query'][$sql_md5]['pos'] = 0;
+        }
+
+        if (PMA_isValid(
+            $_REQUEST['display_text'],
+            array(
+                self::DISPLAY_PARTIAL_TEXT, self::DISPLAY_FULL_TEXT
+            )
+        )
+        ) {
+            $_SESSION['tmp_user_values']['query'][$sql_md5]['display_text']
+                = $_REQUEST['display_text'];
+            unset($_REQUEST['display_text']);
+        } elseif (
+            empty($_SESSION['tmp_user_values']['query'][$sql_md5]['display_text'])
+        ) {
+            $_SESSION['tmp_user_values']['query'][$sql_md5]['display_text']
+                = self::DISPLAY_PARTIAL_TEXT;
+        }
+
+        if (PMA_isValid(
+            $_REQUEST['relational_display'],
+            array(
+                self::RELATIONAL_KEY, self::RELATIONAL_DISPLAY_COLUMN
+            )
+        )
+        ) {
+            $_SESSION['tmp_user_values']['query'][$sql_md5]['relational_display']
+                = $_REQUEST['relational_display'];
+            unset($_REQUEST['relational_display']);
+        } elseif (
+            empty(
+                $_SESSION['tmp_user_values']['query'][$sql_md5]['relational_display']
+            )
+        ) {
+            $_SESSION['tmp_user_values']['query'][$sql_md5]['relational_display']
+                = self::RELATIONAL_KEY;
+        }
+
+        if (PMA_isValid(
+            $_REQUEST['geometry_display'],
+            array(
+                self::GEOMETRY_DISP_WKT, self::GEOMETRY_DISP_WKB,
+                self::GEOMETRY_DISP_GEOM
+            )
+        )
+        ) {
+            $_SESSION['tmp_user_values']['query'][$sql_md5]['geometry_display']
+                = $_REQUEST['geometry_display'];
+            unset($_REQUEST['geometry_display']);
+        } elseif (
+            empty(
+                $_SESSION['tmp_user_values']['query'][$sql_md5]['geometry_display']
+            )
+        ) {
+            $_SESSION['tmp_user_values']['query'][$sql_md5]['geometry_display']
+                = self::GEOMETRY_DISP_GEOM;
+        }
+
+        if (isset($_REQUEST['display_binary'])) {
+            $_SESSION['tmp_user_values']['query'][$sql_md5]['display_binary'] = true;
+            unset($_REQUEST['display_binary']);
+        } elseif (isset($_REQUEST['display_options_form'])) {
+            // we know that the checkbox was unchecked
+            unset($_SESSION['tmp_user_values']['query'][$sql_md5]['display_binary']);
+        } elseif (isset($_REQUEST['full_text_button'])) {
+            // do nothing to keep the value that is there in the session
+        } else {
+            // selected by default because some operations like OPTIMIZE TABLE
+            // and all queries involving functions return "binary" contents,
+            // according to low-level field flags
+            $_SESSION['tmp_user_values']['query'][$sql_md5]['display_binary'] = true;
+        }
+
+        if (isset($_REQUEST['display_binary_as_hex'])) {
+            $_SESSION['tmp_user_values']['query'][$sql_md5]['display_binary_as_hex']
+                = true;
+            unset($_REQUEST['display_binary_as_hex']);
+        } elseif (isset($_REQUEST['display_options_form'])) {
+            // we know that the checkbox was unchecked
+            unset($_SESSION['tmp_user_values']['query'][$sql_md5]
+                ['display_binary_as_hex']
+            );
+        } elseif (isset($_REQUEST['full_text_button'])) {
+            // do nothing to keep the value that is there in the session
+        } else {
+            // display_binary_as_hex config option
+            if (isset($GLOBALS['cfg']['DisplayBinaryAsHex'])
+                && ($GLOBALS['cfg']['DisplayBinaryAsHex'] === true)
+            ) {
+                $_SESSION['tmp_user_values']['query'][$sql_md5]
+                    ['display_binary_as_hex'] = true;
+            }
+        }
+
+        if (isset($_REQUEST['display_blob'])) {
+            $_SESSION['tmp_user_values']['query'][$sql_md5]['display_blob'] = true;
+            unset($_REQUEST['display_blob']);
+        } elseif (isset($_REQUEST['display_options_form'])) {
+            // we know that the checkbox was unchecked
+            unset($_SESSION['tmp_user_values']['query'][$sql_md5]['display_blob']);
+        }
+
+        if (isset($_REQUEST['hide_transformation'])) {
+            $_SESSION['tmp_user_values']['query'][$sql_md5]['hide_transformation']
+                = true;
+            unset($_REQUEST['hide_transformation']);
+        } elseif (isset($_REQUEST['display_options_form'])) {
+            // we know that the checkbox was unchecked
+            unset($_SESSION['tmp_user_values']['query'][$sql_md5]
+                ['hide_transformation']
+            );
+        }
+
+        // move current query to the last position, to be removed last
+        // so only least executed query will be removed if maximum remembered queries
+        // limit is reached
+        $tmp = $_SESSION['tmp_user_values']['query'][$sql_md5];
+        unset($_SESSION['tmp_user_values']['query'][$sql_md5]);
+        $_SESSION['tmp_user_values']['query'][$sql_md5] = $tmp;
+
+        // do not exceed a maximum number of queries to remember
+        if (count($_SESSION['tmp_user_values']['query']) > 10) {
+            array_shift($_SESSION['tmp_user_values']['query']);
+            //echo 'deleting one element ...';
+        }
+
+        // populate query configuration
+        $_SESSION['tmp_user_values']['display_text']
+            = $_SESSION['tmp_user_values']['query'][$sql_md5]['display_text'];
+        $_SESSION['tmp_user_values']['relational_display']
+            = $_SESSION['tmp_user_values']['query'][$sql_md5]['relational_display'];
+        $_SESSION['tmp_user_values']['geometry_display']
+            = $_SESSION['tmp_user_values']['query'][$sql_md5]['geometry_display'];
+        $_SESSION['tmp_user_values']['display_binary']
+            = isset($_SESSION['tmp_user_values']['query'][$sql_md5]
+                ['display_binary']
+            )
+            ? true
+            : false;
+        $_SESSION['tmp_user_values']['display_binary_as_hex']
+            = isset($_SESSION['tmp_user_values']['query'][$sql_md5]
+                ['display_binary_as_hex']
+            )
+            ? true
+            : false;
+        $_SESSION['tmp_user_values']['display_blob']
+            = isset($_SESSION['tmp_user_values']['query'][$sql_md5]['display_blob'])
+            ? true
+            : false;
+        $_SESSION['tmp_user_values']['hide_transformation']
+            = isset($_SESSION['tmp_user_values']['query'][$sql_md5]
+                ['hide_transformation']
+            )
+            ? true
+            : false;
+        $_SESSION['tmp_user_values']['pos']
+            = $_SESSION['tmp_user_values']['query'][$sql_md5]['pos'];
+        $_SESSION['tmp_user_values']['max_rows']
+            = $_SESSION['tmp_user_values']['query'][$sql_md5]['max_rows'];
+        $_SESSION['tmp_user_values']['repeat_cells']
+            = $_SESSION['tmp_user_values']['query'][$sql_md5]['repeat_cells'];
+        $_SESSION['tmp_user_values']['disp_direction']
+            = $_SESSION['tmp_user_values']['query'][$sql_md5]['disp_direction'];
+
+    }
+
+
+    /**
+     * Prepare a table of results returned by a SQL query.
+     * This function is called by the "sql.php" script.
+     *
+     * @param integer &$dt_result         the link id associated to the query
+     *                                    which results have to be displayed
+     * @param array   &$the_disp_mode     the display mode
+     * @param array   $analyzed_sql       the analyzed query
+     * @param boolean $is_limited_display With limited operations or not
+     *
+     * @return  string   $table_html   Generated HTML content for resulted table
+     *
+     * @access  public
+     *
+     * @see     sql.php file
+     */
+    public function getTable(
+        &$dt_result, &$the_disp_mode, $analyzed_sql, $is_limited_display = false
+    ) {
+
+        $table_html = '';
+        // Following variable are needed for use in isset/empty or
+        // use with array indexes/safe use in foreach
+        $fields_meta = $this->__get('fields_meta');
+        $showtable = $this->__get('showtable');
+        $printview = $this->__get('printview');
+
+        // why was this called here? (already called from sql.php)
+        //$this->setConfigParamsForDisplayTable();
+
+        /**
+         * @todo move this to a central place
+         * @todo for other future table types
+         */
+        $is_innodb = (isset($showtable['Type'])
+            && $showtable['Type'] == self::TABLE_TYPE_INNO_DB);
+
+        if ($is_innodb
+            && ! isset($analyzed_sql[0]['queryflags']['union'])
+            && ! isset($analyzed_sql[0]['table_ref'][1]['table_name'])
+            && (empty($analyzed_sql[0]['where_clause'])
+            || ($analyzed_sql[0]['where_clause'] == '1 '))
+        ) {
+            // "j u s t   b r o w s i n g"
+            $pre_count = '~';
+            $after_count = PMA_Util::showHint(
+                PMA_sanitize(
+                    __('May be approximate. See [doc at faq3-11]FAQ 3.11[/doc]')
+                )
+            );
+        } else {
+            $pre_count = '';
+            $after_count = '';
+        }
+
+        // 1. ----- Prepares the work -----
+
+        // 1.1 Gets the informations about which functionalities should be
+        //     displayed
+        $total      = '';
+        $is_display = $this->_setDisplayMode($the_disp_mode, $total);
+
+        // 1.2 Defines offsets for the next and previous pages
+        if ($is_display['nav_bar'] == '1') {
+            list($pos_next, $pos_prev) = $this->_getOffsets();
+        } // end if
+        if (!isset($analyzed_sql[0]['order_by_clause'])) {
+            $analyzed_sql[0]['order_by_clause'] = "";
+        }
+
+        // 1.3 Find the sort expression
+        // we need $sort_expression and $sort_expression_nodirection
+        // even if there are many table references
+        list($sort_expression, $sort_expression_nodirection, $sort_direction)
+            = $this->_getSortParams($analyzed_sql[0]['order_by_clause']);
+
+
+        // 1.4 Prepares display of first and last value of the sorted column
+
+        $sorted_column_message = $this->_getSortedColumnMessage(
+            $dt_result, $sort_expression_nodirection
+        );
+
+
+        // 2. ----- Prepare to display the top of the page -----
+
+        // 2.1 Prepares a messages with position informations
+        if (($is_display['nav_bar'] == '1') && isset($pos_next)) {
+
+            $message = $this->_setMessageInformation(
+                $sorted_column_message, $analyzed_sql[0]['limit_clause'],
+                $total, $pos_next, $pre_count, $after_count
+            );
+
+            $table_html .= PMA_Util::getMessage(
+                $message, $this->__get('sql_query'), 'success'
+            );
+
+        } elseif (! isset($printview) || ($printview != '1')) {
+
+            $table_html .= PMA_Util::getMessage(
+                __('Your SQL query has been executed successfully'),
+                $this->__get('sql_query'), 'success'
+            );
+        }
+
+        // 2.3 Prepare the navigation bars
+        if (! strlen($this->__get('table'))) {
+
+            if (isset($analyzed_sql[0]['query_type'])
+                && ($analyzed_sql[0]['query_type'] == self::QUERY_TYPE_SELECT)
+            ) {
+                // table does not always contain a real table name,
+                // for example in MySQL 5.0.x, the query SHOW STATUS
+                // returns STATUS as a table name
+                $this->__set('table', $fields_meta[0]->table);
+            } else {
+                $this->__set('table', '');
+            }
+
+        }
+
+        if (($is_display['nav_bar'] == '1')
+            && empty($analyzed_sql[0]['limit_clause'])
+        ) {
+
+            $table_html .= $this->_getPlacedTableNavigatoins(
+                $pos_next, $pos_prev, self::PLACE_TOP_DIRECTION_DROPDOWN,
+                "\n", $is_innodb
+            );
+
+        } elseif (! isset($printview) || ($printview != '1')) {
+            $table_html .= "\n" . '<br /><br />' . "\n";
+        }
+
+        // 2b ----- Get field references from Database -----
+        // (see the 'relation' configuration variable)
+
+        // initialize map
+        $map = array();
+
+        // find tables
+        $target=array();
+        if (isset($analyzed_sql[0]['table_ref'])
+            && is_array($analyzed_sql[0]['table_ref'])
+        ) {
+
+            foreach ($analyzed_sql[0]['table_ref']
+                as $table_ref_position => $table_ref) {
+                $target[] = $analyzed_sql[0]['table_ref']
+                    [$table_ref_position]['table_true_name'];
+            }
+
+        }
+
+        $tabs = '(\'' . join('\',\'', $target) . '\')';
+
+        if (! strlen($this->__get('table'))) {
+            $exist_rel = false;
+        } else {
+            // This method set the values for $map array
+            $this->_setParamForLinkForeignKeyRelatedTables($map);
+        } // end if
+        // end 2b
+
+        // 3. ----- Prepare the results table -----
+        $table_html .= $this->_getTableHeaders(
+            $is_display, $analyzed_sql, $sort_expression,
+            $sort_expression_nodirection, $sort_direction, $is_limited_display
+        )
+        . '<tbody>' . "\n";
+
+        $url_query = '';
+        $table_html .= $this->_getTableBody(
+            $dt_result, $is_display, $map, $analyzed_sql, $is_limited_display
+        );
+
+        // vertical output case
+        if ($_SESSION['tmp_user_values']['disp_direction'] == self::DISP_DIR_VERTICAL) {
+            $table_html .= $this->_getVerticalTable($analyzed_sql, $is_display);
+        } // end if
+
+        $this->__set('vertical_display', null);
+
+        $table_html .= '</tbody>' . "\n"
+            . '</table>';
+
+        // 4. ----- Prepares the link for multi-fields edit and delete
+
+        if ($is_display['del_lnk'] == self::DELETE_ROW
+            && $is_display['del_lnk'] != self::KILL_PROCESS
+        ) {
+
+            $table_html .= $this->_getMultiRowOperationLinks(
+                $dt_result, $analyzed_sql, $is_display['del_lnk']
+            );
+
+        }
+
+        // 5. ----- Get the navigation bar at the bottom if required -----
+        if (($is_display['nav_bar'] == '1')
+            && empty($analyzed_sql[0]['limit_clause'])
+        ) {
+            $table_html .= $this->_getPlacedTableNavigatoins(
+                $pos_next, $pos_prev, self::PLACE_BOTTOM_DIRECTION_DROPDOWN,
+                '<br />' . "\n", $is_innodb
+            );
+        } elseif (! isset($printview) || ($printview != '1')) {
+            $table_html .= "\n" . '<br /><br />' . "\n";
+        }
+
+
+        // 6. ----- Prepare "Query results operations"
+        if ((! isset($printview) || ($printview != '1')) && ! $is_limited_display) {
+            $table_html .= $this->_getResultsOperations(
+                $the_disp_mode, $analyzed_sql
+            );
+        }
+
+        return $table_html;
+
+    } // end of the 'getTable()' function
+
+
+    /**
+     * Get offsets for next page and previous page
+     *
+     * @return  array           array with two elements - $pos_next, $pos_prev
+     *
+     * @access  private
+     *
+     * @see     getTable()
+     */
+    private function _getOffsets()
+    {
+
+        if ($_SESSION['tmp_user_values']['max_rows'] == self::ALL_ROWS) {
+            $pos_next     = 0;
+            $pos_prev     = 0;
+        } else {
+
+            $pos_next     = $_SESSION['tmp_user_values']['pos']
+                            + $_SESSION['tmp_user_values']['max_rows'];
+
+            $pos_prev     = $_SESSION['tmp_user_values']['pos']
+                            - $_SESSION['tmp_user_values']['max_rows'];
+
+            if ($pos_prev < 0) {
+                $pos_prev = 0;
+            }
+        }
+
+        return array($pos_next, $pos_prev);
+
+    } // end of the '_getOffsets()' function
+
+
+    /**
+     * Get sort parameters
+     *
+     * @param string $order_by_clause the order by clause of the sql query
+     *
+     * @return  array                 3 element array: $sort_expression,
+     *                                $sort_expression_nodirection, $sort_direction
+     *
+     * @access  private
+     *
+     * @see     getTable()
+     */
+    private function _getSortParams($order_by_clause)
+    {
+
+        if (! empty($order_by_clause)) {
+
+            $sort_expression = trim(
+                str_replace('  ', ' ', $order_by_clause)
+            );
+            /**
+             * Get rid of ASC|DESC
+             */
+            preg_match(
+                '@(.*)([[:space:]]*(ASC|DESC))@si', $sort_expression, $matches
+            );
+
+            $sort_expression_nodirection = isset($matches[1])
+                ? trim($matches[1])
+                : $sort_expression;
+
+            $sort_direction = isset($matches[2]) ? trim($matches[2]) : '';
+            unset($matches);
+
+        } else {
+            $sort_expression = $sort_expression_nodirection = $sort_direction = '';
+        }
+
+        return array($sort_expression, $sort_expression_nodirection,
+            $sort_direction
+        );
+
+    } // end of the '_getSortParams()' function
+
+
+    /**
+     * Prepare sorted column message
+     *
+     * @param integer &$dt_result                  the link id associated to the
+     *                                              query which results have to
+     *                                              be displayed
+     * @param string  $sort_expression_nodirection sort expression without direction
+     *
+     * @return  string                              html content
+     *          null                                if not found sorted column
+     *
+     * @access  private
+     *
+     * @see     getTable()
+     */
+    private function _getSortedColumnMessage(
+        &$dt_result, $sort_expression_nodirection
+    ) {
+
+        $fields_meta = $this->__get('fields_meta'); // To use array indexes
+
+        if (! empty($sort_expression_nodirection)) {
+
+            if (strpos($sort_expression_nodirection, '.') === false) {
+                $sort_table = $this->__get('table');
+                $sort_column = $sort_expression_nodirection;
+            } else {
+                list($sort_table, $sort_column)
+                    = explode('.', $sort_expression_nodirection);
+            }
+
+            $sort_table = PMA_Util::unQuote($sort_table);
+            $sort_column = PMA_Util::unQuote($sort_column);
+
+            // find the sorted column index in row result
+            // (this might be a multi-table query)
+            $sorted_column_index = false;
+
+            foreach ($fields_meta as $key => $meta) {
+                if (($meta->table == $sort_table) && ($meta->name == $sort_column)) {
+                    $sorted_column_index = $key;
+                    break;
+                }
+            }
+
+            if ($sorted_column_index !== false) {
+
+                // fetch first row of the result set
+                $row = PMA_DBI_fetch_row($dt_result);
+
+                // initializing default arguments
+                $default_function = '_mimeDefaultFunction';
+                $transformation_plugin = $default_function;
+                $transform_options = array();
+
+                // check for non printable sorted row data
+                $meta = $fields_meta[$sorted_column_index];
+
+                if (stristr($meta->type, self::BLOB_FIELD)
+                    || ($meta->type == self::GEOMETRY_FIELD)
+                ) {
+
+                    $column_for_first_row = $this->_handleNonPrintableContents(
+                        $meta->type, $row[$sorted_column_index],
+                        $transformation_plugin, $transform_options,
+                        $default_function, $meta, null
+                    );
+
+                } else {
+                    $column_for_first_row = $row[$sorted_column_index];
+                }
+
+                $column_for_first_row = strtoupper(
+                    substr($column_for_first_row, 0, $GLOBALS['cfg']['LimitChars'])
+                );
+
+                // fetch last row of the result set
+                PMA_DBI_data_seek($dt_result, $this->__get('num_rows') - 1);
+                $row = PMA_DBI_fetch_row($dt_result);
+
+                // check for non printable sorted row data
+                $meta = $fields_meta[$sorted_column_index];
+                if (stristr($meta->type, self::BLOB_FIELD)
+                    || ($meta->type == self::GEOMETRY_FIELD)
+                ) {
+
+                    $column_for_last_row = $this->_handleNonPrintableContents(
+                        $meta->type, $row[$sorted_column_index],
+                        $transformation_plugin, $transform_options,
+                        $default_function, $meta, null
+                    );
+
+                } else {
+                    $column_for_last_row = $row[$sorted_column_index];
+                }
+
+                $column_for_last_row = strtoupper(
+                    substr($column_for_last_row, 0, $GLOBALS['cfg']['LimitChars'])
+                );
+
+                // reset to first row for the loop in _getTableBody()
+                PMA_DBI_data_seek($dt_result, 0);
+
+                // we could also use here $sort_expression_nodirection
+                return ' [' . htmlspecialchars($sort_column)
+                    . ': <strong>' . htmlspecialchars($column_for_first_row) . ' - '
+                    . htmlspecialchars($column_for_last_row) . '</strong>]';
+            }
+        }
+
+        return null;
+
+    } // end of the '_getSortedColumnMessage()' function
+
+
+    /**
+     * Set the content need to be show in message
+     *
+     * @param string  $sorted_column_message the message for sorted column
+     * @param string  $limit_clause          the limit clause of analyzed query
+     * @param integer $total                 the total number of rows returned by
+     *                                       the SQL query without any
+     *                                       programmatically appended LIMIT clause
+     * @param integer $pos_next              the offset for next page
+     * @param string  $pre_count             the string renders before row count
+     * @param string  $after_count           the string renders after row count
+     *
+     * @return PMA_Message $message an object of PMA_Message
+     *
+     * @access  private
+     *
+     * @see     getTable()
+     */
+    private function _setMessageInformation(
+        $sorted_column_message, $limit_clause, $total,
+        $pos_next, $pre_count, $after_count
+    ) {
+
+        $unlim_num_rows = $this->__get('unlim_num_rows'); // To use in isset()
+
+        if (isset($unlim_num_rows) && ($unlim_num_rows != $total)) {
+            $selectstring = ', ' . $unlim_num_rows . ' ' . __('in query');
+        } else {
+            $selectstring = '';
+        }
+
+        if (! empty($limit_clause)) {
+
+            $limit_data
+                = PMA_Util::analyzeLimitClause($limit_clause);
+            $first_shown_rec = $limit_data['start'];
+
+            if ($limit_data['length'] < $total) {
+                $last_shown_rec = $limit_data['start'] + $limit_data['length'] - 1;
+            } else {
+                $last_shown_rec = $limit_data['start'] + $total - 1;
+            }
+
+        } elseif (($_SESSION['tmp_user_values']['max_rows'] == self::ALL_ROWS)
+            || ($pos_next > $total)
+        ) {
+
+            $first_shown_rec = $_SESSION['tmp_user_values']['pos'];
+            $last_shown_rec  = $total - 1;
+
+        } else {
+
+            $first_shown_rec = $_SESSION['tmp_user_values']['pos'];
+            $last_shown_rec  = $pos_next - 1;
+
+        }
+
+        if (PMA_Table::isView($this->__get('db'), $this->__get('table'))
+            && ($total == $GLOBALS['cfg']['MaxExactCountViews'])
+        ) {
+
+            $message = PMA_Message::notice(
+                __(
+                    'This view has at least this number of rows. '
+                    . 'Please refer to %sdocumentation%s.'
+                )
+            );
+
+            $message->addParam('[doc at cfg_MaxExactCount]');
+            $message->addParam('[/doc]');
+            $message_view_warning = PMA_Util::showHint($message);
+
+        } else {
+            $message_view_warning = false;
+        }
+
+        $message = PMA_Message::success(__('Showing rows'));
+        $message->addMessage($first_shown_rec);
+
+        if ($message_view_warning) {
+
+            $message->addMessage('...', ' - ');
+            $message->addMessage($message_view_warning);
+            $message->addMessage('(');
+
+        } else {
+
+            $message->addMessage($last_shown_rec, ' - ');
+            $message->addMessage(' (');
+            $message->addMessage(
+                $pre_count . PMA_Util::formatNumber($total, 0)
+            );
+            $message->addString(__('total'));
+
+            if (!empty($after_count)) {
+                $message->addMessage($after_count);
+            }
+
+            $message->addMessage($selectstring, '');
+            $message->addMessage(', ', '');
+
+        }
+
+        $messagge_qt = PMA_Message::notice(__('Query took %01.4f sec') . ')');
+        $messagge_qt->addParam($this->__get('querytime'));
+
+        $message->addMessage($messagge_qt, '');
+        if (! is_null($sorted_column_message)) {
+            $message->addMessage($sorted_column_message, '');
+        }
+
+        return $message;
+
+    } // end of the '_setMessageInformation()' function
+
+
+    /**
+     * Set the value of $map array for linking foreign key related tables
+     *
+     * @param array &$map the list of relations
+     *
+     * @return  void
+     *
+     * @access  private
+     *
+     * @see      getTable()
+     */
+    private function _setParamForLinkForeignKeyRelatedTables(&$map)
+    {
+
+        // To be able to later display a link to the related table,
+        // we verify both types of relations: either those that are
+        // native foreign keys or those defined in the phpMyAdmin
+        // configuration storage. If no PMA storage, we won't be able
+        // to use the "column to display" notion (for example show
+        // the name related to a numeric id).
+        $exist_rel = PMA_getForeigners(
+            $this->__get('db'), $this->__get('table'), '', self::POSITION_BOTH
+        );
+
+        if ($exist_rel) {
+
+            foreach ($exist_rel as $master_field => $rel) {
+
+                $display_field = PMA_getDisplayField(
+                    $rel['foreign_db'], $rel['foreign_table']
+                );
+
+                $map[$master_field] = array(
+                        $rel['foreign_table'],
+                        $rel['foreign_field'],
+                        $display_field,
+                        $rel['foreign_db']
+                    );
+            } // end while
+        } // end if
+
+    } // end of the '_setParamForLinkForeignKeyRelatedTables()' function
+
+
+    /**
+     * Prepare multi field edit/delete links
+     *
+     * @param integer &$dt_result   the link id associated to the query
+     *                              which results have to be displayed
+     * @param array   $analyzed_sql the analyzed query
+     * @param string  $del_link     the display element - 'del_link'
+     *
+     * @return string $links_html html content
+     *
+     * @access  private
+     *
+     * @see     getTable()
+     */
+    private function _getMultiRowOperationLinks(
+        &$dt_result, $analyzed_sql, $del_link
+    ) {
+
+        $links_html = '';
+        $url_query = $this->__get('url_query');
+        $delete_text = ($del_link == self::DELETE_ROW) ? __('Delete') : __('Kill');
+
+        $_url_params = array(
+            'db'        => $this->__get('db'),
+            'table'     => $this->__get('table'),
+            'sql_query' => $this->__get('sql_query'),
+            'goto'      => $this->__get('goto'),
+        );
+
+        if ($_SESSION['tmp_user_values']['disp_direction'] != self::DISP_DIR_VERTICAL) {
+
+            $links_html .= '<img class="selectallarrow" width="38" height="22"'
+                . ' src="' . $this->__get('pma_theme_image') . 'arrow_'
+                . $this->__get('text_dir') . '.png' . '"'
+                . ' alt="' . __('With selected:') . '" />';
+        }
+
+        $links_html .= '<input type="checkbox" id="checkall" title="'
+            . __('Check All') . '" /> '
+            . '<label for="checkall">' . __('Check All') . '</label> '
+            . '<i style="margin-left: 2em">' . __('With selected:') . '</i>' . "\n";
+
+        $links_html .= PMA_Util::getButtonOrImage(
+            'submit_mult', 'mult_submit', 'submit_mult_change',
+            __('Change'), 'b_edit.png', 'edit'
+        );
+
+        $links_html .= PMA_Util::getButtonOrImage(
+            'submit_mult', 'mult_submit', 'submit_mult_delete',
+            $delete_text, 'b_drop.png', 'delete'
+        );
+
+        if (isset($analyzed_sql[0])
+            && $analyzed_sql[0]['querytype'] == self::QUERY_TYPE_SELECT
+        ) {
+            $links_html .= PMA_Util::getButtonOrImage(
+                'submit_mult', 'mult_submit', 'submit_mult_export',
+                __('Export'), 'b_tblexport.png', 'export'
+            );
+        }
+
+        $links_html .= "\n";
+
+        $links_html .= '<input type="hidden" name="sql_query"'
+            .' value="' . htmlspecialchars($this->__get('sql_query')) . '" />'
+            . "\n";
+
+        if (! empty($url_query)) {
+            $links_html .= '<input type="hidden" name="url_query"'
+                .' value="' . $url_query . '" />' . "\n";
+        }
+
+        // fetch last row of the result set
+        PMA_DBI_data_seek($dt_result, $this->__get('num_rows') - 1);
+        $row = PMA_DBI_fetch_row($dt_result);
+
+        // $clause_is_unique is needed by getTable() to generate the proper param
+        // in the multi-edit and multi-delete form
+        list($where_clause, $clause_is_unique, $condition_array)
+            = PMA_Util::getUniqueCondition(
+                $dt_result,
+                $this->__get('fields_cnt'),
+                $this->__get('fields_meta'),
+                $row
+            );
+
+        // reset to first row for the loop in _getTableBody()
+        PMA_DBI_data_seek($dt_result, 0);
+
+        $links_html .= '<input type="hidden" name="clause_is_unique"'
+            .' value="' . $clause_is_unique . '" />' . "\n";
+
+        $links_html .= '</form>' . "\n";
+
+        return $links_html;
+
+    } // end of the '_getMultiRowOperationLinks()' function
+
+
+    /**
+     * Prepare table navigation bar at the top or bottom
+     *
+     * @param integer $pos_next   the offset for the "next" page
+     * @param integer $pos_prev   the offset for the "previous" page
+     * @param string  $place      the place to show navigation
+     * @param string  $empty_line empty line depend on the $place
+     * @param boolean $is_innodb  whether its InnoDB or not
+     *
+     * @return  string  html content of navigation bar
+     *
+     * @access  private
+     *
+     * @see     _getTable()
+     */
+    private function _getPlacedTableNavigatoins(
+        $pos_next, $pos_prev, $place, $empty_line, $is_innodb
+    ) {
+
+        $navigation_html = '';
+
+        if ($place == self::PLACE_BOTTOM_DIRECTION_DROPDOWN) {
+            $navigation_html .= '<br />' . "\n";
+        }
+
+        $navigation_html .= $this->_getTableNavigation(
+            $pos_next, $pos_prev, 'top_direction_dropdown', $is_innodb
+        );
+
+        if ($place == self::PLACE_TOP_DIRECTION_DROPDOWN) {
+            $navigation_html .= "\n";
+        }
+
+        return $navigation_html;
+
+    } // end of the '_getPlacedTableNavigatoins()' function
+
+
+    /**
+     * Get operations that are available on results.
+     *
+     * @param array $the_disp_mode the display mode
+     * @param array $analyzed_sql  the analyzed query
+     *
+     * @return string $results_operations_html  html content
+     *
+     * @access  private
+     *
+     * @see     getTable()
+     */
+    private function _getResultsOperations($the_disp_mode, $analyzed_sql)
+    {
+        global $printview;
+
+        $results_operations_html = '';
+        $fields_meta = $this->__get('fields_meta'); // To safe use in foreach
+        $header_shown = false;
+        $header = '<fieldset><legend>' . __('Query results operations')
+            . '</legend>';
+
+        if (($the_disp_mode[6] == '1') || ($the_disp_mode[9] == '1')) {
+            // Displays "printable view" link if required
+            if ($the_disp_mode[9] == '1') {
+
+                if (!$header_shown) {
+                    $results_operations_html .= $header;
+                    $header_shown = true;
+                }
+
+                $_url_params = array(
+                    'db'        => $this->__get('db'),
+                    'table'     => $this->__get('table'),
+                    'printview' => '1',
+                    'sql_query' => $this->__get('sql_query'),
+                );
+                $url_query = PMA_generate_common_url($_url_params);
+
+                $results_operations_html
+                    .= PMA_Util::linkOrButton(
+                        'sql.php' . $url_query,
+                        PMA_Util::getIcon(
+                            'b_print.png', __('Print view'), true
+                        ),
+                        array('target' => 'print_view'),
+                        true,
+                        true,
+                        'print_view'
+                    )
+                    . "\n";
+
+                if ($_SESSION['tmp_user_values']['display_text']) {
+
+                    $_url_params['display_text'] = self::DISPLAY_FULL_TEXT;
+
+                    $results_operations_html
+                        .= PMA_Util::linkOrButton(
+                            'sql.php' . PMA_generate_common_url($_url_params),
+                            PMA_Util::getIcon(
+                                'b_print.png',
+                                __('Print view (with full texts)'), true
+                            ),
+                            array('target' => 'print_view'),
+                            true,
+                            true,
+                            'print_view'
+                        )
+                        . "\n";
+                    unset($_url_params['display_text']);
+                }
+            } // end displays "printable view"
+        }
+
+        // Export link
+        // (the url_query has extra parameters that won't be used to export)
+        // (the single_table parameter is used in display_export.lib.php
+        //  to hide the SQL and the structure export dialogs)
+        // If the parser found a PROCEDURE clause
+        // (most probably PROCEDURE ANALYSE()) it makes no sense to
+        // display the Export link).
+        if (isset($analyzed_sql[0])
+            && ($analyzed_sql[0]['querytype'] == self::QUERY_TYPE_SELECT)
+            && ! isset($printview)
+            && ! isset($analyzed_sql[0]['queryflags']['procedure'])
+        ) {
+
+            if (isset($analyzed_sql[0]['table_ref'][0]['table_true_name'])
+                && ! isset($analyzed_sql[0]['table_ref'][1]['table_true_name'])
+            ) {
+                $_url_params['single_table'] = 'true';
+            }
+
+            if (! $header_shown) {
+                $results_operations_html .= $header;
+                $header_shown = true;
+            }
+
+            $_url_params['unlim_num_rows'] = $this->__get('unlim_num_rows');
+
+            /**
+             * At this point we don't know the table name; this can happen
+             * for example with a query like
+             * SELECT bike_code FROM (SELECT bike_code FROM bikes) tmp
+             * As a workaround we set in the table parameter the name of the
+             * first table of this database, so that tbl_export.php and
+             * the script it calls do not fail
+             */
+            if (empty($_url_params['table']) && ! empty($_url_params['db'])) {
+                $_url_params['table'] = PMA_DBI_fetch_value("SHOW TABLES");
+                /* No result (probably no database selected) */
+                if ($_url_params['table'] === false) {
+                    unset($_url_params['table']);
+                }
+            }
+
+            $results_operations_html .= PMA_Util::linkOrButton(
+                'tbl_export.php' . PMA_generate_common_url($_url_params),
+                PMA_Util::getIcon(
+                    'b_tblexport.png', __('Export'), true
+                ),
+                '',
+                true,
+                true,
+                ''
+            )
+            . "\n";
+
+            // prepare chart
+            $results_operations_html .= PMA_Util::linkOrButton(
+                'tbl_chart.php' . PMA_generate_common_url($_url_params),
+                PMA_Util::getIcon(
+                    'b_chart.png', __('Display chart'), true
+                ),
+                '',
+                true,
+                true,
+                ''
+            )
+            . "\n";
+
+            // prepare GIS chart
+            $geometry_found = false;
+            // If atleast one geometry field is found
+            foreach ($fields_meta as $meta) {
+                if ($meta->type == self::GEOMETRY_FIELD) {
+                    $geometry_found = true;
+                    break;
+                }
+            }
+
+            if ($geometry_found) {
+                $results_operations_html
+                    .= PMA_Util::linkOrButton(
+                        'tbl_gis_visualization.php'
+                        . PMA_generate_common_url($_url_params),
+                        PMA_Util::getIcon(
+                            'b_globe.gif', __('Visualize GIS data'), true
+                        ),
+                        '',
+                        true,
+                        true,
+                        ''
+                    )
+                    . "\n";
+            }
+        }
+
+        // CREATE VIEW
+        /**
+         *
+         * @todo detect privileges to create a view
+         *       (but see 2006-01-19 note in display_create_table.lib.php,
+         *        I think we cannot detect db-specific privileges reliably)
+         * Note: we don't display a Create view link if we found a PROCEDURE clause
+         */
+        if (!$header_shown) {
+            $results_operations_html .= $header;
+            $header_shown = true;
+        }
+
+        if (!PMA_DRIZZLE && !isset($analyzed_sql[0]['queryflags']['procedure'])) {
+
+            $ajax_class = ' ajax';
+
+            $results_operations_html .= '<span>'
+                . PMA_Util::linkOrButton(
+                    'view_create.php' . $url_query,
+                    PMA_Util::getIcon(
+                        'b_views.png', __('Create view'), true
+                    ),
+                    array('class' => 'create_view' . $ajax_class), true, true, ''
+                )
+                . '</span>' . "\n";
+        }
+
+        if ($header_shown) {
+            $results_operations_html .= '</fieldset><br />';
+        }
+
+        return $results_operations_html;
+
+    } // end of the '_getResultsOperations()' function
+
+
+    /**
+     * Verifies what to do with non-printable contents (binary or BLOB)
+     * in Browse mode.
+     *
+     * @param string $category              BLOB|BINARY|GEOMETRY
+     * @param string $content               the binary content
+     * @param string $transformation_plugin transformation plugin.
+     *                                      Can also be the default function:
+     *                                      PMA_mimeDefaultFunction
+     * @param string $transform_options     transformation parameters
+     * @param string $default_function      default transformation function
+     * @param object $meta                  the meta-information about the field
+     * @param array  $url_params            parameters that should go to the
+     *                                      download link
+     *
+     * @return mixed  string or float
+     *
+     * @access  private
+     *
+     * @see     _getDataCellForBlobColumns(),
+     *          _getDataCellForGeometryColumns(),
+     *          _getDataCellForNonNumericAndNonBlobColumns(),
+     *          _getSortedColumnMessage()
+     */
+    private function _handleNonPrintableContents(
+        $category, $content, $transformation_plugin, $transform_options,
+        $default_function, $meta, $url_params = array()
+    ) {
+
+        $result = '[' . $category;
+
+        if (is_null($content)) {
+
+            $result .= ' - NULL';
+            $size = 0;
+
+        } elseif (isset($content)) {
+
+            $size = strlen($content);
+            $display_size
+                = PMA_Util::formatByteDown($size, 3, 1);
+            $result .= ' - '. $display_size[0] . ' ' . $display_size[1];
+
+        }
+
+        $result .= ']';
+
+        if (gettype($transformation_plugin) == "object"
+            && strpos($transformation_plugin->getMIMESubtype(), 'Octetstream')
+        ) {
+            $result = $content;
+        }
+
+        if ($size > 0) {
+
+            if ($default_function != $transformation_plugin) {
+                $result = $transformation_plugin->applyTransformation(
+                    $result,
+                    $transform_options,
+                    $meta
+                );
+            } else {
+
+                $result = $this->$default_function($result, array(), $meta);
+                if (stristr($meta->type, self::BLOB_FIELD)
+                    && $_SESSION['tmp_user_values']['display_blob']
+                ) {
+                    // in this case, restart from the original $content
+                    $result = $this->_displayBinaryAsPrintable($content, 'blob');
+                }
+
+                /* Create link to download */
+                if (count($url_params) > 0) {
+                    $result = '<a href="tbl_get_field.php'
+                        . PMA_generate_common_url($url_params) . '" class="disableAjax">'
+                        . $result . '</a>';
+                }
+            }
+        }
+
+        return($result);
+
+    } // end of the '_handleNonPrintableContents()' function
+
+
+    /**
+     * Prepares the displayable content of a data cell in Browse mode,
+     * taking into account foreign key description field and transformations
+     *
+     * @param string $class                 css classes for the td element
+     * @param bool   $condition_field       whether the column is a part of the
+     *                                      where clause
+     * @param string $analyzed_sql          the analyzed query
+     * @param object $meta                  the meta-information about the field
+     * @param array  $map                   the list of relations
+     * @param string $data                  data
+     * @param string $transformation_plugin transformation plugin.
+     *                                      Can also be the default function:
+     *                                      PMA_mimeDefaultFunction
+     * @param string $default_function      default function
+     * @param string $nowrap                'nowrap' if the content should not
+     *                                      be wrapped
+     * @param string $where_comparison      data for the where clause
+     * @param array  $transform_options     array of options for transformation
+     * @param bool   $is_field_truncated    whether the field is truncated
+     *
+     * @return string  formatted data
+     *
+     * @access  private
+     *
+     * @see     _getDataCellForNumericColumns(), _getDataCellForGeometryColumns(),
+     *          _getDataCellForNonNumericAndNonBlobColumns(),
+     *
+     */
+    private function _getRowData(
+        $class, $condition_field, $analyzed_sql, $meta, $map, $data,
+        $transformation_plugin, $default_function, $nowrap, $where_comparison,
+        $transform_options, $is_field_truncated
+    ) {
+
+        $printview = $this->__get('printview');
+        $result = '<td class="'
+            . $this->_addClass(
+                $class, $condition_field, $meta, $nowrap,
+                $is_field_truncated, $transformation_plugin, $default_function
+            )
+            . '">';
+
+        if (isset($analyzed_sql[0]['select_expr'])
+            && is_array($analyzed_sql[0]['select_expr'])
+        ) {
+
+            foreach ($analyzed_sql[0]['select_expr']
+                as $select_expr_position => $select_expr
+            ) {
+
+                $alias = $analyzed_sql[0]['select_expr']
+                    [$select_expr_position]['alias'];
+
+                if (isset($alias) && strlen($alias)) {
+                    $true_column = $analyzed_sql[0]['select_expr']
+                        [$select_expr_position]['column'];
+
+                    if ($alias == $meta->name) {
+                        // this change in the parameter does not matter
+                        // outside of the function
+                        $meta->name = $true_column;
+                    } // end if
+
+                } // end if
+            } // end foreach
+        } // end if
+
+        if (isset($map[$meta->name])) {
+
+            // Field to display from the foreign table?
+            if (isset($map[$meta->name][2]) && strlen($map[$meta->name][2])) {
+
+                $dispsql = 'SELECT '
+                    . PMA_Util::backquote($map[$meta->name][2])
+                    . ' FROM '
+                    . PMA_Util::backquote($map[$meta->name][3])
+                    . '.'
+                    . PMA_Util::backquote($map[$meta->name][0])
+                    . ' WHERE '
+                    . PMA_Util::backquote($map[$meta->name][1])
+                    . $where_comparison;
+
+                $dispresult = PMA_DBI_try_query($dispsql, null, PMA_DBI_QUERY_STORE);
+
+                if ($dispresult && PMA_DBI_num_rows($dispresult) > 0) {
+                    list($dispval) = PMA_DBI_fetch_row($dispresult, 0);
+                } else {
+                    $dispval = __('Link not found');
+                }
+
+                @PMA_DBI_free_result($dispresult);
+
+            } else {
+                $dispval     = '';
+            } // end if... else...
+
+            if (isset($printview) && ($printview == '1')) {
+
+                $result .= ($transformation_plugin != $default_function
+                    ? $transformation_plugin->applyTransformation(
+                        $data,
+                        $transform_options,
+                        $meta
+                    )
+                    : $this->$default_function($data)
+                )
+                . ' <code>[->' . $dispval . ']</code>';
+
+            } else {
+
+                if ($_SESSION['tmp_user_values']['relational_display'] == self::RELATIONAL_KEY) {
+
+                    // user chose "relational key" in the display options, so
+                    // the title contains the display field
+                    $title = (! empty($dispval))
+                        ? ' title="' . htmlspecialchars($dispval) . '"'
+                        : '';
+
+                } else {
+                    $title = ' title="' . htmlspecialchars($data) . '"';
+                }
+
+                $_url_params = array(
+                    'db'    => $map[$meta->name][3],
+                    'table' => $map[$meta->name][0],
+                    'pos'   => '0',
+                    'sql_query' => 'SELECT * FROM '
+                        . PMA_Util::backquote(
+                            $map[$meta->name][3]
+                        ) . '.'
+                        . PMA_Util::backquote(
+                            $map[$meta->name][0]
+                        )
+                        . ' WHERE '
+                        . PMA_Util::backquote(
+                            $map[$meta->name][1]
+                        )
+                        . $where_comparison,
+                );
+
+                $result .= '<a class="ajax" href="sql.php' . PMA_generate_common_url($_url_params)
+                     . '"' . $title . '>';
+
+                if ($transformation_plugin != $default_function) {
+                    // always apply a transformation on the real data,
+                    // not on the display field
+                    $result .= $transformation_plugin->applyTransformation(
+                        $data,
+                        $transform_options,
+                        $meta
+                    );
+                } else {
+
+                    if ($_SESSION['tmp_user_values']['relational_display'] == self::RELATIONAL_DISPLAY_COLUMN) {
+                        // user chose "relational display field" in the
+                        // display options, so show display field in the cell
+                        $result .= $this->$default_function($dispval);
+                    } else {
+                        // otherwise display data in the cell
+                        $result .= $this->$default_function($data);
+                    }
+
+                }
+                $result .= '</a>';
+            }
+
+        } else {
+            $result .= ($transformation_plugin != $default_function
+                ? $transformation_plugin->applyTransformation(
+                    $data,
+                    $transform_options,
+                    $meta
+                )
+                : $this->$default_function($data)
+            );
+        }
+
+        // create hidden field if results from structure table
+        if (isset($_GET['browse_distinct']) && ($_GET['browse_distinct'] == 1)) {
+
+            $where_comparison = " = '" . $data . "'";
+
+            $_url_params_for_show_data_row = array(
+                'db'    => $this->__get('db'),
+                'table' => $meta->orgtable,
+                'pos'   => '0',
+                'sql_query' => 'SELECT * FROM '
+                    . PMA_Util::backquote($this->__get('db'))
+                    . '.' . PMA_Util::backquote($meta->orgtable)
+                    . ' WHERE '
+                    . PMA_Util::backquote($meta->orgname)
+                    . $where_comparison,
+            );
+
+            $result .= '<input type="hidden" class="data_browse_link" value="'
+                . PMA_generate_common_url($_url_params_for_show_data_row). '" />';
+
+        }
+
+        $result .= '</td>' . "\n";
+
+        return $result;
+
+    } // end of the '_getRowData()' function
+
+
+    /**
+     * Prepares a checkbox for multi-row submits
+     *
+     * @param string $del_url           delete url
+     * @param array  $is_display        array with explicit indexes for all
+     *                                  the display elements
+     * @param string $row_no            the row number
+     * @param string $where_clause_html url encoded where clause
+     * @param array  $condition_array   array of conditions in the where clause
+     * @param string $del_query         delete query
+     * @param string $id_suffix         suffix for the id
+     * @param string $class             css classes for the td element
+     *
+     * @return string  the generated HTML
+     *
+     * @access  private
+     *
+     * @see     _getTableBody(), _getCheckboxAndLinks()
+     */
+    private function _getCheckboxForMultiRowSubmissions(
+        $del_url, $is_display, $row_no, $where_clause_html, $condition_array,
+        $del_query, $id_suffix, $class
+    ) {
+
+        $ret = '';
+
+        if (! empty($del_url) && $is_display['del_lnk'] != self::KILL_PROCESS) {
+
+            $ret .= '<td ';
+            if (! empty($class)) {
+                $ret .= 'class="' . $class . '"';
+            }
+
+            $ret .= ' class="center">'
+                . '<input type="checkbox" id="id_rows_to_delete'
+                . $row_no . $id_suffix
+                . '" name="rows_to_delete[' . $row_no . ']"'
+                . ' class="multi_checkbox checkall"'
+                . ' value="' . $where_clause_html . '" '
+                . ' />'
+                . '<input type="hidden" class="condition_array" value="'
+                . htmlspecialchars(json_encode($condition_array)) . '" />'
+                . '    </td>';
+        }
+
+        return $ret;
+
+    } // end of the '_getCheckboxForMultiRowSubmissions()' function
+
+
+    /**
+     * Prepares an Edit link
+     *
+     * @param string $edit_url          edit url
+     * @param string $class             css classes for td element
+     * @param string $edit_str          text for the edit link
+     * @param string $where_clause      where clause
+     * @param string $where_clause_html url encoded where clause
+     *
+     * @return string  the generated HTML
+     *
+     * @access  private
+     *
+     * @see     _getTableBody(), _getCheckboxAndLinks()
+     */
+    private function _getEditLink(
+        $edit_url, $class, $edit_str, $where_clause, $where_clause_html
+    ) {
+
+        $ret = '';
+        if (! empty($edit_url)) {
+
+            $ret .= '<td class="' . $class . ' center" ' . ' ><span class="nowrap">'
+               . PMA_Util::linkOrButton(
+                   $edit_url, $edit_str, array(), false
+               );
+            /*
+             * Where clause for selecting this row uniquely is provided as
+             * a hidden input. Used by jQuery scripts for handling grid editing
+             */
+            if (! empty($where_clause)) {
+                $ret .= '<input type="hidden" class="where_clause" value ="'
+                    . $where_clause_html . '" />';
+            }
+            $ret .= '</span></td>';
+        }
+
+        return $ret;
+
+    } // end of the '_getEditLink()' function
+
+
+    /**
+     * Prepares an Copy link
+     *
+     * @param string $copy_url          copy url
+     * @param string $copy_str          text for the copy link
+     * @param string $where_clause      where clause
+     * @param string $where_clause_html url encoded where clause
+     * @param string $class             css classes for the td element
+     *
+     * @return string  the generated HTML
+     *
+     * @access  private
+     *
+     * @see     _getTableBody(), _getCheckboxAndLinks()
+     */
+    private function _getCopyLink(
+        $copy_url, $copy_str, $where_clause, $where_clause_html, $class
+    ) {
+
+        $ret = '';
+        if (! empty($copy_url)) {
+
+            $ret .= '<td class="';
+            if (! empty($class)) {
+                $ret .= $class . ' ';
+            }
+
+            $ret .= 'center" ' . ' ><span class="nowrap">'
+               . PMA_Util::linkOrButton(
+                   $copy_url, $copy_str, array(), false
+               );
+
+            /*
+             * Where clause for selecting this row uniquely is provided as
+             * a hidden input. Used by jQuery scripts for handling grid editing
+             */
+            if (! empty($where_clause)) {
+                $ret .= '<input type="hidden" class="where_clause" value="'
+                    . $where_clause_html . '" />';
+            }
+            $ret .= '</span></td>';
+        }
+
+        return $ret;
+
+    } // end of the '_getCopyLink()' function
+
+
+    /**
+     * Prepares a Delete link
+     *
+     * @param string $del_url delete url
+     * @param string $del_str text for the delete link
+     * @param string $js_conf text for the JS confirmation
+     * @param string $class   css classes for the td element
+     *
+     * @return string  the generated HTML
+     *
+     * @access  private
+     *
+     * @see     _getTableBody(), _getCheckboxAndLinks()
+     */
+    private function _getDeleteLink($del_url, $del_str, $js_conf, $class)
+    {
+
+        $ret = '';
+        if (! empty($del_url)) {
+
+            $ret .= '<td class="';
+            if (! empty($class)) {
+                $ret .= $class . ' ';
+            }
+            $ajax = PMA_Response::getInstance()->isAjax() ? ' ajax' : '';
+            $ret .= 'center" ' . ' >'
+               . PMA_Util::linkOrButton(
+                   $del_url, $del_str, array('class' => 'delete_row' . $ajax), false
+               )
+               . '<div class="hide">' . $js_conf . '</div>'
+               . '</td>';
+        }
+
+        return $ret;
+
+    } // end of the '_getDeleteLink()' function
+
+
+    /**
+     * Prepare checkbox and links at some position (left or right)
+     * (only called for horizontal mode)
+     *
+     * @param string $position          the position of the checkbox and links
+     * @param string $del_url           delete url
+     * @param array  $is_display        array with explicit indexes for all the
+     *                                  display elements
+     * @param string $row_no            row number
+     * @param string $where_clause      where clause
+     * @param string $where_clause_html url encoded where clause
+     * @param array  $condition_array   array of conditions in the where clause
+     * @param string $del_query         delete query
+     * @param string $id_suffix         suffix for the id
+     * @param string $edit_url          edit url
+     * @param string $copy_url          copy url
+     * @param string $class             css classes for the td elements
+     * @param string $edit_str          text for the edit link
+     * @param string $copy_str          text for the copy link
+     * @param string $del_str           text for the delete link
+     * @param string $js_conf           text for the JS confirmation
+     *
+     * @return string  the generated HTML
+     *
+     * @access  private
+     *
+     * @see     _getPlacedLinks()
+     */
+    private function _getCheckboxAndLinks(
+        $position, $del_url, $is_display, $row_no, $where_clause,
+        $where_clause_html, $condition_array, $del_query, $id_suffix,
+        $edit_url, $copy_url, $class, $edit_str, $copy_str, $del_str, $js_conf
+    ) {
+
+        $ret = '';
+
+        if ($position == self::POSITION_LEFT) {
+
+            $ret .= $this->_getCheckboxForMultiRowSubmissions(
+                $del_url, $is_display, $row_no, $where_clause_html, $condition_array,
+                $del_query, $id_suffix = '_left', ''
+            );
+
+            $ret .= $this->_getEditLink(
+                $edit_url, $class, $edit_str, $where_clause, $where_clause_html
+            );
+
+            $ret .= $this->_getCopyLink(
+                $copy_url, $copy_str, $where_clause, $where_clause_html, ''
+            );
+
+            $ret .= $this->_getDeleteLink($del_url, $del_str, $js_conf, '');
+
+        } elseif ($position == self::POSITION_RIGHT) {
+
+            $ret .= $this->_getDeleteLink($del_url, $del_str, $js_conf, '');
+
+            $ret .= $this->_getCopyLink(
+                $copy_url, $copy_str, $where_clause, $where_clause_html, ''
+            );
+
+            $ret .= $this->_getEditLink(
+                $edit_url, $class, $edit_str, $where_clause, $where_clause_html
+            );
+
+            $ret .= $this->_getCheckboxForMultiRowSubmissions(
+                $del_url, $is_display, $row_no, $where_clause_html, $condition_array,
+                $del_query, $id_suffix = '_right', ''
+            );
+
+        } else { // $position == self::POSITION_NONE
+
+            $ret .= $this->_getCheckboxForMultiRowSubmissions(
+                $del_url, $is_display, $row_no, $where_clause_html, $condition_array,
+                $del_query, $id_suffix = '_left', ''
+            );
+        }
+
+        return $ret;
+
+    } // end of the '_getCheckboxAndLinks()' function
+
+
+    /**
+     * Replace some html-unfriendly stuff
+     *
+     * @param string $buffer String to process
+     *
+     * @return Escaped and cleaned up text suitable for html.
+     *
+     * @access  private
+     *
+     * @see     _getDataCellForBlobField(), _getRowData(),
+     *          _handleNonPrintableContents()
+     */
+    private function _mimeDefaultFunction($buffer)
+    {
+        $buffer = htmlspecialchars($buffer);
+        $buffer = str_replace(
+            "\011",
+            '    ',
+            str_replace('  ', '  ', $buffer)
+        );
+        $buffer = preg_replace("@((\015\012)|(\015)|(\012))@", '<br />', $buffer);
+
+        return $buffer;
+    }
+
+    /**
+     * Display binary fields as hex string for PHP <5.4, 
+     * otherwise escape the contents if it may be displayed as hex
+     *
+     * @param string $content         String to parse
+     * @param string $binary_or_blob  'binary' or 'blob'
+     * @param int    $hexlength       optional, get substring
+     *
+     * @return Displayable version of the binary string
+     *
+     * @access private
+     *
+     * @see    _getDataCellForGeometryColumns
+     *         _getDataCellForNonNumericAndNonBlobColumns
+     *         _handleNonPrintableContents
+     */
+    private function _displayBinaryAsPrintable(
+        $content, $binary_or_blob, $hexlength = null
+    ) {
+        if (PMA_PHP_INT_VERSION < 50400
+            || ($binary_or_blob === 'binary'
+                && $_SESSION['tmp_user_values']['display_binary_as_hex']
+                && PMA_Util::containsNonPrintableAscii($content)
+            )
+        ) {
+            $content = bin2hex($content);
+            if ($hexlength !== null) {
+                $content = PMA_substr($content, $hexlength);
+            }
+        } else {
+            $content = htmlspecialchars(
+                PMA_Util::replaceBinaryContents(
+                    $content
+                ),
+                ENT_SUBSTITUTE
+            );
+        }
+        return $content;
+    }
+}
+?>
diff --git a/phpmyadmin/libraries/Error.class.php b/phpmyadmin/libraries/Error.class.php
new file mode 100644
index 0000000..e2c0133
--- /dev/null
+++ b/phpmyadmin/libraries/Error.class.php
@@ -0,0 +1,409 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * Holds class PMA_Error
+ *
+ * @package PhpMyAdmin
+ */
+
+/**
+ * base class
+ */
+require_once './libraries/Message.class.php';
+
+/**
+ * a single error
+ *
+ * @package PhpMyAdmin
+ */
+class PMA_Error extends PMA_Message
+{
+    /**
+     * Error types
+     *
+     * @var array
+     */
+    static public $errortype = array (
+        E_ERROR              => 'Error',
+        E_WARNING            => 'Warning',
+        E_PARSE              => 'Parsing Error',
+        E_NOTICE             => 'Notice',
+        E_CORE_ERROR         => 'Core Error',
+        E_CORE_WARNING       => 'Core Warning',
+        E_COMPILE_ERROR      => 'Compile Error',
+        E_COMPILE_WARNING    => 'Compile Warning',
+        E_USER_ERROR         => 'User Error',
+        E_USER_WARNING       => 'User Warning',
+        E_USER_NOTICE        => 'User Notice',
+        E_STRICT             => 'Runtime Notice',
+        E_DEPRECATED         => 'Deprecation Notice',
+        E_RECOVERABLE_ERROR  => 'Catchable Fatal Error',
+    );
+
+    /**
+     * Error levels
+     *
+     * @var array
+     */
+    static public $errorlevel = array (
+        E_ERROR              => 'error',
+        E_WARNING            => 'error',
+        E_PARSE              => 'error',
+        E_NOTICE             => 'notice',
+        E_CORE_ERROR         => 'error',
+        E_CORE_WARNING       => 'error',
+        E_COMPILE_ERROR      => 'error',
+        E_COMPILE_WARNING    => 'error',
+        E_USER_ERROR         => 'error',
+        E_USER_WARNING       => 'error',
+        E_USER_NOTICE        => 'notice',
+        E_STRICT             => 'notice',
+        E_DEPRECATED         => 'notice',
+        E_RECOVERABLE_ERROR  => 'error',
+    );
+
+    /**
+     * The file in which the error occured
+     *
+     * @var string
+     */
+    protected $file = '';
+
+    /**
+     * The line in which the error occured
+     *
+     * @var integer
+     */
+    protected $line = 0;
+
+    /**
+     * Holds the backtrace for this error
+     *
+     * @var array
+     */
+    protected $backtrace = array();
+
+    /**
+     * Unique id
+     *
+     * @var string
+     */
+    protected $hash = null;
+
+    /**
+     * Constructor
+     *
+     * @param integer $errno   error number
+     * @param string  $errstr  error message
+     * @param string  $errfile file
+     * @param integer $errline line
+     */
+    public function __construct($errno, $errstr, $errfile, $errline)
+    {
+        $this->setNumber($errno);
+        $this->setMessage($errstr, false);
+        $this->setFile($errfile);
+        $this->setLine($errline);
+
+        $backtrace = debug_backtrace();
+        // remove last three calls:
+        // debug_backtrace(), handleError() and addError()
+        $backtrace = array_slice($backtrace, 3);
+
+        $this->setBacktrace($backtrace);
+    }
+
+    /**
+     * sets PMA_Error::$_backtrace
+     *
+     * @param array $backtrace backtrace
+     *
+     * @return void
+     */
+    public function setBacktrace($backtrace)
+    {
+        $this->backtrace = $backtrace;
+    }
+
+    /**
+     * sets PMA_Error::$_line
+     *
+     * @param integer $line the line
+     *
+     * @return void
+     */
+    public function setLine($line)
+    {
+        $this->line = $line;
+    }
+
+    /**
+     * sets PMA_Error::$_file
+     *
+     * @param string $file the file
+     *
+     * @return void
+     */
+    public function setFile($file)
+    {
+        $this->file = PMA_Error::relPath($file);
+    }
+
+
+    /**
+     * returns unique PMA_Error::$hash, if not exists it will be created
+     *
+     * @return string PMA_Error::$hash
+     */
+    public function getHash()
+    {
+        try {
+            $backtrace = serialize($this->getBacktrace());
+        } catch(Exception $e) {
+            $backtrace = '';
+        }
+        if ($this->hash === null) {
+            $this->hash = md5(
+                $this->getNumber() .
+                $this->getMessage() .
+                $this->getFile() .
+                $this->getLine() .
+                $backtrace
+            );
+        }
+
+        return $this->hash;
+    }
+
+    /**
+     * returns PMA_Error::$_backtrace
+     *
+     * @return array PMA_Error::$_backtrace
+     */
+    public function getBacktrace()
+    {
+        return $this->backtrace;
+    }
+
+    /**
+     * returns PMA_Error::$file
+     *
+     * @return string PMA_Error::$file
+     */
+    public function getFile()
+    {
+        return $this->file;
+    }
+
+    /**
+     * returns PMA_Error::$line
+     *
+     * @return integer PMA_Error::$line
+     */
+    public function getLine()
+    {
+        return $this->line;
+    }
+
+    /**
+     * returns type of error
+     *
+     * @return string  type of error
+     */
+    public function getType()
+    {
+        return PMA_Error::$errortype[$this->getNumber()];
+    }
+
+    /**
+     * returns level of error
+     *
+     * @return string  level of error
+     */
+    public function getLevel()
+    {
+        return PMA_Error::$errorlevel[$this->getNumber()];
+    }
+
+    /**
+     * returns title prepared for HTML Title-Tag
+     *
+     * @return string   HTML escaped and truncated title
+     */
+    public function getHtmlTitle()
+    {
+        return htmlspecialchars(substr($this->getTitle(), 0, 100));
+    }
+
+    /**
+     * returns title for error
+     *
+     * @return string
+     */
+    public function getTitle()
+    {
+        return $this->getType() . ': ' . $this->getMessage();
+    }
+
+    /**
+     * Get HTML backtrace
+     *
+     * @return void
+     */
+    public function getBacktraceDisplay()
+    {
+        $retval = '';
+
+        foreach ($this->getBacktrace() as $step) {
+            if (isset($step['file']) && isset($step['line'])) {
+                $retval .= PMA_Error::relPath($step['file']) . '#' . $step['line'] . ': ';
+            }
+            if (isset($step['class'])) {
+                $retval .= $step['class'] . $step['type'];
+            }
+            $retval .= $step['function'] . '(';
+            if (isset($step['args']) && (count($step['args']) > 1)) {
+                $retval .= "<br />\n";
+                foreach ($step['args'] as $arg) {
+                    $retval .= "\t";
+                    $retval .= $this->getArg($arg, $step['function']);
+                    $retval .= ',' . "<br />\n";
+                }
+            } elseif (isset($step['args']) && (count($step['args']) > 0)) {
+                foreach ($step['args'] as $arg) {
+                    $retval .= $this->getArg($arg, $step['function']);
+                }
+            }
+            $retval .= ')' . "<br />\n";
+        }
+
+        return $retval;
+    }
+
+    /**
+     * Get a single function argument
+     *
+     * if $function is one of include/require
+     * the $arg is converted to a relative path
+     *
+     * @param string $arg
+     * @param string $function
+     *
+     * @return string
+     */
+    protected function getArg($arg, $function)
+    {
+        $retval = '';
+        $include_functions = array(
+            'include',
+            'include_once',
+            'require',
+            'require_once',
+        );
+        $connect_functions = array(
+            'mysql_connect',
+            'mysql_pconnect',
+            'mysqli_connect',
+            'mysqli_real_connect',
+            'PMA_DBI_connect',
+            'PMA_DBI_real_connect',
+        );
+
+        if (in_array($function, $include_functions)) {
+            $retval .= PMA_Error::relPath($arg);
+        } elseif (in_array($function, $connect_functions)
+            && getType($arg) === 'string'
+        ) {
+            $retval .= getType($arg) . ' ********';
+        } elseif (is_scalar($arg)) {
+            $retval .= getType($arg) . ' ' . htmlspecialchars($arg);
+        } else {
+            $retval .= getType($arg);
+        }
+
+        return $retval;
+    }
+
+    /**
+     * Gets the error as string of HTML
+     *
+     * @return string
+     */
+    public function getDisplay()
+    {
+        $this->isDisplayed(true);
+        $retval = '<div class="' . $this->getLevel() . '">';
+        if (! $this->isUserError()) {
+            $retval .= '<strong>' . $this->getType() . '</strong>';
+            $retval .= ' in ' . $this->getFile() . '#' . $this->getLine();
+            $retval .= "<br />\n";
+        }
+        $retval .= $this->getMessage();
+        if (! $this->isUserError()) {
+            $retval .= "<br />\n";
+            $retval .= "<br />\n";
+            $retval .= "<strong>Backtrace</strong><br />\n";
+            $retval .= "<br />\n";
+            $retval .= $this->getBacktraceDisplay();
+        }
+        $retval .= '</div>';
+
+        return $retval;
+    }
+
+    /**
+     * whether this error is a user error
+     *
+     * @return boolean
+     */
+    public function isUserError()
+    {
+        return $this->getNumber() & (E_USER_WARNING | E_USER_ERROR | E_USER_NOTICE);
+    }
+
+    /**
+     * return short relative path to phpMyAdmin basedir
+     *
+     * prevent path disclusore in error message,
+     * and make users feel save to submit error reports
+     *
+     * @param string $dest path to be shorten
+     *
+     * @return string shortened path
+     * @static
+     */
+    static function relPath($dest)
+    {
+        $dest = realpath($dest);
+
+        if (substr(PHP_OS, 0, 3) == 'WIN') {
+            $path_separator = '\\';
+        } else {
+            $path_separator = '/';
+        }
+
+        $Ahere = explode(
+            $path_separator,
+            realpath(dirname(__FILE__) . $path_separator . '..')
+        );
+        $Adest = explode($path_separator, $dest);
+
+        $result = '.';
+        // && count ($Adest)>0 && count($Ahere)>0 )
+        while (implode($path_separator, $Adest) != implode($path_separator, $Ahere)) {
+            if (count($Ahere) > count($Adest)) {
+                array_pop($Ahere);
+                $result .= $path_separator . '..';
+            } else {
+                array_pop($Adest);
+            }
+        }
+        $path = $result . str_replace(implode($path_separator, $Adest), '', $dest);
+        return str_replace(
+            $path_separator . $path_separator,
+            $path_separator,
+            $path
+        );
+    }
+}
+?>
diff --git a/phpmyadmin/libraries/Error_Handler.class.php b/phpmyadmin/libraries/Error_Handler.class.php
new file mode 100644
index 0000000..799c3fe
--- /dev/null
+++ b/phpmyadmin/libraries/Error_Handler.class.php
@@ -0,0 +1,446 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * Holds class PMA_Error_Handler
+ *
+ * @package PhpMyAdmin
+ */
+
+/**
+ *
+ */
+require_once './libraries/Error.class.php';
+
+/**
+ * handling errors
+ *
+ * @package PhpMyAdmin
+ */
+class PMA_Error_Handler
+{
+    /**
+     * holds errors to be displayed or reported later ...
+     *
+     * @var array of PMA_Error
+     */
+    protected $errors = array();
+
+    /**
+     * Constructor - set PHP error handler
+     *
+     */
+    public function __construct()
+    {
+        /**
+         * Do not set ourselves as error handler in case of testsuite.
+         *
+         * This behavior is not tested there and breaks other tests as they
+         * rely on PHPUnit doing it's own error handling which we break here.
+         */
+        if (!defined('TESTSUITE')) {
+            set_error_handler(array($this, 'handleError'));
+        }
+    }
+
+    /**
+     * Destructor
+     *
+     * stores errors in session
+     *
+     */
+    public function __destruct()
+    {
+        if (isset($_SESSION)) {
+            if (! isset($_SESSION['errors'])) {
+                $_SESSION['errors'] = array();
+            }
+
+            if (isset($GLOBALS['cfg']['Error_Handler'])
+                && $GLOBALS['cfg']['Error_Handler']['gather']
+            ) {
+                // remember all errors
+                $_SESSION['errors'] = array_merge(
+                    $_SESSION['errors'],
+                    $this->errors
+                );
+            } else {
+                // remember only not displayed errors
+                foreach ($this->errors as $key => $error) {
+                    /**
+                     * We don't want to store all errors here as it would
+                     * explode user session. In case  you want them all set
+                     * $GLOBALS['cfg']['Error_Handler']['gather'] to true
+                     */
+                    if (count($_SESSION['errors']) >= 20) {
+                        $error = new PMA_Error(
+                            0,
+                            __('Too many error messages, some are not displayed.'),
+                            __FILE__,
+                            __LINE__
+                        );
+                        $_SESSION['errors'][$error->getHash()] = $error;
+                        break;
+                    } else if (($error instanceof PMA_Error)
+                        && ! $error->isDisplayed()
+                    ) {
+                        $_SESSION['errors'][$key] = $error;
+                    }
+                }
+            }
+        }
+    }
+
+    /**
+     * returns array with all errors
+     *
+     * @return array PMA_Error_Handler::$_errors
+     */
+    protected function getErrors()
+    {
+        $this->checkSavedErrors();
+        return $this->errors;
+    }
+
+    /**
+     * Error handler - called when errors are triggered/occured
+     *
+     * This calls the addError() function, escaping the error string
+     *
+     * @param integer $errno   error number
+     * @param string  $errstr  error string
+     * @param string  $errfile error file
+     * @param integer $errline error line
+     *
+     * @return void
+     */
+    public function handleError($errno, $errstr, $errfile, $errline)
+    {
+        $this->addError($errstr, $errno, $errfile, $errline, true);
+    }
+
+    /**
+     * Add an error; can also be called directly (with or without escaping)
+     *
+     * The following error types cannot be handled with a user defined function:
+     * E_ERROR, E_PARSE, E_CORE_ERROR, E_CORE_WARNING, E_COMPILE_ERROR,
+     * E_COMPILE_WARNING,
+     * and most of E_STRICT raised in the file where set_error_handler() is called.
+     *
+     * Do not use the context parameter as we want to avoid storing the
+     * complete $GLOBALS inside $_SESSION['errors']
+     *
+     * @param string  $errstr  error string
+     * @param integer $errno   error number
+     * @param string  $errfile error file
+     * @param integer $errline error line
+     * @param boolean $escape  whether to escape the error string
+     *
+     * @return void
+     */
+    public function addError($errstr, $errno, $errfile, $errline, $escape = true)
+    {
+        if ($escape) {
+            $errstr = htmlspecialchars($errstr);
+        }
+        // create error object
+        $error = new PMA_Error(
+            $errno,
+            $errstr,
+            $errfile,
+            $errline
+        );
+
+        // do not repeat errors
+        $this->errors[$error->getHash()] = $error;
+
+        switch ($error->getNumber()) {
+        case E_USER_NOTICE:
+        case E_USER_WARNING:
+        case E_STRICT:
+        case E_DEPRECATED:
+        case E_NOTICE:
+        case E_WARNING:
+        case E_CORE_WARNING:
+        case E_COMPILE_WARNING:
+        case E_USER_ERROR:
+        case E_RECOVERABLE_ERROR:
+            // just collect the error
+            // display is called from outside
+            break;
+        case E_ERROR:
+        case E_PARSE:
+        case E_CORE_ERROR:
+        case E_COMPILE_ERROR:
+        default:
+            // FATAL error, dislay it and exit
+            $this->dispFatalError($error);
+            exit;
+            break;
+        }
+    }
+
+
+    /**
+     * log error to configured log facility
+     *
+     * @param PMA_Error $error the error
+     *
+     * @return bool
+     *
+     * @todo finish!
+     */
+    protected function logError($error)
+    {
+        return error_log($error->getMessage());
+    }
+
+    /**
+     * trigger a custom error
+     *
+     * @param string  $errorInfo   error message
+     * @param integer $errorNumber error number
+     * @param string  $file        file name
+     * @param integer $line        line number
+     *
+     * @return void
+     */
+    public function triggerError($errorInfo, $errorNumber = null,
+        $file = null, $line = null
+    ) {
+        // we could also extract file and line from backtrace
+        // and call handleError() directly
+        trigger_error($errorInfo, $errorNumber);
+    }
+
+    /**
+     * display fatal error and exit
+     *
+     * @param PMA_Error $error the error
+     *
+     * @return void
+     */
+    protected function dispFatalError($error)
+    {
+        if (! headers_sent()) {
+            $this->dispPageStart($error);
+        }
+        $error->display();
+        $this->dispPageEnd();
+        exit;
+    }
+
+    /**
+     * display the whole error page with all errors
+     *
+     * @return void
+     */
+    public function dispErrorPage()
+    {
+        if (! headers_sent()) {
+            $this->dispPageStart();
+        }
+        $this->dispAllErrors();
+        $this->dispPageEnd();
+    }
+
+    /**
+     * Displays user errors not displayed
+     *
+     * @return void
+     */
+    public function dispUserErrors()
+    {
+        echo $this->getDispUserErrors();
+    }
+
+    /**
+     * Renders user errors not displayed
+     *
+     * @return string
+     */
+    public function getDispUserErrors()
+    {
+        $retval = '';
+        foreach ($this->getErrors() as $error) {
+            if ($error->isUserError() && ! $error->isDisplayed()) {
+                $retval .= $error->getDisplay();
+            }
+        }
+        return $retval;
+    }
+
+    /**
+     * display HTML header
+     *
+     * @param PMA_error $error the error
+     *
+     * @return void
+     */
+    protected function dispPageStart($error = null)
+    {
+        PMA_Response::getInstance()->disable();
+        echo '<html><head><title>';
+        if ($error) {
+            echo $error->getTitle();
+        } else {
+            echo 'phpMyAdmin error reporting page';
+        }
+        echo '</title></head>';
+    }
+
+    /**
+     * display HTML footer
+     *
+     * @return void
+     */
+    protected function dispPageEnd()
+    {
+        echo '</body></html>';
+    }
+
+    /**
+     * display all errors regardless already displayed or user errors
+     *
+     * @return void
+     */
+    public function dispAllErrors()
+    {
+        foreach ($this->getErrors() as $error) {
+            $error->display();
+        }
+    }
+
+    /**
+     * renders errors not displayed
+     *
+     * @return void
+     */
+    public function getDispErrors()
+    {
+        $retval = '';
+        if ($GLOBALS['cfg']['Error_Handler']['display']) {
+            foreach ($this->getErrors() as $error) {
+                if ($error instanceof PMA_Error) {
+                    if (! $error->isDisplayed()) {
+                        $retval .= $error->getDisplay();
+                    }
+                } else {
+                    ob_start();
+                    var_dump($error);
+                    $retval .= ob_get_contents();
+                    ob_end_clean();
+                }
+            }
+        } else {
+            $retval .= $this->getDispUserErrors();
+        }
+        return $retval;
+    }
+
+    /**
+     * displays errors not displayed
+     *
+     * @return void
+     */
+    public function dispErrors()
+    {
+        echo $this->getDispErrors();
+    }
+
+    /**
+     * look in session for saved errors
+     *
+     * @return void
+     */
+    protected function checkSavedErrors()
+    {
+        if (isset($_SESSION['errors'])) {
+
+            // restore saved errors
+            foreach ($_SESSION['errors'] as $hash => $error) {
+                if ($error instanceof PMA_Error && ! isset($this->errors[$hash])) {
+                    $this->errors[$hash] = $error;
+                }
+            }
+            //$this->errors = array_merge($_SESSION['errors'], $this->errors);
+
+            // delete stored errors
+            $_SESSION['errors'] = array();
+            unset($_SESSION['errors']);
+        }
+    }
+
+    /**
+     * return count of errors
+     *
+     * @return integer number of errors occoured
+     */
+    public function countErrors()
+    {
+        return count($this->getErrors());
+    }
+
+    /**
+     * return count of user errors
+     *
+     * @return integer number of user errors occoured
+     */
+    public function countUserErrors()
+    {
+        $count = 0;
+        if ($this->countErrors()) {
+            foreach ($this->getErrors() as $error) {
+                if ($error->isUserError()) {
+                    $count++;
+                }
+            }
+        }
+
+        return $count;
+    }
+
+    /**
+     * whether use errors occured or not
+     *
+     * @return boolean
+     */
+    public function hasUserErrors()
+    {
+        return (bool) $this->countUserErrors();
+    }
+
+    /**
+     * whether errors occured or not
+     *
+     * @return boolean
+     */
+    public function hasErrors()
+    {
+        return (bool) $this->countErrors();
+    }
+
+    /**
+     * number of errors to be displayed
+     *
+     * @return integer number of errors to be displayed
+     */
+    public function countDisplayErrors()
+    {
+        if ($GLOBALS['cfg']['Error_Handler']['display']) {
+            return $this->countErrors();
+        } else {
+            return $this->countUserErrors();
+        }
+    }
+
+    /**
+     * whether there are errors to display or not
+     *
+     * @return boolean
+     */
+    public function hasDisplayErrors()
+    {
+        return (bool) $this->countDisplayErrors();
+    }
+}
+?>
diff --git a/phpmyadmin/libraries/File.class.php b/phpmyadmin/libraries/File.class.php
new file mode 100644
index 0000000..62b8763
--- /dev/null
+++ b/phpmyadmin/libraries/File.class.php
@@ -0,0 +1,863 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * file upload functions
+ *
+ * @package PhpMyAdmin
+ */
+if (! defined('PHPMYADMIN')) {
+    exit;
+}
+
+/**
+ * File wrapper class
+ *
+ * @todo when uploading a file into a blob field, should we also consider using
+ *       chunks like in import? UPDATE `table` SET `field` = `field` + [chunk]
+ *
+ * @package PhpMyAdmin
+ */
+class PMA_File
+{
+    /**
+     * @var string the temporary file name
+     * @access protected
+     */
+    var $_name = null;
+
+    /**
+     * @var string the content
+     * @access protected
+     */
+    var $_content = null;
+
+    /**
+     * @var string the error message
+     * @access protected
+     */
+    var $_error_message = '';
+
+    /**
+     * @var bool whether the file is temporary or not
+     * @access protected
+     */
+    var $_is_temp = false;
+
+    /**
+     * @var string type of compression
+     * @access protected
+     */
+    var $_compression = null;
+
+    /**
+     * @var integer
+     */
+    var $_offset = 0;
+
+    /**
+     * @var integer size of chunk to read with every step
+     */
+    var $_chunk_size = 32768;
+
+    /**
+     * @var resource file handle
+     */
+    var $_handle = null;
+
+    /**
+     * @var boolean whether to decompress content before returning
+     */
+    var $_decompress = false;
+
+    /**
+     * @var string charset of file
+     */
+    var $_charset = null;
+
+    /**
+     * constructor
+     *
+     * @param string $name file name
+     *
+     * @access public
+     */
+    public function __construct($name = false)
+    {
+        if ($name) {
+            $this->setName($name);
+        }
+    }
+
+    /**
+     * destructor
+     *
+     * @see     PMA_File::cleanUp()
+     * @access  public
+     */
+    public function __destruct()
+    {
+        $this->cleanUp();
+    }
+
+    /**
+     * deletes file if it is temporary, usally from a moved upload file
+     *
+     * @access  public
+     * @return boolean success
+     */
+    public function cleanUp()
+    {
+        if ($this->isTemp()) {
+            return $this->delete();
+        }
+
+        return true;
+    }
+
+    /**
+     * deletes the file
+     *
+     * @access  public
+     * @return boolean success
+     */
+    public function delete()
+    {
+        return unlink($this->getName());
+    }
+
+    /**
+     * checks or sets the temp flag for this file
+     * file objects with temp flags are deleted with object destruction
+     *
+     * @param boolean $is_temp sets the temp flag
+     *
+     * @return boolean PMA_File::$_is_temp
+     * @access  public
+     */
+    public function isTemp($is_temp = null)
+    {
+        if (null !== $is_temp) {
+            $this->_is_temp = (bool) $is_temp;
+        }
+
+        return $this->_is_temp;
+    }
+
+    /**
+     * accessor
+     *
+     * @param string $name file name
+     *
+     * @return void
+     * @access  public
+     */
+    public function setName($name)
+    {
+        $this->_name = trim($name);
+    }
+
+    /**
+     * Gets file content
+     *
+     * @param boolean $as_binary whether to return content as binary
+     * @param integer $offset    starting offset
+     * @param integer $length    length
+     *
+     * @return mixed   the binary file content as a string,
+     *                 or false if no content
+     *
+     * @access  public
+     */
+    public function getContent($as_binary = true, $offset = 0, $length = null)
+    {
+        if (null === $this->_content) {
+            if ($this->isUploaded() && ! $this->checkUploadedFile()) {
+                return false;
+            }
+
+            if (! $this->isReadable()) {
+                return false;
+            }
+
+            if (function_exists('file_get_contents')) {
+                $this->_content = file_get_contents($this->getName());
+            } elseif ($size = filesize($this->getName())) {
+                $this->_content = fread(fopen($this->getName(), 'rb'), $size);
+            }
+        }
+
+        if (! empty($this->_content) && $as_binary) {
+            return '0x' . bin2hex($this->_content);
+        }
+
+        if (null !== $length) {
+            return substr($this->_content, $offset, $length);
+        } elseif ($offset > 0) {
+            return substr($this->_content, $offset);
+        }
+
+        return $this->_content;
+    }
+
+    /**
+     * Whether file is uploaded.
+     *
+     * @access  public
+     *
+     * @return bool
+     */
+    public function isUploaded()
+    {
+        return is_uploaded_file($this->getName());
+    }
+
+    /**
+     * accessor
+     *
+     * @access  public
+     * @return string  PMA_File::$_name
+     */
+    public function getName()
+    {
+        return $this->_name;
+    }
+
+    /**
+     * Initializes object from uploaded file.
+     *
+     * @param string $name name of file uploaded
+     *
+     * @return boolean success
+     * @access  public
+     */
+    public function setUploadedFile($name)
+    {
+        $this->setName($name);
+
+        if (! $this->isUploaded()) {
+            $this->setName(null);
+            $this->_error_message = __('File was not an uploaded file.');
+            return false;
+        }
+
+        return true;
+    }
+
+    /**
+     * Loads uploaded file from table change request.
+     *
+     * @param string $key       the md5 hash of the column name
+     * @param string $rownumber
+     *
+     * @return boolean success
+     * @access  public
+     */
+    public function setUploadedFromTblChangeRequest($key, $rownumber)
+    {
+        if (! isset($_FILES['fields_upload'])
+            || empty($_FILES['fields_upload']['name']['multi_edit'][$rownumber][$key])
+        ) {
+            return false;
+        }
+        $file = PMA_File::fetchUploadedFromTblChangeRequestMultiple(
+            $_FILES['fields_upload'],
+            $rownumber,
+            $key
+        );
+
+        // check for file upload errors
+        switch ($file['error']) {
+        // we do not use the PHP constants here cause not all constants
+        // are defined in all versions of PHP - but the correct constants names
+        // are given as comment
+        case 0: //UPLOAD_ERR_OK:
+            return $this->setUploadedFile($file['tmp_name']);
+            break;
+        case 4: //UPLOAD_ERR_NO_FILE:
+            break;
+        case 1: //UPLOAD_ERR_INI_SIZE:
+            $this->_error_message = __('The uploaded file exceeds the upload_max_filesize directive in php.ini.');
+            break;
+        case 2: //UPLOAD_ERR_FORM_SIZE:
+            $this->_error_message = __('The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form.');
+            break;
+        case 3: //UPLOAD_ERR_PARTIAL:
+            $this->_error_message = __('The uploaded file was only partially uploaded.');
+            break;
+        case 6: //UPLOAD_ERR_NO_TMP_DIR:
+            $this->_error_message = __('Missing a temporary folder.');
+            break;
+        case 7: //UPLOAD_ERR_CANT_WRITE:
+            $this->_error_message = __('Failed to write file to disk.');
+            break;
+        case 8: //UPLOAD_ERR_EXTENSION:
+            $this->_error_message = __('File upload stopped by extension.');
+            break;
+        default:
+            $this->_error_message = __('Unknown error in file upload.');
+        } // end switch
+
+        return false;
+    }
+
+    /**
+     * strips some dimension from the multi-dimensional array from $_FILES
+     *
+     * <code>
+     * $file['name']['multi_edit'][$rownumber][$key] = [value]
+     * $file['type']['multi_edit'][$rownumber][$key] = [value]
+     * $file['size']['multi_edit'][$rownumber][$key] = [value]
+     * $file['tmp_name']['multi_edit'][$rownumber][$key] = [value]
+     * $file['error']['multi_edit'][$rownumber][$key] = [value]
+     *
+     * // becomes:
+     *
+     * $file['name'] = [value]
+     * $file['type'] = [value]
+     * $file['size'] = [value]
+     * $file['tmp_name'] = [value]
+     * $file['error'] = [value]
+     * </code>
+     *
+     * @param array  $file      the array
+     * @param string $rownumber
+     * @param string $key
+     *
+     * @return array
+     * @access  public
+     * @static
+     */
+    public function fetchUploadedFromTblChangeRequestMultiple($file, $rownumber, $key)
+    {
+        $new_file = array(
+            'name' => $file['name']['multi_edit'][$rownumber][$key],
+            'type' => $file['type']['multi_edit'][$rownumber][$key],
+            'size' => $file['size']['multi_edit'][$rownumber][$key],
+            'tmp_name' => $file['tmp_name']['multi_edit'][$rownumber][$key],
+            'error' => $file['error']['multi_edit'][$rownumber][$key],
+        );
+
+        return $new_file;
+    }
+
+    /**
+     * sets the name if the file to the one selected in the tbl_change form
+     *
+     * @param string $key       the md5 hash of the column name
+     * @param string $rownumber
+     *
+     * @return boolean success
+     * @access  public
+     */
+    public function setSelectedFromTblChangeRequest($key, $rownumber = null)
+    {
+        if (! empty($_REQUEST['fields_uploadlocal']['multi_edit'][$rownumber][$key])
+            && is_string($_REQUEST['fields_uploadlocal']['multi_edit'][$rownumber][$key])
+        ) {
+            // ... whether with multiple rows ...
+            return $this->setLocalSelectedFile(
+                $_REQUEST['fields_uploadlocal']['multi_edit'][$rownumber][$key]
+            );
+        } else {
+            return false;
+        }
+    }
+
+    /**
+     * Returns possible error message.
+     *
+     * @access  public
+     * @return string  error message
+     */
+    public function getError()
+    {
+        return $this->_error_message;
+    }
+
+    /**
+     * Checks whether there was any error.
+     *
+     * @access  public
+     * @return boolean whether an error occured or not
+     */
+    public function isError()
+    {
+        return ! empty($this->_error_message);
+    }
+
+    /**
+     * checks the superglobals provided if the tbl_change form is submitted
+     * and uses the submitted/selected file
+     *
+     * @param string $key       the md5 hash of the column name
+     * @param string $rownumber
+     *
+     * @return boolean success
+     * @access  public
+     */
+    public function checkTblChangeForm($key, $rownumber)
+    {
+        if ($this->setUploadedFromTblChangeRequest($key, $rownumber)) {
+            // well done ...
+            $this->_error_message = '';
+            return true;
+        } elseif ($this->setSelectedFromTblChangeRequest($key, $rownumber)) {
+            // well done ...
+            $this->_error_message = '';
+            return true;
+        }
+        // all failed, whether just no file uploaded/selected or an error
+
+        return false;
+    }
+
+    /**
+     * Sets named file to be read from UploadDir.
+     *
+     * @param string $name file name
+     *
+     * @return boolean success
+     * @access  public
+     */
+    public function setLocalSelectedFile($name)
+    {
+        if (empty($GLOBALS['cfg']['UploadDir'])) {
+            return false;
+        }
+
+        $this->setName(
+            PMA_Util::userDir($GLOBALS['cfg']['UploadDir']) . PMA_securePath($name)
+        );
+        if (! $this->isReadable()) {
+            $this->_error_message = __('File could not be read');
+            $this->setName(null);
+            return false;
+        }
+
+        return true;
+    }
+
+    /**
+     * Checks whether file can be read.
+     *
+     * @access  public
+     * @return boolean whether the file is readable or not
+     */
+    public function isReadable()
+    {
+        // suppress warnings from being displayed, but not from being logged
+        // any file access outside of open_basedir will issue a warning
+        ob_start();
+        $is_readable = is_readable($this->getName());
+        ob_end_clean();
+        return $is_readable;
+    }
+
+    /**
+     * If we are on a server with open_basedir, we must move the file
+     * before opening it. The FAQ 1.11 explains how to create the "./tmp"
+     * directory - if needed
+     *
+     * @todo move check of $cfg['TempDir'] into PMA_Config?
+     * @access  public
+     * @return boolean whether uploaded fiel is fine or not
+     */
+    public function checkUploadedFile()
+    {
+        if ($this->isReadable()) {
+            return true;
+        }
+
+        if (empty($GLOBALS['cfg']['TempDir'])
+            || ! is_writable($GLOBALS['cfg']['TempDir'])
+        ) {
+            // cannot create directory or access, point user to FAQ 1.11
+            $this->_error_message = __('Error moving the uploaded file, see [doc at faq1-11]FAQ 1.11[/doc]');
+            return false;
+        }
+
+        $new_file_to_upload = tempnam(
+            realpath($GLOBALS['cfg']['TempDir']),
+            basename($this->getName())
+        );
+
+        // suppress warnings from being displayed, but not from being logged
+        // any file access outside of open_basedir will issue a warning
+        ob_start();
+        $move_uploaded_file_result = move_uploaded_file(
+            $this->getName(),
+            $new_file_to_upload
+        );
+        ob_end_clean();
+        if (! $move_uploaded_file_result) {
+            $this->_error_message = __('Error while moving uploaded file.');
+            return false;
+        }
+
+        $this->setName($new_file_to_upload);
+        $this->isTemp(true);
+
+        if (! $this->isReadable()) {
+            $this->_error_message = __('Cannot read (moved) upload file.');
+            return false;
+        }
+
+        return true;
+    }
+
+    /**
+     * Detects what compression filse uses
+     *
+     * @todo    move file read part into readChunk() or getChunk()
+     * @todo    add support for compression plugins
+     * @access  protected
+     * @return string MIME type of compression, none for none
+     */
+    protected function detectCompression()
+    {
+        // suppress warnings from being displayed, but not from being logged
+        // f.e. any file access outside of open_basedir will issue a warning
+        ob_start();
+        $file = fopen($this->getName(), 'rb');
+        ob_end_clean();
+
+        if (! $file) {
+            $this->_error_message = __('File could not be read');
+            return false;
+        }
+
+        /**
+         * @todo
+         * get registered plugins for file compression
+
+        foreach (PMA_getPlugins($type = 'compression') as $plugin) {
+            if (call_user_func_array(array($plugin['classname'], 'canHandle'), array($this->getName()))) {
+                $this->setCompressionPlugin($plugin);
+                break;
+            }
+        }
+         */
+
+        $test = fread($file, 4);
+        $len = strlen($test);
+        fclose($file);
+
+        if ($len >= 2 && $test[0] == chr(31) && $test[1] == chr(139)) {
+            $this->_compression = 'application/gzip';
+        } elseif ($len >= 3 && substr($test, 0, 3) == 'BZh') {
+            $this->_compression = 'application/bzip2';
+        } elseif ($len >= 4 && $test == "PK\003\004") {
+            $this->_compression = 'application/zip';
+        } else {
+            $this->_compression = 'none';
+        }
+
+        return $this->_compression;
+    }
+
+    /**
+     * Sets whether the content should be decompressed before returned
+     *
+     * @param boolean $decompress whether to decompres
+     *
+     * @return void
+     */
+    public function setDecompressContent($decompress)
+    {
+        $this->_decompress = (bool) $decompress;
+    }
+
+    /**
+     * Returns the file handle
+     *
+     * @return object file handle
+     */
+    public function getHandle()
+    {
+        if (null === $this->_handle) {
+            $this->open();
+        }
+        return $this->_handle;
+    }
+
+    /**
+     * Sets the file handle
+     *
+     * @param object $handle file handle
+     *
+     * @return void
+     */
+    public function setHandle($handle)
+    {
+        $this->_handle = $handle;
+    }
+
+
+    /**
+     * Sets error message for unsupported compression.
+     *
+     * @return void
+     */
+    public function errorUnsupported()
+    {
+        $this->_error_message = sprintf(
+            __('You attempted to load file with unsupported compression (%s). Either support for it is not implemented or disabled by your configuration.'),
+            $this->getCompression()
+        );
+    }
+
+    /**
+     * Attempts to open the file.
+     *
+     * @return bool
+     */
+    public function open()
+    {
+        if (! $this->_decompress) {
+            $this->_handle = @fopen($this->getName(), 'r');
+        }
+
+        switch ($this->getCompression()) {
+        case false:
+            return false;
+        case 'application/bzip2':
+            if ($GLOBALS['cfg']['BZipDump'] && @function_exists('bzopen')) {
+                $this->_handle = @bzopen($this->getName(), 'r');
+            } else {
+                $this->errorUnsupported();
+                return false;
+            }
+            break;
+        case 'application/gzip':
+            if ($GLOBALS['cfg']['GZipDump'] && @function_exists('gzopen')) {
+                $this->_handle = @gzopen($this->getName(), 'r');
+            } else {
+                $this->errorUnsupported();
+                return false;
+            }
+            break;
+        case 'application/zip':
+            if ($GLOBALS['cfg']['ZipDump'] && @function_exists('zip_open')) {
+                include_once './libraries/zip_extension.lib.php';
+                $result = PMA_getZipContents($this->getName());
+                if (! empty($result['error'])) {
+                    $this->_error_message = PMA_Message::rawError($result['error']);
+                    return false;
+                } else {
+                    $this->content_uncompressed = $result['data'];
+                }
+                unset($result);
+            } else {
+                $this->errorUnsupported();
+                return false;
+            }
+            break;
+        case 'none':
+            $this->_handle = @fopen($this->getName(), 'r');
+            break;
+        default:
+            $this->errorUnsupported();
+            return false;
+            break;
+        }
+
+        return true;
+    }
+
+    /**
+     * Returns the character set of the file
+     *
+     * @return string character set of the file
+     */
+    public function getCharset()
+    {
+        return $this->_charset;
+    }
+
+    /**
+     * Sets the character set of the file
+     *
+     * @param string $charset character set of the file
+     *
+     * @return void
+     */
+    public function setCharset($charset)
+    {
+        $this->_charset = $charset;
+    }
+
+    /**
+     * Returns compression used by file.
+     *
+     * @return string MIME type of compression, none for none
+     * @access  public
+     */
+    public function getCompression()
+    {
+        if (null === $this->_compression) {
+            return $this->detectCompression();
+        }
+
+        return $this->_compression;
+    }
+
+    /**
+     * advances the file pointer in the file handle by $length bytes/chars
+     *
+     * @param integer $length numbers of chars/bytes to skip
+     *
+     * @return boolean
+     * @todo this function is unused
+     */
+    public function advanceFilePointer($length)
+    {
+        while ($length > 0) {
+            $this->getNextChunk($length);
+            $length -= $this->getChunkSize();
+        }
+    }
+
+    /**
+     * http://bugs.php.net/bug.php?id=29532
+     * bzip reads a maximum of 8192 bytes on windows systems
+     *
+     * @param int $max_size maximum size of the next chunk to be returned
+     *
+     * @return bool|string
+     * @todo this function is unused
+     */
+    public function getNextChunk($max_size = null)
+    {
+        if (null !== $max_size) {
+            $size = min($max_size, $this->getChunkSize());
+        } else {
+            $size = $this->getChunkSize();
+        }
+
+        // $result = $this->handler->getNextChunk($size);
+        $result = '';
+        switch ($this->getCompression()) {
+        case 'application/bzip2':
+            $result = '';
+            while (strlen($result) < $size - 8192 && ! feof($this->getHandle())) {
+                $result .= bzread($this->getHandle(), $size);
+            }
+            break;
+        case 'application/gzip':
+            $result = gzread($this->getHandle(), $size);
+            break;
+        case 'application/zip':
+            /*
+             * if getNextChunk() is used some day,
+             * replace this code by code similar to the one
+             * in open()
+             *
+            include_once './libraries/unzip.lib.php';
+            $import_handle = new SimpleUnzip();
+            $import_handle->ReadFile($this->getName());
+            if ($import_handle->Count() == 0) {
+                $this->_error_message = __('No files found inside ZIP archive!');
+                return false;
+            } elseif ($import_handle->GetError(0) != 0) {
+                $this->_error_message = __('Error in ZIP archive:')
+                    . ' ' . $import_handle->GetErrorMsg(0);
+                return false;
+            } else {
+                $result = $import_handle->GetData(0);
+            }
+             */
+            break;
+        case 'none':
+            $result = fread($this->getHandle(), $size);
+            break;
+        default:
+            return false;
+        }
+
+        if ($GLOBALS['charset_conversion']) {
+            $result = PMA_convert_string($this->getCharset(), 'utf-8', $result);
+        } else {
+            /**
+             * Skip possible byte order marks (I do not think we need more
+             * charsets, but feel free to add more, you can use wikipedia for
+             * reference: <http://en.wikipedia.org/wiki/Byte_Order_Mark>)
+             *
+             * @todo BOM could be used for charset autodetection
+             */
+            if ($this->getOffset() === 0) {
+                // UTF-8
+                if (strncmp($result, "\xEF\xBB\xBF", 3) == 0) {
+                    $result = substr($result, 3);
+                    // UTF-16 BE, LE
+                } elseif (strncmp($result, "\xFE\xFF", 2) == 0
+                 || strncmp($result, "\xFF\xFE", 2) == 0) {
+                    $result = substr($result, 2);
+                }
+            }
+        }
+
+        $this->_offset += $size;
+        if (0 === $result) {
+            return true;
+        }
+        return $result;
+    }
+
+    /**
+     * Returns the offset
+     *
+     * @return integer the offset
+     */
+    public function getOffset()
+    {
+        return $this->_offset;
+    }
+
+    /**
+     * Returns the chunk size
+     *
+     * @return integer the chunk size
+     */
+    public function getChunkSize()
+    {
+        return $this->_chunk_size;
+    }
+
+    /**
+     * Sets the chunk size
+     *
+     * @param integer $chunk_size the chunk size
+     *
+     * @return void
+     */
+    public function setChunkSize($chunk_size)
+    {
+        $this->_chunk_size = (int) $chunk_size;
+    }
+
+    /**
+     * Returns the length of the content in the file
+     *
+     * @return integer the length of the file content
+     */
+    public function getContentLength()
+    {
+        return strlen($this->_content);
+    }
+
+    /**
+     * Returns whether the end of the file has been reached
+     *
+     * @return boolean whether the end of the file has been reached
+     */
+    public function eof()
+    {
+        if ($this->getHandle()) {
+            return feof($this->getHandle());
+        } else {
+            return ($this->getOffset() >= $this->getContentLength());
+        }
+
+    }
+}
+?>
diff --git a/phpmyadmin/libraries/Footer.class.php b/phpmyadmin/libraries/Footer.class.php
new file mode 100644
index 0000000..a0d14ad
--- /dev/null
+++ b/phpmyadmin/libraries/Footer.class.php
@@ -0,0 +1,283 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * Used to render the footer of PMA's pages
+ *
+ * @package PhpMyAdmin
+ */
+if (! defined('PHPMYADMIN')) {
+    exit;
+}
+
+require_once 'libraries/Scripts.class.php';
+
+/**
+ * Class used to output the footer
+ *
+ * @package PhpMyAdmin
+ */
+class PMA_Footer
+{
+    /**
+     * PMA_Scripts instance
+     *
+     * @access private
+     * @var object
+     */
+    private $_scripts;
+    /**
+     * Whether we are servicing an ajax request.
+     * We can't simply use $GLOBALS['is_ajax_request']
+     * here since it may have not been initialised yet.
+     *
+     * @access private
+     * @var bool
+     */
+    private $_isAjax;
+    /**
+     * Whether to only close the BODY and HTML tags
+     * or also include scripts, errors and links
+     *
+     * @access private
+     * @var bool
+     */
+    private $_isMinimal;
+    /**
+     * Whether to display anything
+     *
+     * @access private
+     * @var bool
+     */
+    private $_isEnabled;
+
+    /**
+     * Creates a new class instance
+     *
+     * @return new PMA_Footer object
+     */
+    public function __construct()
+    {
+        $this->_isEnabled = true;
+        $this->_scripts   = new PMA_Scripts();
+        $this->_isMinimal = false;
+    }
+
+    /**
+     * Renders the debug messages
+     *
+     * @return string
+     */
+    private function _getDebugMessage()
+    {
+        $retval = '';
+        if (! empty($_SESSION['debug'])) {
+            $sum_time = 0;
+            $sum_exec = 0;
+            foreach ($_SESSION['debug']['queries'] as $query) {
+                $sum_time += $query['count'] * $query['time'];
+                $sum_exec += $query['count'];
+            }
+
+            $retval .= '<div id="session_debug">';
+            $retval .= count($_SESSION['debug']['queries']) . ' queries executed ';
+            $retval .= $sum_exec . ' times in ' . $sum_time . ' seconds';
+            $retval .= '<pre>';
+
+            ob_start();
+            print_r($_SESSION['debug']);
+            $retval .= ob_get_contents();
+            ob_end_clean();
+
+            $retval .= '</pre>';
+            $retval .= '</div>';
+            $_SESSION['debug'] = array();
+        }
+        return $retval;
+    }
+
+    /**
+     * Returns the url of the current page
+     *
+     * @param mixed $encoding See PMA_generate_common_url()
+     *
+     * @return string
+     */
+    public function getSelfUrl($encoding = null)
+    {
+        $db = ! empty($GLOBALS['db']) ? $GLOBALS['db'] : '';
+        $table = ! empty($GLOBALS['table']) ? $GLOBALS['table'] : '';
+        $target = ! empty($_REQUEST['target']) ? $_REQUEST['target'] : '';
+        return basename(PMA_getenv('SCRIPT_NAME')) . PMA_generate_common_url(
+            array(
+                'db' => $db,
+                'table' => $table,
+                'server' => $GLOBALS['server'],
+                'target' => $target
+            ),
+            $encoding
+        );
+    }
+
+    /**
+     * Renders the link to open a new page
+     *
+     * @param string $url The url of the page
+     *
+     * @return string
+     */
+    private function _getSelfLink($url)
+    {
+        $retval  = '';
+        $retval .= '<div id="selflink" class="print_ignore">';
+        $retval .= '<a href="' . $url . '"'
+            . ' title="' . __('Open new phpMyAdmin window') . '" target="_blank">';
+        if ($GLOBALS['cfg']['NavigationBarIconic']) {
+            $retval .= PMA_Util::getImage(
+                'window-new.png',
+                __('Open new phpMyAdmin window')
+            );
+        } else {
+            $retval .=  __('Open new phpMyAdmin window');
+        }
+        $retval .= '</a>';
+        $retval .= '</div>';
+        return $retval;
+    }
+
+    /**
+     * Renders the link to open a new page
+     *
+     * @return string
+     */
+    public function getErrorMessages()
+    {
+        $retval = '';
+        if ($GLOBALS['error_handler']->hasDisplayErrors()) {
+            $retval .= '<div class="clearfloat" id="pma_errors">';
+            $retval .= $GLOBALS['error_handler']->getDispErrors();
+            $retval .= '</div>';
+        }
+        return $retval;
+    }
+
+    /**
+     * Saves query in history
+     *
+     * @return void
+     */
+    private function _setHistory()
+    {
+        if (! PMA_isValid($_REQUEST['no_history'])
+            && empty($GLOBALS['error_message'])
+            && ! empty($GLOBALS['sql_query'])
+        ) {
+            PMA_setHistory(
+                PMA_ifSetOr($GLOBALS['db'], ''),
+                PMA_ifSetOr($GLOBALS['table'], ''),
+                $GLOBALS['cfg']['Server']['user'],
+                $GLOBALS['sql_query']
+            );
+        }
+    }
+
+    /**
+     * Disables the rendering of the footer
+     *
+     * @return void
+     */
+    public function disable()
+    {
+        $this->_isEnabled = false;
+    }
+
+    /**
+     * Set the ajax flag to indicate whether
+     * we are sevicing an ajax request
+     *
+     * @param bool $isAjax Whether we are sevicing an ajax request
+     *
+     * @return void
+     */
+    public function setAjax($isAjax)
+    {
+        $this->_isAjax = ($isAjax == true);
+    }
+
+    /**
+     * Turn on minimal display mode
+     *
+     * @return void
+     */
+    public function setMinimal()
+    {
+        $this->_isMinimal = true;
+    }
+
+    /**
+     * Returns the PMA_Scripts object
+     *
+     * @return PMA_Scripts object
+     */
+    public function getScripts()
+    {
+        return $this->_scripts;
+    }
+
+    /**
+     * Renders the footer
+     *
+     * @return string
+     */
+    public function getDisplay()
+    {
+        $retval = '';
+        $this->_setHistory();
+        if ($this->_isEnabled) {
+            if (! $this->_isAjax) {
+                $retval .= "</div>";
+            }
+            if (! $this->_isAjax && ! $this->_isMinimal) {
+                if (PMA_getenv('SCRIPT_NAME')
+                    && empty($_POST)
+                    && empty($GLOBALS['checked_special'])
+                    && ! $this->_isAjax
+                ) {
+                    $url = $this->getSelfUrl('unencoded');
+                    $header = PMA_Response::getInstance()->getHeader();
+                    $scripts = $header->getScripts()->getFiles();
+                    $menuHash = $header->getMenu()->getHash();
+                    // prime the client-side cache
+                    $this->_scripts->addCode(
+                        sprintf(
+                            'AJAX.cache.primer = {'
+                            . ' url: "%s",'
+                            . ' scripts: %s,'
+                            . ' menuHash: "%s"'
+                            . '};',
+                            PMA_escapeJsString($url),
+                            json_encode($scripts),
+                            PMA_escapeJsString($menuHash)
+                        )
+                    );
+                    $url = $this->getSelfUrl();
+                    $retval .= $this->_getSelfLink($url);
+                }
+                $retval .= $this->_getDebugMessage();
+                $retval .= $this->getErrorMessages();
+                $retval .= $this->_scripts->getDisplay();
+                // Include possible custom footers
+                if (file_exists(CUSTOM_FOOTER_FILE)) {
+                    ob_start();
+                    include CUSTOM_FOOTER_FILE;
+                    $retval .= ob_get_contents();
+                    ob_end_clean();
+                }
+            }
+            if (! $this->_isAjax) {
+                $retval .= "</body></html>";
+            }
+        }
+
+        return $retval;
+    }
+}
diff --git a/phpmyadmin/libraries/Header.class.php b/phpmyadmin/libraries/Header.class.php
new file mode 100644
index 0000000..1a934c6
--- /dev/null
+++ b/phpmyadmin/libraries/Header.class.php
@@ -0,0 +1,660 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * Used to render the header of PMA's pages
+ *
+ * @package PhpMyAdmin
+ */
+if (! defined('PHPMYADMIN')) {
+    exit;
+}
+
+require_once 'libraries/Scripts.class.php';
+require_once 'libraries/RecentTable.class.php';
+require_once 'libraries/Menu.class.php';
+require_once 'libraries/navigation/Navigation.class.php';
+require_once 'libraries/url_generating.lib.php';
+
+
+/**
+ * Class used to output the HTTP and HTML headers
+ *
+ * @package PhpMyAdmin
+ */
+class PMA_Header
+{
+    /**
+     * PMA_Scripts instance
+     *
+     * @access private
+     * @var object
+     */
+    private $_scripts;
+    /**
+     * PMA_Menu instance
+     *
+     * @access private
+     * @var object
+     */
+    private $_menu;
+    /**
+     * Whether to offer the option of importing user settings
+     *
+     * @access private
+     * @var bool
+     */
+    private $_userprefsOfferImport;
+    /**
+     * The page title
+     *
+     * @access private
+     * @var string
+     */
+    private $_title;
+    /**
+     * The value for the id attribute for the body tag
+     *
+     * @access private
+     * @var string
+     */
+    private $_bodyId;
+    /**
+     * Whether to show the top menu
+     *
+     * @access private
+     * @var bool
+     */
+    private $_menuEnabled;
+    /**
+     * Whether to show the warnings
+     *
+     * @access private
+     * @var bool
+     */
+    private $_warningsEnabled;
+    /**
+     * Whether the page is in 'print view' mode
+     *
+     * @access private
+     * @var bool
+     */
+    private $_isPrintView;
+    /**
+     * Whether we are servicing an ajax request.
+     * We can't simply use $GLOBALS['is_ajax_request']
+     * here since it may have not been initialised yet.
+     *
+     * @access private
+     * @var bool
+     */
+    private $_isAjax;
+    /**
+     * Whether to display anything
+     *
+     * @access private
+     * @var bool
+     */
+    private $_isEnabled;
+    /**
+     * Whether the HTTP headers (and possibly some HTML)
+     * have already been sent to the browser
+     *
+     * @access private
+     * @var bool
+     */
+    private $_headerIsSent;
+
+    /**
+     * Creates a new class instance
+     *
+     * @return new PMA_Header object
+     */
+    public function __construct()
+    {
+        $this->_isEnabled = true;
+        $this->_isAjax = false;
+        $this->_bodyId = '';
+        $this->_title  = '';
+        $db = ! empty($GLOBALS['db']) ? $GLOBALS['db'] : '';
+        $table = ! empty($GLOBALS['table']) ? $GLOBALS['table'] : '';
+        $this->_menu   = new PMA_Menu(
+            $GLOBALS['server'],
+            $db,
+            $table
+        );
+        $this->_menuEnabled = true;
+        $this->_warningsEnabled = true;
+        $this->_isPrintView = false;
+        $this->_scripts     = new PMA_Scripts();
+        $this->_addDefaultScripts();
+        $this->_headerIsSent = false;
+        // if database storage for user preferences is transient,
+        // offer to load exported settings from localStorage
+        // (detection will be done in JavaScript)
+        $this->_userprefsOfferImport = false;
+        if ($GLOBALS['PMA_Config']->get('user_preferences') == 'session'
+            && ! isset($_SESSION['userprefs_autoload'])
+        ) {
+            $this->_userprefsOfferImport = true;
+        }
+    }
+
+    /**
+     * Loads common scripts
+     *
+     * @return void
+     */
+    private function _addDefaultScripts()
+    {
+        $this->_scripts->addFile('jquery/jquery-1.8.3.js');
+        $this->_scripts->addFile('ajax.js');
+        $this->_scripts->addFile('keyhandler.js');
+        $this->_scripts->addFile('jquery/jquery-ui-1.9.2.custom.js');
+        $this->_scripts->addFile('jquery/jquery.sprintf.js');
+        $this->_scripts->addFile('jquery/jquery.cookie.js');
+        $this->_scripts->addFile('jquery/jquery.mousewheel.js');
+        $this->_scripts->addFile('jquery/jquery.event.drag-2.2.js');
+        $this->_scripts->addFile('jquery/jquery-ui-timepicker-addon.js');
+        $this->_scripts->addFile('jquery/jquery.ba-hashchange-1.3.js');
+        $this->_scripts->addFile('jquery/jquery.debounce-1.0.5.js');
+        $this->_scripts->addFile('jquery/jquery.menuResizer-1.0.js');
+        $this->_scripts->addFile('rte.js');
+
+        // Here would not be a good place to add CodeMirror because
+        // the user preferences have not been merged at this point
+
+        // Localised strings
+        $params = array('lang' => $GLOBALS['lang']);
+        if (isset($GLOBALS['db'])) {
+            $params['db'] = $GLOBALS['db'];
+        }
+        $this->_scripts->addFile('messages.php' . PMA_generate_common_url($params));
+        // Append the theme id to this url to invalidate
+        // the cache on a theme change. Though this might be
+        // unavailable for fatal errors.
+        if (isset($_SESSION['PMA_Theme'])) {
+            $theme_id = urlencode($_SESSION['PMA_Theme']->getId());
+        } else {
+            $theme_id = 'default';
+        }
+        $this->_scripts->addFile(
+            'get_image.js.php?theme=' . $theme_id
+        );
+        $this->_scripts->addFile('functions.js');
+        $this->_scripts->addFile('navigation.js');
+        $this->_scripts->addFile('indexes.js');
+        $this->_scripts->addFile('common.js');
+        $this->_scripts->addCode($this->getJsParamsCode());
+    }
+
+    /**
+     * Returns, as an array, a list of parameters
+     * used on the client side
+     *
+     * @return array
+     */
+    public function getJsParams()
+    {
+        $db = ! empty($GLOBALS['db']) ? $GLOBALS['db'] : '';
+        $table = ! empty($GLOBALS['table']) ? $GLOBALS['table'] : '';
+        return array(
+            'common_query' => PMA_generate_common_url('', '', '&'),
+            'opendb_url' => $GLOBALS['cfg']['DefaultTabDatabase'],
+            'safari_browser' => PMA_USR_BROWSER_AGENT == 'SAFARI' ? 1 : 0,
+            'querywindow_height' => $GLOBALS['cfg']['QueryWindowHeight'],
+            'querywindow_width' => $GLOBALS['cfg']['QueryWindowWidth'],
+            'collation_connection' => $GLOBALS['collation_connection'],
+            'lang' => $GLOBALS['lang'],
+            'server' => $GLOBALS['server'],
+            'table' => $table,
+            'db'    => $db,
+            'token' => $_SESSION[' PMA_token '],
+            'text_dir' => $GLOBALS['text_dir'],
+            'pma_absolute_uri' => $GLOBALS['cfg']['PmaAbsoluteUri'],
+            'pma_text_default_tab' => PMA_Util::getTitleForTarget(
+                $GLOBALS['cfg']['DefaultTabTable']
+            ),
+            'pma_text_left_default_tab' => PMA_Util::getTitleForTarget(
+                $GLOBALS['cfg']['NavigationTreeDefaultTabTable']
+            ),
+            'confirm' => $GLOBALS['cfg']['Confirm']
+        );
+    }
+
+    /**
+     * Returns, as a string, a list of parameters
+     * used on the client side
+     *
+     * @return string
+     */
+    public function getJsParamsCode()
+    {
+        $params = $this->getJsParams();
+        foreach ($params as $key => $value) {
+            $params[$key] = $key . ':"' . PMA_escapeJsString($value) . '"';
+        }
+        return 'PMA_commonParams.setAll({' . implode(',', $params) . '});';
+    }
+
+    /**
+     * Disables the rendering of the header
+     *
+     * @return void
+     */
+    public function disable()
+    {
+        $this->_isEnabled = false;
+    }
+
+    /**
+     * Set the ajax flag to indicate whether
+     * we are sevicing an ajax request
+     *
+     * @param bool $isAjax Whether we are sevicing an ajax request
+     *
+     * @return void
+     */
+    public function setAjax($isAjax)
+    {
+        $this->_isAjax = ($isAjax == true);
+    }
+
+    /**
+     * Returns the PMA_Scripts object
+     *
+     * @return PMA_Scripts object
+     */
+    public function getScripts()
+    {
+        return $this->_scripts;
+    }
+
+    /**
+     * Returns the PMA_Menu object
+     *
+     * @return PMA_Menu object
+     */
+    public function getMenu()
+    {
+        return $this->_menu;
+    }
+
+    /**
+     * Setter for the ID attribute in the BODY tag
+     *
+     * @param string $id Value for the ID attribute
+     *
+     * @return void
+     */
+    public function setBodyId($id)
+    {
+        $this->_bodyId = htmlspecialchars($id);
+    }
+
+    /**
+     * Setter for the title of the page
+     *
+     * @param string $title New title
+     *
+     * @return void
+     */
+    public function setTitle($title)
+    {
+        $this->_title = htmlspecialchars($title);
+    }
+
+    /**
+     * Disables the display of the top menu
+     *
+     * @return void
+     */
+    public function disableMenu()
+    {
+        $this->_menuEnabled = false;
+    }
+
+    /**
+     * Disables the display of the top menu
+     *
+     * @return void
+     */
+    public function disableWarnings()
+    {
+        $this->_warningsEnabled = false;
+    }
+
+    /**
+     * Turns on 'print view' mode
+     *
+     * @return void
+     */
+    public function enablePrintView()
+    {
+        $this->disableMenu();
+        $this->setTitle(__('Print view') . ' - phpMyAdmin ' . PMA_VERSION);
+        $this->_isPrintView = true;
+    }
+
+    /**
+     * Generates the header
+     *
+     * @return string The header
+     */
+    public function getDisplay()
+    {
+        $retval = '';
+        if (! $this->_headerIsSent) {
+            if (! $this->_isAjax && $this->_isEnabled) {
+                $this->sendHttpHeaders();
+                $retval .= $this->_getHtmlStart();
+                $retval .= $this->_getMetaTags();
+                $retval .= $this->_getLinkTags();
+                $retval .= $this->getTitleTag();
+
+                // The user preferences have been merged at this point
+                // so we can conditionally add CodeMirror
+                if ($GLOBALS['cfg']['CodemirrorEnable']) {
+                    $this->_scripts->addFile('codemirror/lib/codemirror.js');
+                    $this->_scripts->addFile('codemirror/mode/mysql/mysql.js');
+                }
+                if ($this->_userprefsOfferImport) {
+                    $this->_scripts->addFile('config.js');
+                }
+                $retval .= $this->_scripts->getDisplay();
+                $retval .= $this->_getBodyStart();
+                if ($this->_menuEnabled && $GLOBALS['server'] > 0) {
+                    $nav = new PMA_Navigation();
+                    $retval .= $nav->getDisplay();
+                }
+                // Include possible custom headers
+                if (file_exists(CUSTOM_HEADER_FILE)) {
+                    ob_start();
+                    include CUSTOM_HEADER_FILE;
+                    $retval .= ob_get_contents();
+                    ob_end_clean();
+                }
+                // offer to load user preferences from localStorage
+                if ($this->_userprefsOfferImport) {
+                    include_once './libraries/user_preferences.lib.php';
+                    $retval .= PMA_userprefsAutoloadGetHeader();
+                }
+                // pass configuration for hint tooltip display
+                // (to be used by PMA_tooltip() in js/functions.js)
+                if (! $GLOBALS['cfg']['ShowHint']) {
+                    $retval .= '<span id="no_hint" class="hide"></span>';
+                }
+                $retval .= $this->_getWarnings();
+                if ($this->_menuEnabled && $GLOBALS['server'] > 0) {
+                    $retval .= $this->_menu->getDisplay();
+                    $pagetop_link = '<a id="goto_pagetop" href="#" title="%s">%s</a>';
+                    $retval .= sprintf(
+                        $pagetop_link,
+                        __('Click on the bar to scroll to top of page'),
+                        PMA_Util::getImage('s_top.png')
+                    );
+                }
+                $retval .= '<div id="page_content">';
+                $retval .= $this->getMessage();
+            }
+            if ($this->_isEnabled && empty($_REQUEST['recent_table'])) {
+                $retval .= $this->_addRecentTable(
+                    $GLOBALS['db'],
+                    $GLOBALS['table']
+                );
+            }
+        }
+        return $retval;
+    }
+
+    /**
+     * Returns the message to be displayed at the top of
+     * the page, including the executed SQL query, if any.
+     *
+     * @return string
+     */
+    public function getMessage()
+    {
+        $retval = '';
+        $message = '';
+        if (! empty($GLOBALS['message'])) {
+            $message = $GLOBALS['message'];
+            unset($GLOBALS['message']);
+        } else if (! empty($_REQUEST['message'])) {
+            $message = $_REQUEST['message'];
+        }
+        if (! empty($message)) {
+            if (isset($GLOBALS['buffer_message'])) {
+                $buffer_message = $GLOBALS['buffer_message'];
+            }
+            $retval .= PMA_Util::getMessage($message);
+            if (isset($buffer_message)) {
+                $GLOBALS['buffer_message'] = $buffer_message;
+            }
+        }
+        return $retval;
+    }
+
+    /**
+     * Sends out the HTTP headers
+     *
+     * @return void
+     */
+    public function sendHttpHeaders()
+    {
+        $https = $GLOBALS['PMA_Config']->isHttps();
+        $mapTilesUrls = ' *.tile.openstreetmap.org *.tile.opencyclemap.org';
+
+        /**
+         * Sends http headers
+         */
+        $GLOBALS['now'] = gmdate('D, d M Y H:i:s') . ' GMT';
+        if (! defined('TESTSUITE')) {
+            header(
+                "X-Content-Security-Policy: default-src 'self' "
+                . $GLOBALS['cfg']['CSPAllow'] . ';'
+                . "options inline-script eval-script;"
+                . "img-src 'self' data: "
+                . $GLOBALS['cfg']['CSPAllow']
+                . ($https ? "" : $mapTilesUrls)
+                . ";"
+            );
+            if (PMA_USR_BROWSER_AGENT == 'SAFARI'
+                && PMA_USR_BROWSER_VER < '6.0.0'
+            ) {
+                header(
+                    "X-WebKit-CSP: allow 'self' "
+                    . $GLOBALS['cfg']['CSPAllow'] . ';'
+                    . "options inline-script eval-script;"
+                    . "img-src 'self' data: "
+                    . $GLOBALS['cfg']['CSPAllow']
+                    . ($https ? "" : $mapTilesUrls)
+                    . ";"
+                );
+            } else {
+                header(
+                    "X-WebKit-CSP: default-src 'self' "
+                    . $GLOBALS['cfg']['CSPAllow'] . ';'
+                    . "script-src 'self' "
+                    . $GLOBALS['cfg']['CSPAllow']
+                    . " 'unsafe-inline' 'unsafe-eval';"
+                    . "style-src 'self' 'unsafe-inline';"
+                    . "img-src 'self' data: "
+                    . $GLOBALS['cfg']['CSPAllow']
+                    . ($https ? "" : $mapTilesUrls)
+                    . ";"
+                );
+            }
+        }
+        PMA_noCacheHeader();
+        if (! defined('IS_TRANSFORMATION_WRAPPER') && ! defined('TESTSUITE')) {
+            // Define the charset to be used
+            header('Content-Type: text/html; charset=utf-8');
+        }
+        $this->_headerIsSent = true;
+    }
+
+    /**
+     * Returns the DOCTYPE and the start HTML tag
+     *
+     * @return string DOCTYPE and HTML tags
+     */
+    private function _getHtmlStart()
+    {
+        $lang = $GLOBALS['available_languages'][$GLOBALS['lang']][1];
+        $dir  = $GLOBALS['text_dir'];
+
+        $retval  = "<!DOCTYPE HTML>";
+        $retval .= "<html lang='$lang' dir='$dir'>";
+
+        return $retval;
+    }
+
+    /**
+     * Returns the META tags
+     *
+     * @return string the META tags
+     */
+    private function _getMetaTags()
+    {
+        $retval  = '<meta charset="utf-8" />';
+        $retval .= '<meta name="robots" content="noindex,nofollow" />';
+        $retval .= '<meta http-equiv="X-UA-Compatible" content="IE=Edge">';
+        return $retval;
+    }
+
+    /**
+     * Returns the LINK tags for the favicon and the stylesheets
+     *
+     * @return string the LINK tags
+     */
+    private function _getLinkTags()
+    {
+        $retval = '<link rel="icon" href="favicon.ico" '
+            . 'type="image/x-icon" />'
+            . '<link rel="shortcut icon" href="favicon.ico" '
+            . 'type="image/x-icon" />';
+        // stylesheets
+        $basedir    = defined('PMA_PATH_TO_BASEDIR') ? PMA_PATH_TO_BASEDIR : '';
+        $common_url = PMA_generate_common_url(array('server' => $GLOBALS['server']));
+        $theme_id   = $GLOBALS['PMA_Config']->getThemeUniqueValue();
+        $theme_path = $GLOBALS['pmaThemePath'];
+
+        if ($this->_isPrintView) {
+            $retval .= '<link rel="stylesheet" type="text/css" href="'
+                . $basedir . 'print.css" />';
+        } else {
+            $retval .= '<link rel="stylesheet" type="text/css" href="'
+                . $basedir . 'phpmyadmin.css.php'
+                . $common_url . '&nocache='
+                . $theme_id . $GLOBALS['text_dir'] . '" />';
+            $retval .= '<link rel="stylesheet" type="text/css" href="'
+                . $theme_path . '/jquery/jquery-ui-1.9.2.custom.css" />';
+        }
+
+        return $retval;
+    }
+
+    /**
+     * Returns the TITLE tag
+     *
+     * @return string the TITLE tag
+     */
+    public function getTitleTag()
+    {
+        $retval  = "<title>";
+        $retval .= $this->_getPageTitle();
+        $retval .= "</title>";
+        return $retval;
+    }
+
+    /**
+     * If the page is missing the title, this function
+     * will set it to something reasonable
+     *
+     * @return string
+     */
+    private function _getPageTitle()
+    {
+        if (empty($this->_title)) {
+            if ($GLOBALS['server'] > 0) {
+                if (! empty($GLOBALS['table'])) {
+                    $temp_title = $GLOBALS['cfg']['TitleTable'];
+                } else if (! empty($GLOBALS['db'])) {
+                    $temp_title = $GLOBALS['cfg']['TitleDatabase'];
+                } elseif (! empty($GLOBALS['cfg']['Server']['host'])) {
+                    $temp_title = $GLOBALS['cfg']['TitleServer'];
+                } else {
+                    $temp_title = $GLOBALS['cfg']['TitleDefault'];
+                }
+                $this->_title = htmlspecialchars(
+                    PMA_Util::expandUserString($temp_title)
+                );
+            } else {
+                $this->_title = 'phpMyAdmin';
+            }
+        }
+        return $this->_title;
+    }
+
+    /**
+     * Returns the close tag to the HEAD
+     * and the start tag for the BODY
+     *
+     * @return string HEAD and BODY tags
+     */
+    private function _getBodyStart()
+    {
+        $retval = "</head><body";
+        if (! empty($this->_bodyId)) {
+            $retval .= " id='" . $this->_bodyId . "'";
+        }
+        $retval .= ">";
+        return $retval;
+    }
+
+    /**
+     * Returns some warnings to be displayed at the top of the page
+     *
+     * @return string The warnings
+     */
+    private function _getWarnings()
+    {
+        $retval = '';
+        if ($this->_warningsEnabled) {
+            $retval .= "<noscript>";
+            $retval .= PMA_message::error(
+                __("Javascript must be enabled past this point")
+            )->getDisplay();
+            $retval .= "</noscript>";
+        }
+        return $retval;
+    }
+
+    /**
+     * Add recently used table and reload the navigation.
+     *
+     * @param string $db    Database name where the table is located.
+     * @param string $table The table name
+     *
+     * @return string
+     */
+    private function _addRecentTable($db, $table)
+    {
+        $retval = '';
+        if ($this->_menuEnabled && strlen($table) && $GLOBALS['cfg']['NumRecentTables'] > 0) {
+            $tmp_result = PMA_RecentTable::getInstance()->add($db, $table);
+            if ($tmp_result === true) {
+                $params  = array('ajax_request' => true, 'recent_table' => true);
+                $url     = 'index.php' . PMA_generate_common_url($params);
+                $retval  = '<a class="hide" id="update_recent_tables"';
+                $retval .= ' href="' . $url . '"></a>';
+            } else {
+                $error  = $tmp_result;
+                $retval = $error->getDisplay();
+            }
+        }
+        return $retval;
+    }
+}
+
+?>
diff --git a/phpmyadmin/libraries/Index.class.php b/phpmyadmin/libraries/Index.class.php
new file mode 100644
index 0000000..c349ea4
--- /dev/null
+++ b/phpmyadmin/libraries/Index.class.php
@@ -0,0 +1,863 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * holds the database index class
+ *
+ * @package PhpMyAdmin
+ */
+if (! defined('PHPMYADMIN')) {
+    exit;
+}
+
+/**
+ *
+ * @package PhpMyAdmin
+ * @since   phpMyAdmin 3.0.0
+ */
+class PMA_Index
+{
+    /**
+     * Class-wide storage container for indexes (caching, singleton)
+     *
+     * @var array
+     */
+    private static $_registry = array();
+
+    /**
+     * @var string The name of the schema
+     */
+    private $_schema = '';
+
+    /**
+     * @var string The name of the table
+     */
+    private $_table = '';
+
+    /**
+     * @var string The name of the index
+     */
+    private $_name = '';
+
+    /**
+     * Columns in index
+     *
+     * @var array
+     */
+    private $_columns = array();
+
+    /**
+     * The index method used (BTREE, SPATIAL, FULLTEXT, HASH, RTREE).
+     *
+     * @var string
+     */
+    private $_type = '';
+
+    /**
+     * The index choice (PRIMARY, UNIQUE, INDEX, SPATIAL, FULLTEXT)
+     *
+     * @var string
+     */
+    private $_choice = '';
+
+    /**
+     * Various remarks.
+     *
+     * @var string
+     */
+    private $_remarks = '';
+
+    /**
+     * Any comment provided for the index with a COMMENT attribute when the
+     * index was created.
+     *
+     * @var string
+     */
+    private $_comment = '';
+
+    /**
+     * @var integer 0 if the index cannot contain duplicates, 1 if it can.
+     */
+    private $_non_unique = 0;
+
+    /**
+     * Indicates how the key is packed. NULL if it is not.
+     *
+     * @var string
+     */
+    private $_packed = null;
+
+    /**
+     * Constructor
+     *
+     * @param array $params parameters
+     */
+    public function __construct($params = array())
+    {
+        $this->set($params);
+    }
+
+    /**
+     * Creates(if not already created) and returns the corresponding Index object
+     *
+     * @param string $schema     database name
+     * @param string $table      table name
+     * @param string $index_name index name
+     *
+     * @return object corresponding Index object
+     */
+    static public function singleton($schema, $table, $index_name = '')
+    {
+        PMA_Index::_loadIndexes($table, $schema);
+        if (! isset(PMA_Index::$_registry[$schema][$table][$index_name])) {
+            $index = new PMA_Index;
+            if (strlen($index_name)) {
+                $index->setName($index_name);
+                PMA_Index::$_registry[$schema][$table][$index->getName()] = $index;
+            }
+            return $index;
+        } else {
+            return PMA_Index::$_registry[$schema][$table][$index_name];
+        }
+    }
+
+    /**
+     * returns an array with all indexes from the given table
+     *
+     * @param string $table  table
+     * @param string $schema schema
+     *
+     * @return array  array of indexes
+     */
+    static public function getFromTable($table, $schema)
+    {
+        PMA_Index::_loadIndexes($table, $schema);
+
+        if (isset(PMA_Index::$_registry[$schema][$table])) {
+            return PMA_Index::$_registry[$schema][$table];
+        } else {
+            return array();
+        }
+    }
+
+    /**
+     * return primary if set, false otherwise
+     *
+     * @param string $table  table
+     * @param string $schema schema
+     *
+     * @return mixed primary index or false if no one exists
+     */
+    static public function getPrimary($table, $schema)
+    {
+        PMA_Index::_loadIndexes($table, $schema);
+
+        if (isset(PMA_Index::$_registry[$schema][$table]['PRIMARY'])) {
+            return PMA_Index::$_registry[$schema][$table]['PRIMARY'];
+        } else {
+            return false;
+        }
+    }
+
+    /**
+     * Load index data for table
+     *
+     * @param string $table  table
+     * @param string $schema schema
+     *
+     * @return boolean whether loading was successful
+     */
+    static private function _loadIndexes($table, $schema)
+    {
+        if (isset(PMA_Index::$_registry[$schema][$table])) {
+            return true;
+        }
+
+        $_raw_indexes = PMA_DBI_get_table_indexes($schema, $table);
+        foreach ($_raw_indexes as $_each_index) {
+            $_each_index['Schema'] = $schema;
+            if (! isset(PMA_Index::$_registry[$schema][$table][$_each_index['Key_name']])) {
+                $key = new PMA_Index($_each_index);
+                PMA_Index::$_registry[$schema][$table][$_each_index['Key_name']] = $key;
+            } else {
+                $key = PMA_Index::$_registry[$schema][$table][$_each_index['Key_name']];
+            }
+
+            $key->addColumn($_each_index);
+        }
+
+        return true;
+    }
+
+    /**
+     * Add column to index
+     *
+     * @param array $params column params
+     *
+     * @return void
+     */
+    public function addColumn($params)
+    {
+        if (strlen($params['Column_name'])) {
+            $this->_columns[$params['Column_name']] = new PMA_Index_Column($params);
+        }
+    }
+
+    /**
+     * Adds a list of columns to the index
+     *
+     * @param array $columns array containing details about the columns
+     *
+     * @return void
+     */
+    public function addColumns($columns)
+    {
+        $_columns = array();
+
+        if (isset($columns['names'])) {
+            // coming from form
+            // $columns[names][]
+            // $columns[sub_parts][]
+            foreach ($columns['names'] as $key => $name) {
+                $sub_part = isset($columns['sub_parts'][$key])
+                    ? $columns['sub_parts'][$key] : '';
+                $_columns[] = array(
+                    'Column_name'   => $name,
+                    'Sub_part'      => $sub_part,
+                );
+            }
+        } else {
+            // coming from SHOW INDEXES
+            // $columns[][name]
+            // $columns[][sub_part]
+            // ...
+            $_columns = $columns;
+        }
+
+        foreach ($_columns as $column) {
+            $this->addColumn($column);
+        }
+    }
+
+    /**
+     * Returns true if $column indexed in this index
+     *
+     * @param string $column the column
+     *
+     * @return boolean  true if $column indexed in this index
+     */
+    public function hasColumn($column)
+    {
+        return isset($this->_columns[$column]);
+    }
+
+    /**
+     * Sets index details
+     *
+     * @param array $params index details
+     *
+     * @return void
+     */
+    public function set($params)
+    {
+        if (isset($params['columns'])) {
+            $this->addColumns($params['columns']);
+        }
+        if (isset($params['Schema'])) {
+            $this->_schema = $params['Schema'];
+        }
+        if (isset($params['Table'])) {
+            $this->_table = $params['Table'];
+        }
+        if (isset($params['Key_name'])) {
+            $this->_name = $params['Key_name'];
+        }
+        if (isset($params['Index_type'])) {
+            $this->_type = $params['Index_type'];
+        }
+        if (isset($params['Comment'])) {
+            $this->_remarks = $params['Comment'];
+        }
+        if (isset($params['Index_comment'])) {
+            $this->_comment = $params['Index_comment'];
+        }
+        if (isset($params['Non_unique'])) {
+            $this->_non_unique = $params['Non_unique'];
+        }
+        if (isset($params['Packed'])) {
+            $this->_packed = $params['Packed'];
+        }
+        if ('PRIMARY' == $this->_name) {
+            $this->_choice = 'PRIMARY';
+        } elseif ('FULLTEXT' == $this->_type) {
+            $this->_choice = 'FULLTEXT';
+        } elseif ('SPATIAL' == $this->_type) {
+            $this->_choice = 'SPATIAL';
+        } elseif ('0' == $this->_non_unique) {
+            $this->_choice = 'UNIQUE';
+        } else {
+            $this->_choice = 'INDEX';
+        }
+    }
+
+    /**
+     * Returns the number of columns of the index
+     *
+     * @return integer the number of the columns
+     */
+    public function getColumnCount()
+    {
+        return count($this->_columns);
+    }
+
+    /**
+     * Returns the index comment
+     *
+     * @return string index comment
+     */
+    public function getComment()
+    {
+        return $this->_comment;
+    }
+
+    /**
+     * Returns index remarks
+     *
+     * @return string index remarks
+     */
+    public function getRemarks()
+    {
+        return $this->_remarks;
+    }
+
+    /**
+     * Returns concatenated remarks and comment
+     *
+     * @return string concatenated remarks and comment
+     */
+    public function getComments()
+    {
+        $comments = $this->getRemarks();
+        if (strlen($comments)) {
+            $comments .= "\n";
+        }
+        $comments .= $this->getComment();
+
+        return $comments;
+    }
+
+    /**
+     * Returns index type ((BTREE, SPATIAL, FULLTEXT, HASH, RTREE)
+     *
+     * @return string index type
+     */
+    public function getType()
+    {
+        return $this->_type;
+    }
+
+    /**
+     * Returns index choice (PRIMARY, UNIQUE, INDEX, SPATIAL, FULLTEXT)
+     *
+     * @return index choice
+     */
+    public function getChoice()
+    {
+        return $this->_choice;
+    }
+
+    /**
+     * Return a list of all index choices
+     *
+     * @return array index choices
+     */
+    static public function getIndexChoices()
+    {
+        return array(
+            'PRIMARY',
+            'INDEX',
+            'UNIQUE',
+            'SPATIAL',
+            'FULLTEXT',
+        );
+    }
+
+    /**
+     * Returns HTML for the index choice selector
+     *
+     * @return string HTML for the index choice selector
+     */
+    public function generateIndexSelector()
+    {
+        $html_options = '';
+
+        foreach (PMA_Index::getIndexChoices() as $each_index_choice) {
+            if ($each_index_choice === 'PRIMARY'
+                && $this->_choice !== 'PRIMARY'
+                && PMA_Index::getPrimary($this->_table, $this->_schema)
+            ) {
+                // skip PRIMARY if there is already one in the table
+                continue;
+            }
+            $html_options .= '<option value="' . $each_index_choice . '"'
+                 . (($this->_choice == $each_index_choice) ? ' selected="selected"' : '')
+                 . '>'. $each_index_choice . '</option>' . "\n";
+        }
+
+        return $html_options;
+    }
+
+    /**
+     * Returns how the index is packed
+     *
+     * @return string how the index is packed
+     */
+    public function getPacked()
+    {
+        return $this->_packed;
+    }
+
+    /**
+     * Returns 'No'/false if the index is not packed,
+     * how the index is packed if packed
+     *
+     * @param boolean $as_text whether to output should be in text
+     *
+     * @return mixed how index is paked
+     */
+    public function isPacked($as_text = false)
+    {
+        if ($as_text) {
+            $r = array(
+                '0' => __('No'),
+                '1' => __('Yes'),
+            );
+        } else {
+            $r = array(
+                '0' => false,
+                '1' => true,
+            );
+        }
+
+        if (null === $this->_packed) {
+            return $r[0];
+        }
+
+        return $this->_packed;
+    }
+
+    /**
+     * Returns integer 0 if the index cannot contain duplicates, 1 if it can
+     *
+     * @return integer 0 if the index cannot contain duplicates, 1 if it can
+     */
+    public function getNonUnique()
+    {
+        return $this->_non_unique;
+    }
+
+    /**
+     * Returns whether the index is a 'Unique' index
+     *
+     * @param boolean $as_text whether to output should be in text
+     *
+     * @return mixed whether the index is a 'Unique' index
+     */
+    public function isUnique($as_text = false)
+    {
+        if ($as_text) {
+            $r = array(
+                '0' => __('Yes'),
+                '1' => __('No'),
+            );
+        } else {
+            $r = array(
+                '0' => true,
+                '1' => false,
+            );
+        }
+
+        return $r[$this->_non_unique];
+    }
+
+    /**
+     * Returns the name of the index
+     *
+     * @return string the name of the index
+     */
+    public function getName()
+    {
+        return $this->_name;
+    }
+
+    /**
+     * Sets the name of the index
+     *
+     * @param string $name index name
+     *
+     * @return void
+     */
+    public function setName($name)
+    {
+        $this->_name = (string) $name;
+    }
+
+    /**
+     * Returns the columns of the index
+     *
+     * @return array the columns of the index
+     */
+    public function getColumns()
+    {
+        return $this->_columns;
+    }
+
+    /**
+     * Show index data
+     *
+     * @param string  $table      The table name
+     * @param string  $schema     The schema name
+     * @param boolean $print_mode Whether the output is for the print mode
+     *
+     * @return array  Index collection array
+     *
+     * @access  public
+     */
+    static public function getView($table, $schema, $print_mode = false)
+    {
+        $indexes = PMA_Index::getFromTable($table, $schema);
+
+        $no_indexes_class = count($indexes) > 0 ? ' hide' : '';
+        $no_indexes  = "<div class='no_indexes_defined$no_indexes_class'>";
+        $no_indexes .= PMA_Message::notice(__('No index defined!'))->getDisplay();
+        $no_indexes .= '</div>';
+
+        if (! $print_mode) {
+            $r  = '<fieldset class="index_info">';
+            $r .= '<legend id="index_header">' . __('Indexes');
+            $r .= PMA_Util::showMySQLDocu(
+                'optimization', 'optimizing-database-structure'
+            );
+
+            $r .= '</legend>';
+            $r .= $no_indexes;
+            if (count($indexes) < 1) {
+                $r .= '</fieldset>';
+                return $r;
+            }
+            $r .= PMA_Index::findDuplicates($table, $schema);
+        } else {
+            $r  = '<h3>' . __('Indexes') . '</h3>';
+            $r .= $no_indexes;
+            if (count($indexes) < 1) {
+                return $r;
+            }
+        }
+        $r .= '<table id="table_index">';
+        $r .= '<thead>';
+        $r .= '<tr>';
+        if (! $print_mode) {
+            $r .= '<th colspan="2">' . __('Action') . '</th>';
+        }
+        $r .= '<th>' . __('Keyname') . '</th>';
+        $r .= '<th>' . __('Type') . '</th>';
+        $r .= '<th>' . __('Unique') . '</th>';
+        $r .= '<th>' . __('Packed') . '</th>';
+        $r .= '<th>' . __('Column') . '</th>';
+        $r .= '<th>' . __('Cardinality') . '</th>';
+        $r .= '<th>' . __('Collation') . '</th>';
+        $r .= '<th>' . __('Null') . '</th>';
+        if (PMA_MYSQL_INT_VERSION > 50500) {
+            $r .= '<th>' . __('Comment') . '</th>';
+        }
+        $r .= '</tr>';
+        $r .= '</thead>';
+        $r .= '<tbody>';
+
+        $odd_row = true;
+        foreach ($indexes as $index) {
+            $row_span = ' rowspan="' . $index->getColumnCount() . '" ';
+
+            $r .= '<tr class="noclick ' . ($odd_row ? 'odd' : 'even') . '">';
+
+            if (! $print_mode) {
+                $this_params = $GLOBALS['url_params'];
+                $this_params['index'] = $index->getName();
+                $r .= '<td class="edit_index';
+                $r .= ' ajax';
+                $r .= '" ' . $row_span . '>'
+                   . '    <a class="';
+                $r .= 'ajax';
+                $r .= '" href="tbl_indexes.php' . PMA_generate_common_url($this_params)
+                   . '">' . PMA_Util::getIcon('b_edit.png', __('Edit')) . '</a>'
+                   . '</td>' . "\n";
+                $this_params = $GLOBALS['url_params'];
+                if ($index->getName() == 'PRIMARY') {
+                    $this_params['sql_query'] = 'ALTER TABLE '
+                        . PMA_Util::backquote($table)
+                        . ' DROP PRIMARY KEY;';
+                    $this_params['message_to_show']
+                        = __('The primary key has been dropped');
+                    $js_msg = PMA_jsFormat(
+                        'ALTER TABLE ' . $table . ' DROP PRIMARY KEY'
+                    );
+                } else {
+                    $this_params['sql_query'] = 'ALTER TABLE '
+                        . PMA_Util::backquote($table) . ' DROP INDEX '
+                        . PMA_Util::backquote($index->getName()) . ';';
+                    $this_params['message_to_show'] = sprintf(
+                        __('Index %s has been dropped'), $index->getName()
+                    );
+
+                    $js_msg = PMA_jsFormat(
+                        'ALTER TABLE ' . $table . ' DROP INDEX '
+                        . $index->getName() . ';'
+                    );
+
+                }
+
+                $r .= '<td ' . $row_span . '>';
+                $r .= '<input type="hidden" class="drop_primary_key_index_msg"'
+                    . ' value="' . $js_msg . '" />';
+                $r .= '    <a class="drop_primary_key_index_anchor';
+                $r .= ' ajax';
+                $r .= '" href="sql.php' . PMA_generate_common_url($this_params)
+                   . '" >'
+                   . PMA_Util::getIcon('b_drop.png', __('Drop'))  . '</a>'
+                   . '</td>' . "\n";
+            }
+
+            if (! $print_mode) {
+                $r .= '<th ' . $row_span . '>'
+                    . htmlspecialchars($index->getName())
+                    . '</th>';
+            } else {
+                $r .= '<td ' . $row_span . '>'
+                    . htmlspecialchars($index->getName())
+                    . '</td>';
+            }
+            $r .= '<td ' . $row_span . '>'
+                . htmlspecialchars($index->getType())
+                . '</td>';
+            $r .= '<td ' . $row_span . '>' . $index->isUnique(true) . '</td>';
+            $r .= '<td ' . $row_span . '>' . $index->isPacked(true) . '</td>';
+
+            foreach ($index->getColumns() as $column) {
+                if ($column->getSeqInIndex() > 1) {
+                    $r .= '<tr class="noclick ' . ($odd_row ? 'odd' : 'even') . '">';
+                }
+                $r .= '<td>' . htmlspecialchars($column->getName());
+                if ($column->getSubPart()) {
+                    $r .= ' (' . $column->getSubPart() . ')';
+                }
+                $r .= '</td>';
+                $r .= '<td>'
+                    . htmlspecialchars($column->getCardinality())
+                    . '</td>';
+                $r .= '<td>'
+                    . htmlspecialchars($column->getCollation())
+                    . '</td>';
+                $r .= '<td>'
+                    . htmlspecialchars($column->getNull(true))
+                    . '</td>';
+
+                if (PMA_MYSQL_INT_VERSION > 50500
+                    && $column->getSeqInIndex() == 1) {
+                    $r .= '<td ' . $row_span . '>'
+                        . htmlspecialchars($index->getComments()) . '</td>';
+                }
+                $r .= '</tr>';
+            } // end foreach $index['Sequences']
+
+            $odd_row = ! $odd_row;
+        } // end while
+        $r .= '</tbody>';
+        $r .= '</table>';
+        if (! $print_mode) {
+            $r .= '</fieldset>';
+        }
+
+        return $r;
+    }
+
+    public function getCompareData()
+    {
+        $data = array(
+            // 'Non_unique'    => $this->_non_unique,
+            'Packed'        => $this->_packed,
+            'Index_type'    => $this->_type,
+        );
+
+        foreach ($this->_columns as $column) {
+            $data['columns'][] = $column->getCompareData();
+        }
+
+        return $data;
+    }
+
+    /**
+     * Function to check over array of indexes and look for common problems
+     *
+     * @param string $table  table name
+     * @param string $schema schema name
+     *
+     * @return string  Output HTML
+     * @access  public
+     */
+    static public function findDuplicates($table, $schema)
+    {
+        $indexes = PMA_Index::getFromTable($table, $schema);
+
+        $output  = '';
+
+        // count($indexes) < 2:
+        //   there is no need to check if there less than two indexes
+        if (count($indexes) < 2) {
+            return $output;
+        }
+
+        // remove last index from stack and ...
+        while ($while_index = array_pop($indexes)) {
+            // ... compare with every remaining index in stack
+            foreach ($indexes as $each_index) {
+                if ($each_index->getCompareData() !== $while_index->getCompareData()) {
+                    continue;
+                }
+
+                // did not find any difference
+                // so it makes no sense to have this two equal indexes
+
+                $message = PMA_Message::notice(
+                    __('The indexes %1$s and %2$s seem to be equal and one of them could possibly be removed.')
+                );
+                $message->addParam($each_index->getName());
+                $message->addParam($while_index->getName());
+                $output .= $message->getDisplay();
+
+                // there is no need to check any further indexes if we have already
+                // found that this one has a duplicate
+                continue 2;
+            }
+        }
+        return $output;
+    }
+}
+
+/**
+ * @package PhpMyAdmin
+ */
+class PMA_Index_Column
+{
+    /**
+     * @var string The column name
+     */
+    private $_name = '';
+
+    /**
+     * @var integer The column sequence number in the index, starting with 1.
+     */
+    private $_seq_in_index = 1;
+
+    /**
+     * @var string How the column is sorted in the index. “A” (Ascending) or
+     * NULL (Not sorted)
+     */
+    private $_collation = null;
+
+    /**
+     * The number of indexed characters if the column is only partly indexed,
+     * NULL if the entire column is indexed.
+     *
+     * @var integer
+     */
+    private $_sub_part = null;
+
+    /**
+     * Contains YES if the column may contain NULL.
+     * If not, the column contains NO.
+     *
+     * @var string
+     */
+    private $_null = '';
+
+    /**
+     * An estimate of the number of unique values in the index. This is updated
+     * by running ANALYZE TABLE or myisamchk -a. Cardinality is counted based on
+     * statistics stored as integers, so the value is not necessarily exact even
+     * for small tables. The higher the cardinality, the greater the chance that
+     * MySQL uses the index when doing joins.
+     *
+     * @var integer
+     */
+    private $_cardinality = null;
+
+    public function __construct($params = array())
+    {
+        $this->set($params);
+    }
+
+    public function set($params)
+    {
+        if (isset($params['Column_name'])) {
+            $this->_name = $params['Column_name'];
+        }
+        if (isset($params['Seq_in_index'])) {
+            $this->_seq_in_index = $params['Seq_in_index'];
+        }
+        if (isset($params['Collation'])) {
+            $this->_collation = $params['Collation'];
+        }
+        if (isset($params['Cardinality'])) {
+            $this->_cardinality = $params['Cardinality'];
+        }
+        if (isset($params['Sub_part'])) {
+            $this->_sub_part = $params['Sub_part'];
+        }
+        if (isset($params['Null'])) {
+            $this->_null = $params['Null'];
+        }
+    }
+
+    public function getName()
+    {
+        return $this->_name;
+    }
+
+    public function getCollation()
+    {
+        return $this->_collation;
+    }
+
+    public function getCardinality()
+    {
+        return $this->_cardinality;
+    }
+
+    public function getNull($as_text = false)
+    {
+        return $as_text
+            ? (!$this->_null || $this->_null == 'NO' ? __('No') : __('Yes'))
+            : $this->_null;
+    }
+
+    public function getSeqInIndex()
+    {
+        return $this->_seq_in_index;
+    }
+
+    public function getSubPart()
+    {
+        return $this->_sub_part;
+    }
+
+    public function getCompareData()
+    {
+        return array(
+            'Column_name'   => $this->_name,
+            'Seq_in_index'  => $this->_seq_in_index,
+            'Collation'     => $this->_collation,
+            'Sub_part'      => $this->_sub_part,
+            'Null'          => $this->_null,
+        );
+    }
+}
+?>
diff --git a/phpmyadmin/libraries/List.class.php b/phpmyadmin/libraries/List.class.php
new file mode 100644
index 0000000..f87c89d
--- /dev/null
+++ b/phpmyadmin/libraries/List.class.php
@@ -0,0 +1,121 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * hold the PMA_List base class
+ *
+ * @package PhpMyAdmin
+ */
+if (! defined('PHPMYADMIN')) {
+    exit;
+}
+
+/**
+ * @todo add caching
+ * @abstract
+ * @package PhpMyAdmin
+ * @since   phpMyAdmin 2.9.10
+ */
+abstract class PMA_List extends ArrayObject
+{
+    /**
+     * @var mixed   empty item
+     */
+    protected $item_empty = '';
+
+    public function __construct($array = array(), $flags = 0, $iterator_class = "ArrayIterator")
+    {
+        parent::__construct($array, $flags, $iterator_class);
+    }
+
+    /**
+     * returns item only if there is only one in the list
+     *
+     * @return single item
+     */
+    public function getSingleItem()
+    {
+        if (count($this) === 1) {
+            return reset($this);
+        }
+
+        return $this->getEmpty();
+    }
+
+    /**
+     * defines what is an empty item (0, '', false or null)
+     *
+     * @return mixed   an empty item
+     */
+    public function getEmpty()
+    {
+        return $this->item_empty;
+    }
+
+    /**
+     * checks if the given db names exists in the current list, if there is
+     * missing at least one item it returns false otherwise true
+     *
+     * @return boolean true if all items exists, otheriwse false
+     */
+    public function exists()
+    {
+        $this_elements = $this->getArrayCopy();
+        foreach (func_get_args() as $result) {
+            if (! in_array($result, $this_elements)) {
+                return false;
+            }
+        }
+
+        return true;
+    }
+
+    /**
+     * returns HTML <option>-tags to be used inside <select></select>
+     *
+     * @param mixed   $selected                   the selected db or true for
+     *                                            selecting current db
+     * @param boolean $include_information_schema whether include information schema
+     *
+     * @return string  HTML option tags
+     */
+    public function getHtmlOptions($selected = '', $include_information_schema = true)
+    {
+        if (true === $selected) {
+            $selected = $this->getDefault();
+        }
+
+        $options = '';
+        foreach ($this as $each_item) {
+            if (false === $include_information_schema
+                && PMA_is_system_schema($each_item)
+            ) {
+                continue;
+            }
+            $options .= '<option value="' . htmlspecialchars($each_item) . '"';
+            if ($selected === $each_item) {
+                $options .= ' selected="selected"';
+            }
+            $options .= '>' . htmlspecialchars($each_item) . '</option>' . "\n";
+        }
+
+        return $options;
+    }
+
+    /**
+     * returns default item
+     *
+     * @return string  default item
+     */
+    public function getDefault()
+    {
+        return $this->getEmpty();
+    }
+
+    /**
+     * builds up the list
+     *
+     * @return void
+     */
+    abstract public function build();
+}
+?>
diff --git a/phpmyadmin/libraries/List_Database.class.php b/phpmyadmin/libraries/List_Database.class.php
new file mode 100644
index 0000000..f2902e1
--- /dev/null
+++ b/phpmyadmin/libraries/List_Database.class.php
@@ -0,0 +1,318 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * holds the PMA_List_Database class
+ *
+ * @package PhpMyAdmin
+ */
+if (! defined('PHPMYADMIN')) {
+    exit;
+}
+
+/**
+ * the list base class
+ */
+require_once './libraries/List.class.php';
+
+/**
+ * handles database lists
+ *
+ * <code>
+ * $PMA_List_Database = new PMA_List_Database($userlink, $controllink);
+ * </code>
+ *
+ * @todo this object should be attached to the PMA_Server object
+ * @todo ? make use of INFORMATION_SCHEMA
+ * @todo ? support --skip-showdatabases and user has only global rights
+ *
+ * @package PhpMyAdmin
+ * @since   phpMyAdmin 2.9.10
+ */
+class PMA_List_Database extends PMA_List
+{
+    /**
+     * @var mixed   database link resource|object to be used
+     * @access protected
+     */
+    protected $db_link = null;
+
+    /**
+     * @var mixed   user database link resource|object
+     * @access protected
+     */
+    protected $db_link_user = null;
+
+    /**
+     * @var mixed   controluser database link resource|object
+     * @access protected
+     */
+    protected $db_link_control = null;
+
+    /**
+     * @var boolean whether SHOW DATABASES is disabled or not
+     * @access protected
+     */
+    protected $show_databases_disabled = false;
+
+    /**
+     * @var string command to retrieve databases from server
+     * @access protected
+     */
+    protected $command = null;
+
+    /**
+     * Constructor
+     *
+     * @param mixed $db_link_user    user database link resource|object
+     * @param mixed $db_link_control control database link resource|object
+     *
+     * @return void
+     */
+    public function __construct($db_link_user = null, $db_link_control = null)
+    {
+        $this->db_link = $db_link_user;
+        $this->db_link_user = $db_link_user;
+        $this->db_link_control = $db_link_control;
+
+        parent::__construct();
+        $this->build();
+    }
+
+    /**
+     * checks if the configuration wants to hide some databases
+     *
+     * @return void
+     */
+    protected function checkHideDatabase()
+    {
+        if (empty($GLOBALS['cfg']['Server']['hide_db'])) {
+            return;
+        }
+
+        foreach ($this->getArrayCopy() as $key => $db) {
+            if (preg_match('/' . $GLOBALS['cfg']['Server']['hide_db'] . '/', $db)) {
+                $this->offsetUnset($key);
+            }
+        }
+    }
+
+    /**
+     * retrieves database list from server
+     *
+     * @param string $like_db_name usally a db_name containing wildcards
+     *
+     * @return array
+     * @todo   we could also search mysql tables if all fail?
+     */
+    protected function retrieve($like_db_name = null)
+    {
+        if ($this->show_databases_disabled) {
+            return array();
+        }
+
+        if (null !== $like_db_name) {
+            $command = "SHOW DATABASES LIKE '" . $like_db_name . "'";
+        } elseif (null === $this->command) {
+            $command = str_replace(
+                '#user#', $GLOBALS['cfg']['Server']['user'],
+                $GLOBALS['cfg']['Server']['ShowDatabasesCommand']
+            );
+            $this->command = $command;
+        } else {
+            $command = $this->command;
+        }
+
+        $database_list = PMA_DBI_fetch_result($command, null, null, $this->db_link);
+        PMA_DBI_getError();
+
+        if ($GLOBALS['errno'] !== 0) {
+            // failed to get database list, try the control user
+            // (hopefully there is one and he has SHOW DATABASES right)
+            $this->db_link = $this->db_link_control;
+            $database_list = PMA_DBI_fetch_result(
+                $command, null, null, $this->db_link
+            );
+
+            PMA_DBI_getError();
+
+            if ($GLOBALS['errno'] !== 0) {
+                // failed! we will display a warning that phpMyAdmin could not safely
+                // retrieve database list, the admin has to setup a control user or
+                // allow SHOW DATABASES
+                $GLOBALS['error_showdatabases'] = true;
+                $this->show_databases_disabled = true;
+            }
+        }
+
+        if ($GLOBALS['cfg']['NaturalOrder']) {
+            natsort($database_list);
+        } else {
+            // need to sort anyway, otherwise information_schema
+            // goes at the top
+            sort($database_list);
+        }
+
+        return $database_list;
+    }
+
+    /**
+     * builds up the list
+     *
+     * @return void
+     */
+    public function build()
+    {
+        if (! $this->checkOnlyDatabase()) {
+            $items = $this->retrieve();
+            $this->exchangeArray($items);
+        }
+
+        $this->checkHideDatabase();
+    }
+
+    /**
+     * checks the only_db configuration
+     *
+     * @return boolean false if there is no only_db, otherwise true
+     */
+    protected function checkOnlyDatabase()
+    {
+        if (is_string($GLOBALS['cfg']['Server']['only_db'])
+            && strlen($GLOBALS['cfg']['Server']['only_db'])
+        ) {
+            $GLOBALS['cfg']['Server']['only_db'] = array(
+                $GLOBALS['cfg']['Server']['only_db']
+            );
+        }
+
+        if (! is_array($GLOBALS['cfg']['Server']['only_db'])) {
+            return false;
+        }
+
+        $items = array();
+
+        foreach ($GLOBALS['cfg']['Server']['only_db'] as $each_only_db) {
+
+            // check if the db name contains wildcard,
+            // thus containing not escaped _ or %
+            if (! preg_match('/(^|[^\\\\])(_|%)/', $each_only_db)) {
+                // ... not contains wildcard
+                $items[] = PMA_Util::unescapeMysqlWildcards($each_only_db);
+                continue;
+            }
+
+            if (! $this->show_databases_disabled) {
+                $items = array_merge($items, $this->retrieve($each_only_db));
+                continue;
+            }
+
+            // @todo induce error, about not using wildcards
+            // with SHOW DATABASE disabled?
+        }
+
+        $this->exchangeArray($items);
+
+        return true;
+    }
+
+    /**
+     * returns default item
+     *
+     * @return string default item
+     */
+    public function getDefault()
+    {
+        if (strlen($GLOBALS['db'])) {
+            return $GLOBALS['db'];
+        }
+
+        return $this->getEmpty();
+    }
+
+    /**
+     * this is just a backup, if all is fine this can be deleted later
+     *
+     * @deprecated
+     * @return void
+     */
+    protected function checkAgainstPrivTables()
+    {
+        // 1. get allowed dbs from the "mysql.db" table
+        // User can be blank (anonymous user)
+        $local_query = "
+            SELECT DISTINCT `Db` FROM `mysql`.`db`
+            WHERE `Select_priv` = 'Y'
+            AND `User`
+            IN ('" . PMA_Util::sqlAddSlashes($GLOBALS['cfg']['Server']['user']) . "', '')";
+        $tmp_mydbs = PMA_DBI_fetch_result(
+            $local_query, null, null, $GLOBALS['controllink']
+        );
+        if ($tmp_mydbs) {
+            // Will use as associative array of the following 2 code
+            // lines:
+            //   the 1st is the only line intact from before
+            //     correction,
+            //   the 2nd replaces $dblist[] = $row['Db'];
+
+            // Code following those 2 lines in correction continues
+            // populating $dblist[], as previous code did. But it is
+            // now populated with actual database names instead of
+            // with regular expressions.
+            $tmp_alldbs = PMA_DBI_query('SHOW DATABASES;', $GLOBALS['controllink']);
+            // all databases cases - part 2
+            if (isset($tmp_mydbs['%'])) {
+                while ($tmp_row = PMA_DBI_fetch_row($tmp_alldbs)) {
+                    $dblist[] = $tmp_row[0];
+                } // end while
+            } else {
+                while ($tmp_row = PMA_DBI_fetch_row($tmp_alldbs)) {
+                    $tmp_db = $tmp_row[0];
+                    if (isset($tmp_mydbs[$tmp_db]) && $tmp_mydbs[$tmp_db] == 1) {
+                        $dblist[]           = $tmp_db;
+                        $tmp_mydbs[$tmp_db] = 0;
+                    } elseif (! isset($dblist[$tmp_db])) {
+                        foreach ($tmp_mydbs as $tmp_matchpattern => $tmp_value) {
+                            // fixed bad regexp
+                            // TODO: db names may contain characters
+                            //       that are regexp instructions
+                            $re        = '(^|(\\\\\\\\)+|[^\])';
+                            $tmp_regex = preg_replace(
+                                '/' . addcslashes($re, '/') . '%/',
+                                '\\1.*',
+                                preg_replace(
+                                    '/' . addcslashes($re, '/') . '_/',
+                                    '\\1.{1}',
+                                    $tmp_matchpattern
+                                )
+                            );
+                            // Fixed db name matching
+                            // 2000-08-28 -- Benjamin Gandon
+                            if (preg_match('/^' . addcslashes($tmp_regex, '/') . '$/', $tmp_db)) {
+                                $dblist[] = $tmp_db;
+                                break;
+                            }
+                        } // end while
+                    } // end if ... elseif ...
+                } // end while
+            } // end else
+            PMA_DBI_free_result($tmp_alldbs);
+            unset($tmp_mydbs);
+        } // end if
+
+        // 2. get allowed dbs from the "mysql.tables_priv" table
+        $local_query = 'SELECT DISTINCT `Db` FROM `mysql`.`tables_priv`';
+        $local_query .= ' WHERE `Table_priv` LIKE \'%Select%\'';
+        $local_query .= ' AND `User` = \'';
+        $local_query .= PMA_Util::sqlAddSlashes($GLOBALS['cfg']['Server']['user']) . '\'';
+        $rs          = PMA_DBI_try_query($local_query, $GLOBALS['controllink']);
+        if ($rs && @PMA_DBI_num_rows($rs)) {
+            while ($row = PMA_DBI_fetch_assoc($rs)) {
+                if (!in_array($row['Db'], $dblist)) {
+                    $dblist[] = $row['Db'];
+                }
+            } // end while
+            PMA_DBI_free_result($rs);
+        } // end if
+    }
+}
+?>
diff --git a/phpmyadmin/libraries/Menu.class.php b/phpmyadmin/libraries/Menu.class.php
new file mode 100644
index 0000000..ac5042b
--- /dev/null
+++ b/phpmyadmin/libraries/Menu.class.php
@@ -0,0 +1,525 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * Generates and renders the top menu
+ *
+ * @package PhpMyAdmin
+ */
+if (! defined('PHPMYADMIN')) {
+    exit;
+}
+
+/**
+ * Class for generating the top menu
+ *
+ * @package PhpMyAdmin
+ */
+class PMA_Menu
+{
+    /**
+     * Server id
+     *
+     * @access private
+     * @var string
+     */
+    private $_server;
+    /**
+     * Database name
+     *
+     * @access private
+     * @var string
+     */
+    private $_db;
+    /**
+     * Table name
+     *
+     * @access private
+     * @var string
+     */
+    private $_table;
+
+    /**
+     * Creates a new instance of PMA_Menu
+     *
+     * @param int    $server Server id
+     * @param string $db     Database name
+     * @param string $table  Table name
+     *
+     * @return New PMA_Table
+     */
+    public function __construct($server, $db, $table)
+    {
+        $this->_server = $server;
+        $this->_db     = $db;
+        $this->_table  = $table;
+    }
+
+    /**
+     * Prints the menu and the breadcrumbs
+     *
+     * @return void
+     */
+    public function display()
+    {
+        echo $this->getDisplay();
+    }
+
+    /**
+     * Returns the menu and the breadcrumbs as a string
+     *
+     * @return string
+     */
+    public function getDisplay()
+    {
+        $retval  = $this->_getBreadcrumbs();
+        $retval .= $this->_getMenu();
+        return $retval;
+    }
+
+    /**
+     * Returns hash for the menu and the breadcrumbs
+     *
+     * @return string
+     */
+    public function getHash()
+    {
+        return substr(
+            md5($this->_getMenu() . $this->_getBreadcrumbs()),
+            0,
+            8
+        );
+    }
+
+    /**
+     * Returns the menu as HTML
+     *
+     * @return string HTML formatted menubar
+     */
+    private function _getMenu()
+    {
+        $tabs = array();
+        $url_params = array('db' => $this->_db);
+        if (strlen($this->_table)) {
+            $tabs = $this->_getTableTabs();
+            $url_params['table'] = $this->_table;
+        } else if (strlen($this->_db)) {
+            $tabs = $this->_getDbTabs();
+        } else {
+            $tabs = $this->_getServerTabs();
+        }
+        return PMA_Util::getHtmlTabs($tabs, $url_params, 'topmenu', true);
+    }
+
+    /**
+     * Returns the breadcrumbs as HTML
+     *
+     * @return string HTML formatted breadcrumbs
+     */
+    private function _getBreadcrumbs()
+    {
+        $retval = '';
+        $tbl_is_view = PMA_Table::isView($this->_db, $this->_table);
+        $server_info = ! empty($GLOBALS['cfg']['Server']['verbose'])
+            ? $GLOBALS['cfg']['Server']['verbose']
+            : $GLOBALS['cfg']['Server']['host'];
+        $server_info .= empty($GLOBALS['cfg']['Server']['port'])
+            ? ''
+            : ':' . $GLOBALS['cfg']['Server']['port'];
+
+        $separator = "<span class='separator item'> »</span>";
+        $item = '<a href="%1$s?%2$s" class="item">';
+
+        if ($GLOBALS['cfg']['NavigationBarIconic'] !== true) {
+            $item .= '%4$s: ';
+        }
+        $item .= '%3$s</a>';
+        $retval .= "<div id='floating_menubar'></div>";
+        $retval .= "<div id='serverinfo'>";
+        if ($GLOBALS['cfg']['NavigationBarIconic']) {
+            $retval .= PMA_Util::getImage(
+                's_host.png',
+                '',
+                array('class' => 'item')
+            );
+        }
+        $retval .= sprintf(
+            $item,
+            $GLOBALS['cfg']['DefaultTabServer'],
+            PMA_generate_common_url(),
+            htmlspecialchars($server_info),
+            __('Server')
+        );
+
+        if (strlen($this->_db)) {
+            $retval .= $separator;
+            if ($GLOBALS['cfg']['NavigationBarIconic']) {
+                $retval .= PMA_Util::getImage(
+                    's_db.png',
+                    '',
+                    array('class' => 'item')
+                );
+            }
+            $retval .= sprintf(
+                $item,
+                $GLOBALS['cfg']['DefaultTabDatabase'],
+                PMA_generate_common_url($this->_db),
+                htmlspecialchars($this->_db),
+                __('Database')
+            );
+            // if the table is being dropped, $_REQUEST['purge'] is set to '1'
+            // so do not display the table name in upper div
+            if (strlen($this->_table)
+                && ! (isset($_REQUEST['purge']) && $_REQUEST['purge'] == '1')
+            ) {
+                include './libraries/tbl_info.inc.php';
+
+                $retval .= $separator;
+                if ($GLOBALS['cfg']['NavigationBarIconic']) {
+                    $icon = $tbl_is_view ? 'b_views.png' : 's_tbl.png';
+                    $retval .= PMA_Util::getImage(
+                        $icon,
+                        '',
+                        array('class' => 'item')
+                    );
+                }
+                $retval .= sprintf(
+                    $item,
+                    $GLOBALS['cfg']['DefaultTabTable'],
+                    PMA_generate_common_url($this->_db, $this->_table),
+                    str_replace(' ', ' ', htmlspecialchars($this->_table)),
+                    $tbl_is_view ? __('View') : __('Table')
+                );
+
+                /**
+                 * Displays table comment
+                 */
+                if (! empty($show_comment)
+                    && ! isset($GLOBALS['avoid_show_comment'])
+                ) {
+                    if (strstr($show_comment, '; InnoDB free')) {
+                        $show_comment = preg_replace(
+                            '@; InnoDB free:.*?$@',
+                            '',
+                            $show_comment
+                        );
+                    }
+                    $retval .= '<span class="table_comment"';
+                    $retval .= ' id="span_table_comment">"';
+                    $retval .= htmlspecialchars($show_comment);
+                    $retval .= '"</span>';
+                } // end if
+            } else {
+                // no table selected, display database comment if present
+                $cfgRelation = PMA_getRelationsParam();
+
+                // Get additional information about tables for tooltip is done
+                // in libraries/db_info.inc.php only once
+                if ($cfgRelation['commwork']) {
+                    $comment = PMA_getDbComment($this->_db);
+                    /**
+                     * Displays table comment
+                     */
+                    if (! empty($comment)) {
+                        $retval .= '<span class="table_comment"'
+                            . ' id="span_table_comment">"'
+                            . htmlspecialchars($comment)
+                            . '"</span>';
+                    } // end if
+                }
+            }
+        }
+        $retval .= '<div class="clearfloat"></div>';
+        $retval .= '</div>';
+        return $retval;
+    }
+
+    /**
+     * Returns the table tabs as an array
+     *
+     * @return array Data for generating table tabs
+     */
+    private function _getTableTabs()
+    {
+        $db_is_information_schema = PMA_is_system_schema($this->_db);
+        $tbl_is_view = PMA_Table::isView($this->_db, $this->_table);
+        $table_info_num_rows = PMA_Table::countRecords($this->_db, $this->_table);
+
+        $tabs = array();
+
+        $tabs['browse']['icon'] = 'b_browse.png';
+        $tabs['browse']['text'] = __('Browse');
+        $tabs['browse']['link'] = 'sql.php';
+        $tabs['browse']['args']['pos'] = 0;
+
+        $tabs['structure']['icon'] = 'b_props.png';
+        $tabs['structure']['link'] = 'tbl_structure.php';
+        $tabs['structure']['text'] = __('Structure');
+
+        $tabs['sql']['icon'] = 'b_sql.png';
+        $tabs['sql']['link'] = 'tbl_sql.php';
+        $tabs['sql']['text'] = __('SQL');
+
+        $tabs['search']['icon'] = 'b_search.png';
+        $tabs['search']['text'] = __('Search');
+        $tabs['search']['link'] = 'tbl_select.php';
+        $tabs['search']['active'] = in_array(
+            basename($GLOBALS['PMA_PHP_SELF']),
+            array('tbl_select.php', 'tbl_zoom_select.php')
+        );
+
+        if (! $db_is_information_schema) {
+            $tabs['insert']['icon'] = 'b_insrow.png';
+            $tabs['insert']['link'] = 'tbl_change.php';
+            $tabs['insert']['text'] = __('Insert');
+        }
+
+        $tabs['export']['icon'] = 'b_tblexport.png';
+        $tabs['export']['link'] = 'tbl_export.php';
+        $tabs['export']['args']['single_table'] = 'true';
+        $tabs['export']['text'] = __('Export');
+
+        /**
+         * Don't display "Import" and "Operations"
+         * for views and information_schema
+         */
+        if (! $tbl_is_view && ! $db_is_information_schema) {
+            $tabs['import']['icon'] = 'b_tblimport.png';
+            $tabs['import']['link'] = 'tbl_import.php';
+            $tabs['import']['text'] = __('Import');
+
+            $tabs['operation']['icon'] = 'b_tblops.png';
+            $tabs['operation']['link'] = 'tbl_operations.php';
+            $tabs['operation']['text'] = __('Operations');
+        }
+        if (PMA_Tracker::isActive()) {
+            $tabs['tracking']['icon'] = 'eye.png';
+            $tabs['tracking']['text'] = __('Tracking');
+            $tabs['tracking']['link'] = 'tbl_tracking.php';
+        }
+        if (! $db_is_information_schema
+            && ! PMA_DRIZZLE
+            && PMA_Util::currentUserHasPrivilege('TRIGGER', $this->_db, $this->_table)
+            && ! $tbl_is_view
+        ) {
+            $tabs['triggers']['link'] = 'tbl_triggers.php';
+            $tabs['triggers']['text'] = __('Triggers');
+            $tabs['triggers']['icon'] = 'b_triggers.png';
+        }
+
+        /**
+         * Views support a limited number of operations
+         */
+        if ($tbl_is_view && ! $db_is_information_schema) {
+            $tabs['operation']['icon'] = 'b_tblops.png';
+            $tabs['operation']['link'] = 'view_operations.php';
+            $tabs['operation']['text'] = __('Operations');
+        }
+
+        return $tabs;
+    }
+
+    /**
+     * Returns the db tabs as an array
+     *
+     * @return array Data for generating db tabs
+     */
+    private function _getDbTabs()
+    {
+        $db_is_information_schema = PMA_is_system_schema($this->_db);
+        $num_tables = count(PMA_DBI_get_tables($this->_db));
+        $is_superuser = PMA_isSuperuser();
+
+        /**
+         * Gets the relation settings
+         */
+        $cfgRelation = PMA_getRelationsParam();
+
+        $tabs = array();
+
+        $tabs['structure']['link'] = 'db_structure.php';
+        $tabs['structure']['text'] = __('Structure');
+        $tabs['structure']['icon'] = 'b_props.png';
+
+        $tabs['sql']['link'] = 'db_sql.php';
+        $tabs['sql']['args']['db_query_force'] = 1;
+        $tabs['sql']['text'] = __('SQL');
+        $tabs['sql']['icon'] = 'b_sql.png';
+
+        $tabs['search']['text'] = __('Search');
+        $tabs['search']['icon'] = 'b_search.png';
+        $tabs['search']['link'] = 'db_search.php';
+        if ($num_tables == 0) {
+            $tabs['search']['warning'] = __('Database seems to be empty!');
+        }
+
+        $tabs['qbe']['text'] = __('Query');
+        $tabs['qbe']['icon'] = 's_db.png';
+        $tabs['qbe']['link'] = 'db_qbe.php';
+        if ($num_tables == 0) {
+            $tabs['qbe']['warning'] = __('Database seems to be empty!');
+        }
+
+        $tabs['export']['text'] = __('Export');
+        $tabs['export']['icon'] = 'b_export.png';
+        $tabs['export']['link'] = 'db_export.php';
+        if ($num_tables == 0) {
+            $tabs['export']['warning'] = __('Database seems to be empty!');
+        }
+
+        if (! $db_is_information_schema) {
+            $tabs['import']['link'] = 'db_import.php';
+            $tabs['import']['text'] = __('Import');
+            $tabs['import']['icon'] = 'b_import.png';
+
+            $tabs['operation']['link'] = 'db_operations.php';
+            $tabs['operation']['text'] = __('Operations');
+            $tabs['operation']['icon'] = 'b_tblops.png';
+
+            if ($is_superuser && ! PMA_DRIZZLE) {
+                $tabs['privileges']['link'] = 'server_privileges.php';
+                $tabs['privileges']['args']['checkprivs'] = $this->_db;
+                // stay on database view
+                $tabs['privileges']['args']['viewing_mode'] = 'db';
+                $tabs['privileges']['text'] = __('Privileges');
+                $tabs['privileges']['icon'] = 's_rights.png';
+            }
+            if (! PMA_DRIZZLE) {
+                $tabs['routines']['link'] = 'db_routines.php';
+                $tabs['routines']['text'] = __('Routines');
+                $tabs['routines']['icon'] = 'b_routines.png';
+            }
+            if (PMA_MYSQL_INT_VERSION >= 50106
+                && ! PMA_DRIZZLE
+                && PMA_Util::currentUserHasPrivilege('EVENT', $this->_db)
+            ) {
+                $tabs['events']['link'] = 'db_events.php';
+                $tabs['events']['text'] = __('Events');
+                $tabs['events']['icon'] = 'b_events.png';
+            }
+            if (! PMA_DRIZZLE
+                && PMA_Util::currentUserHasPrivilege('TRIGGER', $this->_db)
+            ) {
+                $tabs['triggers']['link'] = 'db_triggers.php';
+                $tabs['triggers']['text'] = __('Triggers');
+                $tabs['triggers']['icon'] = 'b_triggers.png';
+            }
+        }
+
+        if (PMA_Tracker::isActive()) {
+            $tabs['tracking']['text'] = __('Tracking');
+            $tabs['tracking']['icon'] = 'eye.png';
+            $tabs['tracking']['link'] = 'db_tracking.php';
+        }
+
+        if (! $db_is_information_schema && $cfgRelation['designerwork']) {
+            $tabs['designer']['text'] = __('Designer');
+            $tabs['designer']['icon'] = 'b_relations.png';
+            $tabs['designer']['link'] = 'pmd_general.php';
+        }
+
+        return $tabs;
+    }
+
+    /**
+     * Returns the server tabs as an array
+     *
+     * @return array Data for generating server tabs
+     */
+    private function _getServerTabs()
+    {
+        $is_superuser = function_exists('PMA_isSuperuser') && PMA_isSuperuser();
+        $binary_logs = null;
+        if (function_exists('PMA_DBI_fetch_result')
+            && (! defined('PMA_DRIZZLE') 
+                || (defined('PMA_DRIZZLE') && ! PMA_DRIZZLE)
+            )
+        ) {
+            $binary_logs = PMA_DBI_fetch_result(
+                'SHOW MASTER LOGS',
+                'Log_name',
+                null,
+                null,
+                PMA_DBI_QUERY_STORE
+            );
+        }
+
+        $tabs = array();
+
+        $tabs['databases']['icon'] = 's_db.png';
+        $tabs['databases']['link'] = 'server_databases.php';
+        $tabs['databases']['text'] = __('Databases');
+
+        $tabs['sql']['icon'] = 'b_sql.png';
+        $tabs['sql']['link'] = 'server_sql.php';
+        $tabs['sql']['text'] = __('SQL');
+
+        $tabs['status']['icon'] = 's_status.png';
+        $tabs['status']['link'] = 'server_status.php';
+        $tabs['status']['text'] = __('Status');
+        $tabs['status']['active'] = in_array(
+            basename($GLOBALS['PMA_PHP_SELF']),
+            array(
+                'server_status.php',
+                'server_status_advisor.php',
+                'server_status_monitor.php',
+                'server_status_queries.php',
+                'server_status_variables.php'
+            )
+        );
+
+        if ($is_superuser && ! PMA_DRIZZLE) {
+            $tabs['rights']['icon'] = 's_rights.png';
+            $tabs['rights']['link'] = 'server_privileges.php';
+            $tabs['rights']['text'] = __('Users');
+        }
+
+        $tabs['export']['icon'] = 'b_export.png';
+        $tabs['export']['link'] = 'server_export.php';
+        $tabs['export']['text'] = __('Export');
+
+        $tabs['import']['icon'] = 'b_import.png';
+        $tabs['import']['link'] = 'server_import.php';
+        $tabs['import']['text'] = __('Import');
+
+        $tabs['settings']['icon']   = 'b_tblops.png';
+        $tabs['settings']['link']   = 'prefs_manage.php';
+        $tabs['settings']['text']   = __('Settings');
+        $tabs['settings']['active'] = in_array(
+            basename($GLOBALS['PMA_PHP_SELF']),
+            array('prefs_forms.php', 'prefs_manage.php')
+        );
+
+        if (! empty($binary_logs)) {
+            $tabs['binlog']['icon'] = 's_tbl.png';
+            $tabs['binlog']['link'] = 'server_binlog.php';
+            $tabs['binlog']['text'] = __('Binary log');
+        }
+
+        if ($is_superuser && ! PMA_DRIZZLE) {
+            $tabs['replication']['icon'] = 's_replication.png';
+            $tabs['replication']['link'] = 'server_replication.php';
+            $tabs['replication']['text'] = __('Replication');
+        }
+
+        $tabs['vars']['icon'] = 's_vars.png';
+        $tabs['vars']['link'] = 'server_variables.php';
+        $tabs['vars']['text'] = __('Variables');
+
+        $tabs['charset']['icon'] = 's_asci.png';
+        $tabs['charset']['link'] = 'server_collations.php';
+        $tabs['charset']['text'] = __('Charsets');
+
+        if (defined('PMA_DRIZZLE') && PMA_DRIZZLE) {
+            $tabs['plugins']['icon'] = 'b_engine.png';
+            $tabs['plugins']['link'] = 'server_plugins.php';
+            $tabs['plugins']['text'] = __('Plugins');
+        } else {
+            $tabs['engine']['icon'] = 'b_engine.png';
+            $tabs['engine']['link'] = 'server_engines.php';
+            $tabs['engine']['text'] = __('Engines');
+        }
+        return $tabs;
+    }
+}
+
+?>
diff --git a/phpmyadmin/libraries/Message.class.php b/phpmyadmin/libraries/Message.class.php
new file mode 100644
index 0000000..1f93ad2
--- /dev/null
+++ b/phpmyadmin/libraries/Message.class.php
@@ -0,0 +1,749 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * Holds class PMA_Message
+ *
+ * @package PhpMyAdmin
+ */
+
+/**
+ * a single message
+ *
+ * simple usage examples:
+ * <code>
+ * // display simple error message 'Error'
+ * PMA_Message::error()->display();
+ *
+ * // get simple success message 'Success'
+ * $message = PMA_Message::success();
+ *
+ * // get special notice 'Some locale notice'
+ * $message = PMA_Message::notice('strSomeLocaleNotice');
+ * </code>
+ *
+ * more advanced usage example:
+ * <code>
+ * // create a localized success message
+ * $message = PMA_Message::success('strSomeLocaleMessage');
+ *
+ * // create another message, a hint, with a localized string which expects
+ * // two parameters: $strSomeTooltip = 'Read the %smanual%s'
+ * $hint = PMA_Message::notice('strSomeTooltip');
+ * // replace %d with the following params
+ * $hint->addParam('[doc at cfg_Example]');
+ * $hint->addParam('[/doc]');
+ * // add this hint as a tooltip
+ * $hint = showHint($hint);
+ *
+ * // add the retrieved tooltip reference to the original message
+ * $message->addMessage($hint);
+ *
+ * // create another message ...
+ * $more = PMA_Message::notice('strSomeMoreLocale');
+ * $more->addString('strSomeEvenMoreLocale', '<br />');
+ * $more->addParam('parameter for strSomeMoreLocale');
+ * $more->addParam('more parameter for strSomeMoreLocale');
+ *
+ * // and add it also to the original message
+ * $message->addMessage($more);
+ * // finally add another raw message
+ * $message->addMessage('some final words', ' - ');
+ *
+ * // display() will now print all messages in the same order as they are added
+ * $message->display();
+ * // strSomeLocaleMessage <sup>1</sup> strSomeMoreLocale<br />
+ * // strSomeEvenMoreLocale - some final words
+ * </code>
+ *
+ * @package PhpMyAdmin
+ */
+class PMA_Message
+{
+    const SUCCESS = 1; // 0001
+    const NOTICE  = 2; // 0010
+    const ERROR   = 8; // 1000
+
+    const SANITIZE_NONE   = 0;  // 0000 0000
+    const SANITIZE_STRING = 16; // 0001 0000
+    const SANITIZE_PARAMS = 32; // 0010 0000
+    const SANITIZE_BOOTH  = 48; // 0011 0000
+
+    /**
+     * message levels
+     *
+     * @var array
+     */
+    static public $level = array (
+        PMA_Message::SUCCESS => 'success',
+        PMA_Message::NOTICE  => 'notice',
+        PMA_Message::ERROR   => 'error',
+    );
+
+    /**
+     * The message number
+     *
+     * @access  protected
+     * @var     integer
+     */
+    protected $number = PMA_Message::NOTICE;
+
+    /**
+     * The locale string identifier
+     *
+     * @access  protected
+     * @var     string
+     */
+    protected $string = '';
+
+    /**
+     * The formatted message
+     *
+     * @access  protected
+     * @var     string
+     */
+    protected $message = '';
+
+    /**
+     * Whether the message was already displayed
+     *
+     * @access  protected
+     * @var     boolean
+     */
+    protected $isDisplayed = false;
+
+    /**
+     * Unique id
+     *
+     * @access  protected
+     * @var string
+     */
+    protected $hash = null;
+
+    /**
+     * holds parameters
+     *
+     * @access  protected
+     * @var     array
+     */
+    protected $params = array();
+
+    /**
+     * holds additional messages
+     *
+     * @access  protected
+     * @var     array
+     */
+    protected $addedMessages = array();
+
+    /**
+     * Constructor
+     *
+     * @param string  $string   The message to be displayed
+     * @param integer $number   A numeric representation of the type of message
+     * @param array   $params   An array of parameters to use in the message
+     * @param integer $sanitize A flag to indicate what to sanitize, see
+     *                          constant definitions above
+     */
+    public function __construct($string = '', $number = PMA_Message::NOTICE,
+        $params = array(), $sanitize = PMA_Message::SANITIZE_NONE
+    ) {
+        $this->setString($string, $sanitize & PMA_Message::SANITIZE_STRING);
+        $this->setNumber($number);
+        $this->setParams($params, $sanitize & PMA_Message::SANITIZE_PARAMS);
+    }
+
+    /**
+     * magic method: return string representation for this object
+     *
+     * @return string
+     */
+    public function __toString()
+    {
+        return $this->getMessage();
+    }
+
+    /**
+     * get PMA_Message of type success
+     *
+     * shorthand for getting a simple success message
+     *
+     * @param string $string A localized string
+     *                       e.g. __('Your SQL query has been
+     *                       executed successfully')
+     *
+     * @return PMA_Message
+     * @static
+     */
+    static public function success($string = '')
+    {
+        if (empty($string)) {
+            $string = __('Your SQL query has been executed successfully');
+        }
+
+        return new PMA_Message($string, PMA_Message::SUCCESS);
+    }
+
+    /**
+     * get PMA_Message of type error
+     *
+     * shorthand for getting a simple error message
+     *
+     * @param string $string A localized string e.g. __('Error')
+     *
+     * @return PMA_Message
+     * @static
+     */
+    static public function error($string = '')
+    {
+        if (empty($string)) {
+            $string = __('Error');
+        }
+
+        return new PMA_Message($string, PMA_Message::ERROR);
+    }
+
+    /**
+     * get PMA_Message of type notice
+     *
+     * shorthand for getting a simple notice message
+     *
+     * @param string $string A localized string
+     *                       e.g. __('The additional features for working with
+     *                       linked tables have been deactivated. To find out
+     *                       why click %shere%s.')
+     *
+     * @return PMA_Message
+     * @static
+     */
+    static public function notice($string)
+    {
+        return new PMA_Message($string, PMA_Message::NOTICE);
+    }
+
+    /**
+     * get PMA_Message with customized content
+     *
+     * shorthand for getting a customized message
+     *
+     * @param string  $message A localized string
+     * @param integer $type    A numeric representation of the type of message
+     *
+     * @return PMA_Message
+     * @static
+     */
+    static public function raw($message, $type = PMA_Message::NOTICE)
+    {
+        $r = new PMA_Message('', $type);
+        $r->setMessage($message);
+        return $r;
+    }
+
+    /**
+     * get PMA_Message for number of affected rows
+     *
+     * shorthand for getting a customized message
+     *
+     * @param integer $rows Number of rows
+     *
+     * @return PMA_Message
+     * @static
+     */
+    static public function getMessageForAffectedRows($rows)
+    {
+        $message = PMA_Message::success(
+            _ngettext('%1$d row affected.', '%1$d rows affected.', $rows)
+        );
+        $message->addParam($rows);
+        return $message;
+    }
+
+    /**
+     * get PMA_Message for number of deleted rows
+     *
+     * shorthand for getting a customized message
+     *
+     * @param integer $rows Number of rows
+     *
+     * @return PMA_Message
+     * @static
+     */
+    static public function getMessageForDeletedRows($rows)
+    {
+        $message = PMA_Message::success(
+            _ngettext('%1$d row deleted.', '%1$d rows deleted.', $rows)
+        );
+        $message->addParam($rows);
+        return $message;
+    }
+
+    /**
+     * get PMA_Message for number of inserted rows
+     *
+     * shorthand for getting a customized message
+     *
+     * @param integer $rows Number of rows
+     *
+     * @return PMA_Message
+     * @static
+     */
+    static public function getMessageForInsertedRows($rows)
+    {
+        $message = PMA_Message::success(
+            _ngettext('%1$d row inserted.', '%1$d rows inserted.', $rows)
+        );
+        $message->addParam($rows);
+        return $message;
+    }
+
+    /**
+     * get PMA_Message of type error with custom content
+     *
+     * shorthand for getting a customized error message
+     *
+     * @param string $message A localized string
+     *
+     * @return PMA_Message
+     * @static
+     */
+    static public function rawError($message)
+    {
+        return PMA_Message::raw($message, PMA_Message::ERROR);
+    }
+
+    /**
+     * get PMA_Message of type notice with custom content
+     *
+     * shorthand for getting a customized notice message
+     *
+     * @param string $message A localized string
+     *
+     * @return PMA_Message
+     * @static
+     */
+    static public function rawNotice($message)
+    {
+        return PMA_Message::raw($message, PMA_Message::NOTICE);
+    }
+
+    /**
+     * get PMA_Message of type success with custom content
+     *
+     * shorthand for getting a customized success message
+     *
+     * @param string $message A localized string
+     *
+     * @return PMA_Message
+     * @static
+     */
+    static public function rawSuccess($message)
+    {
+        return PMA_Message::raw($message, PMA_Message::SUCCESS);
+    }
+
+    /**
+     * returns whether this message is a success message or not
+     * and optionaly makes this message a success message
+     *
+     * @param boolean $set Whether to make this message of SUCCESS type
+     *
+     * @return boolean whether this is a success message or not
+     */
+    public function isSuccess($set = false)
+    {
+        if ($set) {
+            $this->setNumber(PMA_Message::SUCCESS);
+        }
+
+        return $this->getNumber() === PMA_Message::SUCCESS;
+    }
+
+    /**
+     * returns whether this message is a notice message or not
+     * and optionally makes this message a notice message
+     *
+     * @param boolean $set Whether to make this message of NOTICE type
+     *
+     * @return boolean whether this is a notice message or not
+     */
+    public function isNotice($set = false)
+    {
+        if ($set) {
+            $this->setNumber(PMA_Message::NOTICE);
+        }
+
+        return $this->getNumber() === PMA_Message::NOTICE;
+    }
+
+    /**
+     * returns whether this message is an error message or not
+     * and optionally makes this message an error message
+     *
+     * @param boolean $set Whether to make this message of ERROR type
+     *
+     * @return boolean Whether this is an error message or not
+     */
+    public function isError($set = false)
+    {
+        if ($set) {
+            $this->setNumber(PMA_Message::ERROR);
+        }
+
+        return $this->getNumber() === PMA_Message::ERROR;
+    }
+
+    /**
+     * set raw message (overrides string)
+     *
+     * @param string  $message  A localized string
+     * @param boolean $sanitize Whether to sanitize $message or not
+     *
+     * @return void
+     */
+    public function setMessage($message, $sanitize = false)
+    {
+        if ($sanitize) {
+            $message = PMA_Message::sanitize($message);
+        }
+        $this->message = $message;
+    }
+
+    /**
+     * set string (does not take effect if raw message is set)
+     *
+     * @param string  $string   string to set
+     * @param boolean $sanitize whether to sanitize $string or not
+     *
+     * @return void
+     */
+    public function setString($string, $sanitize = true)
+    {
+        if ($sanitize) {
+            $string = PMA_Message::sanitize($string);
+        }
+        $this->string = $string;
+    }
+
+    /**
+     * set message type number
+     *
+     * @param integer $number message type number to set
+     *
+     * @return void
+     */
+    public function setNumber($number)
+    {
+        $this->number = $number;
+    }
+
+    /**
+     * add parameter, usually in conjunction with strings
+     *
+     * usage
+     * <code>
+     * $message->addParam('strLocale', false);
+     * $message->addParam('[em]some string[/em]');
+     * $message->addParam('<img src="img" />', false);
+     * </code>
+     *
+     * @param mixed   $param parameter to add
+     * @param boolean $raw   whether parameter should be passed as is
+     *                       without html escaping
+     *
+     * @return void
+     */
+    public function addParam($param, $raw = true)
+    {
+        if ($param instanceof PMA_Message) {
+            $this->params[] = $param;
+        } elseif ($raw) {
+            $this->params[] = htmlspecialchars($param);
+        } else {
+            $this->params[] = PMA_Message::notice($param);
+        }
+    }
+
+    /**
+     * add another string to be concatenated on displaying
+     *
+     * @param string $string    to be added
+     * @param string $separator to use between this and previous string/message
+     *
+     * @return void
+     */
+    public function addString($string, $separator = ' ')
+    {
+        $this->addedMessages[] = $separator;
+        $this->addedMessages[] = PMA_Message::notice($string);
+    }
+
+    /**
+     * add a bunch of messages at once
+     *
+     * @param array  $messages  to be added
+     * @param string $separator to use between this and previous string/message
+     *
+     * @return void
+     */
+    public function addMessages($messages, $separator = ' ')
+    {
+        foreach ($messages as $message) {
+            $this->addMessage($message, $separator);
+        }
+    }
+
+    /**
+     * add another raw message to be concatenated on displaying
+     *
+     * @param mixed  $message   to be added
+     * @param string $separator to use between this and previous string/message
+     *
+     * @return void
+     */
+    public function addMessage($message, $separator = ' ')
+    {
+        if (strlen($separator)) {
+            $this->addedMessages[] = $separator;
+        }
+
+        if ($message instanceof PMA_Message) {
+            $this->addedMessages[] = $message;
+        } else {
+            $this->addedMessages[] = PMA_Message::rawNotice($message);
+        }
+    }
+
+    /**
+     * set all params at once, usually used in conjunction with string
+     *
+     * @param array   $params   parameters to set
+     * @param boolean $sanitize whether to sanitize params
+     *
+     * @return void
+     */
+    public function setParams($params, $sanitize = false)
+    {
+        if ($sanitize) {
+            $params = PMA_Message::sanitize($params);
+        }
+        $this->params = $params;
+    }
+
+    /**
+     * return all parameters
+     *
+     * @return array
+     */
+    public function getParams()
+    {
+        return $this->params;
+    }
+
+    /**
+     * return all added messages
+     *
+     * @return array
+     */
+    public function getAddedMessages()
+    {
+        return $this->addedMessages;
+    }
+
+    /**
+     * Sanitizes $message
+     *
+     * @param mixed $message the message(s)
+     *
+     * @return mixed  the sanitized message(s)
+     * @access  public
+     * @static
+     */
+    static public function sanitize($message)
+    {
+        if (is_array($message)) {
+            foreach ($message as $key => $val) {
+                $message[$key] = PMA_Message::sanitize($val);
+            }
+
+            return $message;
+        }
+
+        return htmlspecialchars($message);
+    }
+
+    /**
+     * decode $message, taking into account our special codes
+     * for formatting
+     *
+     * @param string $message the message
+     *
+     * @return string  the decoded message
+     * @access  public
+     * @static
+     */
+    static public function decodeBB($message)
+    {
+        return PMA_sanitize($message, false, true);
+    }
+
+    /**
+     * wrapper for sprintf()
+     *
+     * @return string formatted
+     */
+    static public function format()
+    {
+        $params = func_get_args();
+        if (isset($params[1]) && is_array($params[1])) {
+            array_unshift($params[1], $params[0]);
+            $params = $params[1];
+        }
+
+        return call_user_func_array('sprintf', $params);
+    }
+
+    /**
+     * returns unique PMA_Message::$hash, if not exists it will be created
+     *
+     * @return string PMA_Message::$hash
+     */
+    public function getHash()
+    {
+        if (null === $this->hash) {
+            $this->hash = md5(
+                $this->getNumber() .
+                $this->string .
+                $this->message
+            );
+        }
+
+        return $this->hash;
+    }
+
+    /**
+     * returns compiled message
+     *
+     * @return string complete message
+     */
+    public function getMessage()
+    {
+        $message = $this->message;
+
+        if (0 === strlen($message)) {
+            $string = $this->getString();
+            if (isset($GLOBALS[$string])) {
+                $message = $GLOBALS[$string];
+            } elseif (0 === strlen($string)) {
+                $message = '';
+            } else {
+                $message = $string;
+            }
+        }
+
+        if ($this->isDisplayed()) {
+            $message = $this->getMessageWithIcon($message);
+        }
+        if (count($this->getParams()) > 0) {
+            $message = PMA_Message::format($message, $this->getParams());
+        }
+
+        $message = PMA_Message::decodeBB($message);
+
+        foreach ($this->getAddedMessages() as $add_message) {
+            $message .= $add_message;
+        }
+
+        return $message;
+    }
+
+    /**
+     * returns PMA_Message::$string
+     *
+     * @return string PMA_Message::$string
+     */
+    public function getString()
+    {
+        return $this->string;
+    }
+
+    /**
+     * returns PMA_Message::$number
+     *
+     * @return integer PMA_Message::$number
+     */
+    public function getNumber()
+    {
+        return $this->number;
+    }
+
+    /**
+     * returns level of message
+     *
+     * @return string  level of message
+     */
+    public function getLevel()
+    {
+        return PMA_Message::$level[$this->getNumber()];
+    }
+
+    /**
+     * Displays the message in HTML
+     *
+     * @return void
+     */
+    public function display()
+    {
+        echo $this->getDisplay();
+        $this->isDisplayed(true);
+    }
+
+    /**
+     * returns HTML code for displaying this message
+     *
+     * @return string whole message box
+     */
+    public function getDisplay()
+    {
+        $this->isDisplayed(true);
+        return '<div class="' . $this->getLevel() . '">'
+            . $this->getMessage() . '</div>';
+    }
+
+    /**
+     * sets and returns whether the message was displayed or not
+     *
+     * @param boolean $isDisplayed whether to set displayed flag
+     *
+     * @return boolean PMA_Message::$isDisplayed
+     */
+    public function isDisplayed($isDisplayed = false)
+    {
+        if ($isDisplayed) {
+            $this->isDisplayed = true;
+        }
+
+        return $this->isDisplayed;
+    }
+    
+    /**
+     * Returns the message with corresponding image icon
+     * 
+     * @param string $message the message(s)
+     * 
+     * @return string message with icon
+     */
+    public function getMessageWithIcon($message)
+    {
+        $image = '';
+        if ('error' == $this->getLevel()) {
+            $image = 's_error.png';
+        } elseif ('success' == $this->getLevel()) {
+            $image = 's_success.png';
+        } else {
+            $image = 's_notice.png';
+        }
+        $message = PMA_Message::notice(PMA_Util::getImage($image)) . " " . $message;
+        return $message;
+        
+    }
+}
+?>
diff --git a/phpmyadmin/libraries/OutputBuffering.class.php b/phpmyadmin/libraries/OutputBuffering.class.php
new file mode 100644
index 0000000..1ef7643
--- /dev/null
+++ b/phpmyadmin/libraries/OutputBuffering.class.php
@@ -0,0 +1,148 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * Output buffering wrapper
+ *
+ * @package PhpMyAdmin
+ */
+if (! defined('PHPMYADMIN')) {
+    exit;
+}
+
+/**
+ * Output buffering wrapper class
+ *
+ * @package PhpMyAdmin
+ */
+class PMA_OutputBuffering
+{
+    private static $_instance;
+    private $_mode;
+    private $_content;
+    private $_on;
+
+    /**
+     * Initializes class
+     *
+     * @return void
+     */
+    private function __construct()
+    {
+        $this->_mode = $this->_getMode();
+        $this->_on = false;
+    }
+
+    /**
+     * This function could be used eventually to support more modes.
+     *
+     * @return integer  the output buffer mode
+     */
+    private function _getMode()
+    {
+        $mode = 0;
+        if ($GLOBALS['cfg']['OBGzip'] && function_exists('ob_start')) {
+            if (ini_get('output_handler') == 'ob_gzhandler') {
+                // If a user sets the output_handler in php.ini to ob_gzhandler, then
+                // any right frame file in phpMyAdmin will not be handled properly by
+                // the browser. My fix was to check the ini file within the
+                // PMA_outBufferModeGet() function.
+                $mode = 0;
+            } elseif (function_exists('ob_get_level') && ob_get_level() > 0) {
+                // If output buffering is enabled in php.ini it's not possible to
+                // add the ob_gzhandler without a warning message from php 4.3.0.
+                // Being better safe than sorry, check for any existing output handler
+                // instead of just checking the 'output_buffering' setting.
+                $mode = 0;
+            } else {
+                $mode = 1;
+            }
+        }
+        // Zero (0) is no mode or in other words output buffering is OFF.
+        // Follow 2^0, 2^1, 2^2, 2^3 type values for the modes.
+        // Usefull if we ever decide to combine modes.  Then a bitmask field of
+        // the sum of all modes will be the natural choice.
+        return $mode;
+    }
+
+    /**
+     * Returns the singleton PMA_OutputBuffering object
+     *
+     * @return PMA_OutputBuffering object
+     */
+    public static function getInstance()
+    {
+        if (empty(self::$_instance)) {
+            self::$_instance = new PMA_OutputBuffering();
+        }
+        return self::$_instance;
+    }
+
+    /**
+     * This function will need to run at the top of all pages if output
+     * output buffering is turned on.  It also needs to be passed $mode from
+     * the PMA_outBufferModeGet() function or it will be useless.
+     *
+     * @return void
+     */
+    public function start()
+    {
+        if (! $this->_on) {
+            if ($this->_mode) {
+                ob_start('ob_gzhandler');
+            }
+            ob_start();
+            if (! defined('TESTSUITE')) {
+                header('X-ob_mode: ' . $this->_mode);
+            }
+            register_shutdown_function('PMA_OutputBuffering::stop');
+            $this->_on = true;
+        }
+    }
+
+    /**
+     * This function will need to run at the bottom of all pages if output
+     * buffering is turned on.  It also needs to be passed $mode from the
+     * PMA_outBufferModeGet() function or it will be useless.
+     *
+     * @return void
+     */
+    public static function stop()
+    {
+        $buffer = PMA_OutputBuffering::getInstance();
+        if ($buffer->_on) {
+            $buffer->_on = false;
+            $buffer->_content = ob_get_contents();
+            ob_end_clean();
+        }
+        PMA_Response::response();
+    }
+
+    /**
+     * Gets buffer content
+     *
+     * @return buffer content
+     */
+    public function getContents()
+    {
+        return $this->_content;
+    }
+
+    /**
+     * Flushes output buffer
+     *
+     * @return void
+     */
+    public function flush()
+    {
+        if (ob_get_status() && $this->_mode) {
+            ob_flush();
+        }
+        /**
+         * previously we had here an "else flush()" but some PHP versions
+         * (at least PHP 5.2.11) have a bug (49816) that produces garbled
+         * data
+         */
+    }
+}
+
+?>
diff --git a/phpmyadmin/libraries/PDF.class.php b/phpmyadmin/libraries/PDF.class.php
new file mode 100644
index 0000000..fa4b48a
--- /dev/null
+++ b/phpmyadmin/libraries/PDF.class.php
@@ -0,0 +1,143 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * TCPDF wrapper class.
+ *
+ * @package PhpMyAdmin
+ */
+if (! defined('PHPMYADMIN')) {
+    exit;
+}
+
+require_once TCPDF_INC;
+
+/**
+ * PDF font to use.
+ */
+define('PMA_PDF_FONT', 'DejaVuSans');
+
+/**
+ * PDF export base class providing basic configuration.
+ *
+ * @package PhpMyAdmin
+ */
+class PMA_PDF extends TCPDF
+{
+    var $footerset;
+    var $Alias = array();
+
+    /**
+     * Constructs PDF and configures standard parameters.
+     *
+     * @param string  $orientation page orientation
+     * @param string  $unit        unit
+     * @param mixed   $format      the format used for pages
+     * @param boolean $unicode     true means that the input text is unicode
+     * @param string  $encoding    charset encoding; default is UTF-8.
+     * @param boolean $diskcache   if true reduce the RAM memory usage by caching
+     *                             temporary data on filesystem (slower).
+     *
+     * @return void
+     * @access public
+     */
+    public function __construct($orientation = 'P', $unit = 'mm', $format = 'A4',
+        $unicode = true, $encoding = 'UTF-8', $diskcache = false
+    ) {
+        parent::__construct();
+        $this->SetAuthor('phpMyAdmin ' . PMA_VERSION);
+        $this->AddFont('DejaVuSans', '', 'dejavusans.php');
+        $this->AddFont('DejaVuSans', 'B', 'dejavusansb.php');
+        $this->SetFont(PMA_PDF_FONT, '', 14);
+        $this->setFooterFont(array(PMA_PDF_FONT, '', 14));
+    }
+
+    /**
+     * This function must be named "Footer" to work with the TCPDF library
+     *
+     * @return void
+     */
+    function Footer()
+    {
+        // Check if footer for this page already exists
+        if (!isset($this->footerset[$this->page])) {
+            $this->SetY(-15);
+            $this->SetFont(PMA_PDF_FONT, '', 14);
+            $this->Cell(0, 6, __('Page number:') . ' ' . $this->getAliasNumPage() . '/' .  $this->getAliasNbPages(), 'T', 0, 'C');
+            $this->Cell(0, 6, PMA_Util::localisedDate(), 0, 1, 'R');
+            $this->SetY(20);
+
+            // set footerset
+            $this->footerset[$this->page] = 1;
+        }
+    }
+
+    /**
+     * Function to test an empty string (was in tcpdf < 6.0)
+     *
+     * @param string $str to test
+     *
+     * @return boolean
+     */
+    public function empty_string($str) {
+            return (is_null($str) OR (is_string($str) AND (strlen($str) == 0)));
+    }
+
+    /**
+     * Function to set alias which will be expanded on page rendering.
+     *
+     * @param string $name  name of the alias
+     * @param string $value value of the alias
+     *
+     * @return void
+     */
+    function SetAlias($name, $value)
+    {
+        $this->Alias[$this->UTF8ToUTF16BE($name)] = $this->UTF8ToUTF16BE($value);
+    }
+
+    /**
+     * Improved with alias expading.
+     *
+     * @return void
+     */
+    function _putpages()
+    {
+        if (count($this->Alias) > 0) {
+            $nb = count($this->pages);
+            for ($n = 1;$n <= $nb;$n++) {
+                $this->pages[$n] = strtr($this->pages[$n], $this->Alias);
+            }
+        }
+        parent::_putpages();
+    }
+
+    /**
+     * Displays an error message
+     *
+     * @param string $error_message the error mesage
+     *
+     * @return void
+     */
+    function Error($error_message = '')
+    {
+        PMA_Message::error(
+            __('Error while creating PDF:') . ' ' . $error_message
+        )->display();
+        exit;
+    }
+
+    /**
+     * Sends file as a download to user.
+     *
+     * @param string $filename file name
+     *
+     * @return void
+     */
+    function Download($filename)
+    {
+        $pdfData = $this->getPDFData();
+        PMA_Response::getInstance()->disable();
+        PMA_downloadHeader($filename, 'application/pdf', strlen($pdfData));
+        echo $pdfData;
+    }
+}
diff --git a/phpmyadmin/libraries/PMA.php b/phpmyadmin/libraries/PMA.php
new file mode 100644
index 0000000..0d0c39e
--- /dev/null
+++ b/phpmyadmin/libraries/PMA.php
@@ -0,0 +1,106 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * phpMyAdmin main Controller
+ *
+ * @package PhpMyAdmin
+ *
+ */
+
+/**
+ * Database listing.
+ */
+require_once './libraries/List_Database.class.php';
+
+/**
+ * phpMyAdmin main Controller
+ *
+ * @package PhpMyAdmin
+ */
+class PMA
+{
+    /**
+     * Holds database list
+     *
+     * @var PMA_List_Database
+     */
+    protected $databases = null;
+
+    /**
+     * DBMS user link
+     *
+     * @var resource
+     */
+    protected $userlink = null;
+
+    /**
+     * DBMS control link
+     *
+     * @var resource
+     */
+    protected $controllink = null;
+
+    /**
+     * magic access to protected/inaccessible members/properties
+     *
+     * @param string $param parameter name
+     *
+     * @return mixed
+     * @see http://php.net/language.oop5.overloading
+     */
+    public function __get($param)
+    {
+        switch ($param) {
+        case 'databases' :
+            return $this->getDatabaseList();
+            break;
+        case 'userlink' :
+            return $this->userlink;
+            break;
+        case 'controllink' :
+            return $this->controllink;
+            break;
+        }
+
+        return null;
+    }
+
+    /**
+     * magic access to protected/inaccessible members/properties
+     *
+     * @param string $param parameter name
+     * @param mixed  $value value to set
+     *
+     * @return void
+     * @see http://php.net/language.oop5.overloading
+     */
+    public function __set($param, $value)
+    {
+        switch ($param) {
+        case 'userlink' :
+            $this->userlink = $value;
+            break;
+        case 'controllink' :
+            $this->controllink = $value;
+            break;
+        }
+    }
+
+    /**
+     * Accessor to PMA::$databases
+     *
+     * @return PMA_List_Databases
+     */
+    public function getDatabaseList()
+    {
+        if (null === $this->databases) {
+            $this->databases = new PMA_List_Database(
+                $this->userlink,
+                $this->controllink
+            );
+        }
+
+        return $this->databases;
+    }
+}
+?>
diff --git a/phpmyadmin/libraries/Partition.class.php b/phpmyadmin/libraries/Partition.class.php
new file mode 100644
index 0000000..72137f8
--- /dev/null
+++ b/phpmyadmin/libraries/Partition.class.php
@@ -0,0 +1,79 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * Library for extracting information about the partitions
+ *
+ * @package PhpMyAdmin
+ */
+if (! defined('PHPMYADMIN')) {
+    exit;
+}
+
+/**
+ * base Partition Class
+ *
+ * @package PhpMyAdmin
+ */
+class PMA_Partition
+{
+    /**
+     * returns array of partition names for a specific db/table
+     *
+     * @param string $db    database name
+     * @param string $table table name
+     *
+     * @access  public
+     * @return array   of partition names
+     */
+    static public function getPartitionNames($db, $table)
+    {
+        if (PMA_Partition::havePartitioning()) {
+            return PMA_DBI_fetch_result(
+                "SELECT `PARTITION_NAME` FROM `information_schema`.`PARTITIONS`"
+                . " WHERE `TABLE_SCHEMA` = '" . $db
+                . "' AND `TABLE_NAME` = '" . $table . "'"
+            );
+        } else {
+            return array();
+        }
+    }
+
+    /**
+     * checks if MySQL server supports partitioning
+     *
+     * @static
+     * @staticvar boolean $have_partitioning
+     * @staticvar boolean $already_checked
+     * @access  public
+     * @return boolean
+     */
+    static public function havePartitioning()
+    {
+        static $have_partitioning = false;
+        static $already_checked = false;
+
+        if (! $already_checked) {
+            if (PMA_MYSQL_INT_VERSION >= 50100) {
+                if (PMA_MYSQL_INT_VERSION < 50600) {
+                    if (PMA_DBI_fetch_value(
+                        "SHOW VARIABLES LIKE 'have_partitioning';"
+                    )) {
+                        $have_partitioning = true;
+                    }
+                } else {
+                    // see http://dev.mysql.com/doc/refman/5.6/en/partitioning.html
+                    $plugins = PMA_DBI_fetch_result("SHOW PLUGINS");
+                    foreach ($plugins as $value) {
+                        if ($value['Name'] == 'partition') {
+                            $have_partitioning = true;
+                            break;
+                        }
+                    }
+                }
+                $already_checked = true;
+            }
+        }
+        return $have_partitioning;
+    }
+}
+?>
diff --git a/phpmyadmin/libraries/RecentTable.class.php b/phpmyadmin/libraries/RecentTable.class.php
new file mode 100644
index 0000000..9468eeb
--- /dev/null
+++ b/phpmyadmin/libraries/RecentTable.class.php
@@ -0,0 +1,210 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ *
+ * @package PhpMyAdmin
+ */
+if (! defined('PHPMYADMIN')) {
+    exit;
+}
+
+require_once './libraries/Message.class.php';
+
+/**
+ * Handles the recently used tables.
+ *
+ * @TODO Change the release version in table pma_recent
+ * (#recent in documentation)
+ *
+ * @package PhpMyAdmin
+ */
+class PMA_RecentTable
+{
+    /**
+     * Defines the internal PMA table which contains recent tables.
+     *
+     * @access  private
+     * @var string
+     */
+    private $_pmaTable;
+
+    /**
+     * Reference to session variable containing recently used tables.
+     *
+     * @access public
+     * @var array
+     */
+    public $tables;
+
+    /**
+     * PMA_RecentTable instance.
+     *
+     * @var PMA_RecentTable
+     */
+    private static $_instance;
+
+    public function __construct()
+    {
+        if (strlen($GLOBALS['cfg']['Server']['pmadb'])
+            && strlen($GLOBALS['cfg']['Server']['recent'])
+        ) {
+            $this->_pmaTable
+                = PMA_Util::backquote($GLOBALS['cfg']['Server']['pmadb']) . "."
+                . PMA_Util::backquote($GLOBALS['cfg']['Server']['recent']);
+        }
+        $server_id = $GLOBALS['server'];
+        if (! isset($_SESSION['tmp_user_values']['recent_tables'][$server_id])) {
+            $_SESSION['tmp_user_values']['recent_tables'][$server_id]
+                = isset($this->_pmaTable) ? $this->getFromDb() : array();
+        }
+        $this->tables =& $_SESSION['tmp_user_values']['recent_tables'][$server_id];
+    }
+
+    /**
+     * Returns class instance.
+     *
+     * @return PMA_RecentTable
+     */
+    public static function getInstance()
+    {
+        if (is_null(self::$_instance)) {
+            self::$_instance = new PMA_RecentTable();
+        }
+        return self::$_instance;
+    }
+
+    /**
+     * Returns recently used tables from phpMyAdmin database.
+     *
+     * @return array
+     */
+    public function getFromDb()
+    {
+        // Read from phpMyAdmin database, if recent tables is not in session
+        $sql_query
+            = " SELECT `tables` FROM " . $this->_pmaTable .
+            " WHERE `username` = '" . $GLOBALS['cfg']['Server']['user'] . "'";
+
+        $row = PMA_DBI_fetch_array(PMA_queryAsControlUser($sql_query));
+        if (isset($row[0])) {
+            return json_decode($row[0], true);
+        } else {
+            return array();
+        }
+    }
+
+    /**
+     * Save recent tables into phpMyAdmin database.
+     *
+     * @return true|PMA_Message
+     */
+    public function saveToDb()
+    {
+        $username = $GLOBALS['cfg']['Server']['user'];
+        $sql_query
+            = " REPLACE INTO " . $this->_pmaTable . " (`username`, `tables`)" .
+                " VALUES ('" . $username . "', '"
+                . PMA_Util::sqlAddSlashes(
+                    json_encode($this->tables)
+                ) . "')";
+
+        $success = PMA_DBI_try_query($sql_query, $GLOBALS['controllink']);
+
+        if (! $success) {
+            $message = PMA_Message::error(__('Could not save recent table'));
+            $message->addMessage('<br /><br />');
+            $message->addMessage(
+                PMA_Message::rawError(PMA_DBI_getError($GLOBALS['controllink']))
+            );
+            return $message;
+        }
+        return true;
+    }
+
+    /**
+     * Trim recent table according to the NumRecentTables configuration.
+     *
+     * @return boolean True if trimming occurred
+     */
+    public function trim()
+    {
+        $max = max($GLOBALS['cfg']['NumRecentTables'], 0);
+        $trimming_occured = count($this->tables) > $max;
+        while (count($this->tables) > $max) {
+            array_pop($this->tables);
+        }
+        return $trimming_occured;
+    }
+
+    /**
+     * Return options for HTML select.
+     *
+     * @return string
+     */
+    public function getHtmlSelectOption()
+    {
+        // trim and save, in case where the configuration is changed
+        if ($this->trim() && isset($this->_pmaTable)) {
+            $this->saveToDb();
+        }
+
+        $html = '<option value="">(' . __('Recent tables') . ') ...</option>';
+        if (count($this->tables)) {
+            foreach ($this->tables as $table) {
+                $html .= '<option value="'
+                    . htmlspecialchars(json_encode($table)) . '">'
+                    . htmlspecialchars(
+                        '`' . $table['db'] . '`.`' . $table['table'] . '`'
+                    )
+                    . '</option>';
+            }
+        } else {
+            $html .= '<option value="">'
+                . __('There are no recent tables')
+                . '</option>';
+        }
+        return $html;
+    }
+
+    /**
+     * Return HTML select.
+     *
+     * @return string
+     */
+    public function getHtmlSelect()
+    {
+        $html  = '<select name="selected_recent_table" id="recentTable">';
+        $html .= $this->getHtmlSelectOption();
+        $html .= '</select>';
+
+        return $html;
+    }
+
+    /**
+     * Add recently used tables.
+     *
+     * @param string $db    database name where the table is located
+     * @param string $table table name
+     *
+     * @return true|PMA_Message True if success, PMA_Message if not
+     */
+    public function add($db, $table)
+    {
+        $table_arr = array();
+        $table_arr['db'] = $db;
+        $table_arr['table'] = $table;
+
+        // add only if this is new table
+        if (! isset($this->tables[0]) || $this->tables[0] != $table_arr) {
+            array_unshift($this->tables, $table_arr);
+            $this->tables = array_merge(array_unique($this->tables, SORT_REGULAR));
+            $this->trim();
+            if (isset($this->_pmaTable)) {
+                return $this->saveToDb();
+            }
+        }
+        return true;
+    }
+
+}
+?>
diff --git a/phpmyadmin/libraries/Response.class.php b/phpmyadmin/libraries/Response.class.php
new file mode 100644
index 0000000..1bc1832
--- /dev/null
+++ b/phpmyadmin/libraries/Response.class.php
@@ -0,0 +1,377 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * Manages the rendering of pages in PMA
+ *
+ * @package PhpMyAdmin
+ */
+if (! defined('PHPMYADMIN')) {
+    exit;
+}
+
+require_once 'libraries/OutputBuffering.class.php';
+require_once 'libraries/Header.class.php';
+require_once 'libraries/Footer.class.php';
+
+/**
+ * Singleton class used to manage the rendering of pages in PMA
+ *
+ * @package PhpMyAdmin
+ */
+class PMA_Response
+{
+    /**
+     * PMA_Response instance
+     *
+     * @access private
+     * @static
+     * @var object
+     */
+    private static $_instance;
+    /**
+     * PMA_Header instance
+     *
+     * @access private
+     * @var object
+     */
+    private $_header;
+    /**
+     * HTML data to be used in the response
+     *
+     * @access private
+     * @var string
+     */
+    private $_HTML;
+    /**
+     * An array of JSON key-value pairs
+     * to be sent back for ajax requests
+     *
+     * @access private
+     * @var array
+     */
+    private $_JSON;
+    /**
+     * PMA_Footer instance
+     *
+     * @access private
+     * @var object
+     */
+    private $_footer;
+    /**
+     * Whether we are servicing an ajax request.
+     * We can't simply use $GLOBALS['is_ajax_request']
+     * here since it may have not been initialised yet.
+     *
+     * @access private
+     * @var bool
+     */
+    private $_isAjax;
+    /**
+     * Whether we are servicing an ajax request for a page
+     * that was fired using the generic page handler in JS.
+     *
+     * @access private
+     * @var bool
+     */
+    private $_isAjaxPage;
+    /**
+     * Whether there were any errors druing the processing of the request
+     * Only used for ajax responses
+     *
+     * @access private
+     * @var bool
+     */
+    private $_isSuccess;
+    /**
+     * Workaround for PHP bug
+     *
+     * @access private
+     * @var bool
+     */
+    private $_CWD;
+
+    /**
+     * Creates a new class instance
+     *
+     * @return new PMA_Response object
+     */
+    private function __construct()
+    {
+        if (! defined('TESTSUITE')) {
+            $buffer = PMA_OutputBuffering::getInstance();
+            $buffer->start();
+        }
+        $this->_header = new PMA_Header();
+        $this->_HTML   = '';
+        $this->_JSON   = array();
+        $this->_footer = new PMA_Footer();
+
+        $this->_isSuccess  = true;
+        $this->_isAjax     = false;
+        $this->_isAjaxPage = false;
+        if (isset($_REQUEST['ajax_request']) && $_REQUEST['ajax_request'] == true) {
+            $this->_isAjax = true;
+        }
+        if (isset($_REQUEST['ajax_page_request'])
+            && $_REQUEST['ajax_page_request'] == true
+        ) {
+            $this->_isAjaxPage = true;
+        }
+        $this->_header->setAjax($this->_isAjax);
+        $this->_footer->setAjax($this->_isAjax);
+        $this->_CWD = getcwd();
+    }
+
+    /**
+     * Returns the singleton PMA_Response object
+     *
+     * @return PMA_Response object
+     */
+    public static function getInstance()
+    {
+        if (empty(self::$_instance)) {
+            self::$_instance = new PMA_Response();
+        }
+        return self::$_instance;
+    }
+
+    /**
+     * Set the status of an ajax response,
+     * whether it is a success or an error
+     *
+     * @param bool $state Whether the request was successfully processed
+     *
+     * @return void
+     */
+    public function isSuccess($state)
+    {
+        $this->_isSuccess = ($state == true);
+    }
+
+    /**
+     * Returns true or false depending on whether
+     * we are servicing an ajax request
+     *
+     * @return bool
+     */
+    public function isAjax()
+    {
+        return $this->_isAjax;
+    }
+
+    /**
+     * Returns the path to the current working directory
+     * Necessary to work around a PHP bug where the CWD is
+     * reset after the initial script exits
+     *
+     * @return string
+     */
+    public function getCWD()
+    {
+        return $this->_CWD;
+    }
+
+    /**
+     * Disables the rendering of the header
+     * and the footer in responses
+     *
+     * @return void
+     */
+    public function disable()
+    {
+        $this->_header->disable();
+        $this->_footer->disable();
+    }
+
+    /**
+     * Returns a PMA_Header object
+     *
+     * @return object
+     */
+    public function getHeader()
+    {
+        return $this->_header;
+    }
+
+    /**
+     * Returns a PMA_Footer object
+     *
+     * @return object
+     */
+    public function getFooter()
+    {
+        return $this->_footer;
+    }
+
+    /**
+     * Add HTML code to the response
+     *
+     * @param string $content A string to be appended to
+     *                        the current output buffer
+     *
+     * @return void
+     */
+    public function addHTML($content)
+    {
+        if ($content instanceof PMA_Message) {
+            $this->_HTML .= $content->getDisplay();
+        } else {
+            $this->_HTML .= $content;
+        }
+    }
+
+    /**
+     * Add JSON code to the response
+     *
+     * @param mixed $json  Either a key (string) or an
+     *                     array or key-value pairs
+     * @param mixed $value Null, if passing an array in $json otherwise
+     *                     it's a string value to the key
+     *
+     * @return void
+     */
+    public function addJSON($json, $value = null)
+    {
+        if (is_array($json)) {
+            foreach ($json as $key => $value) {
+                $this->addJSON($key, $value);
+            }
+        } else {
+            if ($value instanceof PMA_Message) {
+                $this->_JSON[$json] = $value->getDisplay();
+            } else {
+                $this->_JSON[$json] = $value;
+            }
+        }
+
+    }
+
+    /**
+     * Renders the HTML response text
+     *
+     * @return string
+     */
+    private function _getDisplay()
+    {
+        // The header may contain nothing at all,
+        // if it's content was already rendered
+        // and, in this case, the header will be
+        // in the content part of the request
+        $retval  = $this->_header->getDisplay();
+        $retval .= $this->_HTML;
+        $retval .= $this->_footer->getDisplay();
+        return $retval;
+    }
+
+    /**
+     * Sends an HTML response to the browser
+     *
+     * @return void
+     */
+    private function _htmlResponse()
+    {
+        echo $this->_getDisplay();
+    }
+
+    /**
+     * Sends a JSON response to the browser
+     *
+     * @return void
+     */
+    private function _ajaxResponse()
+    {
+        if (! isset($this->_JSON['message'])) {
+            $this->_JSON['message'] = $this->_getDisplay();
+        } else if ($this->_JSON['message'] instanceof PMA_Message) {
+            $this->_JSON['message'] = $this->_JSON['message']->getDisplay();
+        }
+
+        if ($this->_isSuccess) {
+            $this->_JSON['success'] = true;
+        } else {
+            $this->_JSON['success'] = false;
+            $this->_JSON['error']   = $this->_JSON['message'];
+            unset($this->_JSON['message']);
+        }
+
+        if ($this->_isAjaxPage && $this->_isSuccess) {
+            $this->addJSON('_title', $this->getHeader()->getTitleTag());
+
+            $menuHash = $this->getHeader()->getMenu()->getHash();
+            $this->addJSON('_menuHash', $menuHash);
+            $hashes = array();
+            if (isset($_REQUEST['menuHashes'])) {
+                $hashes = explode('-', $_REQUEST['menuHashes']);
+            }
+            if (! in_array($menuHash, $hashes)) {
+                $this->addJSON('_menu', $this->getHeader()->getMenu()->getDisplay());
+            }
+
+            $this->addJSON('_scripts', $this->getHeader()->getScripts()->getFiles());
+            $this->addJSON('_selflink', $this->getFooter()->getSelfUrl('unencoded'));
+            $this->addJSON('_displayMessage', $this->getHeader()->getMessage());
+            $errors = $this->_footer->getErrorMessages();
+            if (strlen($errors)) {
+                $this->addJSON('_errors', $errors);
+            }
+            if (empty($GLOBALS['error_message'])) {
+                // set current db, table and sql query in the querywindow
+                $query = '';
+                if (isset($GLOBALS['sql_query'])
+                    && strlen($GLOBALS['sql_query']) < $GLOBALS['cfg']['MaxCharactersInDisplayedSQL']
+                ) {
+                    $query = PMA_escapeJsString($GLOBALS['sql_query']);
+                }
+                $this->addJSON(
+                    '_reloadQuerywindow',
+                    array(
+                        'db' => PMA_ifSetOr($GLOBALS['db'], ''),
+                        'table' => PMA_ifSetOr($GLOBALS['table'], ''),
+                        'sql_query' => $query
+                    )
+                );
+                if (! empty($GLOBALS['focus_querywindow'])) {
+                    $this->addJSON('_focusQuerywindow', $query);
+                }
+                if (! empty($GLOBALS['reload'])) {
+                    $this->addJSON('_reloadNavigation', 1);
+                }
+                $this->addJSON('_params', $this->getHeader()->getJsParams());
+            }
+        }
+
+        // Set the Content-Type header to JSON so that jQuery parses the
+        // response correctly.
+        if (! defined('TESTSUITE')) {
+            header('Cache-Control: no-cache');
+            header('Content-Type: application/json');
+        }
+
+        echo json_encode($this->_JSON);
+    }
+
+    /**
+     * Sends an HTML response to the browser
+     *
+     * @static
+     * @return void
+     */
+    public static function response()
+    {
+        $response = PMA_Response::getInstance();
+        chdir($response->getCWD());
+        $buffer = PMA_OutputBuffering::getInstance();
+        if (empty($response->_HTML)) {
+            $response->_HTML = $buffer->getContents();
+        }
+        if ($response->isAjax()) {
+            $response->_ajaxResponse();
+        } else {
+            $response->_htmlResponse();
+        }
+        $buffer->flush();
+        exit;
+    }
+}
+
+?>
diff --git a/phpmyadmin/libraries/Scripts.class.php b/phpmyadmin/libraries/Scripts.class.php
new file mode 100644
index 0000000..c0d64d8
--- /dev/null
+++ b/phpmyadmin/libraries/Scripts.class.php
@@ -0,0 +1,243 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * JavaScript management
+ *
+ * @package PhpMyAdmin
+ */
+if (! defined('PHPMYADMIN')) {
+    exit;
+}
+
+/**
+ * Collects information about which JavaScript
+ * files and objects are necessary to render
+ * the page and generates the relevant code.
+ *
+ * @package PhpMyAdmin
+ */
+class PMA_Scripts
+{
+    /**
+     * An array of SCRIPT tags
+     *
+     * @access private
+     * @var array of strings
+     */
+    private $_files;
+    /**
+     * An array of discrete javascript code snippets
+     *
+     * @access private
+     * @var array of strings
+     */
+    private $_code;
+    /**
+     * An array of event names to bind and javascript code
+     * snippets to fire for the corresponding events
+     *
+     * @access private
+     * @var array
+     */
+    private $_events;
+
+    /**
+     * Returns HTML code to include javascript file.
+     *
+     * @param array $files The list of js file to include
+     *
+     * @return string HTML code for javascript inclusion.
+     */
+    private function _includeFiles($files)
+    {
+        $dynamic_scripts = "";
+        $params = array();
+        foreach ($files as $value) {
+            if (strpos($value['filename'], "?") === false) {
+                $include = true;
+                if ($value['conditional_ie'] !== false && PMA_USR_BROWSER_AGENT === 'IE') {
+                    if ($value['conditional_ie'] === true) {
+                        $include = true;
+                    } else if ($value['conditional_ie'] == PMA_USR_BROWSER_VER) {
+                        $include = true;
+                    } else {
+                        $include = false;
+                    }
+                }
+                if ($include) {
+                    $params[] = "scripts[]=" . $value['filename'];
+                }
+            } else {
+                $dynamic_scripts .= "<script type='text/javascript' src='js/" . $value['filename'] . "'></script>";
+            }
+        }
+        $static_scripts = sprintf(
+            "<script type='text/javascript' src='js/get_scripts.js.php?%s'></script>",
+            implode("&", $params)
+        );
+        return $static_scripts . $dynamic_scripts;
+    }
+
+    /**
+     * Generates new PMA_Scripts objects
+     *
+     * @return PMA_Scripts object
+     */
+    public function __construct()
+    {
+        $this->_files  = array();
+        $this->_code   = '';
+        $this->_events = array();
+
+    }
+
+    /**
+     * Adds a new file to the list of scripts
+     *
+     * @param string $filename       The name of the file to include
+     * @param bool   $conditional_ie Whether to wrap the script tag in
+     *                               conditional comments for IE
+     *
+     * @return void
+     */
+    public function addFile($filename, $conditional_ie = false)
+    {
+        $hash = md5($filename);
+        if (empty($this->_files[$hash])) {
+            $has_onload = $this->_eventBlacklist($filename);
+            $this->_files[$hash] = array(
+                'has_onload' => $has_onload,
+                'filename' => $filename,
+                'conditional_ie' => $conditional_ie
+            );
+        }
+    }
+
+    /**
+     * Determines whether to fire up an onload event for a file
+     *
+     * @param string $filename The name of the file to be checked
+     *                         against the blacklist
+     *
+     * @return int 1 to fire up the event, 0 not to
+     */
+    private function _eventBlacklist($filename)
+    {
+        if (   strpos($filename, 'jquery') !== false
+            || strpos($filename, 'codemirror') !== false
+            || strpos($filename, 'messages.php') !== false
+            || strpos($filename, 'ajax.js') !== false
+            || strpos($filename, 'navigation.js') !== false
+            || strpos($filename, 'get_image.js.php') !== false
+        ) {
+            return 0;
+        } else {
+            return 1;
+        }
+    }
+
+    /**
+     * Adds a new code snippet to the code to be executed
+     *
+     * @param string $code The JS code to be added
+     *
+     * @return void
+     */
+    public function addCode($code)
+    {
+        $this->_code .= "$code\n";
+    }
+
+    /**
+     * Adds a new event to the list of events
+     *
+     * @param string $event    The name of the event to register
+     * @param string $function The code to execute when the event fires
+     *                         E.g: 'function () { doSomething(); }'
+     *                         or 'doSomething'
+     *
+     * @return void
+     */
+    public function addEvent($event, $function)
+    {
+        $this->_events[] = array(
+            'event' => $event,
+            'function' => $function
+        );
+    }
+
+    /**
+     * Returns a list with filenames and a flag to indicate
+     * whether to register onload events for this file
+     *
+     * @return array
+     */
+    public function getFiles()
+    {
+        $retval = array();
+        foreach ($this->_files as $file) {
+            if (strpos($file['filename'], "?") === false) {
+                if (! $file['conditional_ie'] || PMA_USR_BROWSER_AGENT == 'IE') {
+                    $retval[] = array(
+                        'name' => $file['filename'],
+                        'fire' => $file['has_onload']
+                    );
+                }
+            }
+        }
+        return $retval;
+    }
+
+    /**
+     * Renders all the JavaScript file inclusions, code and events
+     *
+     * @return string
+     */
+    public function getDisplay()
+    {
+        $retval = '';
+
+        if (count($this->_files) > 0) {
+            $retval .= $this->_includeFiles(
+                $this->_files
+            );
+        }
+
+        $code = 'AJAX.scriptHandler';
+        foreach ($this->_files as $file) {
+            $code .= sprintf(
+                '.add("%s",%d)',
+                PMA_escapeJsString($file['filename']),
+                $file['has_onload'] ? 1 : 0
+            );
+        }
+        $code .= ';';
+        $this->addCode($code);
+
+        $code = '$(function() {';
+        foreach ($this->_files as $file) {
+            if ($file['has_onload']) {
+                $code .= 'AJAX.fireOnload("';
+                $code .= PMA_escapeJsString($file['filename']);
+                $code .= '");';
+            }
+        }
+        $code .= '});';
+        $this->addCode($code);
+
+        $retval .= '<script type="text/javascript">';
+        $retval .= "// <![CDATA[\n";
+        $retval .= $this->_code;
+        foreach ($this->_events as $js_event) {
+            $retval .= sprintf(
+                "$(window).bind('%s', %s);\n",
+                $js_event['event'],
+                $js_event['function']
+            );
+        }
+        $retval .= '// ]]>';
+        $retval .= '</script>';
+
+        return $retval;
+    }
+}
diff --git a/phpmyadmin/libraries/ServerStatusData.class.php b/phpmyadmin/libraries/ServerStatusData.class.php
new file mode 100644
index 0000000..de23d47
--- /dev/null
+++ b/phpmyadmin/libraries/ServerStatusData.class.php
@@ -0,0 +1,380 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * PMA_ServerStatusData class
+ * Used by server_status_*.php pages
+ *
+ * @package PhpMyAdmin
+ */
+
+require_once 'libraries/common.inc.php';
+
+/**
+ * This class provides data about the server status
+ *
+ * All properties of the class are read-only
+ *
+ * TODO: Use lazy initialisation for some of the properties
+ *       since not all of the server_status_*.php pages need
+ *       all the data that this class provides.
+ *
+ * @package PhpMyAdmin
+ */
+class PMA_ServerStatusData
+{
+    public $status;
+    public $sections;
+    public $variables;
+    public $used_queries;
+    public $allocationMap;
+    public $links;
+    public $db_isLocal;
+    public $section;
+    public $categoryUsed;
+    public $selfUrl;
+
+    /**
+     * An empty setter makes the above properties read-only
+     *
+     * @param string $a key
+     * @param mixed  $b value
+     *
+     * @return void
+     */
+    public function __set($a, $b)
+    {
+        // Discard everything
+    }
+
+    /**
+     * Constructor
+     *
+     * @return object
+     */
+    public function __construct()
+    {
+        $this->selfUrl = basename($GLOBALS['PMA_PHP_SELF']);
+        /**
+         * get status from server
+         */
+        $server_status = PMA_DBI_fetch_result('SHOW GLOBAL STATUS', 0, 1);
+        if (PMA_DRIZZLE) {
+            // Drizzle doesn't put query statistics into variables, add it
+            $sql = "SELECT concat('Com_', variable_name), variable_value
+                FROM data_dictionary.GLOBAL_STATEMENTS";
+            $statements = PMA_DBI_fetch_result($sql, 0, 1);
+            $server_status = array_merge($server_status, $statements);
+        }
+
+        /**
+         * for some calculations we require also some server settings
+         */
+        $server_variables = PMA_DBI_fetch_result('SHOW GLOBAL VARIABLES', 0, 1);
+
+        /**
+         * cleanup of some deprecated values
+         */
+        $server_status = self::cleanDeprecated($server_status);
+
+        /**
+         * calculate some values
+         */
+        // Key_buffer_fraction
+        if (isset($server_status['Key_blocks_unused'])
+            && isset($server_variables['key_cache_block_size'])
+            && isset($server_variables['key_buffer_size'])
+        ) {
+            $server_status['Key_buffer_fraction_%']
+                = 100
+                - $server_status['Key_blocks_unused']
+                * $server_variables['key_cache_block_size']
+                / $server_variables['key_buffer_size']
+                * 100;
+        } elseif (isset($server_status['Key_blocks_used'])
+                && isset($server_variables['key_buffer_size'])) {
+            $server_status['Key_buffer_fraction_%']
+                = $server_status['Key_blocks_used']
+                * 1024
+                / $server_variables['key_buffer_size'];
+        }
+
+        // Ratio for key read/write
+        if (isset($server_status['Key_writes'])
+            && isset($server_status['Key_write_requests'])
+            && $server_status['Key_write_requests'] > 0
+        ) {
+            $server_status['Key_write_ratio_%']
+                = 100 * $server_status['Key_writes'] / $server_status['Key_write_requests'];
+        }
+
+        if (isset($server_status['Key_reads'])
+            && isset($server_status['Key_read_requests'])
+            && $server_status['Key_read_requests'] > 0
+        ) {
+            $server_status['Key_read_ratio_%']
+                = 100 * $server_status['Key_reads'] / $server_status['Key_read_requests'];
+        }
+
+        // Threads_cache_hitrate
+        if (isset($server_status['Threads_created'])
+            && isset($server_status['Connections'])
+            && $server_status['Connections'] > 0
+        ) {
+
+            $server_status['Threads_cache_hitrate_%']
+                = 100 - $server_status['Threads_created']
+                / $server_status['Connections'] * 100;
+        }
+
+        /**
+         * split variables in sections
+         */
+        $allocations = array(
+            // variable name => section
+            // variable names match when they begin with the given string
+
+            'Com_'              => 'com',
+            'Innodb_'           => 'innodb',
+            'Ndb_'              => 'ndb',
+            'Handler_'          => 'handler',
+            'Qcache_'           => 'qcache',
+            'Threads_'          => 'threads',
+            'Slow_launch_threads' => 'threads',
+
+            'Binlog_cache_'     => 'binlog_cache',
+            'Created_tmp_'      => 'created_tmp',
+            'Key_'              => 'key',
+
+            'Delayed_'          => 'delayed',
+            'Not_flushed_delayed_rows' => 'delayed',
+
+            'Flush_commands'    => 'query',
+            'Last_query_cost'   => 'query',
+            'Slow_queries'      => 'query',
+            'Queries'           => 'query',
+            'Prepared_stmt_count' => 'query',
+
+            'Select_'           => 'select',
+            'Sort_'             => 'sort',
+
+            'Open_tables'       => 'table',
+            'Opened_tables'     => 'table',
+            'Open_table_definitions' => 'table',
+            'Opened_table_definitions' => 'table',
+            'Table_locks_'      => 'table',
+
+            'Rpl_status'        => 'repl',
+            'Slave_'            => 'repl',
+
+            'Tc_'               => 'tc',
+
+            'Ssl_'              => 'ssl',
+
+            'Open_files'        => 'files',
+            'Open_streams'      => 'files',
+            'Opened_files'      => 'files',
+        );
+
+        $sections = array(
+            // section => section name (description)
+            'com'           => 'Com',
+            'query'         => __('SQL query'),
+            'innodb'        => 'InnoDB',
+            'ndb'           => 'NDB',
+            'handler'       => __('Handler'),
+            'qcache'        => __('Query cache'),
+            'threads'       => __('Threads'),
+            'binlog_cache'  => __('Binary log'),
+            'created_tmp'   => __('Temporary data'),
+            'delayed'       => __('Delayed inserts'),
+            'key'           => __('Key cache'),
+            'select'        => __('Joins'),
+            'repl'          => __('Replication'),
+            'sort'          => __('Sorting'),
+            'table'         => __('Tables'),
+            'tc'            => __('Transaction coordinator'),
+            'files'         => __('Files'),
+            'ssl'           => 'SSL',
+            'other'         => __('Other')
+        );
+
+        /**
+         * define some needfull links/commands
+         */
+        // variable or section name => (name => url)
+        $links = array();
+
+        $links['table'][__('Flush (close) all tables')]
+            = $this->selfUrl . '?flush=TABLES&' . PMA_generate_common_url();
+        $links['table'][__('Show open tables')]
+            = 'sql.php?sql_query=' . urlencode('SHOW OPEN TABLES') .
+                '&goto=' . $this->selfUrl . '&' . PMA_generate_common_url();
+
+        if ($GLOBALS['server_master_status']) {
+            $links['repl'][__('Show slave hosts')]
+                = 'sql.php?sql_query=' . urlencode('SHOW SLAVE HOSTS')
+                    . '&goto=' . $this->selfUrl . '&'
+                    . PMA_generate_common_url();
+            $links['repl'][__('Show master status')] = '#replication_master';
+        }
+        if ($GLOBALS['server_slave_status']) {
+            $links['repl'][__('Show slave status')] = '#replication_slave';
+        }
+
+        $links['repl']['doc'] = 'replication';
+
+        $links['qcache'][__('Flush query cache')]
+            = $this->selfUrl . '?flush=' . urlencode('QUERY CACHE') . '&' .
+                PMA_generate_common_url();
+        $links['qcache']['doc'] = 'query_cache';
+
+        $links['threads']['doc'] = 'mysql_threads';
+
+        $links['key']['doc'] = 'myisam_key_cache';
+
+        $links['binlog_cache']['doc'] = 'binary_log';
+
+        $links['Slow_queries']['doc'] = 'slow_query_log';
+
+        $links['innodb'][__('Variables')]
+            = 'server_engines.php?engine=InnoDB&' . PMA_generate_common_url();
+        $links['innodb'][__('InnoDB Status')]
+            = 'server_engines.php?engine=InnoDB&page=Status&' .
+                PMA_generate_common_url();
+        $links['innodb']['doc'] = 'innodb';
+
+
+        // Variable to contain all com_ variables (query statistics)
+        $used_queries = array();
+
+        // Variable to map variable names to their respective section name
+        // (used for js category filtering)
+        $allocationMap = array();
+
+        // Variable to mark used sections
+        $categoryUsed = array();
+
+        // sort vars into arrays
+        foreach ($server_status as $name => $value) {
+            $section_found = false;
+            foreach ($allocations as $filter => $section) {
+                if (strpos($name, $filter) !== false) {
+                    $allocationMap[$name] = $section;
+                    $categoryUsed[$section] = true;
+                    $section_found = true;
+                    if ($section == 'com' && $value > 0) {
+                        $used_queries[$name] = $value;
+                    }
+                    break; // Only exits inner loop
+                }
+            }
+            if (!$section_found) {
+                $allocationMap[$name] = 'other';
+                $categoryUsed['other'] = true;
+            }
+        }
+
+        if (PMA_DRIZZLE) {
+            $used_queries = PMA_DBI_fetch_result(
+                'SELECT * FROM data_dictionary.global_statements',
+                0,
+                1
+            );
+            unset($used_queries['admin_commands']);
+        } else {
+            // admin commands are not queries (e.g. they include COM_PING,
+            // which is excluded from $server_status['Questions'])
+            unset($used_queries['Com_admin_commands']);
+        }
+
+        // Set all class properties
+        $this->db_isLocal = false;
+        if (strtolower($GLOBALS['cfg']['Server']['host']) === 'localhost'
+            || $GLOBALS['cfg']['Server']['host'] === '127.0.0.1'
+            || $GLOBALS['cfg']['Server']['host'] === '::1'
+        ) {
+            $this->db_isLocal = true;
+        }
+        $this->status = $server_status;
+        $this->sections = $sections;
+        $this->variables = $server_variables;
+        $this->used_queries = $used_queries;
+        $this->allocationMap = $allocationMap;
+        $this->links = $links;
+        $this->categoryUsed = $categoryUsed;
+    }
+
+    /**
+     * cleanup of some deprecated values
+     *
+     * @param array $server_status status array to process
+     *
+     * @return array
+     */
+    public static function cleanDeprecated($server_status)
+    {
+        $deprecated = array(
+            'Com_prepare_sql' => 'Com_stmt_prepare',
+            'Com_execute_sql' => 'Com_stmt_execute',
+            'Com_dealloc_sql' => 'Com_stmt_close',
+        );
+        foreach ($deprecated as $old => $new) {
+            if (isset($server_status[$old]) && isset($server_status[$new])) {
+                unset($server_status[$old]);
+            }
+        }
+        return $server_status;
+    }
+
+    /**
+     * cleanup of some deprecated values
+     *
+     * @return array
+     */
+    public function getMenuHtml()
+    {
+        $url_params = PMA_generate_common_url();
+        $items = array(
+            array(
+                'name' => __('Server'),
+                'url' => 'server_status.php'
+            ),
+            array(
+                'name' => __('Query statistics'),
+                'url' => 'server_status_queries.php'
+            ),
+            array(
+                'name' => __('All status variables'),
+                'url' => 'server_status_variables.php'
+            ),
+            array(
+                'name' => __('Monitor'),
+                'url' => 'server_status_monitor.php'
+            ),
+            array(
+                'name' => __('Advisor'),
+                'url' => 'server_status_advisor.php'
+            )
+        );
+
+        $retval  = '<ul id="topmenu2">';
+        foreach ($items as $item) {
+            $class = '';
+            if ($item['url'] === $this->selfUrl) {
+                $class = ' class="tabactive"';
+            }
+            $retval .= '<li>';
+            $retval .= '<a' . $class;
+            $retval .= ' href="' . $item['url'] . '?' . $url_params . '">';
+            $retval .= $item['name'];
+            $retval .= '</a>';
+            $retval .= '</li>';
+        }
+        $retval .= '</ul>';
+        $retval .= '<div class="clearfloat"></div>';
+
+        return $retval;
+    }
+}
+
+?>
diff --git a/phpmyadmin/libraries/StorageEngine.class.php b/phpmyadmin/libraries/StorageEngine.class.php
new file mode 100644
index 0000000..2dfe7f7
--- /dev/null
+++ b/phpmyadmin/libraries/StorageEngine.class.php
@@ -0,0 +1,434 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * Library for extracting information about the available storage engines
+ *
+ * @package PhpMyAdmin
+ */
+if (! defined('PHPMYADMIN')) {
+    exit;
+}
+
+/**
+ * defines
+ */
+define('PMA_ENGINE_SUPPORT_NO', 0);
+define('PMA_ENGINE_SUPPORT_DISABLED', 1);
+define('PMA_ENGINE_SUPPORT_YES', 2);
+define('PMA_ENGINE_SUPPORT_DEFAULT', 3);
+
+define('PMA_ENGINE_DETAILS_TYPE_PLAINTEXT', 0);
+define('PMA_ENGINE_DETAILS_TYPE_SIZE',      1);
+define('PMA_ENGINE_DETAILS_TYPE_NUMERIC',   2); //Has no effect yet...
+define('PMA_ENGINE_DETAILS_TYPE_BOOLEAN',   3); // 'ON' or 'OFF'
+
+/**
+ * Base Storage Engine Class
+ *
+ * @package PhpMyAdmin
+ */
+class PMA_StorageEngine
+{
+    /**
+     * @var string engine name
+     */
+    var $engine  = 'dummy';
+
+    /**
+     * @var string engine title/description
+     */
+    var $title   = 'PMA Dummy Engine Class';
+
+    /**
+     * @var string engine lang description
+     */
+    var $comment
+        = 'If you read this text inside phpMyAdmin, something went wrong...';
+
+    /**
+     * @var integer engine supported by current server
+     */
+    var $support = PMA_ENGINE_SUPPORT_NO;
+
+    /**
+     * returns array of storage engines
+     *
+     * @static
+     * @staticvar array $storage_engines storage engines
+     * @access  public
+     * @return array    of storage engines
+     */
+    static public function getStorageEngines()
+    {
+        static $storage_engines = null;
+
+        if (null == $storage_engines) {
+            if (PMA_DRIZZLE) {
+                $sql = "SELECT
+                        p.plugin_name            AS Engine,
+                        (CASE
+                            WHEN p.plugin_name = @@storage_engine THEN 'DEFAULT'
+                            WHEN p.is_active THEN 'YES'
+                            ELSE 'DISABLED' END) AS Support,
+                        m.module_description     AS Comment
+                    FROM data_dictionary.plugins p
+                        JOIN data_dictionary.modules m USING (module_name)
+                    WHERE p.plugin_type = 'StorageEngine'
+                        AND p.plugin_name NOT IN ('FunctionEngine', 'schema')";
+                $storage_engines = PMA_DBI_fetch_result($sql, 'Engine');
+            } else {
+                $storage_engines
+                    = PMA_DBI_fetch_result('SHOW STORAGE ENGINES', 'Engine');
+            }
+        }
+
+        return $storage_engines;
+    }
+
+    /**
+     * returns HTML code for storage engine select box
+     *
+     * @param string  $name                    The name of the select form element
+     * @param string  $id                      The ID of the form field
+     * @param string  $selected                The selected engine
+     * @param boolean $offerUnavailableEngines Should unavailable storage
+     *                                         engines be offered?
+     *
+     * @static
+     * @return string  html selectbox
+     */
+    static public function getHtmlSelect(
+        $name = 'engine', $id = null,
+        $selected = null, $offerUnavailableEngines = false
+    ) {
+        $selected   = strtolower($selected);
+        $output     = '<select name="' . $name . '"'
+            . (empty($id) ? '' : ' id="' . $id . '"') . '>' . "\n";
+
+        foreach (PMA_StorageEngine::getStorageEngines() as $key => $details) {
+            // Don't show PERFORMANCE_SCHEMA engine (MySQL 5.5)
+            // Don't show MyISAM for Drizzle (allowed only for temporary tables)
+            if (! $offerUnavailableEngines
+                && ($details['Support'] == 'NO'
+                || $details['Support'] == 'DISABLED'
+                || $details['Engine'] == 'PERFORMANCE_SCHEMA')
+                || (PMA_DRIZZLE && $details['Engine'] == 'MyISAM')
+            ) {
+                continue;
+            }
+
+            $output .= '    <option value="' . htmlspecialchars($key). '"'
+                . (empty($details['Comment'])
+                    ? '' : ' title="' . htmlspecialchars($details['Comment']) . '"')
+                . (strtolower($key) == $selected
+                    || (empty($selected) && $details['Support'] == 'DEFAULT')
+                    ? ' selected="selected"' : '')
+                . '>' . "\n"
+                . '        ' . htmlspecialchars($details['Engine']) . "\n"
+                . '    </option>' . "\n";
+        }
+        $output .= '</select>' . "\n";
+        return $output;
+    }
+
+    /**
+     * public static final PMA_StorageEngine getEngine()
+     *
+     * Loads the corresponding engine plugin, if available.
+     *
+     * @param string $engine The engine ID
+     *
+     * @return object  The engine plugin
+     */
+    static public function getEngine($engine)
+    {
+        $engine = str_replace('/', '', str_replace('.', '', $engine));
+        $filename = './libraries/engines/' . strtolower($engine) . '.lib.php';
+        if (file_exists($filename) && include_once $filename) {
+            $class_name = 'PMA_StorageEngine_' . $engine;
+            $engine_object = new $class_name($engine);
+        } else {
+            $engine_object = new PMA_StorageEngine($engine);
+        }
+        return $engine_object;
+    }
+
+    /**
+     * return true if given engine name is supported/valid, otherwise false
+     *
+     * @param string $engine name of engine
+     *
+     * @static
+     * @return boolean whether $engine is valid or not
+     */
+    static public function isValid($engine)
+    {
+        if ($engine == "PBMS") {
+            return true;
+        }
+        $storage_engines = PMA_StorageEngine::getStorageEngines();
+        return isset($storage_engines[$engine]);
+    }
+
+    /**
+     * returns as HTML table of the engine's server variables
+     *
+     * @return string The table that was generated based on the retrieved
+     *                information
+     */
+    function getHtmlVariables()
+    {
+        $odd_row    = false;
+        $ret        = '';
+
+        foreach ($this->getVariablesStatus() as $details) {
+            $ret .= '<tr class="' . ($odd_row ? 'odd' : 'even') . '">' . "\n"
+                  . '    <td>' . "\n";
+            if (! empty($details['desc'])) {
+                $ret .= '        '
+                    . PMA_Util::showHint($details['desc'])
+                    . "\n";
+            }
+            $ret .= '    </td>' . "\n"
+                  . '    <th>' . htmlspecialchars($details['title']) . '</th>'
+                  . "\n"
+                  . '    <td class="value">';
+            switch ($details['type']) {
+            case PMA_ENGINE_DETAILS_TYPE_SIZE:
+                $parsed_size = $this->resolveTypeSize($details['value']);
+                $ret .= $parsed_size[0] . ' ' . $parsed_size[1];
+                unset($parsed_size);
+                break;
+            case PMA_ENGINE_DETAILS_TYPE_NUMERIC:
+                $ret .= PMA_Util::formatNumber($details['value']) . ' ';
+                break;
+            default:
+                $ret .= htmlspecialchars($details['value']) . '   ';
+            }
+            $ret .= '</td>' . "\n"
+                  . '</tr>' . "\n";
+            $odd_row = ! $odd_row;
+        }
+
+        if (! $ret) {
+            $ret = '<p>' . "\n"
+                 . '    '
+                 . __('There is no detailed status information available for this storage engine.')
+                 . "\n"
+                 . '</p>' . "\n";
+        } else {
+            $ret = '<table class="data">' . "\n" . $ret . '</table>' . "\n";
+        }
+
+        return $ret;
+    }
+
+    /**
+     * Returns the engine specific handling for
+     * PMA_ENGINE_DETAILS_TYPE_SIZE type variables.
+     *
+     * This function should be overridden when
+     * PMA_ENGINE_DETAILS_TYPE_SIZE type needs to be
+     * handled differently for a particular engine.
+     *
+     * @param integer $value Value to format
+     *
+     * @return string the formatted value and its unit
+     */
+    function resolveTypeSize($value)
+    {
+        return PMA_Util::formatByteDown($value);
+    }
+
+    /**
+     * returns array with detailed info about engine specific server variables
+     *
+     * @return array   with detailed info about specific engine server variables
+     */
+    function getVariablesStatus()
+    {
+        $variables = $this->getVariables();
+        $like = $this->getVariablesLikePattern();
+
+        if ($like) {
+            $like = " LIKE '" . $like . "' ";
+        } else {
+            $like = '';
+        }
+
+        $mysql_vars = array();
+
+        $sql_query = 'SHOW GLOBAL VARIABLES ' . $like . ';';
+        $res = PMA_DBI_query($sql_query);
+        while ($row = PMA_DBI_fetch_assoc($res)) {
+            if (isset($variables[$row['Variable_name']])) {
+                $mysql_vars[$row['Variable_name']] = $variables[$row['Variable_name']];
+            } elseif (! $like
+                && strpos(strtolower($row['Variable_name']), strtolower($this->engine)) !== 0
+            ) {
+                continue;
+            }
+            $mysql_vars[$row['Variable_name']]['value'] = $row['Value'];
+
+            if (empty($mysql_vars[$row['Variable_name']]['title'])) {
+                $mysql_vars[$row['Variable_name']]['title'] = $row['Variable_name'];
+            }
+
+            if (! isset($mysql_vars[$row['Variable_name']]['type'])) {
+                $mysql_vars[$row['Variable_name']]['type']
+                    = PMA_ENGINE_DETAILS_TYPE_PLAINTEXT;
+            }
+        }
+        PMA_DBI_free_result($res);
+
+        return $mysql_vars;
+    }
+
+    /**
+     * Constructor
+     *
+     * @param string $engine The engine ID
+     */
+    function __construct($engine)
+    {
+        $storage_engines = PMA_StorageEngine::getStorageEngines();
+        if (! empty($storage_engines[$engine])) {
+            $this->engine  = $engine;
+            $this->title   = $storage_engines[$engine]['Engine'];
+            $this->comment
+                = (isset($storage_engines[$engine]['Comment'])
+                    ? $storage_engines[$engine]['Comment']
+                    : '');
+            switch ($storage_engines[$engine]['Support']) {
+            case 'DEFAULT':
+                $this->support = PMA_ENGINE_SUPPORT_DEFAULT;
+                break;
+            case 'YES':
+                $this->support = PMA_ENGINE_SUPPORT_YES;
+                break;
+            case 'DISABLED':
+                $this->support = PMA_ENGINE_SUPPORT_DISABLED;
+                break;
+            case 'NO':
+            default:
+                $this->support = PMA_ENGINE_SUPPORT_NO;
+            }
+        }
+    }
+
+    /**
+     * public String getTitle()
+     *
+     * Reveals the engine's title
+     *
+     * @return string The title
+     */
+    function getTitle()
+    {
+        return $this->title;
+    }
+
+    /**
+     * public String getComment()
+     *
+     * Fetches the server's comment about this engine
+     *
+     * @return string The comment
+     */
+    function getComment()
+    {
+        return $this->comment;
+    }
+
+    /**
+     * public String getSupportInformationMessage()
+     *
+     * @return string   The localized message.
+     */
+    function getSupportInformationMessage()
+    {
+        switch ($this->support) {
+        case PMA_ENGINE_SUPPORT_DEFAULT:
+            $message = __('%s is the default storage engine on this MySQL server.');
+            break;
+        case PMA_ENGINE_SUPPORT_YES:
+            $message = __('%s is available on this MySQL server.');
+            break;
+        case PMA_ENGINE_SUPPORT_DISABLED:
+            $message = __('%s has been disabled for this MySQL server.');
+            break;
+        case PMA_ENGINE_SUPPORT_NO:
+        default:
+            $message = __('This MySQL server does not support the %s storage engine.');
+        }
+        return sprintf($message, htmlspecialchars($this->title));
+    }
+
+    /**
+     * public string[][] getVariables()
+     *
+     * Generates a list of MySQL variables that provide information about this
+     * engine. This function should be overridden when extending this class
+     * for a particular engine.
+     *
+     * @abstract
+     * @return Array   The list of variables.
+     */
+    function getVariables()
+    {
+        return array();
+    }
+
+    /**
+     * returns string with filename for the MySQL helppage
+     * about this storage engine
+     *
+     * @return string  mysql helppage filename
+     */
+    function getMysqlHelpPage()
+    {
+        return $this->engine . '-storage-engine';
+    }
+
+    /**
+     * public string getVariablesLikePattern()
+     *
+     * @abstract
+     * @return string  SQL query LIKE pattern
+     */
+    function getVariablesLikePattern()
+    {
+        return false;
+    }
+
+    /**
+     * public String[] getInfoPages()
+     *
+     * Returns a list of available information pages with labels
+     *
+     * @abstract
+     * @return array    The list
+     */
+    function getInfoPages()
+    {
+        return array();
+    }
+
+    /**
+     * public String getPage()
+     *
+     * Generates the requested information page
+     *
+     * @param string $id The page ID
+     *
+     * @abstract
+     * @return string      The page
+     *          boolean     or false on error.
+     */
+    function getPage($id)
+    {
+        return false;
+    }
+}
+
+?>
diff --git a/phpmyadmin/libraries/Table.class.php b/phpmyadmin/libraries/Table.class.php
new file mode 100644
index 0000000..49ea68e
--- /dev/null
+++ b/phpmyadmin/libraries/Table.class.php
@@ -0,0 +1,1664 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * Holds the PMA_Table class
+ *
+ * @package PhpMyAdmin
+ */
+if (! defined('PHPMYADMIN')) {
+    exit;
+}
+
+/**
+ * Handles everything related to tables
+ *
+ * @todo make use of PMA_Message and PMA_Error
+ * @package PhpMyAdmin
+ */
+class PMA_Table
+{
+    /**
+     * UI preferences properties
+     */
+    const PROP_SORTED_COLUMN = 'sorted_col';
+    const PROP_COLUMN_ORDER = 'col_order';
+    const PROP_COLUMN_VISIB = 'col_visib';
+
+    static $cache = array();
+
+    /**
+     * @var string  table name
+     */
+    var $name = '';
+
+    /**
+     * @var string  database name
+     */
+    var $db_name = '';
+
+    /**
+     * @var string  engine (innodb, myisam, bdb, ...)
+     */
+    var $engine = '';
+
+    /**
+     * @var string  type (view, base table, system view)
+     */
+    var $type = '';
+
+    /**
+     * @var array   settings
+     */
+    var $settings = array();
+
+    /**
+     * @var array UI preferences
+     */
+    var $uiprefs;
+
+    /**
+     * @var array errors occured
+     */
+    var $errors = array();
+
+    /**
+     * @var array messages
+     */
+    var $messages = array();
+
+    /**
+     * Constructor
+     *
+     * @param string $table_name table name
+     * @param string $db_name    database name
+     */
+    function __construct($table_name, $db_name)
+    {
+        $this->setName($table_name);
+        $this->setDbName($db_name);
+    }
+
+    /**
+     * returns table name
+     *
+     * @see PMA_Table::getName()
+     * @return string  table name
+     */
+    function __toString()
+    {
+        return $this->getName();
+    }
+
+    /**
+     * return the last error
+     *
+     * @return the last error
+     */
+    function getLastError()
+    {
+        return end($this->errors);
+    }
+
+    /**
+     * return the last message
+     *
+     * @return the last message
+     */
+    function getLastMessage()
+    {
+        return end($this->messages);
+    }
+
+    /**
+     * sets table name
+     *
+     * @param string $table_name new table name
+     *
+     * @return void
+     */
+    function setName($table_name)
+    {
+        $this->name = $table_name;
+    }
+
+    /**
+     * returns table name
+     *
+     * @param boolean $backquoted whether to quote name with backticks ``
+     *
+     * @return string  table name
+     */
+    function getName($backquoted = false)
+    {
+        if ($backquoted) {
+            return PMA_Util::backquote($this->name);
+        }
+        return $this->name;
+    }
+
+    /**
+     * sets database name for this table
+     *
+     * @param string $db_name database name
+     *
+     * @return void
+     */
+    function setDbName($db_name)
+    {
+        $this->db_name = $db_name;
+    }
+
+    /**
+     * returns database name for this table
+     *
+     * @param boolean $backquoted whether to quote name with backticks ``
+     *
+     * @return string  database name for this table
+     */
+    function getDbName($backquoted = false)
+    {
+        if ($backquoted) {
+            return PMA_Util::backquote($this->db_name);
+        }
+        return $this->db_name;
+    }
+
+    /**
+     * returns full name for table, including database name
+     *
+     * @param boolean $backquoted whether to quote name with backticks ``
+     *
+     * @return string
+     */
+    function getFullName($backquoted = false)
+    {
+        return $this->getDbName($backquoted) . '.'
+            . $this->getName($backquoted);
+    }
+
+    /**
+     * returns whether the table is actually a view
+     *
+     * @param string $db    database
+     * @param string $table table
+     *
+     * @return whether the given is a view
+     */
+    static public function isView($db = null, $table = null)
+    {
+        if (empty($db) || empty($table)) {
+            return false;
+        }
+
+        // use cached data or load information with SHOW command
+        if (isset(PMA_Table::$cache[$db][$table])
+            || $GLOBALS['cfg']['Server']['DisableIS']
+        ) {
+            $type = PMA_Table::sGetStatusInfo($db, $table, 'TABLE_TYPE');
+            return $type == 'VIEW';
+        }
+
+        // query information_schema
+        $result = PMA_DBI_fetch_result(
+            "SELECT TABLE_NAME
+            FROM information_schema.VIEWS
+            WHERE TABLE_SCHEMA = '" . PMA_Util::sqlAddSlashes($db) . "'
+                AND TABLE_NAME = '" . PMA_Util::sqlAddSlashes($table) . "'"
+        );
+        return $result ? true : false;
+    }
+
+    /**
+     * Returns whether the table is actually an updatable view
+     *
+     * @param string $db    database
+     * @param string $table table
+     *
+     * @return boolean whether the given is an updatable view
+     */
+    static public function isUpdatableView($db = null, $table = null)
+    {
+        if (empty($db) || empty($table)) {
+            return false;
+        }
+
+        $result = PMA_DBI_fetch_result(
+            "SELECT TABLE_NAME
+            FROM information_schema.VIEWS
+            WHERE TABLE_SCHEMA = '" . PMA_Util::sqlAddSlashes($db) . "'
+                AND TABLE_NAME = '" . PMA_Util::sqlAddSlashes($table) . "'
+                AND IS_UPDATABLE = 'YES'"
+        );
+        return $result ? true : false;
+    }
+
+    /**
+     * Returns the analysis of 'SHOW CREATE TABLE' query for the table.
+     * In case of a view, the values are taken from the information_schema.
+     *
+     * @param string $db    database
+     * @param string $table table
+     *
+     * @return array analysis of 'SHOW CREATE TABLE' query for the table
+     */
+    static public function analyzeStructure($db = null, $table = null)
+    {
+        if (empty($db) || empty($table)) {
+            return false;
+        }
+
+        $analyzed_sql = array();
+        if (self::isView($db, $table)) {
+            // For a view, 'SHOW CREATE TABLE' returns the definition,
+            // but the structure of the view. So, we try to mock 
+            // the result of analyzing 'SHOW CREATE TABLE' query.
+            $analyzed_sql[0] = array();
+            $analyzed_sql[0]['create_table_fields'] = array();
+
+            $results = PMA_DBI_fetch_result(
+                "SELECT COLUMN_NAME, DATA_TYPE
+                FROM information_schema.COLUMNS
+                WHERE TABLE_SCHEMA = '" . PMA_Util::sqlAddSlashes($db) . "'
+                AND TABLE_NAME = '" . PMA_Util::sqlAddSlashes($table) . "'"
+            );
+            foreach ($results as $result) {
+                $analyzed_sql[0]['create_table_fields'][$result['COLUMN_NAME']]
+                    = array('type' => strtoupper($result['DATA_TYPE']));
+            }
+        } else {
+            $show_create_table = PMA_DBI_fetch_value(
+                'SHOW CREATE TABLE ' . PMA_Util::backquote($db) . '.' . PMA_Util::backquote($table),
+                0,
+                1
+            );
+            $analyzed_sql = PMA_SQP_analyze(PMA_SQP_parse($show_create_table));
+        }
+        return $analyzed_sql;
+    }
+
+    /**
+     * sets given $value for given $param
+     *
+     * @param string $param name
+     * @param mixed  $value value
+     *
+     * @return void
+     */
+    function set($param, $value)
+    {
+        $this->settings[$param] = $value;
+    }
+
+    /**
+     * returns value for given setting/param
+     *
+     * @param string $param name for value to return
+     *
+     * @return mixed   value for $param
+     */
+    function get($param)
+    {
+        if (isset($this->settings[$param])) {
+            return $this->settings[$param];
+        }
+
+        return null;
+    }
+
+    /**
+     * Checks if this is a merge table
+     *
+     * If the ENGINE of the table is MERGE or MRG_MYISAM (alias),
+     * this is a merge table.
+     *
+     * @param string $db    the database name
+     * @param string $table the table name
+     *
+     * @return boolean  true if it is a merge table
+     */
+    static public function isMerge($db = null, $table = null)
+    {
+        $engine = null;
+        // if called static, with parameters
+        if (! empty($db) && ! empty($table)) {
+            $engine = PMA_Table::sGetStatusInfo(
+                $db, $table, 'ENGINE', null, true
+            );
+        }
+
+        // did we get engine?
+        if (empty($engine)) {
+            return false;
+        }
+
+        // any of known merge engines?
+        return in_array(strtoupper($engine), array('MERGE', 'MRG_MYISAM'));
+    }
+
+    /**
+     * Returns tooltip for the table
+     * Format : <table_comment> (<number_of_rows>)
+     *
+     * @param string $db    database name
+     * @param string $table table name
+     *
+     * @return string tooltip fot the table
+     */
+    static public function sGetToolTip($db, $table)
+    {
+        return PMA_Table::sGetStatusInfo($db, $table, 'Comment')
+            . ' (' . PMA_Table::countRecords($db, $table)
+            . ' ' . __('Rows') . ')';
+    }
+
+    /**
+     * Returns full table status info, or specific if $info provided
+     * this info is collected from information_schema
+     *
+     * @param string  $db            database name
+     * @param string  $table         table name
+     * @param string  $info          specific information to be fetched
+     * @param boolean $force_read    read new rather than serving from cache
+     * @param boolean $disable_error if true, disables error message
+     *
+     * @todo PMA_DBI_get_tables_full needs to be merged somehow into this class
+     * or at least better documented
+     *
+     * @return mixed
+     */
+    static public function sGetStatusInfo($db, $table, $info = null,
+        $force_read = false, $disable_error = false
+    ) {
+        if (! empty($_SESSION['is_multi_query'])) {
+            $disable_error = true;
+        }
+
+        if (! isset(PMA_Table::$cache[$db][$table]) || $force_read) {
+            PMA_DBI_get_tables_full($db, $table);
+        }
+
+        if (! isset(PMA_Table::$cache[$db][$table])) {
+            // happens when we enter the table creation dialog
+            // or when we really did not get any status info, for example
+            // when $table == 'TABLE_NAMES' after the user tried SHOW TABLES
+            return '';
+        }
+
+        if (null === $info) {
+            return PMA_Table::$cache[$db][$table];
+        }
+
+        // array_key_exists allows for null values
+        if (!array_key_exists($info, PMA_Table::$cache[$db][$table])) {
+            if (! $disable_error) {
+                trigger_error(
+                    __('unknown table status: ') . $info,
+                    E_USER_WARNING
+                );
+            }
+            return false;
+        }
+
+        return PMA_Table::$cache[$db][$table][$info];
+    }
+
+    /**
+     * generates column specification for ALTER or CREATE TABLE syntax
+     *
+     * @param string      $name           name
+     * @param string      $type           type ('INT', 'VARCHAR', 'BIT', ...)
+     * @param string      $index          index
+     * @param string      $length         length ('2', '5,2', '', ...)
+     * @param string      $attribute      attribute
+     * @param string      $collation      collation
+     * @param bool|string $null           with 'NULL' or 'NOT NULL'
+     * @param string      $default_type   whether default is CURRENT_TIMESTAMP,
+     *                                    NULL, NONE, USER_DEFINED
+     * @param string      $default_value  default value for USER_DEFINED
+     *                                    default type
+     * @param string      $extra          'AUTO_INCREMENT'
+     * @param string      $comment        field comment
+     * @param array       &$field_primary list of fields for PRIMARY KEY
+     * @param string      $move_to        new position for column
+     *
+     * @todo    move into class PMA_Column
+     * @todo on the interface, some js to clear the default value when the
+     * default current_timestamp is checked
+     *
+     * @return string  field specification
+     */
+    static function generateFieldSpec($name, $type, $index, $length = '',
+        $attribute = '', $collation = '', $null = false,
+        $default_type = 'USER_DEFINED', $default_value = '',  $extra = '',
+        $comment = '', &$field_primary = null, $move_to = ''
+    ) {
+        $is_timestamp = strpos(strtoupper($type), 'TIMESTAMP') !== false;
+
+        $query = PMA_Util::backquote($name) . ' ' . $type;
+
+        if ($length != ''
+            && ! preg_match(
+                '@^(DATE|DATETIME|TIME|TINYBLOB|TINYTEXT|BLOB|TEXT|'
+                . 'MEDIUMBLOB|MEDIUMTEXT|LONGBLOB|LONGTEXT|SERIAL|BOOLEAN|UUID)$@i',
+                $type
+            )
+        ) {
+            $query .= '(' . $length . ')';
+        }
+
+        if ($attribute != '') {
+            $query .= ' ' . $attribute;
+        }
+
+        $matches = preg_match(
+            '@^(TINYTEXT|TEXT|MEDIUMTEXT|LONGTEXT|VARCHAR|CHAR|ENUM|SET)$@i',
+            $type
+        );
+        if (! empty($collation) && $collation != 'NULL' && $matches) {
+            $query .= PMA_generateCharsetQueryPart($collation);
+        }
+
+        if ($null !== false) {
+            if ($null == 'NULL') {
+                $query .= ' NULL';
+            } else {
+                $query .= ' NOT NULL';
+            }
+        }
+
+        switch ($default_type) {
+        case 'USER_DEFINED' :
+            if ($is_timestamp && $default_value === '0') {
+                // a TIMESTAMP does not accept DEFAULT '0'
+                // but DEFAULT 0 works
+                $query .= ' DEFAULT 0';
+            } elseif ($type == 'BIT') {
+                $query .= ' DEFAULT b\''
+                        . preg_replace('/[^01]/', '0', $default_value)
+                        . '\'';
+            } elseif ($type == 'BOOLEAN') {
+                if (preg_match('/^1|T|TRUE|YES$/i', $default_value)) {
+                    $query .= ' DEFAULT TRUE';
+                } elseif (preg_match('/^0|F|FALSE|NO$/i', $default_value)) {
+                    $query .= ' DEFAULT FALSE';
+                } else {
+                    // Invalid BOOLEAN value
+                    $query .= ' DEFAULT \''
+                        . PMA_Util::sqlAddSlashes($default_value) . '\'';
+                }
+            } else {
+                $query .= ' DEFAULT \'' . PMA_Util::sqlAddSlashes($default_value) . '\'';
+            }
+            break;
+        case 'NULL' :
+            //If user uncheck null checkbox and not change default value null,
+            //default value will be ignored.
+            if ($null !== false && $null != 'NULL') {
+                break;
+            }
+        case 'CURRENT_TIMESTAMP' :
+            $query .= ' DEFAULT ' . $default_type;
+            break;
+        case 'NONE' :
+        default :
+            break;
+        }
+
+        if (!empty($extra)) {
+            $query .= ' ' . $extra;
+            // Force an auto_increment field to be part of the primary key
+            // even if user did not tick the PK box;
+            if ($extra == 'AUTO_INCREMENT') {
+                $primary_cnt = count($field_primary);
+                if (1 == $primary_cnt) {
+                    for ($j = 0; $j < $primary_cnt; $j++) {
+                        if ($field_primary[$j] == $index) {
+                            break;
+                        }
+                    }
+                    if (isset($field_primary[$j]) && $field_primary[$j] == $index) {
+                        $query .= ' PRIMARY KEY';
+                        unset($field_primary[$j]);
+                    }
+                } else {
+                    // but the PK could contain other columns so do not append
+                    // a PRIMARY KEY clause, just add a member to $field_primary
+                    $found_in_pk = false;
+                    for ($j = 0; $j < $primary_cnt; $j++) {
+                        if ($field_primary[$j] == $index) {
+                            $found_in_pk = true;
+                            break;
+                        }
+                    } // end for
+                    if (! $found_in_pk) {
+                        $field_primary[] = $index;
+                    }
+                }
+            } // end if (auto_increment)
+        }
+        if (!empty($comment)) {
+            $query .= " COMMENT '" . PMA_Util::sqlAddSlashes($comment) . "'";
+        }
+
+        // move column
+        if ($move_to == '-first') { // dash can't appear as part of column name
+            $query .= ' FIRST';
+        } elseif ($move_to != '') {
+            $query .= ' AFTER ' . PMA_Util::backquote($move_to);
+        }
+        return $query;
+    } // end function
+
+    /**
+     * Counts and returns (or displays) the number of records in a table
+     *
+     * @param string $db          the current database name
+     * @param string $table       the current table name
+     * @param bool   $force_exact whether to force an exact count
+     * @param bool   $is_view     whether the table is a view
+     *
+     * @return mixed the number of records if "retain" param is true,
+     *               otherwise true
+     */
+    static public function countRecords($db, $table, $force_exact = false,
+        $is_view = null
+    ) {
+        if (isset(PMA_Table::$cache[$db][$table]['ExactRows'])) {
+            $row_count = PMA_Table::$cache[$db][$table]['ExactRows'];
+        } else {
+            $row_count = false;
+
+            if (null === $is_view) {
+                $is_view = PMA_Table::isView($db, $table);
+            }
+
+            if (! $force_exact) {
+                if (! isset(PMA_Table::$cache[$db][$table]['Rows']) && ! $is_view) {
+                    $tmp_tables = PMA_DBI_get_tables_full($db, $table);
+                    if (isset($tmp_tables[$table])) {
+                        PMA_Table::$cache[$db][$table] = $tmp_tables[$table];
+                    }
+                }
+                if (isset(PMA_Table::$cache[$db][$table]['Rows'])) {
+                    $row_count = PMA_Table::$cache[$db][$table]['Rows'];
+                } else {
+                    $row_count = false;
+                }
+            }
+
+            // for a VIEW, $row_count is always false at this point
+            if (false === $row_count
+                || $row_count < $GLOBALS['cfg']['MaxExactCount']
+            ) {
+                // Make an exception for views in I_S and D_D schema in
+                // Drizzle, as these map to in-memory data and should execute
+                // fast enough
+                if (! $is_view || (PMA_DRIZZLE && PMA_is_system_schema($db))) {
+                    $row_count = PMA_DBI_fetch_value(
+                        'SELECT COUNT(*) FROM ' . PMA_Util::backquote($db) . '.'
+                        . PMA_Util::backquote($table)
+                    );
+                } else {
+                    // For complex views, even trying to get a partial record
+                    // count could bring down a server, so we offer an
+                    // alternative: setting MaxExactCountViews to 0 will bypass
+                    // completely the record counting for views
+
+                    if ($GLOBALS['cfg']['MaxExactCountViews'] == 0) {
+                        $row_count = 0;
+                    } else {
+                        // Counting all rows of a VIEW could be too long,
+                        // so use a LIMIT clause.
+                        // Use try_query because it can fail (when a VIEW is
+                        // based on a table that no longer exists)
+                        $result = PMA_DBI_try_query(
+                            'SELECT 1 FROM ' . PMA_Util::backquote($db) . '.'
+                            . PMA_Util::backquote($table) . ' LIMIT '
+                            . $GLOBALS['cfg']['MaxExactCountViews'],
+                            null,
+                            PMA_DBI_QUERY_STORE
+                        );
+                        if (!PMA_DBI_getError()) {
+                            $row_count = PMA_DBI_num_rows($result);
+                            PMA_DBI_free_result($result);
+                        }
+                    }
+                }
+                if ($row_count) {
+                    PMA_Table::$cache[$db][$table]['ExactRows'] = $row_count;
+                }
+            }
+        }
+
+        return $row_count;
+    } // end of the 'PMA_Table::countRecords()' function
+
+    /**
+     * Generates column specification for ALTER syntax
+     *
+     * @param string      $oldcol         old column name
+     * @param string      $newcol         new column name
+     * @param string      $type           type ('INT', 'VARCHAR', 'BIT', ...)
+     * @param string      $length         length ('2', '5,2', '', ...)
+     * @param string      $attribute      attribute
+     * @param string      $collation      collation
+     * @param bool|string $null           with 'NULL' or 'NOT NULL'
+     * @param string      $default_type   whether default is CURRENT_TIMESTAMP,
+     *                                    NULL, NONE, USER_DEFINED
+     * @param string      $default_value  default value for USER_DEFINED default
+     *                                    type
+     * @param string      $extra          'AUTO_INCREMENT'
+     * @param string      $comment        field comment
+     * @param array       &$field_primary list of fields for PRIMARY KEY
+     * @param string      $index          index
+     * @param string      $move_to        new position for column
+     *
+     * @see PMA_Table::generateFieldSpec()
+     *
+     * @return string  field specification
+     */
+    static public function generateAlter($oldcol, $newcol, $type, $length,
+        $attribute, $collation, $null, $default_type, $default_value,
+        $extra, $comment, &$field_primary, $index, $move_to
+    ) {
+        return PMA_Util::backquote($oldcol) . ' '
+            . PMA_Table::generateFieldSpec(
+                $newcol, $type, $index, $length, $attribute,
+                $collation, $null, $default_type, $default_value, $extra,
+                $comment, $field_primary, $move_to
+            );
+    } // end function
+
+    /**
+     * Inserts existing entries in a PMA_* table by reading a value from an old
+     * entry
+     *
+     * @param string $work         The array index, which Relation feature to
+     *                             check ('relwork', 'commwork', ...)
+     * @param string $pma_table    The array index, which PMA-table to update
+     *                             ('bookmark', 'relation', ...)
+     * @param array  $get_fields   Which fields will be SELECT'ed from the old entry
+     * @param array  $where_fields Which fields will be used for the WHERE query
+     *                             (array('FIELDNAME' => 'FIELDVALUE'))
+     * @param array  $new_fields   Which fields will be used as new VALUES.
+     *                             These are the important keys which differ
+     *                             from the old entry
+     *                             (array('FIELDNAME' => 'NEW FIELDVALUE'))
+     *
+     * @global relation variable
+     *
+     * @return int|true
+     */
+    static public function duplicateInfo($work, $pma_table, $get_fields,
+        $where_fields, $new_fields
+    ) {
+        $last_id = -1;
+
+        if (isset($GLOBALS['cfgRelation']) && $GLOBALS['cfgRelation'][$work]) {
+            $select_parts = array();
+            $row_fields = array();
+            foreach ($get_fields as $get_field) {
+                $select_parts[] = PMA_Util::backquote($get_field);
+                $row_fields[$get_field] = 'cc';
+            }
+
+            $where_parts = array();
+            foreach ($where_fields as $_where => $_value) {
+                $where_parts[] = PMA_Util::backquote($_where) . ' = \''
+                    . PMA_Util::sqlAddSlashes($_value) . '\'';
+            }
+
+            $new_parts = array();
+            $new_value_parts = array();
+            foreach ($new_fields as $_where => $_value) {
+                $new_parts[] = PMA_Util::backquote($_where);
+                $new_value_parts[] = PMA_Util::sqlAddSlashes($_value);
+            }
+
+            $table_copy_query = '
+                SELECT ' . implode(', ', $select_parts) . '
+                  FROM ' . PMA_Util::backquote($GLOBALS['cfgRelation']['db']) . '.'
+                  . PMA_Util::backquote($GLOBALS['cfgRelation'][$pma_table]) . '
+                 WHERE ' . implode(' AND ', $where_parts);
+
+            // must use PMA_DBI_QUERY_STORE here, since we execute another
+            // query inside the loop
+            $table_copy_rs = PMA_queryAsControlUser(
+                $table_copy_query, true, PMA_DBI_QUERY_STORE
+            );
+
+            while ($table_copy_row = @PMA_DBI_fetch_assoc($table_copy_rs)) {
+                $value_parts = array();
+                foreach ($table_copy_row as $_key => $_val) {
+                    if (isset($row_fields[$_key]) && $row_fields[$_key] == 'cc') {
+                        $value_parts[] = PMA_Util::sqlAddSlashes($_val);
+                    }
+                }
+
+                $new_table_query = 'INSERT IGNORE INTO '
+                    . PMA_Util::backquote($GLOBALS['cfgRelation']['db'])
+                    . '.' . PMA_Util::backquote($GLOBALS['cfgRelation'][$pma_table]) . '
+                    (' . implode(', ', $select_parts) . ',
+                     ' . implode(', ', $new_parts) . ')
+                    VALUES
+                    (\'' . implode('\', \'', $value_parts) . '\',
+                     \'' . implode('\', \'', $new_value_parts) . '\')';
+
+                PMA_queryAsControlUser($new_table_query);
+                $last_id = PMA_DBI_insert_id();
+            } // end while
+
+            PMA_DBI_free_result($table_copy_rs);
+
+            return $last_id;
+        }
+
+        return true;
+    } // end of 'PMA_Table::duplicateInfo()' function
+
+    /**
+     * Copies or renames table
+     *
+     * @param string $source_db    source database
+     * @param string $source_table source table
+     * @param string $target_db    target database
+     * @param string $target_table target table
+     * @param string $what         what to be moved or copied (data, dataonly)
+     * @param bool   $move         whether to move
+     * @param string $mode         mode
+     *
+     * @return bool true if success, false otherwise
+     */
+    static public function moveCopy($source_db, $source_table, $target_db,
+        $target_table, $what, $move, $mode
+    ) {
+        global $err_url;
+
+        /* Try moving table directly */
+        if ($move && $what == 'data') {
+            $tbl = new PMA_Table($source_table, $source_db);
+            $result = $tbl->rename($target_table, $target_db);
+            if ($result) {
+                $GLOBALS['message'] = $tbl->getLastMessage();
+                return true;
+            }
+        }
+
+        // set export settings we need
+        $GLOBALS['sql_backquotes'] = 1;
+        $GLOBALS['asfile']         = 1;
+
+        // Ensure the target is valid
+        if (! $GLOBALS['pma']->databases->exists($source_db, $target_db)) {
+            if (! $GLOBALS['pma']->databases->exists($source_db)) {
+                $GLOBALS['message'] = PMA_Message::rawError(
+                    sprintf(
+                        __('Source database `%s` was not found!'),
+                        htmlspecialchars($source_db)
+                    )
+                );
+            }
+            if (! $GLOBALS['pma']->databases->exists($target_db)) {
+                $GLOBALS['message'] = PMA_Message::rawError(
+                    sprintf(
+                        __('Target database `%s` was not found!'),
+                        htmlspecialchars($target_db)
+                    )
+                );
+            }
+            return false;
+        }
+
+        $source = PMA_Util::backquote($source_db) . '.' . PMA_Util::backquote($source_table);
+        if (! isset($target_db) || ! strlen($target_db)) {
+            $target_db = $source_db;
+        }
+
+        // Doing a select_db could avoid some problems with replicated databases,
+        // when moving table from replicated one to not replicated one
+        PMA_DBI_select_db($target_db);
+
+        $target = PMA_Util::backquote($target_db) . '.' . PMA_Util::backquote($target_table);
+
+        // do not create the table if dataonly
+        if ($what != 'dataonly') {
+            include_once "libraries/plugin_interface.lib.php";
+            // get Export SQL instance
+            $export_sql_plugin = PMA_getPlugin(
+                "export",
+                "sql",
+                'libraries/plugins/export/',
+                array(
+                    'export_type' => 'table',
+                    'single_table' => isset($single_table)
+                )
+            );
+
+            $no_constraints_comments = true;
+            $GLOBALS['sql_constraints_query'] = '';
+
+            $sql_structure = $export_sql_plugin->getTableDef(
+                $source_db, $source_table, "\n", $err_url, false, false
+            );
+            unset($no_constraints_comments);
+            $parsed_sql =  PMA_SQP_parse($sql_structure);
+            $analyzed_sql = PMA_SQP_analyze($parsed_sql);
+            $i = 0;
+            if (empty($analyzed_sql[0]['create_table_fields'])) {
+                // this is not a CREATE TABLE, so find the first VIEW
+                $target_for_view = PMA_Util::backquote($target_db);
+                while (true) {
+                    if ($parsed_sql[$i]['type'] == 'alpha_reservedWord'
+                        && $parsed_sql[$i]['data'] == 'VIEW'
+                    ) {
+                        break;
+                    }
+                    $i++;
+                }
+            }
+            unset($analyzed_sql);
+            if (PMA_DRIZZLE) {
+                $table_delimiter = 'quote_backtick';
+            } else {
+                $server_sql_mode = PMA_DBI_fetch_value(
+                    "SHOW VARIABLES LIKE 'sql_mode'",
+                    0,
+                    1
+                );
+                // ANSI_QUOTES might be a subset of sql_mode, for example
+                // REAL_AS_FLOAT,PIPES_AS_CONCAT,ANSI_QUOTES,IGNORE_SPACE,ANSI
+                if (false !== strpos($server_sql_mode, 'ANSI_QUOTES')) {
+                    $table_delimiter = 'quote_double';
+                } else {
+                    $table_delimiter = 'quote_backtick';
+                }
+                unset($server_sql_mode);
+            }
+
+            /* Find table name in query and replace it */
+            while ($parsed_sql[$i]['type'] != $table_delimiter) {
+                $i++;
+            }
+
+            /* no need to backquote() */
+            if (isset($target_for_view)) {
+                // this a view definition; we just found the first db name
+                // that follows DEFINER VIEW
+                // so change it for the new db name
+                $parsed_sql[$i]['data'] = $target_for_view;
+                // then we have to find all references to the source db
+                // and change them to the target db, ensuring we stay into
+                // the $parsed_sql limits
+                $last = $parsed_sql['len'] - 1;
+                $backquoted_source_db = PMA_Util::backquote($source_db);
+                for (++$i; $i <= $last; $i++) {
+                    if ($parsed_sql[$i]['type'] == $table_delimiter
+                        && $parsed_sql[$i]['data'] == $backquoted_source_db
+                        && $parsed_sql[$i - 1]['type'] != 'punct_qualifier'
+                    ) {
+                        $parsed_sql[$i]['data'] = $target_for_view;
+                    }
+                }
+                unset($last,$backquoted_source_db);
+            } else {
+                $parsed_sql[$i]['data'] = $target;
+            }
+
+            /* Generate query back */
+            $sql_structure = PMA_SQP_formatHtml($parsed_sql, 'query_only');
+            // If table exists, and 'add drop table' is selected: Drop it!
+            $drop_query = '';
+            if (isset($_REQUEST['drop_if_exists'])
+                && $_REQUEST['drop_if_exists'] == 'true'
+            ) {
+                if (PMA_Table::isView($target_db, $target_table)) {
+                    $drop_query = 'DROP VIEW';
+                } else {
+                    $drop_query = 'DROP TABLE';
+                }
+                $drop_query .= ' IF EXISTS '
+                    . PMA_Util::backquote($target_db) . '.'
+                    . PMA_Util::backquote($target_table);
+                PMA_DBI_query($drop_query);
+
+                $GLOBALS['sql_query'] .= "\n" . $drop_query . ';';
+
+                // If an existing table gets deleted, maintain any
+                // entries for the PMA_* tables
+                $maintain_relations = true;
+            }
+
+            @PMA_DBI_query($sql_structure);
+            $GLOBALS['sql_query'] .= "\n" . $sql_structure . ';';
+
+            if (($move || isset($GLOBALS['add_constraints']))
+                && !empty($GLOBALS['sql_constraints_query'])
+            ) {
+                $parsed_sql =  PMA_SQP_parse($GLOBALS['sql_constraints_query']);
+                $i = 0;
+
+                // find the first $table_delimiter, it must be the source
+                // table name
+                while ($parsed_sql[$i]['type'] != $table_delimiter) {
+                    $i++;
+                    // maybe someday we should guard against going over limit
+                    //if ($i == $parsed_sql['len']) {
+                    //    break;
+                    //}
+                }
+
+                // replace it by the target table name, no need
+                // to backquote()
+                $parsed_sql[$i]['data'] = $target;
+
+                // now we must remove all $table_delimiter that follow a
+                // CONSTRAINT keyword, because a constraint name must be
+                // unique in a db
+
+                $cnt = $parsed_sql['len'] - 1;
+
+                for ($j = $i; $j < $cnt; $j++) {
+                    if ($parsed_sql[$j]['type'] == 'alpha_reservedWord'
+                        && strtoupper($parsed_sql[$j]['data']) == 'CONSTRAINT'
+                    ) {
+                        if ($parsed_sql[$j+1]['type'] == $table_delimiter) {
+                            $parsed_sql[$j+1]['data'] = '';
+                        }
+                    }
+                }
+
+                // Generate query back
+                $GLOBALS['sql_constraints_query'] = PMA_SQP_formatHtml(
+                    $parsed_sql, 'query_only'
+                );
+                if ($mode == 'one_table') {
+                    PMA_DBI_query($GLOBALS['sql_constraints_query']);
+                }
+                $GLOBALS['sql_query'] .= "\n" . $GLOBALS['sql_constraints_query'];
+                if ($mode == 'one_table') {
+                    unset($GLOBALS['sql_constraints_query']);
+                }
+            }
+        } else {
+            $GLOBALS['sql_query'] = '';
+        }
+
+        // Copy the data unless this is a VIEW
+        if (($what == 'data' || $what == 'dataonly')
+            && ! PMA_Table::isView($target_db, $target_table)
+        ) {
+            $sql_set_mode = "SET SQL_MODE='NO_AUTO_VALUE_ON_ZERO'";
+            PMA_DBI_query($sql_set_mode);
+            $GLOBALS['sql_query'] .= "\n\n" . $sql_set_mode . ';';
+
+            $sql_insert_data = 'INSERT INTO ' . $target
+                . ' SELECT * FROM ' . $source;
+            PMA_DBI_query($sql_insert_data);
+            $GLOBALS['sql_query']      .= "\n\n" . $sql_insert_data . ';';
+        }
+
+        $GLOBALS['cfgRelation'] = PMA_getRelationsParam();
+
+        // Drops old table if the user has requested to move it
+        if ($move) {
+
+            // This could avoid some problems with replicated databases, when
+            // moving table from replicated one to not replicated one
+            PMA_DBI_select_db($source_db);
+
+            if (PMA_Table::isView($source_db, $source_table)) {
+                $sql_drop_query = 'DROP VIEW';
+            } else {
+                $sql_drop_query = 'DROP TABLE';
+            }
+            $sql_drop_query .= ' ' . $source;
+            PMA_DBI_query($sql_drop_query);
+
+            // Renable table in configuration storage
+            PMA_REL_renameTable(
+                $source_db, $target_db,
+                $source_table, $target_table
+            );
+
+            $GLOBALS['sql_query']      .= "\n\n" . $sql_drop_query . ';';
+            // end if ($move)
+        } else {
+            // we are copying
+            // Create new entries as duplicates from old PMA DBs
+            if ($what != 'dataonly' && ! isset($maintain_relations)) {
+                if ($GLOBALS['cfgRelation']['commwork']) {
+                    // Get all comments and MIME-Types for current table
+                    $comments_copy_query = 'SELECT
+                                                column_name, comment' . ($GLOBALS['cfgRelation']['mimework'] ? ', mimetype, transformation, transformation_options' : '') . '
+                                            FROM ' . PMA_Util::backquote($GLOBALS['cfgRelation']['db']) . '.' . PMA_Util::backquote($GLOBALS['cfgRelation']['column_info']) . '
+                                            WHERE
+                                                db_name = \'' . PMA_Util::sqlAddSlashes($source_db) . '\' AND
+                                                table_name = \'' . PMA_Util::sqlAddSlashes($source_table) . '\'';
+                    $comments_copy_rs    = PMA_queryAsControlUser($comments_copy_query);
+
+                    // Write every comment as new copied entry. [MIME]
+                    while ($comments_copy_row = PMA_DBI_fetch_assoc($comments_copy_rs)) {
+                        $new_comment_query = 'REPLACE INTO ' . PMA_Util::backquote($GLOBALS['cfgRelation']['db']) . '.' . PMA_Util::backquote($GLOBALS['cfgRelation']['column_info'])
+                                    . ' (db_name, table_name, column_name, comment' . ($GLOBALS['cfgRelation']['mimework'] ? ', mimetype, transformation, transformation_options' : '') . ') '
+                                    . ' VALUES('
+                                    . '\'' . PMA_Util::sqlAddSlashes($target_db) . '\','
+                                    . '\'' . PMA_Util::sqlAddSlashes($target_table) . '\','
+                                    . '\'' . PMA_Util::sqlAddSlashes($comments_copy_row['column_name']) . '\''
+                                    . ($GLOBALS['cfgRelation']['mimework'] ? ',\'' . PMA_Util::sqlAddSlashes($comments_copy_row['comment']) . '\','
+                                            . '\'' . PMA_Util::sqlAddSlashes($comments_copy_row['mimetype']) . '\','
+                                            . '\'' . PMA_Util::sqlAddSlashes($comments_copy_row['transformation']) . '\','
+                                            . '\'' . PMA_Util::sqlAddSlashes($comments_copy_row['transformation_options']) . '\'' : '')
+                                    . ')';
+                        PMA_queryAsControlUser($new_comment_query);
+                    } // end while
+                    PMA_DBI_free_result($comments_copy_rs);
+                    unset($comments_copy_rs);
+                }
+
+                // duplicating the bookmarks must not be done here, but
+                // just once per db
+
+                $get_fields = array('display_field');
+                $where_fields = array(
+                    'db_name' => $source_db,
+                    'table_name' => $source_table
+                );
+                $new_fields = array(
+                    'db_name' => $target_db,
+                    'table_name' => $target_table
+                );
+                PMA_Table::duplicateInfo(
+                    'displaywork',
+                    'table_info',
+                    $get_fields,
+                    $where_fields,
+                    $new_fields
+                );
+
+
+                /**
+                 * @todo revise this code when we support cross-db relations
+                 */
+                $get_fields = array(
+                    'master_field',
+                    'foreign_table',
+                    'foreign_field'
+                );
+                $where_fields = array(
+                    'master_db' => $source_db,
+                    'master_table' => $source_table
+                );
+                $new_fields = array(
+                    'master_db' => $target_db,
+                    'foreign_db' => $target_db,
+                    'master_table' => $target_table
+                );
+                PMA_Table::duplicateInfo(
+                    'relwork',
+                    'relation',
+                    $get_fields,
+                    $where_fields,
+                    $new_fields
+                );
+
+
+                $get_fields = array(
+                    'foreign_field',
+                    'master_table',
+                    'master_field'
+                );
+                $where_fields = array(
+                    'foreign_db' => $source_db,
+                    'foreign_table' => $source_table
+                );
+                $new_fields = array(
+                    'master_db' => $target_db,
+                    'foreign_db' => $target_db,
+                    'foreign_table' => $target_table
+                );
+                PMA_Table::duplicateInfo(
+                    'relwork',
+                    'relation',
+                    $get_fields,
+                    $where_fields,
+                    $new_fields
+                );
+
+
+                $get_fields = array('x', 'y', 'v', 'h');
+                $where_fields = array(
+                    'db_name' => $source_db,
+                    'table_name' => $source_table
+                );
+                $new_fields = array(
+                    'db_name' => $target_db,
+                    'table_name' => $target_table
+                );
+                PMA_Table::duplicateInfo(
+                    'designerwork',
+                    'designer_coords',
+                    $get_fields,
+                    $where_fields,
+                    $new_fields
+                );
+
+                /**
+                 * @todo Can't get duplicating PDFs the right way. The
+                 * page numbers always get screwed up independently from
+                 * duplication because the numbers do not seem to be stored on a
+                 * per-database basis. Would the author of pdf support please
+                 * have a look at it?
+                 *
+                $get_fields = array('page_descr');
+                $where_fields = array('db_name' => $source_db);
+                $new_fields = array('db_name' => $target_db);
+                $last_id = PMA_Table::duplicateInfo(
+                    'pdfwork',
+                    'pdf_pages',
+                    $get_fields,
+                    $where_fields,
+                    $new_fields
+                );
+
+                if (isset($last_id) && $last_id >= 0) {
+                    $get_fields = array('x', 'y');
+                    $where_fields = array(
+                        'db_name' => $source_db,
+                        'table_name' => $source_table
+                    );
+                    $new_fields = array(
+                        'db_name' => $target_db,
+                        'table_name' => $target_table,
+                        'pdf_page_number' => $last_id
+                    );
+                    PMA_Table::duplicateInfo(
+                        'pdfwork',
+                        'table_coords',
+                        $get_fields,
+                        $where_fields,
+                        $new_fields
+                    );
+                }
+                 */
+            }
+        }
+        return true;
+    }
+
+    /**
+     * checks if given name is a valid table name,
+     * currently if not empty, trailing spaces, '.', '/' and '\'
+     *
+     * @param string $table_name name to check
+     *
+     * @todo add check for valid chars in filename on current system/os
+     * @see  http://dev.mysql.com/doc/refman/5.0/en/legal-names.html
+     *
+     * @return boolean whether the string is valid or not
+     */
+    static function isValidName($table_name)
+    {
+        if ($table_name !== trim($table_name)) {
+            // trailing spaces
+            return false;
+        }
+
+        if (! strlen($table_name)) {
+            // zero length
+            return false;
+        }
+
+        if (preg_match('/[.\/\\\\]+/i', $table_name)) {
+            // illegal char . / \
+            return false;
+        }
+
+        return true;
+    }
+
+    /**
+     * renames table
+     *
+     * @param string $new_name new table name
+     * @param string $new_db   new database name
+     *
+     * @return bool success
+     */
+    function rename($new_name, $new_db = null)
+    {
+        if (null !== $new_db && $new_db !== $this->getDbName()) {
+            // Ensure the target is valid
+            if (! $GLOBALS['pma']->databases->exists($new_db)) {
+                $this->errors[] = __('Invalid database') . ': ' . $new_db;
+                return false;
+            }
+        } else {
+            $new_db = $this->getDbName();
+        }
+
+        $new_table = new PMA_Table($new_name, $new_db);
+
+        if ($this->getFullName() === $new_table->getFullName()) {
+            return true;
+        }
+
+        if (! PMA_Table::isValidName($new_name)) {
+            $this->errors[] = __('Invalid table name') . ': '
+                . $new_table->getFullName();
+            return false;
+        }
+
+        // If the table is moved to a different database drop its triggers first
+        $triggers = PMA_DBI_get_triggers($this->getDbName(), $this->getName(), '');
+        $handle_triggers = $this->getDbName() != $new_db && $triggers;
+        if ($handle_triggers) {
+            foreach ($triggers as $trigger) {
+                $sql = 'DROP TRIGGER IF EXISTS ' . PMA_Util::backquote($this->getDbName())
+                    . '.' . PMA_Util::backquote($trigger['name']) . ';';
+                PMA_DBI_query($sql);
+            }
+        }
+
+        /*
+         * tested also for a view, in MySQL 5.0.92, 5.1.55 and 5.5.13
+         */
+        $GLOBALS['sql_query'] = '
+            RENAME TABLE ' . $this->getFullName(true) . '
+                  TO ' . $new_table->getFullName(true) . ';';
+        // I don't think a specific error message for views is necessary
+        if (! PMA_DBI_query($GLOBALS['sql_query'])) {
+            // Restore triggers in the old database
+            if ($handle_triggers) {
+                PMA_DBI_select_db($this->getDbName());
+                foreach ($triggers as $trigger) {
+                    PMA_DBI_query($trigger['create']);
+                }
+            }
+            $this->errors[] = sprintf(
+                __('Error renaming table %1$s to %2$s'),
+                $this->getFullName(),
+                $new_table->getFullName()
+            );
+            return false;
+        }
+
+        $old_name = $this->getName();
+        $old_db = $this->getDbName();
+        $this->setName($new_name);
+        $this->setDbName($new_db);
+
+        // Renable table in configuration storage
+        PMA_REL_renameTable(
+            $old_db, $new_db,
+            $old_name, $new_name
+        );
+
+        $this->messages[] = sprintf(
+            __('Table %1$s has been renamed to %2$s.'),
+            htmlspecialchars($old_name),
+            htmlspecialchars($new_name)
+        );
+        return true;
+    }
+
+    /**
+     * Get all unique columns
+     *
+     * returns an array with all columns with unqiue content, in fact these are
+     * all columns being single indexed in PRIMARY or UNIQUE
+     *
+     * e.g.
+     *  - PRIMARY(id) // id
+     *  - UNIQUE(name) // name
+     *  - PRIMARY(fk_id1, fk_id2) // NONE
+     *  - UNIQUE(x,y) // NONE
+     *
+     * @param bool $backquoted whether to quote name with backticks ``
+     *
+     * @return array
+     */
+    public function getUniqueColumns($backquoted = true)
+    {
+        $sql = PMA_DBI_get_table_indexes_sql(
+            $this->getDbName(),
+            $this->getName(),
+            'Non_unique = 0'
+        );
+        $uniques = PMA_DBI_fetch_result(
+            $sql,
+            array('Key_name', null),
+            'Column_name'
+        );
+
+        $return = array();
+        foreach ($uniques as $index) {
+            if (count($index) > 1) {
+                continue;
+            }
+            $return[] = $this->getFullName($backquoted) . '.'
+                . ($backquoted ? PMA_Util::backquote($index[0]) : $index[0]);
+        }
+
+        return $return;
+    }
+
+    /**
+     * Get all indexed columns
+     *
+     * returns an array with all columns make use of an index, in fact only
+     * first columns in an index
+     *
+     * e.g. index(col1, col2) would only return col1
+     *
+     * @param bool $backquoted whether to quote name with backticks ``
+     *
+     * @return array
+     */
+    public function getIndexedColumns($backquoted = true)
+    {
+        $sql = PMA_DBI_get_table_indexes_sql(
+            $this->getDbName(),
+            $this->getName(),
+            'Seq_in_index = 1'
+        );
+        $indexed = PMA_DBI_fetch_result($sql, 'Column_name', 'Column_name');
+
+        $return = array();
+        foreach ($indexed as $column) {
+            $return[] = $this->getFullName($backquoted) . '.'
+                . ($backquoted ? PMA_Util::backquote($column) : $column);
+        }
+
+        return $return;
+    }
+
+    /**
+     * Get all columns
+     *
+     * returns an array with all columns
+     *
+     * @param bool $backquoted whether to quote name with backticks ``
+     *
+     * @return array
+     */
+    public function getColumns($backquoted = true)
+    {
+        $sql = 'SHOW COLUMNS FROM ' . $this->getFullName(true);
+        $indexed = PMA_DBI_fetch_result($sql, 'Field', 'Field');
+
+        $return = array();
+        foreach ($indexed as $column) {
+            $return[] = $this->getFullName($backquoted) . '.'
+                . ($backquoted ? PMA_Util::backquote($column) : $column);
+        }
+
+        return $return;
+    }
+
+    /**
+     * Return UI preferences for this table from phpMyAdmin database.
+     *
+     * @return array
+     */
+    protected function getUiPrefsFromDb()
+    {
+        $pma_table = PMA_Util::backquote($GLOBALS['cfg']['Server']['pmadb']) ."."
+            . PMA_Util::backquote($GLOBALS['cfg']['Server']['table_uiprefs']);
+
+        // Read from phpMyAdmin database
+        $sql_query = " SELECT `prefs` FROM " . $pma_table
+            . " WHERE `username` = '" . $GLOBALS['cfg']['Server']['user'] . "'"
+            . " AND `db_name` = '" . PMA_Util::sqlAddSlashes($this->db_name) . "'"
+            . " AND `table_name` = '" . PMA_Util::sqlAddSlashes($this->name) . "'";
+
+        $row = PMA_DBI_fetch_array(PMA_queryAsControlUser($sql_query));
+        if (isset($row[0])) {
+            return json_decode($row[0], true);
+        } else {
+            return array();
+        }
+    }
+
+    /**
+     * Save this table's UI preferences into phpMyAdmin database.
+     *
+     * @return true|PMA_Message
+     */
+    protected function saveUiPrefsToDb()
+    {
+        $pma_table = PMA_Util::backquote($GLOBALS['cfg']['Server']['pmadb']) . "."
+            . PMA_Util::backquote($GLOBALS['cfg']['Server']['table_uiprefs']);
+
+        $username = $GLOBALS['cfg']['Server']['user'];
+        $sql_query = " REPLACE INTO " . $pma_table
+            . " VALUES ('" . $username . "', '" . PMA_Util::sqlAddSlashes($this->db_name)
+            . "', '" . PMA_Util::sqlAddSlashes($this->name) . "', '"
+            . PMA_Util::sqlAddSlashes(json_encode($this->uiprefs)) . "', NULL)";
+
+        $success = PMA_DBI_try_query($sql_query, $GLOBALS['controllink']);
+
+        if (!$success) {
+            $message = PMA_Message::error(__('Could not save table UI preferences'));
+            $message->addMessage('<br /><br />');
+            $message->addMessage(
+                PMA_Message::rawError(PMA_DBI_getError($GLOBALS['controllink']))
+            );
+            return $message;
+        }
+
+        // Remove some old rows in table_uiprefs if it exceeds the configured
+        // maximum rows
+        $sql_query = 'SELECT COUNT(*) FROM ' . $pma_table;
+        $rows_count = PMA_DBI_fetch_value($sql_query);
+        $max_rows = $GLOBALS['cfg']['Server']['MaxTableUiprefs'];
+        if ($rows_count > $max_rows) {
+            $num_rows_to_delete = $rows_count - $max_rows;
+            $sql_query
+                = ' DELETE FROM ' . $pma_table .
+                ' ORDER BY last_update ASC' .
+                ' LIMIT ' . $num_rows_to_delete;
+            $success = PMA_DBI_try_query($sql_query, $GLOBALS['controllink']);
+
+            if (!$success) {
+                $message = PMA_Message::error(
+                    sprintf(
+                        __('Failed to cleanup table UI preferences (see $cfg[\'Servers\'][$i][\'MaxTableUiprefs\'] %s)'),
+                        PMA_Util::showDocu('config', 'cfg_Servers_MaxTableUiprefs')
+                    )
+                );
+                $message->addMessage('<br /><br />');
+                $message->addMessage(
+                    PMA_Message::rawError(PMA_DBI_getError($GLOBALS['controllink']))
+                );
+                print_r($message);
+                return $message;
+            }
+        }
+
+        return true;
+    }
+
+    /**
+     * Loads the UI preferences for this table.
+     * If pmadb and table_uiprefs is set, it will load the UI preferences from
+     * phpMyAdmin database.
+     *
+     * @return void
+     */
+    protected function loadUiPrefs()
+    {
+        $server_id = $GLOBALS['server'];
+        // set session variable if it's still undefined
+        if (! isset($_SESSION['tmp_user_values']['table_uiprefs'][$server_id][$this->db_name][$this->name])) {
+            // check whether we can get from pmadb
+            $_SESSION['tmp_user_values']['table_uiprefs'][$server_id][$this->db_name][$this->name]
+                = (strlen($GLOBALS['cfg']['Server']['pmadb'])
+                    && strlen($GLOBALS['cfg']['Server']['table_uiprefs']))
+                    ?  $this->getUiPrefsFromDb()
+                    : array();
+        }
+        $this->uiprefs =& $_SESSION['tmp_user_values']['table_uiprefs'][$server_id]
+            [$this->db_name][$this->name];
+    }
+
+    /**
+     * Get a property from UI preferences.
+     * Return false if the property is not found.
+     * Available property:
+     * - PROP_SORTED_COLUMN
+     * - PROP_COLUMN_ORDER
+     * - PROP_COLUMN_VISIB
+     *
+     * @param string $property property
+     *
+     * @return mixed
+     */
+    public function getUiProp($property)
+    {
+        if (! isset($this->uiprefs)) {
+            $this->loadUiPrefs();
+        }
+        // do checking based on property
+        if ($property == self::PROP_SORTED_COLUMN) {
+            if (isset($this->uiprefs[$property])) {
+                // check if the column name is exist in this table
+                $tmp = explode(' ', $this->uiprefs[$property]);
+                $colname = $tmp[0];
+                $avail_columns = $this->getColumns();
+                foreach ($avail_columns as $each_col) {
+                    // check if $each_col ends with $colname
+                    if (substr_compare($each_col, $colname, strlen($each_col) - strlen($colname)) === 0) {
+                        return $this->uiprefs[$property];
+                    }
+                }
+                // remove the property, since it is not exist anymore in database
+                $this->removeUiProp(self::PROP_SORTED_COLUMN);
+                return false;
+            } else {
+                return false;
+            }
+        } elseif ($property == self::PROP_COLUMN_ORDER
+            || $property == self::PROP_COLUMN_VISIB
+        ) {
+            if (! PMA_Table::isView($this->db_name, $this->name)
+                && isset($this->uiprefs[$property])
+            ) {
+                // check if the table has not been modified
+                if (self::sGetStatusInfo($this->db_name, $this->name, 'Create_time') == $this->uiprefs['CREATE_TIME']) {
+                    return $this->uiprefs[$property];
+                } else {
+                    // remove the property, since the table has been modified
+                    $this->removeUiProp(self::PROP_COLUMN_ORDER);
+                    return false;
+                }
+            } else {
+                return false;
+            }
+        }
+        // default behaviour for other property:
+        return isset($this->uiprefs[$property]) ? $this->uiprefs[$property] : false;
+    }
+
+    /**
+     * Set a property from UI preferences.
+     * If pmadb and table_uiprefs is set, it will save the UI preferences to
+     * phpMyAdmin database.
+     * Available property:
+     * - PROP_SORTED_COLUMN
+     * - PROP_COLUMN_ORDER
+     * - PROP_COLUMN_VISIB
+     *
+     * @param string $property          Property
+     * @param mixed  $value             Value for the property
+     * @param string $table_create_time Needed for PROP_COLUMN_ORDER
+     *                                  and PROP_COLUMN_VISIB
+     *
+     * @return boolean|PMA_Message
+     */
+    public function setUiProp($property, $value, $table_create_time = null)
+    {
+        if (! isset($this->uiprefs)) {
+            $this->loadUiPrefs();
+        }
+        // we want to save the create time if the property is PROP_COLUMN_ORDER
+        if (! PMA_Table::isView($this->db_name, $this->name)
+            && ($property == self::PROP_COLUMN_ORDER
+            || $property == self::PROP_COLUMN_VISIB)
+        ) {
+            $curr_create_time = self::sGetStatusInfo(
+                $this->db_name,
+                $this->name,
+                'CREATE_TIME'
+            );
+            if (isset($table_create_time)
+                && $table_create_time == $curr_create_time
+            ) {
+                $this->uiprefs['CREATE_TIME'] = $curr_create_time;
+            } else {
+                // there is no $table_create_time, or
+                // supplied $table_create_time is older than current create time,
+                // so don't save
+                return PMA_Message::error(
+                    sprintf(
+                        __('Cannot save UI property "%s". The changes made will not be persistent after you refresh this page. Please check if the table structure has been changed.'),
+                        $property
+                    )
+                );
+            }
+        }
+        // save the value
+        $this->uiprefs[$property] = $value;
+        // check if pmadb is set
+        if (strlen($GLOBALS['cfg']['Server']['pmadb'])
+            && strlen($GLOBALS['cfg']['Server']['table_uiprefs'])
+        ) {
+            return $this->saveUiprefsToDb();
+        }
+        return true;
+    }
+
+    /**
+     * Remove a property from UI preferences.
+     *
+     * @param string $property the property
+     *
+     * @return true|PMA_Message
+     */
+    public function removeUiProp($property)
+    {
+        if (! isset($this->uiprefs)) {
+            $this->loadUiPrefs();
+        }
+        if (isset($this->uiprefs[$property])) {
+            unset($this->uiprefs[$property]);
+            // check if pmadb is set
+            if (strlen($GLOBALS['cfg']['Server']['pmadb'])
+                && strlen($GLOBALS['cfg']['Server']['table_uiprefs'])
+            ) {
+                return $this->saveUiprefsToDb();
+            }
+        }
+        return true;
+    }
+
+    /**
+     * Get all column names which are MySQL reserved words
+     * 
+     * @return array
+     * @access public
+     */
+    public function getReservedColumnNames()
+    {
+        $columns = $this->getColumns($backquoted = false);
+        $return = array();
+        foreach ($columns as $column) {
+            $temp = explode('.', $column);
+            $column_name = $temp[2];
+            if (PMA_SQP_isKeyWord($column_name)) {
+                $return[] = $column_name;
+            }
+        }       
+        return $return;
+    }
+}
+?>
diff --git a/phpmyadmin/libraries/TableSearch.class.php b/phpmyadmin/libraries/TableSearch.class.php
new file mode 100644
index 0000000..d9bb830
--- /dev/null
+++ b/phpmyadmin/libraries/TableSearch.class.php
@@ -0,0 +1,1229 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * Handles Table search and Zoom search
+ *
+ * @package PhpMyAdmin
+ */
+if (! defined('PHPMYADMIN')) {
+    exit;
+}
+
+/**
+ * Class to handle normal-search
+ * and zoom-search in a table
+ *
+ * @package PhpMyAdmin
+ */
+class PMA_TableSearch
+{
+    /**
+     * Database name
+     *
+     * @access private
+     * @var string
+     */
+    private $_db;
+    /**
+     * Table name
+     *
+     * @access private
+     * @var string
+     */
+    private $_table;
+    /**
+     * Normal search or Zoom search
+     *
+     * @access private
+     * @var string
+     */
+    private $_searchType;
+    /**
+     * Names of columns
+     *
+     * @access private
+     * @var array
+     */
+    private $_columnNames;
+    /**
+     * Types of columns
+     *
+     * @access private
+     * @var array
+     */
+    private $_columnTypes;
+    /**
+     * Collations of columns
+     *
+     * @access private
+     * @var array
+     */
+    private $_columnCollations;
+    /**
+     * Null Flags of columns
+     *
+     * @access private
+     * @var array
+     */
+    private $_columnNullFlags;
+    /**
+     * Whether a geometry column is present
+     *
+     * @access private
+     * @var boolean
+     */
+    private $_geomColumnFlag;
+    /**
+     * Foreign Keys
+     *
+     * @access private
+     * @var array
+     */
+    private $_foreigners;
+
+
+    /**
+     * Public Constructor
+     *
+     * @param string $db         Database name
+     * @param string $table      Table name
+     * @param string $searchType Whether normal or zoom search
+     */
+    public function __construct($db, $table, $searchType)
+    {
+        $this->_db = $db;
+        $this->_table = $table;
+        $this->_searchType = $searchType;
+        $this->_columnNames = array();
+        $this->_columnNullFlags = array();
+        $this->_columnTypes = array();
+        $this->_columnCollations = array();
+        $this->_geomColumnFlag = false;
+        $this->_foreigners = array();
+        // Loads table's information
+        $this->_loadTableInfo();
+    }
+
+    /**
+     * Returns Column names array
+     *
+     * @return array column names
+     */
+    public function getColumnNames()
+    {
+        return $this->_columnNames;
+    }
+
+    /**
+     * Gets all the columns of a table along with their types, collations
+     * and whether null or not.
+     *
+     * @return void
+     */
+    private function _loadTableInfo()
+    {
+        // Gets the list and number of columns
+        $columns = PMA_DBI_get_columns($this->_db, $this->_table, null, true);
+        // Get details about the geometry fucntions
+        $geom_types = PMA_Util::getGISDatatypes();
+
+        foreach ($columns as $row) {
+            // set column name
+            $this->_columnNames[] = $row['Field'];
+
+            $type = $row['Type'];
+            // check whether table contains geometric columns
+            if (in_array($type, $geom_types)) {
+                $this->_geomColumnFlag = true;
+            }
+            // reformat mysql query output
+            if (strncasecmp($type, 'set', 3) == 0
+                || strncasecmp($type, 'enum', 4) == 0
+            ) {
+                $type = str_replace(',', ', ', $type);
+            } else {
+                // strip the "BINARY" attribute, except if we find "BINARY(" because
+                // this would be a BINARY or VARBINARY column type
+                if (! preg_match('@BINARY[\(]@i', $type)) {
+                    $type = preg_replace('@BINARY at i', '', $type);
+                }
+                $type = preg_replace('@ZEROFILL at i', '', $type);
+                $type = preg_replace('@UNSIGNED at i', '', $type);
+                $type = strtolower($type);
+            }
+            if (empty($type)) {
+                $type = ' ';
+            }
+            $this->_columnTypes[] = $type;
+            $this->_columnNullFlags[] = $row['Null'];
+            $this->_columnCollations[]
+                = ! empty($row['Collation']) && $row['Collation'] != 'NULL'
+                ? $row['Collation']
+                : '';
+        } // end for
+
+        // Retrieve foreign keys
+        $this->_foreigners = PMA_getForeigners($this->_db, $this->_table);
+    }
+
+    /**
+     * Sets the table header for displaying a table in query-by-example format.
+     *
+     * @return HTML content, the tags and content for table header
+     */
+    private function _getTableHeader()
+    {
+        // Display the Function column only if there is at least one geometry column
+        $func = '';
+        if ($this->_geomColumnFlag) {
+            $func = '<th>' . __('Function') . '</th>';
+        }
+
+        return '<thead>
+            <tr>' . $func . '<th>' .  __('Column') . '</th>
+            <th>' .  __('Type') . '</th>
+            <th>' .  __('Collation') . '</th>
+            <th>' .  __('Operator') . '</th>
+            <th>' .  __('Value') . '</th>
+            </tr>
+            </thead>';
+    }
+
+    /**
+     * Returns an array with necessary configrations to create
+     * sub-tabs(Table Search and Zoom Search) in the table_select page.
+     *
+     * @return array Array containing configuration (icon, text, link, id, args)
+     * of sub-tabs for Table Search and Zoom search
+     */
+    private function _getSubTabs()
+    {
+        $subtabs = array();
+        $subtabs['search']['icon'] = 'b_search.png';
+        $subtabs['search']['text'] = __('Table Search');
+        $subtabs['search']['link'] = 'tbl_select.php';
+        $subtabs['search']['id'] = 'tbl_search_id';
+        $subtabs['search']['args']['pos'] = 0;
+
+        $subtabs['zoom']['icon'] = 'b_props.png';
+        $subtabs['zoom']['link'] = 'tbl_zoom_select.php';
+        $subtabs['zoom']['text'] = __('Zoom Search');
+        $subtabs['zoom']['id'] = 'zoom_search_id';
+
+        return $subtabs;
+    }
+
+    /**
+     * Provides html elements for search criteria inputbox
+     * in case the column's type is geometrical
+     *
+     * @param int  $column_index Column's index
+     * @param bool $in_fbs       Whether we are in 'function based search'
+     *
+     * @return HTML elements.
+     */
+    private function _getGeometricalInputBox($column_index, $in_fbs)
+    {
+        $html_output = '<input type="text" name="criteriaValues[' . $column_index . ']"'
+            . ' size="40" class="textfield" id="field_' . $column_index . '" />';
+
+        if ($in_fbs) {
+            $edit_url = 'gis_data_editor.php?' . PMA_generate_common_url();
+            $edit_str = PMA_Util::getIcon('b_edit.png', __('Edit/Insert'));
+            $html_output .= '<span class="open_search_gis_editor">';
+            $html_output .= PMA_Util::linkOrButton(
+                $edit_url, $edit_str, array(), false, false, '_blank'
+            );
+            $html_output .= '</span>';
+        }
+        return $html_output;
+    }
+
+    /**
+     * Provides html elements for search criteria inputbox
+     * in case the column is a Foreign Key
+     *
+     * @param array  $foreignData         Foreign keys data
+     * @param string $column_name         Column name
+     * @param int    $column_index        Column index
+     * @param array  $titles              Selected title
+     * @param int    $foreignMaxLimit     Max limit of displaying foreign elements
+     * @param array  $criteriaValues      Array of search criteria inputs
+     * @param string $column_id           Column's inputbox's id
+     * @param bool   $in_zoom_search_edit Whether we are in zoom search edit
+     *
+     * @return HTML elements.
+     */
+    private function _getForeignKeyInputBox($foreignData, $column_name,
+        $column_index, $titles, $foreignMaxLimit, $criteriaValues, $column_id,
+        $in_zoom_search_edit = false
+    ) {
+        $html_output = '';
+        if (is_array($foreignData['disp_row'])) {
+            $html_output .=  '<select name="criteriaValues[' . $column_index . ']"'
+                . ' id="' . $column_id . $column_index .'">';
+            $html_output .= PMA_foreignDropdown(
+                $foreignData['disp_row'], $foreignData['foreign_field'],
+                $foreignData['foreign_display'], '', $foreignMaxLimit
+            );
+            $html_output .= '</select>';
+
+        } elseif ($foreignData['foreign_link'] == true) {
+            $html_output .= '<input type="text" id="' . $column_id . $column_index . '"'
+                . ' name="criteriaValues[' . $column_index . ']" id="field_'
+                . md5($column_name) . '[' . $column_index .']" class="textfield"'
+                . (isset($criteriaValues[$column_index])
+                    && is_string($criteriaValues[$column_index])
+                    ? (' value="' . $criteriaValues[$column_index] . '"')
+                    : '')
+                . ' />';
+
+            $html_output .=  <<<EOT
+<a target="_blank" onclick="window.open(this.href, 'foreigners', 'width=640,height=240,scrollbars=yes'); return false" href="browse_foreigners.php?
+EOT;
+            $html_output .= '' . PMA_generate_common_url($this->_db, $this->_table)
+                . '&field=' . urlencode($column_name) . '&fieldkey='
+                . $column_index . '"';
+            if ($in_zoom_search_edit) {
+                $html_output .= ' class="browse_foreign"';
+            }
+            $html_output .= '>' . str_replace("'", "\'", $titles['Browse']) . '</a>';
+        }
+        return $html_output;
+    }
+
+    /**
+     * Provides html elements for search criteria inputbox
+     * in case the column is of ENUM or SET type
+     *
+     * @param int    $column_index        Column index
+     * @param array  $criteriaValues      Array of search criteria inputs
+     * @param string $column_type         Column type
+     * @param string $column_id           Column's inputbox's id
+     * @param bool   $in_zoom_search_edit Whether we are in zoom search edit
+     *
+     * @return HTML elements.
+     */
+    private function _getEnumSetInputBox($column_index, $criteriaValues,
+        $column_type, $column_id, $in_zoom_search_edit = false
+    ) {
+        $html_output = '';
+        $value = explode(
+            ', ',
+            str_replace("'", '', substr($column_type, 5, -1))
+        );
+        $cnt_value = count($value);
+
+        /*
+         * Enum in edit mode   --> dropdown
+         * Enum in search mode --> multiselect
+         * Set in edit mode    --> multiselect
+         * Set in search mode  --> input (skipped here, so the 'else'
+         *                                 section would handle it)
+         */
+        if ((strncasecmp($column_type, 'enum', 4) && ! $in_zoom_search_edit)
+            || (strncasecmp($column_type, 'set', 3) && $in_zoom_search_edit)
+        ) {
+            $html_output .= '<select name="criteriaValues[' . ($column_index)
+                . ']" id="' . $column_id . $column_index .'">';
+        } else {
+            $html_output .= '<select name="criteriaValues[' . $column_index . ']"'
+                . ' id="' . $column_id . $column_index . '" multiple="multiple"'
+                . ' size="' . min(3, $cnt_value) . '">';
+        }
+
+        //Add select options
+        for ($j = 0; $j < $cnt_value; $j++) {
+            if (isset($criteriaValues[$column_index])
+                && is_array($criteriaValues[$column_index])
+                && in_array($value[$j], $criteriaValues[$column_index])
+            ) {
+                $html_output .= '<option value="' . $value[$j] . '" Selected>'
+                    . $value[$j] . '</option>';
+            } else {
+                $html_output .= '<option value="' . $value[$j] . '">'
+                    . $value[$j] . '</option>';
+            }
+        } // end for
+        $html_output .= '</select>';
+        return $html_output;
+    }
+
+    /**
+     * Creates the HTML content for:
+     * 1) Browsing foreign data for a column.
+     * 2) Creating elements for search criteria input on columns.
+     *
+     * @param array  $foreignData         Foreign keys data
+     * @param string $column_name         Column name
+     * @param string $column_type         Column type
+     * @param int    $column_index        Column index
+     * @param array  $titles              Selected title
+     * @param int    $foreignMaxLimit     Max limit of displaying foreign elements
+     * @param array  $criteriaValues      Array of search criteria inputs
+     * @param bool   $in_fbs              Whether we are in 'function based search'
+     * @param bool   $in_zoom_search_edit Whether we are in zoom search edit
+     *
+     * @return string HTML content for viewing foreign data and elements
+     * for search criteria input.
+     */
+    private function _getInputbox($foreignData, $column_name, $column_type,
+        $column_index, $titles, $foreignMaxLimit, $criteriaValues, $in_fbs = false,
+        $in_zoom_search_edit = false
+    ) {
+        $str = '';
+        $column_type = (string)$column_type;
+        $column_id = ($in_zoom_search_edit) ? 'edit_fieldID_' : 'fieldID_';
+
+        // Get inputbox based on different column types
+        // (Foreign key, geometrical, enum)
+        if ($this->_foreigners && isset($this->_foreigners[$column_name])) {
+            $str .= $this->_getForeignKeyInputBox(
+                $foreignData, $column_name, $column_index, $titles,
+                $foreignMaxLimit, $criteriaValues, $column_id
+            );
+
+        } elseif (in_array($column_type, PMA_Util::getGISDatatypes())) {
+            $str .= $this->_getGeometricalInputBox($column_index, $in_fbs);
+
+        } elseif (strncasecmp($column_type, 'enum', 4) == 0
+            || (strncasecmp($column_type, 'set', 3) == 0 && $in_zoom_search_edit)
+        ) {
+            $str .= $this->_getEnumSetInputBox(
+                $column_index, $criteriaValues, $column_type, $column_id,
+                $in_zoom_search_edit = false
+            );
+
+        } else {
+            // other cases
+            $the_class = 'textfield';
+
+            if ($column_type == 'date') {
+                $the_class .= ' datefield';
+            } elseif ($column_type == 'datetime'
+                || substr($column_type, 0, 9) == 'timestamp'
+            ) {
+                $the_class .= ' datetimefield';
+            } elseif (substr($column_type, 0, 3) == 'bit') {
+                $the_class .= ' bit';
+            }
+
+            $str .= '<input type="text" name="criteriaValues[' . $column_index . ']"'
+                .' size="40" class="' . $the_class . '" id="'
+                . $column_id . $column_index . '"'
+                . (isset($criteriaValues[$column_index])
+                    && is_string($criteriaValues[$column_index])
+                    ? (' value="' . $criteriaValues[$column_index] . '"')
+                    : '')
+                . ' />';
+        }
+        return $str;
+    }
+
+    /**
+     * Return the where clause in case column's type is ENUM.
+     *
+     * @param mixed  $criteriaValues Search criteria input
+     * @param string $func_type      Search function/operator
+     *
+     * @return string part of where clause.
+     */
+    private function _getEnumWhereClause($criteriaValues, $func_type)
+    {
+        if (! is_array($criteriaValues)) {
+            $criteriaValues = explode(',', $criteriaValues);
+        }
+        $enum_selected_count = count($criteriaValues);
+        if ($func_type == '=' && $enum_selected_count > 1) {
+            $func_type    = 'IN';
+            $parens_open  = '(';
+            $parens_close = ')';
+
+        } elseif ($func_type == '!=' && $enum_selected_count > 1) {
+            $func_type    = 'NOT IN';
+            $parens_open  = '(';
+            $parens_close = ')';
+
+        } else {
+            $parens_open  = '';
+            $parens_close = '';
+        }
+        $enum_where = '\''
+            . PMA_Util::sqlAddSlashes($criteriaValues[0]) . '\'';
+        for ($e = 1; $e < $enum_selected_count; $e++) {
+            $enum_where .= ', \''
+                . PMA_Util::sqlAddSlashes($criteriaValues[$e]) . '\'';
+        }
+
+        return ' ' . $func_type . ' ' . $parens_open
+            . $enum_where . $parens_close;
+    }
+
+    /**
+     * Return the where clause for a geometrical column.
+     *
+     * @param mixed  $criteriaValues Search criteria input
+     * @param string $names          Name of the column on which search is submitted
+     * @param string $func_type      Search function/operator
+     * @param string $types          Type of the field
+     * @param bool   $geom_func      Whether geometry functions should be applied
+     *
+     * @return string part of where clause.
+     */
+    private function _getGeomWhereClause($criteriaValues, $names,
+        $func_type, $types, $geom_func = null
+    ) {
+        $geom_unary_functions = array(
+            'IsEmpty' => 1,
+            'IsSimple' => 1,
+            'IsRing' => 1,
+            'IsClosed' => 1,
+        );
+        $where = '';
+
+        // Get details about the geometry functions
+        $geom_funcs = PMA_Util::getGISFunctions($types, true, false);
+        // New output type is the output type of the function being applied
+        $types = $geom_funcs[$geom_func]['type'];
+
+        // If the function takes a single parameter
+        if ($geom_funcs[$geom_func]['params'] == 1) {
+            $backquoted_name = $geom_func . '(' . PMA_Util::backquote($names) . ')';
+        } else {
+            // If the function takes two parameters
+            // create gis data from the criteria input
+            $gis_data = PMA_Util::createGISData($criteriaValues);
+            $where = $geom_func . '(' . PMA_Util::backquote($names) . ',' . $gis_data . ')';
+            return $where;
+        }
+
+        // If the where clause is something like 'IsEmpty(`spatial_col_name`)'
+        if (isset($geom_unary_functions[$geom_func])
+            && trim($criteriaValues) == ''
+        ) {
+            $where = $backquoted_name;
+
+        } elseif (in_array($types, PMA_Util::getGISDatatypes())
+            && ! empty($criteriaValues)
+        ) {
+            // create gis data from the criteria input
+            $gis_data = PMA_Util::createGISData($criteriaValues);
+            $where = $backquoted_name . ' ' . $func_type . ' ' . $gis_data;
+        }
+        return $where;
+    }
+
+    /**
+     * Return the where clause for query generation based on the inputs provided.
+     *
+     * @param mixed  $criteriaValues Search criteria input
+     * @param string $names          Name of the column on which search is submitted
+     * @param string $types          Type of the field
+     * @param string $collations     Field collation
+     * @param string $func_type      Search function/operator
+     * @param bool   $unaryFlag      Whether operator unary or not
+     * @param bool   $geom_func      Whether geometry functions should be applied
+     *
+     * @return string generated where clause.
+     */
+    private function _getWhereClause($criteriaValues, $names, $types, $collations,
+        $func_type, $unaryFlag, $geom_func = null
+    ) {
+        // If geometry function is set
+        if ($geom_func != null && trim($geom_func) != '') {
+            return $this->_getGeomWhereClause(
+                $criteriaValues, $names, $func_type, $types, $geom_func
+            );
+        }
+
+        $backquoted_name = PMA_Util::backquote($names);
+        $where = '';
+        if ($unaryFlag) {
+            $criteriaValues = '';
+            $where = $backquoted_name . ' ' . $func_type;
+
+        } elseif (strncasecmp($types, 'enum', 4) == 0 && ! empty($criteriaValues)) {
+            $where = $backquoted_name;
+            $where .= $this->_getEnumWhereClause($criteriaValues, $func_type);
+
+        } elseif ($criteriaValues != '') {
+            // For these types we quote the value. Even if it's another type
+            // (like INT), for a LIKE we always quote the value. MySQL converts
+            // strings to numbers and numbers to strings as necessary
+            // during the comparison
+            if (preg_match('@char|binary|blob|text|set|date|time|year at i', $types)
+                || strpos(' ' . $func_type, 'LIKE')
+            ) {
+                $quot = '\'';
+            } else {
+                $quot = '';
+            }
+
+            // LIKE %...%
+            if ($func_type == 'LIKE %...%') {
+                $func_type = 'LIKE';
+                $criteriaValues = '%' . $criteriaValues . '%';
+            }
+            if ($func_type == 'REGEXP ^...$') {
+                $func_type = 'REGEXP';
+                $criteriaValues = '^' . $criteriaValues . '$';
+            }
+
+            if ($func_type == 'IN (...)'
+                || $func_type == 'NOT IN (...)'
+                || $func_type == 'BETWEEN'
+                || $func_type == 'NOT BETWEEN'
+            ) {
+                $func_type = str_replace(' (...)', '', $func_type);
+
+                // quote values one by one
+                $values = explode(',', $criteriaValues);
+                foreach ($values as &$value) {
+                    $value = $quot . PMA_Util::sqlAddSlashes(trim($value))
+                        . $quot;
+                }
+
+                if ($func_type == 'BETWEEN' || $func_type == 'NOT BETWEEN') {
+                    $where = $backquoted_name . ' ' . $func_type . ' '
+                        . (isset($values[0]) ? $values[0] : '')
+                        . ' AND ' . (isset($values[1]) ? $values[1] : '');
+                } else {
+                    $where = $backquoted_name . ' ' . $func_type
+                        . ' (' . implode(',', $values) . ')';
+                }
+            } else {
+                if ($func_type == 'LIKE %...%' || $func_type == 'LIKE') {
+                    $where = $backquoted_name . ' ' . $func_type . ' ' . $quot
+                        . PMA_Util::sqlAddSlashes($criteriaValues, true) . $quot;
+                } else {
+                    $where = $backquoted_name . ' ' . $func_type . ' ' . $quot
+                        . PMA_Util::sqlAddSlashes($criteriaValues) . $quot;
+                }
+            }
+        } // end if
+
+        return $where;
+    }
+
+    /**
+     * Builds the sql search query from the post parameters
+     *
+     * @return string the generated SQL query
+     */
+    public function buildSqlQuery()
+    {
+        $sql_query = 'SELECT ';
+
+        // If only distinct values are needed
+        $is_distinct = (isset($_POST['distinct'])) ? 'true' : 'false';
+        if ($is_distinct == 'true') {
+            $sql_query .= 'DISTINCT ';
+        }
+
+        // if all column names were selected to display, we do a 'SELECT *'
+        // (more efficient and this helps prevent a problem in IE
+        // if one of the rows is edited and we come back to the Select results)
+        if (isset($_POST['zoom_submit']) || ! empty($_POST['displayAllColumns'])) {
+            $sql_query .= '* ';
+        } else {
+            $sql_query .= implode(
+                ', ',
+                PMA_Util::backquote($_POST['columnsToDisplay'])
+            );
+        } // end if
+
+        $sql_query .= ' FROM '
+            . PMA_Util::backquote($_POST['table']);
+        $whereClause = $this->_generateWhereClause();
+        $sql_query .= $whereClause;
+
+        // if the search results are to be ordered
+        if (isset($_POST['orderByColumn']) && $_POST['orderByColumn'] != '--nil--') {
+            $sql_query .= ' ORDER BY '
+                . PMA_Util::backquote($_POST['orderByColumn'])
+                . ' ' . $_POST['order'];
+        } // end if
+        return $sql_query;
+    }
+
+    /**
+     * Generates the where clause for the SQL search query to be executed
+     *
+     * @return string the generated where clause
+     */
+    private function _generateWhereClause()
+    {
+        if (isset($_POST['customWhereClause'])
+            && trim($_POST['customWhereClause']) != ''
+        ) {
+            return ' WHERE ' . $_POST['customWhereClause'];
+        }
+
+        // If there are no search criteria set or no unary criteria operators, return
+        if (! isset($_POST['criteriaValues'])
+            && ! isset($_POST['criteriaColumnOperators'])
+        ) {
+            return '';
+        }
+
+        // else continue to form the where clause from column criteria values
+        $fullWhereClause = $charsets = array();
+        reset($_POST['criteriaColumnOperators']);
+        while (list($column_index, $operator) = each($_POST['criteriaColumnOperators'])) {
+            list($charsets[$column_index]) = explode(
+                '_', $_POST['criteriaColumnCollations'][$column_index]
+            );
+            $unaryFlag =  $GLOBALS['PMA_Types']->isUnaryOperator($operator);
+            $tmp_geom_func = isset($geom_func[$column_index])
+                ? $geom_func[$column_index] : null;
+
+            $whereClause = $this->_getWhereClause(
+                $_POST['criteriaValues'][$column_index],
+                $_POST['criteriaColumnNames'][$column_index],
+                $_POST['criteriaColumnTypes'][$column_index],
+                $_POST['criteriaColumnCollations'][$column_index],
+                $operator,
+                $unaryFlag,
+                $tmp_geom_func
+            );
+
+            if ($whereClause) {
+                $fullWhereClause[] = $whereClause;
+            }
+        } // end while
+
+        if ($fullWhereClause) {
+            return ' WHERE ' . implode(' AND ', $fullWhereClause);
+        }
+        return '';
+    }
+
+    /**
+     * Generates HTML for a geometrical function column to be displayed in table
+     * search selection form
+     *
+     * @param integer $column_index index of current column in $columnTypes array
+     *
+     * @return string the generated HTML
+     */
+    private function _getGeomFuncHtml($column_index)
+    {
+        $html_output = '';
+        // return if geometrical column is not present
+        if (! $this->_geomColumnFlag) {
+            return $html_output;
+        }
+
+        /**
+         * Displays 'Function' column if it is present
+         */
+        $html_output .= '<td>';
+        $geom_types = PMA_Util::getGISDatatypes();
+        // if a geometry column is present
+        if (in_array($this->_columnTypes[$column_index], $geom_types)) {
+            $html_output .= '<select class="geom_func" name="geom_func['
+                . $column_index . ']">';
+            // get the relevant list of GIS functions
+            $funcs = PMA_Util::getGISFunctions($this->_columnTypes[$column_index], true, true);
+            /**
+             * For each function in the list of functions,
+             * add an option to select list
+             */
+            foreach ($funcs as $func_name => $func) {
+                $name = isset($func['display']) ? $func['display'] : $func_name;
+                $html_output .= '<option value="' . htmlspecialchars($name) . '">'
+                        . htmlspecialchars($name) . '</option>';
+            }
+            $html_output .= '</select>';
+        } else {
+            $html_output .= ' ';
+        }
+        $html_output .= '</td>';
+        return $html_output;
+    }
+
+    /**
+     * Generates formatted HTML for extra search options in table search form
+     *
+     * @return string the generated HTML
+     */
+    private function _getOptions()
+    {
+        $html_output = '';
+        $html_output .= PMA_Util::getDivForSliderEffect(
+            'searchoptions', __('Options')
+        );
+
+        /**
+         * Displays columns select list for selecting distinct columns in the search
+         */
+        $html_output .= '<fieldset id="fieldset_select_fields">'
+            . '<legend>' . __('Select columns (at least one):') . '</legend>'
+            . '<select name="columnsToDisplay[]"'
+            . ' size="' . min(count($this->_columnNames), 10) . '"'
+            . ' multiple="multiple">';
+        // Displays the list of the fields
+        foreach ($this->_columnNames as $each_field) {
+            $html_output .= '        '
+                . '<option value="' . htmlspecialchars($each_field) . '"'
+                . ' selected="selected">' . htmlspecialchars($each_field)
+                . '</option>' . "\n";
+        } // end for
+        $html_output .= '</select>'
+            . '<input type="checkbox" name="distinct" value="DISTINCT" id="oDistinct" />'
+            . '<label for="oDistinct">DISTINCT</label></fieldset>';
+
+        /**
+         * Displays input box for custom 'Where' clause to be used in the search
+         */
+        $html_output .= '<fieldset id="fieldset_search_conditions">'
+            . '<legend>' . '<em>' . __('Or') . '</em> '
+            . __('Add search conditions (body of the "where" clause):') . '</legend>';
+        $html_output .= PMA_Util::showMySQLDocu(
+            'SQL-Syntax', 'Functions'
+        );
+        $html_output .= '<input type="text" name="customWhereClause"'
+            . ' class="textfield" size="64" />';
+        $html_output .= '</fieldset>';
+
+        /**
+         * Displays option of changing default number of rows displayed per page
+         */
+        $html_output .= '<fieldset id="fieldset_limit_rows">'
+            . '<legend>' . __('Number of rows per page') . '</legend>'
+            . '<input type="text" size="4" name="session_max_rows" '
+            . 'value="' . $GLOBALS['cfg']['MaxRows'] . '" class="textfield" />'
+            . '</fieldset>';
+
+        /**
+         * Displays option for ordering search results
+         * by a column value (Asc or Desc)
+         */
+        $html_output .= '<fieldset id="fieldset_display_order">'
+            . '<legend>' . __('Display order:') . '</legend>'
+            . '<select name="orderByColumn"><option value="--nil--"></option>';
+        foreach ($this->_columnNames as $each_field) {
+            $html_output .= '        '
+                . '<option value="' . htmlspecialchars($each_field) . '">'
+                . htmlspecialchars($each_field) . '</option>' . "\n";
+        } // end for
+        $html_output .= '</select>';
+        $choices = array(
+            'ASC' => __('Ascending'),
+            'DESC' => __('Descending')
+        );
+        $html_output .= PMA_Util::getRadioFields(
+            'order', $choices, 'ASC', false, true, "formelement"
+        );
+        unset($choices);
+
+        $html_output .= '</fieldset><br style="clear: both;"/></div>';
+        return $html_output;
+    }
+
+    /**
+     * Other search criteria like data label
+     * (for tbl_zoom_select.php)
+     *
+     * @param array $dataLabel Label for points in zoom plot
+     *
+     * @return string the generated html
+     */
+    private function _getOptionsZoom($dataLabel)
+    {
+        $html_output = '';
+        $html_output .= '<table class="data">';
+        //Select options for datalabel
+        $html_output .= '<tr>';
+        $html_output .= '<td><label for="dataLabel">'
+            . __("Use this column to label each point") . '</label></td>';
+        $html_output .= '<td><select name="dataLabel" id="dataLabel" >'
+            . '<option value = "">' . __('None') . '</option>';
+        for ($j = 0; $j < count($this->_columnNames); $j++) {
+            if (isset($dataLabel)
+                && $dataLabel == htmlspecialchars($this->_columnNames[$j])
+            ) {
+                $html_output .= '<option value="'
+                    . htmlspecialchars($this->_columnNames[$j]) . '" selected="selected">'
+                    . htmlspecialchars($this->_columnNames[$j]) . '</option>';
+            } else {
+                $html_output .= '<option value="'
+                    . htmlspecialchars($this->_columnNames[$j]) . '" >'
+                    . htmlspecialchars($this->_columnNames[$j]) . '</option>';
+            }
+        }
+        $html_output .= '</select></td>';
+        $html_output .= '</tr>';
+        //Inputbox for changing default maximum rows to plot
+        $html_output .= '<tr>';
+        $html_output .= '<td><label for="maxRowPlotLimit">'
+            . __("Maximum rows to plot") . '</label></td>';
+        $html_output .= '<td>';
+        $html_output .= '<input type="text" name="maxPlotLimit"'
+            . ' id="maxRowPlotLimit"'
+            . ' value="' . ((! empty($_POST['maxPlotLimit']))
+                ? htmlspecialchars($_POST['maxPlotLimit'])
+                : $GLOBALS['cfg']['maxRowPlotLimit'])
+            . '" />';
+        $html_output .= '</td></tr>';
+        $html_output .= '</table>';
+        return $html_output;
+    }
+
+    /**
+     * Provides a column's type, collation, operators list, and crietria value
+     * to display in table search form
+     *
+     * @param integer $search_index Row number in table search form
+     * @param integer $column_index Column index in ColumnNames array
+     *
+     * @return array Array contaning column's properties
+     */
+    public function getColumnProperties($search_index, $column_index)
+    {
+        $selected_operator = (isset($_POST['criteriaColumnOperators'])
+            ? $_POST['criteriaColumnOperators'][$search_index] : '');
+        $entered_value = (isset($_POST['criteriaValues'])
+            ? $_POST['criteriaValues'] : '');
+        $titles['Browse'] = PMA_Util::getIcon('b_browse.png', __('Browse foreign values'));
+        //Gets column's type and collation
+        $type = $this->_columnTypes[$column_index];
+        $collation = $this->_columnCollations[$column_index];
+        //Gets column's comparison operators depending on column type
+        $func = '<select name="criteriaColumnOperators[' . $search_index . ']">';
+        $func .= $GLOBALS['PMA_Types']->getTypeOperatorsHtml(
+            preg_replace('@\(.*@s', '', $this->_columnTypes[$column_index]),
+            $this->_columnNullFlags[$column_index], $selected_operator
+        );
+        $func .= '</select>';
+        //Gets link to browse foreign data(if any) and criteria inputbox
+        $foreignData = PMA_getForeignData(
+            $this->_foreigners, $this->_columnNames[$column_index], false, '', ''
+        );
+        $value =  $this->_getInputbox(
+            $foreignData, $this->_columnNames[$column_index], $type, $search_index,
+            $titles, $GLOBALS['cfg']['ForeignKeyMaxLimit'], $entered_value
+        );
+        return array(
+            'type' => $type,
+            'collation' => $collation,
+            'func' => $func,
+            'value' => $value
+        );
+    }
+
+    /**
+     * Provides the search form's table row in case of Normal Search
+     * (for tbl_select.php)
+     *
+     * @return string the generated table row
+     */
+    private function _getRowsNormal()
+    {
+        $odd_row = true;
+        $html_output = '';
+        // for every column present in table
+        for ($column_index = 0; $column_index < count($this->_columnNames); $column_index++) {
+            $html_output .= '<tr class="noclick ' . ($odd_row ? 'odd' : 'even') . '">';
+            $odd_row = !$odd_row;
+            //If 'Function' column is present
+            $html_output .= $this->_getGeomFuncHtml($column_index);
+            //Displays column's name, type, collation and value
+            $html_output .= '<th>'
+                . htmlspecialchars($this->_columnNames[$column_index]) . '</th>';
+            $properties = $this->getColumnProperties($column_index, $column_index);
+            $html_output .= '<td>' . $properties['type'] . '</td>';
+            $html_output .= '<td>' . $properties['collation'] . '</td>';
+            $html_output .= '<td>' . $properties['func'] . '</td>';
+            $html_output .= '<td>' . $properties['value'] . '</td>';
+            $html_output .= '</tr>';
+            //Displays hidden fields
+            $html_output .= '<tr><td>';
+            $html_output .= '<input type="hidden"'
+                . ' name="criteriaColumnNames[' . $column_index . ']"'
+                . ' value="' . htmlspecialchars($this->_columnNames[$column_index])
+                . '" />';
+            $html_output .= '<input type="hidden"'
+                . ' name="criteriaColumnTypes[' . $column_index . ']"'
+                . ' value="' . $this->_columnTypes[$column_index] . '" />';
+            $html_output .= '<input type="hidden"'
+                . ' name="criteriaColumnCollations[' . $column_index . ']"'
+                . ' value="' . $this->_columnCollations[$column_index] . '" />';
+            $html_output .= '</td></tr>';
+        } // end for
+
+        return $html_output;
+    }
+
+    /**
+     * Provides the search form's table row in case of Zoom Search
+     * (for tbl_zoom_select.php)
+     *
+     * @return string the generated table row
+     */
+    private function _getRowsZoom()
+    {
+        $odd_row = true;
+        $html_output = '';
+        /**
+         * Get already set search criteria (if any)
+         */
+
+        //Displays column rows for search criteria input
+        for ($i = 0; $i < 4; $i++) {
+            //After X-Axis and Y-Axis column rows, display additional criteria option
+            if ($i == 2) {
+                $html_output .= '<tr><td>';
+                $html_output .= __("Additional search criteria");
+                $html_output .= '</td></tr>';
+            }
+            $html_output .= '<tr class="noclick ' . ($odd_row ? 'odd' : 'even') . '">';
+            $odd_row = ! $odd_row;
+            //Select options for column names
+            $html_output .= '<th><select name="criteriaColumnNames[]" id="'
+                . 'tableid_' . $i . '" >';
+            $html_output .= '<option value="' . 'pma_null' . '">' . __('None')
+                . '</option>';
+            for ($j = 0 ; $j < count($this->_columnNames); $j++) {
+                if (isset($_POST['criteriaColumnNames'][$i])
+                    && $_POST['criteriaColumnNames'][$i] == htmlspecialchars($this->_columnNames[$j])
+                ) {
+                    $html_output .= '<option value="'
+                        . htmlspecialchars($this->_columnNames[$j]) . '" selected="selected">'
+                        . htmlspecialchars($this->_columnNames[$j]) . '</option>';
+                } else {
+                    $html_output .= '<option value="'
+                        . htmlspecialchars($this->_columnNames[$j]) . '">'
+                        . htmlspecialchars($this->_columnNames[$j]) . '</option>';
+                }
+            }
+            $html_output .= '</select></th>';
+            if (isset($_POST['criteriaColumnNames'])
+                && $_POST['criteriaColumnNames'][$i] != 'pma_null'
+            ) {
+                $key = array_search(
+                    $_POST['criteriaColumnNames'][$i],
+                    $this->_columnNames
+                );
+                $properties = $this->getColumnProperties($i, $key);
+                $type[$i] = $properties['type'];
+                $collation[$i] = $properties['collation'];
+                $func[$i] = $properties['func'];
+                $value[$i] = $properties['value'];
+            }
+            //Column type
+            $html_output .= '<td>' . (isset($type[$i]) ? $type[$i] : '') . '</td>';
+            //Column Collation
+            $html_output .= '<td>' . (isset($collation[$i]) ? $collation[$i] : '')
+                . '</td>';
+            //Select options for column operators
+            $html_output .= '<td>' . (isset($func[$i]) ? $func[$i] : '') . '</td>';
+            //Inputbox for search criteria value
+            $html_output .= '<td>' . (isset($value[$i]) ? $value[$i] : '') . '</td>';
+            $html_output .= '</tr>';
+            //Displays hidden fields
+            $html_output .= '<tr><td>';
+            $html_output .= '<input type="hidden" name="criteriaColumnTypes[' . $i . ']"'
+                . ' id="types_' . $i . '" ';
+            if (isset($_POST['criteriaColumnTypes'][$i])) {
+                $html_output .= 'value="' . $_POST['criteriaColumnTypes'][$i] . '" ';
+            }
+            $html_output .= '/>';
+            $html_output .= '<input type="hidden" name="criteriaColumnCollations['
+                . $i . ']" id="collations_' . $i . '" />';
+            $html_output .= '</td></tr>';
+        }//end for
+        return $html_output;
+    }
+
+    /**
+     * Generates HTML for displaying fields table in search form
+     *
+     * @return string the generated HTML
+     */
+    private function _getFieldsTableHtml()
+    {
+        $html_output = '';
+        $html_output .= '<table class="data"'
+            . ($this->_searchType == 'zoom' ? ' id="tableFieldsId"' : '') . '>';
+        $html_output .= $this->_getTableHeader();
+        $html_output .= '<tbody>';
+
+        if ($this->_searchType == 'zoom') {
+            $html_output .= $this->_getRowsZoom();
+        } else {
+            $html_output .= $this->_getRowsNormal();
+        }
+
+        $html_output .= '</tbody></table>';
+        return $html_output;
+    }
+
+    /**
+     * Provides the form tag for table search form
+     * (normal search or zoom search)
+     *
+     * @param string $goto Goto URL
+     *
+     * @return string the HTML for form tag
+     */
+    private function _getFormTag($goto)
+    {
+        $html_output = '';
+        $scriptName = ($this->_searchType == 'zoom' ? 'tbl_zoom_select.php' : 'tbl_select.php');
+        $formId = ($this->_searchType == 'zoom' ? 'zoom_search_form' : 'tbl_search_form');
+
+        $html_output .= '<form method="post" action="' . $scriptName . '" '
+            . 'name="insertForm" id="' . $formId . '" '
+            . 'class="ajax"' . '>';
+
+        $html_output .= PMA_generate_common_hidden_inputs($this->_db, $this->_table);
+        $html_output .= '<input type="hidden" name="goto" value="' . $goto . '" />';
+        $html_output .= '<input type="hidden" name="back" value="' . $scriptName
+            . '" />';
+
+        return $html_output;
+    }
+
+    /**
+     * Generates the table search form under table search tab
+     *
+     * @param string $goto      Goto URL
+     * @param string $dataLabel Label for points in zoom plot
+     *
+     * @return string the generated HTML for table search form
+     */
+    public function getSelectionForm($goto, $dataLabel = null)
+    {
+        $url_params = array();
+        $url_params['db'] = $this->_db;
+        $url_params['table'] = $this->_table;
+
+        $html_output = '<ul id="topmenu2">';
+        foreach ($this->_getSubTabs() as $tab) {
+            $html_output .= PMA_Util::getHtmlTab($tab, $url_params);
+        }
+        $html_output .= '</ul>';
+        $html_output .= '<div class="clearfloat"></div>';
+
+        $html_output .= $this->_getFormTag($goto);
+
+        if ($this->_searchType == 'zoom') {
+            $html_output .= '<fieldset id="fieldset_zoom_search">';
+            $html_output .= '<fieldset id="inputSection">';
+            $html_output .= '<legend>'
+                . __('Do a "query by example" (wildcard: "%") for two different columns')
+                . '</legend>';
+            $html_output .= $this->_getFieldsTableHtml();
+            $html_output .= $this->_getOptionsZoom($dataLabel);
+            $html_output .= '</fieldset>';
+            $html_output .= '</fieldset>';
+        } else {
+            $html_output .= '<fieldset id="fieldset_table_search">';
+            $html_output .= '<fieldset id="fieldset_table_qbe">';
+            $html_output .= '<legend>'
+                . __('Do a "query by example" (wildcard: "%")')
+                . '</legend>';
+            $html_output .= $this->_getFieldsTableHtml();
+            $html_output .= '<div id="gis_editor"></div>';
+            $html_output .= '<div id="popup_background"></div>';
+            $html_output .= '</fieldset>';
+            $html_output .= $this->_getOptions();
+            $html_output .= '</fieldset>';
+        }
+
+        /**
+         * Displays selection form's footer elements
+         */
+        $html_output .= '<fieldset class="tblFooters">';
+        $html_output .= '<input type="submit" name="'
+            . ($this->_searchType == 'zoom' ? 'zoom_submit' : 'submit')
+            . ($this->_searchType == 'zoom' ? '" id="inputFormSubmitId"' : '" ')
+            . 'value="' . __('Go') . '" />';
+        $html_output .= '</fieldset></form>';
+        $html_output .= '<div id="sqlqueryresults"></div>';
+        return $html_output;
+    }
+
+    /**
+     * Provides form for displaying point data and also the scatter plot
+     * (for tbl_zoom_select.php)
+     *
+     * @param string $goto Goto URL
+     * @param array  $data Array containing SQL query data
+     *
+     * @return string form's html
+     */
+    public function getZoomResultsForm($goto, $data)
+    {
+        $html_output = '';
+        $titles['Browse'] = PMA_Util::getIcon('b_browse.png', __('Browse foreign values'));
+        $html_output .= '<form method="post" action="tbl_zoom_select.php"'
+            . ' name="displayResultForm" id="zoom_display_form"'
+            . ' class="ajax"' . '>';
+        $html_output .= PMA_generate_common_hidden_inputs($this->_db, $this->_table);
+        $html_output .= '<input type="hidden" name="goto" value="' . $goto . '" />';
+        $html_output .= '<input type="hidden" name="back" value="tbl_zoom_select.php" />';
+
+        $html_output .= '<fieldset id="displaySection">';
+        $html_output .= '<legend>' . __('Browse/Edit the points') . '</legend>';
+
+        //JSON encode the data(query result)
+        $html_output .= '<center>';
+        if (isset($_POST['zoom_submit']) && ! empty($data)) {
+            $html_output .= '<div id="resizer">';
+            $html_output .= '<center><a href="#" onclick="displayHelp();">'
+                . __('How to use') . '</a></center>';
+            $html_output .= '<div id="querydata" style="display:none">'
+                . json_encode($data) . '</div>';
+            $html_output .= '<div id="querychart"></div>';
+            $html_output .= '<button class="button-reset">'
+                . __('Reset zoom') . '</button>';
+            $html_output .= '</div>';
+        }
+        $html_output .= '</center>';
+
+        //Displays rows in point edit form
+        $html_output .= '<div id="dataDisplay" style="display:none">';
+        $html_output .= '<table><thead>';
+        $html_output .= '<tr>';
+        $html_output .= '<th>' . __('Column') . '</th>'
+            . '<th>' . __('Null') . '</th>'
+            . '<th>' . __('Value') . '</th>';
+        $html_output .= '</tr>';
+        $html_output .= '</thead>';
+
+        $html_output .= '<tbody>';
+        $odd_row = true;
+        for ($column_index = 0; $column_index < count($this->_columnNames); $column_index++) {
+            $fieldpopup = $this->_columnNames[$column_index];
+            $foreignData = PMA_getForeignData($this->_foreigners, $fieldpopup, false, '', '');
+            $html_output .= '<tr class="noclick ' . ($odd_row ? 'odd' : 'even') . '">';
+            $odd_row = ! $odd_row;
+            //Display column Names
+            $html_output .= '<th>' . htmlspecialchars($this->_columnNames[$column_index])
+                . '</th>';
+            //Null checkbox if column can be null
+            $html_output .= '<th>' . (($this->_columnNullFlags[$column_index] == 'YES')
+                ? '<input type="checkbox" class="checkbox_null"'
+                    . ' name="criteriaColumnNullFlags[' . $column_index . ']"'
+                    . ' id="edit_fields_null_id_' . $column_index . '" />'
+                : '');
+            $html_output .= '</th>';
+            //Column's Input box
+            $html_output .= '<th>';
+            $html_output .= $this->_getInputbox(
+                $foreignData, $fieldpopup, $this->_columnTypes[$column_index],
+                $column_index, $titles, $GLOBALS['cfg']['ForeignKeyMaxLimit'],
+                '', false, true
+            );
+            $html_output .= '</th></tr>';
+        }
+        $html_output .= '</tbody></table>';
+        $html_output .= '</div>';
+        $html_output .= '<input type="hidden" id="queryID" name="sql_query" />';
+        $html_output .= '</form>';
+        return $html_output;
+    }
+}
+?>
diff --git a/phpmyadmin/libraries/Theme.class.php b/phpmyadmin/libraries/Theme.class.php
new file mode 100644
index 0000000..bf1ee8f
--- /dev/null
+++ b/phpmyadmin/libraries/Theme.class.php
@@ -0,0 +1,601 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * hold PMA_Theme class
+ *
+ * @package PhpMyAdmin
+ */
+if (! defined('PHPMYADMIN')) {
+    exit;
+}
+
+/**
+ * handles theme
+ *
+ * @todo add the possibility to make a theme depend on another theme
+ * and by default on original
+ * @todo make all components optional - get missing components from 'parent' theme
+ *
+ * @package PhpMyAdmin
+ */
+class PMA_Theme
+{
+    /**
+     * @var string theme version
+     * @access  protected
+     */
+    var $version = '0.0.0.0';
+
+    /**
+     * @var string theme name
+     * @access  protected
+     */
+    var $name = '';
+
+    /**
+     * @var string theme id
+     * @access  protected
+     */
+    var $id = '';
+
+    /**
+     * @var string theme path
+     * @access  protected
+     */
+    var $path = '';
+
+    /**
+     * @var string image path
+     * @access  protected
+     */
+    var $img_path = '';
+
+    /**
+     * @var integer last modification time for info file
+     * @access  protected
+     */
+    var $mtime_info = 0;
+
+    /**
+     * needed because sometimes, the mtime for different themes
+     * is identical
+     * @var integer filesize for info file
+     * @access  protected
+     */
+    var $filesize_info = 0;
+
+    /**
+     * @var array List of css files to load
+     * @access private
+     */
+    private $_cssFiles = array(
+        'common',
+        'enum_editor',
+        'gis',
+        'navigation',
+        'pmd',
+        'rte',
+        'codemirror',
+        'jqplot',
+        'resizable-menu'
+    );
+
+    /**
+     * Loads theme information
+     *
+     * @return boolean whether loading them info was successful or not
+     * @access  public
+     */
+    function loadInfo()
+    {
+        if (! file_exists($this->getPath() . '/info.inc.php')) {
+            return false;
+        }
+
+        if ($this->mtime_info === filemtime($this->getPath() . '/info.inc.php')) {
+            return true;
+        }
+
+        @include $this->getPath() . '/info.inc.php';
+
+        // was it set correctly?
+        if (! isset($theme_name)) {
+            return false;
+        }
+
+        $this->mtime_info = filemtime($this->getPath() . '/info.inc.php');
+        $this->filesize_info = filesize($this->getPath() . '/info.inc.php');
+
+        if (isset($theme_full_version)) {
+            $this->setVersion($theme_full_version);
+        } elseif (isset($theme_generation, $theme_version)) {
+            $this->setVersion($theme_generation . '.' . $theme_version);
+        }
+        $this->setName($theme_name);
+
+        return true;
+    }
+
+    /**
+     * returns theme object loaded from given folder
+     * or false if theme is invalid
+     *
+     * @param string $folder path to theme
+     *
+     * @return object PMA_Theme
+     * @static
+     * @access public
+     */
+    static public function load($folder)
+    {
+        $theme = new PMA_Theme();
+
+        $theme->setPath($folder);
+
+        if (! $theme->loadInfo()) {
+            return false;
+        }
+
+        $theme->checkImgPath();
+
+        return $theme;
+    }
+
+    /**
+     * checks image path for existance - if not found use img from fallback theme
+     *
+     * @access public
+     * @return bool
+     */
+    public function checkImgPath()
+    {
+        // try current theme first
+        if (is_dir($this->getPath() . '/img/')) {
+            $this->setImgPath($this->getPath() . '/img/');
+            return true;
+        }
+
+        // try fallback theme
+        $fallback = $GLOBALS['cfg']['ThemePath'] . '/'
+            . PMA_Theme_Manager::FALLBACK_THEME
+            . '/img/';
+        if (is_dir($fallback)) {
+            $this->setImgPath($fallback);
+            return true;
+        }
+
+        // we failed
+        trigger_error(
+            sprintf(
+                __('No valid image path for theme %s found!'),
+                $this->getName()
+            ),
+            E_USER_ERROR
+        );
+        return false;
+    }
+
+    /**
+     * returns path to theme
+     *
+     * @access public
+     * @return string path to theme
+     */
+    public function getPath()
+    {
+        return $this->path;
+    }
+
+    /**
+     * returns layout file
+     *
+     * @access public
+     * @return string layout file
+     */
+    public function getLayoutFile()
+    {
+        return $this->getPath() . '/layout.inc.php';
+    }
+
+    /**
+     * set path to theme
+     *
+     * @param string $path path to theme
+     *
+     * @return void
+     * @access public
+     */
+    public function setPath($path)
+    {
+        $this->path = trim($path);
+    }
+
+    /**
+     * sets version
+     *
+     * @param string $version version to set
+     *
+     * @return void
+     * @access public
+     */
+    public function setVersion($version)
+    {
+        $this->version = trim($version);
+    }
+
+    /**
+     * returns version
+     *
+     * @return string version
+     * @access public
+     */
+    public function getVersion()
+    {
+        return $this->version;
+    }
+
+    /**
+     * checks theme version agaisnt $version
+     * returns true if theme version is equal or higher to $version
+     *
+     * @param string $version version to compare to
+     *
+     * @return boolean true if theme version is equal or higher to $version
+     * @access public
+     */
+    public function checkVersion($version)
+    {
+        return version_compare($this->getVersion(), $version, 'lt');
+    }
+
+    /**
+     * sets name
+     *
+     * @param string $name name to set
+     *
+     * @return void
+     * @access public
+     */
+    public function setName($name)
+    {
+        $this->name = trim($name);
+    }
+
+    /**
+     * returns name
+     *
+     * @access  public
+     * @return string name
+     */
+    public function getName()
+    {
+        return $this->name;
+    }
+
+    /**
+     * sets id
+     *
+     * @param string $id new id
+     *
+     * @return void
+     * @access public
+     */
+    public function setId($id)
+    {
+        $this->id = trim($id);
+    }
+
+    /**
+     * returns id
+     *
+     * @return string id
+     * @access public
+     */
+    public function getId()
+    {
+        return $this->id;
+    }
+
+    /**
+     * Sets path to images for the theme
+     *
+     * @param string $path path to images for this theme
+     *
+     * @return void
+     * @access public
+     */
+    public function setImgPath($path)
+    {
+        $this->img_path = $path;
+    }
+
+    /**
+     * Returns the path to image for the theme.
+     * If filename is given, it possibly fallbacks to fallback
+     * theme for it if image does not exist.
+     *
+     * @param string $file file name for image
+     *
+     * @access public
+     * @return string image path for this theme
+     */
+    public function getImgPath($file = null)
+    {
+        if (is_null($file)) {
+            return $this->img_path;
+        } else {
+            if (is_readable($this->img_path . $file)) {
+                return $this->img_path . $file;
+            } else {
+                return $GLOBALS['cfg']['ThemePath'] . '/'
+                    . PMA_Theme_Manager::FALLBACK_THEME . '/img/' . $file;
+            }
+        }
+    }
+
+    /**
+     * Builds a CSS rule used for html formatted SQL queries
+     *
+     * @param string $classname The class name
+     * @param string $property  The property name
+     * @param string $value     The property value
+     *
+     * @return string  The CSS rule
+     *
+     * @access public
+     *
+     * @see    PMA_SQP_buildCssData()
+     */
+    public function buildSQPCssRule($classname, $property, $value)
+    {
+        $str     = '.' . $classname . ' {';
+        if ($value != '') {
+            $str .= $property . ': ' . $value . ';';
+        }
+        $str     .= '}' . "\n";
+
+        return $str;
+    } // end of the "PMA_SQP_buildCssRule()" function
+
+
+    /**
+     * Builds CSS rules used for html formatted SQL queries
+     *
+     * @return string  The CSS rules set
+     *
+     * @access public
+     *
+     * @global array   The current PMA configuration
+     *
+     * @see    PMA_SQP_buildCssRule()
+     */
+    public function buildSQPCssData()
+    {
+        global $cfg;
+
+        $css_string     = '';
+        foreach ($cfg['SQP']['fmtColor'] AS $key => $col) {
+            $css_string .= $this->buildSQPCssRule('syntax_' . $key, 'color', $col);
+        }
+
+        for ($i = 0; $i < 8; $i++) {
+            $css_string .= $this->buildSQPCssRule(
+                'syntax_indent' . $i, 'margin-left',
+                ($i * $cfg['SQP']['fmtInd']) . $cfg['SQP']['fmtIndUnit']
+            );
+        }
+
+        return $css_string;
+    } // end of the "PMA_SQP_buildCssData()" function
+
+    /**
+     * load css (send to stdout, normally the browser)
+     *
+     * @return bool
+     * @access  public
+     */
+    public function loadCss()
+    {
+        $success = true;
+
+        echo $this->buildSQPCssData();
+
+        if ($GLOBALS['text_dir'] === 'ltr') {
+            $right = 'right';
+            $left = 'left';
+        } else {
+            $right = 'left';
+            $left = 'right';
+        }
+
+        foreach ($this->_cssFiles as $file) {
+            $path = $this->getPath() . "/css/$file.css.php";
+            $fallback = "./themes/"
+                . PMA_Theme_Manager::FALLBACK_THEME .  "/css/$file.css.php";
+
+            if (is_readable($path)) {
+                echo "\n/* FILE: $file.css.php */\n";
+                include $path;
+            } else if (is_readable($fallback)) {
+                echo "\n/* FILE: $file.css.php */\n";
+                include $fallback;
+            } else {
+                $success = false;
+            }
+        }
+
+        include './themes/sprites.css.php';
+
+        return $success;
+    }
+
+    /**
+     * Renders the preview for this theme
+     *
+     * @return string
+     * @access public
+     */
+    public function getPrintPreview()
+    {
+        $url_params = array('set_theme' => $this->getId());
+        $url = 'index.php'. PMA_generate_common_url($url_params);
+
+        $retval  = '<div class="theme_preview">';
+        $retval .= '<h2>';
+        $retval .= htmlspecialchars($this->getName());
+        $retval .= ' (' . htmlspecialchars($this->getVersion()) . ') ';
+        $retval .= '</h2>';
+        $retval .= '<p>';
+        $retval .= '<a class="take_theme" ';
+        $retval .= 'name="' . htmlspecialchars($this->getId()) . '" ';
+        $retval .=  'href="' . $url . '">';
+        if (@file_exists($this->getPath() . '/screen.png')) {
+            // if screen exists then output
+            $retval .= '<img src="' . $this->getPath() . '/screen.png" border="1"';
+            $retval .= ' alt="' . htmlspecialchars($this->getName()) . '"';
+            $retval .= ' title="' . htmlspecialchars($this->getName()) . '" />';
+            $retval .= '<br />';
+        } else {
+            $retval .= __('No preview available.');
+        }
+        $retval .= '[ <strong>' . __('take it') . '</strong> ]';
+        $retval .= '</a>';
+        $retval .= '</p>';
+        $retval .= '</div>';
+        return $retval;
+    }
+
+    /**
+     * Remove filter for IE.
+     *
+     * @return string CSS code.
+     */
+    function getCssIEClearFilter()
+    {
+        return PMA_USR_BROWSER_AGENT == 'IE'
+            && PMA_USR_BROWSER_VER >= 6
+            && PMA_USR_BROWSER_VER <= 8
+            ? 'filter: none'
+            : '';
+    }
+
+    /**
+     * Gets currently configured font size.
+     *
+     * @return String with font size.
+     */
+    function getFontSize()
+    {
+        $fs = $GLOBALS['PMA_Config']->get('fontsize');
+        if (!is_null($fs)) {
+            return $fs;
+        }
+        if (isset($_COOKIE['pma_fontsize'])) {
+            return $_COOKIE['pma_fontsize'];
+        }
+        return '82%';
+    }
+
+    /**
+     * Generates code for CSS gradient using various browser extensions.
+     *
+     * @param string $start_color Color of gradient start, hex value without #
+     * @param string $end_color   Color of gradient end, hex value without #
+     *
+     * @return string CSS code.
+     */
+    function getCssGradient($start_color, $end_color)
+    {
+        $result = array();
+        // Opera 9.5+, IE 9
+        $result[] = 'background-image: url(./themes/svg_gradient.php?from='
+            . $start_color . '&to=' . $end_color . ');';
+        $result[] = 'background-size: 100% 100%;';
+        // Safari 4-5, Chrome 1-9
+        $result[] = 'background: '
+            . '-webkit-gradient(linear, left top, left bottom, from(#'
+            . $start_color . '), to(#' . $end_color . '));';
+        // Safari 5.1, Chrome 10+
+        $result[] = 'background: -webkit-linear-gradient(top, #'
+            . $start_color . ', #' . $end_color . ');';
+        // Firefox 3.6+
+        $result[] = 'background: -moz-linear-gradient(top, #'
+            . $start_color . ', #' . $end_color . ');';
+        // IE 10
+        $result[] = 'background: -ms-linear-gradient(top, #'
+            . $start_color . ', #' . $end_color . ');';
+        // Opera 11.10
+        $result[] = 'background: -o-linear-gradient(top, #'
+            . $start_color . ', #' . $end_color . ');';
+        // IE 6-8
+        if (PMA_USR_BROWSER_AGENT == 'IE'
+            && PMA_USR_BROWSER_VER >= 6
+            && PMA_USR_BROWSER_VER <= 8
+        ) {
+            $result[] = 'filter: '
+                . 'progid:DXImageTransform.Microsoft.gradient(startColorstr="#'
+                . $start_color . '", endColorstr="#' . $end_color . '");';
+        }
+        return implode("\n", $result);
+    }
+
+    /**
+     * Returns CSS styles for CodeMirror editor based on query formatter colors.
+     *
+     * @return string CSS code.
+     */
+    function getCssCodeMirror()
+    {
+        if (! $GLOBALS['cfg']['CodemirrorEnable']) {
+            return '';
+        }
+
+        $result[] = 'span.cm-keyword, span.cm-statement-verb {';
+        $result[] = '    color: '
+            . $GLOBALS['cfg']['SQP']['fmtColor']['alpha_reservedWord'] . ';';
+        $result[] = '}';
+        $result[] = 'span.cm-variable {';
+        $result[] = '    color: '
+            . $GLOBALS['cfg']['SQP']['fmtColor']['alpha_identifier'] . ';';
+        $result[] = '}';
+        $result[] = 'span.cm-comment {';
+        $result[] = '    color: '
+            . $GLOBALS['cfg']['SQP']['fmtColor']['comment'] . ';';
+        $result[] = '}';
+        $result[] = 'span.cm-mysql-string {';
+        $result[] = '    color: '
+            . $GLOBALS['cfg']['SQP']['fmtColor']['quote'] . ';';
+        $result[] = '}';
+        $result[] = 'span.cm-operator {';
+        $result[] = '    color: '
+            . $GLOBALS['cfg']['SQP']['fmtColor']['punct'] . ';';
+        $result[] = '}';
+        $result[] = 'span.cm-mysql-word {';
+        $result[] = '    color: '
+            . $GLOBALS['cfg']['SQP']['fmtColor']['alpha_identifier'] . ';';
+        $result[] = '}';
+        $result[] = 'span.cm-builtin {';
+        $result[] = '    color: '
+            . $GLOBALS['cfg']['SQP']['fmtColor']['alpha_functionName'] . ';';
+        $result[] = '}';
+        $result[] = 'span.cm-variable-2 {';
+        $result[] = '    color: '
+            . $GLOBALS['cfg']['SQP']['fmtColor']['alpha_columnType'] . ';';
+        $result[] = '}';
+        $result[] = 'span.cm-variable-3 {';
+        $result[] = '    color: '
+            . $GLOBALS['cfg']['SQP']['fmtColor']['alpha_columnAttrib'] . ';';
+        $result[] = '}';
+        $result[] = 'span.cm-separator {';
+        $result[] = '    color: '
+            . $GLOBALS['cfg']['SQP']['fmtColor']['punct'] . ';';
+        $result[] = '}';
+        $result[] = 'span.cm-number {';
+        $result[] = '    color: '
+            . $GLOBALS['cfg']['SQP']['fmtColor']['digit_integer'] . ';';
+        $result[] = '}';
+
+        return implode("\n", $result);
+    }
+}
+?>
diff --git a/phpmyadmin/libraries/Theme_Manager.class.php b/phpmyadmin/libraries/Theme_Manager.class.php
new file mode 100644
index 0000000..7520516
--- /dev/null
+++ b/phpmyadmin/libraries/Theme_Manager.class.php
@@ -0,0 +1,453 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ *
+ * @package PhpMyAdmin
+ */
+if (! defined('PHPMYADMIN')) {
+    exit;
+}
+
+/**
+ *
+ * @package PhpMyAdmin
+ */
+class PMA_Theme_Manager
+{
+    /**
+     * @var string path to theme folder
+     * @access protected
+     */
+    private $_themes_path;
+
+    /**
+     * @var array available themes
+     */
+    var $themes = array();
+
+    /**
+     * @var string  cookie name
+     */
+    var $cookie_name = 'pma_theme';
+
+    /**
+     * @var boolean
+     */
+    var $per_server = false;
+
+    /**
+     * @var string name of active theme
+     */
+    var $active_theme = '';
+
+    /**
+     * @var PMA_Theme PMA_Theme active theme
+     */
+    var $theme = null;
+
+    /**
+     * @var string
+     */
+    var $theme_default;
+
+    /**
+     * @const string The name of the fallback theme
+     */
+    const FALLBACK_THEME = 'pmahomme';
+
+    /**
+     * Constructor for Theme Manager class
+     *
+     * @access public
+     * @return void
+     */
+    public function __construct()
+    {
+        $this->init();
+    }
+
+    /**
+     * sets path to folder containing the themes
+     *
+     * @param string $path path to themes folder
+     *
+     * @access public
+     * @return boolean success
+     */
+    public function setThemesPath($path)
+    {
+        if (! $this->_checkThemeFolder($path)) {
+            return false;
+        }
+
+        $this->_themes_path = trim($path);
+        return true;
+    }
+
+    /**
+     * Returns path to folder containing themes
+     *
+     * @access public
+     * @return string theme path
+     */
+    public function getThemesPath()
+    {
+        return $this->_themes_path;
+    }
+
+    /**
+     * sets if there are different themes per server
+     *
+     * @param boolean $per_server
+     *
+     * @access public
+     * @return void
+     */
+    public function setThemePerServer($per_server)
+    {
+        $this->per_server  = (bool) $per_server;
+    }
+
+    /**
+     * Initialise the class
+     *
+     * @access public
+     * @return void
+     */
+    public function init()
+    {
+        $this->themes = array();
+        $this->theme_default = self::FALLBACK_THEME;
+        $this->active_theme = '';
+
+        if (! $this->setThemesPath($GLOBALS['cfg']['ThemePath'])) {
+            return false;
+        }
+
+        $this->setThemePerServer($GLOBALS['cfg']['ThemePerServer']);
+
+        $this->loadThemes();
+
+        $this->theme = new PMA_Theme;
+
+
+        if (! $this->checkTheme($GLOBALS['cfg']['ThemeDefault'])) {
+            trigger_error(
+                sprintf(
+                    __('Default theme %s not found!'),
+                    htmlspecialchars($GLOBALS['cfg']['ThemeDefault'])
+                ),
+                E_USER_ERROR
+            );
+            $GLOBALS['cfg']['ThemeDefault'] = false;
+        }
+
+        $this->theme_default = $GLOBALS['cfg']['ThemeDefault'];
+
+        // check if user have a theme cookie
+        if (! $this->getThemeCookie()
+            || ! $this->setActiveTheme($this->getThemeCookie())
+        ) {
+            if ($GLOBALS['cfg']['ThemeDefault']) {
+                // otherwise use default theme
+                $this->setActiveTheme($this->theme_default);
+            } else {
+                // or fallback theme
+                $this->setActiveTheme(self::FALLBACK_THEME);
+            }
+        }
+    }
+
+    /**
+     * Checks configuration
+     *
+     * @access public
+     * @return void
+     */
+    public function checkConfig()
+    {
+        if ($this->_themes_path != trim($GLOBALS['cfg']['ThemePath'])
+            || $this->theme_default != $GLOBALS['cfg']['ThemeDefault']
+        ) {
+            $this->init();
+        } else {
+            // at least the theme path needs to be checked every time for new
+            // themes, as there is no other way at the moment to keep track of
+            // new or removed themes
+            $this->loadThemes();
+        }
+    }
+
+    /**
+     * Sets active theme
+     *
+     * @param string $theme theme name
+     *
+     * @access public
+     * @return bool true on success
+     */
+    public function setActiveTheme($theme = null)
+    {
+        if (! $this->checkTheme($theme)) {
+            trigger_error(
+                sprintf(
+                    __('Theme %s not found!'),
+                    htmlspecialchars($theme)
+                ),
+                E_USER_ERROR
+            );
+            return false;
+        }
+
+        $this->active_theme = $theme;
+        $this->theme = $this->themes[$theme];
+
+        // need to set later
+        //$this->setThemeCookie();
+
+        return true;
+    }
+
+    /**
+     *
+     * @return string cookie name
+     * @access public
+     */
+    public function getThemeCookieName()
+    {
+        // Allow different theme per server
+        if (isset($GLOBALS['server']) && $this->per_server) {
+            return $this->cookie_name . '-' . $GLOBALS['server'];
+        } else {
+            return $this->cookie_name;
+        }
+    }
+
+    /**
+     * returns name of theme stored in the cookie
+     *
+     * @return string  theme name from cookie
+     * @access public
+     */
+    public function getThemeCookie()
+    {
+        if (isset($_COOKIE[$this->getThemeCookieName()])) {
+            return $_COOKIE[$this->getThemeCookieName()];
+        }
+
+        return false;
+    }
+
+    /**
+     * save theme in cookie
+     *
+     * @return bool true
+     * @access public
+     */
+    public function setThemeCookie()
+    {
+        $GLOBALS['PMA_Config']->setCookie(
+            $this->getThemeCookieName(),
+            $this->theme->id,
+            $this->theme_default
+        );
+        // force a change of a dummy session variable to avoid problems
+        // with the caching of phpmyadmin.css.php
+        $GLOBALS['PMA_Config']->set('theme-update', $this->theme->id);
+        return true;
+    }
+
+    /**
+     * @param string $folder
+     *
+     * @return boolean
+     * @access private
+     */
+    private function _checkThemeFolder($folder)
+    {
+        if (! is_dir($folder)) {
+            trigger_error(
+                sprintf(
+                    __('Theme path not found for theme %s!'),
+                    htmlspecialchars($folder)
+                ),
+                E_USER_ERROR
+            );
+            return false;
+        }
+
+        return true;
+    }
+
+    /**
+     * read all themes
+     *
+     * @return bool true
+     * @access public
+     */
+    public function loadThemes()
+    {
+        $this->themes = array();
+
+        if ($handleThemes = opendir($this->getThemesPath())) {
+            // check for themes directory
+            while (false !== ($PMA_Theme = readdir($handleThemes))) {
+                // Skip non dirs, . and ..
+                if ($PMA_Theme == '.'
+                    || $PMA_Theme == '..'
+                    || ! is_dir($this->getThemesPath() . '/' . $PMA_Theme)
+                ) {
+                    continue;
+                }
+                if (array_key_exists($PMA_Theme, $this->themes)) {
+                    continue;
+                }
+                $new_theme = PMA_Theme::load(
+                    $this->getThemesPath() . '/' . $PMA_Theme
+                );
+                if ($new_theme) {
+                    $new_theme->setId($PMA_Theme);
+                    $this->themes[$PMA_Theme] = $new_theme;
+                }
+            } // end get themes
+            closedir($handleThemes);
+        } else {
+            trigger_error(
+                'phpMyAdmin-ERROR: cannot open themes folder: ' . $this->getThemesPath(),
+                E_USER_WARNING
+            );
+            return false;
+        } // end check for themes directory
+
+        ksort($this->themes);
+        return true;
+    }
+
+    /**
+     * checks if given theme name is a known theme
+     *
+     * @param string $theme name fo theme to check for
+     *
+     * @return bool
+     * @access public
+     */
+    public function checkTheme($theme)
+    {
+        if (! array_key_exists($theme, $this->themes)) {
+            return false;
+        }
+
+        return true;
+    }
+
+    /**
+     * returns HTML selectbox, with or without form enclosed
+     *
+     * @param boolean $form whether enclosed by from tags or not
+     *
+     * @return string
+     * @access public
+     */
+    public function getHtmlSelectBox($form = true)
+    {
+        $select_box = '';
+
+        if ($form) {
+            $select_box .= '<form name="setTheme" method="get"';
+            $select_box .= ' action="index.php" class="disableAjax">';
+            $select_box .=  PMA_generate_common_hidden_inputs();
+        }
+
+        $theme_preview_path= './themes.php';
+        $theme_preview_href = '<a href="' . $theme_preview_path . '" target="themes" class="themeselect">';
+        $select_box .=  $theme_preview_href . __('Theme') . '</a>:' . "\n";
+
+        $select_box .=  '<select name="set_theme" lang="en" dir="ltr" class="autosubmit">';
+        foreach ($this->themes as $each_theme_id => $each_theme) {
+            $select_box .=  '<option value="' . $each_theme_id . '"';
+            if ($this->active_theme === $each_theme_id) {
+                $select_box .=  ' selected="selected"';
+            }
+            $select_box .=  '>' . htmlspecialchars($each_theme->getName()) . '</option>';
+        }
+        $select_box .=  '</select>';
+
+        if ($form) {
+            $select_box .=  '</form>';
+        }
+
+        return $select_box;
+    }
+
+    /**
+     * enables backward compatibility
+     *
+     * @return void
+     * @access public
+     */
+    public function makeBc()
+    {
+        $GLOBALS['theme']           = $this->theme->getId();
+        $GLOBALS['pmaThemePath']    = $this->theme->getPath();
+        $GLOBALS['pmaThemeImage']   = $this->theme->getImgPath();
+
+        /**
+         * load layout file if exists
+         */
+        if (file_exists($this->theme->getLayoutFile())) {
+            include $this->theme->getLayoutFile();
+        }
+    }
+
+    /**
+     * Renders the previews for all themes
+     *
+     * @return string
+     * @access public
+     */
+    public function getPrintPreviews()
+    {
+        $retval = '';
+        foreach ($this->themes as $each_theme) {
+            $retval .= $each_theme->getPrintPreview();
+        } // end 'open themes'
+        return $retval;
+    }
+
+    /**
+     * returns PMA_Theme object for fall back theme
+     *
+     * @return object PMA_Theme
+     * @access public
+     */
+    public function getFallBackTheme()
+    {
+        if (isset($this->themes[self::FALLBACK_THEME])) {
+            return $this->themes[self::FALLBACK_THEME];
+        }
+
+        return false;
+    }
+
+    /**
+     * prints css data
+     *
+     * @return bool
+     * @access public
+     */
+    public function printCss()
+    {
+        if ($this->theme->loadCss()) {
+            return true;
+        }
+
+        // if loading css for this theme failed, try default theme css
+        $fallback_theme = $this->getFallBackTheme();
+        if ($fallback_theme && $fallback_theme->loadCss()) {
+            return true;
+        }
+
+        return false;
+    }
+}
+?>
diff --git a/phpmyadmin/libraries/Tracker.class.php b/phpmyadmin/libraries/Tracker.class.php
new file mode 100644
index 0000000..4e67c08
--- /dev/null
+++ b/phpmyadmin/libraries/Tracker.class.php
@@ -0,0 +1,1079 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * Tracking changes on databases, tables and views
+ *
+ * @package PhpMyAdmin
+ */
+if (! defined('PHPMYADMIN')) {
+    exit;
+}
+
+/**
+ * This class tracks changes on databases, tables and views.
+ *
+ * @package PhpMyAdmin
+ *
+ * @todo use stristr instead of strstr
+ */
+class PMA_Tracker
+{
+    /**
+     * Whether tracking is ready.
+     */
+    static protected $enabled = false;
+
+    /**
+     * Defines the internal PMA table which contains tracking data.
+     *
+     * @access  protected
+     * @var string
+     */
+    static protected $pma_table;
+
+    /**
+     * Defines the usage of DROP TABLE statment in SQL dumps.
+     *
+     * @access protected
+     * @var boolean
+     */
+    static protected $add_drop_table;
+
+    /**
+     * Defines the usage of DROP VIEW statment in SQL dumps.
+     *
+     * @access protected
+     * @var boolean
+     */
+    static protected $add_drop_view;
+
+    /**
+     * Defines the usage of DROP DATABASE statment in SQL dumps.
+     *
+     * @access protected
+     * @var boolean
+     */
+    static protected $add_drop_database;
+
+    /**
+     * Defines auto-creation of tracking versions.
+     *
+     * @var boolean
+     */
+    static protected $version_auto_create;
+
+    /**
+     * Defines the default set of tracked statements.
+     *
+     * @var string
+     */
+    static protected $default_tracking_set;
+
+    /**
+     * Flags copied from `tracking` column definition in `pma_tracking` table.
+     * Used for column type conversion in Drizzle.
+     *
+     * @var array
+     */
+    static private $_tracking_set_flags = array(
+        'UPDATE','REPLACE','INSERT','DELETE','TRUNCATE','CREATE DATABASE',
+        'ALTER DATABASE','DROP DATABASE','CREATE TABLE','ALTER TABLE',
+        'RENAME TABLE','DROP TABLE','CREATE INDEX','DROP INDEX',
+        'CREATE VIEW','ALTER VIEW','DROP VIEW'
+    );
+
+
+    /**
+     * Initializes settings.
+     *
+     * @static
+     *
+     * @return void
+     */
+    static protected function init()
+    {
+        self::$pma_table = PMA_Util::backquote($GLOBALS['cfg']['Server']['pmadb']) .".".
+                           PMA_Util::backquote($GLOBALS['cfg']['Server']['tracking']);
+
+        self::$add_drop_table = $GLOBALS['cfg']['Server']['tracking_add_drop_table'];
+
+        self::$add_drop_view = $GLOBALS['cfg']['Server']['tracking_add_drop_view'];
+
+        self::$add_drop_database
+            = $GLOBALS['cfg']['Server']['tracking_add_drop_database'];
+
+        self::$default_tracking_set
+            = $GLOBALS['cfg']['Server']['tracking_default_statements'];
+
+        self::$version_auto_create
+            = $GLOBALS['cfg']['Server']['tracking_version_auto_create'];
+    }
+
+    /**
+     * Actually enables tracking. This needs to be done after all
+     * underlaying code is initialized.
+     *
+     * @static
+     *
+     * @return void
+     */
+    static public function enable()
+    {
+        self::$enabled = true;
+    }
+
+    /**
+     * Gets the on/off value of the Tracker module, starts initialization.
+     *
+     * @static
+     *
+     * @return boolean (true=on|false=off)
+     */
+    static public function isActive()
+    {
+        if (! self::$enabled) {
+            return false;
+        }
+        /* We need to avoid attempt to track any queries
+         * from PMA_getRelationsParam
+         */
+        self::$enabled = false;
+        $cfgRelation = PMA_getRelationsParam();
+        /* Restore original state */
+        self::$enabled = true;
+        if (! $cfgRelation['trackingwork']) {
+            return false;
+        }
+        self::init();
+
+        if (isset(self::$pma_table)) {
+            return true;
+        } else {
+            return false;
+        }
+    }
+
+    /**
+     * Parses the name of a table from a SQL statement substring.
+     *
+     * @param string $string part of SQL statement
+     *
+     * @static
+     *
+     * @return string the name of table
+     */
+    static protected function getTableName($string)
+    {
+        if (strstr($string, '.')) {
+            $temp = explode('.', $string);
+            $tablename = $temp[1];
+        } else {
+            $tablename = $string;
+        }
+
+        $str = explode("\n", $tablename);
+        $tablename = $str[0];
+
+        $tablename = str_replace(';', '', $tablename);
+        $tablename = str_replace('`', '', $tablename);
+        $tablename = trim($tablename);
+
+        return $tablename;
+    }
+
+
+    /**
+     * Gets the tracking status of a table, is it active or deactive ?
+     *
+     * @param string $dbname    name of database
+     * @param string $tablename name of table
+     *
+     * @static
+     *
+     * @return boolean true or false
+     */
+    static public function isTracked($dbname, $tablename)
+    {
+        if (! self::$enabled) {
+            return false;
+        }
+        /* We need to avoid attempt to track any queries
+         * from PMA_getRelationsParam
+         */
+        self::$enabled = false;
+        $cfgRelation = PMA_getRelationsParam();
+        /* Restore original state */
+        self::$enabled = true;
+        if (! $cfgRelation['trackingwork']) {
+            return false;
+        }
+
+        $sql_query = " SELECT tracking_active FROM " . self::$pma_table .
+        " WHERE db_name = '" . PMA_Util::sqlAddSlashes($dbname) . "' " .
+        " AND table_name = '" . PMA_Util::sqlAddSlashes($tablename) . "' " .
+        " ORDER BY version DESC";
+
+        $row = PMA_DBI_fetch_array(PMA_queryAsControlUser($sql_query));
+
+        if (isset($row['tracking_active']) && $row['tracking_active'] == 1) {
+            return true;
+        } else {
+            return false;
+        }
+    }
+
+    /**
+     * Returns the comment line for the log.
+     *
+     * @return string Comment, contains date and username
+     */
+    static public function getLogComment()
+    {
+        $date = date('Y-m-d H:i:s');
+
+        return "# log " . $date . " " . $GLOBALS['cfg']['Server']['user'] . "\n";
+    }
+
+    /**
+     * Creates tracking version of a table / view
+     * (in other words: create a job to track future changes on the table).
+     *
+     * @param string $dbname       name of database
+     * @param string $tablename    name of table
+     * @param string $version      version
+     * @param string $tracking_set set of tracking statements
+     * @param bool   $is_view      if table is a view
+     *
+     * @static
+     *
+     * @return int result of version insertion
+     */
+    static public function createVersion($dbname, $tablename, $version,
+        $tracking_set = '', $is_view = false
+    ) {
+        global $sql_backquotes, $export_type;
+
+        if ($tracking_set == '') {
+            $tracking_set = self::$default_tracking_set;
+        }
+
+        // get Export SQL instance
+        include_once "libraries/plugin_interface.lib.php";
+        $export_sql_plugin = PMA_getPlugin(
+            "export",
+            "sql",
+            'libraries/plugins/export/',
+            array(
+                'export_type' => $export_type,
+                'single_table' => isset($single_table)
+            )
+        );
+
+        $sql_backquotes = true;
+
+        $date = date('Y-m-d H:i:s');
+
+        // Get data definition snapshot of table
+
+        $columns = PMA_DBI_get_columns($dbname, $tablename, null, true);
+        // int indices to reduce size
+        $columns = array_values($columns);
+        // remove Privileges to reduce size
+        for ($i = 0; $i < count($columns); $i++) {
+            unset($columns[$i]['Privileges']);
+        }
+
+        $indexes = PMA_DBI_get_table_indexes($dbname, $tablename);
+
+        $snapshot = array('COLUMNS' => $columns, 'INDEXES' => $indexes);
+        $snapshot = serialize($snapshot);
+
+        // Get DROP TABLE / DROP VIEW and CREATE TABLE SQL statements
+        $sql_backquotes = true;
+
+        $create_sql  = "";
+
+        if (self::$add_drop_table == true && $is_view == false) {
+            $create_sql .= self::getLogComment()
+                . 'DROP TABLE IF EXISTS ' . PMA_Util::backquote($tablename) . ";\n";
+
+        }
+
+        if (self::$add_drop_view == true && $is_view == true) {
+            $create_sql .= self::getLogComment()
+                . 'DROP VIEW IF EXISTS ' . PMA_Util::backquote($tablename) . ";\n";
+        }
+
+        $create_sql .= self::getLogComment() .
+            $export_sql_plugin->getTableDef($dbname, $tablename, "\n", "");
+
+        // Save version
+
+        $sql_query = "/*NOTRACK*/\n" .
+        "INSERT INTO" . self::$pma_table . " (" .
+        "db_name, " .
+        "table_name, " .
+        "version, " .
+        "date_created, " .
+        "date_updated, " .
+        "schema_snapshot, " .
+        "schema_sql, " .
+        "data_sql, " .
+        "tracking " .
+        ") " .
+        "values (
+        '" . PMA_Util::sqlAddSlashes($dbname) . "',
+        '" . PMA_Util::sqlAddSlashes($tablename) . "',
+        '" . PMA_Util::sqlAddSlashes($version) . "',
+        '" . PMA_Util::sqlAddSlashes($date) . "',
+        '" . PMA_Util::sqlAddSlashes($date) . "',
+        '" . PMA_Util::sqlAddSlashes($snapshot) . "',
+        '" . PMA_Util::sqlAddSlashes($create_sql) . "',
+        '" . PMA_Util::sqlAddSlashes("\n") . "',
+        '" . PMA_Util::sqlAddSlashes(self::_transformTrackingSet($tracking_set)) . "' )";
+
+        $result = PMA_queryAsControlUser($sql_query);
+
+        if ($result) {
+            // Deactivate previous version
+            self::deactivateTracking($dbname, $tablename, ($version - 1));
+        }
+
+        return $result;
+    }
+
+
+    /**
+     * Removes all tracking data for a table
+     *
+     * @param string $dbname    name of database
+     * @param string $tablename name of table
+     *
+     * @static
+     *
+     * @return int result of version insertion
+     */
+    static public function deleteTracking($dbname, $tablename)
+    {
+        $sql_query = "/*NOTRACK*/\n"
+            . "DELETE FROM " . self::$pma_table
+            . " WHERE `db_name` = '"
+            . PMA_Util::sqlAddSlashes($dbname) . "'"
+            . " AND `table_name` = '"
+            . PMA_Util::sqlAddSlashes($tablename) . "'";
+        $result = PMA_queryAsControlUser($sql_query);
+
+        return $result;
+    }
+
+    /**
+     * Creates tracking version of a database
+     * (in other words: create a job to track future changes on the database).
+     *
+     * @param string $dbname       name of database
+     * @param string $version      version
+     * @param string $query        query
+     * @param string $tracking_set set of tracking statements
+     *
+     * @static
+     *
+     * @return int result of version insertion
+     */
+    static public function createDatabaseVersion($dbname, $version, $query,
+        $tracking_set = 'CREATE DATABASE,ALTER DATABASE,DROP DATABASE'
+    ) {
+        $date = date('Y-m-d H:i:s');
+
+        if ($tracking_set == '') {
+            $tracking_set = self::$default_tracking_set;
+        }
+
+        include_once './libraries/export/sql.php';
+
+        $create_sql  = "";
+
+        if (self::$add_drop_database == true) {
+            $create_sql .= self::getLogComment()
+                . 'DROP DATABASE IF EXISTS ' . PMA_Util::backquote($dbname) . ";\n";
+        }
+
+        $create_sql .= self::getLogComment() . $query;
+
+        // Save version
+        $sql_query = "/*NOTRACK*/\n" .
+        "INSERT INTO" . self::$pma_table . " (" .
+        "db_name, " .
+        "table_name, " .
+        "version, " .
+        "date_created, " .
+        "date_updated, " .
+        "schema_snapshot, " .
+        "schema_sql, " .
+        "data_sql, " .
+        "tracking " .
+        ") " .
+        "values (
+        '" . PMA_Util::sqlAddSlashes($dbname) . "',
+        '" . PMA_Util::sqlAddSlashes('') . "',
+        '" . PMA_Util::sqlAddSlashes($version) . "',
+        '" . PMA_Util::sqlAddSlashes($date) . "',
+        '" . PMA_Util::sqlAddSlashes($date) . "',
+        '" . PMA_Util::sqlAddSlashes('') . "',
+        '" . PMA_Util::sqlAddSlashes($create_sql) . "',
+        '" . PMA_Util::sqlAddSlashes("\n") . "',
+        '" . PMA_Util::sqlAddSlashes(self::_transformTrackingSet($tracking_set)) . "' )";
+
+        $result = PMA_queryAsControlUser($sql_query);
+
+        return $result;
+    }
+
+
+
+    /**
+     * Changes tracking of a table.
+     *
+     * @param string  $dbname    name of database
+     * @param string  $tablename name of table
+     * @param string  $version   version
+     * @param integer $new_state the new state of tracking
+     *
+     * @static
+     *
+     * @return int result of SQL query
+     */
+    static private function _changeTracking($dbname, $tablename,
+        $version, $new_state
+    ) {
+
+        $sql_query = " UPDATE " . self::$pma_table .
+        " SET `tracking_active` = '" . $new_state . "' " .
+        " WHERE `db_name` = '" . PMA_Util::sqlAddSlashes($dbname) . "' " .
+        " AND `table_name` = '" . PMA_Util::sqlAddSlashes($tablename) . "' " .
+        " AND `version` = '" . PMA_Util::sqlAddSlashes($version) . "' ";
+
+        $result = PMA_queryAsControlUser($sql_query);
+
+        return $result;
+    }
+
+    /**
+     * Changes tracking data of a table.
+     *
+     * @param string       $dbname    name of database
+     * @param string       $tablename name of table
+     * @param string       $version   version
+     * @param string       $type      type of data(DDL || DML)
+     * @param string|array $new_data  the new tracking data
+     *
+     * @static
+     *
+     * @return bool result of change
+     */
+    static public function changeTrackingData($dbname, $tablename,
+        $version, $type, $new_data
+    ) {
+        if ($type == 'DDL') {
+            $save_to = 'schema_sql';
+        } elseif ($type == 'DML') {
+            $save_to = 'data_sql';
+        } else {
+            return false;
+        }
+        $date  = date('Y-m-d H:i:s');
+
+        $new_data_processed = '';
+        if (is_array($new_data)) {
+            foreach ($new_data as $data) {
+                $new_data_processed .= '# log ' . $date . ' ' . $data['username']
+                    . PMA_Util::sqlAddSlashes($data['statement']) . "\n";
+            }
+        } else {
+            $new_data_processed = $new_data;
+        }
+
+        $sql_query = " UPDATE " . self::$pma_table .
+        " SET `" . $save_to . "` = '" . $new_data_processed . "' " .
+        " WHERE `db_name` = '" . PMA_Util::sqlAddSlashes($dbname) . "' " .
+        " AND `table_name` = '" . PMA_Util::sqlAddSlashes($tablename) . "' " .
+        " AND `version` = '" . PMA_Util::sqlAddSlashes($version) . "' ";
+
+        $result = PMA_queryAsControlUser($sql_query);
+
+        return $result;
+    }
+
+    /**
+     * Activates tracking of a table.
+     *
+     * @param string $dbname    name of database
+     * @param string $tablename name of table
+     * @param string $version   version
+     *
+     * @static
+     *
+     * @return int result of SQL query
+     */
+    static public function activateTracking($dbname, $tablename, $version)
+    {
+        return self::_changeTracking($dbname, $tablename, $version, 1);
+    }
+
+
+    /**
+     * Deactivates tracking of a table.
+     *
+     * @param string $dbname    name of database
+     * @param string $tablename name of table
+     * @param string $version   version
+     *
+     * @static
+     *
+     * @return int result of SQL query
+     */
+    static public function deactivateTracking($dbname, $tablename, $version)
+    {
+        return self::_changeTracking($dbname, $tablename, $version, 0);
+    }
+
+
+    /**
+     * Gets the newest version of a tracking job
+     * (in other words: gets the HEAD version).
+     *
+     * @param string $dbname    name of database
+     * @param string $tablename name of table
+     * @param string $statement tracked statement
+     *
+     * @static
+     *
+     * @return int (-1 if no version exists | >  0 if a version exists)
+     */
+    static public function getVersion($dbname, $tablename, $statement = null)
+    {
+        $sql_query = " SELECT MAX(version) FROM " . self::$pma_table .
+        " WHERE `db_name` = '" . PMA_Util::sqlAddSlashes($dbname) . "' " .
+        " AND `table_name` = '" . PMA_Util::sqlAddSlashes($tablename) . "' ";
+
+        if ($statement != "") {
+            $sql_query .= PMA_DRIZZLE
+                ? ' AND tracking & ' . self::_transformTrackingSet($statement) . ' <> 0'
+                : " AND FIND_IN_SET('" . $statement . "',tracking) > 0" ;
+        }
+        $row = PMA_DBI_fetch_array(PMA_queryAsControlUser($sql_query));
+        return isset($row[0])
+            ? $row[0]
+            : -1;
+    }
+
+
+    /**
+     * Gets the record of a tracking job.
+     *
+     * @param string $dbname    name of database
+     * @param string $tablename name of table
+     * @param string $version   version number
+     *
+     * @static
+     *
+     * @return mixed record DDM log, DDL log, structure snapshot, tracked statements.
+     */
+    static public function getTrackedData($dbname, $tablename, $version)
+    {
+        if (! isset(self::$pma_table)) {
+            self::init();
+        }
+        $sql_query = " SELECT * FROM " . self::$pma_table .
+            " WHERE `db_name` = '" . PMA_Util::sqlAddSlashes($dbname) . "' ";
+        if (! empty($tablename)) {
+            $sql_query .= " AND `table_name` = '"
+                . PMA_Util::sqlAddSlashes($tablename) ."' ";
+        }
+        $sql_query .= " AND `version` = '" . PMA_Util::sqlAddSlashes($version) ."' ".
+                     " ORDER BY `version` DESC LIMIT 1";
+
+        $mixed = PMA_DBI_fetch_assoc(PMA_queryAsControlUser($sql_query));
+
+        // Parse log
+        $log_schema_entries = explode('# log ',  $mixed['schema_sql']);
+        $log_data_entries   = explode('# log ',  $mixed['data_sql']);
+
+        $ddl_date_from = $date = date('Y-m-d H:i:s');
+
+        $ddlog = array();
+        $i = 0;
+
+        // Iterate tracked data definition statements
+        // For each log entry we want to get date, username and statement
+        foreach ($log_schema_entries as $log_entry) {
+            if (trim($log_entry) != '') {
+                $date      = substr($log_entry, 0, 19);
+                $username  = substr($log_entry, 20, strpos($log_entry, "\n") - 20);
+                if ($i == 0) {
+                    $ddl_date_from = $date;
+                }
+                $statement = rtrim(strstr($log_entry, "\n"));
+
+                $ddlog[] = array( 'date' => $date,
+                                  'username'=> $username,
+                                  'statement' => $statement );
+                $i++;
+            }
+        }
+
+        $date_from = $ddl_date_from;
+        $date_to   = $ddl_date_to = $date;
+
+        $dml_date_from = $date_from;
+
+        $dmlog = array();
+        $i = 0;
+
+        // Iterate tracked data manipulation statements
+        // For each log entry we want to get date, username and statement
+        foreach ($log_data_entries as $log_entry) {
+            if (trim($log_entry) != '') {
+                $date      = substr($log_entry, 0, 19);
+                $username  = substr($log_entry, 20, strpos($log_entry, "\n") - 20);
+                if ($i == 0) {
+                    $dml_date_from = $date;
+                }
+                $statement = rtrim(strstr($log_entry, "\n"));
+
+                $dmlog[] = array( 'date' => $date,
+                                  'username' => $username,
+                                  'statement' => $statement );
+                $i++;
+            }
+        }
+
+        $dml_date_to = $date;
+
+        // Define begin and end of date range for both logs
+        if (strtotime($ddl_date_from) <= strtotime($dml_date_from)) {
+            $data['date_from'] = $ddl_date_from;
+        } else {
+            $data['date_from'] = $dml_date_from;
+        }
+        if (strtotime($ddl_date_to) >= strtotime($dml_date_to)) {
+            $data['date_to'] = $ddl_date_to;
+        } else {
+            $data['date_to'] = $dml_date_to;
+        }
+        $data['ddlog']           = $ddlog;
+        $data['dmlog']           = $dmlog;
+        $data['tracking']        = self::_transformTrackingSet($mixed['tracking']);
+        $data['schema_snapshot'] = $mixed['schema_snapshot'];
+
+        return $data;
+    }
+
+
+    /**
+     * Parses a query. Gets
+     *  - statement identifier (UPDATE, ALTER TABLE, ...)
+     *  - type of statement, is it part of DDL or DML ?
+     *  - tablename
+     *
+     * @param string $query query
+     *
+     * @static
+     * @todo: using PMA SQL Parser when possible
+     * @todo: support multi-table/view drops
+     *
+     * @return mixed Array containing identifier, type and tablename.
+     *
+     */
+    static public function parseQuery($query)
+    {
+
+        // Usage of PMA_SQP does not work here
+        //
+        // require_once("libraries/sqlparser.lib.php");
+        // $parsed_sql = PMA_SQP_parse($query);
+        // $sql_info = PMA_SQP_analyze($parsed_sql);
+
+        $query = str_replace("\n", " ", $query);
+        $query = str_replace("\r", " ", $query);
+
+        $query = trim($query);
+        $query = trim($query, ' -');
+
+        $tokens = explode(" ", $query);
+        foreach ($tokens as $key => $value) {
+            $tokens[$key] = strtoupper($value);
+        }
+
+        // Parse USE statement, need it for SQL dump imports
+        if (substr($query, 0, 4) == 'USE ') {
+            $prefix = explode('USE ', $query);
+            $GLOBALS['db'] = self::getTableName($prefix[1]);
+        }
+
+        /*
+         * DDL statements
+         */
+
+        $result['type']         = 'DDL';
+
+        // Parse CREATE VIEW statement
+        if (in_array('CREATE', $tokens) == true
+            && in_array('VIEW', $tokens) == true
+            && in_array('AS', $tokens) == true
+        ) {
+            $result['identifier'] = 'CREATE VIEW';
+
+            $index = array_search('VIEW', $tokens);
+
+            $result['tablename'] = strtolower(
+                self::getTableName($tokens[$index + 1])
+            );
+        }
+
+        // Parse ALTER VIEW statement
+        if (in_array('ALTER', $tokens) == true
+            && in_array('VIEW', $tokens) == true
+            && in_array('AS', $tokens) == true
+            && ! isset($result['identifier'])
+        ) {
+            $result['identifier'] = 'ALTER VIEW';
+
+            $index = array_search('VIEW', $tokens);
+
+            $result['tablename'] = strtolower(
+                self::getTableName($tokens[$index + 1])
+            );
+        }
+
+        // Parse DROP VIEW statement
+        if (! isset($result['identifier'])
+            && substr($query, 0, 10) == 'DROP VIEW '
+        ) {
+            $result['identifier'] = 'DROP VIEW';
+
+            $prefix  = explode('DROP VIEW ', $query);
+            $str = strstr($prefix[1], 'IF EXISTS');
+
+            if ($str == false ) {
+                $str = $prefix[1];
+            }
+            $result['tablename'] = self::getTableName($str);
+        }
+
+        // Parse CREATE DATABASE statement
+        if (! isset($result['identifier'])
+            && substr($query, 0, 15) == 'CREATE DATABASE'
+        ) {
+            $result['identifier'] = 'CREATE DATABASE';
+            $str = str_replace('CREATE DATABASE', '', $query);
+            $str = str_replace('IF NOT EXISTS', '', $str);
+
+            $prefix = explode('DEFAULT ', $str);
+
+            $result['tablename'] = '';
+            $GLOBALS['db'] = self::getTableName($prefix[0]);
+        }
+
+        // Parse ALTER DATABASE statement
+        if (! isset($result['identifier'])
+            && substr($query, 0, 14) == 'ALTER DATABASE'
+        ) {
+            $result['identifier'] = 'ALTER DATABASE';
+            $result['tablename'] = '';
+        }
+
+        // Parse DROP DATABASE statement
+        if (! isset($result['identifier'])
+            && substr($query, 0, 13) == 'DROP DATABASE'
+        ) {
+            $result['identifier'] = 'DROP DATABASE';
+            $str = str_replace('DROP DATABASE', '', $query);
+            $str = str_replace('IF EXISTS', '', $str);
+            $GLOBALS['db'] = self::getTableName($str);
+            $result['tablename'] = '';
+        }
+
+        // Parse CREATE TABLE statement
+        if (! isset($result['identifier'])
+            && substr($query, 0, 12) == 'CREATE TABLE'
+        ) {
+            $result['identifier'] = 'CREATE TABLE';
+            $query   = str_replace('IF NOT EXISTS', '', $query);
+            $prefix  = explode('CREATE TABLE ', $query);
+            $suffix  = explode('(', $prefix[1]);
+            $result['tablename'] = self::getTableName($suffix[0]);
+        }
+
+        // Parse ALTER TABLE statement
+        if (! isset($result['identifier'])
+            && substr($query, 0, 12) == 'ALTER TABLE '
+        ) {
+            $result['identifier'] = 'ALTER TABLE';
+
+            $prefix  = explode('ALTER TABLE ', $query);
+            $suffix  = explode(' ', $prefix[1]);
+            $result['tablename']  = self::getTableName($suffix[0]);
+        }
+
+        // Parse DROP TABLE statement
+        if (! isset($result['identifier'])
+            && substr($query, 0, 11) == 'DROP TABLE '
+        ) {
+            $result['identifier'] = 'DROP TABLE';
+
+            $prefix  = explode('DROP TABLE ', $query);
+            $str = strstr($prefix[1], 'IF EXISTS');
+
+            if ($str == false ) {
+                $str = $prefix[1];
+            }
+            $result['tablename'] = self::getTableName($str);
+        }
+
+        // Parse CREATE INDEX statement
+        if (! isset($result['identifier'])
+            && (substr($query, 0, 12) == 'CREATE INDEX'
+            || substr($query, 0, 19) == 'CREATE UNIQUE INDEX'
+            || substr($query, 0, 20) == 'CREATE SPATIAL INDEX')
+        ) {
+             $result['identifier'] = 'CREATE INDEX';
+             $prefix = explode('ON ', $query);
+             $suffix = explode('(', $prefix[1]);
+             $result['tablename'] = self::getTableName($suffix[0]);
+        }
+
+        // Parse DROP INDEX statement
+        if (! isset($result['identifier'])
+            && substr($query, 0, 10) == 'DROP INDEX'
+        ) {
+             $result['identifier'] = 'DROP INDEX';
+             $prefix = explode('ON ', $query);
+             $result['tablename'] = self::getTableName($prefix[1]);
+        }
+
+        // Parse RENAME TABLE statement
+        if (! isset($result['identifier'])
+            && substr($query, 0, 13) == 'RENAME TABLE '
+        ) {
+            $result['identifier'] = 'RENAME TABLE';
+            $prefix = explode('RENAME TABLE ', $query);
+            $names  = explode(' TO ', $prefix[1]);
+            $result['tablename']      = self::getTableName($names[0]);
+            $result["tablename_after_rename"]  = self::getTableName($names[1]);
+        }
+
+        /*
+         * DML statements
+         */
+
+        if (! isset($result['identifier'])) {
+            $result["type"]       = 'DML';
+        }
+        // Parse UPDATE statement
+        if (! isset($result['identifier'])
+            && substr($query, 0, 6) == 'UPDATE'
+        ) {
+            $result['identifier'] = 'UPDATE';
+            $prefix  = explode('UPDATE ', $query);
+            $suffix  = explode(' ', $prefix[1]);
+            $result['tablename'] = self::getTableName($suffix[0]);
+        }
+
+        // Parse INSERT INTO statement
+        if (! isset($result['identifier'])
+            && substr($query, 0, 11) == 'INSERT INTO'
+        ) {
+            $result['identifier'] = 'INSERT';
+            $prefix  = explode('INSERT INTO', $query);
+            $suffix  = explode('(', $prefix[1]);
+            $result['tablename'] = self::getTableName($suffix[0]);
+        }
+
+        // Parse DELETE statement
+        if (! isset($result['identifier'])
+            && substr($query, 0, 6) == 'DELETE'
+        ) {
+            $result['identifier'] = 'DELETE';
+            $prefix  = explode('FROM ', $query);
+            $suffix  = explode(' ', $prefix[1]);
+            $result['tablename'] = self::getTableName($suffix[0]);
+        }
+
+        // Parse TRUNCATE statement
+        if (! isset($result['identifier'])
+            && substr($query, 0, 8) == 'TRUNCATE'
+        ) {
+            $result['identifier'] = 'TRUNCATE';
+            $prefix  = explode('TRUNCATE', $query);
+            $result['tablename'] = self::getTableName($prefix[1]);
+        }
+
+        return $result;
+    }
+
+
+    /**
+     * Analyzes a given SQL statement and saves tracking data.
+     *
+     * @param string $query a SQL query
+     *
+     * @static
+     *
+     * @return void
+     */
+    static public function handleQuery($query)
+    {
+        // If query is marked as untouchable, leave
+        if (strstr($query, "/*NOTRACK*/")) {
+            return;
+        }
+
+        if (! (substr($query, -1) == ';')) {
+            $query = $query . ";\n";
+        }
+        // Get some information about query
+        $result = self::parseQuery($query);
+
+        // Get database name
+        $dbname = trim(isset($GLOBALS['db']) ? $GLOBALS['db'] : '', '`');
+        // $dbname can be empty, for example when coming from Synchronize
+        // and this is a query for the remote server
+        if (empty($dbname)) {
+            return;
+        }
+        // Remove null bytes (preg_replace() is vulnerable in some
+        // PHP versions)
+        $dbname = str_replace("\0", "", $dbname);
+
+        // If we found a valid statement
+        if (isset($result['identifier'])) {
+            $version = self::getVersion(
+                $dbname, $result['tablename'], $result['identifier']
+            );
+
+            // If version not exists and auto-creation is enabled
+            if (self::$version_auto_create == true
+                && self::isTracked($dbname, $result['tablename']) == false
+                && $version == -1
+            ) {
+                // Create the version
+
+                switch ($result['identifier']) {
+                case 'CREATE TABLE':
+                    self::createVersion($dbname, $result['tablename'], '1');
+                    break;
+                case 'CREATE VIEW':
+                    self::createVersion(
+                        $dbname, $result['tablename'], '1', '', true
+                    );
+                    break;
+                case 'CREATE DATABASE':
+                    self::createDatabaseVersion($dbname, '1', $query);
+                    break;
+                } // end switch
+            }
+
+            // If version exists
+            if (self::isTracked($dbname, $result['tablename']) && $version != -1) {
+                if ($result['type'] == 'DDL') {
+                    $save_to = 'schema_sql';
+                } elseif ($result['type'] == 'DML') {
+                    $save_to = 'data_sql';
+                } else {
+                    $save_to = '';
+                }
+                $date  = date('Y-m-d H:i:s');
+
+                // Cut off `dbname`. from query
+                $query = preg_replace('/`' . $dbname . '`\s?\./', '', $query);
+
+                // Add log information
+                $query = self::getLogComment() . $query ;
+
+                // Mark it as untouchable
+                $sql_query = " /*NOTRACK*/\n"
+                    . " UPDATE " . self::$pma_table
+                    . " SET " . PMA_Util::backquote($save_to)
+                    . " = CONCAT( " . PMA_Util::backquote($save_to) . ",'\n"
+                    . PMA_Util::sqlAddSlashes($query) . "') ,"
+                    . " `date_updated` = '" . $date . "' ";
+
+                // If table was renamed we have to change
+                // the tablename attribute in pma_tracking too
+                if ($result['identifier'] == 'RENAME TABLE') {
+                    $sql_query .= ', `table_name` = \''
+                        . PMA_Util::sqlAddSlashes($result['tablename_after_rename'])
+                        . '\' ';
+                }
+
+                // Save the tracking information only for
+                //     1. the database
+                //     2. the table / view
+                //     3. the statements
+                // we want to track
+                $sql_query .=
+                " WHERE FIND_IN_SET('" . $result['identifier'] . "',tracking) > 0" .
+                " AND `db_name` = '" . PMA_Util::sqlAddSlashes($dbname) . "' " .
+                " AND `table_name` = '" . PMA_Util::sqlAddSlashes($result['tablename']) . "' " .
+                " AND `version` = '" . PMA_Util::sqlAddSlashes($version) . "' ";
+
+                $result = PMA_queryAsControlUser($sql_query);
+            }
+        }
+    }
+
+    /**
+     * Transforms tracking set for Drizzle, which has no SET type
+     *
+     * Converts int<>string for Drizzle, does nothing for MySQL
+     *
+     * @param int|string $tracking_set
+     *
+     * @return int|string
+     */
+    static private function _transformTrackingSet($tracking_set)
+    {
+        if (!PMA_DRIZZLE) {
+            return $tracking_set;
+        }
+
+        // init conversion array (key 3 doesn't exist in calculated array)
+        if (isset(self::$_tracking_set_flags[3])) {
+            // initialize flags
+            $set = self::$_tracking_set_flags;
+            $array = array();
+            for ($i = 0; $i < count($set); $i++) {
+                $flag = 1 << $i;
+                $array[$flag] = $set[$i];
+                $array[$set[$i]] = $flag;
+            }
+            self::$_tracking_set_flags = $array;
+        }
+
+        if (is_numeric($tracking_set)) {
+            // int > string conversion
+            $aflags = array();
+            // count/2 - conversion table has both int > string
+            // and string > int values
+            for ($i = 0; $i < count(self::$_tracking_set_flags)/2; $i++) {
+                $flag = 1 << $i;
+                if ($tracking_set & $flag) {
+                    $aflags[] = self::$_tracking_set_flags[$flag];
+                }
+            }
+            $flags = implode(',', $aflags);
+        } else {
+            // string > int conversion
+            $flags = 0;
+            foreach (explode(',', $tracking_set) as $strflag) {
+                if ($strflag == '') {
+                    continue;
+                }
+                $flags |= self::$_tracking_set_flags[$strflag];
+            }
+        }
+
+        return $flags;
+    }
+}
+?>
diff --git a/phpmyadmin/libraries/Types.class.php b/phpmyadmin/libraries/Types.class.php
new file mode 100644
index 0000000..81e037e
--- /dev/null
+++ b/phpmyadmin/libraries/Types.class.php
@@ -0,0 +1,984 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * SQL data types definition
+ *
+ * @package PhpMyAdmin
+ */
+if (! defined('PHPMYADMIN')) {
+    exit;
+}
+
+/**
+ * Generic class holding type definitions.
+ *
+ * @package PhpMyAdmin
+ */
+class PMA_Types
+{
+    /**
+     * Returns list of unary operators.
+     *
+     * @return array
+     */
+    public function getUnaryOperators()
+    {
+        return array(
+            'IS NULL',
+            'IS NOT NULL',
+            "= ''",
+            "!= ''",
+        );
+    }
+
+    /**
+     * Check whether operator is unary.
+     *
+     * @param string $op operator name
+     *
+     * @return boolean
+     */
+    public function isUnaryOperator($op)
+    {
+        return in_array($op, $this->getUnaryOperators());
+    }
+
+    /**
+     * Returns list of operators checking for NULL.
+     *
+     * @return array
+     */
+    public function getNullOperators()
+    {
+        return array(
+            'IS NULL',
+            'IS NOT NULL',
+        );
+    }
+
+    /**
+     * ENUM search operators
+     *
+     * @return array
+     */
+    public function getEnumOperators()
+    {
+        return array(
+            '=',
+            '!=',
+        );
+    }
+
+    /**
+     * TEXT search operators
+     *
+     * @return array
+     */
+    public function getTextOperators()
+    {
+        return array(
+            'LIKE',
+            'LIKE %...%',
+            'NOT LIKE',
+            '=',
+            '!=',
+            'REGEXP',
+            'REGEXP ^...$',
+            'NOT REGEXP',
+            "= ''",
+            "!= ''",
+            'IN (...)',
+            'NOT IN (...)',
+            'BETWEEN',
+            'NOT BETWEEN',
+        );
+    }
+
+    /**
+     * Number search operators
+     *
+     * @return array
+     */
+    public function getNumberOperators()
+    {
+        return array(
+            '=',
+            '>',
+            '>=',
+            '<',
+            '<=',
+            '!=',
+            'LIKE',
+            'LIKE %...%',
+            'NOT LIKE',
+            'IN (...)',
+            'NOT IN (...)',
+            'BETWEEN',
+            'NOT BETWEEN',
+        );
+    }
+
+    /**
+     * Returns operators for given type
+     *
+     * @param string  $type Type of field
+     * @param boolean $null Whether field can be NULL
+     *
+     * @return array
+     */
+    public function getTypeOperators($type, $null)
+    {
+        $ret = array();
+        $class = $this->getTypeClass($type);
+
+        if (strncasecmp($type, 'enum', 4) == 0) {
+            $ret = array_merge($ret, $this->getEnumOperators());
+        } elseif ($class == 'CHAR') {
+            $ret = array_merge($ret, $this->getTextOperators());
+        } else {
+            $ret = array_merge($ret, $this->getNumberOperators());
+        }
+
+        if ($null) {
+            $ret = array_merge($ret, $this->getNullOperators());
+        }
+
+        return $ret;
+    }
+
+    /**
+     * Returns operators for given type as html options
+     *
+     * @param string  $type             Type of field
+     * @param boolean $null             Whether field can be NULL
+     * @param string  $selectedOperator Option to be selected
+     *
+     * @return string Generated Html
+     */
+    public function getTypeOperatorsHtml($type, $null, $selectedOperator = null)
+    {
+        $html = '';
+
+        foreach ($this->getTypeOperators($type, $null) as $fc) {
+            if (isset($selectedOperator) && $selectedOperator == $fc) {
+                $html .= '<option value="' . htmlspecialchars($fc)  . '" selected="selected">'
+                    . htmlspecialchars($fc)  . '</option>';
+            } else {
+                $html .= '<option value="' . htmlspecialchars($fc)  . '">'
+                    . htmlspecialchars($fc)  . '</option>';
+            }
+        }
+
+        return $html;
+    }
+
+    /**
+     * Returns the data type description.
+     *
+     * @param string $type The data type to get a description.
+     *
+     * @return string
+     *
+     */
+    public function getTypeDescription($type)
+    {
+        return '';
+    }
+
+    /**
+     * Returns class of a type, used for functions available for type
+     * or default values.
+     *
+     * @param string $type The data type to get a class.
+     *
+     * @return string
+     *
+     */
+    public function getTypeClass($type)
+    {
+        return '';
+    }
+
+    /**
+     * Returns array of functions available for a class.
+     *
+     * @param string $class The class to get function list.
+     *
+     * @return array
+     *
+     */
+    public function getFunctionsClass($class)
+    {
+        return array();
+    }
+
+    /**
+     * Returns array of functions available for a type.
+     *
+     * @param string $type The data type to get function list.
+     *
+     * @return array
+     *
+     */
+    public function getFunctions($type)
+    {
+        $class = $this->getTypeClass($type);
+        return $this->getFunctionsClass($class);
+    }
+
+    /**
+     * Returns array of all functions available.
+     *
+     * @return array
+     *
+     */
+    public function getAllFunctions()
+    {
+        $ret = array_merge(
+            $this->getFunctionsClass('CHAR'),
+            $this->getFunctionsClass('NUMBER'),
+            $this->getFunctionsClass('DATE'),
+            $this->getFunctionsClass('UUID')
+        );
+        sort($ret);
+        return $ret;
+    }
+
+    /**
+     * Returns array of all attributes available.
+     *
+     * @return array
+     *
+     */
+    public function getAttributes()
+    {
+        return array();
+    }
+
+    /**
+     * Returns array of all column types available.
+     *
+     * @return array
+     *
+     */
+    public function getColumns()
+    {
+        // most used types
+        return array(
+            'INT',
+            'VARCHAR',
+            'TEXT',
+            'DATE',
+        );
+    }
+}
+
+/**
+ * Class holding type definitions for MySQL.
+ *
+ * @package PhpMyAdmin
+ */
+class PMA_Types_MySQL extends PMA_Types
+{
+    /**
+     * Returns the data type description.
+     *
+     * @param string $type The data type to get a description.
+     *
+     * @return string
+     *
+     */
+    public function getTypeDescription($type)
+    {
+        $type = strtoupper($type);
+        switch ($type) {
+        case 'TINYINT':
+            return __('A 1-byte integer, signed range is -128 to 127, unsigned range is 0 to 255');
+        case 'SMALLINT':
+            return __('A 2-byte integer, signed range is -32,768 to 32,767, unsigned range is 0 to 65,535');
+        case 'MEDIUMINT':
+            return __('A 3-byte integer, signed range is -8,388,608 to 8,388,607, unsigned range is 0 to 16,777,215');
+        case 'INT':
+            return __('A 4-byte integer, signed range is -2,147,483,648 to 2,147,483,647, unsigned range is 0 to 4,294,967,295.');
+        case 'BIGINT':
+            return __('An 8-byte integer, signed range is -9,223,372,036,854,775,808 to 9,223,372,036,854,775,807, unsigned range is 0 to 18,446,744,073,709,551,615');
+        case 'DECIMAL':
+            return __('A fixed-point number (M, D) - the maximum number of digits (M) is 65 (default 10), the maximum number of decimals (D) is 30 (default 0)');
+        case 'FLOAT':
+            return __('A small floating-point number, allowable values are -3.402823466E+38 to -1.175494351E-38, 0, and 1.175494351E-38 to 3.402823466E+38');
+        case 'DOUBLE':
+            return __('A double-precision floating-point number, allowable values are -1.7976931348623157E+308 to -2.2250738585072014E-308, 0, and 2.2250738585072014E-308 to 1.7976931348623157E+308');
+        case 'REAL':
+            return __('Synonym for DOUBLE (exception: in REAL_AS_FLOAT SQL mode it is a synonym for FLOAT)');
+        case 'BIT':
+            return __('A bit-field type (M), storing M of bits per value (default is 1, maximum is 64)');
+        case 'BOOLEAN':
+            return __('A synonym for TINYINT(1), a value of zero is considered false, nonzero values are considered true');
+        case 'SERIAL':
+            return __('An alias for BIGINT UNSIGNED NOT NULL AUTO_INCREMENT UNIQUE');
+        case 'DATE':
+            return sprintf(__('A date, supported range is %1$s to %2$s'), '1000-01-01', '9999-12-31');
+        case 'DATETIME':
+            return sprintf(__('A date and time combination, supported range is %1$s to %2$s'), '1000-01-01 00:00:00', '9999-12-31 23:59:59');
+        case 'TIMESTAMP':
+            return __('A timestamp, range is 1970-01-01 00:00:01 UTC to 2038-01-09 03:14:07 UTC, stored as the number of seconds since the epoch (1970-01-01 00:00:00 UTC)');
+        case 'TIME':
+            return sprintf(__('A time, range is %1$s to %2$s'), '-838:59:59', '838:59:59');
+        case 'YEAR':
+            return __("A year in four-digit (4, default) or two-digit (2) format, the allowable values are 70 (1970) to 69 (2069) or 1901 to 2155 and 0000");
+        case 'CHAR':
+            return __('A fixed-length (0-255, default 1) string that is always right-padded with spaces to the specified length when stored');
+        case 'VARCHAR':
+            return sprintf(__('A variable-length (%s) string, the effective maximum length is subject to the maximum row size'), '0-65,535');
+        case 'TINYTEXT':
+            return __('A TEXT column with a maximum length of 255 (2^8 - 1) characters, stored with a one-byte prefix indicating the length of the value in bytes');
+        case 'TEXT':
+            return __('A TEXT column with a maximum length of 65,535 (2^16 - 1) characters, stored with a two-byte prefix indicating the length of the value in bytes');
+        case 'MEDIUMTEXT':
+            return __('A TEXT column with a maximum length of 16,777,215 (2^24 - 1) characters, stored with a three-byte prefix indicating the length of the value in bytes');
+        case 'LONGTEXT':
+            return __('A TEXT column with a maximum length of 4,294,967,295 or 4GiB (2^32 - 1) characters, stored with a four-byte prefix indicating the length of the value in bytes');
+        case 'BINARY':
+            return __('Similar to the CHAR type, but stores binary byte strings rather than non-binary character strings');
+        case 'VARBINARY':
+            return __('Similar to the VARCHAR type, but stores binary byte strings rather than non-binary character strings');
+        case 'TINYBLOB':
+            return __('A BLOB column with a maximum length of 255 (2^8 - 1) bytes, stored with a one-byte prefix indicating the length of the value');
+        case 'MEDIUMBLOB':
+            return __('A BLOB column with a maximum length of 16,777,215 (2^24 - 1) bytes, stored with a three-byte prefix indicating the length of the value');
+        case 'BLOB':
+            return __('A BLOB column with a maximum length of 65,535 (2^16 - 1) bytes, stored with a two-byte prefix indicating the length of the value');
+        case 'LONGBLOB':
+            return __('A BLOB column with a maximum length of 4,294,967,295 or 4GiB (2^32 - 1) bytes, stored with a four-byte prefix indicating the length of the value');
+        case 'ENUM':
+            return __("An enumeration, chosen from the list of up to 65,535 values or the special '' error value");
+        case 'SET':
+            return __("A single value chosen from a set of up to 64 members");
+        case 'GEOMETRY':
+            return __('A type that can store a geometry of any type');
+        case 'POINT':
+            return __('A point in 2-dimensional space');
+        case 'LINESTRING':
+            return __('A curve with linear interpolation between points');
+        case 'POLYGON':
+            return __('A polygon');
+        case 'MULTIPOINT':
+            return __('A collection of points');
+        case 'MULTILINESTRING':
+            return __('A collection of curves with linear interpolation between points');
+        case 'MULTIPOLYGON':
+            return __('A collection of polygons');
+        case 'GEOMETRYCOLLECTION':
+            return __('A collection of geometry objects of any type');
+        }
+        return '';
+    }
+
+    /**
+     * Returns class of a type, used for functions available for type
+     * or default values.
+     *
+     * @param string $type The data type to get a class.
+     *
+     * @return string
+     *
+     */
+    public function getTypeClass($type)
+    {
+        $type = strtoupper($type);
+        switch ($type) {
+        case 'TINYINT':
+        case 'SMALLINT':
+        case 'MEDIUMINT':
+        case 'INT':
+        case 'BIGINT':
+        case 'DECIMAL':
+        case 'FLOAT':
+        case 'DOUBLE':
+        case 'REAL':
+        case 'BIT':
+        case 'BOOLEAN':
+        case 'SERIAL':
+            return 'NUMBER';
+
+        case 'DATE':
+        case 'DATETIME':
+        case 'TIMESTAMP':
+        case 'TIME':
+        case 'YEAR':
+            return 'DATE';
+
+        case 'CHAR':
+        case 'VARCHAR':
+        case 'TINYTEXT':
+        case 'TEXT':
+        case 'MEDIUMTEXT':
+        case 'LONGTEXT':
+        case 'BINARY':
+        case 'VARBINARY':
+        case 'TINYBLOB':
+        case 'MEDIUMBLOB':
+        case 'BLOB':
+        case 'LONGBLOB':
+        case 'ENUM':
+        case 'SET':
+            return 'CHAR';
+
+        case 'GEOMETRY':
+        case 'POINT':
+        case 'LINESTRING':
+        case 'POLYGON':
+        case 'MULTIPOINT':
+        case 'MULTILINESTRING':
+        case 'MULTIPOLYGON':
+        case 'GEOMETRYCOLLECTION':
+            return 'SPATIAL';
+        }
+
+        return '';
+    }
+
+    /**
+     * Returns array of functions available for a class.
+     *
+     * @param string $class The class to get function list.
+     *
+     * @return array
+     *
+     */
+    public function getFunctionsClass($class)
+    {
+        switch ($class) {
+        case 'CHAR':
+            return array(
+                'BIN',
+                'CHAR',
+                'COMPRESS',
+                'CURRENT_USER',
+                'DATABASE',
+                'DAYNAME',
+                'DES_DECRYPT',
+                'DES_ENCRYPT',
+                'ENCRYPT',
+                'HEX',
+                'INET_NTOA',
+                'LOAD_FILE',
+                'LOWER',
+                'LTRIM',
+                'MD5',
+                'MONTHNAME',
+                'OLD_PASSWORD',
+                'PASSWORD',
+                'QUOTE',
+                'REVERSE',
+                'RTRIM',
+                'SHA1',
+                'SOUNDEX',
+                'SPACE',
+                'TRIM',
+                'UNCOMPRESS',
+                'UNHEX',
+                'UPPER',
+                'USER',
+                'UUID',
+                'VERSION',
+            );
+
+        case 'DATE':
+            return array(
+                'CURRENT_DATE',
+                'CURRENT_TIME',
+                'DATE',
+                'FROM_DAYS',
+                'FROM_UNIXTIME',
+                'LAST_DAY',
+                'NOW',
+                'SEC_TO_TIME',
+                'SYSDATE',
+                'TIME',
+                'TIMESTAMP',
+                'UTC_DATE',
+                'UTC_TIME',
+                'UTC_TIMESTAMP',
+                'YEAR',
+            );
+
+        case 'NUMBER':
+            $ret = array(
+                'ABS',
+                'ACOS',
+                'ASCII',
+                'ASIN',
+                'ATAN',
+                'BIT_LENGTH',
+                'BIT_COUNT',
+                'CEILING',
+                'CHAR_LENGTH',
+                'CONNECTION_ID',
+                'COS',
+                'COT',
+                'CRC32',
+                'DAYOFMONTH',
+                'DAYOFWEEK',
+                'DAYOFYEAR',
+                'DEGREES',
+                'EXP',
+                'FLOOR',
+                'HOUR',
+                'INET_ATON',
+                'LENGTH',
+                'LN',
+                'LOG',
+                'LOG2',
+                'LOG10',
+                'MICROSECOND',
+                'MINUTE',
+                'MONTH',
+                'OCT',
+                'ORD',
+                'PI',
+                'QUARTER',
+                'RADIANS',
+                'RAND',
+                'ROUND',
+                'SECOND',
+                'SIGN',
+                'SIN',
+                'SQRT',
+                'TAN',
+                'TO_DAYS',
+                'TO_SECONDS',
+                'TIME_TO_SEC',
+                'UNCOMPRESSED_LENGTH',
+                'UNIX_TIMESTAMP',
+                'UUID_SHORT',
+                'WEEK',
+                'WEEKDAY',
+                'WEEKOFYEAR',
+                'YEARWEEK',
+            );
+            // remove functions that are unavailable on current server
+            if (PMA_MYSQL_INT_VERSION < 50500) {
+                $ret = array_diff($ret, array('TO_SECONDS'));
+            }
+            if (PMA_MYSQL_INT_VERSION < 50120) {
+                $ret = array_diff($ret, array('UUID_SHORT'));
+            }
+            return $ret;
+
+        case 'SPATIAL':
+            return array(
+                'GeomFromText',
+                'GeomFromWKB',
+
+                'GeomCollFromText',
+                'LineFromText',
+                'MLineFromText',
+                'PointFromText',
+                'MPointFromText',
+                'PolyFromText',
+                'MPolyFromText',
+
+                'GeomCollFromWKB',
+                'LineFromWKB',
+                'MLineFromWKB',
+                'PointFromWKB',
+                'MPointFromWKB',
+                'PolyFromWKB',
+                'MPolyFromWKB',
+            );
+        }
+        return array();
+    }
+
+    /**
+     * Returns array of all attributes available.
+     *
+     * @return array
+     *
+     */
+    public function getAttributes()
+    {
+        return array(
+            '',
+            'BINARY',
+            'UNSIGNED',
+            'UNSIGNED ZEROFILL',
+            'on update CURRENT_TIMESTAMP',
+        );
+    }
+
+    /**
+     * Returns array of all column types available.
+     *
+     * VARCHAR, TINYINT, TEXT and DATE are listed first, based on
+     * estimated popularity.
+     *
+     * @return array
+     *
+     */
+    public function getColumns()
+    {
+        $ret = parent::getColumns();
+        // numeric
+        $ret[_pgettext('numeric types', 'Numeric')] = array(
+            'TINYINT',
+            'SMALLINT',
+            'MEDIUMINT',
+            'INT',
+            'BIGINT',
+            '-',
+            'DECIMAL',
+            'FLOAT',
+            'DOUBLE',
+            'REAL',
+            '-',
+            'BIT',
+            'BOOLEAN',
+            'SERIAL',
+        );
+
+
+        // Date/Time
+        $ret[_pgettext('date and time types', 'Date and time')] = array(
+            'DATE',
+            'DATETIME',
+            'TIMESTAMP',
+            'TIME',
+            'YEAR',
+        );
+
+        // Text
+        $ret[_pgettext('string types', 'String')] = array(
+            'CHAR',
+            'VARCHAR',
+            '-',
+            'TINYTEXT',
+            'TEXT',
+            'MEDIUMTEXT',
+            'LONGTEXT',
+            '-',
+            'BINARY',
+            'VARBINARY',
+            '-',
+            'TINYBLOB',
+            'MEDIUMBLOB',
+            'BLOB',
+            'LONGBLOB',
+            '-',
+            'ENUM',
+            'SET',
+        );
+
+        $ret[_pgettext('spatial types', 'Spatial')] = array(
+            'GEOMETRY',
+            'POINT',
+            'LINESTRING',
+            'POLYGON',
+            'MULTIPOINT',
+            'MULTILINESTRING',
+            'MULTIPOLYGON',
+            'GEOMETRYCOLLECTION',
+        );
+
+        return $ret;
+    }
+}
+
+/**
+ * Class holding type definitions for Drizzle.
+ *
+ * @package PhpMyAdmin
+ */
+class PMA_Types_Drizzle extends PMA_Types
+{
+    /**
+     * Returns the data type description.
+     *
+     * @param string $type The data type to get a description.
+     *
+     * @return string
+     *
+     */
+    public function getTypeDescription($type)
+    {
+        $type = strtoupper($type);
+        switch ($type) {
+        case 'INTEGER':
+            return __('A 4-byte integer, range is -2,147,483,648 to 2,147,483,647');
+        case 'BIGINT':
+            return __('An 8-byte integer, range is -9,223,372,036,854,775,808 to 9,223,372,036,854,775,807');
+        case 'DECIMAL':
+            return __('A fixed-point number (M, D) - the maximum number of digits (M) is 65 (default 10), the maximum number of decimals (D) is 30 (default 0)');
+        case 'DOUBLE':
+            return __("A system's default double-precision floating-point number");
+        case 'BOOLEAN':
+            return __('True or false');
+        case 'SERIAL':
+            return __('An alias for BIGINT NOT NULL AUTO_INCREMENT UNIQUE');
+        case 'UUID':
+            return __('Stores a Universally Unique Identifier (UUID)');
+        case 'DATE':
+            return sprintf(__('A date, supported range is %1$s to %2$s'), '0001-01-01', '9999-12-31');
+        case 'DATETIME':
+            return sprintf(__('A date and time combination, supported range is %1$s to %2$s'), '0001-01-01 00:00:0', '9999-12-31 23:59:59');
+        case 'TIMESTAMP':
+            return __("A timestamp, range is '0001-01-01 00:00:00' UTC to '9999-12-31 23:59:59' UTC; TIMESTAMP(6) can store microseconds");
+        case 'TIME':
+            return sprintf(__('A time, range is %1$s to %2$s'), '00:00:00', '23:59:59');
+        case 'VARCHAR':
+            return sprintf(__('A variable-length (%s) string, the effective maximum length is subject to the maximum row size'), '0-16,383');
+        case 'TEXT':
+            return __('A TEXT column with a maximum length of 65,535 (2^16 - 1) characters, stored with a two-byte prefix indicating the length of the value in bytes');
+        case 'VARBINARY':
+            return __('A variable-length (0-65,535) string, uses binary collation for all comparisons');
+        case 'BLOB':
+            return __('A BLOB column with a maximum length of 65,535 (2^16 - 1) bytes, stored with a two-byte prefix indicating the length of the value');
+        case 'ENUM':
+            return __("An enumeration, chosen from the list of defined values");
+        }
+        return '';
+    }
+
+    /**
+     * Returns class of a type, used for functions available for type
+     * or default values.
+     *
+     * @param string $type The data type to get a class.
+     *
+     * @return string
+     *
+     */
+    public function getTypeClass($type)
+    {
+        $type = strtoupper($type);
+        switch ($type) {
+        case 'INTEGER':
+        case 'BIGINT':
+        case 'DECIMAL':
+        case 'DOUBLE':
+        case 'BOOLEAN':
+        case 'SERIAL':
+            return 'NUMBER';
+
+        case 'DATE':
+        case 'DATETIME':
+        case 'TIMESTAMP':
+        case 'TIME':
+            return 'DATE';
+
+        case 'VARCHAR':
+        case 'TEXT':
+        case 'VARBINARY':
+        case 'BLOB':
+        case 'ENUM':
+            return 'CHAR';
+
+        case 'UUID':
+            return 'UUID';
+        }
+        return '';
+    }
+
+    /**
+     * Returns array of functions available for a class.
+     *
+     * @param string $class The class to get function list.
+     *
+     * @return array
+     *
+     */
+    public function getFunctionsClass($class)
+    {
+        switch ($class) {
+        case 'CHAR':
+            $ret = array(
+                'BIN',
+                'CHAR',
+                'COMPRESS',
+                'CURRENT_USER',
+                'DATABASE',
+                'DAYNAME',
+                'HEX',
+                'LOAD_FILE',
+                'LOWER',
+                'LTRIM',
+                'MD5',
+                'MONTHNAME',
+                'QUOTE',
+                'REVERSE',
+                'RTRIM',
+                'SCHEMA',
+                'SPACE',
+                'TRIM',
+                'UNCOMPRESS',
+                'UNHEX',
+                'UPPER',
+                'USER',
+                'UUID',
+                'VERSION',
+            );
+
+            // check for some functions known to be in modules
+            $functions = array(
+                'MYSQL_PASSWORD',
+                'ROT13',
+            );
+
+            // add new functions
+            $sql = "SELECT upper(plugin_name) f
+                FROM data_dictionary.plugins
+                WHERE plugin_name IN ('" . implode("','", $functions) . "')
+                  AND plugin_type = 'Function'
+                  AND is_active";
+            $drizzle_functions = PMA_DBI_fetch_result($sql, 'f', 'f');
+            if (count($drizzle_functions) > 0) {
+                $ret = array_merge($ret, $drizzle_functions);
+                sort($ret);
+            }
+
+            return $ret;
+
+        case 'UUID':
+            return array(
+                'UUID',
+            );
+
+        case 'DATE':
+            return array(
+                'CURRENT_DATE',
+                'CURRENT_TIME',
+                'DATE',
+                'FROM_DAYS',
+                'FROM_UNIXTIME',
+                'LAST_DAY',
+                'NOW',
+                'SYSDATE',
+                //'TIME', // https://bugs.launchpad.net/drizzle/+bug/804571
+                'TIMESTAMP',
+                'UTC_DATE',
+                'UTC_TIME',
+                'UTC_TIMESTAMP',
+                'YEAR',
+            );
+
+        case 'NUMBER':
+            return array(
+                'ABS',
+                'ACOS',
+                'ASCII',
+                'ASIN',
+                'ATAN',
+                'BIT_COUNT',
+                'CEILING',
+                'CHAR_LENGTH',
+                'CONNECTION_ID',
+                'COS',
+                'COT',
+                'CRC32',
+                'DAYOFMONTH',
+                'DAYOFWEEK',
+                'DAYOFYEAR',
+                'DEGREES',
+                'EXP',
+                'FLOOR',
+                'HOUR',
+                'LENGTH',
+                'LN',
+                'LOG',
+                'LOG2',
+                'LOG10',
+                'MICROSECOND',
+                'MINUTE',
+                'MONTH',
+                'OCT',
+                'ORD',
+                'PI',
+                'QUARTER',
+                'RADIANS',
+                'RAND',
+                'ROUND',
+                'SECOND',
+                'SIGN',
+                'SIN',
+                'SQRT',
+                'TAN',
+                'TO_DAYS',
+                'TIME_TO_SEC',
+                'UNCOMPRESSED_LENGTH',
+                'UNIX_TIMESTAMP',
+                //'WEEK', // same as TIME
+                'WEEKDAY',
+                'WEEKOFYEAR',
+                'YEARWEEK',
+            );
+        }
+        return array();
+    }
+
+    /**
+     * Returns array of all attributes available.
+     *
+     * @return array
+     *
+     */
+    public function getAttributes()
+    {
+        return array(
+            '',
+            'on update CURRENT_TIMESTAMP',
+        );
+    }
+
+    /**
+     * Returns array of all column types available.
+     *
+     * @return array
+     *
+     */
+    public function getColumns()
+    {
+        $types_num = array(
+            'INTEGER',
+            'BIGINT',
+            '-',
+            'DECIMAL',
+            'DOUBLE',
+            '-',
+            'BOOLEAN',
+            'SERIAL',
+            'UUID',
+        );
+        $types_date = array(
+            'DATE',
+            'DATETIME',
+            'TIMESTAMP',
+            'TIME',
+        );
+        $types_string = array(
+            'VARCHAR',
+            'TEXT',
+            '-',
+            'VARBINARY',
+            'BLOB',
+            '-',
+            'ENUM',
+        );
+        if (PMA_MYSQL_INT_VERSION >= 20120130) {
+            $types_string[] = '-';
+            $types_string[] = 'IPV6';
+        }
+
+        $ret = parent::getColumns();
+        // numeric
+        $ret[_pgettext('numeric types', 'Numeric')] = $types_num;
+
+        // Date/Time
+        $ret[_pgettext('date and time types', 'Date and time')] = $types_date;
+
+        // Text
+        $ret[_pgettext('string types', 'String')] = $types_string;
+
+        return $ret;
+    }
+}
diff --git a/phpmyadmin/libraries/Util.class.php b/phpmyadmin/libraries/Util.class.php
new file mode 100644
index 0000000..3468776
--- /dev/null
+++ b/phpmyadmin/libraries/Util.class.php
@@ -0,0 +1,4098 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * Hold the PMA_Util class
+ *
+ * @package PhpMyAdmin
+ */
+if (! defined('PHPMYADMIN')) {
+    exit;
+}
+
+/**
+ * Misc functions used all over the scripts.
+ *
+ * @package PhpMyAdmin
+ */
+class PMA_Util
+{
+
+    /**
+     * Detects which function to use for pow.
+     *
+     * @return string Function name.
+     */
+    public static function detectPow()
+    {
+        if (function_exists('bcpow')) {
+            // BCMath Arbitrary Precision Mathematics Function
+            return 'bcpow';
+        } elseif (function_exists('gmp_pow')) {
+            // GMP Function
+            return 'gmp_pow';
+        } else {
+            // PHP function
+            return 'pow';
+        }
+    }
+
+    /**
+     * Exponential expression / raise number into power
+     *
+     * @param string $base         base to raise
+     * @param string $exp          exponent to use
+     * @param mixed  $use_function pow function to use, or false for auto-detect
+     *
+     * @return mixed string or float
+     */
+    public static function pow($base, $exp, $use_function = false)
+    {
+        static $pow_function = null;
+
+        if ($pow_function == null) {
+            $pow_function = self::detectPow();
+        }
+
+        if (! $use_function) {
+            if ($exp < 0) {
+                $use_function = 'pow';
+            } else {
+                $use_function = $pow_function;
+            }
+        }
+
+        if (($exp < 0) && ($use_function != 'pow')) {
+            return false;
+        }
+
+        switch ($use_function) {
+        case 'bcpow' :
+            // bcscale() needed for testing pow() with base values < 1
+            bcscale(10);
+            $pow = bcpow($base, $exp);
+            break;
+        case 'gmp_pow' :
+             $pow = gmp_strval(gmp_pow($base, $exp));
+            break;
+        case 'pow' :
+            $base = (float) $base;
+            $exp = (int) $exp;
+            $pow = pow($base, $exp);
+            break;
+        default:
+            $pow = $use_function($base, $exp);
+        }
+
+        return $pow;
+    }
+
+    /**
+     * Returns an HTML IMG tag for a particular icon from a theme,
+     * which may be an actual file or an icon from a sprite.
+     * This function takes into account the PropertiesIconic
+     * configuration setting and wraps the image tag in a span tag.
+     *
+     * @param string  $icon       name of icon file
+     * @param string  $alternate  alternate text
+     * @param boolean $force_text whether to force alternate text to be displayed
+     * @param boolean $menu_icon  whether this icon is for the menu bar or not
+     *
+     * @return string an html snippet
+     */
+    public static function getIcon($icon, $alternate = '', $force_text = false,
+        $menu_icon = false
+    ) {
+        // $cfg['PropertiesIconic'] is true or both
+        $include_icon = ($GLOBALS['cfg']['PropertiesIconic'] !== false);
+        // $cfg['PropertiesIconic'] is false or both
+        // OR we have no $include_icon
+        $include_text = ($force_text
+            || ($GLOBALS['cfg']['PropertiesIconic'] !== true));
+
+        // Sometimes use a span (we rely on this in js/sql.js). But for menu bar
+        // we don't need a span
+        $button = $menu_icon ? '' : '<span class="nowrap">';
+        if ($include_icon) {
+            $button .= self::getImage($icon, $alternate);
+        }
+        if ($include_icon && $include_text) {
+            $button .= ' ';
+        }
+        if ($include_text) {
+            $button .= $alternate;
+        }
+        $button .= $menu_icon ? '' : '</span>';
+
+        return $button;
+    }
+
+    /**
+     * Returns an HTML IMG tag for a particular image from a theme,
+     * which may be an actual file or an icon from a sprite
+     *
+     * @param string $image      The name of the file to get
+     * @param string $alternate  Used to set 'alt' and 'title' attributes
+     *                           of the image
+     * @param array  $attributes An associative array of other attributes
+     *
+     * @return string an html IMG tag
+     */
+    public static function getImage($image, $alternate = '', $attributes = array())
+    {
+        static $sprites; // cached list of available sprites (if any)
+        if (defined('TESTSUITE')) {
+            // prevent caching in testsuite
+            unset($sprites);
+        }
+
+        $url       = '';
+        $is_sprite = false;
+        $alternate = htmlspecialchars($alternate);
+
+        // If it's the first time this function is called
+        if (! isset($sprites)) {
+            // Try to load the list of sprites
+            if (is_readable($_SESSION['PMA_Theme']->getPath() . '/sprites.lib.php')) {
+                include_once $_SESSION['PMA_Theme']->getPath() . '/sprites.lib.php';
+                $sprites = PMA_sprites();
+            } else {
+                // No sprites are available for this theme
+                $sprites = array();
+            }
+        }
+
+        // Check if we have the requested image as a sprite
+        //  and set $url accordingly
+        $class = str_replace(array('.gif','.png'), '', $image);
+        if (array_key_exists($class, $sprites)) {
+            $is_sprite = true;
+            $url = (defined('PMA_TEST_THEME') ? '../' : '') . 'themes/dot.gif';
+        } else {
+            $url = $GLOBALS['pmaThemeImage'] . $image;
+        }
+
+        // set class attribute
+        if ($is_sprite) {
+            if (isset($attributes['class'])) {
+                $attributes['class'] = "icon ic_$class " . $attributes['class'];
+            } else {
+                $attributes['class'] = "icon ic_$class";
+            }
+        }
+
+        // set all other attributes
+        $attr_str = '';
+        foreach ($attributes as $key => $value) {
+            if (! in_array($key, array('alt', 'title'))) {
+                $attr_str .= " $key=\"$value\"";
+            }
+        }
+
+        // override the alt attribute
+        if (isset($attributes['alt'])) {
+            $alt = $attributes['alt'];
+        } else {
+            $alt = $alternate;
+        }
+
+        // override the title attribute
+        if (isset($attributes['title'])) {
+            $title = $attributes['title'];
+        } else {
+            $title = $alternate;
+        }
+
+        // generate the IMG tag
+        $template = '<img src="%s" title="%s" alt="%s"%s />';
+        $retval = sprintf($template, $url, $title, $alt, $attr_str);
+
+        return $retval;
+    }
+
+    /**
+     * Returns the formatted maximum size for an upload
+     *
+     * @param integer $max_upload_size the size
+     *
+     * @return string the message
+     *
+     * @access  public
+     */
+    public static function getFormattedMaximumUploadSize($max_upload_size)
+    {
+        // I have to reduce the second parameter (sensitiveness) from 6 to 4
+        // to avoid weird results like 512 kKib
+        list($max_size, $max_unit) = self::formatByteDown($max_upload_size, 4);
+        return '(' . sprintf(__('Max: %s%s'), $max_size, $max_unit) . ')';
+    }
+
+    /**
+     * Generates a hidden field which should indicate to the browser
+     * the maximum size for upload
+     *
+     * @param integer $max_size the size
+     *
+     * @return string the INPUT field
+     *
+     * @access  public
+     */
+    public static function generateHiddenMaxFileSize($max_size)
+    {
+        return '<input type="hidden" name="MAX_FILE_SIZE" value="'
+            . $max_size . '" />';
+    }
+
+    /**
+     * Add slashes before "'" and "\" characters so a value containing them can
+     * be used in a sql comparison.
+     *
+     * @param string $a_string the string to slash
+     * @param bool   $is_like  whether the string will be used in a 'LIKE' clause
+     *                         (it then requires two more escaped sequences) or not
+     * @param bool   $crlf     whether to treat cr/lfs as escape-worthy entities
+     *                         (converts \n to \\n, \r to \\r)
+     * @param bool   $php_code whether this function is used as part of the
+     *                         "Create PHP code" dialog
+     *
+     * @return string   the slashed string
+     *
+     * @access  public
+     */
+    public static function sqlAddSlashes(
+        $a_string = '', $is_like = false, $crlf = false, $php_code = false
+    ) {
+        if ($is_like) {
+            $a_string = str_replace('\\', '\\\\\\\\', $a_string);
+        } else {
+            $a_string = str_replace('\\', '\\\\', $a_string);
+        }
+
+        if ($crlf) {
+            $a_string = strtr(
+                $a_string,
+                array("\n" => '\n', "\r" => '\r', "\t" => '\t')
+            );
+        }
+
+        if ($php_code) {
+            $a_string = str_replace('\'', '\\\'', $a_string);
+        } else {
+            $a_string = str_replace('\'', '\'\'', $a_string);
+        }
+
+        return $a_string;
+    } // end of the 'sqlAddSlashes()' function
+
+    /**
+     * Add slashes before "_" and "%" characters for using them in MySQL
+     * database, table and field names.
+     * Note: This function does not escape backslashes!
+     *
+     * @param string $name the string to escape
+     *
+     * @return string the escaped string
+     *
+     * @access  public
+     */
+    public static function escapeMysqlWildcards($name)
+    {
+        return strtr($name, array('_' => '\\_', '%' => '\\%'));
+    } // end of the 'escapeMysqlWildcards()' function
+
+    /**
+     * removes slashes before "_" and "%" characters
+     * Note: This function does not unescape backslashes!
+     *
+     * @param string $name the string to escape
+     *
+     * @return string   the escaped string
+     *
+     * @access  public
+     */
+    public static function unescapeMysqlWildcards($name)
+    {
+        return strtr($name, array('\\_' => '_', '\\%' => '%'));
+    } // end of the 'unescapeMysqlWildcards()' function
+
+    /**
+     * removes quotes (',",`) from a quoted string
+     *
+     * checks if the string is quoted and removes this quotes
+     *
+     * @param string $quoted_string string to remove quotes from
+     * @param string $quote         type of quote to remove
+     *
+     * @return string unqoted string
+     */
+    public static function unQuote($quoted_string, $quote = null)
+    {
+        $quotes = array();
+
+        if ($quote === null) {
+            $quotes[] = '`';
+            $quotes[] = '"';
+            $quotes[] = "'";
+        } else {
+            $quotes[] = $quote;
+        }
+
+        foreach ($quotes as $quote) {
+            if (substr($quoted_string, 0, 1) === $quote
+                && substr($quoted_string, -1, 1) === $quote
+            ) {
+                $unquoted_string = substr($quoted_string, 1, -1);
+                // replace escaped quotes
+                $unquoted_string = str_replace(
+                    $quote . $quote,
+                    $quote,
+                    $unquoted_string
+                );
+                return $unquoted_string;
+            }
+        }
+
+        return $quoted_string;
+    }
+
+    /**
+     * format sql strings
+     *
+     * @param mixed  $parsed_sql   pre-parsed SQL structure
+     * @param string $unparsed_sql raw SQL string
+     *
+     * @return string  the formatted sql
+     *
+     * @global  array    the configuration array
+     * @global  boolean  whether the current statement is a multiple one or not
+     *
+     * @access  public
+     * @todo    move into PMA_Sql
+     */
+    public static function formatSql($parsed_sql, $unparsed_sql = '')
+    {
+        global $cfg;
+
+        // Check that we actually have a valid set of parsed data
+        // well, not quite
+        // first check for the SQL parser having hit an error
+        if (PMA_SQP_isError()) {
+            return htmlspecialchars($parsed_sql['raw']);
+        }
+        // then check for an array
+        if (! is_array($parsed_sql)) {
+            // We don't so just return the input directly
+            // This is intended to be used for when the SQL Parser is turned off
+            $formatted_sql = "<pre>\n";
+            if (($cfg['SQP']['fmtType'] == 'none') && ($unparsed_sql != '')) {
+                $formatted_sql .= $unparsed_sql;
+            } else {
+                $formatted_sql .= $parsed_sql;
+            }
+            $formatted_sql .= "\n</pre>";
+            return $formatted_sql;
+        }
+
+        $formatted_sql = '';
+
+        switch ($cfg['SQP']['fmtType']) {
+        case 'none':
+            if ($unparsed_sql != '') {
+                $formatted_sql = '<span class="inner_sql"><pre>' . "\n"
+                    . PMA_SQP_formatNone(array('raw' => $unparsed_sql)) . "\n"
+                    . '</pre></span>';
+            } else {
+                $formatted_sql = PMA_SQP_formatNone($parsed_sql);
+            }
+            break;
+        case 'html':
+            $formatted_sql = PMA_SQP_formatHtml($parsed_sql, 'color');
+            break;
+        case 'text':
+            $formatted_sql = PMA_SQP_formatHtml($parsed_sql, 'text');
+            break;
+        default:
+            break;
+        } // end switch
+
+        return $formatted_sql;
+    } // end of the "formatSql()" function
+
+    /**
+     * Displays a link to the documentation as an icon
+     *
+     * @param string $link   documentation link
+     * @param string $target optional link target
+     *
+     * @return string the html link
+     *
+     * @access public
+     */
+    public static function showDocLink($link, $target = 'documentation')
+    {
+        return '<a href="' . $link . '" target="' . $target . '">'
+            . self::getImage('b_help.png', __('Documentation'))
+            . '</a>';
+    } // end of the 'showDocLink()' function
+
+    /**
+     * Displays a link to the official MySQL documentation
+     *
+     * @param string $chapter   chapter of "HTML, one page per chapter" documentation
+     * @param string $link      contains name of page/anchor that is being linked
+     * @param bool   $big_icon  whether to use big icon (like in left frame)
+     * @param string $anchor    anchor to page part
+     * @param bool   $just_open whether only the opening <a> tag should be returned
+     *
+     * @return string  the html link
+     *
+     * @access  public
+     */
+    public static function showMySQLDocu(
+        $chapter, $link, $big_icon = false, $anchor = '', $just_open = false
+    ) {
+        global $cfg;
+
+        if (($cfg['MySQLManualType'] == 'none') || empty($cfg['MySQLManualBase'])) {
+            return '';
+        }
+
+        // Fixup for newly used names:
+        $chapter = str_replace('_', '-', strtolower($chapter));
+        $link = str_replace('_', '-', strtolower($link));
+
+        switch ($cfg['MySQLManualType']) {
+        case 'chapters':
+            if (empty($chapter)) {
+                $chapter = 'index';
+            }
+            if (empty($anchor)) {
+                $anchor = $link;
+            }
+            $url = $cfg['MySQLManualBase'] . '/' . $chapter . '.html#' . $anchor;
+            break;
+        case 'big':
+            if (empty($anchor)) {
+                $anchor = $link;
+            }
+            $url = $cfg['MySQLManualBase'] . '#' . $anchor;
+            break;
+        case 'searchable':
+            if (empty($link)) {
+                $link = 'index';
+            }
+            $url = $cfg['MySQLManualBase'] . '/' . $link . '.html';
+            if (! empty($anchor)) {
+                $url .= '#' . $anchor;
+            }
+            break;
+        case 'viewable':
+        default:
+            if (empty($link)) {
+                $link = 'index';
+            }
+            $mysql = '5.5';
+            $lang = 'en';
+            if (defined('PMA_MYSQL_INT_VERSION')) {
+                if (PMA_MYSQL_INT_VERSION >= 50600) {
+                    $mysql = '5.6';
+                } else if (PMA_MYSQL_INT_VERSION >= 50500) {
+                    $mysql = '5.5';
+                } else if (PMA_MYSQL_INT_VERSION >= 50100) {
+                    $mysql = '5.1';
+                } else {
+                    $mysql = '5.0';
+                }
+            }
+            $url = $cfg['MySQLManualBase']
+                . '/' . $mysql . '/' . $lang . '/' . $link . '.html';
+            if (! empty($anchor)) {
+                $url .= '#' . $anchor;
+            }
+            break;
+        }
+
+        $open_link = '<a href="' . PMA_linkURL($url) . '" target="mysql_doc">';
+        if ($just_open) {
+            return $open_link;
+        } elseif ($big_icon) {
+            return $open_link
+                . self::getImage('b_sqlhelp.png', __('Documentation')) . '</a>';
+        } else {
+            return self::showDocLink(PMA_linkURL($url), 'mysql_doc');
+        }
+    } // end of the 'showMySQLDocu()' function
+
+    /**
+     * Returns link to documentation.
+     *
+     * @param string $page   Page in documentation
+     * @param string $anchor Optional anchor in page
+     *
+     * @return string URL
+     */
+    public static function getDocuLink($page, $anchor = '')
+    {
+        /* Construct base URL */
+        $url =  $page . '.html';
+        if (!empty($anchor)) {
+            $url .= '#' . $anchor;
+        }
+
+        /* Check if we have built local documentation */
+        if (defined('TESTSUITE')) {
+            /* Provide consistent URL for testsuite */
+            return PMA_linkURL('http://docs.phpmyadmin.net/en/latest/' . $url);
+        } else if (file_exists('doc/html/index.html')) {
+            if (defined('PMA_SETUP')) {
+                return '../doc/html/' . $url;
+            } else {
+                return './doc/html/' . $url;
+            }
+        } else {
+            /* TODO: Should link to correct branch for released versions */
+            return PMA_linkURL('http://docs.phpmyadmin.net/en/latest/' . $url);
+        }
+    }
+
+    /**
+     * Displays a link to the phpMyAdmin documentation
+     *
+     * @param string $page   Page in documentation
+     * @param string $anchor Optional anchor in page
+     *
+     * @return string  the html link
+     *
+     * @access  public
+     */
+    public static function showDocu($page, $anchor = '')
+    {
+        return self::showDocLink(self::getDocuLink($page, $anchor));
+    } // end of the 'showDocu()' function
+
+    /**
+     * Displays a link to the PHP documentation
+     *
+     * @param string $target anchor in documentation
+     *
+     * @return string  the html link
+     *
+     * @access  public
+     */
+    public static function showPHPDocu($target)
+    {
+        $url = PMA_getPHPDocLink($target);
+
+        return self::showDocLink($url);
+    } // end of the 'showPHPDocu()' function
+
+    /**
+     * Returns HTML code for a tooltip
+     *
+     * @param string $message the message for the tooltip
+     *
+     * @return string
+     *
+     * @access  public
+     */
+    public static function showHint($message)
+    {
+        if ($GLOBALS['cfg']['ShowHint']) {
+            $classClause = ' class="pma_hint"';
+        } else {
+            $classClause = '';
+        }
+        return '<span' . $classClause . '>'
+            . self::getImage('b_help.png')
+            . '<span class="hide">' . $message . '</span>'
+            . '</span>';
+    }
+
+    /**
+     * Displays a MySQL error message in the main panel when $exit is true.
+     * Returns the error message otherwise.
+     *
+     * @param string $error_message  the error message
+     * @param string $the_query      the sql query that failed
+     * @param bool   $is_modify_link whether to show a "modify" link or not
+     * @param string $back_url       the "back" link url (full path is not required)
+     * @param bool   $exit           EXIT the page?
+     *
+     * @return mixed
+     *
+     * @global  string    the curent table
+     * @global  string    the current db
+     *
+     * @access  public
+     */
+    public static function mysqlDie(
+        $error_message = '', $the_query = '',
+        $is_modify_link = true, $back_url = '', $exit = true
+    ) {
+        global $table, $db;
+
+        $error_msg = '';
+
+        if (! $error_message) {
+            $error_message = PMA_DBI_getError();
+        }
+        if (! $the_query && ! empty($GLOBALS['sql_query'])) {
+            $the_query = $GLOBALS['sql_query'];
+        }
+
+        // --- Added to solve bug #641765
+        if (! function_exists('PMA_SQP_isError') || PMA_SQP_isError()) {
+            $formatted_sql = htmlspecialchars($the_query);
+        } elseif (empty($the_query) || (trim($the_query) == '')) {
+            $formatted_sql = '';
+        } else {
+            if (strlen($the_query) > $GLOBALS['cfg']['MaxCharactersInDisplayedSQL']) {
+                $formatted_sql = htmlspecialchars(
+                    substr(
+                        $the_query, 0,
+                        $GLOBALS['cfg']['MaxCharactersInDisplayedSQL']
+                    )
+                )
+                . '[...]';
+            } else {
+                $formatted_sql = self::formatSql(
+                    PMA_SQP_parse($the_query), $the_query
+                );
+            }
+        }
+        // ---
+        $error_msg .= "\n" . '<!-- PMA-SQL-ERROR -->' . "\n";
+        $error_msg .= '    <div class="error"><h1>' . __('Error')
+            . '</h1>' . "\n";
+        // if the config password is wrong, or the MySQL server does not
+        // respond, do not show the query that would reveal the
+        // username/password
+        if (! empty($the_query) && ! strstr($the_query, 'connect')) {
+            // --- Added to solve bug #641765
+            if (function_exists('PMA_SQP_isError') && PMA_SQP_isError()) {
+                $error_msg .= PMA_SQP_getErrorString() . "\n";
+                $error_msg .= '<br />' . "\n";
+            }
+            // ---
+            // modified to show the help on sql errors
+            $error_msg .= '<p><strong>' . __('SQL query') . ':</strong>' . "\n";
+            if (strstr(strtolower($formatted_sql), 'select')) {
+                // please show me help to the error on select
+                $error_msg .= self::showMySQLDocu('SQL-Syntax', 'SELECT');
+            }
+            if ($is_modify_link) {
+                $_url_params = array(
+                    'sql_query' => $the_query,
+                    'show_query' => 1,
+                );
+                if (strlen($table)) {
+                    $_url_params['db'] = $db;
+                    $_url_params['table'] = $table;
+                    $doedit_goto = '<a href="tbl_sql.php'
+                        . PMA_generate_common_url($_url_params) . '">';
+                } elseif (strlen($db)) {
+                    $_url_params['db'] = $db;
+                    $doedit_goto = '<a href="db_sql.php'
+                        . PMA_generate_common_url($_url_params) . '">';
+                } else {
+                    $doedit_goto = '<a href="server_sql.php'
+                        . PMA_generate_common_url($_url_params) . '">';
+                }
+
+                $error_msg .= $doedit_goto
+                   . self::getIcon('b_edit.png', __('Edit'))
+                   . '</a>';
+            } // end if
+            $error_msg .= '    </p>' . "\n"
+                .'<p>' . "\n"
+                . $formatted_sql . "\n"
+                . '</p>' . "\n";
+        } // end if
+
+        if (! empty($error_message)) {
+            $error_message = preg_replace(
+                "@((\015\012)|(\015)|(\012)){3,}@",
+                "\n\n",
+                $error_message
+            );
+        }
+        // modified to show the help on error-returns
+        // (now error-messages-server)
+        $error_msg .= '<p>' . "\n"
+            . '    <strong>' . __('MySQL said: ') . '</strong>'
+            . self::showMySQLDocu('Error-messages-server', 'Error-messages-server')
+            . "\n"
+            . '</p>' . "\n";
+
+        // The error message will be displayed within a CODE segment.
+        // To preserve original formatting, but allow wordwrapping,
+        // we do a couple of replacements
+
+        // Replace all non-single blanks with their HTML-counterpart
+        $error_message = str_replace('  ', '  ', $error_message);
+        // Replace TAB-characters with their HTML-counterpart
+        $error_message = str_replace(
+            "\t", '    ', $error_message
+        );
+        // Replace linebreaks
+        $error_message = nl2br($error_message);
+
+        $error_msg .= '<code>' . "\n"
+            . $error_message . "\n"
+            . '</code><br />' . "\n";
+        $error_msg .= '</div>';
+
+        $_SESSION['Import_message']['message'] = $error_msg;
+
+        if ($exit) {
+            /**
+             * If in an Ajax request
+             * - avoid displaying a Back link
+             * - use PMA_Response() to transmit the message and exit
+             */
+            if ($GLOBALS['is_ajax_request'] == true) {
+                $response = PMA_Response::getInstance();
+                $response->isSuccess(false);
+                $response->addJSON('message', $error_msg);
+                exit;
+            }
+            if (! empty($back_url)) {
+                if (strstr($back_url, '?')) {
+                    $back_url .= '&no_history=true';
+                } else {
+                    $back_url .= '?no_history=true';
+                }
+
+                $_SESSION['Import_message']['go_back_url'] = $back_url;
+
+                $error_msg .= '<fieldset class="tblFooters">'
+                    . '[ <a href="' . $back_url . '">' . __('Back') . '</a> ]'
+                    . '</fieldset>' . "\n\n";
+            }
+            echo $error_msg;
+            exit;
+        } else {
+            return $error_msg;
+        }
+    } // end of the 'mysqlDie()' function
+
+    /**
+     * returns array with tables of given db with extended information and grouped
+     *
+     * @param string   $db           name of db
+     * @param string   $tables       name of tables
+     * @param integer  $limit_offset list offset
+     * @param int|bool $limit_count  max tables to return
+     *
+     * @return array    (recursive) grouped table list
+     */
+    public static function getTableList(
+        $db, $tables = null, $limit_offset = 0, $limit_count = false
+    ) {
+        $sep = $GLOBALS['cfg']['NavigationTreeTableSeparator'];
+
+        if ($tables === null) {
+            $tables = PMA_DBI_get_tables_full(
+                $db, false, false, null, $limit_offset, $limit_count
+            );
+            if ($GLOBALS['cfg']['NaturalOrder']) {
+                uksort($tables, 'strnatcasecmp');
+            }
+        }
+
+        if (count($tables) < 1) {
+            return $tables;
+        }
+
+        $default = array(
+            'Name'      => '',
+            'Rows'      => 0,
+            'Comment'   => '',
+            'disp_name' => '',
+        );
+
+        $table_groups = array();
+
+        foreach ($tables as $table_name => $table) {
+            // check for correct row count
+            if ($table['Rows'] === null) {
+                // Do not check exact row count here,
+                // if row count is invalid possibly the table is defect
+                // and this would break left frame;
+                // but we can check row count if this is a view or the
+                // information_schema database
+                // since PMA_Table::countRecords() returns a limited row count
+                // in this case.
+
+                // set this because PMA_Table::countRecords() can use it
+                $tbl_is_view = $table['TABLE_TYPE'] == 'VIEW';
+
+                if ($tbl_is_view || PMA_is_system_schema($db)) {
+                    $table['Rows'] = PMA_Table::countRecords(
+                        $db,
+                        $table['Name'],
+                        false,
+                        true
+                    );
+                }
+            }
+
+            // in $group we save the reference to the place in $table_groups
+            // where to store the table info
+            if ($GLOBALS['cfg']['NavigationTreeEnableGrouping']
+                && $sep && strstr($table_name, $sep)
+            ) {
+                $parts = explode($sep, $table_name);
+
+                $group =& $table_groups;
+                $i = 0;
+                $group_name_full = '';
+                $parts_cnt = count($parts) - 1;
+
+                while (($i < $parts_cnt)
+                    && ($i < $GLOBALS['cfg']['NavigationTreeTableLevel'])
+                ) {
+                    $group_name = $parts[$i] . $sep;
+                    $group_name_full .= $group_name;
+
+                    if (! isset($group[$group_name])) {
+                        $group[$group_name] = array();
+                        $group[$group_name]['is' . $sep . 'group'] = true;
+                        $group[$group_name]['tab' . $sep . 'count'] = 1;
+                        $group[$group_name]['tab' . $sep . 'group']
+                            = $group_name_full;
+
+                    } elseif (! isset($group[$group_name]['is' . $sep . 'group'])) {
+                        $table = $group[$group_name];
+                        $group[$group_name] = array();
+                        $group[$group_name][$group_name] = $table;
+                        unset($table);
+                        $group[$group_name]['is' . $sep . 'group'] = true;
+                        $group[$group_name]['tab' . $sep . 'count'] = 1;
+                        $group[$group_name]['tab' . $sep . 'group']
+                            = $group_name_full;
+
+                    } else {
+                        $group[$group_name]['tab' . $sep . 'count']++;
+                    }
+
+                    $group =& $group[$group_name];
+                    $i++;
+                }
+
+            } else {
+                if (! isset($table_groups[$table_name])) {
+                    $table_groups[$table_name] = array();
+                }
+                $group =& $table_groups;
+            }
+
+            $table['disp_name'] = $table['Name'];
+            $group[$table_name] = array_merge($default, $table);
+        }
+
+        return $table_groups;
+    }
+
+    /* ----------------------- Set of misc functions ----------------------- */
+
+    /**
+     * Adds backquotes on both sides of a database, table or field name.
+     * and escapes backquotes inside the name with another backquote
+     *
+     * example:
+     * <code>
+     * echo backquote('owner`s db'); // `owner``s db`
+     *
+     * </code>
+     *
+     * @param mixed   $a_name the database, table or field name to "backquote"
+     *                        or array of it
+     * @param boolean $do_it  a flag to bypass this function (used by dump
+     *                        functions)
+     *
+     * @return mixed    the "backquoted" database, table or field name
+     *
+     * @access  public
+     */
+    public static function backquote($a_name, $do_it = true)
+    {
+        if (is_array($a_name)) {
+            foreach ($a_name as &$data) {
+                $data = self::backquote($data, $do_it);
+            }
+            return $a_name;
+        }
+
+        if (! $do_it) {
+            global $PMA_SQPdata_forbidden_word;
+            if (! in_array(strtoupper($a_name), $PMA_SQPdata_forbidden_word)) {
+                return $a_name;
+            }
+        }
+
+        // '0' is also empty for php :-(
+        if (strlen($a_name) && $a_name !== '*') {
+            return '`' . str_replace('`', '``', $a_name) . '`';
+        } else {
+            return $a_name;
+        }
+    } // end of the 'backquote()' function
+
+    /**
+     * Adds quotes on both sides of a database, table or field name.
+     * in compatibility mode
+     *
+     * example:
+     * <code>
+     * echo backquote('owner`s db'); // `owner``s db`
+     *
+     * </code>
+     *
+     * @param mixed   $a_name        the database, table or field name to
+     *                               "backquote" or array of it
+     * @param string  $compatibility string compatibility mode (used by dump
+     *                               functions)
+     * @param boolean $do_it         a flag to bypass this function (used by dump
+     *                               functions)
+     *
+     * @return mixed the "backquoted" database, table or field name
+     *
+     * @access  public
+     */
+    public static function backquoteCompat(
+        $a_name, $compatibility = 'MSSQL', $do_it = true
+    ) {
+        if (is_array($a_name)) {
+            foreach ($a_name as &$data) {
+                $data = self::backquoteCompat($data, $compatibility, $do_it);
+            }
+            return $a_name;
+        }
+
+        if (! $do_it) {
+            global $PMA_SQPdata_forbidden_word;
+            if (! in_array(strtoupper($a_name), $PMA_SQPdata_forbidden_word)) {
+                return $a_name;
+            }
+        }
+
+        // @todo add more compatibility cases (ORACLE for example)
+        switch ($compatibility) {
+        case 'MSSQL':
+            $quote = '"';
+            break;
+        default:
+            (isset($GLOBALS['sql_backquotes'])) ? $quote = "`" : $quote = '';
+            break;
+        }
+
+        // '0' is also empty for php :-(
+        if (strlen($a_name) && $a_name !== '*') {
+            return $quote . $a_name . $quote;
+        } else {
+            return $a_name;
+        }
+    } // end of the 'backquoteCompat()' function
+
+    /**
+     * Defines the <CR><LF> value depending on the user OS.
+     *
+     * @return string   the <CR><LF> value to use
+     *
+     * @access  public
+     */
+    public static function whichCrlf()
+    {
+        // The 'PMA_USR_OS' constant is defined in "libraries/Config.class.php"
+        // Win case
+        if (PMA_USR_OS == 'Win') {
+            $the_crlf = "\r\n";
+        } else {
+            // Others
+            $the_crlf = "\n";
+        }
+
+        return $the_crlf;
+    } // end of the 'whichCrlf()' function
+
+    /**
+     * Prepare the message and the query
+     * usually the message is the result of the query executed
+     *
+     * @param string  $message   the message to display
+     * @param string  $sql_query the query to display
+     * @param string  $type      the type (level) of the message
+     * @param boolean $is_view   is this a message after a VIEW operation?
+     *
+     * @return string
+     *
+     * @access  public
+     */
+    public static function getMessage(
+        $message, $sql_query = null, $type = 'notice', $is_view = false
+    ) {
+        global $cfg;
+        $retval = '';
+
+        if (null === $sql_query) {
+            if (! empty($GLOBALS['display_query'])) {
+                $sql_query = $GLOBALS['display_query'];
+            } elseif ($cfg['SQP']['fmtType'] == 'none'
+                && ! empty($GLOBALS['unparsed_sql'])
+            ) {
+                $sql_query = $GLOBALS['unparsed_sql'];
+            } elseif (! empty($GLOBALS['sql_query'])) {
+                $sql_query = $GLOBALS['sql_query'];
+            } else {
+                $sql_query = '';
+            }
+        }
+
+        if (isset($GLOBALS['using_bookmark_message'])) {
+            $retval .= $GLOBALS['using_bookmark_message']->getDisplay();
+            unset($GLOBALS['using_bookmark_message']);
+        }
+
+        // In an Ajax request, $GLOBALS['cell_align_left'] may not be defined. Hence,
+        // check for it's presence before using it
+        $retval .= '<div id="result_query"'
+            . ( isset($GLOBALS['cell_align_left'])
+                ? ' style="text-align: ' . $GLOBALS['cell_align_left'] . '"'
+                : '' )
+            . '>' . "\n";
+
+        if ($message instanceof PMA_Message) {
+            if (isset($GLOBALS['special_message'])) {
+                $message->addMessage($GLOBALS['special_message']);
+                unset($GLOBALS['special_message']);
+            }
+            $retval .= $message->getDisplay();
+        } else {
+            $retval .= '<div class="' . $type . '">';
+            $retval .= PMA_sanitize($message);
+            if (isset($GLOBALS['special_message'])) {
+                $retval .= PMA_sanitize($GLOBALS['special_message']);
+                unset($GLOBALS['special_message']);
+            }
+            $retval .= '</div>';
+        }
+
+        if ($cfg['ShowSQL'] == true && ! empty($sql_query)) {
+            // Html format the query to be displayed
+            // If we want to show some sql code it is easiest to create it here
+            /* SQL-Parser-Analyzer */
+
+            if (! empty($GLOBALS['show_as_php'])) {
+                $new_line = '\\n"<br />' . "\n"
+                    . '    . "';
+                $query_base = htmlspecialchars(addslashes($sql_query));
+                $query_base = preg_replace(
+                    '/((\015\012)|(\015)|(\012))/', $new_line, $query_base
+                );
+            } else {
+                $query_base = $sql_query;
+            }
+
+            $query_too_big = false;
+
+            if (strlen($query_base) > $cfg['MaxCharactersInDisplayedSQL']) {
+                // when the query is large (for example an INSERT of binary
+                // data), the parser chokes; so avoid parsing the query
+                $query_too_big = true;
+                $shortened_query_base = nl2br(
+                    htmlspecialchars(
+                        substr($sql_query, 0, $cfg['MaxCharactersInDisplayedSQL'])
+                        . '[...]'
+                    )
+                );
+            } elseif (! empty($GLOBALS['parsed_sql'])
+             && $query_base == $GLOBALS['parsed_sql']['raw']) {
+                // (here, use "! empty" because when deleting a bookmark,
+                // $GLOBALS['parsed_sql'] is set but empty
+                $parsed_sql = $GLOBALS['parsed_sql'];
+            } else {
+                // Parse SQL if needed
+                $parsed_sql = PMA_SQP_parse($query_base);
+            }
+
+            // Analyze it
+            if (isset($parsed_sql) && ! PMA_SQP_isError()) {
+                $analyzed_display_query = PMA_SQP_analyze($parsed_sql);
+
+                // Same as below (append LIMIT), append the remembered ORDER BY
+                if ($GLOBALS['cfg']['RememberSorting']
+                    && isset($analyzed_display_query[0]['queryflags']['select_from'])
+                    && isset($GLOBALS['sql_order_to_append'])
+                ) {
+                    $query_base = $analyzed_display_query[0]['section_before_limit']
+                        . "\n" . $GLOBALS['sql_order_to_append']
+                        . $analyzed_display_query[0]['limit_clause'] . ' '
+                        . $analyzed_display_query[0]['section_after_limit'];
+
+                    // Need to reparse query
+                    $parsed_sql = PMA_SQP_parse($query_base);
+                    // update the $analyzed_display_query
+                    $analyzed_display_query[0]['section_before_limit']
+                        .= $GLOBALS['sql_order_to_append'];
+                    $analyzed_display_query[0]['order_by_clause']
+                        = $GLOBALS['sorted_col'];
+                }
+
+                // Here we append the LIMIT added for navigation, to
+                // enable its display. Adding it higher in the code
+                // to $sql_query would create a problem when
+                // using the Refresh or Edit links.
+
+                // Only append it on SELECTs.
+
+                /**
+                 * @todo what would be the best to do when someone hits Refresh:
+                 * use the current LIMITs ?
+                 */
+
+                if (isset($analyzed_display_query[0]['queryflags']['select_from'])
+                    && ! empty($GLOBALS['sql_limit_to_append'])
+                ) {
+                    $query_base = $analyzed_display_query[0]['section_before_limit']
+                        . "\n" . $GLOBALS['sql_limit_to_append']
+                        . $analyzed_display_query[0]['section_after_limit'];
+                    // Need to reparse query
+                    $parsed_sql = PMA_SQP_parse($query_base);
+                }
+            }
+
+            if (! empty($GLOBALS['show_as_php'])) {
+                $query_base = '$sql  = "' . $query_base;
+            } elseif (! empty($GLOBALS['validatequery'])) {
+                try {
+                    $query_base = PMA_validateSQL($query_base);
+                } catch (Exception $e) {
+                    $retval .= PMA_Message::error(
+                        __('Failed to connect to SQL validator!')
+                    )->getDisplay();
+                }
+            } elseif (isset($parsed_sql)) {
+                $query_base = self::formatSql($parsed_sql, $query_base);
+            }
+
+            // Prepares links that may be displayed to edit/explain the query
+            // (don't go to default pages, we must go to the page
+            // where the query box is available)
+
+            // Basic url query part
+            $url_params = array();
+            if (! isset($GLOBALS['db'])) {
+                $GLOBALS['db'] = '';
+            }
+            if (strlen($GLOBALS['db'])) {
+                $url_params['db'] = $GLOBALS['db'];
+                if (strlen($GLOBALS['table'])) {
+                    $url_params['table'] = $GLOBALS['table'];
+                    $edit_link = 'tbl_sql.php';
+                } else {
+                    $edit_link = 'db_sql.php';
+                }
+            } else {
+                $edit_link = 'server_sql.php';
+            }
+
+            // Want to have the query explained
+            // but only explain a SELECT (that has not been explained)
+            /* SQL-Parser-Analyzer */
+            $explain_link = '';
+            $is_select = false;
+            if (! empty($cfg['SQLQuery']['Explain']) && ! $query_too_big) {
+                $explain_params = $url_params;
+                // Detect if we are validating as well
+                // To preserve the validate uRL data
+                if (! empty($GLOBALS['validatequery'])) {
+                    $explain_params['validatequery'] = 1;
+                }
+                if (preg_match('@^SELECT[[:space:]]+ at i', $sql_query)) {
+                    $explain_params['sql_query'] = 'EXPLAIN ' . $sql_query;
+                    $_message = __('Explain SQL');
+                    $is_select = true;
+                } elseif (
+                    preg_match(
+                        '@^EXPLAIN[[:space:]]+SELECT[[:space:]]+ at i', $sql_query
+                    )
+                ) {
+                    $explain_params['sql_query'] = substr($sql_query, 8);
+                    $_message = __('Skip Explain SQL');
+                }
+                if (isset($explain_params['sql_query'])) {
+                    $explain_link = 'import.php'
+                        . PMA_generate_common_url($explain_params);
+                    $explain_link = ' ['
+                        . self::linkOrButton($explain_link, $_message) . ']';
+                }
+            } //show explain
+
+            $url_params['sql_query']  = $sql_query;
+            $url_params['show_query'] = 1;
+
+            // even if the query is big and was truncated, offer the chance
+            // to edit it (unless it's enormous, see linkOrButton() )
+            if (! empty($cfg['SQLQuery']['Edit'])) {
+                if ($cfg['EditInWindow'] == true) {
+                    $onclick = 'PMA_querywindow.focus(\''
+                        . PMA_jsFormat($sql_query, false) . '\'); return false;';
+                } else {
+                    $onclick = '';
+                }
+
+                $edit_link .= PMA_generate_common_url($url_params) . '#querybox';
+                $edit_link = ' ['
+                    . self::linkOrButton(
+                        $edit_link, __('Edit'),
+                        array('onclick' => $onclick, 'class' => 'disableAjax')
+                    )
+                    . ']';
+            } else {
+                $edit_link = '';
+            }
+
+            // Also we would like to get the SQL formed in some nice
+            // php-code
+            if (! empty($cfg['SQLQuery']['ShowAsPHP']) && ! $query_too_big) {
+                $php_params = $url_params;
+
+                if (! empty($GLOBALS['show_as_php'])) {
+                    $_message = __('Without PHP Code');
+                } else {
+                    $php_params['show_as_php'] = 1;
+                    $_message = __('Create PHP Code');
+                }
+
+                $php_link = 'import.php' . PMA_generate_common_url($php_params);
+                $php_link = ' [' . self::linkOrButton($php_link, $_message) . ']';
+
+                if (isset($GLOBALS['show_as_php'])) {
+
+                    $runquery_link = 'import.php'
+                        . PMA_generate_common_url($url_params);
+
+                    $php_link .= ' ['
+                        . self::linkOrButton($runquery_link, __('Submit Query'))
+                        . ']';
+                }
+            } else {
+                $php_link = '';
+            } //show as php
+
+            // Refresh query
+            if (! empty($cfg['SQLQuery']['Refresh'])
+                && ! isset($GLOBALS['show_as_php']) // 'Submit query' does the same
+                && preg_match('@^(SELECT|SHOW)[[:space:]]+ at i', $sql_query)
+            ) {
+                $refresh_link = 'import.php' . PMA_generate_common_url($url_params);
+                $refresh_link = ' ['
+                    . self::linkOrButton($refresh_link, __('Refresh')) . ']';
+            } else {
+                $refresh_link = '';
+            } //refresh
+
+            if (! empty($cfg['SQLValidator']['use'])
+                && ! empty($cfg['SQLQuery']['Validate'])
+            ) {
+                $validate_params = $url_params;
+                if (! empty($GLOBALS['validatequery'])) {
+                    $validate_message = __('Skip Validate SQL');
+                } else {
+                    $validate_params['validatequery'] = 1;
+                    $validate_message = __('Validate SQL');
+                }
+
+                $validate_link = 'import.php'
+                    . PMA_generate_common_url($validate_params);
+                $validate_link = ' ['
+                    . self::linkOrButton($validate_link, $validate_message) . ']';
+            } else {
+                $validate_link = '';
+            } //validator
+
+            if (! empty($GLOBALS['validatequery'])) {
+                $retval .= '<div class="sqlvalidate">';
+            } else {
+                $retval .= '<code class="sql">';
+            }
+            if ($query_too_big) {
+                $retval .= $shortened_query_base;
+            } else {
+                $retval .= $query_base;
+            }
+
+            //Clean up the end of the PHP
+            if (! empty($GLOBALS['show_as_php'])) {
+                $retval .= '";';
+            }
+            if (! empty($GLOBALS['validatequery'])) {
+                $retval .= '</div>';
+            } else {
+                $retval .= '</code>';
+            }
+
+            $retval .= '<div class="tools">';
+            // avoid displaying a Profiling checkbox that could
+            // be checked, which would reexecute an INSERT, for example
+            if (! empty($refresh_link)) {
+                $retval .= self::getProfilingForm($sql_query);
+            }
+            // if needed, generate an invisible form that contains controls for the
+            // Inline link; this way, the behavior of the Inline link does not
+            // depend on the profiling support or on the refresh link
+            if (empty($refresh_link) || !self::profilingSupported()) {
+                $retval .= '<form action="sql.php" method="post">';
+                $retval .= PMA_generate_common_hidden_inputs(
+                    $GLOBALS['db'], $GLOBALS['table']
+                );
+                $retval .= '<input type="hidden" name="sql_query" value="'
+                    . htmlspecialchars($sql_query) . '" />';
+                $retval .= '</form>';
+            }
+
+            // in the tools div, only display the Inline link when not in ajax
+            // mode because 1) it currently does not work and 2) we would
+            // have two similar mechanisms on the page for the same goal
+            if ($is_select || ($GLOBALS['is_ajax_request'] === false)
+                && ! $query_too_big
+            ) {
+                // see in js/functions.js the jQuery code attached to id inline_edit
+                // document.write conflicts with jQuery, hence used $().append()
+                $retval .= "<script type=\"text/javascript\">\n" .
+                    "//<![CDATA[\n" .
+                    "$('.tools form').last().after('[ <a href=\"#\" title=\"" .
+                    PMA_escapeJsString(__('Inline edit of this query')) .
+                    "\" class=\"inline_edit_sql\">" .
+                    PMA_escapeJsString(_pgettext('Inline edit query', 'Inline')) .
+                    "</a> ]');\n" .
+                    "//]]>\n" .
+                    "</script>";
+            }
+            $retval .= $edit_link . $explain_link . $php_link
+                . $refresh_link . $validate_link;
+            $retval .= '</div>';
+        }
+
+        $retval .= '</div>';
+        if ($GLOBALS['is_ajax_request'] === false) {
+            $retval .= '<br class="clearfloat" />';
+        }
+
+        return $retval;
+    } // end of the 'getMessage()' function
+
+    /**
+     * Verifies if current MySQL server supports profiling
+     *
+     * @access  public
+     *
+     * @return boolean whether profiling is supported
+     */
+    public static function profilingSupported()
+    {
+        if (!self::cacheExists('profiling_supported', true)) {
+            // 5.0.37 has profiling but for example, 5.1.20 does not
+            // (avoid a trip to the server for MySQL before 5.0.37)
+            // and do not set a constant as we might be switching servers
+            if (defined('PMA_MYSQL_INT_VERSION')
+                && (PMA_MYSQL_INT_VERSION >= 50037)
+                && PMA_DBI_fetch_value("SHOW VARIABLES LIKE 'profiling'")
+            ) {
+                self::cacheSet('profiling_supported', true, true);
+            } else {
+                self::cacheSet('profiling_supported', false, true);
+            }
+        }
+
+        return self::cacheGet('profiling_supported', true);
+    }
+
+    /**
+     * Returns HTML for the form with the Profiling checkbox
+     *
+     * @param string $sql_query sql query
+     *
+     * @return string HTML for the form with the Profiling checkbox
+     *
+     * @access  public
+     */
+    public static function getProfilingForm($sql_query)
+    {
+        $retval = '';
+        if (self::profilingSupported()) {
+
+            $retval .= '<form action="sql.php" method="post">' . "\n";
+            $retval .= PMA_generate_common_hidden_inputs(
+                $GLOBALS['db'], $GLOBALS['table']
+            );
+
+            $retval .= '<input type="hidden" name="sql_query" value="'
+                . htmlspecialchars($sql_query) . '" />' . "\n"
+                . '<input type="hidden" name="profiling_form" value="1" />' . "\n";
+
+            $retval .= self::getCheckbox(
+                'profiling', __('Profiling'), isset($_SESSION['profiling']), true
+            );
+            $retval .= ' </form>' . "\n";
+
+        }
+        return $retval;
+    }
+
+    /**
+     * Formats $value to byte view
+     *
+     * @param double $value the value to format
+     * @param int    $limes the sensitiveness
+     * @param int    $comma the number of decimals to retain
+     *
+     * @return array    the formatted value and its unit
+     *
+     * @access  public
+     */
+    public static function formatByteDown($value, $limes = 6, $comma = 0)
+    {
+        if ($value === null) {
+            return null;
+        }
+
+        $byteUnits = array(
+            /* l10n: shortcuts for Byte */
+            __('B'),
+            /* l10n: shortcuts for Kilobyte */
+            __('KiB'),
+            /* l10n: shortcuts for Megabyte */
+            __('MiB'),
+            /* l10n: shortcuts for Gigabyte */
+            __('GiB'),
+            /* l10n: shortcuts for Terabyte */
+            __('TiB'),
+            /* l10n: shortcuts for Petabyte */
+            __('PiB'),
+            /* l10n: shortcuts for Exabyte */
+            __('EiB')
+        );
+
+        $dh   = self::pow(10, $comma);
+        $li   = self::pow(10, $limes);
+        $unit = $byteUnits[0];
+
+        for ($d = 6, $ex = 15; $d >= 1; $d--, $ex-=3) {
+            if (isset($byteUnits[$d]) && ($value >= $li * self::pow(10, $ex))) {
+                // use 1024.0 to avoid integer overflow on 64-bit machines
+                $value = round($value / (self::pow(1024, $d) / $dh)) /$dh;
+                $unit = $byteUnits[$d];
+                break 1;
+            } // end if
+        } // end for
+
+        if ($unit != $byteUnits[0]) {
+            // if the unit is not bytes (as represented in current language)
+            // reformat with max length of 5
+            // 4th parameter=true means do not reformat if value < 1
+            $return_value = self::formatNumber($value, 5, $comma, true);
+        } else {
+            // do not reformat, just handle the locale
+            $return_value = self::formatNumber($value, 0);
+        }
+
+        return array(trim($return_value), $unit);
+    } // end of the 'formatByteDown' function
+
+    /**
+     * Changes thousands and decimal separators to locale specific values.
+     *
+     * @param string $value the value
+     *
+     * @return string
+     */
+    public static function localizeNumber($value)
+    {
+        return str_replace(
+            array(',', '.'),
+            array(
+                /* l10n: Thousands separator */
+                __(','),
+                /* l10n: Decimal separator */
+                __('.'),
+            ),
+            $value
+        );
+    }
+
+    /**
+     * Formats $value to the given length and appends SI prefixes
+     * with a $length of 0 no truncation occurs, number is only formated
+     * to the current locale
+     *
+     * examples:
+     * <code>
+     * echo formatNumber(123456789, 6);     // 123,457 k
+     * echo formatNumber(-123456789, 4, 2); //    -123.46 M
+     * echo formatNumber(-0.003, 6);        //      -3 m
+     * echo formatNumber(0.003, 3, 3);      //       0.003
+     * echo formatNumber(0.00003, 3, 2);    //       0.03 m
+     * echo formatNumber(0, 6);             //       0
+     * </code>
+     *
+     * @param double  $value          the value to format
+     * @param integer $digits_left    number of digits left of the comma
+     * @param integer $digits_right   number of digits right of the comma
+     * @param boolean $only_down      do not reformat numbers below 1
+     * @param boolean $noTrailingZero removes trailing zeros right of the comma
+     *                                (default: true)
+     *
+     * @return string   the formatted value and its unit
+     *
+     * @access  public
+     */
+    public static function formatNumber(
+        $value, $digits_left = 3, $digits_right = 0,
+        $only_down = false, $noTrailingZero = true
+    ) {
+        if ($value == 0) {
+            return '0';
+        }
+
+        $originalValue = $value;
+        //number_format is not multibyte safe, str_replace is safe
+        if ($digits_left === 0) {
+            $value = number_format($value, $digits_right);
+            if (($originalValue != 0) && (floatval($value) == 0)) {
+                $value = ' <' . (1 / self::pow(10, $digits_right));
+            }
+            return self::localizeNumber($value);
+        }
+
+        // this units needs no translation, ISO
+        $units = array(
+            -8 => 'y',
+            -7 => 'z',
+            -6 => 'a',
+            -5 => 'f',
+            -4 => 'p',
+            -3 => 'n',
+            -2 => 'µ',
+            -1 => 'm',
+            0 => ' ',
+            1 => 'k',
+            2 => 'M',
+            3 => 'G',
+            4 => 'T',
+            5 => 'P',
+            6 => 'E',
+            7 => 'Z',
+            8 => 'Y'
+        );
+
+        // check for negative value to retain sign
+        if ($value < 0) {
+            $sign = '-';
+            $value = abs($value);
+        } else {
+            $sign = '';
+        }
+
+        $dh = self::pow(10, $digits_right);
+
+        /*
+         * This gives us the right SI prefix already,
+         * but $digits_left parameter not incorporated
+         */
+        $d = floor(log10($value) / 3);
+        /*
+         * Lowering the SI prefix by 1 gives us an additional 3 zeros
+         * So if we have 3,6,9,12.. free digits ($digits_left - $cur_digits)
+         * to use, then lower the SI prefix
+         */
+        $cur_digits = floor(log10($value / self::pow(1000, $d, 'pow'))+1);
+        if ($digits_left > $cur_digits) {
+            $d -= floor(($digits_left - $cur_digits)/3);
+        }
+
+        if ($d < 0 && $only_down) {
+            $d = 0;
+        }
+
+        $value = round($value / (self::pow(1000, $d, 'pow') / $dh)) /$dh;
+        $unit = $units[$d];
+
+        // If we dont want any zeros after the comma just add the thousand separator
+        if ($noTrailingZero) {
+            $value = self::localizeNumber(
+                preg_replace('/(?<=\d)(?=(\d{3})+(?!\d))/', ',', $value)
+            );
+        } else {
+            //number_format is not multibyte safe, str_replace is safe
+            $value = self::localizeNumber(number_format($value, $digits_right));
+        }
+
+        if ($originalValue != 0 && floatval($value) == 0) {
+            return ' <' . (1 / self::pow(10, $digits_right)) . ' ' . $unit;
+        }
+
+        return $sign . $value . ' ' . $unit;
+    } // end of the 'formatNumber' function
+
+    /**
+     * Returns the number of bytes when a formatted size is given
+     *
+     * @param string $formatted_size the size expression (for example 8MB)
+     *
+     * @return integer  The numerical part of the expression (for example 8)
+     */
+    public static function extractValueFromFormattedSize($formatted_size)
+    {
+        $return_value = -1;
+
+        if (preg_match('/^[0-9]+GB$/', $formatted_size)) {
+            $return_value = substr($formatted_size, 0, -2) * self::pow(1024, 3);
+        } elseif (preg_match('/^[0-9]+MB$/', $formatted_size)) {
+            $return_value = substr($formatted_size, 0, -2) * self::pow(1024, 2);
+        } elseif (preg_match('/^[0-9]+K$/', $formatted_size)) {
+            $return_value = substr($formatted_size, 0, -1) * self::pow(1024, 1);
+        }
+        return $return_value;
+    }// end of the 'extractValueFromFormattedSize' function
+
+    /**
+     * Writes localised date
+     *
+     * @param string $timestamp the current timestamp
+     * @param string $format    format
+     *
+     * @return string   the formatted date
+     *
+     * @access  public
+     */
+    public static function localisedDate($timestamp = -1, $format = '')
+    {
+        $month = array(
+            /* l10n: Short month name */
+            __('Jan'),
+            /* l10n: Short month name */
+            __('Feb'),
+            /* l10n: Short month name */
+            __('Mar'),
+            /* l10n: Short month name */
+            __('Apr'),
+            /* l10n: Short month name */
+            _pgettext('Short month name', 'May'),
+            /* l10n: Short month name */
+            __('Jun'),
+            /* l10n: Short month name */
+            __('Jul'),
+            /* l10n: Short month name */
+            __('Aug'),
+            /* l10n: Short month name */
+            __('Sep'),
+            /* l10n: Short month name */
+            __('Oct'),
+            /* l10n: Short month name */
+            __('Nov'),
+            /* l10n: Short month name */
+            __('Dec'));
+        $day_of_week = array(
+            /* l10n: Short week day name */
+            _pgettext('Short week day name', 'Sun'),
+            /* l10n: Short week day name */
+            __('Mon'),
+            /* l10n: Short week day name */
+            __('Tue'),
+            /* l10n: Short week day name */
+            __('Wed'),
+            /* l10n: Short week day name */
+            __('Thu'),
+            /* l10n: Short week day name */
+            __('Fri'),
+            /* l10n: Short week day name */
+            __('Sat'));
+
+        if ($format == '') {
+            /* l10n: See http://www.php.net/manual/en/function.strftime.php */
+            $format = __('%B %d, %Y at %I:%M %p');
+        }
+
+        if ($timestamp == -1) {
+            $timestamp = time();
+        }
+
+        $date = preg_replace(
+            '@%[aA]@',
+            $day_of_week[(int)strftime('%w', $timestamp)],
+            $format
+        );
+        $date = preg_replace(
+            '@%[bB]@',
+            $month[(int)strftime('%m', $timestamp)-1],
+            $date
+        );
+
+        return strftime($date, $timestamp);
+    } // end of the 'localisedDate()' function
+
+    /**
+     * returns a tab for tabbed navigation.
+     * If the variables $link and $args ar left empty, an inactive tab is created
+     *
+     * @param array $tab        array with all options
+     * @param array $url_params tab specific URL parameters
+     *
+     * @return string  html code for one tab, a link if valid otherwise a span
+     *
+     * @access  public
+     */
+    public static function getHtmlTab($tab, $url_params = array())
+    {
+        // default values
+        $defaults = array(
+            'text'      => '',
+            'class'     => '',
+            'active'    => null,
+            'link'      => '',
+            'sep'       => '?',
+            'attr'      => '',
+            'args'      => '',
+            'warning'   => '',
+            'fragment'  => '',
+            'id'        => '',
+        );
+
+        $tab = array_merge($defaults, $tab);
+
+        // determine additionnal style-class
+        if (empty($tab['class'])) {
+            if (! empty($tab['active'])
+                || PMA_isValid($GLOBALS['active_page'], 'identical', $tab['link'])
+            ) {
+                $tab['class'] = 'active';
+            } elseif (is_null($tab['active']) && empty($GLOBALS['active_page'])
+              && (basename($GLOBALS['PMA_PHP_SELF']) == $tab['link'])) {
+                $tab['class'] = 'active';
+            }
+        }
+
+        // If there are any tab specific URL parameters, merge those with
+        // the general URL parameters
+        if (! empty($tab['url_params']) && is_array($tab['url_params'])) {
+            $url_params = array_merge($url_params, $tab['url_params']);
+        }
+
+        // build the link
+        if (! empty($tab['link'])) {
+            $tab['link'] = htmlentities($tab['link']);
+            $tab['link'] = $tab['link'] . PMA_generate_common_url($url_params);
+            if (! empty($tab['args'])) {
+                foreach ($tab['args'] as $param => $value) {
+                    $tab['link'] .= PMA_get_arg_separator('html') . urlencode($param)
+                        . '=' . urlencode($value);
+                }
+            }
+        }
+
+        if (! empty($tab['fragment'])) {
+            $tab['link'] .= $tab['fragment'];
+        }
+
+        // display icon
+        if (isset($tab['icon'])) {
+            // avoid generating an alt tag, because it only illustrates
+            // the text that follows and if browser does not display
+            // images, the text is duplicated
+            $tab['text'] = self::getIcon($tab['icon'], $tab['text'], false, true);
+
+        } elseif (empty($tab['text'])) {
+            // check to not display an empty link-text
+            $tab['text'] = '?';
+            trigger_error(
+                'empty linktext in function ' . __FUNCTION__ . '()',
+                E_USER_NOTICE
+            );
+        }
+
+        //Set the id for the tab, if set in the params
+        $id_string = ( empty($tab['id']) ? '' : ' id="'.$tab['id'].'" ' );
+        $out = '<li' . ($tab['class'] == 'active' ? ' class="active"' : '') . '>';
+
+        if (! empty($tab['link'])) {
+            $out .= '<a class="tab' . htmlentities($tab['class']) . '"'
+                .$id_string
+                .' href="' . $tab['link'] . '" ' . $tab['attr'] . '>'
+                . $tab['text'] . '</a>';
+        } else {
+            $out .= '<span class="tab' . htmlentities($tab['class']) . '"'
+                . $id_string. '>' . $tab['text'] . '</span>';
+        }
+
+        $out .= '</li>';
+        return $out;
+    } // end of the 'getHtmlTab()' function
+
+    /**
+     * returns html-code for a tab navigation
+     *
+     * @param array  $tabs       one element per tab
+     * @param string $url_params additional URL parameters
+     * @param string $menu_id    HTML id attribute for the menu container
+     * @param bool   $resizable  whether to add a "resizable" class
+     *
+     * @return string  html-code for tab-navigation
+     */
+    public static function getHtmlTabs($tabs, $url_params, $menu_id,
+        $resizable = false
+    ) {
+        $class = '';
+        if ($resizable) {
+            $class = ' class="resizable-menu"';
+        }
+
+        $tab_navigation = '<div id="' . htmlentities($menu_id)
+            . 'container" class="menucontainer">'
+            .'<ul id="' . htmlentities($menu_id) . '" ' . $class . '>';
+
+        foreach ($tabs as $tab) {
+            $tab_navigation .= self::getHtmlTab($tab, $url_params);
+        }
+
+        $tab_navigation .=
+             '</ul>' . "\n"
+            .'<div class="clearfloat"></div>'
+            .'</div>' . "\n";
+
+        return $tab_navigation;
+    }
+
+    /**
+     * Displays a link, or a button if the link's URL is too large, to
+     * accommodate some browsers' limitations
+     *
+     * @param string  $url        the URL
+     * @param string  $message    the link message
+     * @param mixed   $tag_params string: js confirmation
+     *                            array: additional tag params (f.e. style="")
+     * @param boolean $new_form   we set this to false when we are already in
+     *                            a  form, to avoid generating nested forms
+     * @param boolean $strip_img  whether to strip the image
+     * @param string  $target     target
+     *
+     * @return string  the results to be echoed or saved in an array
+     */
+    public static function linkOrButton(
+        $url, $message, $tag_params = array(),
+        $new_form = true, $strip_img = false, $target = ''
+    ) {
+        $url_length = strlen($url);
+        // with this we should be able to catch case of image upload
+        // into a (MEDIUM) BLOB; not worth generating even a form for these
+        if ($url_length > $GLOBALS['cfg']['LinkLengthLimit'] * 100) {
+            return '';
+        }
+
+        if (! is_array($tag_params)) {
+            $tmp = $tag_params;
+            $tag_params = array();
+            if (! empty($tmp)) {
+                $tag_params['onclick'] = 'return confirmLink(this, \''
+                    . PMA_escapeJsString($tmp) . '\')';
+            }
+            unset($tmp);
+        }
+        if (! empty($target)) {
+            $tag_params['target'] = htmlentities($target);
+        }
+
+        $tag_params_strings = array();
+        foreach ($tag_params as $par_name => $par_value) {
+            // htmlspecialchars() only on non javascript
+            $par_value = substr($par_name, 0, 2) == 'on'
+                ? $par_value
+                : htmlspecialchars($par_value);
+            $tag_params_strings[] = $par_name . '="' . $par_value . '"';
+        }
+
+        $displayed_message = '';
+        // Add text if not already added
+        if (stristr($message, '<img')
+            && (! $strip_img || ($GLOBALS['cfg']['PropertiesIconic'] === true))
+            && (strip_tags($message) == $message)
+        ) {
+            $displayed_message = '<span>'
+                . htmlspecialchars(
+                    preg_replace('/^.*\salt="([^"]*)".*$/si', '\1', $message)
+                )
+                . '</span>';
+        }
+
+        // Suhosin: Check that each query parameter is not above maximum
+        $in_suhosin_limits = true;
+        if ($url_length <= $GLOBALS['cfg']['LinkLengthLimit']) {
+            if ($suhosin_get_MaxValueLength = ini_get('suhosin.get.max_value_length')) {
+                $query_parts = self::splitURLQuery($url);
+                foreach ($query_parts as $query_pair) {
+                    list($eachvar, $eachval) = explode('=', $query_pair);
+                    if (strlen($eachval) > $suhosin_get_MaxValueLength) {
+                        $in_suhosin_limits = false;
+                        break;
+                    }
+                }
+            }
+        }
+
+        if (($url_length <= $GLOBALS['cfg']['LinkLengthLimit'])
+            && $in_suhosin_limits
+        ) {
+            // no whitespace within an <a> else Safari will make it part of the link
+            $ret = "\n" . '<a href="' . $url . '" '
+                . implode(' ', $tag_params_strings) . '>'
+                . $message . $displayed_message . '</a>' . "\n";
+        } else {
+            // no spaces (linebreaks) at all
+            // or after the hidden fields
+            // IE will display them all
+
+            // add class=link to submit button
+            if (empty($tag_params['class'])) {
+                $tag_params['class'] = 'link';
+            }
+
+            if (! isset($query_parts)) {
+                $query_parts = self::splitURLQuery($url);
+            }
+            $url_parts   = parse_url($url);
+
+            if ($new_form) {
+                $ret = '<form action="' . $url_parts['path'] . '" class="link"'
+                     . ' method="post"' . $target . ' style="display: inline;">';
+                $subname_open   = '';
+                $subname_close  = '';
+                $submit_link    = '#';
+            } else {
+                $query_parts[] = 'redirect=' . $url_parts['path'];
+                if (empty($GLOBALS['subform_counter'])) {
+                    $GLOBALS['subform_counter'] = 0;
+                }
+                $GLOBALS['subform_counter']++;
+                $ret            = '';
+                $subname_open   = 'subform[' . $GLOBALS['subform_counter'] . '][';
+                $subname_close  = ']';
+                $submit_link    = '#usesubform[' . $GLOBALS['subform_counter']
+                    . ']=1';
+            }
+
+            foreach ($query_parts as $query_pair) {
+                list($eachvar, $eachval) = explode('=', $query_pair);
+                $ret .= '<input type="hidden" name="' . $subname_open . $eachvar
+                    . $subname_close . '" value="'
+                    . htmlspecialchars(urldecode($eachval)) . '" />';
+            } // end while
+
+            $ret .= "\n" . '<a href="' . $submit_link . '" class="formLinkSubmit" '
+                . implode(' ', $tag_params_strings) . '>'
+                . $message . ' ' . $displayed_message . '</a>' . "\n";
+
+            if ($new_form) {
+                $ret .= '</form>';
+            }
+        } // end if... else...
+
+        return $ret;
+    } // end of the 'linkOrButton()' function
+
+    /**
+     * Splits a URL string by parameter
+     *
+     * @param string $url the URL
+     *
+     * @return array  the parameter/value pairs, for example [0] db=sakila
+     */
+    public static function splitURLQuery($url)
+    {
+        // decode encoded url separators
+        $separator = PMA_get_arg_separator();
+        // on most places separator is still hard coded ...
+        if ($separator !== '&') {
+            // ... so always replace & with $separator
+            $url = str_replace(htmlentities('&'), $separator, $url);
+            $url = str_replace('&', $separator, $url);
+        }
+
+        $url = str_replace(htmlentities($separator), $separator, $url);
+        // end decode
+
+        $url_parts = parse_url($url);
+
+        return explode($separator, $url_parts['query']);
+    }
+
+    /**
+     * Returns a given timespan value in a readable format.
+     *
+     * @param int $seconds the timespan
+     *
+     * @return string  the formatted value
+     */
+    public static function timespanFormat($seconds)
+    {
+        $days = floor($seconds / 86400);
+        if ($days > 0) {
+            $seconds -= $days * 86400;
+        }
+
+        $hours = floor($seconds / 3600);
+        if ($days > 0 || $hours > 0) {
+            $seconds -= $hours * 3600;
+        }
+
+        $minutes = floor($seconds / 60);
+        if ($days > 0 || $hours > 0 || $minutes > 0) {
+            $seconds -= $minutes * 60;
+        }
+
+        return sprintf(
+            __('%s days, %s hours, %s minutes and %s seconds'),
+            (string)$days, (string)$hours, (string)$minutes, (string)$seconds
+        );
+    }
+
+    /**
+     * Takes a string and outputs each character on a line for itself. Used
+     * mainly for horizontalflipped display mode.
+     * Takes care of special html-characters.
+     * Fulfills https://sourceforge.net/p/phpmyadmin/feature-requests/164/
+     *
+     * @param string $string    The string
+     * @param string $Separator The Separator (defaults to "<br />\n")
+     *
+     * @access  public
+     * @todo    add a multibyte safe function PMA_STR_split()
+     *
+     * @return string      The flipped string
+     */
+    public static function flipstring($string, $Separator = "<br />\n")
+    {
+        $format_string = '';
+        $charbuff = false;
+
+        for ($i = 0, $str_len = strlen($string); $i < $str_len; $i++) {
+            $char = $string{$i};
+            $append = false;
+
+            if ($char == '&') {
+                $format_string .= $charbuff;
+                $charbuff = $char;
+            } elseif ($char == ';' && ! empty($charbuff)) {
+                $format_string .= $charbuff . $char;
+                $charbuff = false;
+                $append = true;
+            } elseif (! empty($charbuff)) {
+                $charbuff .= $char;
+            } else {
+                $format_string .= $char;
+                $append = true;
+            }
+
+            // do not add separator after the last character
+            if ($append && ($i != $str_len - 1)) {
+                $format_string .= $Separator;
+            }
+        }
+
+        return $format_string;
+    }
+
+    /**
+     * Function added to avoid path disclosures.
+     * Called by each script that needs parameters, it displays
+     * an error message and, by default, stops the execution.
+     *
+     * Not sure we could use a strMissingParameter message here,
+     * would have to check if the error message file is always available
+     *
+     * @param array $params  The names of the parameters needed by the calling script
+     * @param bool  $request Whether to include this list in checking for
+     *                       special params
+     *
+     * @return void
+     *
+     * @global  string  path to current script
+     * @global  boolean flag whether any special variable was required
+     *
+     * @access  public
+     */
+    public static function checkParameters($params, $request = true)
+    {
+        global $checked_special;
+
+        if (! isset($checked_special)) {
+            $checked_special = false;
+        }
+
+        $reported_script_name = basename($GLOBALS['PMA_PHP_SELF']);
+        $found_error = false;
+        $error_message = '';
+
+        foreach ($params as $param) {
+            if ($request && ($param != 'db') && ($param != 'table')) {
+                $checked_special = true;
+            }
+
+            if (! isset($GLOBALS[$param])) {
+                $error_message .= $reported_script_name
+                    . ': ' . __('Missing parameter:') . ' '
+                    . $param
+                    . self::showDocu('faq', 'faqmissingparameters')
+                    . '<br />';
+                $found_error = true;
+            }
+        }
+        if ($found_error) {
+            PMA_fatalError($error_message, null, false);
+        }
+    } // end function
+
+    /**
+     * Function to generate unique condition for specified row.
+     *
+     * @param resource $handle       current query result
+     * @param integer  $fields_cnt   number of fields
+     * @param array    $fields_meta  meta information about fields
+     * @param array    $row          current row
+     * @param boolean  $force_unique generate condition only on pk or unique
+     *
+     * @access  public
+     *
+     * @return array     the calculated condition and whether condition is unique
+     */
+    public static function getUniqueCondition(
+        $handle, $fields_cnt, $fields_meta, $row, $force_unique = false
+    ) {
+        $primary_key          = '';
+        $unique_key           = '';
+        $nonprimary_condition = '';
+        $preferred_condition = '';
+        $primary_key_array    = array();
+        $unique_key_array     = array();
+        $nonprimary_condition_array = array();
+        $condition_array = array();
+
+        for ($i = 0; $i < $fields_cnt; ++$i) {
+
+            $condition   = '';
+            $con_key     = '';
+            $con_val     = '';
+            $field_flags = PMA_DBI_field_flags($handle, $i);
+            $meta        = $fields_meta[$i];
+
+            // do not use a column alias in a condition
+            if (! isset($meta->orgname) || ! strlen($meta->orgname)) {
+                $meta->orgname = $meta->name;
+
+                if (isset($GLOBALS['analyzed_sql'][0]['select_expr'])
+                    && is_array($GLOBALS['analyzed_sql'][0]['select_expr'])
+                ) {
+                    foreach (
+                        $GLOBALS['analyzed_sql'][0]['select_expr'] as $select_expr
+                    ) {
+                        // need (string) === (string)
+                        // '' !== 0 but '' == 0
+                        if ((string)$select_expr['alias'] === (string)$meta->name) {
+                            $meta->orgname = $select_expr['column'];
+                            break;
+                        } // end if
+                    } // end foreach
+                }
+            }
+
+            // Do not use a table alias in a condition.
+            // Test case is:
+            // select * from galerie x WHERE
+            //(select count(*) from galerie y where y.datum=x.datum)>1
+            //
+            // But orgtable is present only with mysqli extension so the
+            // fix is only for mysqli.
+            // Also, do not use the original table name if we are dealing with
+            // a view because this view might be updatable.
+            // (The isView() verification should not be costly in most cases
+            // because there is some caching in the function).
+            if (isset($meta->orgtable)
+                && ($meta->table != $meta->orgtable)
+                && ! PMA_Table::isView($GLOBALS['db'], $meta->table)
+            ) {
+                $meta->table = $meta->orgtable;
+            }
+
+            // to fix the bug where float fields (primary or not)
+            // can't be matched because of the imprecision of
+            // floating comparison, use CONCAT
+            // (also, the syntax "CONCAT(field) IS NULL"
+            // that we need on the next "if" will work)
+            if ($meta->type == 'real') {
+                $con_key = 'CONCAT(' . self::backquote($meta->table) . '.'
+                    . self::backquote($meta->orgname) . ')';
+            } else {
+                $con_key = self::backquote($meta->table) . '.'
+                    . self::backquote($meta->orgname);
+            } // end if... else...
+            $condition = ' ' . $con_key . ' ';
+
+            if (! isset($row[$i]) || is_null($row[$i])) {
+                $con_val = 'IS NULL';
+            } else {
+                // timestamp is numeric on some MySQL 4.1
+                // for real we use CONCAT above and it should compare to string
+                if ($meta->numeric
+                    && ($meta->type != 'timestamp')
+                    && ($meta->type != 'real')
+                ) {
+                    $con_val = '= ' . $row[$i];
+                } elseif ((($meta->type == 'blob') || ($meta->type == 'string'))
+                    // hexify only if this is a true not empty BLOB or a BINARY
+                        && stristr($field_flags, 'BINARY')
+                        && ! empty($row[$i])
+                ) {
+                    // do not waste memory building a too big condition
+                    if (strlen($row[$i]) < 1000) {
+                        // use a CAST if possible, to avoid problems
+                        // if the field contains wildcard characters % or _
+                        $con_val = '= CAST(0x' . bin2hex($row[$i]) . ' AS BINARY)';
+                    } else if ($fields_cnt == 1) {
+                        // when this blob is the only field present
+                        // try settling with length comparison
+                        $condition = ' CHAR_LENGTH(' . $con_key . ') ';
+                        $con_val = ' = ' .  strlen($row[$i]);
+                    } else {
+                        // this blob won't be part of the final condition
+                        $con_val = null;
+                    }
+                } elseif (in_array($meta->type, self::getGISDatatypes())
+                    && ! empty($row[$i])
+                ) {
+                    // do not build a too big condition
+                    if (strlen($row[$i]) < 5000) {
+                        $condition .= '=0x' . bin2hex($row[$i]) . ' AND';
+                    } else {
+                        $condition = '';
+                    }
+                } elseif ($meta->type == 'bit') {
+                    $con_val = "= b'"
+                        . self::printableBitValue($row[$i], $meta->length) . "'";
+                } else {
+                    $con_val = '= \''
+                        . self::sqlAddSlashes($row[$i], false, true) . '\'';
+                }
+            }
+
+            if ($con_val != null) {
+
+                $condition .= $con_val . ' AND';
+
+                if ($meta->primary_key > 0) {
+                    $primary_key .= $condition;
+                    $primary_key_array[$con_key] = $con_val;
+                } elseif ($meta->unique_key > 0) {
+                    $unique_key  .= $condition;
+                    $unique_key_array[$con_key] = $con_val;
+                }
+
+                $nonprimary_condition .= $condition;
+                $nonprimary_condition_array[$con_key] = $con_val;
+            }
+        } // end for
+
+        // Correction University of Virginia 19991216:
+        // prefer primary or unique keys for condition,
+        // but use conjunction of all values if no primary key
+        $clause_is_unique = true;
+
+        if ($primary_key) {
+            $preferred_condition = $primary_key;
+            $condition_array = $primary_key_array;
+
+        } elseif ($unique_key) {
+            $preferred_condition = $unique_key;
+            $condition_array = $unique_key_array;
+
+        } elseif (! $force_unique) {
+            $preferred_condition = $nonprimary_condition;
+            $condition_array = $nonprimary_condition_array;
+            $clause_is_unique = false;
+        }
+
+        $where_clause = trim(preg_replace('|\s?AND$|', '', $preferred_condition));
+        return(array($where_clause, $clause_is_unique, $condition_array));
+    } // end function
+
+    /**
+     * Generate a button or image tag
+     *
+     * @param string $button_name  name of button element
+     * @param string $button_class class of button or image element
+     * @param string $image_name   name of image element
+     * @param string $text         text to display
+     * @param string $image        image to display
+     * @param string $value        value
+     *
+     * @return string              html content
+     *
+     * @access  public
+     */
+    public static function getButtonOrImage(
+        $button_name, $button_class, $image_name, $text, $image, $value = ''
+    ) {
+        if ($value == '') {
+            $value = $text;
+        }
+
+        if ($GLOBALS['cfg']['PropertiesIconic'] === false) {
+            return ' <input type="submit" name="' . $button_name . '"'
+                .' value="' . htmlspecialchars($value) . '"'
+                .' title="' . htmlspecialchars($text) . '" />' . "\n";
+        }
+
+        /* Opera has trouble with <input type="image"> */
+        /* IE (before version 9) has trouble with <button> */
+        if (PMA_USR_BROWSER_AGENT == 'IE' && PMA_USR_BROWSER_VER < 9) {
+            return '<input type="image" name="' . $image_name
+                . '" class="' . $button_class
+                . '" value="' . htmlspecialchars($value)
+                . '" title="' . htmlspecialchars($text)
+                . '" src="' . $GLOBALS['pmaThemeImage']. $image . '" />'
+                . ($GLOBALS['cfg']['PropertiesIconic'] === 'both'
+                    ? ' ' . htmlspecialchars($text)
+                    : '') . "\n";
+        } else {
+            return '<button class="' . $button_class . '" type="submit"'
+                .' name="' . $button_name . '" value="' . htmlspecialchars($value)
+                . '" title="' . htmlspecialchars($text) . '">' . "\n"
+                . self::getIcon($image, $text)
+                .'</button>' . "\n";
+        }
+    } // end function
+
+    /**
+     * Generate a pagination selector for browsing resultsets
+     *
+     * @param string $name        The name for the request parameter
+     * @param int    $rows        Number of rows in the pagination set
+     * @param int    $pageNow     current page number
+     * @param int    $nbTotalPage number of total pages
+     * @param int    $showAll     If the number of pages is lower than this
+     *                            variable, no pages will be omitted in pagination
+     * @param int    $sliceStart  How many rows at the beginning should always
+     *                            be shown?
+     * @param int    $sliceEnd    How many rows at the end should always be shown?
+     * @param int    $percent     Percentage of calculation page offsets to hop to a
+     *                            next page
+     * @param int    $range       Near the current page, how many pages should
+     *                            be considered "nearby" and displayed as well?
+     * @param string $prompt      The prompt to display (sometimes empty)
+     *
+     * @return string
+     *
+     * @access  public
+     */
+    public static function pageselector(
+        $name, $rows, $pageNow = 1, $nbTotalPage = 1, $showAll = 200,
+        $sliceStart = 5,
+        $sliceEnd = 5, $percent = 20, $range = 10, $prompt = ''
+    ) {
+        $increment = floor($nbTotalPage / $percent);
+        $pageNowMinusRange = ($pageNow - $range);
+        $pageNowPlusRange = ($pageNow + $range);
+
+        $gotopage = $prompt . ' <select class="pageselector ';
+        $gotopage .= ' ajax';
+
+        $gotopage .= '" name="' . $name . '" >';
+        if ($nbTotalPage < $showAll) {
+            $pages = range(1, $nbTotalPage);
+        } else {
+            $pages = array();
+
+            // Always show first X pages
+            for ($i = 1; $i <= $sliceStart; $i++) {
+                $pages[] = $i;
+            }
+
+            // Always show last X pages
+            for ($i = $nbTotalPage - $sliceEnd; $i <= $nbTotalPage; $i++) {
+                $pages[] = $i;
+            }
+
+            // Based on the number of results we add the specified
+            // $percent percentage to each page number,
+            // so that we have a representing page number every now and then to
+            // immediately jump to specific pages.
+            // As soon as we get near our currently chosen page ($pageNow -
+            // $range), every page number will be shown.
+            $i = $sliceStart;
+            $x = $nbTotalPage - $sliceEnd;
+            $met_boundary = false;
+
+            while ($i <= $x) {
+                if ($i >= $pageNowMinusRange && $i <= $pageNowPlusRange) {
+                    // If our pageselector comes near the current page, we use 1
+                    // counter increments
+                    $i++;
+                    $met_boundary = true;
+                } else {
+                    // We add the percentage increment to our current page to
+                    // hop to the next one in range
+                    $i += $increment;
+
+                    // Make sure that we do not cross our boundaries.
+                    if ($i > $pageNowMinusRange && ! $met_boundary) {
+                        $i = $pageNowMinusRange;
+                    }
+                }
+
+                if ($i > 0 && $i <= $x) {
+                    $pages[] = $i;
+                }
+            }
+
+            /*
+            Add page numbers with "geometrically increasing" distances.
+
+            This helps me a lot when navigating through giant tables.
+
+            Test case: table with 2.28 million sets, 76190 pages. Page of interest
+            is between 72376 and 76190.
+            Selecting page 72376.
+            Now, old version enumerated only +/- 10 pages around 72376 and the
+            percentage increment produced steps of about 3000.
+
+            The following code adds page numbers +/- 2,4,8,16,32,64,128,256 etc.
+            around the current page.
+            */
+            $i = $pageNow;
+            $dist = 1;
+            while ($i < $x) {
+                $dist = 2 * $dist;
+                $i = $pageNow + $dist;
+                if ($i > 0 && $i <= $x) {
+                    $pages[] = $i;
+                }
+            }
+
+            $i = $pageNow;
+            $dist = 1;
+            while ($i >0) {
+                $dist = 2 * $dist;
+                $i = $pageNow - $dist;
+                if ($i > 0 && $i <= $x) {
+                    $pages[] = $i;
+                }
+            }
+
+            // Since because of ellipsing of the current page some numbers may be
+            // double, we unify our array:
+            sort($pages);
+            $pages = array_unique($pages);
+        }
+
+        foreach ($pages as $i) {
+            if ($i == $pageNow) {
+                $selected = 'selected="selected" style="font-weight: bold"';
+            } else {
+                $selected = '';
+            }
+            $gotopage .= '                <option ' . $selected
+                . ' value="' . (($i - 1) * $rows) . '">' . $i . '</option>' . "\n";
+        }
+
+        $gotopage .= ' </select>';
+
+        return $gotopage;
+    } // end function
+
+    /**
+     * Prepare navigation for a list
+     *
+     * @param int    $count       number of elements in the list
+     * @param int    $pos         current position in the list
+     * @param array  $_url_params url parameters
+     * @param string $script      script name for form target
+     * @param string $frame       target frame
+     * @param int    $max_count   maximum number of elements to display from the list
+     * @param string $name        the name for the request parameter
+     * @param array  $classes     additional classes for the container
+     *
+     * @return string $list_navigator_html the  html content
+     *
+     * @access  public
+     *
+     * @todo    use $pos from $_url_params
+     */
+    public static function getListNavigator(
+        $count, $pos, $_url_params, $script, $frame, $max_count, $name = 'pos',
+        $classes = array()
+    ) {
+
+        $class = $frame == 'frame_navigation' ? ' class="ajax"' : '';
+
+        $list_navigator_html = '';
+
+        if ($max_count < $count) {
+
+            $classes[] = 'pageselector';
+            $list_navigator_html .= '<div class="' . implode(' ', $classes) . '">';
+
+            if ($frame != 'frame_navigation') {
+                $list_navigator_html .= __('Page number:');
+            }
+
+            // Move to the beginning or to the previous page
+            if ($pos > 0) {
+                // patch #474210 - part 1
+                if ($GLOBALS['cfg']['NavigationBarIconic']) {
+                    $caption1 = '<<';
+                    $caption2 = ' < ';
+                    $title1   = ' title="' . _pgettext('First page', 'Begin') . '"';
+                    $title2   = ' title="'
+                        . _pgettext('Previous page', 'Previous') . '"';
+                } else {
+                    $caption1 = _pgettext('First page', 'Begin') . ' <<';
+                    $caption2 = _pgettext('Previous page', 'Previous') . ' <';
+                    $title1   = '';
+                    $title2   = '';
+                } // end if... else...
+
+                $_url_params[$name] = 0;
+                $list_navigator_html .= '<a' . $class . $title1 . ' href="' . $script
+                    . PMA_generate_common_url($_url_params) . '">' . $caption1
+                    . '</a>';
+
+                $_url_params[$name] = $pos - $max_count;
+                $list_navigator_html .= '<a' . $class . $title2 . ' href="' . $script
+                    . PMA_generate_common_url($_url_params) . '">' . $caption2
+                    . '</a>';
+            }
+
+            $list_navigator_html .= '<form action="' . basename($script).
+                '" method="post">';
+
+            $list_navigator_html .= PMA_generate_common_hidden_inputs($_url_params);
+            $list_navigator_html .= self::pageselector(
+                $name,
+                $max_count,
+                floor(($pos + 1) / $max_count) + 1,
+                ceil($count / $max_count)
+            );
+            $list_navigator_html .= '</form>';
+
+            if ($pos + $max_count < $count) {
+                if ($GLOBALS['cfg']['NavigationBarIconic']) {
+                    $caption3 = ' > ';
+                    $caption4 = '>>';
+                    $title3   = ' title="' . _pgettext('Next page', 'Next') . '"';
+                    $title4   = ' title="' . _pgettext('Last page', 'End') . '"';
+                } else {
+                    $caption3 = '> ' . _pgettext('Next page', 'Next');
+                    $caption4 = '>> ' . _pgettext('Last page', 'End');
+                    $title3   = '';
+                    $title4   = '';
+                } // end if... else...
+
+                $_url_params[$name] = $pos + $max_count;
+                $list_navigator_html .= '<a' . $class . $title3 . ' href="' . $script
+                    . PMA_generate_common_url($_url_params) . '" >' . $caption3
+                    . '</a>';
+
+                $_url_params[$name] = floor($count / $max_count) * $max_count;
+                if ($_url_params[$name] == $count) {
+                    $_url_params[$name] = $count - $max_count;
+                }
+
+                $list_navigator_html .= '<a' . $class . $title4 . ' href="' . $script
+                    . PMA_generate_common_url($_url_params) . '" >' . $caption4
+                    . '</a>';
+            }
+            $list_navigator_html .= '</div>' . "\n";
+        }
+
+        return $list_navigator_html;
+    }
+
+    /**
+     * replaces %u in given path with current user name
+     *
+     * example:
+     * <code>
+     * $user_dir = userDir('/var/pma_tmp/%u/'); // '/var/pma_tmp/root/'
+     *
+     * </code>
+     *
+     * @param string $dir with wildcard for user
+     *
+     * @return string  per user directory
+     */
+    public static function userDir($dir)
+    {
+        // add trailing slash
+        if (substr($dir, -1) != '/') {
+            $dir .= '/';
+        }
+
+        return str_replace('%u', $GLOBALS['cfg']['Server']['user'], $dir);
+    }
+
+    /**
+     * returns html code for db link to default db page
+     *
+     * @param string $database database
+     *
+     * @return string  html link to default db page
+     */
+    public static function getDbLink($database = null)
+    {
+        if (! strlen($database)) {
+            if (! strlen($GLOBALS['db'])) {
+                return '';
+            }
+            $database = $GLOBALS['db'];
+        } else {
+            $database = self::unescapeMysqlWildcards($database);
+        }
+
+        return '<a href="' . $GLOBALS['cfg']['DefaultTabDatabase'] . '?'
+            . PMA_generate_common_url($database) . '" title="'
+            . sprintf(
+                __('Jump to database "%s".'),
+                htmlspecialchars($database)
+            )
+            . '">' . htmlspecialchars($database) . '</a>';
+    }
+
+    /**
+     * Prepare a lightbulb hint explaining a known external bug
+     * that affects a functionality
+     *
+     * @param string $functionality   localized message explaining the func.
+     * @param string $component       'mysql' (eventually, 'php')
+     * @param string $minimum_version of this component
+     * @param string $bugref          bug reference for this component
+     *
+     * @return void
+     */
+    public static function getExternalBug(
+        $functionality, $component, $minimum_version, $bugref
+    ) {
+        $ext_but_html = '';
+        if (($component == 'mysql') && (PMA_MYSQL_INT_VERSION < $minimum_version)) {
+            $ext_but_html .= self::showHint(
+                sprintf(
+                    __('The %s functionality is affected by a known bug, see %s'),
+                    $functionality,
+                    PMA_linkURL('http://bugs.mysql.com/') . $bugref
+                )
+            );
+        }
+        return $ext_but_html;
+    }
+
+    /**
+     * Returns a HTML checkbox
+     *
+     * @param string  $html_field_name the checkbox HTML field
+     * @param string  $label           label for checkbox
+     * @param boolean $checked         is it initially checked?
+     * @param boolean $onclick         should it submit the form on click?
+     *
+     * @return string                  HTML for the checkbox
+     */
+    public static function getCheckbox($html_field_name, $label, $checked, $onclick)
+    {
+        return '<input type="checkbox" name="' . $html_field_name . '" id="'
+            . $html_field_name . '"' . ($checked ? ' checked="checked"' : '')
+            . ($onclick ? ' class="autosubmit"' : '') . ' /><label for="'
+            . $html_field_name . '">' . $label . '</label>';
+    }
+
+    /**
+     * Generates a set of radio HTML fields
+     *
+     * @param string  $html_field_name the radio HTML field
+     * @param array   $choices         the choices values and labels
+     * @param string  $checked_choice  the choice to check by default
+     * @param boolean $line_break      whether to add HTML line break after a choice
+     * @param boolean $escape_label    whether to use htmlspecialchars() on label
+     * @param string  $class           enclose each choice with a div of this class
+     *
+     * @return string                  set of html radio fiels
+     */
+    public static function getRadioFields(
+        $html_field_name, $choices, $checked_choice = '',
+        $line_break = true, $escape_label = true, $class = ''
+    ) {
+        $radio_html = '';
+
+        foreach ($choices as $choice_value => $choice_label) {
+
+            if (! empty($class)) {
+                $radio_html .= '<div class="' . $class . '">';
+            }
+
+            $html_field_id = $html_field_name . '_' . $choice_value;
+            $radio_html .= '<input type="radio" name="' . $html_field_name . '" id="'
+                        . $html_field_id . '" value="'
+                        . htmlspecialchars($choice_value) . '"';
+
+            if ($choice_value == $checked_choice) {
+                $radio_html .= ' checked="checked"';
+            }
+
+            $radio_html .= ' />' . "\n"
+                        . '<label for="' . $html_field_id . '">'
+                        . ($escape_label
+                        ? htmlspecialchars($choice_label)
+                        : $choice_label)
+                        . '</label>';
+
+            if ($line_break) {
+                $radio_html .= '<br />';
+            }
+
+            if (! empty($class)) {
+                $radio_html .= '</div>';
+            }
+            $radio_html .= "\n";
+        }
+
+        return $radio_html;
+    }
+
+    /**
+     * Generates and returns an HTML dropdown
+     *
+     * @param string $select_name   name for the select element
+     * @param array  $choices       choices values
+     * @param string $active_choice the choice to select by default
+     * @param string $id            id of the select element; can be different in
+     *                              case the dropdown is present more than once
+     *                              on the page
+     *
+     * @return string               html content
+     *
+     * @todo    support titles
+     */
+    public static function getDropdown($select_name, $choices, $active_choice, $id)
+    {
+        $result = '<select name="' . htmlspecialchars($select_name) . '" id="'
+            . htmlspecialchars($id) . '">';
+
+        foreach ($choices as $one_choice_value => $one_choice_label) {
+            $result .= '<option value="' . htmlspecialchars($one_choice_value) . '"';
+
+            if ($one_choice_value == $active_choice) {
+                $result .= ' selected="selected"';
+            }
+            $result .= '>' . htmlspecialchars($one_choice_label) . '</option>';
+        }
+        $result .= '</select>';
+
+        return $result;
+    }
+
+    /**
+     * Generates a slider effect (jQjuery)
+     * Takes care of generating the initial <div> and the link
+     * controlling the slider; you have to generate the </div> yourself
+     * after the sliding section.
+     *
+     * @param string $id      the id of the <div> on which to apply the effect
+     * @param string $message the message to show as a link
+     *
+     * @return string         html div element
+     *
+     */
+    public static function getDivForSliderEffect($id, $message)
+    {
+        if ($GLOBALS['cfg']['InitialSlidersState'] == 'disabled') {
+            return '<div id="' . $id . '">';
+        }
+        /**
+         * Bad hack on the next line. document.write() conflicts with jQuery,
+         * hence, opening the <div> with PHP itself instead of JavaScript.
+         *
+         * @todo find a better solution that uses $.append(), the recommended
+         * method maybe by using an additional param, the id of the div to
+         * append to
+         */
+
+        return '<div id="' . $id . '"'
+            . (($GLOBALS['cfg']['InitialSlidersState'] == 'closed')
+                ? ' style="display: none; overflow:auto;"'
+                : '')
+            . ' class="pma_auto_slider" title="' . htmlspecialchars($message) . '">';
+    }
+
+    /**
+     * Creates an AJAX sliding toggle button
+     * (or and equivalent form when AJAX is disabled)
+     *
+     * @param string $action      The URL for the request to be executed
+     * @param string $select_name The name for the dropdown box
+     * @param array  $options     An array of options (see rte_footer.lib.php)
+     * @param string $callback    A JS snippet to execute when the request is
+     *                            successfully processed
+     *
+     * @return string   HTML code for the toggle button
+     */
+    public static function toggleButton($action, $select_name, $options, $callback)
+    {
+        // Do the logic first
+        $link = "$action&" . urlencode($select_name) . "=";
+        $link_on = $link . urlencode($options[1]['value']);
+        $link_off = $link . urlencode($options[0]['value']);
+
+        if ($options[1]['selected'] == true) {
+            $state = 'on';
+        } else if ($options[0]['selected'] == true) {
+            $state = 'off';
+        } else {
+            $state = 'on';
+        }
+
+        // Generate output
+        return "<!-- TOGGLE START -->\n"
+            . "<div class='wrapper toggleAjax hide'>\n"
+            . "    <div class='toggleButton'>\n"
+            . "        <div title='" . __('Click to toggle')
+            . "' class='container $state'>\n"
+            . "           <img src='" . htmlspecialchars($GLOBALS['pmaThemeImage'])
+            . "toggle-" . htmlspecialchars($GLOBALS['text_dir']) . ".png'\n"
+            . "                 alt='' />\n"
+            . "            <table class='nospacing nopadding'>\n"
+            . "                <tbody>\n"
+            . "                <tr>\n"
+            . "                <td class='toggleOn'>\n"
+            . "                    <span class='hide'>$link_on</span>\n"
+            . "                    <div>"
+            . str_replace(' ', ' ', htmlspecialchars($options[1]['label']))
+            . "\n" . "                    </div>\n"
+            . "                </td>\n"
+            . "                <td><div> </div></td>\n"
+            . "                <td class='toggleOff'>\n"
+            . "                    <span class='hide'>$link_off</span>\n"
+            . "                    <div>"
+            . str_replace(' ', ' ', htmlspecialchars($options[0]['label']))
+            . "\n" . "                    </div>\n"
+            . "                </tr>\n"
+            . "                </tbody>\n"
+            . "            </table>\n"
+            . "            <span class='hide callback'>"
+            . htmlspecialchars($callback) . "</span>\n"
+            . "            <span class='hide text_direction'>"
+            . htmlspecialchars($GLOBALS['text_dir']) . "</span>\n"
+            . "        </div>\n"
+            . "    </div>\n"
+            . "</div>\n"
+            . "<!-- TOGGLE END -->";
+
+    } // end toggleButton()
+
+    /**
+     * Clears cache content which needs to be refreshed on user change.
+     *
+     * @return void
+     */
+    public static function clearUserCache()
+    {
+        self::cacheUnset('is_superuser', true);
+    }
+
+    /**
+     * Verifies if something is cached in the session
+     *
+     * @param string   $var    variable name
+     * @param int|true $server server
+     *
+     * @return boolean
+     */
+    public static function cacheExists($var, $server = 0)
+    {
+        if ($server === true) {
+            $server = $GLOBALS['server'];
+        }
+        return isset($_SESSION['cache']['server_' . $server][$var]);
+    }
+
+    /**
+     * Gets cached information from the session
+     *
+     * @param string   $var    varibale name
+     * @param int|true $server server
+     *
+     * @return mixed
+     */
+    public static function cacheGet($var, $server = 0)
+    {
+        if ($server === true) {
+            $server = $GLOBALS['server'];
+        }
+        if (isset($_SESSION['cache']['server_' . $server][$var])) {
+            return $_SESSION['cache']['server_' . $server][$var];
+        } else {
+            return null;
+        }
+    }
+
+    /**
+     * Caches information in the session
+     *
+     * @param string   $var    variable name
+     * @param mixed    $val    value
+     * @param int|true $server server
+     *
+     * @return mixed
+     */
+    public static function cacheSet($var, $val = null, $server = 0)
+    {
+        if ($server === true) {
+            $server = $GLOBALS['server'];
+        }
+        $_SESSION['cache']['server_' . $server][$var] = $val;
+    }
+
+    /**
+     * Removes cached information from the session
+     *
+     * @param string   $var    variable name
+     * @param int|true $server server
+     *
+     * @return void
+     */
+    public static function cacheUnset($var, $server = 0)
+    {
+        if ($server === true) {
+            $server = $GLOBALS['server'];
+        }
+        unset($_SESSION['cache']['server_' . $server][$var]);
+    }
+
+    /**
+     * Converts a bit value to printable format;
+     * in MySQL a BIT field can be from 1 to 64 bits so we need this
+     * function because in PHP, decbin() supports only 32 bits
+     *
+     * @param numeric $value  coming from a BIT field
+     * @param integer $length length
+     *
+     * @return string  the printable value
+     */
+    public static function printableBitValue($value, $length)
+    {
+        $printable = '';
+        for ($i = 0, $len_ceiled = ceil($length / 8); $i < $len_ceiled; $i++) {
+            $printable .= sprintf('%08d', decbin(ord(substr($value, $i, 1))));
+        }
+        $printable = substr($printable, -$length);
+        return $printable;
+    }
+
+    /**
+     * Verifies whether the value contains a non-printable character
+     *
+     * @param string $value value
+     *
+     * @return boolean
+     */
+    public static function containsNonPrintableAscii($value)
+    {
+        return preg_match('@[^[:print:]]@', $value);
+    }
+
+    /**
+     * Converts a BIT type default value
+     * for example, b'010' becomes 010
+     *
+     * @param string $bit_default_value value
+     *
+     * @return string the converted value
+     */
+    public static function convertBitDefaultValue($bit_default_value)
+    {
+        return strtr($bit_default_value, array("b" => "", "'" => ""));
+    }
+
+    /**
+     * Extracts the various parts from a column spec
+     *
+     * @param string $columnspec Column specification
+     *
+     * @return array associative array containing type, spec_in_brackets
+     *          and possibly enum_set_values (another array)
+     */
+    public static function extractColumnSpec($columnspec)
+    {
+        $first_bracket_pos = strpos($columnspec, '(');
+        if ($first_bracket_pos) {
+            $spec_in_brackets = chop(
+                substr(
+                    $columnspec,
+                    $first_bracket_pos + 1,
+                    (strrpos($columnspec, ')') - $first_bracket_pos - 1)
+                )
+            );
+            // convert to lowercase just to be sure
+            $type = strtolower(chop(substr($columnspec, 0, $first_bracket_pos)));
+        } else {
+            $type = strtolower($columnspec);
+            $spec_in_brackets = '';
+        }
+
+        if ('enum' == $type || 'set' == $type) {
+            // Define our working vars
+            $enum_set_values = self::parseEnumSetValues($columnspec, false);
+            $printtype = $type
+                . '(' .  str_replace("','", "', '", $spec_in_brackets) . ')';
+            $binary = false;
+            $unsigned = false;
+            $zerofill = false;
+        } else {
+            $enum_set_values = array();
+
+            /* Create printable type name */
+            $printtype = strtolower($columnspec);
+
+            // Strip the "BINARY" attribute, except if we find "BINARY(" because
+            // this would be a BINARY or VARBINARY column type;
+            // by the way, a BLOB should not show the BINARY attribute
+            // because this is not accepted in MySQL syntax.
+            if (preg_match('@binary@', $printtype)
+                && ! preg_match('@binary[\(]@', $printtype)
+            ) {
+                $printtype = preg_replace('@binary@', '', $printtype);
+                $binary = true;
+            } else {
+                $binary = false;
+            }
+
+            $printtype = preg_replace(
+                '@zerofill@', '', $printtype, -1, $zerofill_cnt
+            );
+            $zerofill = ($zerofill_cnt > 0);
+            $printtype = preg_replace(
+                '@unsigned@', '', $printtype, -1, $unsigned_cnt
+            );
+            $unsigned = ($unsigned_cnt > 0);
+            $printtype = trim($printtype);
+        }
+
+        $attribute     = ' ';
+        if ($binary) {
+            $attribute = 'BINARY';
+        }
+        if ($unsigned) {
+            $attribute = 'UNSIGNED';
+        }
+        if ($zerofill) {
+            $attribute = 'UNSIGNED ZEROFILL';
+        }
+
+        $can_contain_collation = false;
+        if (! $binary
+            && preg_match(
+                "@^(char|varchar|text|tinytext|mediumtext|longtext|set|enum)@", $type
+            )
+        ) {
+            $can_contain_collation = true;
+        }
+
+        // for the case ENUM('–','“')
+        $displayed_type = htmlspecialchars($printtype);
+        if (strlen($printtype) > $GLOBALS['cfg']['LimitChars']) {
+            $displayed_type  = '<abbr title="' . $printtype . '">';
+            $displayed_type .= substr($printtype, 0, $GLOBALS['cfg']['LimitChars']);
+            $displayed_type .= '</abbr>';
+        }
+
+        return array(
+            'type' => $type,
+            'spec_in_brackets' => $spec_in_brackets,
+            'enum_set_values'  => $enum_set_values,
+            'print_type' => $printtype,
+            'binary' => $binary,
+            'unsigned' => $unsigned,
+            'zerofill' => $zerofill,
+            'attribute' => $attribute,
+            'can_contain_collation' => $can_contain_collation,
+            'displayed_type' => $displayed_type
+        );
+    }
+
+    /**
+     * Verifies if this table's engine supports foreign keys
+     *
+     * @param string $engine engine
+     *
+     * @return boolean
+     */
+    public static function isForeignKeySupported($engine)
+    {
+        $engine = strtoupper($engine);
+        if (($engine == 'INNODB') || ($engine == 'PBXT')) {
+            return true;
+        } else {
+            return false;
+        }
+    }
+
+    /**
+     * Replaces some characters by a displayable equivalent
+     *
+     * @param string $content content
+     *
+     * @return string the content with characters replaced
+     */
+    public static function replaceBinaryContents($content)
+    {
+        $result = str_replace("\x00", '\0', $content);
+        $result = str_replace("\x08", '\b', $result);
+        $result = str_replace("\x0a", '\n', $result);
+        $result = str_replace("\x0d", '\r', $result);
+        $result = str_replace("\x1a", '\Z', $result);
+        return $result;
+    }
+
+    /**
+     * Converts GIS data to Well Known Text format
+     *
+     * @param binary $data        GIS data
+     * @param bool   $includeSRID Add SRID to the WKT
+     *
+     * @return string GIS data in Well Know Text format
+     */
+    public static function asWKT($data, $includeSRID = false)
+    {
+        // Convert to WKT format
+        $hex = bin2hex($data);
+        $wktsql     = "SELECT ASTEXT(x'" . $hex . "')";
+        if ($includeSRID) {
+            $wktsql .= ", SRID(x'" . $hex . "')";
+        }
+
+        $wktresult  = PMA_DBI_try_query($wktsql, null, PMA_DBI_QUERY_STORE);
+        $wktarr     = PMA_DBI_fetch_row($wktresult, 0);
+        $wktval     = $wktarr[0];
+
+        if ($includeSRID) {
+            $srid = $wktarr[1];
+            $wktval = "'" . $wktval . "'," . $srid;
+        }
+        @PMA_DBI_free_result($wktresult);
+
+        return $wktval;
+    }
+
+    /**
+     * If the string starts with a \r\n pair (0x0d0a) add an extra \n
+     *
+     * @param string $string string
+     *
+     * @return string with the chars replaced
+     */
+    public static function duplicateFirstNewline($string)
+    {
+        $first_occurence = strpos($string, "\r\n");
+        if ($first_occurence === 0) {
+            $string = "\n" . $string;
+        }
+        return $string;
+    }
+
+    /**
+     * Get the action word corresponding to a script name
+     * in order to display it as a title in navigation panel
+     *
+     * @param string $target a valid value for $cfg['NavigationTreeDefaultTabTable'],
+     *                       $cfg['DefaultTabTable'] or $cfg['DefaultTabDatabase']
+     *
+     * @return array
+     */
+    public static function getTitleForTarget($target)
+    {
+        $mapping = array(
+            // Values for $cfg['DefaultTabTable']
+            'tbl_structure.php' =>  __('Structure'),
+            'tbl_sql.php' => __('SQL'),
+            'tbl_select.php' =>__('Search'),
+            'tbl_change.php' =>__('Insert'),
+            'sql.php' => __('Browse'),
+
+            // Values for $cfg['DefaultTabDatabase']
+            'db_structure.php' => __('Structure'),
+            'db_sql.php' => __('SQL'),
+            'db_search.php' => __('Search'),
+            'db_operations.php' => __('Operations'),
+        );
+        return $mapping[$target];
+    }
+
+    /**
+     * Formats user string, expanding @VARIABLES@, accepting strftime format
+     * string.
+     *
+     * @param string   $string  Text where to do expansion.
+     * @param function $escape  Function to call for escaping variable values.
+     *                          Can also be an array of:
+     *                          - the escape method name
+     *                          - the class that contains the method
+     *                          - location of the class (for inclusion)
+     * @param array    $updates Array with overrides for default parameters
+     *                 (obtained from GLOBALS).
+     *
+     * @return string
+     */
+    public static function expandUserString(
+        $string, $escape = null, $updates = array()
+    ) {
+        /* Content */
+        $vars['http_host'] = PMA_getenv('HTTP_HOST');
+        $vars['server_name'] = $GLOBALS['cfg']['Server']['host'];
+        $vars['server_verbose'] = $GLOBALS['cfg']['Server']['verbose'];
+
+        if (empty($GLOBALS['cfg']['Server']['verbose'])) {
+            $vars['server_verbose_or_name'] = $GLOBALS['cfg']['Server']['host'];
+        } else {
+            $vars['server_verbose_or_name'] = $GLOBALS['cfg']['Server']['verbose'];
+        }
+
+        $vars['database'] = $GLOBALS['db'];
+        $vars['table'] = $GLOBALS['table'];
+        $vars['phpmyadmin_version'] = 'phpMyAdmin ' . PMA_VERSION;
+
+        /* Update forced variables */
+        foreach ($updates as $key => $val) {
+            $vars[$key] = $val;
+        }
+
+        /* Replacement mapping */
+        /*
+         * The __VAR__ ones are for backward compatibility, because user
+         * might still have it in cookies.
+         */
+        $replace = array(
+            '@HTTP_HOST@' => $vars['http_host'],
+            '@SERVER@' => $vars['server_name'],
+            '__SERVER__' => $vars['server_name'],
+            '@VERBOSE@' => $vars['server_verbose'],
+            '@VSERVER@' => $vars['server_verbose_or_name'],
+            '@DATABASE@' => $vars['database'],
+            '__DB__' => $vars['database'],
+            '@TABLE@' => $vars['table'],
+            '__TABLE__' => $vars['table'],
+            '@PHPMYADMIN@' => $vars['phpmyadmin_version'],
+            );
+
+        /* Optional escaping */
+        if (! is_null($escape)) {
+            if (is_array($escape)) {
+                include_once $escape[2];
+                $escape_class = new $escape[1];
+                $escape_method = $escape[0];
+            }
+            foreach ($replace as $key => $val) {
+                if (is_array($escape)) {
+                    $replace[$key] = $escape_class->$escape_method($val);
+                } else {
+                    $replace[$key] = ($escape == 'backquote')
+                        ? self::$escape($val)
+                        : $escape($val);
+                }
+            }
+        }
+
+        /* Backward compatibility in 3.5.x */
+        if (strpos($string, '@FIELDS@') !== false) {
+            $string = strtr($string, array('@FIELDS@' => '@COLUMNS@'));
+        }
+
+        /* Fetch columns list if required */
+        if (strpos($string, '@COLUMNS@') !== false) {
+            $columns_list = PMA_DBI_get_columns($GLOBALS['db'], $GLOBALS['table']);
+
+            // sometimes the table no longer exists at this point
+            if (! is_null($columns_list)) {
+                $column_names = array();
+                foreach ($columns_list as $column) {
+                    if (! is_null($escape)) {
+                        $column_names[] = self::$escape($column['Field']);
+                    } else {
+                        $column_names[] = $column['Field'];
+                    }
+                }
+                $replace['@COLUMNS@'] = implode(',', $column_names);
+            } else {
+                $replace['@COLUMNS@'] = '*';
+            }
+        }
+
+        /* Do the replacement */
+        return strtr(strftime($string), $replace);
+    }
+
+    /**
+     * Prepare the form used to browse anywhere on the local server for a file to
+     * import
+     *
+     * @param string $max_upload_size maximum upload size
+     *
+     * @return void
+     */
+    public static function getBrowseUploadFileBlock($max_upload_size)
+    {
+        $block_html = '';
+
+        if ($GLOBALS['is_upload'] && ! empty($GLOBALS['cfg']['UploadDir'])) {
+            $block_html .= '<label for="radio_import_file">';
+        } else {
+            $block_html .= '<label for="input_import_file">';
+        }
+
+        $block_html .= __("Browse your computer:") . '</label>'
+            . '<div id="upload_form_status" style="display: none;"></div>'
+            . '<div id="upload_form_status_info" style="display: none;"></div>'
+            . '<input type="file" name="import_file" id="input_import_file" />'
+            . self::getFormattedMaximumUploadSize($max_upload_size) . "\n"
+            // some browsers should respect this :)
+            . self::generateHiddenMaxFileSize($max_upload_size) . "\n";
+
+        return $block_html;
+    }
+
+    /**
+     * Prepare the form used to select a file to import from the server upload
+     * directory
+     *
+     * @param array  $import_list array of import plugins
+     * @param string $uploaddir   upload directory
+     *
+     * @return void
+     */
+    public static function getSelectUploadFileBlock($import_list, $uploaddir)
+    {
+        $block_html = '';
+        $block_html .= '<label for="radio_local_import_file">'
+            . sprintf(
+                __("Select from the web server upload directory <b>%s</b>:"),
+                htmlspecialchars(self::userDir($uploaddir))
+            )
+            . '</label>';
+
+        $extensions = '';
+        foreach ($import_list as $import_plugin) {
+            if (! empty($extensions)) {
+                $extensions .= '|';
+            }
+            $extensions .= $import_plugin->getProperties()->getExtension();
+        }
+
+        $matcher = '@\.(' . $extensions . ')(\.('
+            . PMA_supportedDecompressions() . '))?$@';
+
+        $active = (isset($GLOBALS['timeout_passed']) && $GLOBALS['timeout_passed']
+            && isset($local_import_file))
+            ? $local_import_file
+            : '';
+
+        $files = PMA_getFileSelectOptions(
+            self::userDir($uploaddir),
+            $matcher,
+            $active
+        );
+
+        if ($files === false) {
+            PMA_Message::error(
+                __('The directory you set for upload work cannot be reached')
+            )->display();
+        } elseif (! empty($files)) {
+            $block_html .= "\n"
+                . '    <select style="margin: 5px" size="1" '
+                . 'name="local_import_file" '
+                . 'id="select_local_import_file">' . "\n"
+                . '        <option value=""> </option>' . "\n"
+                . $files
+                . '    </select>' . "\n";
+        } elseif (empty ($files)) {
+            $block_html .= '<i>' . __('There are no files to upload') . '</i>';
+        }
+
+        return $block_html;
+
+    }
+
+    /**
+     * Build titles and icons for action links
+     *
+     * @return array   the action titles
+     */
+    public static function buildActionTitles()
+    {
+        $titles = array();
+
+        $titles['Browse']     = self::getIcon('b_browse.png', __('Browse'));
+        $titles['NoBrowse']   = self::getIcon('bd_browse.png', __('Browse'));
+        $titles['Search']     = self::getIcon('b_select.png', __('Search'));
+        $titles['NoSearch']   = self::getIcon('bd_select.png', __('Search'));
+        $titles['Insert']     = self::getIcon('b_insrow.png', __('Insert'));
+        $titles['NoInsert']   = self::getIcon('bd_insrow.png', __('Insert'));
+        $titles['Structure']  = self::getIcon('b_props.png', __('Structure'));
+        $titles['Drop']       = self::getIcon('b_drop.png', __('Drop'));
+        $titles['NoDrop']     = self::getIcon('bd_drop.png', __('Drop'));
+        $titles['Empty']      = self::getIcon('b_empty.png', __('Empty'));
+        $titles['NoEmpty']    = self::getIcon('bd_empty.png', __('Empty'));
+        $titles['Edit']       = self::getIcon('b_edit.png', __('Edit'));
+        $titles['NoEdit']     = self::getIcon('bd_edit.png', __('Edit'));
+        $titles['Export']     = self::getIcon('b_export.png', __('Export'));
+        $titles['NoExport']   = self::getIcon('bd_export.png', __('Export'));
+        $titles['Execute']    = self::getIcon('b_nextpage.png', __('Execute'));
+        $titles['NoExecute']  = self::getIcon('bd_nextpage.png', __('Execute'));
+
+        return $titles;
+    }
+
+    /**
+     * This function processes the datatypes supported by the DB,
+     * as specified in PMA_Types->getColumns() and either returns an array
+     * (useful for quickly checking if a datatype is supported)
+     * or an HTML snippet that creates a drop-down list.
+     *
+     * @param bool   $html     Whether to generate an html snippet or an array
+     * @param string $selected The value to mark as selected in HTML mode
+     *
+     * @return mixed   An HTML snippet or an array of datatypes.
+     *
+     */
+    public static function getSupportedDatatypes($html = false, $selected = '')
+    {
+        if ($html) {
+
+            // NOTE: the SELECT tag in not included in this snippet.
+            $retval = '';
+
+            foreach ($GLOBALS['PMA_Types']->getColumns() as $key => $value) {
+                if (is_array($value)) {
+                    $retval .= "<optgroup label='" . htmlspecialchars($key) . "'>";
+                    foreach ($value as $subvalue) {
+                        if ($subvalue == $selected) {
+                            $retval .= sprintf(
+                                '<option selected="selected" title="%s">%s</option>',
+                                $GLOBALS['PMA_Types']->getTypeDescription($subvalue),
+                                $subvalue
+                            );
+                        } else if ($subvalue === '-') {
+                            $retval .= '<option disabled="disabled">';
+                            $retval .= $subvalue;
+                            $retval .= '</option>';
+                        } else {
+                            $retval .= sprintf(
+                                '<option title="%s">%s</option>',
+                                $GLOBALS['PMA_Types']->getTypeDescription($subvalue),
+                                $subvalue
+                            );
+                        }
+                    }
+                    $retval .= '</optgroup>';
+                } else {
+                    if ($selected == $value) {
+                        $retval .= sprintf(
+                            '<option selected="selected" title="%s">%s</option>',
+                            $GLOBALS['PMA_Types']->getTypeDescription($value),
+                            $value
+                        );
+                    } else {
+                        $retval .= sprintf(
+                            '<option title="%s">%s</option>',
+                            $GLOBALS['PMA_Types']->getTypeDescription($value),
+                            $value
+                        );
+                    }
+                }
+            }
+        } else {
+            $retval = array();
+            foreach ($GLOBALS['PMA_Types']->getColumns() as $value) {
+                if (is_array($value)) {
+                    foreach ($value as $subvalue) {
+                        if ($subvalue !== '-') {
+                            $retval[] = $subvalue;
+                        }
+                    }
+                } else {
+                    if ($value !== '-') {
+                        $retval[] = $value;
+                    }
+                }
+            }
+        }
+
+        return $retval;
+    } // end getSupportedDatatypes()
+
+    /**
+     * Returns a list of datatypes that are not (yet) handled by PMA.
+     * Used by: tbl_change.php and libraries/db_routines.inc.php
+     *
+     * @return array   list of datatypes
+     */
+    public static function unsupportedDatatypes()
+    {
+        $no_support_types = array();
+        return $no_support_types;
+    }
+
+    /**
+     * Return GIS data types
+     *
+     * @param bool $upper_case whether to return values in upper case
+     *
+     * @return array GIS data types
+     */
+    public static function getGISDatatypes($upper_case = false)
+    {
+        $gis_data_types = array(
+            'geometry',
+            'point',
+            'linestring',
+            'polygon',
+            'multipoint',
+            'multilinestring',
+            'multipolygon',
+            'geometrycollection'
+        );
+        if ($upper_case) {
+            for ($i = 0; $i < count($gis_data_types); $i++) {
+                $gis_data_types[$i] = strtoupper($gis_data_types[$i]);
+            }
+        }
+        return $gis_data_types;
+    }
+
+    /**
+     * Generates GIS data based on the string passed.
+     *
+     * @param string $gis_string GIS string
+     *
+     * @return string GIS data enclosed in 'GeomFromText' function
+     */
+    public static function createGISData($gis_string)
+    {
+        $gis_string = trim($gis_string);
+        $geom_types = '(POINT|MULTIPOINT|LINESTRING|MULTILINESTRING|'
+            . 'POLYGON|MULTIPOLYGON|GEOMETRYCOLLECTION)';
+        if (preg_match("/^'" . $geom_types . "\(.*\)',[0-9]*$/i", $gis_string)) {
+            return 'GeomFromText(' . $gis_string . ')';
+        } elseif (preg_match("/^" . $geom_types . "\(.*\)$/i", $gis_string)) {
+            return "GeomFromText('" . $gis_string . "')";
+        } else {
+            return $gis_string;
+        }
+    }
+
+    /**
+     * Returns the names and details of the functions
+     * that can be applied on geometry data typess.
+     *
+     * @param string $geom_type if provided the output is limited to the functions
+     *                          that are applicable to the provided geometry type.
+     * @param bool   $binary    if set to false functions that take two geometries
+     *                          as arguments will not be included.
+     * @param bool   $display   if set to true separators will be added to the
+     *                          output array.
+     *
+     * @return array names and details of the functions that can be applied on
+     *               geometry data typess.
+     */
+    public static function getGISFunctions(
+        $geom_type = null, $binary = true, $display = false
+    ) {
+        $funcs = array();
+        if ($display) {
+            $funcs[] = array('display' => ' ');
+        }
+
+        // Unary functions common to all geomety types
+        $funcs['Dimension']    = array('params' => 1, 'type' => 'int');
+        $funcs['Envelope']     = array('params' => 1, 'type' => 'Polygon');
+        $funcs['GeometryType'] = array('params' => 1, 'type' => 'text');
+        $funcs['SRID']         = array('params' => 1, 'type' => 'int');
+        $funcs['IsEmpty']      = array('params' => 1, 'type' => 'int');
+        $funcs['IsSimple']     = array('params' => 1, 'type' => 'int');
+
+        $geom_type = trim(strtolower($geom_type));
+        if ($display && $geom_type != 'geometry' && $geom_type != 'multipoint') {
+            $funcs[] = array('display' => '--------');
+        }
+
+        // Unary functions that are specific to each geomety type
+        if ($geom_type == 'point') {
+            $funcs['X'] = array('params' => 1, 'type' => 'float');
+            $funcs['Y'] = array('params' => 1, 'type' => 'float');
+
+        } elseif ($geom_type == 'multipoint') {
+            // no fucntions here
+        } elseif ($geom_type == 'linestring') {
+            $funcs['EndPoint']   = array('params' => 1, 'type' => 'point');
+            $funcs['GLength']    = array('params' => 1, 'type' => 'float');
+            $funcs['NumPoints']  = array('params' => 1, 'type' => 'int');
+            $funcs['StartPoint'] = array('params' => 1, 'type' => 'point');
+            $funcs['IsRing']     = array('params' => 1, 'type' => 'int');
+
+        } elseif ($geom_type == 'multilinestring') {
+            $funcs['GLength']  = array('params' => 1, 'type' => 'float');
+            $funcs['IsClosed'] = array('params' => 1, 'type' => 'int');
+
+        } elseif ($geom_type == 'polygon') {
+            $funcs['Area']         = array('params' => 1, 'type' => 'float');
+            $funcs['ExteriorRing'] = array('params' => 1, 'type' => 'linestring');
+            $funcs['NumInteriorRings'] = array('params' => 1, 'type' => 'int');
+
+        } elseif ($geom_type == 'multipolygon') {
+            $funcs['Area']     = array('params' => 1, 'type' => 'float');
+            $funcs['Centroid'] = array('params' => 1, 'type' => 'point');
+            // Not yet implemented in MySQL
+            //$funcs['PointOnSurface'] = array('params' => 1, 'type' => 'point');
+
+        } elseif ($geom_type == 'geometrycollection') {
+            $funcs['NumGeometries'] = array('params' => 1, 'type' => 'int');
+        }
+
+        // If we are asked for binary functions as well
+        if ($binary) {
+            // section separator
+            if ($display) {
+                $funcs[] = array('display' => '--------');
+            }
+
+            if (PMA_MYSQL_INT_VERSION < 50601) {
+                $funcs['Crosses']    = array('params' => 2, 'type' => 'int');
+                $funcs['Contains']   = array('params' => 2, 'type' => 'int');
+                $funcs['Disjoint']   = array('params' => 2, 'type' => 'int');
+                $funcs['Equals']     = array('params' => 2, 'type' => 'int');
+                $funcs['Intersects'] = array('params' => 2, 'type' => 'int');
+                $funcs['Overlaps']   = array('params' => 2, 'type' => 'int');
+                $funcs['Touches']    = array('params' => 2, 'type' => 'int');
+                $funcs['Within']     = array('params' => 2, 'type' => 'int');
+            } else {
+                // If MySQl version is greaeter than or equal 5.6.1,
+                // use the ST_ prefix.
+                $funcs['ST_Crosses']    = array('params' => 2, 'type' => 'int');
+                $funcs['ST_Contains']   = array('params' => 2, 'type' => 'int');
+                $funcs['ST_Disjoint']   = array('params' => 2, 'type' => 'int');
+                $funcs['ST_Equals']     = array('params' => 2, 'type' => 'int');
+                $funcs['ST_Intersects'] = array('params' => 2, 'type' => 'int');
+                $funcs['ST_Overlaps']   = array('params' => 2, 'type' => 'int');
+                $funcs['ST_Touches']    = array('params' => 2, 'type' => 'int');
+                $funcs['ST_Within']     = array('params' => 2, 'type' => 'int');
+            }
+
+            if ($display) {
+                $funcs[] = array('display' => '--------');
+            }
+            // Minimum bounding rectangle functions
+            $funcs['MBRContains']   = array('params' => 2, 'type' => 'int');
+            $funcs['MBRDisjoint']   = array('params' => 2, 'type' => 'int');
+            $funcs['MBREquals']     = array('params' => 2, 'type' => 'int');
+            $funcs['MBRIntersects'] = array('params' => 2, 'type' => 'int');
+            $funcs['MBROverlaps']   = array('params' => 2, 'type' => 'int');
+            $funcs['MBRTouches']    = array('params' => 2, 'type' => 'int');
+            $funcs['MBRWithin']     = array('params' => 2, 'type' => 'int');
+        }
+        return $funcs;
+    }
+
+    /**
+     * Returns default function for a particular column.
+     *
+     * @param array $field       Data about the column for which
+     *                           to generate the dropdown
+     * @param bool  $insert_mode Whether the operation is 'insert'
+     *
+     * @global   array    $cfg            PMA configuration
+     * @global   array    $analyzed_sql   Analyzed SQL query
+     * @global   mixed    $data           data of currently edited row
+     *                                    (used to detect whether to choose defaults)
+     *
+     * @return string   An HTML snippet of a dropdown list with function
+     *                    names appropriate for the requested column.
+     */
+    public static function getDefaultFunctionForField($field, $insert_mode)
+    {
+        global $cfg, $analyzed_sql, $data;
+
+        $default_function   = '';
+
+        // Can we get field class based values?
+        $current_class = $GLOBALS['PMA_Types']->getTypeClass($field['True_Type']);
+        if (! empty($current_class)) {
+            if (isset($cfg['DefaultFunctions']['FUNC_' . $current_class])) {
+                $default_function
+                    = $cfg['DefaultFunctions']['FUNC_' . $current_class];
+            }
+        }
+
+        $analyzed_sql_field_array = $analyzed_sql[0]['create_table_fields']
+            [$field['Field']];
+        // what function defined as default?
+        // for the first timestamp we don't set the default function
+        // if there is a default value for the timestamp
+        // (not including CURRENT_TIMESTAMP)
+        // and the column does not have the
+        // ON UPDATE DEFAULT TIMESTAMP attribute.
+        if (($field['True_Type'] == 'timestamp')
+            && $field['first_timestamp']
+            && empty($field['Default'])
+            && empty($data)
+            && ! isset($analyzed_sql_field_array['on_update_current_timestamp'])
+            && ($analyzed_sql_field_array['default_value'] != 'NULL')
+        ) {
+            $default_function = $cfg['DefaultFunctions']['first_timestamp'];
+        }
+
+        // For primary keys of type char(36) or varchar(36) UUID if the default
+        // function
+        // Only applies to insert mode, as it would silently trash data on updates.
+        if ($insert_mode
+            && $field['Key'] == 'PRI'
+            && ($field['Type'] == 'char(36)' || $field['Type'] == 'varchar(36)')
+        ) {
+             $default_function = $cfg['DefaultFunctions']['FUNC_UUID'];
+        }
+
+        // this is set only when appropriate and is always true
+        if (isset($field['display_binary_as_hex'])) {
+            $default_function = 'UNHEX';
+        }
+
+        return $default_function;
+    }
+
+    /**
+     * Creates a dropdown box with MySQL functions for a particular column.
+     *
+     * @param array $field       Data about the column for which
+     *                           to generate the dropdown
+     * @param bool  $insert_mode Whether the operation is 'insert'
+     *
+     * @return string   An HTML snippet of a dropdown list with function
+     *                    names appropriate for the requested column.
+     */
+    public static function getFunctionsForField($field, $insert_mode)
+    {
+        $default_function = self::getDefaultFunctionForField($field, $insert_mode);
+        $dropdown_built = array();
+
+        // Create the output
+        $retval = '<option></option>' . "\n";
+        // loop on the dropdown array and print all available options for that
+        // field.
+        $functions = $GLOBALS['PMA_Types']->getFunctions($field['True_Type']);
+        foreach ($functions as $function) {
+            $retval .= '<option';
+            if ($default_function === $function) {
+                $retval .= ' selected="selected"';
+            }
+            $retval .= '>' . $function . '</option>' . "\n";
+            $dropdown_built[$function] = true;
+        }
+
+        // Create separator before all functions list
+        if (count($functions) > 0) {
+            $retval .= '<option value="" disabled="disabled">--------</option>'
+                . "\n";
+        }
+
+        // For compatibility's sake, do not let out all other functions. Instead
+        // print a separator (blank) and then show ALL functions which weren't
+        // shown yet.
+        $functions = $GLOBALS['PMA_Types']->getAllFunctions();
+        foreach ($functions as $function) {
+            // Skip already included functions
+            if (isset($dropdown_built[$function])) {
+                continue;
+            }
+            $retval .= '<option';
+            if ($default_function === $function) {
+                $retval .= ' selected="selected"';
+            }
+            $retval .= '>' . $function . '</option>' . "\n";
+        } // end for
+
+        return $retval;
+    } // end getFunctionsForField()
+
+    /**
+     * Checks if the current user has a specific privilege and returns true if the
+     * user indeed has that privilege or false if (s)he doesn't. This function must
+     * only be used for features that are available since MySQL 5, because it
+     * relies on the INFORMATION_SCHEMA database to be present.
+     *
+     * Example:   currentUserHasPrivilege('CREATE ROUTINE', 'mydb');
+     *            // Checks if the currently logged in user has the global
+     *            // 'CREATE ROUTINE' privilege or, if not, checks if the
+     *            // user has this privilege on database 'mydb'.
+     *
+     * @param string $priv The privilege to check
+     * @param mixed  $db   null, to only check global privileges
+     *                     string, db name where to also check for privileges
+     * @param mixed  $tbl  null, to only check global/db privileges
+     *                     string, table name where to also check for privileges
+     *
+     * @return bool
+     */
+    public static function currentUserHasPrivilege($priv, $db = null, $tbl = null)
+    {
+        // Get the username for the current user in the format
+        // required to use in the information schema database.
+        $user = PMA_DBI_fetch_value("SELECT CURRENT_USER();");
+        if ($user === false) {
+            return false;
+        }
+
+        $user = explode('@', $user);
+        $username  = "''";
+        $username .= str_replace("'", "''", $user[0]);
+        $username .= "''@''";
+        $username .= str_replace("'", "''", $user[1]);
+        $username .= "''";
+
+        // Prepage the query
+        $query = "SELECT `PRIVILEGE_TYPE` FROM `INFORMATION_SCHEMA`.`%s` "
+               . "WHERE GRANTEE='%s' AND PRIVILEGE_TYPE='%s'";
+
+        // Check global privileges first.
+        $user_privileges = PMA_DBI_fetch_value(
+            sprintf(
+                $query,
+                'USER_PRIVILEGES',
+                $username,
+                $priv
+            )
+        );
+        if ($user_privileges) {
+            return true;
+        }
+        // If a database name was provided and user does not have the
+        // required global privilege, try database-wise permissions.
+        if ($db !== null) {
+            // need to escape wildcards in db and table names, see bug #3518484
+            $db = str_replace(array('%', '_'), array('\%', '\_'), $db);
+            $query .= " AND TABLE_SCHEMA='%s'";
+            $schema_privileges = PMA_DBI_fetch_value(
+                sprintf(
+                    $query,
+                    'SCHEMA_PRIVILEGES',
+                    $username,
+                    $priv,
+                    self::sqlAddSlashes($db)
+                )
+            );
+            if ($schema_privileges) {
+                return true;
+            }
+        } else {
+            // There was no database name provided and the user
+            // does not have the correct global privilege.
+            return false;
+        }
+        // If a table name was also provided and we still didn't
+        // find any valid privileges, try table-wise privileges.
+        if ($tbl !== null) {
+            // need to escape wildcards in db and table names, see bug #3518484
+            $tbl = str_replace(array('%', '_'), array('\%', '\_'), $tbl);
+            $query .= " AND TABLE_NAME='%s'";
+            $table_privileges = PMA_DBI_fetch_value(
+                sprintf(
+                    $query,
+                    'TABLE_PRIVILEGES',
+                    $username,
+                    $priv,
+                    self::sqlAddSlashes($db),
+                    self::sqlAddSlashes($tbl)
+                )
+            );
+            if ($table_privileges) {
+                return true;
+            }
+        }
+        // If we reached this point, the user does not
+        // have even valid table-wise privileges.
+        return false;
+    }
+
+    /**
+     * Returns server type for current connection
+     *
+     * Known types are: Drizzle, MariaDB and MySQL (default)
+     *
+     * @return string
+     */
+    public static function getServerType()
+    {
+        $server_type = 'MySQL';
+        if (PMA_DRIZZLE) {
+            $server_type = 'Drizzle';
+        } else if (stripos(PMA_MYSQL_STR_VERSION, 'mariadb') !== false) {
+            $server_type = 'MariaDB';
+        } else if (stripos(PMA_MYSQL_VERSION_COMMENT, 'percona') !== false) {
+            $server_type = 'Percona Server';
+        }
+        return $server_type;
+    }
+
+    /**
+     * Analyzes the limit clause and return the start and length attributes of it.
+     *
+     * @param string $limit_clause limit clause
+     *
+     * @return array Start and length attributes of the limit clause
+     */
+    public static function analyzeLimitClause($limit_clause)
+    {
+        $start_and_length = explode(',', str_ireplace('LIMIT', '', $limit_clause));
+        $size = count($start_and_length);
+        if ($size == 1) {
+            return array(
+                'start'  => '0',
+                'length' => trim($start_and_length[0])
+            );
+        } elseif ($size == 2) {
+            return array(
+                'start'  => trim($start_and_length[0]),
+                'length' => trim($start_and_length[1])
+            );
+        }
+    }
+
+    /**
+     * Prepare HTML code for display button.
+     *
+     * @return void
+     */
+    public static function getButton()
+    {
+        return '<p class="print_ignore">'
+            . '<input type="button" class="button" id="print" value="'
+            . __('Print') . '" />'
+            . '</p>';
+    }
+
+    /**
+     * Parses ENUM/SET values
+     *
+     * @param string $definition The definition of the column
+     *                           for which to parse the values
+     * @param bool   $escapeHtml Whether to escape html entitites
+     *
+     * @return array
+     */
+    public static function parseEnumSetValues($definition, $escapeHtml = true)
+    {
+        $values_string = htmlentities($definition, ENT_COMPAT, "UTF-8");
+        // There is a JS port of the below parser in functions.js
+        // If you are fixing something here,
+        // you need to also update the JS port.
+        $values = array();
+        $in_string = false;
+        $buffer = '';
+
+        for ($i=0; $i<strlen($values_string); $i++) {
+
+            $curr = $values_string[$i];
+            $next = ($i == strlen($values_string)-1) ? '' : $values_string[$i+1];
+
+            if (! $in_string && $curr == "'") {
+                $in_string = true;
+            } else if (($in_string && $curr == "\\") && $next == "\\") {
+                $buffer .= "\";
+                $i++;
+            } else if (($in_string && $next == "'")
+                && ($curr == "'" || $curr == "\\")
+            ) {
+                $buffer .= "'";
+                $i++;
+            } else if ($in_string && $curr == "'") {
+                $in_string = false;
+                $values[] = $buffer;
+                $buffer = '';
+            } else if ($in_string) {
+                 $buffer .= $curr;
+            }
+
+        }
+
+        if (strlen($buffer) > 0) {
+            // The leftovers in the buffer are the last value (if any)
+            $values[] = $buffer;
+        }
+
+        if (! $escapeHtml) {
+            foreach ($values as $key => $value) {
+                $values[$key] = html_entity_decode($value, ENT_QUOTES);
+            }
+        }
+
+        return $values;
+    }
+
+    /**
+     * fills given tooltip arrays
+     *
+     * @param array &$tooltip_truename  tooltip data
+     * @param array &$tooltip_aliasname tooltip data
+     * @param array $table              tabledata
+     *
+     * @return void
+     */
+    public static function fillTooltip(
+        &$tooltip_truename, &$tooltip_aliasname, $table
+    ) {
+        if (strstr($table['Comment'], '; InnoDB free') === false) {
+            if (!strstr($table['Comment'], 'InnoDB free') === false) {
+                // here we have just InnoDB generated part
+                $table['Comment'] = '';
+            }
+        } else {
+            // remove InnoDB comment from end, just the minimal part
+            // (*? is non greedy)
+            $table['Comment'] = preg_replace(
+                '@; InnoDB free:.*?$@', '', $table['Comment']
+            );
+        }
+        // views have VIEW as comment so it's not a real comment put by a user
+        if ('VIEW' == $table['Comment']) {
+            $table['Comment'] = '';
+        }
+        if (empty($table['Comment'])) {
+            $table['Comment'] = $table['Name'];
+        } else {
+            // todo: why?
+            $table['Comment'] .= ' ';
+        }
+
+        $tooltip_truename[$table['Name']] = $table['Name'];
+        $tooltip_aliasname[$table['Name']] = $table['Comment'];
+
+        if (isset($table['Create_time']) && !empty($table['Create_time'])) {
+            $tooltip_aliasname[$table['Name']] .= ', ' . __('Creation')
+                . ': '
+                . PMA_Util::localisedDate(strtotime($table['Create_time']));
+        }
+
+        if (! empty($table['Update_time'])) {
+            $tooltip_aliasname[$table['Name']] .= ', ' . __('Last update')
+                . ': '
+                . PMA_Util::localisedDate(strtotime($table['Update_time']));
+        }
+
+        if (! empty($table['Check_time'])) {
+            $tooltip_aliasname[$table['Name']] .= ', ' . __('Last check')
+                . ': '
+                . PMA_Util::localisedDate(strtotime($table['Check_time']));
+        }
+    }
+}
+?>
diff --git a/phpmyadmin/libraries/advisory_rules.txt b/phpmyadmin/libraries/advisory_rules.txt
new file mode 100644
index 0000000..3ffa1d9
--- /dev/null
+++ b/phpmyadmin/libraries/advisory_rules.txt
@@ -0,0 +1,470 @@
+# phpMyAdmin Advisory rules file
+#
+# Use only UNIX style newlines
+#
+# This file is being parsed by Advisor.class.php, which should handle syntax
+# errors correctly. However, PHP Warnings and the like are being consumed by
+# the phpMyAdmin error handler, so those won't show up E.g.: Justification line
+# is empty because you used an unescape percent sign, sprintf() returns an
+# empty string and no warning/error is shown
+#
+# Rule Syntax:
+# 'rule' identifier[the name of the rule] eexpr [an optional precondition]
+#	expr		[variable or value calculation used for the test]
+#	expr		[test, if evaluted to 'true' it fires the rule. Use 'value' to insert the calculated value (without quotes)]
+#	string		[the issue (what is the problem?)]
+#	string		[the recommendation (how do i fix it?)]
+#	formatted-string '|' comma-seperated-expr		[the justification  (result of the calculated value / why did this rule fire?)]
+
+# comma-seperated-expr: expr(,expr)*
+# eexpr: [expr]		- expr enclosed in []
+# expr: a php code literal with extras:
+#       - variable names are replaced with their respective values
+#       - fired('name of rule') is replaced with true/false when given rule has
+#         been fired. Note however that this is a very simple rules engine.
+#         Rules are only checked in sequential order as they are written down
+#         here. If given rule has not been checked yet, fired() will always
+#         evaluate to false
+#       - 'value' is replaced with the calculated value. If it is a string, it
+#         will be put within single quotes
+#       - other than that you may use any php function, initialized variable or
+#         constant
+#
+# identifier: A string enclosed in single quotes
+# string: A quoteless string, may contain HTML. Variable names enclosed in
+#         curly braces are replaced with links to directly edit this variable.
+#         e.g. {tmp_table_size}
+# formatted-string: You may use classic php sprintf() string formatting here,
+#                   the arguments must be appended after a trailing pipe (|) as
+#                   mentioned in above syntax percent signs (%) are
+#                   automatically escaped (%%) in the following cases: When
+#                   followed by a space, dot or comma and at the end of the
+#                   line)
+#
+# Comments start with #
+#
+
+# Queries
+
+rule 'Uptime below one day'
+	Uptime
+	value < 86400
+	Uptime is less than 1 day, performance tuning may not be accurate.
+	To have more accurate averages it is recommended to let the server run for longer than a day before running this analyzer
+	The uptime is only %s | ADVISOR_timespanFormat(Uptime)
+
+rule 'Questions below 1,000'
+	Questions
+	value < 1000
+	Fewer than 1,000 questions have been run against this server. The recommendations may not be accurate.
+	Let the server run for a longer time until it has executed a greater amount of queries.
+	Current amount of Questions: %s | Questions
+
+rule 'Percentage of slow queries' [Questions > 0 && !PMA_DRIZZLE]
+	Slow_queries / Questions * 100
+	value >= 5
+	There is a lot of slow queries compared to the overall amount of Queries.
+	You might want to increase {long_query_time} or optimize the queries listed in the slow query log
+	The slow query rate should be below 5%, your value is %s%. | round(value,2)
+
+rule 'Slow query rate' [Questions > 0]
+	(Slow_queries / Questions * 100) / Uptime
+	value * 60 * 60 > 1
+	There is a high percentage of slow queries compared to the server uptime.
+	You might want to increase {long_query_time} or optimize the queries listed in the slow query log
+	You have a slow query rate of %s per hour, you should have less than 1% per hour. | ADVISOR_bytime(value,2)
+
+rule 'Long query time' [!PMA_DRIZZLE]
+	long_query_time
+	value >= 10
+	{long_query_time} is set to 10 seconds or more, thus only slow queries that take above 10 seconds are logged.
+	It is suggested to set {long_query_time} to a lower value, depending on your environment. Usually a value of 1-5 seconds is suggested.
+	long_query_time is currently set to %ds. | value
+
+rule 'Slow query logging' [!PMA_DRIZZLE && PMA_MYSQL_INT_VERSION < 50600]
+	log_slow_queries
+	value == 'OFF'
+	The slow query log is disabled.
+	Enable slow query logging by setting {log_slow_queries} to 'ON'. This will help troubleshooting badly performing queries.
+	log_slow_queries is set to 'OFF'
+
+rule 'Slow query logging' [!PMA_DRIZZLE && PMA_MYSQL_INT_VERSION >= 50600]
+	slow_query_log
+	value == 'OFF'
+	The slow query log is disabled.
+	Enable slow query logging by setting {slow_query_log} to 'ON'. This will help troubleshooting badly performing queries.
+	slow_query_log is set to 'OFF'
+
+#
+# versions
+rule 'Release Series' [!PMA_DRIZZLE]
+	version
+	substr(value,0,1) <= 5 && substr(value,2,1) < 1
+	The MySQL server version less than 5.1.
+	You should upgrade, as MySQL 5.1 has improved performance, and MySQL 5.5 even more so.
+	Current version: %s | value
+
+rule 'Minor Version' [! fired('Release Series')]
+	version
+	substr(value,0,1) <= 5 && substr(value,2,1) < 1 && substr(value,4,2) < 30
+	Version less than 5.1.30 (the first GA release of 5.1).
+	You should upgrade, as recent versions of MySQL 5.1 have improved performance and MySQL 5.5 even more so.
+	Current version: %s | value
+
+rule 'Minor Version' [! fired('Release Series')]
+	version
+	substr(value,0,1) == 5 && substr(value,2,1) == 5 && substr(value,4,2) < 8
+	Version less than 5.5.8 (the first GA release of 5.5).
+	You should upgrade, to a stable version of MySQL 5.5
+	Current version: %s | value
+
+rule 'Distribution'
+	version_comment
+	preg_match('/source/i',value)
+	Version is compiled from source, not a MySQL official binary.
+	If you did not compile from source, you may be using a package modified by a distribution. The MySQL manual only is accurate for official MySQL binaries, not any package distributions (such as RedHat, Debian/Ubuntu etc).
+	'source' found in version_comment
+
+rule 'Distribution'
+	version_comment
+	preg_match('/percona/i',value)
+	The MySQL manual only is accurate for official MySQL binaries.
+	Percona documentation is at http://www.percona.com/docs/wiki/
+	'percona' found in version_comment
+
+rule 'Distribution'
+	version
+	PMA_DRIZZLE
+	The MySQL manual only is accurate for official MySQL binaries.
+	Drizzle documentation is at http://docs.drizzle.org/
+	Version string (%s) matches Drizzle versioning scheme | value
+
+rule 'MySQL Architecture'
+	system_memory
+	value > 3072*1024 && !preg_match('/64/',version_compile_machine) && !preg_match('/64/',version_compile_os)
+	MySQL is not compiled as a 64-bit package.
+	Your memory capacity is above 3 GiB (assuming the Server is on localhost), so MySQL might not be able to access all of your memory. You might want to consider installing the 64-bit version of MySQL.
+	Available memory on this host: %s | implode(' ',ADVISOR_formatByteDown(value*1024, 2, 2))
+
+#
+# Query cache
+
+# Lame: 'ON' == 0 is true, so you need to compare 'ON' == '0'
+rule 'Query cache disabled' [!PMA_DRIZZLE]
+	query_cache_size
+	value == 0 || query_cache_type == 'OFF' || query_cache_type == '0'
+	The query cache is not enabled.
+	The query cache is known to greatly improve performance if configured correctly. Enable it by setting {query_cache_size} to a 2 digit MiB value and setting {query_cache_type} to 'ON'. <b>Note:</b> If you are using memcached, ignore this recommendation.
+	query_cache_size is set to 0 or query_cache_type is set to 'OFF'
+
+rule 'Query caching method' [!fired('Query cache disabled')]
+	Questions / Uptime
+	value > 100
+	Suboptimal caching method.
+	You are using the MySQL Query cache with a fairly high traffic database. It might be worth considering to use <a href="http://dev.mysql.com/doc/refman/5.5/en/ha-memcached.html">memcached</a> instead of the MySQL Query cache, especially if you have multiple slaves.
+	The query cache is enabled and the server receives %d queries per second. This rule fires if there is more than 100 queries per second. | round(value,1)
+
+rule 'Query cache efficiency (%)' [!PMA_DRIZZLE && Com_select + Qcache_hits > 0 && !fired('Query cache disabled')]
+	Qcache_hits / (Com_select + Qcache_hits) * 100
+	value  < 20
+	Query cache not running efficiently, it has a low hit rate.
+	Consider increasing {query_cache_limit}.
+	The current query cache hit rate of %s% is below 20% | round(value,1)
+
+rule 'Query Cache usage' [!fired('Query cache disabled') && !PMA_DRIZZLE]
+	100 - Qcache_free_memory / query_cache_size * 100
+	value < 80
+	Less than 80% of the query cache is being utilized.
+	This might be caused by {query_cache_limit} being too low. Flushing the query cache might help as well.
+	The current ratio of free query cache memory to total query cache size is %s%. It should be above 80% | round(value,1)
+
+rule 'Query cache fragmentation' [!fired('Query cache disabled') && !PMA_DRIZZLE]
+	Qcache_free_blocks / (Qcache_total_blocks / 2) * 100
+	value > 20
+	The query cache is considerably fragmented.
+	Severe fragmentation is likely to (further) increase Qcache_lowmem_prunes. This might be caused by many Query cache low memory prunes due to {query_cache_size} being too small. For a immediate but short lived fix you can flush the query cache (might lock the query cache for a long time). Carefully adjusting {query_cache_min_res_unit} to a lower value might help too, e.g. you can set it to the average size of your queries in the cache using this formula: (query_cache_size - qcache_free_m [...]
+	The cache is currently fragmented by %s% , with 100% fragmentation meaning that the query cache is an alternating pattern of free and used blocks. This value should be below 20%. | round(value,1)
+
+rule 'Query cache low memory prunes' [!PMA_DRIZZLE && Qcache_inserts > 0 && !fired('Query cache disabled')]
+	Qcache_lowmem_prunes / Qcache_inserts * 100
+	value > 0.1
+	Cached queries are removed due to low query cache memory from the query cache.
+	You might want to increase {query_cache_size}, however keep in mind that the overhead of maintaining the cache is likely to increase with its size, so do this in small increments and monitor the results.
+	The ratio of removed queries to inserted queries is %s%. The lower this value is, the better (This rules firing limit: 0.1%) | round(value,1)
+
+rule 'Query cache max size' [!fired('Query cache disabled')]
+	query_cache_size
+	value > 1024 * 1024 * 128
+	The query cache size is above 128 MiB. Big query caches may cause significant overhead that is required to maintain the cache.
+	Depending on your environment, it might be performance increasing to reduce this value.
+	Current query cache size: %s | implode(' ',ADVISOR_formatByteDown(value, 2, 2))
+
+rule 'Query cache min result size' [!fired('Query cache disabled')]
+	value == 1024*1024
+	query_cache_limit
+	The max size of the result set in the query cache is the default of 1 MiB.
+	Changing {query_cache_limit} (usually by increasing) may increase efficiency. This variable determines the maximum size a query result may have to be inserted into the query cache. If there are many query results above 1 MiB that are well cacheable (many reads, little writes) then increasing {query_cache_limit} will increase efficiency. Whereas in the case of many query results being above 1 MiB that are not very well cacheable (often invalidated due to table updates) increasing {query_ [...]
+	query_cache_limit is set to 1 MiB
+
+#
+# Sorts
+rule 'Percentage of sorts that cause temporary tables' [Sort_scan + Sort_range > 0]
+	Sort_merge_passes / (Sort_scan + Sort_range) * 100
+	value > 10
+	Too many sorts are causing temporary tables.
+	Consider increasing {sort_buffer_size} and/or {read_rnd_buffer_size}, depending on your system memory limits
+	%s% of all sorts cause temporary tables, this value should be lower than 10%. | round(value,1)
+
+rule 'Rate of sorts that cause temporary tables'
+	Sort_merge_passes / Uptime
+	value * 60 * 60 > 1
+	Too many sorts are causing temporary tables.
+	Consider increasing {sort_buffer_size} and/or {read_rnd_buffer_size}, depending on your system memory limits
+	Temporary tables average: %s, this value should be less than 1 per hour. | ADVISOR_bytime(value,2)
+
+rule 'Sort rows'
+	Sort_rows / Uptime
+	value * 60 >= 1
+	There are lots of rows being sorted.
+	While there is nothing wrong with a high amount of row sorting, you might want to make sure that the queries which require a lot of sorting use indexed columns in the ORDER BY clause, as this will result in much faster sorting
+	Sorted rows average: %s | ADVISOR_bytime(value,2)
+
+# Joins, scans
+rule 'Rate of joins without indexes'
+	(Select_range_check + Select_scan + Select_full_join) / Uptime
+	value * 60 * 60 > 1
+	There are too many joins without indexes.
+	This means that joins are doing full table scans. Adding indexes for the columns being used in the join conditions will greatly speed up table joins
+	Table joins average: %s, this value should be less than 1 per hour | ADVISOR_bytime(value,2)
+
+rule 'Rate of reading first index entry'
+	Handler_read_first / Uptime
+	value * 60 * 60 > 1
+	The rate of reading the first index entry is high.
+	This usually indicates frequent full index scans. Full index scans are faster than table scans but require lots of CPU cycles in big tables, if those tables that have or had high volumes of UPDATEs and DELETEs, running 'OPTIMIZE TABLE' might reduce the amount of and/or speed up full index scans. Other than that full index scans can only be reduced by rewriting queries.
+	Index scans average: %s, this value should be less than 1 per hour | ADVISOR_bytime(value,2)
+
+rule 'Rate of reading fixed position'
+	Handler_read_rnd / Uptime
+	value * 60 * 60 > 1
+	The rate of reading data from a fixed position is high.
+	This indicates that many queries need to sort results and/or do a full table scan, including join queries that do not use indexes. Add indexes where applicable.
+	Rate of reading fixed position average: %s, this value should be less than 1 per hour | ADVISOR_bytime(value,2)
+
+rule 'Rate of reading next table row'
+	Handler_read_rnd_next / Uptime
+	value * 60 * 60 > 1
+	The rate of reading the next table row is high.
+	This indicates that many queries are doing full table scans. Add indexes where applicable.
+	Rate of reading next table row: %s, this value should be less than 1 per hour | ADVISOR_bytime(value,2)
+
+# temp tables
+rule 'tmp_table_size vs. max_heap_table_size'
+	tmp_table_size - max_heap_table_size
+	value !=0
+	{tmp_table_size} and {max_heap_table_size} are not the same.
+	If you have deliberately changed one of either: The server uses the lower value of either to determine the maximum size of in-memory tables. So if you wish to increase the in-memory table limit you will have to increase the other value as well.
+	Current values are tmp_table_size: %s, max_heap_table_size: %s | implode(' ',ADVISOR_formatByteDown(tmp_table_size, 2, 2)), implode(' ',ADVISOR_formatByteDown(max_heap_table_size, 2, 2))
+
+rule 'Percentage of temp tables on disk' [Created_tmp_tables + Created_tmp_disk_tables > 0]
+	Created_tmp_disk_tables / (Created_tmp_tables + Created_tmp_disk_tables) * 100
+	value > 25
+	Many temporary tables are being written to disk instead of being kept in memory.
+	Increasing {max_heap_table_size} and {tmp_table_size} might help. However some temporary tables are always being written to disk, independent of the value of these variables. To eliminate these you will have to rewrite your queries to avoid those conditions (Within a temporary table: Presence of a BLOB or TEXT column or presence of a column bigger than 512 bytes) as mentioned in the beginning of an <a href="http://www.facebook.com/note.php?note_id=10150111255065841&comments">Article by  [...]
+	%s% of all temporary tables are being written to disk, this value should be below 25% | round(value,1)
+
+rule 'Temp disk rate' [!fired('Percentage of temp tables on disk')]
+	Created_tmp_disk_tables / Uptime
+	value * 60 * 60 > 1
+	Many temporary tables are being written to disk instead of being kept in memory.
+	Increasing {max_heap_table_size} and {tmp_table_size} might help. However some temporary tables are always being written to disk, independent of the value of these variables. To eliminate these you will have to rewrite your queries to avoid those conditions (Within a temporary table: Presence of a BLOB or TEXT column or presence of a column bigger than 512 bytes) as mentioned in the <a href="http://dev.mysql.com/doc/refman/5.5/en/internal-temporary-tables.html">MySQL Documentation</a>
+	Rate of temporary tables being written to disk: %s, this value should be less than 1 per hour | ADVISOR_bytime(value,2)
+
+# I couldn't find any source on the internet that suggests a direct relation between high counts of temporary tables and any of these variables.
+# Several independent Blog entries suggest (http://ronaldbradford.com/blog/more-on-understanding-sort_buffer_size-2010-05-10/ and http://www.xaprb.com/blog/2010/05/09/how-to-tune-mysqls-sort_buffer_size/)
+# that sort_buffer_size should be left as it is. And increasing read_buffer_size is only suggested when there are a lot of
+# table scans (http://dev.mysql.com/doc/refman/5.5/en/server-system-variables.html#sysvar_read_buffer_size and other sources) though
+# setting it too high is bad too (http://www.mysqlperformanceblog.com/2007/09/17/mysql-what-read_buffer_size-value-is-optimal/).
+#rule 'Temp table rate'
+#	Created_tmp_tables / Uptime
+#	value * 60 * 60 > 1
+#	Many intermediate temporary tables are being created.
+#	This may be caused by queries under certain conditions as mentioned in the <a href="http://dev.mysql.com/doc/refman/5.5/en/internal-temporary-tables.html">MySQL Documentation</a>. Consider increasing {sort_buffer_size} (sorting), {read_rnd_buffer_size} (random read buffer, ie, post-sort), {read_buffer_size} (sequential scan).
+
+#
+# MyISAM index cache
+rule 'MyISAM key buffer size' [!PMA_DRIZZLE]
+	key_buffer_size
+	value == 0
+	Key buffer is not initialized. No MyISAM indexes will be cached.
+	Set {key_buffer_size} depending on the size of your MyISAM indexes. 64M is a good start.
+	key_buffer_size is 0
+
+rule 'Max % MyISAM key buffer ever used' [!PMA_DRIZZLE && key_buffer_size > 0]
+	Key_blocks_used * key_cache_block_size / key_buffer_size * 100
+	value < 95
+	MyISAM key buffer (index cache) % used is low.
+	You may need to decrease the size of {key_buffer_size}, re-examine your tables to see if indexes have been removed, or examine queries and expectations about what indexes are being used.
+	max % MyISAM key buffer ever used: %s%, this value should be above 95% | round(value,1)
+
+# Don't fire if above rule fired - we don't need the same advice twice
+rule 'Percentage of MyISAM key buffer used' [!PMA_DRIZZLE && key_buffer_size > 0 && !fired('Max % MyISAM key buffer ever used')]
+	( 1 - Key_blocks_unused * key_cache_block_size / key_buffer_size) * 100
+	value < 95
+	MyISAM key buffer (index cache) % used is low.
+	You may need to decrease the size of {key_buffer_size}, re-examine your tables to see if indexes have been removed, or examine queries and expectations about what indexes are being used.
+	% MyISAM key buffer used: %s%, this value should be above 95% | round(value,1)
+
+rule 'Percentage of index reads from memory' [!PMA_DRIZZLE && Key_read_requests > 0]
+	100 - (Key_reads / Key_read_requests * 100)
+	value < 95
+	The % of indexes that use the MyISAM key buffer is low.
+	You may need to increase {key_buffer_size}.
+	Index reads from memory: %s%, this value should be above 95% | round(value,1)
+
+#
+# other caches
+rule 'Rate of table open' [!PMA_DRIZZLE]
+	Opened_tables / Uptime
+	value*60*60 > 10
+	The rate of opening tables is high.
+	Opening tables requires disk I/O which is costly. Increasing {table_open_cache} might avoid this.
+	Opened table rate: %s, this value should be less than 10 per hour | ADVISOR_bytime(value,2)
+
+rule 'Percentage of used open files limit' [!PMA_DRIZZLE]
+	Open_files / open_files_limit * 100
+	value > 85
+	The number of open files is approaching the max number of open files.  You may get a "Too many open files" error.
+	Consider increasing {open_files_limit}, and check the error log when restarting after changing {open_files_limit}.
+	The number of opened files is at %s% of the limit. It should be below 85% | round(value,1)
+
+rule 'Rate of open files' [!PMA_DRIZZLE]
+	Open_files / Uptime
+	value * 60 * 60 > 5
+	The rate of opening files is high.
+	Consider increasing {open_files_limit}, and check the error log when restarting after changing {open_files_limit}.
+	Opened files rate: %s, this value should be less than 5 per hour | ADVISOR_bytime(value,2)
+
+rule 'Immediate table locks %' [Table_locks_waited + Table_locks_immediate > 0]
+	Table_locks_immediate / (Table_locks_waited + Table_locks_immediate) * 100
+	value < 95
+	Too many table locks were not granted immediately.
+	Optimize queries and/or use InnoDB to reduce lock wait.
+	Immediate table locks: %s%, this value should be above 95% | round(value,1)
+
+rule 'Table lock wait rate'
+	Table_locks_waited / Uptime
+	value * 60 * 60 > 1
+	Too many table locks were not granted immediately.
+	Optimize queries and/or use InnoDB to reduce lock wait.
+	Table lock wait rate: %s, this value should be less than 1 per hour | ADVISOR_bytime(value,2)
+
+rule 'Thread cache' [!PMA_DRIZZLE]
+	thread_cache_size
+	value < 1
+	Thread cache is disabled, resulting in more overhead from new connections to MySQL.
+	Enable the thread cache by setting {thread_cache_size} > 0.
+	The thread cache is set to 0
+
+rule 'Thread cache hit rate %' [!PMA_DRIZZLE && thread_cache_size > 0]
+	100 - Threads_created / Connections
+	value < 80
+	Thread cache is not efficient.
+	Increase {thread_cache_size}.
+	Thread cache hitrate: %s%, this value should be above 80% | round(value,1)
+
+rule 'Threads that are slow to launch' [!PMA_DRIZZLE && slow_launch_time > 0]
+	Slow_launch_threads
+	value > 0
+	There are too many threads that are slow to launch.
+	This generally happens in case of general system overload as it is pretty simple operations. You might want to monitor your system load carefully.
+	%s thread(s) took longer than %s seconds to start, it should be 0 | value, slow_launch_time
+
+rule 'Slow launch time' [!PMA_DRIZZLE]
+	slow_launch_time
+	value > 2
+	Slow_launch_threads is above 2s
+	Set {slow_launch_time} to 1s or 2s to correctly count threads that are slow to launch
+	slow_launch_time is set to %s | value
+
+#
+#Connections
+rule 'Percentage of used connections' [!PMA_DRIZZLE]
+	Max_used_connections / max_connections * 100
+	value > 80
+	The maximum amount of used connections is getting close to the value of {max_connections}.
+	Increase {max_connections}, or decrease {wait_timeout} so that connections that do not close database handlers properly get killed sooner. Make sure the code closes database handlers properly.
+	Max_used_connections is at %s% of max_connections, it should be below 80% | round(value,1)
+
+rule 'Percentage of aborted connections'
+	Aborted_connects / Connections * 100
+	value > 1
+	Too many connections are aborted.
+	Connections are usually aborted when they cannot be authorized. <a href="http://www.mysqlperformanceblog.com/2008/08/23/how-to-track-down-the-source-of-aborted_connects/">This article</a> might help you track down the source.
+	%s% of all connections are aborted. This value should be below 1% | round(value,1)
+
+rule 'Rate of aborted connections'
+	Aborted_connects / Uptime
+	value * 60 * 60 > 1
+	Too many connections are aborted.
+	Connections are usually aborted when they cannot be authorized. <a href="http://www.mysqlperformanceblog.com/2008/08/23/how-to-track-down-the-source-of-aborted_connects/">This article</a> might help you track down the source.
+	Aborted connections rate is at %s, this value should be less than 1 per hour | ADVISOR_bytime(value,2)
+
+rule 'Percentage of aborted clients'
+	Aborted_clients / Connections * 100
+	value > 2
+	Too many clients are aborted.
+	Clients are usually aborted when they did not close their connection to MySQL properly. This can be due to network issues or code not closing a database handler properly. Check your network and code.
+	%s% of all clients are aborted. This value should be below 2% | round(value,1)
+
+rule 'Rate of aborted clients'
+	Aborted_clients / Uptime
+	value * 60 * 60 > 1
+	Too many clients are aborted.
+	Clients are usually aborted when they did not close their connection to MySQL properly. This can be due to network issues or code not closing a database handler properly. Check your network and code.
+	Aborted client rate is at %s, this value should be less than 1 per hour | ADVISOR_bytime(value,2)
+
+#
+# InnoDB
+rule 'Is InnoDB disabled?' [!PMA_DRIZZLE && PMA_MYSQL_INT_VERSION < 50600]
+	have_innodb
+	value != "YES"
+	You do not have InnoDB enabled.
+	InnoDB is usually the better choice for table engines.
+	have_innodb is set to 'value'
+
+rule 'InnoDB log size' [innodb_buffer_pool_size > 0]
+	innodb_log_file_size / innodb_buffer_pool_size * 100
+	value < 20 && innodb_log_file_size / (1024 * 1024) < 256
+	The InnoDB log file size is not an appropriate size, in relation to the InnoDB buffer pool.
+	Especially on a system with a lot of writes to InnoDB tables you should set {innodb_log_file_size} to 25% of {innodb_buffer_pool_size}. However the bigger this value, the longer the recovery time will be when database crashes, so this value should not be set much higher than 256 MiB. Please note however that you cannot simply change the value of this variable. You need to shutdown the server, remove the InnoDB log files, set the new value in my.cnf, start the server, then check the erro [...]
+	Your InnoDB log size is at %s% in relation to the InnoDB buffer pool size, it should not be below 20% | round(value,1)
+
+rule 'Max InnoDB log size' [innodb_buffer_pool_size > 0 && innodb_log_file_size / innodb_buffer_pool_size * 100 < 30]
+	innodb_log_file_size / (1024 * 1024)
+	value > 256
+	The InnoDB log file size is inadequately large.
+	It is usually sufficient to set {innodb_log_file_size} to 25% of the size of {innodb_buffer_pool_size}. A very big {innodb_log_file_size} slows down the recovery time after a database crash considerably. See also <a href="http://www.mysqlperformanceblog.com/2006/07/03/choosing-proper-innodb_log_file_size/">this Article</a>. You need to shutdown the server, remove the InnoDB log files, set the new value in my.cnf, start the server, then check the error logs if everything went fine. See a [...]
+	Your absolute InnoDB log size is %s MiB | round(value,1)
+
+rule 'InnoDB buffer pool size' [system_memory > 0]
+	innodb_buffer_pool_size / system_memory * 100
+	value < 60
+	Your InnoDB buffer pool is fairly small.
+	The InnoDB buffer pool has a profound impact on performance for InnoDB tables. Assign all your remaining memory to this buffer. For database servers that use solely InnoDB as storage engine and have no other services (e.g. a web server) running, you may set this as high as 80% of your available memory. If that is not the case, you need to carefully assess the memory consumption of your other services and non-InnoDB-Tables and set this variable accordingly. If it is set too high, your sy [...]
+	You are currently using %s% of your memory for the InnoDB buffer pool. This rule fires if you are assigning less than 60%, however this might be perfectly adequate for your system if you don't have much InnoDB tables or other services running on the same machine. | value
+
+#
+# other
+rule 'MyISAM concurrent inserts' [!PMA_DRIZZLE]
+	concurrent_insert
+	value === 0 || value === 'NEVER'
+	Enable {concurrent_insert} by setting it to 1
+	Setting {concurrent_insert} to 1 reduces contention between readers and writers for a given table. See also <a href="http://dev.mysql.com/doc/refman/5.5/en/concurrent-inserts.html">MySQL Documentation</a>
+	concurrent_insert is set to 0
+
+# INSERT DELAYED USAGE
+#Delayed_errors 0
+#Delayed_insert_threads 0
+#Delayed_writes 0
+#Not_flushed_delayed_rows
diff --git a/phpmyadmin/libraries/bfShapeFiles/ShapeFile.lib.php b/phpmyadmin/libraries/bfShapeFiles/ShapeFile.lib.php
new file mode 100644
index 0000000..56057d2
--- /dev/null
+++ b/phpmyadmin/libraries/bfShapeFiles/ShapeFile.lib.php
@@ -0,0 +1,666 @@
+<?php
+/**
+ * BytesFall ShapeFiles library
+ *
+ * The library implements the 2D variants of the ShapeFile format as defined in
+ * http://www.esri.com/library/whitepapers/pdfs/shapefile.pdf.
+ * The library currently supports reading and editing of ShapeFiles and the
+ * Associated information (DBF file).
+ *
+ * @package bfShapeFiles
+ * @version 0.0.2
+ * @link http://bfshapefiles.sourceforge.net/
+ * @license http://www.gnu.org/copyleft/gpl.html GPLv2
+ */
+  function loadData($type, $data) {
+    if (!$data) return $data;
+    $tmp = unpack($type, $data);
+    return current($tmp);
+  }
+
+  function swap($binValue) {
+    $result = $binValue{strlen($binValue) - 1};
+    for($i = strlen($binValue) - 2; $i >= 0 ; $i--) {
+      $result .= $binValue{$i};
+    }
+
+    return $result;
+  }
+
+  function packDouble($value, $mode = 'LE') {
+    $value = (double)$value;
+    $bin = pack("d", $value);
+
+    //We test if the conversion of an integer (1) is done as LE or BE by default
+    switch (pack ('L', 1)) {
+      case pack ('V', 1): //Little Endian
+        $result = ($mode == 'LE') ? $bin : swap($bin);
+      break;
+      case pack ('N', 1): //Big Endian
+        $result = ($mode == 'BE') ? $bin : swap($bin);
+      break;
+      default: //Some other thing, we just return false
+        $result = FALSE;
+    }
+
+    return $result;
+  }
+/**
+ * ShapeFile class
+ *
+ * @package bfShapeFiles
+ */
+  class ShapeFile {
+    var $FileName;
+
+    var $SHPFile;
+    var $SHXFile;
+    var $DBFFile;
+
+    var $DBFHeader;
+
+    var $lastError = "";
+
+    var $boundingBox = array("xmin" => 0.0, "ymin" => 0.0, "xmax" => 0.0, "ymax" => 0.0);
+    var $fileLength = 0;
+    var $shapeType = 0;
+
+    var $records;
+
+    function ShapeFile($shapeType, $boundingBox = array("xmin" => 0.0, "ymin" => 0.0, "xmax" => 0.0, "ymax" => 0.0), $FileName = NULL) {
+      $this->shapeType = $shapeType;
+      $this->boundingBox = $boundingBox;
+      $this->FileName = $FileName;
+      $this->fileLength = 50;
+    }
+
+    function loadFromFile($FileName) {
+      $this->FileName = $FileName;
+
+      if (($this->_openSHPFile()) && ($this->_openDBFFile())) {
+        $this->_loadHeaders();
+        $this->_loadRecords();
+        $this->_closeSHPFile();
+        $this->_closeDBFFile();
+      } else {
+        return false;
+      }
+    }
+
+    function saveToFile($FileName = NULL) {
+      if ($FileName != NULL) $this->FileName = $FileName;
+
+      if (($this->_openSHPFile(TRUE)) && ($this->_openSHXFile(TRUE)) && ($this->_openDBFFile(TRUE))) {
+        $this->_saveHeaders();
+        $this->_saveRecords();
+        $this->_closeSHPFile();
+        $this->_closeSHXFile();
+        $this->_closeDBFFile();
+      } else {
+        return false;
+      }
+    }
+
+    function addRecord($record) {
+      if ((isset($this->DBFHeader)) && (is_array($this->DBFHeader))) {
+        $record->updateDBFInfo($this->DBFHeader);
+      }
+
+      $this->fileLength += ($record->getContentLength() + 4);
+      $this->records[] = $record;
+      $this->records[count($this->records) - 1]->recordNumber = count($this->records);
+
+      return (count($this->records) - 1);
+    }
+
+    function deleteRecord($index) {
+      if (isset($this->records[$index])) {
+        $this->fileLength -= ($this->records[$index]->getContentLength() + 4);
+        for ($i = $index; $i < (count($this->records) - 1); $i++) {
+          $this->records[$i] = $this->records[$i + 1];
+        }
+        unset($this->records[count($this->records) - 1]);
+        $this->_deleteRecordFromDBF($index);
+      }
+    }
+
+    function getDBFHeader() {
+      return $this->DBFHeader;
+    }
+
+    function setDBFHeader($header) {
+      $this->DBFHeader = $header;
+
+      for ($i = 0; $i < count($this->records); $i++) {
+        $this->records[$i]->updateDBFInfo($header);
+      }
+    }
+
+    function getIndexFromDBFData($field, $value) {
+      $result = -1;
+      for ($i = 0; $i < (count($this->records) - 1); $i++) {
+        if (isset($this->records[$i]->DBFData[$field]) && (strtoupper($this->records[$i]->DBFData[$field]) == strtoupper($value))) {
+          $result = $i;
+        }
+      }
+
+      return $result;
+    }
+
+    function _loadDBFHeader() {
+      $DBFFile = fopen(str_replace('.*', '.dbf', $this->FileName), 'r');
+
+      $result = array();
+      $buff32 = array();
+      $i = 1;
+      $inHeader = true;
+
+      while ($inHeader) {
+        if (!feof($DBFFile)) {
+          $buff32 = fread($DBFFile, 32);
+          if ($i > 1) {
+            if (substr($buff32, 0, 1) == chr(13)) {
+              $inHeader = false;
+            } else {
+              $pos = strpos(substr($buff32, 0, 10), chr(0));
+              $pos = ($pos == 0 ? 10 : $pos);
+
+              $fieldName = substr($buff32, 0, $pos);
+              $fieldType = substr($buff32, 11, 1);
+              $fieldLen = ord(substr($buff32, 16, 1));
+              $fieldDec = ord(substr($buff32, 17, 1));
+
+              array_push($result, array($fieldName, $fieldType, $fieldLen, $fieldDec));
+            }
+          }
+          $i++;
+        } else {
+          $inHeader = false;
+        }
+      }
+
+      fclose($DBFFile);
+      return($result);
+    }
+
+    function _deleteRecordFromDBF($index) {
+      if (@dbase_delete_record($this->DBFFile, $index)) {
+        @dbase_pack($this->DBFFile);
+      }
+    }
+
+    function _loadHeaders() {
+      fseek($this->SHPFile, 24, SEEK_SET);
+      $this->fileLength = loadData("N", fread($this->SHPFile, 4));
+
+      fseek($this->SHPFile, 32, SEEK_SET);
+      $this->shapeType = loadData("V", fread($this->SHPFile, 4));
+
+      $this->boundingBox = array();
+      $this->boundingBox["xmin"] = loadData("d", fread($this->SHPFile, 8));
+      $this->boundingBox["ymin"] = loadData("d", fread($this->SHPFile, 8));
+      $this->boundingBox["xmax"] = loadData("d", fread($this->SHPFile, 8));
+      $this->boundingBox["ymax"] = loadData("d", fread($this->SHPFile, 8));
+
+      $this->DBFHeader = $this->_loadDBFHeader();
+    }
+
+    function _saveHeaders() {
+      fwrite($this->SHPFile, pack("NNNNNN", 9994, 0, 0, 0, 0, 0));
+      fwrite($this->SHPFile, pack("N", $this->fileLength));
+      fwrite($this->SHPFile, pack("V", 1000));
+      fwrite($this->SHPFile, pack("V", $this->shapeType));
+      fwrite($this->SHPFile, packDouble($this->boundingBox['xmin']));
+      fwrite($this->SHPFile, packDouble($this->boundingBox['ymin']));
+      fwrite($this->SHPFile, packDouble($this->boundingBox['xmax']));
+      fwrite($this->SHPFile, packDouble($this->boundingBox['ymax']));
+      fwrite($this->SHPFile, pack("dddd", 0, 0, 0, 0));
+
+      fwrite($this->SHXFile, pack("NNNNNN", 9994, 0, 0, 0, 0, 0));
+      fwrite($this->SHXFile, pack("N", 50 + 4*count($this->records)));
+      fwrite($this->SHXFile, pack("V", 1000));
+      fwrite($this->SHXFile, pack("V", $this->shapeType));
+      fwrite($this->SHXFile, packDouble($this->boundingBox['xmin']));
+      fwrite($this->SHXFile, packDouble($this->boundingBox['ymin']));
+      fwrite($this->SHXFile, packDouble($this->boundingBox['xmax']));
+      fwrite($this->SHXFile, packDouble($this->boundingBox['ymax']));
+      fwrite($this->SHXFile, pack("dddd", 0, 0, 0, 0));
+    }
+
+    function _loadRecords() {
+      fseek($this->SHPFile, 100);
+      while (!feof($this->SHPFile)) {
+        $bByte = ftell($this->SHPFile);
+        $record = new ShapeRecord(-1);
+        $record->loadFromFile($this->SHPFile, $this->DBFFile);
+        $eByte = ftell($this->SHPFile);
+        if (($eByte <= $bByte) || ($record->lastError != "")) {
+          return false;
+        }
+
+        $this->records[] = $record;
+      }
+    }
+
+    function _saveRecords() {
+      if (file_exists(str_replace('.*', '.dbf', $this->FileName))) {
+        @unlink(str_replace('.*', '.dbf', $this->FileName));
+      }
+      if (!($this->DBFFile = @dbase_create(str_replace('.*', '.dbf', $this->FileName), $this->DBFHeader))) {
+        return $this->setError(sprintf("It wasn't possible to create the DBase file '%s'", str_replace('.*', '.dbf', $this->FileName)));
+      }
+
+      $offset = 50;
+      if (is_array($this->records) && (count($this->records) > 0)) {
+        reset($this->records);
+        while (list($index, $record) = each($this->records)) {
+          //Save the record to the .shp file
+          $record->saveToFile($this->SHPFile, $this->DBFFile, $index + 1);
+
+          //Save the record to the .shx file
+          fwrite($this->SHXFile, pack("N", $offset));
+          fwrite($this->SHXFile, pack("N", $record->getContentLength()));
+          $offset += (4 + $record->getContentLength());
+        }
+      }
+      @dbase_pack($this->DBFFile);
+    }
+
+    function _openSHPFile($toWrite = false) {
+      $this->SHPFile = @fopen(str_replace('.*', '.shp', $this->FileName), ($toWrite ? "wb+" : "rb"));
+      if (!$this->SHPFile) {
+        return $this->setError(sprintf("It wasn't possible to open the Shape file '%s'", str_replace('.*', '.shp', $this->FileName)));
+      }
+
+      return TRUE;
+    }
+
+    function _closeSHPFile() {
+      if ($this->SHPFile) {
+        fclose($this->SHPFile);
+        $this->SHPFile = NULL;
+      }
+    }
+
+    function _openSHXFile($toWrite = false) {
+      $this->SHXFile = @fopen(str_replace('.*', '.shx', $this->FileName), ($toWrite ? "wb+" : "rb"));
+      if (!$this->SHXFile) {
+        return $this->setError(sprintf("It wasn't possible to open the Index file '%s'", str_replace('.*', '.shx', $this->FileName)));
+      }
+
+      return TRUE;
+    }
+
+    function _closeSHXFile() {
+      if ($this->SHXFile) {
+        fclose($this->SHXFile);
+        $this->SHXFile = NULL;
+      }
+    }
+
+    function _openDBFFile($toWrite = false) {
+      $checkFunction = $toWrite ? "is_writable" : "is_readable";
+      if (($toWrite) && (!file_exists(str_replace('.*', '.dbf', $this->FileName)))) {
+        if (!@dbase_create(str_replace('.*', '.dbf', $this->FileName), $this->DBFHeader)) {
+          return $this->setError(sprintf("It wasn't possible to create the DBase file '%s'", str_replace('.*', '.dbf', $this->FileName)));
+        }
+      }
+      if ($checkFunction(str_replace('.*', '.dbf', $this->FileName))) {
+        $this->DBFFile = dbase_open(str_replace('.*', '.dbf', $this->FileName), ($toWrite ? 2 : 0));
+        if (!$this->DBFFile) {
+          return $this->setError(sprintf("It wasn't possible to open the DBase file '%s'", str_replace('.*', '.dbf', $this->FileName)));
+        }
+      } else {
+        return $this->setError(sprintf("It wasn't possible to find the DBase file '%s'", str_replace('.*', '.dbf', $this->FileName)));
+      }
+      return TRUE;
+    }
+
+    function _closeDBFFile() {
+      if ($this->DBFFile) {
+        dbase_close($this->DBFFile);
+        $this->DBFFile = NULL;
+      }
+    }
+
+    function setError($error) {
+      $this->lastError = $error;
+      return false;
+    }
+  }
+
+  class ShapeRecord {
+    var $SHPFile = NULL;
+    var $DBFFile = NULL;
+
+    var $recordNumber = NULL;
+    var $shapeType = NULL;
+
+    var $lastError = "";
+
+    var $SHPData = array();
+    var $DBFData = array();
+
+    function ShapeRecord($shapeType) {
+      $this->shapeType = $shapeType;
+    }
+
+    function loadFromFile(&$SHPFile, &$DBFFile) {
+      $this->SHPFile = $SHPFile;
+      $this->DBFFile = $DBFFile;
+      $this->_loadHeaders();
+
+      switch ($this->shapeType) {
+        case 0:
+          $this->_loadNullRecord();
+        break;
+        case 1:
+          $this->_loadPointRecord();
+        break;
+        case 3:
+          $this->_loadPolyLineRecord();
+        break;
+        case 5:
+          $this->_loadPolygonRecord();
+        break;
+        case 8:
+          $this->_loadMultiPointRecord();
+        break;
+        default:
+          $this->setError(sprintf("The Shape Type '%s' is not supported.", $this->shapeType));
+        break;
+      }
+      $this->_loadDBFData();
+    }
+
+    function saveToFile(&$SHPFile, &$DBFFile, $recordNumber) {
+      $this->SHPFile = $SHPFile;
+      $this->DBFFile = $DBFFile;
+      $this->recordNumber = $recordNumber;
+      $this->_saveHeaders();
+
+      switch ($this->shapeType) {
+        case 0:
+          $this->_saveNullRecord();
+        break;
+        case 1:
+          $this->_savePointRecord();
+        break;
+        case 3:
+          $this->_savePolyLineRecord();
+        break;
+        case 5:
+          $this->_savePolygonRecord();
+        break;
+        case 8:
+          $this->_saveMultiPointRecord();
+        break;
+        default:
+          $this->setError(sprintf("The Shape Type '%s' is not supported.", $this->shapeType));
+        break;
+      }
+      $this->_saveDBFData();
+    }
+
+    function updateDBFInfo($header) {
+      $tmp = $this->DBFData;
+      unset($this->DBFData);
+      $this->DBFData = array();
+      reset($header);
+      while (list($key, $value) = each($header)) {
+        $this->DBFData[$value[0]] = (isset($tmp[$value[0]])) ? $tmp[$value[0]] : "";
+      }
+    }
+
+    function _loadHeaders() {
+      $this->recordNumber = loadData("N", fread($this->SHPFile, 4));
+      $tmp = loadData("N", fread($this->SHPFile, 4)); //We read the length of the record
+      $this->shapeType = loadData("V", fread($this->SHPFile, 4));
+    }
+
+    function _saveHeaders() {
+      fwrite($this->SHPFile, pack("N", $this->recordNumber));
+      fwrite($this->SHPFile, pack("N", $this->getContentLength()));
+      fwrite($this->SHPFile, pack("V", $this->shapeType));
+    }
+
+    function _loadPoint() {
+      $data = array();
+
+      $data["x"] = loadData("d", fread($this->SHPFile, 8));
+      $data["y"] = loadData("d", fread($this->SHPFile, 8));
+
+      return $data;
+    }
+
+    function _savePoint($data) {
+      fwrite($this->SHPFile, packDouble($data["x"]));
+      fwrite($this->SHPFile, packDouble($data["y"]));
+    }
+
+    function _loadNullRecord() {
+      $this->SHPData = array();
+    }
+
+    function _saveNullRecord() {
+      //Don't save anything
+    }
+
+    function _loadPointRecord() {
+      $this->SHPData = $this->_loadPoint();
+    }
+
+    function _savePointRecord() {
+      $this->_savePoint($this->SHPData);
+    }
+
+    function _loadMultiPointRecord() {
+      $this->SHPData = array();
+      $this->SHPData["xmin"] = loadData("d", fread($this->SHPFile, 8));
+      $this->SHPData["ymin"] = loadData("d", fread($this->SHPFile, 8));
+      $this->SHPData["xmax"] = loadData("d", fread($this->SHPFile, 8));
+      $this->SHPData["ymax"] = loadData("d", fread($this->SHPFile, 8));
+
+      $this->SHPData["numpoints"] = loadData("V", fread($this->SHPFile, 4));
+
+      for ($i = 0; $i <= $this->SHPData["numpoints"]; $i++) {
+        $this->SHPData["points"][] = $this->_loadPoint();
+      }
+    }
+
+    function _saveMultiPointRecord() {
+      fwrite($this->SHPFile, pack("dddd", $this->SHPData["xmin"], $this->SHPData["ymin"], $this->SHPData["xmax"], $this->SHPData["ymax"]));
+
+      fwrite($this->SHPFile, pack("V", $this->SHPData["numpoints"]));
+
+      for ($i = 0; $i <= $this->SHPData["numpoints"]; $i++) {
+        $this->_savePoint($this->SHPData["points"][$i]);
+      }
+    }
+
+    function _loadPolyLineRecord() {
+      $this->SHPData = array();
+      $this->SHPData["xmin"] = loadData("d", fread($this->SHPFile, 8));
+      $this->SHPData["ymin"] = loadData("d", fread($this->SHPFile, 8));
+      $this->SHPData["xmax"] = loadData("d", fread($this->SHPFile, 8));
+      $this->SHPData["ymax"] = loadData("d", fread($this->SHPFile, 8));
+
+      $this->SHPData["numparts"]  = loadData("V", fread($this->SHPFile, 4));
+      $this->SHPData["numpoints"] = loadData("V", fread($this->SHPFile, 4));
+
+      for ($i = 0; $i < $this->SHPData["numparts"]; $i++) {
+        $this->SHPData["parts"][$i] = loadData("V", fread($this->SHPFile, 4));
+      }
+
+      $firstIndex = ftell($this->SHPFile);
+      $readPoints = 0;
+      reset($this->SHPData["parts"]);
+      while (list($partIndex, $partData) = each($this->SHPData["parts"])) {
+        if (!isset($this->SHPData["parts"][$partIndex]["points"]) || !is_array($this->SHPData["parts"][$partIndex]["points"])) {
+          $this->SHPData["parts"][$partIndex] = array();
+          $this->SHPData["parts"][$partIndex]["points"] = array();
+        }
+        while (!in_array($readPoints, $this->SHPData["parts"]) && ($readPoints < ($this->SHPData["numpoints"])) && !feof($this->SHPFile)) {
+          $this->SHPData["parts"][$partIndex]["points"][] = $this->_loadPoint();
+          $readPoints++;
+        }
+      }
+
+      fseek($this->SHPFile, $firstIndex + ($readPoints*16));
+    }
+
+    function _savePolyLineRecord() {
+      fwrite($this->SHPFile, pack("dddd", $this->SHPData["xmin"], $this->SHPData["ymin"], $this->SHPData["xmax"], $this->SHPData["ymax"]));
+
+      fwrite($this->SHPFile, pack("VV", $this->SHPData["numparts"], $this->SHPData["numpoints"]));
+
+      for ($i = 0; $i < $this->SHPData["numparts"]; $i++) {
+        fwrite($this->SHPFile, pack("V", count($this->SHPData["parts"][$i])));
+      }
+
+      reset($this->SHPData["parts"]);
+      foreach ($this->SHPData["parts"] as $partData){
+        reset($partData["points"]);
+        while (list($pointIndex, $pointData) = each($partData["points"])) {
+          $this->_savePoint($pointData);
+        }
+      }
+    }
+
+    function _loadPolygonRecord() {
+      $this->_loadPolyLineRecord();
+    }
+
+    function _savePolygonRecord() {
+      $this->_savePolyLineRecord();
+    }
+
+    function addPoint($point, $partIndex = 0) {
+      switch ($this->shapeType) {
+        case 0:
+          //Don't add anything
+        break;
+        case 1:
+          //Substitutes the value of the current point
+          $this->SHPData = $point;
+        break;
+        case 3:
+        case 5:
+          //Adds a new point to the selected part
+          if (!isset($this->SHPData["xmin"]) || ($this->SHPData["xmin"] > $point["x"])) $this->SHPData["xmin"] = $point["x"];
+          if (!isset($this->SHPData["ymin"]) || ($this->SHPData["ymin"] > $point["y"])) $this->SHPData["ymin"] = $point["y"];
+          if (!isset($this->SHPData["xmax"]) || ($this->SHPData["xmax"] < $point["x"])) $this->SHPData["xmax"] = $point["x"];
+          if (!isset($this->SHPData["ymax"]) || ($this->SHPData["ymax"] < $point["y"])) $this->SHPData["ymax"] = $point["y"];
+
+          $this->SHPData["parts"][$partIndex]["points"][] = $point;
+
+          $this->SHPData["numparts"] = count($this->SHPData["parts"]);
+          $this->SHPData["numpoints"]++;
+        break;
+        case 8:
+          //Adds a new point
+          if (!isset($this->SHPData["xmin"]) || ($this->SHPData["xmin"] > $point["x"])) $this->SHPData["xmin"] = $point["x"];
+          if (!isset($this->SHPData["ymin"]) || ($this->SHPData["ymin"] > $point["y"])) $this->SHPData["ymin"] = $point["y"];
+          if (!isset($this->SHPData["xmax"]) || ($this->SHPData["xmax"] < $point["x"])) $this->SHPData["xmax"] = $point["x"];
+          if (!isset($this->SHPData["ymax"]) || ($this->SHPData["ymax"] < $point["y"])) $this->SHPData["ymax"] = $point["y"];
+
+          $this->SHPData["points"][] = $point;
+          $this->SHPData["numpoints"]++;
+        break;
+        default:
+          $this->setError(sprintf("The Shape Type '%s' is not supported.", $this->shapeType));
+        break;
+      }
+    }
+
+    function deletePoint($pointIndex = 0, $partIndex = 0) {
+      switch ($this->shapeType) {
+        case 0:
+          //Don't delete anything
+        break;
+        case 1:
+          //Sets the value of the point to zero
+          $this->SHPData["x"] = 0.0;
+          $this->SHPData["y"] = 0.0;
+        break;
+        case 3:
+        case 5:
+          //Deletes the point from the selected part, if exists
+          if (isset($this->SHPData["parts"][$partIndex]) && isset($this->SHPData["parts"][$partIndex]["points"][$pointIndex])) {
+            for ($i = $pointIndex; $i < (count($this->SHPData["parts"][$partIndex]["points"]) - 1); $i++) {
+              $this->SHPData["parts"][$partIndex]["points"][$i] = $this->SHPData["parts"][$partIndex]["points"][$i + 1];
+            }
+            unset($this->SHPData["parts"][$partIndex]["points"][count($this->SHPData["parts"][$partIndex]["points"]) - 1]);
+
+            $this->SHPData["numparts"] = count($this->SHPData["parts"]);
+            $this->SHPData["numpoints"]--;
+          }
+        break;
+        case 8:
+          //Deletes the point, if exists
+          if (isset($this->SHPData["points"][$pointIndex])) {
+            for ($i = $pointIndex; $i < (count($this->SHPData["points"]) - 1); $i++) {
+              $this->SHPData["points"][$i] = $this->SHPData["points"][$i + 1];
+            }
+            unset($this->SHPData["points"][count($this->SHPData["points"]) - 1]);
+
+            $this->SHPData["numpoints"]--;
+          }
+        break;
+        default:
+          $this->setError(sprintf("The Shape Type '%s' is not supported.", $this->shapeType));
+        break;
+      }
+    }
+
+    function getContentLength() {
+      switch ($this->shapeType) {
+        case 0:
+          $result = 0;
+        break;
+        case 1:
+          $result = 10;
+        break;
+        case 3:
+        case 5:
+          $result = 22 + 2*count($this->SHPData["parts"]);
+          for ($i = 0; $i < count($this->SHPData["parts"]); $i++) {
+            $result += 8*count($this->SHPData["parts"][$i]["points"]);
+          }
+        break;
+        case 8:
+          $result = 20 + 8*count($this->SHPData["points"]);
+        break;
+        default:
+          $result = false;
+          $this->setError(sprintf("The Shape Type '%s' is not supported.", $this->shapeType));
+        break;
+      }
+      return $result;
+    }
+
+    function _loadDBFData() {
+      $this->DBFData = @dbase_get_record_with_names($this->DBFFile, $this->recordNumber);
+      unset($this->DBFData["deleted"]);
+    }
+
+    function _saveDBFData() {
+      unset($this->DBFData["deleted"]);
+      if ($this->recordNumber <= dbase_numrecords($this->DBFFile)) {
+        if (!dbase_replace_record($this->DBFFile, array_values($this->DBFData), $this->recordNumber)) {
+          $this->setError("I wasn't possible to update the information in the DBF file.");
+        }
+      } else {
+        if (!dbase_add_record($this->DBFFile, array_values($this->DBFData))) {
+          $this->setError("I wasn't possible to add the information to the DBF file.");
+        }
+      }
+    }
+
+    function setError($error) {
+      $this->lastError = $error;
+      return false;
+    }
+  }
+
+?>
diff --git a/phpmyadmin/libraries/bookmark.lib.php b/phpmyadmin/libraries/bookmark.lib.php
new file mode 100644
index 0000000..9f3d52f
--- /dev/null
+++ b/phpmyadmin/libraries/bookmark.lib.php
@@ -0,0 +1,208 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * Set of functions used with the bookmark feature
+ *
+ * @package PhpMyAdmin
+ */
+if (! defined('PHPMYADMIN')) {
+    exit;
+}
+
+/**
+ * Defines the bookmark parameters for the current user
+ *
+ * @return array    the bookmark parameters for the current user
+ * @access  public
+ */
+function PMA_Bookmark_getParams()
+{
+    static $cfgBookmark = null;
+
+    if (null !== $cfgBookmark) {
+        return $cfgBookmark;
+    }
+
+    $cfgRelation = PMA_getRelationsParam();
+
+    if ($cfgRelation['bookmarkwork']) {
+        $cfgBookmark = array(
+            'user'  => $GLOBALS['cfg']['Server']['user'],
+            'db'    => $GLOBALS['cfg']['Server']['pmadb'],
+            'table' => $GLOBALS['cfg']['Server']['bookmarktable'],
+        );
+    } else {
+        $cfgBookmark = false;
+    }
+
+    return $cfgBookmark;
+} // end of the 'PMA_Bookmark_getParams()' function
+
+
+/**
+ * Gets the list of bookmarks defined for the current database
+ *
+ * @param string $db the current database name
+ *
+ * @return array the bookmarks list (key as index, label as value)
+ *
+ * @access public
+ *
+ * @global resource the controluser db connection handle
+ */
+function PMA_Bookmark_getList($db)
+{
+    global $controllink;
+
+    $cfgBookmark = PMA_Bookmark_getParams();
+
+    if (empty($cfgBookmark)) {
+        return array();
+    }
+
+    $query  = 'SELECT label, id FROM '. PMA_Util::backquote($cfgBookmark['db'])
+        . '.' . PMA_Util::backquote($cfgBookmark['table'])
+        . ' WHERE dbase = \'' . PMA_Util::sqlAddSlashes($db) . '\''
+        . ' AND user = \'' . PMA_Util::sqlAddSlashes($cfgBookmark['user']) . '\''
+        . ' ORDER BY label';
+    $per_user = PMA_DBI_fetch_result(
+        $query, 'id', 'label', $controllink, PMA_DBI_QUERY_STORE
+    );
+
+    $query  = 'SELECT label, id FROM '. PMA_Util::backquote($cfgBookmark['db'])
+        . '.' . PMA_Util::backquote($cfgBookmark['table'])
+        . ' WHERE dbase = \'' . PMA_Util::sqlAddSlashes($db) . '\''
+        . ' AND user = \'\''
+        . ' ORDER BY label';
+    $global = PMA_DBI_fetch_result(
+        $query, 'id', 'label', $controllink, PMA_DBI_QUERY_STORE
+    );
+
+    foreach ($global as $key => $val) {
+        $global[$key] = $val . ' (' . __('shared') . ')';
+    }
+
+    $ret = $global + $per_user;
+
+    asort($ret);
+
+    return $ret;
+} // end of the 'PMA_Bookmark_getList()' function
+
+
+/**
+ * Gets the sql command from a bookmark
+ *
+ * @param string  $db                  the current database name
+ * @param mixed   $id                  the id of the bookmark to get
+ * @param string  $id_field            which field to look up the $id
+ * @param boolean $action_bookmark_all true: get all bookmarks regardless
+ *                                     of the owning user
+ * @param boolean $exact_user_match    whether to ignore bookmarks with no user
+ *
+ * @return string    the sql query
+ *
+ * @access  public
+ *
+ * @global  resource  the controluser db connection handle
+ *
+ */
+function PMA_Bookmark_get($db, $id, $id_field = 'id', $action_bookmark_all = false,
+    $exact_user_match = false
+) {
+    global $controllink;
+
+    $cfgBookmark = PMA_Bookmark_getParams();
+
+    if (empty($cfgBookmark)) {
+        return '';
+    }
+
+    $query = 'SELECT query FROM ' . PMA_Util::backquote($cfgBookmark['db'])
+        . '.' . PMA_Util::backquote($cfgBookmark['table'])
+        . ' WHERE dbase = \'' . PMA_Util::sqlAddSlashes($db) . '\'';
+
+    if (!$action_bookmark_all) {
+        $query .= ' AND (user = \'' . PMA_Util::sqlAddSlashes($cfgBookmark['user']) . '\'';
+        if (!$exact_user_match) {
+            $query .= ' OR user = \'\'';
+        }
+        $query .= ')';
+    }
+
+    $query .= ' AND ' . PMA_Util::backquote($id_field) . ' = ' . $id;
+
+    return PMA_DBI_fetch_value($query, 0, 0, $controllink);
+} // end of the 'PMA_Bookmark_get()' function
+
+/**
+ * Adds a bookmark
+ *
+ * @param array   $fields    the properties of the bookmark to add; here,
+ *                           $fields['query'] is urlencoded
+ * @param boolean $all_users whether to make the bookmark available for all users
+ *
+ * @return boolean   whether the INSERT succeeds or not
+ *
+ * @access  public
+ *
+ * @global  resource  the controluser db connection handle
+ */
+function PMA_Bookmark_save($fields, $all_users = false)
+{
+    global $controllink;
+
+    $cfgBookmark = PMA_Bookmark_getParams();
+
+    if (empty($cfgBookmark)) {
+        return false;
+    }
+
+    $query = 'INSERT INTO ' . PMA_Util::backquote($cfgBookmark['db'])
+        . '.' . PMA_Util::backquote($cfgBookmark['table'])
+        . ' (id, dbase, user, query, label)'
+        . ' VALUES (NULL, \'' . PMA_Util::sqlAddSlashes($fields['dbase']) . '\', '
+        . '\'' . ($all_users ? '' : PMA_Util::sqlAddSlashes($fields['user'])) . '\', '
+        . '\'' . PMA_Util::sqlAddSlashes(urldecode($fields['query'])) . '\', '
+        . '\'' . PMA_Util::sqlAddSlashes($fields['label']) . '\')';
+    return PMA_DBI_query($query, $controllink);
+} // end of the 'PMA_Bookmark_save()' function
+
+
+/**
+ * Deletes a bookmark
+ *
+ * @param string  $db the current database name
+ * @param integer $id the id of the bookmark to get
+ *
+ * @return bool true if successful
+ *
+ * @access  public
+ *
+ * @global  resource  the controluser db connection handle
+ */
+function PMA_Bookmark_delete($db, $id)
+{
+    global $controllink;
+
+    $cfgBookmark = PMA_Bookmark_getParams();
+
+    if (empty($cfgBookmark)) {
+        return false;
+    }
+
+    $query  = 'DELETE FROM ' . PMA_Util::backquote($cfgBookmark['db'])
+        . '.' . PMA_Util::backquote($cfgBookmark['table'])
+        . ' WHERE (user = \'' . PMA_Util::sqlAddSlashes($cfgBookmark['user']) . '\''
+        . '        OR user = \'\')'
+        . ' AND id = ' . $id;
+    return PMA_DBI_try_query($query, $controllink);
+} // end of the 'PMA_Bookmark_delete()' function
+
+
+/**
+ * Bookmark Support
+ */
+$GLOBALS['cfg']['Bookmark'] = PMA_Bookmark_getParams();
+
+?>
diff --git a/phpmyadmin/libraries/build_html_for_db.lib.php b/phpmyadmin/libraries/build_html_for_db.lib.php
new file mode 100644
index 0000000..21602cc
--- /dev/null
+++ b/phpmyadmin/libraries/build_html_for_db.lib.php
@@ -0,0 +1,180 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ *
+ * @package PhpMyAdmin
+ */
+if (! defined('PHPMYADMIN')) {
+    exit;
+}
+
+/**
+ * Prepares the $column_order array
+ *
+ * @return array
+ */
+function PMA_getColumnOrder()
+{
+
+    $column_order['DEFAULT_COLLATION_NAME'] = array(
+            'disp_name' => __('Collation'),
+            'description_function' => 'PMA_getCollationDescr',
+            'format'    => 'string',
+            'footer'    => PMA_getServerCollation(),
+        );
+    $column_order['SCHEMA_TABLES'] = array(
+        'disp_name' => __('Tables'),
+        'format'    => 'number',
+        'footer'    => 0,
+    );
+    $column_order['SCHEMA_TABLE_ROWS'] = array(
+        'disp_name' => __('Rows'),
+        'format'    => 'number',
+        'footer'    => 0,
+    );
+    $column_order['SCHEMA_DATA_LENGTH'] = array(
+        'disp_name' => __('Data'),
+        'format'    => 'byte',
+        'footer'    => 0,
+    );
+    $column_order['SCHEMA_INDEX_LENGTH'] = array(
+        'disp_name' => __('Indexes'),
+        'format'    => 'byte',
+        'footer'    => 0,
+    );
+    $column_order['SCHEMA_LENGTH'] = array(
+        'disp_name' => __('Total'),
+        'format'    => 'byte',
+        'footer'    => 0,
+    );
+    $column_order['SCHEMA_DATA_FREE'] = array(
+        'disp_name' => __('Overhead'),
+        'format'    => 'byte',
+        'footer'    => 0,
+    );
+
+    return $column_order;
+}
+
+/*
+ * Builds the HTML td elements for one database to display in the list
+ * of databases from server_databases.php (which can be modified by
+ * db_create.php)
+ *
+ * @param array   $current
+ * @param boolean $is_superuser
+ * @param string  $url_query
+ * @param array   $column_order
+ * @param array   $replication_types
+ * @param array   $replication_info
+ *
+ * @return array $column_order, $out
+ */
+function PMA_buildHtmlForDb(
+    $current, $is_superuser, $url_query,
+    $column_order, $replication_types, $replication_info
+) {
+    $out = '';
+    if ($is_superuser || $GLOBALS['cfg']['AllowUserDropDatabase']) {
+        $out .= '<td class="tool">';
+        $out .= '<input type="checkbox" name="selected_dbs[]" class="checkall" '
+            . 'title="' . htmlspecialchars($current['SCHEMA_NAME']) . '" '
+            . 'value="' . htmlspecialchars($current['SCHEMA_NAME']) . '"';
+
+        if (PMA_is_system_schema($current['SCHEMA_NAME'], true)) {
+            $out .= ' disabled="disabled"';
+        }
+        $out .= ' /></td>';
+    }
+    $out .= '<td class="name">'
+           . '<a href="' . $GLOBALS['cfg']['DefaultTabDatabase']
+           . '?' . $url_query . '&db='
+           . urlencode($current['SCHEMA_NAME']) . '" title="'
+           . sprintf(
+               __('Jump to database'),
+               htmlspecialchars($current['SCHEMA_NAME'])
+           )
+           . '">'
+           . ' ' . htmlspecialchars($current['SCHEMA_NAME'])
+           . '</a>'
+           . '</td>';
+
+    foreach ($column_order as $stat_name => $stat) {
+        if (array_key_exists($stat_name, $current)) {
+            if (is_numeric($stat['footer'])) {
+                $column_order[$stat_name]['footer'] += $current[$stat_name];
+            }
+            if ($stat['format'] === 'byte') {
+                list($value, $unit) = PMA_Util::formatByteDown(
+                    $current[$stat_name], 3, 1
+                );
+            } elseif ($stat['format'] === 'number') {
+                $value = PMA_Util::formatNumber(
+                    $current[$stat_name], 0
+                );
+            } else {
+                $value = htmlentities($current[$stat_name], 0);
+            }
+            $out .= '<td class="value">';
+            if (isset($stat['description_function'])) {
+                $out .= '<dfn title="'
+                    . $stat['description_function']($current[$stat_name]) . '">';
+            }
+            $out .= $value;
+            if (isset($stat['description_function'])) {
+                $out .= '</dfn>';
+            }
+            $out .= '</td>';
+            if ($stat['format'] === 'byte') {
+                $out .= '<td class="unit">' . $unit . '</td>';
+            }
+        }
+    }
+    foreach ($replication_types as $type) {
+        if ($replication_info[$type]['status']) {
+            $out .= '<td class="tool" style="text-align: center;">';
+
+            $key = array_search(
+                $current["SCHEMA_NAME"],
+                $replication_info[$type]['Ignore_DB']
+            );
+            if (strlen($key) > 0) {
+                $out .= PMA_Util::getIcon('s_cancel.png',  __('Not replicated'));
+            } else {
+                $key = array_search(
+                    $current["SCHEMA_NAME"], $replication_info[$type]['Do_DB']
+                );
+
+                if (strlen($key) > 0
+                    || ($replication_info[$type]['Do_DB'][0] == ""
+                    && count($replication_info[$type]['Do_DB']) == 1)
+                ) {
+                    // if ($key != null) did not work for index "0"
+                    $out .= PMA_Util::getIcon('s_success.png', __('Replicated'));
+                }
+            }
+
+            $out .= '</td>';
+        }
+    }
+
+    if ($is_superuser && !PMA_DRIZZLE) {
+        $out .= '<td class="tool">'
+               . '<a onclick="'
+               . 'PMA_commonActions.setDb(\''
+               . PMA_jsFormat($current['SCHEMA_NAME']) . '\');'
+               . '" href="server_privileges.php?' . $url_query
+               . '&checkprivs=' . urlencode($current['SCHEMA_NAME'])
+               . '" title="'
+               . sprintf(
+                   __('Check privileges for database "%s".'),
+                   htmlspecialchars($current['SCHEMA_NAME'])
+               )
+               . '">'
+               . ' '
+               . PMA_Util::getIcon('s_rights.png', __('Check Privileges'))
+               . '</a></td>';
+    }
+    return array($column_order, $out);
+}
+?>
diff --git a/phpmyadmin/libraries/charset_conversion.lib.php b/phpmyadmin/libraries/charset_conversion.lib.php
new file mode 100644
index 0000000..eccb320
--- /dev/null
+++ b/phpmyadmin/libraries/charset_conversion.lib.php
@@ -0,0 +1,97 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * Charset conversion functions.
+ *
+ * @package PhpMyAdmin
+ */
+if (! defined('PHPMYADMIN')) {
+    exit;
+}
+
+define('PMA_CHARSET_NONE', 0);
+define('PMA_CHARSET_ICONV', 1);
+define('PMA_CHARSET_RECODE', 2);
+define('PMA_CHARSET_ICONV_AIX', 3);
+
+// Finally detect which function we will use:
+if ($cfg['RecodingEngine'] == 'iconv') {
+    if (@function_exists('iconv')) {
+        if ((@stristr(PHP_OS, 'AIX'))
+            && (@strcasecmp(ICONV_IMPL, 'unknown') == 0)
+            && (@strcasecmp(ICONV_VERSION, 'unknown') == 0)
+        ) {
+            $PMA_recoding_engine = PMA_CHARSET_ICONV_AIX;
+        } else {
+            $PMA_recoding_engine = PMA_CHARSET_ICONV;
+        }
+    } else {
+        $PMA_recoding_engine = PMA_CHARSET_NONE;
+        PMA_warnMissingExtension('iconv');
+    }
+} elseif ($cfg['RecodingEngine'] == 'recode') {
+    if (@function_exists('recode_string')) {
+        $PMA_recoding_engine = PMA_CHARSET_RECODE;
+    } else {
+        $PMA_recoding_engine = PMA_CHARSET_NONE;
+        PMA_warnMissingExtension('recode');
+    }
+} elseif ($cfg['RecodingEngine'] == 'auto') {
+    if (@function_exists('iconv')) {
+        if ((@stristr(PHP_OS, 'AIX'))
+            && (@strcasecmp(ICONV_IMPL, 'unknown') == 0)
+            && (@strcasecmp(ICONV_VERSION, 'unknown') == 0)
+        ) {
+            $PMA_recoding_engine = PMA_CHARSET_ICONV_AIX;
+        } else {
+            $PMA_recoding_engine = PMA_CHARSET_ICONV;
+        }
+    } elseif (@function_exists('recode_string')) {
+        $PMA_recoding_engine = PMA_CHARSET_RECODE;
+    } else {
+        $PMA_recoding_engine = PMA_CHARSET_NONE;
+    }
+} else {
+    $PMA_recoding_engine = PMA_CHARSET_NONE;
+}
+
+/* Load AIX iconv wrapper if needed */
+if ($PMA_recoding_engine == PMA_CHARSET_ICONV_AIX) {
+    include_once './libraries/iconv_wrapper.lib.php';
+}
+
+/**
+ * Converts encoding of text according to parameters with detected
+ * conversion function.
+ *
+ * @param string $src_charset  source charset
+ * @param string $dest_charset target charset
+ * @param string $what         what to convert
+ *
+ * @return string   converted text
+ *
+ * @access  public
+ *
+ */
+function PMA_convert_string($src_charset, $dest_charset, $what)
+{
+    if ($src_charset == $dest_charset) {
+        return $what;
+    }
+    switch ($GLOBALS['PMA_recoding_engine']) {
+    case PMA_CHARSET_RECODE:
+        return recode_string($src_charset . '..'  . $dest_charset, $what);
+    case PMA_CHARSET_ICONV:
+        return iconv(
+            $src_charset, $dest_charset . $GLOBALS['cfg']['IconvExtraParams'], $what
+        );
+    case PMA_CHARSET_ICONV_AIX:
+        return PMA_aix_iconv_wrapper(
+            $src_charset, $dest_charset . $GLOBALS['cfg']['IconvExtraParams'], $what
+        );
+    default:
+        return $what;
+    }
+} //  end of the "PMA_convert_string()" function
+
+?>
diff --git a/phpmyadmin/libraries/check_user_privileges.lib.php b/phpmyadmin/libraries/check_user_privileges.lib.php
new file mode 100644
index 0000000..aba20d7
--- /dev/null
+++ b/phpmyadmin/libraries/check_user_privileges.lib.php
@@ -0,0 +1,165 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * Get user's global privileges and some db-specific privileges
+ *
+ * @package PhpMyAdmin
+ */
+if (! defined('PHPMYADMIN')) {
+    exit;
+}
+
+/**
+ *
+ */
+$GLOBALS['is_superuser'] = PMA_isSuperuser();
+
+/**
+ * sets privilege information extracted from SHOW GRANTS result
+ *
+ * Detection for some CREATE privilege.
+ *
+ * Since MySQL 4.1.2, we can easily detect current user's grants using $userlink
+ * (no control user needed) and we don't have to try any other method for
+ * detection
+ *
+ * @todo fix to get really all privileges, not only explicitly defined for this user
+ * from MySQL manual: (http://dev.mysql.com/doc/refman/5.0/en/show-grants.html)
+ * SHOW GRANTS displays only the privileges granted explicitly to the named
+ * account. Other privileges might be available to the account, but they are not
+ * displayed. For example, if an anonymous account exists, the named account
+ * might be able to use its privileges, but SHOW GRANTS will not display them.
+ *
+ * @return void
+ */
+function PMA_analyseShowGrant()
+{
+    if (PMA_Util::cacheExists('is_create_db_priv', true)) {
+        $GLOBALS['is_create_db_priv']  = PMA_Util::cacheGet('is_create_db_priv', true);
+        $GLOBALS['is_process_priv']    = PMA_Util::cacheGet('is_process_priv', true);
+        $GLOBALS['is_reload_priv']     = PMA_Util::cacheGet('is_reload_priv', true);
+        $GLOBALS['db_to_create']       = PMA_Util::cacheGet('db_to_create', true);
+        $GLOBALS['dbs_where_create_table_allowed']
+            = PMA_Util::cacheGet('dbs_where_create_table_allowed', true);
+        return;
+    }
+
+    // defaults
+    $GLOBALS['is_create_db_priv']  = false;
+    $GLOBALS['is_process_priv']    = true;
+    $GLOBALS['is_reload_priv']     = false;
+    $GLOBALS['db_to_create']       = '';
+    $GLOBALS['dbs_where_create_table_allowed'] = array();
+
+    $rs_usr = PMA_DBI_try_query('SHOW GRANTS');
+
+    if (! $rs_usr) {
+        return;
+    }
+
+    $re0 = '(^|(\\\\\\\\)+|[^\\\\])'; // non-escaped wildcards
+    $re1 = '(^|[^\\\\])(\\\)+'; // escaped wildcards
+
+    while ($row = PMA_DBI_fetch_row($rs_usr)) {
+        // extract db from GRANT ... ON *.* or GRANT ... ON db.*
+        $db_name_offset = strpos($row[0], ' ON ') + 4;
+        $show_grants_dbname = substr(
+            $row[0], $db_name_offset,
+            strpos($row[0], '.', $db_name_offset) - $db_name_offset
+        );
+        $show_grants_dbname
+            = PMA_Util::unQuote($show_grants_dbname, '`');
+
+        $show_grants_str    = substr($row[0], 6, (strpos($row[0], ' ON ') - 6));
+        if ($show_grants_str == 'RELOAD') {
+            $GLOBALS['is_reload_priv'] = true;
+        }
+
+        /**
+         * @todo if we find CREATE VIEW but not CREATE, do not offer
+         * the create database dialog box
+         */
+        if ($show_grants_str == 'ALL'
+            || $show_grants_str == 'ALL PRIVILEGES'
+            || $show_grants_str == 'CREATE'
+            || strpos($show_grants_str, 'CREATE,') !== false
+        ) {
+            if ($show_grants_dbname == '*') {
+                // a global CREATE privilege
+                $GLOBALS['is_create_db_priv'] = true;
+                $GLOBALS['is_reload_priv'] = true;
+                $GLOBALS['db_to_create']   = '';
+                $GLOBALS['dbs_where_create_table_allowed'][] = '*';
+                // @todo we should not break here, cause GRANT ALL *.*
+                // could be revoked by a later rule like GRANT SELECT ON db.*
+                break;
+            } else {
+                // this array may contain wildcards
+                $GLOBALS['dbs_where_create_table_allowed'][] = $show_grants_dbname;
+
+                $dbname_to_test = PMA_Util::backquote($show_grants_dbname);
+
+                if ($GLOBALS['is_create_db_priv']) {
+                    // no need for any more tests if we already know this
+                    continue;
+                }
+
+                // does this db exist?
+                if ((preg_match('/' . $re0 . '%|_/', $show_grants_dbname)
+                    && ! preg_match('/\\\\%|\\\\_/', $show_grants_dbname))
+                    || (! PMA_DBI_try_query('USE ' .  preg_replace('/' . $re1 . '(%|_)/', '\\1\\3', $dbname_to_test))
+                    && substr(PMA_DBI_getError(), 1, 4) != 1044)
+                ) {
+                    /**
+                     * Do not handle the underscore wildcard
+                     * (this case must be rare anyway)
+                     */
+                    $GLOBALS['db_to_create'] = preg_replace(
+                        '/' . $re0 . '%/',     '\\1...',
+                        $show_grants_dbname
+                    );
+                    $GLOBALS['db_to_create'] = preg_replace(
+                        '/' . $re1 . '(%|_)/', '\\1\\3',
+                        $GLOBALS['db_to_create']
+                    );
+                    $GLOBALS['is_create_db_priv'] = true;
+
+                    /**
+                     * @todo collect $GLOBALS['db_to_create'] into an array,
+                     * to display a drop-down in the "Create database" dialog
+                     */
+                     // we don't break, we want all possible databases
+                     //break;
+                } // end if
+            } // end elseif
+        } // end if
+    } // end while
+
+    PMA_DBI_free_result($rs_usr);
+
+    // must also cacheUnset() them in
+    // libraries/plugins/auth/AuthenticationCookie.class.php
+    PMA_Util::cacheSet('is_create_db_priv', $GLOBALS['is_create_db_priv'], true);
+    PMA_Util::cacheSet('is_process_priv', $GLOBALS['is_process_priv'], true);
+    PMA_Util::cacheSet('is_reload_priv', $GLOBALS['is_reload_priv'], true);
+    PMA_Util::cacheSet('db_to_create', $GLOBALS['db_to_create'], true);
+    PMA_Util::cacheSet(
+        'dbs_where_create_table_allowed',
+        $GLOBALS['dbs_where_create_table_allowed'],
+        true
+    );
+} // end function
+
+if (!PMA_DRIZZLE) {
+    PMA_analyseShowGrant();
+} else {
+    // todo: for simple_user_policy only database with user's login can be created
+    // (unless logged in as root)
+    $GLOBALS['is_create_db_priv'] = $GLOBALS['is_superuser'];
+    $GLOBALS['is_process_priv']   = false;
+    $GLOBALS['is_reload_priv']    = false;
+    $GLOBALS['db_to_create']      = '';
+    $GLOBALS['dbs_where_create_table_allowed'] = array('*');
+}
+
+?>
diff --git a/phpmyadmin/libraries/cleanup.lib.php b/phpmyadmin/libraries/cleanup.lib.php
new file mode 100644
index 0000000..1fdfe35
--- /dev/null
+++ b/phpmyadmin/libraries/cleanup.lib.php
@@ -0,0 +1,50 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * Functions for cleanup of user input.
+ *
+ * @package PhpMyAdmin
+ */
+if (! defined('PHPMYADMIN')) {
+    exit;
+}
+
+/**
+ * Removes all variables from request except whitelisted ones.
+ *
+ * @param string &$whitelist list of variables to allow
+ *
+ * @return void
+ * @access public
+ */
+function PMA_remove_request_vars(&$whitelist)
+{
+    // do not check only $_REQUEST because it could have been overwritten
+    // and use type casting because the variables could have become
+    // strings
+    $keys = array_keys(
+        array_merge((array)$_REQUEST, (array)$_GET, (array)$_POST, (array)$_COOKIE)
+    );
+
+    foreach ($keys as $key) {
+        if (! in_array($key, $whitelist)) {
+            unset($_REQUEST[$key], $_GET[$key], $_POST[$key], $GLOBALS[$key]);
+        } else {
+            // allowed stuff could be compromised so escape it
+            // we require it to be a string
+            if (isset($_REQUEST[$key]) && ! is_string($_REQUEST[$key])) {
+                unset($_REQUEST[$key]);
+            }
+            if (isset($_POST[$key]) && ! is_string($_POST[$key])) {
+                unset($_POST[$key]);
+            }
+            if (isset($_COOKIE[$key]) && ! is_string($_COOKIE[$key])) {
+                unset($_COOKIE[$key]);
+            }
+            if (isset($_GET[$key]) && ! is_string($_GET[$key])) {
+                unset($_GET[$key]);
+            }
+        }
+    }
+}
+?>
diff --git a/phpmyadmin/libraries/common.inc.php b/phpmyadmin/libraries/common.inc.php
new file mode 100644
index 0000000..85cf8f4
--- /dev/null
+++ b/phpmyadmin/libraries/common.inc.php
@@ -0,0 +1,1142 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * Misc stuff and REQUIRED by ALL the scripts.
+ * MUST be included by every script
+ *
+ * Among other things, it contains the advanced authentication work.
+ *
+ * Order of sections for common.inc.php:
+ *
+ * the authentication libraries must be before the connection to db
+ *
+ * ... so the required order is:
+ *
+ * LABEL_variables_init
+ *  - initialize some variables always needed
+ * LABEL_parsing_config_file
+ *  - parsing of the configuration file
+ * LABEL_loading_language_file
+ *  - loading language file
+ * LABEL_setup_servers
+ *  - check and setup configured servers
+ * LABEL_theme_setup
+ *  - setting up themes
+ *
+ * - load of MySQL extension (if necessary)
+ * - loading of an authentication library
+ * - db connection
+ * - authentication work
+ *
+ * @package PhpMyAdmin
+ */
+
+/**
+ * Minimum PHP version; can't call PMA_fatalError() which uses a
+ * PHP 5 function, so cannot easily localize this message.
+ */
+if (version_compare(PHP_VERSION, '5.2.0', 'lt')) {
+    die('PHP 5.2+ is required');
+}
+
+/**
+  * Backward compatibility for PHP 5.2
+  */
+if (!defined('E_DEPRECATED')) {
+    define('E_DEPRECATED', 8192);
+}
+
+/**
+ * the error handler
+ */
+require './libraries/Error_Handler.class.php';
+
+/**
+ * initialize the error handler
+ */
+$GLOBALS['error_handler'] = new PMA_Error_Handler();
+$cfg['Error_Handler']['display'] = true;
+
+/*
+ * This setting was removed in PHP 5.3. But at this point PMA_PHP_INT_VERSION
+ * is not yet defined so we use another way to find out the PHP version.
+ */
+if (version_compare(phpversion(), '5.3', 'lt')) {
+    /**
+     * Avoid object cloning errors
+     */
+    @ini_set('zend.ze1_compatibility_mode', false);
+}
+
+/**
+ * This setting was removed in PHP 5.4. But at this point PMA_PHP_INT_VERSION
+ * is not yet defined so we use another way to find out the PHP version.
+ */
+if (version_compare(phpversion(), '5.4', 'lt')) {
+    /**
+     * Avoid problems with magic_quotes_runtime
+     */
+    @ini_set('magic_quotes_runtime', false);
+}
+
+/**
+ * for verification in all procedural scripts under libraries
+ */
+define('PHPMYADMIN', true);
+
+/**
+ * core functions
+ */
+require './libraries/core.lib.php';
+
+/**
+ * Input sanitizing
+ */
+require './libraries/sanitizing.lib.php';
+
+/**
+ * the PMA_Theme class
+ */
+require './libraries/Theme.class.php';
+
+/**
+ * the PMA_Theme_Manager class
+ */
+require './libraries/Theme_Manager.class.php';
+
+/**
+ * the PMA_Config class
+ */
+require './libraries/Config.class.php';
+
+/**
+ * the relation lib, tracker needs it
+ */
+require './libraries/relation.lib.php';
+
+/**
+ * the PMA_Tracker class
+ */
+require './libraries/Tracker.class.php';
+
+/**
+ * the PMA_Table class
+ */
+require './libraries/Table.class.php';
+
+/**
+ * the PMA_Types class
+ */
+require './libraries/Types.class.php';
+
+if (! defined('PMA_MINIMUM_COMMON')) {
+    /**
+     * common functions
+     */
+    include_once './libraries/Util.class.php';
+
+    /**
+     * JavaScript escaping.
+     */
+    include_once './libraries/js_escape.lib.php';
+
+    /**
+     * Include URL/hidden inputs generating.
+     */
+    include_once './libraries/url_generating.lib.php';
+
+    /**
+     * Used to generate the page
+     */
+    include_once 'libraries/Response.class.php';
+}
+
+/******************************************************************************/
+/* start procedural code                       label_start_procedural         */
+
+/**
+ * PATH_INFO could be compromised if set, so remove it from PHP_SELF
+ * and provide a clean PHP_SELF here
+ */
+$PMA_PHP_SELF = PMA_getenv('PHP_SELF');
+$_PATH_INFO = PMA_getenv('PATH_INFO');
+if (! empty($_PATH_INFO) && ! empty($PMA_PHP_SELF)) {
+    $path_info_pos = strrpos($PMA_PHP_SELF, $_PATH_INFO);
+    if ($path_info_pos + strlen($_PATH_INFO) === strlen($PMA_PHP_SELF)) {
+        $PMA_PHP_SELF = substr($PMA_PHP_SELF, 0, $path_info_pos);
+    }
+}
+$PMA_PHP_SELF = htmlspecialchars($PMA_PHP_SELF);
+
+
+/**
+ * just to be sure there was no import (registering) before here
+ * we empty the global space (but avoid unsetting $variables_list
+ * and $key in the foreach (), we still need them!)
+ */
+$variables_whitelist = array (
+    'GLOBALS',
+    '_SERVER',
+    '_GET',
+    '_POST',
+    '_REQUEST',
+    '_FILES',
+    '_ENV',
+    '_COOKIE',
+    '_SESSION',
+    'error_handler',
+    'PMA_PHP_SELF',
+    'variables_whitelist',
+    'key'
+);
+
+foreach (get_defined_vars() as $key => $value) {
+    if (! in_array($key, $variables_whitelist)) {
+        unset($$key);
+    }
+}
+unset($key, $value, $variables_whitelist);
+
+
+/**
+ * Subforms - some functions need to be called by form, cause of the limited URL
+ * length, but if this functions inside another form you cannot just open a new
+ * form - so phpMyAdmin uses 'arrays' inside this form
+ *
+ * <code>
+ * <form ...>
+ * ... main form elments ...
+ * <input type="hidden" name="subform[action1][id]" value="1" />
+ * ... other subform data ...
+ * <input type="submit" name="usesubform[action1]" value="do action1" />
+ * ... other subforms ...
+ * <input type="hidden" name="subform[actionX][id]" value="X" />
+ * ... other subform data ...
+ * <input type="submit" name="usesubform[actionX]" value="do actionX" />
+ * ... main form elments ...
+ * <input type="submit" name="main_action" value="submit form" />
+ * </form>
+ * </code>
+ *
+ * so we now check if a subform is submitted
+ */
+$__redirect = null;
+if (isset($_POST['usesubform'])) {
+    // if a subform is present and should be used
+    // the rest of the form is deprecated
+    $subform_id = key($_POST['usesubform']);
+    $subform    = $_POST['subform'][$subform_id];
+    $_POST      = $subform;
+    $_REQUEST   = $subform;
+    /**
+     * some subforms need another page than the main form, so we will just
+     * include this page at the end of this script - we use $__redirect to
+     * track this
+     */
+    if (isset($_POST['redirect'])
+        && $_POST['redirect'] != basename($PMA_PHP_SELF)
+    ) {
+        $__redirect = $_POST['redirect'];
+        unset($_POST['redirect']);
+    }
+    unset($subform_id, $subform);
+} else {
+    // Note: here we overwrite $_REQUEST so that it does not contain cookies,
+    // because another application for the same domain could have set
+    // a cookie (with a compatible path) that overrides a variable
+    // we expect from GET or POST.
+    // We'll refer to cookies explicitly with the $_COOKIE syntax.
+    $_REQUEST = array_merge($_GET, $_POST);
+}
+// end check if a subform is submitted
+
+/**
+ * This setting was removed in PHP 5.4. But at this point PMA_PHP_INT_VERSION
+ * is not yet defined so we use another way to find out the PHP version.
+ */
+if (version_compare(phpversion(), '5.4', 'lt')) {
+    // remove quotes added by PHP
+    if (function_exists('get_magic_quotes_gpc') && get_magic_quotes_gpc()) {
+        PMA_arrayWalkRecursive($_GET, 'stripslashes', true);
+        PMA_arrayWalkRecursive($_POST, 'stripslashes', true);
+        PMA_arrayWalkRecursive($_COOKIE, 'stripslashes', true);
+        PMA_arrayWalkRecursive($_REQUEST, 'stripslashes', true);
+    }
+}
+
+/**
+ * check timezone setting
+ * this could produce an E_STRICT - but only once,
+ * if not done here it will produce E_STRICT on every date/time function
+ * (starting with PHP 5.3, this code can produce E_WARNING rather than
+ *  E_STRICT)
+ *
+ */
+date_default_timezone_set(@date_default_timezone_get());
+
+/******************************************************************************/
+/* parsing configuration file                  LABEL_parsing_config_file      */
+
+/**
+ * We really need this one!
+ */
+if (! function_exists('preg_replace')) {
+    PMA_warnMissingExtension('pcre', true);
+}
+
+/**
+ * JSON is required in several places.
+ */
+if (! function_exists('json_encode')) {
+    PMA_warnMissingExtension('json', true);
+}
+
+/**
+ * @global PMA_Config $GLOBALS['PMA_Config']
+ * force reading of config file, because we removed sensitive values
+ * in the previous iteration
+ */
+$GLOBALS['PMA_Config'] = new PMA_Config(CONFIG_FILE);
+
+if (!defined('PMA_MINIMUM_COMMON')) {
+    $GLOBALS['PMA_Config']->checkPmaAbsoluteUri();
+}
+
+/**
+ * BC - enable backward compatibility
+ * exports all configuration settings into $GLOBALS ($GLOBALS['cfg'])
+ */
+$GLOBALS['PMA_Config']->enableBc();
+
+/**
+ * clean cookies on upgrade
+ * when changing something related to PMA cookies, increment the cookie version
+ */
+$pma_cookie_version = 4;
+if (isset($_COOKIE)
+    && (isset($_COOKIE['pmaCookieVer'])
+    && $_COOKIE['pmaCookieVer'] < $pma_cookie_version)
+) {
+    // delete all cookies
+    foreach ($_COOKIE as $cookie_name => $tmp) {
+        $GLOBALS['PMA_Config']->removeCookie($cookie_name);
+    }
+    $_COOKIE = array();
+    $GLOBALS['PMA_Config']->setCookie('pmaCookieVer', $pma_cookie_version);
+}
+
+
+/**
+ * check HTTPS connection
+ */
+if ($GLOBALS['PMA_Config']->get('ForceSSL')
+    && ! $GLOBALS['PMA_Config']->get('is_https')
+) {
+    // grab SSL URL
+    $url = $GLOBALS['PMA_Config']->getSSLUri();
+    // Actually redirect
+    PMA_sendHeaderLocation($url . PMA_generate_common_url($_GET, 'text'));
+    // delete the current session, otherwise we get problems (see bug #2397877)
+    $GLOBALS['PMA_Config']->removeCookie($GLOBALS['session_name']);
+    exit;
+}
+
+
+/**
+ * include session handling after the globals, to prevent overwriting
+ */
+require './libraries/session.inc.php';
+
+/**
+ * init some variables LABEL_variables_init
+ */
+
+/**
+ * holds parameters to be passed to next page
+ * @global array $GLOBALS['url_params']
+ */
+$GLOBALS['url_params'] = array();
+
+/**
+ * the whitelist for $GLOBALS['goto']
+ * @global array $goto_whitelist
+ */
+$goto_whitelist = array(
+    //'browse_foreigners.php',
+    //'changelog.php',
+    //'chk_rel.php',
+    'db_create.php',
+    'db_datadict.php',
+    'db_sql.php',
+    'db_events.php',
+    'db_export.php',
+    'db_importdocsql.php',
+    'db_qbe.php',
+    'db_structure.php',
+    'db_import.php',
+    'db_operations.php',
+    'db_printview.php',
+    'db_search.php',
+    'db_routines.php',
+    'export.php',
+    'import.php',
+    //'index.php',
+    //'navigation.php',
+    //'license.php',
+    'index.php',
+    'pdf_pages.php',
+    'pdf_schema.php',
+    //'phpinfo.php',
+    'querywindow.php',
+    'server_binlog.php',
+    'server_collations.php',
+    'server_databases.php',
+    'server_engines.php',
+    'server_export.php',
+    'server_import.php',
+    'server_privileges.php',
+    'server_sql.php',
+    'server_status.php',
+    'server_status_advisor.php',
+    'server_status_monitor.php',
+    'server_status_queries.php',
+    'server_status_variables.php',
+    'server_variables.php',
+    'sql.php',
+    'tbl_addfield.php',
+    'tbl_change.php',
+    'tbl_create.php',
+    'tbl_import.php',
+    'tbl_indexes.php',
+    'tbl_move_copy.php',
+    'tbl_printview.php',
+    'tbl_sql.php',
+    'tbl_export.php',
+    'tbl_operations.php',
+    'tbl_structure.php',
+    'tbl_relation.php',
+    'tbl_replace.php',
+    'tbl_row_action.php',
+    'tbl_select.php',
+    'tbl_zoom_select.php',
+    //'themes.php',
+    'transformation_overview.php',
+    'transformation_wrapper.php',
+    'user_password.php',
+);
+
+/**
+ * check $__redirect against whitelist
+ */
+if (! PMA_checkPageValidity($__redirect, $goto_whitelist)) {
+    $__redirect = null;
+}
+
+/**
+ * holds page that should be displayed
+ * @global string $GLOBALS['goto']
+ */
+$GLOBALS['goto'] = '';
+// Security fix: disallow accessing serious server files via "?goto="
+if (PMA_checkPageValidity($_REQUEST['goto'], $goto_whitelist)) {
+    $GLOBALS['goto'] = $_REQUEST['goto'];
+    $GLOBALS['url_params']['goto'] = $_REQUEST['goto'];
+} else {
+    unset($_REQUEST['goto'], $_GET['goto'], $_POST['goto'], $_COOKIE['goto']);
+}
+
+/**
+ * returning page
+ * @global string $GLOBALS['back']
+ */
+if (PMA_checkPageValidity($_REQUEST['back'], $goto_whitelist)) {
+    $GLOBALS['back'] = $_REQUEST['back'];
+} else {
+    unset($_REQUEST['back'], $_GET['back'], $_POST['back'], $_COOKIE['back']);
+}
+
+/**
+ * Check whether user supplied token is valid, if not remove any possibly
+ * dangerous stuff from request.
+ *
+ * remember that some objects in the session with session_start and __wakeup()
+ * could access this variables before we reach this point
+ * f.e. PMA_Config: fontsize
+ *
+ * @todo variables should be handled by their respective owners (objects)
+ * f.e. lang, server, collation_connection in PMA_Config
+ */
+$token_mismatch = true;
+if (PMA_isValid($_REQUEST['token'])) {
+    $token_mismatch = ($_SESSION[' PMA_token '] != $_REQUEST['token']);
+}
+
+if ($token_mismatch) {
+    /**
+     *  List of parameters which are allowed from unsafe source
+     */
+    $allow_list = array(
+        /* needed for direct access, see FAQ 1.34
+         * also, server needed for cookie login screen (multi-server)
+         */
+        'server', 'db', 'table', 'target', 'lang',
+        /* Session ID */
+        'phpMyAdmin',
+        /* Cookie preferences */
+        'pma_lang', 'pma_collation_connection',
+        /* Possible login form */
+        'pma_servername', 'pma_username', 'pma_password',
+        /* Needed to send the correct reply */
+        'ajax_request',
+        /* Permit to log out even if there is a token mismatch */
+        'old_usr'
+    );
+    /**
+     * Allow changing themes in test/theme.php
+     */
+    if (defined('PMA_TEST_THEME')) {
+        $allow_list[] = 'set_theme';
+    }
+    /**
+     * Require cleanup functions
+     */
+    include './libraries/cleanup.lib.php';
+    /**
+     * Do actual cleanup
+     */
+    PMA_remove_request_vars($allow_list);
+
+}
+
+
+/**
+ * current selected database
+ * @global string $GLOBALS['db']
+ */
+$GLOBALS['db'] = '';
+if (PMA_isValid($_REQUEST['db'])) {
+    // can we strip tags from this?
+    // only \ and / is not allowed in db names for MySQL
+    $GLOBALS['db'] = $_REQUEST['db'];
+    $GLOBALS['url_params']['db'] = $GLOBALS['db'];
+}
+
+/**
+ * current selected table
+ * @global string $GLOBALS['table']
+ */
+$GLOBALS['table'] = '';
+if (PMA_isValid($_REQUEST['table'])) {
+    // can we strip tags from this?
+    // only \ and / is not allowed in table names for MySQL
+    $GLOBALS['table'] = $_REQUEST['table'];
+    $GLOBALS['url_params']['table'] = $GLOBALS['table'];
+}
+
+/**
+ * Store currently selected recent table.
+ * Affect $GLOBALS['db'] and $GLOBALS['table']
+ */
+if (PMA_isValid($_REQUEST['selected_recent_table'])) {
+    $recent_table = json_decode($_REQUEST['selected_recent_table'], true);
+    $GLOBALS['db'] = $recent_table['db'];
+    $GLOBALS['url_params']['db'] = $GLOBALS['db'];
+    $GLOBALS['table'] = $recent_table['table'];
+    $GLOBALS['url_params']['table'] = $GLOBALS['table'];
+}
+
+/**
+ * SQL query to be executed
+ * @global string $GLOBALS['sql_query']
+ */
+$GLOBALS['sql_query'] = '';
+if (PMA_isValid($_REQUEST['sql_query'])) {
+    $GLOBALS['sql_query'] = $_REQUEST['sql_query'];
+}
+
+//$_REQUEST['set_theme'] // checked later in this file LABEL_theme_setup
+//$_REQUEST['server']; // checked later in this file
+//$_REQUEST['lang'];   // checked by LABEL_loading_language_file
+
+/******************************************************************************/
+/* loading language file                       LABEL_loading_language_file    */
+
+/**
+ * lang detection is done here
+ */
+require './libraries/select_lang.lib.php';
+
+// Defines the cell alignment values depending on text direction
+if ($GLOBALS['text_dir'] == 'ltr') {
+    $GLOBALS['cell_align_left']  = 'left';
+    $GLOBALS['cell_align_right'] = 'right';
+} else {
+    $GLOBALS['cell_align_left']  = 'right';
+    $GLOBALS['cell_align_right'] = 'left';
+}
+
+/**
+ * check for errors occurred while loading configuration
+ * this check is done here after loading language files to present errors in locale
+ */
+$GLOBALS['PMA_Config']->checkPermissions();
+
+if ($GLOBALS['PMA_Config']->error_config_file) {
+    $error = '[strong]' . __('Failed to read configuration file') . '[/strong]'
+        . '[br][br]'
+        . __('This usually means there is a syntax error in it, please check any errors shown below.')
+        . '[br][br]'
+        . '[conferr]';
+    trigger_error($error, E_USER_ERROR);
+}
+if ($GLOBALS['PMA_Config']->error_config_default_file) {
+    $error = sprintf(
+        __('Could not load default configuration from: %1$s'),
+        $GLOBALS['PMA_Config']->default_source
+    );
+    trigger_error($error, E_USER_ERROR);
+}
+if ($GLOBALS['PMA_Config']->error_pma_uri) {
+    trigger_error(
+        __('The [code]$cfg[\'PmaAbsoluteUri\'][/code] directive MUST be set in your configuration file!'),
+        E_USER_ERROR
+    );
+}
+
+
+/******************************************************************************/
+/* setup servers                                       LABEL_setup_servers    */
+
+/**
+ * current server
+ * @global integer $GLOBALS['server']
+ */
+$GLOBALS['server'] = 0;
+
+/**
+ * Servers array fixups.
+ * $default_server comes from PMA_Config::enableBc()
+ * @todo merge into PMA_Config
+ */
+// Do we have some server?
+if (! isset($cfg['Servers']) || count($cfg['Servers']) == 0) {
+    // No server => create one with defaults
+    $cfg['Servers'] = array(1 => $default_server);
+} else {
+    // We have server(s) => apply default configuration
+    $new_servers = array();
+
+    foreach ($cfg['Servers'] as $server_index => $each_server) {
+
+        // Detect wrong configuration
+        if (!is_int($server_index) || $server_index < 1) {
+            trigger_error(
+                sprintf(__('Invalid server index: %s'), $server_index),
+                E_USER_ERROR
+            );
+        }
+
+        $each_server = array_merge($default_server, $each_server);
+
+        // Don't use servers with no hostname
+        if ($each_server['connect_type'] == 'tcp' && empty($each_server['host'])) {
+            trigger_error(
+                sprintf(
+                    __('Invalid hostname for server %1$s. Please review your configuration.'),
+                    $server_index
+                ),
+                E_USER_ERROR
+            );
+        }
+
+        // Final solution to bug #582890
+        // If we are using a socket connection
+        // and there is nothing in the verbose server name
+        // or the host field, then generate a name for the server
+        // in the form of "Server 2", localized of course!
+        if ($each_server['connect_type'] == 'socket'
+            && empty($each_server['host'])
+            && empty($each_server['verbose'])
+        ) {
+            $each_server['verbose'] = __('Server') . $server_index;
+        }
+
+        $new_servers[$server_index] = $each_server;
+    }
+    $cfg['Servers'] = $new_servers;
+    unset($new_servers, $server_index, $each_server);
+}
+
+// Cleanup
+unset($default_server);
+
+
+/******************************************************************************/
+/* setup themes                                          LABEL_theme_setup    */
+
+/**
+ * @global PMA_Theme_Manager $_SESSION['PMA_Theme_Manager']
+ */
+if (! isset($_SESSION['PMA_Theme_Manager'])) {
+    $_SESSION['PMA_Theme_Manager'] = new PMA_Theme_Manager;
+} else {
+    /**
+     * @todo move all __wakeup() functionality into session.inc.php
+     */
+    $_SESSION['PMA_Theme_Manager']->checkConfig();
+}
+
+// for the theme per server feature
+if (isset($_REQUEST['server']) && ! isset($_REQUEST['set_theme'])) {
+    $GLOBALS['server'] = $_REQUEST['server'];
+    $tmp = $_SESSION['PMA_Theme_Manager']->getThemeCookie();
+    if (empty($tmp)) {
+        $tmp = $_SESSION['PMA_Theme_Manager']->theme_default;
+    }
+    $_SESSION['PMA_Theme_Manager']->setActiveTheme($tmp);
+    unset($tmp);
+}
+/**
+ * @todo move into PMA_Theme_Manager::__wakeup()
+ */
+if (isset($_REQUEST['set_theme'])) {
+    // if user selected a theme
+    $_SESSION['PMA_Theme_Manager']->setActiveTheme($_REQUEST['set_theme']);
+}
+
+/**
+ * the theme object
+ * @global PMA_Theme $_SESSION['PMA_Theme']
+ */
+$_SESSION['PMA_Theme'] = $_SESSION['PMA_Theme_Manager']->theme;
+
+// BC
+/**
+ * the active theme
+ * @global string $GLOBALS['theme']
+ */
+$GLOBALS['theme']           = $_SESSION['PMA_Theme']->getName();
+/**
+ * the theme path
+ * @global string $GLOBALS['pmaThemePath']
+ */
+$GLOBALS['pmaThemePath']    = $_SESSION['PMA_Theme']->getPath();
+/**
+ * the theme image path
+ * @global string $GLOBALS['pmaThemeImage']
+ */
+$GLOBALS['pmaThemeImage']   = $_SESSION['PMA_Theme']->getImgPath();
+
+/**
+ * load layout file if exists
+ */
+if (@file_exists($_SESSION['PMA_Theme']->getLayoutFile())) {
+    include $_SESSION['PMA_Theme']->getLayoutFile();
+}
+
+if (! defined('PMA_MINIMUM_COMMON')) {
+    // get a dummy object to ensure that the class is instanciated
+    PMA_Response::getInstance();
+
+    /**
+     * Character set conversion.
+     */
+    include_once './libraries/charset_conversion.lib.php';
+
+    /**
+     * String handling
+     */
+    include_once './libraries/string.lib.php';
+
+    /**
+     * Lookup server by name
+     * (see FAQ 4.8)
+     */
+    if (! empty($_REQUEST['server'])
+        && is_string($_REQUEST['server'])
+        && ! is_numeric($_REQUEST['server'])
+    ) {
+        foreach ($cfg['Servers'] as $i => $server) {
+            if ($server['host'] == $_REQUEST['server']) {
+                $_REQUEST['server'] = $i;
+                break;
+            }
+        }
+        if (is_string($_REQUEST['server'])) {
+            unset($_REQUEST['server']);
+        }
+        unset($i);
+    }
+
+    /**
+     * If no server is selected, make sure that $cfg['Server'] is empty (so
+     * that nothing will work), and skip server authentication.
+     * We do NOT exit here, but continue on without logging into any server.
+     * This way, the welcome page will still come up (with no server info) and
+     * present a choice of servers in the case that there are multiple servers
+     * and '$cfg['ServerDefault'] = 0' is set.
+     */
+
+    if (isset($_REQUEST['server'])
+        && (is_string($_REQUEST['server']) || is_numeric($_REQUEST['server']))
+        && ! empty($_REQUEST['server'])
+        && ! empty($cfg['Servers'][$_REQUEST['server']])
+    ) {
+        $GLOBALS['server'] = $_REQUEST['server'];
+        $cfg['Server'] = $cfg['Servers'][$GLOBALS['server']];
+    } else {
+        if (!empty($cfg['Servers'][$cfg['ServerDefault']])) {
+            $GLOBALS['server'] = $cfg['ServerDefault'];
+            $cfg['Server'] = $cfg['Servers'][$GLOBALS['server']];
+        } else {
+            $GLOBALS['server'] = 0;
+            $cfg['Server'] = array();
+        }
+    }
+    $GLOBALS['url_params']['server'] = $GLOBALS['server'];
+
+    /**
+     * Kanji encoding convert feature appended by Y.Kawada (2002/2/20)
+     */
+    if (function_exists('mb_convert_encoding')
+        && $lang == 'ja'
+    ) {
+        include_once './libraries/kanji-encoding.lib.php';
+    } // end if
+
+    /**
+     * save some settings in cookies
+     * @todo should be done in PMA_Config
+     */
+    $GLOBALS['PMA_Config']->setCookie('pma_lang', $GLOBALS['lang']);
+    if (isset($GLOBALS['collation_connection'])) {
+        $GLOBALS['PMA_Config']->setCookie(
+            'pma_collation_connection',
+            $GLOBALS['collation_connection']
+        );
+    }
+
+    $_SESSION['PMA_Theme_Manager']->setThemeCookie();
+
+    if (! empty($cfg['Server'])) {
+
+        /**
+         * Loads the proper database interface for this server
+         */
+        include_once './libraries/database_interface.lib.php';
+
+        include_once './libraries/logging.lib.php';
+
+        // get LoginCookieValidity from preferences cache
+        // no generic solution for loading preferences from cache as some settings
+        // need to be kept for processing in PMA_Config::loadUserPreferences()
+        $cache_key = 'server_' . $GLOBALS['server'];
+        if (isset($_SESSION['cache'][$cache_key]['userprefs']['LoginCookieValidity'])) {
+            $value = $_SESSION['cache'][$cache_key]['userprefs']['LoginCookieValidity'];
+            $GLOBALS['PMA_Config']->set('LoginCookieValidity', $value);
+            $GLOBALS['cfg']['LoginCookieValidity'] = $value;
+            unset($value);
+        }
+        unset($cache_key);
+
+        // Gets the authentication library that fits the $cfg['Server'] settings
+        // and run authentication
+
+        // to allow HTTP or http
+        $cfg['Server']['auth_type'] = strtolower($cfg['Server']['auth_type']);
+
+        /**
+         * the required auth type plugin
+         */
+        $auth_class = "Authentication" . ucfirst($cfg['Server']['auth_type']);
+        if (! file_exists('./libraries/plugins/auth/' . $auth_class . '.class.php')) {
+            PMA_fatalError(
+                __('Invalid authentication method set in configuration:')
+                . ' ' . $cfg['Server']['auth_type']
+            );
+        }
+        include_once  './libraries/plugins/auth/' . $auth_class . '.class.php';
+        // todo: add plugin manager
+        $plugin_manager = null;
+        $auth_plugin = new $auth_class($plugin_manager);
+
+        if (! $auth_plugin->authCheck()) {
+            /* Force generating of new session on login */
+            PMA_secureSession();
+            $auth_plugin->auth();
+        } else {
+            $auth_plugin->authSetUser();
+        }
+
+         // Check IP-based Allow/Deny rules as soon as possible to reject the
+        // user
+        // Based on mod_access in Apache:
+        // http://cvs.apache.org/viewcvs.cgi/httpd-2.0/modules/aaa/mod_access.c?rev=1.37&content-type=text/vnd.viewcvs-markup
+        // Look at: "static int check_dir_access(request_rec *r)"
+        if (isset($cfg['Server']['AllowDeny'])
+            && isset($cfg['Server']['AllowDeny']['order'])
+        ) {
+
+            /**
+             * ip based access library
+             */
+            include_once './libraries/ip_allow_deny.lib.php';
+
+            $allowDeny_forbidden         = false; // default
+            if ($cfg['Server']['AllowDeny']['order'] == 'allow,deny') {
+                $allowDeny_forbidden     = true;
+                if (PMA_allowDeny('allow')) {
+                    $allowDeny_forbidden = false;
+                }
+                if (PMA_allowDeny('deny')) {
+                    $allowDeny_forbidden = true;
+                }
+            } elseif ($cfg['Server']['AllowDeny']['order'] == 'deny,allow') {
+                if (PMA_allowDeny('deny')) {
+                    $allowDeny_forbidden = true;
+                }
+                if (PMA_allowDeny('allow')) {
+                    $allowDeny_forbidden = false;
+                }
+            } elseif ($cfg['Server']['AllowDeny']['order'] == 'explicit') {
+                if (PMA_allowDeny('allow') && ! PMA_allowDeny('deny')) {
+                    $allowDeny_forbidden = false;
+                } else {
+                    $allowDeny_forbidden = true;
+                }
+            } // end if ... elseif ... elseif
+
+            // Ejects the user if banished
+            if ($allowDeny_forbidden) {
+                PMA_log_user($cfg['Server']['user'], 'allow-denied');
+                $auth_plugin->authFails();
+            }
+        } // end if
+
+        // is root allowed?
+        if (!$cfg['Server']['AllowRoot'] && $cfg['Server']['user'] == 'root') {
+            $allowDeny_forbidden = true;
+            PMA_log_user($cfg['Server']['user'], 'root-denied');
+            $auth_plugin->authFails();
+        }
+
+        // is a login without password allowed?
+        if (!$cfg['Server']['AllowNoPassword'] && $cfg['Server']['password'] == '') {
+            $login_without_password_is_forbidden = true;
+            PMA_log_user($cfg['Server']['user'], 'empty-denied');
+            $auth_plugin->authFails();
+        }
+
+        // if using TCP socket is not needed
+        if (strtolower($cfg['Server']['connect_type']) == 'tcp') {
+            $cfg['Server']['socket'] = '';
+        }
+
+        // Try to connect MySQL with the control user profile (will be used to
+        // get the privileges list for the current user but the true user link
+        // must be open after this one so it would be default one for all the
+        // scripts)
+        $controllink = false;
+        if ($cfg['Server']['controluser'] != '') {
+            if (! empty($cfg['Server']['controlhost'])) {
+                $controllink = PMA_DBI_connect(
+                    $cfg['Server']['controluser'],
+                    $cfg['Server']['controlpass'],
+                    true,
+                    array('host' => $cfg['Server']['controlhost'])
+                );
+            } else {
+                $controllink = PMA_DBI_connect(
+                    $cfg['Server']['controluser'],
+                    $cfg['Server']['controlpass'],
+                    true
+                );
+            }
+        }
+
+        // Connects to the server (validates user's login)
+        $userlink = PMA_DBI_connect(
+            $cfg['Server']['user'], $cfg['Server']['password'], false
+        );
+
+        if (! $controllink) {
+            $controllink = $userlink;
+        }
+
+        /* Log success */
+        PMA_log_user($cfg['Server']['user']);
+
+        /**
+         * with phpMyAdmin 3 we support MySQL >=5
+         * but only production releases:
+         *  - > 5.0.15
+         */
+        if (PMA_MYSQL_INT_VERSION < 50015) {
+            PMA_fatalError(
+                __('You should upgrade to %s %s or later.'),
+                array('MySQL', '5.0.15')
+            );
+        }
+
+        /**
+         * Type handling object.
+         */
+        if (PMA_DRIZZLE) {
+            $GLOBALS['PMA_Types'] = new PMA_Types_Drizzle();
+        } else {
+            $GLOBALS['PMA_Types'] = new PMA_Types_MySQL();
+        }
+
+        if (PMA_DRIZZLE) {
+            // DisableIS must be set to false for Drizzle, it maps SHOW commands
+            // to INFORMATION_SCHEMA queries anyway so it's fast on large servers
+            $cfg['Server']['DisableIS'] = false;
+            // SHOW OPEN TABLES is not supported by Drizzle
+            $cfg['SkipLockedTables'] = false;
+        }
+
+        /**
+         * SQL Parser code
+         */
+        include_once './libraries/sqlparser.lib.php';
+
+        /**
+         * SQL Validator interface code
+         */
+        include_once './libraries/sqlvalidator.lib.php';
+
+        /**
+         * the PMA_List_Database class
+         */
+        include_once './libraries/PMA.php';
+        $pma = new PMA;
+        $pma->userlink = $userlink;
+        $pma->controllink = $controllink;
+
+        /**
+         * some resetting has to be done when switching servers
+         */
+        if (isset($_SESSION['tmp_user_values']['previous_server'])
+            && $_SESSION['tmp_user_values']['previous_server'] != $GLOBALS['server']
+        ) {
+            unset($_SESSION['tmp_user_values']['navi_limit_offset']);
+        }
+        $_SESSION['tmp_user_values']['previous_server'] = $GLOBALS['server'];
+
+    } // end server connecting
+
+    /**
+     * check if profiling was requested and remember it
+     * (note: when $cfg['ServerDefault'] = 0, constant is not defined)
+     */
+    if (isset($_REQUEST['profiling'])
+        && PMA_Util::profilingSupported()
+    ) {
+        $_SESSION['profiling'] = true;
+    } elseif (isset($_REQUEST['profiling_form'])) {
+        // the checkbox was unchecked
+        unset($_SESSION['profiling']);
+    }
+    /**
+     * Inclusion of profiling scripts is needed on various
+     * pages like sql, tbl_sql, db_sql, tbl_select
+     */
+    $response = PMA_Response::getInstance();
+    if (isset($_SESSION['profiling'])) {
+        $header   = $response->getHeader();
+        $scripts  = $header->getScripts();
+        /* < IE 9 doesn't support canvas natively */
+        if (PMA_USR_BROWSER_AGENT == 'IE' && PMA_USR_BROWSER_VER < 9) {
+            $scripts->addFile('canvg/flashcanvas.js');
+        }
+        $scripts->addFile('jqplot/jquery.jqplot.js');
+        $scripts->addFile('jqplot/plugins/jqplot.pieRenderer.js');
+        $scripts->addFile('canvg/canvg.js');
+    }
+
+    /*
+     * There is no point in even attempting to process
+     * an ajax request if there is a token mismatch
+     */
+    if ($response->isAjax() && $token_mismatch) {
+        $response->isSuccess(false);
+        $response->addJSON(
+            'message',
+            PMA_Message::error(__('Error: Token mismatch'))
+        );
+        exit;
+    }
+} // end if !defined('PMA_MINIMUM_COMMON')
+
+// load user preferences
+$GLOBALS['PMA_Config']->loadUserPreferences();
+
+// remove sensitive values from session
+$GLOBALS['PMA_Config']->set('blowfish_secret', '');
+$GLOBALS['PMA_Config']->set('Servers', '');
+$GLOBALS['PMA_Config']->set('default_server', '');
+
+/* Tell tracker that it can actually work */
+PMA_Tracker::enable();
+
+/**
+ * @global boolean $GLOBALS['is_ajax_request']
+ * @todo should this be moved to the variables init section above?
+ *
+ * Check if the current request is an AJAX request, and set is_ajax_request
+ * accordingly.  Suppress headers, footers and unnecessary output if set to
+ * true
+ */
+if (isset($_REQUEST['ajax_request']) && $_REQUEST['ajax_request'] == true) {
+    $GLOBALS['is_ajax_request'] = true;
+} else {
+    $GLOBALS['is_ajax_request'] = false;
+}
+
+/**
+ * @global  boolean $GLOBALS['grid_edit']
+ *
+ * Set to true if this is a request made during an grid edit process.  This
+ * request is made to retrieve the non-truncated/transformed values.
+ */
+if (isset($_REQUEST['grid_edit']) && $_REQUEST['grid_edit'] == true) {
+    $GLOBALS['grid_edit'] = true;
+} else {
+    $GLOBALS['grid_edit'] = false;
+}
+
+if (isset($_REQUEST['GLOBALS']) || isset($_FILES['GLOBALS'])) {
+    PMA_fatalError(__("GLOBALS overwrite attempt"));
+}
+
+/**
+ * protect against possible exploits - there is no need to have so much variables
+ */
+if (count($_REQUEST) > 1000) {
+    PMA_fatalError(__('possible exploit'));
+}
+
+/**
+ * Check for numeric keys
+ * (if register_globals is on, numeric key can be found in $GLOBALS)
+ */
+foreach ($GLOBALS as $key => $dummy) {
+    if (is_numeric($key)) {
+        PMA_fatalError(__('numeric key detected'));
+    }
+}
+unset($dummy);
+
+// here, the function does not exist with this configuration:
+// $cfg['ServerDefault'] = 0;
+$GLOBALS['is_superuser'] = function_exists('PMA_isSuperuser') && PMA_isSuperuser();
+
+if (!empty($__redirect) && in_array($__redirect, $goto_whitelist)) {
+    /**
+     * include subform target page
+     */
+    include $__redirect;
+    exit();
+}
+
+?>
diff --git a/phpmyadmin/libraries/config.default.php b/phpmyadmin/libraries/config.default.php
new file mode 100644
index 0000000..0b25126
--- /dev/null
+++ b/phpmyadmin/libraries/config.default.php
@@ -0,0 +1,2824 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * <code>
+ * N   N  OOO  !!   DDDD   OOO    N   N  OOO  TTTTT   EEEE DDDD  I TTTTT !!
+ * NN  N O   O !!   D   D O   O   NN  N O   O   T     E    D   D I   T   !!
+ * N N N O   O !!   D   D O   O   N N N O   O   T     EEEE D   D I   T   !!
+ * N  NN O   O      D   D O   O   N  NN O   O   T     E    D   D I   T
+ * N   N  OOO  !!   DDDD   OOO    N   N  OOO    T     EEEE DDDD  I   T   !!
+ * </code>
+ *
+ * DO NOT EDIT THIS FILE, EDIT config.inc.php INSTEAD !!!
+ *
+ * phpMyAdmin default configuration, you can copy values from here to your
+ * config.inc.php
+ *
+ * All directives are explained in the documentation
+ *
+ * @package PhpMyAdmin
+ */
+
+/**
+ * Your phpMyAdmin URL.
+ *
+ * Complete the variable below with the full URL ie
+ *    http://www.your_web.net/path_to_your_phpMyAdmin_directory/
+ *
+ * It must contain characters that are valid for a URL, and the path is
+ * case sensitive on some Web servers, for example Unix-based servers.
+ *
+ * In most cases you can leave this variable empty, as the correct value
+ * will be detected automatically. However, we recommend that you do
+ * test to see that the auto-detection code works in your system. A good
+ * test is to browse a table, then edit a row and save it.  There will be
+ * an error message if phpMyAdmin cannot auto-detect the correct value.
+ *
+ * @global string $cfg['PmaAbsoluteUri']
+ */
+$cfg['PmaAbsoluteUri'] = '';
+
+/**
+ * Disable the default warning that is displayed on the DB Details Structure page if
+ * any of the required Tables for the configuration storage could not be found
+ *
+ * @global boolean $cfg['PmaNoRelation_DisableWarning']
+ */
+$cfg['PmaNoRelation_DisableWarning'] = false;
+
+/**
+ * Disable the default warning that is displayed if Suhosin is detected
+ *
+ * @global boolean $cfg['SuhosinDisableWarning']
+ */
+$cfg['SuhosinDisableWarning'] = false;
+
+/**
+ * Disable the default warning that is displayed if mcrypt is missing for
+ * cookie authentication.
+ *
+ * @global boolean $cfg['McryptDisableWarning']
+ */
+$cfg['McryptDisableWarning'] = false;
+
+/**
+ * Disable the default warning that is displayed if a diffrence between
+ * the MySQL library and server is detected.
+ *
+ * @global boolean $cfg['['ServerLibraryDifference_DisableWarning']']
+ */
+$cfg['ServerLibraryDifference_DisableWarning'] = false;
+
+/**
+ * Disable the default warning about MySQL reserved words in column names
+ *
+ * @global boolean $cfg['ReservedWordDisableWarning']
+ */
+$cfg['ReservedWordDisableWarning'] = false;
+
+/**
+ * Show warning about incomplete translations on certain threshold.
+ *
+ * @global boolean $cfg['TranslationWarningThreshold']
+ */
+$cfg['TranslationWarningThreshold'] = 80;
+
+/**
+ * The 'cookie' auth_type uses blowfish algorithm to encrypt the password. If
+ * at least one server configuration uses 'cookie' auth_type, enter here a
+ * pass phrase that will be used by blowfish. The maximum length seems to be 46
+ * characters.
+ *
+ * @global string $cfg['blowfish_secret']
+ */
+$cfg['blowfish_secret'] = '';
+
+
+/*******************************************************************************
+ * Server(s) configuration
+ *
+ * The $cfg['Servers'] array starts with $cfg['Servers'][1].  Do not use
+ * $cfg['Servers'][0]. You can disable a server configuration entry by setting host
+ * to ''. If you want more than one server, just copy following section
+ * (including $i incrementation) several times. There is no need to define
+ * full server array, just define values you need to change.
+ *
+ * @global array $cfg['Servers']
+ */
+$cfg['Servers'] = array();
+
+$i = 1;
+
+/**
+ * MySQL hostname or IP address
+ *
+ * @global string $cfg['Servers'][$i]['host']
+ */
+$cfg['Servers'][$i]['host'] = 'localhost';
+
+/**
+ * MySQL port - leave blank for default port
+ *
+ * @global string $cfg['Servers'][$i]['port']
+ */
+$cfg['Servers'][$i]['port'] = '';
+
+/**
+ * Path to the socket - leave blank for default socket
+ *
+ * @global string $cfg['Servers'][$i]['socket']
+ */
+$cfg['Servers'][$i]['socket'] = '';
+
+/**
+ * Use SSL for connecting to MySQL server?
+ *
+ * @global boolean $cfg['Servers'][$i]['ssl']
+ */
+$cfg['Servers'][$i]['ssl'] = false;
+
+/**
+ * How to connect to MySQL server ('tcp' or 'socket')
+ *
+ * @global string $cfg['Servers'][$i]['connect_type']
+ */
+$cfg['Servers'][$i]['connect_type'] = 'tcp';
+
+/**
+ * The PHP MySQL extension to use ('mysql' or 'mysqli')
+ *
+ * @global string $cfg['Servers'][$i]['extension']
+ */
+$cfg['Servers'][$i]['extension'] = 'mysqli';
+
+/**
+ * Use compressed protocol for the MySQL connection
+ *
+ * @global boolean $cfg['Servers'][$i]['compress']
+ */
+$cfg['Servers'][$i]['compress'] = false;
+
+/**
+ * MySQL control host. This permits to use a host different than the
+ * main host, for the phpMyAdmin configuration storage. If left empty,
+ * $cfg['Servers'][$i]['host'] is used instead.
+ *
+ * @global string $cfg['Servers'][$i]['controlhost']
+ */
+$cfg['Servers'][$i]['controlhost'] = '';
+
+/**
+ * MySQL control user settings (this user must have read-only
+ * access to the "mysql/user" and "mysql/db" tables). The controluser is also
+ * used for all relational features (pmadb)
+ *
+ * @global string $cfg['Servers'][$i]['controluser']
+ */
+$cfg['Servers'][$i]['controluser'] = '';
+
+/**
+ * MySQL control user settings (this user must have read-only
+ * access to the "mysql/user" and "mysql/db" tables). The controluser is also
+ * used for all relational features (pmadb)
+ *
+ * @global string $cfg['Servers'][$i]['controlpass']
+ */
+$cfg['Servers'][$i]['controlpass'] = '';
+
+/**
+ * Authentication method (valid choices: config, http, signon or cookie)
+ *
+ * @global string $cfg['Servers'][$i]['auth_type']
+ */
+$cfg['Servers'][$i]['auth_type'] = 'cookie';
+
+/**
+ * HTTP Basic Auth Realm name to display (only used with 'HTTP' auth_type)
+ *
+ * @global string $cfg['Servers'][$i]['auth_http_realm']
+ */
+$cfg['Servers'][$i]['auth_http_realm'] = '';
+
+/**
+ * File containing Swekey ids and login names (see /contrib);
+ * leave empty to deactivate Swekey hardware authentication
+ *
+ * @global string $cfg['Servers'][$i]['auth_swekey_config']
+ */
+$cfg['Servers'][$i]['auth_swekey_config'] = '';
+
+/**
+ * MySQL user
+ *
+ * @global string $cfg['Servers'][$i]['user']
+ */
+$cfg['Servers'][$i]['user'] = 'root';
+
+/**
+ * MySQL password (only needed with 'config' auth_type)
+ *
+ * @global string $cfg['Servers'][$i]['password']
+ */
+$cfg['Servers'][$i]['password'] = '';
+
+/**
+ * Session to use for 'signon' authentication method
+ *
+ * @global string $cfg['Servers'][$i]['SignonSession']
+ */
+$cfg['Servers'][$i]['SignonSession'] = '';
+
+/**
+ * PHP script to use for 'signon' authentication method
+ *
+ * @global string $cfg['Servers'][$i]['SignonScript']
+ */
+$cfg['Servers'][$i]['SignonScript'] = '';
+
+/**
+ * URL where to redirect user to login for 'signon' authentication method
+ *
+ * @global string $cfg['Servers'][$i]['SignonURL']
+ */
+$cfg['Servers'][$i]['SignonURL'] = '';
+
+/**
+ * URL where to redirect user after logout
+ *
+ * @global string $cfg['Servers'][$i]['LogoutURL']
+ */
+$cfg['Servers'][$i]['LogoutURL'] = '';
+
+/**
+ * Whether to try to connect without password
+ *
+ * @global boolean $cfg['Servers'][$i]['nopassword']
+ */
+$cfg['Servers'][$i]['nopassword'] = false;
+
+/**
+ * If set to a db-name, only this db is displayed in navigation panel
+ * It may also be an array of db-names
+ *
+ * @global string $cfg['Servers'][$i]['only_db']
+ */
+$cfg['Servers'][$i]['only_db'] = '';
+
+/**
+ * Database name to be hidden from listings
+ *
+ * @global string $cfg['Servers'][$i]['hide_db']
+ */
+$cfg['Servers'][$i]['hide_db'] = '';
+
+/**
+ * Verbose name for this host - leave blank to show the hostname
+ * (for HTTP authentication, all non-US-ASCII characters will be stripped)
+ *
+ * @global string $cfg['Servers'][$i]['verbose']
+ */
+$cfg['Servers'][$i]['verbose'] = '';
+
+/**
+ * Database used for Relation, Bookmark and PDF Features
+ * (see examples/create_tables.sql)
+ *   - leave blank for no support
+ *     SUGGESTED: 'phpmyadmin'
+ *
+ * @global string $cfg['Servers'][$i]['pmadb']
+ */
+$cfg['Servers'][$i]['pmadb'] = '';
+
+/**
+ * Bookmark table
+ *   - leave blank for no bookmark support
+ *     SUGGESTED: 'pma__bookmark'
+ *
+ * @global string $cfg['Servers'][$i]['bookmarktable']
+ */
+$cfg['Servers'][$i]['bookmarktable'] = '';
+
+/**
+ * table to describe the relation between links (see doc)
+ *   - leave blank for no relation-links support
+ *     SUGGESTED: 'pma__relation'
+ *
+ * @global string $cfg['Servers'][$i]['relation']
+ */
+$cfg['Servers'][$i]['relation'] = '';
+
+/**
+ * table to describe the display fields
+ *   - leave blank for no display fields support
+ *     SUGGESTED: 'pma__table_info'
+ *
+ * @global string $cfg['Servers'][$i]['table_info']
+ */
+$cfg['Servers'][$i]['table_info'] = '';
+
+/**
+ * table to describe the tables position for the PDF schema
+ *   - leave blank for no PDF schema support
+ *     SUGGESTED: 'pma__table_coords'
+ *
+ * @global string $cfg['Servers'][$i]['table_coords']
+ */
+$cfg['Servers'][$i]['table_coords'] = '';
+
+/**
+ * table to describe pages of relationpdf
+ *   - leave blank if you don't want to use this
+ *     SUGGESTED: 'pma__pdf_pages'
+ *
+ * @global string $cfg['Servers'][$i]['pdf_pages']
+ */
+$cfg['Servers'][$i]['pdf_pages'] = '';
+
+/**
+ * table to store column information
+ *   - leave blank for no column comments/mime types
+ *     SUGGESTED: 'pma__column_info'
+ *
+ * @global string $cfg['Servers'][$i]['column_info']
+ */
+$cfg['Servers'][$i]['column_info'] = '';
+
+/**
+ * table to store SQL history
+ *   - leave blank for no SQL query history
+ *     SUGGESTED: 'pma__history'
+ *
+ * @global string $cfg['Servers'][$i]['history']
+ */
+$cfg['Servers'][$i]['history'] = '';
+
+/**
+ * table to store the coordinates for Designer
+ *   - leave blank for no Designer feature
+ *     SUGGESTED: 'pma__designer_coords'
+ *
+ * @global string $cfg['Servers'][$i]['designer_coords']
+ */
+$cfg['Servers'][$i]['designer_coords'] = '';
+
+/**
+ * table to store recently used tables
+ *   - leave blank for no "persistent" recently used tables
+ *     SUGGESTED: 'pma__recent'
+ */
+$cfg['Servers'][$i]['recent'] = '';
+
+/**
+ * table to store UI preferences for tables
+ *   - leave blank for no "persistent" UI preferences
+ *     SUGGESTED: 'pma__table_uiprefs'
+ */
+$cfg['Servers'][$i]['table_uiprefs'] = '';
+
+/**
+ * table to store SQL tracking
+ *   - leave blank for no SQL tracking
+ *     SUGGESTED: 'pma__tracking'
+ *
+ * @global string $cfg['Servers'][$i]['tracking']
+ */
+$cfg['Servers'][$i]['tracking'] = '';
+
+/**
+ * table to store user preferences
+ *   - leave blank to disable server storage
+ *     SUGGESTED: 'pma__userconfig'
+ *
+ * @global string $cfg['Servers'][$i]['userconfig']
+ */
+$cfg['Servers'][$i]['userconfig'] = '';
+
+/**
+ * Maximum number of records saved in $cfg['Servers'][$i]['table_uiprefs'] table.
+ *
+ * In case where tables in databases is modified (e.g. dropped or renamed),
+ * table_uiprefs may contains invalid data (referring to tables which are not
+ * exist anymore).
+ * This configuration make sure that we only keep N (N = MaxTableUiprefs)
+ * newest record in table_uiprefs and automatically delete older records.
+ *
+ * @global integer $cfg['Servers'][$i]['userconfig'] = '';
+ */
+$cfg['Servers'][$i]['MaxTableUiprefs'] = 100;
+
+/**
+ * whether to allow root login
+ *
+ * @global boolean $cfg['Servers'][$i]['AllowRoot']
+ */
+$cfg['Servers'][$i]['AllowRoot'] = true;
+
+/**
+ * whether to allow login of any user without a password
+ *
+ * @global boolean $cfg['Servers'][$i]['AllowNoPassword']
+ */
+$cfg['Servers'][$i]['AllowNoPassword'] = false;
+
+/**
+ * Host authentication order, leave blank to not use
+ *
+ * @global string $cfg['Servers'][$i]['AllowDeny']['order']
+ */
+$cfg['Servers'][$i]['AllowDeny']['order'] = '';
+
+/**
+ * Host authentication rules, leave blank for defaults
+ *
+ * @global array $cfg['Servers'][$i]['AllowDeny']['rules']
+ */
+$cfg['Servers'][$i]['AllowDeny']['rules'] = array();
+
+/**
+ * Disable use of INFORMATION_SCHEMA. Is always 'false' for Drizzle.
+ *
+ * @see https://sourceforge.net/p/phpmyadmin/bugs/2606/
+ * @see http://bugs.mysql.com/19588
+ * @global boolean $cfg['Servers'][$i]['DisableIS']
+ */
+$cfg['Servers'][$i]['DisableIS'] = true;
+
+/**
+ * SQL command to fetch available databases
+ *
+ * by default most user will be fine with SHOW DATABASES,
+ * for servers with a huge amount of databases it is possible to
+ * define a command which executes faster but with less information
+ *
+ * especially when accessing database servers from ISPs changing this command
+ * can result in a great speed improvement
+ *
+ * false will disable fetching databases from the server, only databases in
+ * $cfg['Servers'][$i]['only_db'] will be displayed
+ *
+ * #user# will be replaced by current user
+ *
+ * examples:
+ * 'SHOW DATABASES'
+ * "SHOW DATABASES LIKE '#user#\_%'"
+ * 'SELECT DISTINCT TABLE_SCHEMA FROM information_schema.SCHEMA_PRIVILEGES'
+ * 'SELECT SCHEMA_NAME FROM information_schema.SCHEMATA'
+ * false
+ *
+ * @global array $cfg['Servers'][$i]['ShowDatabasesCommand']
+ */
+$cfg['Servers'][$i]['ShowDatabasesCommand'] = 'SHOW DATABASES';
+
+/**
+ * Whether the tracking mechanism creates
+ * versions for tables and views automatically.
+ *
+ * @global bool $cfg['Servers'][$i]['tracking_version_auto_create']
+ */
+
+$cfg['Servers'][$i]['tracking_version_auto_create'] = false;
+
+/**
+ * Defines the list of statements
+ * the auto-creation uses for new versions.
+ *
+ * @global string $cfg['Servers'][$i]['tracking_default_statements']
+ */
+
+$cfg['Servers'][$i]['tracking_default_statements']
+    = 'CREATE TABLE,ALTER TABLE,DROP TABLE,RENAME TABLE,CREATE INDEX,' .
+      'DROP INDEX,INSERT,UPDATE,DELETE,TRUNCATE,REPLACE,CREATE VIEW,' .
+      'ALTER VIEW,DROP VIEW,CREATE DATABASE,ALTER DATABASE,DROP DATABASE';
+
+/**
+ * Whether a DROP VIEW IF EXISTS statement will be added
+ * as first line to the log when creating a view.
+ *
+ * @global bool $cfg['Servers'][$i]['tracking_add_drop_view']
+ */
+
+$cfg['Servers'][$i]['tracking_add_drop_view'] = true;
+
+/**
+ * Whether a DROP TABLE IF EXISTS statement will be added
+ * as first line to the log when creating a table.
+ *
+ * @global bool $cfg['Servers'][$i]['tracking_add_drop_table']
+ */
+
+$cfg['Servers'][$i]['tracking_add_drop_table'] = true;
+
+/**
+ * Whether a DROP DATABASE IF EXISTS statement will be added
+ * as first line to the log when creating a database.
+ *
+ * @global bool $cfg['Servers'][$i]['tracking_add_drop_database']
+ */
+
+$cfg['Servers'][$i]['tracking_add_drop_database'] = true;
+
+/**
+ * Enables caching of TABLE STATUS outputs for specific databases on this server
+ * (in some cases TABLE STATUS can be very slow, so you may want to cache it).
+ * APC is used (if the PHP extension is available, if not, this setting is ignored
+ * silently). You have to provide StatusCacheLifetime.
+ * Takes effect only if DisableIS is true.
+ *
+ * @global array $cfg['Servers'][$i]['StatusCacheDatabases']
+ */
+$cfg['Servers'][$i]['StatusCacheDatabases'] = array();
+
+/**
+ * Lifetime in seconds of the TABLE STATUS cache if StatusCacheDatabases is used
+ *
+ * @global integer $cfg['Servers'][$i]['StatusCacheLifetime']
+ */
+$cfg['Servers'][$i]['StatusCacheLifetime'] = 0;
+
+/**
+ * Default server (0 = no default server)
+ *
+ * If you have more than one server configured, you can set $cfg['ServerDefault']
+ * to any one of them to auto-connect to that server when phpMyAdmin is started,
+ * or set it to 0 to be given a list of servers without logging in
+ * If you have only one server configured, $cfg['ServerDefault'] *MUST* be
+ * set to that server.
+ *
+ * @global integer $cfg['ServerDefault']
+ */
+$cfg['ServerDefault'] = 1;
+
+/*
+ * Other core phpMyAdmin settings
+ */
+
+/**
+ * whether version check is active
+ *
+ * @global boolean $cfg['VersionCheck']
+ */
+$cfg['VersionCheck'] = VERSION_CHECK_DEFAULT;
+
+/**
+ * maximum number of db's displayed in database list
+ *
+ * @global integer $cfg['MaxDbList']
+ */
+$cfg['MaxDbList'] = 100;
+
+/**
+ * maximum number of items displayed in navigation panel
+ *
+ * @global integer $cfg['MaxDbList']
+ */
+$cfg['MaxNavigationItems'] = 25;
+
+/**
+ * maximum number of tables displayed in table list
+ *
+ * @global integer $cfg['MaxTableList']
+ */
+$cfg['MaxTableList'] = 250;
+
+/**
+ * whether to show hint or not
+ *
+ * @global boolean $cfg['ShowHint']
+ */
+$cfg['ShowHint'] = true;
+
+/**
+ * maximum number of characters when a SQL query is displayed
+ *
+ * @global integer $cfg['MaxCharactersInDisplayedSQL']
+ */
+$cfg['MaxCharactersInDisplayedSQL'] = 1000;
+
+/**
+ * use GZIP output buffering if possible (true|false|'auto')
+ *
+ * @global string $cfg['OBGzip']
+ */
+$cfg['OBGzip'] = 'auto';
+
+/**
+ * use persistent connections to MySQL database
+ *
+ * @global boolean $cfg['PersistentConnections']
+ */
+$cfg['PersistentConnections'] = false;
+
+/**
+ * whether to force using HTTPS
+ *
+ * @global boolean $cfg['ForceSSL']
+ */
+$cfg['ForceSSL'] = false;
+
+/**
+ * maximum execution time in seconds (0 for no limit)
+ *
+ * @global integer $cfg['ExecTimeLimit']
+ */
+$cfg['ExecTimeLimit'] = 300;
+
+/**
+ * Path for storing session data (session_save_path PHP parameter).
+ *
+ * @global integer $cfg['SessionSavePath']
+ */
+$cfg['SessionSavePath'] = '';
+
+/**
+ * maximum allocated bytes ('0' for no limit)
+ * this is a string because '16M' is a valid value; we must put here
+ * a string as the default value so that /setup accepts strings
+ *
+ * @global string $cfg['MemoryLimit']
+ */
+$cfg['MemoryLimit'] = '0';
+
+/**
+ * mark used tables, make possible to show locked tables (since MySQL 3.23.30)
+ * Is ignored for Drizzle.
+ *
+ * @global boolean $cfg['SkipLockedTables']
+ */
+$cfg['SkipLockedTables'] = false;
+
+/**
+ * show SQL queries as run
+ *
+ * @global boolean $cfg['ShowSQL']
+ */
+$cfg['ShowSQL'] = true;
+
+/**
+ * retain SQL input on Ajax execute
+ *
+ * @global boolean $cfg['RetainQueryEditor']
+ */
+$cfg['RetainQueryBox'] = false;
+
+/**
+ * use CodeMirror syntax highlighting for editing SQL
+ *
+ * @global boolean $cfg['CodemirrorEnable']
+ */
+$cfg['CodemirrorEnable'] = true;
+
+/**
+ * show a 'Drop database' link to normal users
+ *
+ * @global boolean $cfg['AllowUserDropDatabase']
+ */
+$cfg['AllowUserDropDatabase'] = false;
+
+/**
+ * confirm some commands that can result in loss of data
+ * (see "need_confirm" in the parser)
+ *
+ * @global boolean $cfg['Confirm']
+ */
+$cfg['Confirm'] = true;
+
+/**
+ * recall previous login in cookie authentication mode or not
+ *
+ * @global boolean $cfg['LoginCookieRecall']
+ */
+$cfg['LoginCookieRecall'] = true;
+
+/**
+ * validity of cookie login (in seconds; 1440 matches php.ini's
+ * session.gc_maxlifetime)
+ *
+ * @global integer $cfg['LoginCookieValidity']
+ */
+$cfg['LoginCookieValidity'] = 1440;
+
+/**
+ * how long login cookie should be stored (in seconds)
+ *
+ * @global integer $cfg['LoginCookieStore']
+ */
+$cfg['LoginCookieStore'] = 0;
+
+/**
+ * whether to delete all login cookies on logout
+ *
+ * @global boolean $cfg['LoginCookieDeleteAll']
+ */
+$cfg['LoginCookieDeleteAll'] = true;
+
+/**
+ * whether to enable the "database search" feature or not
+ *
+ * @global boolean $cfg['UseDbSearch']
+ */
+$cfg['UseDbSearch'] = true;
+
+/**
+ * if set to true, PMA continues computing multiple-statement queries
+ * even if one of the queries failed
+ *
+ * @global boolean $cfg['IgnoreMultiSubmitErrors']
+ */
+$cfg['IgnoreMultiSubmitErrors'] = false;
+
+/**
+ * allow login to any user entered server in cookie based authentication
+ *
+ * @global boolean $cfg['AllowArbitraryServer']
+ */
+$cfg['AllowArbitraryServer'] = false;
+
+
+/*******************************************************************************
+ * Error handler configuration
+ *
+ * this configures phpMyAdmin's own error handler, it is used to avoid information
+ * disclosure, gather errors for logging, reporting and displaying
+ *
+ * @global array $cfg['Error_Handler']
+ */
+$cfg['Error_Handler'] = array();
+
+/**
+ * whether to display errors or not
+ *
+ * this does not affect errors of type  E_USER_*
+ *
+ * @global boolean $cfg['Error_Handler']['display']
+ */
+$cfg['Error_Handler']['display'] = false;
+
+/**
+ * (NOT IMPLEMENTED YET)
+ * where to log errors, false or empty to disable
+ *
+ * <code>
+ * // EXAMPLE log to std PHP error log
+ * $cfg['Error_Handler']['log'] = array(0);
+ * // EXAMPLE mail errors
+ * $cfg['Error_Handler']['log'] = array(1, 'admin at example.org');
+ * // EXAMPLE append to specific file
+ * $cfg['Error_Handler']['log'] = array(3, '/var/log/phpmyadmin_error.log');
+ * </code>
+ *
+ * @see     http://php.net/error_log
+ * @global  string $cfg['Error_Handler']['log']
+ */
+//$cfg['Error_Handler']['log'] = false;
+
+/**
+ * gather all errors in session to be displayed on a error reporting page
+ * for viewing and/or sending to phpMyAdmin developer team
+ *
+ * @global boolean $cfg['Error_Handler']['gather']
+ */
+$cfg['Error_Handler']['gather'] = false;
+
+
+/*******************************************************************************
+ * Navigation panel setup
+ */
+
+/**
+ * turn the select-based light menu into a tree
+ *
+ * @global boolean $cfg['NavigationTreeEnableGrouping']
+ */
+$cfg['NavigationTreeEnableGrouping'] = true;
+
+/**
+ * the separator to sub-tree the select-based light menu tree
+ *
+ * @global string $cfg['NavigationTreeDbSeparator']
+ */
+$cfg['NavigationTreeDbSeparator'] = '_';
+
+/**
+ * Which string will be used to generate table prefixes
+ * to split/nest tables into multiple categories
+ *
+ * @global string $cfg['NavigationTreeTableSeparator']
+ */
+$cfg['NavigationTreeTableSeparator'] = '__';
+
+/**
+ * How many sublevels should be displayed when splitting up tables
+ * by the above Separator
+ *
+ * @global integer $cfg['NavigationTreeTableLevel']
+ */
+$cfg['NavigationTreeTableLevel'] = 1;
+
+/**
+ * display table comment as tooltip in navigation panel
+ *
+ * @global boolean $cfg['ShowTooltip']
+ */
+$cfg['ShowTooltip'] = true;
+
+/**
+ * display logo at top of navigation panel
+ *
+ * @global boolean $cfg['NavigationDisplayLogo']
+ */
+$cfg['NavigationDisplayLogo'] = true;
+
+/**
+ * where should logo link point to (can also contain an external URL)
+ *
+ * @global string $cfg['NavigationLogoLink']
+ */
+$cfg['NavigationLogoLink'] = 'index.php';
+
+/**
+ * whether to open the linked page in the main window ('main') or
+ * in a new window ('new')
+ *
+ * @global string $cfg['NavigationLogoLinkWindow']
+ */
+$cfg['NavigationLogoLinkWindow'] = 'main';
+
+/**
+ * number of recently used tables displayed in the navigation panel
+ *
+ * @global integer $cfg['NumRecentTables']
+ */
+$cfg['NumRecentTables'] = 10;
+
+/**
+ * display a JavaScript table filter in the navigation panel
+ * when more then x tables are present
+ *
+ * @global boolean $cfg['NavigationTreeDisplayItemFilterMinimum']
+ */
+$cfg['NavigationTreeDisplayItemFilterMinimum'] = 30;
+
+/**
+ * display server choice at top of navigation panel
+ *
+ * @global boolean $cfg['NavigationDisplayServers']
+ */
+$cfg['NavigationDisplayServers'] = true;
+
+/**
+ * server choice as links
+ *
+ * @global boolean $cfg['DisplayServersList']
+ */
+$cfg['DisplayServersList'] = false;
+
+/**
+ * display a JavaScript database filter in the navigation panel
+ * when more then x databases are present
+ *
+ * @global boolean $cfg['NavigationTreeDisplayDbFilterMinimum']
+ */
+$cfg['NavigationTreeDisplayDbFilterMinimum'] = 30;
+
+/**
+ * target of the navigation panel quick access icon
+ *
+ * Possible values:
+ * 'tbl_structure.php' = fields list
+ * 'tbl_sql.php' = SQL form
+ * 'tbl_select.php' = search page
+ * 'tbl_change.php' = insert row page
+ * 'sql.php' = browse page
+ *
+ * @global string $cfg['NavigationTreeDefaultTabTable']
+ */
+$cfg['NavigationTreeDefaultTabTable'] = 'tbl_structure.php';
+
+
+/*******************************************************************************
+ * In the main panel, at startup...
+ */
+
+/**
+ * allow to display statistics and space usage in the pages about database
+ * details and table properties
+ *
+ * @global boolean $cfg['ShowStats']
+ */
+$cfg['ShowStats'] = true;
+
+/**
+ * show PHP info link
+ *
+ * @global boolean $cfg['ShowPhpInfo']
+ */
+$cfg['ShowPhpInfo'] = false;
+
+/**
+ * show MySQL server and web server information
+ *
+ * @global boolean $cfg['ShowServerInfo']
+ */
+$cfg['ShowServerInfo'] = true;
+
+/**
+ * show change password link
+ *
+ * @global boolean $cfg['ShowChgPassword']
+ */
+$cfg['ShowChgPassword'] = true;
+
+/**
+ * show create database form
+ *
+ * @global boolean $cfg['ShowCreateDb']
+ */
+$cfg['ShowCreateDb'] = true;
+
+
+/*******************************************************************************
+ * Database structure
+ */
+
+/**
+ * show creation timestamp column in database structure (true|false)?
+ *
+ * @global boolean $cfg['ShowDbStructureCreation']
+ */
+$cfg['ShowDbStructureCreation'] = false;
+
+/**
+ * show last update timestamp column in database structure (true|false)?
+ *
+ * @global boolean $cfg['ShowDbStructureLastUpdate']
+ */
+$cfg['ShowDbStructureLastUpdate'] = false;
+
+/**
+ * show last check timestamp column in database structure (true|false)?
+ *
+ * @global boolean $cfg['ShowDbStructureLastCheck']
+ */
+$cfg['ShowDbStructureLastCheck'] = false;
+
+/**
+ * allow hide action columns to drop down menu in database structure (true|false)?
+ *
+ * @global boolean $cfg['HideStructureActions']
+ */
+$cfg['HideStructureActions'] = true;
+
+
+/*******************************************************************************
+ * In browse mode...
+ */
+
+/**
+ * Use icons instead of text for the navigation bar buttons
+ * and on right panel top menu (server db table) (true|false|'both')
+ *
+ * @global string $cfg['NavigationBarIconic']
+ */
+$cfg['NavigationBarIconic'] = true;
+
+/**
+ * Defines whether a user should be displayed a "show all (records)"
+ * button in browse mode or not.
+ *
+ * @global boolean $cfg['ShowAll']
+ */
+$cfg['ShowAll'] = false;
+
+/**
+ * Number of rows displayed when browsing a result set. If the result
+ * set contains more rows, "Previous" and "Next".
+ *
+ * @global integer $cfg['MaxRows']
+ */
+$cfg['MaxRows'] = 30;
+
+/**
+ * default for 'ORDER BY' clause (valid values are 'ASC', 'DESC' or 'SMART' -ie
+ * descending order for fields of type TIME, DATE, DATETIME & TIMESTAMP,
+ * ascending order else-)
+ *
+ * @global string $cfg['Order']
+ */
+$cfg['Order'] = 'SMART';
+
+/**
+ * default for 'Show binary contents as HEX'
+ *
+ * @global string $cfg['DisplayBinaryAsHex']
+ */
+$cfg['DisplayBinaryAsHex'] = true;
+
+/**
+ * grid editing: save edited cell(s) in browse-mode at once
+ *
+ * @global boolean $cfg['SaveCellsAtOnce']
+ */
+
+$cfg['SaveCellsAtOnce'] = false;
+
+/**
+ * grid editing: which action triggers it, or completely disable the feature
+ *
+ * Possible values:
+ * 'click'
+ * 'double-click'
+ * 'disabled'
+ *
+ * @global string $cfg['GridEditing']
+ */
+$cfg['GridEditing'] ='double-click';
+
+
+/*******************************************************************************
+ * In edit mode...
+ */
+
+/**
+ * disallow editing of binary fields
+ * valid values are:
+ *   false    allow editing
+ *   'blob'   allow editing except for BLOB fields
+ *   'noblob' disallow editing except for BLOB fields
+ *   'all'    disallow editing
+ *
+ * @global string $cfg['ProtectBinary']
+ */
+$cfg['ProtectBinary'] = 'blob';
+
+/**
+ * Display the function fields in edit/insert mode
+ *
+ * @global boolean $cfg['ShowFunctionFields']
+ */
+$cfg['ShowFunctionFields'] = true;
+
+/**
+ * Display the type fields in edit/insert mode
+ *
+ * @global boolean $cfg['ShowFieldTypesInDataEditView']
+ */
+$cfg['ShowFieldTypesInDataEditView'] = true;
+
+/**
+ * Which editor should be used for CHAR/VARCHAR fields:
+ *  input - allows limiting of input length
+ *  textarea - allows newlines in fields
+ *
+ * @global string $cfg['CharEditing']
+ */
+$cfg['CharEditing'] = 'input';
+
+/**
+ * The minimum size for character input fields
+ *
+ * @global integer $cfg['MinSizeForInputField']
+ */
+$cfg['MinSizeForInputField'] = 4;
+
+/**
+ * The maximum size for character input fields
+ *
+ * @global integer $cfg['MinSizeForInputField']
+ */
+$cfg['MaxSizeForInputField'] = 60;
+
+/**
+ * How many rows can be inserted at one time
+ *
+ * @global integer $cfg['InsertRows']
+ */
+$cfg['InsertRows'] = 2;
+
+/**
+ * Sort order for items in a foreign-key drop-down list.
+ * 'content' is the referenced data, 'id' is the key value.
+ *
+ * @global array $cfg['ForeignKeyDropdownOrder']
+ */
+$cfg['ForeignKeyDropdownOrder'] = array('content-id', 'id-content');
+
+/**
+ * A drop-down list will be used if fewer items are present
+ *
+ * @global integer $cfg['ForeignKeyMaxLimit']
+ */
+$cfg['ForeignKeyMaxLimit'] = 100;
+
+
+/*******************************************************************************
+ * For the export features...
+ */
+
+/**
+ * Allow for the use of zip compression (requires zip support to be enabled)
+ *
+ * @global boolean $cfg['ZipDump']
+ */
+$cfg['ZipDump'] = true;
+
+/**
+ * Allow for the use of gzip compression (requires zlib)
+ *
+ * @global boolean $cfg['GZipDump']
+ */
+$cfg['GZipDump'] = true;
+
+/**
+ * Allow for the use of bzip2 compression (requires bz2 extension)
+ *
+ * @global boolean $cfg['BZipDump']
+ */
+$cfg['BZipDump'] = true;
+
+/**
+ * Will compress gzip/bzip2 exports on the fly without the need for much memory.
+ * If you encounter problems with created gzip/bzip2 files disable this feature.
+ *
+ * @global boolean $cfg['CompressOnFly']
+ */
+$cfg['CompressOnFly'] = true;
+
+
+/*******************************************************************************
+ * Tabs display settings
+ */
+
+/**
+ * Use icons instead of text for the table display of a database (true|false|'both')
+ *
+ * @global boolean $cfg['PropertiesIconic']
+ */
+$cfg['PropertiesIconic'] = 'both';
+
+/**
+ * How many columns should be used for table display of a database?
+ * (a value larger than 1 results in some information being hidden)
+ *
+ * @global integer $cfg['PropertiesNumColumns']
+ */
+$cfg['PropertiesNumColumns'] = 1;
+
+/**
+ * Possible values:
+ * 'index.php' = the welcome page
+ * (recommended for multiuser setups)
+ * 'server_databases.php' = list of databases
+ * 'server_status.php' = runtime information
+ * 'server_variables.php' = MySQL server variables
+ * 'server_privileges.php' = user management
+ *
+ * @global string $cfg['DefaultTabServer']
+ */
+$cfg['DefaultTabServer'] = 'index.php';
+
+/**
+ * Possible values:
+ * 'db_structure.php' = tables list
+ * 'db_sql.php' = SQL form
+ * 'db_search.php' = search query
+ * 'db_operations.php' = operations on database
+ *
+ * @global string $cfg['DefaultTabDatabase']
+ */
+$cfg['DefaultTabDatabase'] = 'db_structure.php';
+
+/**
+ * Possible values:
+ * 'tbl_structure.php' = fields list
+ * 'tbl_sql.php' = SQL form
+ * 'tbl_select.php' = search page
+ * 'tbl_change.php' = insert row page
+ * 'sql.php' = browse page
+ *
+ * @global string $cfg['DefaultTabTable']
+ */
+$cfg['DefaultTabTable'] = 'sql.php';
+
+/*******************************************************************************
+ * Export defaults
+ */
+$cfg['Export'] = array();
+
+/**
+ * codegen/csv/excel/htmlexcel/htmlword/latex/ods/odt/pdf/sql/texytext/xls/xml/yaml
+ *
+ * @global string $cfg['Export']['format']
+ */
+$cfg['Export']['format'] = 'sql';
+
+/**
+ * quick/custom/custom-no-form
+ *
+ * @global string $cfg['Export']['format']
+ */
+$cfg['Export']['method'] = 'quick';
+
+/**
+ * none/zip/gzip/bzip2
+ *
+ * @global string $cfg['Export']['compression']
+ */
+$cfg['Export']['compression'] = 'none';
+
+/**
+ *
+ *
+ * @global boolean $cfg['Export']['asfile']
+ */
+$cfg['Export']['asfile'] = true;
+
+/**
+ *
+ *
+ * @global string $cfg['Export']['charset']
+ */
+$cfg['Export']['charset'] = '';
+
+/**
+ *
+ *
+ * @global boolean $cfg['Export']['onserver']
+ */
+$cfg['Export']['onserver'] = false;
+
+/**
+ *
+ *
+ * @global boolean $cfg['Export']['onserver_overwrite']
+ */
+$cfg['Export']['onserver_overwrite'] = false;
+
+/**
+ *
+ *
+ * @global boolean $cfg['Export']['quick_export_onserver']
+ */
+$cfg['Export']['quick_export_onserver'] = false;
+
+/**
+ *
+ *
+ * @global boolean $cfg['Export']['quick_export_onserver_overwrite']
+ */
+$cfg['Export']['quick_export_onserver_overwrite'] = false;
+
+/**
+ *
+ *
+ * @global boolean $cfg['Export']['remember_file_template']
+ */
+$cfg['Export']['remember_file_template'] = true;
+
+/**
+ *
+ *
+ * @global string $cfg['Export']['file_template_table']
+ */
+$cfg['Export']['file_template_table'] = '@TABLE@';
+
+/**
+ *
+ *
+ * @global string $cfg['Export']['file_template_database']
+ */
+$cfg['Export']['file_template_database'] = '@DATABASE@';
+
+/**
+ *
+ *
+ * @global string $cfg['Export']['file_template_server']
+ */
+$cfg['Export']['file_template_server'] = '@SERVER@';
+
+/**
+ *
+ *
+ * @global string $cfg['Export']['codegen_structure_or_data']
+ */
+$cfg['Export']['codegen_structure_or_data'] = 'data';
+
+/**
+ *
+ *
+ * @global $cfg['Export']['codegen_format']
+ */
+$cfg['Export']['codegen_format'] = 0;
+
+/**
+ *
+ *
+ * @global boolean $cfg['Export']['ods_columns']
+ */
+$cfg['Export']['ods_columns'] = false;
+
+/**
+ *
+ *
+ * @global string $cfg['Export']['ods_null']
+ */
+$cfg['Export']['ods_null'] = 'NULL';
+
+/**
+ *
+ *
+ * @global string $cfg['Export']['odt_structure_or_data']
+ */
+$cfg['Export']['odt_structure_or_data'] = 'structure_and_data';
+
+/**
+ *
+ *
+ * @global boolean $cfg['Export']['odt_columns']
+ */
+$cfg['Export']['odt_columns'] = true;
+
+/**
+ *
+ *
+ * @global boolean $cfg['Export']['odt_relation']
+ */
+$cfg['Export']['odt_relation'] = true;
+
+/**
+ *
+ *
+ * @global boolean $cfg['Export']['odt_comments']
+ */
+$cfg['Export']['odt_comments'] = true;
+
+/**
+ *
+ *
+ * @global boolean $cfg['Export']['odt_mime']
+ */
+$cfg['Export']['odt_mime'] = true;
+
+/**
+ *
+ *
+ * @global string $cfg['Export']['odt_null']
+ */
+$cfg['Export']['odt_null'] = 'NULL';
+
+/**
+ *
+ *
+ * @global boolean $cfg['Export']['htmlword_structure_or_data']
+ */
+$cfg['Export']['htmlword_structure_or_data'] = 'structure_and_data';
+
+/**
+ *
+ *
+ * @global boolean $cfg['Export']['htmlword_columns']
+ */
+$cfg['Export']['htmlword_columns'] = false;
+
+/**
+ *
+ *
+ * @global string $cfg['Export']['htmlword_null']
+ */
+$cfg['Export']['htmlword_null'] = 'NULL';
+
+/**
+ *
+ *
+ * @global string $cfg['Export']['texytext_structure_or_data']
+ */
+$cfg['Export']['texytext_structure_or_data'] = 'structure_and_data';
+
+/**
+ *
+ *
+ * @global boolean $cfg['Export']['texytext_columns']
+ */
+$cfg['Export']['texytext_columns'] = false;
+
+/**
+ *
+ *
+ * @global string $cfg['Export']['texytext_null']
+ */
+$cfg['Export']['texytext_null'] = 'NULL';
+
+/**
+ *
+ *
+ * @global boolean $cfg['Export']['xls_columns']
+ */
+$cfg['Export']['xls_columns'] = false;
+
+/**
+ *
+ *
+ * @global string $cfg['Export']['xls_structure_or_data']
+ */
+$cfg['Export']['xls_structure_or_data'] = 'data';
+
+/**
+ *
+ *
+ * @global string $cfg['Export']['xls_null']
+ */
+$cfg['Export']['xls_null'] = 'NULL';
+
+/**
+ *
+ *
+ * @global boolean $cfg['Export']['xlsx_columns']
+ */
+$cfg['Export']['xlsx_columns'] = false;
+
+/**
+ *
+ *
+ * @global string $cfg['Export']['xlsx_structure_or_data']
+ */
+$cfg['Export']['xlsx_structure_or_data'] = 'data';
+
+/**
+ *
+ *
+ * @global string $cfg['Export']['xlsx_null']
+ */
+$cfg['Export']['xlsx_null'] = 'NULL';
+
+/**
+ *
+ *
+ * @global boolean $cfg['Export']['csv_columns']
+ */
+$cfg['Export']['csv_columns'] = false;
+
+/**
+ *
+ *
+ * @global string $cfg['Export']['csv_structure_or_data']
+ */
+$cfg['Export']['csv_structure_or_data'] = 'data';
+
+/**
+ *
+ *
+ * @global string $cfg['Export']['csv_null']
+ */
+$cfg['Export']['csv_null'] = 'NULL';
+
+/**
+ *
+ *
+ * @global string $cfg['Export']['csv_separator']
+ */
+$cfg['Export']['csv_separator'] = ',';
+
+/**
+ *
+ *
+ * @global string $cfg['Export']['csv_enclosed']
+ */
+$cfg['Export']['csv_enclosed'] = '"';
+
+/**
+ *
+ *
+ * @global string $cfg['Export']['csv_escaped']
+ */
+$cfg['Export']['csv_escaped'] = '"';
+
+/**
+ *
+ *
+ * @global string $cfg['Export']['csv_terminated']
+ */
+$cfg['Export']['csv_terminated'] = 'AUTO';
+
+/**
+ *
+ *
+ * @global string $cfg['Export']['csv_removeCRLF']
+ */
+$cfg['Export']['csv_removeCRLF'] = false;
+
+/**
+ *
+ *
+ * @global boolean $cfg['Export']['excel_columns']
+ */
+$cfg['Export']['excel_columns'] = false;
+
+/**
+ *
+ *
+ * @global string $cfg['Export']['excel_null']
+ */
+$cfg['Export']['excel_null'] = 'NULL';
+
+/**
+ * win/mac
+ *
+ * @global string $cfg['Export']['excel_edition']
+ */
+$cfg['Export']['excel_edition'] = 'win';
+
+/**
+ *
+ *
+ * @global string $cfg['Export']['excel_removeCRLF']
+ */
+$cfg['Export']['excel_removeCRLF'] = false;
+
+/**
+ *
+ *
+ * @global string $cfg['Export']['excel_structure_or_data']
+ */
+$cfg['Export']['excel_structure_or_data'] = 'data';
+
+/**
+ *
+ *
+ * @global string $cfg['Export']['latex_structure_or_data']
+ */
+$cfg['Export']['latex_structure_or_data'] = 'structure_and_data';
+
+/**
+ *
+ *
+ * @global boolean $cfg['Export']['latex_columns']
+ */
+$cfg['Export']['latex_columns'] = true;
+
+/**
+ *
+ *
+ * @global boolean $cfg['Export']['latex_relation']
+ */
+$cfg['Export']['latex_relation'] = true;
+
+/**
+ *
+ *
+ * @global boolean $cfg['Export']['latex_comments']
+ */
+$cfg['Export']['latex_comments'] = true;
+
+/**
+ *
+ *
+ * @global boolean $cfg['Export']['latex_mime']
+ */
+$cfg['Export']['latex_mime'] = true;
+
+/**
+ *
+ *
+ * @global string $cfg['Export']['latex_null']
+ */
+$cfg['Export']['latex_null'] = '\textit{NULL}';
+
+/**
+ *
+ *
+ * @global boolean $cfg['Export']['latex_caption']
+ */
+$cfg['Export']['latex_caption'] = true;
+
+/**
+ *
+ *
+ * @global string $cfg['Export']['latex_structure_caption']
+ */
+$cfg['Export']['latex_structure_caption'] = 'strLatexStructure';
+
+/**
+ *
+ *
+ * @global string $cfg['Export']['latex_structure_continued_caption']
+ */
+$cfg['Export']['latex_structure_continued_caption']
+    = 'strLatexStructure strLatexContinued';
+
+/**
+ *
+ *
+ * @global string $cfg['Export']['latex_data_caption']
+ */
+$cfg['Export']['latex_data_caption'] = 'strLatexContent';
+
+/**
+ *
+ *
+ * @global string $cfg['Export']['latex_data_continued_caption']
+ */
+$cfg['Export']['latex_data_continued_caption'] = 'strLatexContent strLatexContinued';
+
+/**
+ *
+ *
+ * @global string $cfg['Export']['latex_data_label']
+ */
+$cfg['Export']['latex_data_label'] = 'tab:@TABLE at -data';
+
+/**
+ *
+ *
+ * @global string $cfg['Export']['latex_structure_label']
+ */
+$cfg['Export']['latex_structure_label'] = 'tab:@TABLE at -structure';
+
+/**
+ *
+ *
+ * @global string $cfg['Export']['mediawiki_structure_or_data']
+ */
+$cfg['Export']['mediawiki_structure_or_data'] = 'data';
+
+/**
+ *
+ *
+ * @global boolean $cfg['Export']['mediawiki_caption']
+ */
+
+$cfg['Export']['mediawiki_caption'] = true;
+/**
+ *
+ *
+ * @global boolean $cfg['Export']['mediawiki_headers']
+ */
+$cfg['Export']['mediawiki_headers'] = true;
+
+/**
+ *
+ *
+ * @global string $cfg['Export']['ods_structure_or_data']
+ */
+$cfg['Export']['ods_structure_or_data'] = 'data';
+
+/**
+ *
+ *
+ * @global string $cfg['Export']['pdf_structure_or_data']
+ */
+$cfg['Export']['pdf_structure_or_data'] = 'data';
+
+/**
+ *
+ *
+ * @global string $cfg['Export']['phparray_structure_or_data']
+ */
+$cfg['Export']['phparray_structure_or_data'] = 'data';
+
+/**
+ *
+ *
+ * @global string $cfg['Export']['json_structure_or_data']
+ */
+$cfg['Export']['json_structure_or_data'] = 'data';
+
+/**
+ *
+ *
+ * @global string $cfg['Export']['sql_structure_or_data']
+ */
+$cfg['Export']['sql_structure_or_data'] = 'structure_and_data';
+
+/**
+ *
+ *
+ * @global string $cfg['Export']['sql_compatibility']
+ */
+$cfg['Export']['sql_compatibility'] = 'NONE';
+
+/**
+ * Whether to include comments in SQL export.
+ *
+ * @global string $cfg['Export']['sql_include_comments']
+ */
+$cfg['Export']['sql_include_comments'] = true;
+
+/**
+ *
+ *
+ * @global boolean $cfg['Export']['sql_disable_fk']
+ */
+$cfg['Export']['sql_disable_fk'] = false;
+
+/**
+ *
+ *
+ * @global boolean $cfg['Export']['sql_use_transaction']
+ */
+$cfg['Export']['sql_use_transaction'] = false;
+
+/**
+ *
+ *
+ * @global boolean $cfg['Export']['sql_drop_database']
+ */
+$cfg['Export']['sql_drop_database'] = false;
+
+/**
+ *
+ *
+ * @global boolean $cfg['Export']['sql_drop_table']
+ */
+$cfg['Export']['sql_drop_table'] = false;
+
+/**
+ *
+ *
+ * true by default for correct behavior when dealing with exporting
+ * of VIEWs and the stand-in table
+ * @global boolean $cfg['Export']['sql_if_not_exists']
+ */
+$cfg['Export']['sql_if_not_exists'] = true;
+
+/**
+ *
+ *
+ * @global boolean $cfg['Export']['sql_procedure_function']
+ */
+$cfg['Export']['sql_procedure_function'] = true;
+
+/**
+ *
+ *
+ * @global boolean $cfg['Export']['sql_auto_increment']
+ */
+$cfg['Export']['sql_auto_increment'] = true;
+
+/**
+ *
+ *
+ * @global boolean $cfg['Export']['sql_backquotes']
+ */
+$cfg['Export']['sql_backquotes'] = true;
+
+/**
+ *
+ *
+ * @global boolean $cfg['Export']['sql_dates']
+ */
+$cfg['Export']['sql_dates'] = false;
+
+/**
+ *
+ *
+ * @global boolean $cfg['Export']['sql_relation']
+ */
+$cfg['Export']['sql_relation'] = false;
+
+/**
+ *
+ *
+ * @global boolean $cfg['Export']['sql_truncate']
+ */
+$cfg['Export']['sql_truncate'] = false;
+
+/**
+ *
+ *
+ * @global boolean $cfg['Export']['sql_delayed']
+ */
+$cfg['Export']['sql_delayed'] = false;
+
+/**
+ *
+ *
+ * @global boolean $cfg['Export']['sql_ignore']
+ */
+$cfg['Export']['sql_ignore'] = false;
+
+/**
+ * Export time in UTC.
+ *
+ * @global boolean $cfg['Export']['sql_utc_time']
+ */
+$cfg['Export']['sql_utc_time'] = true;
+
+/**
+ *
+ *
+ * @global boolean $cfg['Export']['sql_hex_for_blob']
+ */
+$cfg['Export']['sql_hex_for_blob'] = true;
+
+/**
+ * insert/update/replace
+ *
+ * @global string $cfg['Export']['sql_type']
+ */
+$cfg['Export']['sql_type'] = 'INSERT';
+
+/**
+ *
+ *
+ * @global integer $cfg['Export']['sql_max_query_size']
+ */
+$cfg['Export']['sql_max_query_size'] = 50000;
+
+/**
+ *
+ *
+ * @global boolean $cfg['Export']['sql_comments']
+ */
+$cfg['Export']['sql_comments'] = false;
+
+/**
+ *
+ *
+ * @global boolean $cfg['Export']['sql_mime']
+ */
+$cfg['Export']['sql_mime'] = false;
+
+/**
+ * \n is replaced by new line
+ *
+ * @global string $cfg['Export']['sql_header_comment']
+ */
+$cfg['Export']['sql_header_comment'] = '';
+
+/**
+ *
+ *
+ * @global boolean $cfg['Export']['sql_create_table_statements']
+ */
+$cfg['Export']['sql_create_table_statements'] = true;
+
+/**
+ * Whether to use complete inserts, extended inserts, both, or neither
+ *
+ * @global string $cfg['Export']['sql_insert_syntax']
+ */
+$cfg['Export']['sql_insert_syntax'] = 'both';
+
+/**
+ *
+ *
+ * @global string $cfg['Export']['pdf_report_title']
+ */
+$cfg['Export']['pdf_report_title'] = '';
+
+/**
+ *
+ *
+ *@global string $cfg['Export']['xml_structure_or_data']
+ */
+$cfg['Export']['xml_structure_or_data'] = 'data';
+
+/**
+ * Export schema for each structure
+ *
+ * @global string $cfg['Export']['xml_export_struc']
+ */
+$cfg['Export']['xml_export_struc'] = true;
+
+/**
+ * Export functions
+ *
+ * @global string $cfg['Export']['xml_export_functions']
+ */
+$cfg['Export']['xml_export_functions'] = true;
+
+/**
+ * Export procedures
+ *
+ * @global string $cfg['Export']['xml_export_procedures']
+ */
+$cfg['Export']['xml_export_procedures'] = true;
+
+/**
+ * Export schema for each table
+ *
+ * @global string $cfg['Export']['xml_export_tables']
+ */
+$cfg['Export']['xml_export_tables'] = true;
+
+/**
+ * Export triggers
+ *
+ * @global string $cfg['Export']['xml_export_triggers']
+ */
+$cfg['Export']['xml_export_triggers'] = true;
+
+/**
+ * Export views
+ *
+ * @global string $cfg['Export']['xml_export_views']
+ */
+$cfg['Export']['xml_export_views'] = true;
+
+/**
+ * Export contents data
+ *
+ * @global string $cfg['Export']['xml_export_contents']
+ */
+$cfg['Export']['xml_export_contents'] = true;
+
+/**
+ *
+ *
+ * @global string $cfg['Export']['yaml_structure_or_data']
+ */
+$cfg['Export']['yaml_structure_or_data'] = 'data';
+
+/*******************************************************************************
+ * Import defaults
+ */
+$cfg['Import'] = array();
+
+/**
+ *
+ *
+ * @global string $cfg['Import']['format']
+ */
+$cfg['Import']['format'] = 'sql';
+
+/**
+ * Default charset for import.
+ *
+ * @global string $cfg['Import']['charset']
+ */
+$cfg['Import']['charset'] = '';
+
+/**
+ *
+ *
+ * @global boolean $cfg['Import']['allow_interrupt']
+ */
+$cfg['Import']['allow_interrupt'] = true;
+
+/**
+ *
+ *
+ * @global integer $cfg['Import']['skip_queries']
+ */
+$cfg['Import']['skip_queries'] = 0;
+
+/**
+ *
+ *
+ * @global string $cfg['Import']['sql_compatibility']
+ */
+$cfg['Import']['sql_compatibility'] = 'NONE';
+
+/**
+ *
+ *
+ * @global string $cfg['Import']['sql_no_auto_value_on_zero']
+ */
+$cfg['Import']['sql_no_auto_value_on_zero'] = true;
+
+/**
+ *
+ *
+ * @global boolean $cfg['Import']['csv_replace']
+ */
+$cfg['Import']['csv_replace'] = false;
+
+/**
+ *
+ *
+ * @global boolean $cfg['Import']['csv_ignore']
+ */
+$cfg['Import']['csv_ignore'] = false;
+
+/**
+ *
+ *
+ * @global string $cfg['Import']['csv_terminated']
+ */
+$cfg['Import']['csv_terminated'] = ',';
+
+/**
+ *
+ *
+ * @global string $cfg['Import']['csv_enclosed']
+ */
+$cfg['Import']['csv_enclosed'] = '"';
+
+/**
+ *
+ *
+ * @global string $cfg['Import']['csv_escaped']
+ */
+$cfg['Import']['csv_escaped'] = '"';
+
+/**
+ *
+ *
+ * @global string $cfg['Import']['csv_new_line']
+ */
+$cfg['Import']['csv_new_line'] = 'auto';
+
+/**
+ *
+ *
+ * @global string $cfg['Import']['csv_columns']
+ */
+$cfg['Import']['csv_columns'] = '';
+
+/**
+ *
+ *
+ * @global string $cfg['Import']['csv_col_names']
+ */
+$cfg['Import']['csv_col_names'] = false;
+
+/**
+ *
+ *
+ * @global boolean $cfg['Import']['ldi_replace']
+ */
+$cfg['Import']['ldi_replace'] = false;
+
+/**
+ *
+ *
+ * @global boolean $cfg['Import']['ldi_ignore']
+ */
+$cfg['Import']['ldi_ignore'] = false;
+
+/**
+ *
+ *
+ * @global string $cfg['Import']['ldi_terminated']
+ */
+$cfg['Import']['ldi_terminated'] = ';';
+
+/**
+ *
+ *
+ * @global string $cfg['Import']['ldi_enclosed']
+ */
+$cfg['Import']['ldi_enclosed'] = '"';
+
+/**
+ *
+ *
+ * @global string $cfg['Import']['ldi_escaped']
+ */
+$cfg['Import']['ldi_escaped'] = '\\';
+
+/**
+ *
+ *
+ * @global string $cfg['Import']['ldi_new_line']
+ */
+$cfg['Import']['ldi_new_line'] = 'auto';
+
+/**
+ *
+ *
+ * @global string $cfg['Import']['ldi_columns']
+ */
+$cfg['Import']['ldi_columns'] = '';
+
+/**
+ * 'auto' for auto-detection, true or false for forcing
+ *
+ * @global string $cfg['Import']['ldi_local_option']
+ */
+$cfg['Import']['ldi_local_option'] = 'auto';
+
+/**
+ *
+ *
+ * @global string $cfg['Import']['ods_col_names']
+ */
+$cfg['Import']['ods_col_names'] = false;
+
+/**
+ *
+ *
+ * @global string $cfg['Import']['ods_empty_rows']
+ */
+$cfg['Import']['ods_empty_rows'] = true;
+
+/**
+ *
+ *
+ * @global string $cfg['Import']['ods_recognize_percentages']
+ */
+$cfg['Import']['ods_recognize_percentages'] = true;
+
+/**
+ *
+ *
+ * @global string $cfg['Import']['ods_recognize_currency']
+ */
+$cfg['Import']['ods_recognize_currency'] = true;
+
+/**
+ *
+ *
+ * @global string $cfg['Import']['xml_col_names']
+ */
+$cfg['Import']['xls_col_names'] = false;
+
+/**
+ *
+ *
+ * @global string $cfg['Import']['xml_empty_rows']
+ */
+$cfg['Import']['xls_empty_rows'] = true;
+
+/**
+ *
+ *
+ * @global string $cfg['Import']['xlsx_col_names']
+ */
+$cfg['Import']['xlsx_col_names'] = false;
+
+/**
+ * Link to the official MySQL documentation.
+ * Be sure to include no trailing slash on the path.
+ * See http://dev.mysql.com/doc/ for more information
+ * about MySQL manuals and their types.
+ *
+ * @global string $cfg['MySQLManualBase']
+ */
+$cfg['MySQLManualBase'] = 'http://dev.mysql.com/doc/refman';
+
+/**
+ * Type of MySQL documentation:
+ *   viewable     - "viewable online", current one used on MySQL website
+ *   searchable   - "Searchable, with user comments"
+ *   chapters     - "HTML, one page per chapter"
+ *   chapters_old - "HTML, one page per chapter",
+ *                  format used prior to MySQL 5.0 release
+ *   big          - "HTML, all on one page"
+ *   old          - old style used in phpMyAdmin 2.3.0 and sooner
+ *   none         - do not show documentation links
+ *
+ * @global string $cfg['MySQLManualType']
+ */
+$cfg['MySQLManualType'] = 'viewable';
+
+
+/*******************************************************************************
+ * PDF options
+ */
+
+/**
+ *
+ *
+ * @global array $cfg['PDFPageSizes']
+ */
+$cfg['PDFPageSizes'] = array('A3', 'A4', 'A5', 'letter', 'legal');
+
+/**
+ *
+ *
+ * @global string $cfg['PDFDefaultPageSize']
+ */
+$cfg['PDFDefaultPageSize'] = 'A4';
+
+
+/*******************************************************************************
+ * Language and character set conversion settings
+ */
+
+/**
+ * Default language to use, if not browser-defined or user-defined
+ *
+ * @global string $cfg['DefaultLang']
+ */
+$cfg['DefaultLang'] = 'en';
+
+/**
+ * Default connection collation
+ *
+ * @global string $cfg['DefaultConnectionCollation']
+ */
+$cfg['DefaultConnectionCollation'] = 'utf8_general_ci';
+
+/**
+ * Force: always use this language
+ * $cfg['Lang'] = 'en';
+ *
+ * Regular expression to limit listed languages, e.g. '^(cs|en)' for Czech and
+ * English only
+ *
+ * @global string $cfg['FilterLanguages']
+ */
+$cfg['FilterLanguages'] = '';
+
+/**
+ * You can select here which functions will be used for character set conversion.
+ * Possible values are:
+ *      auto   - automatically use available one (first is tested iconv, then
+ *               recode)
+ *      iconv  - use iconv or libiconv functions
+ *      recode - use recode_string function
+ *      none   - disable encoding conversion
+ *
+ * @global string $cfg['RecodingEngine']
+ */
+$cfg['RecodingEngine'] = 'auto';
+
+/**
+ * Specify some parameters for iconv used in character set conversion. See iconv
+ * documentation for details:
+ * http://www.gnu.org/software/libiconv/documentation/libiconv/iconv_open.3.html
+ *
+ * @global string $cfg['IconvExtraParams']
+ */
+$cfg['IconvExtraParams'] = '//TRANSLIT';
+
+/**
+ * Available character sets for MySQL conversion. currently contains all which could
+ * be found in lang/* files and few more.
+ * Character sets will be shown in same order as here listed, so if you frequently
+ * use some of these move them to the top.
+ *
+ * @global array $cfg['AvailableCharsets']
+ */
+$cfg['AvailableCharsets'] = array(
+    'iso-8859-1',
+    'iso-8859-2',
+    'iso-8859-3',
+    'iso-8859-4',
+    'iso-8859-5',
+    'iso-8859-6',
+    'iso-8859-7',
+    'iso-8859-8',
+    'iso-8859-9',
+    'iso-8859-10',
+    'iso-8859-11',
+    'iso-8859-12',
+    'iso-8859-13',
+    'iso-8859-14',
+    'iso-8859-15',
+    'windows-1250',
+    'windows-1251',
+    'windows-1252',
+    'windows-1256',
+    'windows-1257',
+    'koi8-r',
+    'big5',
+    'gb2312',
+    'utf-16',
+    'utf-8',
+    'utf-7',
+    'x-user-defined',
+    'euc-jp',
+    'ks_c_5601-1987',
+    'tis-620',
+    'SHIFT_JIS'
+);
+
+
+/*******************************************************************************
+ * Customization & design
+ *
+ * The graphical settings are now located in themes/theme-name/layout.inc.php
+ */
+
+/**
+ * enable the left panel pointer
+ * see also LeftPointerColor
+ * in layout.inc.php
+ *
+ * @global boolean $cfg['NavigationTreePointerEnable']
+ */
+$cfg['NavigationTreePointerEnable'] = true;
+
+/**
+ * enable the browse pointer
+ * see also BrowsePointerColor
+ * in layout.inc.php
+ *
+ * @global boolean $cfg['BrowsePointerEnable']
+ */
+$cfg['BrowsePointerEnable'] = true;
+
+/**
+ * enable the browse marker
+ * see also BrowseMarkerColor
+ * in layout.inc.php
+ *
+ * @global boolean $cfg['BrowseMarkerEnable']
+ */
+$cfg['BrowseMarkerEnable'] = true;
+
+/**
+ * textarea size (columns) in edit mode
+ * (this value will be emphasized (*2) for SQL
+ * query textareas and (*1.25) for query window)
+ *
+ * @global integer $cfg['TextareaCols']
+ */
+$cfg['TextareaCols'] = 40;
+
+/**
+ * textarea size (rows) in edit mode
+ *
+ * @global integer $cfg['TextareaRows']
+ */
+$cfg['TextareaRows'] = 15;
+
+/**
+ * double size of textarea size for LONGTEXT columns
+ *
+ * @global boolean $cfg['LongtextDoubleTextarea']
+ */
+$cfg['LongtextDoubleTextarea'] = true;
+
+/**
+ * auto-select when clicking in the textarea of the query-box
+ *
+ * @global boolean $cfg['TextareaAutoSelect']
+ */
+$cfg['TextareaAutoSelect'] = false;
+
+/**
+ * textarea size (columns) for CHAR/VARCHAR
+ *
+ * @global integer $cfg['CharTextareaCols']
+ */
+$cfg['CharTextareaCols'] = 40;
+
+/**
+ * textarea size (rows) for CHAR/VARCHAR
+ *
+ * @global integer $cfg['CharTextareaRows']
+ */
+$cfg['CharTextareaRows'] = 2;
+
+/**
+ * Max field data length in browse mode for all non-numeric fields
+ *
+ * @global integer $cfg['LimitChars']
+ */
+$cfg['LimitChars'] = 50;
+
+/**
+ * Where to show the edit/copy/delete links in browse mode
+ * Possible values are 'left', 'right', 'both' and 'none';
+ * which will be interpreted as 'top', 'bottom', 'both' and 'none'
+ * respectively for vertical display mode
+ *
+ * @global string $cfg['RowActionLinks']
+ */
+$cfg['RowActionLinks'] = 'left';
+
+/**
+ * default display direction (horizontal|vertical|horizontalflipped)
+ *
+ * @global string $cfg['DefaultDisplay']
+ */
+$cfg['DefaultDisplay'] = 'horizontal';
+
+/**
+ * remember the last way a table sorted
+ *
+ * @global string $cfg['RememberSorting']
+ */
+$cfg['RememberSorting'] = true;
+
+/**
+ * table-header rotation via faking or CSS? (css|fake|auto)
+ * NOTE: CSS only works in IE browsers!
+ *
+ * @global string $cfg['HeaderFlipType']
+ */
+$cfg['HeaderFlipType'] = 'auto';
+
+/**
+ * shows stored relation-comments in 'browse' mode.
+ *
+ * @global boolean $cfg['ShowBrowseComments']
+ */
+$cfg['ShowBrowseComments'] = true;
+
+/**
+ * shows stored relation-comments in 'table property' mode.
+ *
+ * @global boolean $cfg['ShowPropertyComments']
+ */
+$cfg['ShowPropertyComments']= true;
+
+/**
+ * shows table display direction.
+ */
+$cfg['ShowDisplayDirection'] = false;
+
+/**
+ * repeat header names every X cells? (0 = deactivate)
+ *
+ * @global integer $cfg['RepeatCells']
+ */
+$cfg['RepeatCells'] = 100;
+
+/**
+ * Set to true if Edit link should open the query to edit in the query window
+ * and to false if we should edit in the right panel
+ *
+ * @global boolean $cfg['EditInWindow']
+ */
+$cfg['EditInWindow'] = true;
+
+/**
+ * Width of Query window
+ *
+ * @global integer $cfg['QueryWindowWidth']
+ */
+$cfg['QueryWindowWidth'] = 550;
+
+/**
+ * Height of Query window
+ *
+ * @global integer $cfg['QueryWindowHeight']
+ */
+$cfg['QueryWindowHeight'] = 310;
+
+/**
+ * Set to true if you want DB-based query history.If false, this utilizes
+ * JS-routines to display query history (lost by window close)
+ *
+ * @global boolean $cfg['QueryHistoryDB']
+ */
+$cfg['QueryHistoryDB'] = false;
+
+/**
+ * which tab to display in the querywindow on startup
+ * (sql|files|history|full)
+ *
+ * @global string $cfg['QueryWindowDefTab']
+ */
+$cfg['QueryWindowDefTab'] = 'sql';
+
+/**
+ * When using DB-based query history, how many entries should be kept?
+ *
+ * @global integer $cfg['QueryHistoryMax']
+ */
+$cfg['QueryHistoryMax'] = 25;
+
+/**
+ * Use MIME-Types (stored in column comments table) for
+ *
+ * @global boolean $cfg['BrowseMIME']
+ */
+$cfg['BrowseMIME'] = true;
+
+/**
+ * When approximate count < this, PMA will get exact count for table rows.
+ *
+ * @global integer $cfg['MaxExactCount']
+ */
+$cfg['MaxExactCount'] = 0;
+
+/**
+ * Zero means that no row count is done for views; see the doc
+ *
+ * @global integer $cfg['MaxExactCountViews']
+ */
+$cfg['MaxExactCountViews'] = 0;
+
+/**
+ * Sort table and database in natural order
+ *
+ * @global boolean $cfg['NaturalOrder']
+ */
+$cfg['NaturalOrder'] = true;
+
+/**
+ * Initial state for sliders
+ * (open | closed | disabled)
+ *
+ * @global string $cfg['InitialSlidersState']
+ */
+$cfg['InitialSlidersState'] = 'closed';
+
+/**
+ * User preferences: disallow these settings
+ * For possible setting names look in libraries/config/user_preferences.forms.php
+ *
+ * @global array $cfg['UserprefsDisallow']
+ */
+$cfg['UserprefsDisallow'] = array();
+
+/**
+ * User preferences: enable the Developer tab
+ */
+$cfg['UserprefsDeveloperTab'] = false;
+
+/*******************************************************************************
+ * Window title settings
+ */
+
+/**
+ * title of browser window when a table is selected
+ *
+ * @global string $cfg['TitleTable']
+ */
+$cfg['TitleTable'] = '@HTTP_HOST@ / @VSERVER@ / @DATABASE@ / @TABLE@ | @PHPMYADMIN@';
+
+/**
+ * title of browser window when a database is selected
+ *
+ * @global string $cfg['TitleDatabase']
+ */
+$cfg['TitleDatabase'] = '@HTTP_HOST@ / @VSERVER@ / @DATABASE@ | @PHPMYADMIN@';
+
+/**
+ * title of browser window when a server is selected
+ *
+ * @global string $cfg['TitleServer']
+ */
+$cfg['TitleServer'] = '@HTTP_HOST@ / @VSERVER@ | @PHPMYADMIN@';
+
+/**
+ * title of browser window when nothing is selected
+ * @global string $cfg['TitleDefault']
+ */
+$cfg['TitleDefault'] = '@HTTP_HOST@ | @PHPMYADMIN@';
+
+
+/*******************************************************************************
+ * theme manager
+ */
+
+/**
+ * using themes manager please set up here the path to 'themes' else leave empty
+ *
+ * @global string $cfg['ThemePath']
+ */
+$cfg['ThemePath'] = './themes';
+
+/**
+ * if you want to use selectable themes and if ThemesPath not empty
+ * set it to true, else set it to false (default is false);
+ *
+ * @global boolean $cfg['ThemeManager']
+ */
+$cfg['ThemeManager'] = true;
+
+/**
+ * set up default theme, if ThemePath not empty you can set up here an valid
+ * path to themes or 'original' for the original pma-theme
+ *
+ * @global string $cfg['ThemeDefault']
+ */
+$cfg['ThemeDefault'] = 'pmahomme';
+
+/**
+ * allow different theme for each configured server
+ *
+ * @global boolean $cfg['ThemePerServer']
+ */
+$cfg['ThemePerServer'] = false;
+
+
+/*******************************************************************************
+ *
+ */
+
+/**
+ * Default query for table
+ *
+ * @global string $cfg['DefaultQueryTable']
+ */
+$cfg['DefaultQueryTable'] = 'SELECT * FROM @TABLE@ WHERE 1';
+
+/**
+ * Default query for database
+ *
+ * @global string $cfg['DefaultQueryDatabase']
+ */
+$cfg['DefaultQueryDatabase'] = '';
+
+
+/*******************************************************************************
+ * SQL Query box settings
+ * These are the links display in all of the SQL Query boxes
+ *
+ * @global array $cfg['SQLQuery']
+ */
+$cfg['SQLQuery'] = array();
+
+/**
+ * Edit link to change a query
+ *
+ * @global boolean $cfg['SQLQuery']['Edit']
+ */
+$cfg['SQLQuery']['Edit'] = true;
+
+/**
+ * EXPLAIN on SELECT queries
+ *
+ * @global boolean $cfg['SQLQuery']['Explain']
+ */
+$cfg['SQLQuery']['Explain'] = true;
+
+/**
+ * Wrap a query in PHP
+ *
+ * @global boolean $cfg['SQLQuery']['ShowAsPHP']
+ */
+$cfg['SQLQuery']['ShowAsPHP'] = true;
+
+/**
+ * Validate a query (see $cfg['SQLValidator'] as well)
+ *
+ * @global boolean $cfg['SQLQuery']['Validate']
+ */
+$cfg['SQLQuery']['Validate'] = false;
+
+/**
+ * Refresh the results page
+ *
+ * @global boolean $cfg['SQLQuery']['Refresh']
+ */
+$cfg['SQLQuery']['Refresh'] = true;
+
+
+/*******************************************************************************
+ * Web server upload/save/import directories
+ */
+
+/**
+ * Directory for uploaded files that can be executed by phpMyAdmin.
+ * For example './upload'. Leave empty for no upload directory support.
+ * Use %u for username inclusion.
+ *
+ * @global string $cfg['UploadDir']
+ */
+$cfg['UploadDir'] = '';
+
+/**
+ * Directory where phpMyAdmin can save exported data on server.
+ * For example './save'. Leave empty for no save directory support.
+ * Use %u for username inclusion.
+ *
+ * @global string $cfg['SaveDir']
+ */
+$cfg['SaveDir'] = '';
+
+/**
+ * Directory where phpMyAdmin can save temporary files.
+ *
+ * @global string $cfg['TempDir']
+ */
+$cfg['TempDir'] = '';
+
+
+/**
+ * Misc. settings
+ */
+
+/**
+ * Is GD >= 2 available? Set to yes/no/auto. 'auto' does auto-detection,
+ * which is the only safe way to determine GD version.
+ *
+ * @global string $cfg['GD2Available']
+ */
+$cfg['GD2Available'] = 'auto';
+
+/**
+ * Lists proxy IP and HTTP header combinations which are trusted for IP allow/deny
+ *
+ * @global array $cfg['TrustedProxies']
+ */
+$cfg['TrustedProxies'] = array();
+
+/**
+ * We normally check the permissions on the configuration file to ensure
+ * it's not world writable. However, phpMyAdmin could be installed on
+ * a NTFS filesystem mounted on a non-Windows server, in which case the
+ * permissions seems wrong but in fact cannot be detected. In this case
+ * a sysadmin would set the following to false.
+ */
+$cfg['CheckConfigurationPermissions'] = true;
+
+/**
+ * Limit for length of URL in links. When length would be above this limit, it
+ * is replaced by form with button.
+ * This is required as some web servers (IIS) have problems with long URLs.
+ * The recommended limit is 2000
+ * (see http://www.boutell.com/newfaq/misc/urllength.html) but we put
+ * 1000 to accommodate Suhosin, see bug #3358750.
+ */
+$cfg['LinkLengthLimit'] = 1000;
+
+/**
+ * Additional string to allow in CSP headers.
+ */
+ $cfg['CSPAllow'] = '';
+
+/**
+ * Disable the table maintenance mass operations, like optimizing or
+ * repairing the selected tables of a database. An accidental execution
+ * of such a maintenance task can enormously slow down a bigger database.
+ */
+$cfg['DisableMultiTableMaintenance'] = false;
+
+/*******************************************************************************
+ * SQL Parser Settings
+ *
+ * @global array $cfg['SQP']
+ */
+$cfg['SQP'] = array();
+
+/**
+ * Pretty-printing style to use on queries (html, text, none)
+ *
+ * @global string $cfg['SQP']['fmtType']
+ */
+$cfg['SQP']['fmtType'] = 'html';
+
+/**
+ * Amount to indent each level (floats are valid)
+ *
+ * @global integer $cfg['SQP']['fmtInd']
+ */
+$cfg['SQP']['fmtInd'] = '1';
+
+/**
+ * Units for indenting each level (CSS Types - {em, px, pt})
+ *
+ * @global string $cfg['SQP']['fmtIndUnit']
+ */
+$cfg['SQP']['fmtIndUnit'] = 'em';
+
+
+/*******************************************************************************
+ * If you wish to use the SQL Validator service, you should be aware of the
+ * following:
+ * All SQL statements are stored anonymously for statistical purposes.
+ * Mimer SQL Validator, Copyright 2002 Upright Database Technology.
+ * All rights reserved.
+ *
+ * @global array $cfg['SQLValidator']
+ */
+$cfg['SQLValidator'] = array();
+
+/**
+ * Make the SQL Validator available
+ *
+ * @global boolean $cfg['SQLValidator']['use']
+ */
+$cfg['SQLValidator']['use'] = false;
+
+/**
+ * If you have a custom username, specify it here (defaults to anonymous)
+ *
+ * @global string $cfg['SQLValidator']['username']
+ */
+$cfg['SQLValidator']['username'] = '';
+
+/**
+ * Password for username
+ *
+ * @global string $cfg['SQLValidator']['password']
+ */
+$cfg['SQLValidator']['password'] = '';
+
+
+/*******************************************************************************
+ * Developers ONLY!
+ *
+ * @global array $cfg['DBG']
+ */
+$cfg['DBG'] = array();
+
+/**
+ * Output executed queries and their execution times
+ *
+ * @global boolean $cfg['DBG']['sql']
+ */
+$cfg['DBG']['sql'] = false;
+
+
+/*******************************************************************************
+ * MySQL settings
+ */
+
+/**
+ * Default functions for above defined groups
+ *
+ * @global array $cfg['DefaultFunctions']
+ */
+$cfg['DefaultFunctions'] = array(
+    'FUNC_CHAR' => '',
+    'FUNC_DATE' => '',
+    'FUNC_NUMBER' => '',
+    'FUNC_SPATIAL' => 'GeomFromText',
+    'FUNC_UUID' => 'UUID',
+    'first_timestamp' => 'NOW',
+);
+
+/**
+ * Max rows retreived for zoom search
+ */
+$cfg['maxRowPlotLimit'] = 500;
+
+?>
diff --git a/phpmyadmin/libraries/config.values.php b/phpmyadmin/libraries/config.values.php
new file mode 100644
index 0000000..b38526c
--- /dev/null
+++ b/phpmyadmin/libraries/config.values.php
@@ -0,0 +1,239 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * Database with allowed values for configuration stored in the $cfg array,
+ * used by setup script and user preferences to generate forms.
+ *
+ * @package PhpMyAdmin
+ */
+
+if (!defined('PHPMYADMIN')) {
+    exit;
+}
+
+/**
+ * Value meaning:
+ * o array - select field, array contains allowed values
+ * o string - type override
+ *
+ * Use normal array, paths won't be expanded
+ */
+$cfg_db = array();
+
+$cfg_db['Servers'] = array(
+    1 => array(
+        'port'         => 'integer',
+        'connect_type' => array('tcp', 'socket'),
+        'extension'    => array('mysql', 'mysqli'),
+        'auth_type'    => array('config', 'http', 'signon', 'cookie'),
+        'AllowDeny'    => array(
+            'order' => array('', 'deny,allow', 'allow,deny', 'explicit')
+        ),
+        'only_db'      => 'array'
+    )
+);
+$cfg_db['RecodingEngine'] = array('auto', 'iconv', 'recode', 'none');
+$cfg_db['OBGzip'] = array('auto', true, false);
+$cfg_db['MemoryLimit'] = 'short_string';
+$cfg_db['NavigationLogoLinkWindow'] = array('main', 'new');
+$cfg_db['NavigationTreeDefaultTabTable'] = array(
+    'tbl_structure.php', // fields list
+    'tbl_sql.php',       // SQL form
+    'tbl_select.php',    // search page
+    'tbl_change.php',    // insert row page
+    'sql.php'            // browse page
+);
+$cfg_db['NavigationTreeDbSeparator'] = 'short_string';
+$cfg_db['NavigationTreeTableSeparator'] = 'short_string';
+$cfg_db['NavigationBarIconic'] = array(
+    true   => __('Yes'),
+    false  => __('No'),
+    'both' => __('Both')
+);
+$cfg_db['Order'] = array('ASC', 'DESC', 'SMART');
+$cfg_db['RowActionLinks'] = array(
+    'none'  => __('Nowhere'),
+    'left'  => __('Left'),
+    'right' => __('Right'),
+    'both'  => __('Both')
+);
+$cfg_db['ProtectBinary'] = array(false, 'blob', 'noblob', 'all');
+$cfg_db['DefaultDisplay'] = array('horizontal', 'vertical', 'horizontalflipped');
+$cfg_db['CharEditing'] = array('input', 'textarea');
+$cfg_db['PropertiesIconic'] = array(
+    true   => __('Yes'),
+    false  => __('No'),
+    'both' => __('Both')
+);
+$cfg_db['GridEditing'] = array(
+    'click' => __('Click'),
+    'double-click' => __('Double click'),
+    'disabled' => __('Disabled'),
+);
+$cfg_db['DefaultTabServer'] = array(
+    'index.php',               // the welcome page (recommended for multiuser setups)
+    'server_databases.php',    // list of databases
+    'server_status.php',       // runtime information
+    'server_variables.php',    // MySQL server variables
+    'server_privileges.php'    // user management
+);
+$cfg_db['DefaultTabDatabase'] = array(
+    'db_structure.php',   // tables list
+    'db_sql.php',         // SQL form
+    'db_search.php',      // search query
+    'db_operations.php'   // operations on database
+);
+$cfg_db['DefaultTabTable'] = array(
+    'tbl_structure.php', // fields list
+    'tbl_sql.php',       // SQL form
+    'tbl_select.php',    // search page
+    'tbl_change.php',    // insert row page
+    'sql.php'            // browse page
+);
+$cfg_db['QueryWindowDefTab'] = array(
+    'sql',     // SQL
+    'files',   // Import files
+    'history', // SQL history
+    'full'     // All (SQL and SQL history)
+);
+$cfg_db['InitialSlidersState'] = array(
+    'open'     => __('Open'),
+    'closed'   => __('Closed'),
+    'disabled' => __('Disabled')
+);
+$cfg_db['Import']['format'] = array(
+    'csv',    // CSV
+    'docsql', // DocSQL
+    'ldi',    // CSV using LOAD DATA
+    'sql'     // SQL
+);
+$cfg_db['Import']['charset'] = array_merge(
+    array(''),
+    $GLOBALS['cfg']['AvailableCharsets']
+);
+$cfg_db['Import']['sql_compatibility']
+    = $cfg_db['Export']['sql_compatibility'] = array(
+    'NONE', 'ANSI', 'DB2', 'MAXDB', 'MYSQL323',
+    'MYSQL40', 'MSSQL', 'ORACLE',
+    // removed; in MySQL 5.0.33, this produces exports that
+    // can't be read by POSTGRESQL (see our bug #1596328)
+    //'POSTGRESQL',
+    'TRADITIONAL'
+);
+$cfg_db['Import']['csv_terminated'] = 'short_string';
+$cfg_db['Import']['csv_enclosed'] = 'short_string';
+$cfg_db['Import']['csv_escaped'] = 'short_string';
+$cfg_db['Import']['ldi_terminated'] = 'short_string';
+$cfg_db['Import']['ldi_enclosed'] = 'short_string';
+$cfg_db['Import']['ldi_escaped'] = 'short_string';
+$cfg_db['Import']['ldi_local_option'] = array('auto', true, false);
+$cfg_db['Export']['_sod_select'] = array(
+    'structure'          => __('structure'),
+    'data'               => __('data'),
+    'structure_and_data' => __('structure and data')
+);
+$cfg_db['Export']['method'] = array(
+    'quick'          => __('Quick - display only the minimal options to configure'),
+    'custom'         => __('Custom - display all possible options to configure'),
+    'custom-no-form' => __('Custom - like above, but without the quick/custom choice')
+);
+$cfg_db['Export']['format'] = array(
+    'codegen', 'csv', 'excel', 'htmlexcel','htmlword', 'latex', 'ods',
+    'odt', 'pdf', 'sql', 'texytext', 'xls', 'xml', 'yaml'
+);
+$cfg_db['Export']['compression'] = array('none', 'zip', 'gzip', 'bzip2');
+$cfg_db['Export']['charset'] = array_merge(
+    array(''),
+    $GLOBALS['cfg']['AvailableCharsets']
+);
+$cfg_db['Export']['codegen_format'] = array(
+    '#', 'NHibernate C# DO', 'NHibernate XML'
+);
+$cfg_db['Export']['csv_separator'] = 'short_string';
+$cfg_db['Export']['csv_terminated'] = 'short_string';
+$cfg_db['Export']['csv_enclosed'] = 'short_string';
+$cfg_db['Export']['csv_escaped'] = 'short_string';
+$cfg_db['Export']['csv_null'] = 'short_string';
+$cfg_db['Export']['excel_null'] = 'short_string';
+$cfg_db['Export']['excel_edition'] = array(
+    'win'           => 'Windows',
+    'mac_excel2003' => 'Excel 2003 / Macintosh',
+    'mac_excel2008' => 'Excel 2008 / Macintosh'
+);
+$cfg_db['Export']['sql_structure_or_data'] = $cfg_db['Export']['_sod_select'];
+$cfg_db['Export']['sql_type'] = array('INSERT', 'UPDATE', 'REPLACE');
+$cfg_db['Export']['sql_insert_syntax'] = array(
+    'complete' => __('complete inserts'),
+    'extended' => __('extended inserts'),
+    'both'     => __('both of the above'),
+    'none'     => __('neither of the above')
+);
+$cfg_db['Export']['xls_null'] = 'short_string';
+$cfg_db['Export']['xlsx_null'] = 'short_string';
+$cfg_db['Export']['htmlword_structure_or_data'] = $cfg_db['Export']['_sod_select'];
+$cfg_db['Export']['htmlword_null'] = 'short_string';
+$cfg_db['Export']['ods_null'] = 'short_string';
+$cfg_db['Export']['odt_null'] = 'short_string';
+$cfg_db['Export']['odt_structure_or_data'] = $cfg_db['Export']['_sod_select'];
+$cfg_db['Export']['texytext_structure_or_data'] = $cfg_db['Export']['_sod_select'];
+$cfg_db['Export']['texytext_null'] = 'short_string';
+
+/**
+ * Default values overrides
+ * Use only full paths
+ */
+$cfg_db['_overrides'] = array();
+$cfg_db['_overrides']['Servers/1/extension'] = extension_loaded('mysqli')
+    ? 'mysqli' : 'mysql';
+
+/**
+ * Basic validator assignments (functions from libraries/config/validate.lib.php
+ * and 'validators' object in js/config.js)
+ * Use only full paths and form ids
+ */
+$cfg_db['_validators'] = array(
+    'CharTextareaCols' => 'validate_positive_number',
+    'CharTextareaRows' => 'validate_positive_number',
+    'ExecTimeLimit' => 'validate_non_negative_number',
+    'Export/sql_max_query_size' => 'validate_positive_number',
+    'ForeignKeyMaxLimit' => 'validate_positive_number',
+    'Import/csv_enclosed' => array(array('validate_by_regex', '/^.?$/')),
+    'Import/csv_escaped' => array(array('validate_by_regex', '/^.$/')),
+    'Import/csv_terminated' => array(array('validate_by_regex', '/^.$/')),
+    'Import/ldi_enclosed' => array(array('validate_by_regex', '/^.?$/')),
+    'Import/ldi_escaped' => array(array('validate_by_regex', '/^.$/')),
+    'Import/ldi_terminated' => array(array('validate_by_regex', '/^.$/')),
+    'Import/skip_queries' => 'validate_non_negative_number',
+    'InsertRows' => 'validate_positive_number',
+    'NumRecentTables' => 'validate_non_negative_number',
+    'LimitChars' => 'validate_positive_number',
+    'LoginCookieValidity' => 'validate_positive_number',
+    'LoginCookieStore' => 'validate_non_negative_number',
+    'MaxDbList' => 'validate_positive_number',
+    'MaxNavigationItems' => 'validate_positive_number',
+    'MaxCharactersInDisplayedSQL' => 'validate_positive_number',
+    'MaxRows' => 'validate_positive_number',
+    'MaxTableList' => 'validate_positive_number',
+    'MemoryLimit' => array(array('validate_by_regex', '/^\d+(?:[kmg])?$/i')),
+    'NavigationTreeTableLevel' => 'validate_positive_number',
+    'QueryHistoryMax' => 'validate_positive_number',
+    'QueryWindowWidth' => 'validate_positive_number',
+    'QueryWindowHeight' => 'validate_positive_number',
+    'RepeatCells' => 'validate_non_negative_number',
+    'Server' => 'validate_server',
+    'Server_pmadb' => 'validate_pmadb',
+    'Servers/1/port' => 'validate_port_number',
+    'Servers/1/hide_db' => 'validate_regex',
+    'TextareaCols' => 'validate_positive_number',
+    'TextareaRows' => 'validate_positive_number',
+    'TrustedProxies' => 'validate_trusted_proxies');
+
+/**
+ * Additional validators used for user preferences
+ */
+$cfg_db['_userValidators'] = array(
+    'MaxDbList'       => array(array('validate_upper_bound', 'value:MaxDbList')),
+    'MaxTableList'    => array(array('validate_upper_bound', 'value:MaxTableList')),
+    'QueryHistoryMax' => array(array('validate_upper_bound', 'value:QueryHistoryMax'))
+);
+?>
diff --git a/phpmyadmin/libraries/config/ConfigFile.class.php b/phpmyadmin/libraries/config/ConfigFile.class.php
new file mode 100644
index 0000000..238f0b0
--- /dev/null
+++ b/phpmyadmin/libraries/config/ConfigFile.class.php
@@ -0,0 +1,549 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * Config file management
+ *
+ * @package PhpMyAdmin
+ */
+
+/**
+ * Config file management class.
+ * Stores its data in $_SESSION
+ *
+ * @package PhpMyAdmin
+ */
+class ConfigFile
+{
+    /**
+     * Stores default PMA config from config.default.php
+     * @var array
+     */
+    private $_cfg;
+
+    /**
+     * Stores original PMA_Config object, not modified by user preferences
+     * @var PMA_Config
+     */
+    private $_orgCfgObject;
+
+    /**
+     * Stores allowed values for non-standard fields
+     * @var array
+     */
+    private $_cfgDb;
+
+    /**
+     * Keys which will be always written to config file
+     * @var array
+     */
+    private $_persistKeys = array();
+
+    /**
+     * Changes keys while updating config in {@link updateWithGlobalConfig()}
+     * or reading by {@link getConfig()} or {@link getConfigArray()}
+     * @var array
+     */
+    private $_cfgUpdateReadMapping = array();
+
+    /**
+     * Key filter for {@link set()}
+     * @var array|null
+     */
+    private $_setFilter;
+
+    /**
+     * Instance id (key in $_SESSION array, separate for each server -
+     * ConfigFile{server id})
+     * @var string
+     */
+    private $_id;
+
+    /**
+     * Result for {@link _flattenArray()}
+     * @var array
+     */
+    private $_flattenArrayResult;
+
+    /**
+     * ConfigFile instance
+     * @var ConfigFile
+     */
+    private static $_instance;
+
+    /**
+     * Private constructor, use {@link getInstance()}
+     *
+     */
+    private function __construct()
+    {
+        // load default config values
+        $cfg = &$this->_cfg;
+        include './libraries/config.default.php';
+        $cfg['fontsize'] = '82%';
+
+        // create PMA_Config to read config.inc.php values
+        $this->_orgCfgObject = new PMA_Config(CONFIG_FILE);
+
+        // load additional config information
+        $cfg_db = &$this->_cfgDb;
+        include './libraries/config.values.php';
+
+        // apply default values overrides
+        if (count($cfg_db['_overrides'])) {
+            foreach ($cfg_db['_overrides'] as $path => $value) {
+                PMA_arrayWrite($path, $cfg, $value);
+            }
+        }
+
+        $this->_id = 'ConfigFile' . $GLOBALS['server'];
+        if (!isset($_SESSION[$this->_id])) {
+            $_SESSION[$this->_id] = array();
+        }
+    }
+
+    /**
+     * Returns class instance
+     *
+     * @return ConfigFile
+     */
+    public static function getInstance()
+    {
+        if (is_null(self::$_instance)) {
+            self::$_instance = new ConfigFile();
+        }
+        return self::$_instance;
+    }
+
+    /**
+     * Returns PMA_Config without user preferences applied
+     *
+     * @return PMA_Config
+     */
+    public function getOrgConfigObj()
+    {
+        return $this->_orgCfgObject;
+    }
+
+    /**
+     * Sets names of config options which will be placed in config file even if
+     * they are set to their default values (use only full paths)
+     *
+     * @param array $keys
+     *
+     * @return void
+     */
+    public function setPersistKeys($keys)
+    {
+        // checking key presence is much faster than searching so move values
+        // to keys
+        $this->_persistKeys = array_flip($keys);
+    }
+
+    /**
+     * Returns flipped array set by {@link setPersistKeys()}
+     *
+     * @return array
+     */
+    public function getPersistKeysMap()
+    {
+        return $this->_persistKeys;
+    }
+
+    /**
+     * By default ConfigFile allows setting of all configuration keys, use
+     * this method to set up a filter on {@link set()} method
+     *
+     * @param array|null $keys array of allowed keys or null to remove filter
+     *
+     * @return void
+     */
+    public function setAllowedKeys($keys)
+    {
+        if ($keys === null) {
+            $this->_setFilter = null;
+            return;
+        }
+        // checking key presence is much faster than searching so move values
+        // to keys
+        $this->_setFilter = array_flip($keys);
+    }
+
+    /**
+     * Sets path mapping for updating config in
+     * {@link updateWithGlobalConfig()} or reading
+     * by {@link getConfig()} or {@link getConfigArray()}
+     *
+     * @param array $mapping
+     *
+     * @return void
+     */
+    public function setCfgUpdateReadMapping(array $mapping)
+    {
+        $this->_cfgUpdateReadMapping = $mapping;
+    }
+
+    /**
+     * Resets configuration data
+     *
+     * @return void
+     */
+    public function resetConfigData()
+    {
+        $_SESSION[$this->_id] = array();
+    }
+
+    /**
+     * Sets configuration data (overrides old data)
+     *
+     * @param array $cfg
+     *
+     * @return void
+     */
+    public function setConfigData(array $cfg)
+    {
+        $_SESSION[$this->_id] = $cfg;
+    }
+
+    /**
+     * Sets config value
+     *
+     * @param string $path
+     * @param mixed  $value
+     * @param string $canonical_path
+     *
+     * @return void
+     */
+    public function set($path, $value, $canonical_path = null)
+    {
+        if ($canonical_path === null) {
+            $canonical_path = $this->getCanonicalPath($path);
+        }
+        // apply key whitelist
+        if ($this->_setFilter !== null
+            && ! isset($this->_setFilter[$canonical_path])
+        ) {
+            return;
+        }
+        // remove if the path isn't protected and it's empty or has a default
+        // value
+        if (!isset($this->_persistKeys[$canonical_path])) {
+            $default_value = $this->getDefault($canonical_path);
+            // we need original config values not overwritten by user
+            // preferences to allow for overwriting options set in
+            // config.inc.php with default values
+            $instance_default_value = PMA_arrayRead(
+                $canonical_path,
+                $this->_orgCfgObject->settings
+            );
+            if (($value === $default_value && (defined('PMA_SETUP')
+                || $instance_default_value === $default_value))
+                || (empty($value) && empty($default_value) && (defined('PMA_SETUP')))
+            ) {
+                PMA_arrayRemove($path, $_SESSION[$this->_id]);
+                return;
+            }
+        }
+        PMA_arrayWrite($path, $_SESSION[$this->_id], $value);
+    }
+
+    /**
+     * Flattens multidimensional array, changes indices to paths
+     * (eg. 'key/subkey').
+     * Used as array_walk() callback.
+     *
+     * @param mixed $value
+     * @param mixed $key
+     * @param mixed $prefix
+     *
+     * @return void
+     */
+    private function _flattenArray($value, $key, $prefix)
+    {
+        // no recursion for numeric arrays
+        if (is_array($value) && !isset($value[0])) {
+            $prefix .= $key . '/';
+            array_walk($value, array($this, '_flattenArray'), $prefix);
+        } else {
+            $this->_flattenArrayResult[$prefix . $key] = $value;
+        }
+    }
+
+    /**
+     * Returns default config in a flattened array
+     *
+     * @return array
+     */
+    public function getFlatDefaultConfig()
+    {
+        $this->_flattenArrayResult = array();
+        array_walk($this->_cfg, array($this, '_flattenArray'), '');
+        $flat_cfg = $this->_flattenArrayResult;
+        $this->_flattenArrayResult = null;
+        return $flat_cfg;
+    }
+
+    /**
+     * Updates config with values read from given array
+     * (config will contain differences to defaults from config.defaults.php).
+     *
+     * @param array $cfg
+     *
+     * @return void
+     */
+    public function updateWithGlobalConfig(array $cfg)
+    {
+        // load config array and flatten it
+        $this->_flattenArrayResult = array();
+        array_walk($cfg, array($this, '_flattenArray'), '');
+        $flat_cfg = $this->_flattenArrayResult;
+        $this->_flattenArrayResult = null;
+
+        // save values map for translating a few user preferences paths,
+        // should be complemented by code reading from generated config
+        // to perform inverse mapping
+        foreach ($flat_cfg as $path => $value) {
+            if (isset($this->_cfgUpdateReadMapping[$path])) {
+                $path = $this->_cfgUpdateReadMapping[$path];
+            }
+            $this->set($path, $value, $path);
+        }
+    }
+
+    /**
+     * Returns config value or $default if it's not set
+     *
+     * @param string $path
+     * @param mixed  $default
+     *
+     * @return mixed
+     */
+    public function get($path, $default = null)
+    {
+        return PMA_arrayRead($path, $_SESSION[$this->_id], $default);
+    }
+
+    /**
+     * Returns default config value or $default it it's not set ie. it doesn't
+     * exist in config.default.php ($cfg) and config.values.php
+     * ($_cfg_db['_overrides'])
+     *
+     * @param string $canonical_path
+     * @param mixed  $default
+     *
+     * @return mixed
+     */
+    public function getDefault($canonical_path, $default = null)
+    {
+        return PMA_arrayRead($canonical_path, $this->_cfg, $default);
+    }
+
+    /**
+     * Returns config value, if it's not set uses the default one; returns
+     * $default if the path isn't set and doesn't contain a default value
+     *
+     * @param string $path
+     * @param mixed  $default
+     *
+     * @return mixed
+     */
+    public function getValue($path, $default = null)
+    {
+        $v = PMA_arrayRead($path, $_SESSION[$this->_id], null);
+        if ($v !== null) {
+            return $v;
+        }
+        $path = $this->getCanonicalPath($path);
+        return $this->getDefault($path, $default);
+    }
+
+    /**
+     * Returns canonical path
+     *
+     * @param string $path
+     *
+     * @return string
+     */
+    public function getCanonicalPath($path)
+    {
+        return preg_replace('#^Servers/([\d]+)/#', 'Servers/1/', $path);
+    }
+
+    /**
+     * Returns config database entry for $path ($cfg_db in config_info.php)
+     *
+     * @param string $path
+     * @param mixed  $default
+     *
+     * @return mixed
+     */
+    public function getDbEntry($path, $default = null)
+    {
+        return PMA_arrayRead($path, $this->_cfgDb, $default);
+    }
+
+    /**
+     * Returns server count
+     *
+     * @return int
+     */
+    public function getServerCount()
+    {
+        return isset($_SESSION[$this->_id]['Servers'])
+            ? count($_SESSION[$this->_id]['Servers'])
+            : 0;
+    }
+
+    /**
+     * Returns server list
+     *
+     * @return array|null
+     */
+    public function getServers()
+    {
+        return isset($_SESSION[$this->_id]['Servers'])
+            ? $_SESSION[$this->_id]['Servers']
+            : null;
+    }
+
+    /**
+     * Returns DSN of given server
+     *
+     * @param integer $server
+     *
+     * @return string
+     */
+    function getServerDSN($server)
+    {
+        if (!isset($_SESSION[$this->_id]['Servers'][$server])) {
+            return '';
+        }
+
+        $path = 'Servers/' . $server;
+        $dsn = $this->getValue("$path/extension") . '://';
+        if ($this->getValue("$path/auth_type") == 'config') {
+            $dsn .= $this->getValue("$path/user");
+            if (!$this->getValue("$path/nopassword")) {
+                $dsn .= ':***';
+            }
+            $dsn .= '@';
+        }
+        if ($this->getValue("$path/connect_type") == 'tcp') {
+            $dsn .= $this->getValue("$path/host");
+            $port = $this->getValue("$path/port");
+            if ($port) {
+                $dsn .= ':' . $port;
+            }
+        } else {
+            $dsn .= $this->getValue("$path/socket");
+        }
+        return $dsn;
+    }
+
+    /**
+     * Returns server name
+     *
+     * @param int $id
+     *
+     * @return string
+     */
+    public function getServerName($id)
+    {
+        if (!isset($_SESSION[$this->_id]['Servers'][$id])) {
+            return '';
+        }
+        $verbose = $this->get("Servers/$id/verbose");
+        if (!empty($verbose)) {
+            return $verbose;
+        }
+        $host = $this->get("Servers/$id/host");
+        return empty($host) ? 'localhost' : $host;
+    }
+
+    /**
+     * Removes server
+     *
+     * @param int $server
+     *
+     * @return void
+     */
+    public function removeServer($server)
+    {
+        if (!isset($_SESSION[$this->_id]['Servers'][$server])) {
+            return;
+        }
+        $last_server = $this->getServerCount();
+
+        for ($i = $server; $i < $last_server; $i++) {
+            $_SESSION[$this->_id]['Servers'][$i]
+                = $_SESSION[$this->_id]['Servers'][$i + 1];
+        }
+        unset($_SESSION[$this->_id]['Servers'][$last_server]);
+
+        if (isset($_SESSION[$this->_id]['ServerDefault'])
+            && $_SESSION[$this->_id]['ServerDefault'] >= 0
+        ) {
+            unset($_SESSION[$this->_id]['ServerDefault']);
+        }
+    }
+
+    /**
+     * Returns config file path, relative to phpMyAdmin's root path
+     *
+     * @return string
+     */
+    public function getFilePath()
+    {
+        // Load paths
+        if (!defined('SETUP_CONFIG_FILE')) {
+            include_once './libraries/vendor_config.php';
+        }
+
+        return SETUP_CONFIG_FILE;
+    }
+
+    /**
+     * Returns configuration array (full, multidimensional format)
+     *
+     * @return array
+     */
+    public function getConfig()
+    {
+        $c = $_SESSION[$this->_id];
+        foreach ($this->_cfgUpdateReadMapping as $map_to => $map_from) {
+            PMA_arrayWrite($map_to, $c, PMA_arrayRead($map_from, $c));
+            PMA_arrayRemove($map_from, $c);
+        }
+        return $c;
+    }
+
+    /**
+     * Returns configuration array (flat format)
+     *
+     * @return array
+     */
+    public function getConfigArray()
+    {
+        $this->_flattenArrayResult = array();
+        array_walk($_SESSION[$this->_id], array($this, '_flattenArray'), '');
+        $c = $this->_flattenArrayResult;
+        $this->_flattenArrayResult = null;
+
+        $persistKeys = array_diff(
+            array_keys($this->_persistKeys),
+            array_keys($c)
+        );
+        foreach ($persistKeys as $k) {
+            $c[$k] = $this->getDefault($k);
+        }
+
+        foreach ($this->_cfgUpdateReadMapping as $map_to => $map_from) {
+            if (!isset($c[$map_from])) {
+                continue;
+            }
+            $c[$map_to] = $c[$map_from];
+            unset($c[$map_from]);
+        }
+        return $c;
+    }
+}
+?>
diff --git a/phpmyadmin/libraries/config/Form.class.php b/phpmyadmin/libraries/config/Form.class.php
new file mode 100644
index 0000000..d82e66b
--- /dev/null
+++ b/phpmyadmin/libraries/config/Form.class.php
@@ -0,0 +1,210 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * Form handling code.
+ *
+ * @package PhpMyAdmin
+ */
+
+/**
+ * Base class for forms, loads default configuration options, checks allowed
+ * values etc.
+ *
+ * @package PhpMyAdmin
+ */
+class Form
+{
+    /**
+     * Form name
+     * @var string
+     */
+    public $name;
+
+    /**
+     * Arbitrary index, doesn't affect class' behavior
+     * @var int
+     */
+    public $index;
+
+    /**
+     * Form fields (paths), filled by {@link readFormPaths()}, indexed by field name
+     * @var array
+     */
+    public $fields;
+
+    /**
+     * Stores default values for some fields (eg. pmadb tables)
+     * @var array
+     */
+    public $default;
+
+    /**
+     * Caches field types, indexed by field names
+     * @var array
+     */
+    private $_fieldsTypes;
+
+    /**
+     * Constructor, reads default config values
+     *
+     * @param string $form_name
+     * @param array  $form
+     * @param int    $index     arbitrary index, stored in Form::$index
+     */
+    public function __construct($form_name, array $form, $index = null)
+    {
+        $this->index = $index;
+        $this->loadForm($form_name, $form);
+    }
+
+    /**
+     * Returns type of given option
+     *
+     * @param string $option_name path or field name
+     *
+     * @return string|null  one of: boolean, integer, double, string, select, array
+     */
+    public function getOptionType($option_name)
+    {
+        $key = ltrim(substr($option_name, strrpos($option_name, '/')), '/');
+        return isset($this->_fieldsTypes[$key])
+            ? $this->_fieldsTypes[$key]
+            : null;
+    }
+
+    /**
+     * Returns allowed values for select fields
+     *
+     * @param string $option_path
+     *
+     * @return array
+     */
+    public function getOptionValueList($option_path)
+    {
+        $value = ConfigFile::getInstance()->getDbEntry($option_path);
+        if ($value === null) {
+            trigger_error("$option_path - select options not defined", E_USER_ERROR);
+            return array();
+        }
+        if (!is_array($value)) {
+            trigger_error("$option_path - not a static value list", E_USER_ERROR);
+            return array();
+        }
+        // convert array('#', 'a', 'b') to array('a', 'b')
+        if (isset($value[0]) && $value[0] === '#') {
+            // remove first element ('#')
+            array_shift($value);
+        } else {
+            // convert value list array('a', 'b') to array('a' => 'a', 'b' => 'b')
+            $has_string_keys = false;
+            $keys = array();
+            for ($i = 0; $i < count($value); $i++) {
+                if (!isset($value[$i])) {
+                    $has_string_keys = true;
+                    break;
+                }
+                $keys[] = is_bool($value[$i]) ? (int)$value[$i] : $value[$i];
+            }
+            if (!$has_string_keys) {
+                $value = array_combine($keys, $value);
+            }
+        }
+
+        // $value has keys and value names, return it
+        return $value;
+    }
+
+    /**
+     * array_walk callback function, reads path of form fields from
+     * array (see file comment in setup.forms.php or user_preferences.forms.inc)
+     *
+     * @param mixed $value
+     * @param mixed $key
+     * @param mixed $prefix
+     *
+     * @return void
+     */
+    private function _readFormPathsCallback($value, $key, $prefix)
+    {
+        static $group_counter = 0;
+
+        if (is_array($value)) {
+            $prefix .= $key . '/';
+            array_walk($value, array($this, '_readFormPathsCallback'), $prefix);
+        } else {
+            if (!is_int($key)) {
+                $this->default[$prefix . $key] = $value;
+                $value = $key;
+            }
+            // add unique id to group ends
+            if ($value == ':group:end') {
+                $value .= ':' . $group_counter++;
+            }
+            $this->fields[] = $prefix . $value;
+        }
+    }
+
+    /**
+     * Reads form paths to {@link $fields}
+     *
+     * @param array $form
+     *
+     * @return void
+     */
+    protected function readFormPaths($form)
+    {
+        // flatten form fields' paths and save them to $fields
+        $this->fields = array();
+        array_walk($form, array($this, '_readFormPathsCallback'), '');
+
+        // $this->fields is an array of the form: [0..n] => 'field path'
+        // change numeric indexes to contain field names (last part of the path)
+        $paths = $this->fields;
+        $this->fields = array();
+        foreach ($paths as $path) {
+            $key = ltrim(substr($path, strrpos($path, '/')), '/');
+            $this->fields[$key] = $path;
+        }
+        // now $this->fields is an array of the form: 'field name' => 'field path'
+    }
+
+    /**
+     * Reads fields' types to $this->_fieldsTypes
+     *
+     * @return void
+     */
+    protected function readTypes()
+    {
+        $cf = ConfigFile::getInstance();
+        foreach ($this->fields as $name => $path) {
+            if (strpos($name, ':group:') === 0) {
+                $this->_fieldsTypes[$name] = 'group';
+                continue;
+            }
+            $v = $cf->getDbEntry($path);
+            if ($v !== null) {
+                $type = is_array($v) ? 'select' : $v;
+            } else {
+                $type = gettype($cf->getDefault($path));
+            }
+            $this->_fieldsTypes[$name] = $type;
+        }
+    }
+
+    /**
+     * Reads form settings and prepares class to work with given subset of
+     * config file
+     *
+     * @param string $form_name
+     * @param array  $form
+     *
+     * @return void
+     */
+    public function loadForm($form_name, $form)
+    {
+        $this->name = $form_name;
+        $this->readFormPaths($form);
+        $this->readTypes();
+    }
+}
+?>
diff --git a/phpmyadmin/libraries/config/FormDisplay.class.php b/phpmyadmin/libraries/config/FormDisplay.class.php
new file mode 100644
index 0000000..ee86f53
--- /dev/null
+++ b/phpmyadmin/libraries/config/FormDisplay.class.php
@@ -0,0 +1,831 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * Form management class, displays and processes forms
+ *
+ * Explanation of used terms:
+ * o work_path - original field path, eg. Servers/4/verbose
+ * o system_path - work_path modified so that it points to the first server,
+ *                 eg. Servers/1/verbose
+ * o translated_path - work_path modified for HTML field name, a path with
+ *                     slashes changed to hyphens, eg. Servers-4-verbose
+ *
+ * @package PhpMyAdmin
+ */
+
+/**
+ * Core libraries.
+ */
+require_once './libraries/config/FormDisplay.tpl.php';
+require_once './libraries/config/validate.lib.php';
+require_once './libraries/js_escape.lib.php';
+
+/**
+ * Form management class, displays and processes forms
+ *
+ * @package PhpMyAdmin
+ */
+class FormDisplay
+{
+    /**
+     * Form list
+     * @var Form[]
+     */
+    private $_forms = array();
+
+    /**
+     * Stores validation errors, indexed by paths
+     * [ Form_name ] is an array of form errors
+     * [path] is a string storing error associated with single field
+     * @var array
+     */
+    private $_errors = array();
+
+    /**
+     * Paths changed so that they can be used as HTML ids, indexed by paths
+     * @var array
+     */
+    private $_translatedPaths = array();
+
+    /**
+     * Server paths change indexes so we define maps from current server
+     * path to the first one, indexed by work path
+     * @var array
+     */
+    private $_systemPaths = array();
+
+    /**
+     * Language strings which will be sent to PMA_messages JS variable
+     * Will be looked up in $GLOBALS: str{value} or strSetup{value}
+     * @var array
+     */
+    private $_jsLangStrings = array();
+
+    /**
+     * Tells whether forms have been validated
+     * @var bool
+     */
+    private $_isValidated = true;
+
+    /**
+     * Dictionary with user preferences keys
+     * @var array
+     */
+    private $_userprefsKeys;
+
+    /**
+     * Dictionary with disallowed user preferences keys
+     * @var array
+     */
+    private $_userprefsDisallow;
+
+    /**
+     * Constructor
+     */
+    public function __construct()
+    {
+        $this->_jsLangStrings = array(
+            'error_nan_p' => __('Not a positive number'),
+            'error_nan_nneg' => __('Not a non-negative number'),
+            'error_incorrect_port' => __('Not a valid port number'),
+            'error_invalid_value' => __('Incorrect value'),
+            'error_value_lte' => __('Value must be equal or lower than %s'));
+        // initialize validators
+        PMA_config_get_validators();
+    }
+
+    /**
+     * Registers form in form manager
+     *
+     * @param string $form_name
+     * @param array  $form
+     * @param int    $server_id 0 if new server, validation; >= 1 if editing a server
+     *
+     * @return void
+     */
+    public function registerForm($form_name, array $form, $server_id = null)
+    {
+        $this->_forms[$form_name] = new Form($form_name, $form, $server_id);
+        $this->_isValidated = false;
+        foreach ($this->_forms[$form_name]->fields as $path) {
+            $work_path = $server_id === null
+                ? $path
+                : str_replace('Servers/1/', "Servers/$server_id/", $path);
+            $this->_systemPaths[$work_path] = $path;
+            $this->_translatedPaths[$work_path] = str_replace('/', '-', $work_path);
+        }
+    }
+
+    /**
+     * Processes forms, returns true on successful save
+     *
+     * @param bool $allow_partial_save allows for partial form saving
+     *                                 on failed validation
+     * @param bool $check_form_submit  whether check for $_POST['submit_save']
+     *
+     * @return boolean whether processing was successful
+     */
+    public function process($allow_partial_save = true, $check_form_submit = true)
+    {
+        if ($check_form_submit && !isset($_POST['submit_save'])) {
+            return false;
+        }
+
+        // save forms
+        if (count($this->_forms) > 0) {
+            return $this->save(array_keys($this->_forms), $allow_partial_save);
+        }
+        return false;
+    }
+
+    /**
+     * Runs validation for all registered forms
+     *
+     * @return void
+     */
+    private function _validate()
+    {
+        if ($this->_isValidated) {
+            return;
+        }
+
+        $cf = ConfigFile::getInstance();
+        $paths = array();
+        $values = array();
+        foreach ($this->_forms as $form) {
+            /* @var $form Form */
+            $paths[] = $form->name;
+            // collect values and paths
+            foreach ($form->fields as $path) {
+                $work_path = array_search($path, $this->_systemPaths);
+                $values[$path] = $cf->getValue($work_path);
+                $paths[] = $path;
+            }
+        }
+
+        // run validation
+        $errors = PMA_config_validate($paths, $values, false);
+
+        // change error keys from canonical paths to work paths
+        if (is_array($errors) && count($errors) > 0) {
+            $this->_errors = array();
+            foreach ($errors as $path => $error_list) {
+                $work_path = array_search($path, $this->_systemPaths);
+                // field error
+                if (!$work_path) {
+                    // form error, fix path
+                    $work_path = $path;
+                }
+                $this->_errors[$work_path] = $error_list;
+            }
+        }
+        $this->_isValidated = true;
+    }
+
+    /**
+     * Outputs HTML for forms
+     *
+     * @param bool $tabbed_form
+     * @param bool $show_restore_default whether show "restore default" button
+     *                                   besides the input field
+     *
+     * @return void
+     */
+    public function display($tabbed_form = false, $show_restore_default = false)
+    {
+        static $js_lang_sent = false;
+
+        $js = array();
+        $js_default = array();
+        $tabbed_form = $tabbed_form && (count($this->_forms) > 1);
+        $validators = PMA_config_get_validators();
+
+        PMA_displayFormTop();
+
+        if ($tabbed_form) {
+            $tabs = array();
+            foreach ($this->_forms as $form) {
+                $tabs[$form->name] = PMA_lang("Form_$form->name");
+            }
+            PMA_displayTabsTop($tabs);
+        }
+
+        // valdiate only when we aren't displaying a "new server" form
+        $is_new_server = false;
+        foreach ($this->_forms as $form) {
+            /* @var $form Form */
+            if ($form->index === 0) {
+                $is_new_server = true;
+                break;
+            }
+        }
+        if (!$is_new_server) {
+            $this->_validate();
+        }
+
+        // user preferences
+        $this->_loadUserprefsInfo();
+
+        // display forms
+        foreach ($this->_forms as $form) {
+            /* @var $form Form */
+            $form_desc = isset($GLOBALS["strConfigForm_{$form->name}_desc"])
+                ? PMA_lang("Form_{$form->name}_desc")
+                : '';
+            $form_errors = isset($this->_errors[$form->name])
+                ? $this->_errors[$form->name] : null;
+            PMA_displayFieldsetTop(
+                PMA_lang("Form_$form->name"),
+                $form_desc,
+                $form_errors,
+                array('id' => $form->name)
+            );
+
+            foreach ($form->fields as $field => $path) {
+                $work_path = array_search($path, $this->_systemPaths);
+                $translated_path = $this->_translatedPaths[$work_path];
+                // always true/false for user preferences display
+                // otherwise null
+                $userprefs_allow = isset($this->_userprefsKeys[$path])
+                    ? !isset($this->_userprefsDisallow[$path])
+                    : null;
+                // display input
+                $this->_displayFieldInput(
+                    $form,
+                    $field,
+                    $path,
+                    $work_path,
+                    $translated_path,
+                    $show_restore_default,
+                    $userprefs_allow,
+                    $js_default
+                );
+                // register JS validators for this field
+                if (isset($validators[$path])) {
+                    PMA_addJsValidate($translated_path, $validators[$path], $js);
+                }
+            }
+            PMA_displayFieldsetBottom();
+        }
+
+        if ($tabbed_form) {
+            PMA_displayTabsBottom();
+        }
+        PMA_displayFormBottom();
+
+        // if not already done, send strings used for valdiation to JavaScript
+        if (!$js_lang_sent) {
+            $js_lang_sent = true;
+            $js_lang = array();
+            foreach ($this->_jsLangStrings as $strName => $strValue) {
+                $js_lang[] = "'$strName': '" . PMA_jsFormat($strValue, false) . '\'';
+            }
+            $js[] = "$.extend(PMA_messages, {\n\t" . implode(",\n\t", $js_lang) . '})';
+        }
+
+        $js[] = "$.extend(defaultValues, {\n\t" . implode(",\n\t", $js_default) . '})';
+        PMA_displayJavascript($js);
+    }
+
+    /**
+     * Prepares data for input field display and outputs HTML code
+     *
+     * @param Form   $form
+     * @param string $field                field name as it appears in $form
+     * @param string $system_path          field path, eg. Servers/1/verbose
+     * @param string $work_path            work path, eg. Servers/4/verbose
+     * @param string $translated_path      work path changed so that it can be
+     *                                     used as XHTML id
+     * @param bool   $show_restore_default whether show "restore default" button
+     *                                     besides the input field
+     * @param mixed  $userprefs_allow      whether user preferences are enabled
+     *                                     for this field (null - no support,
+     *                                     true/false - enabled/disabled)
+     * @param array  &$js_default          array which stores JavaScript code
+     *                                     to be displayed
+     *
+     * @return void
+     */
+    private function _displayFieldInput(
+        Form $form, $field, $system_path, $work_path,
+        $translated_path, $show_restore_default, $userprefs_allow, array &$js_default
+    ) {
+        $name = PMA_lang_name($system_path);
+        $description = PMA_lang_name($system_path, 'desc', '');
+
+        $cf = ConfigFile::getInstance();
+        $value = $cf->get($work_path);
+        $value_default = $cf->getDefault($system_path);
+        $value_is_default = false;
+        if ($value === null || $value === $value_default) {
+            $value = $value_default;
+            $value_is_default = true;
+        }
+
+        $opts = array(
+            'doc' => $this->getDocLink($system_path),
+            'wiki' =>  $this->getWikiLink($system_path),
+            'show_restore_default' => $show_restore_default,
+            'userprefs_allow' => $userprefs_allow,
+            'userprefs_comment' => PMA_lang_name($system_path, 'cmt', ''));
+        if (isset($form->default[$system_path])) {
+            $opts['setvalue'] = $form->default[$system_path];
+        }
+
+        if (isset($this->_errors[$work_path])) {
+            $opts['errors'] = $this->_errors[$work_path];
+        }
+        switch ($form->getOptionType($field)) {
+        case 'string':
+            $type = 'text';
+            break;
+        case 'short_string':
+            $type = 'short_text';
+            break;
+        case 'double':
+        case 'integer':
+            $type = 'number_text';
+            break;
+        case 'boolean':
+            $type = 'checkbox';
+            break;
+        case 'select':
+            $type = 'select';
+            $opts['values'] = $form->getOptionValueList($form->fields[$field]);
+            break;
+        case 'array':
+            $type = 'list';
+            $value = (array) $value;
+            $value_default = (array) $value_default;
+            break;
+        case 'group':
+            // :group:end is changed to :group:end:{unique id} in Form class
+            if (substr($field, 7, 4) != 'end:') {
+                PMA_displayGroupHeader(substr($field, 7));
+            } else {
+                PMA_displayGroupFooter();
+            }
+            return;
+        case 'NULL':
+            trigger_error("Field $system_path has no type", E_USER_WARNING);
+            return;
+        }
+
+        // TrustedProxies requires changes before displaying
+        if ($system_path == 'TrustedProxies') {
+            foreach ($value as $ip => &$v) {
+                if (!preg_match('/^-\d+$/', $ip)) {
+                    $v = $ip . ': ' . $v;
+                }
+            }
+        }
+        $this->_setComments($system_path, $opts);
+
+        // send default value to form's JS
+        $js_line = '\'' . $translated_path . '\': ';
+        switch ($type) {
+        case 'text':
+        case 'short_text':
+        case 'number_text':
+            $js_line .= '\'' . PMA_escapeJsString($value_default) . '\'';
+            break;
+        case 'checkbox':
+            $js_line .= $value_default ? 'true' : 'false';
+            break;
+        case 'select':
+            $value_default_js = is_bool($value_default)
+                ? (int) $value_default
+                : $value_default;
+            $js_line .= '[\'' . PMA_escapeJsString($value_default_js) . '\']';
+            break;
+        case 'list':
+            $js_line .= '\'' . PMA_escapeJsString(implode("\n", $value_default))
+                . '\'';
+            break;
+        }
+        $js_default[] = $js_line;
+
+        PMA_displayInput(
+            $translated_path, $name, $type, $value,
+            $description, $value_is_default, $opts
+        );
+    }
+
+    /**
+     * Displays errors
+     *
+     * @return void
+     */
+    public function displayErrors()
+    {
+        $this->_validate();
+        if (count($this->_errors) == 0) {
+            return;
+        }
+
+        foreach ($this->_errors as $system_path => $error_list) {
+            if (isset($this->_systemPaths[$system_path])) {
+                $path = $this->_systemPaths[$system_path];
+                $name = PMA_lang_name($path);
+            } else {
+                $name = $GLOBALS["strConfigForm_$system_path"];
+            }
+            PMA_displayErrors($name, $error_list);
+        }
+    }
+
+    /**
+     * Reverts erroneous fields to their default values
+     *
+     * @return void
+     */
+    public function fixErrors()
+    {
+        $this->_validate();
+        if (count($this->_errors) == 0) {
+            return;
+        }
+
+        $cf = ConfigFile::getInstance();
+        foreach (array_keys($this->_errors) as $work_path) {
+            if (!isset($this->_systemPaths[$work_path])) {
+                continue;
+            }
+            $canonical_path = $this->_systemPaths[$work_path];
+            $cf->set($work_path, $cf->getDefault($canonical_path));
+        }
+    }
+
+    /**
+     * Validates select field and casts $value to correct type
+     *
+     * @param string $value
+     * @param array  $allowed
+     *
+     * @return bool
+     */
+    private function _validateSelect(&$value, array $allowed)
+    {
+        $value_cmp = is_bool($value)
+            ? (int) $value
+            : $value;
+        foreach ($allowed as $vk => $v) {
+            // equality comparison only if both values are numeric or not numeric
+            // (allows to skip 0 == 'string' equalling to true)
+            // or identity (for string-string)
+            if (($vk == $value && !(is_numeric($value_cmp) xor is_numeric($vk)))
+                || $vk === $value
+            ) {
+                // keep boolean value as boolean
+                if (!is_bool($value)) {
+                    settype($value, gettype($vk));
+                }
+                return true;
+            }
+        }
+        return false;
+    }
+
+    /**
+     * Validates and saves form data to session
+     *
+     * @param array|string $forms              array of form names
+     * @param bool         $allow_partial_save allows for partial form saving on
+     *                                         failed validation
+     *
+     * @return boolean true on success (no errors and all saved)
+     */
+    public function save($forms, $allow_partial_save = true)
+    {
+        $result = true;
+        $cf = ConfigFile::getInstance();
+        $forms = (array) $forms;
+
+        $values = array();
+        $to_save = array();
+        $is_setup_script = defined('PMA_SETUP');
+        if ($is_setup_script) {
+            $this->_loadUserprefsInfo();
+        }
+
+        $this->_errors = array();
+        foreach ($forms as $form_name) {
+            /* @var $form Form */
+            if (isset($this->_forms[$form_name])) {
+                $form = $this->_forms[$form_name];
+            } else {
+                continue;
+            }
+            // get current server id
+            $change_index = $form->index === 0
+                ? $cf->getServerCount() + 1
+                : false;
+            // grab POST values
+            foreach ($form->fields as $field => $system_path) {
+                $work_path = array_search($system_path, $this->_systemPaths);
+                $key = $this->_translatedPaths[$work_path];
+                $type = $form->getOptionType($field);
+
+                // skip groups
+                if ($type == 'group') {
+                    continue;
+                }
+
+                // ensure the value is set
+                if (!isset($_POST[$key])) {
+                    // checkboxes aren't set by browsers if they're off
+                    if ($type == 'boolean') {
+                        $_POST[$key] = false;
+                    } else {
+                        $this->_errors[$form->name][] = sprintf(
+                            __('Missing data for %s'),
+                            '<i>' . PMA_lang_name($system_path) . '</i>'
+                        );
+                        $result = false;
+                        continue;
+                    }
+                }
+
+                // user preferences allow/disallow
+                if ($is_setup_script
+                    && isset($this->_userprefsKeys[$system_path])
+                ) {
+                    if (isset($this->_userprefsDisallow[$system_path])
+                        && isset($_POST[$key . '-userprefs-allow'])
+                    ) {
+                        unset($this->_userprefsDisallow[$system_path]);
+                    } else if (!isset($_POST[$key . '-userprefs-allow'])) {
+                        $this->_userprefsDisallow[$system_path] = true;
+                    }
+                }
+
+                // cast variables to correct type
+                switch ($type) {
+                case 'double':
+                    settype($_POST[$key], 'float');
+                    break;
+                case 'boolean':
+                case 'integer':
+                    if ($_POST[$key] !== '') {
+                        settype($_POST[$key], $type);
+                    }
+                    break;
+                case 'select':
+                    // special treatment for NavigationBarIconic and PropertiesIconic
+                    if ($key === 'NavigationBarIconic'
+                        || $key === 'PropertiesIconic'
+                    ) {
+                        if ($_POST[$key] !== 'both') {
+                            settype($_POST[$key], 'boolean');
+                        }
+                    }
+                    $successfully_validated = $this->_validateSelect(
+                        $_POST[$key],
+                        $form->getOptionValueList($system_path)
+                    );
+                    if (! $successfully_validated) {
+                        $this->_errors[$work_path][] = __('Incorrect value');
+                        $result = false;
+                        continue;
+                    }
+                    break;
+                case 'string':
+                case 'short_string':
+                    $_POST[$key] = trim($_POST[$key]);
+                    break;
+                case 'array':
+                    // eliminate empty values and ensure we have an array
+                    $post_values = is_array($_POST[$key])
+                        ? $_POST[$key]
+                        : explode("\n", $_POST[$key]);
+                    $_POST[$key] = array();
+                    foreach ($post_values as $v) {
+                        $v = trim($v);
+                        if ($v !== '') {
+                            $_POST[$key][] = $v;
+                        }
+                    }
+                    break;
+                }
+
+                // now we have value with proper type
+                $values[$system_path] = $_POST[$key];
+                if ($change_index !== false) {
+                    $work_path = str_replace(
+                        "Servers/$form->index/",
+                        "Servers/$change_index/", $work_path
+                    );
+                }
+                $to_save[$work_path] = $system_path;
+            }
+        }
+
+        // save forms
+        if ($allow_partial_save || empty($this->_errors)) {
+            foreach ($to_save as $work_path => $path) {
+                // TrustedProxies requires changes before saving
+                if ($path == 'TrustedProxies') {
+                    $proxies = array();
+                    $i = 0;
+                    foreach ($values[$path] as $value) {
+                        $matches = array();
+                        $match = preg_match(
+                            "/^(.+):(?:[ ]?)(\\w+)$/", $value, $matches
+                        );
+                        if ($match) {
+                            // correct 'IP: HTTP header' pair
+                            $ip = trim($matches[1]);
+                            $proxies[$ip] = trim($matches[2]);
+                        } else {
+                            // save also incorrect values
+                            $proxies["-$i"] = $value;
+                            $i++;
+                        }
+                    }
+                    $values[$path] = $proxies;
+                }
+                $cf->set($work_path, $values[$path], $path);
+            }
+            if ($is_setup_script) {
+                $cf->set(
+                    'UserprefsDisallow',
+                    array_keys($this->_userprefsDisallow)
+                );
+            }
+        }
+
+        // don't look for non-critical errors
+        $this->_validate();
+
+        return $result;
+    }
+
+    /**
+     * Tells whether form validation failed
+     *
+     * @return boolean
+     */
+    public function hasErrors()
+    {
+        return count($this->_errors) > 0;
+    }
+
+
+    /**
+     * Returns link to documentation
+     *
+     * @param string $path
+     *
+     * @return string
+     */
+    public function getDocLink($path)
+    {
+        $test = substr($path, 0, 6);
+        if ($test == 'Import' || $test == 'Export') {
+            return '';
+        }
+        return PMA_Util::getDocuLink(
+            'config',
+            'cfg_' .  $this->_getOptName($path)
+        );
+    }
+
+    /**
+     * Returns link to wiki
+     *
+     * @param string $path
+     *
+     * @return string
+     */
+    public function getWikiLink($path)
+    {
+        $opt_name = $this->_getOptName($path);
+        if (substr($opt_name, 0, 7) == 'Servers') {
+            $opt_name = substr($opt_name, 8);
+            if (strpos($opt_name, 'AllowDeny') === 0) {
+                $opt_name = str_replace('_', '_.28', $opt_name) . '.29';
+            }
+        }
+        $test = substr($path, 0, 6);
+        if ($test == 'Import') {
+            $opt_name = substr($opt_name, 7);
+            if ($opt_name == 'format') {
+                $opt_name = 'format_2';
+            }
+        }
+        if ($test == 'Export') {
+            $opt_name = substr($opt_name, 7);
+        }
+        return PMA_linkURL('http://wiki.phpmyadmin.net/pma/Config#' . $opt_name);
+    }
+
+    /**
+     * Changes path so it can be used in URLs
+     *
+     * @param string $path
+     *
+     * @return string
+     */
+    private function _getOptName($path)
+    {
+        return str_replace(array('Servers/1/', '/'), array('Servers/', '_'), $path);
+    }
+
+    /**
+     * Fills out {@link userprefs_keys} and {@link userprefs_disallow}
+     *
+     * @return void
+     */
+    private function _loadUserprefsInfo()
+    {
+        if ($this->_userprefsKeys === null) {
+            $this->_userprefsKeys = array_flip(PMA_readUserprefsFieldNames());
+            // read real config for user preferences display
+            $userprefs_disallow = defined('PMA_SETUP')
+                ? ConfigFile::getInstance()->get('UserprefsDisallow', array())
+                : $GLOBALS['cfg']['UserprefsDisallow'];
+            $this->_userprefsDisallow = array_flip($userprefs_disallow);
+        }
+    }
+
+    /**
+     * Sets field comments and warnings based on current environment
+     *
+     * @param string $system_path
+     * @param array  $opts
+     *
+     * @return void
+     */
+    private function _setComments($system_path, array &$opts)
+    {
+        // RecodingEngine - mark unavailable types
+        if ($system_path == 'RecodingEngine') {
+            $comment = '';
+            if (!function_exists('iconv')) {
+                $opts['values']['iconv'] .= ' (' . __('unavailable') . ')';
+                $comment = sprintf(
+                    __('"%s" requires %s extension'), 'iconv', 'iconv'
+                );
+            }
+            if (!function_exists('recode_string')) {
+                $opts['values']['recode'] .= ' (' . __('unavailable') . ')';
+                $comment .= ($comment ? ", " : '') . sprintf(
+                    __('"%s" requires %s extension'),
+                    'recode', 'recode'
+                );
+            }
+            $opts['comment'] = $comment;
+            $opts['comment_warning'] = true;
+        }
+        // ZipDump, GZipDump, BZipDump - check function availability
+        if ($system_path == 'ZipDump'
+            || $system_path == 'GZipDump'
+            || $system_path == 'BZipDump'
+        ) {
+            $comment = '';
+            $funcs = array(
+                'ZipDump'  => array('zip_open', 'gzcompress'),
+                'GZipDump' => array('gzopen', 'gzencode'),
+                'BZipDump' => array('bzopen', 'bzcompress'));
+            if (!function_exists($funcs[$system_path][0])) {
+                $comment = sprintf(
+                    __('import will not work, missing function (%s)'),
+                    $funcs[$system_path][0]
+                );
+            }
+            if (!function_exists($funcs[$system_path][1])) {
+                $comment .= ($comment ? '; ' : '') . sprintf(
+                    __('export will not work, missing function (%s)'),
+                    $funcs[$system_path][1]
+                );
+            }
+            $opts['comment'] = $comment;
+            $opts['comment_warning'] = true;
+        }
+        if ($system_path == 'SQLQuery/Validate'
+            && ! $GLOBALS['cfg']['SQLValidator']['use']
+        ) {
+            $opts['comment'] = __('SQL Validator is disabled');
+            $opts['comment_warning'] = true;
+        }
+        if ($system_path == 'SQLValidator/use') {
+            if (!class_exists('SOAPClient')) {
+                @include_once 'SOAP/Client.php';
+                if (!class_exists('SOAP_Client')) {
+                    $opts['comment'] = __('SOAP extension not found');
+                    $opts['comment_warning'] = true;
+                }
+            }
+        }
+        if (!defined('PMA_SETUP')) {
+            if (($system_path == 'MaxDbList' || $system_path == 'MaxTableList'
+                || $system_path == 'QueryHistoryMax')
+            ) {
+                $opts['comment'] = sprintf(
+                    __('maximum %s'), $GLOBALS['cfg'][$system_path]
+                );
+            }
+        }
+    }
+}
+?>
diff --git a/phpmyadmin/libraries/config/FormDisplay.tpl.php b/phpmyadmin/libraries/config/FormDisplay.tpl.php
new file mode 100644
index 0000000..677e3f4
--- /dev/null
+++ b/phpmyadmin/libraries/config/FormDisplay.tpl.php
@@ -0,0 +1,489 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * Form templates
+ *
+ * @package PhpMyAdmin
+ */
+
+/**
+ * Displays top part of the form
+ *
+ * @param string $action        default: $_SERVER['REQUEST_URI']
+ * @param string $method        'post' or 'get'
+ * @param array  $hidden_fields array of form hidden fields (key: field name)
+ *
+ * @return void
+ */
+function PMA_displayFormTop($action = null, $method = 'post', $hidden_fields = null)
+{
+    static $has_check_page_refresh = false;
+
+    if ($action === null) {
+        $action = $_SERVER['REQUEST_URI'];
+    }
+    if ($method != 'post') {
+        $method = 'get';
+    }
+    echo '<form method="' . $method . '" action="'
+        . htmlspecialchars($action) . '" class="config-form disableAjax">';
+    echo '<input type="hidden" name="tab_hash" value="" />';
+    // we do validation on page refresh when browser remembers field values,
+    // add a field with known value which will be used for checks
+    if (!$has_check_page_refresh) {
+        $has_check_page_refresh = true;
+        echo '<input type="hidden" name="check_page_refresh" '
+            . ' id="check_page_refresh" value="" />' . "\n";
+    }
+    echo PMA_generate_common_hidden_inputs('', '', 0, 'server') . "\n";
+    echo PMA_getHiddenFields((array)$hidden_fields);
+}
+
+/**
+ * Displays form tabs which are given by an array indexed by fieldset id
+ * ({@link PMA_displayFieldsetTop}), with values being tab titles.
+ *
+ * @param array $tabs tab names
+ *
+ * @return void
+ */
+function PMA_displayTabsTop($tabs)
+{
+    echo '<ul class="tabs">';
+    foreach ($tabs as $tab_id => $tab_name) {
+        echo '<li><a href="#' . $tab_id . '">'
+            . htmlspecialchars($tab_name) . '</a></li>';
+    }
+    echo '</ul>';
+    echo '<br clear="right" />';
+    echo '<div class="tabs_contents">';
+}
+
+
+/**
+ * Displays top part of a fieldset
+ *
+ * @param string $title       title of fieldset
+ * @param string $description description shown on top of fieldset
+ * @param array  $errors      error messages to display
+ * @param array  $attributes  optional extra attributes of fieldset
+ *
+ * @return void
+ */
+function PMA_displayFieldsetTop($title = '', $description = '', $errors = null,
+    $attributes = array()
+) {
+    global $_FormDisplayGroup;
+
+    $_FormDisplayGroup = 0;
+
+    $attributes = array_merge(array('class' => 'optbox'), $attributes);
+    foreach ($attributes as $k => &$attr) {
+        $attr = $k . '="' . htmlspecialchars($attr) . '"';
+    }
+
+    echo '<fieldset ' . implode(' ', $attributes) . '>';
+    echo '<legend>' . $title . '</legend>';
+    if (!empty($description)) {
+        echo '<p>' . $description . '</p>';
+    }
+    // this must match with displayErrors() in scripts.js
+    if (is_array($errors) && count($errors) > 0) {
+        echo '<dl class="errors">';
+        foreach ($errors as $error) {
+            echo '<dd>' . $error . '</dd>';
+        }
+        echo '</dl>';
+    }
+    echo '<table width="100%" cellspacing="0">';
+}
+
+/**
+ * Displays input field
+ *
+ * $opts keys:
+ * o doc - (string) documentation link
+ * o errors - error array
+ * o setvalue - (string) shows button allowing to set poredefined value
+ * o show_restore_default - (boolean) whether show "restore default" button
+ * o userprefs_allow - whether user preferences are enabled for this field
+ *                    (null - no support, true/false - enabled/disabled)
+ * o userprefs_comment - (string) field comment
+ * o values - key - value paris for <select> fields
+ * o values_escaped - (boolean) tells whether values array is already escaped
+ *                    (defaults to false)
+ * o values_disabled -  (array)list of disabled values (keys from values)
+ * o comment - (string) tooltip comment
+ * o comment_warning - (bool) whether this comments warns about something
+ * o wiki - (string) wiki link
+ *
+ * @param string $path             config option path
+ * @param string $name             config option name
+ * @param string $type             type of config option
+ * @param mixed  $value            current value
+ * @param string $description      verbose description
+ * @param bool   $value_is_default whether value is default
+ * @param array  $opts             see above description
+ *
+ * @return void
+ */
+function PMA_displayInput($path, $name, $type, $value, $description = '',
+    $value_is_default = true, $opts = null
+) {
+    global $_FormDisplayGroup;
+    static $icons;    // An array of IMG tags used further below in the function
+
+    $is_setup_script = defined('PMA_SETUP');
+    if ($icons === null) { // if the static variables have not been initialised
+        $icons = array();
+        // Icon definitions:
+        // The same indexes will be used in the $icons array.
+        // The first element contains the filename and the second
+        // element is used for the "alt" and "title" attributes.
+        $icon_init = array(
+            'edit'   => array('b_edit.png',   ''),
+            'help'   => array('b_help.png',   __('Documentation')),
+            'info'   => array('b_info.png',   __('Wiki')),
+            'reload' => array('s_reload.png', ''),
+            'tblops' => array('b_tblops.png', '')
+        );
+        if ($is_setup_script) {
+            // When called from the setup script, we don't have access to the
+            // sprite-aware getImage() function because the PMA_theme class
+            // has not been loaded, so we generate the img tags manually.
+            foreach ($icon_init as $k => $v) {
+                $title = '';
+                if (! empty($v[1])) {
+                    $title = ' title="' . $v[1] . '"';
+                }
+                $icons[$k] = sprintf(
+                    '<img alt="%s" src="%s"%s />',
+                    $v[1],
+                    ".{$GLOBALS['cfg']['ThemePath']}/original/img/{$v[0]}",
+                    $title
+                );
+            }
+        } else {
+            // In this case we just use getImage() because it's available
+            foreach ($icon_init as $k => $v) {
+                $icons[$k] = PMA_Util::getImage(
+                    $v[0], $v[1]
+                );
+            }
+        }
+    }
+    $has_errors = isset($opts['errors']) && !empty($opts['errors']);
+    $option_is_disabled = ! $is_setup_script && isset($opts['userprefs_allow'])
+        && ! $opts['userprefs_allow'];
+    $name_id = 'name="' . htmlspecialchars($path) . '" id="'
+        . htmlspecialchars($path) . '"';
+    $field_class = $type == 'checkbox' ? 'checkbox' : '';
+    if (! $value_is_default) {
+        $field_class .= ($field_class == '' ? '' : ' ')
+            . ($has_errors ? 'custom field-error' : 'custom');
+    }
+    $field_class = $field_class ? ' class="' . $field_class . '"' : '';
+    $tr_class = $_FormDisplayGroup > 0
+        ? 'group-field group-field-' . $_FormDisplayGroup
+        : '';
+    if (isset($opts['setvalue']) && $opts['setvalue'] == ':group') {
+        unset($opts['setvalue']);
+        $_FormDisplayGroup++;
+        $tr_class = 'group-header-field group-header-' . $_FormDisplayGroup;
+    }
+    if ($option_is_disabled) {
+        $tr_class .= ($tr_class ? ' ' : '') . 'disabled-field';
+    }
+    $tr_class = $tr_class ? ' class="' . $tr_class . '"' : '';
+
+    echo '<tr' . $tr_class . '>';
+    echo '<th>';
+    echo '<label for="' . htmlspecialchars($path) . '">' . $name . '</label>';
+
+    if (! empty($opts['doc']) || ! empty($opts['wiki'])) {
+        echo '<span class="doc">';
+        if (! empty($opts['doc'])) {
+            echo '<a href="' . $opts['doc']
+                . '" target="documentation">' . $icons['help'] . '</a>';
+            echo "\n";
+        }
+        if (! empty($opts['wiki'])) {
+            echo '<a href="' . $opts['wiki']
+                . '" target="wiki">' . $icons['info'] . '</a>';
+            echo "\n";
+        }
+        echo '</span>';
+    }
+
+    if ($option_is_disabled) {
+        echo '<span class="disabled-notice" title="';
+        echo __(
+            'This setting is disabled, it will not be applied to your configuration'
+        );
+        echo '">' . __('Disabled') . "</span>";
+    }
+
+    if (!empty($description)) {
+        echo '<small>' . $description . '</small>';
+    }
+
+    echo '</th>';
+    echo '<td>';
+
+    switch ($type) {
+    case 'text':
+        echo '<input type="text" size="60" ' . $name_id . $field_class
+            . ' value="' . htmlspecialchars($value) . '" />';
+        break;
+    case 'short_text':
+        echo '<input type="text" size="25" ' . $name_id . $field_class
+            . ' value="' . htmlspecialchars($value) . '" />';
+        break;
+    case 'number_text':
+        echo '<input type="text" size="15" ' . $name_id . $field_class
+            . ' value="' . htmlspecialchars($value) . '" />';
+        break;
+    case 'checkbox':
+        echo '<span' . $field_class . '><input type="checkbox" ' . $name_id
+          . ($value ? ' checked="checked"' : '') . ' /></span>';
+        break;
+    case 'select':
+        echo '<select ' . $name_id . $field_class . '>';
+        $escape = !(isset($opts['values_escaped']) && $opts['values_escaped']);
+        $values_disabled = isset($opts['values_disabled'])
+            ? array_flip($opts['values_disabled']) : array();
+        foreach ($opts['values'] as $opt_value_key => $opt_value) {
+            // set names for boolean values
+            if (is_bool($opt_value)) {
+                $opt_value = strtolower($opt_value ? __('Yes') : __('No'));
+            }
+            // escape if necessary
+            if ($escape) {
+                $display = htmlspecialchars($opt_value);
+                $display_value = htmlspecialchars($opt_value_key);
+            } else {
+                $display = $opt_value;
+                $display_value = $opt_value_key;
+            }
+            // compare with selected value
+            // boolean values are cast to integers when used as array keys
+            $selected = is_bool($value)
+                ? (int) $value === $opt_value_key
+                : $opt_value_key === $value;
+            echo '<option value="' . $display_value . '"';
+            if ($selected) {
+                echo ' selected="selected"';
+            }
+            if (isset($values_disabled[$opt_value_key])) {
+                echo ' disabled="disabled"';
+            }
+            echo '>' . $display . '</option>';
+        }
+        echo '</select>';
+        break;
+    case 'list':
+        echo '<textarea cols="40" rows="5" ' . $name_id . $field_class . '>'
+            . htmlspecialchars(implode("\n", $value))
+            . '</textarea>';
+        break;
+    }
+    if (isset($opts['comment']) && $opts['comment']) {
+        $class = 'field-comment-mark';
+        if (isset($opts['comment_warning']) && $opts['comment_warning']) {
+            $class .= ' field-comment-warning';
+        }
+        echo '<span class="' . $class . '" title="'
+            . htmlspecialchars($opts['comment']) . '">i</span>';
+    }
+    if ($is_setup_script
+        && isset($opts['userprefs_comment'])
+        && $opts['userprefs_comment']
+    ) {
+        echo '<a class="userprefs-comment" title="'
+            . htmlspecialchars($opts['userprefs_comment']) . '">'
+            . $icons['tblops'] . '</a>';
+    }
+    if (isset($opts['setvalue']) && $opts['setvalue']) {
+        echo '<a class="set-value" href="#'
+            . htmlspecialchars("$path={$opts['setvalue']}") . '" title="'
+            . sprintf(__('Set value: %s'), htmlspecialchars($opts['setvalue']))
+            . '" style="display:none">' . $icons['edit'] . '</a>';
+    }
+    if (isset($opts['show_restore_default']) && $opts['show_restore_default']) {
+        echo '<a class="restore-default" href="#' . $path . '" title="'
+            .  __('Restore default value') . '" style="display:none">'
+            . $icons['reload'] . '</a>';
+    }
+    // this must match with displayErrors() in scripts/config.js
+    if ($has_errors) {
+        echo "\n        <dl class=\"inline_errors\">";
+        foreach ($opts['errors'] as $error) {
+            echo '<dd>' . htmlspecialchars($error) . '</dd>';
+        }
+        echo '</dl>';
+    }
+    echo '</td>';
+    if ($is_setup_script && isset($opts['userprefs_allow'])) {
+        echo '<td class="userprefs-allow" title="' .
+            __('Allow users to customize this value') . '">';
+        echo '<input type="checkbox" name="' . $path . '-userprefs-allow" ';
+        if ($opts['userprefs_allow']) {
+            echo 'checked="checked"';
+        };
+        echo '/>';
+        echo '</td>';
+    } else if ($is_setup_script) {
+        echo '<td> </td>';
+    }
+    echo '</tr>';
+}
+
+/**
+ * Display group header
+ *
+ * @param string $header_text Text of header
+ *
+ * @return void
+ */
+function PMA_displayGroupHeader($header_text)
+{
+    global $_FormDisplayGroup;
+
+    $_FormDisplayGroup++;
+    if (!$header_text) {
+        return;
+    }
+    $colspan = defined('PMA_SETUP')
+        ? 3
+        : 2;
+    echo '<tr class="group-header group-header-' . $_FormDisplayGroup . '">';
+    echo '<th colspan="' . $colspan . '">';
+    echo $header_text;
+    echo '</th>';
+    echo '</tr>';
+}
+
+/**
+ * Display group footer
+ *
+ * @return void
+ */
+function PMA_displayGroupFooter()
+{
+    global $_FormDisplayGroup;
+
+    $_FormDisplayGroup--;
+}
+
+/**
+ * Displays bottom part of a fieldset
+ *
+ * @return void
+ */
+function PMA_displayFieldsetBottom()
+{
+    $colspan = 2;
+    if (defined('PMA_SETUP')) {
+        $colspan++;
+    }
+    echo '<tr>';
+    echo '<td colspan="' . $colspan . '" class="lastrow">';
+    echo '<input type="submit" name="submit_save" value="'
+        . __('Save') . '" class="green" />';
+    echo '<input type="button" name="submit_reset" value="'
+        . __('Reset') . '" />';
+    echo '</td>';
+    echo '</tr>';
+    echo '</table>';
+    echo '</fieldset>';
+}
+
+/**
+ * Displays simple bottom part of a fieldset (without submit buttons)
+ *
+ * @return void
+ */
+function PMA_displayFieldsetBottomSimple()
+{
+    echo '</table>';
+    echo '</fieldset>';
+}
+
+/**
+ * Closes form tabs
+ *
+ * @return void
+ */
+function PMA_displayTabsBottom()
+{
+    echo "</div>\n";
+}
+
+/**
+ * Displays bottom part of the form
+ *
+ * @return void
+ */
+function PMA_displayFormBottom()
+{
+    echo "</form>\n";
+}
+
+/**
+ * Appends JS validation code to $js_array
+ *
+ * @param string       $field_id   ID of field to validate
+ * @param string|array $validators validators callback
+ * @param array        &$js_array  will be updated with javascript code
+ *
+ * @return void
+ */
+function PMA_addJsValidate($field_id, $validators, &$js_array)
+{
+    foreach ((array)$validators as $validator) {
+        $validator = (array)$validator;
+        $v_name = array_shift($validator);
+        $v_args = array();
+        foreach ($validator as $arg) {
+            $v_args[] = PMA_escapeJsString($arg);
+        }
+        $v_args = $v_args ? ", ['" . implode("', '", $v_args) . "']" : '';
+        $js_array[] = "validateField('$field_id', '$v_name', true$v_args)";
+    }
+}
+
+/**
+ * Displays JavaScript code
+ *
+ * @param array $js_array lines of javascript code
+ *
+ * @return void
+ */
+function PMA_displayJavascript($js_array)
+{
+    if (empty($js_array)) {
+        return;
+    }
+    echo '<script type="text/javascript">' . "\n";
+    echo implode(";\n", $js_array) . ";\n";
+    echo '</script>' . "\n";
+}
+
+/**
+ * Displays error list
+ *
+ * @param string $name       name of item with errors
+ * @param array  $error_list list of errors to show
+ *
+ * @return void
+ */
+function PMA_displayErrors($name, $error_list)
+{
+    echo '<dl>';
+    echo '<dt>' . htmlspecialchars($name) . '</dt>';
+    foreach ($error_list as $error) {
+        echo '<dd>' . htmlspecialchars($error) . '</dd>';
+    }
+    echo '</dl>';
+}
+?>
diff --git a/phpmyadmin/libraries/config/config_functions.lib.php b/phpmyadmin/libraries/config/config_functions.lib.php
new file mode 100644
index 0000000..44a2624
--- /dev/null
+++ b/phpmyadmin/libraries/config/config_functions.lib.php
@@ -0,0 +1,55 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * Common config manipulation functions
+ *
+ * @package PhpMyAdmin
+ */
+
+/**
+ * Returns sanitized language string, taking into account our special codes
+ * for formatting. Takes variable number of arguments.
+ * Based on PMA_sanitize from sanitize.lib.php.
+ *
+ * @param string $lang_key key in $GLOBALS WITHOUT 'strSetup' prefix
+ * @param mixed  $args,... arguments for sprintf
+ *
+ * @return string
+ */
+function PMA_lang($lang_key, $args = null)
+{
+    $message = isset($GLOBALS["strConfig$lang_key"])
+        ? $GLOBALS["strConfig$lang_key"] : $lang_key;
+
+    $message = PMA_sanitize($message);
+
+    if (func_num_args() == 1) {
+        return $message;
+    } else {
+        $args = func_get_args();
+        array_shift($args);
+        return vsprintf($message, $args);
+    }
+}
+
+/**
+ * Returns translated field name/description or comment
+ *
+ * @param string $canonical_path
+ * @param string $type  'name', 'desc' or 'cmt'
+ * @param mixed  $default
+ *
+ * @return string
+ */
+function PMA_lang_name($canonical_path, $type = 'name', $default = 'key')
+{
+    $lang_key = str_replace(
+        array('Servers/1/', '/'),
+        array('Servers/', '_'),
+        $canonical_path
+    ) . '_' . $type;
+    return isset($GLOBALS["strConfig$lang_key"])
+        ? ($type == 'desc' ? PMA_lang($lang_key) : $GLOBALS["strConfig$lang_key"])
+        : ($default == 'key' ? $lang_key : $default);
+}
+?>
diff --git a/phpmyadmin/libraries/config/messages.inc.php b/phpmyadmin/libraries/config/messages.inc.php
new file mode 100644
index 0000000..988c2eb
--- /dev/null
+++ b/phpmyadmin/libraries/config/messages.inc.php
@@ -0,0 +1,523 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * Messages for phpMyAdmin.
+ *
+ * This file defines variables in a special format suited for the
+ * configuration subsystem, with $strConfig as a prefix, _desc or _name
+ * as a suffix, and the directive name in between.
+ *
+ * @package PhpMyAdmin
+ */
+
+if (!function_exists('__')) {
+    PMA_fatalError('Bad invocation!');
+}
+
+$strConfigAllowArbitraryServer_desc = __('If enabled user can enter any MySQL server in login form for cookie auth');
+$strConfigAllowArbitraryServer_name = __('Allow login to any MySQL server');
+$strConfigAllowUserDropDatabase_name = __('Show "Drop database" link to normal users');
+$strConfigblowfish_secret_desc = __('Secret passphrase used for encrypting cookies in [kbd]cookie[/kbd] authentication');
+$strConfigblowfish_secret_name = __('Blowfish secret');
+$strConfigBrowseMarkerEnable_desc = __('Highlight selected rows');
+$strConfigBrowseMarkerEnable_name = __('Row marker');
+$strConfigBrowsePointerEnable_desc = __('Highlight row pointed by the mouse cursor');
+$strConfigBrowsePointerEnable_name = __('Highlight pointer');
+$strConfigBZipDump_desc = __('Enable [a at http://en.wikipedia.org/wiki/Bzip2]bzip2[/a] compression for import and export operations');
+$strConfigBZipDump_name = __('Bzip2');
+$strConfigCharEditing_desc = __('Defines which type of editing controls should be used for CHAR and VARCHAR columns; [kbd]input[/kbd] - allows limiting of input length, [kbd]textarea[/kbd] - allows newlines in columns');
+$strConfigCharEditing_name = __('CHAR columns editing');
+$strConfigCodemirrorEnable_desc = __('Use user-friendly editor for editing SQL queries ([a at http://codemirror.net/]CodeMirror[/a]) with syntax highlighting and line numbers');
+$strConfigCodemirrorEnable_name = __('Enable CodeMirror');
+$strConfigMinSizeForInputField_desc = __('Defines the minimum size for input fields generated for CHAR and VARCHAR columns');
+$strConfigMinSizeForInputField_name = __('Minimum size for input field');
+$strConfigMaxSizeForInputField_desc = __('Defines the maximum size for input fields generated for CHAR and VARCHAR columns');
+$strConfigMaxSizeForInputField_name = __('Maximum size for input field');
+$strConfigCharTextareaCols_desc = __('Number of columns for CHAR/VARCHAR textareas');
+$strConfigCharTextareaCols_name = __('CHAR textarea columns');
+$strConfigCharTextareaRows_desc = __('Number of rows for CHAR/VARCHAR textareas');
+$strConfigCharTextareaRows_name = __('CHAR textarea rows');
+$strConfigCheckConfigurationPermissions_name = __('Check config file permissions');
+$strConfigCompressOnFly_desc = __('Compress gzip/bzip2 exports on the fly without the need for much memory; if you encounter problems with created gzip/bzip2 files disable this feature');
+$strConfigCompressOnFly_name = __('Compress on the fly');
+$strConfigConfigurationFile = __('Configuration file');
+$strConfigConfirm_desc = __('Whether a warning ("Are your really sure…") should be displayed when you\'re about to lose data');
+$strConfigConfirm_name = __('Confirm DROP queries');
+$strConfigDBG_sql_name = __('Debug SQL');
+$strConfigDefaultDisplay_name = __('Default display direction');
+$strConfigDefaultTabDatabase_desc = __('Tab that is displayed when entering a database');
+$strConfigDefaultTabDatabase_name = __('Default database tab');
+$strConfigDefaultTabServer_desc = __('Tab that is displayed when entering a server');
+$strConfigDefaultTabServer_name = __('Default server tab');
+$strConfigDefaultTabTable_desc = __('Tab that is displayed when entering a table');
+$strConfigDefaultTabTable_name = __('Default table tab');
+$strConfigHideStructureActions_desc = __('Whether the table structure actions should be hidden');
+$strConfigHideStructureActions_name = __('Hide table structure actions');
+$strConfigDisplayBinaryAsHex_desc = __('Show binary contents as HEX by default');
+$strConfigDisplayBinaryAsHex_name = __('Show binary contents as HEX');
+$strConfigDisplayServersList_desc = __('Show server listing as a list instead of a drop down');
+$strConfigDisplayServersList_name = __('Display servers as a list');
+$strConfigDisableMultiTableMaintenance_desc = __('Disable the table maintenance mass operations, like optimizing or repairing the selected tables of a database.');
+$strConfigDisableMultiTableMaintenance_name = __('Disable multi table maintenance');
+$strConfigEditInWindow_desc = __('Edit SQL queries in popup window');
+$strConfigEditInWindow_name = __('Edit in window');
+$strConfigError_Handler_display_name = __('Display errors');
+$strConfigError_Handler_gather_name = __('Gather errors');
+$strConfigExecTimeLimit_desc = __('Set the number of seconds a script is allowed to run ([kbd]0[/kbd] for no limit)');
+$strConfigExecTimeLimit_name = __('Maximum execution time');
+$strConfigExport_asfile_name = __('Save as file');
+$strConfigExport_charset_name = __('Character set of the file');
+$strConfigExport_codegen_format_name = __('Format');
+$strConfigExport_compression_name = __('Compression');
+$strConfigExport_csv_columns_name = __('Put columns names in the first row');
+$strConfigExport_csv_enclosed_name = __('Columns enclosed by');
+$strConfigExport_csv_escaped_name = __('Columns escaped by');
+$strConfigExport_csv_null_name = __('Replace NULL by');
+$strConfigExport_csv_removeCRLF_name = __('Remove CRLF characters within columns');
+$strConfigExport_csv_separator_name = __('Columns terminated by');
+$strConfigExport_csv_terminated_name = __('Lines terminated by');
+$strConfigExport_excel_columns_name = __('Put columns names in the first row');
+$strConfigExport_excel_edition_name = __('Excel edition');
+$strConfigExport_excel_null_name = __('Replace NULL by');
+$strConfigExport_excel_removeCRLF_name = __('Remove CRLF characters within columns');
+$strConfigExport_file_template_database_name = __('Database name template');
+$strConfigExport_file_template_server_name = __('Server name template');
+$strConfigExport_file_template_table_name = __('Table name template');
+$strConfigExport_format_name = __('Format');
+$strConfigExport_htmlword_columns_name = __('Put columns names in the first row');
+$strConfigExport_htmlword_null_name = __('Replace NULL by');
+$strConfigExport_htmlword_structure_or_data_name = __('Dump table');
+$strConfigExport_latex_caption_name = __('Include table caption');
+$strConfigExport_latex_columns_name = __('Put columns names in the first row');
+$strConfigExport_latex_comments_name = __('Comments');
+$strConfigExport_latex_data_caption_name = __('Table caption');
+$strConfigExport_latex_data_continued_caption_name = __('Continued table caption');
+$strConfigExport_latex_data_label_name = __('Label key');
+$strConfigExport_latex_mime_name = __('MIME type');
+$strConfigExport_latex_null_name  = __('Replace NULL by');
+$strConfigExport_latex_relation_name = __('Relations');
+$strConfigExport_latex_structure_caption_name = __('Table caption');
+$strConfigExport_latex_structure_continued_caption_name = __('Continued table caption');
+$strConfigExport_latex_structure_label_name = __('Label key');
+$strConfigExport_latex_structure_or_data_name = __('Dump table');
+$strConfigExport_method_name = __('Export method');
+$strConfigExport_ods_columns_name = __('Put columns names in the first row');
+$strConfigExport_ods_null_name = __('Replace NULL by');
+$strConfigExport_odt_columns_name = __('Put columns names in the first row');
+$strConfigExport_odt_comments_name = __('Comments');
+$strConfigExport_odt_mime_name = __('MIME type');
+$strConfigExport_odt_null_name = __('Replace NULL by');
+$strConfigExport_odt_relation_name = __('Relations');
+$strConfigExport_odt_structure_or_data_name = __('Dump table');
+$strConfigExport_onserver_name = __('Save on server');
+$strConfigExport_onserver_overwrite_name = __('Overwrite existing file(s)');
+$strConfigExport_quick_export_onserver_name = __('Save on server');
+$strConfigExport_quick_export_onserver_overwrite_name = __('Overwrite existing file(s)');
+$strConfigExport_remember_file_template_name = __('Remember file name template');
+$strConfigExport_sql_auto_increment_name = __('Add AUTO_INCREMENT value');
+$strConfigExport_sql_backquotes_name = __('Enclose table and column names with backquotes');
+$strConfigExport_sql_compatibility_name = __('SQL compatibility mode');
+$strConfigExport_sql_create_table_statements_name = __('<code>CREATE TABLE</code> options:');
+$strConfigExport_sql_dates_name = __('Creation/Update/Check dates');
+$strConfigExport_sql_delayed_name = __('Use delayed inserts');
+$strConfigExport_sql_disable_fk_name = __('Disable foreign key checks');
+$strConfigExport_sql_drop_database_name = sprintf(__('Add %s'), 'DROP DATABASE');
+$strConfigExport_sql_drop_table_name = sprintf(__('Add %s'), 'DROP TABLE / VIEW / PROCEDURE / FUNCTION / EVENT');
+$strConfigExport_sql_hex_for_blob_name = __('Use hexadecimal for BLOB');
+$strConfigExport_sql_if_not_exists_name = sprintf(__('Add %s'), 'IF NOT EXISTS');
+$strConfigExport_sql_ignore_name = __('Use ignore inserts');
+$strConfigExport_sql_include_comments_name = __('Comments');
+$strConfigExport_sql_insert_syntax_name = __('Syntax to use when inserting data');
+$strConfigExport_sql_max_query_size_name = __('Maximal length of created query');
+$strConfigExport_sql_mime_name = __('MIME type');
+$strConfigExport_sql_procedure_function_name = sprintf(__('Add %s'), 'CREATE PROCEDURE / FUNCTION / EVENT');
+$strConfigExport_sql_relation_name = __('Relations');
+$strConfigExport_sql_structure_or_data_name = __('Dump table');
+$strConfigExport_sql_type_name = __('Export type');
+$strConfigExport_sql_use_transaction_name = __('Enclose export in a transaction');
+$strConfigExport_sql_utc_time_name = __('Export time in UTC');
+$strConfigExport_texytext_columns_name = __('Put columns names in the first row');
+$strConfigExport_texytext_null_name = __('Replace NULL by');
+$strConfigExport_texytext_structure_or_data_name = __('Dump table');
+$strConfigExport_xls_columns_name = __('Put columns names in the first row');
+$strConfigExport_xls_null_name = __('Replace NULL by');
+$strConfigExport_xlsx_columns_name = __('Put columns names in the first row');
+$strConfigExport_xlsx_null_name = __('Replace NULL by');
+$strConfigForceSSL_desc = __('Force secured connection while using phpMyAdmin');
+$strConfigForceSSL_name = __('Force SSL connection');
+$strConfigForeignKeyDropdownOrder_desc = __('Sort order for items in a foreign-key dropdown box; [kbd]content[/kbd] is the referenced data, [kbd]id[/kbd] is the key value');
+$strConfigForeignKeyDropdownOrder_name = __('Foreign key dropdown order');
+$strConfigForeignKeyMaxLimit_desc = __('A dropdown will be used if fewer items are present');
+$strConfigForeignKeyMaxLimit_name = __('Foreign key limit');
+$strConfigForm_Browse = __('Browse mode');
+$strConfigForm_Browse_desc = __('Customize browse mode');
+$strConfigForm_CodeGen = 'CodeGen';
+$strConfigForm_CodeGen_desc = __('Customize default options');
+$strConfigForm_Csv = __('CSV');
+$strConfigForm_Csv_desc = __('Customize default options');
+$strConfigForm_Developer = __('Developer');
+$strConfigForm_Developer_desc = __('Settings for phpMyAdmin developers');
+$strConfigForm_Edit = __('Edit mode');
+$strConfigForm_Edit_desc = __('Customize edit mode');
+$strConfigForm_Export = __('Export');
+$strConfigForm_Export_defaults = __('Export defaults');
+$strConfigForm_Export_defaults_desc = __('Customize default export options');
+$strConfigForm_Features = __('Features');
+$strConfigForm_General = __('General');
+$strConfigForm_General_desc = __('Set some commonly used options');
+$strConfigForm_Import = __('Import');
+$strConfigForm_Import_defaults = __('Import defaults');
+$strConfigForm_Import_defaults_desc = __('Customize default common import options');
+$strConfigForm_Import_export = __('Import / export');
+$strConfigForm_Import_export_desc = __('Set import and export directories and compression options');
+$strConfigForm_Latex = __('LaTeX');
+$strConfigForm_Latex_desc = __('Customize default options');
+$strConfigForm_Navi_databases = __('Databases');
+$strConfigForm_Navi_databases_desc = __('Databases display options');
+$strConfigForm_Navi_panel = __('Navigation panel');
+$strConfigForm_Navi_panel_desc = __('Customize appearance of the navigation panel');
+$strConfigForm_Navi_servers = __('Servers');
+$strConfigForm_Navi_servers_desc = __('Servers display options');
+$strConfigForm_Navi_tables = __('Tables');
+$strConfigForm_Navi_tables_desc = __('Tables display options');
+$strConfigForm_Main_panel = __('Main panel');
+$strConfigForm_Microsoft_Office = __('Microsoft Office');
+$strConfigForm_Microsoft_Office_desc = __('Customize default options');
+$strConfigForm_Open_Document = 'OpenDocument';
+$strConfigForm_Open_Document_desc = __('Customize default options');
+$strConfigForm_Other_core_settings = __('Other core settings');
+$strConfigForm_Other_core_settings_desc = __('Settings that didn\'t fit anywhere else');
+$strConfigForm_Page_titles = __('Page titles');
+$strConfigForm_Page_titles_desc = __('Specify browser\'s title bar text. Refer to [doc at cfg_TitleTable]documentation[/doc] for magic strings that can be used to get special values.');
+$strConfigForm_Query_window = __('Query window');
+$strConfigForm_Query_window_desc = __('Customize query window options');
+$strConfigForm_Security = __('Security');
+$strConfigForm_Security_desc = __('Please note that phpMyAdmin is just a user interface and its features do not limit MySQL');
+$strConfigForm_Server = __('Basic settings');
+$strConfigForm_Server_auth = __('Authentication');
+$strConfigForm_Server_auth_desc = __('Authentication settings');
+$strConfigForm_Server_config = __('Server configuration');
+$strConfigForm_Server_config_desc = __('Advanced server configuration, do not change these options unless you know what they are for');
+$strConfigForm_Server_desc = __('Enter server connection parameters');
+$strConfigForm_Server_pmadb = __('Configuration storage');
+$strConfigForm_Server_pmadb_desc = __('Configure phpMyAdmin configuration storage to gain access to additional features, see [doc at linked-tables]phpMyAdmin configuration storage[/doc] in documentation');
+$strConfigForm_Server_tracking = __('Changes tracking');
+$strConfigForm_Server_tracking_desc = __('Tracking of changes made in database. Requires the phpMyAdmin configuration storage.');
+$strConfigFormset_Export = __('Customize export options');
+$strConfigFormset_Features = __('Features');
+$strConfigFormset_Import = __('Customize import defaults');
+$strConfigFormset_Navi_panel = __('Customize navigation panel');
+$strConfigFormset_Main_panel = __('Customize main panel');
+$strConfigFormset_Sql_queries = __('SQL queries');
+$strConfigForm_Sql = __('SQL');
+$strConfigForm_Sql_box = __('SQL Query box');
+$strConfigForm_Sql_box_desc = __('Customize links shown in SQL Query boxes');
+$strConfigForm_Sql_desc = __('Customize default options');
+$strConfigForm_Sql_queries = __('SQL queries');
+$strConfigForm_Sql_queries_desc = __('SQL queries settings');
+$strConfigForm_Sql_validator = __('SQL Validator');
+$strConfigForm_Sql_validator_desc = __('If you wish to use the SQL Validator service, you should be aware that [strong]all SQL statements are stored anonymously for statistical purposes[/strong].[br][em][a at http://sqlvalidator.mimer.com/]Mimer SQL Validator[/a], Copyright 2002 Upright Database Technology. All rights reserved.[/em]');
+$strConfigForm_Startup = __('Startup');
+$strConfigForm_Startup_desc = __('Customize startup page');
+$strConfigForm_DbStructure = __('Database structure');
+$strConfigForm_DbStructure_desc = __('Choose which details to show in the database structure (list of tables)');
+$strConfigForm_TableStructure = __('Table structure');
+$strConfigForm_TableStructure_desc = __('Settings for the table structure (list of columns)');
+$strConfigForm_Tabs = __('Tabs');
+$strConfigForm_Tabs_desc = __('Choose how you want tabs to work');
+$strConfigForm_Text_fields = __('Text fields');
+$strConfigForm_Text_fields_desc = __('Customize text input fields');
+$strConfigForm_Texy = __('Texy! text');
+$strConfigForm_Texy_desc = __('Customize default options');
+$strConfigForm_Warnings = __('Warnings');
+$strConfigForm_Warnings_desc = __('Disable some of the warnings shown by phpMyAdmin');
+$strConfigGZipDump_desc = __('Enable [a at http://en.wikipedia.org/wiki/Gzip]gzip[/a] compression for import and export operations');
+$strConfigGZipDump_name = __('GZip');
+$strConfigIconvExtraParams_name = __('Extra parameters for iconv');
+$strConfigIgnoreMultiSubmitErrors_desc = __('If enabled, phpMyAdmin continues computing multiple-statement queries even if one of the queries failed');
+$strConfigIgnoreMultiSubmitErrors_name = __('Ignore multiple statement errors');
+$strConfigImport_allow_interrupt_desc = __('Allow interrupt of import in case script detects it is close to time limit. This might be a good way to import large files, however it can break transactions.');
+$strConfigImport_allow_interrupt_name = __('Partial import: allow interrupt');
+$strConfigImport_charset_name = __('Character set of the file');
+$strConfigImport_csv_col_names_name = __('Lines terminated by');
+$strConfigImport_csv_enclosed_name = __('Columns enclosed by');
+$strConfigImport_csv_escaped_name = __('Columns escaped by');
+$strConfigImport_csv_ignore_name = __('Do not abort on INSERT error');
+$strConfigImport_csv_replace_name = __('Replace table data with file');
+$strConfigImport_csv_terminated_name = __('Columns terminated by');
+$strConfigImport_format_desc = __('Default format; be aware that this list depends on location (database, table) and only SQL is always available');
+$strConfigImport_format_name = __('Format of imported file');
+$strConfigImport_ldi_enclosed_name = __('Columns enclosed by');
+$strConfigImport_ldi_escaped_name = __('Columns escaped by');
+$strConfigImport_ldi_ignore_name = __('Do not abort on INSERT error');
+$strConfigImport_ldi_local_option_name = __('Use LOCAL keyword');
+$strConfigImport_ldi_replace_name = __('Replace table data with file');
+$strConfigImport_ldi_terminated_name = __('Columns terminated by');
+$strConfigImport_ods_col_names_name = __('Column names in first row');
+$strConfigImport_ods_empty_rows_name = __('Do not import empty rows');
+$strConfigImport_ods_recognize_currency_name = __('Import currencies ($5.00 to 5.00)');
+$strConfigImport_ods_recognize_percentages_name = __('Import percentages as proper decimals (12.00% to .12)');
+$strConfigImport_skip_queries_desc = __('Number of queries to skip from start');
+$strConfigImport_skip_queries_name = __('Partial import: skip queries');
+$strConfigImport_sql_compatibility_name = __('SQL compatibility mode');
+$strConfigImport_sql_no_auto_value_on_zero_name = __('Do not use AUTO_INCREMENT for zero values');
+$strConfigImport_xls_col_names_name = __('Column names in first row');
+$strConfigImport_xlsx_col_names_name = __('Column names in first row');
+$strConfigInitialSlidersState_name = __('Initial state for sliders');
+$strConfigInsertRows_desc = __('How many rows can be inserted at one time');
+$strConfigInsertRows_name = __('Number of inserted rows');
+$strConfigLimitChars_desc = __('Maximum number of characters shown in any non-numeric column on browse view');
+$strConfigLimitChars_name = __('Limit column characters');
+$strConfigLoginCookieDeleteAll_desc = __('If TRUE, logout deletes cookies for all servers; when set to FALSE, logout only occurs for the current server. Setting this to FALSE makes it easy to forget to log out from other servers when connected to multiple servers.');
+$strConfigLoginCookieDeleteAll_name = __('Delete all cookies on logout');
+$strConfigLoginCookieRecall_desc = __('Define whether the previous login should be recalled or not in cookie authentication mode');
+$strConfigLoginCookieRecall_name = __('Recall user name');
+$strConfigLoginCookieStore_desc = __('Defines how long (in seconds) a login cookie should be stored in browser. The default of 0 means that it will be kept for the existing session only, and will be deleted as soon as you close the browser window. This is recommended for non-trusted environments.');
+$strConfigLoginCookieStore_name = __('Login cookie store');
+$strConfigLoginCookieValidity_desc = __('Define how long (in seconds) a login cookie is valid');
+$strConfigLoginCookieValidity_name = __('Login cookie validity');
+$strConfigLongtextDoubleTextarea_desc = __('Double size of textarea for LONGTEXT columns');
+$strConfigLongtextDoubleTextarea_name = __('Bigger textarea for LONGTEXT');
+$strConfigMaxCharactersInDisplayedSQL_desc = __('Maximum number of characters used when a SQL query is displayed');
+$strConfigMaxCharactersInDisplayedSQL_name = __('Maximum displayed SQL length');
+$strConfigMaxDbList_cmt = __('Users cannot set a higher value');
+$strConfigMaxDbList_desc = __('Maximum number of databases displayed in database list');
+$strConfigMaxDbList_name = __('Maximum databases');
+$strConfigMaxNavigationItems_desc = __('The number of items that can be displayed on each page of the navigation tree');
+$strConfigMaxNavigationItems_name = __('Maximum items in branch');
+$strConfigMaxRows_desc = __('Number of rows displayed when browsing a result set. If the result set contains more rows, "Previous" and "Next" links will be shown.');
+$strConfigMaxRows_name = __('Maximum number of rows to display');
+$strConfigMaxTableList_cmt = __('Users cannot set a higher value');
+$strConfigMaxTableList_desc = __('Maximum number of tables displayed in table list');
+$strConfigMaxTableList_name = __('Maximum tables');
+$strConfigMcryptDisableWarning_desc = __('Disable the default warning that is displayed if mcrypt is missing for cookie authentication');
+$strConfigMcryptDisableWarning_name = __('mcrypt warning');
+$strConfigMemoryLimit_desc = __('The number of bytes a script is allowed to allocate, eg. [kbd]32M[/kbd] ([kbd]0[/kbd] for no limit)');
+$strConfigMemoryLimit_name = __('Memory limit');
+$strConfigNavigationDisplayLogo_desc = __('Show logo in navigation panel');
+$strConfigNavigationDisplayLogo_name = __('Display logo');
+$strConfigNavigationLogoLink_desc = __('URL where logo in the navigation panel will point to');
+$strConfigNavigationLogoLink_name = __('Logo link URL');
+$strConfigNavigationLogoLinkWindow_desc = __('Open the linked page in the main window ([kbd]main[/kbd]) or in a new one ([kbd]new[/kbd])');
+$strConfigNavigationLogoLinkWindow_name = __('Logo link target');
+$strConfigNavigationDisplayServers_desc = __('Display server choice at the top of the navigation panel');
+$strConfigNavigationDisplayServers_name = __('Display servers selection');
+$strConfigNavigationTreeDefaultTabTable_name = __('Target for quick access icon');
+$strConfigNavigationTreeDisplayItemFilterMinimum_desc = __('Defines the minimum number of items (tables, views, routines and events) to display a filter box.');
+$strConfigNavigationTreeDisplayItemFilterMinimum_name = __('Minimum number of items to display the filter box');
+$strConfigNavigationTreeDisplayDbFilterMinimum_name = __('Minimum number of databases to display the database filter box');
+$strConfigNavigationTreeEnableGrouping_desc = __('Group items in the navigation tree (determined by the separator defined below)');
+$strConfigNavigationTreeEnableGrouping_name = __('Group items in the tree');
+$strConfigNavigationTreeDbSeparator_desc = __('String that separates databases into different tree levels');
+$strConfigNavigationTreeDbSeparator_name = __('Database tree separator');
+$strConfigNavigationTreeTableSeparator_desc = __('String that separates tables into different tree levels');
+$strConfigNavigationTreeTableSeparator_name = __('Table tree separator');
+$strConfigNavigationTreeTableLevel_name = __('Maximum table tree depth');
+$strConfigNavigationTreePointerEnable_desc = __('Highlight server under the mouse cursor');
+$strConfigNavigationTreePointerEnable_name = __('Enable highlighting');
+$strConfigNumRecentTables_desc = __('Maximum number of recently used tables; set 0 to disable');
+$strConfigNumRecentTables_name = __('Recently used tables');
+$strConfigRowActionLinks_desc = __('These are Edit, Copy and Delete links');
+$strConfigRowActionLinks_name = __('Where to show the table row links');
+$strConfigNaturalOrder_desc = __('Use natural order for sorting table and database names');
+$strConfigNaturalOrder_name = __('Natural order');
+$strConfigNavigationBarIconic_desc = __('Use only icons, only text or both');
+$strConfigNavigationBarIconic_name = __('Iconic navigation bar');
+$strConfigOBGzip_desc = __('use GZip output buffering for increased speed in HTTP transfers');
+$strConfigOBGzip_name = __('GZip output buffering');
+$strConfigOrder_desc = __('[kbd]SMART[/kbd] - i.e. descending order for columns of type TIME, DATE, DATETIME and TIMESTAMP, ascending order otherwise');
+$strConfigOrder_name = __('Default sorting order');
+$strConfigPersistentConnections_desc = __('Use persistent connections to MySQL databases');
+$strConfigPersistentConnections_name = __('Persistent connections');
+$strConfigPmaNoRelation_DisableWarning_desc = __('Disable the default warning that is displayed on the database details Structure page if any of the required tables for the phpMyAdmin configuration storage could not be found');
+$strConfigPmaNoRelation_DisableWarning_name = __('Missing phpMyAdmin configuration storage tables');
+$strConfigServerLibraryDifference_DisableWarning_desc = __('Disable the default warning that is displayed if a difference between the MySQL library and server is detected');
+$strConfigServerLibraryDifference_DisableWarning_name = __('Server/library difference warning');
+$strConfigReservedWordDisableWarning_desc = __('Disable the default warning that is displayed on the Structure page if column names in a table are reserved MySQL words');
+$strConfigReservedWordDisableWarning_name = __('MySQL reserved word warning');
+$strConfigPropertiesIconic_desc = __('Use only icons, only text or both');
+$strConfigPropertiesIconic_name = __('Iconic table operations');
+$strConfigProtectBinary_desc = __('Disallow BLOB and BINARY columns from editing');
+$strConfigProtectBinary_name = __('Protect binary columns');
+$strConfigQueryHistoryDB_desc = __('Enable if you want DB-based query history (requires phpMyAdmin configuration storage). If disabled, this utilizes JS-routines to display query history (lost by window close).');
+$strConfigQueryHistoryDB_name = __('Permanent query history');
+$strConfigQueryHistoryMax_cmt = __('Users cannot set a higher value');
+$strConfigQueryHistoryMax_desc = __('How many queries are kept in history');
+$strConfigQueryHistoryMax_name = __('Query history length');
+$strConfigQueryWindowDefTab_desc = __('Tab displayed when opening a new query window');
+$strConfigQueryWindowDefTab_name = __('Default query window tab');
+$strConfigQueryWindowHeight_desc = __('Query window height (in pixels)');
+$strConfigQueryWindowHeight_name = __('Query window height');
+$strConfigQueryWindowWidth_desc = __('Query window width (in pixels)');
+$strConfigQueryWindowWidth_name = __('Query window width');
+$strConfigRecodingEngine_desc = __('Select which functions will be used for character set conversion');
+$strConfigRecodingEngine_name = __('Recoding engine');
+$strConfigRememberSorting_desc = __('When browsing tables, the sorting of each table is remembered');
+$strConfigRememberSorting_name = __('Remember table\'s sorting');
+$strConfigRepeatCells_desc = __('Repeat the headers every X cells, [kbd]0[/kbd] deactivates this feature');
+$strConfigRepeatCells_name = __('Repeat headers');
+$strConfigRestoreDefaultValue = __('Restore default value');
+$strConfigGridEditing_name = __('Grid editing: trigger action');
+$strConfigSaveCellsAtOnce_name = __('Grid editing: save all edited cells at once');
+$strConfigSaveDir_desc = __('Directory where exports can be saved on server');
+$strConfigSaveDir_name = __('Save directory');
+$strConfigServers_AllowDeny_order_desc = __('Leave blank if not used');
+$strConfigServers_AllowDeny_order_name = __('Host authorization order');
+$strConfigServers_AllowDeny_rules_desc = __('Leave blank for defaults');
+$strConfigServers_AllowDeny_rules_name = __('Host authorization rules');
+$strConfigServers_AllowNoPassword_name = __('Allow logins without a password');
+$strConfigServers_AllowRoot_name = __('Allow root login');
+$strConfigServers_auth_http_realm_desc = __('HTTP Basic Auth Realm name to display when doing HTTP Auth');
+$strConfigServers_auth_http_realm_name = __('HTTP Realm');
+$strConfigServers_auth_swekey_config_desc = __('The path for the config file for [a at http://swekey.com]SweKey hardware authentication[/a] (not located in your document root; suggested: /etc/swekey.conf)');
+$strConfigServers_auth_swekey_config_name = __('SweKey config file');
+$strConfigServers_auth_type_desc = __('Authentication method to use');
+$strConfigServers_auth_type_name = __('Authentication type');
+$strConfigServers_bookmarktable_desc = __('Leave blank for no [a at http://wiki.phpmyadmin.net/pma/bookmark]bookmark[/a] support, suggested: [kbd]pma__bookmark[/kbd]');
+$strConfigServers_bookmarktable_name = __('Bookmark table');
+$strConfigServers_column_info_desc = __('Leave blank for no column comments/mime types, suggested: [kbd]pma__column_info[/kbd]');
+$strConfigServers_column_info_name = __('Column information table');
+$strConfigServers_compress_desc = __('Compress connection to MySQL server');
+$strConfigServers_compress_name = __('Compress connection');
+$strConfigServers_connect_type_desc = __('How to connect to server, keep [kbd]tcp[/kbd] if unsure');
+$strConfigServers_connect_type_name = __('Connection type');
+$strConfigServers_controlpass_name = __('Control user password');
+$strConfigServers_controluser_desc = __('A special MySQL user configured with limited permissions, more information available on [a at http://wiki.phpmyadmin.net/pma/controluser]wiki[/a]');
+$strConfigServers_controluser_name = __('Control user');
+$strConfigServers_controlhost_desc = __('An alternate host to hold the configuration storage; leave blank to use the already defined host');
+$strConfigServers_controlhost_name = __('Control host');
+$strConfigServers_designer_coords_desc = __('Leave blank for no Designer support, suggested: [kbd]pma__designer_coords[/kbd]');
+$strConfigServers_designer_coords_name = __('Designer table');
+$strConfigServers_DisableIS_desc = __('More information on [a at https://sourceforge.net/p/phpmyadmin/bugs/2606/]PMA bug tracker[/a] and [a at http://bugs.mysql.com/19588]MySQL Bugs[/a]');
+$strConfigServers_DisableIS_name = __('Disable use of INFORMATION_SCHEMA');
+$strConfigServers_extension_desc = __('What PHP extension to use; you should use mysqli if supported');
+$strConfigServers_extension_name = __('PHP extension to use');
+$strConfigServers_hide_db_desc = __('Hide databases matching regular expression (PCRE)');
+$strConfigServers_hide_db_name = __('Hide databases');
+$strConfigServers_history_desc = __('Leave blank for no SQL query history support, suggested: [kbd]pma__history[/kbd]');
+$strConfigServers_history_name = __('SQL query history table');
+$strConfigServers_host_desc = __('Hostname where MySQL server is running');
+$strConfigServers_host_name = __('Server hostname');
+$strConfigServers_LogoutURL_name = __('Logout URL');
+$strConfigServers_MaxTableUiprefs_desc = __('Limits number of table preferences which are stored in database, the oldest records are automatically removed');
+$strConfigServers_MaxTableUiprefs_name = __('Maximal number of table preferences to store');
+$strConfigServers_nopassword_desc = __('Try to connect without password');
+$strConfigServers_nopassword_name = __('Connect without password');
+$strConfigServers_only_db_desc = __('You can use MySQL wildcard characters (% and _), escape them if you want to use their literal instances, i.e. use [kbd]\'my\_db\'[/kbd] and not [kbd]\'my_db\'[/kbd].');
+$strConfigServers_only_db_name = __('Show only listed databases');
+$strConfigServers_password_desc = __('Leave empty if not using config auth');
+$strConfigServers_password_name = __('Password for config auth');
+$strConfigServers_pdf_pages_desc = __('Leave blank for no PDF schema support, suggested: [kbd]pma__pdf_pages[/kbd]');
+$strConfigServers_pdf_pages_name = __('PDF schema: pages table');
+$strConfigServers_pmadb_desc = __('Database used for relations, bookmarks, and PDF features. See [a at http://wiki.phpmyadmin.net/pma/pmadb]pmadb[/a] for complete information. Leave blank for no support. Suggested: [kbd]phpmyadmin[/kbd]');
+$strConfigServers_pmadb_name = __('Database name');
+$strConfigServers_port_desc = __('Port on which MySQL server is listening, leave empty for default');
+$strConfigServers_port_name = __('Server port');
+$strConfigServers_recent_desc = __('Leave blank for no "persistent" recently used tables across sessions, suggested: [kbd]pma__recent[/kbd]');
+$strConfigServers_recent_name = __('Recently used table');
+$strConfigServers_relation_desc = __('Leave blank for no [a at http://wiki.phpmyadmin.net/pma/relation]relation-links[/a] support, suggested: [kbd]pma__relation[/kbd]');
+$strConfigServers_relation_name = __('Relation table');
+$strConfigServers_ShowDatabasesCommand_desc = __('SQL command to fetch available databases');
+$strConfigServers_ShowDatabasesCommand_name = __('SHOW DATABASES command');
+$strConfigServers_SignonSession_desc = __('See [a at http://wiki.phpmyadmin.net/pma/auth_types#signon]authentication types[/a] for an example');
+$strConfigServers_SignonSession_name = __('Signon session name');
+$strConfigServers_SignonURL_name = __('Signon URL');
+$strConfigServers_socket_desc = __('Socket on which MySQL server is listening, leave empty for default');
+$strConfigServers_socket_name = __('Server socket');
+$strConfigServers_ssl_desc = __('Enable SSL for connection to MySQL server');
+$strConfigServers_ssl_name = __('Use SSL');
+$strConfigServers_table_coords_desc = __('Leave blank for no PDF schema support, suggested: [kbd]pma__table_coords[/kbd]');
+$strConfigServers_table_coords_name = __('PDF schema: table coordinates');
+$strConfigServers_table_info_desc = __('Table to describe the display columns, leave blank for no support; suggested: [kbd]pma__table_info[/kbd]');
+$strConfigServers_table_info_name = __('Display columns table');
+$strConfigServers_table_uiprefs_desc = __('Leave blank for no "persistent" tables\'UI preferences across sessions, suggested: [kbd]pma__table_uiprefs[/kbd]');
+$strConfigServers_table_uiprefs_name = __('UI preferences table');
+$strConfigServers_tracking_add_drop_database_desc = __('Whether a DROP DATABASE IF EXISTS statement will be added as first line to the log when creating a database.');
+$strConfigServers_tracking_add_drop_database_name = __('Add DROP DATABASE');
+$strConfigServers_tracking_add_drop_table_desc = __('Whether a DROP TABLE IF EXISTS statement will be added as first line to the log when creating a table.');
+$strConfigServers_tracking_add_drop_table_name = __('Add DROP TABLE');
+$strConfigServers_tracking_add_drop_view_desc = __('Whether a DROP VIEW IF EXISTS statement will be added as first line to the log when creating a view.');
+$strConfigServers_tracking_add_drop_view_name = __('Add DROP VIEW');
+$strConfigServers_tracking_default_statements_desc = __('Defines the list of statements the auto-creation uses for new versions.');
+$strConfigServers_tracking_default_statements_name = __('Statements to track');
+$strConfigServers_tracking_desc = __('Leave blank for no SQL query tracking support, suggested: [kbd]pma__tracking[/kbd]');
+$strConfigServers_tracking_name = __('SQL query tracking table');
+$strConfigServers_tracking_version_auto_create_desc = __('Whether the tracking mechanism creates versions for tables and views automatically.');
+$strConfigServers_tracking_version_auto_create_name = __('Automatically create versions');
+$strConfigServers_userconfig_desc = __('Leave blank for no user preferences storage in database, suggested: [kbd]pma__userconfig[/kbd]');
+$strConfigServers_userconfig_name = __('User preferences storage table');
+$strConfigServers_user_desc = __('Leave empty if not using config auth');
+$strConfigServers_user_name = __('User for config auth');
+$strConfigServers_verbose_desc = __('A user-friendly description of this server. Leave blank to display the hostname instead.');
+$strConfigServers_verbose_name = __('Verbose name of this server');
+$strConfigShowAll_desc = __('Whether a user should be displayed a "show all (rows)" button');
+$strConfigShowAll_name = __('Allow to display all the rows');
+$strConfigShowChgPassword_desc = __('Please note that enabling this has no effect with [kbd]config[/kbd] authentication mode because the password is hard coded in the configuration file; this does not limit the ability to execute the same command directly');
+$strConfigShowChgPassword_name = __('Show password change form');
+$strConfigShowCreateDb_name = __('Show create database form');
+$strConfigShowDbStructureCreation_desc = __('Show or hide a column displaying the Creation timestamp for all tables');
+$strConfigShowDbStructureCreation_name = __('Show Creation timestamp');
+$strConfigShowDbStructureLastUpdate_desc = __('Show or hide a column displaying the Last update timestamp for all tables');
+$strConfigShowDbStructureLastUpdate_name = __('Show Last update timestamp');
+$strConfigShowDbStructureLastCheck_desc = __('Show or hide a column displaying the Last check timestamp for all tables');
+$strConfigShowDbStructureLastCheck_name = __('Show Last check timestamp');
+$strConfigShowDisplayDirection_desc = __('Defines whether or not type display direction option is shown when browsing a table');
+$strConfigShowDisplayDirection_name = __('Show display direction');
+$strConfigShowFieldTypesInDataEditView_desc = __('Defines whether or not type fields should be initially displayed in edit/insert mode');
+$strConfigShowFieldTypesInDataEditView_name = __('Show field types');
+$strConfigShowFunctionFields_desc = __('Display the function fields in edit/insert mode');
+$strConfigShowFunctionFields_name = __('Show function fields');
+$strConfigShowHint_desc = __('Whether to show hint or not');
+$strConfigShowHint_name = __('Show hint');
+$strConfigShowPhpInfo_desc = __('Shows link to [a at http://php.net/manual/function.phpinfo.php]phpinfo()[/a] output');
+$strConfigShowPhpInfo_name = __('Show phpinfo() link');
+$strConfigShowServerInfo_name = __('Show detailed MySQL server information');
+$strConfigShowSQL_desc = __('Defines whether SQL queries generated by phpMyAdmin should be displayed');
+$strConfigShowSQL_name = __('Show SQL queries');
+$strConfigRetainQueryBox_desc = __('Defines whether the query box should stay on-screen after its submission');
+$strConfigRetainQueryBox_name = __('Retain query box');
+$strConfigShowStats_desc = __('Allow to display database and table statistics (eg. space usage)');
+$strConfigShowStats_name = __('Show statistics');
+$strConfigShowTooltip_name = __('Display table comments in tooltips');
+$strConfigSkipLockedTables_desc = __('Mark used tables and make it possible to show databases with locked tables');
+$strConfigSkipLockedTables_name = __('Skip locked tables');
+$strConfigSQLQuery_Edit_name = __('Edit');
+$strConfigSQLQuery_Explain_name = __('Explain SQL');
+$strConfigSQLQuery_Refresh_name = __('Refresh');
+$strConfigSQLQuery_ShowAsPHP_name = __('Create PHP Code');
+$strConfigSQLQuery_Validate_desc = __('Requires SQL Validator to be enabled');
+$strConfigSQLQuery_Validate_name = __('Validate SQL');
+$strConfigSQLValidator_password_name = __('Password');
+$strConfigSQLValidator_use_desc = __('[strong]Warning:[/strong] requires PHP SOAP extension or PEAR SOAP to be installed');
+$strConfigSQLValidator_use_name = __('Enable SQL Validator');
+$strConfigSQLValidator_username_desc = __('If you have a custom username, specify it here (defaults to [kbd]anonymous[/kbd])');
+$strConfigSQLValidator_username_name = __('Username');
+$strConfigSuhosinDisableWarning_desc = __('A warning is displayed on the main page if Suhosin is detected');
+$strConfigSuhosinDisableWarning_name = __('Suhosin warning');
+$strConfigTextareaCols_desc = __('Textarea size (columns) in edit mode, this value will be emphasized for SQL query textareas (*2) and for query window (*1.25)');
+$strConfigTextareaCols_name = __('Textarea columns');
+$strConfigTextareaRows_desc = __('Textarea size (rows) in edit mode, this value will be emphasized for SQL query textareas (*2) and for query window (*1.25)');
+$strConfigTextareaRows_name = __('Textarea rows');
+$strConfigTitleDatabase_desc = __('Title of browser window when a database is selected');
+$strConfigTitleDatabase_name = __('Database');
+$strConfigTitleDefault_desc = __('Title of browser window when nothing is selected');
+$strConfigTitleDefault_name = __('Default title');
+$strConfigTitleServer_desc = __('Title of browser window when a server is selected');
+$strConfigTitleServer_name = __('Server');
+$strConfigTitleTable_desc = __('Title of browser window when a table is selected');
+$strConfigTitleTable_name = __('Table');
+$strConfigTrustedProxies_desc = __('Input proxies as [kbd]IP: trusted HTTP header[/kbd]. The following example specifies that phpMyAdmin should trust a HTTP_X_FORWARDED_FOR (X-Forwarded-For) header coming from the proxy 1.2.3.4:[br][kbd]1.2.3.4: HTTP_X_FORWARDED_FOR[/kbd]');
+$strConfigTrustedProxies_name = __('List of trusted proxies for IP allow/deny');
+$strConfigUploadDir_desc = __('Directory on server where you can upload files for import');
+$strConfigUploadDir_name = __('Upload directory');
+$strConfigUseDbSearch_desc = __('Allow for searching inside the entire database');
+$strConfigUseDbSearch_name = __('Use database search');
+$strConfigUserprefsDeveloperTab_desc = __('When disabled, users cannot set any of the options below, regardless of the checkbox on the right');
+$strConfigUserprefsDeveloperTab_name = __('Enable the Developer tab in settings');
+$strConfigVersionCheckLink = __('Check for latest version');
+$strConfigVersionCheck_desc = __('Enables check for latest version on main phpMyAdmin page');
+$strConfigVersionCheck_name = __('Version check');
+$strConfigZipDump_desc = __('Enable [a at http://en.wikipedia.org/wiki/ZIP_(file_format)]ZIP[/a] compression for import and export operations');
+$strConfigZipDump_name = __('ZIP');
+
+?>
diff --git a/phpmyadmin/libraries/config/setup.forms.php b/phpmyadmin/libraries/config/setup.forms.php
new file mode 100644
index 0000000..4a9cb1b
--- /dev/null
+++ b/phpmyadmin/libraries/config/setup.forms.php
@@ -0,0 +1,367 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * List of avaible forms, each form is described as an array of fields to display.
+ * Fields MUST have their counterparts in the $cfg array.
+ *
+ * There are two possible notations:
+ * $forms['Form group']['Form name'] = array('Servers' => array(1 => array('host')));
+ * can be written as
+ * $forms['Form group']['Form name'] = array('Servers/1/host');
+ *
+ * You can assign default values set by special button ("set value: ..."), eg.:
+ * 'Servers/1/pmadb' => 'phpmyadmin'
+ *
+ * To group options, use:
+ * ':group:' . __('group name') // just define a group
+ * or
+ * 'option' => ':group' // group starting from this option
+ * End group blocks with:
+ * ':group:end'
+ *
+ * @package PhpMyAdmin-Setup
+ */
+
+$forms = array();
+$forms['_config.php'] = array(
+    'DefaultLang',
+    'ServerDefault');
+$forms['Servers']['Server'] = array('Servers' => array(1 => array(
+    'verbose',
+    'host',
+    'port',
+    'socket',
+    'ssl',
+    'connect_type',
+    'extension',
+    'compress',
+    'nopassword')));
+$forms['Servers']['Server_auth'] = array('Servers' => array(1 => array(
+    'auth_type',
+    ':group:' . __('Config authentication'),
+        'user',
+        'password',
+        ':group:end',
+    ':group:' . __('Cookie authentication'),
+        'auth_swekey_config' => './swekey.conf',
+        ':group:end',
+    ':group:' . __('HTTP authentication'),
+        'auth_http_realm',
+        ':group:end',
+    ':group:' . __('Signon authentication'),
+        'SignonSession',
+        'SignonURL',
+        'LogoutURL')));
+$forms['Servers']['Server_config'] = array('Servers' => array(1 => array(
+    'only_db',
+    'hide_db',
+    'AllowRoot',
+    'AllowNoPassword',
+    'DisableIS',
+    'AllowDeny/order',
+    'AllowDeny/rules',
+    'ShowDatabasesCommand')));
+$forms['Servers']['Server_pmadb'] = array('Servers' => array(1 => array(
+    'pmadb' => 'phpmyadmin',
+    'controlhost',
+    'controluser',
+    'controlpass',
+    'bookmarktable' => 'pma__bookmark',
+    'relation' => 'pma__relation',
+    'userconfig' => 'pma__userconfig',
+    'table_info' => 'pma__table_info',
+    'column_info' => 'pma__column_info',
+    'history' => 'pma__history',
+    'recent' => 'pma__recent',
+    'table_uiprefs' => 'pma__table_uiprefs',
+    'tracking' => 'pma__tracking',
+    'table_coords' => 'pma__table_coords',
+    'pdf_pages' => 'pma__pdf_pages',
+    'designer_coords' => 'pma__designer_coords',
+    'MaxTableUiprefs' => 100)));
+$forms['Servers']['Server_tracking'] = array('Servers' => array(1 => array(
+    'tracking_version_auto_create',
+    'tracking_default_statements',
+    'tracking_add_drop_view',
+    'tracking_add_drop_table',
+    'tracking_add_drop_database',
+)));
+$forms['Features']['Import_export'] = array(
+    'UploadDir',
+    'SaveDir',
+    'RecodingEngine' => ':group',
+        'IconvExtraParams',
+        ':group:end',
+    'ZipDump',
+    'GZipDump',
+    'BZipDump',
+    'CompressOnFly');
+$forms['Features']['Security'] = array(
+    'blowfish_secret',
+    'ForceSSL',
+    'CheckConfigurationPermissions',
+    'TrustedProxies',
+    'AllowUserDropDatabase',
+    'AllowArbitraryServer',
+    'LoginCookieRecall',
+    'LoginCookieValidity',
+    'LoginCookieStore',
+    'LoginCookieDeleteAll');
+$forms['Features']['Page_titles'] = array(
+    'TitleDefault',
+    'TitleTable',
+    'TitleDatabase',
+    'TitleServer');
+$forms['Features']['Warnings'] = array(
+    'ServerLibraryDifference_DisableWarning',
+    'PmaNoRelation_DisableWarning',
+    'SuhosinDisableWarning',
+    'McryptDisableWarning');
+$forms['Features']['Developer'] = array(
+    'UserprefsDeveloperTab',
+    'Error_Handler/display',
+    'Error_Handler/gather',
+    'DBG/sql');
+$forms['Features']['Other_core_settings'] = array(
+    'VersionCheck',
+    'NaturalOrder',
+    'InitialSlidersState',
+    'MaxDbList',
+    'MaxTableList',
+    'NumRecentTables',
+    'ShowHint',
+    'OBGzip',
+    'PersistentConnections',
+    'ExecTimeLimit',
+    'MemoryLimit',
+    'SkipLockedTables',
+    'DisableMultiTableMaintenance',
+    'UseDbSearch');
+$forms['Sql_queries']['Sql_queries'] = array(
+    'ShowSQL',
+    'Confirm',
+    'QueryHistoryDB',
+    'QueryHistoryMax',
+    'IgnoreMultiSubmitErrors',
+    'MaxCharactersInDisplayedSQL',
+    'EditInWindow',
+    //'QueryWindowWidth', // overridden in theme
+    //'QueryWindowHeight',
+    'QueryWindowDefTab',
+    'RetainQueryBox',
+    'CodemirrorEnable');
+$forms['Sql_queries']['Sql_box'] = array('SQLQuery' => array(
+    'Edit',
+    'Explain',
+    'ShowAsPHP',
+    'Validate',
+    'Refresh'));
+$forms['Sql_queries']['Sql_validator'] = array('SQLValidator' => array(
+    'use',
+    'username',
+    'password'));
+$forms['Navi_panel']['Navi_panel'] = array(
+    'NavigationDisplayLogo',
+    'NavigationLogoLink',
+    'NavigationLogoLinkWindow',
+    'NavigationTreePointerEnable',
+    'MaxNavigationItems',
+    'NavigationTreeEnableGrouping',
+    'NavigationTreeDisplayItemFilterMinimum');
+$forms['Navi_panel']['Navi_servers'] = array(
+    'NavigationDisplayServers',
+    'DisplayServersList');
+$forms['Navi_panel']['Navi_databases'] = array(
+    'NavigationTreeDbSeparator');
+$forms['Navi_panel']['Navi_tables'] = array(
+    'NavigationTreeDefaultTabTable',
+    'NavigationTreeTableSeparator',
+    'NavigationTreeTableLevel',
+    'ShowTooltip');
+$forms['Main_panel']['Startup'] = array(
+    'ShowCreateDb',
+    'ShowStats',
+    'ShowServerInfo',
+    'ShowPhpInfo',
+    'ShowChgPassword');
+$forms['Main_panel']['DbStructure'] = array(
+    'ShowDbStructureCreation',
+    'ShowDbStructureLastUpdate',
+    'ShowDbStructureLastCheck');
+$forms['Main_panel']['TableStructure'] = array(
+    'HideStructureActions');
+$forms['Main_panel']['Browse'] = array(
+    'NavigationBarIconic',
+    'ShowAll',
+    'MaxRows',
+    'Order',
+    'BrowsePointerEnable',
+    'BrowseMarkerEnable',
+    'GridEditing',
+    'SaveCellsAtOnce',
+    'ShowDisplayDirection',
+    'RepeatCells',
+    'LimitChars',
+    'RowActionLinks',
+    'DefaultDisplay',
+    'RememberSorting');
+$forms['Main_panel']['Edit'] = array(
+    'ProtectBinary',
+    'ShowFunctionFields',
+    'ShowFieldTypesInDataEditView',
+    'CharEditing',
+    'MinSizeForInputField',
+    'MaxSizeForInputField',
+    'CharTextareaCols',
+    'CharTextareaRows',
+    'TextareaCols',
+    'TextareaRows',
+    'LongtextDoubleTextarea',
+    'InsertRows',
+    'ForeignKeyDropdownOrder',
+    'ForeignKeyMaxLimit');
+$forms['Main_panel']['Tabs'] = array(
+    'PropertiesIconic',
+    'DefaultTabServer',
+    'DefaultTabDatabase',
+    'DefaultTabTable',
+    'QueryWindowDefTab');
+$forms['Import']['Import_defaults'] = array('Import' => array(
+    'format',
+    'charset',
+    'allow_interrupt',
+    'skip_queries'));
+$forms['Import']['Sql'] = array('Import' => array(
+    'sql_compatibility',
+    'sql_no_auto_value_on_zero'));
+$forms['Import']['Csv'] = array('Import' => array(
+    ':group:' . __('CSV'),
+        'csv_replace',
+        'csv_ignore',
+        'csv_terminated',
+        'csv_enclosed',
+        'csv_escaped',
+        'csv_col_names',
+        ':group:end',
+    ':group:' . __('CSV using LOAD DATA'),
+        'ldi_replace',
+        'ldi_ignore',
+        'ldi_terminated',
+        'ldi_enclosed',
+        'ldi_escaped',
+        'ldi_local_option',
+        ':group:end'));
+$forms['Import']['Open_Document'] = array('Import' => array(
+    ':group:' . __('OpenDocument Spreadsheet'),
+        'ods_col_names',
+        'ods_empty_rows',
+        'ods_recognize_percentages',
+        'ods_recognize_currency'));
+$forms['Export']['Export_defaults'] = array('Export' => array(
+    'method',
+    ':group:' . __('Quick'),
+        'quick_export_onserver',
+        'quick_export_onserver_overwrite',
+        ':group:end',
+    ':group:' . __('Custom'),
+        'format',
+        'compression',
+        'charset',
+        'asfile' => ':group',
+            'onserver',
+            'onserver_overwrite',
+            ':group:end',
+        'remember_file_template',
+        'file_template_table',
+        'file_template_database',
+        'file_template_server'));
+$forms['Export']['Sql'] = array('Export' => array(
+    'sql_include_comments' => ':group',
+        'sql_dates',
+        'sql_relation',
+        'sql_mime',
+        ':group:end',
+    'sql_use_transaction',
+    'sql_disable_fk',
+    'sql_compatibility',
+    ':group:' . __('Database export options'),
+        'sql_drop_database',
+        'sql_structure_or_data',
+        ':group:end',
+    ':group:' . __('Structure'),
+        'sql_drop_table',
+        'sql_procedure_function',
+        'sql_create_table_statements' => ':group',
+            'sql_if_not_exists',
+            'sql_auto_increment',
+            ':group:end',
+        'sql_backquotes',
+        ':group:end',
+    ':group:' . __('Data'),
+        'sql_delayed',
+        'sql_ignore',
+        'sql_type',
+        'sql_insert_syntax',
+        'sql_max_query_size',
+        'sql_hex_for_blob',
+        'sql_utc_time'));
+$forms['Export']['CodeGen'] = array('Export' => array(
+    'codegen_format'));
+$forms['Export']['Csv'] = array('Export' => array(
+    ':group:' . __('CSV'),
+        'csv_separator',
+        'csv_enclosed',
+        'csv_escaped',
+        'csv_terminated',
+        'csv_null',
+        'csv_removeCRLF',
+        'csv_columns',
+        ':group:end',
+    ':group:' . __('CSV for MS Excel'),
+        'excel_null',
+        'excel_removeCRLF',
+        'excel_columns',
+        'excel_edition'));
+$forms['Export']['Latex'] = array('Export' => array(
+    'latex_caption',
+    'latex_structure_or_data',
+    ':group:' . __('Structure'),
+        'latex_structure_caption',
+        'latex_structure_continued_caption',
+        'latex_structure_label',
+        'latex_relation',
+        'latex_comments',
+        'latex_mime',
+        ':group:end',
+    ':group:' . __('Data'),
+        'latex_columns',
+        'latex_data_caption',
+        'latex_data_continued_caption',
+        'latex_data_label',
+        'latex_null'));
+$forms['Export']['Microsoft_Office'] = array('Export' => array(
+    ':group:' . __('Microsoft Word 2000'),
+        'htmlword_structure_or_data',
+        'htmlword_null',
+        'htmlword_columns'));
+$forms['Export']['Open_Document'] = array('Export' => array(
+    ':group:' . __('OpenDocument Spreadsheet'),
+        'ods_columns',
+        'ods_null',
+        ':group:end',
+    ':group:' . __('OpenDocument Text'),
+        'odt_structure_or_data',
+        ':group:' . __('Structure'),
+            'odt_relation',
+            'odt_comments',
+            'odt_mime',
+            ':group:end',
+        ':group:' . __('Data'),
+            'odt_columns',
+            'odt_null'));
+$forms['Export']['Texy'] = array('Export' => array(
+    'texytext_structure_or_data',
+    ':group:' . __('Data'),
+        'texytext_null',
+        'texytext_columns'));
+?>
diff --git a/phpmyadmin/libraries/config/user_preferences.forms.php b/phpmyadmin/libraries/config/user_preferences.forms.php
new file mode 100644
index 0000000..e2d2bda
--- /dev/null
+++ b/phpmyadmin/libraries/config/user_preferences.forms.php
@@ -0,0 +1,271 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * List of avaible forms, each form is described as an array of fields to display.
+ * Fields MUST have their counterparts in the $cfg array.
+ *
+ * To define form field, use the notatnion below:
+ * $forms['Form group']['Form name'] = array('Option/path');
+ *
+ * You can assign default values set by special button ("set value: ..."), eg.:
+ * 'Servers/1/pmadb' => 'phpmyadmin'
+ *
+ * To group options, use:
+ * ':group:' . __('group name') // just define a group
+ * or
+ * 'option' => ':group' // group starting from this option
+ * End group blocks with:
+ * ':group:end'
+ *
+ * @package PhpMyAdmin
+ */
+
+$forms = array();
+$forms['Features']['General'] = array(
+    'VersionCheck',
+    'NaturalOrder',
+    'InitialSlidersState',
+    'LoginCookieValidity',
+    'Servers/1/only_db', // saves to Server/only_db
+    'Servers/1/hide_db', // saves to Server/hide_db
+    'SkipLockedTables',
+    'DisableMultiTableMaintenance',
+    'MaxDbList',
+    'MaxTableList',
+    'NumRecentTables',
+    'ShowHint');
+$forms['Features']['Text_fields'] = array(
+    'CharEditing',
+    'MinSizeForInputField',
+    'MaxSizeForInputField',
+    'CharTextareaCols',
+    'CharTextareaRows',
+    'TextareaCols',
+    'TextareaRows',
+    'LongtextDoubleTextarea');
+$forms['Features']['Page_titles'] = array(
+    'TitleDefault',
+    'TitleTable',
+    'TitleDatabase',
+    'TitleServer');
+$forms['Features']['Warnings'] = array(
+    'ServerLibraryDifference_DisableWarning',
+    'PmaNoRelation_DisableWarning',
+    'SuhosinDisableWarning',
+    'McryptDisableWarning',
+    'ReservedWordDisableWarning');
+// settings from this form are treated specially,
+// see prefs_forms.php and user_preferences.lib.php
+$forms['Features']['Developer'] = array(
+    'Error_Handler/display',
+    'Error_Handler/gather',
+    'DBG/sql');
+$forms['Sql_queries']['Sql_queries'] = array(
+    'ShowSQL',
+    'Confirm',
+    'QueryHistoryMax',
+    'IgnoreMultiSubmitErrors',
+    'MaxCharactersInDisplayedSQL',
+    'EditInWindow',
+    //'QueryWindowWidth', // overridden in theme
+    //'QueryWindowHeight',
+    'QueryWindowDefTab',
+    'RetainQueryBox',
+    'CodemirrorEnable');
+$forms['Sql_queries']['Sql_box'] = array(
+    'SQLQuery/Edit',
+    'SQLQuery/Explain',
+    'SQLQuery/ShowAsPHP',
+    'SQLQuery/Validate',
+    'SQLQuery/Refresh');
+$forms['Navi_panel']['Navi_panel'] = array(
+    'NavigationDisplayLogo',
+    'NavigationLogoLink',
+    'NavigationLogoLinkWindow',
+    'NavigationTreePointerEnable',
+    'MaxNavigationItems',
+    'NavigationTreeEnableGrouping',
+    'NavigationTreeDisplayItemFilterMinimum');
+$forms['Navi_panel']['Navi_databases'] = array(
+    'NavigationTreeDisplayDbFilterMinimum',
+    'NavigationTreeDbSeparator');
+$forms['Navi_panel']['Navi_tables'] = array(
+    'NavigationTreeDefaultTabTable',
+    'NavigationTreeTableSeparator',
+    'NavigationTreeTableLevel',
+    'ShowTooltip');
+$forms['Main_panel']['Startup'] = array(
+    'ShowCreateDb',
+    'ShowStats',
+    'ShowServerInfo');
+$forms['Main_panel']['DbStructure'] = array(
+    'ShowDbStructureCreation',
+    'ShowDbStructureLastUpdate',
+    'ShowDbStructureLastCheck');
+$forms['Main_panel']['TableStructure'] = array(
+    'HideStructureActions');
+$forms['Main_panel']['Browse'] = array(
+    'NavigationBarIconic',
+    'PropertiesIconic',
+    'ShowAll',
+    'MaxRows',
+    'Order',
+    'DisplayBinaryAsHex',
+    'BrowsePointerEnable',
+    'BrowseMarkerEnable',
+    'GridEditing',
+    'SaveCellsAtOnce',
+    'ShowDisplayDirection',
+    'RepeatCells',
+    'LimitChars',
+    'RowActionLinks',
+    'DefaultDisplay',
+    'RememberSorting');
+$forms['Main_panel']['Edit'] = array(
+    'ProtectBinary',
+    'ShowFunctionFields',
+    'ShowFieldTypesInDataEditView',
+    'InsertRows',
+    'ForeignKeyDropdownOrder',
+    'ForeignKeyMaxLimit');
+$forms['Main_panel']['Tabs'] = array(
+    'DefaultTabServer',
+    'DefaultTabDatabase',
+    'DefaultTabTable');
+$forms['Import']['Import_defaults'] = array(
+    'Import/format',
+    'Import/charset',
+    'Import/allow_interrupt',
+    'Import/skip_queries');
+$forms['Import']['Sql'] = array(
+    'Import/sql_compatibility',
+    'Import/sql_no_auto_value_on_zero');
+$forms['Import']['Csv'] = array(
+    ':group:' . __('CSV'),
+        'Import/csv_replace',
+        'Import/csv_ignore',
+        'Import/csv_terminated',
+        'Import/csv_enclosed',
+        'Import/csv_escaped',
+        'Import/csv_col_names',
+        ':group:end',
+    ':group:' . __('CSV using LOAD DATA'),
+        'Import/ldi_replace',
+        'Import/ldi_ignore',
+        'Import/ldi_terminated',
+        'Import/ldi_enclosed',
+        'Import/ldi_escaped',
+        'Import/ldi_local_option');
+$forms['Import']['Open_Document'] = array(
+    ':group:' . __('OpenDocument Spreadsheet'),
+        'Import/ods_col_names',
+        'Import/ods_empty_rows',
+        'Import/ods_recognize_percentages',
+        'Import/ods_recognize_currency');
+$forms['Export']['Export_defaults'] = array(
+    'Export/method',
+    ':group:' . __('Quick'),
+        'Export/quick_export_onserver',
+        'Export/quick_export_onserver_overwrite',
+        ':group:end',
+    ':group:' . __('Custom'),
+        'Export/format',
+        'Export/compression',
+        'Export/charset',
+        'Export/asfile' => ':group',
+            'Export/onserver',
+            'Export/onserver_overwrite',
+            ':group:end',
+        'Export/file_template_table',
+        'Export/file_template_database',
+        'Export/file_template_server');
+$forms['Export']['Sql'] = array(
+    'Export/sql_include_comments' => ':group',
+        'Export/sql_dates',
+        'Export/sql_relation',
+        'Export/sql_mime',
+        ':group:end',
+    'Export/sql_use_transaction',
+    'Export/sql_disable_fk',
+    'Export/sql_compatibility',
+    ':group:' . __('Database export options'),
+        'Export/sql_drop_database',
+        'Export/sql_structure_or_data',
+        ':group:end',
+    ':group:' . __('Structure'),
+        'Export/sql_drop_table',
+        'Export/sql_procedure_function',
+        'Export/sql_create_table_statements' => ':group',
+            'Export/sql_if_not_exists',
+            'Export/sql_auto_increment',
+            ':group:end',
+        'Export/sql_backquotes',
+        ':group:end',
+    ':group:' . __('Data'),
+        'Export/sql_delayed',
+        'Export/sql_ignore',
+        'Export/sql_type',
+        'Export/sql_insert_syntax',
+        'Export/sql_max_query_size',
+        'Export/sql_hex_for_blob',
+        'Export/sql_utc_time');
+$forms['Export']['CodeGen'] = array(
+    'Export/codegen_format');
+$forms['Export']['Csv'] = array(
+    ':group:' . __('CSV'),
+        'Export/csv_separator',
+        'Export/csv_enclosed',
+        'Export/csv_escaped',
+        'Export/csv_terminated',
+        'Export/csv_null',
+        'Export/csv_removeCRLF',
+        'Export/csv_columns',
+        ':group:end',
+    ':group:' . __('CSV for MS Excel'),
+        'Export/excel_null',
+        'Export/excel_removeCRLF',
+        'Export/excel_columns',
+        'Export/excel_edition');
+$forms['Export']['Latex'] = array(
+    'Export/latex_caption',
+    'Export/latex_structure_or_data',
+    ':group:' . __('Structure'),
+        'Export/latex_structure_caption',
+        'Export/latex_structure_continued_caption',
+        'Export/latex_structure_label',
+        'Export/latex_relation',
+        'Export/latex_comments',
+        'Export/latex_mime',
+        ':group:end',
+    ':group:' . __('Data'),
+        'Export/latex_columns',
+        'Export/latex_data_caption',
+        'Export/latex_data_continued_caption',
+        'Export/latex_data_label',
+        'Export/latex_null');
+$forms['Export']['Microsoft_Office'] = array(
+    ':group:' . __('Microsoft Word 2000'),
+        'Export/htmlword_structure_or_data',
+        'Export/htmlword_null',
+        'Export/htmlword_columns');
+$forms['Export']['Open_Document'] = array(
+    ':group:' . __('OpenDocument Spreadsheet'),
+        'Export/ods_columns',
+        'Export/ods_null',
+        ':group:end',
+    ':group:' . __('OpenDocument Text'),
+        'Export/odt_structure_or_data',
+        ':group:' . __('Structure'),
+            'Export/odt_relation',
+            'Export/odt_comments',
+            'Export/odt_mime',
+            ':group:end',
+        ':group:' . __('Data'),
+            'Export/odt_columns',
+            'Export/odt_null');
+$forms['Export']['Texy'] = array(
+    'Export/texytext_structure_or_data',
+    ':group:' . __('Data'),
+        'Export/texytext_null',
+        'Export/texytext_columns');
+?>
diff --git a/phpmyadmin/libraries/config/validate.lib.php b/phpmyadmin/libraries/config/validate.lib.php
new file mode 100644
index 0000000..cd03b6b
--- /dev/null
+++ b/phpmyadmin/libraries/config/validate.lib.php
@@ -0,0 +1,584 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * Various validation functions
+ *
+ * Validation function takes two argument: id for which it is called
+ * and array of fields' values (usually values for entire formset, as defined
+ * in forms.inc.php).
+ * The function must always return an array with an error (or error array)
+ * assigned to a form element (formset name or field path). Even if there are
+ * no errors, key must be set with an empty value.
+ *
+ * Valdiation functions are assigned in $cfg_db['_validators'] (config.values.php).
+ *
+ * @package PhpMyAdmin
+ */
+
+/**
+ * Returns validator list
+ *
+ * @return array
+ */
+function PMA_config_get_validators()
+{
+    static $validators = null;
+
+    if ($validators === null) {
+        $cf = ConfigFile::getInstance();
+        $validators = $cf->getDbEntry('_validators', array());
+        if (!defined('PMA_SETUP')) {
+            // not in setup script: load additional validators for user
+            // preferences we need original config values not overwritten
+            // by user preferences, creating a new PMA_Config instance is a
+            // better idea than hacking into its code
+            $org_cfg = $cf->getOrgConfigObj();
+            $uvs = $cf->getDbEntry('_userValidators', array());
+            foreach ($uvs as $field => $uv_list) {
+                $uv_list = (array)$uv_list;
+                foreach ($uv_list as &$uv) {
+                    if (!is_array($uv)) {
+                        continue;
+                    }
+                    for ($i = 1; $i < count($uv); $i++) {
+                        if (substr($uv[$i], 0, 6) == 'value:') {
+                            $uv[$i] = PMA_arrayRead(
+                                substr($uv[$i], 6), $org_cfg->settings
+                            );
+                        }
+                    }
+                }
+                $validators[$field] = isset($validators[$field])
+                    ? array_merge((array)$validators[$field], $uv_list)
+                    : $uv_list;
+            }
+        }
+    }
+    return $validators;
+}
+
+/**
+ * Runs validation $validator_id on values $values and returns error list.
+ *
+ * Return values:
+ * o array, keys - field path or formset id, values - array of errors
+ *   when $isPostSource is true values is an empty array to allow for error list
+ *   cleanup in HTML documen
+ * o false - when no validators match name(s) given by $validator_id
+ *
+ * @param string|array $validator_id ID of validator(s) to run
+ * @param array        &$values      Values to validate
+ * @param bool         $isPostSource tells whether $values are directly from
+ *                                   POST request
+ *
+ * @return bool|array
+ */
+function PMA_config_validate($validator_id, &$values, $isPostSource)
+{
+    // find validators
+    $validator_id = (array) $validator_id;
+    $validators = PMA_config_get_validators();
+    $vids = array();
+    $cf = ConfigFile::getInstance();
+    foreach ($validator_id as &$vid) {
+        $vid = $cf->getCanonicalPath($vid);
+        if (isset($validators[$vid])) {
+            $vids[] = $vid;
+        }
+    }
+    if (empty($vids)) {
+        return false;
+    }
+
+    // create argument list with canonical paths and remember path mapping
+    $arguments = array();
+    $key_map = array();
+    foreach ($values as $k => $v) {
+        $k2 = $isPostSource ? str_replace('-', '/', $k) : $k;
+        $k2 = strpos($k2, '/') ? $cf->getCanonicalPath($k2) : $k2;
+        $key_map[$k2] = $k;
+        $arguments[$k2] = $v;
+    }
+
+    // validate
+    $result = array();
+    foreach ($vids as $vid) {
+        // call appropriate validation functions
+        foreach ((array)$validators[$vid] as $validator) {
+            $vdef = (array) $validator;
+            $vname = array_shift($vdef);
+            $args = array_merge(array($vid, &$arguments), $vdef);
+            $r = call_user_func_array($vname, $args);
+
+            // merge results
+            if (is_array($r)) {
+                foreach ($r as $key => $error_list) {
+                    // skip empty values if $isPostSource is false
+                    if (!$isPostSource && empty($error_list)) {
+                        continue;
+                    }
+                    if (!isset($result[$key])) {
+                        $result[$key] = array();
+                    }
+                    $result[$key] = array_merge($result[$key], (array)$error_list);
+                }
+            }
+        }
+    }
+
+    // restore original paths
+    $new_result = array();
+    foreach ($result as $k => $v) {
+        $k2 = isset($key_map[$k]) ? $key_map[$k] : $k;
+        $new_result[$k2] = $v;
+    }
+    return empty($new_result) ? true : $new_result;
+}
+
+/**
+ * Empty error handler, used to temporarily restore PHP internal error handler
+ *
+ * @return bool
+ */
+function PMA_null_error_handler()
+{
+    return false;
+}
+
+/**
+ * Ensures that $php_errormsg variable will be registered in case of an error
+ * and enables output buffering (when $start = true).
+ * Called with $start = false disables output buffering end restores
+ * html_errors and track_errors.
+ *
+ * @param boolean $start Whether to start buffering
+ *
+ * @return void
+ */
+function test_php_errormsg($start = true)
+{
+    static $old_html_errors, $old_track_errors, $old_error_reporting;
+    static $old_display_errors;
+    if ($start) {
+        $old_html_errors = ini_get('html_errors');
+        $old_track_errors = ini_get('track_errors');
+        $old_display_errors = ini_get('display_errors');
+        $old_error_reporting = error_reporting(E_ALL);
+        ini_set('html_errors', false);
+        ini_set('track_errors', true);
+        ini_set('display_errors', true);
+        set_error_handler("PMA_null_error_handler");
+        ob_start();
+    } else {
+        ob_end_clean();
+        restore_error_handler();
+        error_reporting($old_error_reporting);
+        ini_set('html_errors', $old_html_errors);
+        ini_set('track_errors', $old_track_errors);
+        ini_set('display_errors', $old_display_errors);
+    }
+}
+
+/**
+ * Test database connection
+ *
+ * @param string $extension    'drizzle', 'mysql' or 'mysqli'
+ * @param string $connect_type 'tcp' or 'socket'
+ * @param string $host         host name
+ * @param string $port         tcp port to use
+ * @param string $socket       socket to use
+ * @param string $user         username to use
+ * @param string $pass         password to use
+ * @param string $error_key    key to use in return array
+ *
+ * @return bool|array
+ */
+function test_db_connection(
+    $extension,
+    $connect_type,
+    $host,
+    $port,
+    $socket,
+    $user,
+    $pass = null,
+    $error_key = 'Server'
+) {
+    //    test_php_errormsg();
+    $socket = empty($socket) || $connect_type == 'tcp' ? null : $socket;
+    $port = empty($port) || $connect_type == 'socket' ? null : ':' . $port;
+    $error = null;
+    if ($extension == 'drizzle') {
+        while (1) {
+            $drizzle = @drizzle_create();
+            if (!$drizzle) {
+                $error = __('Could not initialize Drizzle connection library');
+                break;
+            }
+            $conn = $socket
+                ? @drizzle_con_add_uds($socket, $user, $pass, null, 0)
+                : @drizzle_con_add_tcp(
+                    $drizzle, $host, $port, $user, $pass, null, 0
+                );
+            if (!$conn) {
+                $error = __('Could not connect to Drizzle server');
+                drizzle_free($drizzle);
+                break;
+            }
+            // connection object is set up but we have to send some query
+            // to actually connect
+            $res = @drizzle_query($conn, 'SELECT 1');
+            if (!$res) {
+                $error = __('Could not connect to Drizzle server');
+            } else {
+                drizzle_result_free($res);
+            }
+            drizzle_con_free($conn);
+            drizzle_free($drizzle);
+            break;
+        }
+    } else if ($extension == 'mysql') {
+        $conn = @mysql_connect($host . $socket . $port, $user, $pass);
+        if (!$conn) {
+            $error = __('Could not connect to MySQL server');
+        } else {
+            mysql_close($conn);
+        }
+    } else {
+        $conn = @mysqli_connect($host, $user, $pass, null, $port, $socket);
+        if (!$conn) {
+            $error = __('Could not connect to MySQL server');
+        } else {
+            mysqli_close($conn);
+        }
+    }
+    //    test_php_errormsg(false);
+    if (isset($php_errormsg)) {
+        $error .= " - $php_errormsg";
+    }
+    return is_null($error) ? true : array($error_key => $error);
+}
+
+/**
+ * Validate server config
+ *
+ * @param string $path   path to config, not used
+ * @param array  $values config values
+ *
+ * @return array
+ */
+function validate_server($path, $values)
+{
+    $result = array(
+        'Server' => '',
+        'Servers/1/user' => '',
+        'Servers/1/SignonSession' => '',
+        'Servers/1/SignonURL' => ''
+    );
+    $error = false;
+    if ($values['Servers/1/auth_type'] == 'config'
+        && empty($values['Servers/1/user'])
+    ) {
+        $result['Servers/1/user']
+            = __('Empty username while using config authentication method');
+        $error = true;
+    }
+    if ($values['Servers/1/auth_type'] == 'signon'
+        && empty($values['Servers/1/SignonSession'])
+    ) {
+        $result['Servers/1/SignonSession'] = __(
+            'Empty signon session name '
+            . 'while using signon authentication method'
+        );
+        $error = true;
+    }
+    if ($values['Servers/1/auth_type'] == 'signon'
+        && empty($values['Servers/1/SignonURL'])
+    ) {
+        $result['Servers/1/SignonURL']
+            = __('Empty signon URL while using signon authentication method');
+        $error = true;
+    }
+
+    if (!$error && $values['Servers/1/auth_type'] == 'config') {
+        $password = $values['Servers/1/nopassword'] ? null
+            : $values['Servers/1/password'];
+        $test = test_db_connection(
+            $values['Servers/1/extension'],
+            $values['Servers/1/connect_type'],
+            $values['Servers/1/host'],
+            $values['Servers/1/port'],
+            $values['Servers/1/socket'],
+            $values['Servers/1/user'],
+            $password,
+            'Server'
+        );
+        if ($test !== true) {
+            $result = array_merge($result, $test);
+        }
+    }
+    return $result;
+}
+
+/**
+ * Validate pmadb config
+ *
+ * @param string $path   path to config, not used
+ * @param array  $values config values
+ *
+ * @return array
+ */
+function validate_pmadb($path, $values)
+{
+    $result = array(
+        'Server_pmadb' => '',
+        'Servers/1/controluser' => '',
+        'Servers/1/controlpass' => ''
+    );
+    $error = false;
+
+    if ($values['Servers/1/pmadb'] == '') {
+        return $result;
+    }
+
+    $result = array();
+    if ($values['Servers/1/controluser'] == '') {
+        $result['Servers/1/controluser']
+            = __('Empty phpMyAdmin control user while using pmadb');
+        $error = true;
+    }
+    if ($values['Servers/1/controlpass'] == '') {
+        $result['Servers/1/controlpass']
+            = __('Empty phpMyAdmin control user password while using pmadb');
+        $error = true;
+    }
+    if (!$error) {
+        $test = test_db_connection(
+            $values['Servers/1/extension'], $values['Servers/1/connect_type'],
+            $values['Servers/1/host'], $values['Servers/1/port'],
+            $values['Servers/1/socket'], $values['Servers/1/controluser'],
+            $values['Servers/1/controlpass'], 'Server_pmadb'
+        );
+        if ($test !== true) {
+            $result = array_merge($result, $test);
+        }
+    }
+    return $result;
+}
+
+
+/**
+ * Validates regular expression
+ *
+ * @param string $path   path to config
+ * @param array  $values config values
+ *
+ * @return array
+ */
+function validate_regex($path, $values)
+{
+    $result = array($path => '');
+
+    if ($values[$path] == '') {
+        return $result;
+    }
+
+    test_php_errormsg();
+
+    $matches = array();
+    // in libraries/List_Database.class.php _checkHideDatabase(),
+    // a '/' is used as the delimiter for hide_db
+    preg_match('/' . $values[$path] . '/', '', $matches);
+
+    test_php_errormsg(false);
+
+    if (isset($php_errormsg)) {
+        $error = preg_replace('/^preg_match\(\): /', '', $php_errormsg);
+        return array($path => $error);
+    }
+
+    return $result;
+}
+
+/**
+ * Validates TrustedProxies field
+ *
+ * @param string $path   path to config
+ * @param array  $values config values
+ *
+ * @return array
+ */
+function validate_trusted_proxies($path, $values)
+{
+    $result = array($path => array());
+
+    if (empty($values[$path])) {
+        return $result;
+    }
+
+    if (is_array($values[$path])) {
+        // value already processed by FormDisplay::save
+        $lines = array();
+        foreach ($values[$path] as $ip => $v) {
+            $lines[] = preg_match('/^-\d+$/', $ip)
+                ? $v
+                : $ip . ': ' . $v;
+        }
+    } else {
+        // AJAX validation
+        $lines = explode("\n", $values[$path]);
+    }
+    foreach ($lines as $line) {
+        $line = trim($line);
+        $matches = array();
+        // we catch anything that may (or may not) be an IP
+        if (!preg_match("/^(.+):(?:[ ]?)\\w+$/", $line, $matches)) {
+            $result[$path][] = __('Incorrect value') . ': ' . $line;
+            continue;
+        }
+        // now let's check whether we really have an IP address
+        if (filter_var($matches[1], FILTER_VALIDATE_IP, FILTER_FLAG_IPV4) === false
+            && filter_var($matches[1], FILTER_VALIDATE_IP, FILTER_FLAG_IPV6) === false
+        ) {
+            $ip = htmlspecialchars(trim($matches[1]));
+            $result[$path][] = sprintf(__('Incorrect IP address: %s'), $ip);
+            continue;
+        }
+    }
+
+    return $result;
+}
+
+/**
+ * Tests integer value
+ *
+ * @param string $path         path to config
+ * @param array  $values       config values
+ * @param bool   $allow_neg    allow negative values
+ * @param bool   $allow_zero   allow zero
+ * @param int    $max_value    max allowed value
+ * @param string $error_string error message key:
+ *                             $GLOBALS["strConfig$error_lang_key"]
+ *
+ * @return string  empty string if test is successful
+ */
+function test_number(
+    $path,
+    $values,
+    $allow_neg,
+    $allow_zero,
+    $max_value,
+    $error_string
+) {
+    if ($values[$path] === '') {
+        return '';
+    }
+
+    if (intval($values[$path]) != $values[$path]
+        || (!$allow_neg && $values[$path] < 0)
+        || (!$allow_zero && $values[$path] == 0)
+        || $values[$path] > $max_value
+    ) {
+        return $error_string;
+    }
+
+    return '';
+}
+
+/**
+ * Validates port number
+ *
+ * @param string $path   path to config
+ * @param array  $values config values
+ *
+ * @return array
+ */
+function validate_port_number($path, $values)
+{
+    return array(
+        $path => test_number(
+            $path,
+            $values,
+            false,
+            false,
+            65535,
+            __('Not a valid port number')
+        )
+    );
+}
+
+/**
+ * Validates positive number
+ *
+ * @param string $path   path to config
+ * @param array  $values config values
+ *
+ * @return array
+ */
+function validate_positive_number($path, $values)
+{
+    return array(
+        $path => test_number(
+            $path,
+            $values,
+            false,
+            false,
+            PHP_INT_MAX,
+            __('Not a positive number')
+        )
+    );
+}
+
+/**
+ * Validates non-negative number
+ *
+ * @param string $path   path to config
+ * @param array  $values config values
+ *
+ * @return array
+ */
+function validate_non_negative_number($path, $values)
+{
+    return array(
+        $path => test_number(
+            $path,
+            $values,
+            false,
+            true,
+            PHP_INT_MAX,
+            __('Not a non-negative number')
+        )
+    );
+}
+
+/**
+ * Validates value according to given regular expression
+ * Pattern and modifiers must be a valid for PCRE <b>and</b> JavaScript RegExp
+ *
+ * @param string $path   path to config
+ * @param array  $values config values
+ * @param string $regex  regullar expression to match
+ *
+ * @return array
+ */
+function validate_by_regex($path, $values, $regex)
+{
+    $result = preg_match($regex, $values[$path]);
+    return array($path => ($result ? '' : __('Incorrect value')));
+}
+
+/**
+ * Validates upper bound for numeric inputs
+ *
+ * @param string $path      path to config
+ * @param array  $values    config values
+ * @param int    $max_value maximal allowed value
+ *
+ * @return array
+ */
+function validate_upper_bound($path, $values, $max_value)
+{
+    $result = $values[$path] <= $max_value;
+    return array($path => ($result ? ''
+        : sprintf(__('Value must be equal or lower than %s'), $max_value)));
+}
+?>
diff --git a/phpmyadmin/libraries/core.lib.php b/phpmyadmin/libraries/core.lib.php
new file mode 100644
index 0000000..f5d92bd
--- /dev/null
+++ b/phpmyadmin/libraries/core.lib.php
@@ -0,0 +1,802 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * Core functions used all over the scripts.
+ * This script is distinct from libraries/common.inc.php because this
+ * script is called from /test.
+ *
+ * @package PhpMyAdmin
+ */
+if (! defined('PHPMYADMIN')) {
+    exit;
+}
+
+/**
+ * checks given $var and returns it if valid, or $default of not valid
+ * given $var is also checked for type being 'similar' as $default
+ * or against any other type if $type is provided
+ *
+ * <code>
+ * // $_REQUEST['db'] not set
+ * echo PMA_ifSetOr($_REQUEST['db'], ''); // ''
+ * // $_REQUEST['sql_query'] not set
+ * echo PMA_ifSetOr($_REQUEST['sql_query']); // null
+ * // $cfg['ForceSSL'] not set
+ * echo PMA_ifSetOr($cfg['ForceSSL'], false, 'boolean'); // false
+ * echo PMA_ifSetOr($cfg['ForceSSL']); // null
+ * // $cfg['ForceSSL'] set to 1
+ * echo PMA_ifSetOr($cfg['ForceSSL'], false, 'boolean'); // false
+ * echo PMA_ifSetOr($cfg['ForceSSL'], false, 'similar'); // 1
+ * echo PMA_ifSetOr($cfg['ForceSSL'], false); // 1
+ * // $cfg['ForceSSL'] set to true
+ * echo PMA_ifSetOr($cfg['ForceSSL'], false, 'boolean'); // true
+ * </code>
+ *
+ * @param mixed &$var    param to check
+ * @param mixed $default default value
+ * @param mixed $type    var type or array of values to check against $var
+ *
+ * @return mixed   $var or $default
+ *
+ * @see     PMA_isValid()
+ */
+function PMA_ifSetOr(&$var, $default = null, $type = 'similar')
+{
+    if (! PMA_isValid($var, $type, $default)) {
+        return $default;
+    }
+
+    return $var;
+}
+
+/**
+ * checks given $var against $type or $compare
+ *
+ * $type can be:
+ * - false       : no type checking
+ * - 'scalar'    : whether type of $var is integer, float, string or boolean
+ * - 'numeric'   : whether type of $var is any number repesentation
+ * - 'length'    : whether type of $var is scalar with a string length > 0
+ * - 'similar'   : whether type of $var is similar to type of $compare
+ * - 'equal'     : whether type of $var is identical to type of $compare
+ * - 'identical' : whether $var is identical to $compare, not only the type!
+ * - or any other valid PHP variable type
+ *
+ * <code>
+ * // $_REQUEST['doit'] = true;
+ * PMA_isValid($_REQUEST['doit'], 'identical', 'true'); // false
+ * // $_REQUEST['doit'] = 'true';
+ * PMA_isValid($_REQUEST['doit'], 'identical', 'true'); // true
+ * </code>
+ *
+ * NOTE: call-by-reference is used to not get NOTICE on undefined vars,
+ * but the var is not altered inside this function, also after checking a var
+ * this var exists nut is not set, example:
+ * <code>
+ * // $var is not set
+ * isset($var); // false
+ * functionCallByReference($var); // false
+ * isset($var); // true
+ * functionCallByReference($var); // true
+ * </code>
+ *
+ * to avoid this we set this var to null if not isset
+ *
+ * @param mixed &$var    variable to check
+ * @param mixed $type    var type or array of valid values to check against $var
+ * @param mixed $compare var to compare with $var
+ *
+ * @return boolean whether valid or not
+ *
+ * @todo add some more var types like hex, bin, ...?
+ * @see     http://php.net/gettype
+ */
+function PMA_isValid(&$var, $type = 'length', $compare = null)
+{
+    if (! isset($var)) {
+        // var is not even set
+        return false;
+    }
+
+    if ($type === false) {
+        // no vartype requested
+        return true;
+    }
+
+    if (is_array($type)) {
+        return in_array($var, $type);
+    }
+
+    // allow some aliaes of var types
+    $type = strtolower($type);
+    switch ($type) {
+    case 'identic' :
+        $type = 'identical';
+        break;
+    case 'len' :
+        $type = 'length';
+        break;
+    case 'bool' :
+        $type = 'boolean';
+        break;
+    case 'float' :
+        $type = 'double';
+        break;
+    case 'int' :
+        $type = 'integer';
+        break;
+    case 'null' :
+        $type = 'NULL';
+        break;
+    }
+
+    if ($type === 'identical') {
+        return $var === $compare;
+    }
+
+    // whether we should check against given $compare
+    if ($type === 'similar') {
+        switch (gettype($compare)) {
+        case 'string':
+        case 'boolean':
+            $type = 'scalar';
+            break;
+        case 'integer':
+        case 'double':
+            $type = 'numeric';
+            break;
+        default:
+            $type = gettype($compare);
+        }
+    } elseif ($type === 'equal') {
+        $type = gettype($compare);
+    }
+
+    // do the check
+    if ($type === 'length' || $type === 'scalar') {
+        $is_scalar = is_scalar($var);
+        if ($is_scalar && $type === 'length') {
+            return (bool) strlen($var);
+        }
+        return $is_scalar;
+    }
+
+    if ($type === 'numeric') {
+        return is_numeric($var);
+    }
+
+    if (gettype($var) === $type) {
+        return true;
+    }
+
+    return false;
+}
+
+/**
+ * Removes insecure parts in a path; used before include() or
+ * require() when a part of the path comes from an insecure source
+ * like a cookie or form.
+ *
+ * @param string $path The path to check
+ *
+ * @return string  The secured path
+ *
+ * @access  public
+ */
+function PMA_securePath($path)
+{
+    // change .. to .
+    $path = preg_replace('@\.\.*@', '.', $path);
+
+    return $path;
+} // end function
+
+/**
+ * displays the given error message on phpMyAdmin error page in foreign language,
+ * ends script execution and closes session
+ *
+ * loads language file if not loaded already
+ *
+ * @param string       $error_message  the error message or named error message
+ * @param string|array $message_args   arguments applied to $error_message
+ * @param boolean      $delete_session whether to delete session cookie
+ *
+ * @return exit
+ */
+function PMA_fatalError(
+    $error_message, $message_args = null, $delete_session = true
+) {
+    /* Use format string if applicable */
+    if (is_string($message_args)) {
+        $error_message = sprintf($error_message, $message_args);
+    } elseif (is_array($message_args)) {
+        $error_message = vsprintf($error_message, $message_args);
+    }
+
+    if ($GLOBALS['is_ajax_request']) {
+        $response = PMA_Response::getInstance();
+        $response->isSuccess(false);
+        $response->addJSON('message', PMA_Message::error($error_message));
+    } else {
+        $error_message = strtr($error_message, array('<br />' => '[br]'));
+
+        /* Define fake gettext for fatal errors */
+        if (!function_exists('__')) {
+            function __($text)
+            {
+                return $text;
+            }
+        }
+
+        // these variables are used in the included file libraries/error.inc.php
+        $error_header = __('Error');
+        $lang = $GLOBALS['available_languages'][$GLOBALS['lang']][1];
+        $dir = $GLOBALS['text_dir'];
+
+        // on fatal errors it cannot hurt to always delete the current session
+        if ($delete_session
+            && isset($GLOBALS['session_name'])
+            && isset($_COOKIE[$GLOBALS['session_name']])
+        ) {
+            $GLOBALS['PMA_Config']->removeCookie($GLOBALS['session_name']);
+        }
+
+        // Displays the error message
+        include './libraries/error.inc.php';
+    }
+    if (! defined('TESTSUITE')) {
+        exit;
+    }
+}
+
+/**
+ * Returns a link to the PHP documentation
+ *
+ * @param string $target anchor in documentation
+ *
+ * @return string  the URL
+ *
+ * @access  public
+ */
+function PMA_getPHPDocLink($target)
+{
+    /* List of PHP documentation translations */
+    $php_doc_languages = array(
+        'pt_BR', 'zh', 'fr', 'de', 'it', 'ja', 'pl', 'ro', 'ru', 'fa', 'es', 'tr'
+    );
+
+    $lang = 'en';
+    if (in_array($GLOBALS['lang'], $php_doc_languages)) {
+        $lang = $GLOBALS['lang'];
+    }
+
+    return PMA_linkURL('http://php.net/manual/' . $lang . '/' . $target);
+}
+
+/**
+ * Warn or fail on missing extension.
+ *
+ * @param string $extension Extension name
+ * @param bool   $fatal     Whether the error is fatal.
+ * @param string $extra     Extra string to append to messsage.
+ *
+ * @return void
+ */
+function PMA_warnMissingExtension($extension, $fatal = false, $extra = '')
+{
+    /* Gettext does not have to be loaded yet here */
+    if (function_exists('__')) {
+        $message = __(
+            'The %s extension is missing. Please check your PHP configuration.'
+        );
+    } else {
+        $message
+            = 'The %s extension is missing. Please check your PHP configuration.';
+    }
+    $doclink = PMA_getPHPDocLink('book.' . $extension . '.php');
+    $message = sprintf(
+        $message,
+        '[a@' . $doclink . '@Documentation][em]' . $extension . '[/em][/a]'
+    );
+    if ($extra != '') {
+        $message .= ' ' . $extra;
+    }
+    if ($fatal) {
+        PMA_fatalError($message);
+    } else {
+        $GLOBALS['error_handler']->addError(
+            $message, 
+            E_USER_WARNING,
+            '',
+            '',
+            false
+        );
+    }
+}
+
+/**
+ * returns count of tables in given db
+ *
+ * @param string $db database to count tables for
+ *
+ * @return integer count of tables in $db
+ */
+function PMA_getTableCount($db)
+{
+    $tables = PMA_DBI_try_query(
+        'SHOW TABLES FROM ' . PMA_Util::backquote($db) . ';',
+        null, PMA_DBI_QUERY_STORE
+    );
+    if ($tables) {
+        $num_tables = PMA_DBI_num_rows($tables);
+        PMA_DBI_free_result($tables);
+    } else {
+        $num_tables = 0;
+    }
+
+    return $num_tables;
+}
+
+/**
+ * Converts numbers like 10M into bytes
+ * Used with permission from Moodle (http://moodle.org) by Martin Dougiamas
+ * (renamed with PMA prefix to avoid double definition when embedded
+ * in Moodle)
+ *
+ * @param string $size size
+ *
+ * @return integer $size
+ */
+function PMA_getRealSize($size = 0)
+{
+    if (! $size) {
+        return 0;
+    }
+
+    $scan['gb'] = 1073741824; //1024 * 1024 * 1024;
+    $scan['g']  = 1073741824; //1024 * 1024 * 1024;
+    $scan['mb'] = 1048576;
+    $scan['m']  = 1048576;
+    $scan['kb'] =    1024;
+    $scan['k']  =    1024;
+    $scan['b']  =       1;
+
+    foreach ($scan as $unit => $factor) {
+        if (strlen($size) > strlen($unit)
+            && strtolower(substr($size, strlen($size) - strlen($unit))) == $unit
+        ) {
+            return substr($size, 0, strlen($size) - strlen($unit)) * $factor;
+        }
+    }
+
+    return $size;
+} // end function PMA_getRealSize()
+
+/**
+ * merges array recursive like array_merge_recursive() but keyed-values are
+ * always overwritten.
+ *
+ * array PMA_arrayMergeRecursive(array $array1[, array $array2[, array ...]])
+ *
+ * @return array   merged array
+ *
+ * @see     http://php.net/array_merge
+ * @see     http://php.net/array_merge_recursive
+ */
+function PMA_arrayMergeRecursive()
+{
+    switch(func_num_args()) {
+    case 0 :
+        return false;
+        break;
+    case 1 :
+        // when does that happen?
+        return func_get_arg(0);
+        break;
+    case 2 :
+        $args = func_get_args();
+        if (! is_array($args[0]) || ! is_array($args[1])) {
+            return $args[1];
+        }
+        foreach ($args[1] as $key2 => $value2) {
+            if (isset($args[0][$key2]) && !is_int($key2)) {
+                $args[0][$key2] = PMA_arrayMergeRecursive(
+                    $args[0][$key2], $value2
+                );
+            } else {
+                // we erase the parent array, otherwise we cannot override
+                // a directive that contains array elements, like this:
+                // (in config.default.php)
+                // $cfg['ForeignKeyDropdownOrder']= array('id-content','content-id');
+                // (in config.inc.php)
+                // $cfg['ForeignKeyDropdownOrder']= array('content-id');
+                if (is_int($key2) && $key2 == 0) {
+                    unset($args[0]);
+                }
+                $args[0][$key2] = $value2;
+            }
+        }
+        return $args[0];
+        break;
+    default :
+        $args = func_get_args();
+        $args[1] = PMA_arrayMergeRecursive($args[0], $args[1]);
+        array_shift($args);
+        return call_user_func_array('PMA_arrayMergeRecursive', $args);
+        break;
+    }
+}
+
+/**
+ * calls $function for every element in $array recursively
+ *
+ * this function is protected against deep recursion attack CVE-2006-1549,
+ * 1000 seems to be more than enough
+ *
+ * @param array  &$array             array to walk
+ * @param string $function           function to call for every array element
+ * @param bool   $apply_to_keys_also whether to call the function for the keys also
+ *
+ * @return void
+ *
+ * @see http://www.php-security.org/MOPB/MOPB-02-2007.html
+ * @see http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2006-1549
+ */
+function PMA_arrayWalkRecursive(&$array, $function, $apply_to_keys_also = false)
+{
+    static $recursive_counter = 0;
+    if (++$recursive_counter > 1000) {
+        PMA_fatalError(__('possible deep recursion attack'));
+    }
+    foreach ($array as $key => $value) {
+        if (is_array($value)) {
+            PMA_arrayWalkRecursive($array[$key], $function, $apply_to_keys_also);
+        } else {
+            $array[$key] = $function($value);
+        }
+
+        if ($apply_to_keys_also && is_string($key)) {
+            $new_key = $function($key);
+            if ($new_key != $key) {
+                $array[$new_key] = $array[$key];
+                unset($array[$key]);
+            }
+        }
+    }
+    $recursive_counter--;
+}
+
+/**
+ * boolean phpMyAdmin.PMA_checkPageValidity(string &$page, array $whitelist)
+ *
+ * checks given given $page against given $whitelist and returns true if valid
+ * it ignores optionaly query paramters in $page (script.php?ignored)
+ *
+ * @param string &$page     page to check
+ * @param array  $whitelist whitelist to check page against
+ *
+ * @return boolean whether $page is valid or not (in $whitelist or not)
+ */
+function PMA_checkPageValidity(&$page, $whitelist)
+{
+    if (! isset($page) || !is_string($page)) {
+        return false;
+    }
+
+    if (in_array($page, $whitelist)) {
+        return true;
+    } elseif (in_array(substr($page, 0, strpos($page . '?', '?')), $whitelist)) {
+        return true;
+    } else {
+        $_page = urldecode($page);
+        if (in_array(substr($_page, 0, strpos($_page . '?', '?')), $whitelist)) {
+            return true;
+        }
+    }
+    return false;
+}
+
+/**
+ * tries to find the value for the given environment variable name
+ *
+ * searches in $_SERVER, $_ENV then tries getenv() and apache_getenv()
+ * in this order
+ *
+ * @param string $var_name variable name
+ *
+ * @return string  value of $var or empty string
+ */
+function PMA_getenv($var_name)
+{
+    if (isset($_SERVER[$var_name])) {
+        return $_SERVER[$var_name];
+    } elseif (isset($_ENV[$var_name])) {
+        return $_ENV[$var_name];
+    } elseif (getenv($var_name)) {
+        return getenv($var_name);
+    } elseif (function_exists('apache_getenv')
+     && apache_getenv($var_name, true)) {
+        return apache_getenv($var_name, true);
+    }
+
+    return '';
+}
+
+/**
+ * Send HTTP header, taking IIS limits into account (600 seems ok)
+ *
+ * @param string $uri         the header to send
+ * @param bool   $use_refresh whether to use Refresh: header when running on IIS
+ *
+ * @return boolean  always true
+ */
+function PMA_sendHeaderLocation($uri, $use_refresh = false)
+{
+    if (PMA_IS_IIS && strlen($uri) > 600) {
+        include_once './libraries/js_escape.lib.php';
+        PMA_Response::getInstance()->disable();
+
+        echo '<html><head><title>- - -</title>' . "\n";
+        echo '<meta http-equiv="expires" content="0">' . "\n";
+        echo '<meta http-equiv="Pragma" content="no-cache">' . "\n";
+        echo '<meta http-equiv="Cache-Control" content="no-cache">' . "\n";
+        echo '<meta http-equiv="Refresh" content="0;url='
+            .  htmlspecialchars($uri) . '">' . "\n";
+        echo '<script type="text/javascript">' . "\n";
+        echo '//<![CDATA[' . "\n";
+        echo 'setTimeout("window.location = unescape(\'"'
+            . PMA_escapeJsString($uri) . '"\')", 2000);' . "\n";
+        echo '//]]>' . "\n";
+        echo '</script>' . "\n";
+        echo '</head>' . "\n";
+        echo '<body>' . "\n";
+        echo '<script type="text/javascript">' . "\n";
+        echo '//<![CDATA[' . "\n";
+        echo 'document.write(\'<p><a href="' . htmlspecialchars($uri) . '">'
+            . __('Go') . '</a></p>\');' . "\n";
+        echo '//]]>' . "\n";
+        echo '</script></body></html>' . "\n";
+
+    } else {
+        if (SID) {
+            if (strpos($uri, '?') === false) {
+                header('Location: ' . $uri . '?' . SID);
+            } else {
+                $separator = PMA_get_arg_separator();
+                header('Location: ' . $uri . $separator . SID);
+            }
+        } else {
+            session_write_close();
+            if (headers_sent()) {
+                if (function_exists('debug_print_backtrace')) {
+                    echo '<pre>';
+                    debug_print_backtrace();
+                    echo '</pre>';
+                }
+                trigger_error(
+                    'PMA_sendHeaderLocation called when headers are already sent!',
+                    E_USER_ERROR
+                );
+            }
+            // bug #1523784: IE6 does not like 'Refresh: 0', it
+            // results in a blank page
+            // but we need it when coming from the cookie login panel)
+            if (PMA_IS_IIS && $use_refresh) {
+                header('Refresh: 0; ' . $uri);
+            } else {
+                header('Location: ' . $uri);
+            }
+        }
+    }
+}
+
+/**
+ * Outputs headers to prevent caching in browser (and on the way).
+ *
+ * @return void
+ */
+function PMA_noCacheHeader()
+{
+    if (defined('TESTSUITE')) {
+        return;
+    }
+    // rfc2616 - Section 14.21
+    header('Expires: ' . date(DATE_RFC1123));
+    // HTTP/1.1
+    header(
+        'Cache-Control: no-store, no-cache, must-revalidate,'
+        . '  pre-check=0, post-check=0, max-age=0'
+    );
+    if (PMA_USR_BROWSER_AGENT == 'IE') {
+        /* On SSL IE sometimes fails with:
+         *
+         * Internet Explorer was not able to open this Internet site. The
+         * requested site is either unavailable or cannot be found. Please
+         * try again later.
+         *
+         * Adding Pragma: public fixes this.
+         */
+        header('Pragma: public');
+    } else {
+        header('Pragma: no-cache'); // HTTP/1.0
+        // test case: exporting a database into a .gz file with Safari
+        // would produce files not having the current time
+        // (added this header for Safari but should not harm other browsers)
+        header('Last-Modified: ' . date(DATE_RFC1123));
+    }
+}
+
+
+/**
+ * Sends header indicating file download.
+ *
+ * @param string $filename Filename to include in headers if empty,
+ *                         none Content-Disposition header will be sent.
+ * @param string $mimetype MIME type to include in headers.
+ * @param int    $length   Length of content (optional)
+ * @param bool   $no_cache Whether to include no-caching headers.
+ *
+ * @return void
+ */
+function PMA_downloadHeader($filename, $mimetype, $length = 0, $no_cache = true)
+{
+    if ($no_cache) {
+        PMA_noCacheHeader();
+    }
+    /* Replace all possibly dangerous chars in filename */
+    $filename = str_replace(array(';', '"', "\n", "\r"), '-', $filename);
+    if (!empty($filename)) {
+        header('Content-Description: File Transfer');
+        header('Content-Disposition: attachment; filename="' . $filename . '"');
+    }
+    header('Content-Type: ' . $mimetype);
+    header('Content-Transfer-Encoding: binary');
+    if ($length > 0) {
+        header('Content-Length: ' . $length);
+    }
+}
+
+
+/**
+ * Returns value of an element in $array given by $path.
+ * $path is a string describing position of an element in an associative array,
+ * eg. Servers/1/host refers to $array[Servers][1][host]
+ *
+ * @param string $path    path in the arry
+ * @param array  $array   the array
+ * @param mixed  $default default value
+ *
+ * @return mixed    array element or $default
+ */
+function PMA_arrayRead($path, $array, $default = null)
+{
+    $keys = explode('/', $path);
+    $value =& $array;
+    foreach ($keys as $key) {
+        if (! isset($value[$key])) {
+            return $default;
+        }
+        $value =& $value[$key];
+    }
+    return $value;
+}
+
+/**
+ * Stores value in an array
+ *
+ * @param string $path   path in the array
+ * @param array  &$array the array
+ * @param mixed  $value  value to store
+ *
+ * @return void
+ */
+function PMA_arrayWrite($path, &$array, $value)
+{
+    $keys = explode('/', $path);
+    $last_key = array_pop($keys);
+    $a =& $array;
+    foreach ($keys as $key) {
+        if (! isset($a[$key])) {
+            $a[$key] = array();
+        }
+        $a =& $a[$key];
+    }
+    $a[$last_key] = $value;
+}
+
+/**
+ * Removes value from an array
+ *
+ * @param string $path   path in the array
+ * @param array  &$array the array
+ *
+ * @return void
+ */
+function PMA_arrayRemove($path, &$array)
+{
+    $keys = explode('/', $path);
+    $keys_last = array_pop($keys);
+    $path = array();
+    $depth = 0;
+
+    $path[0] =& $array;
+    $found = true;
+    // go as deep as required or possible
+    foreach ($keys as $key) {
+        if (! isset($path[$depth][$key])) {
+            $found = false;
+            break;
+        }
+        $depth++;
+        $path[$depth] =& $path[$depth-1][$key];
+    }
+    // if element found, remove it
+    if ($found) {
+        unset($path[$depth][$keys_last]);
+        $depth--;
+    }
+
+    // remove empty nested arrays
+    for (; $depth >= 0; $depth--) {
+        if (! isset($path[$depth+1]) || count($path[$depth+1]) == 0) {
+            unset($path[$depth][$keys[$depth]]);
+        } else {
+            break;
+        }
+    }
+}
+
+/**
+ * Returns link to (possibly) external site using defined redirector.
+ *
+ * @param string $url URL where to go.
+ *
+ * @return string URL for a link.
+ */
+function PMA_linkURL($url)
+{
+    if (!preg_match('#^https?://#', $url) || defined('PMA_SETUP')) {
+        return $url;
+    } else {
+        if (!function_exists('PMA_generate_common_url')) {
+            include_once './libraries/url_generating.lib.php';
+        }
+        $params = array();
+        $params['url'] = $url;
+        return './url.php' . PMA_generate_common_url($params);
+    }
+}
+
+/**
+ * Adds JS code snippets to be displayed by the PMA_Response class.
+ * Adds a newline to each snippet.
+ *
+ * @param string $str Js code to be added (e.g. "token=1234;")
+ *
+ * @return void
+ */
+function PMA_addJSCode($str)
+{
+    $response = PMA_Response::getInstance();
+    $header   = $response->getHeader();
+    $scripts  = $header->getScripts();
+    $scripts->addCode($str);
+}
+
+/**
+ * Adds JS code snippet for variable assignment
+ * to be displayed by the PMA_Response class.
+ *
+ * @param string $key    Name of value to set
+ * @param mixed  $value  Value to set, can be either string or array of strings
+ * @param bool   $escape Whether to escape value or keep it as it is
+ *                       (for inclusion of js code)
+ *
+ * @return void
+ */
+function PMA_addJSVar($key, $value, $escape = true)
+{
+    PMA_addJSCode(PMA_getJsValue($key, $value, $escape));
+}
+
+?>
diff --git a/phpmyadmin/libraries/data_dictionary_relations.lib.php b/phpmyadmin/libraries/data_dictionary_relations.lib.php
new file mode 100644
index 0000000..651dd65
--- /dev/null
+++ b/phpmyadmin/libraries/data_dictionary_relations.lib.php
@@ -0,0 +1,166 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ *
+ * @package PhpMyAdmin
+ */
+if (! defined('PHPMYADMIN')) {
+    exit;
+}
+
+/**
+ *
+ */
+$GLOBALS['data_dictionary_relations'] = array(
+    'CHARACTER_SETS' => array(
+        'DEFAULT_COLLATE_NAME' => array(
+            'foreign_db'    => 'data_dictionary',
+            'foreign_table' => 'COLLATIONS',
+            'foreign_field' => 'COLLATION_NAME'
+        )
+    ),
+    'COLLATIONS' => array(
+        'CHARACTER_SET_NAME' => array(
+            'foreign_db'    => 'data_dictionary',
+            'foreign_table' => 'CHARACTER_SETS',
+            'foreign_field' => 'CHARACTER_SET_NAME'
+        )
+    ),
+    'COLUMNS' => array(
+        'TABLE_SCHEMA' => array(
+            'foreign_db'    => 'data_dictionary',
+            'foreign_table' => 'SCHEMAS',
+            'foreign_field' => 'SCHEMA_NAME'
+        ),
+        'COLLATION_NAME' => array(
+            'foreign_db'    => 'data_dictionary',
+            'foreign_table' => 'COLLATIONS',
+            'foreign_field' => 'COLLATION_NAME'
+        )
+    ),
+    'INDEXES' => array(
+        'TABLE_SCHEMA' => array(
+            'foreign_db'    => 'data_dictionary',
+            'foreign_table' => 'SCHEMAS',
+            'foreign_field' => 'SCHEMA_NAME'
+        )
+    ),
+    'INDEX_PARTS' => array(
+        'TABLE_SCHEMA' => array(
+            'foreign_db'    => 'data_dictionary',
+            'foreign_table' => 'SCHEMAS',
+            'foreign_field' => 'SCHEMA_NAME'
+        )
+    ),
+    'INNODB_LOCKS' => array(
+        'LOCK_TRX_ID' => array(
+            'foreign_db'    => 'data_dictionary',
+            'foreign_table' => 'INNODB_TRX',
+            'foreign_field' => 'TRX_ID'
+        )
+    ),
+    'INNODB_LOCK_WAITS' => array(
+        'REQUESTING_TRX_ID' => array(
+            'foreign_db'    => 'data_dictionary',
+            'foreign_table' => 'INNODB_TRX',
+            'foreign_field' => 'TRX_ID'
+        ),
+        'REQUESTED_LOCK_ID' => array(
+            'foreign_db'    => 'data_dictionary',
+            'foreign_table' => 'INNODB_LOCKS',
+            'foreign_field' => 'LOCK_ID'
+        ),
+        'BLOCKING_TRX_ID' => array(
+            'foreign_db'    => 'data_dictionary',
+            'foreign_table' => 'INNODB_TRX',
+            'foreign_field' => 'TRX_ID'
+        ),
+        'BLOCKING_LOCK_ID' => array(
+            'foreign_db'    => 'data_dictionary',
+            'foreign_table' => 'INNODB_LOCKS',
+            'foreign_field' => 'LOCK_ID'
+        )
+    ),
+    'INNODB_SYS_COLUMNS' => array(
+        'TABLE_ID' => array(
+            'foreign_db'    => 'data_dictionary',
+            'foreign_table' => 'INNODB_SYS_TABLES',
+            'foreign_field' => 'TABLE_ID'
+        )
+    ),
+    'INNODB_SYS_FIELDS' => array(
+        'INDEX_ID' => array(
+            'foreign_db'    => 'data_dictionary',
+            'foreign_table' => 'INNODB_SYS_INDEXES',
+            'foreign_field' => 'INDEX_ID'
+        )
+    ),
+    'INNODB_SYS_INDEXES' => array(
+        'TABLE_ID' => array(
+            'foreign_db'    => 'data_dictionary',
+            'foreign_table' => 'INNODB_SYS_TABLES',
+            'foreign_field' => 'TABLE_ID'
+        )
+    ),
+    'INNODB_SYS_TABLESTATS' => array(
+        'TABLE_ID' => array(
+            'foreign_db'    => 'data_dictionary',
+            'foreign_table' => 'INNODB_SYS_TABLES',
+            'foreign_field' => 'TABLE_ID'
+        )
+    ),
+    'PLUGINS' => array(
+        'MODULE_NAME' => array(
+            'foreign_db'    => 'data_dictionary',
+            'foreign_table' => 'MODULES',
+            'foreign_field' => 'MODULE_NAME'
+        )
+    ),
+    'SCHEMAS' => array(
+        'DEFAULT_COLLATION_NAME' => array(
+            'foreign_db'    => 'data_dictionary',
+            'foreign_table' => 'COLLATIONS',
+            'foreign_field' => 'COLLATION_NAME'
+        )
+    ),
+    'TABLES' => array(
+        'TABLE_SCHEMA' => array(
+            'foreign_db'    => 'data_dictionary',
+            'foreign_table' => 'SCHEMAS',
+            'foreign_field' => 'SCHEMA_NAME'
+        ),
+        'TABLE_COLLATION' => array(
+            'foreign_db'    => 'data_dictionary',
+            'foreign_table' => 'COLLATIONS',
+            'foreign_field' => 'COLLATION_NAME'
+        )
+    ),
+    'TABLE_CACHE' => array(
+        'TABLE_SCHEMA' => array(
+            'foreign_db'    => 'data_dictionary',
+            'foreign_table' => 'SCHEMAS',
+            'foreign_field' => 'SCHEMA_NAME'
+        )
+    ),
+    'TABLE_CONSTRAINTS' => array(
+        'CONSTRAINT_SCHEMA' => array(
+            'foreign_db'    => 'data_dictionary',
+            'foreign_table' => 'SCHEMAS',
+            'foreign_field' => 'SCHEMA_NAME'
+        ),
+        'TABLE_SCHEMA' => array(
+            'foreign_db'    => 'data_dictionary',
+            'foreign_table' => 'SCHEMAS',
+            'foreign_field' => 'SCHEMA_NAME'
+        )
+    ),
+    'TABLE_DEFINITION_CACHE' => array(
+        'TABLE_SCHEMA' => array(
+            'foreign_db'    => 'data_dictionary',
+            'foreign_table' => 'SCHEMAS',
+            'foreign_field' => 'SCHEMA_NAME'
+        )
+    )
+);
+
+?>
diff --git a/phpmyadmin/libraries/database_interface.lib.php b/phpmyadmin/libraries/database_interface.lib.php
new file mode 100644
index 0000000..de697ec
--- /dev/null
+++ b/phpmyadmin/libraries/database_interface.lib.php
@@ -0,0 +1,2134 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * Common Option Constants For DBI Functions
+ *
+ * @package PhpMyAdmin-DBI
+ */
+if (! defined('PHPMYADMIN')) {
+    exit;
+}
+
+/**
+ * Force STORE_RESULT method, ignored by classic MySQL.
+ */
+define('PMA_DBI_QUERY_STORE',       1);
+/**
+ * Do not read whole query.
+ */
+define('PMA_DBI_QUERY_UNBUFFERED',  2);
+/**
+ * Get session variable.
+ */
+define('PMA_DBI_GETVAR_SESSION',    1);
+/**
+ * Get global variable.
+ */
+define('PMA_DBI_GETVAR_GLOBAL',     2);
+
+/**
+ * Checks whether database extension is loaded
+ *
+ * @param string $extension mysql extension to check
+ *
+ * @return bool
+ */
+function PMA_DBI_checkDbExtension($extension = 'mysql')
+{
+    if ($extension == 'drizzle' && function_exists('drizzle_create')) {
+        return true;
+    } else if (function_exists($extension . '_connect')) {
+        return true;
+    }
+
+    return false;
+}
+
+if (defined('TESTSUITE')) {
+    /**
+     * For testsuite we use dummy driver which can fake some queries.
+     */
+    include_once './libraries/dbi/dummy.lib.php';
+} else {
+
+    /**
+     * check for requested extension
+     */
+    if (! PMA_DBI_checkDbExtension($GLOBALS['cfg']['Server']['extension'])) {
+
+        // if it fails try alternative extension ...
+        // and display an error ...
+
+        /**
+         * @todo add different messages for alternative extension
+         * and complete fail (no alternative extension too)
+         */
+        PMA_warnMissingExtension(
+            $GLOBALS['cfg']['Server']['extension'],
+            false,
+            PMA_Util::showDocu('faq', 'faqmysql')
+        );
+
+        if ($GLOBALS['cfg']['Server']['extension'] === 'mysql') {
+            $alternativ_extension = 'mysqli';
+        } else {
+            $alternativ_extension = 'mysql';
+        }
+
+        if (! PMA_DBI_checkDbExtension($alternativ_extension)) {
+            // if alternative fails too ...
+            PMA_warnMissingExtension(
+                $GLOBALS['cfg']['Server']['extension'],
+                true,
+                PMA_Util::showDocu('faq', 'faqmysql')
+            );
+        }
+
+        $GLOBALS['cfg']['Server']['extension'] = $alternativ_extension;
+        unset($alternativ_extension);
+    }
+
+    /**
+     * Including The DBI Plugin
+     */
+    include_once './libraries/dbi/'
+        . $GLOBALS['cfg']['Server']['extension'] . '.dbi.lib.php';
+
+}
+
+/**
+ * runs a query
+ *
+ * @param string $query               SQL query to execte
+ * @param mixed  $link                optional database link to use
+ * @param int    $options             optional query options
+ * @param bool   $cache_affected_rows whether to cache affected rows
+ *
+ * @return mixed
+ */
+function PMA_DBI_query($query, $link = null, $options = 0,
+    $cache_affected_rows = true
+) {
+    $res = PMA_DBI_try_query($query, $link, $options, $cache_affected_rows)
+        or PMA_Util::mysqlDie(PMA_DBI_getError($link), $query);
+    return $res;
+}
+
+/**
+ * Stores query data into session data for debugging purposes
+ *
+ * @param string   $query  Query text
+ * @param resource $link   database link
+ * @param resource $result Query result
+ * @param integer  $time   Time to execute query
+ *
+ * @return void
+ */
+function PMA_DBI_DBG_query($query, $link, $result, $time)
+{
+    $hash = md5($query);
+
+    if (isset($_SESSION['debug']['queries'][$hash])) {
+        $_SESSION['debug']['queries'][$hash]['count']++;
+    } else {
+        $_SESSION['debug']['queries'][$hash] = array();
+        if ($result == false) {
+            $_SESSION['debug']['queries'][$hash]['error']
+                = '<b style="color:red">' . mysqli_error($link) . '</b>';
+        }
+        $_SESSION['debug']['queries'][$hash]['count'] = 1;
+        $_SESSION['debug']['queries'][$hash]['query'] = $query;
+        $_SESSION['debug']['queries'][$hash]['time'] = $time;
+    }
+
+    $trace = array();
+    foreach (debug_backtrace() as $trace_step) {
+        $trace[]
+            = (isset($trace_step['file'])
+                ? PMA_Error::relPath($trace_step['file'])
+                : '')
+            . (isset($trace_step['line'])
+                ?  '#' . $trace_step['line'] . ': '
+                : '')
+            . (isset($trace_step['class']) ? $trace_step['class'] : '')
+            . (isset($trace_step['type']) ? $trace_step['type'] : '')
+            . (isset($trace_step['function']) ? $trace_step['function'] : '')
+            . '('
+            . (isset($trace_step['params'])
+                ? implode(', ', $trace_step['params'])
+                : ''
+            )
+            . ')'
+            ;
+    }
+    $_SESSION['debug']['queries'][$hash]['trace'][] = $trace;
+}
+
+/**
+ * runs a query and returns the result
+ *
+ * @param string   $query               query to run
+ * @param resource $link                mysql link resource
+ * @param integer  $options             query options
+ * @param bool     $cache_affected_rows whether to cache affected row
+ *
+ * @return mixed
+ */
+function PMA_DBI_try_query($query, $link = null, $options = 0,
+    $cache_affected_rows = true
+) {
+    if (empty($link)) {
+        if (isset($GLOBALS['userlink'])) {
+            $link = $GLOBALS['userlink'];
+        } else {
+            return false;
+        }
+    }
+
+    if ($GLOBALS['cfg']['DBG']['sql']) {
+        $time = microtime(true);
+    }
+
+    $result = PMA_DBI_real_query($query, $link, $options);
+
+    if ($cache_affected_rows) {
+        $GLOBALS['cached_affected_rows'] = PMA_DBI_affected_rows($link, false);
+    }
+
+    if ($GLOBALS['cfg']['DBG']['sql']) {
+        $time = microtime(true) - $time;
+        PMA_DBI_DBG_query($query, $link, $result, $time);
+    }
+    if ($result != false && PMA_Tracker::isActive() == true ) {
+        PMA_Tracker::handleQuery($query);
+    }
+
+    return $result;
+}
+
+/**
+ * Run multi query statement and return results
+ *
+ * @param string $multi_query multi query statement to execute
+ * @param mysqli $link        mysqli object
+ *
+ * @return mysqli_result collection | boolean(false)
+ */
+function PMA_DBI_try_multi_query($multi_query = '', $link = null)
+{
+
+    if (empty($link)) {
+        if (isset($GLOBALS['userlink'])) {
+            $link = $GLOBALS['userlink'];
+        } else {
+            return false;
+        }
+    }
+
+    return PMA_DBI_real_multi_query($link, $multi_query);
+
+}
+
+/**
+ * converts charset of a mysql message, usually coming from mysql_error(),
+ * into PMA charset, usally UTF-8
+ * uses language to charset mapping from mysql/share/errmsg.txt
+ * and charset names to ISO charset from information_schema.CHARACTER_SETS
+ *
+ * @param string $message the message
+ *
+ * @return string  $message
+ */
+function PMA_DBI_convert_message($message)
+{
+    // latin always last!
+    $encodings = array(
+        'japanese'      => 'EUC-JP', //'ujis',
+        'japanese-sjis' => 'Shift-JIS', //'sjis',
+        'korean'        => 'EUC-KR', //'euckr',
+        'russian'       => 'KOI8-R', //'koi8r',
+        'ukrainian'     => 'KOI8-U', //'koi8u',
+        'greek'         => 'ISO-8859-7', //'greek',
+        'serbian'       => 'CP1250', //'cp1250',
+        'estonian'      => 'ISO-8859-13', //'latin7',
+        'slovak'        => 'ISO-8859-2', //'latin2',
+        'czech'         => 'ISO-8859-2', //'latin2',
+        'hungarian'     => 'ISO-8859-2', //'latin2',
+        'polish'        => 'ISO-8859-2', //'latin2',
+        'romanian'      => 'ISO-8859-2', //'latin2',
+        'spanish'       => 'CP1252', //'latin1',
+        'swedish'       => 'CP1252', //'latin1',
+        'italian'       => 'CP1252', //'latin1',
+        'norwegian-ny'  => 'CP1252', //'latin1',
+        'norwegian'     => 'CP1252', //'latin1',
+        'portuguese'    => 'CP1252', //'latin1',
+        'danish'        => 'CP1252', //'latin1',
+        'dutch'         => 'CP1252', //'latin1',
+        'english'       => 'CP1252', //'latin1',
+        'french'        => 'CP1252', //'latin1',
+        'german'        => 'CP1252', //'latin1',
+    );
+
+    $server_language = PMA_DBI_fetch_value(
+        'SHOW VARIABLES LIKE \'language\';',
+        0,
+        1
+    );
+    if ($server_language) {
+        $found = array();
+        $match = preg_match(
+            '&(?:\\\|\\/)([^\\\\\/]*)(?:\\\|\\/)$&i',
+            $server_language,
+            $found
+        );
+        if ($match) {
+            $server_language = $found[1];
+        }
+    }
+
+    if (! empty($server_language) && isset($encodings[$server_language])) {
+        $encoding = $encodings[$server_language];
+    } else {
+        /* Fallback to CP1252 if we can not detect */
+        $encoding = 'CP1252';
+    }
+
+    if (function_exists('iconv')) {
+        if ((@stristr(PHP_OS, 'AIX'))
+            && (@strcasecmp(ICONV_IMPL, 'unknown') == 0)
+            && (@strcasecmp(ICONV_VERSION, 'unknown') == 0)
+        ) {
+            include_once './libraries/iconv_wrapper.lib.php';
+            $message = PMA_aix_iconv_wrapper(
+                $encoding,
+                'utf-8' . $GLOBALS['cfg']['IconvExtraParams'],
+                $message
+            );
+        } else {
+            $message = iconv(
+                $encoding,
+                'utf-8' . $GLOBALS['cfg']['IconvExtraParams'],
+                $message
+            );
+        }
+    } elseif (function_exists('recode_string')) {
+        $message = recode_string(
+            $encoding . '..'  . 'utf-8',
+            $message
+        );
+    } elseif (function_exists('libiconv')) {
+        $message = libiconv($encoding, 'utf-8', $message);
+    } elseif (function_exists('mb_convert_encoding')) {
+        // do not try unsupported charsets
+        if (! in_array($server_language, array('ukrainian', 'greek', 'serbian'))) {
+            $message = mb_convert_encoding(
+                $message,
+                'utf-8',
+                $encoding
+            );
+        }
+    }
+
+    return $message;
+}
+
+/**
+ * returns array with table names for given db
+ *
+ * @param string $database name of database
+ * @param mixed  $link     mysql link resource|object
+ *
+ * @return array   tables names
+ */
+function PMA_DBI_get_tables($database, $link = null)
+{
+    return PMA_DBI_fetch_result(
+        'SHOW TABLES FROM ' . PMA_Util::backquote($database) . ';',
+        null,
+        0,
+        $link,
+        PMA_DBI_QUERY_STORE
+    );
+}
+
+/**
+ * usort comparison callback
+ *
+ * @param string $a first argument to sort
+ * @param string $b second argument to sort
+ *
+ * @return integer  a value representing whether $a should be before $b in the
+ *                   sorted array or not
+ *
+ * @access  private
+ */
+function PMA_usort_comparison_callback($a, $b)
+{
+    if ($GLOBALS['cfg']['NaturalOrder']) {
+        $sorter = 'strnatcasecmp';
+    } else {
+        $sorter = 'strcasecmp';
+    }
+    /* No sorting when key is not present */
+    if (! isset($a[$GLOBALS['callback_sort_by']])
+        || ! isset($b[$GLOBALS['callback_sort_by']])
+    ) {
+        return 0;
+    }
+    // produces f.e.:
+    // return -1 * strnatcasecmp($a["SCHEMA_TABLES"], $b["SCHEMA_TABLES"])
+    return ($GLOBALS['callback_sort_order'] == 'ASC' ? 1 : -1) * $sorter(
+        $a[$GLOBALS['callback_sort_by']], $b[$GLOBALS['callback_sort_by']]
+    );
+} // end of the 'PMA_usort_comparison_callback()' function
+
+/**
+ * returns array of all tables in given db or dbs
+ * this function expects unquoted names:
+ * RIGHT: my_database
+ * WRONG: `my_database`
+ * WRONG: my\_database
+ * if $tbl_is_group is true, $table is used as filter for table names
+ * if $tbl_is_group is 'comment, $table is used as filter for table comments
+ *
+ * <code>
+ * PMA_DBI_get_tables_full('my_database');
+ * PMA_DBI_get_tables_full('my_database', 'my_table'));
+ * PMA_DBI_get_tables_full('my_database', 'my_tables_', true));
+ * PMA_DBI_get_tables_full('my_database', 'my_tables_', 'comment'));
+ * </code>
+ *
+ * @param string          $database     database
+ * @param string|bool     $table        table or false
+ * @param boolean|string  $tbl_is_group $table is a table group
+ * @param mixed           $link         mysql link
+ * @param integer         $limit_offset zero-based offset for the count
+ * @param boolean|integer $limit_count  number of tables to return
+ * @param string          $sort_by      table attribute to sort by
+ * @param string          $sort_order   direction to sort (ASC or DESC)
+ *
+ * @todo    move into PMA_Table
+ *
+ * @return array           list of tables in given db(s)
+ */
+function PMA_DBI_get_tables_full($database, $table = false,
+    $tbl_is_group = false,  $link = null, $limit_offset = 0,
+    $limit_count = false, $sort_by = 'Name', $sort_order = 'ASC'
+) {
+    if (true === $limit_count) {
+        $limit_count = $GLOBALS['cfg']['MaxTableList'];
+    }
+    // prepare and check parameters
+    if (! is_array($database)) {
+        $databases = array($database);
+    } else {
+        $databases = $database;
+    }
+
+    $tables = array();
+
+    if (! $GLOBALS['cfg']['Server']['DisableIS']) {
+        // get table information from information_schema
+        if ($table) {
+            if (true === $tbl_is_group) {
+                $sql_where_table = 'AND t.`TABLE_NAME` LIKE \''
+                    . PMA_Util::escapeMysqlWildcards(PMA_Util::sqlAddSlashes($table))
+                    . '%\'';
+            } elseif ('comment' === $tbl_is_group) {
+                $sql_where_table = 'AND t.`TABLE_COMMENT` LIKE \''
+                    . PMA_Util::escapeMysqlWildcards(PMA_Util::sqlAddSlashes($table))
+                    . '%\'';
+            } else {
+                $sql_where_table = 'AND t.`TABLE_NAME` = \''
+                    . PMA_Util::sqlAddSlashes($table) . '\'';
+            }
+        } else {
+            $sql_where_table = '';
+        }
+
+        // for PMA bc:
+        // `SCHEMA_FIELD_NAME` AS `SHOW_TABLE_STATUS_FIELD_NAME`
+        //
+        // on non-Windows servers,
+        // added BINARY in the WHERE clause to force a case sensitive
+        // comparison (if we are looking for the db Aa we don't want
+        // to find the db aa)
+        $this_databases = array_map('PMA_Util::sqlAddSlashes', $databases);
+
+        if (PMA_DRIZZLE) {
+            $engine_info = PMA_Util::cacheGet('drizzle_engines', true);
+            $stats_join = "LEFT JOIN (SELECT 0 NUM_ROWS) AS stat ON false";
+            if (isset($engine_info['InnoDB'])
+                && $engine_info['InnoDB']['module_library'] == 'innobase'
+            ) {
+                $stats_join = "LEFT JOIN data_dictionary.INNODB_SYS_TABLESTATS stat"
+                    . " ON (t.ENGINE = 'InnoDB' AND stat.NAME"
+                    . " = (t.TABLE_SCHEMA || '/') || t.TABLE_NAME)";
+            }
+
+            // data_dictionary.table_cache may not contain any data for some tables,
+            // it's just a table cache
+            // auto_increment == 0 is cast to NULL because currently (2011.03.13 GA)
+            // Drizzle doesn't provide correct value
+            $sql = "
+                SELECT t.*,
+                    t.TABLE_SCHEMA        AS `Db`,
+                    t.TABLE_NAME          AS `Name`,
+                    t.TABLE_TYPE          AS `TABLE_TYPE`,
+                    t.ENGINE              AS `Engine`,
+                    t.ENGINE              AS `Type`,
+                    t.TABLE_VERSION       AS `Version`,-- VERSION
+                    t.ROW_FORMAT          AS `Row_format`,
+                    coalesce(tc.ROWS, stat.NUM_ROWS)
+                                          AS `Rows`,-- TABLE_ROWS,
+                    coalesce(tc.ROWS, stat.NUM_ROWS)
+                                          AS `TABLE_ROWS`,
+                    tc.AVG_ROW_LENGTH     AS `Avg_row_length`, -- AVG_ROW_LENGTH
+                    tc.TABLE_SIZE         AS `Data_length`, -- DATA_LENGTH
+                    NULL                  AS `Max_data_length`, -- MAX_DATA_LENGTH
+                    NULL                  AS `Index_length`, -- INDEX_LENGTH
+                    NULL                  AS `Data_free`, -- DATA_FREE
+                    nullif(t.AUTO_INCREMENT, 0)
+                                          AS `Auto_increment`,
+                    t.TABLE_CREATION_TIME AS `Create_time`, -- CREATE_TIME
+                    t.TABLE_UPDATE_TIME   AS `Update_time`, -- UPDATE_TIME
+                    NULL                  AS `Check_time`, -- CHECK_TIME
+                    t.TABLE_COLLATION     AS `Collation`,
+                    NULL                  AS `Checksum`, -- CHECKSUM
+                    NULL                  AS `Create_options`, -- CREATE_OPTIONS
+                    t.TABLE_COMMENT       AS `Comment`
+                FROM data_dictionary.TABLES t
+                    LEFT JOIN data_dictionary.TABLE_CACHE tc
+                        ON tc.TABLE_SCHEMA = t.TABLE_SCHEMA AND tc.TABLE_NAME
+                        = t.TABLE_NAME
+                    $stats_join
+                WHERE t.TABLE_SCHEMA IN ('" . implode("', '", $this_databases) . "')
+                    " . $sql_where_table;
+        } else {
+            $sql = '
+                SELECT *,
+                    `TABLE_SCHEMA`       AS `Db`,
+                    `TABLE_NAME`         AS `Name`,
+                    `TABLE_TYPE`         AS `TABLE_TYPE`,
+                    `ENGINE`             AS `Engine`,
+                    `ENGINE`             AS `Type`,
+                    `VERSION`            AS `Version`,
+                    `ROW_FORMAT`         AS `Row_format`,
+                    `TABLE_ROWS`         AS `Rows`,
+                    `AVG_ROW_LENGTH`     AS `Avg_row_length`,
+                    `DATA_LENGTH`        AS `Data_length`,
+                    `MAX_DATA_LENGTH`    AS `Max_data_length`,
+                    `INDEX_LENGTH`       AS `Index_length`,
+                    `DATA_FREE`          AS `Data_free`,
+                    `AUTO_INCREMENT`     AS `Auto_increment`,
+                    `CREATE_TIME`        AS `Create_time`,
+                    `UPDATE_TIME`        AS `Update_time`,
+                    `CHECK_TIME`         AS `Check_time`,
+                    `TABLE_COLLATION`    AS `Collation`,
+                    `CHECKSUM`           AS `Checksum`,
+                    `CREATE_OPTIONS`     AS `Create_options`,
+                    `TABLE_COMMENT`      AS `Comment`
+                FROM `information_schema`.`TABLES` t
+                WHERE ' . (PMA_IS_WINDOWS ? '' : 'BINARY') . ' `TABLE_SCHEMA`
+                    IN (\'' . implode("', '", $this_databases) . '\')
+                    ' . $sql_where_table;
+        }
+
+        // Sort the tables
+        $sql .= " ORDER BY $sort_by $sort_order";
+
+        if ($limit_count) {
+            $sql .= ' LIMIT ' . $limit_count . ' OFFSET ' . $limit_offset;
+        }
+
+        $tables = PMA_DBI_fetch_result(
+            $sql, array('TABLE_SCHEMA', 'TABLE_NAME'), null, $link
+        );
+        unset($sql_where_table, $sql);
+
+        if (PMA_DRIZZLE) {
+            // correct I_S and D_D names returned by D_D.TABLES -
+            // Drizzle generally uses lower case for them,
+            // but TABLES returns uppercase
+            foreach ((array)$database as $db) {
+                $db_upper = strtoupper($db);
+                if (!isset($tables[$db]) && isset($tables[$db_upper])) {
+                    $tables[$db] = $tables[$db_upper];
+                    unset($tables[$db_upper]);
+                }
+            }
+        }
+
+        if ($sort_by == 'Name' && $GLOBALS['cfg']['NaturalOrder']) {
+            // here, the array's first key is by schema name
+            foreach ($tables as $one_database_name => $one_database_tables) {
+                uksort($one_database_tables, 'strnatcasecmp');
+
+                if ($sort_order == 'DESC') {
+                    $one_database_tables = array_reverse($one_database_tables);
+                }
+                $tables[$one_database_name] = $one_database_tables;
+            }
+        }
+    } // end (get information from table schema)
+
+    // If permissions are wrong on even one database directory,
+    // information_schema does not return any table info for any database
+    // this is why we fall back to SHOW TABLE STATUS even for MySQL >= 50002
+    if (empty($tables) && !PMA_DRIZZLE) {
+        foreach ($databases as $each_database) {
+            if ($table || (true === $tbl_is_group)) {
+                $sql = 'SHOW TABLE STATUS FROM '
+                    . PMA_Util::backquote($each_database)
+                    .' LIKE \''
+                    . PMA_Util::escapeMysqlWildcards(
+                        PMA_Util::sqlAddSlashes($table, true)
+                    )
+                    . '%\'';
+            } else {
+                $sql = 'SHOW TABLE STATUS FROM '
+                    . PMA_Util::backquote($each_database);
+            }
+
+            $useStatusCache = false;
+
+            if (extension_loaded('apc')
+                && isset($GLOBALS['cfg']['Server']['StatusCacheDatabases'])
+                && ! empty($GLOBALS['cfg']['Server']['StatusCacheLifetime'])
+            ) {
+                $statusCacheDatabases
+                    = (array) $GLOBALS['cfg']['Server']['StatusCacheDatabases'];
+                if (in_array($each_database, $statusCacheDatabases)) {
+                    $useStatusCache = true;
+                }
+            }
+
+            $each_tables = null;
+
+            if ($useStatusCache) {
+                $cacheKey = 'phpMyAdmin_tableStatus_'
+                    . sha1($GLOBALS['cfg']['Server']['host'] . '_' . $sql);
+
+                $each_tables = apc_fetch($cacheKey);
+            }
+
+            if (!$each_tables) {
+                $each_tables = PMA_DBI_fetch_result($sql, 'Name', null, $link);
+            }
+
+            if ($useStatusCache) {
+                apc_store(
+                    $cacheKey, $each_tables,
+                    $GLOBALS['cfg']['Server']['StatusCacheLifetime']
+                );
+            }
+
+            // Sort naturally if the config allows it and we're sorting
+            // the Name column.
+            if ($sort_by == 'Name' && $GLOBALS['cfg']['NaturalOrder']) {
+                uksort($each_tables, 'strnatcasecmp');
+
+                if ($sort_order == 'DESC') {
+                    $each_tables = array_reverse($each_tables);
+                }
+            } else {
+                // Prepare to sort by creating array of the selected sort
+                // value to pass to array_multisort
+
+                // Size = Data_length + Index_length
+                if ($sort_by == 'Data_length') {
+                    foreach ($each_tables as $table_name => $table_data) {
+                        ${$sort_by}[$table_name] = strtolower(
+                            $table_data['Data_length'] + $table_data['Index_length']
+                        );
+                    }
+                } else {
+                    foreach ($each_tables as $table_name => $table_data) {
+                        ${$sort_by}[$table_name] = strtolower($table_data[$sort_by]);
+                    }
+                }
+
+                if ($sort_order == 'DESC') {
+                    array_multisort($$sort_by, SORT_DESC, $each_tables);
+                } else {
+                    array_multisort($$sort_by, SORT_ASC, $each_tables);
+                }
+
+                // cleanup the temporary sort array
+                unset($$sort_by);
+            }
+
+            if ($limit_count) {
+                $each_tables = array_slice(
+                    $each_tables, $limit_offset, $limit_count
+                );
+            }
+
+            foreach ($each_tables as $table_name => $each_table) {
+                if ('comment' === $tbl_is_group
+                    && 0 === strpos($each_table['Comment'], $table)
+                ) {
+                    // remove table from list
+                    unset($each_tables[$table_name]);
+                    continue;
+                }
+
+                if (! isset($each_tables[$table_name]['Type'])
+                    && isset($each_tables[$table_name]['Engine'])
+                ) {
+                    // pma BC, same parts of PMA still uses 'Type'
+                    $each_tables[$table_name]['Type']
+                        =& $each_tables[$table_name]['Engine'];
+                } elseif (! isset($each_tables[$table_name]['Engine'])
+                        && isset($each_tables[$table_name]['Type'])) {
+                    // old MySQL reports Type, newer MySQL reports Engine
+                    $each_tables[$table_name]['Engine']
+                        =& $each_tables[$table_name]['Type'];
+                }
+
+                // MySQL forward compatibility
+                // so pma could use this array as if every server is of version >5.0
+                // todo : remove and check usage in the rest of the code,
+                // MySQL 5.0 is required by current PMA version
+                $each_tables[$table_name]['TABLE_SCHEMA']      = $each_database;
+                $each_tables[$table_name]['TABLE_NAME']
+                    =& $each_tables[$table_name]['Name'];
+                $each_tables[$table_name]['ENGINE']
+                    =& $each_tables[$table_name]['Engine'];
+                $each_tables[$table_name]['VERSION']
+                    =& $each_tables[$table_name]['Version'];
+                $each_tables[$table_name]['ROW_FORMAT']
+                    =& $each_tables[$table_name]['Row_format'];
+                $each_tables[$table_name]['TABLE_ROWS']
+                    =& $each_tables[$table_name]['Rows'];
+                $each_tables[$table_name]['AVG_ROW_LENGTH']
+                    =& $each_tables[$table_name]['Avg_row_length'];
+                $each_tables[$table_name]['DATA_LENGTH']
+                    =& $each_tables[$table_name]['Data_length'];
+                $each_tables[$table_name]['MAX_DATA_LENGTH']
+                    =& $each_tables[$table_name]['Max_data_length'];
+                $each_tables[$table_name]['INDEX_LENGTH']
+                    =& $each_tables[$table_name]['Index_length'];
+                $each_tables[$table_name]['DATA_FREE']
+                    =& $each_tables[$table_name]['Data_free'];
+                $each_tables[$table_name]['AUTO_INCREMENT']
+                    =& $each_tables[$table_name]['Auto_increment'];
+                $each_tables[$table_name]['CREATE_TIME']
+                    =& $each_tables[$table_name]['Create_time'];
+                $each_tables[$table_name]['UPDATE_TIME']
+                    =& $each_tables[$table_name]['Update_time'];
+                $each_tables[$table_name]['CHECK_TIME']
+                    =& $each_tables[$table_name]['Check_time'];
+                $each_tables[$table_name]['TABLE_COLLATION']
+                    =& $each_tables[$table_name]['Collation'];
+                $each_tables[$table_name]['CHECKSUM']
+                    =& $each_tables[$table_name]['Checksum'];
+                $each_tables[$table_name]['CREATE_OPTIONS']
+                    =& $each_tables[$table_name]['Create_options'];
+                $each_tables[$table_name]['TABLE_COMMENT']
+                    =& $each_tables[$table_name]['Comment'];
+
+                if (strtoupper($each_tables[$table_name]['Comment']) === 'VIEW'
+                    && $each_tables[$table_name]['Engine'] == null
+                ) {
+                    $each_tables[$table_name]['TABLE_TYPE'] = 'VIEW';
+                } else {
+                    /**
+                     * @todo difference between 'TEMPORARY' and 'BASE TABLE'
+                     * but how to detect?
+                     */
+                    $each_tables[$table_name]['TABLE_TYPE'] = 'BASE TABLE';
+                }
+            }
+
+            $tables[$each_database] = $each_tables;
+        }
+    }
+
+    // cache table data
+    // so PMA_Table does not require to issue SHOW TABLE STATUS again
+    // Note: I don't see why we would need array_merge_recursive() here,
+    // as it creates double entries for the same table (for example a double
+    // entry for Comment when changing the storage engine in Operations)
+    // Note 2: Instead of array_merge(), simply use the + operator because
+    //  array_merge() renumbers numeric keys starting with 0, therefore
+    //  we would lose a db name thats consists only of numbers
+    foreach ($tables as $one_database => $its_tables) {
+        if (isset(PMA_Table::$cache[$one_database])) {
+            PMA_Table::$cache[$one_database]
+                = PMA_Table::$cache[$one_database] + $tables[$one_database];
+        } else {
+            PMA_Table::$cache[$one_database] = $tables[$one_database];
+        }
+    }
+    unset($one_database, $its_tables);
+
+    if (! is_array($database)) {
+        if (isset($tables[$database])) {
+            return $tables[$database];
+        } elseif (isset($tables[strtolower($database)])) {
+            // on windows with lower_case_table_names = 1
+            // MySQL returns
+            // with SHOW DATABASES or information_schema.SCHEMATA: `Test`
+            // but information_schema.TABLES gives `test`
+            // bug #2036
+            // https://sourceforge.net/p/phpmyadmin/bugs/2036/
+            return $tables[strtolower($database)];
+        } else {
+            // one database but inexact letter case match
+            // as Drizzle is always case insensitive,
+            // we can safely return the only result
+            if (PMA_DRIZZLE && count($tables) == 1) {
+                $keys = array_keys($tables);
+                if (strlen(array_pop($keys)) == strlen($database)) {
+                    return array_pop($tables);
+                }
+            }
+            return $tables;
+        }
+    } else {
+        return $tables;
+    }
+}
+
+
+/**
+ * Get VIEWs in a particular database
+ *
+ * @param string $db Database name to look in
+ *
+ * @return array $views Set of VIEWs inside the database
+ */
+function PMA_DBI_getVirtualTables($db)
+{
+
+    $tables_full = PMA_DBI_get_tables_full($db);
+    $views = array();
+
+    foreach ($tables_full as $table=>$tmp) {
+
+        if (PMA_Table::isView($db, $table)) {
+            $views[] = $table;
+        }
+
+    }
+
+    return $views;
+
+}
+
+
+/**
+ * returns array with databases containing extended infos about them
+ *
+ * @param string   $database     database
+ * @param boolean  $force_stats  retrieve stats also for MySQL < 5
+ * @param resource $link         mysql link
+ * @param string   $sort_by      column to order by
+ * @param string   $sort_order   ASC or DESC
+ * @param integer  $limit_offset starting offset for LIMIT
+ * @param bool|int $limit_count  row count for LIMIT or true
+ *                               for $GLOBALS['cfg']['MaxDbList']
+ *
+ * @todo    move into PMA_List_Database?
+ *
+ * @return array $databases
+ */
+function PMA_DBI_get_databases_full($database = null, $force_stats = false,
+    $link = null, $sort_by = 'SCHEMA_NAME', $sort_order = 'ASC',
+    $limit_offset = 0, $limit_count = false
+) {
+    $sort_order = strtoupper($sort_order);
+
+    if (true === $limit_count) {
+        $limit_count = $GLOBALS['cfg']['MaxDbList'];
+    }
+
+    // initialize to avoid errors when there are no databases
+    $databases = array();
+
+    $apply_limit_and_order_manual = true;
+
+    if (! $GLOBALS['cfg']['Server']['DisableIS']) {
+        /**
+         * if $GLOBALS['cfg']['NaturalOrder'] is enabled, we cannot use LIMIT
+         * cause MySQL does not support natural ordering, we have to do it afterward
+         */
+        $limit = '';
+        if (!$GLOBALS['cfg']['NaturalOrder']) {
+            if ($limit_count) {
+                $limit = ' LIMIT ' . $limit_count . ' OFFSET ' . $limit_offset;
+            }
+
+            $apply_limit_and_order_manual = false;
+        }
+
+        // get table information from information_schema
+        if ($database) {
+            $sql_where_schema = 'WHERE `SCHEMA_NAME` LIKE \''
+                . PMA_Util::sqlAddSlashes($database) . '\'';
+        } else {
+            $sql_where_schema = '';
+        }
+
+        if (PMA_DRIZZLE) {
+            // data_dictionary.table_cache may not contain any data for some
+            // tables, it's just a table cache
+            $sql = 'SELECT
+                s.SCHEMA_NAME,
+                s.DEFAULT_COLLATION_NAME';
+            if ($force_stats) {
+                // no TABLE_CACHE data, stable results are better than
+                // constantly changing
+                $sql .= ',
+                    COUNT(t.TABLE_SCHEMA) AS SCHEMA_TABLES,
+                    SUM(stat.NUM_ROWS)    AS SCHEMA_TABLE_ROWS';
+            }
+            $sql .= '
+                   FROM data_dictionary.SCHEMAS s';
+            if ($force_stats) {
+                $engine_info = PMA_Util::cacheGet('drizzle_engines', true);
+                $stats_join = "LEFT JOIN (SELECT 0 NUM_ROWS) AS stat ON false";
+                if (isset($engine_info['InnoDB'])
+                    && $engine_info['InnoDB']['module_library'] == 'innobase'
+                ) {
+                    $stats_join = "LEFT JOIN data_dictionary.INNODB_SYS_TABLESTATS"
+                        . " stat ON (t.ENGINE = 'InnoDB' AND stat.NAME"
+                        . " = (t.TABLE_SCHEMA || '/') || t.TABLE_NAME)";
+                }
+
+                $sql .= "
+                    LEFT JOIN data_dictionary.TABLES t
+                        ON t.TABLE_SCHEMA = s.SCHEMA_NAME
+                    $stats_join";
+            }
+            $sql .= $sql_where_schema . '
+                    GROUP BY s.SCHEMA_NAME
+                    ORDER BY ' . PMA_Util::backquote($sort_by) . ' ' . $sort_order
+                . $limit;
+        } else {
+            $sql = 'SELECT
+                s.SCHEMA_NAME,
+                s.DEFAULT_COLLATION_NAME';
+            if ($force_stats) {
+                $sql .= ',
+                    COUNT(t.TABLE_SCHEMA)  AS SCHEMA_TABLES,
+                    SUM(t.TABLE_ROWS)      AS SCHEMA_TABLE_ROWS,
+                    SUM(t.DATA_LENGTH)     AS SCHEMA_DATA_LENGTH,
+                    SUM(t.MAX_DATA_LENGTH) AS SCHEMA_MAX_DATA_LENGTH,
+                    SUM(t.INDEX_LENGTH)    AS SCHEMA_INDEX_LENGTH,
+                    SUM(t.DATA_LENGTH + t.INDEX_LENGTH)
+                                           AS SCHEMA_LENGTH,
+                    SUM(t.DATA_FREE)       AS SCHEMA_DATA_FREE';
+            }
+            $sql .= '
+                   FROM `information_schema`.SCHEMATA s';
+            if ($force_stats) {
+                $sql .= '
+                    LEFT JOIN `information_schema`.TABLES t
+                        ON BINARY t.TABLE_SCHEMA = BINARY s.SCHEMA_NAME';
+            }
+            $sql .= $sql_where_schema . '
+                    GROUP BY BINARY s.SCHEMA_NAME
+                    ORDER BY BINARY ' . PMA_Util::backquote($sort_by)
+                . ' ' . $sort_order
+                . $limit;
+        }
+
+        $databases = PMA_DBI_fetch_result($sql, 'SCHEMA_NAME', null, $link);
+
+        $mysql_error = PMA_DBI_getError($link);
+        if (! count($databases) && $GLOBALS['errno']) {
+            PMA_Util::mysqlDie($mysql_error, $sql);
+        }
+
+        // display only databases also in official database list
+        // f.e. to apply hide_db and only_db
+        $drops = array_diff(
+            array_keys($databases), (array) $GLOBALS['pma']->databases
+        );
+        if (count($drops)) {
+            foreach ($drops as $drop) {
+                unset($databases[$drop]);
+            }
+            unset($drop);
+        }
+        unset($sql_where_schema, $sql, $drops);
+    } else {
+        foreach ($GLOBALS['pma']->databases as $database_name) {
+            // MySQL forward compatibility
+            // so pma could use this array as if every server is of version >5.0
+            // todo : remove and check the rest of the code for usage,
+            // MySQL 5.0 or higher is required for current PMA version
+            $databases[$database_name]['SCHEMA_NAME']      = $database_name;
+
+            if ($force_stats) {
+                include_once './libraries/mysql_charsets.lib.php';
+
+                $databases[$database_name]['DEFAULT_COLLATION_NAME']
+                    = PMA_getDbCollation($database_name);
+
+                // get additional info about tables
+                $databases[$database_name]['SCHEMA_TABLES']          = 0;
+                $databases[$database_name]['SCHEMA_TABLE_ROWS']      = 0;
+                $databases[$database_name]['SCHEMA_DATA_LENGTH']     = 0;
+                $databases[$database_name]['SCHEMA_MAX_DATA_LENGTH'] = 0;
+                $databases[$database_name]['SCHEMA_INDEX_LENGTH']    = 0;
+                $databases[$database_name]['SCHEMA_LENGTH']          = 0;
+                $databases[$database_name]['SCHEMA_DATA_FREE']       = 0;
+
+                $res = PMA_DBI_query(
+                    'SHOW TABLE STATUS FROM '
+                    . PMA_Util::backquote($database_name) . ';'
+                );
+
+                while ($row = PMA_DBI_fetch_assoc($res)) {
+                    $databases[$database_name]['SCHEMA_TABLES']++;
+                    $databases[$database_name]['SCHEMA_TABLE_ROWS']
+                        += $row['Rows'];
+                    $databases[$database_name]['SCHEMA_DATA_LENGTH']
+                        += $row['Data_length'];
+                    $databases[$database_name]['SCHEMA_MAX_DATA_LENGTH']
+                        += $row['Max_data_length'];
+                    $databases[$database_name]['SCHEMA_INDEX_LENGTH']
+                        += $row['Index_length'];
+
+                    // for InnoDB, this does not contain the number of
+                    // overhead bytes but the total free space
+                    if ('InnoDB' != $row['Engine']) {
+                        $databases[$database_name]['SCHEMA_DATA_FREE']
+                            += $row['Data_free'];
+                    }
+                    $databases[$database_name]['SCHEMA_LENGTH']
+                        += $row['Data_length'] + $row['Index_length'];
+                }
+                PMA_DBI_free_result($res);
+                unset($res);
+            }
+        }
+    }
+
+
+    /**
+     * apply limit and order manually now
+     * (caused by older MySQL < 5 or $GLOBALS['cfg']['NaturalOrder'])
+     */
+    if ($apply_limit_and_order_manual) {
+        $GLOBALS['callback_sort_order'] = $sort_order;
+        $GLOBALS['callback_sort_by'] = $sort_by;
+        usort($databases, 'PMA_usort_comparison_callback');
+        unset($GLOBALS['callback_sort_order'], $GLOBALS['callback_sort_by']);
+
+        /**
+         * now apply limit
+         */
+        if ($limit_count) {
+            $databases = array_slice($databases, $limit_offset, $limit_count);
+        }
+    }
+
+    return $databases;
+}
+
+/**
+ * returns detailed array with all columns for given table in database,
+ * or all tables/databases
+ *
+ * @param string $database name of database
+ * @param string $table    name of table to retrieve columns from
+ * @param string $column   name of specific column
+ * @param mixed  $link     mysql link resource
+ *
+ * @return array
+ */
+function PMA_DBI_get_columns_full($database = null, $table = null,
+    $column = null, $link = null
+) {
+    $columns = array();
+
+    if (! $GLOBALS['cfg']['Server']['DisableIS']) {
+        $sql_wheres = array();
+        $array_keys = array();
+
+        // get columns information from information_schema
+        if (null !== $database) {
+            $sql_wheres[] = '`TABLE_SCHEMA` = \''
+                . PMA_Util::sqlAddSlashes($database) . '\' ';
+        } else {
+            $array_keys[] = 'TABLE_SCHEMA';
+        }
+        if (null !== $table) {
+            $sql_wheres[] = '`TABLE_NAME` = \''
+                . PMA_Util::sqlAddSlashes($table) . '\' ';
+        } else {
+            $array_keys[] = 'TABLE_NAME';
+        }
+        if (null !== $column) {
+            $sql_wheres[] = '`COLUMN_NAME` = \''
+                . PMA_Util::sqlAddSlashes($column) . '\' ';
+        } else {
+            $array_keys[] = 'COLUMN_NAME';
+        }
+
+        // for PMA bc:
+        // `[SCHEMA_FIELD_NAME]` AS `[SHOW_FULL_COLUMNS_FIELD_NAME]`
+        if (PMA_DRIZZLE) {
+            $sql = "SELECT TABLE_SCHEMA, TABLE_NAME, COLUMN_NAME,
+                column_name        AS `Field`,
+                (CASE
+                    WHEN character_maximum_length > 0
+                    THEN concat(lower(data_type), '(', character_maximum_length, ')')
+                    WHEN numeric_precision > 0 OR numeric_scale > 0
+                    THEN concat(lower(data_type), '(', numeric_precision,
+                        ',', numeric_scale, ')')
+                    WHEN enum_values IS NOT NULL
+                        THEN concat(lower(data_type), '(', enum_values, ')')
+                    ELSE lower(data_type) END)
+                                   AS `Type`,
+                collation_name     AS `Collation`,
+                (CASE is_nullable
+                    WHEN 1 THEN 'YES'
+                    ELSE 'NO' END) AS `Null`,
+                (CASE
+                    WHEN is_used_in_primary THEN 'PRI'
+                    ELSE '' END)   AS `Key`,
+                column_default     AS `Default`,
+                (CASE
+                    WHEN is_auto_increment THEN 'auto_increment'
+                    WHEN column_default_update
+                    THEN 'on update ' || column_default_update
+                    ELSE '' END)   AS `Extra`,
+                NULL               AS `Privileges`,
+                column_comment     AS `Comment`
+            FROM data_dictionary.columns";
+        } else {
+            $sql = '
+                 SELECT *,
+                        `COLUMN_NAME`       AS `Field`,
+                        `COLUMN_TYPE`       AS `Type`,
+                        `COLLATION_NAME`    AS `Collation`,
+                        `IS_NULLABLE`       AS `Null`,
+                        `COLUMN_KEY`        AS `Key`,
+                        `COLUMN_DEFAULT`    AS `Default`,
+                        `EXTRA`             AS `Extra`,
+                        `PRIVILEGES`        AS `Privileges`,
+                        `COLUMN_COMMENT`    AS `Comment`
+                   FROM `information_schema`.`COLUMNS`';
+        }
+        if (count($sql_wheres)) {
+            $sql .= "\n" . ' WHERE ' . implode(' AND ', $sql_wheres);
+        }
+
+        $columns = PMA_DBI_fetch_result($sql, $array_keys, null, $link);
+        unset($sql_wheres, $sql);
+    } else {
+        if (null === $database) {
+            foreach ($GLOBALS['pma']->databases as $database) {
+                $columns[$database] = PMA_DBI_get_columns_full(
+                    $database, null, null, $link
+                );
+            }
+            return $columns;
+        } elseif (null === $table) {
+            $tables = PMA_DBI_get_tables($database);
+            foreach ($tables as $table) {
+                $columns[$table] = PMA_DBI_get_columns_full(
+                    $database, $table, null, $link
+                );
+            }
+            return $columns;
+        }
+
+        $sql = 'SHOW FULL COLUMNS FROM '
+            . PMA_Util::backquote($database) . '.' . PMA_Util::backquote($table);
+        if (null !== $column) {
+            $sql .= " LIKE '" . PMA_Util::sqlAddSlashes($column, true) . "'";
+        }
+
+        $columns = PMA_DBI_fetch_result($sql, 'Field', null, $link);
+    }
+    $ordinal_position = 1;
+    foreach ($columns as $column_name => $each_column) {
+
+        // MySQL forward compatibility
+        // so pma could use this array as if every server is of version >5.0
+        // todo : remove and check the rest of the code for usage,
+        // MySQL 5.0 or higher is required for current PMA version
+        $columns[$column_name]['COLUMN_NAME'] =& $columns[$column_name]['Field'];
+        $columns[$column_name]['COLUMN_TYPE'] =& $columns[$column_name]['Type'];
+        $columns[$column_name]['COLLATION_NAME']
+            =& $columns[$column_name]['Collation'];
+        $columns[$column_name]['IS_NULLABLE'] =& $columns[$column_name]['Null'];
+        $columns[$column_name]['COLUMN_KEY'] =& $columns[$column_name]['Key'];
+        $columns[$column_name]['COLUMN_DEFAULT']
+            =& $columns[$column_name]['Default'];
+        $columns[$column_name]['EXTRA']
+            =& $columns[$column_name]['Extra'];
+        $columns[$column_name]['PRIVILEGES']
+            =& $columns[$column_name]['Privileges'];
+        $columns[$column_name]['COLUMN_COMMENT']
+            =& $columns[$column_name]['Comment'];
+
+        $columns[$column_name]['TABLE_CATALOG'] = null;
+        $columns[$column_name]['TABLE_SCHEMA'] = $database;
+        $columns[$column_name]['TABLE_NAME'] = $table;
+        $columns[$column_name]['ORDINAL_POSITION'] = $ordinal_position;
+        $columns[$column_name]['DATA_TYPE']
+            = substr(
+                $columns[$column_name]['COLUMN_TYPE'],
+                0,
+                strpos($columns[$column_name]['COLUMN_TYPE'], '(')
+            );
+        /**
+         * @todo guess CHARACTER_MAXIMUM_LENGTH from COLUMN_TYPE
+         */
+        $columns[$column_name]['CHARACTER_MAXIMUM_LENGTH'] = null;
+        /**
+         * @todo guess CHARACTER_OCTET_LENGTH from CHARACTER_MAXIMUM_LENGTH
+         */
+        $columns[$column_name]['CHARACTER_OCTET_LENGTH'] = null;
+        $columns[$column_name]['NUMERIC_PRECISION'] = null;
+        $columns[$column_name]['NUMERIC_SCALE'] = null;
+        $columns[$column_name]['CHARACTER_SET_NAME']
+            = substr(
+                $columns[$column_name]['COLLATION_NAME'],
+                0,
+                strpos($columns[$column_name]['COLLATION_NAME'], '_')
+            );
+
+        $ordinal_position++;
+    }
+
+    if (null !== $column) {
+        reset($columns);
+        $columns = current($columns);
+    }
+
+    return $columns;
+}
+
+/**
+ * Returns SQL query for fetching columns for a table
+ *
+ * The 'Key' column is not calculated properly, use PMA_DBI_get_columns() to get
+ * correct values.
+ *
+ * @param string  $database name of database
+ * @param string  $table    name of table to retrieve columns from
+ * @param string  $column   name of column, null to show all columns
+ * @param boolean $full     whether to return full info or only column names
+ *
+ * @see PMA_DBI_get_columns()
+ *
+ * @return string
+ */
+function PMA_DBI_get_columns_sql($database, $table, $column = null, $full = false)
+{
+    if (PMA_DRIZZLE) {
+        // `Key` column:
+        // * used in primary key => PRI
+        // * unique one-column => UNI
+        // * indexed, one-column or first in multi-column => MUL
+        // Promotion of UNI to PRI in case no promary index exists
+        // is done after query is executed
+        $sql = "SELECT
+                column_name        AS `Field`,
+                (CASE
+                    WHEN character_maximum_length > 0
+                    THEN concat(lower(data_type), '(', character_maximum_length, ')')
+                    WHEN numeric_precision > 0 OR numeric_scale > 0
+                    THEN concat(lower(data_type), '(', numeric_precision,
+                        ',', numeric_scale, ')')
+                    WHEN enum_values IS NOT NULL
+                        THEN concat(lower(data_type), '(', enum_values, ')')
+                    ELSE lower(data_type) END)
+                                   AS `Type`,
+                " . ($full ? "
+                collation_name     AS `Collation`," : '') . "
+                (CASE is_nullable
+                    WHEN 1 THEN 'YES'
+                    ELSE 'NO' END) AS `Null`,
+                (CASE
+                    WHEN is_used_in_primary THEN 'PRI'
+                    WHEN is_unique AND NOT is_multi THEN 'UNI'
+                    WHEN is_indexed
+                    AND (NOT is_multi OR is_first_in_multi) THEN 'MUL'
+                    ELSE '' END)   AS `Key`,
+                column_default     AS `Default`,
+                (CASE
+                    WHEN is_auto_increment THEN 'auto_increment'
+                    WHEN column_default_update <> ''
+                    THEN 'on update ' || column_default_update
+                    ELSE '' END)   AS `Extra`
+                " . ($full ? " ,
+                NULL               AS `Privileges`,
+                column_comment     AS `Comment`" : '') . "
+            FROM data_dictionary.columns
+            WHERE table_schema = '" . PMA_Util::sqlAddSlashes($database) . "'
+                AND table_name = '" . PMA_Util::sqlAddSlashes($table) . "'
+                " . (($column != null) ? "
+                AND column_name = '" . PMA_Util::sqlAddSlashes($column) . "'" : '');
+        // ORDER BY ordinal_position
+    } else {
+        $sql = 'SHOW ' . ($full ? 'FULL' : '') . ' COLUMNS FROM '
+            . PMA_Util::backquote($database) . '.' . PMA_Util::backquote($table)
+            . (($column != null) ? "LIKE '"
+            . PMA_Util::sqlAddSlashes($column, true) . "'" : '');
+    }
+    return $sql;
+}
+
+/**
+ * Returns descriptions of columns in given table (all or given by $column)
+ *
+ * @param string  $database name of database
+ * @param string  $table    name of table to retrieve columns from
+ * @param string  $column   name of column, null to show all columns
+ * @param boolean $full     whether to return full info or only column names
+ * @param mixed   $link     mysql link resource
+ *
+ * @return false|array   array indexed by column names or,
+ *                        if $column is given, flat array description
+ */
+function PMA_DBI_get_columns($database, $table, $column = null, $full = false,
+    $link = null
+) {
+    $sql = PMA_DBI_get_columns_sql($database, $table, $column, $full);
+    $fields = PMA_DBI_fetch_result($sql, 'Field', null, $link);
+    if (! is_array($fields) || count($fields) == 0) {
+        return null;
+    }
+    if (PMA_DRIZZLE) {
+        // fix Key column, it's much simpler in PHP than in SQL
+        $has_pk = false;
+        $has_pk_candidates = false;
+        foreach ($fields as $f) {
+            if ($f['Key'] == 'PRI') {
+                $has_pk = true;
+                break;
+            } else if ($f['Null'] == 'NO'
+                && ($f['Key'] == 'MUL'
+                || $f['Key'] == 'UNI')
+            ) {
+                $has_pk_candidates = true;
+            }
+        }
+        if (!$has_pk && $has_pk_candidates) {
+            // check whether we can promote some unique index to PRI
+            $sql = "
+                SELECT i.index_name, p.column_name
+                FROM data_dictionary.indexes i
+                    JOIN data_dictionary.index_parts p
+                    USING (table_schema, table_name)
+                WHERE i.table_schema = '" . PMA_Util::sqlAddSlashes($database) . "'
+                    AND i.table_name = '" . PMA_Util::sqlAddSlashes($table) . "'
+                    AND i.is_unique
+                        AND NOT i.is_nullable";
+            $fs = PMA_DBI_fetch_result($sql, 'index_name', null, $link);
+            $fs = $fs ? array_shift($fs) : array();
+            foreach ($fs as $f) {
+                $fields[$f]['Key'] = 'PRI';
+            }
+        }
+    }
+
+    return ($column != null) ? array_shift($fields) : $fields;
+}
+
+/**
+ * Returns all column names in given table
+ *
+ * @param string $database name of database
+ * @param string $table    name of table to retrieve columns from
+ * @param mixed  $link     mysql link resource
+ *
+ * @return null|array
+ */
+function PMA_DBI_get_column_names($database, $table, $link = null)
+{
+    $sql = PMA_DBI_get_columns_sql($database, $table);
+    // We only need the 'Field' column which contains the table's column names
+    $fields = array_keys(PMA_DBI_fetch_result($sql, 'Field', null, $link));
+
+    if ( ! is_array($fields) || count($fields) == 0 ) {
+        return null;
+    }
+    return $fields;
+}
+
+/**
+* Returns SQL for fetching information on table indexes (SHOW INDEXES)
+*
+* @param string $database name of database
+* @param string $table    name of the table whose indexes are to be retreived
+* @param string $where    additional conditions for WHERE
+*
+* @return array   $indexes
+*/
+function PMA_DBI_get_table_indexes_sql($database, $table, $where = null)
+{
+    if (PMA_DRIZZLE) {
+        $sql = "SELECT
+                ip.table_name          AS `Table`,
+                (NOT ip.is_unique)     AS Non_unique,
+                ip.index_name          AS Key_name,
+                ip.sequence_in_index+1 AS Seq_in_index,
+                ip.column_name         AS Column_name,
+                (CASE
+                    WHEN i.index_type = 'BTREE' THEN 'A'
+                    ELSE NULL END)     AS Collation,
+                NULL                   AS Cardinality,
+                compare_length         AS Sub_part,
+                NULL                   AS Packed,
+                ip.is_nullable         AS `Null`,
+                i.index_type           AS Index_type,
+                NULL                   AS Comment,
+                i.index_comment        AS Index_comment
+            FROM data_dictionary.index_parts ip
+                LEFT JOIN data_dictionary.indexes i
+                USING (table_schema, table_name, index_name)
+            WHERE table_schema = '" . PMA_Util::sqlAddSlashes($database) . "'
+                AND table_name = '" . PMA_Util::sqlAddSlashes($table) . "'
+        ";
+    } else {
+        $sql = 'SHOW INDEXES FROM ' . PMA_Util::backquote($database) . '.'
+            . PMA_Util::backquote($table);
+    }
+    if ($where) {
+        $sql .= (PMA_DRIZZLE ? ' AND (' : ' WHERE (') . $where . ')';
+    }
+    return $sql;
+}
+
+/**
+* Returns indexes of a table
+*
+* @param string $database name of database
+* @param string $table    name of the table whose indexes are to be retrieved
+* @param mixed  $link     mysql link resource
+*
+* @return array   $indexes
+*/
+function PMA_DBI_get_table_indexes($database, $table, $link = null)
+{
+    $sql = PMA_DBI_get_table_indexes_sql($database, $table);
+    $indexes = PMA_DBI_fetch_result($sql, null, null, $link);
+
+    if (! is_array($indexes) || count($indexes) < 1) {
+        return array();
+    }
+    return $indexes;
+}
+
+/**
+ * returns value of given mysql server variable
+ *
+ * @param string $var  mysql server variable name
+ * @param int    $type PMA_DBI_GETVAR_SESSION|PMA_DBI_GETVAR_GLOBAL
+ * @param mixed  $link mysql link resource|object
+ *
+ * @return mixed   value for mysql server variable
+ */
+function PMA_DBI_get_variable($var, $type = PMA_DBI_GETVAR_SESSION, $link = null)
+{
+    if ($link === null) {
+        if (isset($GLOBALS['userlink'])) {
+            $link = $GLOBALS['userlink'];
+        } else {
+            return false;
+        }
+    }
+
+    switch ($type) {
+    case PMA_DBI_GETVAR_SESSION:
+        $modifier = ' SESSION';
+        break;
+    case PMA_DBI_GETVAR_GLOBAL:
+        $modifier = ' GLOBAL';
+        break;
+    default:
+        $modifier = '';
+    }
+    return PMA_DBI_fetch_value(
+        'SHOW' . $modifier . ' VARIABLES LIKE \'' . $var . '\';', 0, 1, $link
+    );
+}
+
+/**
+ * Function called just after a connection to the MySQL database server has
+ * been established. It sets the connection collation, and determins the
+ * version of MySQL which is running.
+ *
+ * @param mixed   $link           mysql link resource|object
+ * @param boolean $is_controluser whether link is for control user
+ *
+ * @return void
+ */
+function PMA_DBI_postConnect($link, $is_controluser = false)
+{
+    if (! defined('PMA_MYSQL_INT_VERSION')) {
+        if (PMA_Util::cacheExists('PMA_MYSQL_INT_VERSION', true)) {
+            define(
+                'PMA_MYSQL_INT_VERSION',
+                PMA_Util::cacheGet('PMA_MYSQL_INT_VERSION', true)
+            );
+            define(
+                'PMA_MYSQL_MAJOR_VERSION',
+                PMA_Util::cacheGet('PMA_MYSQL_MAJOR_VERSION', true)
+            );
+            define(
+                'PMA_MYSQL_STR_VERSION',
+                PMA_Util::cacheGet('PMA_MYSQL_STR_VERSION', true)
+            );
+            define(
+                'PMA_MYSQL_VERSION_COMMENT',
+                PMA_Util::cacheGet('PMA_MYSQL_VERSION_COMMENT', true)
+            );
+        } else {
+            $version = PMA_DBI_fetch_single_row(
+                'SELECT @@version, @@version_comment',
+                'ASSOC',
+                $link
+            );
+
+            if ($version) {
+                $match = explode('.', $version['@@version']);
+                define('PMA_MYSQL_MAJOR_VERSION', (int)$match[0]);
+                define(
+                    'PMA_MYSQL_INT_VERSION',
+                    (int) sprintf(
+                        '%d%02d%02d', $match[0], $match[1], intval($match[2])
+                    )
+                );
+                define('PMA_MYSQL_STR_VERSION', $version['@@version']);
+                define('PMA_MYSQL_VERSION_COMMENT', $version['@@version_comment']);
+            } else {
+                define('PMA_MYSQL_INT_VERSION', 50015);
+                define('PMA_MYSQL_MAJOR_VERSION', 5);
+                define('PMA_MYSQL_STR_VERSION', '5.00.15');
+                define('PMA_MYSQL_VERSION_COMMENT', '');
+            }
+            PMA_Util::cacheSet(
+                'PMA_MYSQL_INT_VERSION',
+                PMA_MYSQL_INT_VERSION,
+                true
+            );
+            PMA_Util::cacheSet(
+                'PMA_MYSQL_MAJOR_VERSION',
+                PMA_MYSQL_MAJOR_VERSION,
+                true
+            );
+            PMA_Util::cacheSet(
+                'PMA_MYSQL_STR_VERSION',
+                PMA_MYSQL_STR_VERSION,
+                true
+            );
+            PMA_Util::cacheSet(
+                'PMA_MYSQL_VERSION_COMMENT',
+                PMA_MYSQL_VERSION_COMMENT,
+                true
+            );
+        }
+        // detect Drizzle by version number:
+        // <year>.<month>.<build number>(.<patch rev)
+        define('PMA_DRIZZLE', PMA_MYSQL_MAJOR_VERSION >= 2009);
+    }
+
+    // Skip charsets for Drizzle
+    if (!PMA_DRIZZLE) {
+        if (! empty($GLOBALS['collation_connection'])) {
+            PMA_DBI_query("SET CHARACTER SET 'utf8';", $link, PMA_DBI_QUERY_STORE);
+            $set_collation_con_query = "SET collation_connection = '"
+                . PMA_Util::sqlAddSlashes($GLOBALS['collation_connection']) . "';";
+            PMA_DBI_query(
+                $set_collation_con_query,
+                $link,
+                PMA_DBI_QUERY_STORE
+            );
+        } else {
+            PMA_DBI_query(
+                "SET NAMES 'utf8' COLLATE 'utf8_general_ci';",
+                $link,
+                PMA_DBI_QUERY_STORE
+            );
+        }
+    }
+
+    // Cache plugin list for Drizzle
+    if (PMA_DRIZZLE && !PMA_Util::cacheExists('drizzle_engines', true)) {
+        $sql = "SELECT p.plugin_name, m.module_library
+            FROM data_dictionary.plugins p
+                JOIN data_dictionary.modules m USING (module_name)
+            WHERE p.plugin_type = 'StorageEngine'
+                AND p.plugin_name NOT IN ('FunctionEngine', 'schema')
+                AND p.is_active = 'YES'";
+        $engines = PMA_DBI_fetch_result($sql, 'plugin_name', null, $link);
+        PMA_Util::cacheSet('drizzle_engines', $engines, true);
+    }
+}
+
+/**
+ * returns a single value from the given result or query,
+ * if the query or the result has more than one row or field
+ * the first field of the first row is returned
+ *
+ * <code>
+ * $sql = 'SELECT `name` FROM `user` WHERE `id` = 123';
+ * $user_name = PMA_DBI_fetch_value($sql);
+ * // produces
+ * // $user_name = 'John Doe'
+ * </code>
+ *
+ * @param string|mysql_result $result     query or mysql result
+ * @param integer             $row_number row to fetch the value from,
+ *                                        starting at 0, with 0 being default
+ * @param integer|string      $field      field to fetch the value from,
+ *                                        starting at 0, with 0 being default
+ * @param resource            $link       mysql link
+ *
+ * @return mixed value of first field in first row from result
+ *               or false if not found
+ */
+function PMA_DBI_fetch_value($result, $row_number = 0, $field = 0, $link = null)
+{
+    $value = false;
+
+    if (is_string($result)) {
+        $result = PMA_DBI_try_query($result, $link, PMA_DBI_QUERY_STORE, false);
+    }
+
+    // return false if result is empty or false
+    // or requested row is larger than rows in result
+    if (PMA_DBI_num_rows($result) < ($row_number + 1)) {
+        return $value;
+    }
+
+    // if $field is an integer use non associative mysql fetch function
+    if (is_int($field)) {
+        $fetch_function = 'PMA_DBI_fetch_row';
+    } else {
+        $fetch_function = 'PMA_DBI_fetch_assoc';
+    }
+
+    // get requested row
+    for ($i = 0; $i <= $row_number; $i++) {
+        $row = $fetch_function($result);
+    }
+    PMA_DBI_free_result($result);
+
+    // return requested field
+    if (isset($row[$field])) {
+        $value = $row[$field];
+    }
+    unset($row);
+
+    return $value;
+}
+
+/**
+ * returns only the first row from the result
+ *
+ * <code>
+ * $sql = 'SELECT * FROM `user` WHERE `id` = 123';
+ * $user = PMA_DBI_fetch_single_row($sql);
+ * // produces
+ * // $user = array('id' => 123, 'name' => 'John Doe')
+ * </code>
+ *
+ * @param string|mysql_result $result query or mysql result
+ * @param string              $type   NUM|ASSOC|BOTH
+ *                                    returned array should either numeric
+ *                                    associativ or booth
+ * @param resource            $link   mysql link
+ *
+ * @return array|boolean first row from result
+ *                       or false if result is empty
+ */
+function PMA_DBI_fetch_single_row($result, $type = 'ASSOC', $link = null)
+{
+    if (is_string($result)) {
+        $result = PMA_DBI_try_query($result, $link, PMA_DBI_QUERY_STORE, false);
+    }
+
+    // return null if result is empty or false
+    if (! PMA_DBI_num_rows($result)) {
+        return false;
+    }
+
+    switch ($type) {
+    case 'NUM' :
+        $fetch_function = 'PMA_DBI_fetch_row';
+        break;
+    case 'ASSOC' :
+        $fetch_function = 'PMA_DBI_fetch_assoc';
+        break;
+    case 'BOTH' :
+    default :
+        $fetch_function = 'PMA_DBI_fetch_array';
+        break;
+    }
+
+    $row = $fetch_function($result);
+    PMA_DBI_free_result($result);
+    return $row;
+}
+
+/**
+ * returns all rows in the resultset in one array
+ *
+ * <code>
+ * $sql = 'SELECT * FROM `user`';
+ * $users = PMA_DBI_fetch_result($sql);
+ * // produces
+ * // $users[] = array('id' => 123, 'name' => 'John Doe')
+ *
+ * $sql = 'SELECT `id`, `name` FROM `user`';
+ * $users = PMA_DBI_fetch_result($sql, 'id');
+ * // produces
+ * // $users['123'] = array('id' => 123, 'name' => 'John Doe')
+ *
+ * $sql = 'SELECT `id`, `name` FROM `user`';
+ * $users = PMA_DBI_fetch_result($sql, 0);
+ * // produces
+ * // $users['123'] = array(0 => 123, 1 => 'John Doe')
+ *
+ * $sql = 'SELECT `id`, `name` FROM `user`';
+ * $users = PMA_DBI_fetch_result($sql, 'id', 'name');
+ * // or
+ * $users = PMA_DBI_fetch_result($sql, 0, 1);
+ * // produces
+ * // $users['123'] = 'John Doe'
+ *
+ * $sql = 'SELECT `name` FROM `user`';
+ * $users = PMA_DBI_fetch_result($sql);
+ * // produces
+ * // $users[] = 'John Doe'
+ *
+ * $sql = 'SELECT `group`, `name` FROM `user`'
+ * $users = PMA_DBI_fetch_result($sql, array('group', null), 'name');
+ * // produces
+ * // $users['admin'][] = 'John Doe'
+ *
+ * $sql = 'SELECT `group`, `name` FROM `user`'
+ * $users = PMA_DBI_fetch_result($sql, array('group', 'name'), 'id');
+ * // produces
+ * // $users['admin']['John Doe'] = '123'
+ * </code>
+ *
+ * @param string|mysql_result $result  query or mysql result
+ * @param string|integer      $key     field-name or offset
+ *                                     used as key for array
+ * @param string|integer      $value   value-name or offset
+ *                                     used as value for array
+ * @param resource            $link    mysql link
+ * @param mixed               $options query options
+ *
+ * @return array resultrows or values indexed by $key
+ */
+function PMA_DBI_fetch_result($result, $key = null, $value = null,
+    $link = null, $options = 0
+) {
+    $resultrows = array();
+
+    if (is_string($result)) {
+        $result = PMA_DBI_try_query($result, $link, $options, false);
+    }
+
+    // return empty array if result is empty or false
+    if (! $result) {
+        return $resultrows;
+    }
+
+    $fetch_function = 'PMA_DBI_fetch_assoc';
+
+    // no nested array if only one field is in result
+    if (null === $key && 1 === PMA_DBI_num_fields($result)) {
+        $value = 0;
+        $fetch_function = 'PMA_DBI_fetch_row';
+    }
+
+    // if $key is an integer use non associative mysql fetch function
+    if (is_int($key)) {
+        $fetch_function = 'PMA_DBI_fetch_row';
+    }
+
+    if (null === $key && null === $value) {
+        while ($row = $fetch_function($result)) {
+            $resultrows[] = $row;
+        }
+    } elseif (null === $key) {
+        while ($row = $fetch_function($result)) {
+            $resultrows[] = $row[$value];
+        }
+    } elseif (null === $value) {
+        if (is_array($key)) {
+            while ($row = $fetch_function($result)) {
+                $result_target =& $resultrows;
+                foreach ($key as $key_index) {
+                    if (null === $key_index) {
+                        $result_target =& $result_target[];
+                        continue;
+                    }
+
+                    if (! isset($result_target[$row[$key_index]])) {
+                        $result_target[$row[$key_index]] = array();
+                    }
+                    $result_target =& $result_target[$row[$key_index]];
+                }
+                $result_target = $row;
+            }
+        } else {
+            while ($row = $fetch_function($result)) {
+                $resultrows[$row[$key]] = $row;
+            }
+        }
+    } else {
+        if (is_array($key)) {
+            while ($row = $fetch_function($result)) {
+                $result_target =& $resultrows;
+                foreach ($key as $key_index) {
+                    if (null === $key_index) {
+                        $result_target =& $result_target[];
+                        continue;
+                    }
+
+                    if (! isset($result_target[$row[$key_index]])) {
+                        $result_target[$row[$key_index]] = array();
+                    }
+                    $result_target =& $result_target[$row[$key_index]];
+                }
+                $result_target = $row[$value];
+            }
+        } else {
+            while ($row = $fetch_function($result)) {
+                $resultrows[$row[$key]] = $row[$value];
+            }
+        }
+    }
+
+    PMA_DBI_free_result($result);
+    return $resultrows;
+}
+
+/**
+ * Get supported SQL compatibility modes
+ *
+ * @return array supported SQL compatibility modes
+ */
+function PMA_DBI_getCompatibilities()
+{
+    // Drizzle doesn't support compatibility modes
+    if (PMA_DRIZZLE) {
+        return array();
+    }
+
+    $compats = array('NONE');
+    $compats[] = 'ANSI';
+    $compats[] = 'DB2';
+    $compats[] = 'MAXDB';
+    $compats[] = 'MYSQL323';
+    $compats[] = 'MYSQL40';
+    $compats[] = 'MSSQL';
+    $compats[] = 'ORACLE';
+    // removed; in MySQL 5.0.33, this produces exports that
+    // can't be read by POSTGRESQL (see our bug #1596328)
+    //$compats[] = 'POSTGRESQL';
+    $compats[] = 'TRADITIONAL';
+
+    return $compats;
+}
+
+/**
+ * returns warnings for last query
+ *
+ * @param resource $link mysql link resource
+ *
+ * @return array warnings
+ */
+function PMA_DBI_get_warnings($link = null)
+{
+    if (empty($link)) {
+        if (isset($GLOBALS['userlink'])) {
+            $link = $GLOBALS['userlink'];
+        } else {
+            return array();
+        }
+    }
+
+    return PMA_DBI_fetch_result('SHOW WARNINGS', null, null, $link);
+}
+
+/**
+ * returns true (int > 0) if current user is superuser
+ * otherwise 0
+ *
+ * @return bool Whether use is a superuser
+ */
+function PMA_isSuperuser()
+{
+    if (PMA_Util::cacheExists('is_superuser', true)) {
+        return PMA_Util::cacheGet('is_superuser', true);
+    }
+
+    // when connection failed we don't have a $userlink
+    if (isset($GLOBALS['userlink'])) {
+        if (PMA_DRIZZLE) {
+            // Drizzle has no authorization by default, so when no plugin is
+            // enabled everyone is a superuser
+            // Known authorization libraries: regex_policy, simple_user_policy
+            // Plugins limit object visibility (dbs, tables, processes), we can
+            // safely assume we always deal with superuser
+            $result = true;
+        } else {
+            // check access to mysql.user table
+            $result = (bool) PMA_DBI_try_query(
+                'SELECT COUNT(*) FROM mysql.user',
+                $GLOBALS['userlink'],
+                PMA_DBI_QUERY_STORE
+            );
+        }
+        PMA_Util::cacheSet('is_superuser', $result, true);
+    } else {
+        PMA_Util::cacheSet('is_superuser', false, true);
+    }
+
+    return PMA_Util::cacheGet('is_superuser', true);
+}
+
+/**
+ * returns an array of PROCEDURE or FUNCTION names for a db
+ *
+ * @param string   $db    db name
+ * @param string   $which PROCEDURE | FUNCTION
+ * @param resource $link  mysql link
+ *
+ * @return array the procedure names or function names
+ */
+function PMA_DBI_get_procedures_or_functions($db, $which, $link = null)
+{
+    if (PMA_DRIZZLE) {
+        // Drizzle doesn't support functions and procedures
+        return array();
+    }
+    $shows = PMA_DBI_fetch_result('SHOW ' . $which . ' STATUS;', null, null, $link);
+    $result = array();
+    foreach ($shows as $one_show) {
+        if ($one_show['Db'] == $db && $one_show['Type'] == $which) {
+            $result[] = $one_show['Name'];
+        }
+    }
+    return($result);
+}
+
+/**
+ * returns the definition of a specific PROCEDURE, FUNCTION, EVENT or VIEW
+ *
+ * @param string   $db    db name
+ * @param string   $which PROCEDURE | FUNCTION | EVENT | VIEW
+ * @param string   $name  the procedure|function|event|view name
+ * @param resource $link  mysql link
+ *
+ * @return string the definition
+ */
+function PMA_DBI_get_definition($db, $which, $name, $link = null)
+{
+    $returned_field = array(
+        'PROCEDURE' => 'Create Procedure',
+        'FUNCTION'  => 'Create Function',
+        'EVENT'     => 'Create Event',
+        'VIEW'      => 'Create View'
+    );
+    $query = 'SHOW CREATE ' . $which . ' '
+        . PMA_Util::backquote($db) . '.'
+        . PMA_Util::backquote($name);
+    return(PMA_DBI_fetch_value($query, 0, $returned_field[$which]));
+}
+
+/**
+ * returns details about the TRIGGERs for a specific table or database
+ *
+ * @param string $db        db name
+ * @param string $table     table name
+ * @param string $delimiter the delimiter to use (may be empty)
+ *
+ * @return array information about triggers (may be empty)
+ */
+function PMA_DBI_get_triggers($db, $table = '', $delimiter = '//')
+{
+    if (PMA_DRIZZLE) {
+        // Drizzle doesn't support triggers
+        return array();
+    }
+
+    $result = array();
+    if (! $GLOBALS['cfg']['Server']['DisableIS']) {
+        // Note: in http://dev.mysql.com/doc/refman/5.0/en/faqs-triggers.html
+        // their example uses WHERE TRIGGER_SCHEMA='dbname' so let's use this
+        // instead of WHERE EVENT_OBJECT_SCHEMA='dbname'
+        $query = 'SELECT TRIGGER_SCHEMA, TRIGGER_NAME, EVENT_MANIPULATION'
+            . ', EVENT_OBJECT_TABLE, ACTION_TIMING, ACTION_STATEMENT'
+            . ', EVENT_OBJECT_SCHEMA, EVENT_OBJECT_TABLE, DEFINER'
+            . ' FROM information_schema.TRIGGERS'
+            . ' WHERE TRIGGER_SCHEMA= \'' . PMA_Util::sqlAddSlashes($db) . '\'';
+
+        if (! empty($table)) {
+            $query .= " AND EVENT_OBJECT_TABLE = '"
+                . PMA_Util::sqlAddSlashes($table) . "';";
+        }
+    } else {
+        $query = "SHOW TRIGGERS FROM " . PMA_Util::backquote($db);
+        if (! empty($table)) {
+            $query .= " LIKE '" . PMA_Util::sqlAddSlashes($table, true) . "';";
+        }
+    }
+
+    if ($triggers = PMA_DBI_fetch_result($query)) {
+        foreach ($triggers as $trigger) {
+            if ($GLOBALS['cfg']['Server']['DisableIS']) {
+                $trigger['TRIGGER_NAME'] = $trigger['Trigger'];
+                $trigger['ACTION_TIMING'] = $trigger['Timing'];
+                $trigger['EVENT_MANIPULATION'] = $trigger['Event'];
+                $trigger['EVENT_OBJECT_TABLE'] = $trigger['Table'];
+                $trigger['ACTION_STATEMENT'] = $trigger['Statement'];
+                $trigger['DEFINER'] = $trigger['Definer'];
+            }
+            $one_result = array();
+            $one_result['name'] = $trigger['TRIGGER_NAME'];
+            $one_result['table'] = $trigger['EVENT_OBJECT_TABLE'];
+            $one_result['action_timing'] = $trigger['ACTION_TIMING'];
+            $one_result['event_manipulation'] = $trigger['EVENT_MANIPULATION'];
+            $one_result['definition'] = $trigger['ACTION_STATEMENT'];
+            $one_result['definer'] = $trigger['DEFINER'];
+
+            // do not prepend the schema name; this way, importing the
+            // definition into another schema will work
+            $one_result['full_trigger_name'] = PMA_Util::backquote(
+                $trigger['TRIGGER_NAME']
+            );
+            $one_result['drop'] = 'DROP TRIGGER IF EXISTS '
+                . $one_result['full_trigger_name'];
+            $one_result['create'] = 'CREATE TRIGGER '
+                . $one_result['full_trigger_name'] . ' '
+                . $trigger['ACTION_TIMING']. ' '
+                . $trigger['EVENT_MANIPULATION']
+                . ' ON ' . PMA_Util::backquote($trigger['EVENT_OBJECT_TABLE'])
+                . "\n" . ' FOR EACH ROW '
+                . $trigger['ACTION_STATEMENT'] . "\n" . $delimiter . "\n";
+
+            $result[] = $one_result;
+        }
+    }
+
+    // Sort results by name
+    $name = array();
+    foreach ($result as $value) {
+        $name[] = $value['name'];
+    }
+    array_multisort($name, SORT_ASC, $result);
+
+    return($result);
+}
+
+/**
+ * Formats database error message in a friendly way.
+ * This is needed because some errors messages cannot
+ * be obtained by mysql_error().
+ *
+ * @param int    $error_number  Error code
+ * @param string $error_message Error message as returned by server
+ *
+ * @return string HML text with error details
+ */
+function PMA_DBI_formatError($error_number, $error_message)
+{
+    if (! empty($error_message)) {
+        $error_message = PMA_DBI_convert_message($error_message);
+    }
+
+    $error_message = htmlspecialchars($error_message);
+
+    $error = '#' . ((string) $error_number);
+
+    if ($error_number == 2002) {
+        $error .= ' - ' . $error_message;
+        $error .= '<br />';
+        $error .= __(
+            'The server is not responding (or the local server\'s socket'
+            . ' is not correctly configured).'
+        );
+    } elseif ($error_number == 2003) {
+        $error .= ' - ' . $error_message;
+        $error .= '<br />' . __('The server is not responding.');
+    } elseif ($error_number == 1005) {
+        if (strpos($error_message, 'errno: 13') !== false) {
+            $error .= ' - ' . $error_message;
+            $error .= '<br />'
+                . __('Please check privileges of directory containing database.');
+        } else {
+            /* InnoDB contraints, see
+             * http://dev.mysql.com/doc/refman/5.0/en/
+             *  innodb-foreign-key-constraints.html
+             */
+            $error .= ' - ' . $error_message .
+                ' (<a href="server_engines.php' .
+                PMA_generate_common_url(
+                    array('engine' => 'InnoDB', 'page' => 'Status')
+                ) . '">' . __('Details…') . '</a>)';
+        }
+    } else {
+        $error .= ' - ' . $error_message;
+    }
+
+    return $error;
+}
+
+/**
+ * Checks whether given schema is a system schema: information_schema
+ * (MySQL and Drizzle) or data_dictionary (Drizzle)
+ *
+ * @param string $schema_name           Name of schema (database) to test
+ * @param bool   $test_for_mysql_schema Whether 'mysql' schema should
+ *                                      be treated the same as IS and DD
+ *
+ * @return bool
+ */
+function PMA_is_system_schema($schema_name, $test_for_mysql_schema = false)
+{
+    return strtolower($schema_name) == 'information_schema'
+            || (!PMA_DRIZZLE && strtolower($schema_name) == 'performance_schema')
+            || (PMA_DRIZZLE && strtolower($schema_name) == 'data_dictionary')
+            || ($test_for_mysql_schema && !PMA_DRIZZLE && $schema_name == 'mysql');
+}
+
+/**
+ * Get regular expression which occur first inside the given sql query.
+ *
+ * @param Array $regex_array Comparing regular expressions.
+ * @param String $query SQL query to be checked.
+ *
+ * @return String Matching regular expression.
+ */
+function PMA_getFirstOccurringRegularExpression($regex_array, $query)
+{
+    
+    $minimum_first_occurence_index = null;
+    $regex = null;
+    
+    for ($i = 0; $i < count($regex_array); $i++) {
+        if (preg_match($regex_array[$i], $query, $matches, PREG_OFFSET_CAPTURE)) {
+            
+            if (is_null($minimum_first_occurence_index)
+                || ($matches[0][1] < $minimum_first_occurence_index)
+            ) {
+                $regex = $regex_array[$i];
+                $minimum_first_occurence_index = $matches[0][1];
+            }
+            
+        }
+    }
+    
+    return $regex;
+    
+}
+
+?>
diff --git a/phpmyadmin/libraries/db_common.inc.php b/phpmyadmin/libraries/db_common.inc.php
new file mode 100644
index 0000000..6cd4fc4
--- /dev/null
+++ b/phpmyadmin/libraries/db_common.inc.php
@@ -0,0 +1,100 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * Common includes for the database level views
+ *
+ * @package PhpMyAdmin
+ */
+if (! defined('PHPMYADMIN')) {
+    exit;
+}
+
+/**
+ * Gets some core libraries
+ */
+require_once './libraries/bookmark.lib.php';
+
+PMA_Util::checkParameters(array('db'));
+
+$is_show_stats = $cfg['ShowStats'];
+
+$db_is_information_schema = PMA_is_system_schema($db);
+if ($db_is_information_schema) {
+    $is_show_stats = false;
+}
+
+/**
+ * Defines the urls to return to in case of error in a sql statement
+ */
+$err_url_0 = 'index.php?' . PMA_generate_common_url();
+$err_url   = $cfg['DefaultTabDatabase'] . '?' . PMA_generate_common_url($db);
+
+
+/**
+ * Ensures the database exists (else move to the "parent" script) and displays
+ * headers
+ */
+if (! isset($is_db) || ! $is_db) {
+    if (strlen($db)) {
+        $is_db = PMA_DBI_select_db($db);
+        // This "Command out of sync" 2014 error may happen, for example
+        // after calling a MySQL procedure; at this point we can't select
+        // the db but it's not necessarily wrong
+        if (PMA_DBI_getError() && $GLOBALS['errno'] == 2014) {
+            $is_db = true;
+            unset($GLOBALS['errno']);
+        }
+    }
+    // Not a valid db name -> back to the welcome page
+    $uri = $cfg['PmaAbsoluteUri'] . 'index.php?'
+        . PMA_generate_common_url('', '', '&')
+        . (isset($message) ? '&message=' . urlencode($message) : '') . '&reload=1';
+    if (! strlen($db) || ! $is_db) {
+        $response = PMA_Response::getInstance();
+        if ($response->isAjax()) {
+            $response->isSuccess(false);
+            $response->addJSON(
+                'message',
+                PMA_Message::error(__('No databases selected.'))
+            );
+        } else {
+            PMA_sendHeaderLocation($uri);
+        }
+        exit;
+    }
+} // end if (ensures db exists)
+
+/**
+ * Changes database charset if requested by the user
+ */
+if (isset($_REQUEST['submitcollation'])
+    && isset($_REQUEST['db_collation'])
+    && ! empty($_REQUEST['db_collation'])
+) {
+    list($db_charset) = explode('_', $_REQUEST['db_collation']);
+    $sql_query        = 'ALTER DATABASE '
+        . PMA_Util::backquote($db)
+        . ' DEFAULT' . PMA_generateCharsetQueryPart($_REQUEST['db_collation']);
+    $result           = PMA_DBI_query($sql_query);
+    $message          = PMA_Message::success();
+    unset($db_charset);
+
+    /**
+     * If we are in an Ajax request, let us stop the execution here. Necessary for
+     * db charset change action on db_operations.php.  If this causes a bug on
+     * other pages, we might have to move this to a different location.
+     */
+    if ( $GLOBALS['is_ajax_request'] == true) {
+        $response = PMA_Response::getInstance();
+        $response->isSuccess($message->isSuccess());
+        $response->addJSON('message', $message);
+        exit;
+    }
+}
+
+/**
+ * Set parameters for links
+ */
+$url_query = PMA_generate_common_url($db);
+
+?>
diff --git a/phpmyadmin/libraries/db_info.inc.php b/phpmyadmin/libraries/db_info.inc.php
new file mode 100644
index 0000000..569cb4a
--- /dev/null
+++ b/phpmyadmin/libraries/db_info.inc.php
@@ -0,0 +1,224 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * Gets the list of the table in the current db and informations about these
+ * tables if possible
+ *
+ * fills tooltip arrays and provides $tables, $num_tables, $is_show_stats
+ * and $db_is_information_schema
+ *
+ * speedup view on locked tables
+ *
+ * @package PhpMyAdmin
+ */
+if (! defined('PHPMYADMIN')) {
+    exit;
+}
+
+/**
+ * limits for table list
+ */
+if (! isset($_SESSION['tmp_user_values']['table_limit_offset'])
+    || $_SESSION['tmp_user_values']['table_limit_offset_db'] != $db
+) {
+    $_SESSION['tmp_user_values']['table_limit_offset'] = 0;
+    $_SESSION['tmp_user_values']['table_limit_offset_db'] = $db;
+}
+if (isset($_REQUEST['pos'])) {
+    $_SESSION['tmp_user_values']['table_limit_offset'] = (int) $_REQUEST['pos'];
+}
+$pos = $_SESSION['tmp_user_values']['table_limit_offset'];
+
+PMA_Util::checkParameters(array('db'));
+
+/**
+ * @global bool whether to display extended stats
+ */
+$is_show_stats = $cfg['ShowStats'];
+
+/**
+ * @global bool whether selected db is information_schema
+ */
+$db_is_information_schema = false;
+
+if (PMA_is_system_schema($db)) {
+    $is_show_stats = false;
+    $db_is_information_schema = true;
+}
+
+/**
+ * @global array information about tables in db
+ */
+$tables = array();
+
+// When used in Nested table group mode,
+// only show tables matching the given groupname
+if (PMA_isValid($tbl_group)) {
+    $tbl_group_sql = ' LIKE "'
+        . PMA_Util::escapeMysqlWildcards($tbl_group)
+        . '%"';
+} else {
+    $tbl_group_sql = '';
+}
+
+$tooltip_truename = array();
+$tooltip_aliasname = array();
+
+// Special speedup for newer MySQL Versions (in 4.0 format changed)
+if (true === $cfg['SkipLockedTables']) {
+    $db_info_result = PMA_DBI_query(
+        'SHOW OPEN TABLES FROM ' . PMA_Util::backquote($db) . ';'
+    );
+
+    // Blending out tables in use
+    if ($db_info_result && PMA_DBI_num_rows($db_info_result) > 0) {
+        while ($tmp = PMA_DBI_fetch_row($db_info_result)) {
+            // if in use memorize tablename
+            if (preg_match('@in_use=[1-9]+ at i', $tmp[1])) {
+                $sot_cache[$tmp[0]] = true;
+            }
+        }
+        PMA_DBI_free_result($db_info_result);
+
+        if (isset($sot_cache)) {
+            $db_info_result = PMA_DBI_query(
+                'SHOW TABLES FROM ' . PMA_Util::backquote($db) . $tbl_group_sql . ';',
+                null, PMA_DBI_QUERY_STORE
+            );
+            if ($db_info_result && PMA_DBI_num_rows($db_info_result) > 0) {
+                while ($tmp = PMA_DBI_fetch_row($db_info_result)) {
+                    if (! isset($sot_cache[$tmp[0]])) {
+                        $sts_result  = PMA_DBI_query(
+                            'SHOW TABLE STATUS FROM ' . PMA_Util::backquote($db)
+                            . ' LIKE \'' . PMA_Util::sqlAddSlashes($tmp[0], true) . '\';'
+                        );
+                        $sts_tmp     = PMA_DBI_fetch_assoc($sts_result);
+                        PMA_DBI_free_result($sts_result);
+                        unset($sts_result);
+
+                        if (! isset($sts_tmp['Type']) && isset($sts_tmp['Engine'])) {
+                            $sts_tmp['Type'] =& $sts_tmp['Engine'];
+                        }
+
+                        if (! empty($tbl_group)
+                            && ! preg_match('@' . preg_quote($tbl_group, '@') . '@i', $sts_tmp['Comment'])
+                        ) {
+                            continue;
+                        }
+
+                        if ($cfg['ShowTooltip']) {
+                            PMA_Util::fillTooltip(
+                                $tooltip_truename, $tooltip_aliasname, $sts_tmp
+                            );
+                        }
+
+                        $tables[$sts_tmp['Name']]    = $sts_tmp;
+                    } else { // table in use
+                        $tables[$tmp[0]]    = array('Name' => $tmp[0]);
+                    }
+                }
+                if ($GLOBALS['cfg']['NaturalOrder']) {
+                    uksort($tables, 'strnatcasecmp');
+                }
+
+                $sot_ready = true;
+            } elseif ($db_info_result) {
+                PMA_DBI_free_result($db_info_result);
+            }
+            unset($sot_cache);
+        }
+        unset($tmp);
+    } elseif ($db_info_result) {
+        PMA_DBI_free_result($db_info_result);
+    }
+}
+
+if (! isset($sot_ready)) {
+
+    // Set some sorting defaults
+    $sort = 'Name';
+    $sort_order = 'ASC';
+
+    if (isset($_REQUEST['sort'])) {
+        $sortable_name_mappings = array(
+            'table'       => 'Name',
+            'records'     => 'Rows',
+            'type'        => 'Engine',
+            'collation'   => 'Collation',
+            'size'        => 'Data_length',
+            'overhead'    => 'Data_free',
+            'creation'    => 'Create_time',
+            'last_update' => 'Update_time',
+            'last_check'  => 'Check_time'
+        );
+
+        // Make sure the sort type is implemented
+        if (isset($sortable_name_mappings[$_REQUEST['sort']])) {
+            $sort = $sortable_name_mappings[$_REQUEST['sort']];
+            if ($_REQUEST['sort_order'] == 'DESC') {
+                $sort_order = 'DESC';
+            }
+        }
+    }
+
+    if (! empty($tbl_group)) {
+        // only tables for selected group
+        $tables = PMA_DBI_get_tables_full(
+            $db, $tbl_group, true, null, 0, false, $sort, $sort_order
+        );
+    } else {
+        // all tables in db
+        // - get the total number of tables
+        //  (needed for proper working of the MaxTableList feature)
+        $tables = PMA_DBI_get_tables($db);
+        $total_num_tables = count($tables);
+        if (isset($sub_part) && $sub_part == '_export') {
+            // (don't fetch only a subset if we are coming from db_export.php,
+            // because I think it's too risky to display only a subset of the
+            // table names when exporting a db)
+            /**
+             *
+             * @todo Page selector for table names?
+             */
+            $tables = PMA_DBI_get_tables_full(
+                $db, false, false, null, 0, false, $sort, $sort_order
+            );
+        } else {
+            // fetch the details for a possible limited subset
+            $tables = PMA_DBI_get_tables_full(
+                $db, false, false, null, $pos, true, $sort, $sort_order
+            );
+        }
+    }
+
+    if ($cfg['ShowTooltip']) {
+        foreach ($tables as $each_table) {
+            PMA_Util::fillTooltip(
+                $tooltip_truename, $tooltip_aliasname, $each_table
+            );
+        }
+    }
+}
+
+/**
+ * @global int count of tables in db
+ */
+$num_tables = count($tables);
+//  (needed for proper working of the MaxTableList feature)
+if (! isset($total_num_tables)) {
+    $total_num_tables = $num_tables;
+}
+
+/**
+ * cleanup
+ */
+unset($each_table, $tbl_group_sql, $db_info_result);
+
+/**
+ * If coming from a Show MySQL link on the home page,
+ * put something in $sub_part
+ */
+if (empty($sub_part)) {
+    $sub_part = '_structure';
+}
+?>
diff --git a/phpmyadmin/libraries/db_table_exists.lib.php b/phpmyadmin/libraries/db_table_exists.lib.php
new file mode 100644
index 0000000..ef8b927
--- /dev/null
+++ b/phpmyadmin/libraries/db_table_exists.lib.php
@@ -0,0 +1,103 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * Ensure the database and the table exist (else move to the "parent" script)
+ * and display headers
+ *
+ * @package PhpMyAdmin
+ */
+if (! defined('PHPMYADMIN')) {
+    exit;
+}
+
+if (empty($is_db)) {
+    if (strlen($db)) {
+        $is_db = @PMA_DBI_select_db($db);
+    } else {
+        $is_db = false;
+    }
+
+    if (! $is_db) {
+        // not a valid db name -> back to the welcome page
+        if (! defined('IS_TRANSFORMATION_WRAPPER')) {
+            $response = PMA_Response::getInstance();
+            if ($response->isAjax()) {
+                $response->isSuccess(false);
+                $response->addJSON(
+                    'message',
+                    PMA_Message::error(__('No databases selected.'))
+                );
+            } else {
+                $url_params = array('reload' => 1);
+                if (isset($message)) {
+                    $url_params['message'] = $message;
+                }
+                if (! empty($sql_query)) {
+                    $url_params['sql_query'] = $sql_query;
+                }
+                if (isset($show_as_php)) {
+                    $url_params['show_as_php'] = $show_as_php;
+                }
+                PMA_sendHeaderLocation(
+                    $cfg['PmaAbsoluteUri'] . 'index.php'
+                    . PMA_generate_common_url($url_params, '&')
+                );
+            }
+            exit;
+        }
+    }
+} // end if (ensures db exists)
+
+if (empty($is_table)
+    && !defined('PMA_SUBMIT_MULT')
+    && ! defined('TABLE_MAY_BE_ABSENT')
+) {
+    // Not a valid table name -> back to the db_sql.php
+
+    if (strlen($table)) {
+        $is_table = isset(PMA_Table::$cache[$db][$table]);
+
+        if (! $is_table) {
+            $_result = PMA_DBI_try_query(
+                'SHOW TABLES LIKE \'' . PMA_Util::sqlAddSlashes($table, true) . '\';',
+                null, PMA_DBI_QUERY_STORE
+            );
+            $is_table = @PMA_DBI_num_rows($_result);
+            PMA_DBI_free_result($_result);
+        }
+    } else {
+        $is_table = false;
+    }
+
+    if (! $is_table) {
+        if (! defined('IS_TRANSFORMATION_WRAPPER')) {
+            if (strlen($table)) {
+                // SHOW TABLES doesn't show temporary tables, so try select
+                // (as it can happen just in case temporary table, it should be
+                // fast):
+
+                /**
+                 * @todo should this check really
+                 * only happen if IS_TRANSFORMATION_WRAPPER?
+                 */
+                $_result = PMA_DBI_try_query(
+                    'SELECT COUNT(*) FROM ' . PMA_Util::backquote($table) . ';',
+                    null,
+                    PMA_DBI_QUERY_STORE
+                );
+                $is_table = ($_result && @PMA_DBI_num_rows($_result));
+                PMA_DBI_free_result($_result);
+            }
+
+            if (! $is_table) {
+                include './db_sql.php';
+                exit;
+            }
+        }
+
+        if (! $is_table) {
+            exit;
+        }
+    }
+} // end if (ensures table exists)
+?>
diff --git a/phpmyadmin/libraries/dbi/drizzle-wrappers.lib.php b/phpmyadmin/libraries/dbi/drizzle-wrappers.lib.php
new file mode 100644
index 0000000..430a78d
--- /dev/null
+++ b/phpmyadmin/libraries/dbi/drizzle-wrappers.lib.php
@@ -0,0 +1,437 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * Wrappers for Drizzle extension classes
+ *
+ * Drizzle extension exposes libdrizzle functions and requires user to have it in
+ * mind while using them.
+ * This wrapper is not complete and hides a lot of original functionality,
+ * but allows for easy usage of the drizzle PHP extension.
+ *
+ * @package    PhpMyAdmin-DBI
+ * @subpackage Drizzle
+ */
+if (! defined('PHPMYADMIN')) {
+    exit;
+}
+
+/**
+ * Workaround for crashing module
+ *
+ * @return void
+ *
+ * @todo drizzle module segfaults while freeing resources, often.
+ *       This allows at least for some development
+ */
+function PMA_drizzleShutdownFlush()
+{
+    flush();
+}
+register_shutdown_function('PMA_drizzleShutdownFlush');
+
+/**
+ * Wrapper for Drizzle class
+ *
+ * @package    PhpMyAdmin-DBI
+ * @subpackage Drizzle
+ */
+class PMA_Drizzle extends Drizzle
+{
+    /**
+     * Fetch mode: result rows contain column names
+     */
+    const FETCH_ASSOC = 1;
+    /**
+     * Fetch mode: result rows contain only numeric indices
+     */
+    const FETCH_NUM = 2;
+    /**
+     * Fetch mode: result rows have both column names and numeric indices
+     */
+    const FETCH_BOTH = 3;
+
+    /**
+     * Result buffering: entire result set is buffered upon execution
+     */
+    const BUFFER_RESULT = 1;
+    /**
+     * Result buffering: buffering occurs only on row level
+     */
+    const BUFFER_ROW = 2;
+
+    /**
+     * Constructor
+     */
+    public function __construct()
+    {
+        parent::__construct();
+    }
+
+    /**
+     * Creates a new database conection using TCP
+     *
+     * @param string  $host     Drizzle host
+     * @param integer $port     Drizzle port
+     * @param string  $user     username
+     * @param string  $password password
+     * @param string  $db       database name
+     * @param integer $options  connection options
+     *
+     * @return PMA_DrizzleCon
+     */
+    public function addTcp($host, $port, $user, $password, $db, $options)
+    {
+        $dcon = parent::addTcp($host, $port, $user, $password, $db, $options);
+        return $dcon instanceof DrizzleCon
+            ? new PMA_DrizzleCon($dcon)
+            : $dcon;
+    }
+
+    /**
+     * Creates a new connection using unix domain socket
+     *
+     * @param string  $uds      socket
+     * @param string  $user     username
+     * @param string  $password password
+     * @param string  $db       database name
+     * @param integer $options  connection options
+     *
+     * @return PMA_DrizzleCon
+     */
+    public function addUds($uds, $user, $password, $db, $options)
+    {
+        $dcon = parent::addUds($uds, $user, $password, $db, $options);
+        return $dcon instanceof DrizzleCon
+            ? new PMA_DrizzleCon($dcon)
+            : $dcon;
+    }
+}
+
+/**
+ * Wrapper around DrizzleCon class
+ *
+ * Its main task is to wrap results with PMA_DrizzleResult class
+ *
+ * @package    PhpMyAdmin-DBI
+ * @subpackage Drizzle
+ */
+class PMA_DrizzleCon
+{
+    /**
+     * Instance of DrizzleCon class
+     * @var DrizzleCon
+     */
+    private $_dcon;
+
+    /**
+     * Result of the most recent query
+     * @var PMA_DrizzleResult
+     */
+    private $_lastResult;
+
+    /**
+     * Constructor
+     *
+     * @param DrizzleCon $dcon connection handle
+     *
+     * @return void
+     */
+    public function __construct(DrizzleCon $dcon)
+    {
+        $this->_dcon = $dcon;
+    }
+
+    /**
+     * Executes given query. Opens database connection if not already done.
+     *
+     * @param string $query      query to execute
+     * @param int    $bufferMode PMA_Drizzle::BUFFER_RESULT,PMA_Drizzle::BUFFER_ROW
+     * @param int    $fetchMode  PMA_Drizzle::FETCH_ASSOC, PMA_Drizzle::FETCH_NUM
+     *                           or PMA_Drizzle::FETCH_BOTH
+     *
+     * @return PMA_DrizzleResult
+     */
+    public function query($query, $bufferMode = PMA_Drizzle::BUFFER_RESULT,
+        $fetchMode = PMA_Drizzle::FETCH_ASSOC
+    ) {
+        $result = $this->_dcon->query($query);
+        if ($result instanceof DrizzleResult) {
+            $this->_lastResult = new PMA_DrizzleResult(
+                $result, $bufferMode, $fetchMode
+            );
+            return $this->_lastResult;
+        }
+        return $result;
+    }
+
+    /**
+     * Returns the number of rows affected by last query
+     *
+     * @return int|false
+     */
+    public function affectedRows()
+    {
+        return $this->_lastResult
+            ? $this->_lastResult->affectedRows()
+            : false;
+    }
+
+    /**
+     * Pass calls of undefined methods to DrizzleCon object
+     *
+     * @param string $method method name
+     * @param mixed  $args   method parameters
+     *
+     * @return mixed
+     */
+    public function __call($method, $args)
+    {
+        return call_user_func_array(array($this->_dcon, $method), $args);
+    }
+
+    /**
+     * Returns original Drizzle connection object
+     *
+     * @return DrizzleCon
+     */
+    public function getConnectionObject()
+    {
+        return $this->_dcon;
+    }
+}
+
+/**
+ * Wrapper around DrizzleResult.
+ *
+ * Allows for reading result rows as an associative array and hides complexity
+ * behind buffering.
+ *
+ * @package    PhpMyAdmin-DBI
+ * @subpackage Drizzle
+ */
+class PMA_DrizzleResult
+{
+    /**
+     * Instamce of DrizzleResult class
+     * @var DrizzleResult
+     */
+    private $_dresult;
+    /**
+     * Fetch mode
+     * @var int
+     */
+    private $_fetchMode;
+    /**
+     * Buffering mode
+     * @var int
+     */
+    private $_bufferMode;
+
+    /**
+     * Cached column data
+     * @var DrizzleColumn[]
+     */
+    private $_columns = null;
+    /**
+     * Cached column names
+     * @var string[]
+     */
+    private $_columnNames = null;
+
+    /**
+     * Constructor
+     *
+     * @param DrizzleResult $dresult    result handler
+     * @param int           $bufferMode buffering mode
+     * @param int           $fetchMode  fetching mode
+     */
+    public function __construct(DrizzleResult $dresult, $bufferMode, $fetchMode)
+    {
+        $this->_dresult = $dresult;
+        $this->_bufferMode = $bufferMode;
+        $this->_fetchMode = $fetchMode;
+
+        if ($this->_bufferMode == PMA_Drizzle::BUFFER_RESULT) {
+            $this->_dresult->buffer();
+        }
+    }
+
+    /**
+     * Sets fetch mode
+     *
+     * @param int $fetchMode fetch mode
+     *
+     * @return void
+     */
+    public function setFetchMode($fetchMode)
+    {
+        $this->_fetchMode = $fetchMode;
+    }
+
+    /**
+     * Reads information about columns contained in current result
+     * set into {@see $_columns} and {@see $_columnNames} arrays
+     *
+     * @return void
+     */
+    private function _readColumns()
+    {
+        $this->_columns = array();
+        $this->_columnNames = array();
+        if ($this->_bufferMode == PMA_Drizzle::BUFFER_RESULT) {
+            while (($column = $this->_dresult->columnNext()) !== null) {
+                $this->_columns[] = $column;
+                $this->_columnNames[] = $column->name();
+            }
+        } else {
+            while (($column = $this->_dresult->columnRead()) !== null) {
+                $this->_columns[] = $column;
+                $this->_columnNames[] = $column->name();
+            }
+        }
+    }
+
+    /**
+     * Returns columns in current result
+     *
+     * @return DrizzleColumn[]
+     */
+    public function getColumns()
+    {
+        if (!$this->_columns) {
+            $this->_readColumns();
+        }
+        return $this->_columns;
+    }
+
+    /**
+     * Returns number if columns in result
+     *
+     * @return int
+     */
+    public function numColumns()
+    {
+        return $this->_dresult->columnCount();
+    }
+
+    /**
+     * Transforms result row to conform to current fetch mode
+     *
+     * @param mixed &$row      row to process
+     * @param int   $fetchMode fetch mode
+     *
+     * @return void
+     */
+    private function _transformResultRow(&$row, $fetchMode)
+    {
+        if (!$row) {
+            return;
+        }
+
+        switch ($fetchMode) {
+        case PMA_Drizzle::FETCH_ASSOC:
+            $row = array_combine($this->_columnNames, $row);
+            break;
+        case PMA_Drizzle::FETCH_BOTH:
+            $length = count($row);
+            for ($i = 0; $i < $length; $i++) {
+                $row[$this->_columnNames[$i]] = $row[$i];
+            }
+            break;
+        default:
+            break;
+        }
+    }
+
+    /**
+     * Fetches next for from this result set
+     *
+     * @param int $fetchMode fetch mode to use, if not given the default one is used
+     *
+     * @return array|null
+     */
+    public function fetchRow($fetchMode = null)
+    {
+        // read column names on first fetch, only buffered results
+        // allow for reading it later
+        if (!$this->_columns) {
+            $this->_readColumns();
+        }
+        if ($fetchMode === null) {
+            $fetchMode = $this->_fetchMode;
+        }
+        $row = null;
+        switch ($this->_bufferMode) {
+        case PMA_Drizzle::BUFFER_RESULT:
+            $row = $this->_dresult->rowNext();
+            break;
+        case PMA_Drizzle::BUFFER_ROW:
+            $row = $this->_dresult->rowBuffer();
+            break;
+        }
+        $this->_transformResultRow($row, $fetchMode);
+        return $row;
+    }
+
+    /**
+     * Adjusts the result pointer to an arbitrary row in buffered result
+     *
+     * @param integer $row_index where to seek
+     *
+     * @return bool
+     */
+    public function seek($row_index)
+    {
+        if ($this->_bufferMode != PMA_Drizzle::BUFFER_RESULT) {
+            trigger_error(
+                __("Can't seek in an unbuffered result set"), E_USER_WARNING
+            );
+            return false;
+        }
+        // rowSeek always returns NULL (drizzle extension v.0.5, API v.7)
+        if ($row_index >= 0 && $row_index < $this->_dresult->rowCount()) {
+            $this->_dresult->rowSeek($row_index);
+            return true;
+        }
+        return false;
+    }
+
+    /**
+     * Returns the number of rows in buffered result set
+     *
+     * @return int|false
+     */
+    public function numRows()
+    {
+        if ($this->_bufferMode != PMA_Drizzle::BUFFER_RESULT) {
+            trigger_error(
+                __("Can't count rows in an unbuffered result set"), E_USER_WARNING
+            );
+            return false;
+        }
+        return $this->_dresult->rowCount();
+    }
+
+    /**
+     * Returns the number of rows affected by query
+     *
+     * @return int|false
+     */
+    public function affectedRows()
+    {
+        return $this->_dresult->affectedRows();
+    }
+
+    /**
+     * Frees resources taken by this result
+     *
+     * @return void
+     */
+    public function free()
+    {
+        unset($this->_columns);
+        unset($this->_columnNames);
+        drizzle_result_free($this->_dresult);
+        unset($this->_dresult);
+    }
+}
diff --git a/phpmyadmin/libraries/dbi/drizzle.dbi.lib.php b/phpmyadmin/libraries/dbi/drizzle.dbi.lib.php
new file mode 100644
index 0000000..093e5d6
--- /dev/null
+++ b/phpmyadmin/libraries/dbi/drizzle.dbi.lib.php
@@ -0,0 +1,667 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * Interface to the Drizzle extension
+ *
+ * WARNING - EXPERIMENTAL, never use in production,
+ * drizzle module segfaults often and when you least expect it to
+ *
+ * TODO: This file and drizzle-wrappers.lib.php should be devoid
+ *       of any segault related hacks.
+ * TODO: Crashing versions of drizzle module and/or libdrizzle
+ *       should be blacklisted
+ *
+ * @package    PhpMyAdmin-DBI
+ * @subpackage Drizzle
+ */
+if (! defined('PHPMYADMIN')) {
+    exit;
+}
+
+require_once './libraries/logging.lib.php';
+require_once './libraries/dbi/drizzle-wrappers.lib.php';
+
+/**
+ * MySQL client API
+ */
+if (!defined('PMA_MYSQL_CLIENT_API')) {
+    define('PMA_MYSQL_CLIENT_API', (int)drizzle_version());
+}
+
+/**
+ * Helper function for connecting to the database server
+ *
+ * @param PMA_Drizzle $drizzle  connection handle
+ * @param string      $host     Drizzle host
+ * @param integer     $port     Drizzle port
+ * @param string      $uds      server socket
+ * @param string      $user     username
+ * @param string      $password password
+ * @param string      $db       database name
+ * @param integer     $options  connection options
+ *
+ * @return PMA_DrizzleCon
+ */
+function PMA_DBI_real_connect($drizzle, $host, $port, $uds, $user, $password,
+    $db = null, $options = DRIZZLE_CON_NONE
+) {
+    if ($uds) {
+        $con = $drizzle->addUds($uds, $user, $password, $db, $options);
+    } else {
+        $con = $drizzle->addTcp($host, $port, $user, $password, $db, $options);
+    }
+
+    return $con;
+}
+
+/**
+ * connects to the database server
+ *
+ * @param string $user                 drizzle user name
+ * @param string $password             drizzle user password
+ * @param bool   $is_controluser       whether this is a control user connection
+ * @param array  $server               host/port/socket/persistent
+ * @param bool   $auxiliary_connection (when true, don't go back to login if
+ *                                     connection fails)
+ *
+ * @return mixed false on error or a mysqli object on success
+ */
+function PMA_DBI_connect($user, $password, $is_controluser = false,
+    $server = null, $auxiliary_connection = false
+) {
+    global $cfg;
+
+    if ($server) {
+        $server_port   = (empty($server['port']))
+            ? false
+            : (int)$server['port'];
+        $server_socket = (empty($server['socket']))
+            ? ''
+            : $server['socket'];
+        $server['host'] = (empty($server['host']))
+            ? 'localhost'
+            : $server['host'];
+    } else {
+        $server_port   = (empty($cfg['Server']['port']))
+            ? false
+            : (int) $cfg['Server']['port'];
+        $server_socket = (empty($cfg['Server']['socket']))
+            ? null
+            : $cfg['Server']['socket'];
+    }
+
+    if (strtolower($GLOBALS['cfg']['Server']['connect_type']) == 'tcp') {
+        $GLOBALS['cfg']['Server']['socket'] = '';
+    }
+
+    $drizzle = new PMA_Drizzle();
+
+    $client_flags = 0;
+
+    /* Optionally compress connection */
+    if ($GLOBALS['cfg']['Server']['compress']) {
+        $client_flags |= DRIZZLE_CAPABILITIES_COMPRESS;
+    }
+
+    /* Optionally enable SSL */
+    if ($GLOBALS['cfg']['Server']['ssl']) {
+        $client_flags |= DRIZZLE_CAPABILITIES_SSL;
+    }
+
+    if (!$server) {
+        $link = @PMA_DBI_real_connect(
+            $drizzle, $cfg['Server']['host'], $server_port, $server_socket, $user,
+            $password, false, $client_flags
+        );
+        // Retry with empty password if we're allowed to
+        if ($link == false && isset($cfg['Server']['nopassword'])
+            && $cfg['Server']['nopassword'] && !$is_controluser
+        ) {
+            $link = @PMA_DBI_real_connect(
+                $drizzle, $cfg['Server']['host'], $server_port, $server_socket,
+                $user, null, false, $client_flags
+            );
+        }
+    } else {
+        $link = @PMA_DBI_real_connect(
+            $drizzle, $server['host'], $server_port, $server_socket,
+            $user, $password
+        );
+    }
+
+    if ($link == false) {
+        if ($is_controluser) {
+            trigger_error(
+                __(
+                    'Connection for controluser as defined'
+                    . ' in your configuration failed.'
+                ),
+                E_USER_WARNING
+            );
+            return false;
+        }
+        // we could be calling PMA_DBI_connect() to connect to another
+        // server, for example in the Synchronize feature, so do not
+        // go back to main login if it fails
+        if (! $auxiliary_connection) {
+            PMA_log_user($user, 'drizzle-denied');
+            global $auth_plugin;
+            $auth_plugin->authFails();
+        } else {
+            return false;
+        }
+    } else {
+        PMA_DBI_postConnect($link, $is_controluser);
+    }
+
+    return $link;
+}
+
+/**
+ * selects given database
+ *
+ * @param string         $dbname database name to select
+ * @param PMA_DrizzleCom $link   connection object
+ *
+ * @return bool
+ */
+function PMA_DBI_select_db($dbname, $link = null)
+{
+    if (empty($link)) {
+        if (isset($GLOBALS['userlink'])) {
+            $link = $GLOBALS['userlink'];
+        } else {
+            return false;
+        }
+    }
+    return $link->selectDb($dbname);
+}
+
+/**
+ * runs a query and returns the result
+ *
+ * @param string         $query   query to execute
+ * @param PMA_DrizzleCon $link    connection object
+ * @param int            $options query options
+ *
+ * @return PMA_DrizzleResult
+ */
+function PMA_DBI_real_query($query, $link, $options)
+{
+    $buffer_mode = $options & PMA_DBI_QUERY_UNBUFFERED
+        ? PMA_Drizzle::BUFFER_ROW
+        : PMA_Drizzle::BUFFER_RESULT;
+    $res = $link->query($query, $buffer_mode);
+    return $res;
+}
+
+/**
+ * returns array of rows with associative and numeric keys from $result
+ *
+ * @param PMA_DrizzleResult $result Drizzle result object
+ *
+ * @return array
+ */
+function PMA_DBI_fetch_array($result)
+{
+    return $result->fetchRow(PMA_Drizzle::FETCH_BOTH);
+}
+
+/**
+ * returns array of rows with associative keys from $result
+ *
+ * @param PMA_DrizzleResult $result Drizzle result object
+ *
+ * @return array
+ */
+function PMA_DBI_fetch_assoc($result)
+{
+    return $result->fetchRow(PMA_Drizzle::FETCH_ASSOC);
+}
+
+/**
+ * returns array of rows with numeric keys from $result
+ *
+ * @param PMA_DrizzleResult $result Drizzle result object
+ *
+ * @return array
+ */
+function PMA_DBI_fetch_row($result)
+{
+    return $result->fetchRow(PMA_Drizzle::FETCH_NUM);
+}
+
+/**
+ * Adjusts the result pointer to an arbitrary row in the result
+ *
+ * @param PMA_DrizzleResult $result Drizzle result object
+ * @param int               $offset offset to seek
+ *
+ * @return boolean true on success, false on failure
+ */
+function PMA_DBI_data_seek($result, $offset)
+{
+    return $result->seek($offset);
+}
+
+/**
+ * Frees memory associated with the result
+ *
+ * @param PMA_DrizzleResult $result database result
+ *
+ * @return void
+ */
+function PMA_DBI_free_result($result)
+{
+    if ($result instanceof PMA_DrizzleResult) {
+        $result->free();
+    }
+}
+
+/**
+ * Check if there are any more query results from a multi query
+ *
+ * @return bool false
+ */
+function PMA_DBI_more_results()
+{
+    // N.B.: PHP's 'mysql' extension does not support
+    // multi_queries so this function will always
+    // return false. Use the 'mysqli' extension, if
+    // you need support for multi_queries.
+    return false;
+}
+
+/**
+ * Prepare next result from multi_query
+ *
+ * @return bool false
+ */
+function PMA_DBI_next_result()
+{
+    // N.B.: PHP's 'mysql' extension does not support
+    // multi_queries so this function will always
+    // return false. Use the 'mysqli' extension, if
+    // you need support for multi_queries.
+    return false;
+}
+
+/**
+ * Returns a string representing the type of connection used
+ *
+ * @param PMA_DrizzleCon $link connection object
+ *
+ * @return string type of connection used
+ */
+function PMA_DBI_get_host_info($link = null)
+{
+    if (null === $link) {
+        if (isset($GLOBALS['userlink'])) {
+            $link = $GLOBALS['userlink'];
+        } else {
+            return false;
+        }
+    }
+
+    $str = $link->port()
+        ? $link->host() . ':' . $link->port() . ' via TCP/IP'
+        : 'Localhost via UNIX socket';
+    return $str;
+}
+
+/**
+ * Returns the version of the Drizzle protocol used
+ *
+ * @param PMA_DrizzleCon $link connection object
+ *
+ * @return int version of the Drizzle protocol used
+ */
+function PMA_DBI_get_proto_info($link = null)
+{
+    if (null === $link) {
+        if (isset($GLOBALS['userlink'])) {
+            $link = $GLOBALS['userlink'];
+        } else {
+            return false;
+        }
+    }
+
+    return $link->protocolVersion();
+}
+
+/**
+ * returns a string that represents the client library version
+ *
+ * @return string Drizzle client library version
+ */
+function PMA_DBI_get_client_info()
+{
+    return 'libdrizzle (Drizzle ' . drizzle_version() . ')';
+}
+
+/**
+ * returns last error message or false if no errors occured
+ *
+ * @param PMA_DrizzleCon $link connection object
+ *
+ * @return string|bool $error or false
+ */
+function PMA_DBI_getError($link = null)
+{
+    $GLOBALS['errno'] = 0;
+
+    /* Treat false same as null because of controllink */
+    if ($link === false) {
+        $link = null;
+    }
+
+    if (null === $link && isset($GLOBALS['userlink'])) {
+        $link =& $GLOBALS['userlink'];
+        // Do not stop now. We still can get the error code
+        // with mysqli_connect_errno()
+        // } else {
+        //    return false;
+    }
+
+    if (null !== $link) {
+        $error_number = drizzle_con_errno($link->getConnectionObject());
+        $error_message = drizzle_con_error($link->getConnectionObject());
+    } else {
+        $error_number = drizzle_errno();
+        $error_message = drizzle_error();
+    }
+    if (0 == $error_number) {
+        return false;
+    }
+
+    // keep the error number for further check after the call to PMA_DBI_getError()
+    $GLOBALS['errno'] = $error_number;
+
+    return PMA_DBI_formatError($error_number, $error_message);
+}
+
+/**
+ * returns the number of rows returned by last query
+ *
+ * @param PMA_DrizzleResult $result Drizzle result object
+ *
+ * @return string|int
+ */
+function PMA_DBI_num_rows($result)
+{
+    // see the note for PMA_DBI_try_query();
+    if (!is_bool($result)) {
+        return @$result->numRows();
+    } else {
+        return 0;
+    }
+}
+
+/**
+ * returns last inserted auto_increment id for given $link or $GLOBALS['userlink']
+ *
+ * @param PMA_DrizzleCon $link connection object
+ *
+ * @return string|int
+ */
+function PMA_DBI_insert_id($link = null)
+{
+    if (empty($link)) {
+        if (isset($GLOBALS['userlink'])) {
+            $link = $GLOBALS['userlink'];
+        } else {
+            return false;
+        }
+    }
+
+    // copied from mysql and mysqli
+
+    // When no controluser is defined, using mysqli_insert_id($link)
+    // does not always return the last insert id due to a mixup with
+    // the tracking mechanism, but this works:
+    return PMA_DBI_fetch_value('SELECT LAST_INSERT_ID();', 0, 0, $link);
+    // Curiously, this problem does not happen with the mysql extension but
+    // there is another problem with BIGINT primary keys so PMA_DBI_insert_id()
+    // in the mysql extension also uses this logic.
+}
+
+/**
+ * returns the number of rows affected by last query
+ *
+ * @param PMA_DrizzleResult $link           connection object
+ * @param bool              $get_from_cache whether to retrieve from cache
+ *
+ * @return string|int
+ */
+function PMA_DBI_affected_rows($link = null, $get_from_cache = true)
+{
+    if (empty($link)) {
+        if (isset($GLOBALS['userlink'])) {
+            $link = $GLOBALS['userlink'];
+        } else {
+            return false;
+        }
+    }
+    if ($get_from_cache) {
+        return $GLOBALS['cached_affected_rows'];
+    } else {
+        return $link->affectedRows();
+    }
+}
+
+/**
+ * returns metainfo for fields in $result
+ *
+ * @param PMA_DrizzleResult $result Drizzle result object
+ *
+ * @return array meta info for fields in $result
+ */
+function PMA_DBI_get_fields_meta($result)
+{
+    // Build an associative array for a type look up
+    $typeAr = array();
+    /*$typeAr[DRIZZLE_COLUMN_TYPE_DECIMAL]     = 'real';
+    $typeAr[DRIZZLE_COLUMN_TYPE_NEWDECIMAL]  = 'real';
+    $typeAr[DRIZZLE_COLUMN_TYPE_BIT]         = 'int';
+    $typeAr[DRIZZLE_COLUMN_TYPE_TINY]        = 'int';
+    $typeAr[DRIZZLE_COLUMN_TYPE_SHORT]       = 'int';
+    $typeAr[DRIZZLE_COLUMN_TYPE_LONG]        = 'int';
+    $typeAr[DRIZZLE_COLUMN_TYPE_FLOAT]       = 'real';
+    $typeAr[DRIZZLE_COLUMN_TYPE_DOUBLE]      = 'real';
+    $typeAr[DRIZZLE_COLUMN_TYPE_NULL]        = 'null';
+    $typeAr[DRIZZLE_COLUMN_TYPE_TIMESTAMP]   = 'timestamp';
+    $typeAr[DRIZZLE_COLUMN_TYPE_LONGLONG]    = 'int';
+    $typeAr[DRIZZLE_COLUMN_TYPE_INT24]       = 'int';
+    $typeAr[DRIZZLE_COLUMN_TYPE_DATE]        = 'date';
+    $typeAr[DRIZZLE_COLUMN_TYPE_TIME]        = 'date';
+    $typeAr[DRIZZLE_COLUMN_TYPE_DATETIME]    = 'datetime';
+    $typeAr[DRIZZLE_COLUMN_TYPE_YEAR]        = 'year';
+    $typeAr[DRIZZLE_COLUMN_TYPE_NEWDATE]     = 'date';
+    $typeAr[DRIZZLE_COLUMN_TYPE_ENUM]        = 'unknown';
+    $typeAr[DRIZZLE_COLUMN_TYPE_SET]         = 'unknown';
+    $typeAr[DRIZZLE_COLUMN_TYPE_VIRTUAL]     = 'unknown';
+    $typeAr[DRIZZLE_COLUMN_TYPE_TINY_BLOB]   = 'blob';
+    $typeAr[DRIZZLE_COLUMN_TYPE_MEDIUM_BLOB] = 'blob';
+    $typeAr[DRIZZLE_COLUMN_TYPE_LONG_BLOB]   = 'blob';
+    $typeAr[DRIZZLE_COLUMN_TYPE_BLOB]        = 'blob';
+    $typeAr[DRIZZLE_COLUMN_TYPE_VAR_STRING]  = 'string';
+    $typeAr[DRIZZLE_COLUMN_TYPE_VARCHAR]     = 'string';
+    $typeAr[DRIZZLE_COLUMN_TYPE_STRING]      = 'string';
+    $typeAr[DRIZZLE_COLUMN_TYPE_GEOMETRY]    = 'geometry';*/
+
+    $typeAr[DRIZZLE_COLUMN_TYPE_DRIZZLE_BLOB]      = 'blob';
+    $typeAr[DRIZZLE_COLUMN_TYPE_DRIZZLE_DATE]      = 'date';
+    $typeAr[DRIZZLE_COLUMN_TYPE_DRIZZLE_DATETIME]  = 'datetime';
+    $typeAr[DRIZZLE_COLUMN_TYPE_DRIZZLE_DOUBLE]    = 'real';
+    $typeAr[DRIZZLE_COLUMN_TYPE_DRIZZLE_ENUM]      = 'unknown';
+    $typeAr[DRIZZLE_COLUMN_TYPE_DRIZZLE_LONG]      = 'int';
+    $typeAr[DRIZZLE_COLUMN_TYPE_DRIZZLE_LONGLONG]  = 'int';
+    $typeAr[DRIZZLE_COLUMN_TYPE_DRIZZLE_MAX]       = 'unknown';
+    $typeAr[DRIZZLE_COLUMN_TYPE_DRIZZLE_NULL]      = 'null';
+    $typeAr[DRIZZLE_COLUMN_TYPE_DRIZZLE_TIMESTAMP] = 'timestamp';
+    $typeAr[DRIZZLE_COLUMN_TYPE_DRIZZLE_TINY]      = 'int';
+    $typeAr[DRIZZLE_COLUMN_TYPE_DRIZZLE_VARCHAR]   = 'string';
+
+    // array of DrizzleColumn
+    $columns = $result->getColumns();
+    // columns in a standarized format
+    $std_columns = array();
+
+    foreach ($columns as $k => $column) {
+        $c = new stdClass();
+        $c->name = $column->name();
+        $c->orgname = $column->origName();
+        $c->table = $column->table();
+        $c->orgtable = $column->origTable();
+        $c->def = $column->defaultValue();
+        $c->db = $column->db();
+        $c->catalog = $column->catalog();
+        // $column->maxSize() returns always 0 while size() seems
+        // to return a correct value (drizzle extension v.0.5, API v.7)
+        $c->max_length = $column->size();
+        $c->decimals = $column->decimals();
+        $c->charsetnr = $column->charset();
+        $c->type = $typeAr[$column->typeDrizzle()];
+        $c->_type = $column->type();
+        $c->flags = PMA_DBI_field_flags($result, $k);
+        $c->_flags = $column->flags();
+
+        $c->multiple_key = (int) (bool) ($c->_flags & DRIZZLE_COLUMN_FLAGS_MULTIPLE_KEY);
+        $c->primary_key =  (int) (bool) ($c->_flags & DRIZZLE_COLUMN_FLAGS_PRI_KEY);
+        $c->unique_key =   (int) (bool) ($c->_flags & DRIZZLE_COLUMN_FLAGS_UNIQUE_KEY);
+        $c->not_null =     (int) (bool) ($c->_flags & DRIZZLE_COLUMN_FLAGS_NOT_NULL);
+        $c->unsigned =     (int) (bool) ($c->_flags & DRIZZLE_COLUMN_FLAGS_UNSIGNED);
+        $c->zerofill =     (int) (bool) ($c->_flags & DRIZZLE_COLUMN_FLAGS_ZEROFILL);
+        $c->numeric =      (int) (bool) ($c->_flags & DRIZZLE_COLUMN_FLAGS_NUM);
+        $c->blob =         (int) (bool) ($c->_flags & DRIZZLE_COLUMN_FLAGS_BLOB);
+
+        $std_columns[] = $c;
+    }
+
+    return $std_columns;
+}
+
+/**
+ * return number of fields in given $result
+ *
+ * @param PMA_DrizzleResult $result Drizzle result object
+ *
+ * @return int field count
+ */
+function PMA_DBI_num_fields($result)
+{
+    return $result->numColumns();
+}
+
+/**
+ * returns the length of the given field $i in $result
+ *
+ * @param PMA_DrizzleResult $result Drizzle result object
+ * @param int               $i      field
+ *
+ * @return int length of field
+ */
+function PMA_DBI_field_len($result, $i)
+{
+    $colums = $result->getColumns();
+    return $colums[$i]->size();
+}
+
+/**
+ * returns name of $i. field in $result
+ *
+ * @param PMA_DrizzleResult $result Drizzle result object
+ * @param int               $i      field
+ *
+ * @return string name of $i. field in $result
+ */
+function PMA_DBI_field_name($result, $i)
+{
+    $colums = $result->getColumns();
+    return $colums[$i]->name();
+}
+
+/**
+ * returns concatenated string of human readable field flags
+ *
+ * @param PMA_DrizzleResult $result Drizzle result object
+ * @param int               $i      field
+ *
+ * @return string field flags
+ */
+function PMA_DBI_field_flags($result, $i)
+{
+    $columns = $result->getColumns();
+    $f = $columns[$i];
+    $type = $f->typeDrizzle();
+    $charsetnr = $f->charset();
+    $f = $f->flags();
+    $flags = '';
+    if ($f & DRIZZLE_COLUMN_FLAGS_UNIQUE_KEY) {
+        $flags .= 'unique ';
+    }
+    if ($f & DRIZZLE_COLUMN_FLAGS_NUM) {
+        $flags .= 'num ';
+    }
+    if ($f & DRIZZLE_COLUMN_FLAGS_PART_KEY) {
+        $flags .= 'part_key ';
+    }
+    if ($f & DRIZZLE_COLUMN_FLAGS_SET) {
+        $flags .= 'set ';
+    }
+    if ($f & DRIZZLE_COLUMN_FLAGS_TIMESTAMP) {
+        $flags .= 'timestamp ';
+    }
+    if ($f & DRIZZLE_COLUMN_FLAGS_AUTO_INCREMENT) {
+        $flags .= 'auto_increment ';
+    }
+    if ($f & DRIZZLE_COLUMN_FLAGS_ENUM) {
+        $flags .= 'enum ';
+    }
+    // See http://dev.mysql.com/doc/refman/6.0/en/c-api-datatypes.html:
+    // to determine if a string is binary, we should not use MYSQLI_BINARY_FLAG
+    // but instead the charsetnr member of the MYSQL_FIELD
+    // structure. Watch out: some types like DATE returns 63 in charsetnr
+    // so we have to check also the type.
+    // Unfortunately there is no equivalent in the mysql extension.
+    if (($type == DRIZZLE_COLUMN_TYPE_DRIZZLE_BLOB
+        || $type == DRIZZLE_COLUMN_TYPE_DRIZZLE_VARCHAR)
+        && 63 == $charsetnr
+    ) {
+        $flags .= 'binary ';
+    }
+    if ($f & DRIZZLE_COLUMN_FLAGS_ZEROFILL) {
+        $flags .= 'zerofill ';
+    }
+    if ($f & DRIZZLE_COLUMN_FLAGS_UNSIGNED) {
+        $flags .= 'unsigned ';
+    }
+    if ($f & DRIZZLE_COLUMN_FLAGS_BLOB) {
+        $flags .= 'blob ';
+    }
+    if ($f & DRIZZLE_COLUMN_FLAGS_MULTIPLE_KEY) {
+        $flags .= 'multiple_key ';
+    }
+    if ($f & DRIZZLE_COLUMN_FLAGS_UNIQUE_KEY) {
+        $flags .= 'unique_key ';
+    }
+    if ($f & DRIZZLE_COLUMN_FLAGS_PRI_KEY) {
+        $flags .= 'primary_key ';
+    }
+    if ($f & DRIZZLE_COLUMN_FLAGS_NOT_NULL) {
+        $flags .= 'not_null ';
+    }
+    return trim($flags);
+}
+
+/**
+ * Store the result returned from multi query
+ *
+ * @return false
+ */
+function PMA_DBI_store_result()
+{
+    return false;
+}
+
+?>
diff --git a/phpmyadmin/libraries/dbi/dummy.lib.php b/phpmyadmin/libraries/dbi/dummy.lib.php
new file mode 100644
index 0000000..66138bc
--- /dev/null
+++ b/phpmyadmin/libraries/dbi/dummy.lib.php
@@ -0,0 +1,511 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * Fake database driver for testing purposes
+ *
+ * It has hardcoded results for given queries what makes easy to use it
+ * in testsuite. Feel free to include other queries which your test will
+ * need.
+ *
+ * @package    PhpMyAdmin-DBI
+ * @subpackage Dummy
+ */
+if (! defined('PHPMYADMIN')) {
+    exit;
+}
+
+/**
+ * Array of queries this "driver" supports
+ */
+$GLOBALS['dummy_queries'] = array(
+    array('query' => 'SELECT 1', 'result' => array(array('1'))),
+    array(
+        'query' => 'SELECT CURRENT_USER();',
+        'result' => array(array('pma_test at localhost')),
+    ),
+    array(
+        'query' => 'SELECT COUNT(*) FROM mysql.user',
+        'result' => false,
+    ),
+    array(
+        'query' => 'SHOW MASTER LOGS',
+        'result' => false,
+    ),
+    array(
+        'query' => 'SHOW STORAGE ENGINES',
+        'result' => array(
+            array('Engine' => 'dummy', 'Support' => 'YES', 'Comment' => 'dummy comment'),
+            array('Engine' => 'dummy2', 'Support' => 'NO', 'Comment' => 'dummy2 comment'),
+        )
+    ),
+    array(
+        'query' => 'SHOW STATUS WHERE Variable_name LIKE \'Innodb\\_buffer\\_pool\\_%\' OR Variable_name = \'Innodb_page_size\';',
+        'result' => array(
+            array('Innodb_buffer_pool_pages_data', 0),
+            array('Innodb_buffer_pool_pages_dirty', 0),
+            array('Innodb_buffer_pool_pages_flushed', 0),
+            array('Innodb_buffer_pool_pages_free', 0),
+            array('Innodb_buffer_pool_pages_misc', 0),
+            array('Innodb_buffer_pool_pages_total', 4096),
+            array('Innodb_buffer_pool_read_ahead_rnd', 0),
+            array('Innodb_buffer_pool_read_ahead', 0),
+            array('Innodb_buffer_pool_read_ahead_evicted', 0),
+            array('Innodb_buffer_pool_read_requests', 64),
+            array('Innodb_buffer_pool_reads', 32),
+            array('Innodb_buffer_pool_wait_free', 0),
+            array('Innodb_buffer_pool_write_requests', 64),
+            array('Innodb_page_size', 16384),
+        )
+    ),
+    array(
+        'query' => 'SHOW INNODB STATUS;',
+        'result' => false,
+    ),
+    array(
+        'query' => 'SELECT @@innodb_version;',
+        'result' => array(
+            array('1.1.8'),
+        )
+    ),
+    array(
+        'query' => 'SHOW GLOBAL VARIABLES LIKE \'innodb_file_per_table\';',
+        'result' => array(
+            array('innodb_file_per_table', 'OFF'),
+        )
+    ),
+    array(
+        'query' => 'SHOW GLOBAL VARIABLES LIKE \'innodb_file_format\';',
+        'result' => array(
+            array('innodb_file_format', 'Antelope'),
+        )
+    ),
+    array(
+        'query' => 'SHOW VARIABLES LIKE \'collation_server\'',
+        'result' => array(
+            array('collation_server', 'utf8_general_ci'),
+        )
+    ),
+    array(
+        'query' => 'SHOW VARIABLES LIKE \'language\';',
+        'result' => array(),
+    ),
+    array(
+        'query' => 'SHOW TABLES FROM `pma_test`;',
+        'result' => array(
+            array('table1'),
+            array('table2'),
+        )
+    ),
+    array(
+        'query' => 'SHOW TABLES FROM `pmadb`',
+        'result' => array(
+            array('column_info'),
+        )
+    ),
+    array(
+        'query' => 'SHOW COLUMNS FROM `pma_test`.`table1`',
+        'columns' => array(
+            'Field', 'Type', 'Null', 'Key', 'Default', 'Extra'
+        ),
+        'result' => array(
+            array('i', 'int(11)', 'NO', 'PRI', 'NULL', 'auto_increment'),
+            array('o', 'int(11)', 'NO', 'MUL', 'NULL', ''),
+        )
+    ),
+    array(
+        'query' => 'SHOW INDEXES FROM `pma_test`.`table1` WHERE (Non_unique = 0)',
+        'result' => array(),
+    ),
+    array(
+        'query' => 'SHOW COLUMNS FROM `pma_test`.`table2`',
+        'columns' => array(
+            'Field', 'Type', 'Null', 'Key', 'Default', 'Extra'
+        ),
+        'result' => array(
+            array('i', 'int(11)', 'NO', 'PRI', 'NULL', 'auto_increment'),
+            array('o', 'int(11)', 'NO', 'MUL', 'NULL', ''),
+        )
+    ),
+    array(
+        'query' => 'SHOW INDEXES FROM `pma_test`.`table1`',
+        'result' => array(),
+    ),
+    array(
+        'query' => 'SHOW INDEXES FROM `pma_test`.`table2`',
+        'result' => array(),
+    ),
+    array(
+        'query' => 'SHOW COLUMNS FROM `pma`.`table1`',
+        'columns' => array(
+            'Field', 'Type', 'Null', 'Key', 'Default', 'Extra', 'Privileges', 'Comment'
+        ),
+        'result' => array(
+            array('i', 'int(11)', 'NO', 'PRI', 'NULL', 'auto_increment', 'select,insert,update,references', ''),
+            array('o', 'varchar(100)', 'NO', 'MUL', 'NULL', '', 'select,insert,update,references', ''),
+        )
+    ),
+    array(
+        'query' => 'SELECT * FROM information_schema.CHARACTER_SETS',
+        'columns' => array('CHARACTER_SET_NAME', 'DEFAULT_COLLATE_NAME', 'DESCRIPTION', 'MAXLEN'),
+        'result' => array(
+            array('utf8', 'utf8_general_ci', 'UTF-8 Unicode', 3),
+        )
+    ),
+    array(
+        'query' => 'SELECT * FROM information_schema.COLLATIONS',
+        'columns' => array(
+            'COLLATION_NAME', 'CHARACTER_SET_NAME', 'ID', 'IS_DEFAULT', 'IS_COMPILED', 'SORTLEN'
+        ),
+        'result' => array(
+            array('utf8_general_ci', 'utf8', 33, 'Yes', 'Yes', 1),
+            array('utf8_bin', 'utf8', 83, '', 'Yes', 1),
+        )
+    ),
+    array(
+        'query' => 'SELECT `TABLE_NAME` FROM `INFORMATION_SCHEMA`.`TABLES` WHERE `TABLE_SCHEMA`=\'pma_test\' AND `TABLE_TYPE`=\'BASE TABLE\'',
+        'result' => array(),
+    ),
+    array(
+        'query' => 'SELECT upper(plugin_name) f FROM data_dictionary.plugins WHERE plugin_name IN (\'MYSQL_PASSWORD\',\'ROT13\') AND plugin_type = \'Function\' AND is_active',
+        'columns' => array('f'),
+        'result' => array(array('ROT13')),
+    ),
+    array(
+        'query' => 'SELECT `column_name`, `mimetype`, `transformation`, `transformation_options` FROM `pmadb`.`column_info` WHERE `db_name` = \'pma_test\' AND `table_name` = \'table1\' AND ( `mimetype` != \'\' OR `transformation` != \'\' OR `transformation_options` != \'\')',
+        'columns' => array('column_name', 'mimetype', 'transformation', 'transformation_options'),
+        'result' => array(
+            array('o', 'text/plain', 'sql'),
+        )
+    ),
+    array(
+        'query' => 'SELECT TABLE_NAME FROM information_schema.VIEWS WHERE TABLE_SCHEMA = \'pma_test\' AND TABLE_NAME = \'table1\'',
+        'result' => array(),
+    ),
+    array(
+        'query' => 'SELECT *, `TABLE_SCHEMA` AS `Db`, `TABLE_NAME` AS `Name`, `TABLE_TYPE` AS `TABLE_TYPE`, `ENGINE` AS `Engine`, `ENGINE` AS `Type`, `VERSION` AS `Version`, `ROW_FORMAT` AS `Row_format`, `TABLE_ROWS` AS `Rows`, `AVG_ROW_LENGTH` AS `Avg_row_length`, `DATA_LENGTH` AS `Data_length`, `MAX_DATA_LENGTH` AS `Max_data_length`, `INDEX_LENGTH` AS `Index_length`, `DATA_FREE` AS `Data_free`, `AUTO_INCREMENT` AS `Auto_increment`, `CREATE_TIME` AS `Create_time`, `UPDATE_TIME` AS `Upda [...]
+        'columns' => array('TABLE_CATALOG', 'TABLE_SCHEMA', 'TABLE_NAME', 'TABLE_TYPE', 'ENGINE', 'VERSION', 'ROW_FORMAT', 'TABLE_ROWS', 'AVG_ROW_LENGTH', 'DATA_LENGTH', 'MAX_DATA_LENGTH', 'INDEX_LENGTH', 'DATA_FREE', 'AUTO_INCREMENT', 'CREATE_TIME', 'UPDATE_TIME', 'CHECK_TIME', 'TABLE_COLLATION', 'CHECKSUM', 'CREATE_OPTIONS', 'TABLE_COMMENT', 'Db', 'Name', 'TABLE_TYPE', 'Engine', 'Type', 'Version', 'Row_format', 'Rows', 'Avg_row_length', 'Data_length', 'Max_data_length', 'Index_length', [...]
+        'result' => array(
+            array('def', 'smash', 'issues_issue', 'BASE TABLE', 'InnoDB', '10', 'Compact', '9136', '862', '7880704', '0', '1032192', '420478976', '155862', '2012-08-29 13:28:28', 'NULL', 'NULL', 'utf8_general_ci', 'NULL', '', '', 'smash', 'issues_issue', 'BASE TABLE', 'InnoDB', 'InnoDB', '10', 'Compact', '9136', '862', '7880704', '0', '1032192', '420478976', '155862', '2012-08-29 13:28:28', 'NULL', 'NULL', 'utf8_general_ci', 'NULL'),
+        ),
+    ),
+    array(
+        'query' => 'SELECT *, `TABLE_SCHEMA` AS `Db`, `TABLE_NAME` AS `Name`, `TABLE_TYPE` AS `TABLE_TYPE`, `ENGINE` AS `Engine`, `ENGINE` AS `Type`, `VERSION` AS `Version`, `ROW_FORMAT` AS `Row_format`, `TABLE_ROWS` AS `Rows`, `AVG_ROW_LENGTH` AS `Avg_row_length`, `DATA_LENGTH` AS `Data_length`, `MAX_DATA_LENGTH` AS `Max_data_length`, `INDEX_LENGTH` AS `Index_length`, `DATA_FREE` AS `Data_free`, `AUTO_INCREMENT` AS `Auto_increment`, `CREATE_TIME` AS `Create_time`, `UPDATE_TIME` AS `Upda [...]
+        'columns' => array('TABLE_CATALOG', 'TABLE_SCHEMA', 'TABLE_NAME', 'TABLE_TYPE', 'ENGINE', 'VERSION', 'ROW_FORMAT', 'TABLE_ROWS', 'AVG_ROW_LENGTH', 'DATA_LENGTH', 'MAX_DATA_LENGTH', 'INDEX_LENGTH', 'DATA_FREE', 'AUTO_INCREMENT', 'CREATE_TIME', 'UPDATE_TIME', 'CHECK_TIME', 'TABLE_COLLATION', 'CHECKSUM', 'CREATE_OPTIONS', 'TABLE_COMMENT', 'Db', 'Name', 'TABLE_TYPE', 'Engine', 'Type', 'Version', 'Row_format', 'Rows', 'Avg_row_length', 'Data_length', 'Max_data_length', 'Index_length', [...]
+        'result' => array(
+            array('def', 'smash', 'issues_issue', 'BASE TABLE', 'InnoDB', '10', 'Compact', '9136', '862', '7880704', '0', '1032192', '420478976', '155862', '2012-08-29 13:28:28', 'NULL', 'NULL', 'utf8_general_ci', 'NULL', '', '', 'smash', 'issues_issue', 'BASE TABLE', 'InnoDB', 'InnoDB', '10', 'Compact', '9136', '862', '7880704', '0', '1032192', '420478976', '155862', '2012-08-29 13:28:28', 'NULL', 'NULL', 'utf8_general_ci', 'NULL'),
+        ),
+    ),
+    array(
+        'query' => 'SELECT COUNT(*) FROM `pma_test`.`table1`',
+        'result' => array(array(0)),
+    ),
+    array(
+        'query' => 'SELECT `PRIVILEGE_TYPE` FROM `INFORMATION_SCHEMA`.`USER_PRIVILEGES` WHERE GRANTEE=\'\'\'pma_test\'\'@\'\'localhost\'\'\' AND PRIVILEGE_TYPE=\'TRIGGER\'',
+        'result' => array(),
+    ),
+    array(
+        'query' => 'SELECT `PRIVILEGE_TYPE` FROM `INFORMATION_SCHEMA`.`SCHEMA_PRIVILEGES` WHERE GRANTEE=\'\'\'pma_test\'\'@\'\'localhost\'\'\' AND PRIVILEGE_TYPE=\'TRIGGER\' AND TABLE_SCHEMA=\'pma\\\\_test\'',
+
+        'result' => array(),
+    ),
+    array(
+        'query' => 'SELECT `PRIVILEGE_TYPE` FROM `INFORMATION_SCHEMA`.`TABLE_PRIVILEGES` WHERE GRANTEE=\'\'\'pma_test\'\'@\'\'localhost\'\'\' AND PRIVILEGE_TYPE=\'TRIGGER\' AND TABLE_SCHEMA=\'pma\\\\_test\' AND TABLE_NAME=\'table1\'',
+        'result' => array(),
+    ),
+    array(
+        'query' => 'SELECT `PRIVILEGE_TYPE` FROM `INFORMATION_SCHEMA`.`USER_PRIVILEGES` WHERE GRANTEE=\'\'\'pma_test\'\'@\'\'localhost\'\'\' AND PRIVILEGE_TYPE=\'EVENT\'',
+        'result' => array(),
+    ),
+    array(
+        'query' => 'SELECT `PRIVILEGE_TYPE` FROM `INFORMATION_SCHEMA`.`SCHEMA_PRIVILEGES` WHERE GRANTEE=\'\'\'pma_test\'\'@\'\'localhost\'\'\' AND PRIVILEGE_TYPE=\'EVENT\' AND TABLE_SCHEMA=\'pma\\\\_test\'',
+
+        'result' => array(),
+    ),
+    array(
+        'query' => 'SELECT `PRIVILEGE_TYPE` FROM `INFORMATION_SCHEMA`.`TABLE_PRIVILEGES` WHERE GRANTEE=\'\'\'pma_test\'\'@\'\'localhost\'\'\' AND PRIVILEGE_TYPE=\'EVENT\' AND TABLE_SCHEMA=\'pma\\\\_test\' AND TABLE_NAME=\'table1\'',
+        'result' => array(),
+    ),
+    array(
+        'query' => 'RENAME TABLE `pma_test`.`table1` TO `pma_test`.`table3`;',
+        'result' => array(),
+    ),
+    array(
+        'query' => 'SELECT TRIGGER_SCHEMA, TRIGGER_NAME, EVENT_MANIPULATION, EVENT_OBJECT_TABLE, ACTION_TIMING, ACTION_STATEMENT, EVENT_OBJECT_SCHEMA, EVENT_OBJECT_TABLE, DEFINER FROM information_schema.TRIGGERS WHERE TRIGGER_SCHEMA= \'pma_test\' AND EVENT_OBJECT_TABLE = \'table1\';',
+        'result' => array(),
+    ),
+    array(
+        'query' => 'SHOW TABLES FROM `pma`;',
+        'result' => array(),
+    ),
+    array(
+        'query' => "SELECT `PRIVILEGE_TYPE` FROM `INFORMATION_SCHEMA`.`SCHEMA_PRIVILEGES` WHERE GRANTEE='''pma_test''@''localhost''' AND PRIVILEGE_TYPE='EVENT' AND TABLE_SCHEMA='pma'",
+        'result' => array(),
+    ),
+    array(
+        'query' => "SELECT `PRIVILEGE_TYPE` FROM `INFORMATION_SCHEMA`.`SCHEMA_PRIVILEGES` WHERE GRANTEE='''pma_test''@''localhost''' AND PRIVILEGE_TYPE='TRIGGER' AND TABLE_SCHEMA='pma'",
+        'result' => array(),
+    ),
+
+);
+/**
+ * Current database.
+ */
+$GLOBALS['dummy_db'] = '';
+
+/* Some basic setup for dummy driver */
+$GLOBALS['userlink'] = 1;
+$GLOBALS['controllink'] = 2;
+$GLOBALS['cfg']['DBG']['sql'] = false;
+if (! defined('PMA_DRIZZLE')) {
+    define('PMA_DRIZZLE', 0);
+}
+
+
+/**
+ * Run the multi query and output the results
+ *
+ * @param mysqli $link  mysqli object
+ * @param string $query multi query statement to execute
+ *
+ * @return boolean false always false since mysql extention not support
+ *                       for multi query executions
+ */
+function PMA_DBI_real_multi_query($link, $query)
+{
+    return false;
+}
+
+/**
+ * connects to the database server
+ *
+ * @param string $user                 mysql user name
+ * @param string $password             mysql user password
+ * @param bool   $is_controluser       whether this is a control user connection
+ * @param array  $server               host/port/socket/persistent
+ * @param bool   $auxiliary_connection (when true, don't go back to login if
+ *                                     connection fails)
+ *
+ * @return mixed false on error or a mysqli object on success
+ */
+function PMA_DBI_connect(
+    $user, $password, $is_controluser = false, $server = null,
+    $auxiliary_connection = false
+) {
+    return true;
+}
+
+/**
+ * selects given database
+ *
+ * @param string   $dbname name of db to select
+ * @param resource $link   mysql link resource
+ *
+ * @return bool
+ */
+function PMA_DBI_select_db($dbname, $link = null)
+{
+    $GLOBALS['dummy_db'] = $dbname;
+    return true;
+}
+
+/**
+ * runs a query and returns the result
+ *
+ * @param string   $query   query to run
+ * @param resource $link    mysql link resource
+ * @param int      $options query options
+ *
+ * @return mixed
+ */
+function PMA_DBI_real_query($query, $link = null, $options = 0)
+{
+    $query = trim(preg_replace('/  */', ' ', str_replace("\n", ' ', $query)));
+    for ($i = 0; $i < count($GLOBALS['dummy_queries']); $i++) {
+        if ($GLOBALS['dummy_queries'][$i]['query'] == $query) {
+            $GLOBALS['dummy_queries'][$i]['pos'] = 0;
+            if (is_array($GLOBALS['dummy_queries'][$i]['result'])) {
+                return $i;
+            } else {
+                return false;
+            }
+        }
+    }
+    echo "Not supported query: $query\n";
+    return false;
+}
+
+/**
+ * returns result data from $result
+ *
+ * @param resource $result result  MySQL result
+ *
+ * @return array
+ */
+function PMA_DBI_fetch_any($result)
+{
+    $query_data = $GLOBALS['dummy_queries'][$result];
+    if ($query_data['pos'] >= count($query_data['result'])) {
+        return false;
+    }
+    $ret = $query_data['result'][$query_data['pos']];
+    $GLOBALS['dummy_queries'][$result]['pos'] += 1;
+    return $ret;
+}
+
+/**
+ * returns array of rows with associative and numeric keys from $result
+ *
+ * @param resource $result result  MySQL result
+ *
+ * @return array
+ */
+function PMA_DBI_fetch_array($result)
+{
+    $data = PMA_DBI_fetch_any($result);
+    if (is_array($data) && isset($GLOBALS['dummy_queries'][$result]['columns'])) {
+        foreach ($data as $key => $val) {
+            $data[$GLOBALS['dummy_queries'][$result]['columns'][$key]] = $val;
+        }
+        return $data;
+    }
+    return $data;
+}
+
+/**
+ * returns array of rows with associative keys from $result
+ *
+ * @param resource $result MySQL result
+ *
+ * @return array
+ */
+function PMA_DBI_fetch_assoc($result)
+{
+    $data = PMA_DBI_fetch_any($result);
+    if (is_array($data) && isset($GLOBALS['dummy_queries'][$result]['columns'])) {
+        $ret = array();
+        foreach ($data as $key => $val) {
+            $ret[$GLOBALS['dummy_queries'][$result]['columns'][$key]] = $val;
+        }
+        return $ret;
+    }
+    return $data;
+}
+
+/**
+ * returns array of rows with numeric keys from $result
+ *
+ * @param resource $result MySQL result
+ *
+ * @return array
+ */
+function PMA_DBI_fetch_row($result)
+{
+    $data = PMA_DBI_fetch_any($result);
+    return $data;
+}
+
+/**
+ * Adjusts the result pointer to an arbitrary row in the result
+ *
+ * @param resource $result database result
+ * @param integer  $offset offset to seek
+ *
+ * @return bool true on success, false on failure
+ */
+function PMA_DBI_data_seek($result, $offset)
+{
+    if ($offset > count($GLOBALS['dummy_queries'][$result]['result'])) {
+        return false;
+    }
+    $GLOBALS['dummy_queries'][$result]['pos'] = $offset;
+    return true;
+}
+
+/**
+ * Frees memory associated with the result
+ *
+ * @param resource $result database result
+ *
+ * @return void
+ */
+function PMA_DBI_free_result($result)
+{
+    return;
+}
+
+/**
+ * Check if there are any more query results from a multi query
+ *
+ * @return bool false
+ */
+function PMA_DBI_more_results()
+{
+    return false;
+}
+
+/**
+ * Prepare next result from multi_query
+ *
+ * @return boo false
+ */
+function PMA_DBI_next_result()
+{
+    return false;
+}
+
+/**
+ * returns the number of rows returned by last query
+ *
+ * @param resource $result MySQL result
+ *
+ * @return string|int
+ */
+function PMA_DBI_num_rows($result)
+{
+    if (!is_bool($result)) {
+        return count($GLOBALS['dummy_queries'][$result]['result']);
+    } else {
+        return 0;
+    }
+}
+
+/**
+ * returns the number of rows affected by last query
+ *
+ * @param resource $link           the mysql object
+ * @param bool     $get_from_cache whether to retrieve from cache
+ *
+ * @return string|int
+ */
+function PMA_DBI_affected_rows($link = null, $get_from_cache = true)
+{
+    return 0;
+}
+
+/**
+ * return number of fields in given $result
+ *
+ * @param resource $result MySQL result
+ *
+ * @return int  field count
+ */
+function PMA_DBI_num_fields($result)
+{
+    if (isset($GLOBALS['dummy_queries'][$result]['columns'])) {
+        return count($GLOBALS['dummy_queries'][$result]['columns']);
+    } else {
+        return 0;
+    }
+}
+
+/**
+ * returns last error message or false if no errors occured
+ *
+ * @param resource $link mysql link
+ *
+ * @return string|bool $error or false
+ */
+function PMA_DBI_getError($link = null)
+{
+    return false;
+}
diff --git a/phpmyadmin/libraries/dbi/mysql.dbi.lib.php b/phpmyadmin/libraries/dbi/mysql.dbi.lib.php
new file mode 100644
index 0000000..6a7e15d
--- /dev/null
+++ b/phpmyadmin/libraries/dbi/mysql.dbi.lib.php
@@ -0,0 +1,552 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * Interface to the classic MySQL extension
+ *
+ * @package    PhpMyAdmin-DBI
+ * @subpackage MySQL
+ */
+if (! defined('PHPMYADMIN')) {
+    exit;
+}
+
+require_once './libraries/logging.lib.php';
+
+/**
+ * MySQL client API
+ */
+if (! defined('PMA_MYSQL_CLIENT_API')) {
+    $client_api = explode('.', mysql_get_client_info());
+    define(
+        'PMA_MYSQL_CLIENT_API',
+        (int)sprintf(
+            '%d%02d%02d',
+            $client_api[0], $client_api[1], intval($client_api[2])
+        )
+    );
+    unset($client_api);
+}
+
+/**
+ * Helper function for connecting to the database server
+ *
+ * @param array  $server       host/port/socket
+ * @param string $user         mysql user name
+ * @param string $password     mysql user password
+ * @param int    $client_flags client flags of connection
+ * @param bool   $persistent   whether to use peristent connection
+ *
+ * @return mixed   false on error or a mysql connection resource on success
+ */
+function PMA_DBI_real_connect($server, $user, $password, $client_flags,
+    $persistent = false
+) {
+    global $cfg;
+
+    if (empty($client_flags)) {
+        if ($cfg['PersistentConnections'] || $persistent) {
+            $link = @mysql_pconnect($server, $user, $password);
+        } else {
+            $link = @mysql_connect($server, $user, $password);
+        }
+    } else {
+        if ($cfg['PersistentConnections'] || $persistent) {
+            $link = @mysql_pconnect($server, $user, $password, $client_flags);
+        } else {
+            $link = @mysql_connect($server, $user, $password, false, $client_flags);
+        }
+    }
+
+    return $link;
+}
+
+/**
+ * Run the multi query and output the results
+ *
+ * @param mysqli $link  mysqli object
+ * @param string $query multi query statement to execute
+ *
+ * @return boolean false always false since mysql extention not support
+ *                       for multi query executions
+ */
+function PMA_DBI_real_multi_query($link, $query)
+{
+    // N.B.: PHP's 'mysql' extension does not support
+    // multi_queries so this function will always
+    // return false. Use the 'mysqli' extension, if
+    // you need support for multi_queries.
+    return false;
+}
+
+/**
+ * connects to the database server
+ *
+ * @param string $user                 mysql user name
+ * @param string $password             mysql user password
+ * @param bool   $is_controluser       whether this is a control user connection
+ * @param array  $server               host/port/socket/persistent
+ * @param bool   $auxiliary_connection (when true, don't go back to login if
+ *                                     connection fails)
+ *
+ * @return mixed false on error or a mysqli object on success
+ */
+function PMA_DBI_connect(
+    $user, $password, $is_controluser = false, $server = null,
+    $auxiliary_connection = false
+) {
+    global $cfg;
+
+    if ($server) {
+        $server_port = (empty($server['port']))
+            ? ''
+            : ':' . (int)$server['port'];
+        $server_socket = (empty($server['socket']))
+            ? ''
+            : ':' . $server['socket'];
+    } else {
+        $server_port   = (empty($cfg['Server']['port']))
+            ? ''
+            : ':' . (int)$cfg['Server']['port'];
+        $server_socket = (empty($cfg['Server']['socket']))
+            ? ''
+            : ':' . $cfg['Server']['socket'];
+    }
+
+    $client_flags = 0;
+
+    // always use CLIENT_LOCAL_FILES as defined in mysql_com.h
+    // for the case where the client library was not compiled
+    // with --enable-local-infile
+    $client_flags |= 128;
+
+    /* Optionally compress connection */
+    if (defined('MYSQL_CLIENT_COMPRESS') && $cfg['Server']['compress']) {
+        $client_flags |= MYSQL_CLIENT_COMPRESS;
+    }
+
+    /* Optionally enable SSL */
+    if (defined('MYSQL_CLIENT_SSL') && $cfg['Server']['ssl']) {
+        $client_flags |= MYSQL_CLIENT_SSL;
+    }
+
+    if (!$server) {
+        $link = PMA_DBI_real_connect(
+            $cfg['Server']['host'] . $server_port . $server_socket,
+            $user, $password, empty($client_flags) ? null : $client_flags
+        );
+
+        // Retry with empty password if we're allowed to
+        if (empty($link) && $cfg['Server']['nopassword'] && !$is_controluser) {
+            $link = PMA_DBI_real_connect(
+                $cfg['Server']['host'] . $server_port . $server_socket,
+                $user, '', empty($client_flags) ? null : $client_flags
+            );
+        }
+    } else {
+        if (!isset($server['host'])) {
+            $link = PMA_DBI_real_connect($server_socket, $user, $password, null);
+        } else {
+            $link = PMA_DBI_real_connect(
+                $server['host'] . $server_port . $server_socket,
+                $user, $password, null
+            );
+        }
+    }
+    if (empty($link)) {
+        if ($is_controluser) {
+            trigger_error(
+                __(
+                    'Connection for controluser as defined'
+                    . ' in your configuration failed.'
+                ),
+                E_USER_WARNING
+            );
+            return false;
+        }
+        // we could be calling PMA_DBI_connect() to connect to another
+        // server, for example in the Synchronize feature, so do not
+        // go back to main login if it fails
+        if (! $auxiliary_connection) {
+            PMA_log_user($user, 'mysql-denied');
+            global $auth_plugin;
+            $auth_plugin->authFails();
+        } else {
+            return false;
+        }
+    } // end if
+    if (! $server) {
+        PMA_DBI_postConnect($link, $is_controluser);
+    }
+    return $link;
+}
+
+/**
+ * selects given database
+ *
+ * @param string   $dbname name of db to select
+ * @param resource $link   mysql link resource
+ *
+ * @return bool
+ */
+function PMA_DBI_select_db($dbname, $link = null)
+{
+    if (empty($link)) {
+        if (isset($GLOBALS['userlink'])) {
+            $link = $GLOBALS['userlink'];
+        } else {
+            return false;
+        }
+    }
+    return mysql_select_db($dbname, $link);
+}
+
+/**
+ * runs a query and returns the result
+ *
+ * @param string   $query   query to run
+ * @param resource $link    mysql link resource
+ * @param int      $options query options
+ *
+ * @return mixed
+ */
+function PMA_DBI_real_query($query, $link, $options)
+{
+    if ($options == ($options | PMA_DBI_QUERY_STORE)) {
+        return mysql_query($query, $link);
+    } elseif ($options == ($options | PMA_DBI_QUERY_UNBUFFERED)) {
+        return mysql_unbuffered_query($query, $link);
+    } else {
+        return mysql_query($query, $link);
+    }
+}
+
+/**
+ * returns array of rows with associative and numeric keys from $result
+ *
+ * @param resource $result result  MySQL result
+ *
+ * @return array
+ */
+function PMA_DBI_fetch_array($result)
+{
+    return mysql_fetch_array($result, MYSQL_BOTH);
+}
+
+/**
+ * returns array of rows with associative keys from $result
+ *
+ * @param resource $result MySQL result
+ *
+ * @return array
+ */
+function PMA_DBI_fetch_assoc($result)
+{
+    return mysql_fetch_array($result, MYSQL_ASSOC);
+}
+
+/**
+ * returns array of rows with numeric keys from $result
+ *
+ * @param resource $result MySQL result
+ *
+ * @return array
+ */
+function PMA_DBI_fetch_row($result)
+{
+    return mysql_fetch_array($result, MYSQL_NUM);
+}
+
+/**
+ * Adjusts the result pointer to an arbitrary row in the result
+ *
+ * @param resource $result database result
+ * @param integer  $offset offset to seek
+ *
+ * @return bool true on success, false on failure
+ */
+function PMA_DBI_data_seek($result, $offset)
+{
+    return mysql_data_seek($result, $offset);
+}
+
+/**
+ * Frees memory associated with the result
+ *
+ * @param resource $result database result
+ *
+ * @return void
+ */
+function PMA_DBI_free_result($result)
+{
+    if (is_resource($result) && get_resource_type($result) === 'mysql result') {
+        mysql_free_result($result);
+    }
+}
+
+/**
+ * Check if there are any more query results from a multi query
+ *
+ * @return bool false
+ */
+function PMA_DBI_more_results()
+{
+    // N.B.: PHP's 'mysql' extension does not support
+    // multi_queries so this function will always
+    // return false. Use the 'mysqli' extension, if
+    // you need support for multi_queries.
+    return false;
+}
+
+/**
+ * Prepare next result from multi_query
+ *
+ * @return boo false
+ */
+function PMA_DBI_next_result()
+{
+    // N.B.: PHP's 'mysql' extension does not support
+    // multi_queries so this function will always
+    // return false. Use the 'mysqli' extension, if
+    // you need support for multi_queries.
+    return false;
+}
+
+/**
+ * Returns a string representing the type of connection used
+ *
+ * @param resource $link mysql link
+ *
+ * @return string type of connection used
+ */
+function PMA_DBI_get_host_info($link = null)
+{
+    if (null === $link) {
+        if (isset($GLOBALS['userlink'])) {
+            $link = $GLOBALS['userlink'];
+        } else {
+            return false;
+        }
+    }
+    return mysql_get_host_info($link);
+}
+
+/**
+ * Returns the version of the MySQL protocol used
+ *
+ * @param resource $link mysql link
+ *
+ * @return int version of the MySQL protocol used
+ */
+function PMA_DBI_get_proto_info($link = null)
+{
+    if (null === $link) {
+        if (isset($GLOBALS['userlink'])) {
+            $link = $GLOBALS['userlink'];
+        } else {
+            return false;
+        }
+    }
+    return mysql_get_proto_info($link);
+}
+
+/**
+ * returns a string that represents the client library version
+ *
+ * @return string MySQL client library version
+ */
+function PMA_DBI_get_client_info()
+{
+    return mysql_get_client_info();
+}
+
+/**
+ * returns last error message or false if no errors occured
+ *
+ * @param resource $link mysql link
+ *
+ * @return string|bool $error or false
+ */
+function PMA_DBI_getError($link = null)
+{
+    $GLOBALS['errno'] = 0;
+
+    /* Treat false same as null because of controllink */
+    if ($link === false) {
+        $link = null;
+    }
+
+    if (null === $link && isset($GLOBALS['userlink'])) {
+        $link =& $GLOBALS['userlink'];
+
+        // Do not stop now. On the initial connection, we don't have a $link,
+        // we don't have a $GLOBALS['userlink'], but we can catch the error code
+        //    } else {
+        //            return false;
+    }
+
+    if (null !== $link && false !== $link) {
+        $error_number = mysql_errno($link);
+        $error_message = mysql_error($link);
+    } else {
+        $error_number = mysql_errno();
+        $error_message = mysql_error();
+    }
+    if (0 == $error_number) {
+        return false;
+    }
+
+    // keep the error number for further check after the call to PMA_DBI_getError()
+    $GLOBALS['errno'] = $error_number;
+
+    return PMA_DBI_formatError($error_number, $error_message);
+}
+
+/**
+ * returns the number of rows returned by last query
+ *
+ * @param resource $result MySQL result
+ *
+ * @return string|int
+ */
+function PMA_DBI_num_rows($result)
+{
+    if (!is_bool($result)) {
+        return mysql_num_rows($result);
+    } else {
+        return 0;
+    }
+}
+
+/**
+ * returns last inserted auto_increment id for given $link or $GLOBALS['userlink']
+ *
+ * @param resource $link the mysql object
+ *
+ * @return string|int
+ */
+function PMA_DBI_insert_id($link = null)
+{
+    if (empty($link)) {
+        if (isset($GLOBALS['userlink'])) {
+            $link = $GLOBALS['userlink'];
+        } else {
+            return false;
+        }
+    }
+    // If the primary key is BIGINT we get an incorrect result
+    // (sometimes negative, sometimes positive)
+    // and in the present function we don't know if the PK is BIGINT
+    // so better play safe and use LAST_INSERT_ID()
+    //
+    return PMA_DBI_fetch_value('SELECT LAST_INSERT_ID();', 0, 0, $link);
+}
+
+/**
+ * returns the number of rows affected by last query
+ *
+ * @param resource $link           the mysql object
+ * @param bool     $get_from_cache whether to retrieve from cache
+ *
+ * @return string|int
+ */
+function PMA_DBI_affected_rows($link = null, $get_from_cache = true)
+{
+    if (empty($link)) {
+        if (isset($GLOBALS['userlink'])) {
+            $link = $GLOBALS['userlink'];
+        } else {
+            return false;
+        }
+    }
+
+    if ($get_from_cache) {
+        return $GLOBALS['cached_affected_rows'];
+    } else {
+        return mysql_affected_rows($link);
+    }
+}
+
+/**
+ * returns metainfo for fields in $result
+ *
+ * @param resource $result MySQL result
+ *
+ * @return array meta info for fields in $result
+ *
+ * @todo add missing keys like in mysqli_query (decimals)
+ */
+function PMA_DBI_get_fields_meta($result)
+{
+    $fields       = array();
+    $num_fields   = mysql_num_fields($result);
+    for ($i = 0; $i < $num_fields; $i++) {
+        $field = mysql_fetch_field($result, $i);
+        $field->flags = mysql_field_flags($result, $i);
+        $field->orgtable = mysql_field_table($result, $i);
+        $field->orgname = mysql_field_name($result, $i);
+        $fields[] = $field;
+    }
+    return $fields;
+}
+
+/**
+ * return number of fields in given $result
+ *
+ * @param resource $result MySQL result
+ *
+ * @return int  field count
+ */
+function PMA_DBI_num_fields($result)
+{
+    return mysql_num_fields($result);
+}
+
+/**
+ * returns the length of the given field $i in $result
+ *
+ * @param resource $result MySQL result
+ * @param int      $i      field
+ *
+ * @return int length of field
+ */
+function PMA_DBI_field_len($result, $i)
+{
+    return mysql_field_len($result, $i);
+}
+
+/**
+ * returns name of $i. field in $result
+ *
+ * @param resource $result MySQL result
+ * @param int      $i      field
+ *
+ * @return string name of $i. field in $result
+ */
+function PMA_DBI_field_name($result, $i)
+{
+    return mysql_field_name($result, $i);
+}
+
+/**
+ * returns concatenated string of human readable field flags
+ *
+ * @param resource $result MySQL result
+ * @param int      $i      field
+ *
+ * @return string field flags
+ */
+function PMA_DBI_field_flags($result, $i)
+{
+    return mysql_field_flags($result, $i);
+}
+
+/**
+ * Store the result returned from multi query
+ *
+ * @return false
+ */
+function PMA_DBI_store_result()
+{
+    return false;
+}
+?>
diff --git a/phpmyadmin/libraries/dbi/mysqli.dbi.lib.php b/phpmyadmin/libraries/dbi/mysqli.dbi.lib.php
new file mode 100644
index 0000000..bf48521
--- /dev/null
+++ b/phpmyadmin/libraries/dbi/mysqli.dbi.lib.php
@@ -0,0 +1,748 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * Interface to the improved MySQL extension (MySQLi)
+ *
+ * @package    PhpMyAdmin-DBI
+ * @subpackage MySQLi
+ */
+if (! defined('PHPMYADMIN')) {
+    exit;
+}
+
+require_once './libraries/logging.lib.php';
+
+/**
+ * MySQL client API
+ */
+if (!defined('PMA_MYSQL_CLIENT_API')) {
+    $client_api = explode('.', mysqli_get_client_info());
+    define(
+        'PMA_MYSQL_CLIENT_API',
+        (int)sprintf(
+            '%d%02d%02d',
+            $client_api[0], $client_api[1], intval($client_api[2])
+        )
+    );
+    unset($client_api);
+}
+
+/**
+ * some PHP versions are reporting extra messages like "No index used in query"
+ */
+
+mysqli_report(MYSQLI_REPORT_OFF);
+
+/**
+ * some older mysql client libs are missing these constants ...
+ */
+if (! defined('MYSQLI_BINARY_FLAG')) {
+    define('MYSQLI_BINARY_FLAG', 128);
+}
+
+/**
+ * @see http://bugs.php.net/36007
+ */
+if (! defined('MYSQLI_TYPE_NEWDECIMAL')) {
+    define('MYSQLI_TYPE_NEWDECIMAL', 246);
+}
+if (! defined('MYSQLI_TYPE_BIT')) {
+    define('MYSQLI_TYPE_BIT', 16);
+}
+
+// for Drizzle
+if (! defined('MYSQLI_TYPE_VARCHAR')) {
+    define('MYSQLI_TYPE_VARCHAR', 15);
+}
+
+/**
+ * Helper function for connecting to the database server
+ *
+ * @param mysqli $link          connection link
+ * @param string $host          mysql hostname
+ * @param string $user          mysql user name
+ * @param string $password      mysql user password
+ * @param string $dbname        database name
+ * @param int    $server_port   server port
+ * @param string $server_socket server socket
+ * @param int    $client_flags  client flags of connection
+ * @param bool   $persistent    whether to use peristent connection
+ *
+ * @return bool
+ */
+function PMA_DBI_real_connect(
+    $link, $host, $user, $password, $dbname, $server_port,
+    $server_socket, $client_flags = null, $persistent = false
+) {
+    global $cfg;
+
+    // mysqli persistent connections only on PHP 5.3+
+    if (PMA_PHP_INT_VERSION >= 50300) {
+        if ($cfg['PersistentConnections'] || $persistent) {
+            $host = 'p:' . $host;
+        }
+    }
+    if ($client_flags === null) {
+        return @mysqli_real_connect(
+            $link,
+            $host,
+            $user,
+            $password,
+            $dbname,
+            $server_port,
+            $server_socket
+        );
+    } else {
+        return @mysqli_real_connect(
+            $link,
+            $host,
+            $user,
+            $password,
+            $dbname,
+            $server_port,
+            $server_socket,
+            $client_flags
+        );
+    }
+}
+
+/**
+ * connects to the database server
+ *
+ * @param string $user                 mysql user name
+ * @param string $password             mysql user password
+ * @param bool   $is_controluser       whether this is a control user connection
+ * @param array  $server               host/port/socket/persistent
+ * @param bool   $auxiliary_connection (when true, don't go back to login if
+ *                                     connection fails)
+ *
+ * @return mixed false on error or a mysqli object on success
+ */
+function PMA_DBI_connect(
+    $user, $password, $is_controluser = false, $server = null,
+    $auxiliary_connection = false
+) {
+    global $cfg;
+
+    if ($server) {
+        $server_port   = (empty($server['port']))
+            ? false
+            : (int)$server['port'];
+        $server_socket = (empty($server['socket']))
+            ? ''
+            : $server['socket'];
+        $server['host'] = (empty($server['host']))
+            ? 'localhost'
+            : $server['host'];
+    } else {
+        $server_port   = (empty($cfg['Server']['port']))
+            ? false
+            : (int) $cfg['Server']['port'];
+        $server_socket = (empty($cfg['Server']['socket']))
+            ? null
+            : $cfg['Server']['socket'];
+    }
+
+    // NULL enables connection to the default socket
+
+    $link = mysqli_init();
+
+    mysqli_options($link, MYSQLI_OPT_LOCAL_INFILE, true);
+
+    $client_flags = 0;
+
+    /* Optionally compress connection */
+    if ($cfg['Server']['compress'] && defined('MYSQLI_CLIENT_COMPRESS')) {
+        $client_flags |= MYSQLI_CLIENT_COMPRESS;
+    }
+
+    /* Optionally enable SSL */
+    if ($cfg['Server']['ssl'] && defined('MYSQLI_CLIENT_SSL')) {
+        $client_flags |= MYSQLI_CLIENT_SSL;
+    }
+
+    if (!$server) {
+        $return_value = @PMA_DBI_real_connect(
+            $link,
+            $cfg['Server']['host'],
+            $user,
+            $password,
+            false,
+            $server_port,
+            $server_socket,
+            $client_flags
+        );
+        // Retry with empty password if we're allowed to
+        if ($return_value == false
+            && isset($cfg['Server']['nopassword']) && $cfg['Server']['nopassword']
+            && !$is_controluser
+        ) {
+            $return_value = @PMA_DBI_real_connect(
+                $link,
+                $cfg['Server']['host'],
+                $user,
+                '',
+                false,
+                $server_port,
+                $server_socket,
+                $client_flags
+            );
+        }
+    } else {
+        $return_value = @PMA_DBI_real_connect(
+            $link,
+            $server['host'],
+            $user,
+            $password,
+            false,
+            $server_port,
+            $server_socket
+        );
+    }
+
+    if ($return_value == false) {
+        if ($is_controluser) {
+            trigger_error(
+                __('Connection for controluser as defined in your configuration failed.'),
+                E_USER_WARNING
+            );
+            return false;
+        }
+        // we could be calling PMA_DBI_connect() to connect to another
+        // server, for example in the Synchronize feature, so do not
+        // go back to main login if it fails
+        if (! $auxiliary_connection) {
+            PMA_log_user($user, 'mysql-denied');
+            global $auth_plugin;
+            $auth_plugin->authFails();
+        } else {
+            return false;
+        }
+    } else {
+        PMA_DBI_postConnect($link, $is_controluser);
+    }
+
+    return $link;
+}
+
+/**
+ * selects given database
+ *
+ * @param string $dbname database name to select
+ * @param mysqli $link   the mysqli object
+ *
+ * @return boolean
+ */
+function PMA_DBI_select_db($dbname, $link = null)
+{
+    if (empty($link)) {
+        if (isset($GLOBALS['userlink'])) {
+            $link = $GLOBALS['userlink'];
+        } else {
+            return false;
+        }
+    }
+    return mysqli_select_db($link, $dbname);
+}
+
+/**
+ * runs a query and returns the result
+ *
+ * @param string $query   query to execute
+ * @param mysqli $link    mysqli object
+ * @param int    $options query options
+ *
+ * @return mysqli_result|bool
+ */
+function PMA_DBI_real_query($query, $link, $options)
+{
+    if ($options == ($options | PMA_DBI_QUERY_STORE)) {
+        $method = MYSQLI_STORE_RESULT;
+    } elseif ($options == ($options | PMA_DBI_QUERY_UNBUFFERED)) {
+        $method = MYSQLI_USE_RESULT;
+    } else {
+        $method = 0;
+    }
+
+    return mysqli_query($link, $query, $method);
+}
+
+/**
+ * Run the multi query and output the results
+ *
+ * @param mysqli $link  mysqli object
+ * @param string $query multi query statement to execute
+ *
+ * @return mysqli_result collection | boolean(false)
+ */
+function PMA_DBI_real_multi_query($link, $query)
+{
+    return mysqli_multi_query($link, $query);
+}
+
+/**
+ * returns array of rows with associative and numeric keys from $result
+ *
+ * @param mysqli_result $result result set identifier
+ *
+ * @return array
+ */
+function PMA_DBI_fetch_array($result)
+{
+    return mysqli_fetch_array($result, MYSQLI_BOTH);
+}
+
+/**
+ * returns array of rows with associative keys from $result
+ *
+ * @param mysqli_result $result result set identifier
+ *
+ * @return array
+ */
+function PMA_DBI_fetch_assoc($result)
+{
+    return mysqli_fetch_array($result, MYSQLI_ASSOC);
+}
+
+/**
+ * returns array of rows with numeric keys from $result
+ *
+ * @param mysqli_result $result result set identifier
+ *
+ * @return array
+ */
+function PMA_DBI_fetch_row($result)
+{
+    return mysqli_fetch_array($result, MYSQLI_NUM);
+}
+
+/**
+ * Adjusts the result pointer to an arbitrary row in the result
+ *
+ * @param resource $result database result
+ * @param integer  $offset offset to seek
+ *
+ * @return bool true on success, false on failure
+ */
+function PMA_DBI_data_seek($result, $offset)
+{
+    return mysqli_data_seek($result, $offset);
+}
+
+/**
+ * Frees memory associated with the result
+ *
+ * @param mysqli_result $result database result
+ *
+ * @return void
+ */
+function PMA_DBI_free_result($result)
+{
+    if ($result instanceof mysqli_result) {
+        mysqli_free_result($result);
+    }
+}
+
+/**
+ * Check if there are any more query results from a multi query
+ *
+ * @param mysqli $link the mysqli object
+ *
+ * @return bool true or false
+ */
+function PMA_DBI_more_results($link = null)
+{
+    if (empty($link)) {
+        if (isset($GLOBALS['userlink'])) {
+            $link = $GLOBALS['userlink'];
+        } else {
+            return false;
+        }
+    }
+    return mysqli_more_results($link);
+}
+
+/**
+ * Prepare next result from multi_query
+ *
+ * @param mysqli $link the mysqli object
+ *
+ * @return bool true or false
+ */
+function PMA_DBI_next_result($link = null)
+{
+    if (empty($link)) {
+        if (isset($GLOBALS['userlink'])) {
+            $link = $GLOBALS['userlink'];
+        } else {
+            return false;
+        }
+    }
+    return mysqli_next_result($link);
+}
+
+/**
+ * Store the result returned from multi query
+ *
+ * @return mixed false when empty results / result set when not empty
+ */
+function PMA_DBI_store_result()
+{
+    if (isset($GLOBALS['userlink'])) {
+        $link = $GLOBALS['userlink'];
+    } else {
+        return false;
+    }
+    return mysqli_store_result($link);
+}
+
+/**
+ * Returns a string representing the type of connection used
+ *
+ * @param resource $link mysql link
+ *
+ * @return string type of connection used
+ */
+function PMA_DBI_get_host_info($link = null)
+{
+    if (null === $link) {
+        if (isset($GLOBALS['userlink'])) {
+            $link = $GLOBALS['userlink'];
+        } else {
+            return false;
+        }
+    }
+    return mysqli_get_host_info($link);
+}
+
+/**
+ * Returns the version of the MySQL protocol used
+ *
+ * @param resource $link mysql link
+ *
+ * @return integer version of the MySQL protocol used
+ */
+function PMA_DBI_get_proto_info($link = null)
+{
+    if (null === $link) {
+        if (isset($GLOBALS['userlink'])) {
+            $link = $GLOBALS['userlink'];
+        } else {
+            return false;
+        }
+    }
+    return mysqli_get_proto_info($link);
+}
+
+/**
+ * returns a string that represents the client library version
+ *
+ * @return string MySQL client library version
+ */
+function PMA_DBI_get_client_info()
+{
+    return mysqli_get_client_info();
+}
+
+/**
+ * returns last error message or false if no errors occured
+ *
+ * @param resource $link mysql link
+ *
+ * @return string|bool $error or false
+ */
+function PMA_DBI_getError($link = null)
+{
+    $GLOBALS['errno'] = 0;
+
+    /* Treat false same as null because of controllink */
+    if ($link === false) {
+        $link = null;
+    }
+
+    if (null === $link && isset($GLOBALS['userlink'])) {
+        $link =& $GLOBALS['userlink'];
+        // Do not stop now. We still can get the error code
+        // with mysqli_connect_errno()
+    }
+
+    if (null !== $link) {
+        $error_number = mysqli_errno($link);
+        $error_message = mysqli_error($link);
+    } else {
+        $error_number = mysqli_connect_errno();
+        $error_message = mysqli_connect_error();
+    }
+    if (0 == $error_number) {
+        return false;
+    }
+
+    // keep the error number for further check after the call to PMA_DBI_getError()
+    $GLOBALS['errno'] = $error_number;
+
+    return PMA_DBI_formatError($error_number, $error_message);
+}
+
+/**
+ * returns the number of rows returned by last query
+ *
+ * @param mysqli_result $result result set identifier
+ *
+ * @return string|int
+ */
+function PMA_DBI_num_rows($result)
+{
+    // see the note for PMA_DBI_try_query();
+    if (!is_bool($result)) {
+        return @mysqli_num_rows($result);
+    } else {
+        return 0;
+    }
+}
+
+/**
+ * returns last inserted auto_increment id for given $link or $GLOBALS['userlink']
+ *
+ * @param mysqli $link the mysqli object
+ *
+ * @return string|int
+ */
+function PMA_DBI_insert_id($link = null)
+{
+    if (empty($link)) {
+        if (isset($GLOBALS['userlink'])) {
+            $link = $GLOBALS['userlink'];
+        } else {
+            return false;
+        }
+    }
+    // When no controluser is defined, using mysqli_insert_id($link)
+    // does not always return the last insert id due to a mixup with
+    // the tracking mechanism, but this works:
+    return PMA_DBI_fetch_value('SELECT LAST_INSERT_ID();', 0, 0, $link);
+    // Curiously, this problem does not happen with the mysql extension but
+    // there is another problem with BIGINT primary keys so PMA_DBI_insert_id()
+    // in the mysql extension also uses this logic.
+}
+
+/**
+ * returns the number of rows affected by last query
+ *
+ * @param mysqli $link           the mysqli object
+ * @param bool   $get_from_cache whether to retrieve from cache
+ *
+ * @return string|int
+ */
+function PMA_DBI_affected_rows($link = null, $get_from_cache = true)
+{
+    if (empty($link)) {
+        if (isset($GLOBALS['userlink'])) {
+            $link = $GLOBALS['userlink'];
+        } else {
+            return false;
+        }
+    }
+    if ($get_from_cache) {
+        return $GLOBALS['cached_affected_rows'];
+    } else {
+        return mysqli_affected_rows($link);
+    }
+}
+
+/**
+ * returns metainfo for fields in $result
+ *
+ * @param mysqli_result $result result set identifier
+ *
+ * @return array meta info for fields in $result
+ */
+function PMA_DBI_get_fields_meta($result)
+{
+    // Build an associative array for a type look up
+    $typeAr = array();
+    $typeAr[MYSQLI_TYPE_DECIMAL]     = 'real';
+    $typeAr[MYSQLI_TYPE_NEWDECIMAL]  = 'real';
+    $typeAr[MYSQLI_TYPE_BIT]         = 'int';
+    $typeAr[MYSQLI_TYPE_TINY]        = 'int';
+    $typeAr[MYSQLI_TYPE_SHORT]       = 'int';
+    $typeAr[MYSQLI_TYPE_LONG]        = 'int';
+    $typeAr[MYSQLI_TYPE_FLOAT]       = 'real';
+    $typeAr[MYSQLI_TYPE_DOUBLE]      = 'real';
+    $typeAr[MYSQLI_TYPE_NULL]        = 'null';
+    $typeAr[MYSQLI_TYPE_TIMESTAMP]   = 'timestamp';
+    $typeAr[MYSQLI_TYPE_LONGLONG]    = 'int';
+    $typeAr[MYSQLI_TYPE_INT24]       = 'int';
+    $typeAr[MYSQLI_TYPE_DATE]        = 'date';
+    $typeAr[MYSQLI_TYPE_TIME]        = 'time';
+    $typeAr[MYSQLI_TYPE_DATETIME]    = 'datetime';
+    $typeAr[MYSQLI_TYPE_YEAR]        = 'year';
+    $typeAr[MYSQLI_TYPE_NEWDATE]     = 'date';
+    $typeAr[MYSQLI_TYPE_ENUM]        = 'unknown';
+    $typeAr[MYSQLI_TYPE_SET]         = 'unknown';
+    $typeAr[MYSQLI_TYPE_TINY_BLOB]   = 'blob';
+    $typeAr[MYSQLI_TYPE_MEDIUM_BLOB] = 'blob';
+    $typeAr[MYSQLI_TYPE_LONG_BLOB]   = 'blob';
+    $typeAr[MYSQLI_TYPE_BLOB]        = 'blob';
+    $typeAr[MYSQLI_TYPE_VAR_STRING]  = 'string';
+    $typeAr[MYSQLI_TYPE_STRING]      = 'string';
+    $typeAr[MYSQLI_TYPE_VARCHAR]     = 'string'; // for Drizzle
+    // MySQL returns MYSQLI_TYPE_STRING for CHAR
+    // and MYSQLI_TYPE_CHAR === MYSQLI_TYPE_TINY
+    // so this would override TINYINT and mark all TINYINT as string
+    // https://sourceforge.net/p/phpmyadmin/bugs/2205/
+    //$typeAr[MYSQLI_TYPE_CHAR]        = 'string';
+    $typeAr[MYSQLI_TYPE_GEOMETRY]    = 'geometry';
+    $typeAr[MYSQLI_TYPE_BIT]         = 'bit';
+
+    $fields = mysqli_fetch_fields($result);
+
+    // this happens sometimes (seen under MySQL 4.0.25)
+    if (!is_array($fields)) {
+        return false;
+    }
+
+    foreach ($fields as $k => $field) {
+        $fields[$k]->_type = $field->type;
+        $fields[$k]->type = $typeAr[$field->type];
+        $fields[$k]->_flags = $field->flags;
+        $fields[$k]->flags = PMA_DBI_field_flags($result, $k);
+
+        // Enhance the field objects for mysql-extension compatibilty
+        //$flags = explode(' ', $fields[$k]->flags);
+        //array_unshift($flags, 'dummy');
+        $fields[$k]->multiple_key
+            = (int) (bool) ($fields[$k]->_flags & MYSQLI_MULTIPLE_KEY_FLAG);
+        $fields[$k]->primary_key
+            = (int) (bool) ($fields[$k]->_flags & MYSQLI_PRI_KEY_FLAG);
+        $fields[$k]->unique_key
+            = (int) (bool) ($fields[$k]->_flags & MYSQLI_UNIQUE_KEY_FLAG);
+        $fields[$k]->not_null
+            = (int) (bool) ($fields[$k]->_flags & MYSQLI_NOT_NULL_FLAG);
+        $fields[$k]->unsigned
+            = (int) (bool) ($fields[$k]->_flags & MYSQLI_UNSIGNED_FLAG);
+        $fields[$k]->zerofill
+            = (int) (bool) ($fields[$k]->_flags & MYSQLI_ZEROFILL_FLAG);
+        $fields[$k]->numeric
+            = (int) (bool) ($fields[$k]->_flags & MYSQLI_NUM_FLAG);
+        $fields[$k]->blob
+            = (int) (bool) ($fields[$k]->_flags & MYSQLI_BLOB_FLAG);
+    }
+    return $fields;
+}
+
+/**
+ * return number of fields in given $result
+ *
+ * @param mysqli_result $result result set identifier
+ *
+ * @return int field count
+ */
+function PMA_DBI_num_fields($result)
+{
+    return mysqli_num_fields($result);
+}
+
+/**
+ * returns the length of the given field $i in $result
+ *
+ * @param mysqli_result $result result set identifier
+ * @param int           $i      field
+ *
+ * @return int length of field
+ */
+function PMA_DBI_field_len($result, $i)
+{
+    return mysqli_fetch_field_direct($result, $i)->length;
+}
+
+/**
+ * returns name of $i. field in $result
+ *
+ * @param mysqli_result $result result set identifier
+ * @param int           $i      field
+ *
+ * @return string name of $i. field in $result
+ */
+function PMA_DBI_field_name($result, $i)
+{
+    return mysqli_fetch_field_direct($result, $i)->name;
+}
+
+/**
+ * returns concatenated string of human readable field flags
+ *
+ * @param mysqli_result $result result set identifier
+ * @param int           $i      field
+ *
+ * @return string field flags
+ */
+function PMA_DBI_field_flags($result, $i)
+{
+    // This is missing from PHP 5.2.5, see http://bugs.php.net/bug.php?id=44846
+    if (! defined('MYSQLI_ENUM_FLAG')) {
+        define('MYSQLI_ENUM_FLAG', 256); // see MySQL source include/mysql_com.h
+    }
+    $f = mysqli_fetch_field_direct($result, $i);
+    $type = $f->type;
+    $charsetnr = $f->charsetnr;
+    $f = $f->flags;
+    $flags = '';
+    if ($f & MYSQLI_UNIQUE_KEY_FLAG) {
+        $flags .= 'unique ';
+    }
+    if ($f & MYSQLI_NUM_FLAG) {
+        $flags .= 'num ';
+    }
+    if ($f & MYSQLI_PART_KEY_FLAG) {
+        $flags .= 'part_key ';
+    }
+    if ($f & MYSQLI_SET_FLAG) {
+        $flags .= 'set ';
+    }
+    if ($f & MYSQLI_TIMESTAMP_FLAG) {
+        $flags .= 'timestamp ';
+    }
+    if ($f & MYSQLI_AUTO_INCREMENT_FLAG) {
+        $flags .= 'auto_increment ';
+    }
+    if ($f & MYSQLI_ENUM_FLAG) {
+        $flags .= 'enum ';
+    }
+    // See http://dev.mysql.com/doc/refman/6.0/en/c-api-datatypes.html:
+    // to determine if a string is binary, we should not use MYSQLI_BINARY_FLAG
+    // but instead the charsetnr member of the MYSQL_FIELD
+    // structure. Watch out: some types like DATE returns 63 in charsetnr
+    // so we have to check also the type.
+    // Unfortunately there is no equivalent in the mysql extension.
+    if (($type == MYSQLI_TYPE_TINY_BLOB || $type == MYSQLI_TYPE_BLOB
+        || $type == MYSQLI_TYPE_MEDIUM_BLOB || $type == MYSQLI_TYPE_LONG_BLOB
+        || $type == MYSQLI_TYPE_VAR_STRING || $type == MYSQLI_TYPE_STRING)
+        && 63 == $charsetnr
+    ) {
+        $flags .= 'binary ';
+    }
+    if ($f & MYSQLI_ZEROFILL_FLAG) {
+        $flags .= 'zerofill ';
+    }
+    if ($f & MYSQLI_UNSIGNED_FLAG) {
+        $flags .= 'unsigned ';
+    }
+    if ($f & MYSQLI_BLOB_FLAG) {
+        $flags .= 'blob ';
+    }
+    if ($f & MYSQLI_MULTIPLE_KEY_FLAG) {
+        $flags .= 'multiple_key ';
+    }
+    if ($f & MYSQLI_UNIQUE_KEY_FLAG) {
+        $flags .= 'unique_key ';
+    }
+    if ($f & MYSQLI_PRI_KEY_FLAG) {
+        $flags .= 'primary_key ';
+    }
+    if ($f & MYSQLI_NOT_NULL_FLAG) {
+        $flags .= 'not_null ';
+    }
+    return trim($flags);
+}
+
+?>
diff --git a/phpmyadmin/libraries/display_change_password.lib.php b/phpmyadmin/libraries/display_change_password.lib.php
new file mode 100644
index 0000000..ba5b012
--- /dev/null
+++ b/phpmyadmin/libraries/display_change_password.lib.php
@@ -0,0 +1,98 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * Displays form for password change
+ *
+ * @package PhpMyAdmin
+ */
+if (! defined('PHPMYADMIN')) {
+    exit;
+}
+
+/**
+  * Get HTML for the Change password dialog 
+  *
+  * @param string $username username
+  * @param string $hostname hostname
+  *
+  * @return string html snippet
+  */
+function PMA_getHtmlForChangePassword($username, $hostname)
+{
+    /**
+     * autocomplete feature of IE kills the "onchange" event handler and it
+     * must be replaced by the "onpropertychange" one in this case
+     */
+    $chg_evt_handler = (PMA_USR_BROWSER_AGENT == 'IE'
+        && PMA_USR_BROWSER_VER >= 5
+        && PMA_USR_BROWSER_VER < 7)
+                 ? 'onpropertychange'
+                 : 'onchange';
+
+    $html = '<form method="post" id="change_password_form" '
+        . 'action="' . $GLOBALS['PMA_PHP_SELF'] . '" '
+        . 'name="chgPassword" ' 
+        . 'class="ajax" >';
+
+    $html .= PMA_generate_common_hidden_inputs();
+
+    if (strpos($GLOBALS['PMA_PHP_SELF'], 'server_privileges') !== false) {
+        $html .= '<input type="hidden" name="username" '
+            . 'value="' . htmlspecialchars($username) . '" />'
+            . '<input type="hidden" name="hostname" '
+            . 'value="' . htmlspecialchars($hostname) . '" />';
+    }
+    $html .= '<fieldset id="fieldset_change_password">'
+        . '<legend>' . __('Change password') . '</legend>'
+        . '<table class="data noclick">'
+        . '<tr class="odd">'
+        . '<td colspan="2">'
+        . '<input type="radio" name="nopass" value="1" id="nopass_1" '
+        . 'onclick="pma_pw.value = \'\'; pma_pw2.value = \'\'; '
+        . 'this.checked = true" />'
+        . '<label for="nopass_1">' . __('No Password') . '</label>'
+        . '</td>'
+        . '</tr>'
+        . '<tr class="even vmiddle">'
+        . '<td>'
+        . '<input type="radio" name="nopass" value="0" id="nopass_0" '
+        . 'onclick="document.getElementById(\'text_pma_pw\').focus();" '
+        . 'checked="checked " />'
+        . '<label for="nopass_0">' . __('Password') . ': </label>'
+        . '</td>'
+        . '<td>'
+        . '<input type="password" name="pma_pw" id="text_pma_pw" size="10" '
+        . 'class="textfield"' 
+        . $chg_evt_handler . '="nopass[1].checked = true" />'
+        . '  ' . __('Re-type') . ': '
+        . '<input type="password" name="pma_pw2" id="text_pma_pw2" size="10" '
+        . 'class="textfield"'
+        . $chg_evt_handler . '="nopass[1].checked = true" />'
+        . '</td>'
+        . '</tr>'
+        . '<tr class="vmiddle">'
+        . '<td>' . __('Password Hashing') . ':'
+        . '</td>'
+        . '<td>'
+        . '<input type="radio" name="pw_hash" id="radio_pw_hash_new" '
+        . 'value="new" checked="checked" />'
+        . '<label for="radio_pw_hash_new">MySQL 4.1+</label>'
+        . '</td>'
+        . '</tr>'
+        . '<tr id="tr_element_before_generate_password">'
+        . '<td> </td>'
+        . '<td>'
+        . '<input type="radio" name="pw_hash" id="radio_pw_hash_old" '
+        . 'value="old" />'
+        . '<label for="radio_pw_hash_old">' . __('MySQL 4.0 compatible') 
+        . '</label>'
+        . '</td>'
+        . '</tr>'
+        . '</table>'
+        . '</fieldset>'
+        . '<fieldset id="fieldset_change_password_footer" class="tblFooters">'
+        . '<input type="submit" name="change_pw" value="' . __('Go') . '" />'
+        . '</fieldset>'
+        . '</form>';
+    return $html;
+}
diff --git a/phpmyadmin/libraries/display_create_database.lib.php b/phpmyadmin/libraries/display_create_database.lib.php
new file mode 100644
index 0000000..228477c
--- /dev/null
+++ b/phpmyadmin/libraries/display_create_database.lib.php
@@ -0,0 +1,49 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * Displays form for creating database (if user has privileges for that)
+ *
+ * @package PhpMyAdmin
+ */
+if (! defined('PHPMYADMIN')) {
+    exit;
+}
+
+/**
+ *
+ */
+require_once './libraries/check_user_privileges.lib.php';
+
+if ($is_create_db_priv) {
+    // The user is allowed to create a db
+    ?>
+        <form method="post" action="db_create.php" id="create_database_form" class="ajax"><strong>
+            <?php echo '<label for="text_create_db">' 
+                       . PMA_Util::getImage('b_newdb.png')
+                       . " " . __('Create database')
+                       . '</label> '
+                       . PMA_Util::showMySQLDocu('SQL-Syntax', 'CREATE_DATABASE'); ?></strong><br />
+            <?php echo PMA_generate_common_hidden_inputs('', '', 5); ?>
+            <input type="hidden" name="reload" value="1" />
+            <input type="text" name="new_db" value="<?php echo $db_to_create; ?>" maxlength="64" class="textfield" id="text_create_db"/>
+    <?php
+    include_once './libraries/mysql_charsets.lib.php';
+    echo PMA_generateCharsetDropdownBox(PMA_CSDROPDOWN_COLLATION, 'db_collation', null, null, true, 5);
+
+    if (! empty($dbstats)) {
+        echo '<input type="hidden" name="dbstats" value="1" />';
+    }
+    ?>
+            <input type="submit" value="<?php echo __('Create'); ?>" id="buttonGo" />
+        </form>
+    <?php
+} else {
+    ?>
+    <!-- db creation no privileges message -->
+        <strong><?php echo __('Create database') . ': ' . PMA_Util::showMySQLDocu('SQL-Syntax', 'CREATE_DATABASE'); ?></strong><br />
+        <?php
+              echo '<span class="noPrivileges">'
+                 . PMA_Util::getImage('s_error2.png', '', array('hspace' => 2, 'border' => 0, 'align' => 'middle'))
+                 . '' . __('No Privileges') .'</span>';
+} // end create db form or message
+?>
diff --git a/phpmyadmin/libraries/display_create_table.lib.php b/phpmyadmin/libraries/display_create_table.lib.php
new file mode 100644
index 0000000..eb803cc
--- /dev/null
+++ b/phpmyadmin/libraries/display_create_table.lib.php
@@ -0,0 +1,63 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * Displays form for creating a table (if user has privileges for that)
+ *
+ * for MySQL >= 4.1.0, we should be able to detect if user has a CREATE
+ * privilege by looking at SHOW GRANTS output;
+ * for < 4.1.0, it could be more difficult because the logic tries to
+ * detect the current host and it might be expressed in many ways; also
+ * on a shared server, the user might be unable to define a controluser
+ * that has the proper rights to the "mysql" db;
+ * so we give up and assume that user has the right to create a table
+ *
+ * Note: in this case we could even skip the following "foreach" logic
+ *
+ * Addendum, 2006-01-19: ok, I give up. We got some reports about servers
+ * where the hostname field in mysql.user is not the same as the one
+ * in mysql.db for a user. In this case, SHOW GRANTS does not return
+ * the db-specific privileges. And probably, those users are on a shared
+ * server, so can't set up a control user with rights to the "mysql" db.
+ * We cannot reliably detect the db-specific privileges, so no more
+ * warnings about the lack of privileges for CREATE TABLE. Tested
+ * on MySQL 5.0.18.
+ *
+ * @package PhpMyAdmin
+ */
+if (! defined('PHPMYADMIN')) {
+    exit;
+}
+
+/**
+ *
+ */
+require_once './libraries/check_user_privileges.lib.php';
+
+$is_create_table_priv = true;
+
+?>
+    <form id="create_table_form_minimal" method="post" action="tbl_create.php">
+<fieldset>
+    <legend>
+<?php
+if ($GLOBALS['cfg']['PropertiesIconic']) {
+    echo PMA_Util::getImage('b_newtbl.png');
+}
+echo __('Create table');
+?>
+    </legend>
+    <?php echo PMA_generate_common_hidden_inputs($db); ?>
+    <div class="formelement">
+        <?php echo __('Name'); ?>:
+        <input type="text" name="table" maxlength="64" size="30" />
+    </div>
+    <div class="formelement">
+        <?php echo __('Number of columns'); ?>:
+        <input type="text" name="num_fields" size="2" />
+    </div>
+    <div class="clearfloat"></div>
+</fieldset>
+<fieldset class="tblFooters">
+    <input type="submit" value="<?php echo __('Go'); ?>" />
+</fieldset>
+</form>
diff --git a/phpmyadmin/libraries/display_export.lib.php b/phpmyadmin/libraries/display_export.lib.php
new file mode 100644
index 0000000..9e162a0
--- /dev/null
+++ b/phpmyadmin/libraries/display_export.lib.php
@@ -0,0 +1,443 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * Displays export tab.
+ *
+ * @package PhpMyAdmin
+ */
+if (! defined('PHPMYADMIN')) {
+    exit;
+}
+
+// Get relations & co. status
+$cfgRelation = PMA_getRelationsParam();
+
+if (isset($_REQUEST['single_table'])) {
+    $GLOBALS['single_table'] = $_REQUEST['single_table'];
+}
+
+require_once './libraries/file_listing.lib.php';
+require_once './libraries/plugin_interface.lib.php';
+
+/**
+ * Outputs appropriate checked statement for checkbox.
+ *
+ * @param string $str option name
+ *
+ * @return void
+ */
+function PMA_exportCheckboxCheck($str)
+{
+    if (isset($GLOBALS['cfg']['Export'][$str]) && $GLOBALS['cfg']['Export'][$str]) {
+        echo ' checked="checked"';
+    }
+}
+
+/* Scan for plugins */
+$export_list = PMA_getPlugins(
+    "export",
+    'libraries/plugins/export/',
+    array(
+        'export_type' => $export_type,
+        'single_table' => isset($single_table)
+    )
+);
+
+/* Fail if we didn't find any plugin */
+if (empty($export_list)) {
+    PMA_Message::error(
+        __('Could not load export plugins, please check your installation!')
+    )->display();
+    exit;
+}
+
+echo '<form method="post" action="export.php" name="dump" class="disableAjax">';
+
+if ($export_type == 'server') {
+    echo PMA_generate_common_hidden_inputs('', '', 1);
+} elseif ($export_type == 'database') {
+    echo PMA_generate_common_hidden_inputs($db, '', 1);
+} else {
+    echo PMA_generate_common_hidden_inputs($db, $table, 1);
+}
+
+// just to keep this value for possible next display of this form after saving
+// on server
+if (isset($single_table)) {
+    echo '<input type="hidden" name="single_table" value="TRUE" />' . "\n";
+}
+
+echo '<input type="hidden" name="export_type" value="' . $export_type . '" />';
+echo "\n";
+
+// If the export method was not set, the default is quick
+if (isset($_GET['export_method'])) {
+    $cfg['Export']['method'] = $_GET['export_method'];
+} elseif (! isset($cfg['Export']['method'])) {
+    $cfg['Export']['method'] = 'quick';
+}
+// The export method (quick, custom or custom-no-form)
+echo '<input type="hidden" name="export_method" value="'
+    . htmlspecialchars($cfg['Export']['method']) . '" />';
+
+
+if (isset($_GET['sql_query'])) {
+    echo '<input type="hidden" name="sql_query" value="'
+        . htmlspecialchars($_GET['sql_query']) . '" />' . "\n";
+} elseif (! empty($sql_query)) {
+    echo '<input type="hidden" name="sql_query" value="'
+        . htmlspecialchars($sql_query) . '" />' . "\n";
+}
+
+echo '<div class="exportoptions" id="header">';
+echo '<h2>';
+echo PMA_Util::getImage('b_export.png', __('Export'));
+if ($export_type == 'server') {
+    echo __('Exporting databases from the current server');
+} elseif ($export_type == 'database') {
+    printf(__('Exporting tables from "%s" database'), htmlspecialchars($db));
+} else {
+    printf(__('Exporting rows from "%s" table'), htmlspecialchars($table));
+}
+echo '</h2>';
+echo '</div>';
+
+if (isset($_GET['quick_or_custom'])) {
+    $export_method = $_GET['quick_or_custom'];
+} else {
+    $export_method = $cfg['Export']['method'];
+}
+
+echo '<div class="exportoptions" id="quick_or_custom">';
+echo '<h3>' . __('Export Method:') . '</h3>';
+echo '<ul>';
+echo '<li>';
+echo '<input type="radio" name="quick_or_custom" value="quick" '
+    . ' id="radio_quick_export"';
+if ($export_method == 'quick' || $export_method == 'quick_no_form') {
+    echo ' checked="checked"';
+}
+echo ' />';
+echo '<label for ="radio_quick_export">';
+echo __('Quick - display only the minimal options');
+echo '</label>';
+echo '</li>';
+
+echo '<li>';
+echo '<input type="radio" name="quick_or_custom" value="custom" '
+    . ' id="radio_custom_export"';
+if ($export_method == 'custom' || $export_method == 'custom_no_form') {
+    echo ' checked="checked"';
+}
+echo ' />';
+echo '<label for="radio_custom_export">';
+echo __('Custom - display all possible options');
+echo '</label>';
+echo '</li>';
+
+echo '</ul>';
+echo '</div>';
+
+echo '<div class="exportoptions" id="databases_and_tables">';
+if ($export_type == 'server') {
+    echo '<h3>' . __('Database(s):') . '</h3>';
+} else if ($export_type == 'database') {
+    echo '<h3>' . __('Table(s):') . '</h3>';
+}
+if (! empty($multi_values)) {
+    echo $multi_values;
+}
+echo '</div>';
+
+if (strlen($table) && ! isset($num_tables) && ! PMA_Table::isMerge($db, $table)) {
+    echo '<div class="exportoptions" id="rows">';
+    echo '<h3>' . __('Rows:') . '</h3>';
+    echo '<ul>';
+    echo '<li>';
+    echo '<input type="radio" name="allrows" value="0" id="radio_allrows_0"';
+    if (isset($_GET['allrows']) && $_GET['allrows'] == 0) {
+        echo ' checked="checked"';
+    }
+    echo '/>';
+    echo '<label for ="radio_allrows_0">' . __('Dump some row(s)') . '</label>';
+    echo '<ul>';
+    echo '<li>';
+    echo '<label for="limit_to">' . __('Number of rows:') . '</label>';
+    echo '<input type="text" id="limit_to" name="limit_to" size="5" value="';
+    if (isset($_GET['limit_to'])) {
+        echo htmlspecialchars($_GET['limit_to']);
+    } elseif (isset($unlim_num_rows)) {
+        echo $unlim_num_rows;
+    } else {
+        echo PMA_Table::countRecords($db, $table);
+    }
+    echo '" onfocus="this.select()" />';
+    echo '</li>';
+    echo '<li>';
+    echo '<label for="limit_from">' . __('Row to begin at:') . '</label>';
+    echo '<input type="text" id="limit_from" name="limit_from" value="';
+    if (isset($_GET['limit_from'])) {
+        echo htmlspecialchars($_GET['limit_from']);
+    } else {
+        echo '0';
+    }
+    echo '" size="5" onfocus="this.select()" />';
+    echo '</li>';
+    echo '</ul>';
+    echo '</li>';
+    echo '<li>';
+    echo '<input type="radio" name="allrows" value="1" id="radio_allrows_1"';
+    if (! isset($_GET['allrows']) || $_GET['allrows'] == 1) {
+        echo ' checked="checked"';
+    }
+    echo '/>';
+    echo ' <label for="radio_allrows_1">' . __('Dump all rows') . '</label>';
+    echo '</li>';
+    echo '</ul>';
+    echo '</div>';
+}
+
+if (isset($cfg['SaveDir']) && !empty($cfg['SaveDir'])) {
+    echo '<div class="exportoptions" id="output_quick_export">';
+    echo '<h3>' . __('Output:') . '</h3>';
+    echo '<ul>';
+    echo '<li>';
+    echo '<input type="checkbox" name="quick_export_onserver" value="saveit" ';
+    echo 'id="checkbox_quick_dump_onserver" ';
+    PMA_exportCheckboxCheck('quick_export_onserver');
+    echo '/>';
+    echo '<label for="checkbox_quick_dump_onserver">';
+    printf(
+        __('Save on server in the directory <b>%s</b>'),
+        htmlspecialchars(PMA_Util::userDir($cfg['SaveDir']))
+    );
+    echo '</label>';
+    echo '</li>';
+    echo '<li>';
+    echo '<input type="checkbox" name="quick_export_onserverover" ';
+    echo 'value="saveitover" id="checkbox_quick_dump_onserverover" ';
+    PMA_exportCheckboxCheck('quick_export_onserver_overwrite');
+    echo '/>';
+    echo '<label for="checkbox_quick_dump_onserverover">';
+    echo __('Overwrite existing file(s)');
+    echo '</label>';
+    echo '</li>';
+    echo '</ul>';
+    echo '</div>';
+}
+
+echo '<div class="exportoptions" id="output">';
+echo '<h3>' . __('Output:') . '</h3>';
+echo '<ul id="ul_output">';
+echo '<li>';
+echo '<input type="radio" name="output_format" value="sendit" ';
+echo 'id="radio_dump_asfile" ';
+if (!isset($_GET['repopulate'])) {
+    PMA_exportCheckboxCheck('asfile');
+}
+echo '/>';
+echo '<label for="radio_dump_asfile">' . __('Save output to a file') . '</label>';
+echo '<ul id="ul_save_asfile">';
+if (isset($cfg['SaveDir']) && !empty($cfg['SaveDir'])) {
+    echo '<li>';
+    echo '<input type="checkbox" name="onserver" value="saveit" ';
+    echo 'id="checkbox_dump_onserver" ';
+    PMA_exportCheckboxCheck('onserver');
+    echo '/>';
+    echo '<label for="checkbox_dump_onserver">';
+    printf(
+        __('Save on server in the directory <b>%s</b>'),
+        htmlspecialchars(PMA_Util::userDir($cfg['SaveDir']))
+    );
+    echo '</label>';
+    echo '</li>';
+    echo '<li>';
+    echo '<input type="checkbox" name="onserverover" value="saveitover"';
+    echo ' id="checkbox_dump_onserverover" ';
+    PMA_exportCheckboxCheck('onserver_overwrite');
+    echo '/>';
+    echo '<label for="checkbox_dump_onserverover">';
+    echo __('Overwrite existing file(s)');
+    echo '</label>';
+    echo '</li>';
+}
+echo '<li>';
+echo '<label for="filename_template" class="desc">';
+echo __('File name template:');
+$trans = new PMA_Message;
+$trans->addMessage(__('@SERVER@ will become the server name'));
+if ($export_type == 'database' || $export_type == 'table') {
+    $trans->addMessage(__(', @DATABASE@ will become the database name'));
+    if ($export_type == 'table') {
+        $trans->addMessage(__(', @TABLE@ will become the table name'));
+    }
+}
+
+$msg = new PMA_Message(
+    __('This value is interpreted using %1$sstrftime%2$s, so you can use time formatting strings. Additionally the following transformations will happen: %3$s. Other text will be kept as is. See the %4$sFAQ%5$s for details.')
+);
+$msg->addParam(
+    '<a href="' . PMA_linkURL(PMA_getPHPDocLink('function.strftime.php'))
+    . '" target="documentation" title="' . __('Documentation') . '">',
+    false
+);
+$msg->addParam('</a>', false);
+$msg->addParam($trans);
+$doc_url = PMA_Util::getDocuLink('faq', 'faq6-27');
+$msg->addParam(
+    '<a href="'. $doc_url . '" target="documentation">',
+    false
+);
+$msg->addParam('</a>', false);
+
+echo PMA_Util::showHint($msg);
+echo '</label>';
+echo '<input type="text" name="filename_template" id="filename_template" ';
+echo ' value="';
+if (isset($_GET['filename_template'])) {
+    echo htmlspecialchars($_GET['filename_template']);
+} else {
+    if ($export_type == 'database') {
+        echo htmlspecialchars(
+            $GLOBALS['PMA_Config']->getUserValue(
+                'pma_db_filename_template',
+                $GLOBALS['cfg']['Export']['file_template_database']
+            )
+        );
+    } elseif ($export_type == 'table') {
+        echo htmlspecialchars(
+            $GLOBALS['PMA_Config']->getUserValue(
+                'pma_table_filename_template',
+                $GLOBALS['cfg']['Export']['file_template_table']
+            )
+        );
+    } else {
+        echo htmlspecialchars(
+            $GLOBALS['PMA_Config']->getUserValue(
+                'pma_server_filename_template',
+                $GLOBALS['cfg']['Export']['file_template_server']
+            )
+        );
+    }
+}
+echo '"';
+echo '/>';
+echo '<input type="checkbox" name="remember_template" ';
+echo 'id="checkbox_remember_template" ';
+PMA_exportCheckboxCheck('remember_file_template');
+echo '/>';
+echo '<label for="checkbox_remember_template">';
+echo __('use this for future exports');
+echo '</label>';
+echo '</li>';
+// charset of file
+if ($GLOBALS['PMA_recoding_engine'] != PMA_CHARSET_NONE) {
+    echo '        <li><label for="select_charset_of_file" class="desc">'
+        . __('Character set of the file:') . '</label>' . "\n";
+    reset($cfg['AvailableCharsets']);
+    echo '<select id="select_charset_of_file" name="charset_of_file" size="1">';
+    foreach ($cfg['AvailableCharsets'] as $temp_charset) {
+        echo '<option value="' . $temp_charset . '"';
+        if (isset($_GET['charset_of_file'])
+            && ($_GET['charset_of_file'] != $temp_charset)
+        ) {
+            echo '';
+        } elseif ((empty($cfg['Export']['charset']) && $temp_charset == 'utf-8')
+            || $temp_charset == $cfg['Export']['charset']
+        ) {
+            echo ' selected="selected"';
+        }
+        echo '>' . $temp_charset . '</option>';
+    } // end foreach
+    echo '</select></li>';
+} // end if
+
+if (isset($_GET['compression'])) {
+    $selected_compression = $_GET['compression'];
+} elseif (isset($cfg['Export']['compression'])) {
+    $selected_compression = $cfg['Export']['compression'];
+} else {
+    $selected_compression = "none";
+}
+
+// zip, gzip and bzip2 encode features
+$is_zip  = ($cfg['ZipDump']  && @function_exists('gzcompress'));
+$is_gzip = ($cfg['GZipDump'] && @function_exists('gzencode'));
+$is_bzip2 = ($cfg['BZipDump'] && @function_exists('bzcompress'));
+if ($is_zip || $is_gzip || $is_bzip2) {
+    echo '<li>';
+    echo '<label for="compression" class="desc">' . __('Compression:') . '</label>';
+    echo '<select id="compression" name="compression">';
+    echo '<option value="none">' . __('None') . '</option>';
+    if ($is_zip) {
+        echo '<option value="zip" ';
+        if ($selected_compression == "zip") {
+            echo 'selected="selected"';
+        }
+        echo '>' . __('zipped') . '</option>';
+    }
+    if ($is_gzip) {
+        echo '<option value="gzip" ';
+        if ($selected_compression == "gzip") {
+            echo 'selected="selected"';
+        }
+        echo '>' . __('gzipped') . '</option>';
+    }
+    if ($is_bzip2) {
+        echo '<option value="bzip2" ';
+        if ($selected_compression == "bzip2") {
+            echo 'selected="selected"';
+        }
+        echo '>' . __('bzipped') . '</option>';
+    }
+    echo '</select>';
+    echo '</li>';
+} else {
+    echo '<input type="hidden" name="compression" value="'
+        . htmlspecialchars($selected_compression) . '" />';
+}
+echo '</ul>';
+echo '</li>';
+echo '<li>';
+echo '<input type="radio" id="radio_view_as_text" name="output_format" '
+    . 'value="astext" ';
+if (isset($_GET['repopulate']) || $GLOBALS['cfg']['Export']['asfile'] == false) {
+    echo 'checked="checked"';
+}
+echo '/>';
+echo '<label for="radio_view_as_text">'
+    . __('View output as text') . '</label></li>';
+echo '</ul>';
+echo '</div>';
+
+echo '<div class="exportoptions" id="format">';
+echo '<h3>' . __('Format:') . '</h3>';
+echo PMA_pluginGetChoice('Export', 'what', $export_list, 'format');
+echo '</div>';
+
+echo '<div class="exportoptions" id="format_specific_opts">';
+echo '<h3>' . __('Format-specific options:') . '</h3>';
+echo '<p class="no_js_msg" id="scroll_to_options_msg">';
+echo __('Scroll down to fill in the options for the selected format and ignore the options for other formats.');
+echo '</p>';
+echo PMA_pluginGetOptions('Export', $export_list);
+echo '</div>';
+
+if (function_exists('PMA_set_enc_form')) {
+    // Encoding setting form appended by Y.Kawada
+    // Japanese encoding setting
+    echo '<div class="exportoptions" id="kanji_encoding">';
+    echo '<h3>' . __('Encoding Conversion:') . '</h3>';
+    echo PMA_set_enc_form('            ');
+    echo '</div>';
+}
+
+echo '<div class="exportoptions" id="submit">';
+
+echo PMA_Util::getExternalBug(
+    __('SQL compatibility mode'), 'mysql', '50027', '14515'
+);
+
+echo '<input type="submit" value="' . __('Go') . '" id="buttonGo" />';
+echo '</div>';
+echo '</form>';
diff --git a/phpmyadmin/libraries/display_git_revision.lib.php b/phpmyadmin/libraries/display_git_revision.lib.php
new file mode 100644
index 0000000..939c84f
--- /dev/null
+++ b/phpmyadmin/libraries/display_git_revision.lib.php
@@ -0,0 +1,83 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * Displays form for password change
+ *
+ * @package PhpMyAdmin
+ */
+if (! defined('PHPMYADMIN')) {
+    exit;
+}
+
+/**
+* Prints details about the current Git commit revision
+*
+* @return void
+*/
+function PMA_printGitRevision()
+{
+    if (! $GLOBALS['PMA_Config']->get('PMA_VERSION_GIT')) {
+        $response = PMA_Response::getInstance();
+        $response->isSuccess(false);
+        return;
+    }
+
+    // load revision data from repo
+    $GLOBALS['PMA_Config']->checkGitRevision();
+
+    // if using a remote commit fast-forwarded, link to Github
+    $commit_hash = substr(
+        $GLOBALS['PMA_Config']->get('PMA_VERSION_GIT_COMMITHASH'),
+        0,
+        7
+    );
+    $commit_hash = '<strong title="'
+        . htmlspecialchars($GLOBALS['PMA_Config']->get('PMA_VERSION_GIT_MESSAGE'))
+        . '">' . $commit_hash . '</strong>';
+    if ($GLOBALS['PMA_Config']->get('PMA_VERSION_GIT_ISREMOTECOMMIT')) {
+        $commit_hash = '<a href="'
+            . PMA_linkURL(
+                'https://github.com/phpmyadmin/phpmyadmin/commit/'
+                . $GLOBALS['PMA_Config']->get('PMA_VERSION_GIT_COMMITHASH')
+            )
+            . '" target="_blank">' . $commit_hash . '</a>';
+    }
+
+    $branch = $GLOBALS['PMA_Config']->get('PMA_VERSION_GIT_BRANCH');
+    if ($GLOBALS['PMA_Config']->get('PMA_VERSION_GIT_ISREMOTEBRANCH')) {
+        $branch = '<a href="'
+            . PMA_linkURL(
+                'https://github.com/phpmyadmin/phpmyadmin/tree/'
+                . $GLOBALS['PMA_Config']->get('PMA_VERSION_GIT_BRANCH')
+            )
+            . '" target="_blank">' . $branch . '</a>';
+    }
+    if ($branch !== false) {
+        $branch = sprintf(__('%1$s from %2$s branch'), $commit_hash, $branch);
+    } else {
+        $branch = $commit_hash . ' (' . __('no branch') . ')';
+    }
+
+    $committer = $GLOBALS['PMA_Config']->get('PMA_VERSION_GIT_COMMITTER');
+    $author = $GLOBALS['PMA_Config']->get('PMA_VERSION_GIT_AUTHOR');
+    PMA_printListItem(
+        __('Git revision') . ': '
+        . $branch . ',<br /> '
+        . sprintf(
+            __('committed on %1$s by %2$s'),
+            PMA_Util::localisedDate(strtotime($committer['date'])),
+            '<a href="' . PMA_linkURL('mailto:' . $committer['email']) . '">'
+            . htmlspecialchars($committer['name']) . '</a>'
+        )
+        . ($author != $committer
+            ? ', <br />'
+            . sprintf(
+                __('authored on %1$s by %2$s'),
+                PMA_Util::localisedDate(strtotime($author['date'])),
+                '<a href="' . PMA_linkURL('mailto:' . $author['email']) . '">'
+                . htmlspecialchars($author['name']) . '</a>'
+            )
+            : ''),
+        'li_pma_version_git', null, null, null
+    );
+}
diff --git a/phpmyadmin/libraries/display_import.lib.php b/phpmyadmin/libraries/display_import.lib.php
new file mode 100644
index 0000000..79149d1
--- /dev/null
+++ b/phpmyadmin/libraries/display_import.lib.php
@@ -0,0 +1,338 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ *
+ * @package PhpMyAdmin
+ */
+if (! defined('PHPMYADMIN')) {
+    exit;
+}
+
+/**
+ *
+ */
+require_once './libraries/file_listing.lib.php';
+require_once './libraries/plugin_interface.lib.php';
+require_once './libraries/display_import_ajax.lib.php';
+
+/* Scan for plugins */
+$import_list = PMA_getPlugins(
+    "import",
+    'libraries/plugins/import/',
+    $import_type
+);
+
+/* Fail if we didn't find any plugin */
+if (empty($import_list)) {
+    PMA_Message::error(
+        __(
+            'Could not load import plugins, please check your installation!'
+        )
+    )->display();
+    exit;
+}
+?>
+
+<iframe id="import_upload_iframe" name="import_upload_iframe" width="1" height="1" style="display: none;"></iframe>
+<div id="import_form_status" style="display: none;"></div>
+<div id="importmain">
+    <img src="<?php echo $GLOBALS['pmaThemeImage'];?>ajax_clock_small.gif" width="16" height="16" alt="ajax clock" style="display: none;" />
+    <script type="text/javascript">
+        //<![CDATA[
+        $( function() {
+            // add event when user click on "Go" button
+            $('#buttonGo').bind('click', function() {
+                $('#upload_form_form').css("display", "none"); // hide form
+                $('#upload_form_status').css("display", "inline"); // show progress bar
+                $('#upload_form_status_info').css("display", "inline"); // - || -
+<?php
+if ($_SESSION[$SESSION_KEY]["handler"] != "UploadNoplugin") {
+    ?>
+                var finished = false;
+                var percent  = 0.0;
+                var total    = 0;
+                var complete = 0;
+                var original_title = parent && parent.document ? parent.document.title : false;
+                var import_start;
+
+                var perform_upload = function () {
+                    new $.getJSON(
+                    'import_status.php?id=<?php echo $upload_id ; ?>&<?php echo PMA_generate_common_url(array('import_status'=>1), '&'); ?>',
+                    {},
+                    function(response) {
+                        finished = response.finished;
+                        percent = response.percent;
+                        total = response.total;
+                        complete = response.complete;
+
+                        if (total==0 && complete==0 && percent==0) {
+                            $('#upload_form_status_info').html('<img src="<?php echo $GLOBALS['pmaThemeImage'];?>ajax_clock_small.gif" width="16" height="16" alt="ajax clock" /> <?php echo PMA_jsFormat(__('The file being uploaded is probably larger than the maximum allowed size or this is a known bug in webkit based (Safari, Google Chrome, Arora etc.) browsers.'), false); ?>');
+                            $('#upload_form_status').css("display", "none");
+                        } else {
+                            var now = new Date();
+                            now = Date.UTC(
+                                now.getFullYear(), now.getMonth(), now.getDate(),
+                                now.getHours(), now.getMinutes(), now.getSeconds())
+                                + now.getMilliseconds() - 1000;
+                            var statustext = $.sprintf('<?php echo PMA_escapeJsString(__('%s of %s')); ?>',
+                                formatBytes(complete, 1, PMA_messages.strDecimalSeparator),
+                                formatBytes(total, 1, PMA_messages.strDecimalSeparator)
+                            );
+
+                            if ($('#importmain').is(':visible')) {
+                                // show progress UI
+                                $('#importmain').hide();
+                                $('#import_form_status')
+                                    .html('<div class="upload_progress"><div class="upload_progress_bar_outer"><div class="percentage"></div><div id="status" class="upload_progress_bar_inner"><div class="percentage"></div></div></div><div><img src="<?php echo $GLOBALS['pmaThemeImage'];?>ajax_clock_small.gif" width="16" height="16" alt="ajax clock" /> <?php echo PMA_jsFormat(__('Uploading your import file…'), false); ?></div><div id="statustext"></div></div>')
+                                    .show();
+                                import_start = now;
+                            }
+                            else if (percent > 9 || complete > 2000000) {
+                                // calculate estimated time
+                                var used_time = now - import_start;
+                                var seconds = parseInt(((total - complete) / complete) * used_time / 1000);
+                                var speed = $.sprintf('<?php echo PMA_jsFormat(__('%s/sec.'), false); ?>'
+                                    , formatBytes(complete / used_time * 1000, 1, PMA_messages.strDecimalSeparator));
+
+                                var minutes = parseInt(seconds / 60);
+                                seconds %= 60;
+                                var estimated_time;
+                                if (minutes > 0) {
+                                    estimated_time = '<?php echo PMA_jsFormat(__('About %MIN min. %SEC sec. remaining.'), false); ?>'
+                                        .replace('%MIN', minutes).replace('%SEC', seconds);
+                                }
+                                else {
+                                    estimated_time = '<?php echo PMA_jsFormat(__('About %SEC sec. remaining.'), false); ?>'
+                                        .replace('%SEC', seconds);
+                                }
+
+                                statustext += '<br />' + speed + '<br /><br />' + estimated_time;
+                            }
+
+                            var percent_str = Math.round(percent) + '%';
+                            $('#status').animate({width: percent_str}, 150);
+                            $('.percentage').text(percent_str);
+
+                            // show percent in window title
+                            if (original_title !== false) {
+                                parent.document.title = percent_str + ' - ' + original_title;
+                            }
+                            else {
+                                document.title = percent_str + ' - ' + original_title;
+                            }
+                            $('#statustext').html(statustext);
+                        } // else
+
+                        if (finished == true) {
+                            if (original_title !== false) {
+                                parent.document.title = original_title;
+                            }
+                            else {
+                                document.title = original_title;
+                            }
+                            $('#importmain').hide();
+                            $('#import_form_status')
+                                .html('<img src="<?php echo $GLOBALS['pmaThemeImage'];?>ajax_clock_small.gif" width="16" height="16" alt="ajax clock" /> <?php echo PMA_jsFormat(__('The file is being processed, please be patient.'), false); ?> ')
+                                .show();
+                            $('#import_form_status').load('import_status.php?message=true&<?php echo PMA_generate_common_url(array('import_status'=>1), '&'); ?>'); // loads the message, either success or mysql error
+                            <?php
+                            // reload the left sidebar when the import is finished
+                            $GLOBALS['reload'] = true;
+                            ?>
+
+                        } // if finished
+                        else {
+                            setTimeout(perform_upload, 1000);
+                        }
+                    });
+                };
+                setTimeout(perform_upload, 1000);
+
+    <?php
+} else { // no plugin available
+    ?>
+                $('#upload_form_status_info').html('<img src="<?php echo $GLOBALS['pmaThemeImage'];?>ajax_clock_small.gif" width="16" height="16" alt="ajax clock" /> <?php echo PMA_jsFormat(__('Please be patient, the file is being uploaded. Details about the upload are not available.'), false) . PMA_Util::showDocu('faq', 'faq2-9'); ?>');
+                        $('#upload_form_status').css("display", "none");
+    <?php
+} // else
+?>
+                    }); // onclick
+                }); // domready
+                //]]>
+    </script>
+    <form action="import.php" method="post" enctype="multipart/form-data"
+        name="import"<?php
+if ($_SESSION[$SESSION_KEY]["handler"] != "UploadNoplugin") {
+    echo ' target="import_upload_iframe"';
+}
+echo ' class="ajax"';
+?>>
+    <input type="hidden" name="<?php
+        echo call_user_func($_SESSION[$SESSION_KEY]['handler'] . '::getIdKey');
+    ?>" value="<?php echo $upload_id ; ?>" />
+
+    <?php
+if ($import_type == 'server') {
+    echo PMA_generate_common_hidden_inputs('', '', 1);
+} elseif ($import_type == 'database') {
+    echo PMA_generate_common_hidden_inputs($db, '', 1);
+} else {
+    echo PMA_generate_common_hidden_inputs($db, $table, 1);
+}
+echo '    <input type="hidden" name="import_type" value="' . $import_type . '" />'."\n";
+    ?>
+
+    <div class="exportoptions" id="header">
+        <h2>
+            <?php echo PMA_Util::getImage('b_import.png', __('Import')); ?>
+            <?php
+if ($import_type == 'server') {
+    echo __('Importing into the current server');
+} elseif ($import_type == 'database') {
+    printf(__('Importing into the database "%s"'), htmlspecialchars($db));
+} else {
+    printf(__('Importing into the table "%s"'), htmlspecialchars($table));
+}?>
+        </h2>
+    </div>
+
+    <div class="importoptions">
+        <h3><?php echo __('File to Import:'); ?></h3>
+        <?php
+// zip, gzip and bzip2 encode features
+$compressions = array();
+
+if ($cfg['GZipDump'] && @function_exists('gzopen')) {
+    $compressions[] = 'gzip';
+}
+if ($cfg['BZipDump'] && @function_exists('bzopen')) {
+    $compressions[] = 'bzip2';
+}
+if ($cfg['ZipDump'] && @function_exists('zip_open')) {
+    $compressions[] = 'zip';
+}
+// We don't have show anything about compression, when no supported
+if ($compressions != array()) {
+    echo '<div class="formelementrow" id="compression_info">';
+    printf(__('File may be compressed (%s) or uncompressed.'), implode(", ", $compressions));
+    echo '<br />';
+    echo __('A compressed file\'s name must end in <b>.[format].[compression]</b>. Example: <b>.sql.zip</b>');
+    echo '</div>';
+}?>
+
+        <div class="formelementrow" id="upload_form">
+        <?php
+if ($GLOBALS['is_upload'] && !empty($cfg['UploadDir'])) { ?>
+            <ul>
+            <li>
+                <input type="radio" name="file_location" id="radio_import_file" />
+                <?php
+    echo PMA_Util::getBrowseUploadFileBlock($max_upload_size);
+                ?>
+            </li>
+            <li>
+                <input type="radio" name="file_location" id="radio_local_import_file" />
+                <?php
+    echo PMA_Util::getSelectUploadFileBlock($import_list, $cfg['UploadDir']);
+                ?>
+            </li>
+            </ul>
+        <?php
+} elseif ($GLOBALS['is_upload']) {
+    $uid = uniqid('');
+    echo PMA_Util::getBrowseUploadFileBlock($max_upload_size);
+} elseif (!$GLOBALS['is_upload']) {
+    PMA_Message::notice(__('File uploads are not allowed on this server.'))->display();
+} elseif (!empty($cfg['UploadDir'])) {
+    echo PMA_Util::getSelectUploadFileBlock($import_list, $cfg['UploadDir']);
+} // end if (web-server upload directory)
+?>
+        </div>
+
+       <div class="formelementrow" id="charaset_of_file">
+        <?php // charset of file
+if ($GLOBALS['PMA_recoding_engine'] != PMA_CHARSET_NONE) {
+    echo '<label for="charset_of_file">' . __('Character set of the file:') . '</label>';
+    reset($cfg['AvailableCharsets']);
+    echo '<select id="charset_of_file" name="charset_of_file" size="1">';
+    foreach ($cfg['AvailableCharsets'] as $temp_charset) {
+        echo '<option value="' . htmlentities($temp_charset) .  '"';
+        if ((empty($cfg['Import']['charset']) && $temp_charset == 'utf-8')
+            || $temp_charset == $cfg['Import']['charset']
+        ) {
+            echo ' selected="selected"';
+        }
+        echo '>' . htmlentities($temp_charset) . '</option>';
+    }
+    echo ' </select><br />';
+} else {
+    echo '<label for="charset_of_file">' . __('Character set of the file:') . '</label>' . "\n";
+    echo PMA_generateCharsetDropdownBox(PMA_CSDROPDOWN_CHARSET, 'charset_of_file', 'charset_of_file', 'utf8', false);
+} // end if (recoding)
+        ?>
+        </div>
+    </div>
+    <div class="importoptions">
+        <h3><?php echo __('Partial Import:'); ?></h3>
+
+        <?php
+if (isset($timeout_passed) && $timeout_passed) {
+    echo '<div class="formelementrow">' . "\n";
+    echo '<input type="hidden" name="skip" value="' . $offset . '" />';
+    echo sprintf(__('Previous import timed out, after resubmitting will continue from position %d.'), $offset) . '';
+    echo '</div>' . "\n";
+}
+        ?>
+        <div class="formelementrow">
+            <input type="checkbox" name="allow_interrupt" value="yes"
+                   id="checkbox_allow_interrupt" <?php echo PMA_pluginCheckboxCheck('Import', 'allow_interrupt'); ?>/>
+            <label for="checkbox_allow_interrupt"><?php echo __('Allow the interruption of an import in case the script detects it is close to the PHP timeout limit. <i>(This might be a good way to import large files, however it can break transactions.)</i>'); ?></label><br />
+        </div>
+
+        <?php
+if (! (isset($timeout_passed) && $timeout_passed)) {
+        ?>
+        <div class="formelementrow">
+            <label for="text_skip_queries"><?php echo __('Number of rows to skip, starting from the first row:'); ?></label>
+            <input type="text" name="skip_queries" value="<?php echo PMA_pluginGetDefault('Import', 'skip_queries');?>" id="text_skip_queries" />
+        </div>
+            <?php
+} else {
+    // If timeout has passed,
+    // do not show the Skip dialog to avoid the risk of someone
+    // entering a value here that would interfere with "skip"
+    ?>
+        <input type="hidden" name="skip_queries" value="<?php echo PMA_pluginGetDefault('Import', 'skip_queries');?>" id="text_skip_queries" />
+            <?php
+}
+        ?>
+    </div>
+
+    <div class="importoptions">
+        <h3><?php echo __('Format:'); ?></h3>
+        <?php echo PMA_pluginGetChoice('Import', 'format', $import_list); ?>
+        <div id="import_notification"></div>
+    </div>
+
+    <div class="importoptions" id="format_specific_opts">
+        <h3><?php echo __('Format-Specific Options:'); ?></h3>
+        <p class="no_js_msg" id="scroll_to_options_msg">Scroll down to fill in the options for the selected format and ignore the options for other formats.</p>
+        <?php echo PMA_pluginGetOptions('Import', $import_list); ?>
+    </div>
+        <div class="clearfloat"></div>
+    <?php
+// Encoding setting form appended by Y.Kawada
+if (function_exists('PMA_set_enc_form')) { ?>
+        <div class="importoptions" id="kanji_encoding">
+            <h3><?php echo __('Encoding Conversion:'); ?></h3>
+            <?php echo PMA_set_enc_form('            '); ?>
+        </div>
+    <?php
+}
+echo "\n";
+    ?>
+    <div class="importoptions" id="submit">
+        <input type="submit" value="<?php echo __('Go'); ?>" id="buttonGo" />
+    </div>
+</form>
+</div>
diff --git a/phpmyadmin/libraries/display_import_ajax.lib.php b/phpmyadmin/libraries/display_import_ajax.lib.php
new file mode 100644
index 0000000..f8e9173
--- /dev/null
+++ b/phpmyadmin/libraries/display_import_ajax.lib.php
@@ -0,0 +1,132 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+* Handles plugins that show the upload progress
+*
+* @package PhpMyAdmin
+*/
+if (! defined('PHPMYADMIN')) {
+    exit;
+}
+
+/**
+  * constant for differenciating array in $_SESSION variable
+  */
+$SESSION_KEY = '__upload_status';
+
+/**
+  * sets default plugin for handling the import process
+  */
+$_SESSION[$SESSION_KEY]["handler"] = "";
+
+/**
+  * unique ID for each upload
+  */
+$upload_id = uniqid("");
+
+/**
+  * list of available plugins
+  *
+  * Each plugin has own checkfunction in display_import_ajax.lib.php
+  * and own file with functions in upload_#KEY#.php
+  */
+$plugins = array(
+   // PHP 5.4 session-based upload progress is problematic, see bug 3964
+   //"session",
+   "progress",
+   "apc",
+   "noplugin"
+);
+
+// select available plugin
+foreach ($plugins as $plugin) {
+    $check = "PMA_import_" . $plugin . "Check";
+
+    if ($check()) {
+        $upload_class = "Upload" . ucwords($plugin);
+        $_SESSION[$SESSION_KEY]["handler"] = $upload_class;
+        include_once "plugins/import/upload/" . $upload_class . ".class.php";
+        break;
+    }
+}
+
+/**
+  * Checks if APC bar extension is available and configured correctly.
+  *
+  * @return boolean true if APC extension is available and if rfc1867 is enabled,
+  *                      false if it is not
+  */
+function PMA_import_apcCheck()
+{
+    if (! extension_loaded('apc')
+        || ! function_exists('apc_fetch')
+        || ! function_exists('getallheaders')
+    ) {
+        return false;
+    }
+    return (ini_get('apc.enabled') && ini_get('apc.rfc1867'));
+}
+
+/**
+  * Checks if UploadProgress bar extension is available.
+  *
+  * @return boolean true if UploadProgress extension is available,
+  *                 false if it is not
+  */
+function PMA_import_progressCheck()
+{
+    if (! function_exists("uploadprogress_get_info")
+        || ! function_exists('getallheaders')
+    ) {
+        return false;
+    }
+    return true;
+}
+
+/**
+  * Checks if PHP 5.4 session upload-progress feature is available.
+  *
+  * @return boolean true if PHP 5.4 session upload-progress is available,
+  *                 false if it is not
+  */
+function PMA_import_sessionCheck()
+{
+    if (PMA_PHP_INT_VERSION < 50400
+        || ! ini_get('session.upload_progress.enabled')
+    ) {
+        return false;
+    }
+    return true;
+}
+
+/**
+  * Default plugin for handling import.
+  * If no other plugin is available, noplugin is used.
+  *
+  * @return boolean true
+  */
+function PMA_import_nopluginCheck()
+{
+    return true;
+}
+
+/**
+  * The function outputs json encoded status of uploaded.
+  * It uses PMA_getUploadStatus, which is defined in plugin's file.
+  *
+  * @param string $id ID of transfer, usually $upload_id
+  *                   from display_import_ajax.lib.php
+  *
+  * @return void
+  */
+function PMA_importAjaxStatus($id)
+{
+    header('Content-type: application/json');
+    echo json_encode(
+        call_user_func(
+            $_SESSION[$GLOBALS['SESSION_KEY']]['handler'] . '::getUploadStatus',
+            $id
+        )
+    );
+}
+?>
diff --git a/phpmyadmin/libraries/display_select_lang.lib.php b/phpmyadmin/libraries/display_select_lang.lib.php
new file mode 100644
index 0000000..41a9098
--- /dev/null
+++ b/phpmyadmin/libraries/display_select_lang.lib.php
@@ -0,0 +1,98 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * Code for displaying language selection
+ *
+ * @package PhpMyAdmin
+ */
+if (! defined('PHPMYADMIN')) {
+    exit;
+}
+
+/**
+ * Compares the names of two languages.
+ * Used by uasort in PMA_getLanguageSelectorHtml()
+ *
+ * @param array $a The first language being compared
+ * @param array $b The second language being compared
+ *
+ * @return the sorted array
+ */
+function PMA_languageCmp($a, $b)
+{
+    return strcmp($a[1], $b[1]);
+}
+
+/**
+ * Returns HTML code for the language selector
+ *
+ * @param boolean $use_fieldset whether to use fieldset for selection
+ * @param boolean $show_doc     whether to show documentation links
+ *
+ * @return string
+ *
+ * @access  public
+ */
+function PMA_getLanguageSelectorHtml($use_fieldset = false, $show_doc = true)
+{
+    global $lang;
+
+    $retval = '';
+
+    // Display language selection only if there
+    // is more than one language to choose from
+    if (count($GLOBALS['available_languages']) > 1) {
+        $retval .= '<form method="get" action="index.php" class="disableAjax">';
+
+        $_form_params = array(
+            'db' => $GLOBALS['db'],
+            'table' => $GLOBALS['table'],
+        );
+        $retval .= PMA_generate_common_hidden_inputs($_form_params);
+
+        // For non-English, display "Language" with emphasis because it's
+        // not a proper word in the current language; we show it to help
+        // people recognize the dialog
+        $language_title = __('Language')
+            . (__('Language') != 'Language' ? ' - <em>Language</em>' : '');
+        if ($show_doc) {
+            $language_title .= PMA_Util::showDocu('faq', 'faq7-2');
+        }
+        if ($use_fieldset) {
+            $retval .= '<fieldset><legend lang="en" dir="ltr">'
+                . $language_title . '</legend>';
+        } else {
+            $retval .= '<bdo lang="en" dir="ltr"><label for="sel-lang">'
+                . $language_title . ': </label></bdo>';
+        }
+
+        $retval .= '<select name="lang" class="autosubmit" lang="en"'
+            . ' dir="ltr" id="sel-lang">';
+
+        uasort($GLOBALS['available_languages'], 'PMA_languageCmp');
+        foreach ($GLOBALS['available_languages'] as $id => $tmplang) {
+            $lang_name = PMA_langName($tmplang);
+
+            //Is current one active?
+            if ($lang == $id) {
+                $selected = ' selected="selected"';
+            } else {
+                $selected = '';
+            }
+            $retval .= '<option value="' . $id . '"' . $selected . '>';
+            $retval .= $lang_name;
+            $retval .= '</option>';
+        }
+
+        $retval .= '</select>';
+
+        if ($use_fieldset) {
+            $retval .= '</fieldset>';
+        }
+
+        $retval .= '</form>';
+    }
+    return $retval;
+}
+
+?>
diff --git a/phpmyadmin/libraries/engines/bdb.lib.php b/phpmyadmin/libraries/engines/bdb.lib.php
new file mode 100644
index 0000000..91a56bb
--- /dev/null
+++ b/phpmyadmin/libraries/engines/bdb.lib.php
@@ -0,0 +1,84 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * @package PhpMyAdmin-Engines
+ */
+if (! defined('PHPMYADMIN')) {
+    exit;
+}
+
+/**
+ *
+ * @package PhpMyAdmin-Engines
+ */
+class PMA_StorageEngine_bdb extends PMA_StorageEngine
+{
+    /**
+     * Returns array with variable names related to this storage engine
+     *
+     * @return array   variable names
+     */
+    function getVariables()
+    {
+        return array(
+            'version_bdb' => array(
+                'title' => __('Version information'),
+            ),
+            'bdb_cache_size' => array(
+                'type'  => PMA_ENGINE_DETAILS_TYPE_SIZE,
+            ),
+            'bdb_home' => array(
+            ),
+            'bdb_log_buffer_size' => array(
+                'type'  => PMA_ENGINE_DETAILS_TYPE_SIZE,
+            ),
+            'bdb_logdir' => array(
+            ),
+            'bdb_max_lock' => array(
+                'type'  => PMA_ENGINE_DETAILS_TYPE_NUMERIC,
+            ),
+            'bdb_shared_data' => array(
+            ),
+            'bdb_tmpdir' => array(
+            ),
+            'bdb_data_direct' => array(
+            ),
+            'bdb_lock_detect' => array(
+            ),
+            'bdb_log_direct' => array(
+            ),
+            'bdb_no_recover' => array(
+            ),
+            'bdb_no_sync' => array(
+            ),
+            'skip_sync_bdb_logs' => array(
+            ),
+            'sync_bdb_logs' => array(
+            ),
+        );
+    }
+
+    /**
+     * Returns the pattern to be used in the query for SQL variables
+     * related to this storage engine
+     *
+     * @return string LIKE pattern
+     */
+    function getVariablesLikePattern()
+    {
+        return '%bdb%';
+    }
+
+    /**
+     * returns string with filename for the MySQL helppage
+     * about this storage engine
+     *
+     * @return string  mysql helppage filename
+     */
+    function getMysqlHelpPage()
+    {
+        return 'bdb';
+    }
+}
+
+?>
diff --git a/phpmyadmin/libraries/engines/berkeleydb.lib.php b/phpmyadmin/libraries/engines/berkeleydb.lib.php
new file mode 100644
index 0000000..d5324b1
--- /dev/null
+++ b/phpmyadmin/libraries/engines/berkeleydb.lib.php
@@ -0,0 +1,24 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * @package PhpMyAdmin-Engines
+ */
+if (! defined('PHPMYADMIN')) {
+    exit;
+}
+
+/**
+ * Load BDB class.
+ */
+require_once './libraries/engines/bdb.lib.php';
+
+/**
+ * This is same as BDB
+ *
+ * @package PhpMyAdmin-Engines
+ */
+class PMA_StorageEngine_berkeleydb extends PMA_StorageEngine_bdb
+{
+}
+
+?>
diff --git a/phpmyadmin/libraries/engines/binlog.lib.php b/phpmyadmin/libraries/engines/binlog.lib.php
new file mode 100644
index 0000000..ea81738
--- /dev/null
+++ b/phpmyadmin/libraries/engines/binlog.lib.php
@@ -0,0 +1,28 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * @package PhpMyAdmin-Engines
+ */
+if (! defined('PHPMYADMIN')) {
+    exit;
+}
+
+/**
+ *
+ * @package PhpMyAdmin-Engines
+ */
+class PMA_StorageEngine_binlog extends PMA_StorageEngine
+{
+    /**
+     * returns string with filename for the MySQL helppage
+     * about this storage engine
+     *
+     * @return string  mysql helppage filename
+     */
+    function getMysqlHelpPage()
+    {
+        return 'binary-log';
+    }
+}
+
+?>
diff --git a/phpmyadmin/libraries/engines/innobase.lib.php b/phpmyadmin/libraries/engines/innobase.lib.php
new file mode 100644
index 0000000..f81ae3f
--- /dev/null
+++ b/phpmyadmin/libraries/engines/innobase.lib.php
@@ -0,0 +1,23 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ *
+ * @package PhpMyAdmin-Engines
+ */
+if (! defined('PHPMYADMIN')) {
+    exit;
+}
+
+/**
+ *
+ */
+require_once './libraries/engines/innodb.lib.php';
+
+/**
+ *
+ * @package PhpMyAdmin-Engines
+ */
+class PMA_StorageEngine_innobase extends PMA_StorageEngine_innodb
+{
+}
+?>
diff --git a/phpmyadmin/libraries/engines/innodb.lib.php b/phpmyadmin/libraries/engines/innodb.lib.php
new file mode 100644
index 0000000..b0eec39
--- /dev/null
+++ b/phpmyadmin/libraries/engines/innodb.lib.php
@@ -0,0 +1,411 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * The InnoDB storage engine
+ *
+ * @package PhpMyAdmin-Engines
+ */
+if (! defined('PHPMYADMIN')) {
+    exit;
+}
+
+/**
+ * The InnoDB storage engine
+ *
+ * @package PhpMyAdmin-Engines
+ */
+class PMA_StorageEngine_innodb extends PMA_StorageEngine
+{
+    /**
+     * Returns array with variable names related to InnoDB storage engine
+     *
+     * @return array   variable names
+     */
+    function getVariables()
+    {
+        return array(
+            'innodb_data_home_dir' => array(
+                'title' => __('Data home directory'),
+                'desc'  => __('The common part of the directory path for all InnoDB data files.'),
+            ),
+            'innodb_data_file_path' => array(
+                'title' => __('Data files'),
+            ),
+            'innodb_autoextend_increment' => array(
+                'title' => __('Autoextend increment'),
+                'desc'  => __('The increment size for extending the size of an autoextending tablespace when it becomes full.'),
+                'type'  => PMA_ENGINE_DETAILS_TYPE_NUMERIC,
+            ),
+            'innodb_buffer_pool_size' => array(
+                'title' => __('Buffer pool size'),
+                'desc'  => __('The size of the memory buffer InnoDB uses to cache data and indexes of its tables.'),
+                'type'  => PMA_ENGINE_DETAILS_TYPE_SIZE,
+            ),
+            'innodb_additional_mem_pool_size' => array(
+                'title' => 'innodb_additional_mem_pool_size',
+                'type'  => PMA_ENGINE_DETAILS_TYPE_SIZE,
+            ),
+            'innodb_buffer_pool_awe_mem_mb' => array(
+                'type'  => PMA_ENGINE_DETAILS_TYPE_SIZE,
+            ),
+            'innodb_checksums' => array(
+            ),
+            'innodb_commit_concurrency' => array(
+            ),
+            'innodb_concurrency_tickets' => array(
+                'type'  => PMA_ENGINE_DETAILS_TYPE_NUMERIC,
+            ),
+            'innodb_doublewrite' => array(
+            ),
+            'innodb_fast_shutdown' => array(
+            ),
+            'innodb_file_io_threads' => array(
+                'type'  => PMA_ENGINE_DETAILS_TYPE_NUMERIC,
+            ),
+            'innodb_file_per_table' => array(
+            ),
+            'innodb_flush_log_at_trx_commit' => array(
+            ),
+            'innodb_flush_method' => array(
+            ),
+            'innodb_force_recovery' => array(
+            ),
+            'innodb_lock_wait_timeout' => array(
+                'type'  => PMA_ENGINE_DETAILS_TYPE_NUMERIC,
+            ),
+            'innodb_locks_unsafe_for_binlog' => array(
+            ),
+            'innodb_log_arch_dir' => array(
+            ),
+            'innodb_log_archive' => array(
+            ),
+            'innodb_log_buffer_size' => array(
+                'type'  => PMA_ENGINE_DETAILS_TYPE_SIZE,
+            ),
+            'innodb_log_file_size' => array(
+                'type'  => PMA_ENGINE_DETAILS_TYPE_SIZE,
+            ),
+            'innodb_log_files_in_group' => array(
+                'type'  => PMA_ENGINE_DETAILS_TYPE_NUMERIC,
+            ),
+            'innodb_log_group_home_dir' => array(
+            ),
+            'innodb_max_dirty_pages_pct' => array(
+                'type'  => PMA_ENGINE_DETAILS_TYPE_NUMERIC,
+            ),
+            'innodb_max_purge_lag' => array(
+            ),
+            'innodb_mirrored_log_groups' => array(
+                'type'  => PMA_ENGINE_DETAILS_TYPE_NUMERIC,
+            ),
+            'innodb_open_files' => array(
+                'type'  => PMA_ENGINE_DETAILS_TYPE_NUMERIC,
+            ),
+            'innodb_support_xa' => array(
+            ),
+            'innodb_sync_spin_loops' => array(
+                'type'  => PMA_ENGINE_DETAILS_TYPE_NUMERIC,
+            ),
+            'innodb_table_locks' => array(
+                'type'  => PMA_ENGINE_DETAILS_TYPE_BOOLEAN,
+            ),
+            'innodb_thread_concurrency' => array(
+                'type'  => PMA_ENGINE_DETAILS_TYPE_NUMERIC,
+            ),
+            'innodb_thread_sleep_delay' => array(
+                'type'  => PMA_ENGINE_DETAILS_TYPE_NUMERIC,
+            ),
+         );
+    }
+
+    /**
+     * Returns the pattern to be used in the query for SQL variables
+     * related to InnoDb storage engine
+     *
+     * @return string  SQL query LIKE pattern
+     */
+    function getVariablesLikePattern()
+    {
+        return 'innodb\\_%';
+    }
+
+    /**
+     * Get information pages
+     *
+     * @return array detail pages
+     */
+    function getInfoPages()
+    {
+        if ($this->support < PMA_ENGINE_SUPPORT_YES) {
+            return array();
+        }
+        $pages = array();
+        $pages['Bufferpool'] = __('Buffer Pool');
+        $pages['Status'] = __('InnoDB Status');
+        return $pages;
+    }
+
+    /**
+     * returns html tables with stats over inno db buffer pool
+     *
+     * @return string  html table with stats
+     */
+    function getPageBufferpool()
+    {
+        // The following query is only possible because we know
+        // that we are on MySQL 5 here (checked above)!
+        // side note: I love MySQL 5 for this. :-)
+        $sql = '
+             SHOW STATUS
+            WHERE Variable_name LIKE \'Innodb\\_buffer\\_pool\\_%\'
+               OR Variable_name = \'Innodb_page_size\';';
+        $status = PMA_DBI_fetch_result($sql, 0, 1);
+
+        $output = '<table class="data" id="table_innodb_bufferpool_usage">' . "\n"
+            . '    <caption class="tblHeaders">' . "\n"
+            . '        ' . __('Buffer Pool Usage') . "\n"
+            . '    </caption>' . "\n"
+            . '    <tfoot>' . "\n"
+            . '        <tr>' . "\n"
+            . '            <th colspan="2">' . "\n"
+            . '                ' . __('Total') . "\n"
+            . '                : '
+            . PMA_Util::formatNumber(
+                $status['Innodb_buffer_pool_pages_total'], 0
+            )
+            . ' ' . __('pages')
+            . ' / '
+            . join(
+                ' ',
+                PMA_Util::formatByteDown(
+                    $status['Innodb_buffer_pool_pages_total']
+                    * $status['Innodb_page_size']
+                )
+            ) . "\n"
+            . '            </th>' . "\n"
+            . '        </tr>' . "\n"
+            . '    </tfoot>' . "\n"
+            . '    <tbody>' . "\n"
+            . '        <tr class="odd">' . "\n"
+            . '            <th>' . __('Free pages') . '</th>' . "\n"
+            . '            <td class="value">'
+            . PMA_Util::formatNumber(
+                $status['Innodb_buffer_pool_pages_free'], 0
+            )
+            . '</td>' . "\n"
+            . '        </tr>' . "\n"
+            . '        <tr class="even">' . "\n"
+            . '            <th>' . __('Dirty pages') . '</th>' . "\n"
+            . '            <td class="value">'
+            . PMA_Util::formatNumber(
+                $status['Innodb_buffer_pool_pages_dirty'], 0
+            )
+            . '</td>' . "\n"
+            . '        </tr>' . "\n"
+            . '        <tr class="odd">' . "\n"
+            . '            <th>' . __('Pages containing data') . '</th>' . "\n"
+            . '            <td class="value">'
+            . PMA_Util::formatNumber(
+                $status['Innodb_buffer_pool_pages_data'], 0
+            ) . "\n"
+            . '</td>' . "\n"
+            . '        </tr>' . "\n"
+            . '        <tr class="even">' . "\n"
+            . '            <th>' . __('Pages to be flushed') . '</th>' . "\n"
+            . '            <td class="value">'
+            . PMA_Util::formatNumber(
+                $status['Innodb_buffer_pool_pages_flushed'], 0
+            ) . "\n"
+            . '</td>' . "\n"
+            . '        </tr>' . "\n"
+            . '        <tr class="odd">' . "\n"
+            . '            <th>' . __('Busy pages') . '</th>' . "\n"
+            . '            <td class="value">'
+            . PMA_Util::formatNumber(
+                $status['Innodb_buffer_pool_pages_misc'], 0
+            ) . "\n"
+            . '</td>' . "\n"
+            . '        </tr>';
+
+        // not present at least since MySQL 5.1.40
+        if (isset($status['Innodb_buffer_pool_pages_latched'])) {
+            $output .= '        <tr class="even">'
+            . '            <th>' . __('Latched pages') . '</th>'
+            . '            <td class="value">'
+            . PMA_Util::formatNumber(
+                $status['Innodb_buffer_pool_pages_latched'], 0
+            )
+            . '</td>'
+            . '        </tr>';
+        }
+
+        $output .= '    </tbody>' . "\n"
+            . '</table>' . "\n\n"
+            . '<table class="data" id="table_innodb_bufferpool_activity">' . "\n"
+            . '    <caption class="tblHeaders">' . "\n"
+            . '        ' . __('Buffer Pool Activity') . "\n"
+            . '    </caption>' . "\n"
+            . '    <tbody>' . "\n"
+            . '        <tr class="odd">' . "\n"
+            . '            <th>' . __('Read requests') . '</th>' . "\n"
+            . '            <td class="value">'
+            . PMA_Util::formatNumber(
+                $status['Innodb_buffer_pool_read_requests'], 0
+            ) . "\n"
+            . '</td>' . "\n"
+            . '        </tr>' . "\n"
+            . '        <tr class="even">' . "\n"
+            . '            <th>' . __('Write requests') . '</th>' . "\n"
+            . '            <td class="value">'
+            . PMA_Util::formatNumber(
+                $status['Innodb_buffer_pool_write_requests'], 0
+            ) . "\n"
+            . '</td>' . "\n"
+            . '        </tr>' . "\n"
+            . '        <tr class="odd">' . "\n"
+            . '            <th>' . __('Read misses') . '</th>' . "\n"
+            . '            <td class="value">'
+            . PMA_Util::formatNumber(
+                $status['Innodb_buffer_pool_reads'], 0
+            ) . "\n"
+            . '</td>' . "\n"
+            . '        </tr>' . "\n"
+            . '        <tr class="even">' . "\n"
+            . '            <th>' . __('Write waits') . '</th>' . "\n"
+            . '            <td class="value">'
+            . PMA_Util::formatNumber(
+                $status['Innodb_buffer_pool_wait_free'], 0
+            ) . "\n"
+            . '</td>' . "\n"
+            . '        </tr>' . "\n"
+            . '        <tr class="odd">' . "\n"
+            . '            <th>' . __('Read misses in %') . '</th>' . "\n"
+            . '            <td class="value">'
+            . ($status['Innodb_buffer_pool_read_requests'] == 0
+                ? '---'
+                : htmlspecialchars(
+                    PMA_Util::formatNumber(
+                        $status['Innodb_buffer_pool_reads'] * 100
+                        / $status['Innodb_buffer_pool_read_requests'],
+                        3,
+                        2
+                    )
+                ) . ' %') . "\n"
+            . '</td>' . "\n"
+            . '        </tr>' . "\n"
+            . '        <tr class="even">' . "\n"
+            . '            <th>' . __('Write waits in %') . '</th>' . "\n"
+            . '            <td class="value">'
+            . ($status['Innodb_buffer_pool_write_requests'] == 0
+                ? '---'
+                : htmlspecialchars(
+                    PMA_Util::formatNumber(
+                        $status['Innodb_buffer_pool_wait_free'] * 100
+                        / $status['Innodb_buffer_pool_write_requests'],
+                        3,
+                        2
+                    )
+                ) . ' %') . "\n"
+            . '</td>' . "\n"
+            . '        </tr>' . "\n"
+            . '    </tbody>' . "\n"
+            . '</table>' . "\n";
+        return $output;
+    }
+
+    /**
+     * returns InnoDB status
+     *
+     * @return string  result of SHOW INNODB STATUS inside pre tags
+     */
+    function getPageStatus()
+    {
+        return '<pre id="pre_innodb_status">' . "\n"
+            . htmlspecialchars(
+                PMA_DBI_fetch_value('SHOW INNODB STATUS;', 0, 'Status')
+            ) . "\n"
+            . '</pre>' . "\n";
+    }
+
+    /**
+     * Returns content for page $id
+     *
+     * @param string $id page id
+     *
+     * @return string html output
+     */
+    function getPage($id)
+    {
+        if (! array_key_exists($id, $this->getInfoPages())) {
+            return false;
+        }
+
+        $id = 'getPage' . $id;
+
+        return $this->$id();
+    }
+
+    /**
+     * returns string with filename for the MySQL helppage
+     * about this storage engine
+     *
+     * @return string  mysql helppage filename
+     */
+    function getMysqlHelpPage()
+    {
+        return 'innodb-storage-engine';
+    }
+
+    /**
+     * Gets the InnoDB plugin version number
+     *
+     * http://www.innodb.com/products/innodb_plugin
+     * (do not confuse this with phpMyAdmin's storage engine plugins!)
+     *
+     * @return string the version number, or empty if not running as a plugin
+     */
+    function getInnodbPluginVersion()
+    {
+        return PMA_DBI_fetch_value('SELECT @@innodb_version;');
+    }
+
+    /**
+     * Gets the InnoDB file format
+     *
+     * (works only for the InnoDB plugin)
+     * http://www.innodb.com/products/innodb_plugin
+     * (do not confuse this with phpMyAdmin's storage engine plugins!)
+     *
+     * @return string the InnoDB file format
+     */
+    function getInnodbFileFormat()
+    {
+        return PMA_DBI_fetch_value(
+            "SHOW GLOBAL VARIABLES LIKE 'innodb_file_format';", 0, 1
+        );
+    }
+
+    /**
+     * Verifies if this server supports the innodb_file_per_table feature
+     *
+     * (works only for the InnoDB plugin)
+     * http://www.innodb.com/products/innodb_plugin
+     * (do not confuse this with phpMyAdmin's storage engine plugins!)
+     *
+     * @return boolean whether this feature is supported or not
+     */
+    function supportsFilePerTable()
+    {
+        $innodb_file_per_table = PMA_DBI_fetch_value(
+            "SHOW GLOBAL VARIABLES LIKE 'innodb_file_per_table';", 0, 1
+        );
+        if ($innodb_file_per_table == 'ON') {
+            return true;
+        } else {
+            return false;
+        }
+
+    }
+}
+
+?>
diff --git a/phpmyadmin/libraries/engines/memory.lib.php b/phpmyadmin/libraries/engines/memory.lib.php
new file mode 100644
index 0000000..8e9fe5f
--- /dev/null
+++ b/phpmyadmin/libraries/engines/memory.lib.php
@@ -0,0 +1,34 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * The MEMORY (HEAP) storage engine
+ *
+ * @package PhpMyAdmin-Engines
+ */
+if (! defined('PHPMYADMIN')) {
+    exit;
+}
+
+/**
+ * The MEMORY (HEAP) storage engine
+ *
+ * @package PhpMyAdmin-Engines
+ */
+class PMA_StorageEngine_memory extends PMA_StorageEngine
+{
+    /**
+     * Returns array with variable names dedicated to MEMORY storage engine
+     *
+     * @return array   variable names
+     */
+    function getVariables()
+    {
+        return array(
+            'max_heap_table_size' => array(
+                'type'  => PMA_ENGINE_DETAILS_TYPE_SIZE,
+            ),
+        );
+    }
+}
+
+?>
diff --git a/phpmyadmin/libraries/engines/merge.lib.php b/phpmyadmin/libraries/engines/merge.lib.php
new file mode 100644
index 0000000..4bccfc7
--- /dev/null
+++ b/phpmyadmin/libraries/engines/merge.lib.php
@@ -0,0 +1,21 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * The MERGE storage engine
+ *
+ * @package PhpMyAdmin-Engines
+ */
+if (! defined('PHPMYADMIN')) {
+    exit;
+}
+
+/**
+ * The MERGE storage engine
+ *
+ * @package PhpMyAdmin-Engines
+ */
+class PMA_StorageEngine_merge extends PMA_StorageEngine
+{
+}
+
+?>
diff --git a/phpmyadmin/libraries/engines/mrg_myisam.lib.php b/phpmyadmin/libraries/engines/mrg_myisam.lib.php
new file mode 100644
index 0000000..d342536
--- /dev/null
+++ b/phpmyadmin/libraries/engines/mrg_myisam.lib.php
@@ -0,0 +1,33 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * @package PhpMyAdmin-Engines
+ */
+if (! defined('PHPMYADMIN')) {
+    exit;
+}
+
+/**
+ *
+ */
+require_once './libraries/engines/merge.lib.php';
+
+/**
+ *
+ * @package PhpMyAdmin-Engines
+ */
+class PMA_StorageEngine_mrg_myisam extends PMA_StorageEngine_merge
+{
+    /**
+     * returns string with filename for the MySQL helppage
+     * about this storage engine
+     *
+     * @return string  mysql helppage filename
+     */
+    function getMysqlHelpPage()
+    {
+        return 'merge-storage-engine';
+    }
+}
+
+?>
diff --git a/phpmyadmin/libraries/engines/myisam.lib.php b/phpmyadmin/libraries/engines/myisam.lib.php
new file mode 100644
index 0000000..5882824
--- /dev/null
+++ b/phpmyadmin/libraries/engines/myisam.lib.php
@@ -0,0 +1,69 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * The MyISAM storage engine
+ *
+ * @package PhpMyAdmin-Engines
+ */
+if (! defined('PHPMYADMIN')) {
+    exit;
+}
+
+/**
+ * The MyISAM storage engine
+ *
+ * @package PhpMyAdmin-Engines
+ */
+class PMA_StorageEngine_myisam extends PMA_StorageEngine
+{
+    /**
+     * Returns array with variable names dedicated to MyISAM storage engine
+     *
+     * @return array   variable names
+     */
+    function getVariables()
+    {
+        return array(
+            'myisam_data_pointer_size' => array(
+                'title' => __('Data pointer size'),
+                'desc'  => __('The default pointer size in bytes, to be used by CREATE TABLE for MyISAM tables when no MAX_ROWS option is specified.'),
+                'type'  => PMA_ENGINE_DETAILS_TYPE_SIZE,
+            ),
+            'myisam_recover_options' => array(
+                'title' => __('Automatic recovery mode'),
+                'desc'  => __('The mode for automatic recovery of crashed MyISAM tables, as set via the --myisam-recover server startup option.'),
+            ),
+            'myisam_max_sort_file_size' => array(
+                'title' => __('Maximum size for temporary sort files'),
+                'desc'  => __('The maximum size of the temporary file MySQL is allowed to use while re-creating a MyISAM index (during REPAIR TABLE, ALTER TABLE, or LOAD DATA INFILE).'),
+                'type'  => PMA_ENGINE_DETAILS_TYPE_SIZE,
+            ),
+            'myisam_max_extra_sort_file_size' => array(
+                'title' => __('Maximum size for temporary files on index creation'),
+                'desc'  => __('If the temporary file used for fast MyISAM index creation would be larger than using the key cache by the amount specified here, prefer the key cache method.'),
+                'type'  => PMA_ENGINE_DETAILS_TYPE_SIZE,
+            ),
+            'myisam_repair_threads' => array(
+                'title' => __('Repair threads'),
+                'desc'  => __('If this value is greater than 1, MyISAM table indexes are created in parallel (each index in its own thread) during the repair by sorting process.'),
+                'type'  => PMA_ENGINE_DETAILS_TYPE_NUMERIC,
+            ),
+            'myisam_sort_buffer_size' => array(
+                'title' => __('Sort buffer size'),
+                'desc'  => __('The buffer that is allocated when sorting MyISAM indexes during a REPAIR TABLE or when creating indexes with CREATE INDEX or ALTER TABLE.'),
+                'type'  => PMA_ENGINE_DETAILS_TYPE_SIZE,
+            ),
+            'myisam_stats_method' => array(
+            ),
+            'delay_key_write' => array(
+            ),
+            'bulk_insert_buffer_size' => array(
+                'type'  => PMA_ENGINE_DETAILS_TYPE_SIZE,
+            ),
+            'skip_external_locking' => array(
+            ),
+        );
+    }
+}
+
+?>
diff --git a/phpmyadmin/libraries/engines/ndbcluster.lib.php b/phpmyadmin/libraries/engines/ndbcluster.lib.php
new file mode 100644
index 0000000..e57846b
--- /dev/null
+++ b/phpmyadmin/libraries/engines/ndbcluster.lib.php
@@ -0,0 +1,55 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * The NDBCLUSTER storage engine
+ *
+ * @package PhpMyAdmin-Engines
+ */
+if (! defined('PHPMYADMIN')) {
+    exit;
+}
+
+/**
+ * The NDBCLUSTER storage engine
+ *
+ * @package PhpMyAdmin-Engines
+ */
+class PMA_StorageEngine_ndbcluster extends PMA_StorageEngine
+{
+    /**
+     * Returns array with variable names realted to NDBCLUSTER storage engine
+     *
+     * @return array   variable names
+     */
+    function getVariables()
+    {
+        return array(
+            'ndb_connectstring' => array(
+            ),
+         );
+    }
+
+    /**
+     * Returns the pattern to be used in the query for SQL variables
+     * related to NDBCLUSTER storage engine
+     *
+     * @return string  SQL query LIKE pattern
+     */
+    function getVariablesLikePattern()
+    {
+        return 'ndb\\_%';
+    }
+
+    /**
+     * Returns string with filename for the MySQL help page
+     * about this storage engine
+     *
+     * @return string  mysql helppage filename
+     */
+    function getMysqlHelpPage()
+    {
+        return 'ndbcluster';
+    }
+}
+
+?>
diff --git a/phpmyadmin/libraries/engines/pbxt.lib.php b/phpmyadmin/libraries/engines/pbxt.lib.php
new file mode 100644
index 0000000..fc4e343
--- /dev/null
+++ b/phpmyadmin/libraries/engines/pbxt.lib.php
@@ -0,0 +1,142 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * The PBXT storage engine
+ *
+ * @package PhpMyAdmin-Engines
+ */
+if (! defined('PHPMYADMIN')) {
+    exit;
+}
+
+/**
+ * The PBXT storage engine
+ *
+ * @package PhpMyAdmin-Engines
+ */
+class PMA_StorageEngine_pbxt extends PMA_StorageEngine
+{
+    /**
+     * Returns array with variable names dedicated to PBXT storage engine
+     *
+     * @return array   variable names
+     */
+    function getVariables()
+    {
+        return array(
+            'pbxt_index_cache_size' => array(
+                'title' => __('Index cache size'),
+                'desc'  => __('This is the amount of memory allocated to the index cache. Default value is 32MB. The memory allocated here is used only for caching index pages.'),
+                'type'  => PMA_ENGINE_DETAILS_TYPE_SIZE
+            ),
+            'pbxt_record_cache_size' => array(
+                'title' => __('Record cache size'),
+                'desc'  => __('This is the amount of memory allocated to the record cache used to cache table data. The default value is 32MB. This memory is used to cache changes to the handle data (.xtd) and row pointer (.xtr) files.'),
+                'type'  => PMA_ENGINE_DETAILS_TYPE_SIZE
+            ),
+            'pbxt_log_cache_size' => array(
+                'title' => __('Log cache size'),
+                'desc'  => __('The amount of memory allocated to the transaction log cache used to cache on transaction log data. The default is 16MB.'),
+                'type'  => PMA_ENGINE_DETAILS_TYPE_SIZE
+            ),
+            'pbxt_log_file_threshold' => array(
+                'title' => __('Log file threshold'),
+                'desc'  => __('The size of a transaction log before rollover, and a new log is created. The default value is 16MB.'),
+                'type'  => PMA_ENGINE_DETAILS_TYPE_SIZE
+            ),
+            'pbxt_transaction_buffer_size' => array(
+                'title' => __('Transaction buffer size'),
+                'desc'  => __('The size of the global transaction log buffer (the engine allocates 2 buffers of this size). The default is 1MB.'),
+                'type'  => PMA_ENGINE_DETAILS_TYPE_SIZE
+            ),
+            'pbxt_checkpoint_frequency' => array(
+                'title' => __('Checkpoint frequency'),
+                'desc'  => __('The amount of data written to the transaction log before a checkpoint is performed. The default value is 24MB.'),
+                'type'  => PMA_ENGINE_DETAILS_TYPE_SIZE
+            ),
+            'pbxt_data_log_threshold' => array(
+                'title' => __('Data log threshold'),
+                'desc'  => __('The maximum size of a data log file. The default value is 64MB. PBXT can create a maximum of 32000 data logs, which are used by all tables. So the value of this variable can be increased to increase the total amount of data that can be stored in the database.'),
+                'type'  => PMA_ENGINE_DETAILS_TYPE_SIZE
+            ),
+            'pbxt_garbage_threshold' => array(
+                'title' => __('Garbage threshold'),
+                'desc'  => __('The percentage of garbage in a data log file before it is compacted. This is a value between 1 and 99. The default is 50.'),
+                'type'  => PMA_ENGINE_DETAILS_TYPE_NUMERIC
+            ),
+            'pbxt_log_buffer_size' => array(
+                'title' => __('Log buffer size'),
+                'desc'  => __('The size of the buffer used when writing a data log. The default is 256MB. The engine allocates one buffer per thread, but only if the thread is required to write a data log.'),
+                'type'  => PMA_ENGINE_DETAILS_TYPE_SIZE
+            ),
+            'pbxt_data_file_grow_size' => array(
+                'title' => __('Data file grow size'),
+                'desc'  => __('The grow size of the handle data (.xtd) files.'),
+                'type'  => PMA_ENGINE_DETAILS_TYPE_SIZE
+            ),
+            'pbxt_row_file_grow_size' => array(
+                'title' => __('Row file grow size'),
+                'desc'  => __('The grow size of the row pointer (.xtr) files.'),
+                'type'  => PMA_ENGINE_DETAILS_TYPE_SIZE
+            ),
+            'pbxt_log_file_count' => array(
+                'title' => __('Log file count'),
+                'desc'  => __('This is the number of transaction log files (pbxt/system/xlog*.xt) the system will maintain. If the number of logs exceeds this value then old logs will be deleted, otherwise they are renamed and given the next highest number.'),
+                'type'  => PMA_ENGINE_DETAILS_TYPE_NUMERIC
+            ),
+        );
+    }
+
+    /**
+     * returns the pbxt engine specific handling for
+     * PMA_ENGINE_DETAILS_TYPE_SIZE variables.
+     *
+     * @param string $formatted_size the size expression (for example 8MB)
+     *
+     * @return string the formatted value and its unit
+     */
+    function resolveTypeSize($formatted_size)
+    {
+        if (preg_match('/^[0-9]+[a-zA-Z]+$/', $formatted_size)) {
+            $value = PMA_Util::extractValueFromFormattedSize($formatted_size);
+        } else {
+            $value = $formatted_size;
+        }
+        return PMA_Util::formatByteDown($value);
+    }
+
+    //--------------------
+    function getInfoPages()
+    {
+        $pages = array();
+        $pages['Documentation'] = __('Documentation');
+        return $pages;
+    }
+
+    //--------------------
+    function getPage($id)
+    {
+        if (! array_key_exists($id, $this->getInfoPages())) {
+            return false;
+        }
+
+        $id = 'getPage' . $id;
+
+        return $this->$id();
+    }
+
+    function getPageDocumentation()
+    {
+        $output = '<p>'
+        . sprintf(__('Documentation and further information about PBXT can be found on the %sPrimeBase XT Home Page%s.'), '<a href="' . PMA_linkURL('http://www.primebase.com/xt/') . '" target="_blank">', '</a>')
+        . '</p>' . "\n"
+        . '<h3>' . __('Related Links') . '</h3>' . "\n"
+        . '<ul>' . "\n"
+        . '<li><a href="' . PMA_linkURL('http://pbxt.blogspot.com/') . '" target="_blank">' . __('The PrimeBase XT Blog by Paul McCullagh') . '</a></li>' . "\n"
+        . '</ul>' . "\n";
+
+        return $output;
+    }
+}
+
+?>
diff --git a/phpmyadmin/libraries/engines/performance_schema.lib.php b/phpmyadmin/libraries/engines/performance_schema.lib.php
new file mode 100644
index 0000000..f7664b6
--- /dev/null
+++ b/phpmyadmin/libraries/engines/performance_schema.lib.php
@@ -0,0 +1,28 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * @package PhpMyAdmin-Engines
+ */
+if (! defined('PHPMYADMIN')) {
+    exit;
+}
+
+/**
+ *
+ * @package PhpMyAdmin-Engines
+ */
+class PMA_StorageEngine_performance_schema extends PMA_StorageEngine
+{
+    /**
+     * returns string with filename for the MySQL helppage
+     * about this storage engine
+     *
+     * @return string  mysql helppage filename
+     */
+    function getMysqlHelpPage()
+    {
+        return 'performance-schema';
+    }
+}
+
+?>
diff --git a/phpmyadmin/libraries/error.inc.php b/phpmyadmin/libraries/error.inc.php
new file mode 100644
index 0000000..c48a7f1
--- /dev/null
+++ b/phpmyadmin/libraries/error.inc.php
@@ -0,0 +1,59 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * phpMyAdmin fatal error display page
+ *
+ * @package PhpMyAdmin
+ */
+
+if (! defined('PHPMYADMIN')) {
+    exit;
+}
+
+if (! defined('TESTSUITE')) {
+    header('Content-Type: text/html; charset=utf-8');
+}
+?>
+<!DOCTYPE HTML>
+<html lang="<?php echo $lang; ?>" dir="<?php echo $dir; ?>">
+<head>
+    <link rel="icon" href="favicon.ico" type="image/x-icon" />
+    <link rel="shortcut icon" href="favicon.ico" type="image/x-icon" />
+    <title>phpMyAdmin</title>
+    <meta charset="utf-8" />
+    <style type="text/css">
+    <!--
+    html {
+        padding: 0;
+        margin: 0;
+    }
+    body  {
+        font-family: sans-serif;
+        font-size: small;
+        color: #000000;
+        background-color: #F5F5F5;
+        margin: 1em;
+    }
+    h1 {
+        margin: 0;
+        padding: 0.3em;
+        font-size: 1.4em;
+        font-weight: bold;
+        color: #ffffff;
+        background-color: #ff0000;
+    }
+    p {
+        margin: 0;
+        padding: 0.5em;
+        border: 0.1em solid red;
+        background-color: #ffeeee;
+    }
+    //-->
+    </style>
+</head>
+<body>
+<h1>phpMyAdmin - <?php echo $error_header; ?></h1>
+<p><?php echo PMA_sanitize($error_message); ?></p>
+</body>
+</html>
+
diff --git a/phpmyadmin/libraries/file_listing.lib.php b/phpmyadmin/libraries/file_listing.lib.php
new file mode 100644
index 0000000..e5b680c
--- /dev/null
+++ b/phpmyadmin/libraries/file_listing.lib.php
@@ -0,0 +1,103 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * Functions for listing directories
+ *
+ * @package PhpMyAdmin
+ */
+if (! defined('PHPMYADMIN')) {
+    exit;
+}
+
+/**
+ * Returns array of filtered file names
+ *
+ * @param string $dir        directory to list
+ * @param string $expression regular expression to match files
+ *
+ * @return array   sorted file list on success, false on failure
+ */
+function PMA_getDirContent($dir, $expression = '')
+{
+    if (file_exists($dir) && $handle = @opendir($dir)) {
+        $result = array();
+        if (substr($dir, -1) != '/') {
+            $dir .= '/';
+        }
+        while ($file = @readdir($handle)) {
+            // for PHP < 5.2.4, is_file() gives a warning when using open_basedir
+            // and verifying '..' or '.'
+            if ('.' != $file
+                && '..' != $file
+                && is_file($dir . $file)
+                && ($expression == '' || preg_match($expression, $file))
+            ) {
+                $result[] = $file;
+            }
+        }
+        @closedir($handle);
+        asort($result);
+        return $result;
+    } else {
+        return false;
+    }
+}
+
+/**
+ * Returns options of filtered file names
+ *
+ * @param string $dir        directory to list
+ * @param string $extensions regullar expression to match files
+ * @param string $active     currently active choice
+ *
+ * @return array   sorted file list on success, false on failure
+ */
+function PMA_getFileSelectOptions($dir, $extensions = '', $active = '')
+{
+    $list = PMA_getDirContent($dir, $extensions);
+    if ($list === false) {
+        return false;
+    }
+    $result = '';
+    foreach ($list as $val) {
+        $result .= '<option value="'. htmlspecialchars($val) . '"';
+        if ($val == $active) {
+            $result .= ' selected="selected"';
+        }
+        $result .= '>' . htmlspecialchars($val) . '</option>' . "\n";
+    }
+    return $result;
+}
+
+/**
+ * Get currently supported decompressions.
+ *
+ * @return string | separated list of extensions usable in PMA_getDirContent
+ */
+function PMA_supportedDecompressions()
+{
+    global $cfg;
+
+    $compressions = '';
+
+    if ($cfg['GZipDump'] && @function_exists('gzopen')) {
+        if (!empty($compressions)) {
+            $compressions .= '|';
+        }
+        $compressions .= 'gz';
+    }
+    if ($cfg['BZipDump'] && @function_exists('bzopen')) {
+        if (!empty($compressions)) {
+            $compressions .= '|';
+        }
+        $compressions .= 'bz2';
+    }
+    if ($cfg['ZipDump'] && @function_exists('gzinflate')) {
+        if (!empty($compressions)) {
+            $compressions .= '|';
+        }
+        $compressions .= 'zip';
+    }
+
+    return $compressions;
+}
diff --git a/phpmyadmin/libraries/gis/pma_gis_factory.php b/phpmyadmin/libraries/gis/pma_gis_factory.php
new file mode 100644
index 0000000..1184ae3
--- /dev/null
+++ b/phpmyadmin/libraries/gis/pma_gis_factory.php
@@ -0,0 +1,61 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * Contains the factory class that handles the creation of geometric objects
+ *
+ * @package PhpMyAdmin-GIS
+ */
+
+if (! defined('PHPMYADMIN')) {
+    exit;
+}
+
+/**
+ * Factory class that handles the creation of geometric objects.
+ *
+ * @package PhpMyAdmin-GIS
+ */
+class PMA_GIS_Factory
+{
+    /**
+     * Returns the singleton instance of geometric class of the given type.
+     *
+     * @param string $type type of the geometric object
+     *
+     * @return object the singleton instance of geometric class of the given type
+     * @access public
+     * @static
+     */
+    public static function factory($type)
+    {
+        include_once './libraries/gis/pma_gis_geometry.php';
+
+        $type_lower = strtolower($type);
+        if (! file_exists('./libraries/gis/pma_gis_' . $type_lower . '.php')) {
+            return false;
+        }
+        if (include_once './libraries/gis/pma_gis_' . $type_lower . '.php') {
+            switch(strtoupper($type)) {
+            case 'MULTIPOLYGON' :
+                return PMA_GIS_Multipolygon::singleton();
+            case 'POLYGON' :
+                return PMA_GIS_Polygon::singleton();
+            case 'MULTIPOINT' :
+                return PMA_GIS_Multipoint::singleton();
+            case 'POINT' :
+                return PMA_GIS_Point::singleton();
+            case 'MULTILINESTRING' :
+                return PMA_GIS_Multilinestring::singleton();
+            case 'LINESTRING' :
+                return PMA_GIS_Linestring::singleton();
+            case 'GEOMETRYCOLLECTION' :
+                return PMA_GIS_Geometrycollection::singleton();
+            default :
+                return false;
+            }
+        } else {
+            return false;
+        }
+    }
+}
+?>
diff --git a/phpmyadmin/libraries/gis/pma_gis_geometry.php b/phpmyadmin/libraries/gis/pma_gis_geometry.php
new file mode 100644
index 0000000..206d7c4
--- /dev/null
+++ b/phpmyadmin/libraries/gis/pma_gis_geometry.php
@@ -0,0 +1,361 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * Base class for all GIS data type classes
+ *
+ * @package PhpMyAdmin-GIS
+ */
+
+if (! defined('PHPMYADMIN')) {
+    exit;
+}
+
+/**
+ * Base class for all GIS data type classes.
+ *
+ * @package PhpMyAdmin-GIS
+ */
+abstract class PMA_GIS_Geometry
+{
+    /**
+     * Prepares and returns the code related to a row in the GIS dataset as SVG.
+     *
+     * @param string $spatial    GIS data object
+     * @param string $label      label for the GIS data object
+     * @param string $color      color for the GIS data object
+     * @param array  $scale_data data related to scaling
+     *
+     * @return string the code related to a row in the GIS dataset
+     * @access public
+     */
+    public abstract function prepareRowAsSvg($spatial, $label, $color, $scale_data);
+
+    /**
+     * Adds to the PNG image object, the data related to a row in the GIS dataset.
+     *
+     * @param string $spatial    GIS data object
+     * @param string $label      label for the GIS data object
+     * @param string $color      color for the GIS data object
+     * @param array  $scale_data array containing data related to scaling
+     * @param object $image      image object
+     *
+     * @return object the modified image object
+     * @access public
+     */
+    public abstract function prepareRowAsPng($spatial, $label, $color,
+        $scale_data, $image
+    );
+
+    /**
+     * Adds to the TCPDF instance, the data related to a row in the GIS dataset.
+     *
+     * @param string $spatial    GIS data object
+     * @param string $label      label for the GIS data object
+     * @param string $color      color for the GIS data object
+     * @param array  $scale_data array containing data related to scaling
+     * @param object $pdf        TCPDF instance
+     *
+     * @return object the modified TCPDF instance
+     * @access public
+     */
+    public abstract function prepareRowAsPdf($spatial, $label, $color,
+        $scale_data, $pdf
+    );
+
+    /**
+     * Prepares the JavaScript related to a row in the GIS dataset
+     * to visualize it with OpenLayers.
+     *
+     * @param string $spatial    GIS data object
+     * @param int    $srid       spatial reference ID
+     * @param string $label      label for the GIS data object
+     * @param string $color      color for the GIS data object
+     * @param array  $scale_data array containing data related to scaling
+     *
+     * @return string the JavaScript related to a row in the GIS dataset
+     * @access public
+     */
+    public abstract function prepareRowAsOl($spatial, $srid, $label,
+        $color, $scale_data
+    );
+
+    /**
+     * Scales each row.
+     *
+     * @param string $spatial spatial data of a row
+     *
+     * @return array array containing the min, max values for x and y cordinates
+     * @access public
+     */
+    public abstract function scaleRow($spatial);
+
+    /**
+     * Generates the WKT with the set of parameters passed by the GIS editor.
+     *
+     * @param array  $gis_data GIS data
+     * @param int    $index    index into the parameter object
+     * @param string $empty    value for empty points
+     *
+     * @return string WKT with the set of parameters passed by the GIS editor
+     * @access public
+     */
+    public abstract function generateWkt($gis_data, $index, $empty = '');
+
+    /**
+     * Returns OpenLayers.Bounds object that correspond to the bounds of GIS data.
+     *
+     * @param string $srid       spatial reference ID
+     * @param array  $scale_data data related to scaling
+     *
+     * @return string OpenLayers.Bounds object that
+     *                correspond to the bounds of GIS data
+     * @access protected
+     */
+    protected function getBoundsForOl($srid, $scale_data)
+    {
+        return 'bound = new OpenLayers.Bounds(); '
+            . 'bound.extend(new OpenLayers.LonLat('
+            . $scale_data['minX'] . ', ' . $scale_data['minY']
+            . ').transform(new OpenLayers.Projection("EPSG:'
+            . $srid . '"), map.getProjectionObject())); '
+            . 'bound.extend(new OpenLayers.LonLat('
+            . $scale_data['maxX'] . ', ' . $scale_data['maxY']
+            . ').transform(new OpenLayers.Projection("EPSG:'
+            . $srid . '"), map.getProjectionObject()));';
+    }
+
+    /**
+     * Updates the min, max values with the given point set.
+     *
+     * @param string $point_set point set
+     * @param array  $min_max   existing min, max values
+     *
+     * @return array the updated min, max values
+     * @access protected
+     */
+    protected function setMinMax($point_set, $min_max)
+    {
+        // Seperate each point
+        $points = explode(",", $point_set);
+
+        foreach ($points as $point) {
+            // Extract cordinates of the point
+            $cordinates = explode(" ", $point);
+
+            $x = (float) $cordinates[0];
+            if (! isset($min_max['maxX']) || $x > $min_max['maxX']) {
+                $min_max['maxX'] = $x;
+            }
+            if (! isset($min_max['minX']) || $x < $min_max['minX']) {
+                $min_max['minX'] = $x;
+            }
+            $y = (float) $cordinates[1];
+            if (! isset($min_max['maxY']) || $y > $min_max['maxY']) {
+                $min_max['maxY'] = $y;
+            }
+            if (! isset($min_max['minY']) || $y < $min_max['minY']) {
+                $min_max['minY'] = $y;
+            }
+        }
+        return $min_max;
+    }
+
+    /**
+     * Generates parameters for the GIS data editor from the value of the GIS column.
+     * This method performs common work.
+     * More specific work is performed by each of the geom classes.
+     *
+     * @param string $value value of the GIS column
+     *
+     * @return array parameters for the GIS editor from the value of the GIS column
+     * @access protected
+     */
+    protected function generateParams($value)
+    {
+        $geom_types = '(POINT|MULTIPOINT|LINESTRING|MULTILINESTRING'
+            . '|POLYGON|MULTIPOLYGON|GEOMETRYCOLLECTION)';
+        $srid = 0;
+        $wkt = '';
+        if (preg_match("/^'" . $geom_types . "\(.*\)',[0-9]*$/i", $value)) {
+            $last_comma = strripos($value, ",");
+            $srid = trim(substr($value, $last_comma + 1));
+            $wkt = trim(substr($value, 1, $last_comma - 2));
+        } elseif (preg_match("/^" . $geom_types . "\(.*\)$/i", $value)) {
+            $wkt = $value;
+        }
+        return array('srid' => $srid, 'wkt' => $wkt);
+    }
+
+    /**
+     * Extracts points, scales and returns them as an array.
+     *
+     * @param string  $point_set  string of comma sperated points
+     * @param array   $scale_data data related to scaling
+     * @param boolean $linear     if true, as a 1D array, else as a 2D array
+     *
+     * @return array scaled points
+     * @access protected
+     */
+    protected function extractPoints($point_set, $scale_data, $linear = false)
+    {
+        $points_arr = array();
+
+        // Seperate each point
+        $points = explode(",", $point_set);
+
+        foreach ($points as $point) {
+            // Extract cordinates of the point
+            $cordinates = explode(" ", $point);
+
+            if (isset($cordinates[0]) && trim($cordinates[0]) != ''
+                && isset($cordinates[1]) && trim($cordinates[1]) != ''
+            ) {
+                if ($scale_data != null) {
+                    $x = ($cordinates[0] - $scale_data['x']) * $scale_data['scale'];
+                    $y = $scale_data['height']
+                        - ($cordinates[1] - $scale_data['y']) * $scale_data['scale'];
+                } else {
+                    $x = trim($cordinates[0]);
+                    $y = trim($cordinates[1]);
+                }
+            } else {
+                $x = '';
+                $y = '';
+            }
+
+
+            if (! $linear) {
+                $points_arr[] = array($x, $y);
+            } else {
+                $points_arr[] = $x;
+                $points_arr[] = $y;
+            }
+        }
+
+        return $points_arr;
+    }
+
+    /**
+     * Generates JavaScript for adding an array of polygons to OpenLayers.
+     *
+     * @param array  $polygons x and y coordinates for each polygon
+     * @param string $srid     spatial reference id
+     *
+     * @return string JavaScript for adding an array of polygons to OpenLayers
+     * @access protected
+     */
+    protected function getPolygonArrayForOpenLayers($polygons, $srid)
+    {
+        $ol_array = 'new Array(';
+        foreach ($polygons as $polygon) {
+            $rings = explode("),(", $polygon);
+            $ol_array .= $this->getPolygonForOpenLayers($rings, $srid) . ', ';
+        }
+        $ol_array = substr($ol_array, 0, strlen($ol_array) - 2);
+        $ol_array .= ')';
+
+        return $ol_array;
+    }
+
+    /**
+     * Generates JavaScript for adding points for OpenLayers polygon.
+     *
+     * @param array  $polygon x and y coordinates for each line
+     * @param string $srid    spatial reference id
+     *
+     * @return string JavaScript for adding points for OpenLayers polygon
+     * @access protected
+     */
+    protected function getPolygonForOpenLayers($polygon, $srid)
+    {
+        return 'new OpenLayers.Geometry.Polygon('
+            . $this->getLineArrayForOpenLayers($polygon, $srid, false)
+            . ')';
+    }
+
+    /**
+     * Generates JavaScript for adding an array of LineString
+     * or LineRing to OpenLayers.
+     *
+     * @param array  $lines          x and y coordinates for each line
+     * @param string $srid           spatial reference id
+     * @param bool   $is_line_string whether it's an array of LineString
+     *
+     * @return string JavaScript for adding an array of LineString
+     *                or LineRing to OpenLayers
+     * @access protected
+     */
+    protected function getLineArrayForOpenLayers($lines, $srid,
+        $is_line_string = true
+    ) {
+        $ol_array = 'new Array(';
+        foreach ($lines as $line) {
+            $points_arr = $this->extractPoints($line, null);
+            $ol_array .= $this->getLineForOpenLayers(
+                $points_arr, $srid, $is_line_string
+            );
+            $ol_array .= ', ';
+        }
+        $ol_array = substr($ol_array, 0, strlen($ol_array) - 2);
+        $ol_array .= ')';
+
+        return $ol_array;
+    }
+
+    /**
+     * Generates JavaScript for adding a LineString or LineRing to OpenLayers.
+     *
+     * @param array  $points_arr     x and y coordinates for each point
+     * @param string $srid           spatial reference id
+     * @param bool   $is_line_string whether it's a LineString
+     *
+     * @return string JavaScript for adding a LineString or LineRing to OpenLayers
+     * @access protected
+     */
+    protected function getLineForOpenLayers($points_arr, $srid,
+        $is_line_string = true
+    ) {
+        return 'new OpenLayers.Geometry.'
+            . ($is_line_string ? 'LineString' : 'LinearRing') . '('
+            . $this->getPointsArrayForOpenLayers($points_arr, $srid)
+            . ')';
+    }
+
+    /**
+     * Generates JavaScript for adding an array of points to OpenLayers.
+     *
+     * @param array  $points_arr x and y coordinates for each point
+     * @param string $srid       spatial reference id
+     *
+     * @return string JavaScript for adding an array of points to OpenLayers
+     * @access protected
+     */
+    protected function getPointsArrayForOpenLayers($points_arr, $srid)
+    {
+        $ol_array = 'new Array(';
+        foreach ($points_arr as $point) {
+            $ol_array .= $this->getPointForOpenLayers($point, $srid) . ', ';
+        }
+        $ol_array = substr($ol_array, 0, strlen($ol_array) - 2);
+        $ol_array .= ')';
+
+        return $ol_array;
+    }
+
+    /**
+     * Generates JavaScript for adding a point to OpenLayers.
+     *
+     * @param array  $point array containing the x and y coordinates of the point
+     * @param string $srid  spatial reference id
+     *
+     * @return string JavaScript for adding points to OpenLayers
+     * @access protected
+     */
+    protected function getPointForOpenLayers($point, $srid)
+    {
+        return '(new OpenLayers.Geometry.Point(' . $point[0] . ',' . $point[1] . '))'
+            . '.transform(new OpenLayers.Projection("EPSG:'
+            . $srid . '"), map.getProjectionObject())';
+    }
+}
+?>
diff --git a/phpmyadmin/libraries/gis/pma_gis_geometrycollection.php b/phpmyadmin/libraries/gis/pma_gis_geometrycollection.php
new file mode 100644
index 0000000..91c5a58
--- /dev/null
+++ b/phpmyadmin/libraries/gis/pma_gis_geometrycollection.php
@@ -0,0 +1,336 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * Handles actions related to GIS GEOMETRYCOLLECTION objects
+ *
+ * @package PhpMyAdmin-GIS
+ */
+
+if (! defined('PHPMYADMIN')) {
+    exit;
+}
+
+/**
+ * Handles actions related to GIS GEOMETRYCOLLECTION objects
+ *
+ * @package PhpMyAdmin-GIS
+ */
+class PMA_GIS_Geometrycollection extends PMA_GIS_Geometry
+{
+    // Hold the singleton instance of the class
+    private static $_instance;
+
+    /**
+     * A private constructor; prevents direct creation of object.
+     *
+     * @access private
+     */
+    private function __construct()
+    {
+    }
+
+    /**
+     * Returns the singleton.
+     *
+     * @return the singleton
+     * @access public
+     */
+    public static function singleton()
+    {
+        if (!isset(self::$_instance)) {
+            $class = __CLASS__;
+            self::$_instance = new $class;
+        }
+
+        return self::$_instance;
+    }
+
+    /**
+     * Scales each row.
+     *
+     * @param string $spatial spatial data of a row
+     *
+     * @return array array containing the min, max values for x and y cordinates
+     * @access public
+     */
+    public function scaleRow($spatial)
+    {
+        $min_max = array();
+
+        // Trim to remove leading 'GEOMETRYCOLLECTION(' and trailing ')'
+        $goem_col = substr($spatial, 19, (strlen($spatial) - 20));
+                    
+        // Split the geometry collection object to get its constituents.
+        $sub_parts = $this->_explodeGeomCol($goem_col);
+
+        foreach ($sub_parts as $sub_part) {
+            $type_pos = stripos($sub_part, '(');
+            $type = substr($sub_part, 0, $type_pos);
+
+            $gis_obj = PMA_GIS_Factory::factory($type);
+            if (! $gis_obj) {
+                continue;
+            }
+            $scale_data = $gis_obj->scaleRow($sub_part);
+
+            // Upadate minimum/maximum values for x and y cordinates.
+            $c_maxX = (float) $scale_data['maxX'];
+            if (! isset($min_max['maxX']) || $c_maxX > $min_max['maxX']) {
+                $min_max['maxX'] = $c_maxX;
+            }
+
+            $c_minX = (float) $scale_data['minX'];
+            if (! isset($min_max['minX']) || $c_minX < $min_max['minX']) {
+                $min_max['minX'] = $c_minX;
+            }
+
+            $c_maxY = (float) $scale_data['maxY'];
+            if (! isset($min_max['maxY']) || $c_maxY > $min_max['maxY']) {
+                $min_max['maxY'] = $c_maxY;
+            }
+
+            $c_minY = (float) $scale_data['minY'];
+            if (! isset($min_max['minY']) || $c_minY < $min_max['minY']) {
+                $min_max['minY'] = $c_minY;
+            }
+        }
+        return $min_max;
+    }
+
+    /**
+     * Adds to the PNG image object, the data related to a row in the GIS dataset.
+     *
+     * @param string $spatial    GIS GEOMETRYCOLLECTION object
+     * @param string $label      label for the GIS GEOMETRYCOLLECTION object
+     * @param string $color      color for the GIS GEOMETRYCOLLECTION object
+     * @param array  $scale_data array containing data related to scaling
+     * @param object $image      image object
+     *
+     * @return object the modified image object
+     * @access public
+     */
+    public function prepareRowAsPng($spatial, $label, $color, $scale_data, $image)
+    {
+        // Trim to remove leading 'GEOMETRYCOLLECTION(' and trailing ')'
+        $goem_col = substr($spatial, 19, (strlen($spatial) - 20));
+        // Split the geometry collection object to get its constituents.
+        $sub_parts = $this->_explodeGeomCol($goem_col);
+
+        foreach ($sub_parts as $sub_part) {
+            $type_pos = stripos($sub_part, '(');
+            $type = substr($sub_part, 0, $type_pos);
+
+            $gis_obj = PMA_GIS_Factory::factory($type);
+            if (! $gis_obj) {
+                continue;
+            }
+            $image = $gis_obj->prepareRowAsPng(
+                $sub_part, $label, $color, $scale_data, $image
+            );
+        }
+        return $image;
+    }
+
+    /**
+     * Adds to the TCPDF instance, the data related to a row in the GIS dataset.
+     *
+     * @param string $spatial    GIS GEOMETRYCOLLECTION object
+     * @param string $label      label for the GIS GEOMETRYCOLLECTION object
+     * @param string $color      color for the GIS GEOMETRYCOLLECTION object
+     * @param array  $scale_data array containing data related to scaling
+     * @param object $pdf        TCPDF instance
+     *
+     * @return object the modified TCPDF instance
+     * @access pubilc
+     */
+    public function prepareRowAsPdf($spatial, $label, $color, $scale_data, $pdf)
+    {
+        // Trim to remove leading 'GEOMETRYCOLLECTION(' and trailing ')'
+        $goem_col = substr($spatial, 19, (strlen($spatial) - 20));
+        // Split the geometry collection object to get its constituents.
+        $sub_parts = $this->_explodeGeomCol($goem_col);
+
+        foreach ($sub_parts as $sub_part) {
+            $type_pos = stripos($sub_part, '(');
+            $type = substr($sub_part, 0, $type_pos);
+
+            $gis_obj = PMA_GIS_Factory::factory($type);
+            if (! $gis_obj) {
+                continue;
+            }
+            $pdf = $gis_obj->prepareRowAsPdf(
+                $sub_part, $label, $color, $scale_data, $pdf
+            );
+        }
+        return $pdf;
+    }
+
+    /**
+     * Prepares and returns the code related to a row in the GIS dataset as SVG.
+     *
+     * @param string $spatial    GIS GEOMETRYCOLLECTION object
+     * @param string $label      label for the GIS GEOMETRYCOLLECTION object
+     * @param string $color      color for the GIS GEOMETRYCOLLECTION object
+     * @param array  $scale_data array containing data related to scaling
+     *
+     * @return string the code related to a row in the GIS dataset
+     * @access public
+     */
+    public function prepareRowAsSvg($spatial, $label, $color, $scale_data)
+    {
+        $row = '';
+
+        // Trim to remove leading 'GEOMETRYCOLLECTION(' and trailing ')'
+        $goem_col = substr($spatial, 19, (strlen($spatial) - 20));
+        // Split the geometry collection object to get its constituents.
+        $sub_parts = $this->_explodeGeomCol($goem_col);
+
+        foreach ($sub_parts as $sub_part) {
+            $type_pos = stripos($sub_part, '(');
+            $type = substr($sub_part, 0, $type_pos);
+
+            $gis_obj = PMA_GIS_Factory::factory($type);
+            if (! $gis_obj) {
+                continue;
+            }
+            $row .= $gis_obj->prepareRowAsSvg(
+                $sub_part, $label, $color, $scale_data
+            );
+        }
+        return $row;
+    }
+
+    /**
+     * Prepares JavaScript related to a row in the GIS dataset
+     * to visualize it with OpenLayers.
+     *
+     * @param string $spatial    GIS GEOMETRYCOLLECTION object
+     * @param int    $srid       spatial reference ID
+     * @param string $label      label for the GIS GEOMETRYCOLLECTION object
+     * @param string $color      color for the GIS GEOMETRYCOLLECTION object
+     * @param array  $scale_data array containing data related to scaling
+     *
+     * @return string JavaScript related to a row in the GIS dataset
+     * @access public
+     */
+    public function prepareRowAsOl($spatial, $srid, $label, $color, $scale_data)
+    {
+        $row = '';
+
+        // Trim to remove leading 'GEOMETRYCOLLECTION(' and trailing ')'
+        $goem_col = substr($spatial, 19, (strlen($spatial) - 20));
+        // Split the geometry collection object to get its constituents.
+        $sub_parts = $this->_explodeGeomCol($goem_col);
+
+        foreach ($sub_parts as $sub_part) {
+            $type_pos = stripos($sub_part, '(');
+            $type = substr($sub_part, 0, $type_pos);
+
+            $gis_obj = PMA_GIS_Factory::factory($type);
+            if (! $gis_obj) {
+                continue;
+            }
+            $row .= $gis_obj->prepareRowAsOl(
+                $sub_part, $srid, $label, $color, $scale_data
+            );
+        }
+        return $row;
+    }
+
+    /**
+     * Splits the GEOMETRYCOLLECTION object and get its constituents.
+     *
+     * @param string $goem_col geometry collection string
+     *
+     * @return array the constituents of the geometry collection object
+     * @access private
+     */
+    private function _explodeGeomCol($goem_col)
+    {
+        $sub_parts = array();
+        $br_count = 0;
+        $start = 0;
+        $count = 0;
+        foreach (str_split($goem_col) as $char) {
+            if ($char == '(') {
+                $br_count++;
+            } elseif ($char == ')') {
+                $br_count--;
+                if ($br_count == 0) {
+                    $sub_parts[] = substr($goem_col, $start, ($count + 1 - $start));
+                    $start = $count + 2;
+                }
+            }
+            $count++;
+        }
+        return $sub_parts;
+    }
+
+    /**
+     * Generates the WKT with the set of parameters passed by the GIS editor.
+     *
+     * @param array  $gis_data GIS data
+     * @param int    $index    index into the parameter object
+     * @param string $empty    value for empty points
+     *
+     * @return string WKT with the set of parameters passed by the GIS editor
+     * @access public
+     */
+    public function generateWkt($gis_data, $index, $empty = '')
+    {
+        $geom_count = (isset($gis_data['GEOMETRYCOLLECTION']['geom_count']))
+            ? $gis_data['GEOMETRYCOLLECTION']['geom_count'] : 1;
+        $wkt = 'GEOMETRYCOLLECTION(';
+        for ($i = 0; $i < $geom_count; $i++) {
+            if (isset($gis_data[$i]['gis_type'])) {
+                $type = $gis_data[$i]['gis_type'];
+                $gis_obj = PMA_GIS_Factory::factory($type);
+                if (! $gis_obj) {
+                    continue;
+                }
+                $wkt .= $gis_obj->generateWkt($gis_data, $i, $empty) . ',';
+            }
+        }
+        if (isset($gis_data[0]['gis_type'])) {
+            $wkt = substr($wkt, 0, strlen($wkt) - 1);
+        }
+        $wkt .= ')';
+        return $wkt;
+    }
+
+    /**
+     * Generates parameters for the GIS data editor from the value of the GIS column.
+     *
+     * @param string $value of the GIS column
+     *
+     * @return array parameters for the GIS editor from the value of the GIS column
+     * @access public
+     */
+    public function generateParams($value)
+    {
+        $params = array();
+        $data = PMA_GIS_Geometry::generateParams($value);
+        $params['srid'] = $data['srid'];
+        $wkt = $data['wkt'];
+
+        // Trim to remove leading 'GEOMETRYCOLLECTION(' and trailing ')'
+        $goem_col = substr($wkt, 19, (strlen($wkt) - 20));
+        // Split the geometry collection object to get its constituents.
+        $sub_parts = $this->_explodeGeomCol($goem_col);
+        $params['GEOMETRYCOLLECTION']['geom_count'] = count($sub_parts);
+
+        $i = 0;
+        foreach ($sub_parts as $sub_part) {
+            $type_pos = stripos($sub_part, '(');
+            $type = substr($sub_part, 0, $type_pos);
+            $gis_obj = PMA_GIS_Factory::factory($type);
+            if (! $gis_obj) {
+                continue;
+            }
+            $params = array_merge($params, $gis_obj->generateParams($sub_part, $i));
+            $i++;
+        }
+        return $params;
+    }
+}
+?>
diff --git a/phpmyadmin/libraries/gis/pma_gis_linestring.php b/phpmyadmin/libraries/gis/pma_gis_linestring.php
new file mode 100644
index 0000000..9c49512
--- /dev/null
+++ b/phpmyadmin/libraries/gis/pma_gis_linestring.php
@@ -0,0 +1,298 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * Handles actions related to GIS LINESTRING objects
+ *
+ * @package PhpMyAdmin-GIS
+ */
+
+if (! defined('PHPMYADMIN')) {
+    exit;
+}
+
+/**
+ * Handles actions related to GIS LINESTRING objects
+ *
+ * @package PhpMyAdmin-GIS
+ */
+class PMA_GIS_Linestring extends PMA_GIS_Geometry
+{
+    // Hold the singleton instance of the class
+    private static $_instance;
+
+    /**
+     * A private constructor; prevents direct creation of object.
+     *
+     * @access private
+     */
+    private function __construct()
+    {
+    }
+
+    /**
+     * Returns the singleton.
+     *
+     * @return object the singleton
+     * @access public
+     */
+    public static function singleton()
+    {
+        if (!isset(self::$_instance)) {
+            $class = __CLASS__;
+            self::$_instance = new $class;
+        }
+
+        return self::$_instance;
+    }
+
+    /**
+     * Scales each row.
+     *
+     * @param string $spatial spatial data of a row
+     *
+     * @return array an array containing the min, max values for x and y cordinates
+     * @access public
+     */
+    public function scaleRow($spatial)
+    {
+        // Trim to remove leading 'LINESTRING(' and trailing ')'
+        $linesrting = substr($spatial, 11, (strlen($spatial) - 12));
+        return $this->setMinMax($linesrting, array());
+    }
+
+    /**
+     * Adds to the PNG image object, the data related to a row in the GIS dataset.
+     *
+     * @param string $spatial    GIS LINESTRING object
+     * @param string $label      Label for the GIS LINESTRING object
+     * @param string $line_color Color for the GIS LINESTRING object
+     * @param array  $scale_data Array containing data related to scaling
+     * @param object $image      Image object
+     *
+     * @return object the modified image object
+     * @access public
+     */
+    public function prepareRowAsPng($spatial, $label, $line_color,
+        $scale_data, $image
+    ) {
+        // allocate colors
+        $black = imagecolorallocate($image, 0, 0, 0);
+        $red   = hexdec(substr($line_color, 1, 2));
+        $green = hexdec(substr($line_color, 3, 2));
+        $blue  = hexdec(substr($line_color, 4, 2));
+        $color = imagecolorallocate($image, $red, $green, $blue);
+
+        // Trim to remove leading 'LINESTRING(' and trailing ')'
+        $linesrting = substr($spatial, 11, (strlen($spatial) - 12));
+        $points_arr = $this->extractPoints($linesrting, $scale_data);
+
+        foreach ($points_arr as $point) {
+            if (! isset($temp_point)) {
+                $temp_point = $point;
+            } else {
+                // draw line section
+                imageline(
+                    $image, $temp_point[0], $temp_point[1],
+                    $point[0], $point[1], $color
+                );
+                $temp_point = $point;
+            }
+        }
+        // print label if applicable
+        if (isset($label) && trim($label) != '') {
+            imagestring(
+                $image, 1, $points_arr[1][0],
+                $points_arr[1][1], trim($label), $black
+            );
+        }
+        return $image;
+    }
+
+    /**
+     * Adds to the TCPDF instance, the data related to a row in the GIS dataset.
+     *
+     * @param string $spatial    GIS LINESTRING object
+     * @param string $label      Label for the GIS LINESTRING object
+     * @param string $line_color Color for the GIS LINESTRING object
+     * @param array  $scale_data Array containing data related to scaling
+     * @param object $pdf        TCPDF instance
+     *
+     * @return object the modified TCPDF instance
+     * @access public
+     */
+    public function prepareRowAsPdf($spatial, $label, $line_color, $scale_data, $pdf)
+    {
+        // allocate colors
+        $red   = hexdec(substr($line_color, 1, 2));
+        $green = hexdec(substr($line_color, 3, 2));
+        $blue  = hexdec(substr($line_color, 4, 2));
+        $line  = array('width' => 1.5, 'color' => array($red, $green, $blue));
+
+        // Trim to remove leading 'LINESTRING(' and trailing ')'
+        $linesrting = substr($spatial, 11, (strlen($spatial) - 12));
+        $points_arr = $this->extractPoints($linesrting, $scale_data);
+
+        foreach ($points_arr as $point) {
+            if (! isset($temp_point)) {
+                $temp_point = $point;
+            } else {
+                // draw line section
+                $pdf->Line(
+                    $temp_point[0], $temp_point[1],
+                    $point[0], $point[1], $line
+                );
+                $temp_point = $point;
+            }
+        }
+        // print label
+        if (isset($label) && trim($label) != '') {
+            $pdf->SetXY($points_arr[1][0], $points_arr[1][1]);
+            $pdf->SetFontSize(5);
+            $pdf->Cell(0, 0, trim($label));
+        }
+        return $pdf;
+    }
+
+    /**
+     * Prepares and returns the code related to a row in the GIS dataset as SVG.
+     *
+     * @param string $spatial    GIS LINESTRING object
+     * @param string $label      Label for the GIS LINESTRING object
+     * @param string $line_color Color for the GIS LINESTRING object
+     * @param array  $scale_data Array containing data related to scaling
+     *
+     * @return string the code related to a row in the GIS dataset
+     * @access public
+     */
+    public function prepareRowAsSvg($spatial, $label, $line_color, $scale_data)
+    {
+        $line_options = array(
+            'name'        => $label,
+            'id'          => $label . rand(),
+            'class'       => 'linestring vector',
+            'fill'        => 'none',
+            'stroke'      => $line_color,
+            'stroke-width'=> 2,
+        );
+
+        // Trim to remove leading 'LINESTRING(' and trailing ')'
+        $linesrting = substr($spatial, 11, (strlen($spatial) - 12));
+        $points_arr = $this->extractPoints($linesrting, $scale_data);
+
+        $row = '<polyline points="';
+        foreach ($points_arr as $point) {
+            $row .= $point[0] . ',' . $point[1] . ' ';
+        }
+        $row .= '"';
+        foreach ($line_options as $option => $val) {
+            $row .= ' ' . $option . '="' . trim($val) . '"';
+        }
+        $row .= '/>';
+
+        return $row;
+    }
+
+    /**
+     * Prepares JavaScript related to a row in the GIS dataset
+     * to visualize it with OpenLayers.
+     *
+     * @param string $spatial    GIS LINESTRING object
+     * @param int    $srid       Spatial reference ID
+     * @param string $label      Label for the GIS LINESTRING object
+     * @param string $line_color Color for the GIS LINESTRING object
+     * @param array  $scale_data Array containing data related to scaling
+     *
+     * @return string JavaScript related to a row in the GIS dataset
+     * @access public
+     */
+    public function prepareRowAsOl($spatial, $srid, $label, $line_color, $scale_data)
+    {
+        $style_options = array(
+            'strokeColor' => $line_color,
+            'strokeWidth' => 2,
+            'label'       => $label,
+            'fontSize'    => 10,
+        );
+        if ($srid == 0) {
+            $srid = 4326;
+        }
+        $result = $this->getBoundsForOl($srid, $scale_data);
+
+        // Trim to remove leading 'LINESTRING(' and trailing ')'
+        $linesrting = substr($spatial, 11, (strlen($spatial) - 12));
+        $points_arr = $this->extractPoints($linesrting, null);
+
+        $result .= 'vectorLayer.addFeatures(new OpenLayers.Feature.Vector('
+            . $this->getLineForOpenLayers($points_arr, $srid)
+            . ', null, ' . json_encode($style_options) . '));';
+        return $result;
+    }
+
+    /**
+     * Generate the WKT with the set of parameters passed by the GIS editor.
+     *
+     * @param array  $gis_data GIS data
+     * @param int    $index    Index into the parameter object
+     * @param string $empty    Value for empty points
+     *
+     * @return string WKT with the set of parameters passed by the GIS editor
+     * @access public
+     */
+    public function generateWkt($gis_data, $index, $empty = '')
+    {
+        $no_of_points = isset($gis_data[$index]['LINESTRING']['no_of_points'])
+            ? $gis_data[$index]['LINESTRING']['no_of_points'] : 2;
+        if ($no_of_points < 2) {
+            $no_of_points = 2;
+        }
+        $wkt = 'LINESTRING(';
+        for ($i = 0; $i < $no_of_points; $i++) {
+            $wkt .= ((isset($gis_data[$index]['LINESTRING'][$i]['x'])
+                && trim($gis_data[$index]['LINESTRING'][$i]['x']) != '')
+                ? $gis_data[$index]['LINESTRING'][$i]['x'] : $empty)
+                . ' ' . ((isset($gis_data[$index]['LINESTRING'][$i]['y'])
+                && trim($gis_data[$index]['LINESTRING'][$i]['y']) != '')
+                ? $gis_data[$index]['LINESTRING'][$i]['y'] : $empty) .',';
+        }
+        $wkt = substr($wkt, 0, strlen($wkt) - 1);
+        $wkt .= ')';
+        return $wkt;
+    }
+
+    /**
+     * Generate parameters for the GIS data editor from the value of the GIS column.
+     *
+     * @param string $value of the GIS column
+     * @param int    $index of the geometry
+     *
+     * @return array params for the GIS data editor from the value of the GIS column
+     * @access public
+     */
+    public function generateParams($value, $index = -1)
+    {
+        if ($index == -1) {
+            $index = 0;
+            $params = array();
+            $data = PMA_GIS_Geometry::generateParams($value);
+            $params['srid'] = $data['srid'];
+            $wkt = $data['wkt'];
+        } else {
+            $params[$index]['gis_type'] = 'LINESTRING';
+            $wkt = $value;
+        }
+
+        // Trim to remove leading 'LINESTRING(' and trailing ')'
+        $linestring = substr($wkt, 11, (strlen($wkt) - 12));
+        $points_arr = $this->extractPoints($linestring, null);
+
+        $no_of_points = count($points_arr);
+        $params[$index]['LINESTRING']['no_of_points'] = $no_of_points;
+        for ($i = 0; $i < $no_of_points; $i++) {
+            $params[$index]['LINESTRING'][$i]['x'] = $points_arr[$i][0];
+            $params[$index]['LINESTRING'][$i]['y'] = $points_arr[$i][1];
+        }
+
+        return $params;
+    }
+}
+?>
diff --git a/phpmyadmin/libraries/gis/pma_gis_multilinestring.php b/phpmyadmin/libraries/gis/pma_gis_multilinestring.php
new file mode 100644
index 0000000..ce4a0c9
--- /dev/null
+++ b/phpmyadmin/libraries/gis/pma_gis_multilinestring.php
@@ -0,0 +1,370 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * Handles actions related to GIS MULTILINESTRING objects
+ *
+ * @package PhpMyAdmin-GIS
+ */
+
+if (! defined('PHPMYADMIN')) {
+    exit;
+}
+
+/**
+ * Handles actions related to GIS MULTILINESTRING objects
+ *
+ * @package PhpMyAdmin-GIS
+ */
+class PMA_GIS_Multilinestring extends PMA_GIS_Geometry
+{
+    // Hold the singleton instance of the class
+    private static $_instance;
+
+    /**
+     * A private constructor; prevents direct creation of object.
+     *
+     * @access private
+     */
+    private function __construct()
+    {
+    }
+
+    /**
+     * Returns the singleton.
+     *
+     * @return object the singleton
+     * @access public
+     */
+    public static function singleton()
+    {
+        if (!isset(self::$_instance)) {
+            $class = __CLASS__;
+            self::$_instance = new $class;
+        }
+
+        return self::$_instance;
+    }
+
+    /**
+     * Scales each row.
+     *
+     * @param string $spatial spatial data of a row
+     *
+     * @return array an array containing the min, max values for x and y cordinates
+     * @access public
+     */
+    public function scaleRow($spatial)
+    {
+        $min_max = array();
+
+        // Trim to remove leading 'MULTILINESTRING((' and trailing '))'
+        $multilinestirng = substr($spatial, 17, (strlen($spatial) - 19));
+        // Seperate each linestring
+        $linestirngs = explode("),(", $multilinestirng);
+
+        foreach ($linestirngs as $linestring) {
+            $min_max = $this->setMinMax($linestring, $min_max);
+        }
+
+        return $min_max;
+    }
+
+    /**
+     * Adds to the PNG image object, the data related to a row in the GIS dataset.
+     *
+     * @param string $spatial    GIS MULTILINESTRING object
+     * @param string $label      Label for the GIS MULTILINESTRING object
+     * @param string $line_color Color for the GIS MULTILINESTRING object
+     * @param array  $scale_data Array containing data related to scaling
+     * @param object $image      Image object
+     *
+     * @return object the modified image object
+     * @access public
+     */
+    public function prepareRowAsPng($spatial, $label, $line_color,
+        $scale_data, $image
+    ) {
+        // allocate colors
+        $black = imagecolorallocate($image, 0, 0, 0);
+        $red   = hexdec(substr($line_color, 1, 2));
+        $green = hexdec(substr($line_color, 3, 2));
+        $blue  = hexdec(substr($line_color, 4, 2));
+        $color = imagecolorallocate($image, $red, $green, $blue);
+
+        // Trim to remove leading 'MULTILINESTRING((' and trailing '))'
+        $multilinestirng = substr($spatial, 17, (strlen($spatial) - 19));
+        // Seperate each linestring
+        $linestirngs = explode("),(", $multilinestirng);
+
+        $first_line = true;
+        foreach ($linestirngs as $linestring) {
+            $points_arr = $this->extractPoints($linestring, $scale_data);
+            foreach ($points_arr as $point) {
+                if (! isset($temp_point)) {
+                    $temp_point = $point;
+                } else {
+                    // draw line section
+                    imageline(
+                        $image, $temp_point[0], $temp_point[1],
+                        $point[0], $point[1], $color
+                    );
+                    $temp_point = $point;
+                }
+            }
+            unset($temp_point);
+            // print label if applicable
+            if (isset($label) && trim($label) != '' && $first_line) {
+                imagestring(
+                    $image, 1, $points_arr[1][0],
+                    $points_arr[1][1], trim($label), $black
+                );
+            }
+            $first_line = false;
+        }
+        return $image;
+    }
+
+    /**
+     * Adds to the TCPDF instance, the data related to a row in the GIS dataset.
+     *
+     * @param string $spatial    GIS MULTILINESTRING object
+     * @param string $label      Label for the GIS MULTILINESTRING object
+     * @param string $line_color Color for the GIS MULTILINESTRING object
+     * @param array  $scale_data Array containing data related to scaling
+     * @param object $pdf        TCPDF instance
+     *
+     * @return object the modified TCPDF instance
+     * @access public
+     */
+    public function prepareRowAsPdf($spatial, $label, $line_color, $scale_data, $pdf)
+    {
+        // allocate colors
+        $red   = hexdec(substr($line_color, 1, 2));
+        $green = hexdec(substr($line_color, 3, 2));
+        $blue  = hexdec(substr($line_color, 4, 2));
+        $line  = array('width' => 1.5, 'color' => array($red, $green, $blue));
+
+        // Trim to remove leading 'MULTILINESTRING((' and trailing '))'
+        $multilinestirng = substr($spatial, 17, (strlen($spatial) - 19));
+        // Seperate each linestring
+        $linestirngs = explode("),(", $multilinestirng);
+
+        $first_line = true;
+        foreach ($linestirngs as $linestring) {
+            $points_arr = $this->extractPoints($linestring, $scale_data);
+            foreach ($points_arr as $point) {
+                if (! isset($temp_point)) {
+                    $temp_point = $point;
+                } else {
+                    // draw line section
+                    $pdf->Line(
+                        $temp_point[0], $temp_point[1], $point[0], $point[1], $line
+                    );
+                    $temp_point = $point;
+                }
+            }
+            unset($temp_point);
+            // print label
+            if (isset($label) && trim($label) != '' && $first_line) {
+                $pdf->SetXY($points_arr[1][0], $points_arr[1][1]);
+                $pdf->SetFontSize(5);
+                $pdf->Cell(0, 0, trim($label));
+            }
+            $first_line = false;
+        }
+        return $pdf;
+    }
+
+    /**
+     * Prepares and returns the code related to a row in the GIS dataset as SVG.
+     *
+     * @param string $spatial    GIS MULTILINESTRING object
+     * @param string $label      Label for the GIS MULTILINESTRING object
+     * @param string $line_color Color for the GIS MULTILINESTRING object
+     * @param array  $scale_data Array containing data related to scaling
+     *
+     * @return string the code related to a row in the GIS dataset
+     * @access public
+     */
+    public function prepareRowAsSvg($spatial, $label, $line_color, $scale_data)
+    {
+        $line_options = array(
+            'name'        => $label,
+            'class'       => 'linestring vector',
+            'fill'        => 'none',
+            'stroke'      => $line_color,
+            'stroke-width'=> 2,
+        );
+
+        // Trim to remove leading 'MULTILINESTRING((' and trailing '))'
+        $multilinestirng = substr($spatial, 17, (strlen($spatial) - 19));
+        // Seperate each linestring
+        $linestirngs = explode("),(", $multilinestirng);
+
+        $row = '';
+        foreach ($linestirngs as $linestring) {
+            $points_arr = $this->extractPoints($linestring, $scale_data);
+
+            $row .= '<polyline points="';
+            foreach ($points_arr as $point) {
+                $row .= $point[0] . ',' . $point[1] . ' ';
+            }
+            $row .= '"';
+            $line_options['id'] = $label . rand();
+            foreach ($line_options as $option => $val) {
+                $row .= ' ' . $option . '="' . trim($val) . '"';
+            }
+            $row .= '/>';
+        }
+
+        return $row;
+    }
+
+    /**
+     * Prepares JavaScript related to a row in the GIS dataset
+     * to visualize it with OpenLayers.
+     *
+     * @param string $spatial    GIS MULTILINESTRING object
+     * @param int    $srid       Spatial reference ID
+     * @param string $label      Label for the GIS MULTILINESTRING object
+     * @param string $line_color Color for the GIS MULTILINESTRING object
+     * @param array  $scale_data Array containing data related to scaling
+     *
+     * @return string JavaScript related to a row in the GIS dataset
+     * @access public
+     */
+    public function prepareRowAsOl($spatial, $srid, $label, $line_color, $scale_data)
+    {
+        $style_options = array(
+            'strokeColor' => $line_color,
+            'strokeWidth' => 2,
+            'label'       => $label,
+            'fontSize'    => 10,
+        );
+        if ($srid == 0) {
+            $srid = 4326;
+        }
+        $row = $this->getBoundsForOl($srid, $scale_data);
+
+        // Trim to remove leading 'MULTILINESTRING((' and trailing '))'
+        $multilinestirng = substr($spatial, 17, (strlen($spatial) - 19));
+        // Seperate each linestring
+        $linestirngs = explode("),(", $multilinestirng);
+
+        $row .= 'vectorLayer.addFeatures(new OpenLayers.Feature.Vector('
+            . 'new OpenLayers.Geometry.MultiLineString('
+            . $this->getLineArrayForOpenLayers($linestirngs, $srid)
+            . '), null, ' . json_encode($style_options) . '));';
+        return $row;
+    }
+
+    /**
+     * Generate the WKT with the set of parameters passed by the GIS editor.
+     *
+     * @param array  $gis_data GIS data
+     * @param int    $index    Index into the parameter object
+     * @param string $empty    Value for empty points
+     *
+     * @return string WKT with the set of parameters passed by the GIS editor
+     * @access public
+     */
+    public function generateWkt($gis_data, $index, $empty = '')
+    {
+        $data_row = $gis_data[$index]['MULTILINESTRING'];
+
+        $no_of_lines = isset($data_row['no_of_lines'])
+            ? $data_row['no_of_lines'] : 1;
+        if ($no_of_lines < 1) {
+            $no_of_lines = 1;
+        }
+        $wkt = 'MULTILINESTRING(';
+        for ($i = 0; $i < $no_of_lines; $i++) {
+            $no_of_points = isset($data_row[$i]['no_of_points'])
+                ? $data_row[$i]['no_of_points'] : 2;
+            if ($no_of_points < 2) {
+                $no_of_points = 2;
+            }
+            $wkt .= '(';
+            for ($j = 0; $j < $no_of_points; $j++) {
+                $wkt .= ((isset($data_row[$i][$j]['x'])
+                    && trim($data_row[$i][$j]['x']) != '')
+                    ? $data_row[$i][$j]['x'] : $empty)
+                    . ' ' . ((isset($data_row[$i][$j]['y'])
+                    && trim($data_row[$i][$j]['y']) != '')
+                    ? $data_row[$i][$j]['y'] : $empty) . ',';
+            }
+            $wkt = substr($wkt, 0, strlen($wkt) - 1);
+            $wkt .= '),';
+        }
+        $wkt = substr($wkt, 0, strlen($wkt) - 1);
+        $wkt .= ')';
+        return $wkt;
+    }
+
+    /**
+     * Generate the WKT for the data from ESRI shape files.
+     *
+     * @param array $row_data GIS data
+     *
+     * @return string the WKT for the data from ESRI shape files
+     * @access public
+     */
+    public function getShape($row_data)
+    {
+        $wkt = 'MULTILINESTRING(';
+        for ($i = 0; $i < $row_data['numparts']; $i++) {
+            $wkt .= '(';
+            foreach ($row_data['parts'][$i]['points'] as $point) {
+                $wkt .= $point['x'] . ' ' . $point['y'] . ',';
+            }
+            $wkt = substr($wkt, 0, strlen($wkt) - 1);
+            $wkt .= '),';
+        }
+        $wkt = substr($wkt, 0, strlen($wkt) - 1);
+        $wkt .= ')';
+        return $wkt;
+    }
+
+    /**
+     * Generate parameters for the GIS data editor from the value of the GIS column.
+     *
+     * @param string $value of the GIS column
+     * @param index  $index of the geometry
+     *
+     * @return array params for the GIS data editor from the value of the GIS column
+     * @access public
+     */
+    public function generateParams($value, $index = -1)
+    {
+        if ($index == -1) {
+            $index = 0;
+            $params = array();
+            $data = PMA_GIS_Geometry::generateParams($value);
+            $params['srid'] = $data['srid'];
+            $wkt = $data['wkt'];
+        } else {
+            $params[$index]['gis_type'] = 'MULTILINESTRING';
+            $wkt = $value;
+        }
+
+        // Trim to remove leading 'MULTILINESTRING((' and trailing '))'
+        $multilinestirng = substr($wkt, 17, (strlen($wkt) - 19));
+        // Seperate each linestring
+        $linestirngs = explode("),(", $multilinestirng);
+        $params[$index]['MULTILINESTRING']['no_of_lines'] = count($linestirngs);
+
+        $j = 0;
+        foreach ($linestirngs as $linestring) {
+            $points_arr = $this->extractPoints($linestring, null);
+            $no_of_points = count($points_arr);
+            $params[$index]['MULTILINESTRING'][$j]['no_of_points'] = $no_of_points;
+            for ($i = 0; $i < $no_of_points; $i++) {
+                $params[$index]['MULTILINESTRING'][$j][$i]['x'] = $points_arr[$i][0];
+                $params[$index]['MULTILINESTRING'][$j][$i]['y'] = $points_arr[$i][1];
+            }
+            $j++;
+        }
+        return $params;
+    }
+}
+?>
diff --git a/phpmyadmin/libraries/gis/pma_gis_multipoint.php b/phpmyadmin/libraries/gis/pma_gis_multipoint.php
new file mode 100644
index 0000000..e6b7ef7
--- /dev/null
+++ b/phpmyadmin/libraries/gis/pma_gis_multipoint.php
@@ -0,0 +1,343 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * Handles actions related to GIS MULTIPOINT objects
+ *
+ * @package PhpMyAdmin-GIS
+ */
+
+if (! defined('PHPMYADMIN')) {
+    exit;
+}
+
+/**
+ * Handles actions related to GIS MULTIPOINT objects
+ *
+ * @package PhpMyAdmin-GIS
+ */
+class PMA_GIS_Multipoint extends PMA_GIS_Geometry
+{
+    // Hold the singleton instance of the class
+    private static $_instance;
+
+    /**
+     * A private constructor; prevents direct creation of object.
+     *
+     * @access private
+     */
+    private function __construct()
+    {
+    }
+
+    /**
+     * Returns the singleton.
+     *
+     * @return object the singleton
+     * @access public
+     */
+    public static function singleton()
+    {
+        if (!isset(self::$_instance)) {
+            $class = __CLASS__;
+            self::$_instance = new $class;
+        }
+
+        return self::$_instance;
+    }
+
+    /**
+     * Scales each row.
+     *
+     * @param string $spatial spatial data of a row
+     *
+     * @return array an array containing the min, max values for x and y cordinates
+     * @access public
+     */
+    public function scaleRow($spatial)
+    {
+        // Trim to remove leading 'MULTIPOINT(' and trailing ')'
+        $multipoint = substr($spatial, 11, (strlen($spatial) - 12));
+        return $this->setMinMax($multipoint, array());
+    }
+
+    /**
+     * Adds to the PNG image object, the data related to a row in the GIS dataset.
+     *
+     * @param string $spatial     GIS MULTIPOINT object
+     * @param string $label       Label for the GIS MULTIPOINT object
+     * @param string $point_color Color for the GIS MULTIPOINT object
+     * @param array  $scale_data  Array containing data related to scaling
+     * @param object $image       Image object
+     *
+     * @return object the modified image object
+     * @access public
+     */
+    public function prepareRowAsPng($spatial, $label, $point_color,
+        $scale_data, $image
+    ) {
+        // allocate colors
+        $black = imagecolorallocate($image, 0, 0, 0);
+        $red   = hexdec(substr($point_color, 1, 2));
+        $green = hexdec(substr($point_color, 3, 2));
+        $blue  = hexdec(substr($point_color, 4, 2));
+        $color = imagecolorallocate($image, $red, $green, $blue);
+
+        // Trim to remove leading 'MULTIPOINT(' and trailing ')'
+        $multipoint = substr($spatial, 11, (strlen($spatial) - 12));
+        $points_arr = $this->extractPoints($multipoint, $scale_data);
+
+        foreach ($points_arr as $point) {
+            // draw a small circle to mark the point
+            if ($point[0] != '' && $point[1] != '') {
+                imagearc($image, $point[0], $point[1], 7, 7, 0, 360, $color);
+            }
+        }
+        // print label for each point
+        if ((isset($label) && trim($label) != '')
+            && ($points_arr[0][0] != '' && $points_arr[0][1] != '')
+        ) {
+            imagestring(
+                $image, 1, $points_arr[0][0], $points_arr[0][1], trim($label), $black
+            );
+        }
+        return $image;
+    }
+
+    /**
+     * Adds to the TCPDF instance, the data related to a row in the GIS dataset.
+     *
+     * @param string $spatial     GIS MULTIPOINT object
+     * @param string $label       Label for the GIS MULTIPOINT object
+     * @param string $point_color Color for the GIS MULTIPOINT object
+     * @param array  $scale_data  Array containing data related to scaling
+     * @param object $pdf         TCPDF instance
+     *
+     * @return object the modified TCPDF instance
+     * @access public
+     */
+    public function prepareRowAsPdf($spatial, $label, $point_color,
+        $scale_data, $pdf
+    ) {
+        // allocate colors
+        $red   = hexdec(substr($point_color, 1, 2));
+        $green = hexdec(substr($point_color, 3, 2));
+        $blue  = hexdec(substr($point_color, 4, 2));
+        $line  = array('width' => 1.25, 'color' => array($red, $green, $blue));
+
+        // Trim to remove leading 'MULTIPOINT(' and trailing ')'
+        $multipoint = substr($spatial, 11, (strlen($spatial) - 12));
+        $points_arr = $this->extractPoints($multipoint, $scale_data);
+
+        foreach ($points_arr as $point) {
+            // draw a small circle to mark the point
+            if ($point[0] != '' && $point[1] != '') {
+                $pdf->Circle($point[0], $point[1], 2, 0, 360, 'D', $line);
+            }
+        }
+        // print label for each point
+        if ((isset($label) && trim($label) != '')
+            && ($points_arr[0][0] != '' && $points_arr[0][1] != '')
+        ) {
+            $pdf->SetXY($points_arr[0][0], $points_arr[0][1]);
+            $pdf->SetFontSize(5);
+            $pdf->Cell(0, 0, trim($label));
+        }
+        return $pdf;
+    }
+
+    /**
+     * Prepares and returns the code related to a row in the GIS dataset as SVG.
+     *
+     * @param string $spatial     GIS MULTIPOINT object
+     * @param string $label       Label for the GIS MULTIPOINT object
+     * @param string $point_color Color for the GIS MULTIPOINT object
+     * @param array  $scale_data  Array containing data related to scaling
+     *
+     * @return string the code related to a row in the GIS dataset
+     * @access public
+     */
+    public function prepareRowAsSvg($spatial, $label, $point_color, $scale_data)
+    {
+        $point_options = array(
+            'name'        => $label,
+            'class'       => 'multipoint vector',
+            'fill'        => 'white',
+            'stroke'      => $point_color,
+            'stroke-width'=> 2,
+        );
+
+        // Trim to remove leading 'MULTIPOINT(' and trailing ')'
+        $multipoint = substr($spatial, 11, (strlen($spatial) - 12));
+        $points_arr = $this->extractPoints($multipoint, $scale_data);
+
+        $row = '';
+        foreach ($points_arr as $point) {
+            if ($point[0] != '' && $point[1] != '') {
+                $row .= '<circle cx="' . $point[0] . '" cy="'
+                    . $point[1] . '" r="3"';
+                $point_options['id'] = $label . rand();
+                foreach ($point_options as $option => $val) {
+                    $row .= ' ' . $option . '="' . trim($val) . '"';
+                }
+                $row .= '/>';
+            }
+        }
+
+        return $row;
+    }
+
+    /**
+     * Prepares JavaScript related to a row in the GIS dataset
+     * to visualize it with OpenLayers.
+     *
+     * @param string $spatial     GIS MULTIPOINT object
+     * @param int    $srid        Spatial reference ID
+     * @param string $label       Label for the GIS MULTIPOINT object
+     * @param string $point_color Color for the GIS MULTIPOINT object
+     * @param array  $scale_data  Array containing data related to scaling
+     *
+     * @return string JavaScript related to a row in the GIS dataset
+     * @access public
+     */
+    public function prepareRowAsOl($spatial, $srid, $label,
+        $point_color, $scale_data
+    ) {
+        $style_options = array(
+            'pointRadius'  => 3,
+            'fillColor'    => '#ffffff',
+            'strokeColor'  => $point_color,
+            'strokeWidth'  => 2,
+            'label'        => $label,
+            'labelYOffset' => -8,
+            'fontSize'     => 10,
+        );
+        if ($srid == 0) {
+            $srid = 4326;
+        }
+        $result = $this->getBoundsForOl($srid, $scale_data);
+
+        // Trim to remove leading 'MULTIPOINT(' and trailing ')'
+        $multipoint = substr($spatial, 11, (strlen($spatial) - 12));
+        $points_arr = $this->extractPoints($multipoint, null);
+
+        $result .= 'vectorLayer.addFeatures(new OpenLayers.Feature.Vector('
+            . 'new OpenLayers.Geometry.MultiPoint('
+            . $this->getPointsArrayForOpenLayers($points_arr, $srid)
+            . '), null, ' . json_encode($style_options) . '));';
+        return $result;
+    }
+
+    /**
+     * Generate the WKT with the set of parameters passed by the GIS editor.
+     *
+     * @param array  $gis_data GIS data
+     * @param int    $index    Index into the parameter object
+     * @param string $empty    Multipoint does not adhere to this
+     *
+     * @return string WKT with the set of parameters passed by the GIS editor
+     * @access public
+     */
+    public function generateWkt($gis_data, $index, $empty = '')
+    {
+        $no_of_points = isset($gis_data[$index]['MULTIPOINT']['no_of_points'])
+            ? $gis_data[$index]['MULTIPOINT']['no_of_points'] : 1;
+        if ($no_of_points < 1) {
+            $no_of_points = 1;
+        }
+        $wkt = 'MULTIPOINT(';
+        for ($i = 0; $i < $no_of_points; $i++) {
+            $wkt .= ((isset($gis_data[$index]['MULTIPOINT'][$i]['x'])
+                && trim($gis_data[$index]['MULTIPOINT'][$i]['x']) != '')
+                ? $gis_data[$index]['MULTIPOINT'][$i]['x'] : '')
+                . ' ' . ((isset($gis_data[$index]['MULTIPOINT'][$i]['y'])
+                && trim($gis_data[$index]['MULTIPOINT'][$i]['y']) != '')
+                ? $gis_data[$index]['MULTIPOINT'][$i]['y'] : '') . ',';
+        }
+        $wkt = substr($wkt, 0, strlen($wkt) - 1);
+        $wkt .= ')';
+        return $wkt;
+    }
+
+    /**
+     * Generate the WKT for the data from ESRI shape files.
+     *
+     * @param array $row_data GIS data
+     *
+     * @return string the WKT for the data from ESRI shape files
+     * @access public
+     */
+    public function getShape($row_data)
+    {
+        $wkt = 'MULTIPOINT(';
+        for ($i = 0; $i < $row_data['numpoints']; $i++) {
+            $wkt .= $row_data['points'][$i]['x'] . ' '
+                . $row_data['points'][$i]['y'] . ',';
+        }
+        $wkt = substr($wkt, 0, strlen($wkt) - 1);
+        $wkt .= ')';
+        return $wkt;
+    }
+
+    /**
+     * Generate parameters for the GIS data editor from the value of the GIS column.
+     *
+     * @param string $value of the GIS column
+     * @param index  $index of the geometry
+     *
+     * @return array params for the GIS data editor from the value of the GIS column
+     * @access public
+     */
+    public function generateParams($value, $index = -1)
+    {
+        if ($index == -1) {
+            $index = 0;
+            $params = array();
+            $data = PMA_GIS_Geometry::generateParams($value);
+            $params['srid'] = $data['srid'];
+            $wkt = $data['wkt'];
+        } else {
+            $params[$index]['gis_type'] = 'MULTIPOINT';
+            $wkt = $value;
+        }
+
+        // Trim to remove leading 'MULTIPOINT(' and trailing ')'
+        $points = substr($wkt, 11, (strlen($wkt) - 12));
+        $points_arr = $this->extractPoints($points, null);
+
+        $no_of_points = count($points_arr);
+        $params[$index]['MULTIPOINT']['no_of_points'] = $no_of_points;
+        for ($i = 0; $i < $no_of_points; $i++) {
+            $params[$index]['MULTIPOINT'][$i]['x'] = $points_arr[$i][0];
+            $params[$index]['MULTIPOINT'][$i]['y'] = $points_arr[$i][1];
+        }
+
+        return $params;
+    }
+
+    /**
+     * Overidden to make sure that only the points having valid values
+     * for x and y coordinates are added.
+     *
+     * @param array  $points_arr x and y coordinates for each point
+     * @param string $srid       spatial reference id
+     *
+     * @return string JavaScript for adding an array of points to OpenLayers
+     * @access protected
+     */
+    protected function getPointsArrayForOpenLayers($points_arr, $srid)
+    {
+        $ol_array = 'new Array(';
+        foreach ($points_arr as $point) {
+            if ($point[0] != '' && $point[1] != '') {
+                $ol_array .= $this->getPointForOpenLayers($point, $srid) . ', ';
+            }
+        }
+        if (substr($ol_array, strlen($ol_array) - 2) == ', ') {
+            $ol_array = substr($ol_array, 0, strlen($ol_array) - 2);
+        }
+        $ol_array .= ')';
+
+        return $ol_array;
+    }
+}
+?>
diff --git a/phpmyadmin/libraries/gis/pma_gis_multipolygon.php b/phpmyadmin/libraries/gis/pma_gis_multipolygon.php
new file mode 100644
index 0000000..a8c8241
--- /dev/null
+++ b/phpmyadmin/libraries/gis/pma_gis_multipolygon.php
@@ -0,0 +1,527 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * Handles actions related to GIS MULTIPOLYGON objects
+ *
+ * @package PhpMyAdmin-GIS
+ */
+
+if (! defined('PHPMYADMIN')) {
+    exit;
+}
+
+/**
+ * Handles actions related to GIS MULTIPOLYGON objects
+ *
+ * @package PhpMyAdmin-GIS
+ */
+class PMA_GIS_Multipolygon extends PMA_GIS_Geometry
+{
+    // Hold the singleton instance of the class
+    private static $_instance;
+
+    /**
+     * A private constructor; prevents direct creation of object.
+     *
+     * @access private
+     */
+    private function __construct()
+    {
+    }
+
+    /**
+     * Returns the singleton.
+     *
+     * @return object the singleton
+     * @access public
+     */
+    public static function singleton()
+    {
+        if (!isset(self::$_instance)) {
+            $class = __CLASS__;
+            self::$_instance = new $class;
+        }
+
+        return self::$_instance;
+    }
+
+    /**
+     * Scales each row.
+     *
+     * @param string $spatial spatial data of a row
+     *
+     * @return array an array containing the min, max values for x and y cordinates
+     * @access public
+     */
+    public function scaleRow($spatial)
+    {
+        $min_max = array();
+
+        // Trim to remove leading 'MULTIPOLYGON(((' and trailing ')))'
+        $multipolygon = substr($spatial, 15, (strlen($spatial) - 18));
+        // Seperate each polygon
+        $polygons = explode(")),((", $multipolygon);
+
+        foreach ($polygons as $polygon) {
+            // If the polygon doesn't have an inner ring, use polygon itself
+            if (strpos($polygon, "),(") === false) {
+                $ring = $polygon;
+            } else {
+                // Seperate outer ring and use it to determin min-max
+                $parts = explode("),(", $polygon);
+                $ring = $parts[0];
+            }
+            $min_max = $this->setMinMax($ring, $min_max);
+        }
+
+        return $min_max;
+    }
+
+    /**
+     * Adds to the PNG image object, the data related to a row in the GIS dataset.
+     *
+     * @param string $spatial    GIS MULTIPOLYGON object
+     * @param string $label      Label for the GIS MULTIPOLYGON object
+     * @param string $fill_color Color for the GIS MULTIPOLYGON object
+     * @param array  $scale_data Array containing data related to scaling
+     * @param object $image      Image object
+     *
+     * @return object the modified image object
+     * @access public
+     */
+    public function prepareRowAsPng($spatial, $label, $fill_color,
+        $scale_data, $image
+    ) {
+        // allocate colors
+        $black = imagecolorallocate($image, 0, 0, 0);
+        $red   = hexdec(substr($fill_color, 1, 2));
+        $green = hexdec(substr($fill_color, 3, 2));
+        $blue  = hexdec(substr($fill_color, 4, 2));
+        $color = imagecolorallocate($image, $red, $green, $blue);
+
+        // Trim to remove leading 'MULTIPOLYGON(((' and trailing ')))'
+        $multipolygon = substr($spatial, 15, (strlen($spatial) - 18));
+        // Seperate each polygon
+        $polygons = explode(")),((", $multipolygon);
+
+        $first_poly = true;
+        foreach ($polygons as $polygon) {
+            // If the polygon doesnt have an inner polygon
+            if (strpos($polygon, "),(") === false) {
+                $points_arr = $this->extractPoints($polygon, $scale_data, true);
+            } else {
+                // Seperate outer and inner polygons
+                $parts = explode("),(", $polygon);
+                $outer = $parts[0];
+                $inner = array_slice($parts, 1);
+
+                $points_arr = $this->extractPoints($outer, $scale_data, true);
+
+                foreach ($inner as $inner_poly) {
+                    $points_arr = array_merge(
+                        $points_arr,
+                        $this->extractPoints($inner_poly, $scale_data, true)
+                    );
+                }
+            }
+            // draw polygon
+            imagefilledpolygon($image, $points_arr, sizeof($points_arr) / 2, $color);
+            // mark label point if applicable
+            if (isset($label) && trim($label) != '' && $first_poly) {
+                $label_point = array($points_arr[2], $points_arr[3]);
+            }
+            $first_poly = false;
+        }
+        // print label if applicable
+        if (isset($label_point)) {
+            imagestring(
+                $image, 1, $points_arr[2], $points_arr[3], trim($label), $black
+            );
+        }
+        return $image;
+    }
+
+    /**
+     * Adds to the TCPDF instance, the data related to a row in the GIS dataset.
+     *
+     * @param string $spatial    GIS MULTIPOLYGON object
+     * @param string $label      Label for the GIS MULTIPOLYGON object
+     * @param string $fill_color Color for the GIS MULTIPOLYGON object
+     * @param array  $scale_data Array containing data related to scaling
+     * @param object $pdf        TCPDF instance
+     *
+     * @return object the modified TCPDF instance
+     * @access public
+     */
+    public function prepareRowAsPdf($spatial, $label, $fill_color, $scale_data, $pdf)
+    {
+        // allocate colors
+        $red   = hexdec(substr($fill_color, 1, 2));
+        $green = hexdec(substr($fill_color, 3, 2));
+        $blue  = hexdec(substr($fill_color, 4, 2));
+        $color = array($red, $green, $blue);
+
+        // Trim to remove leading 'MULTIPOLYGON(((' and trailing ')))'
+        $multipolygon = substr($spatial, 15, (strlen($spatial) - 18));
+        // Seperate each polygon
+        $polygons = explode(")),((", $multipolygon);
+
+        $first_poly = true;
+        foreach ($polygons as $polygon) {
+            // If the polygon doesnt have an inner polygon
+            if (strpos($polygon, "),(") === false) {
+                $points_arr = $this->extractPoints($polygon, $scale_data, true);
+            } else {
+                // Seperate outer and inner polygons
+                $parts = explode("),(", $polygon);
+                $outer = $parts[0];
+                $inner = array_slice($parts, 1);
+
+                $points_arr = $this->extractPoints($outer, $scale_data, true);
+
+                foreach ($inner as $inner_poly) {
+                    $points_arr = array_merge(
+                        $points_arr,
+                        $this->extractPoints($inner_poly, $scale_data, true)
+                    );
+                }
+            }
+            // draw polygon
+            $pdf->Polygon($points_arr, 'F*', array(), $color, true);
+            // mark label point if applicable
+            if (isset($label) && trim($label) != '' && $first_poly) {
+                $label_point = array($points_arr[2], $points_arr[3]);
+            }
+            $first_poly = false;
+        }
+
+        // print label if applicable
+        if (isset($label_point)) {
+            $pdf->SetXY($label_point[0], $label_point[1]);
+            $pdf->SetFontSize(5);
+            $pdf->Cell(0, 0, trim($label));
+        }
+        return $pdf;
+    }
+
+    /**
+     * Prepares and returns the code related to a row in the GIS dataset as SVG.
+     *
+     * @param string $spatial    GIS MULTIPOLYGON object
+     * @param string $label      Label for the GIS MULTIPOLYGON object
+     * @param string $fill_color Color for the GIS MULTIPOLYGON object
+     * @param array  $scale_data Array containing data related to scaling
+     *
+     * @return string the code related to a row in the GIS dataset
+     * @access public
+     */
+    public function prepareRowAsSvg($spatial, $label, $fill_color, $scale_data)
+    {
+        $polygon_options = array(
+            'name'        => $label,
+            'class'       => 'multipolygon vector',
+            'stroke'      => 'black',
+            'stroke-width'=> 0.5,
+            'fill'        => $fill_color,
+            'fill-rule'   => 'evenodd',
+            'fill-opacity'=> 0.8,
+        );
+
+        $row = '';
+
+        // Trim to remove leading 'MULTIPOLYGON(((' and trailing ')))'
+        $multipolygon = substr($spatial, 15, (strlen($spatial) - 18));
+        // Seperate each polygon
+        $polygons = explode(")),((", $multipolygon);
+
+        foreach ($polygons as $polygon) {
+            $row .= '<path d="';
+
+            // If the polygon doesnt have an inner polygon
+            if (strpos($polygon, "),(") === false) {
+                $row .= $this->_drawPath($polygon, $scale_data);
+            } else {
+                // Seperate outer and inner polygons
+                $parts = explode("),(", $polygon);
+                $outer = $parts[0];
+                $inner = array_slice($parts, 1);
+
+                $row .= $this->_drawPath($outer, $scale_data);
+
+                foreach ($inner as $inner_poly) {
+                    $row .= $this->_drawPath($inner_poly, $scale_data);
+                }
+            }
+            $polygon_options['id'] = $label . rand();
+            $row .= '"';
+            foreach ($polygon_options as $option => $val) {
+                $row .= ' ' . $option . '="' . trim($val) . '"';
+            }
+            $row .= '/>';
+        }
+
+        return $row;
+    }
+
+    /**
+     * Prepares JavaScript related to a row in the GIS dataset
+     * to visualize it with OpenLayers.
+     *
+     * @param string $spatial    GIS MULTIPOLYGON object
+     * @param int    $srid       Spatial reference ID
+     * @param string $label      Label for the GIS MULTIPOLYGON object
+     * @param string $fill_color Color for the GIS MULTIPOLYGON object
+     * @param array  $scale_data Array containing data related to scaling
+     *
+     * @return string JavaScript related to a row in the GIS dataset
+     * @access public
+     */
+    public function prepareRowAsOl($spatial, $srid, $label, $fill_color, $scale_data)
+    {
+        $style_options = array(
+            'strokeColor' => '#000000',
+            'strokeWidth' => 0.5,
+            'fillColor'   => $fill_color,
+            'fillOpacity' => 0.8,
+            'label'       => $label,
+            'fontSize'    => 10,
+        );
+        if ($srid == 0) {
+            $srid = 4326;
+        }
+        $row = $this->getBoundsForOl($srid, $scale_data);
+
+        // Trim to remove leading 'MULTIPOLYGON(((' and trailing ')))'
+        $multipolygon = substr($spatial, 15, (strlen($spatial) - 18));
+        // Seperate each polygon
+        $polygons = explode(")),((", $multipolygon);
+
+        $row .= 'vectorLayer.addFeatures(new OpenLayers.Feature.Vector('
+            . 'new OpenLayers.Geometry.MultiPolygon('
+            . $this->getPolygonArrayForOpenLayers($polygons, $srid)
+            . '), null, ' . json_encode($style_options) . '));';
+        return $row;
+    }
+
+    /**
+     * Draws a ring of the polygon using SVG path element.
+     *
+     * @param string $polygon    The ring
+     * @param array  $scale_data Array containing data related to scaling
+     *
+     * @return string the code to draw the ring
+     * @access private
+     */
+    private function _drawPath($polygon, $scale_data)
+    {
+        $points_arr = $this->extractPoints($polygon, $scale_data);
+
+        $row = ' M ' . $points_arr[0][0] . ', ' . $points_arr[0][1];
+        $other_points = array_slice($points_arr, 1, count($points_arr) - 2);
+        foreach ($other_points as $point) {
+            $row .= ' L ' . $point[0] . ', ' . $point[1];
+        }
+        $row .= ' Z ';
+
+        return $row;
+    }
+
+    /**
+     * Generate the WKT with the set of parameters passed by the GIS editor.
+     *
+     * @param array  $gis_data GIS data
+     * @param int    $index    Index into the parameter object
+     * @param string $empty    Value for empty points
+     *
+     * @return string WKT with the set of parameters passed by the GIS editor
+     * @access public
+     */
+    public function generateWkt($gis_data, $index, $empty = '')
+    {
+        $data_row = $gis_data[$index]['MULTIPOLYGON'];
+
+        $no_of_polygons = isset($data_row['no_of_polygons'])
+            ? $data_row['no_of_polygons'] : 1;
+        if ($no_of_polygons < 1) {
+            $no_of_polygons = 1;
+        }
+
+        $wkt = 'MULTIPOLYGON(';
+        for ($k = 0; $k < $no_of_polygons; $k++) {
+            $no_of_lines = isset($data_row[$k]['no_of_lines'])
+                ? $data_row[$k]['no_of_lines'] : 1;
+            if ($no_of_lines < 1) {
+                $no_of_lines = 1;
+            }
+            $wkt .= '(';
+            for ($i = 0; $i < $no_of_lines; $i++) {
+                $no_of_points = isset($data_row[$k][$i]['no_of_points'])
+                    ? $data_row[$k][$i]['no_of_points'] : 4;
+                if ($no_of_points < 4) {
+                    $no_of_points = 4;
+                }
+                $wkt .= '(';
+                for ($j = 0; $j < $no_of_points; $j++) {
+                    $wkt .= ((isset($data_row[$k][$i][$j]['x'])
+                        && trim($data_row[$k][$i][$j]['x']) != '')
+                        ? $data_row[$k][$i][$j]['x'] : $empty)
+                        . ' ' . ((isset($data_row[$k][$i][$j]['y'])
+                        && trim($data_row[$k][$i][$j]['y']) != '')
+                        ? $data_row[$k][$i][$j]['y'] : $empty) .',';
+                }
+                $wkt = substr($wkt, 0, strlen($wkt) - 1);
+                $wkt .= '),';
+            }
+            $wkt = substr($wkt, 0, strlen($wkt) - 1);
+            $wkt .= '),';
+        }
+        $wkt = substr($wkt, 0, strlen($wkt) - 1);
+        $wkt .= ')';
+        return $wkt;
+    }
+
+    /**
+     * Generate the WKT for the data from ESRI shape files.
+     *
+     * @param array $row_data GIS data
+     *
+     * @return string the WKT for the data from ESRI shape files
+     * @access public
+     */
+    public function getShape($row_data)
+    {
+        // Determines whether each line ring is an inner ring or an outer ring.
+        // If it's an inner ring get a point on the surface which can be used to
+        // correctly classify inner rings to their respective outer rings.
+        include_once './libraries/gis/pma_gis_polygon.php';
+        foreach ($row_data['parts'] as $i => $ring) {
+            $row_data['parts'][$i]['isOuter']
+                = PMA_GIS_Polygon::isOuterRing($ring['points']);
+        }
+
+        // Find points on surface for inner rings
+        foreach ($row_data['parts'] as $i => $ring) {
+            if (! $ring['isOuter']) {
+                $row_data['parts'][$i]['pointOnSurface']
+                    = PMA_GIS_Polygon::getPointOnSurface($ring['points']);
+            }
+        }
+
+        // Classify inner rings to their respective outer rings.
+        foreach ($row_data['parts'] as $j => $ring1) {
+            if (! $ring1['isOuter']) {
+                foreach ($row_data['parts'] as $k => $ring2) {
+                    if ($ring2['isOuter']) {
+                        // If the pointOnSurface of the inner ring
+                        // is also inside the outer ring
+                        if (PMA_GIS_Polygon::isPointInsidePolygon(
+                            $ring1['pointOnSurface'], $ring2['points']
+                        )) {
+                            if (! isset($ring2['inner'])) {
+                                $row_data['parts'][$k]['inner'] = array();
+                            }
+                            $row_data['parts'][$k]['inner'][] = $j;
+                        }
+                    }
+                }
+            }
+        }
+
+        $wkt = 'MULTIPOLYGON(';
+        // for each polygon
+        foreach ($row_data['parts'] as $ring) {
+            if ($ring['isOuter']) {
+                $wkt .= '('; // start of polygon
+
+                $wkt .= '('; // start of outer ring
+                foreach ($ring['points'] as $point) {
+                    $wkt .= $point['x'] . ' ' . $point['y'] . ',';
+                }
+                $wkt = substr($wkt, 0, strlen($wkt) - 1);
+                $wkt .= ')'; // end of outer ring
+
+                // inner rings if any
+                if (isset($ring['inner'])) {
+                    foreach ($ring['inner'] as $j) {
+                        $wkt .= ',('; // start of inner ring
+                        foreach ($row_data['parts'][$j]['points'] as $innerPoint) {
+                            $wkt .= $innerPoint['x'] . ' ' . $innerPoint['y'] . ',';
+                        }
+                        $wkt = substr($wkt, 0, strlen($wkt) - 1);
+                        $wkt .= ')';  // end of inner ring
+                    }
+                }
+
+                $wkt .= '),'; // end of polygon
+            }
+        }
+        $wkt = substr($wkt, 0, strlen($wkt) - 1);
+
+        $wkt .= ')'; // end of multipolygon
+        return $wkt;
+    }
+
+    /**
+     * Generate parameters for the GIS data editor from the value of the GIS column.
+     *
+     * @param string $value of the GIS column
+     * @param index  $index of the geometry
+     *
+     * @return array params for the GIS data editor from the value of the GIS column
+     * @access public
+     */
+    public function generateParams($value, $index = -1)
+    {
+        if ($index == -1) {
+            $index = 0;
+            $params = array();
+            $data = PMA_GIS_Geometry::generateParams($value);
+            $params['srid'] = $data['srid'];
+            $wkt = $data['wkt'];
+        } else {
+            $params[$index]['gis_type'] = 'MULTIPOLYGON';
+            $wkt = $value;
+        }
+
+        // Trim to remove leading 'MULTIPOLYGON(((' and trailing ')))'
+        $multipolygon = substr($wkt, 15, (strlen($wkt) - 18));
+        // Seperate each polygon
+        $polygons = explode(")),((", $multipolygon);
+
+        $param_row =& $params[$index]['MULTIPOLYGON'];
+        $param_row['no_of_polygons'] = count($polygons);
+
+        $k = 0;
+        foreach ($polygons as $polygon) {
+            // If the polygon doesnt have an inner polygon
+            if (strpos($polygon, "),(") === false) {
+                $param_row[$k]['no_of_lines'] = 1;
+                $points_arr = $this->extractPoints($polygon, null);
+                $no_of_points = count($points_arr);
+                $param_row[$k][0]['no_of_points'] = $no_of_points;
+                for ($i = 0; $i < $no_of_points; $i++) {
+                    $param_row[$k][0][$i]['x'] = $points_arr[$i][0];
+                    $param_row[$k][0][$i]['y'] = $points_arr[$i][1];
+                }
+            } else {
+                // Seperate outer and inner polygons
+                $parts = explode("),(", $polygon);
+                $param_row[$k]['no_of_lines'] = count($parts);
+                $j = 0;
+                foreach ($parts as $ring) {
+                    $points_arr = $this->extractPoints($ring, null);
+                    $no_of_points = count($points_arr);
+                    $param_row[$k][$j]['no_of_points'] = $no_of_points;
+                    for ($i = 0; $i < $no_of_points; $i++) {
+                        $param_row[$k][$j][$i]['x'] = $points_arr[$i][0];
+                        $param_row[$k][$j][$i]['y'] = $points_arr[$i][1];
+                    }
+                    $j++;
+                }
+            }
+            $k++;
+        }
+        return $params;
+    }
+}
+?>
diff --git a/phpmyadmin/libraries/gis/pma_gis_point.php b/phpmyadmin/libraries/gis/pma_gis_point.php
new file mode 100644
index 0000000..e1e4d23
--- /dev/null
+++ b/phpmyadmin/libraries/gis/pma_gis_point.php
@@ -0,0 +1,294 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * Handles actions related to GIS POINT objects
+ *
+ * @package PhpMyAdmin-GIS
+ */
+
+if (! defined('PHPMYADMIN')) {
+    exit;
+}
+
+/**
+ * Handles actions related to GIS POINT objects
+ *
+ * @package PhpMyAdmin-GIS
+ */
+class PMA_GIS_Point extends PMA_GIS_Geometry
+{
+    // Hold the singleton instance of the class
+    private static $_instance;
+
+    /**
+     * A private constructor; prevents direct creation of object.
+     *
+     * @access private
+     */
+    private function __construct()
+    {
+    }
+
+    /**
+     * Returns the singleton.
+     *
+     * @return object the singleton
+     * @access public
+     */
+    public static function singleton()
+    {
+        if (!isset(self::$_instance)) {
+            $class = __CLASS__;
+            self::$_instance = new $class;
+        }
+
+        return self::$_instance;
+    }
+
+    /**
+     * Scales each row.
+     *
+     * @param string $spatial spatial data of a row
+     *
+     * @return array an array containing the min, max values for x and y cordinates
+     * @access public
+     */
+    public function scaleRow($spatial)
+    {
+        // Trim to remove leading 'POINT(' and trailing ')'
+        $point = substr($spatial, 6, (strlen($spatial) - 7));
+        return $this->setMinMax($point, array());
+    }
+
+    /**
+     * Adds to the PNG image object, the data related to a row in the GIS dataset.
+     *
+     * @param string $spatial     GIS POINT object
+     * @param string $label       Label for the GIS POINT object
+     * @param string $point_color Color for the GIS POINT object
+     * @param array  $scale_data  Array containing data related to scaling
+     * @param object $image       Image object
+     *
+     * @return object the modified image object
+     * @access public
+     */
+    public function prepareRowAsPng($spatial, $label, $point_color,
+        $scale_data, $image
+    ) {
+        // allocate colors
+        $black = imagecolorallocate($image, 0, 0, 0);
+        $red   = hexdec(substr($point_color, 1, 2));
+        $green = hexdec(substr($point_color, 3, 2));
+        $blue  = hexdec(substr($point_color, 4, 2));
+        $color = imagecolorallocate($image, $red, $green, $blue);
+
+        // Trim to remove leading 'POINT(' and trailing ')'
+        $point = substr($spatial, 6, (strlen($spatial) - 7));
+        $points_arr = $this->extractPoints($point, $scale_data);
+
+        // draw a small circle to mark the point
+        if ($points_arr[0][0] != '' && $points_arr[0][1] != '') {
+            imagearc(
+                $image, $points_arr[0][0], $points_arr[0][1], 7, 7, 0, 360, $color
+            );
+            // print label if applicable
+            if (isset($label) && trim($label) != '') {
+                imagestring(
+                    $image, 1, $points_arr[0][0],
+                    $points_arr[0][1], trim($label), $black
+                );
+            }
+        }
+        return $image;
+    }
+
+    /**
+     * Adds to the TCPDF instance, the data related to a row in the GIS dataset.
+     *
+     * @param string $spatial     GIS POINT object
+     * @param string $label       Label for the GIS POINT object
+     * @param string $point_color Color for the GIS POINT object
+     * @param array  $scale_data  Array containing data related to scaling
+     * @param object $pdf         TCPDF instance
+     *
+     * @return object the modified TCPDF instance
+     * @access public
+     */
+    public function prepareRowAsPdf($spatial, $label, $point_color,
+        $scale_data, $pdf
+    ) {
+        // allocate colors
+        $red   = hexdec(substr($point_color, 1, 2));
+        $green = hexdec(substr($point_color, 3, 2));
+        $blue  = hexdec(substr($point_color, 4, 2));
+        $line  = array('width' => 1.25, 'color' => array($red, $green, $blue));
+
+        // Trim to remove leading 'POINT(' and trailing ')'
+        $point = substr($spatial, 6, (strlen($spatial) - 7));
+        $points_arr = $this->extractPoints($point, $scale_data);
+
+        // draw a small circle to mark the point
+        if ($points_arr[0][0] != '' && $points_arr[0][1] != '') {
+            $pdf->Circle(
+                $points_arr[0][0], $points_arr[0][1], 2, 0, 360, 'D', $line
+            );
+            // print label if applicable
+            if (isset($label) && trim($label) != '') {
+                $pdf->SetXY($points_arr[0][0], $points_arr[0][1]);
+                $pdf->SetFontSize(5);
+                $pdf->Cell(0, 0, trim($label));
+            }
+        }
+        return $pdf;
+    }
+
+    /**
+     * Prepares and returns the code related to a row in the GIS dataset as SVG.
+     *
+     * @param string $spatial     GIS POINT object
+     * @param string $label       Label for the GIS POINT object
+     * @param string $point_color Color for the GIS POINT object
+     * @param array  $scale_data  Array containing data related to scaling
+     *
+     * @return string the code related to a row in the GIS dataset
+     * @access public
+     */
+    public function prepareRowAsSvg($spatial, $label, $point_color, $scale_data)
+    {
+        $point_options = array(
+            'name'        => $label,
+            'id'          => $label . rand(),
+            'class'       => 'point vector',
+            'fill'        => 'white',
+            'stroke'      => $point_color,
+            'stroke-width'=> 2,
+        );
+
+        // Trim to remove leading 'POINT(' and trailing ')'
+        $point = substr($spatial, 6, (strlen($spatial) - 7));
+        $points_arr = $this->extractPoints($point, $scale_data);
+
+        $row = '';
+        if ($points_arr[0][0] != '' && $points_arr[0][1] != '') {
+            $row .= '<circle cx="' . $points_arr[0][0]
+                . '" cy="' . $points_arr[0][1] . '" r="3"';
+            foreach ($point_options as $option => $val) {
+                $row .= ' ' . $option . '="' . trim($val) . '"';
+            }
+            $row .= '/>';
+        }
+
+        return $row;
+    }
+
+    /**
+     * Prepares JavaScript related to a row in the GIS dataset
+     * to visualize it with OpenLayers.
+     *
+     * @param string $spatial     GIS POINT object
+     * @param int    $srid        Spatial reference ID
+     * @param string $label       Label for the GIS POINT object
+     * @param string $point_color Color for the GIS POINT object
+     * @param array  $scale_data  Array containing data related to scaling
+     *
+     * @return string JavaScript related to a row in the GIS dataset
+     * @access public
+     */
+    public function prepareRowAsOl($spatial, $srid, $label,
+        $point_color, $scale_data
+    ) {
+        $style_options = array(
+            'pointRadius'  => 3,
+            'fillColor'    => '#ffffff',
+            'strokeColor'  => $point_color,
+            'strokeWidth'  => 2,
+            'label'        => $label,
+            'labelYOffset' => -8,
+            'fontSize'     => 10,
+        );
+        if ($srid == 0) {
+            $srid = 4326;
+        }
+        $result = $this->getBoundsForOl($srid, $scale_data);
+
+        // Trim to remove leading 'POINT(' and trailing ')'
+        $point = substr($spatial, 6, (strlen($spatial) - 7));
+        $points_arr = $this->extractPoints($point, null);
+
+        if ($points_arr[0][0] != '' && $points_arr[0][1] != '') {
+            $result .= 'vectorLayer.addFeatures(new OpenLayers.Feature.Vector('
+                . $this->getPointForOpenLayers($points_arr[0], $srid). ', null, '
+                . json_encode($style_options) . '));';
+        }
+        return $result;
+    }
+
+    /**
+     * Generate the WKT with the set of parameters passed by the GIS editor.
+     *
+     * @param array  $gis_data GIS data
+     * @param int    $index    Index into the parameter object
+     * @param string $empty    Point deos not adhere to this parameter
+     *
+     * @return string WKT with the set of parameters passed by the GIS editor
+     * @access public
+     */
+    public function generateWkt($gis_data, $index, $empty = '')
+    {
+         return 'POINT('
+             . ((isset($gis_data[$index]['POINT']['x'])
+                 && trim($gis_data[$index]['POINT']['x']) != '')
+             ? $gis_data[$index]['POINT']['x'] : '')
+             . ' '
+             . ((isset($gis_data[$index]['POINT']['y'])
+                 && trim($gis_data[$index]['POINT']['y']) != '')
+             ? $gis_data[$index]['POINT']['y'] : '') . ')';
+    }
+
+    /**
+     * Generate the WKT for the data from ESRI shape files.
+     *
+     * @param array $row_data GIS data
+     *
+     * @return string the WKT for the data from ESRI shape files
+     * @access public
+     */
+    public function getShape($row_data)
+    {
+        return 'POINT(' . (isset($row_data['x']) ? $row_data['x'] : '')
+             . ' ' . (isset($row_data['y']) ? $row_data['y'] : '') . ')';
+    }
+
+    /**
+     * Generate parameters for the GIS data editor from the value of the GIS column.
+     *
+     * @param string $value of the GIS column
+     * @param index  $index of the geometry
+     *
+     * @return array params for the GIS data editor from the value of the GIS column
+     * @access public
+     */
+    public function generateParams($value, $index = -1)
+    {
+        if ($index == -1) {
+            $index = 0;
+            $params = array();
+            $data = PMA_GIS_Geometry::generateParams($value);
+            $params['srid'] = $data['srid'];
+            $wkt = $data['wkt'];
+        } else {
+            $params[$index]['gis_type'] = 'POINT';
+            $wkt = $value;
+        }
+
+        // Trim to remove leading 'POINT(' and trailing ')'
+        $point = substr($wkt, 6, (strlen($wkt) - 7));
+        $points_arr = $this->extractPoints($point, null);
+
+        $params[$index]['POINT']['x'] = $points_arr[0][0];
+        $params[$index]['POINT']['y'] = $points_arr[0][1];
+
+        return $params;
+    }
+}
+?>
diff --git a/phpmyadmin/libraries/gis/pma_gis_polygon.php b/phpmyadmin/libraries/gis/pma_gis_polygon.php
new file mode 100644
index 0000000..47dde13
--- /dev/null
+++ b/phpmyadmin/libraries/gis/pma_gis_polygon.php
@@ -0,0 +1,549 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * Handles actions related to GIS POLYGON objects
+ *
+ * @package PhpMyAdmin-GIS
+ */
+
+if (! defined('PHPMYADMIN')) {
+    exit;
+}
+
+/**
+ * Handles actions related to GIS POLYGON objects
+ *
+ * @package PhpMyAdmin-GIS
+ */
+class PMA_GIS_Polygon extends PMA_GIS_Geometry
+{
+    // Hold the singleton instance of the class
+    private static $_instance;
+
+    /**
+     * A private constructor; prevents direct creation of object.
+     *
+     * @access private
+     */
+    private function __construct()
+    {
+    }
+
+    /**
+     * Returns the singleton.
+     *
+     * @return object the singleton
+     * @access public
+     */
+    public static function singleton()
+    {
+        if (!isset(self::$_instance)) {
+            $class = __CLASS__;
+            self::$_instance = new $class;
+        }
+
+        return self::$_instance;
+    }
+
+    /**
+     * Scales each row.
+     *
+     * @param string $spatial spatial data of a row
+     *
+     * @return array an array containing the min, max values for x and y cordinates
+     * @access public
+     */
+    public function scaleRow($spatial)
+    {
+        // Trim to remove leading 'POLYGON((' and trailing '))'
+        $polygon = substr($spatial, 9, (strlen($spatial) - 11));
+
+        // If the polygon doesn't have an inner ring, use polygon itself
+        if (strpos($polygon, "),(") === false) {
+            $ring = $polygon;
+        } else {
+            // Seperate outer ring and use it to determin min-max
+            $parts = explode("),(", $polygon);
+            $ring = $parts[0];
+        }
+        return $this->setMinMax($ring, array());
+    }
+
+    /**
+     * Adds to the PNG image object, the data related to a row in the GIS dataset.
+     *
+     * @param string $spatial    GIS POLYGON object
+     * @param string $label      Label for the GIS POLYGON object
+     * @param string $fill_color Color for the GIS POLYGON object
+     * @param array  $scale_data Array containing data related to scaling
+     * @param object $image      Image object
+     *
+     * @return object the modified image object
+     * @access public
+     */
+    public function prepareRowAsPng($spatial, $label, $fill_color,
+        $scale_data, $image
+    ) {
+        // allocate colors
+        $black = imagecolorallocate($image, 0, 0, 0);
+        $red   = hexdec(substr($fill_color, 1, 2));
+        $green = hexdec(substr($fill_color, 3, 2));
+        $blue  = hexdec(substr($fill_color, 4, 2));
+        $color = imagecolorallocate($image, $red, $green, $blue);
+
+        // Trim to remove leading 'POLYGON((' and trailing '))'
+        $polygon = substr($spatial, 9, (strlen($spatial) - 11));
+
+        // If the polygon doesnt have an inner polygon
+        if (strpos($polygon, "),(") === false) {
+            $points_arr = $this->extractPoints($polygon, $scale_data, true);
+        } else {
+            // Seperate outer and inner polygons
+            $parts = explode("),(", $polygon);
+            $outer = $parts[0];
+            $inner = array_slice($parts, 1);
+
+            $points_arr = $this->extractPoints($outer, $scale_data, true);
+
+            foreach ($inner as $inner_poly) {
+                $points_arr = array_merge(
+                    $points_arr, $this->extractPoints($inner_poly, $scale_data, true)
+                );
+            }
+        }
+
+        // draw polygon
+        imagefilledpolygon($image, $points_arr, sizeof($points_arr) / 2, $color);
+        // print label if applicable
+        if (isset($label) && trim($label) != '') {
+            imagestring(
+                $image, 1, $points_arr[2], $points_arr[3], trim($label), $black
+            );
+        }
+        return $image;
+    }
+
+    /**
+     * Adds to the TCPDF instance, the data related to a row in the GIS dataset.
+     *
+     * @param string $spatial    GIS POLYGON object
+     * @param string $label      Label for the GIS POLYGON object
+     * @param string $fill_color Color for the GIS POLYGON object
+     * @param array  $scale_data Array containing data related to scaling
+     * @param object $pdf        TCPDF instance
+     *
+     * @return object the modified TCPDF instance
+     * @access public
+     */
+    public function prepareRowAsPdf($spatial, $label, $fill_color, $scale_data, $pdf)
+    {
+        // allocate colors
+        $red   = hexdec(substr($fill_color, 1, 2));
+        $green = hexdec(substr($fill_color, 3, 2));
+        $blue  = hexdec(substr($fill_color, 4, 2));
+        $color = array($red, $green, $blue);
+
+        // Trim to remove leading 'POLYGON((' and trailing '))'
+        $polygon = substr($spatial, 9, (strlen($spatial) - 11));
+
+        // If the polygon doesnt have an inner polygon
+        if (strpos($polygon, "),(") === false) {
+            $points_arr = $this->extractPoints($polygon, $scale_data, true);
+        } else {
+            // Seperate outer and inner polygons
+            $parts = explode("),(", $polygon);
+            $outer = $parts[0];
+            $inner = array_slice($parts, 1);
+
+            $points_arr = $this->extractPoints($outer, $scale_data, true);
+
+            foreach ($inner as $inner_poly) {
+                $points_arr = array_merge(
+                    $points_arr, $this->extractPoints($inner_poly, $scale_data, true)
+                );
+            }
+        }
+
+        // draw polygon
+        $pdf->Polygon($points_arr, 'F*', array(), $color, true);
+        // print label if applicable
+        if (isset($label) && trim($label) != '') {
+            $pdf->SetXY($points_arr[2], $points_arr[3]);
+            $pdf->SetFontSize(5);
+            $pdf->Cell(0, 0, trim($label));
+        }
+        return $pdf;
+    }
+
+    /**
+     * Prepares and returns the code related to a row in the GIS dataset as SVG.
+     *
+     * @param string $spatial    GIS POLYGON object
+     * @param string $label      Label for the GIS POLYGON object
+     * @param string $fill_color Color for the GIS POLYGON object
+     * @param array  $scale_data Array containing data related to scaling
+     *
+     * @return string the code related to a row in the GIS dataset
+     * @access public
+     */
+    public function prepareRowAsSvg($spatial, $label, $fill_color, $scale_data)
+    {
+        $polygon_options = array(
+            'name'        => $label,
+            'id'          => $label . rand(),
+            'class'       => 'polygon vector',
+            'stroke'      => 'black',
+            'stroke-width'=> 0.5,
+            'fill'        => $fill_color,
+            'fill-rule'   => 'evenodd',
+            'fill-opacity'=> 0.8,
+        );
+
+        // Trim to remove leading 'POLYGON((' and trailing '))'
+        $polygon = substr($spatial, 9, (strlen($spatial) - 11));
+
+        $row = '<path d="';
+
+        // If the polygon doesnt have an inner polygon
+        if (strpos($polygon, "),(") === false) {
+            $row .= $this->_drawPath($polygon, $scale_data);
+        } else {
+            // Seperate outer and inner polygons
+            $parts = explode("),(", $polygon);
+            $outer = $parts[0];
+            $inner = array_slice($parts, 1);
+
+            $row .= $this->_drawPath($outer, $scale_data);
+
+            foreach ($inner as $inner_poly) {
+                $row .= $this->_drawPath($inner_poly, $scale_data);
+            }
+        }
+
+        $row .= '"';
+        foreach ($polygon_options as $option => $val) {
+            $row .= ' ' . $option . '="' . trim($val) . '"';
+        }
+        $row .= '/>';
+        return $row;
+    }
+
+    /**
+     * Prepares JavaScript related to a row in the GIS dataset
+     * to visualize it with OpenLayers.
+     *
+     * @param string $spatial    GIS POLYGON object
+     * @param int    $srid       Spatial reference ID
+     * @param string $label      Label for the GIS POLYGON object
+     * @param string $fill_color Color for the GIS POLYGON object
+     * @param array  $scale_data Array containing data related to scaling
+     *
+     * @return string JavaScript related to a row in the GIS dataset
+     * @access public
+     */
+    public function prepareRowAsOl($spatial, $srid, $label, $fill_color, $scale_data)
+    {
+        $style_options = array(
+            'strokeColor' => '#000000',
+            'strokeWidth' => 0.5,
+            'fillColor'   => $fill_color,
+            'fillOpacity' => 0.8,
+            'label'       => $label,
+            'fontSize'    => 10,
+        );
+        if ($srid == 0) {
+            $srid = 4326;
+        }
+        $row = $this->getBoundsForOl($srid, $scale_data);
+
+        // Trim to remove leading 'POLYGON((' and trailing '))'
+        $polygon = substr($spatial, 9, (strlen($spatial) - 11));
+
+        // Seperate outer and inner polygons
+        $parts = explode("),(", $polygon);
+        $row .= 'vectorLayer.addFeatures(new OpenLayers.Feature.Vector('
+            . $this->getPolygonForOpenLayers($parts, $srid)
+            . ', null, ' . json_encode($style_options) . '));';
+        return $row;
+    }
+
+    /**
+     * Draws a ring of the polygon using SVG path element.
+     *
+     * @param string $polygon    The ring
+     * @param array  $scale_data Array containing data related to scaling
+     *
+     * @return string the code to draw the ring
+     * @access private
+     */
+    private function _drawPath($polygon, $scale_data)
+    {
+        $points_arr = $this->extractPoints($polygon, $scale_data);
+
+        $row = ' M ' . $points_arr[0][0] . ', ' . $points_arr[0][1];
+        $other_points = array_slice($points_arr, 1, count($points_arr) - 2);
+        foreach ($other_points as $point) {
+            $row .= ' L ' . $point[0] . ', ' . $point[1];
+        }
+        $row .= ' Z ';
+
+        return $row;
+    }
+
+    /**
+     * Generate the WKT with the set of parameters passed by the GIS editor.
+     *
+     * @param array  $gis_data GIS data
+     * @param int    $index    Index into the parameter object
+     * @param string $empty    Value for empty points
+     *
+     * @return string WKT with the set of parameters passed by the GIS editor
+     * @access public
+     */
+    public function generateWkt($gis_data, $index, $empty = '')
+    {
+        $no_of_lines = isset($gis_data[$index]['POLYGON']['no_of_lines'])
+            ? $gis_data[$index]['POLYGON']['no_of_lines'] : 1;
+        if ($no_of_lines < 1) {
+            $no_of_lines = 1;
+        }
+        $wkt = 'POLYGON(';
+        for ($i = 0; $i < $no_of_lines; $i++) {
+            $no_of_points = isset($gis_data[$index]['POLYGON'][$i]['no_of_points'])
+                ? $gis_data[$index]['POLYGON'][$i]['no_of_points'] : 4;
+            if ($no_of_points < 4) {
+                $no_of_points = 4;
+            }
+            $wkt .= '(';
+            for ($j = 0; $j < $no_of_points; $j++) {
+                $wkt .= ((isset($gis_data[$index]['POLYGON'][$i][$j]['x'])
+                    && trim($gis_data[$index]['POLYGON'][$i][$j]['x']) != '')
+                    ? $gis_data[$index]['POLYGON'][$i][$j]['x'] : $empty)
+                    . ' ' . ((isset($gis_data[$index]['POLYGON'][$i][$j]['y'])
+                    && trim($gis_data[$index]['POLYGON'][$i][$j]['y']) != '')
+                    ? $gis_data[$index]['POLYGON'][$i][$j]['y'] : $empty) .',';
+            }
+            $wkt = substr($wkt, 0, strlen($wkt) - 1);
+            $wkt .= '),';
+        }
+        $wkt = substr($wkt, 0, strlen($wkt) - 1);
+        $wkt .= ')';
+        return $wkt;
+    }
+
+    /**
+     * Calculates the area of a closed simple polygon.
+     *
+     * @param array $ring array of points forming the ring
+     *
+     * @return float the area of a closed simple polygon
+     * @access public
+     * @static
+     */
+    public static function area($ring)
+    {
+
+        $no_of_points = count($ring);
+
+        // If the last point is same as the first point ignore it
+        $last = count($ring) - 1;
+        if (($ring[0]['x'] == $ring[$last]['x'])
+            && ($ring[0]['y'] == $ring[$last]['y'])
+        ) {
+            $no_of_points--;
+        }
+
+        //         _n-1
+        // A = _1_ \    (X(i) * Y(i+1)) - (Y(i) * X(i+1))
+        //      2  /__
+        //         i=0
+        $area = 0;
+        for ($i = 0; $i < $no_of_points; $i++) {
+            $j = ($i + 1) % $no_of_points;
+            $area += $ring[$i]['x'] * $ring[$j]['y'];
+            $area -= $ring[$i]['y'] * $ring[$j]['x'];
+        }
+        $area /= 2.0;
+
+        return $area;
+    }
+
+    /**
+     * Determines whether a set of points represents an outer ring.
+     * If points are in clockwise orientation then, they form an outer ring.
+     *
+     * @param array $ring array of points forming the ring
+     *
+     * @return bool whether a set of points represents an outer ring
+     * @access public
+     * @static
+     */
+    public static function isOuterRing($ring)
+    {
+        // If area is negative then it's in clockwise orientation,
+        // i.e. it's an outer ring
+        if (PMA_GIS_Polygon::area($ring) < 0) {
+            return true;
+        }
+        return false;
+    }
+
+    /**
+     * Determines whether a given point is inside a given polygon.
+     *
+     * @param array $point   x, y coordinates of the point
+     * @param array $polygon array of points forming the ring
+     *
+     * @return bool whether a given point is inside a given polygon
+     * @access public
+     * @static
+     */
+    public static function isPointInsidePolygon($point, $polygon)
+    {
+        // If first point is repeated at the end remove it
+        $last = count($polygon) - 1;
+        if (($polygon[0]['x'] == $polygon[$last]['x'])
+            && ($polygon[0]['y'] == $polygon[$last]['y'])
+        ) {
+            $polygon = array_slice($polygon, 0, $last);
+        }
+
+        $no_of_points = count($polygon);
+        $counter = 0;
+
+        // Use ray casting algorithm
+        $p1 = $polygon[0];
+        for ($i = 1; $i <= $no_of_points; $i++) {
+            $p2 = $polygon[$i % $no_of_points];
+            if ($point['y'] > min(array($p1['y'], $p2['y']))) {
+                if ($point['y'] <= max(array($p1['y'], $p2['y']))) {
+                    if ($point['x'] <= max(array($p1['x'], $p2['x']))) {
+                        if ($p1['y'] != $p2['y']) {
+                            $xinters = ($point['y'] - $p1['y'])
+                                * ($p2['x'] - $p1['x'])
+                                / ($p2['y'] - $p1['y']) + $p1['x'];
+                            if ($p1['x'] == $p2['x'] || $point['x'] <= $xinters) {
+                                $counter++;
+                            }
+                        }
+                    }
+                }
+            }
+            $p1 = $p2;
+        }
+
+        if ($counter % 2 == 0) {
+            return  false;
+        } else {
+            return true;
+        }
+    }
+
+    /**
+     * Returns a point that is guaranteed to be on the surface of the ring.
+     * (for simple closed rings)
+     *
+     * @param array $ring array of points forming the ring
+     *
+     * @return array a point on the surface of the ring
+     * @access public
+     * @static
+     */
+    public static function getPointOnSurface($ring)
+    {
+        // Find two consecutive distinct points.
+        for ($i = 0; $i < count($ring) - 1; $i++) {
+            if ($ring[$i]['y'] != $ring[$i + 1]['y']) {
+                $x0 = $ring[$i]['x'];
+                $x1 = $ring[$i + 1]['x'];
+                $y0 = $ring[$i]['y'];
+                $y1 = $ring[$i + 1]['y'];
+                break;
+            }
+        }
+
+        if (! isset($x0)) {
+            return false;
+        }
+
+        // Find the mid point
+        $x2 = ($x0 + $x1) / 2;
+        $y2 = ($y0 + $y1) / 2;
+
+        // Always keep $epsilon < 1 to go with the reduction logic down here
+        $epsilon = 0.1;
+        $denominator = sqrt(
+            PMA_Util::pow(($y1 - $y0), 2)
+            + PMA_Util::pow(($x0 - $x1), 2)
+        );
+        $pointA = array(); $pointB = array();
+
+        while (true) {
+            // Get the points on either sides of the line
+            // with a distance of epsilon to the mid point
+            $pointA['x'] = $x2 + ($epsilon * ($y1 - $y0)) / $denominator;
+            $pointA['y'] = $y2 + ($pointA['x'] - $x2) * ($x0 - $x1) / ($y1 - $y0);
+
+            $pointB['x'] = $x2 + ($epsilon * ($y1 - $y0)) / (0 - $denominator);
+            $pointB['y'] = $y2 + ($pointB['x'] - $x2) * ($x0 - $x1) / ($y1 - $y0);
+
+            // One of the points should be inside the polygon,
+            // unless epcilon chosen is too large
+            if (PMA_GIS_Polygon::isPointInsidePolygon($pointA, $ring)) {
+                return $pointA;
+            } elseif (PMA_GIS_Polygon::isPointInsidePolygon($pointB, $ring)) {
+                return $pointB;
+            } else {
+                //If both are outside the polygon reduce the epsilon and
+                //recalculate the points(reduce exponentially for faster convergance)
+                $epsilon = PMA_Util::pow($epsilon, 2);
+                if ($epsilon == 0) {
+                    return false;
+                }
+            }
+
+        }
+    }
+
+    /** Generate parameters for the GIS data editor from the value of the GIS column.
+     *
+     * @param string $value of the GIS column
+     * @param index  $index of the geometry
+     *
+     * @return array params for the GIS data editor from the value of the GIS column
+     * @access public
+     */
+    public function generateParams($value, $index = -1)
+    {
+        if ($index == -1) {
+            $index = 0;
+            $params = array();
+            $data = PMA_GIS_Geometry::generateParams($value);
+            $params['srid'] = $data['srid'];
+            $wkt = $data['wkt'];
+        } else {
+            $params[$index]['gis_type'] = 'POLYGON';
+            $wkt = $value;
+        }
+
+        // Trim to remove leading 'POLYGON((' and trailing '))'
+        $polygon = substr($wkt, 9, (strlen($wkt) - 11));
+        // Seperate each linestring
+        $linerings = explode("),(", $polygon);
+        $params[$index]['POLYGON']['no_of_lines'] = count($linerings);
+
+        $j = 0;
+        foreach ($linerings as $linering) {
+            $points_arr = $this->extractPoints($linering, null);
+            $no_of_points = count($points_arr);
+            $params[$index]['POLYGON'][$j]['no_of_points'] = $no_of_points;
+            for ($i = 0; $i < $no_of_points; $i++) {
+                $params[$index]['POLYGON'][$j][$i]['x'] = $points_arr[$i][0];
+                $params[$index]['POLYGON'][$j][$i]['y'] = $points_arr[$i][1];
+            }
+            $j++;
+        }
+        return $params;
+    }
+}
+?>
diff --git a/phpmyadmin/libraries/gis/pma_gis_visualization.php b/phpmyadmin/libraries/gis/pma_gis_visualization.php
new file mode 100644
index 0000000..c49589e
--- /dev/null
+++ b/phpmyadmin/libraries/gis/pma_gis_visualization.php
@@ -0,0 +1,503 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * Handles visualization of GIS data
+ *
+ * @package PhpMyAdmin-GIS
+ */
+
+if (! defined('PHPMYADMIN')) {
+    exit;
+}
+
+/**
+ * Handles visualization of GIS data
+ *
+ * @package PhpMyAdmin-GIS
+ */
+class PMA_GIS_Visualization
+{
+    /**
+     * @var array   Raw data for the visualization
+     */
+    private $_data;
+
+    /**
+     * @var array   Set of default settigs values are here.
+     */
+    private $_settings = array(
+
+        // Array of colors to be used for GIS visualizations.
+        'colors' => array(
+            '#B02EE0',
+            '#E0642E',
+            '#E0D62E',
+            '#2E97E0',
+            '#BCE02E',
+            '#E02E75',
+            '#5CE02E',
+            '#E0B02E',
+            '#0022E0',
+            '#726CB1',
+            '#481A36',
+            '#BAC658',
+            '#127224',
+            '#825119',
+            '#238C74',
+            '#4C489B',
+            '#87C9BF',
+        ),
+
+        // The width of the GIS visualization.
+        'width' => 600,
+
+         // The height of the GIS visualization.
+        'height' => 450,
+    );
+
+    /**
+     * @var array   Options that the user has specified.
+     */
+    private $_userSpecifiedSettings = null;
+
+    /**
+     * Returns the settings array
+     *
+     * @return array the settings array
+     * @access public
+     */
+    public function getSettings()
+    {
+        return $this->_settings;
+    }
+
+    /**
+     * Constructor. Stores user specified options.
+     *
+     * @param array $data    Data for the visualization
+     * @param array $options Users specified options
+     *
+     * @access public
+     */
+    public function __construct($data, $options)
+    {
+        $this->_userSpecifiedSettings = $options;
+        $this->_data = $data;
+    }
+
+    /**
+     * All the variable initialization, options handling has to be done here.
+     *
+     * @return void
+     * @access protected
+     */
+    protected function init()
+    {
+        $this->_handleOptions();
+    }
+
+    /**
+     * A function which handles passed parameters. Useful if desired
+     * chart needs to be a little bit different from the default one.
+     *
+     * @return void
+     * @access private
+     */
+    private function _handleOptions()
+    {
+        if (! is_null($this->_userSpecifiedSettings)) {
+            $this->_settings = array_merge(
+                $this->_settings,
+                $this->_userSpecifiedSettings
+            );
+        }
+    }
+
+    /**
+     * Sanitizes the file name.
+     *
+     * @param string $file_name file name
+     * @param string $ext       extension of the file
+     *
+     * @return string the sanitized file name
+     * @access private
+     */
+    private function _sanitizeName($file_name, $ext)
+    {
+        $file_name = PMA_sanitizeFilename($file_name);
+
+        // Check if the user already added extension;
+        // get the substring where the extension would be if it was included
+        $extension_start_pos = strlen($file_name) - strlen($ext) - 1;
+        $user_extension = substr(
+            $file_name, $extension_start_pos, strlen($file_name)
+        );
+        $required_extension = "." . $ext;
+        if (strtolower($user_extension) != $required_extension) {
+            $file_name  .= $required_extension;
+        }
+        return $file_name;
+    }
+
+    /**
+     * Handles common tasks of writing the visualization to file for various formats.
+     *
+     * @param string $file_name file name
+     * @param string $type      mime type
+     * @param string $ext       extension of the file
+     *
+     * @return void
+     * @access private
+     */
+    private function _toFile($file_name, $type, $ext)
+    {
+        $file_name = $this->_sanitizeName($file_name, $ext);
+        PMA_downloadHeader($file_name, $type);
+    }
+
+    /**
+     * Generate the visualization in SVG format.
+     *
+     * @return string the generated image resource
+     * @access private
+     */
+    private function _svg()
+    {
+        $this->init();
+
+        $output   = '<?xml version="1.0" encoding="UTF-8" standalone="no"?>' . "\n";
+        $output  .= '<svg version="1.1" xmlns:svg="http://www.w3.org/2000/svg"'
+            . ' xmlns="http://www.w3.org/2000/svg"'
+            . ' width="' . $this->_settings['width'] . '"'
+            . ' height="' . $this->_settings['height'] . '">';
+        $output .= '<g id="groupPanel">';
+
+        $scale_data = $this->_scaleDataSet($this->_data);
+        $output .= $this->_prepareDataSet($this->_data, $scale_data, 'svg', '');
+
+        $output .= '</g>';
+        $output .= '</svg>';
+
+        return $output;
+    }
+
+    /**
+     * Get the visualization as a SVG.
+     *
+     * @return string the visualization as a SVG
+     * @access public
+     */
+    public function asSVG()
+    {
+        $output = $this->_svg();
+        return $output;
+    }
+
+    /**
+     * Saves as a SVG image to a file.
+     *
+     * @param string $file_name File name
+     *
+     * @return void
+     * @access public
+     */
+    public function toFileAsSvg($file_name)
+    {
+        $img = $this->_svg();
+        $this->_toFile($file_name, 'image/svg+xml', 'svg');
+        echo($img);
+    }
+
+    /**
+     * Generate the visualization in PNG format.
+     *
+     * @return object the generated image resource
+     * @access private
+     */
+    private function _png()
+    {
+        $this->init();
+
+        // create image
+        $image = imagecreatetruecolor(
+            $this->_settings['width'],
+            $this->_settings['height']
+        );
+
+        // fill the background
+        $bg = imagecolorallocate($image, 229, 229, 229);
+        imagefilledrectangle(
+            $image, 0, 0, $this->_settings['width'] - 1,
+            $this->_settings['height'] - 1, $bg
+        );
+
+        $scale_data = $this->_scaleDataSet($this->_data);
+        $image = $this->_prepareDataSet($this->_data, $scale_data, 'png', $image);
+
+        return $image;
+    }
+
+    /**
+     * Get the visualization as a PNG.
+     *
+     * @return string the visualization as a PNG
+     * @access public
+     */
+    public function asPng()
+    {
+        $img = $this->_png();
+
+        // render and save it to variable
+        ob_start();
+        imagepng($img, null, 9, PNG_ALL_FILTERS);
+        imagedestroy($img);
+        $output = ob_get_contents();
+        ob_end_clean();
+
+        // base64 encode
+        $encoded = base64_encode($output);
+        return '<img src="data:image/png;base64,'. $encoded .'" />';
+    }
+
+    /**
+     * Saves as a PNG image to a file.
+     *
+     * @param string $file_name File name
+     *
+     * @return void
+     * @access public
+     */
+    public function toFileAsPng($file_name)
+    {
+        $img = $this->_png();
+        $this->_toFile($file_name, 'image/png', 'png');
+        imagepng($img, null, 9, PNG_ALL_FILTERS);
+        imagedestroy($img);
+    }
+
+    /**
+     * Get the code for visualization with OpenLayers.
+     *
+     * @return string the code for visualization with OpenLayers
+     * @access public
+     */
+    public function asOl()
+    {
+        $this->init();
+        $scale_data = $this->_scaleDataSet($this->_data);
+        $output
+            = 'var options = {'
+                . 'projection: new OpenLayers.Projection("EPSG:900913"),'
+                . 'displayProjection: new OpenLayers.Projection("EPSG:4326"),'
+                . 'units: "m",'
+                . 'numZoomLevels: 18,'
+                . 'maxResolution: 156543.0339,'
+                . 'maxExtent: new OpenLayers.Bounds('
+                . '-20037508, -20037508, 20037508, 20037508),'
+                . 'restrictedExtent: new OpenLayers.Bounds('
+                . '-20037508, -20037508, 20037508, 20037508)'
+            . '};'
+            . 'var map = new OpenLayers.Map("openlayersmap", options);'
+            . 'var layerNone = new OpenLayers.Layer.Boxes('
+            . '"None", {isBaseLayer: true});'
+            . 'var layerMapnik = new OpenLayers.Layer.OSM.Mapnik("Mapnik");'
+            . 'var layerCycleMap = new OpenLayers.Layer.OSM.CycleMap("CycleMap");'
+            . 'map.addLayers([layerMapnik,layerCycleMap,layerNone]);'
+            . 'var vectorLayer = new OpenLayers.Layer.Vector("Data");'
+            . 'var bound;';
+        $output .= $this->_prepareDataSet($this->_data, $scale_data, 'ol', '');
+        $output .=
+              'map.addLayer(vectorLayer);'
+            . 'map.zoomToExtent(bound);'
+            . 'if (map.getZoom() < 2) {'
+                . 'map.zoomTo(2);'
+            . '}'
+            . 'map.addControl(new OpenLayers.Control.LayerSwitcher());'
+            . 'map.addControl(new OpenLayers.Control.MousePosition());';
+        return $output;
+    }
+
+    /**
+     * Saves as a PDF to a file.
+     *
+     * @param string $file_name File name
+     *
+     * @return void
+     * @access public
+     */
+    public function toFileAsPdf($file_name)
+    {
+        $this->init();
+
+        include_once './libraries/tcpdf/tcpdf.php';
+
+        // create pdf
+        $pdf = new TCPDF(
+            '', 'pt', $GLOBALS['cfg']['PDFDefaultPageSize'], true, 'UTF-8', false
+        );
+
+        // disable header and footer
+        $pdf->setPrintHeader(false);
+        $pdf->setPrintFooter(false);
+
+        //set auto page breaks
+        $pdf->SetAutoPageBreak(false);
+
+        // add a page
+        $pdf->AddPage();
+
+        $scale_data = $this->_scaleDataSet($this->_data);
+        $pdf = $this->_prepareDataSet($this->_data, $scale_data, 'pdf', $pdf);
+
+        // sanitize file name
+        $file_name = $this->_sanitizeName($file_name, 'pdf');
+        $pdf->Output($file_name, 'D');
+    }
+
+    /**
+     * Calculates the scale, horizontal and vertical offset that should be used.
+     *
+     * @param array $data Row data
+     *
+     * @return array an array containing the scale, x and y offsets
+     * @access private
+     */
+    private function _scaleDataSet($data)
+    {
+        $min_max = array();
+        $border = 15;
+        // effective width and height of the plot
+        $plot_width = $this->_settings['width'] - 2 * $border;
+        $plot_height = $this->_settings['height'] - 2 * $border;
+
+        foreach ($data as $row) {
+
+            // Figure out the data type
+            $ref_data = $row[$this->_settings['spatialColumn']];
+            $type_pos = stripos($ref_data, '(');
+            $type = substr($ref_data, 0, $type_pos);
+
+            $gis_obj = PMA_GIS_Factory::factory($type);
+            if (! $gis_obj) {
+                continue;
+            }
+            $scale_data = $gis_obj->scaleRow(
+                $row[$this->_settings['spatialColumn']]
+            );
+
+            // Upadate minimum/maximum values for x and y cordinates.
+            $c_maxX = (float) $scale_data['maxX'];
+            if (! isset($min_max['maxX']) || $c_maxX > $min_max['maxX']) {
+                $min_max['maxX'] = $c_maxX;
+            }
+
+            $c_minX = (float) $scale_data['minX'];
+            if (! isset($min_max['minX']) || $c_minX < $min_max['minX']) {
+                $min_max['minX'] = $c_minX;
+            }
+
+            $c_maxY = (float) $scale_data['maxY'];
+            if (! isset($min_max['maxY']) || $c_maxY > $min_max['maxY']) {
+                $min_max['maxY'] = $c_maxY;
+            }
+
+            $c_minY = (float) $scale_data['minY'];
+            if (! isset($min_max['minY']) || $c_minY < $min_max['minY']) {
+                $min_max['minY'] = $c_minY;
+            }
+        }
+
+        // scale the visualization
+        $x_ratio = ($min_max['maxX'] - $min_max['minX']) / $plot_width;
+        $y_ratio = ($min_max['maxY'] - $min_max['minY']) / $plot_height;
+        $ratio = ($x_ratio > $y_ratio) ? $x_ratio : $y_ratio;
+
+        $scale = ($ratio != 0) ? (1 / $ratio) : 1;
+
+        if ($x_ratio < $y_ratio) {
+            // center horizontally
+            $x = ($min_max['maxX'] + $min_max['minX'] - $plot_width / $scale) / 2;
+            // fit vertically
+            $y = $min_max['minY'] - ($border / $scale);
+        } else {
+            // fit horizontally
+            $x = $min_max['minX'] - ($border / $scale);
+            // center vertically
+            $y =($min_max['maxY'] + $min_max['minY'] - $plot_height / $scale) / 2;
+        }
+
+        return array(
+            'scale'  => $scale,
+            'x'      => $x,
+            'y'      => $y,
+            'minX'   => $min_max['minX'],
+            'maxX'   => $min_max['maxX'],
+            'minY'   => $min_max['minY'],
+            'maxY'   => $min_max['maxY'],
+            'height' => $this->_settings['height'],
+        );
+    }
+
+    /**
+     * Prepares and return the dataset as needed by the visualization.
+     *
+     * @param array  $data       Raw data
+     * @param array  $scale_data Data related to scaling
+     * @param string $format     Format of the visulaization
+     * @param object $results    Image object in the case of png
+     *                           TCPDF object in the case of pdf
+     *
+     * @return mixed the formatted array of data
+     * @access private
+     */
+    private function _prepareDataSet($data, $scale_data, $format, $results)
+    {
+        $color_number = 0;
+
+        // loop through the rows
+        foreach ($data as $row) {
+            $index = $color_number % sizeof($this->_settings['colors']);
+
+            // Figure out the data type
+            $ref_data = $row[$this->_settings['spatialColumn']];
+            $type_pos = stripos($ref_data, '(');
+            $type = substr($ref_data, 0, $type_pos);
+
+            $gis_obj = PMA_GIS_Factory::factory($type);
+            if (! $gis_obj) {
+                continue;
+            }
+            $label = '';
+            if (isset($this->_settings['labelColumn'])
+                && isset($row[$this->_settings['labelColumn']])
+            ) {
+                $label = $row[$this->_settings['labelColumn']];
+            }
+
+            if ($format == 'svg') {
+                $results .= $gis_obj->prepareRowAsSvg(
+                    $row[$this->_settings['spatialColumn']], $label,
+                    $this->_settings['colors'][$index], $scale_data
+                );
+            } elseif ($format == 'png') {
+                $results = $gis_obj->prepareRowAsPng(
+                    $row[$this->_settings['spatialColumn']], $label,
+                    $this->_settings['colors'][$index], $scale_data, $results
+                );
+            } elseif ($format == 'pdf') {
+                $results = $gis_obj->prepareRowAsPdf(
+                    $row[$this->_settings['spatialColumn']], $label,
+                    $this->_settings['colors'][$index], $scale_data, $results
+                );
+            } elseif ($format == 'ol') {
+                $results .= $gis_obj->prepareRowAsOl(
+                    $row[$this->_settings['spatialColumn']], $row['srid'],
+                    $label, $this->_settings['colors'][$index], $scale_data
+                );
+            }
+            $color_number++;
+        }
+        return $results;
+    }
+}
+?>
diff --git a/phpmyadmin/libraries/gis_visualization.lib.php b/phpmyadmin/libraries/gis_visualization.lib.php
new file mode 100644
index 0000000..63ad188
--- /dev/null
+++ b/phpmyadmin/libraries/gis_visualization.lib.php
@@ -0,0 +1,182 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * Functions used to generate GIS visualizations.
+ *
+ * @package PhpMyAdmin
+ */
+
+
+
+/**
+ * Returns a modified sql query with only the label column
+ * and spatial column(wrapped with 'ASTEXT()' function).
+ *
+ * @param string $sql_query             original sql query
+ * @param array  $visualizationSettings settings for the visualization
+ *
+ * @return the modified sql query.
+ */
+function PMA_GIS_modifyQuery($sql_query, $visualizationSettings)
+{
+    $modified_query = 'SELECT ';
+
+    $analyzed_query = PMA_SQP_analyze(PMA_SQP_parse($sql_query));
+    // If select clause is not *
+    if (trim($analyzed_query[0]['select_expr_clause']) != '*') {
+        // If label column is chosen add it to the query
+        if (isset($visualizationSettings['labelColumn'])
+            && $visualizationSettings['labelColumn'] != ''
+        ) {
+            // Check to see whether an alias has been used on the label column
+            $is_label_alias = false;
+            foreach ($analyzed_query[0]['select_expr'] as $select) {
+                if ($select['alias'] == $visualizationSettings['labelColumn']) {
+                    $modified_query .= sanitize($select) . ' AS `'
+                    . $select['alias'] . '`, ';
+                    $is_label_alias = true;
+                    break;
+                }
+            }
+            // If no alias have been used on the label column
+            if (! $is_label_alias) {
+                foreach ($analyzed_query[0]['select_expr'] as $select) {
+                    if ($select['column'] == $visualizationSettings['labelColumn']) {
+                        $modified_query .= sanitize($select) . ', ';
+                    }
+                }
+            }
+        }
+
+        // Check to see whether an alias has been used on the spatial column
+        $is_spatial_alias = false;
+        foreach ($analyzed_query[0]['select_expr'] as $select) {
+            if ($select['alias'] == $visualizationSettings['spatialColumn']) {
+                $sanitized = sanitize($select);
+                $modified_query .= 'ASTEXT(' . $sanitized . ') AS `'
+                . $select['alias'] . '`, ';
+                // Get the SRID
+                $modified_query .= 'SRID(' . $sanitized . ') AS `srid` ';
+                $is_spatial_alias = true;
+                break;
+            }
+        }
+        // If no alias have been used on the spatial column
+        if (! $is_spatial_alias) {
+            foreach ($analyzed_query[0]['select_expr'] as $select) {
+                if ($select['column'] == $visualizationSettings['spatialColumn']) {
+                    $sanitized = sanitize($select);
+                    $modified_query .= 'ASTEXT(' . $sanitized
+                        . ') AS `' . $select['column'] . '`, ';
+                    // Get the SRID
+                    $modified_query .= 'SRID(' . $sanitized . ') AS `srid` ';
+                }
+            }
+        }
+        // If select clause is *
+    } else {
+        // If label column is chosen add it to the query
+        if (isset($visualizationSettings['labelColumn'])
+            && $visualizationSettings['labelColumn'] != ''
+        ) {
+            $modified_query .= '`' . $visualizationSettings['labelColumn'] .'`, ';
+        }
+
+        // Wrap the spatial column with 'ASTEXT()' function and add it
+        $modified_query .= 'ASTEXT(`' . $visualizationSettings['spatialColumn']
+            . '`) AS `' . $visualizationSettings['spatialColumn'] . '`, ';
+
+        // Get the SRID
+        $modified_query .= 'SRID(`' . $visualizationSettings['spatialColumn']
+            . '`) AS `srid` ';
+    }
+
+    // Append the rest of the query
+    $from_pos = stripos($sql_query, 'FROM');
+    $modified_query .= substr($sql_query, $from_pos);
+    return $modified_query;
+}
+
+// Local function to sanitize the expression taken
+// from the results of PMA_SQP_analyze function.
+function sanitize($select)
+{
+    $table_col = $select['table_name'] . "." . $select['column'];
+    $db_table_col = $select['db'] . "." . $select['table_name']
+        . "." . $select['column'];
+
+    if ($select['expr'] == $select['column']) {
+        return "`" . $select['column'] . "`";
+    } elseif ($select['expr'] == $table_col) {
+        return "`" . $select['table_name'] . "`.`" . $select['column'] . "`";
+    } elseif ($select['expr'] == $db_table_col) {
+        return "`" . $select['db'] . "`.`" . $select['table_name']
+            . "`.`" . $select['column'] . "`";
+    }
+    return $select['expr'];
+}
+
+/**
+ * Formats a visualization for the GIS query results.
+ *
+ * @param array  $data                   Data for the status chart
+ * @param array  &$visualizationSettings Settings used to generate the chart
+ * @param string $format                 Format of the visulaization
+ *
+ * @return string HTML and JS code for the GIS visualization
+ */
+function PMA_GIS_visualizationResults($data, &$visualizationSettings, $format)
+{
+    include_once './libraries/gis/pma_gis_visualization.php';
+    include_once './libraries/gis/pma_gis_factory.php';
+
+    if (! isset($data[0])) {
+        // empty data
+        return __('No data found for GIS visualization.');
+    } else {
+        $visualization = new PMA_GIS_Visualization($data, $visualizationSettings);
+        if ($visualizationSettings != null) {
+            foreach ($visualization->getSettings() as $setting => $val) {
+                if (! isset($visualizationSettings[$setting])) {
+                    $visualizationSettings[$setting] = $val;
+                }
+            }
+        }
+        if ($format == 'svg') {
+            return $visualization->asSvg();
+        } elseif ($format == 'png') {
+            return $visualization->asPng();
+        } elseif ($format == 'ol') {
+            return $visualization->asOl();
+        }
+    }
+}
+
+/**
+ * Generate visualization for the GIS query results and save it to a file.
+ *
+ * @param array  $data                  data for the status chart
+ * @param array  $visualizationSettings settings used to generate the chart
+ * @param string $format                format of the visulaization
+ * @param string $fileName              file name
+ *
+ * @return file File containing the visualization
+ */
+function PMA_GIS_saveToFile($data, $visualizationSettings, $format, $fileName)
+{
+    include_once './libraries/gis/pma_gis_visualization.php';
+    include_once './libraries/gis/pma_gis_factory.php';
+
+    if (isset($data[0])) {
+        $visualization = new PMA_GIS_Visualization($data, $visualizationSettings);
+
+        if ($format == 'svg') {
+            $visualization->toFileAsSvg($fileName);
+        } elseif ($format == 'png') {
+            $visualization->toFileAsPng($fileName);
+        } elseif ($format == 'pdf') {
+            $visualization->toFileAsPdf($fileName);
+        }
+    }
+}
+?>
diff --git a/phpmyadmin/libraries/iconv_wrapper.lib.php b/phpmyadmin/libraries/iconv_wrapper.lib.php
new file mode 100644
index 0000000..9bacffa
--- /dev/null
+++ b/phpmyadmin/libraries/iconv_wrapper.lib.php
@@ -0,0 +1,105 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ *
+ * @package PhpMyAdmin
+ */
+if (! defined('PHPMYADMIN')) {
+    exit;
+}
+
+/**
+ * GNU iconv code set to IBM AIX libiconv code set table
+ * Keys of this table should be in lowercase,
+ * and searches should be performed using lowercase!
+ */
+$gnu_iconv_to_aix_iconv_codepage_map = array (
+    // "iso-8859-[1-9]" --> "ISO8859-[1-9]" according to
+    // http://publibn.boulder.ibm.com/doc_link/en_US/
+    //     a_doc_lib/libs/basetrf2/setlocale.htm
+    'iso-8859-1' => 'ISO8859-1',
+    'iso-8859-2' => 'ISO8859-2',
+    'iso-8859-3' => 'ISO8859-3',
+    'iso-8859-4' => 'ISO8859-4',
+    'iso-8859-5' => 'ISO8859-5',
+    'iso-8859-6' => 'ISO8859-6',
+    'iso-8859-7' => 'ISO8859-7',
+    'iso-8859-8' => 'ISO8859-8',
+    'iso-8859-9' => 'ISO8859-9',
+
+    // "big5" --> "IBM-eucTW" according to
+    // http://kadesh.cepba.upc.es/mancpp/classref/ref/ITranscoder_DSC.htm
+    'big5' => 'IBM-eucTW',
+
+    // Other mappings corresponding to the phpMyAdmin dropdown box when using the
+    // charset conversion feature
+    'euc-jp' => 'IBM-eucJP',
+    'koi8-r' => 'IBM-eucKR',
+    'ks_c_5601-1987' => 'KSC5601.1987-0',
+    'tis-620' => 'TIS-620',
+    'utf-8' => 'UTF-8'
+);
+
+/**
+ * Wrapper around IBM AIX iconv(), whose character set naming differs
+ * from the GNU version of iconv().
+ *
+ * @param string $in_charset  input character set
+ * @param string $out_charset output character set
+ * @param string $str         the string to convert
+ *
+ * @return mixed    converted string or false on failure
+ *
+ * @access  public
+ *
+ */
+function PMA_aix_iconv_wrapper($in_charset, $out_charset, $str)
+{
+
+    global $gnu_iconv_to_aix_iconv_codepage_map;
+
+    // Check for transliteration argument at the end of output character set name
+    $translit_search = strpos(strtolower($out_charset), '//translit');
+    $using_translit = (!($translit_search === false));
+
+    // Extract "plain" output character set name
+    // (without any transliteration argument)
+    $out_charset_plain = ($using_translit
+        ? substr($out_charset, 0, $translit_search)
+        : $out_charset);
+
+    // Transform name of input character set (if found)
+    $in_charset_exisits = array_key_exists(
+        strtolower($in_charset),
+        $gnu_iconv_to_aix_iconv_codepage_map
+    );
+    if ($in_charset_exisits) {
+        $in_charset = $gnu_iconv_to_aix_iconv_codepage_map[strtolower($in_charset)];
+    }
+
+    // Transform name of "plain" output character set (if found)
+    $out_charset_plain_exists = array_key_exists(
+        strtolower($out_charset_plain),
+        $gnu_iconv_to_aix_iconv_codepage_map
+    );
+    if ($out_charset_plain_exists) {
+        $out_charset_plain = $gnu_iconv_to_aix_iconv_codepage_map[
+            strtolower($out_charset_plain)];
+    }
+
+    // Add transliteration argument again (exactly as specified by user) if used
+    // Build the output character set name that we will use
+    $out_charset = ($using_translit
+        ? $out_charset_plain . substr($out_charset, $translit_search)
+        : $out_charset_plain);
+
+    // NOTE: Transliteration not supported; we will use the "plain"
+    // output character set name
+    $out_charset = $out_charset_plain;
+
+    // Call iconv() with the possibly modified parameters
+    $result = iconv($in_charset, $out_charset, $str);
+    return $result;
+} //  end of the "PMA_aix_iconv_wrapper()" function
+
+?>
diff --git a/phpmyadmin/libraries/import.lib.php b/phpmyadmin/libraries/import.lib.php
new file mode 100644
index 0000000..aa15847
--- /dev/null
+++ b/phpmyadmin/libraries/import.lib.php
@@ -0,0 +1,1248 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * Library that provides common import functions that are used by import plugins
+ *
+ * @package PhpMyAdmin-Import
+ */
+if (! defined('PHPMYADMIN')) {
+    exit;
+}
+
+/**
+ * We need to know something about user
+ */
+require_once './libraries/check_user_privileges.lib.php';
+
+/**
+ * We do this check, DROP DATABASE does not need to be confirmed elsewhere
+ */
+define('PMA_CHK_DROP', 1);
+
+/**
+ * Checks whether timeout is getting close
+ *
+ * @return boolean true if timeout is close
+ * @access public
+ */
+function PMA_checkTimeout()
+{
+    global $timestamp, $maximum_time, $timeout_passed;
+    if ($maximum_time == 0) {
+        return false;
+    } elseif ($timeout_passed) {
+        return true;
+        /* 5 in next row might be too much */
+    } elseif ((time() - $timestamp) > ($maximum_time - 5)) {
+        $timeout_passed = true;
+        return true;
+    } else {
+        return false;
+    }
+}
+
+/**
+ * Detects what compression filse uses
+ *
+ * @param string $filepath filename to check
+ *
+ * @return string MIME type of compression, none for none
+ * @access public
+ */
+function PMA_detectCompression($filepath)
+{
+    $file = @fopen($filepath, 'rb');
+    if (! $file) {
+        return false;
+    }
+    $test = fread($file, 4);
+    $len = strlen($test);
+    fclose($file);
+    if ($len >= 2 && $test[0] == chr(31) && $test[1] == chr(139)) {
+        return 'application/gzip';
+    }
+    if ($len >= 3 && substr($test, 0, 3) == 'BZh') {
+        return 'application/bzip2';
+    }
+    if ($len >= 4 && $test == "PK\003\004") {
+        return 'application/zip';
+    }
+    return 'none';
+}
+
+/**
+ * Runs query inside import buffer. This is needed to allow displaying
+ * of last SELECT, SHOW or HANDLER results and similar nice stuff.
+ *
+ * @param string $sql         query to run
+ * @param string $full        query to display, this might be commented
+ * @param bool   $controluser whether to use control user for queries
+ * @param array  &$sql_data
+ *
+ * @return void
+ * @access public
+ */
+function PMA_importRunQuery($sql = '', $full = '', $controluser = false,
+    &$sql_data = array()
+) {
+    global $import_run_buffer, $go_sql, $complete_query, $display_query,
+        $sql_query, $my_die, $error, $reload,
+        $last_query_with_results,
+        $skip_queries, $executed_queries, $max_sql_len, $read_multiply,
+        $cfg, $sql_query_disabled, $db, $run_query, $is_superuser;
+    $read_multiply = 1;
+    if (isset($import_run_buffer)) {
+        // Should we skip something?
+        if ($skip_queries > 0) {
+            $skip_queries--;
+        } else {
+            if (! empty($import_run_buffer['sql'])
+                && trim($import_run_buffer['sql']) != ''
+            ) {
+
+                // USE query changes the database, son need to track
+                // while running multiple queries
+                $is_use_query
+                    = (stripos($import_run_buffer['sql'], "use ") !== false)
+                        ? true
+                        : false;
+
+                $max_sql_len = max($max_sql_len, strlen($import_run_buffer['sql']));
+                if (! $sql_query_disabled) {
+                    $sql_query .= $import_run_buffer['full'];
+                }
+                if (! $cfg['AllowUserDropDatabase']
+                    && ! $is_superuser
+                    && preg_match('@^[[:space:]]*DROP[[:space:]]+(IF EXISTS[[:space:]]+)?DATABASE @i', $import_run_buffer['sql'])
+                ) {
+                    $GLOBALS['message'] = PMA_Message::error(__('"DROP DATABASE" statements are disabled.'));
+                    $error = true;
+                } else {
+
+                    $executed_queries++;
+
+                    if ($run_query
+                        && $GLOBALS['finished']
+                        && empty($sql)
+                        && ! $error
+                        && ((! empty($import_run_buffer['sql'])
+                        && preg_match('/^[\s]*(SELECT|SHOW|HANDLER)/i', $import_run_buffer['sql']))
+                        || ($executed_queries == 1))
+                    ) {
+                        $go_sql = true;
+                        if (! $sql_query_disabled) {
+                            $complete_query = $sql_query;
+                            $display_query = $sql_query;
+                        } else {
+                            $complete_query = '';
+                            $display_query = '';
+                        }
+                        $sql_query = $import_run_buffer['sql'];
+                        $sql_data['valid_sql'][] = $import_run_buffer['sql'];
+                        $sql_data['valid_queries']++;
+
+                        // If a 'USE <db>' SQL-clause was found,
+                        // set our current $db to the new one
+                        list($db, $reload) = PMA_lookForUse(
+                            $import_run_buffer['sql'],
+                            $db,
+                            $reload
+                        );
+                    } elseif ($run_query) {
+
+                        if ($controluser) {
+                            $result = PMA_queryAsControlUser(
+                                $import_run_buffer['sql']
+                            );
+                        } else {
+                            $result = PMA_DBI_try_query($import_run_buffer['sql']);
+                        }
+
+                        $msg = '# ';
+                        if ($result === false) { // execution failed
+                            if (! isset($my_die)) {
+                                $my_die = array();
+                            }
+                            $my_die[] = array(
+                                'sql' => $import_run_buffer['full'],
+                                'error' => PMA_DBI_getError()
+                            );
+
+                            $msg .= __('Error');
+
+                            if (! $cfg['IgnoreMultiSubmitErrors']) {
+                                $error = true;
+                                return;
+                            }
+                        } else {
+                            $a_num_rows = (int)@PMA_DBI_num_rows($result);
+                            $a_aff_rows = (int)@PMA_DBI_affected_rows();
+                            if ($a_num_rows > 0) {
+                                $msg .= __('Rows'). ': ' . $a_num_rows;
+                                $last_query_with_results = $import_run_buffer['sql'];
+                            } elseif ($a_aff_rows > 0) {
+                                $message = PMA_Message::getMessageForAffectedRows($a_aff_rows);
+                                $msg .= $message->getMessage();
+                            } else {
+                                $msg .= __('MySQL returned an empty result set (i.e. zero rows).');
+                            }
+
+                            if (($a_num_rows > 0) || $is_use_query) {
+                                $sql_data['valid_sql'][] = $import_run_buffer['sql'];
+                                $sql_data['valid_queries']++;
+                            }
+
+                        }
+                        if (! $sql_query_disabled) {
+                            $sql_query .= $msg . "\n";
+                        }
+
+                        // If a 'USE <db>' SQL-clause was found and the query
+                        // succeeded, set our current $db to the new one
+                        if ($result != false) {
+                            list($db, $reload) = PMA_lookForUse(
+                                $import_run_buffer['sql'],
+                                $db,
+                                $reload
+                            );
+                        }
+
+                        if ($result != false
+                            && preg_match('@^[\s]*(DROP|CREATE)[\s]+(IF EXISTS[[:space:]]+)?(TABLE|DATABASE)[[:space:]]+(.+)@im', $import_run_buffer['sql'])
+                        ) {
+                            $reload = true;
+                        }
+                    } // end run query
+                } // end if not DROP DATABASE
+                // end non empty query
+            } elseif (! empty($import_run_buffer['full'])) {
+                if ($go_sql) {
+                    $complete_query .= $import_run_buffer['full'];
+                    $display_query .= $import_run_buffer['full'];
+                } else {
+                    if (! $sql_query_disabled) {
+                        $sql_query .= $import_run_buffer['full'];
+                    }
+                }
+            }
+            // check length of query unless we decided to pass it to sql.php
+            // (if $run_query is false, we are just displaying so show
+            // the complete query in the textarea)
+            if (! $go_sql && $run_query) {
+                if (! empty($sql_query)) {
+                    if (strlen($sql_query) > 50000
+                        || $executed_queries > 50
+                        || $max_sql_len > 1000
+                    ) {
+                        $sql_query = '';
+                        $sql_query_disabled = true;
+                    }
+                }
+            }
+        } // end do query (no skip)
+    } // end buffer exists
+
+    // Do we have something to push into buffer?
+    if (! empty($sql) || ! empty($full)) {
+        $import_run_buffer = array('sql' => $sql, 'full' => $full);
+    } else {
+        unset($GLOBALS['import_run_buffer']);
+    }
+}
+
+/**
+ * Looks for the presence of USE to possibly change current db
+ *
+ * @param string $buffer buffer to examine
+ * @param string $db     current db
+ * @param bool   $reload reload
+ *
+ * @return array (current or new db, whether to reload)
+ * @access public
+ */
+function PMA_lookForUse($buffer, $db, $reload)
+{
+    if (preg_match('@^[\s]*USE[[:space:]]+([\S]+)@i', $buffer, $match)) {
+        $db = trim($match[1]);
+        $db = trim($db, ';'); // for example, USE abc;
+
+        // $db must not contain the escape characters generated by backquote()
+        // ( used in PMA_buildSQL() as: backquote($db_name), and then called
+        // in PMA_importRunQuery() which in turn calls PMA_lookForUse() )
+        $db = PMA_Util::unQuote($db);
+
+        $reload = true;
+    }
+    return(array($db, $reload));
+}
+
+
+/**
+ * Returns next part of imported file/buffer
+ *
+ * @param int $size size of buffer to read
+ *                  (this is maximal size function will return)
+ *
+ * @return string part of file/buffer
+ * @access public
+ */
+function PMA_importGetNextChunk($size = 32768)
+{
+    global $compression, $import_handle, $charset_conversion, $charset_of_file,
+        $read_multiply;
+
+    // Add some progression while reading large amount of data
+    if ($read_multiply <= 8) {
+        $size *= $read_multiply;
+    } else {
+        $size *= 8;
+    }
+    $read_multiply++;
+
+    // We can not read too much
+    if ($size > $GLOBALS['read_limit']) {
+        $size = $GLOBALS['read_limit'];
+    }
+
+    if (PMA_checkTimeout()) {
+        return false;
+    }
+    if ($GLOBALS['finished']) {
+        return true;
+    }
+
+    if ($GLOBALS['import_file'] == 'none') {
+        // Well this is not yet supported and tested,
+        // but should return content of textarea
+        if (strlen($GLOBALS['import_text']) < $size) {
+            $GLOBALS['finished'] = true;
+            return $GLOBALS['import_text'];
+        } else {
+            $r = substr($GLOBALS['import_text'], 0, $size);
+            $GLOBALS['offset'] += $size;
+            $GLOBALS['import_text'] = substr($GLOBALS['import_text'], $size);
+            return $r;
+        }
+    }
+
+    switch ($compression) {
+    case 'application/bzip2':
+        $result = bzread($import_handle, $size);
+        $GLOBALS['finished'] = feof($import_handle);
+        break;
+    case 'application/gzip':
+        $result = gzread($import_handle, $size);
+        $GLOBALS['finished'] = feof($import_handle);
+        break;
+    case 'application/zip':
+        $result = substr($GLOBALS['import_text'], 0, $size);
+        $GLOBALS['import_text'] = substr($GLOBALS['import_text'], $size);
+        $GLOBALS['finished'] = empty($GLOBALS['import_text']);
+        break;
+    case 'none':
+        $result = fread($import_handle, $size);
+        $GLOBALS['finished'] = feof($import_handle);
+        break;
+    }
+    $GLOBALS['offset'] += $size;
+
+    if ($charset_conversion) {
+        return PMA_convert_string($charset_of_file, 'utf-8', $result);
+    } else {
+        /**
+         * Skip possible byte order marks (I do not think we need more
+         * charsets, but feel free to add more, you can use wikipedia for
+         * reference: <http://en.wikipedia.org/wiki/Byte_Order_Mark>)
+         *
+         * @todo BOM could be used for charset autodetection
+         */
+        if ($GLOBALS['offset'] == $size) {
+            // UTF-8
+            if (strncmp($result, "\xEF\xBB\xBF", 3) == 0) {
+                $result = substr($result, 3);
+                // UTF-16 BE, LE
+            } elseif (strncmp($result, "\xFE\xFF", 2) == 0
+                || strncmp($result, "\xFF\xFE", 2) == 0
+            ) {
+                $result = substr($result, 2);
+            }
+        }
+        return $result;
+    }
+}
+
+/**
+ * Returns the "Excel" column name (i.e. 1 = "A", 26 = "Z", 27 = "AA", etc.)
+ *
+ * This functions uses recursion to build the Excel column name.
+ *
+ * The column number (1-26) is converted to the responding
+ * ASCII character (A-Z) and returned.
+ *
+ * If the column number is bigger than 26 (= num of letters in alfabet),
+ * an extra character needs to be added. To find this extra character,
+ * the number is divided by 26 and this value is passed to another instance
+ * of the same function (hence recursion). In that new instance the number is
+ * evaluated again, and if it is still bigger than 26, it is divided again
+ * and passed to another instance of the same function. This continues until
+ * the number is smaller than 26. Then the last called function returns
+ * the corresponding ASCII character to the function that called it.
+ * Each time a called function ends an extra character is added to the column name.
+ * When the first function is reached, the last character is addded and the complete
+ * column name is returned.
+ *
+ * @param int $num the column number
+ *
+ * @return string The column's "Excel" name
+ * @access  public
+ */
+function PMA_getColumnAlphaName($num)
+{
+    $A = 65; // ASCII value for capital "A"
+    $col_name = "";
+
+    if ($num > 26) {
+        $div = (int)($num / 26);
+        $remain = (int)($num % 26);
+
+        // subtract 1 of divided value in case the modulus is 0,
+        // this is necessary because A-Z has no 'zero'
+        if ($remain == 0) {
+            $div--;
+        }
+
+        // recursive function call
+        $col_name = PMA_getColumnAlphaName($div);
+        // use modulus as new column number
+        $num = $remain;
+    }
+
+    if ($num == 0) {
+        // use 'Z' if column number is 0,
+        // this is necessary because A-Z has no 'zero'
+        $col_name .= chr(($A + 26) - 1);
+    } else {
+        // convert column number to ASCII character
+        $col_name .= chr(($A + $num) - 1);
+    }
+
+    return $col_name;
+}
+
+/**
+ * Returns the column number based on the Excel name.
+ * So "A" = 1, "Z" = 26, "AA" = 27, etc.
+ *
+ * Basicly this is a base26 (A-Z) to base10 (0-9) conversion.
+ * It iterates through all characters in the column name and
+ * calculates the corresponding value, based on character value
+ * (A = 1, ..., Z = 26) and position in the string.
+ *
+ * @param string $name column name(i.e. "A", or "BC", etc.)
+ *
+ * @return int The column number
+ * @access  public
+ */
+function PMA_getColumnNumberFromName($name)
+{
+    if (! empty($name)) {
+        $name = strtoupper($name);
+        $num_chars = strlen($name);
+        $column_number = 0;
+        for ($i = 0; $i < $num_chars; ++$i) {
+            // read string from back to front
+            $char_pos = ($num_chars - 1) - $i;
+
+            // convert capital character to ASCII value
+            // and subtract 64 to get corresponding decimal value
+            // ASCII value of "A" is 65, "B" is 66, etc.
+            // Decimal equivalent of "A" is 1, "B" is 2, etc.
+            $number = (ord($name[$char_pos]) - 64);
+
+            // base26 to base10 conversion : multiply each number
+            // with corresponding value of the position, in this case
+            // $i=0 : 1; $i=1 : 26; $i=2 : 676; ...
+            $column_number += $number * PMA_Util::pow(26, $i);
+        }
+        return $column_number;
+    } else {
+        return 0;
+    }
+}
+
+/**
+ * Constants definitions
+ */
+
+/* MySQL type defs */
+define("NONE",      0);
+define("VARCHAR",   1);
+define("INT",       2);
+define("DECIMAL",   3);
+define("BIGINT",    4);
+define("GEOMETRY",  5);
+
+/* Decimal size defs */
+define("M",         0);
+define("D",         1);
+define("FULL",      2);
+
+/* Table array defs */
+define("TBL_NAME",  0);
+define("COL_NAMES", 1);
+define("ROWS",      2);
+
+/* Analysis array defs */
+define("TYPES",        0);
+define("SIZES",        1);
+define("FORMATTEDSQL", 2);
+
+/**
+ * Obtains the precision (total # of digits) from a size of type decimal
+ *
+ * @param string $last_cumulative_size
+ *
+ * @return int Precision of the given decimal size notation
+ * @access  public
+ */
+function PMA_getM($last_cumulative_size)
+{
+    return (int)substr($last_cumulative_size, 0, strpos($last_cumulative_size, ","));
+}
+
+/**
+ * Obtains the scale (# of digits to the right of the decimal point)
+ * from a size of type decimal
+ *
+ * @param string $last_cumulative_size
+ *
+ * @return int Scale of the given decimal size notation
+ * @access  public
+ */
+function PMA_getD($last_cumulative_size)
+{
+    return (int) substr(
+        $last_cumulative_size,
+        (strpos($last_cumulative_size, ",") + 1),
+        (strlen($last_cumulative_size) - strpos($last_cumulative_size, ","))
+    );
+}
+
+/**
+ * Obtains the decimal size of a given cell
+ *
+ * @param string &$cell cell content
+ *
+ * @return array Contains the precision, scale, and full size
+ *                representation of the given decimal cell
+ * @access  public
+ */
+function PMA_getDecimalSize(&$cell)
+{
+    $curr_size = strlen((string)$cell);
+    $decPos = strpos($cell, ".");
+    $decPrecision = ($curr_size - 1) - $decPos;
+
+    $m = $curr_size - 1;
+    $d = $decPrecision;
+
+    return array($m, $d, ($m . "," . $d));
+}
+
+/**
+ * Obtains the size of the given cell
+ *
+ * @param string $last_cumulative_size Last cumulative column size
+ * @param int    $last_cumulative_type Last cumulative column type
+ *                                     (NONE or VARCHAR or DECIMAL or INT or BIGINT)
+ * @param int    $curr_type            Type of the current cell
+ *                                     (NONE or VARCHAR or DECIMAL or INT or BIGINT)
+ * @param string &$cell                The current cell
+ *
+ * @return string  Size of the given cell in the type-appropriate format
+ * @access  public
+ *
+ * @todo    Handle the error cases more elegantly
+ */
+function PMA_detectSize($last_cumulative_size, $last_cumulative_type,
+    $curr_type, &$cell
+) {
+    $curr_size = strlen((string)$cell);
+
+    /**
+     * If the cell is NULL, don't treat it as a varchar
+     */
+    if (! strcmp('NULL', $cell)) {
+        return $last_cumulative_size;
+    } elseif ($curr_type == VARCHAR) {
+        /**
+         * What to do if the current cell is of type VARCHAR
+         */
+        /**
+         * The last cumulative type was VARCHAR
+         */
+        if ($last_cumulative_type == VARCHAR) {
+            if ($curr_size >= $last_cumulative_size) {
+                return $curr_size;
+            } else {
+                return $last_cumulative_size;
+            }
+        } elseif ($last_cumulative_type == DECIMAL) {
+            /**
+             * The last cumulative type was DECIMAL
+             */
+            $oldM = PMA_getM($last_cumulative_size);
+
+            if ($curr_size >= $oldM) {
+                return $curr_size;
+            } else {
+                return $oldM;
+            }
+        } elseif ($last_cumulative_type == BIGINT || $last_cumulative_type == INT) {
+            /**
+             * The last cumulative type was BIGINT or INT
+             */
+            if ($curr_size >= $last_cumulative_size) {
+                return $curr_size;
+            } else {
+                return $last_cumulative_size;
+            }
+        } elseif (! isset($last_cumulative_type) || $last_cumulative_type == NONE) {
+            /**
+             * This is the first row to be analyzed
+             */
+            return $curr_size;
+        } else {
+            /**
+             * An error has DEFINITELY occurred
+             */
+            /**
+             * TODO: Handle this MUCH more elegantly
+             */
+
+            return -1;
+        }
+    } elseif ($curr_type == DECIMAL) {
+        /**
+         * What to do if the current cell is of type DECIMAL
+         */
+        /**
+         * The last cumulative type was VARCHAR
+         */
+        if ($last_cumulative_type == VARCHAR) {
+            /* Convert $last_cumulative_size from varchar to decimal format */
+            $size = PMA_getDecimalSize($cell);
+
+            if ($size[M] >= $last_cumulative_size) {
+                return $size[M];
+            } else {
+                return $last_cumulative_size;
+            }
+        } elseif ($last_cumulative_type == DECIMAL) {
+            /**
+             * The last cumulative type was DECIMAL
+             */
+            $size = PMA_getDecimalSize($cell);
+
+            $oldM = PMA_getM($last_cumulative_size);
+            $oldD = PMA_getD($last_cumulative_size);
+
+            /* New val if M or D is greater than current largest */
+            if ($size[M] > $oldM || $size[D] > $oldD) {
+                /* Take the largest of both types */
+                return (string) ((($size[M] > $oldM) ? $size[M] : $oldM)
+                    . "," . (($size[D] > $oldD) ? $size[D] : $oldD));
+            } else {
+                return $last_cumulative_size;
+            }
+        } elseif ($last_cumulative_type == BIGINT || $last_cumulative_type == INT) {
+            /**
+             * The last cumulative type was BIGINT or INT
+             */
+            /* Convert $last_cumulative_size from int to decimal format */
+            $size = PMA_getDecimalSize($cell);
+
+            if ($size[M] >= $last_cumulative_size) {
+                return $size[FULL];
+            } else {
+                return ($last_cumulative_size.",".$size[D]);
+            }
+        } elseif (! isset($last_cumulative_type) || $last_cumulative_type == NONE) {
+            /**
+             * This is the first row to be analyzed
+             */
+            /* First row of the column */
+            $size = PMA_getDecimalSize($cell);
+
+            return $size[FULL];
+        } else {
+            /**
+             * An error has DEFINITELY occurred
+             */
+            /**
+             * TODO: Handle this MUCH more elegantly
+             */
+
+            return -1;
+        }
+    } elseif ($curr_type == BIGINT || $curr_type == INT) {
+        /**
+         * What to do if the current cell is of type BIGINT or INT
+         */
+        /**
+         * The last cumulative type was VARCHAR
+         */
+        if ($last_cumulative_type == VARCHAR) {
+            if ($curr_size >= $last_cumulative_size) {
+                return $curr_size;
+            } else {
+                return $last_cumulative_size;
+            }
+        } elseif ($last_cumulative_type == DECIMAL) {
+            /**
+             * The last cumulative type was DECIMAL
+             */
+            $oldM = PMA_getM($last_cumulative_size);
+            $oldD = PMA_getD($last_cumulative_size);
+            $oldInt = $oldM - $oldD;
+            $newInt = strlen((string)$cell);
+
+            /* See which has the larger integer length */
+            if ($oldInt >= $newInt) {
+                /* Use old decimal size */
+                return $last_cumulative_size;
+            } else {
+                /* Use $newInt + $oldD as new M */
+                return (($newInt + $oldD) . "," . $oldD);
+            }
+        } elseif ($last_cumulative_type == BIGINT || $last_cumulative_type == INT) {
+            /**
+             * The last cumulative type was BIGINT or INT
+             */
+            if ($curr_size >= $last_cumulative_size) {
+                return $curr_size;
+            } else {
+                return $last_cumulative_size;
+            }
+        } elseif (! isset($last_cumulative_type) || $last_cumulative_type == NONE) {
+            /**
+             * This is the first row to be analyzed
+             */
+            return $curr_size;
+        } else {
+            /**
+             * An error has DEFINITELY occurred
+             */
+            /**
+             * TODO: Handle this MUCH more elegantly
+             */
+
+            return -1;
+        }
+    } else {
+        /**
+         * An error has DEFINITELY occurred
+         */
+        /**
+         * TODO: Handle this MUCH more elegantly
+         */
+
+        return -1;
+    }
+}
+
+/**
+ * Determines what MySQL type a cell is
+ *
+ * @param int    $last_cumulative_type Last cumulative column type
+ *                                     (VARCHAR or INT or BIGINT or DECIMAL or NONE)
+ * @param string &$cell                String representation of the cell for which
+ *                                     a best-fit type is to be determined
+ *
+ * @return int  The MySQL type representation
+ *               (VARCHAR or INT or BIGINT or DECIMAL or NONE)
+ * @access  public
+ */
+function PMA_detectType($last_cumulative_type, &$cell)
+{
+    /**
+     * If numeric, determine if decimal, int or bigint
+     * Else, we call it varchar for simplicity
+     */
+
+    if (! strcmp('NULL', $cell)) {
+        if ($last_cumulative_type === null || $last_cumulative_type == NONE) {
+            return NONE;
+        } else {
+            return $last_cumulative_type;
+        }
+    } elseif (is_numeric($cell)) {
+        if ($cell == (string)(float)$cell
+            && strpos($cell, ".") !== false
+            && substr_count($cell, ".") == 1
+        ) {
+            return DECIMAL;
+        } else {
+            if (abs($cell) > 2147483647) {
+                return BIGINT;
+            } else {
+                return INT;
+            }
+        }
+    } else {
+        return VARCHAR;
+    }
+}
+
+/**
+ * Determines if the column types are int, decimal, or string
+ *
+ * @param array &$table array(string $table_name, array $col_names, array $rows)
+ *
+ * @return array    array(array $types, array $sizes)
+ * @access  public
+ *
+ * @link http://wiki.phpmyadmin.net/pma/Import
+ *
+ * @todo    Handle the error case more elegantly
+ */
+function PMA_analyzeTable(&$table)
+{
+    /* Get number of rows in table */
+    $numRows = count($table[ROWS]);
+    /* Get number of columns */
+    $numCols = count($table[COL_NAMES]);
+    /* Current type for each column */
+    $types = array();
+    $sizes = array();
+
+    /* Initialize $sizes to all 0's */
+    for ($i = 0; $i < $numCols; ++$i) {
+        $sizes[$i] = 0;
+    }
+
+    /* Initialize $types to NONE */
+    for ($i = 0; $i < $numCols; ++$i) {
+        $types[$i] = NONE;
+    }
+
+    /* Temp vars */
+    $curr_type = NONE;
+
+    /* If the passed array is not of the correct form, do not process it */
+    if (is_array($table)
+        && ! is_array($table[TBL_NAME])
+        && is_array($table[COL_NAMES])
+        && is_array($table[ROWS])
+    ) {
+        /* Analyze each column */
+        for ($i = 0; $i < $numCols; ++$i) {
+            /* Analyze the column in each row */
+            for ($j = 0; $j < $numRows; ++$j) {
+                /* Determine type of the current cell */
+                $curr_type = PMA_detectType($types[$i], $table[ROWS][$j][$i]);
+                /* Determine size of the current cell */
+                $sizes[$i] = PMA_detectSize(
+                    $sizes[$i],
+                    $types[$i],
+                    $curr_type,
+                    $table[ROWS][$j][$i]
+                );
+
+                /**
+                 * If a type for this column has already been declared,
+                 * only alter it if it was a number and a varchar was found
+                 */
+                if ($curr_type != NONE) {
+                    if ($curr_type == VARCHAR) {
+                        $types[$i] = VARCHAR;
+                    } else if ($curr_type == DECIMAL) {
+                        if ($types[$i] != VARCHAR) {
+                            $types[$i] = DECIMAL;
+                        }
+                    } else if ($curr_type == BIGINT) {
+                        if ($types[$i] != VARCHAR && $types[$i] != DECIMAL) {
+                            $types[$i] = BIGINT;
+                        }
+                    } else if ($curr_type == INT) {
+                        if ($types[$i] != VARCHAR
+                            && $types[$i] != DECIMAL
+                            && $types[$i] != BIGINT
+                        ) {
+                            $types[$i] = INT;
+                        }
+                    }
+                }
+            }
+        }
+
+        /* Check to ensure that all types are valid */
+        $len = count($types);
+        for ($n = 0; $n < $len; ++$n) {
+            if (! strcmp(NONE, $types[$n])) {
+                $types[$n] = VARCHAR;
+                $sizes[$n] = '10';
+            }
+        }
+
+        return array($types, $sizes);
+    } else {
+        /**
+         * TODO: Handle this better
+         */
+
+        return false;
+    }
+}
+
+/* Needed to quell the beast that is PMA_Message */
+$import_notice = null;
+
+/**
+ * Builds and executes SQL statements to create the database and tables
+ * as necessary, as well as insert all the data.
+ *
+ * @param string $db_name         Name of the database
+ * @param array  &$tables         Array of tables for the specified database
+ * @param array  &$analyses       Analyses of the tables
+ * @param array  &$additional_sql Additional SQL statements to be executed
+ * @param array  $options         Associative array of options
+ *
+ * @return void
+ * @access  public
+ *
+ * @link http://wiki.phpmyadmin.net/pma/Import
+ */
+function PMA_buildSQL($db_name, &$tables, &$analyses = null,
+    &$additional_sql = null, $options = null
+) {
+    /* Take care of the options */
+    if (isset($options['db_collation'])&& ! is_null($options['db_collation'])) {
+        $collation = $options['db_collation'];
+    } else {
+        $collation = "utf8_general_ci";
+    }
+
+    if (isset($options['db_charset']) && ! is_null($options['db_charset'])) {
+        $charset = $options['db_charset'];
+    } else {
+        $charset = "utf8";
+    }
+
+    if (isset($options['create_db'])) {
+        $create_db = $options['create_db'];
+    } else {
+        $create_db = true;
+    }
+
+    /* Create SQL code to handle the database */
+    $sql = array();
+
+    if ($create_db) {
+        if (PMA_DRIZZLE) {
+            $sql[] = "CREATE DATABASE IF NOT EXISTS " . PMA_Util::backquote($db_name)
+                . " COLLATE " . $collation;
+        } else {
+            $sql[] = "CREATE DATABASE IF NOT EXISTS " . PMA_Util::backquote($db_name)
+                . " DEFAULT CHARACTER SET " . $charset . " COLLATE " . $collation;
+        }
+    }
+
+    /**
+     * The calling plug-in should include this statement,
+     * if necessary, in the $additional_sql parameter
+     *
+     * $sql[] = "USE " . backquote($db_name);
+     */
+
+    /* Execute the SQL statements create above */
+    $sql_len = count($sql);
+    for ($i = 0; $i < $sql_len; ++$i) {
+        PMA_importRunQuery($sql[$i], $sql[$i]);
+    }
+
+    /* No longer needed */
+    unset($sql);
+
+    /* Run the $additional_sql statements supplied by the caller plug-in */
+    if ($additional_sql != null) {
+        /* Clean the SQL first */
+        $additional_sql_len = count($additional_sql);
+
+        /**
+         * Only match tables for now, because CREATE IF NOT EXISTS
+         * syntax is lacking or nonexisting for views, triggers,
+         * functions, and procedures.
+         *
+         * See: http://bugs.mysql.com/bug.php?id=15287
+         *
+         * To the best of my knowledge this is still an issue.
+         *
+         * $pattern = 'CREATE (TABLE|VIEW|TRIGGER|FUNCTION|PROCEDURE)';
+         */
+        $pattern = '/CREATE [^`]*(TABLE)/';
+        $replacement = 'CREATE \\1 IF NOT EXISTS';
+
+        /* Change CREATE statements to CREATE IF NOT EXISTS to support
+         * inserting into existing structures
+         */
+        for ($i = 0; $i < $additional_sql_len; ++$i) {
+            $additional_sql[$i] = preg_replace(
+                $pattern,
+                $replacement,
+                $additional_sql[$i]
+            );
+            /* Execute the resulting statements */
+            PMA_importRunQuery($additional_sql[$i], $additional_sql[$i]);
+        }
+    }
+
+    if ($analyses != null) {
+        $type_array = array(
+            NONE => "NULL",
+            VARCHAR => "varchar",
+            INT => "int",
+            DECIMAL => "decimal",
+            BIGINT => "bigint",
+            GEOMETRY => 'geometry'
+        );
+
+        /* TODO: Do more checking here to make sure they really are matched */
+        if (count($tables) != count($analyses)) {
+            exit();
+        }
+
+        /* Create SQL code to create the tables */
+        $tempSQLStr = "";
+        $num_tables = count($tables);
+        for ($i = 0; $i < $num_tables; ++$i) {
+            $num_cols = count($tables[$i][COL_NAMES]);
+            $tempSQLStr = "CREATE TABLE IF NOT EXISTS " . PMA_Util::backquote($db_name)
+                . '.' . PMA_Util::backquote($tables[$i][TBL_NAME]) . " (";
+            for ($j = 0; $j < $num_cols; ++$j) {
+                $size = $analyses[$i][SIZES][$j];
+                if ((int)$size == 0) {
+                    $size = 10;
+                }
+
+                $tempSQLStr .= PMA_Util::backquote($tables[$i][COL_NAMES][$j]) . " "
+                    . $type_array[$analyses[$i][TYPES][$j]];
+                if ($analyses[$i][TYPES][$j] != GEOMETRY) {
+                    $tempSQLStr .= "(" . $size . ")";
+                }
+
+                if ($j != (count($tables[$i][COL_NAMES]) - 1)) {
+                    $tempSQLStr .= ", ";
+                }
+            }
+            $tempSQLStr .= ")"
+                . (PMA_DRIZZLE ? "" : " DEFAULT CHARACTER SET " . $charset)
+                . " COLLATE " . $collation . ";";
+
+            /**
+             * Each SQL statement is executed immediately
+             * after it is formed so that we don't have
+             * to store them in a (possibly large) buffer
+             */
+            PMA_importRunQuery($tempSQLStr, $tempSQLStr);
+        }
+    }
+
+    /**
+     * Create the SQL statements to insert all the data
+     *
+     * Only one insert query is formed for each table
+     */
+    $tempSQLStr = "";
+    $col_count = 0;
+    $num_tables = count($tables);
+    for ($i = 0; $i < $num_tables; ++$i) {
+        $num_cols = count($tables[$i][COL_NAMES]);
+        $num_rows = count($tables[$i][ROWS]);
+
+        $tempSQLStr = "INSERT INTO " . PMA_Util::backquote($db_name) . '.'
+            . PMA_Util::backquote($tables[$i][TBL_NAME]) . " (";
+
+        for ($m = 0; $m < $num_cols; ++$m) {
+            $tempSQLStr .= PMA_Util::backquote($tables[$i][COL_NAMES][$m]);
+
+            if ($m != ($num_cols - 1)) {
+                $tempSQLStr .= ", ";
+            }
+        }
+
+        $tempSQLStr .= ") VALUES ";
+
+        for ($j = 0; $j < $num_rows; ++$j) {
+            $tempSQLStr .= "(";
+
+            for ($k = 0; $k < $num_cols; ++$k) {
+                // If fully formatted SQL, no need to enclose
+                // with aphostrophes, add shalshes etc.
+                if ($analyses != null
+                    && isset($analyses[$i][FORMATTEDSQL][$col_count])
+                    && $analyses[$i][FORMATTEDSQL][$col_count] == true
+                ) {
+                    $tempSQLStr .= (string) $tables[$i][ROWS][$j][$k];
+                } else {
+                    if ($analyses != null) {
+                        $is_varchar = ($analyses[$i][TYPES][$col_count] === VARCHAR);
+                    } else {
+                        $is_varchar = ! is_numeric($tables[$i][ROWS][$j][$k]);
+                    }
+
+                    /* Don't put quotes around NULL fields */
+                    if (! strcmp($tables[$i][ROWS][$j][$k], 'NULL')) {
+                        $is_varchar = false;
+                    }
+
+                    $tempSQLStr .= (($is_varchar) ? "'" : "");
+                    $tempSQLStr .= PMA_Util::sqlAddSlashes(
+                        (string) $tables[$i][ROWS][$j][$k]
+                    );
+                    $tempSQLStr .= (($is_varchar) ? "'" : "");
+                }
+
+                if ($k != ($num_cols - 1)) {
+                    $tempSQLStr .= ", ";
+                }
+
+                if ($col_count == ($num_cols - 1)) {
+                    $col_count = 0;
+                } else {
+                    $col_count++;
+                }
+
+                /* Delete the cell after we are done with it */
+                unset($tables[$i][ROWS][$j][$k]);
+            }
+
+            $tempSQLStr .= ")";
+
+            if ($j != ($num_rows - 1)) {
+                $tempSQLStr .= ",\n ";
+            }
+
+            $col_count = 0;
+            /* Delete the row after we are done with it */
+            unset($tables[$i][ROWS][$j]);
+        }
+
+        $tempSQLStr .= ";";
+
+        /**
+         * Each SQL statement is executed immediately
+         * after it is formed so that we don't have
+         * to store them in a (possibly large) buffer
+         */
+        PMA_importRunQuery($tempSQLStr, $tempSQLStr);
+    }
+
+    /* No longer needed */
+    unset($tempSQLStr);
+
+    /**
+     * A work in progress
+     */
+
+    /* Add the viewable structures from $additional_sql
+     * to $tables so they are also displayed
+     */
+    $view_pattern = '@VIEW `[^`]+`\.`([^`]+)@';
+    $table_pattern = '@CREATE TABLE IF NOT EXISTS `([^`]+)`@';
+    /* Check a third pattern to make sure its not a "USE `db_name`;" statement */
+
+    $regs = array();
+
+    $inTables = false;
+
+    $additional_sql_len = count($additional_sql);
+    for ($i = 0; $i < $additional_sql_len; ++$i) {
+        preg_match($view_pattern, $additional_sql[$i], $regs);
+
+        if (count($regs) == 0) {
+            preg_match($table_pattern, $additional_sql[$i], $regs);
+        }
+
+        if (count($regs)) {
+            for ($n = 0; $n < $num_tables; ++$n) {
+                if (! strcmp($regs[1], $tables[$n][TBL_NAME])) {
+                    $inTables = true;
+                    break;
+                }
+            }
+
+            if (! $inTables) {
+                $tables[] = array(TBL_NAME => $regs[1]);
+            }
+        }
+
+        /* Reset the array */
+        $regs = array();
+        $inTables = false;
+    }
+
+    $params = array('db' => (string)$db_name);
+    $db_url = 'db_structure.php' . PMA_generate_common_url($params);
+    $db_ops_url = 'db_operations.php' . PMA_generate_common_url($params);
+
+    $message = '<br /><br />';
+    $message .= '<strong>' . __('The following structures have either been created or altered. Here you can:') . '</strong><br />';
+    $message .= '<ul><li>' . __("View a structure's contents by clicking on its name") . '</li>';
+    $message .= '<li>' . __('Change any of its settings by clicking the corresponding "Options" link') . '</li>';
+    $message .= '<li>' . __('Edit structure by following the "Structure" link') . '</li>';
+    $message .= sprintf(
+        '<br /><li><a href="%s" title="%s">%s</a> (<a href="%s" title="%s">' . __('Options') . '</a>)</li>',
+        $db_url,
+        sprintf(__('Go to database: %s'), htmlspecialchars(PMA_Util::backquote($db_name))),
+        htmlspecialchars($db_name),
+        $db_ops_url,
+        sprintf(__('Edit settings for %s'), htmlspecialchars(PMA_Util::backquote($db_name)))
+    );
+
+    $message .= '<ul>';
+
+    unset($params);
+
+    $num_tables = count($tables);
+    for ($i = 0; $i < $num_tables; ++$i) {
+        $params = array(
+             'db' => (string) $db_name,
+             'table' => (string) $tables[$i][TBL_NAME]
+        );
+        $tbl_url = 'sql.php' . PMA_generate_common_url($params);
+        $tbl_struct_url = 'tbl_structure.php' . PMA_generate_common_url($params);
+        $tbl_ops_url = 'tbl_operations.php' . PMA_generate_common_url($params);
+
+        unset($params);
+
+        if (! PMA_Table::isView($db_name, $tables[$i][TBL_NAME])) {
+            $message .= sprintf(
+                '<li><a href="%s" title="%s">%s</a> (<a href="%s" title="%s">' . __('Structure') . '</a>) (<a href="%s" title="%s">' . __('Options') . '</a>)</li>',
+                $tbl_url,
+                sprintf(__('Go to table: %s'), htmlspecialchars(PMA_Util::backquote($tables[$i][TBL_NAME]))),
+                htmlspecialchars($tables[$i][TBL_NAME]),
+                $tbl_struct_url,
+                sprintf(__('Structure of %s'), htmlspecialchars(PMA_Util::backquote($tables[$i][TBL_NAME]))),
+                $tbl_ops_url,
+                sprintf(__('Edit settings for %s'), htmlspecialchars(PMA_Util::backquote($tables[$i][TBL_NAME])))
+            );
+        } else {
+            $message .= sprintf(
+                '<li><a href="%s" title="%s">%s</a></li>',
+                $tbl_url,
+                sprintf(__('Go to view: %s'), htmlspecialchars(PMA_Util::backquote($tables[$i][TBL_NAME]))),
+                htmlspecialchars($tables[$i][TBL_NAME])
+            );
+        }
+    }
+
+    $message .= '</ul></ul>';
+
+    global $import_notice;
+    $import_notice = $message;
+
+    unset($tables);
+}
+
+?>
diff --git a/phpmyadmin/libraries/index.lib.php b/phpmyadmin/libraries/index.lib.php
new file mode 100644
index 0000000..ac45bb2
--- /dev/null
+++ b/phpmyadmin/libraries/index.lib.php
@@ -0,0 +1,44 @@
+<?php
+
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * set of functions for structure section in pma
+ *
+ * @package PhpMyAdmin
+ */
+if (!defined('PHPMYADMIN')) {
+    exit;
+}
+
+require_once 'libraries/Index.class.php';
+
+/**
+ * Get HTML for display indexes
+ *
+ * @return string $html_output
+ */
+function PMA_getHtmlForDisplayIndexes()
+{
+    $html_output = PMA_Util::getDivForSliderEffect(
+        'indexes', __('Indexes')
+    );
+    $html_output .= PMA_Index::getView($GLOBALS['table'], $GLOBALS['db']);
+    $html_output .= '<fieldset class="tblFooters" style="text-align: left;">'
+        . '<form action="tbl_indexes.php" method="post">';
+    $html_output .= PMA_generate_common_hidden_inputs($GLOBALS['db'], $GLOBALS['table'])
+        . sprintf(
+            __('Create an index on  %s columns'),
+            '<input type="text" size="2" name="added_fields" value="1" />'
+        );
+    $html_output .= '<input type="hidden" name="create_index" value="1" />'
+        . '<input class="add_index ajax"'
+        . ' type="submit" value="' . __('Go') . '" />';
+
+    $html_output .= '</form>'
+        . '</fieldset>'
+        . '</div>'
+        . '</div>';
+
+    return $html_output;
+}
+
diff --git a/phpmyadmin/libraries/information_schema_relations.lib.php b/phpmyadmin/libraries/information_schema_relations.lib.php
new file mode 100644
index 0000000..e9f3c03
--- /dev/null
+++ b/phpmyadmin/libraries/information_schema_relations.lib.php
@@ -0,0 +1,138 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ *
+ * @package PhpMyAdmin
+ */
+if (! defined('PHPMYADMIN')) {
+    exit;
+}
+
+/**
+ *
+ */
+$GLOBALS['information_schema_relations'] = array(
+    'CHARACTER_SETS' => array(
+        'DEFAULT_COLLATE_NAME' => array(
+            'foreign_db'    => 'information_schema',
+            'foreign_table' => 'COLLATIONS',
+            'foreign_field' => 'COLLATION_NAME'
+        )
+    ),
+    'COLLATIONS' => array(
+        'CHARACTER_SET_NAME' => array(
+            'foreign_db'    => 'information_schema',
+            'foreign_table' => 'CHARACTER_SETS',
+            'foreign_field' => 'CHARACTER_SET_NAME'
+        )
+    ),
+    'COLLATION_CHARACTER_SET_APPLICABILITY' => array(
+        'CHARACTER_SET_NAME' => array(
+            'foreign_db'    => 'information_schema',
+            'foreign_table' => 'CHARACTER_SETS',
+            'foreign_field' => 'CHARACTER_SET_NAME'
+        ),
+        'COLLATION_NAME' => array(
+            'foreign_db'    => 'information_schema',
+            'foreign_table' => 'COLLATIONS',
+            'foreign_field' => 'COLLATION_NAME'
+        )
+    ),
+    'COLUMNS' => array(
+        'TABLE_SCHEMA' => array(
+            'foreign_db'    => 'information_schema',
+            'foreign_table' => 'SCHEMATA',
+            'foreign_field' => 'SCHEMA_NAME'
+        ),
+        'CHARACTER_SET_NAME' => array(
+            'foreign_db'    => 'information_schema',
+            'foreign_table' => 'CHARACTER_SETS',
+            'foreign_field' => 'CHARACTER_SET_NAME'
+        ),
+        'COLLATION_NAME' => array(
+            'foreign_db'    => 'information_schema',
+            'foreign_table' => 'COLLATIONS',
+            'foreign_field' => 'COLLATION_NAME'
+        )
+    ),
+    'COLUMN_PRIVILEGES' => array(
+        'TABLE_SCHEMA' => array(
+            'foreign_db'    => 'information_schema',
+            'foreign_table' => 'SCHEMATA',
+            'foreign_field' => 'SCHEMA_NAME'
+        )
+    ),
+    'KEY_COLUMN_USAGE' => array(
+        'CONSTRAINT_SCHEMA' => array(
+            'foreign_db'    => 'information_schema',
+            'foreign_table' => 'SCHEMATA',
+            'foreign_field' => 'SCHEMA_NAME'
+        ),
+        'TABLE_SCHEMA' => array(
+            'foreign_db'    => 'information_schema',
+            'foreign_table' => 'SCHEMATA',
+            'foreign_field' => 'SCHEMA_NAME'
+        )
+    ),
+    'ROUTINES' => array(
+        'ROUTINE_SCHEMA' => array(
+            'foreign_db'    => 'information_schema',
+            'foreign_table' => 'SCHEMATA',
+            'foreign_field' => 'SCHEMA_NAME'
+        )
+    ),
+    'SCHEMATA' => array(
+        'DEFAULT_CHARACTER_SET_NAME' => array(
+            'foreign_db'    => 'information_schema',
+            'foreign_table' => 'CHARACTER_SETS',
+            'foreign_field' => 'CHARACTER_SET_NAME'
+        )
+    ),
+    'SCHEMA_PRIVILEGES' => array(
+        'TABLE_SCHEMA' => array(
+            'foreign_db'    => 'information_schema',
+            'foreign_table' => 'SCHEMATA',
+            'foreign_field' => 'SCHEMA_NAME'
+        )
+    ),
+    'TABLES' => array(
+        'TABLE_SCHEMA' => array(
+            'foreign_db'    => 'information_schema',
+            'foreign_table' => 'SCHEMATA',
+            'foreign_field' => 'SCHEMA_NAME'
+        ),
+        'TABLE_COLLATION' => array(
+            'foreign_db'    => 'information_schema',
+            'foreign_table' => 'COLLATIONS',
+            'foreign_field' => 'COLLATION_NAME'
+        )
+    ),
+    'TABLE_CONSTRAINTS' => array(
+        'CONSTRAINT_SCHEMA' => array(
+            'foreign_db'    => 'information_schema',
+            'foreign_table' => 'SCHEMATA',
+            'foreign_field' => 'SCHEMA_NAME'
+        ),
+        'TABLE_SCHEMA' => array(
+            'foreign_db'    => 'information_schema',
+            'foreign_table' => 'SCHEMATA',
+            'foreign_field' => 'SCHEMA_NAME'
+        )
+    ),
+    'TABLE_PRIVILEGES' => array(
+        'TABLE_SCHEMA' => array(
+            'foreign_db'    => 'information_schema',
+            'foreign_table' => 'SCHEMATA',
+            'foreign_field' => 'SCHEMA_NAME'
+        )
+    ),
+    'VIEWS' => array(
+        'TABLE_SCHEMA' => array(
+            'foreign_db'    => 'information_schema',
+            'foreign_table' => 'SCHEMATA',
+            'foreign_field' => 'SCHEMA_NAME'
+        )
+    )
+);
+
+?>
diff --git a/phpmyadmin/libraries/insert_edit.lib.php b/phpmyadmin/libraries/insert_edit.lib.php
new file mode 100644
index 0000000..af5cb90
--- /dev/null
+++ b/phpmyadmin/libraries/insert_edit.lib.php
@@ -0,0 +1,2366 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * set of functions with the insert/edit features in pma
+ *
+ * @package PhpMyAdmin
+ */
+
+if (! defined('PHPMYADMIN')) {
+    exit;
+}
+
+/**
+ * Retrieve form parameters for insert/edit form
+ *
+ * @param string $db                 name of the database
+ * @param string $table              name of the table
+ * @param array  $where_clauses      where clauses
+ * @param array  $where_clause_array array of where clauses
+ * @param string $err_url            error url
+ *
+ * @return array $_form_params array of insert/edit form parameters
+ */
+function PMA_getFormParametersForInsertForm($db, $table, $where_clauses,
+    $where_clause_array, $err_url
+) {
+    $_form_params = array(
+        'db'        => $db,
+        'table'     => $table,
+        'goto'      => $GLOBALS['goto'],
+        'err_url'   => $err_url,
+        'sql_query' => $_REQUEST['sql_query'],
+    );
+    if (isset($where_clauses)) {
+        foreach ($where_clause_array as $key_id => $where_clause) {
+            $_form_params['where_clause[' . $key_id . ']'] = trim($where_clause);
+        }
+    }
+    if (isset($_REQUEST['clause_is_unique'])) {
+        $_form_params['clause_is_unique'] = $_REQUEST['clause_is_unique'];
+    }
+    return $_form_params;
+}
+
+/**
+ * Creates array of where clauses
+ *
+ * @param array $where_clause where clause
+ *
+ * @return whereClauseArray array of where clauses
+ */
+function PMA_getWhereClauseArray($where_clause)
+{
+    if (isset ($where_clause)) {
+        if (is_array($where_clause)) {
+            return $where_clause;
+        } else {
+            return array(0 => $where_clause);
+        }
+    }
+}
+
+/**
+ * Analysing where clauses array
+ *
+ * @param array  $where_clause_array array of where clauses
+ * @param string $table              name of the table
+ * @param string $db                 name of the database
+ *
+ * @return array $where_clauses, $result, $rows
+ */
+function PMA_analyzeWhereClauses(
+    $where_clause_array, $table, $db
+) {
+    $rows               = array();
+    $result             = array();
+    $where_clauses      = array();
+    $found_unique_key   = false;
+    foreach ($where_clause_array as $key_id => $where_clause) {
+
+        $local_query     = 'SELECT * FROM '
+            . PMA_Util::backquote($db) . '.'
+            . PMA_Util::backquote($table)
+            . ' WHERE ' . $where_clause . ';';
+        $result[$key_id] = PMA_DBI_query($local_query, null, PMA_DBI_QUERY_STORE);
+        $rows[$key_id]   = PMA_DBI_fetch_assoc($result[$key_id]);
+
+        $where_clauses[$key_id] = str_replace('\\', '\\\\', $where_clause);
+        $has_unique_condition   = PMA_showEmptyResultMessageOrSetUniqueCondition(
+            $rows, $key_id, $where_clause_array, $local_query, $result
+        );
+        if ($has_unique_condition) {
+            $found_unique_key = true;
+        }
+    }
+    return array($where_clauses, $result, $rows, $found_unique_key);
+}
+
+/**
+ * Show message for empty reult or set the unique_condition
+ *
+ * @param array  $rows               MySQL returned rows
+ * @param string $key_id             ID in current key
+ * @param array  $where_clause_array array of where clauses
+ * @param string $local_query        query performed
+ * @param array  $result             MySQL result handle
+ *
+ * @return boolean $has_unique_condition
+ */
+function PMA_showEmptyResultMessageOrSetUniqueCondition($rows, $key_id,
+    $where_clause_array, $local_query, $result
+) {
+    $has_unique_condition = false;
+
+    // No row returned
+    if (! $rows[$key_id]) {
+        unset($rows[$key_id], $where_clause_array[$key_id]);
+        PMA_Response::getInstance()->addHtml(
+            PMA_Util::getMessage(
+                __('MySQL returned an empty result set (i.e. zero rows).'),
+                $local_query
+            )
+        );
+        /**
+         * @todo not sure what should be done at this point, but we must not
+         * exit if we want the message to be displayed
+         */
+    } else {// end if (no row returned)
+        $meta = PMA_DBI_get_fields_meta($result[$key_id]);
+
+        list($unique_condition, $tmp_clause_is_unique)
+            = PMA_Util::getUniqueCondition(
+                $result[$key_id], count($meta), $meta, $rows[$key_id], true
+            );
+
+        if (! empty($unique_condition)) {
+            $has_unique_condition = true;
+        }
+        unset($unique_condition, $tmp_clause_is_unique);
+    }
+    return $has_unique_condition;
+}
+
+/**
+ * No primary key given, just load first row
+ *
+ * @param string $table name of the table
+ * @param string $db    name of the database
+ *
+ * @return array                containing $result and $rows arrays
+ */
+function PMA_loadFirstRow($table, $db)
+{
+    $result = PMA_DBI_query(
+        'SELECT * FROM ' . PMA_Util::backquote($db)
+        . '.' . PMA_Util::backquote($table) . ' LIMIT 1;',
+        null,
+        PMA_DBI_QUERY_STORE
+    );
+    $rows = array_fill(0, $GLOBALS['cfg']['InsertRows'], false);
+    return array($result, $rows);
+}
+
+/**
+ * Add some url parameters
+ *
+ * @param array  $url_params         containing $db and $table as url parameters
+ * @param array  $where_clause_array where clauses array
+ * @param string $where_clause       where clause
+ *
+ * @return array Add some url parameters to $url_params array and return it
+ */
+function PMA_urlParamsInEditMode($url_params, $where_clause_array, $where_clause)
+{
+    if (isset($where_clause)) {
+        foreach ($where_clause_array as $where_clause) {
+            $url_params['where_clause'] = trim($where_clause);
+        }
+    }
+    if (! empty($_REQUEST['sql_query'])) {
+        $url_params['sql_query'] = $_REQUEST['sql_query'];
+    }
+    return $url_params;
+}
+
+/**
+ * Show function fields in data edit view in pma
+ *
+ * @param array   $url_params     containing url parameters
+ * @param boolean $showFuncFields whether to show function field
+ *
+ * @return string an html snippet
+ */
+function PMA_showFunctionFieldsInEditMode($url_params, $showFuncFields)
+{
+    $params = array();
+    if (! $showFuncFields) {
+        $params['ShowFunctionFields'] = 1;
+    } else {
+        $params['ShowFunctionFields'] = 0;
+    }
+    $params['ShowFieldTypesInDataEditView']
+        = $GLOBALS['cfg']['ShowFieldTypesInDataEditView'];
+    $params['goto'] = 'sql.php';
+    $this_url_params = array_merge($url_params, $params);
+    if (! $showFuncFields) {
+        return ' : <a href="tbl_change.php'
+            . PMA_generate_common_url($this_url_params) . '">'
+            . __('Function')
+            . '</a>' . "\n";
+    }
+    return '<th><a href="tbl_change.php'
+        . PMA_generate_common_url($this_url_params)
+        . '" title="' . __('Hide') . '">'
+        . __('Function')
+        . '</a></th>' . "\n";
+}
+
+/**
+ * Show field types in data edit view in pma
+ *
+ * @param array   $url_params     containing url parameters
+ * @param boolean $showColumnType whether to show column type
+ *
+ * @return string an html snippet
+ */
+function PMA_showColumnTypesInDataEditView($url_params, $showColumnType)
+{
+    $params = array();
+    if (! $showColumnType) {
+        $params['ShowFieldTypesInDataEditView'] = 1;
+    } else {
+        $params['ShowFieldTypesInDataEditView'] = 0;
+    }
+    $params['ShowFunctionFields'] = $GLOBALS['cfg']['ShowFunctionFields'];
+    $params['goto'] = 'sql.php';
+    $this_other_url_params = array_merge($url_params, $params);
+    if (! $showColumnType) {
+        return ' : <a href="tbl_change.php'
+            . PMA_generate_common_url($this_other_url_params) . '">'
+            . __('Type') . '</a>' . "\n";
+    }
+    return '<th><a href="tbl_change.php'
+        . PMA_generate_common_url($this_other_url_params)
+        . '" title="' . __('Hide') . '">' . __('Type') . '</a></th>' . "\n";
+
+}
+
+/**
+ * Retrieve the default for datetime data type
+ *
+ * @param array $column containing column type, Default and null
+ *
+ * @return nothing
+ */
+function PMA_getDefaultForDatetime($column)
+{
+    // d a t e t i m e
+    //
+    // Current date should not be set as default if the field is NULL
+    // for the current row, but do not put here the current datetime
+    // if there is a default value (the real default value will be set
+    // in the Default value logic below)
+
+    // Note: (tested in MySQL 4.0.16): when lang is some UTF-8,
+    // $column['Default'] is not set if it contains NULL:
+    // Array ([Field] => d [Type] => datetime [Null] => YES [Key] =>
+    // [Extra] => [True_Type] => datetime)
+    // but, look what we get if we switch to iso: (Default is NULL)
+    // Array ([Field] => d [Type] => datetime [Null] => YES [Key] =>
+    // [Default] => [Extra] => [True_Type] => datetime)
+    // so I force a NULL into it (I don't think it's possible
+    // to have an empty default value for DATETIME)
+    // then, the "if" after this one will work
+    if ($column['Type'] == 'datetime'
+        && ! isset($column['Default'])
+        && isset($column['Null'])
+        && $column['Null'] == 'YES'
+    ) {
+        $column['Default'] = null;
+    }
+}
+
+ /**
+  * Analyze the table column array
+  *
+  * @param array   $column         description of column in given table
+  * @param array   $comments_map   comments for every column that has a comment
+  * @param boolean $timestamp_seen whether a timestamp has been seen
+  *
+  * @return array                   description of column in given table
+  */
+function PMA_analyzeTableColumnsArray($column, $comments_map, $timestamp_seen)
+{
+    $column['Field_html']    = htmlspecialchars($column['Field']);
+    $column['Field_md5']     = md5($column['Field']);
+    // True_Type contains only the type (stops at first bracket)
+    $column['True_Type']     = preg_replace('@\(.*@s', '', $column['Type']);
+    PMA_getDefaultForDatetime($column);
+    $column['len'] = preg_match('@float|double@', $column['Type']) ? 100 : -1;
+    $column['Field_title']   = PMA_getColumnTitle($column, $comments_map);
+    $column['is_binary']     = PMA_isColumnBinary($column);
+    $column['is_blob']       = PMA_isColumnBlob($column);
+    $column['is_char']       = PMA_isColumnChar($column);
+    list($column['pma_type'], $column['wrap'], $column['first_timestamp'])
+        = PMA_getEnumSetAndTimestampColumns($column, $timestamp_seen);
+
+    return $column;
+}
+
+ /**
+  * Retrieve the column title
+  *
+  * @param array $column       description of column in given table
+  * @param array $comments_map comments for every column that has a comment
+  *
+  * @return string              column title
+  */
+function PMA_getColumnTitle($column, $comments_map)
+{
+    if (isset($comments_map[$column['Field']])) {
+        return '<span style="border-bottom: 1px dashed black;" title="'
+            . htmlspecialchars($comments_map[$column['Field']]) . '">'
+            . $column['Field_html'] . '</span>';
+    } else {
+            return $column['Field_html'];
+    }
+}
+
+ /**
+  * check whether the column is a bainary
+  *
+  * @param array $column description of column in given table
+  *
+  * @return boolean If check to ensure types such as "enum('one','two','binary',..)"
+  *                 or "enum('one','two','varbinary',..)" are not categorized as
+  *                 binary.
+  */
+function PMA_isColumnBinary($column)
+{
+    // The type column.
+    // Fix for bug #3152931 'ENUM and SET cannot have "Binary" option'
+    if (stripos($column['Type'], 'binary') === 0
+        || stripos($column['Type'], 'varbinary') === 0
+    ) {
+        return stristr($column['Type'], 'binary');
+    } else {
+        return false;
+    }
+
+}
+
+ /**
+  * check whether the column is a blob
+  *
+  * @param array $column description of column in given table
+  *
+  * @return boolean If check to ensure types such as "enum('one','two','blob',..)"
+  *                 or "enum('one','two','tinyblob',..)" etc. are not categorized
+  *                 as blob.
+  */
+function PMA_isColumnBlob($column)
+{
+    if (stripos($column['Type'], 'blob') === 0
+        || stripos($column['Type'], 'tinyblob') === 0
+        || stripos($column['Type'], 'mediumblob') === 0
+        || stripos($column['Type'], 'longblob') === 0
+    ) {
+        return stristr($column['Type'], 'blob');
+    } else {
+        return false;
+    }
+}
+
+/**
+ * check is table column char
+ *
+ * @param array $column description of column in given table
+ *
+ * @return boolean If check to ensure types such as "enum('one','two','char',..)" or
+ *                 "enum('one','two','varchar',..)" are not categorized as char.
+ */
+function PMA_isColumnChar($column)
+{
+    if (stripos($column['Type'], 'char') === 0
+        || stripos($column['Type'], 'varchar') === 0
+    ) {
+        return stristr($column['Type'], 'char');
+    } else {
+        return false;
+    }
+}
+/**
+ * Retrieve set, enum, timestamp table columns
+ *
+ * @param array   $column         description of column in given table
+ * @param boolean $timestamp_seen whether a timestamp has been seen
+ *
+ * @return array $column['pma_type'], $column['wrap'], $column['first_timestamp']
+ */
+function PMA_getEnumSetAndTimestampColumns($column, $timestamp_seen)
+{
+    $column['first_timestamp'] = false;
+    switch ($column['True_Type']) {
+    case 'set':
+        $column['pma_type'] = 'set';
+        $column['wrap']  = '';
+        break;
+    case 'enum':
+        $column['pma_type'] = 'enum';
+        $column['wrap']  = '';
+        break;
+    case 'timestamp':
+        if (! $timestamp_seen) {   // can only occur once per table
+            $timestamp_seen  = true;
+            $column['first_timestamp'] = true;
+        }
+        $column['pma_type'] = $column['Type'];
+        $column['wrap']  = ' nowrap';
+        break;
+
+    default:
+        $column['pma_type'] = $column['Type'];
+        $column['wrap']  = ' nowrap';
+        break;
+    }
+    return array($column['pma_type'], $column['wrap'], $column['first_timestamp']);
+}
+
+/**
+ * The function column
+ * We don't want binary data to be destroyed
+ * Note: from the MySQL manual: "BINARY doesn't affect how the column is
+ *       stored or retrieved" so it does not mean that the contents is binary
+ *
+ * @param array   $column                description of column in given table
+ * @param boolean $is_upload             upload or no
+ * @param string  $column_name_appendix  the name atttibute
+ * @param string  $unnullify_trigger     validation string
+ * @param array   $no_support_types      list of datatypes that are not (yet)
+ *                                       handled by PMA
+ * @param integer $tabindex_for_function +3000
+ * @param integer $tabindex              tab index
+ * @param integer $idindex               id index
+ * @param boolean $insert_mode           insert mode or edit mode
+ *
+ * @return string                           an html sippet
+ */
+function PMA_getFunctionColumn($column, $is_upload, $column_name_appendix,
+    $unnullify_trigger, $no_support_types, $tabindex_for_function,
+    $tabindex, $idindex, $insert_mode
+) {
+    $html_output = '';
+    if (($GLOBALS['cfg']['ProtectBinary'] && $column['is_blob'] && ! $is_upload)
+        || ($GLOBALS['cfg']['ProtectBinary'] === 'all' && $column['is_binary'])
+        || ($GLOBALS['cfg']['ProtectBinary'] === 'noblob' && ! $column['is_blob'])
+    ) {
+        $html_output .= '<td class="center">' . __('Binary') . '</td>' . "\n";
+    } elseif (strstr($column['True_Type'], 'enum')
+        || strstr($column['True_Type'], 'set')
+        || in_array($column['pma_type'], $no_support_types)
+    ) {
+        $html_output .= '<td class="center">--</td>' . "\n";
+    } else {
+        $html_output .= '<td>' . "\n";
+
+        $html_output .= '<select name="funcs' . $column_name_appendix . '"'
+            . ' ' . $unnullify_trigger
+            . ' tabindex="' . ($tabindex + $tabindex_for_function) . '"'
+            . ' id="field_' . $idindex . '_1">';
+        $html_output .= PMA_Util::getFunctionsForField($column, $insert_mode) . "\n";
+
+        $html_output .= '</select>' .  "\n";
+        $html_output .= '</td>' .  "\n";
+    }
+    return $html_output;
+}
+
+/**
+ * The null column
+ *
+ * @param array   $column               description of column in given table
+ * @param string  $column_name_appendix the name atttibute
+ * @param array   $real_null_value      is column value null or not null
+ * @param integer $tabindex             tab index
+ * @param integer $tabindex_for_null    +6000
+ * @param integer $idindex              id index
+ * @param array   $vkey                 [multi_edit]['row_id']
+ * @param array   $foreigners           keys into foreign fields
+ * @param array   $foreignData          data about the foreign keys
+ *
+ * @return string                       an html snippet
+ */
+function PMA_getNullColumn($column, $column_name_appendix, $real_null_value,
+    $tabindex, $tabindex_for_null, $idindex, $vkey, $foreigners, $foreignData
+) {
+    if ($column['Null'] != 'YES') {
+        return "<td></td>\n";
+    }
+    $html_output = '';
+    $html_output .= '<td>' . "\n";
+    $html_output .= '<input type="hidden" name="fields_null_prev'
+        . $column_name_appendix . '"';
+    if ($real_null_value && !$column['first_timestamp']) {
+        $html_output .= ' value="on"';
+    }
+    $html_output .= ' />' . "\n";
+
+    $html_output .= '<input type="checkbox" class="checkbox_null" tabindex="'
+        . ($tabindex + $tabindex_for_null) . '"'
+        . ' name="fields_null' . $column_name_appendix . '"';
+    if ($real_null_value) {
+        $html_output .= ' checked="checked"';
+    }
+    $html_output .= ' id="field_' . ($idindex) . '_2" />';
+
+    // nullify_code is needed by the js nullify() function
+    $nullify_code = PMA_getNullifyCodeForNullColumn(
+        $column, $foreigners, $foreignData
+    );
+    // to be able to generate calls to nullify() in jQuery
+    $html_output .= '<input type="hidden" class="nullify_code" name="nullify_code'
+        . $column_name_appendix . '" value="' . $nullify_code . '" />';
+    $html_output .= '<input type="hidden" class="hashed_field" name="hashed_field'
+        . $column_name_appendix . '" value="' .  $column['Field_md5'] . '" />';
+    $html_output .= '<input type="hidden" class="multi_edit" name="multi_edit'
+        . $column_name_appendix . '" value="' . PMA_escapeJsString($vkey) . '" />';
+    $html_output .= '</td>' . "\n";
+
+    return $html_output;
+}
+
+/**
+ * Retrieve the nullify code for the null column
+ *
+ * @param array $column      description of column in given table
+ * @param array $foreigners  keys into foreign fields
+ * @param array $foreignData data about the foreign keys
+ *
+ * @return integer              $nullify_code
+ */
+function PMA_getNullifyCodeForNullColumn($column, $foreigners, $foreignData)
+{
+    if (strstr($column['True_Type'], 'enum')) {
+        if (strlen($column['Type']) > 20) {
+            $nullify_code = '1';
+        } else {
+            $nullify_code = '2';
+        }
+    } elseif (strstr($column['True_Type'], 'set')) {
+        $nullify_code = '3';
+    } elseif ($foreigners
+        && isset($foreigners[$column['Field']])
+        && $foreignData['foreign_link'] == false
+    ) {
+        // foreign key in a drop-down
+        $nullify_code = '4';
+    } elseif ($foreigners
+        && isset($foreigners[$column['Field']])
+        && $foreignData['foreign_link'] == true
+    ) {
+        // foreign key with a browsing icon
+        $nullify_code = '6';
+    } else {
+        $nullify_code = '5';
+    }
+    return $nullify_code;
+}
+
+/**
+ * Get the HTML elements for value column in insert form
+ *
+ * @param array   $column                description of column in given table
+ * @param string  $backup_field          hidden input field
+ * @param string  $column_name_appendix  the name atttibute
+ * @param string  $unnullify_trigger     validation string
+ * @param integer $tabindex              tab index
+ * @param integer $tabindex_for_value    offset for the values tabindex
+ * @param integer $idindex               id index
+ * @param array   $data                  description of the column field
+ * @param array   $special_chars         special characters
+ * @param array   $foreignData           data about the foreign keys
+ * @param boolean $odd_row               whether row is odd
+ * @param array   $paramTableDbArray     array containing $table and $db
+ * @param array   $rownumber_param       &rownumber=row_id
+ * @param array   $titles                An HTML IMG tag for a particular icon from
+ *                                       a theme, which may be an actual file or
+ *                                       an icon from a sprite
+ * @param array   $text_dir              text direction
+ * @param string  $special_chars_encoded replaced char if the string starts
+ *                                       with a \r\n pair (0x0d0a) add an extra \n
+ * @param string  $vkey                  [multi_edit]['row_id']
+ * @param boolean $is_upload             is upload or not
+ * @param integer $biggest_max_file_size 0 intger
+ * @param string  $default_char_editing  default char editing mode which is stroe
+ *                                       in the config.inc.php script
+ * @param array   $no_support_types      list of datatypes that are not (yet)
+ *                                       handled by PMA
+ * @param array   $gis_data_types        list of GIS data types
+ * @param array   $extracted_columnspec  associative array containing type,
+ *                                       spec_in_brackets and possibly
+ *                                       enum_set_values (another array)
+ *
+ * @return string an html snippet
+ */
+function PMA_getValueColumn($column, $backup_field, $column_name_appendix,
+    $unnullify_trigger, $tabindex, $tabindex_for_value, $idindex, $data,
+    $special_chars, $foreignData, $odd_row, $paramTableDbArray, $rownumber_param,
+    $titles, $text_dir, $special_chars_encoded, $vkey,
+    $is_upload, $biggest_max_file_size,
+    $default_char_editing, $no_support_types, $gis_data_types, $extracted_columnspec
+) {
+    $html_output = '';
+
+    if ($foreignData['foreign_link'] == true) {
+        $html_output .= PMA_getForeignLink(
+            $column, $backup_field, $column_name_appendix,
+            $unnullify_trigger, $tabindex, $tabindex_for_value, $idindex, $data,
+            $paramTableDbArray, $rownumber_param, $titles
+        );
+
+    } elseif (is_array($foreignData['disp_row'])) {
+        $html_output .= PMA_dispRowForeignData(
+            $backup_field, $column_name_appendix,
+            $unnullify_trigger, $tabindex, $tabindex_for_value,
+            $idindex, $data, $foreignData
+        );
+
+    } elseif ($GLOBALS['cfg']['LongtextDoubleTextarea']
+        && strstr($column['pma_type'], 'longtext')
+    ) {
+        $html_output = ' </td>';
+        $html_output .= '</tr>';
+        $html_output .= '<tr class="' . ($odd_row ? 'odd' : 'even') . '">'
+            . '<td colspan="5" class="right">';
+        $html_output .= PMA_getTextarea(
+            $column, $backup_field, $column_name_appendix, $unnullify_trigger,
+            $tabindex, $tabindex_for_value, $idindex, $text_dir,
+            $special_chars_encoded
+        );
+
+    } elseif (strstr($column['pma_type'], 'text')) {
+
+        $html_output .= PMA_getTextarea(
+            $column, $backup_field, $column_name_appendix, $unnullify_trigger,
+            $tabindex, $tabindex_for_value, $idindex, $text_dir,
+            $special_chars_encoded
+        );
+        $html_output .= "\n";
+        if (strlen($special_chars) > 32000) {
+            $html_output .= "</td>\n";
+            $html_output .= '<td>' . __(
+                'Because of its length,<br /> this column might not be editable'
+            );
+        }
+
+    } elseif ($column['pma_type'] == 'enum') {
+        $html_output .= PMA_getPmaTypeEnum(
+            $column, $backup_field, $column_name_appendix, $extracted_columnspec,
+            $unnullify_trigger, $tabindex, $tabindex_for_value, $idindex, $data
+        );
+
+    } elseif ($column['pma_type'] == 'set') {
+        $html_output .= PMA_getPmaTypeSet(
+            $column, $extracted_columnspec, $backup_field,
+            $column_name_appendix, $unnullify_trigger, $tabindex,
+            $tabindex_for_value, $idindex, $data
+        );
+
+    } elseif ($column['is_binary'] || $column['is_blob']) {
+        $html_output .= PMA_getBinaryAndBlobColumn(
+            $column, $data, $special_chars, $biggest_max_file_size,
+            $backup_field, $column_name_appendix, $unnullify_trigger, $tabindex,
+            $tabindex_for_value, $idindex, $text_dir, $special_chars_encoded,
+            $vkey, $is_upload
+        );
+
+    } elseif (! in_array($column['pma_type'], $no_support_types)) {
+        $html_output .= PMA_getNoSupportTypes(
+            $column, $default_char_editing, $backup_field,
+            $column_name_appendix, $unnullify_trigger, $tabindex, $special_chars,
+            $tabindex_for_value, $idindex, $text_dir, $special_chars_encoded,
+            $data, $extracted_columnspec
+        );
+    }
+
+    if (in_array($column['pma_type'], $gis_data_types)) {
+        $html_output .= PMA_getHTMLforGisDataTypes();
+    }
+
+    return $html_output;
+}
+
+/**
+ * Get HTML for foreign link in insert form
+ *
+ * @param array   $column               description of column in given table
+ * @param string  $backup_field         hidden input field
+ * @param string  $column_name_appendix the name atttibute
+ * @param string  $unnullify_trigger    validation string
+ * @param integer $tabindex             tab index
+ * @param integer $tabindex_for_value   offset for the values tabindex
+ * @param integer $idindex              id index
+ * @param array   $data                 data to edit
+ * @param array   $paramTableDbArray    array containing $table and $db
+ * @param array   $rownumber_param      &rownumber=row_id
+ * @param array   $titles               An HTML IMG tag for a particular icon from
+ *                                      a theme, which may be an actual file or
+ *                                      an icon from a sprite
+ *
+ * @return string                       an html snippet
+ */
+function PMA_getForeignLink($column, $backup_field, $column_name_appendix,
+    $unnullify_trigger, $tabindex, $tabindex_for_value, $idindex, $data,
+    $paramTableDbArray, $rownumber_param, $titles
+) {
+    list($table, $db) = $paramTableDbArray;
+    $html_output = '';
+    $html_output .= $backup_field . "\n";
+
+    $html_output .= '<input type="hidden" name="fields_type'
+        . $column_name_appendix . '" value="foreign" />';
+
+    $html_output .= '<input type="text" name="fields' . $column_name_appendix . '" '
+        . 'class="textfield" '
+        . $unnullify_trigger . ' '
+        . 'tabindex="' . ($tabindex + $tabindex_for_value) . '" '
+        . 'id="field_' . ($idindex) . '_3" '
+        . 'value="' . htmlspecialchars($data) . '" />';
+
+    $html_output .= '<a class="foreign_values_anchor" target="_blank" '
+        . 'onclick="window.open(this.href,\'foreigners\', \'width=640,height=240,'
+        . 'scrollbars=yes,resizable=yes\'); return false;" '
+        . 'href="browse_foreigners.php?'
+        . PMA_generate_common_url($db, $table) . '&field='
+        . PMA_escapeJsString(urlencode($column['Field']) . $rownumber_param) . '">'
+        . str_replace("'", "\'", $titles['Browse']) . '</a>';
+    return $html_output;
+}
+
+/**
+ * Get HTML to display foreign data
+ *
+ * @param string  $backup_field         hidden input field
+ * @param string  $column_name_appendix the name atttibute
+ * @param string  $unnullify_trigger    validation string
+ * @param integer $tabindex             tab index
+ * @param integer $tabindex_for_value   offset for the values tabindex
+ * @param integer $idindex              id index
+ * @param array   $data                 data to edit
+ * @param array   $foreignData          data about the foreign keys
+ *
+ * @return string                       an html snippet
+ */
+function PMA_dispRowForeignData($backup_field, $column_name_appendix,
+    $unnullify_trigger, $tabindex, $tabindex_for_value, $idindex, $data,
+    $foreignData
+) {
+    $html_output = '';
+    $html_output .= $backup_field . "\n";
+    $html_output .= '<input type="hidden"'
+        . ' name="fields_type' . $column_name_appendix . '"'
+        . ' value="foreign" />';
+
+    $html_output .= '<select name="fields' . $column_name_appendix . '"'
+        . ' ' . $unnullify_trigger
+        . ' class="textfield"'
+        . ' tabindex="' . ($tabindex + $tabindex_for_value). '"'
+        . ' id="field_' . $idindex . '_3">';
+    $html_output .= PMA_foreignDropdown(
+        $foreignData['disp_row'], $foreignData['foreign_field'],
+        $foreignData['foreign_display'], $data,
+        $GLOBALS['cfg']['ForeignKeyMaxLimit']
+    );
+    $html_output .= '</select>';
+
+    return $html_output;
+}
+
+/**
+ * Get HTML textarea for insert form
+ *
+ * @param array   $column                column information
+ * @param string  $backup_field          hidden input field
+ * @param string  $column_name_appendix  the name atttibute
+ * @param string  $unnullify_trigger     validation string
+ * @param integer $tabindex              tab index
+ * @param integer $tabindex_for_value    offset for the values tabindex
+ * @param integer $idindex               id index
+ * @param array   $text_dir              text direction
+ * @param array   $special_chars_encoded replaced char if the string starts
+ *                                       with a \r\n pair (0x0d0a) add an extra \n
+ *
+ * @return string                       an html snippet
+ */
+function PMA_getTextarea($column, $backup_field, $column_name_appendix,
+    $unnullify_trigger,
+    $tabindex, $tabindex_for_value, $idindex, $text_dir, $special_chars_encoded
+) {
+    $the_class = '';
+    $textAreaRows = $GLOBALS['cfg']['TextareaRows'];
+    $textareaCols = $GLOBALS['cfg']['TextareaCols'];
+
+    if ($column['is_char']) {
+        $the_class = 'char';
+        $textAreaRows = $GLOBALS['cfg']['CharTextareaRows'];
+        $textareaCols = $GLOBALS['cfg']['CharTextareaCols'];
+    } elseif ($GLOBALS['cfg']['LongtextDoubleTextarea']
+        && strstr($column['pma_type'], 'longtext')
+    ) {
+        $textAreaRows = $GLOBALS['cfg']['TextareaRows'] * 2;
+        $textareaCols = $GLOBALS['cfg']['TextareaCols'] * 2;
+    }
+    $html_output = $backup_field . "\n"
+        . '<textarea name="fields' . $column_name_appendix . '"'
+        . ' class="' . $the_class . '"'
+        . ' rows="' . $textAreaRows . '"'
+        . ' cols="' . $textareaCols . '"'
+        . ' dir="' . $text_dir . '"'
+        . ' id="field_' . ($idindex) . '_3"'
+        . ' ' . $unnullify_trigger
+        . ' tabindex="' . ($tabindex + $tabindex_for_value) . '">'
+        . $special_chars_encoded
+        . '</textarea>';
+
+    return $html_output;
+}
+
+/**
+ * Get HTML for enum type
+ *
+ * @param type $column               description of column in given table
+ * @param type $backup_field         hidden input field
+ * @param type $column_name_appendix the name atttibute
+ * @param type $extracted_columnspec associative array containing type,
+ *                                   spec_in_brackets and possibly
+ *                                   enum_set_values (another array)
+ * @param type $unnullify_trigger    validation string
+ * @param type $tabindex             tab index
+ * @param type $tabindex_for_value   offset for the values tabindex
+ * @param type $idindex              id index
+ * @param type $data                 data to edit
+ *
+ * @return type string an html snippet
+ */
+function PMA_getPmaTypeEnum($column, $backup_field, $column_name_appendix,
+    $extracted_columnspec, $unnullify_trigger, $tabindex, $tabindex_for_value,
+    $idindex, $data
+) {
+    $html_output = '';
+    if (! isset($column['values'])) {
+        $column['values'] = PMA_getColumnEnumValues(
+            $column, $extracted_columnspec
+        );
+    }
+    $column_enum_values = $column['values'];
+    $html_output .= '<input type="hidden" name="fields_type'
+        . $column_name_appendix. '" value="enum" />';
+    $html_output .= '<input type="hidden" name="fields'
+        . $column_name_appendix . '" value="" />';
+    $html_output .= "\n" . '            ' . $backup_field . "\n";
+    if (strlen($column['Type']) > 20) {
+        $html_output .= PMA_getDropDownDependingOnLength(
+            $column, $column_name_appendix, $unnullify_trigger,
+            $tabindex, $tabindex_for_value, $idindex, $data, $column_enum_values
+        );
+    } else {
+        $html_output .= PMA_getRadioButtonDependingOnLength(
+            $column_name_appendix, $unnullify_trigger,
+            $tabindex, $column, $tabindex_for_value,
+            $idindex, $data, $column_enum_values
+        );
+    }
+    return $html_output;
+}
+
+/**
+ * Get column values
+ *
+ * @param array $column               description of column in given table
+ * @param array $extracted_columnspec associative array containing type,
+ *                                    spec_in_brackets and possibly enum_set_values
+ *                                    (another array)
+ *
+ * @return array column values as an associative array
+ */
+function PMA_getColumnEnumValues($column, $extracted_columnspec)
+{
+    $column['values'] = array();
+    foreach ($extracted_columnspec['enum_set_values'] as $val) {
+        $column['values'][] = array(
+            'plain' => $val,
+            'html'  => htmlspecialchars($val),
+        );
+    }
+    return $column['values'];
+}
+
+/**
+ * Get HTML drop down for more than 20 string length
+ *
+ * @param array   $column               description of column in given table
+ * @param string  $column_name_appendix the name atttibute
+ * @param string  $unnullify_trigger    validation string
+ * @param integer $tabindex             tab index
+ * @param integer $tabindex_for_value   offset for the values tabindex
+ * @param integer $idindex              id index
+ * @param array   $data                 data to edit
+ * @param array   $column_enum_values   $column['values']
+ *
+ * @return string                       an html snippet
+ */
+function PMA_getDropDownDependingOnLength(
+    $column, $column_name_appendix, $unnullify_trigger,
+    $tabindex, $tabindex_for_value, $idindex, $data, $column_enum_values
+) {
+    $html_output = '<select name="fields' . $column_name_appendix . '"'
+        . ' ' . $unnullify_trigger
+        . ' class="textfield"'
+        . ' tabindex="' . ($tabindex + $tabindex_for_value) . '"'
+        . ' id="field_' . ($idindex) . '_3">';
+    $html_output .= '<option value=""> </option>' . "\n";
+
+    foreach ($column_enum_values as $enum_value) {
+        $html_output .= '<option value="' . $enum_value['html'] . '"';
+        if ($data == $enum_value['plain']
+            || ($data == ''
+            && (! isset($_REQUEST['where_clause']) || $column['Null'] != 'YES')
+            && isset($column['Default'])
+            && $enum_value['plain'] == $column['Default'])
+        ) {
+            $html_output .= ' selected="selected"';
+        }
+        $html_output .= '>' . $enum_value['html'] . '</option>' . "\n";
+    }
+    $html_output .= '</select>';
+    return $html_output;
+}
+
+/**
+ * Get HTML radio button for less than 20 string length
+ *
+ * @param string  $column_name_appendix the name atttibute
+ * @param string  $unnullify_trigger    validation string
+ * @param integer $tabindex             tab index
+ * @param array   $column               description of column in given table
+ * @param integer $tabindex_for_value   offset for the values tabindex
+ * @param integer $idindex              id index
+ * @param array   $data                 data to edit
+ * @param array   $column_enum_values   $column['values']
+ *
+ * @return string                       an html snippet
+ */
+function PMA_getRadioButtonDependingOnLength(
+    $column_name_appendix, $unnullify_trigger,
+    $tabindex, $column, $tabindex_for_value, $idindex, $data, $column_enum_values
+) {
+    $j = 0;
+    $html_output = '';
+    foreach ($column_enum_values as $enum_value) {
+        $html_output .= '            '
+            . '<input type="radio" name="fields' . $column_name_appendix . '"'
+            . ' class="textfield"'
+            . ' value="' . $enum_value['html'] . '"'
+            . ' id="field_' . ($idindex) . '_3_'  . $j . '"'
+            . ' ' . $unnullify_trigger;
+        if ($data == $enum_value['plain']
+            || ($data == ''
+            && (! isset($_REQUEST['where_clause']) || $column['Null'] != 'YES')
+            && isset($column['Default'])
+            && $enum_value['plain'] == $column['Default'])
+        ) {
+            $html_output .= ' checked="checked"';
+        }
+        $html_output .= ' tabindex="' . ($tabindex + $tabindex_for_value) . '" />';
+        $html_output .= '<label for="field_' . $idindex . '_3_' . $j . '">'
+            . $enum_value['html'] . '</label>' . "\n";
+        $j++;
+    }
+    return $html_output;
+}
+
+/**
+ * Get the HTML for 'set' pma type
+ *
+ * @param array   $column               description of column in given table
+ * @param array   $extracted_columnspec associative array containing type,
+ *                                      spec_in_brackets and possibly
+ *                                      enum_set_values (another array)
+ * @param string  $backup_field         hidden input field
+ * @param string  $column_name_appendix the name atttibute
+ * @param string  $unnullify_trigger    validation string
+ * @param integer $tabindex             tab index
+ * @param integer $tabindex_for_value   offset for the values tabindex
+ * @param integer $idindex              id index
+ * @param array   $data                 description of the column field
+ *
+ * @return string                       an html snippet
+ */
+function PMA_getPmaTypeSet(
+    $column, $extracted_columnspec, $backup_field,
+    $column_name_appendix, $unnullify_trigger, $tabindex,
+    $tabindex_for_value, $idindex, $data
+) {
+    list($column_set_values, $select_size) = PMA_getColumnSetValueAndSelectSize(
+        $column, $extracted_columnspec
+    );
+    $vset = array_flip(explode(',', $data));
+    $html_output = $backup_field . "\n";
+    $html_output .= '<input type="hidden" name="fields_type'
+        . $column_name_appendix . '" value="set" />';
+    $html_output .= '<select name="fields' . $column_name_appendix . '[]' . '"'
+        . ' class="textfield"'
+        . ' size="' . $select_size . '"'
+        . ' multiple="multiple"'
+        . ' ' . $unnullify_trigger
+        . ' tabindex="' . ($tabindex + $tabindex_for_value) . '"'
+        . ' id="field_' . ($idindex) . '_3">';
+    foreach ($column_set_values as $column_set_value) {
+        $html_output .= '<option value="' . $column_set_value['html'] . '"';
+        if (isset($vset[$column_set_value['plain']])) {
+            $html_output .= ' selected="selected"';
+        }
+        $html_output .= '>' . $column_set_value['html'] . '</option>' . "\n";
+    }
+    $html_output .= '</select>';
+    return $html_output;
+}
+
+/**
+ * Retrieve column 'set' value and select size
+ *
+ * @param array $column               description of column in given table
+ * @param array $extracted_columnspec associative array containing type,
+ *                                    spec_in_brackets and possibly enum_set_values
+ *                                    (another array)
+ *
+ * @return array $column['values'], $column['select_size']
+ */
+function PMA_getColumnSetValueAndSelectSize($column, $extracted_columnspec)
+{
+    if (! isset($column['values'])) {
+        $column['values'] = array();
+        foreach ($extracted_columnspec['enum_set_values'] as $val) {
+            $column['values'][] = array(
+                'plain' => $val,
+                'html'  => htmlspecialchars($val),
+            );
+        }
+        $column['select_size'] = min(4, count($column['values']));
+    }
+    return array($column['values'], $column['select_size']);
+}
+
+/**
+ * Get HTML for binary and blob column
+ *
+ * @param array   $column                description of column in given table
+ * @param array   $data                  data to edit
+ * @param array   $special_chars         special characters
+ * @param integer $biggest_max_file_size biggest max file size for uploading
+ * @param string  $backup_field          hidden input field
+ * @param string  $column_name_appendix  the name atttibute
+ * @param string  $unnullify_trigger     validation string
+ * @param integer $tabindex              tab index
+ * @param integer $tabindex_for_value    offset for the values tabindex
+ * @param integer $idindex               id index
+ * @param string  $text_dir              text direction
+ * @param string  $special_chars_encoded replaced char if the string starts
+ *                                       with a \r\n pair (0x0d0a) add an extra \n
+ * @param string  $vkey                  [multi_edit]['row_id']
+ * @param boolean $is_upload             is upload or not
+ *
+ * @return string                           an html snippet
+ */
+function PMA_getBinaryAndBlobColumn(
+    $column, $data, $special_chars, $biggest_max_file_size,
+    $backup_field, $column_name_appendix, $unnullify_trigger, $tabindex,
+    $tabindex_for_value, $idindex, $text_dir, $special_chars_encoded,
+    $vkey, $is_upload
+) {
+    $html_output = '';
+    if (($GLOBALS['cfg']['ProtectBinary'] && $column['is_blob'])
+        || ($GLOBALS['cfg']['ProtectBinary'] == 'all' && $column['is_binary'])
+        || ($GLOBALS['cfg']['ProtectBinary'] == 'noblob' && !$column['is_blob'])
+    ) {
+        $html_output .= __('Binary - do not edit');
+        if (isset($data)) {
+            $data_size = PMA_Util::formatByteDown(
+                strlen(stripslashes($data)), 3, 1
+            );
+            $html_output .= ' ('. $data_size [0] . ' ' . $data_size[1] . ')';
+            unset($data_size);
+        }
+        $html_output .= '<input type="hidden" name="fields_type'
+            . $column_name_appendix . '" value="protected" />'
+            . '<input type="hidden" name="fields'
+            . $column_name_appendix . '" value="" />';
+    } elseif ($column['is_blob']) {
+        $html_output .= "\n" . PMA_getTextarea(
+            $column, $backup_field, $column_name_appendix, $unnullify_trigger,
+            $tabindex, $tabindex_for_value, $idindex, $text_dir,
+            $special_chars_encoded
+        );
+    } else {
+        // field size should be at least 4 and max $GLOBALS['cfg']['LimitChars']
+        $fieldsize = min(max($column['len'], 4), $GLOBALS['cfg']['LimitChars']);
+        $html_output .= "\n" . $backup_field . "\n" . PMA_getHTMLinput(
+            $column, $column_name_appendix, $special_chars, $fieldsize,
+            $unnullify_trigger, $tabindex, $tabindex_for_value, $idindex
+        );
+    }
+
+    if ($is_upload && $column['is_blob']) {
+        $html_output .= '<br />'
+            . '<input type="file"'
+            . ' name="fields_upload' . $vkey . '[' . $column['Field_md5'] . ']"'
+            . ' class="textfield" id="field_' . $idindex . '_3" size="10"'
+            . ' ' . $unnullify_trigger . '/> ';
+        list($html_out, $biggest_max_file_size) = PMA_getMaxUploadSize(
+            $column, $biggest_max_file_size
+        );
+        $html_output .= $html_out;
+    }
+
+    if (!empty($GLOBALS['cfg']['UploadDir'])) {
+        $html_output .= PMA_getSelectOptionForUpload($vkey, $column);
+    }
+
+    return $html_output;
+}
+
+/**
+ * Get HTML input type
+ *
+ * @param array   $column               description of column in given table
+ * @param string  $column_name_appendix the name atttibute
+ * @param array   $special_chars        special characters
+ * @param integer $fieldsize            html field size
+ * @param string  $unnullify_trigger    validation string
+ * @param integer $tabindex             tab index
+ * @param integer $tabindex_for_value   offset for the values tabindex
+ * @param integer $idindex              id index
+ *
+ * @return string                       an html snippet
+ */
+function PMA_getHTMLinput($column, $column_name_appendix, $special_chars,
+    $fieldsize, $unnullify_trigger, $tabindex, $tabindex_for_value, $idindex
+) {
+    $the_class = 'textfield';
+    if ($column['pma_type'] == 'date') {
+        $the_class .= ' datefield';
+    } elseif ($column['pma_type'] == 'datetime'
+        || substr($column['pma_type'], 0, 9) == 'timestamp'
+    ) {
+        $the_class .= ' datetimefield';
+    }
+    return '<input type="text" name="fields' . $column_name_appendix . '"'
+        . ' value="' . $special_chars . '" size="' . $fieldsize . '"'
+        . ' class="' . $the_class . '" ' . $unnullify_trigger
+        . ' tabindex="' . ($tabindex + $tabindex_for_value). '"'
+        . ' id="field_' . ($idindex) . '_3" />';
+}
+
+/**
+ * Get HTML select option for upload
+ *
+ * @param string $vkey   [multi_edit]['row_id']
+ * @param array  $column description of column in given table
+ *
+ * @return string           an html snippet
+ */
+function PMA_getSelectOptionForUpload($vkey, $column)
+{
+    $files = PMA_getFileSelectOptions(
+        PMA_Util::userDir($GLOBALS['cfg']['UploadDir'])
+    );
+
+    if ($files === false) {
+        return '<font color="red">' . __('Error') . '</font><br />' . "\n"
+            .  __('The directory you set for upload work cannot be reached') . "\n";
+    } elseif (!empty($files)) {
+        return "<br />\n"
+            . '<i>' . __('Or') . '</i>' . ' '
+            . __('web server upload directory') . ':<br />' . "\n"
+            . '<select size="1" name="fields_uploadlocal'
+            . $vkey . '[' . $column['Field_md5'] . ']">' . "\n"
+            . '<option value="" selected="selected"></option>' . "\n"
+            . $files
+            . '</select>' . "\n";
+    }
+}
+
+/**
+ * Retrieve the maximum upload file size
+ *
+ * @param array   $column                description of column in given table
+ * @param integer $biggest_max_file_size biggest max file size for uploading
+ *
+ * @return array an html snippet and $biggest_max_file_size
+ */
+function PMA_getMaxUploadSize($column, $biggest_max_file_size)
+{
+    // find maximum upload size, based on field type
+    /**
+     * @todo with functions this is not so easy, as you can basically
+     * process any data with function like MD5
+     */
+    global $max_upload_size;
+    $max_field_sizes = array(
+        'tinyblob'   =>        '256',
+        'blob'       =>      '65536',
+        'mediumblob' =>   '16777216',
+        'longblob'   => '4294967296' // yeah, really
+    );
+
+    $this_field_max_size = $max_upload_size; // from PHP max
+    if ($this_field_max_size > $max_field_sizes[$column['pma_type']]) {
+        $this_field_max_size = $max_field_sizes[$column['pma_type']];
+    }
+    $html_output
+        = PMA_Util::getFormattedMaximumUploadSize(
+            $this_field_max_size
+        ) . "\n";
+    // do not generate here the MAX_FILE_SIZE, because we should
+    // put only one in the form to accommodate the biggest field
+    if ($this_field_max_size > $biggest_max_file_size) {
+        $biggest_max_file_size = $this_field_max_size;
+    }
+    return array($html_output, $biggest_max_file_size);
+}
+
+/**
+ * Get HTML for pma no support types
+ *
+ * @param array   $column                description of column in given table
+ * @param string  $default_char_editing  default char editing mode which is stroe
+ *                                       in the config.inc.php script
+ * @param string  $backup_field          hidden input field
+ * @param string  $column_name_appendix  the name atttibute
+ * @param string  $unnullify_trigger     validation string
+ * @param integer $tabindex              tab index
+ * @param array   $special_chars         apecial characters
+ * @param integer $tabindex_for_value    offset for the values tabindex
+ * @param integer $idindex               id index
+ * @param string  $text_dir              text direction
+ * @param array   $special_chars_encoded replaced char if the string starts
+ *                                       with a \r\n pair (0x0d0a) add an extra \n
+ * @param strign  $data                  data to edit
+ * @param array   $extracted_columnspec  associative array containing type,
+ *                                       spec_in_brackets and possibly
+ *                                       enum_set_values (another array)
+ *
+ * @return string an html snippet
+ */
+function PMA_getNoSupportTypes($column, $default_char_editing, $backup_field,
+    $column_name_appendix, $unnullify_trigger, $tabindex, $special_chars,
+    $tabindex_for_value, $idindex, $text_dir, $special_chars_encoded, $data,
+    $extracted_columnspec
+) {
+    $fieldsize = PMA_getColumnSize($column, $extracted_columnspec);
+    $html_output = $backup_field . "\n";
+    if ($column['is_char']
+        && ($GLOBALS['cfg']['CharEditing'] == 'textarea'
+        || strpos($data, "\n") !== false)
+    ) {
+        $html_output .= "\n";
+        $GLOBALS['cfg']['CharEditing'] = $default_char_editing;
+        $html_output .= PMA_getTextarea(
+            $column, $backup_field, $column_name_appendix, $unnullify_trigger,
+            $tabindex, $tabindex_for_value, $idindex, $text_dir,
+            $special_chars_encoded
+        );
+    } else {
+        $html_output .= PMA_getHTMLinput(
+            $column, $column_name_appendix, $special_chars,
+            $fieldsize, $unnullify_trigger, $tabindex, $tabindex_for_value, $idindex
+        );
+
+        if ($column['Extra'] == 'auto_increment') {
+            $html_output .= '<input type="hidden" name="auto_increment'
+                . $column_name_appendix . '" value="1" />';
+        }
+        if (substr($column['pma_type'], 0, 9) == 'timestamp') {
+            $html_output .= '<input type="hidden" name="fields_type'
+                . $column_name_appendix . '" value="timestamp" />';
+        }
+        if (substr($column['pma_type'], 0, 8) == 'datetime') {
+            $html_output .= '<input type="hidden" name="fields_type'
+                . $column_name_appendix . '" value="datetime" />';
+        }
+        if ($column['True_Type'] == 'bit') {
+            $html_output .= '<input type="hidden" name="fields_type'
+                . $column_name_appendix . '" value="bit" />';
+        }
+        if ($column['pma_type'] == 'date'
+            || $column['pma_type'] == 'datetime'
+            || substr($column['pma_type'], 0, 9) == 'timestamp'
+        ) {
+            // the _3 suffix points to the date field
+            // the _2 suffix points to the corresponding NULL checkbox
+            // in dateFormat, 'yy' means the year with 4 digits
+        }
+    }
+    return $html_output;
+}
+
+/**
+ * Get the field size
+ *
+ * @param array $column               description of column in given table
+ * @param array $extracted_columnspec associative array containing type,
+ *                                    spec_in_brackets and possibly enum_set_values
+ *                                    (another array)
+ *
+ * @return integer      field size
+ */
+function PMA_getColumnSize($column, $extracted_columnspec)
+{
+    if ($column['is_char']) {
+        $fieldsize = $extracted_columnspec['spec_in_brackets'];
+        if ($fieldsize > $GLOBALS['cfg']['MaxSizeForInputField']) {
+            /**
+             * This case happens for CHAR or VARCHAR columns which have
+             * a size larger than the maximum size for input field.
+             */
+            $GLOBALS['cfg']['CharEditing'] = 'textarea';
+        }
+    } else {
+        /**
+         * This case happens for example for INT or DATE columns;
+         * in these situations, the value returned in $column['len']
+         * seems appropriate.
+         */
+        $fieldsize = $column['len'];
+    }
+    return min(
+        max($fieldsize, $GLOBALS['cfg']['MinSizeForInputField']),
+        $GLOBALS['cfg']['MaxSizeForInputField']
+    );
+}
+
+/**
+ * Get HTML for gis data types
+ *
+ * @return string an html snippet
+ */
+function PMA_getHTMLforGisDataTypes()
+{
+    $edit_str = PMA_Util::getIcon('b_edit.png', __('Edit/Insert'));
+    return '<span class="open_gis_editor">'
+        . PMA_Util::linkOrButton(
+            '#', $edit_str, array(), false, false, '_blank'
+        )
+        . '</span>';
+}
+
+/**
+ * get html for continue insertion form
+ *
+ * @param string $table              name of the table
+ * @param string $db                 name of the database
+ * @param array  $where_clause_array array of where clauses
+ * @param string $err_url            error url
+ *
+ * @return string                   an html snippet
+ */
+function PMA_getContinueInsertionForm($table, $db, $where_clause_array, $err_url)
+{
+    $html_output = '<form id="continueForm" method="post"'
+        . ' action="tbl_replace.php" name="continueForm">'
+        . PMA_generate_common_hidden_inputs($db, $table)
+        . '<input type="hidden" name="goto"'
+        . ' value="' . htmlspecialchars($GLOBALS['goto']) . '" />'
+        . '<input type="hidden" name="err_url"'
+        . ' value="' . htmlspecialchars($err_url) . '" />'
+        . '<input type="hidden" name="sql_query"'
+        . ' value="' . htmlspecialchars($_REQUEST['sql_query']) . '" />';
+
+    if (isset($_REQUEST['where_clause'])) {
+        foreach ($where_clause_array as $key_id => $where_clause) {
+
+            $html_output .= '<input type="hidden"'
+                . ' name="where_clause[' . $key_id . ']"'
+                . ' value="' . htmlspecialchars(trim($where_clause)) . '" />'. "\n";
+        }
+    }
+    $tmp = '<select name="insert_rows" id="insert_rows">' . "\n";
+    $option_values = array(1, 2, 5, 10, 15, 20, 30, 40);
+
+    foreach ($option_values as $value) {
+        $tmp .= '<option value="' . $value . '"';
+        if ($value == $GLOBALS['cfg']['InsertRows']) {
+            $tmp .= ' selected="selected"';
+        }
+        $tmp .= '>' . $value . '</option>' . "\n";
+    }
+
+    $tmp .= '</select>' . "\n";
+    $html_output .= "\n" . sprintf(__('Continue insertion with %s rows'), $tmp);
+    unset($tmp);
+    $html_output .= '</form>' . "\n";
+    return $html_output;
+}
+
+/**
+ * Get action panel
+ *
+ * @param array   $where_clause       where clause
+ * @param string  $after_insert       insert mode, e.g. new_insert, same_insert
+ * @param integer $tabindex           tab index
+ * @param integer $tabindex_for_value offset for the values tabindex
+ * @param boolean $found_unique_key   boolean variable for unique key
+ *
+ * @return string an html snippet
+ */
+function PMA_getActionsPanel($where_clause, $after_insert, $tabindex,
+    $tabindex_for_value, $found_unique_key
+) {
+    $html_output = '<fieldset id="actions_panel">'
+        . '<table cellpadding="5" cellspacing="0">'
+        . '<tr>'
+        . '<td class="nowrap vmiddle">'
+        . PMA_getSubmitTypeDropDown($where_clause, $tabindex, $tabindex_for_value)
+        . "\n";
+
+    $html_output .= '</td>'
+        . '<td class="vmiddle">'
+        . '   <strong>'
+        . __('and then') . '</strong>   '
+        . '</td>'
+        . '<td class="nowrap vmiddle">'
+        . PMA_getAfterInsertDropDown(
+            $where_clause, $after_insert, $found_unique_key
+        )
+        . '</td>'
+        . '</tr>';
+    $html_output .='<tr>'
+        . PMA_getSumbitAndResetButtonForActionsPanel($tabindex, $tabindex_for_value)
+        . '</tr>'
+        . '</table>'
+        . '</fieldset>';
+    return $html_output;
+}
+
+/**
+ * Get a HTML drop down for submit types
+ *
+ * @param array   $where_clause       where clause
+ * @param integer $tabindex           tab index
+ * @param integer $tabindex_for_value offset for the values tabindex
+ *
+ * @return string                       an html snippet
+ */
+function PMA_getSubmitTypeDropDown($where_clause, $tabindex, $tabindex_for_value)
+{
+    $html_output = '<select name="submit_type" class="control_at_footer" tabindex="'
+        . ($tabindex + $tabindex_for_value + 1) . '">';
+    if (isset($where_clause)) {
+        $html_output .= '<option value="save">' . __('Save') . '</option>';
+    }
+    $html_output .= '<option value="insert">'
+        . __('Insert as new row')
+        . '</option>'
+        . '<option value="insertignore">'
+        . __('Insert as new row and ignore errors')
+        . '</option>'
+        . '<option value="showinsert">'
+        . __('Show insert query')
+        . '</option>'
+        . '</select>';
+    return $html_output;
+}
+
+/**
+ * Get HTML drop down for after insert
+ *
+ * @param array   $where_clause     where clause
+ * @param string  $after_insert     insert mode, e.g. new_insert, same_insert
+ * @param boolean $found_unique_key boolean variable for unique key
+ *
+ * @return string                   an html snippet
+ */
+function PMA_getAfterInsertDropDown($where_clause, $after_insert, $found_unique_key)
+{
+    $html_output = '<select name="after_insert">'
+        . '<option value="back" '
+        . ($after_insert == 'back' ? 'selected="selected"' : '') . '>'
+        . __('Go back to previous page') . '</option>'
+        . '<option value="new_insert" '
+        . ($after_insert == 'new_insert' ? 'selected="selected"' : '') . '>'
+        . __('Insert another new row') . '</option>';
+
+    if (isset($where_clause)) {
+        $html_output .= '<option value="same_insert" '
+            . ($after_insert == 'same_insert' ? 'selected="selected"' : '') . '>'
+            . __('Go back to this page') . '</option>';
+
+        // If we have just numeric primary key, we can also edit next
+        // in 2.8.2, we were looking for `field_name` = numeric_value
+        //if (preg_match('@^[\s]*`[^`]*` = [0-9]+@', $where_clause)) {
+        // in 2.9.0, we are looking for `table_name`.`field_name` = numeric_value
+        $is_numeric = false;
+        if (! is_array($where_clause)) {
+            $where_clause = array($where_clause);
+        }
+        for ($i = 0; $i < count($where_clause); $i++) {
+            $is_numeric = preg_match(
+                '@^[\s]*`[^`]*`[\.]`[^`]*` = [0-9]+@',
+                $where_clause[$i]
+            );
+            if ($is_numeric == true) {
+                break;
+            }
+        }
+        if ($found_unique_key && $is_numeric) {
+            $html_output .= '<option value="edit_next" '
+                . ($after_insert == 'edit_next' ? 'selected="selected"' : '') . '>'
+                . __('Edit next row') . '</option>';
+
+        }
+    }
+    $html_output .= '</select>';
+    return $html_output;
+
+}
+
+/**
+ * get Submit button and Reset button for action panel
+ *
+ * @param integer $tabindex           tab index
+ * @param integer $tabindex_for_value offset for the values tabindex
+ *
+ * @return string an html snippet
+ */
+function PMA_getSumbitAndResetButtonForActionsPanel($tabindex, $tabindex_for_value)
+{
+    return '<td>'
+    . PMA_Util::showHint(
+        __(
+            'Use TAB key to move from value to value,'
+            . ' or CTRL+arrows to move anywhere'
+        )
+    )
+    . '</td>'
+    . '<td colspan="3" class="right vmiddle">'
+    . '<input type="submit" class="control_at_footer" value="' . __('Go') . '"'
+    . 'tabindex="' . ($tabindex + $tabindex_for_value + 6) . '" id="buttonYes" />'
+    . '<input type="reset" class="control_at_footer" value="' . __('Reset') . '"'
+    . 'tabindex="' . ($tabindex + $tabindex_for_value + 7) . '" />'
+    . '</td>';
+}
+
+/**
+ * Get table head and table foot for insert row table
+ *
+ * @param array $url_params url parameters
+ *
+ * @return string           an html snippet
+ */
+function PMA_getHeadAndFootOfInsertRowTable($url_params)
+{
+    $html_output = '<table class="insertRowTable">'
+        . '<thead>'
+        . '<tr>'
+        . '<th>' . __('Column') . '</th>';
+
+    if ($GLOBALS['cfg']['ShowFieldTypesInDataEditView']) {
+        $html_output .= PMA_showColumnTypesInDataEditView($url_params, true);
+    }
+    if ($GLOBALS['cfg']['ShowFunctionFields']) {
+        $html_output .= PMA_showFunctionFieldsInEditMode($url_params, true);
+    }
+
+    $html_output .= '<th>'. __('Null') . '</th>'
+        . '<th>' . __('Value') . '</th>'
+        . '</tr>'
+        . '</thead>'
+        . ' <tfoot>'
+        . '<tr>'
+        . '<th colspan="5" class="tblFooters right">'
+        . '<input type="submit" value="' . __('Go') . '" />'
+        . '</th>'
+        . '</tr>'
+        . '</tfoot>';
+    return $html_output;
+}
+
+/**
+ * Prepares the field value and retrieve special chars, backup field and data array
+ *
+ * @param array   $current_row          a row of the table
+ * @param array   $column               description of column in given table
+ * @param array   $extracted_columnspec associative array containing type,
+ *                                      spec_in_brackets and possibly
+ *                                      enum_set_values (another array)
+ * @param boolean $real_null_value      whether column value null or not null
+ * @param array   $gis_data_types       list of GIS data types
+ * @param string  $column_name_appendix string to append to column name in input
+ *
+ * @return array $real_null_value, $data, $special_chars, $backup_field,
+ *               $special_chars_encoded
+ */
+function PMA_getSpecialCharsAndBackupFieldForExistingRow(
+    $current_row, $column, $extracted_columnspec,
+    $real_null_value, $gis_data_types, $column_name_appendix
+) {
+    $special_chars_encoded = '';
+    // (we are editing)
+    if (is_null($current_row[$column['Field']])) {
+        $real_null_value = true;
+        $current_row[$column['Field']] = '';
+        $special_chars = '';
+        $data = $current_row[$column['Field']];
+    } elseif ($column['True_Type'] == 'bit') {
+        $special_chars = PMA_Util::printableBitValue(
+            $current_row[$column['Field']], $extracted_columnspec['spec_in_brackets']
+        );
+    } elseif (in_array($column['True_Type'], $gis_data_types)) {
+        // Convert gis data to Well Know Text format
+        $current_row[$column['Field']] = PMA_Util::asWKT(
+            $current_row[$column['Field']], true
+        );
+        $special_chars = htmlspecialchars($current_row[$column['Field']]);
+    } else {
+        // special binary "characters"
+        if ($column['is_binary']
+            || ($column['is_blob'] && ! $GLOBALS['cfg']['ProtectBinary'])
+        ) {
+            if ($_SESSION['tmp_user_values']['display_binary_as_hex']
+                && $GLOBALS['cfg']['ShowFunctionFields']
+            ) {
+                $current_row[$column['Field']] = bin2hex(
+                    $current_row[$column['Field']]
+                );
+                $column['display_binary_as_hex'] = true;
+            } else {
+                $current_row[$column['Field']]
+                    = PMA_Util::replaceBinaryContents(
+                        $current_row[$column['Field']]
+                    );
+            }
+        } // end if
+        $special_chars = htmlspecialchars($current_row[$column['Field']]);
+
+        //We need to duplicate the first \n or otherwise we will lose
+        //the first newline entered in a VARCHAR or TEXT column
+        $special_chars_encoded
+            = PMA_Util::duplicateFirstNewline($special_chars);
+
+        $data = $current_row[$column['Field']];
+    } // end if... else...
+
+    //when copying row, it is useful to empty auto-increment column
+    // to prevent duplicate key error
+    if (isset($_REQUEST['default_action'])
+        && $_REQUEST['default_action'] === 'insert'
+    ) {
+        if ($column['Key'] === 'PRI'
+            && strpos($column['Extra'], 'auto_increment') !== false
+        ) {
+            $data = $special_chars_encoded = $special_chars = null;
+        }
+    }
+    // If a timestamp field value is not included in an update
+    // statement MySQL auto-update it to the current timestamp;
+    // however, things have changed since MySQL 4.1, so
+    // it's better to set a fields_prev in this situation
+    $backup_field = '<input type="hidden" name="fields_prev'
+        . $column_name_appendix . '" value="'
+        . htmlspecialchars($current_row[$column['Field']]) . '" />';
+
+    return array(
+        $real_null_value,
+        $special_chars_encoded,
+        $special_chars,
+        $data,
+        $backup_field
+    );
+}
+
+/**
+ * display default values
+ *
+ * @param type    $column          description of column in given table
+ * @param boolean $real_null_value whether column value null or not null
+ *
+ * @return array $real_null_value, $data, $special_chars,
+ *               $backup_field, $special_chars_encoded
+ */
+function PMA_getSpecialCharsAndBackupFieldForInsertingMode(
+    $column, $real_null_value
+) {
+    if (! isset($column['Default'])) {
+        $column['Default'] 	  = '';
+        $real_null_value          = true;
+        $data                     = '';
+    } else {
+        $data                     = $column['Default'];
+    }
+
+    if ($column['True_Type'] == 'bit') {
+        $special_chars = PMA_Util::convertBitDefaultValue($column['Default']);
+    } else {
+        $special_chars = htmlspecialchars($column['Default']);
+    }
+    $backup_field = '';
+    $special_chars_encoded = PMA_Util::duplicateFirstNewline($special_chars);
+    // this will select the UNHEX function while inserting
+    if (($column['is_binary']
+        || ($column['is_blob'] && ! $GLOBALS['cfg']['ProtectBinary']))
+        && (isset($_SESSION['tmp_user_values']['display_binary_as_hex'])
+        && $_SESSION['tmp_user_values']['display_binary_as_hex'])
+        && $GLOBALS['cfg']['ShowFunctionFields']
+    ) {
+        $column['display_binary_as_hex'] = true;
+    }
+    return array(
+        $real_null_value, $data, $special_chars,
+        $backup_field, $special_chars_encoded
+    );
+}
+
+/**
+ * Prepares the update/insert of a row
+ *
+ * @return array     $loop_array, $using_key, $is_insert, $is_insertignore
+ */
+function PMA_getParamsForUpdateOrInsert()
+{
+    if (isset($_REQUEST['where_clause'])) {
+        // we were editing something => use the WHERE clause
+        $loop_array = is_array($_REQUEST['where_clause'])
+            ? $_REQUEST['where_clause']
+            : array($_REQUEST['where_clause']);
+        $using_key  = true;
+        $is_insert  = $_REQUEST['submit_type'] == 'insert'
+                      || $_REQUEST['submit_type'] == 'showinsert'
+                      || $_REQUEST['submit_type'] == 'insertignore';
+        $is_insertignore  = $_REQUEST['submit_type'] == 'insertignore';
+    } else {
+        // new row => use indexes
+        $loop_array = array();
+        foreach ($_REQUEST['fields']['multi_edit'] as $key => $dummy) {
+            $loop_array[] = $key;
+        }
+        $using_key  = false;
+        $is_insert  = true;
+        $is_insertignore = false;
+    }
+    return array($loop_array, $using_key, $is_insert, $is_insertignore);
+}
+
+/**
+ * Check wether insert row mode and if so include tbl_changen script and set
+ * global variables.
+ *
+ * @return void
+ */
+function PMA_isInsertRow()
+{
+    if (isset($_REQUEST['insert_rows'])
+        && is_numeric($_REQUEST['insert_rows'])
+        && $_REQUEST['insert_rows'] != $GLOBALS['cfg']['InsertRows']
+    ) {
+        $GLOBALS['cfg']['InsertRows'] = $_REQUEST['insert_rows'];
+        $response = PMA_Response::getInstance();
+        $header = $response->getHeader();
+        $scripts = $header->getScripts();
+        $scripts->addFile('tbl_change.js');
+        include 'tbl_change.php';
+        exit;
+    }
+}
+
+/**
+ * set $_SESSION for edit_next
+ *
+ * @param string $one_where_clause one where clause from where clauses array
+ *
+ * @return void
+ */
+function PMA_setSessionForEditNext($one_where_clause)
+{
+    $local_query = 'SELECT * FROM ' . PMA_Util::backquote($GLOBALS['db'])
+        . '.' . PMA_Util::backquote($GLOBALS['table']) . ' WHERE '
+        . str_replace('` =', '` >', $one_where_clause) . ' LIMIT 1;';
+
+    $res            = PMA_DBI_query($local_query);
+    $row            = PMA_DBI_fetch_row($res);
+    $meta           = PMA_DBI_get_fields_meta($res);
+    // must find a unique condition based on unique key,
+    // not a combination of all fields
+    list($unique_condition, $clause_is_unique)
+        = PMA_Util::getUniqueCondition(
+            $res, count($meta), $meta, $row, true
+        );
+    if (! empty($unique_condition)) {
+        $_SESSION['edit_next'] = $unique_condition;
+    }
+    unset($unique_condition, $clause_is_unique);
+}
+
+/**
+ * set $goto_include variable for different cases and retrieve like,
+ * if $GLOBALS['goto'] empty, if $goto_include previously not defined
+ * and new_insert, same_insert, edit_next
+ *
+ * @param string $goto_include store some script for include, otherwise it is
+ *                             boolean false
+ *
+ * @return string               $goto_include
+ */
+function PMA_getGotoInclude($goto_include)
+{
+    $valid_options = array('new_insert', 'same_insert', 'edit_next');
+    if (isset($_REQUEST['after_insert'])
+        && in_array($_REQUEST['after_insert'], $valid_options)
+    ) {
+        $goto_include = 'tbl_change.php';
+    } elseif (! empty($GLOBALS['goto'])) {
+        if (! preg_match('@^[a-z_]+\.php$@', $GLOBALS['goto'])) {
+            // this should NOT happen
+            //$GLOBALS['goto'] = false;
+            $goto_include = false;
+        } else {
+            $goto_include = $GLOBALS['goto'];
+        }
+        if ($GLOBALS['goto'] == 'db_sql.php' && strlen($GLOBALS['table'])) {
+            $GLOBALS['table'] = '';
+        }
+    }
+    if (! $goto_include) {
+        if (! strlen($GLOBALS['table'])) {
+            $goto_include = 'db_sql.php';
+        } else {
+            $goto_include = 'tbl_sql.php';
+        }
+    }
+    return $goto_include;
+}
+
+/**
+ * Defines the url to return in case of failure of the query
+ *
+ * @param array $url_params url parameters
+ *
+ * @return string           error url for query failure
+ */
+function PMA_getErrorUrl($url_params)
+{
+    if (isset($_REQUEST['err_url'])) {
+        return $_REQUEST['err_url'];
+    } else {
+        return 'tbl_change.php' . PMA_generate_common_url($url_params);
+    }
+}
+
+/**
+ * Builds the sql query
+ *
+ * @param boolean $is_insertignore $_REQUEST['submit_type'] == 'insertignore'
+ * @param array   $query_fields    column names array
+ * @param array   $value_sets      array of query values
+ *
+ * @return string a query
+ */
+function PMA_buildSqlQuery($is_insertignore, $query_fields, $value_sets)
+{
+    if ($is_insertignore) {
+        $insert_command = 'INSERT IGNORE ';
+    } else {
+        $insert_command = 'INSERT ';
+    }
+    $query[] = $insert_command . 'INTO '
+        . PMA_Util::backquote($GLOBALS['db']) . '.'
+        . PMA_Util::backquote($GLOBALS['table'])
+        . ' (' . implode(', ', $query_fields) . ') VALUES ('
+        . implode('), (', $value_sets) . ')';
+    unset($insert_command, $query_fields);
+    return $query;
+}
+
+/**
+ * Executes the sql query and get the result, then move back to the calling page
+ *
+ * @param array  $url_params url paramters array
+ * @param string $query      built query from PMA_buildSqlQuery()
+ *
+ * @return array             $url_params, $total_affected_rows, $last_messages
+ *                           $warning_messages, $error_messages, $return_to_sql_query
+ */
+function PMA_executeSqlQuery($url_params, $query)
+{
+    $return_to_sql_query = '';
+    if (! empty($GLOBALS['sql_query'])) {
+        $url_params['sql_query'] = $GLOBALS['sql_query'];
+        $return_to_sql_query = $GLOBALS['sql_query'];
+    }
+    $GLOBALS['sql_query'] = implode('; ', $query) . ';';
+    // to ensure that the query is displayed in case of
+    // "insert as new row" and then "insert another new row"
+    $GLOBALS['display_query'] = $GLOBALS['sql_query'];
+
+    $total_affected_rows = 0;
+    $last_messages = array();
+    $warning_messages = array();
+    $error_messages = array();
+
+    foreach ($query as $single_query) {
+        if ($_REQUEST['submit_type'] == 'showinsert') {
+            $last_messages[] = PMA_Message::notice(__('Showing SQL query'));
+            continue;
+        }
+        if ($GLOBALS['cfg']['IgnoreMultiSubmitErrors']) {
+            $result = PMA_DBI_try_query($single_query);
+        } else {
+            $result = PMA_DBI_query($single_query);
+        }
+        if (! $result) {
+            $error_messages[] = PMA_Message::sanitize(PMA_DBI_getError());
+        } else {
+            // The next line contains a real assignment, it's not a typo
+            if ($tmp = @PMA_DBI_affected_rows()) {
+                $total_affected_rows += $tmp;
+            }
+            unset($tmp);
+
+            $insert_id = PMA_DBI_insert_id();
+            if ($insert_id != 0) {
+                // insert_id is id of FIRST record inserted in one insert, so if we
+                // inserted multiple rows, we had to increment this
+
+                if ($total_affected_rows > 0) {
+                    $insert_id = $insert_id + $total_affected_rows - 1;
+                }
+                $last_message = PMA_Message::notice(__('Inserted row id: %1$d'));
+                $last_message->addParam($insert_id);
+                $last_messages[] = $last_message;
+            }
+            PMA_DBI_free_result($result);
+        }
+        $warning_messages = PMA_getWarningMessages();
+    }
+    return array(
+        $url_params,
+        $total_affected_rows,
+        $last_messages,
+        $warning_messages,
+        $error_messages,
+        $return_to_sql_query
+    );
+}
+
+/**
+ * get the warning messages array
+ *
+ * @return array  $warning_essages
+ */
+function PMA_getWarningMessages()
+{
+    $warning_essages = array();
+    foreach (PMA_DBI_get_warnings() as $warning) {
+        $warning_essages[] = PMA_Message::sanitize(
+            $warning['Level'] . ': #' . $warning['Code'] . ' ' . $warning['Message']
+        );
+    }
+    return $warning_essages;
+}
+
+/**
+ * Column to display from the foreign table?
+ *
+ * @param string $where_comparison     string that contain relation field value
+ * @param string $relation_field_value relation field value
+ * @param array  $map                  all Relations to foreign tables for a given
+ *                                     table or optionally a given column in a table
+ * @param string $relation_field       relation field
+ *
+ * @return string $dispval display value from the foreign table
+ */
+function PMA_getDisplayValueForForeignTableColumn($where_comparison,
+    $relation_field_value, $map, $relation_field
+) {
+    $display_field = PMA_getDisplayField(
+        $map[$relation_field]['foreign_db'],
+        $map[$relation_field]['foreign_table']
+    );
+    // Field to display from the foreign table?
+    if (isset($display_field) && strlen($display_field)) {
+        $dispsql = 'SELECT ' . PMA_Util::backquote($display_field)
+            . ' FROM ' . PMA_Util::backquote($map[$relation_field]['foreign_db'])
+            . '.' . PMA_Util::backquote($map[$relation_field]['foreign_table'])
+            . ' WHERE ' . PMA_Util::backquote($map[$relation_field]['foreign_field'])
+            . $where_comparison;
+        $dispresult  = PMA_DBI_try_query($dispsql, null, PMA_DBI_QUERY_STORE);
+        if ($dispresult && PMA_DBI_num_rows($dispresult) > 0) {
+            list($dispval) = PMA_DBI_fetch_row($dispresult, 0);
+        }
+        @PMA_DBI_free_result($dispresult);
+        return $dispval;
+    }
+    return '';
+}
+
+/**
+ * Display option in the cell according to user choises
+ *
+ * @param array  $map                  all Relations to foreign tables for a given
+ *                                     table or optionally a given column in a table
+ * @param string $relation_field       relation field
+ * @param string $where_comparison     string that contain relation field value
+ * @param string $dispval              display value from the foreign table
+ * @param string $relation_field_value relation field value
+ *
+ * @return string $output HTML <a> tag
+ */
+function PMA_getLinkForRelationalDisplayField($map, $relation_field,
+    $where_comparison, $dispval, $relation_field_value
+) {
+    if ('K' == $_SESSION['tmp_user_values']['relational_display']) {
+        // user chose "relational key" in the display options, so
+        // the title contains the display field
+        $title = (! empty($dispval))
+            ? ' title="' . htmlspecialchars($dispval) . '"'
+            : '';
+    } else {
+        $title = ' title="' . htmlspecialchars($relation_field_value) . '"';
+    }
+    $_url_params = array(
+        'db'    => $map[$relation_field]['foreign_db'],
+        'table' => $map[$relation_field]['foreign_table'],
+        'pos'   => '0',
+        'sql_query' => 'SELECT * FROM '
+            . PMA_Util::backquote($map[$relation_field]['foreign_db'])
+            . '.' . PMA_Util::backquote($map[$relation_field]['foreign_table'])
+            . ' WHERE ' . PMA_Util::backquote($map[$relation_field]['foreign_field'])
+            . $where_comparison
+    );
+    $output = '<a href="sql.php'
+        . PMA_generate_common_url($_url_params) . '"' . $title . '>';
+
+    if ('D' == $_SESSION['tmp_user_values']['relational_display']) {
+        // user chose "relational display field" in the
+        // display options, so show display field in the cell
+        $output .= (!empty($dispval)) ? htmlspecialchars($dispval) : '';
+    } else {
+        // otherwise display data in the cell
+        $output .= htmlspecialchars($relation_field_value);
+    }
+    $output .= '</a>';
+    return $output;
+}
+
+/**
+ * Transform edited values
+ *
+ * @param string $db             db name
+ * @param string $table          table name
+ * @param array  $transformation mimetypes for all columns of a table
+ *                               [field_name][field_key]
+ * @param array  $edited_values  transform columns list and new values
+ * @param string $file           file containing the transformation plugin
+ * @param string $column_name    column name
+ * @param array  $extra_data     extra data array
+ *
+ * @return array $extra_data
+ */
+function PMA_transformEditedValues($db, $table,
+    $transformation, $edited_values, $file, $column_name, $extra_data
+) {
+    foreach ($edited_values as $cell_index => $curr_cell_edited_values) {
+        if (isset($curr_cell_edited_values[$column_name])) {
+            $column_data = $curr_cell_edited_values[$column_name];
+
+            $_url_params = array(
+                'db'            => $db,
+                'table'         => $table,
+                'where_clause'  => $_REQUEST['where_clause'],
+                'transform_key' => $column_name
+            );
+
+            $include_file = 'libraries/plugins/transformations/' . $file;
+            if (file_exists($include_file)) {
+                include_once $include_file;
+
+                $transform_options  = PMA_transformation_getOptions(
+                    isset($transformation['transformation_options'])
+                    ? $transformation['transformation_options']
+                    : ''
+                );
+                $transform_options['wrapper_link']
+                    = PMA_generate_common_url($_url_params);
+                $class_name = str_replace('.class.php', '', $file);
+                $plugin_manager = null;
+                $transformation_plugin = new $class_name(
+                    $plugin_manager
+                );
+            }
+
+            $extra_data['transformations'][$cell_index]
+                = $transformation_plugin->applyTransformation(
+                    $column_data,
+                    $transform_options,
+                    ''
+                );
+        }
+    }   // end of loop for each transformation cell
+    return $extra_data;
+}
+
+/**
+ * Get current value in multi edit mode
+ *
+ * @param array  $multi_edit_colummns     multiple edit column array
+ * @param array  $multi_edit_columns_name multiple edit columns name array
+ * @param array  $multi_edit_funcs        multiple edit functions array
+ * @param array  $gis_from_text_functions array that contains gis from text functions
+ * @param string $current_value           current value in the column
+ * @param array  $gis_from_wkb_functions  initialy $val is $multi_edit_colummns[$key]
+ * @param array  $func_optional_param     array('RAND','UNIX_TIMESTAMP')
+ * @param array  $func_no_param           array of set of string
+ * @param string $key                     an md5 of the column name
+ *
+ * @return array $cur_value
+ */
+function PMA_getCurrentValueAsAnArrayForMultipleEdit($multi_edit_colummns,
+    $multi_edit_columns_name, $multi_edit_funcs, $gis_from_text_functions,
+    $current_value, $gis_from_wkb_functions, $func_optional_param,
+    $func_no_param, $key
+) {
+    if (empty($multi_edit_funcs[$key])) {
+        return $current_value;
+    } elseif ('UUID' === $multi_edit_funcs[$key]) {
+        /* This way user will know what UUID new row has */
+        $uuid = PMA_DBI_fetch_value('SELECT UUID()');
+        return "'" . $uuid . "'";
+    } elseif ((in_array($multi_edit_funcs[$key], $gis_from_text_functions)
+        && substr($current_value, 0, 3) == "'''")
+        || in_array($multi_edit_funcs[$key], $gis_from_wkb_functions)
+    ) {
+        // Remove enclosing apostrophes
+        $current_value = substr($current_value, 1, strlen($current_value) - 2);
+        // Remove escaping apostrophes
+        $current_value = str_replace("''", "'", $current_value);
+        return $multi_edit_funcs[$key] . '(' . $current_value . ')';
+    } elseif (! in_array($multi_edit_funcs[$key], $func_no_param)
+        || ($current_value != "''"
+        && in_array($multi_edit_funcs[$key], $func_optional_param))
+    ) {
+        return $multi_edit_funcs[$key] . '(' . $current_value . ')';
+    } else {
+        return $multi_edit_funcs[$key] . '()';
+    }
+}
+
+/**
+ * Get query values array and query fileds array for insert and update in multi edit
+ *
+ * @param array   $multi_edit_columns_name      multiple edit columns name array
+ * @param array   $multi_edit_columns_null      multiple edit columns null array
+ * @param string  $current_value                current value in the column in loop
+ * @param array   $multi_edit_columns_prev      multiple edit previous columns array
+ * @param array   $multi_edit_funcs             multiple edit functions array
+ * @param boolean $is_insert                    boolean value whether insert or not
+ * @param array   $query_values                 SET part of the sql query
+ * @param array   $query_fields                 array of query fileds
+ * @param string  $current_value_as_an_array    current value in the column
+ *                                              as an array
+ * @param array   $value_sets                   array of valu sets
+ * @param string  $key                          an md5 of the column name
+ * @param array   $multi_edit_columns_null_prev array of multiple edit columns
+ *                                              null previous
+ *
+ * @return array ($query_values, $query_fields)
+ */
+function PMA_getQueryValuesForInsertAndUpdateInMultipleEdit($multi_edit_columns_name,
+    $multi_edit_columns_null, $current_value, $multi_edit_columns_prev,
+    $multi_edit_funcs,$is_insert, $query_values, $query_fields,
+    $current_value_as_an_array, $value_sets, $key, $multi_edit_columns_null_prev
+) {
+    //  i n s e r t
+    if ($is_insert) {
+        // no need to add column into the valuelist
+        if (strlen($current_value_as_an_array)) {
+            $query_values[] = $current_value_as_an_array;
+            // first inserted row so prepare the list of fields
+            if (empty($value_sets)) {
+                $query_fields[] = PMA_Util::backquote(
+                    $multi_edit_columns_name[$key]
+                );
+            }
+        }
+
+    } elseif (! empty($multi_edit_columns_null_prev[$key])
+        && ! isset($multi_edit_columns_null[$key])
+    ) {
+        //  u p d a t e
+
+        // field had the null checkbox before the update
+        // field no longer has the null checkbox
+        $query_values[]
+            = PMA_Util::backquote($multi_edit_columns_name[$key])
+            . ' = ' . $current_value_as_an_array;
+    } elseif (empty($multi_edit_funcs[$key])
+        && isset($multi_edit_columns_prev[$key])
+        && ("'" . PMA_Util::sqlAddSlashes($multi_edit_columns_prev[$key]) . "'"
+        == $current_value)
+    ) {
+        // No change for this column and no MySQL function is used -> next column
+    } elseif (! empty($current_value)) {
+        // avoid setting a field to NULL when it's already NULL
+        // (field had the null checkbox before the update
+        //  field still has the null checkbox)
+        if (empty($multi_edit_columns_null_prev[$key])
+            || empty($multi_edit_columns_null[$key])
+        ) {
+             $query_values[]
+                 = PMA_Util::backquote($multi_edit_columns_name[$key])
+                . ' = ' . $current_value_as_an_array;
+        }
+    }
+    return array($query_values, $query_fields);
+}
+
+/**
+ * Get the current column value in the form for different data types
+ *
+ * @param string  $possibly_uploaded_val        uploaded file content
+ * @param string  $key                          an md5 of the column name
+ * @param array   $multi_edit_columns_type      array of multi edit column types
+ * @param string  $current_value                current column value in the form
+ * @param array   $multi_edit_auto_increment    multi edit auto increment
+ * @param string  $rownumber                    index of where clause array
+ * @param array   $multi_edit_columns_name      multi edit column names array
+ * @param array   $multi_edit_columns_null      multi edit columns null array
+ * @param array   $multi_edit_columns_null_prev multi edit columns previous null
+ * @param boolean $is_insert                    whether insert or not
+ * @param boolean $using_key                    whether editing or new row
+ * @param array   $where_clause                 where clauses
+ * @param string  $table                        table name
+ *
+ * @return string $current_value                current column value in the form
+ */
+function PMA_getCurrentValueForDifferentTypes($possibly_uploaded_val, $key,
+    $multi_edit_columns_type, $current_value, $multi_edit_auto_increment,
+    $rownumber, $multi_edit_columns_name, $multi_edit_columns_null,
+    $multi_edit_columns_null_prev, $is_insert, $using_key, $where_clause, $table
+) {
+    // Fetch the current values of a row to use in case we have a protected field
+    if ($is_insert
+        && $using_key && isset($multi_edit_columns_type)
+        && is_array($multi_edit_columns_type) && isset($where_clause)
+    ) {
+        $protected_row = PMA_DBI_fetch_single_row(
+            'SELECT * FROM ' . PMA_Util::backquote($table)
+            . ' WHERE ' . $where_clause . ';'
+        );
+    }
+
+    if (false !== $possibly_uploaded_val) {
+        $current_value = $possibly_uploaded_val;
+    } else {
+        // c o l u m n    v a l u e    i n    t h e    f o r m
+        if (isset($multi_edit_columns_type[$key])) {
+            $type = $multi_edit_columns_type[$key];
+        } else {
+            $type = '';
+        }
+
+        if ($type != 'protected' && $type != 'set' && 0 === strlen($current_value)) {
+            // best way to avoid problems in strict mode
+            // (works also in non-strict mode)
+            if (isset($multi_edit_auto_increment)
+                && isset($multi_edit_auto_increment[$key])
+            ) {
+                $current_value = 'NULL';
+            } else {
+                $current_value = "''";
+            }
+        } elseif ($type == 'set') {
+            if (! empty($_REQUEST['fields']['multi_edit'][$rownumber][$key])) {
+                $current_value = implode(
+                    ',', $_REQUEST['fields']['multi_edit'][$rownumber][$key]
+                );
+                $current_value = "'" . PMA_Util::sqlAddSlashes($current_value) . "'";
+            } else {
+                 $current_value = "''";
+            }
+        } elseif ($type == 'protected') {
+            // here we are in protected mode (asked in the config)
+            // so tbl_change has put this special value in the
+            // coulmns array, so we do not change the column value
+            // but we can still handle column upload
+
+            // when in UPDATE mode, do not alter field's contents. When in INSERT
+            // mode, insert empty field because no values were submitted.
+            // If protected blobs where set, insert original fields content.
+            if (! empty($protected_row[$multi_edit_columns_name[$key]])) {
+                $current_value = '0x'
+                    . bin2hex($protected_row[$multi_edit_columns_name[$key]]);
+            } else {
+                $current_value = '';
+            }
+        } elseif ($type == 'bit') {
+            $current_value = preg_replace('/[^01]/', '0', $current_value);
+            $current_value = "b'" . PMA_Util::sqlAddSlashes($current_value) . "'";
+        } elseif (! ($type == 'datetime' || $type == 'timestamp')
+            || $current_value != 'CURRENT_TIMESTAMP'
+        ) {
+            $current_value = "'" . PMA_Util::sqlAddSlashes($current_value) . "'";
+        }
+
+        // Was the Null checkbox checked for this field?
+        // (if there is a value, we ignore the Null checkbox: this could
+        // be possible if Javascript is disabled in the browser)
+        if (! empty($multi_edit_columns_null[$key])
+            && ($current_value == "''" || $current_value == '')
+        ) {
+            $current_value = 'NULL';
+        }
+
+        // The Null checkbox was unchecked for this field
+        if (empty($current_value)
+            && ! empty($multi_edit_columns_null_prev[$key])
+            && ! isset($multi_edit_columns_null[$key])
+        ) {
+            $current_value = "''";
+        }
+    }  // end else (column value in the form)
+    return $current_value;
+}
+
+
+/**
+ * Check whether inline edited value can be truncated or not,
+ * and add additional parameters for extra_data array  if needed
+ *
+ * @param string $db               Database name
+ * @param string $table            Table name
+ * @param string $column_name      Column name
+ * @param array  &$extra_data      Extra data for ajax response
+ *
+ * @return void
+ */
+function PMA_verifyWhetherValueCanBeTruncatedAndAppendExtraData(
+    $db, $table, $column_name, &$extra_data
+) {
+    
+    $extra_data['isNeedToRecheck'] = true;
+    
+    $sql_for_real_value = 'SELECT '. PMA_Util::backquote($table) . '.'
+        . PMA_Util::backquote($column_name)
+        . ' FROM ' . PMA_Util::backquote($db) . '.'
+        . PMA_Util::backquote($table)
+        . ' WHERE ' . $_REQUEST['where_clause'][0];
+
+    if (PMA_DBI_fetch_value($sql_for_real_value) !== false) {
+        $extra_data['truncatableFieldValue'] = PMA_DBI_fetch_value($sql_for_real_value);
+    } else {
+        $extra_data['isNeedToRecheck'] = false;
+    }
+    
+}
+
+?>
diff --git a/phpmyadmin/libraries/ip_allow_deny.lib.php b/phpmyadmin/libraries/ip_allow_deny.lib.php
new file mode 100644
index 0000000..f253e37
--- /dev/null
+++ b/phpmyadmin/libraries/ip_allow_deny.lib.php
@@ -0,0 +1,327 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * This library is used with the server IP allow/deny host authentication
+ * feature
+ *
+ * @package PhpMyAdmin
+ */
+if (! defined('PHPMYADMIN')) {
+    exit;
+}
+
+/**
+ * Gets the "true" IP address of the current user
+ *
+ * @return string   the ip of the user
+ *
+ * @access  private
+ */
+function PMA_getIp()
+{
+    /* Get the address of user */
+    if (!empty($_SERVER['REMOTE_ADDR'])) {
+        $direct_ip = $_SERVER['REMOTE_ADDR'];
+    } else {
+        /* We do not know remote IP */
+        return false;
+    }
+
+    /* Do we trust this IP as a proxy? If yes we will use it's header. */
+    if (isset($GLOBALS['cfg']['TrustedProxies'][$direct_ip])) {
+        $trusted_header_value
+            = PMA_getenv($GLOBALS['cfg']['TrustedProxies'][$direct_ip]);
+        $matches = array();
+        // the $ checks that the header contains only one IP address,
+        // ?: makes sure the () don't capture
+        $is_ip = preg_match(
+            '|^(?:[0-9]{1,3}\.){3,3}[0-9]{1,3}$|',
+            $trusted_header_value, $matches
+        );
+        if ($is_ip && (count($matches) == 1)) {
+            // True IP behind a proxy
+            return $matches[0];
+        }
+    }
+
+    /* Return true IP */
+    return $direct_ip;
+} // end of the 'PMA_getIp()' function
+
+
+/**
+ * Matches for IPv4 or IPv6 addresses
+ *
+ * @param string $testRange string of IP range to match
+ * @param string $ipToTest  string of IP to test against range
+ *
+ * @return boolean    whether the IP mask matches
+ *
+ * @access  public
+ */
+function PMA_ipMaskTest($testRange, $ipToTest)
+{
+    $result = true;
+
+    if (strpos($testRange, ':') > -1 || strpos($ipToTest, ':') > -1) {
+        // assume IPv6
+        $result = PMA_ipv6MaskTest($testRange, $ipToTest);
+    } else {
+        $result = PMA_ipv4MaskTest($testRange, $ipToTest);
+    }
+
+    return $result;
+} // end of the "PMA_ipMaskTest()" function
+
+
+/**
+ * Based on IP Pattern Matcher
+ * Originally by J.Adams <jna at retina.net>
+ * Found on <http://www.php.net/manual/en/function.ip2long.php>
+ * Modified for phpMyAdmin
+ *
+ * Matches:
+ * xxx.xxx.xxx.xxx        (exact)
+ * xxx.xxx.xxx.[yyy-zzz]  (range)
+ * xxx.xxx.xxx.xxx/nn     (CIDR)
+ *
+ * Does not match:
+ * xxx.xxx.xxx.xx[yyy-zzz]  (range, partial octets not supported)
+ *
+ * @param string $testRange string of IP range to match
+ * @param string $ipToTest  string of IP to test against range
+ *
+ * @return boolean    whether the IP mask matches
+ *
+ * @access  public
+ */
+function PMA_ipv4MaskTest($testRange, $ipToTest)
+{
+    $result = true;
+    $match = preg_match(
+        '|([0-9]+)\.([0-9]+)\.([0-9]+)\.([0-9]+)/([0-9]+)|',
+        $testRange,
+        $regs
+    );
+    if ($match) {
+        // performs a mask match
+        $ipl    = ip2long($ipToTest);
+        $rangel = ip2long(
+            $regs[1] . '.' . $regs[2] . '.' . $regs[3] . '.' . $regs[4]
+        );
+
+        $maskl  = 0;
+
+        for ($i = 0; $i < 31; $i++) {
+            if ($i < $regs[5] - 1) {
+                $maskl = $maskl + PMA_Util::pow(2, (30 - $i));
+            } // end if
+        } // end for
+
+        if (($maskl & $rangel) == ($maskl & $ipl)) {
+            return true;
+        } else {
+            return false;
+        }
+    } else {
+        // range based
+        $maskocts = explode('.', $testRange);
+        $ipocts   = explode('.', $ipToTest);
+
+        // perform a range match
+        for ($i = 0; $i < 4; $i++) {
+            if (preg_match('|\[([0-9]+)\-([0-9]+)\]|', $maskocts[$i], $regs)) {
+                if (($ipocts[$i] > $regs[2]) || ($ipocts[$i] < $regs[1])) {
+                    $result = false;
+                } // end if
+            } else {
+                if ($maskocts[$i] <> $ipocts[$i]) {
+                    $result = false;
+                } // end if
+            } // end if/else
+        } //end for
+    } //end if/else
+
+    return $result;
+} // end of the "PMA_ipv4MaskTest()" function
+
+
+/**
+ * IPv6 matcher
+ * CIDR section taken from http://stackoverflow.com/a/10086404
+ * Modified for phpMyAdmin
+ *
+ * Matches:
+ * xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx         (exact)
+ * xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:[yyyy-zzzz]  (range, only at end of IP - no subnets)
+ * xxxx:xxxx:xxxx:xxxx/nn                          (CIDR)
+ *
+ * Does not match:
+ * xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xx[yyy-zzz]  (range, partial octets not supported)
+ *
+ * @param string $test_range  string of IP range to match
+ * @param string $ip_to_test  string of IP to test against range
+ *
+ * @return boolean    whether the IP mask matches
+ *
+ * @access  public
+ */
+function PMA_ipv6MaskTest($test_range, $ip_to_test)
+{
+    $result = true;
+    
+    // convert to lowercase for easier comparison
+    $test_range = strtolower($test_range);
+    $ip_to_test = strtolower($ip_to_test);
+
+    $is_cidr = strpos($test_range, '/') > -1;
+    $is_range = strpos($test_range, '[') > -1;
+    $is_single = ! $is_cidr && ! $is_range;
+
+    $ip_hex = bin2hex(inet_pton($ip_to_test));
+
+    if ($is_single) {
+        $range_hex = bin2hex(inet_pton($test_range));
+        $result = $ip_hex === $range_hex;
+    } elseif ($is_range) {
+        // what range do we operate on?
+        $range_match = array();
+        if (preg_match('/\[([0-9a-f]+)\-([0-9a-f]+)\]/', $test_range, $range_match)) {
+            $range_start = $range_match[1];
+            $range_end   = $range_match[2];
+
+            // get the first and last allowed IPs
+            $first_ip  = str_replace($range_match[0], $range_start, $test_range);
+            $first_hex = bin2hex(inet_pton($first_ip));
+            $last_ip   = str_replace($range_match[0], $range_end, $test_range);
+            $last_hex  = bin2hex(inet_pton($last_ip));
+
+            // check if the IP to test is within the range
+            $result = ($ip_hex >= $first_hex && $ip_hex <= $last_hex);
+        }
+    } elseif ($is_cidr) {
+        // Split in address and prefix length
+        list($first_ip, $subnet) = explode('/', $test_range);
+
+        // Parse the address into a binary string
+        $first_bin = inet_pton($first_ip);
+        $first_hex = bin2hex($first_bin);
+
+        // Overwriting first address string to make sure notation is optimal
+        $first_ip = inet_ntop($first_bin);
+
+        $flexbits = 128 - $subnet;
+
+        // Build the hexadecimal string of the last address
+        $last_hex = $first_hex;
+
+        $pos = 31;
+        while ($flexbits > 0) {
+          // Get the character at this position
+          $orig = substr($last_hex, $pos, 1);
+
+          // Convert it to an integer
+          $origval = hexdec($orig);
+
+          // OR it with (2^flexbits)-1, with flexbits limited to 4 at a time
+          $newval = $origval | (pow(2, min(4, $flexbits)) - 1);
+
+          // Convert it back to a hexadecimal character
+          $new = dechex($newval);
+
+          // And put that character back in the string
+          $last_hex = substr_replace($last_hex, $new, $pos, 1);
+
+          // We processed one nibble, move to previous position
+          $flexbits -= 4;
+          $pos -= 1;
+        }
+
+        // check if the IP to test is within the range
+        $result = ($ip_hex >= $first_hex && $ip_hex <= $last_hex);
+    }
+
+    return $result;
+} // end of the "PMA_ipv6MaskTest()" function
+
+
+/**
+ * Runs through IP Allow/Deny rules the use of it below for more information
+ *
+ * @param string $type 'allow' | 'deny' type of rule to match
+ *
+ * @return bool   Matched a rule ?
+ *
+ * @access  public
+ *
+ * @see     PMA_getIp()
+ */
+function PMA_allowDeny($type)
+{
+    global $cfg;
+
+    // Grabs true IP of the user and returns if it can't be found
+    $remote_ip = PMA_getIp();
+    if (empty($remote_ip)) {
+        return false;
+    }
+
+    // copy username
+    $username  = $cfg['Server']['user'];
+
+    // copy rule database
+    $rules     = $cfg['Server']['AllowDeny']['rules'];
+
+    // lookup table for some name shortcuts
+    $shortcuts = array(
+        'all'       => '0.0.0.0/0',
+        'localhost' => '127.0.0.1/8'
+    );
+
+    // Provide some useful shortcuts if server gives us address:
+    if (PMA_getenv('SERVER_ADDR')) {
+        $shortcuts['localnetA'] = PMA_getenv('SERVER_ADDR') . '/8';
+        $shortcuts['localnetB'] = PMA_getenv('SERVER_ADDR') . '/16';
+        $shortcuts['localnetC'] = PMA_getenv('SERVER_ADDR') . '/24';
+    }
+
+    foreach ($rules as $rule) {
+        // extract rule data
+        $rule_data = explode(' ', $rule);
+
+        // check for rule type
+        if ($rule_data[0] != $type) {
+            continue;
+        }
+
+        // check for username
+        if (($rule_data[1] != '%') //wildcarded first
+            && ($rule_data[1] != $username)
+        ) {
+            continue;
+        }
+
+        // check if the config file has the full string with an extra
+        // 'from' in it and if it does, just discard it
+        if ($rule_data[2] == 'from') {
+            $rule_data[2] = $rule_data[3];
+        }
+
+        // Handle shortcuts with above array
+        if (isset($shortcuts[$rule_data[2]])) {
+            $rule_data[2] = $shortcuts[$rule_data[2]];
+        }
+
+        // Add code for host lookups here
+        // Excluded for the moment
+
+        // Do the actual matching now
+        if (PMA_ipMaskTest($rule_data[2], $remote_ip)) {
+            return true;
+        }
+    } // end while
+
+    return false;
+} // end of the "PMA_AllowDeny()" function
+
+?>
diff --git a/phpmyadmin/libraries/js_escape.lib.php b/phpmyadmin/libraries/js_escape.lib.php
new file mode 100644
index 0000000..42d7fed
--- /dev/null
+++ b/phpmyadmin/libraries/js_escape.lib.php
@@ -0,0 +1,133 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * Javascript escaping functions.
+ *
+ * @package PhpMyAdmin
+ *
+ */
+if (! defined('PHPMYADMIN')) {
+    exit;
+}
+
+/**
+ * Format a string so it can be a string inside JavaScript code inside an
+ * eventhandler (onclick, onchange, on..., ).
+ * This function is used to displays a javascript confirmation box for
+ * "DROP/DELETE/ALTER" queries.
+ *
+ * @param string  $a_string       the string to format
+ * @param boolean $add_backquotes whether to add backquotes to the string or not
+ *
+ * @return string   the formatted string
+ *
+ * @access  public
+ */
+function PMA_jsFormat($a_string = '', $add_backquotes = true)
+{
+    if (is_string($a_string)) {
+        $a_string = htmlspecialchars($a_string);
+        $a_string = PMA_escapeJsString($a_string);
+        // Needed for inline javascript to prevent some browsers
+        // treating it as a anchor
+        $a_string = str_replace('#', '\\#', $a_string);
+    }
+
+    return (($add_backquotes) ? PMA_Util::backquote($a_string) : $a_string);
+} // end of the 'PMA_jsFormat()' function
+
+/**
+ * escapes a string to be inserted as string a JavaScript block
+ * enclosed by <![CDATA[ ... ]]>
+ * this requires only to escape ' with \' and end of script block
+ *
+ * We also remove NUL byte as some browsers (namely MSIE) ignore it and
+ * inserting it anywhere inside </script would allow to bypass this check.
+ *
+ * @param string $string the string to be escaped
+ *
+ * @return string  the escaped string
+ */
+function PMA_escapeJsString($string)
+{
+    return preg_replace(
+        '@</script at i', '</\' + \'script',
+        strtr(
+            $string,
+            array(
+                "\000" => '',
+                '\\' => '\\\\',
+                '\'' => '\\\'',
+                '"' => '\"',
+                "\n" => '\n',
+                "\r" => '\r'
+            )
+        )
+    );
+}
+
+/**
+ * Formats a value for javascript code.
+ *
+ * @param string $value String to be formatted.
+ *
+ * @return string formatted value.
+ */
+function PMA_formatJsVal($value)
+{
+    if (is_bool($value)) {
+        if ($value) {
+            return 'true';
+        } else {
+            return 'false';
+        }
+    } elseif (is_int($value)) {
+        return (int)$value;
+    } else {
+        return '"' . PMA_escapeJsString($value) . '"';
+    }
+}
+
+/**
+ * Formats an javascript assignment with proper escaping of a value
+ * and support for assigning array of strings.
+ *
+ * @param string $key    Name of value to set
+ * @param mixed  $value  Value to set, can be either string or array of strings
+ * @param bool   $escape Whether to escape value or keep it as it is
+ *                       (for inclusion of js code)
+ *
+ * @return string Javascript code.
+ */
+function PMA_getJsValue($key, $value, $escape = true)
+{
+    $result = $key . ' = ';
+    if (!$escape) {
+        $result .= $value;
+    } elseif (is_array($value)) {
+        $result .= '[';
+        foreach ($value as $val) {
+            $result .= PMA_formatJsVal($val) . ",";
+        }
+        $result .= "];\n";
+    } else {
+        $result .= PMA_formatJsVal($value) . ";\n";
+    }
+    return $result;
+}
+
+/**
+ * Prints an javascript assignment with proper escaping of a value
+ * and support for assigning array of strings.
+ *
+ * @param string $key   Name of value to set
+ * @param mixed  $value Value to set, can be either string or array of strings
+ *
+ * @return void
+ */
+function PMA_printJsValue($key, $value)
+{
+    echo PMA_getJsValue($key, $value);
+}
+
+?>
diff --git a/phpmyadmin/libraries/kanji-encoding.lib.php b/phpmyadmin/libraries/kanji-encoding.lib.php
new file mode 100644
index 0000000..f78119f
--- /dev/null
+++ b/phpmyadmin/libraries/kanji-encoding.lib.php
@@ -0,0 +1,161 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * Set of functions for kanji-encoding convert (available only with japanese
+ * language)
+ *
+ * PHP4 configure requirements:
+ *     --enable-mbstring --enable-mbstr-enc-trans --enable-mbregex
+ *
+ * 2002/2/22 - by Yukihiro Kawada <kawada at den.fujifilm.co.jp>
+ *
+ * @package PhpMyAdmin
+ */
+if (! defined('PHPMYADMIN')) {
+    exit;
+}
+
+/**
+ * Gets the php internal encoding codes and sets the available encoding
+ * codes list
+ * 2002/1/4 by Y.Kawada
+ *
+ * @global  string   the current encoding code
+ * @global  string   the available encoding codes list
+ *
+ * @return boolean  always true
+ */
+function PMA_internal_enc_check()
+{
+    global $internal_enc, $enc_list;
+
+    $internal_enc = mb_internal_encoding();
+    if ($internal_enc == 'EUC-JP') {
+        $enc_list = 'ASCII,EUC-JP,SJIS,JIS';
+    } else {
+        $enc_list = 'ASCII,SJIS,EUC-JP,JIS';
+    }
+
+    return true;
+} // end of the 'PMA_internal_enc_check' function
+
+
+/**
+ * Reverses SJIS & EUC-JP position in the encoding codes list
+ * 2002/1/4 by Y.Kawada
+ *
+ * @global  string   the available encoding codes list
+ *
+ * @return boolean  always true
+ */
+function PMA_change_enc_order()
+{
+    global $enc_list;
+
+    $p            = explode(',', $enc_list);
+    if ($p[1] == 'EUC-JP') {
+        $enc_list = 'ASCII,SJIS,EUC-JP,JIS';
+    } else {
+        $enc_list = 'ASCII,EUC-JP,SJIS,JIS';
+    }
+
+    return true;
+} // end of the 'PMA_change_enc_order' function
+
+
+/**
+ * Kanji string encoding convert
+ * 2002/1/4 by Y.Kawada
+ *
+ * @param string $str  the string to convert
+ * @param string $enc  the destination encoding code
+ * @param string $kana set 'kana' convert to JIS-X208-kana
+ *
+ * @global  string   the available encoding codes list
+ *
+ * @return string   the converted string
+ */
+function PMA_kanji_str_conv($str, $enc, $kana)
+{
+    global $enc_list;
+
+    if ($enc == '' && $kana == '') {
+        return $str;
+    }
+    $nw       = mb_detect_encoding($str, $enc_list);
+
+    if ($kana == 'kana') {
+        $dist = mb_convert_kana($str, 'KV', $nw);
+        $str  = $dist;
+    }
+    if ($nw != $enc && $enc != '') {
+        $dist = mb_convert_encoding($str, $enc, $nw);
+    } else {
+        $dist = $str;
+    }
+    return $dist;
+} // end of the 'PMA_kanji_str_conv' function
+
+
+/**
+ * Kanji file encoding convert
+ * 2002/1/4 by Y.Kawada
+ *
+ * @param string $file the name of the file to convert
+ * @param string $enc  the destination encoding code
+ * @param string $kana set 'kana' convert to JIS-X208-kana
+ *
+ * @return string   the name of the converted file
+ */
+function PMA_kanji_file_conv($file, $enc, $kana)
+{
+    if ($enc == '' && $kana == '') {
+        return $file;
+    }
+
+    $tmpfname = tempnam('', $enc);
+    $fpd      = fopen($tmpfname, 'wb');
+    $fps      = fopen($file, 'r');
+    PMA_change_enc_order();
+    while (!feof($fps)) {
+        $line = fgets($fps, 4096);
+        $dist = PMA_kanji_str_conv($line, $enc, $kana);
+        fputs($fpd, $dist);
+    } // end while
+    PMA_change_enc_order();
+    fclose($fps);
+    fclose($fpd);
+    unlink($file);
+
+    return $tmpfname;
+} // end of the 'PMA_kanji_file_conv' function
+
+
+/**
+ * Defines radio form fields to switch between encoding modes
+ * 2002/1/4 by Y.Kawada
+ *
+ * @param string $spaces spaces character to prepend the output with
+ *
+ * @return string   xhtml code for the radio controls
+ */
+function PMA_set_enc_form($spaces)
+{
+    return "\n"
+             /* l10n: This is currently used only in Japanese locales */
+           . $spaces . '<ul>' . "\n" . '<li>'
+           . $spaces . '<input type="radio" name="knjenc" value="" checked="checked" id="kj-none" /><label for="kj-none">' . _pgettext('None encoding conversion', 'None') . "</label>\n"
+           . $spaces . '<input type="radio" name="knjenc" value="EUC-JP" id="kj-euc" /><label for="kj-euc">EUC</label>' . "\n"
+           . $spaces . '<input type="radio" name="knjenc" value="SJIS" id="kj-sjis" /><label for="kj-sjis">SJIS</label>' . "\n"
+           . $spaces . '</li>' . "\n" . '<li>'
+           . $spaces . '<input type="checkbox" name="xkana" value="kana" id="kj-kana" />' . "\n"
+           /* l10n: This is currently used only in Japanese locales */
+           . $spaces . '<label for="kj-kana">' . __('Convert to Kana') . '</label><br />' . "\n"
+           . $spaces . '</li>' . "\n" . '</ul>'
+           ;
+} // end of the 'PMA_set_enc_form' function
+
+
+PMA_internal_enc_check();
+
+?>
diff --git a/phpmyadmin/libraries/language_stats.inc.php b/phpmyadmin/libraries/language_stats.inc.php
new file mode 100644
index 0000000..f293cc6
--- /dev/null
+++ b/phpmyadmin/libraries/language_stats.inc.php
@@ -0,0 +1,76 @@
+<?php
+/* Automatically generated file, do not edit! */
+/* Generated by scripts/remove-incomplete-mo */
+
+$GLOBALS["language_stats"] = array (
+    'af' => 10,
+    'ar' => 50,
+    'az' => 16,
+    'be at latin' => 34,
+    'be' => 34,
+    'bg' => 76,
+    'bn' => 20,
+    'br' => 26,
+    'bs' => 18,
+    'ca' => 99,
+    'ckb' => 21,
+    'cs' => 100,
+    'cy' => 25,
+    'da' => 99,
+    'de' => 99,
+    'el' => 100,
+    'en_GB' => 99,
+    'es' => 100,
+    'et' => 100,
+    'eu' => 22,
+    'fa' => 36,
+    'fi' => 69,
+    'fr' => 100,
+    'gl' => 99,
+    'he' => 23,
+    'hi' => 56,
+    'hr' => 41,
+    'hu' => 78,
+    'hy' => 4,
+    'id' => 74,
+    'it' => 93,
+    'ja' => 95,
+    'ka' => 21,
+    'kk' => 13,
+    'ko' => 69,
+    'lt' => 67,
+    'lv' => 24,
+    'mk' => 23,
+    'ml' => 2,
+    'mn' => 27,
+    'ms' => 15,
+    'nb' => 72,
+    'nl' => 100,
+    'pa' => 0,
+    'pl' => 99,
+    'pt_BR' => 100,
+    'pt' => 50,
+    'ro' => 57,
+    'ru' => 99,
+    'si' => 81,
+    'sk' => 83,
+    'sl' => 100,
+    'sq' => 30,
+    'sr at latin' => 68,
+    'sr' => 32,
+    'sv' => 99,
+    'ta' => 15,
+    'te' => 13,
+    'th' => 45,
+    'tk' => 0,
+    'tr' => 100,
+    'tt' => 23,
+    'ug' => 14,
+    'uk' => 92,
+    'ur' => 25,
+    'uz at latin' => 48,
+    'uz' => 49,
+    'zh_CN' => 99,
+    'zh_TW' => 80,
+);
+?>
diff --git a/phpmyadmin/libraries/logging.lib.php b/phpmyadmin/libraries/logging.lib.php
new file mode 100644
index 0000000..dee8407
--- /dev/null
+++ b/phpmyadmin/libraries/logging.lib.php
@@ -0,0 +1,30 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * Logging functionality for webserver.
+ *
+ * This includes web server specific code to log some information.
+ *
+ * @package PhpMyAdmin
+ */
+if (! defined('PHPMYADMIN')) {
+    exit;
+}
+
+/**
+ * Logs user information to webserver logs.
+ *
+ * @param string $user   user name
+ * @param string $status status message
+ *
+ * @return void
+ */
+function PMA_log_user($user, $status = 'ok')
+{
+    if (function_exists('apache_note')) {
+        apache_note('userID', $user);
+        apache_note('userStatus', $status);
+    }
+}
+
+?>
diff --git a/phpmyadmin/libraries/mime.lib.php b/phpmyadmin/libraries/mime.lib.php
new file mode 100644
index 0000000..954c762
--- /dev/null
+++ b/phpmyadmin/libraries/mime.lib.php
@@ -0,0 +1,34 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * MIME detection code.
+ *
+ * @package PhpMyAdmin
+ * @todo Maybe we could try to use fileinfo module if loaded
+ */
+if (! defined('PHPMYADMIN')) {
+    exit;
+}
+
+/**
+ * Tries to detect MIME type of content.
+ *
+ * @param string &$test
+ *
+ * @return string
+ */
+function PMA_detectMIME(&$test)
+{
+    $len = strlen($test);
+    if ($len >= 2 && $test[0] == chr(0xff) && $test[1] == chr(0xd8)) {
+        return 'image/jpeg';
+    }
+    if ($len >= 3 && substr($test, 0, 3) == 'GIF') {
+        return 'image/gif';
+    }
+    if ($len >= 4 && substr($test, 0, 4) == "\x89PNG") {
+        return 'image/png';
+    }
+    return 'application/octet-stream';
+}
+?>
diff --git a/phpmyadmin/libraries/mult_submits.inc.php b/phpmyadmin/libraries/mult_submits.inc.php
new file mode 100644
index 0000000..7423749
--- /dev/null
+++ b/phpmyadmin/libraries/mult_submits.inc.php
@@ -0,0 +1,578 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ *
+ * @package PhpMyAdmin
+ */
+if (! defined('PHPMYADMIN')) {
+    exit;
+}
+
+require_once 'libraries/transformations.lib.php';
+
+$request_params = array(
+    'clause_is_unique',
+    'from_prefix',
+    'goto',
+    'mult_btn',
+    'original_sql_query',
+    'query_type',
+    'reload',
+    'rows_to_delete',
+    'selected',
+    'selected_fld',
+    'selected_recent_table',
+    'sql_query',
+    'submit_mult',
+    'table_type',
+    'to_prefix',
+    'url_query'
+);
+
+foreach ($request_params as $one_request_param) {
+    if (isset($_REQUEST[$one_request_param])) {
+        $GLOBALS[$one_request_param] = $_REQUEST[$one_request_param];
+    }
+}
+
+/**
+ * Prepares the work and runs some other scripts if required
+ */
+if (! empty($submit_mult)
+    && $submit_mult != __('With selected:')
+    && (! empty($selected_db) || ! empty($selected_tbl) || ! empty($selected_fld) || ! empty($rows_to_delete))
+) {
+    define('PMA_SUBMIT_MULT', 1);
+    if (isset($selected_db) && !empty($selected_db)) {
+        // coming from server database view - do something with selected databases
+        $selected     = $selected_db;
+        $what         = 'drop_db';
+    } elseif (isset($selected_tbl) && !empty($selected_tbl)) {
+        // coming from database structure view - do something with selected tables
+        if ($submit_mult == 'print') {
+            include './tbl_printview.php';
+        } else {
+            $selected = $selected_tbl;
+            switch ($submit_mult) {
+            case 'add_prefix_tbl':
+            case 'replace_prefix_tbl':
+            case 'copy_tbl_change_prefix':
+            case 'drop_db':
+            case 'drop_tbl':
+            case 'empty_tbl':
+                $what = $submit_mult;
+                break;
+            case 'check_tbl':
+            case 'optimize_tbl':
+            case 'repair_tbl':
+            case 'analyze_tbl':
+                $query_type = $submit_mult;
+                unset($submit_mult);
+                $mult_btn   = __('Yes');
+                break;
+            case 'export':
+                unset($submit_mult);
+                include 'db_export.php';
+                exit;
+                break;
+            } // end switch
+        }
+    } elseif (isset($selected_fld) && !empty($selected_fld)) {
+        // coming from table structure view - do something with selected columns/fileds
+        $selected     = $selected_fld;
+        switch ($submit_mult) {
+        case 'drop':
+            $what     = 'drop_fld';
+            break;
+        case 'primary':
+            // Gets table primary key
+            PMA_DBI_select_db($db);
+            $result      = PMA_DBI_query('SHOW KEYS FROM ' . PMA_Util::backquote($table) . ';');
+            $primary     = '';
+            while ($row = PMA_DBI_fetch_assoc($result)) {
+                // Backups the list of primary keys
+                if ($row['Key_name'] == 'PRIMARY') {
+                    $primary .= $row['Column_name'] . ', ';
+                }
+            } // end while
+            PMA_DBI_free_result($result);
+            if (empty($primary)) {
+                // no primary key, so we can safely create new
+                unset($submit_mult);
+                $query_type = 'primary_fld';
+                $mult_btn   = __('Yes');
+            } else {
+                // primary key exists, so lets as user
+                $what = 'primary_fld';
+            }
+            break;
+        case 'index':
+            unset($submit_mult);
+            $query_type = 'index_fld';
+            $mult_btn   = __('Yes');
+            break;
+        case 'unique':
+            unset($submit_mult);
+            $query_type = 'unique_fld';
+            $mult_btn   = __('Yes');
+            break;
+        case 'spatial':
+            unset($submit_mult);
+            $query_type = 'spatial_fld';
+            $mult_btn   = __('Yes');
+            break;
+        case 'ftext':
+            unset($submit_mult);
+            $query_type = 'fulltext_fld';
+            $mult_btn   = __('Yes');
+            break;
+        case 'change':
+            PMA_displayHtmlForColumnChange($db, $table, $selected, $action);
+            // execution stops here but PMA_Response correctly finishes
+            // the rendering 
+            exit;
+        case 'browse':
+            // this should already be handled by tbl_structure.php
+        }
+    } else {
+        // coming from browsing - do something with selected rows
+        $what = 'row_delete';
+        $selected = $rows_to_delete;
+    }
+} // end if
+
+$views = PMA_DBI_getVirtualTables($db);
+
+/**
+ * Displays the confirmation form if required
+ */
+if (!empty($submit_mult) && !empty($what)) {
+    unset($message);
+
+    if (strlen($table)) {
+        include './libraries/tbl_common.inc.php';
+        $url_query .= '&goto=tbl_sql.php&back=tbl_sql.php';
+        include './libraries/tbl_info.inc.php';
+    } elseif (strlen($db)) {
+        include './libraries/db_common.inc.php';
+        include './libraries/db_info.inc.php';
+    } else {
+        include_once './libraries/server_common.inc.php';
+    }
+
+    // Builds the query
+    $full_query     = '';
+    if ($what == 'drop_tbl') {
+        $full_query_views = '';
+    }
+    $selected_cnt   = count($selected);
+    $i = 0;
+    foreach ($selected AS $idx => $sval) {
+        switch ($what) {
+        case 'row_delete':
+            $full_query .= 'DELETE FROM ' . PMA_Util::backquote($db) . '.' . PMA_Util::backquote($table)
+                . ' WHERE ' . urldecode($sval) . ' LIMIT 1'
+                . ';<br />';
+            break;
+        case 'drop_db':
+            $full_query .= 'DROP DATABASE '
+                . PMA_Util::backquote(htmlspecialchars($sval))
+                . ';<br />';
+            $reload = 1;
+            break;
+
+        case 'drop_tbl':
+            $current = $sval;
+            if (!empty($views) && in_array($current, $views)) {
+                $full_query_views .= (empty($full_query_views) ? 'DROP VIEW ' : ', ')
+                    . PMA_Util::backquote(htmlspecialchars($current));
+            } else {
+                $full_query .= (empty($full_query) ? 'DROP TABLE ' : ', ')
+                    . PMA_Util::backquote(htmlspecialchars($current));
+            }
+            break;
+
+        case 'empty_tbl':
+            $full_query .= 'TRUNCATE ';
+            $full_query .= PMA_Util::backquote(htmlspecialchars($sval))
+                        . ';<br />';
+            break;
+
+        case 'primary_fld':
+            if ($full_query == '') {
+                $full_query .= 'ALTER TABLE '
+                    . PMA_Util::backquote(htmlspecialchars($table))
+                    . '<br />  DROP PRIMARY KEY,'
+                    . '<br />   ADD PRIMARY KEY('
+                    . '<br />     '
+                    . PMA_Util::backquote(htmlspecialchars($sval))
+                    . ',';
+            } else {
+                $full_query .= '<br />     '
+                    . PMA_Util::backquote(htmlspecialchars($sval))
+                    . ',';
+            }
+            if ($i == $selected_cnt-1) {
+                $full_query = preg_replace('@,$@', ');<br />', $full_query);
+            }
+            break;
+
+        case 'drop_fld':
+            if ($full_query == '') {
+                $full_query .= 'ALTER TABLE '
+                    . PMA_Util::backquote(htmlspecialchars($table));
+            }
+            $full_query .= '<br />  DROP '
+                . PMA_Util::backquote(htmlspecialchars($sval))
+                . ',';
+            if ($i == $selected_cnt - 1) {
+                $full_query = preg_replace('@,$@', ';<br />', $full_query);
+            }
+            break;
+        } // end switch
+        $i++;
+    }
+    if ($what == 'drop_tbl') {
+        if (!empty($full_query)) {
+            $full_query .= ';<br />' . "\n";
+        }
+        if (!empty($full_query_views)) {
+            $full_query .= $full_query_views . ';<br />' . "\n";
+        }
+        unset($full_query_views);
+    }
+
+    // Displays the confirmation form
+    $_url_params = array(
+        'query_type' => $what,
+        'reload' => (! empty($reload) ? 1 : 0),
+    );
+    if (strpos(' ' . $action, 'db_') == 1) {
+        $_url_params['db']= $db;
+    } elseif (strpos(' ' . $action, 'tbl_') == 1 || $what == 'row_delete') {
+        $_url_params['db']= $db;
+        $_url_params['table']= $table;
+    }
+    foreach ($selected as $idx => $sval) {
+        if ($what == 'row_delete') {
+            $_url_params['selected'][] = 'DELETE FROM ' . PMA_Util::backquote($db) . '.' . PMA_Util::backquote($table)
+            . ' WHERE ' . urldecode($sval) . ' LIMIT 1;';
+        } else {
+            $_url_params['selected'][] = $sval;
+        }
+    }
+    if ($what == 'drop_tbl' && !empty($views)) {
+        foreach ($views as $current) {
+            $_url_params['views'][] = $current;
+        }
+    }
+    if ($what == 'row_delete') {
+        $_url_params['original_sql_query'] = $original_sql_query;
+        if (! empty($original_url_query)) {
+            $_url_params['original_url_query'] = $original_url_query;
+        }
+    }
+    if ($what == 'replace_prefix_tbl' || $what == 'copy_tbl_change_prefix') { ?>
+        <form action="<?php echo $action; ?>" method="post">
+        <?php echo PMA_generate_common_hidden_inputs($_url_params); ?>
+        <fieldset class = "input">
+                <legend><?php echo ($what == 'replace_prefix_tbl' ? __('Replace table prefix') : __('Copy table with prefix')) ?>:</legend>
+                <table>
+                <tr>
+                <td><?php echo __('From'); ?></td><td><input type="text" name="from_prefix" id="initialPrefix" /></td>
+                </tr>
+                <tr>
+                <td><?php echo __('To'); ?> </td><td><input type="text" name="to_prefix" id="newPrefix" /></td>
+                </tr>
+                </table>
+        </fieldset>
+        <fieldset class="tblFooters">
+                <input type="hidden" name="mult_btn" value="<?php echo __('Yes'); ?>" />
+                <input type="submit" value="<?php echo __('Submit'); ?>" id="buttonYes" />
+        </fieldset>
+        </form>
+    <?php
+    } elseif ($what == 'add_prefix_tbl') { ?>
+        <form action="<?php echo $action; ?>" method="post">
+        <?php echo PMA_generate_common_hidden_inputs($_url_params); ?>
+        <fieldset class = "input">
+                <legend><?php echo __('Add table prefix') ?>:</legend>
+                <table>
+                <tr>
+                <td><?php echo __('Add prefix'); ?></td>     <td><input type="text" name="add_prefix" id="txtPrefix" /></td>
+                </tr>
+                </table>
+        </fieldset>
+        <fieldset class="tblFooters">
+                <input type="hidden" name="mult_btn" value="<?php echo __('Yes'); ?>" />
+                <input type="submit" value="<?php echo __('Submit'); ?>" id="buttonYes" />
+        </fieldset>
+        </form>
+    <?php
+    } else { ?>
+        <fieldset class="confirmation">
+            <legend><?php
+                if ($what == 'drop_db') {
+                    echo  __('You are about to DESTROY a complete database!') . ' ';
+                }
+                echo __('Do you really want to execute the following query?');
+            ?>:</legend>
+            <code><?php echo $full_query; ?></code>
+        </fieldset>
+        <fieldset class="tblFooters">
+            <form action="<?php echo $action; ?>" method="post">
+            <?php
+            echo PMA_generate_common_hidden_inputs($_url_params);
+            // Display option to disable foreign key checks while dropping tables
+            if ($what == 'drop_tbl') { ?>
+                <div id="foreignkeychk">
+                <span class="fkc_switch"><?php echo __('Foreign key check:'); ?></span>
+                <span class="checkbox"><input type="checkbox" name="fk_check" value="1" id="fkc_checkbox"<?php
+                $default_fk_check_value = (PMA_DBI_fetch_value('SHOW VARIABLES LIKE \'foreign_key_checks\';', 0, 1) == 'ON') ? 1 : 0;
+                echo ($default_fk_check_value) ? ' checked="checked"' : '' ?>/></span>
+                <span id="fkc_status" class="fkc_switch"><?php echo ($default_fk_check_value) ? __('(Enabled)') : __('(Disabled)'); ?></span>
+                </div><?php
+            } ?>
+            <input type="hidden" name="mult_btn" value="<?php echo __('Yes'); ?>" />
+            <input type="submit" value="<?php echo __('Yes'); ?>" id="buttonYes" />
+            </form>
+
+            <form action="<?php echo $action; ?>" method="post">
+                <?php echo PMA_generate_common_hidden_inputs($_url_params); ?>
+                <input type="hidden" name="mult_btn" value="<?php echo __('No'); ?>" />
+                <input type="submit" value="<?php echo __('No'); ?>" id="buttonNo" />
+            </form>
+        </fieldset>
+    <?php
+    }
+    exit;
+
+} elseif (! empty($mult_btn) && $mult_btn == __('Yes')) {
+    /**
+     * Executes the query - dropping rows, columns/fields, tables or dbs
+     */
+    if ($query_type == 'drop_db' || $query_type == 'drop_tbl' || $query_type == 'drop_fld') {
+        include_once './libraries/relation_cleanup.lib.php';
+    }
+
+    $sql_query      = '';
+    if ($query_type == 'drop_tbl') {
+        $sql_query_views = '';
+    }
+    $selected_cnt   = count($selected);
+    $run_parts      = false; // whether to run query after each pass
+    $use_sql        = false; // whether to include sql.php at the end (to display results)
+
+    if ($query_type == 'primary_fld') {
+        // Gets table primary key
+        PMA_DBI_select_db($db);
+        $result      = PMA_DBI_query('SHOW KEYS FROM ' . PMA_Util::backquote($table) . ';');
+        $primary     = '';
+        while ($row = PMA_DBI_fetch_assoc($result)) {
+            // Backups the list of primary keys
+            if ($row['Key_name'] == 'PRIMARY') {
+                $primary .= $row['Column_name'] . ', ';
+            }
+        } // end while
+        PMA_DBI_free_result($result);
+    }
+
+    $rebuild_database_list = false;
+
+    for ($i = 0; $i < $selected_cnt; $i++) {
+        switch ($query_type) {
+        case 'row_delete':
+            $a_query = $selected[$i];
+            $run_parts = true;
+            break;
+
+        case 'drop_db':
+            PMA_relationsCleanupDatabase($selected[$i]);
+            $a_query   = 'DROP DATABASE '
+                       . PMA_Util::backquote($selected[$i]);
+            $reload    = 1;
+            $run_parts = true;
+            $rebuild_database_list = true;
+            break;
+
+        case 'drop_tbl':
+            PMA_relationsCleanupTable($db, $selected[$i]);
+            $current = $selected[$i];
+            if (!empty($views) && in_array($current, $views)) {
+                $sql_query_views .= (empty($sql_query_views) ? 'DROP VIEW ' : ', ')
+                          . PMA_Util::backquote($current);
+            } else {
+                $sql_query .= (empty($sql_query) ? 'DROP TABLE ' : ', ')
+                           . PMA_Util::backquote($current);
+            }
+            $reload    = 1;
+            break;
+
+        case 'check_tbl':
+            $sql_query .= (empty($sql_query) ? 'CHECK TABLE ' : ', ')
+                       . PMA_Util::backquote($selected[$i]);
+            $use_sql    = true;
+            break;
+
+        case 'optimize_tbl':
+            $sql_query .= (empty($sql_query) ? 'OPTIMIZE TABLE ' : ', ')
+                       . PMA_Util::backquote($selected[$i]);
+            $use_sql    = true;
+            break;
+
+        case 'analyze_tbl':
+            $sql_query .= (empty($sql_query) ? 'ANALYZE TABLE ' : ', ')
+                       . PMA_Util::backquote($selected[$i]);
+            $use_sql    = true;
+            break;
+
+        case 'repair_tbl':
+            $sql_query .= (empty($sql_query) ? 'REPAIR TABLE ' : ', ')
+                       . PMA_Util::backquote($selected[$i]);
+            $use_sql    = true;
+            break;
+
+        case 'empty_tbl':
+            $a_query = 'TRUNCATE ';
+            $a_query .= PMA_Util::backquote($selected[$i]);
+            $run_parts = true;
+            break;
+
+        case 'drop_fld':
+            PMA_relationsCleanupColumn($db, $table, $selected[$i]);
+            $sql_query .= (empty($sql_query) ? 'ALTER TABLE ' . PMA_Util::backquote($table) : ',')
+                       . ' DROP ' . PMA_Util::backquote($selected[$i])
+                       . (($i == $selected_cnt-1) ? ';' : '');
+            break;
+
+        case 'primary_fld':
+            $sql_query .= (empty($sql_query) ? 'ALTER TABLE ' . PMA_Util::backquote($table) . (empty($primary) ? '' : ' DROP PRIMARY KEY,') . ' ADD PRIMARY KEY( ' : ', ')
+                       . PMA_Util::backquote($selected[$i])
+                       . (($i == $selected_cnt-1) ? ');' : '');
+            break;
+
+        case 'index_fld':
+            $sql_query .= (empty($sql_query) ? 'ALTER TABLE ' . PMA_Util::backquote($table) . ' ADD INDEX( ' : ', ')
+                       . PMA_Util::backquote($selected[$i])
+                       . (($i == $selected_cnt-1) ? ');' : '');
+            break;
+
+        case 'unique_fld':
+            $sql_query .= (empty($sql_query) ? 'ALTER TABLE ' . PMA_Util::backquote($table) . ' ADD UNIQUE( ' : ', ')
+                       . PMA_Util::backquote($selected[$i])
+                       . (($i == $selected_cnt-1) ? ');' : '');
+            break;
+
+        case 'spatial_fld':
+            $sql_query .= (empty($sql_query) ? 'ALTER TABLE ' . PMA_Util::backquote($table) . ' ADD SPATIAL( ' : ', ')
+                       . PMA_Util::backquote($selected[$i])
+                       . (($i == $selected_cnt-1) ? ');' : '');
+            break;
+
+        case 'fulltext_fld':
+            $sql_query .= (empty($sql_query) ? 'ALTER TABLE ' . PMA_Util::backquote($table) . ' ADD FULLTEXT( ' : ', ')
+                       . PMA_Util::backquote($selected[$i])
+                       . (($i == $selected_cnt-1) ? ');' : '');
+            break;
+
+        case 'add_prefix_tbl':
+            $newtablename = $_POST['add_prefix'] . $selected[$i];
+            $a_query = 'ALTER TABLE ' . PMA_Util::backquote($selected[$i]) . ' RENAME ' . PMA_Util::backquote($newtablename); // ADD PREFIX TO TABLE NAME
+            $run_parts = true;
+            break;
+
+        case 'replace_prefix_tbl':
+            $current = $selected[$i];
+            if (substr($current, 0, strlen($from_prefix)) == $from_prefix) {
+                $newtablename = $to_prefix . substr($current, strlen($from_prefix));
+            } else {
+                $newtablename = $current;
+            }
+            $a_query = 'ALTER TABLE ' 
+                . PMA_Util::backquote($selected[$i]) 
+                . ' RENAME ' 
+                . PMA_Util::backquote($newtablename) ; // CHANGE PREFIX PATTERN
+            $run_parts = true;
+            break;
+
+        case 'copy_tbl_change_prefix':
+            $current = $selected[$i];
+            if (substr($current, 0, strlen($from_prefix)) == $from_prefix) {
+                $newtablename = $to_prefix . substr($current, strlen($from_prefix));
+            } else {
+                $newtablename = $current;
+            }
+            $newtablename = $to_prefix . substr($current, strlen($from_prefix));
+            $a_query = 'CREATE TABLE ' 
+                . PMA_Util::backquote($newtablename) 
+                . ' SELECT * FROM ' 
+                . PMA_Util::backquote($selected[$i]) ; // COPY TABLE AND CHANGE PREFIX PATTERN
+            $run_parts = true;
+            break;
+
+        } // end switch
+
+        // All "DROP TABLE", "DROP FIELD", "OPTIMIZE TABLE" and "REPAIR TABLE"
+        // statements will be run at once below
+        if ($run_parts) {
+            $sql_query .= $a_query . ';' . "\n";
+            if ($query_type != 'drop_db') {
+                PMA_DBI_select_db($db);
+            }
+            $result = PMA_DBI_query($a_query);
+            
+            if ($query_type == 'drop_db') {
+                PMA_clearTransformations($selected[$i]);
+            } elseif ($query_type == 'drop_tbl') {
+                PMA_clearTransformations($db, $selected[$i]);
+            } else if ($query_type == 'drop_fld') {
+                PMA_clearTransformations($db, $table, $selected[$i]);
+            }
+            
+        } // end if
+    } // end for
+
+    if ($query_type == 'drop_tbl') {
+        $default_fk_check_value = (PMA_DBI_fetch_value('SHOW VARIABLES LIKE \'foreign_key_checks\';', 0, 1) == 'ON') ? 1 : 0;
+        if (!empty($sql_query)) {
+            $sql_query .= ';';
+        } elseif (!empty($sql_query_views)) {
+            $sql_query = $sql_query_views . ';';
+            unset($sql_query_views);
+        }
+    }
+
+    if ($use_sql) {
+        include './sql.php';
+    } elseif (!$run_parts) {
+        PMA_DBI_select_db($db);
+        // for disabling foreign key checks while dropping tables
+        if (! isset($_REQUEST['fk_check']) && $query_type == 'drop_tbl') {
+            PMA_DBI_query('SET FOREIGN_KEY_CHECKS = 0;');
+        }
+        $result = PMA_DBI_try_query($sql_query);
+        if (! isset($_REQUEST['fk_check'])
+            && $query_type == 'drop_tbl'
+            && $default_fk_check_value
+        ) {
+            PMA_DBI_query('SET FOREIGN_KEY_CHECKS = 1;');
+        }
+        if ($result && !empty($sql_query_views)) {
+            $sql_query .= ' ' . $sql_query_views . ';';
+            $result = PMA_DBI_try_query($sql_query_views);
+            unset($sql_query_views);
+        }
+
+        if (! $result) {
+            $message = PMA_Message::error(PMA_DBI_getError());
+        }
+    }
+    if ($rebuild_database_list) {
+        // avoid a problem with the database list navigator
+        // when dropping a db from server_databases
+        $GLOBALS['pma']->databases->build();
+    }
+} else {
+    $message = PMA_Message::success(__('No change'));
+}
+?>
diff --git a/phpmyadmin/libraries/mysql_charsets.lib.php b/phpmyadmin/libraries/mysql_charsets.lib.php
new file mode 100644
index 0000000..45c48af
--- /dev/null
+++ b/phpmyadmin/libraries/mysql_charsets.lib.php
@@ -0,0 +1,455 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ *
+ * @package PhpMyAdmin
+ */
+if (! defined('PHPMYADMIN')) {
+    exit;
+}
+
+/**
+ *
+ */
+
+if (! PMA_Util::cacheExists('mysql_charsets', true)) {
+    global $mysql_charsets, $mysql_charsets_descriptions,
+        $mysql_charsets_available, $mysql_collations, $mysql_collations_available,
+        $mysql_default_collations, $mysql_collations_flat;
+    $sql = PMA_DRIZZLE
+        ? 'SELECT * FROM data_dictionary.CHARACTER_SETS'
+        : 'SELECT * FROM information_schema.CHARACTER_SETS';
+    $res = PMA_DBI_query($sql);
+
+    $mysql_charsets = array();
+    while ($row = PMA_DBI_fetch_assoc($res)) {
+        $mysql_charsets[] = $row['CHARACTER_SET_NAME'];
+        // never used
+        //$mysql_charsets_maxlen[$row['Charset']] = $row['Maxlen'];
+        $mysql_charsets_descriptions[$row['CHARACTER_SET_NAME']]
+            = $row['DESCRIPTION'];
+    }
+    PMA_DBI_free_result($res);
+
+    sort($mysql_charsets, SORT_STRING);
+
+    $mysql_collations = array_flip($mysql_charsets);
+    $mysql_default_collations = $mysql_collations_flat
+        = $mysql_charsets_available = $mysql_collations_available = array();
+
+    $sql = PMA_DRIZZLE
+        ? 'SELECT * FROM data_dictionary.COLLATIONS'
+        : 'SELECT * FROM information_schema.COLLATIONS';
+    $res = PMA_DBI_query($sql);
+    while ($row = PMA_DBI_fetch_assoc($res)) {
+        if (! is_array($mysql_collations[$row['CHARACTER_SET_NAME']])) {
+            $mysql_collations[$row['CHARACTER_SET_NAME']]
+                = array($row['COLLATION_NAME']);
+        } else {
+            $mysql_collations[$row['CHARACTER_SET_NAME']][] = $row['COLLATION_NAME'];
+        }
+        $mysql_collations_flat[] = $row['COLLATION_NAME'];
+        if ($row['IS_DEFAULT'] == 'Yes' || $row['IS_DEFAULT'] == '1') {
+            $mysql_default_collations[$row['CHARACTER_SET_NAME']]
+                = $row['COLLATION_NAME'];
+        }
+        //$mysql_collations_available[$row['Collation']]
+        //    = ! isset($row['Compiled']) || $row['Compiled'] == 'Yes';
+        $mysql_collations_available[$row['COLLATION_NAME']] = true;
+        $mysql_charsets_available[$row['CHARACTER_SET_NAME']]
+            = !empty($mysql_charsets_available[$row['CHARACTER_SET_NAME']])
+            || !empty($mysql_collations_available[$row['COLLATION_NAME']]);
+    }
+    PMA_DBI_free_result($res);
+    unset($res, $row);
+
+    if (PMA_DRIZZLE
+        && isset($mysql_collations['utf8_general_ci'])
+        && isset($mysql_collations['utf8'])
+    ) {
+        $mysql_collations['utf8'] = $mysql_collations['utf8_general_ci'];
+        $mysql_default_collations['utf8']
+            = $mysql_default_collations['utf8_general_ci'];
+        $mysql_charsets_available['utf8']
+            = $mysql_charsets_available['utf8_general_ci'];
+        unset(
+            $mysql_collations['utf8_general_ci'],
+            $mysql_default_collations['utf8_general_ci'],
+            $mysql_charsets_available['utf8_general_ci']
+        );
+    }
+
+    sort($mysql_collations_flat, SORT_STRING);
+    foreach ($mysql_collations AS $key => $value) {
+        sort($mysql_collations[$key], SORT_STRING);
+        reset($mysql_collations[$key]);
+    }
+    unset($key, $value);
+
+    PMA_Util::cacheSet('mysql_charsets', $GLOBALS['mysql_charsets'], true);
+    PMA_Util::cacheSet('mysql_charsets_descriptions', $GLOBALS['mysql_charsets_descriptions'], true);
+    PMA_Util::cacheSet('mysql_charsets_available', $GLOBALS['mysql_charsets_available'], true);
+    PMA_Util::cacheSet('mysql_collations', $GLOBALS['mysql_collations'], true);
+    PMA_Util::cacheSet('mysql_default_collations', $GLOBALS['mysql_default_collations'], true);
+    PMA_Util::cacheSet('mysql_collations_flat', $GLOBALS['mysql_collations_flat'], true);
+    PMA_Util::cacheSet('mysql_collations_available', $GLOBALS['mysql_collations_available'], true);
+} else {
+    $GLOBALS['mysql_charsets']              = PMA_Util::cacheGet('mysql_charsets', true);
+    $GLOBALS['mysql_charsets_descriptions'] = PMA_Util::cacheGet('mysql_charsets_descriptions', true);
+    $GLOBALS['mysql_charsets_available']    = PMA_Util::cacheGet('mysql_charsets_available', true);
+    $GLOBALS['mysql_collations']            = PMA_Util::cacheGet('mysql_collations', true);
+    $GLOBALS['mysql_default_collations']    = PMA_Util::cacheGet('mysql_default_collations', true);
+    $GLOBALS['mysql_collations_flat']       = PMA_Util::cacheGet('mysql_collations_flat', true);
+    $GLOBALS['mysql_collations_available']  = PMA_Util::cacheGet('mysql_collations_available', true);
+}
+
+define('PMA_CSDROPDOWN_COLLATION', 0);
+define('PMA_CSDROPDOWN_CHARSET',   1);
+
+function PMA_generateCharsetDropdownBox($type = PMA_CSDROPDOWN_COLLATION,
+    $name = null, $id = null, $default = null, $label = true, $indent = 0,
+    $submitOnChange = false, $displayUnavailable = false
+) {
+    global $mysql_charsets, $mysql_charsets_descriptions,
+        $mysql_charsets_available, $mysql_collations, $mysql_collations_available;
+
+    if (empty($name)) {
+        if ($type == PMA_CSDROPDOWN_COLLATION) {
+            $name = 'collation';
+        } else {
+            $name = 'character_set';
+        }
+    }
+
+    $return_str  = '<select lang="en" dir="ltr" name="'
+        . htmlspecialchars($name) . '"'
+        . (empty($id) ? '' : ' id="' . htmlspecialchars($id) . '"')
+        . ($submitOnChange ? ' class="autosubmit"' : '') . '>' . "\n";
+    if ($label) {
+        $return_str .= '<option value="">'
+            . ($type == PMA_CSDROPDOWN_COLLATION ? __('Collation') : __('Charset'))
+            . '</option>' . "\n";
+    }
+    $return_str .= '<option value=""></option>' . "\n";
+    foreach ($mysql_charsets as $current_charset) {
+        if (!$mysql_charsets_available[$current_charset]) {
+            continue;
+        }
+        $current_cs_descr
+            = empty($mysql_charsets_descriptions[$current_charset])
+            ? $current_charset
+            : $mysql_charsets_descriptions[$current_charset];
+
+        if ($type == PMA_CSDROPDOWN_COLLATION) {
+            $return_str .= '<optgroup label="' . $current_charset
+                . '" title="' . $current_cs_descr . '">' . "\n";
+            foreach ($mysql_collations[$current_charset] as $current_collation) {
+                if (!$mysql_collations_available[$current_collation]) {
+                    continue;
+                }
+                $return_str .= '<option value="' . $current_collation
+                    . '" title="' . PMA_getCollationDescr($current_collation) . '"'
+                    . ($default == $current_collation ? ' selected="selected"' : '')
+                    . '>'
+                    . $current_collation . '</option>' . "\n";
+            }
+            $return_str .= '</optgroup>' . "\n";
+        } else {
+            $return_str .= '<option value="' . $current_charset
+                . '" title="' . $current_cs_descr . '"'
+                . ($default == $current_charset ? ' selected="selected"' : '') . '>'
+                . $current_charset . '</option>' . "\n";
+        }
+    }
+    $return_str .= '</select>' . "\n";
+
+    return $return_str;
+}
+
+function PMA_generateCharsetQueryPart($collation)
+{
+    if (!PMA_DRIZZLE) {
+        list($charset) = explode('_', $collation);
+        return ' CHARACTER SET ' . $charset
+            . ($charset == $collation ? '' : ' COLLATE ' . $collation);
+    } else {
+        return ' COLLATE ' . $collation;
+    }
+}
+
+/**
+ * returns collation of given db
+ *
+ * @param string $db name of db
+ *
+ * @return string  collation of $db
+ */
+function PMA_getDbCollation($db)
+{
+    if (PMA_is_system_schema($db)) {
+        // We don't have to check the collation of the virtual
+        // information_schema database: We know it!
+        return 'utf8_general_ci';
+    }
+
+    if (! $GLOBALS['cfg']['Server']['DisableIS']) {
+        // this is slow with thousands of databases
+        $sql = PMA_DRIZZLE
+            ? 'SELECT DEFAULT_COLLATION_NAME FROM data_dictionary.SCHEMAS'
+            . ' WHERE SCHEMA_NAME = \'' . PMA_Util::sqlAddSlashes($db)
+            . '\' LIMIT 1'
+            : 'SELECT DEFAULT_COLLATION_NAME FROM information_schema.SCHEMATA'
+            . ' WHERE SCHEMA_NAME = \'' . PMA_Util::sqlAddSlashes($db)
+            . '\' LIMIT 1';
+        return PMA_DBI_fetch_value($sql);
+    } else {
+        PMA_DBI_select_db($db);
+        $return = PMA_DBI_fetch_value(
+            'SHOW VARIABLES LIKE \'collation_database\'', 0, 1
+        );
+        if ($db !== $GLOBALS['db']) {
+            PMA_DBI_select_db($GLOBALS['db']);
+        }
+        return $return;
+    }
+}
+
+/**
+ * returns default server collation from show variables
+ *
+ * @return string  $server_collation
+ */
+function PMA_getServerCollation()
+{
+    return PMA_DBI_fetch_value(
+        'SHOW VARIABLES LIKE \'collation_server\'', 0, 1
+    );
+}
+
+/**
+ * returns description for given collation
+ *
+ * @param string $collation MySQL collation string
+ *
+ * @return string  collation description
+ */
+function PMA_getCollationDescr($collation)
+{
+    if ($collation == 'binary') {
+        return __('Binary');
+    }
+    $parts = explode('_', $collation);
+    if (count($parts) == 1) {
+        $parts[1] = 'general';
+    } elseif ($parts[1] == 'ci' || $parts[1] == 'cs') {
+        $parts[2] = $parts[1];
+        $parts[1] = 'general';
+    }
+    $descr = '';
+    switch ($parts[1]) {
+    case 'bulgarian':
+        $descr = __('Bulgarian');
+        break;
+    case 'chinese':
+        if ($parts[0] == 'gb2312' || $parts[0] == 'gbk') {
+            $descr = __('Simplified Chinese');
+        } elseif ($parts[0] == 'big5') {
+            $descr = __('Traditional Chinese');
+        }
+        break;
+    case 'ci':
+        $descr = __('case-insensitive');
+        break;
+    case 'cs':
+        $descr = __('case-sensitive');
+        break;
+    case 'croatian':
+        $descr = __('Croatian');
+        break;
+    case 'czech':
+        $descr = __('Czech');
+        break;
+    case 'danish':
+        $descr = __('Danish');
+        break;
+    case 'english':
+        $descr = __('English');
+        break;
+    case 'esperanto':
+        $descr = __('Esperanto');
+        break;
+    case 'estonian':
+        $descr = __('Estonian');
+        break;
+    case 'german1':
+        $descr = __('German') . ' (' . __('dictionary') . ')';
+        break;
+    case 'german2':
+        $descr = __('German') . ' (' . __('phone book') . ')';
+        break;
+    case 'hungarian':
+        $descr = __('Hungarian');
+        break;
+    case 'icelandic':
+        $descr = __('Icelandic');
+        break;
+    case 'japanese':
+        $descr = __('Japanese');
+        break;
+    case 'latvian':
+        $descr = __('Latvian');
+        break;
+    case 'lithuanian':
+        $descr = __('Lithuanian');
+        break;
+    case 'korean':
+        $descr = __('Korean');
+        break;
+    case 'persian':
+        $descr = __('Persian');
+        break;
+    case 'polish':
+        $descr = __('Polish');
+        break;
+    case 'roman':
+        $descr = __('West European');
+        break;
+    case 'romanian':
+        $descr = __('Romanian');
+        break;
+    case 'slovak':
+        $descr = __('Slovak');
+        break;
+    case 'slovenian':
+        $descr = __('Slovenian');
+        break;
+    case 'spanish':
+        $descr = __('Spanish');
+        break;
+    case 'spanish2':
+        $descr = __('Traditional Spanish');
+        break;
+    case 'swedish':
+        $descr = __('Swedish');
+        break;
+    case 'thai':
+        $descr = __('Thai');
+        break;
+    case 'turkish':
+        $descr = __('Turkish');
+        break;
+    case 'ukrainian':
+        $descr = __('Ukrainian');
+        break;
+    case 'unicode':
+        $descr = __('Unicode') . ' (' . __('multilingual') . ')';
+        break;
+    case 'bin':
+        $is_bin = true;
+    case 'general':
+        switch ($parts[0]) {
+        // Unicode charsets
+        case 'ucs2':
+        case 'utf8':
+            $descr = __('Unicode') . ' (' . __('multilingual') . ')';
+            break;
+        // West European charsets
+        case 'ascii':
+        case 'cp850':
+        case 'dec8':
+        case 'hp8':
+        case 'latin1':
+        case 'macroman':
+            $descr = __('West European') . ' (' . __('multilingual') . ')';
+            break;
+        // Central European charsets
+        case 'cp1250':
+        case 'cp852':
+        case 'latin2':
+        case 'macce':
+            $descr = __('Central European') . ' (' . __('multilingual') . ')';
+            break;
+        // Russian charsets
+        case 'cp866':
+        case 'koi8r':
+            $descr = __('Russian');
+            break;
+        // Simplified Chinese charsets
+        case 'gb2312':
+        case 'gbk':
+            $descr = __('Simplified Chinese');
+            break;
+        // Japanese charsets
+        case 'sjis':
+        case 'ujis':
+        case 'cp932':
+        case 'eucjpms':
+            $descr = __('Japanese');
+            break;
+        // Baltic charsets
+        case 'cp1257':
+        case 'latin7':
+            $descr = __('Baltic') . ' (' . __('multilingual') . ')';
+            break;
+        // Other
+        case 'armscii8':
+        case 'armscii':
+            $descr = __('Armenian');
+            break;
+        case 'big5':
+            $descr = __('Traditional Chinese');
+            break;
+        case 'cp1251':
+            $descr = __('Cyrillic') . ' (' . __('multilingual') . ')';
+            break;
+        case 'cp1256':
+            $descr = __('Arabic');
+            break;
+        case 'euckr':
+            $descr = __('Korean');
+            break;
+        case 'hebrew':
+            $descr = __('Hebrew');
+            break;
+        case 'geostd8':
+            $descr = __('Georgian');
+            break;
+        case 'greek':
+            $descr = __('Greek');
+            break;
+        case 'keybcs2':
+            $descr = __('Czech-Slovak');
+            break;
+        case 'koi8u':
+            $descr = __('Ukrainian');
+            break;
+        case 'latin5':
+            $descr = __('Turkish');
+            break;
+        case 'swe7':
+            $descr = __('Swedish');
+            break;
+        case 'tis620':
+            $descr = __('Thai');
+            break;
+        default:
+            $descr = __('unknown');
+            break;
+        }
+        if (!empty($is_bin)) {
+            $descr .= ', ' . __('Binary');
+        }
+        break;
+    default: $descr = __('unknown');
+    }
+    if (!empty($parts[2])) {
+        if ($parts[2] == 'ci') {
+            $descr .= ', ' . __('case-insensitive');
+        } elseif ($parts[2] == 'cs') {
+            $descr .= ', ' . __('case-sensitive');
+        }
+    }
+
+    return $descr;
+}
+?>
diff --git a/phpmyadmin/libraries/navigation/Navigation.class.php b/phpmyadmin/libraries/navigation/Navigation.class.php
new file mode 100644
index 0000000..d140bbc
--- /dev/null
+++ b/phpmyadmin/libraries/navigation/Navigation.class.php
@@ -0,0 +1,77 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * This class is responsible for instanciating
+ * the various components of the navigation panel
+ *
+ * @package PhpMyAdmin-navigation
+ */
+if (! defined('PHPMYADMIN')) {
+    exit;
+}
+
+require_once 'libraries/navigation/NodeFactory.class.php';
+require_once 'libraries/navigation/NavigationHeader.class.php';
+require_once 'libraries/navigation/NavigationTree.class.php';
+
+/**
+ * The navigation panel - displays server, db and table selection tree
+ *
+ * @package PhpMyAdmin-Navigation
+ */
+class PMA_Navigation
+{
+    /**
+     * Initialises the class
+     *
+     * @return void
+     */
+    public function __construct()
+    {
+        if (empty($GLOBALS['token'])) {
+            $GLOBALS['token'] = $_SESSION[' PMA_token '];
+        }
+    }
+
+    /**
+     * Renders the navigation tree, or part of it
+     *
+     * @return string The navigation tree
+     */
+    public function getDisplay()
+    {
+        /* Init */
+        $retval = '';
+        if (! PMA_Response::getInstance()->isAjax()) {
+            $header = new PMA_NavigationHeader();
+            $retval = $header->getDisplay();
+        }
+        $tree = new PMA_NavigationTree();
+        if (! PMA_Response::getInstance()->isAjax()
+            || ! empty($_REQUEST['full'])
+            || ! empty($_REQUEST['reload'])
+        ) {
+            $treeRender = $tree->renderState();
+        } else {
+            $treeRender = $tree->renderPath();
+        }
+
+        if (! $treeRender) {
+            $retval .= PMA_Message::error(
+                __('An error has occured while loading the navigation tree')
+            )->getDisplay();
+        } else {
+            $retval .= $treeRender;
+        }
+
+        if (! PMA_Response::getInstance()->isAjax()) {
+            // closes the tags that were opened by the navigation header
+            $retval .= '</div>';
+            $retval .= '</div>';
+            $retval .= '</div>';
+        }
+
+        return $retval;
+    }
+}
+?>
diff --git a/phpmyadmin/libraries/navigation/NavigationHeader.class.php b/phpmyadmin/libraries/navigation/NavigationHeader.class.php
new file mode 100644
index 0000000..b1513d2
--- /dev/null
+++ b/phpmyadmin/libraries/navigation/NavigationHeader.class.php
@@ -0,0 +1,298 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * Header for the navigation panel
+ *
+ * @package PhpMyAdmin-Navigation
+ */
+if (! defined('PHPMYADMIN')) {
+    exit;
+}
+
+/**
+ * This class renders the logo, links, server selection and recent tables,
+ * which are then displayed at the top of the naviagtion panel
+ *
+ * @package PhpMyAdmin-Navigation
+ */
+class PMA_NavigationHeader
+{
+    /**
+     * Renders the navigation
+     *
+     * @return void
+     */
+    public function getDisplay()
+    {
+        if (empty($GLOBALS['url_query'])) {
+            $GLOBALS['url_query'] = PMA_generate_common_url();
+        }
+        $link_url = PMA_generate_common_url(
+            array(
+                'ajax_request' => true
+            )
+        );
+        $class = ' class="list_container';
+        if ($GLOBALS['cfg']['NavigationTreePointerEnable']) {
+            $class .= ' highlight';
+        }
+        $class .= '"';
+        $buffer  = '<div id="pma_navigation">';
+        $buffer .= '<div id="pma_navigation_resizer"></div>';
+        $buffer .= '<div id="pma_navigation_collapser"></div>';
+        $buffer .= '<div id="pma_navigation_content">';
+        $buffer .= sprintf(
+            '<a class="hide navigation_url" href="navigation.php%s"></a>',
+            $link_url
+        );
+        $buffer .= $this->_logo();
+        $buffer .= $this->_links();
+        $buffer .= $this->_serverChoice();
+        $buffer .= $this->_recent();
+        $buffer .= PMA_Util::getImage(
+            'ajax_clock_small.gif',
+            __('Loading'),
+            array('style' => 'visibility: hidden;', 'class' => 'throbber')
+        );
+        $buffer .= '<div id="pma_navigation_tree"' . $class . '>';
+        return $buffer;
+    }
+
+    /**
+     * Create the code for displaying the phpMyAdmin
+     * logo based on configuration settings
+     *
+     * @return string HTML code for the logo
+     */
+    private function _logo()
+    {
+        $retval = '<!-- LOGO START -->';
+        // display Logo, depending on $GLOBALS['cfg']['NavigationDisplayLogo']
+        if ($GLOBALS['cfg']['NavigationDisplayLogo']) {
+            $logo = 'phpMyAdmin';
+            if (@file_exists($GLOBALS['pmaThemeImage'] . 'logo_left.png')) {
+                $logo = '<img src="' . $GLOBALS['pmaThemeImage'] . 'logo_left.png" '
+                    . 'alt="' . $logo . '" id="imgpmalogo" />';
+            } elseif (@file_exists($GLOBALS['pmaThemeImage'] . 'pma_logo2.png')) {
+                $logo = '<img src="' . $GLOBALS['pmaThemeImage'] . 'pma_logo2.png" '
+                    . 'alt="' . $logo . '" id="imgpmalogo" />';
+            }
+            $retval .= '<div id="pmalogo">';
+            if ($GLOBALS['cfg']['NavigationLogoLink']) {
+                $retval .= '    <a href="' . htmlspecialchars(
+                    $GLOBALS['cfg']['NavigationLogoLink']
+                );
+                switch ($GLOBALS['cfg']['NavigationLogoLinkWindow']) {
+                case 'new':
+                    $retval .= '" target="_blank"';
+                    break;
+                case 'main':
+                    // do not add our parameters for an external link
+                    if (substr(strtolower($GLOBALS['cfg']['NavigationLogoLink']), 0, 4) !== '://') {
+                        $retval .= '?' . $GLOBALS['url_query'] . '"';
+                    } else {
+                        $retval .= '" target="_blank"';
+                    }
+                }
+                $retval .= '>';
+                $retval .= $logo;
+                $retval .= '</a>';
+            } else {
+                $retval .= $logo;
+            }
+            $retval .= '</div>';
+        }
+        $retval .= '<!-- LOGO END -->';
+        return $retval;
+    }
+
+    /**
+     * Renders a single link for the top of the navigation panel
+     *
+     * @param string $link        The url for the link
+     * @param bool   $showText    Whether to show the text or to
+     *                            only use it for title attributes
+     * @param string $text        The text to display and use for title attributes
+     * @param bool   $showIcon    Whether to show the icon
+     * @param string $icon        The filename of the icon to show
+     * @param string $linkId      Value to use for the ID attribute
+     * @param string $disableAjax Whether to disable ajax page loading for this link
+     * @param string $linkTarget  The name of the target frame for the link
+     *
+     * @return string HTML code for one link
+     */
+    private function _getLink(
+        $link,
+        $showText,
+        $text,
+        $showIcon,
+        $icon,
+        $linkId = '',
+        $disableAjax = false,
+        $linkTarget = ''
+    ) {
+        $retval = '<a href="' . $link . '"';
+        if (! empty($linkId)) {
+            $retval .= ' id="' . $linkId . '"';
+        }
+        if (! empty($linkTarget)) {
+            $retval .= ' target="' . $linkTarget . '"';
+        }
+        if ($disableAjax) {
+            $retval .= ' class="disableAjax"';
+        }
+        $retval .= ' title="' . $text . '">';
+        if ($showIcon) {
+            $retval .= PMA_Util::getImage(
+                $icon,
+                $text
+            );
+        }
+        if ($showText) {
+            $retval .= $text;
+        }
+        $retval .= '</a>';
+        if ($showText) {
+            $retval .= '<br />';
+        }
+        return $retval;
+    }
+
+    /**
+     * Creates the code for displaying the links
+     * at the top of the navigation frame
+     *
+     * @return string HTML code for the links
+     */
+    private function _links()
+    {
+        $iconicNav = $GLOBALS['cfg']['NavigationBarIconic'];
+        $showIcon = $iconicNav === true || $iconicNav === 'both';
+        $showText = $iconicNav === false || $iconicNav === 'both';
+
+        $retval  = '<!-- LINKS START -->';
+        $retval .= '<div id="leftframelinks">';
+        $retval .= $this->_getLink(
+            'index.php?' . PMA_generate_common_url(),
+            $showText,
+            __('Home'),
+            $showIcon,
+            'b_home.png'
+        );
+        // if we have chosen server
+        if ($GLOBALS['server'] != 0) {
+            // Logout for advanced authentication
+            if ($GLOBALS['cfg']['Server']['auth_type'] != 'config') {
+                $link  = 'index.php?' . $GLOBALS['url_query'];
+                $link .= '&old_usr=' . urlencode($GLOBALS['PHP_AUTH_USER']);
+                $retval .= $this->_getLink(
+                    $link,
+                    $showText,
+                    __('Log out'),
+                    $showIcon,
+                    's_loggoff.png',
+                    '',
+                    true
+                );
+            }
+            $link  = 'querywindow.php?';
+            $link .= PMA_generate_common_url($GLOBALS['db'], $GLOBALS['table']);
+            $link .= '&no_js=true';
+            $retval .= $this->_getLink(
+                $link,
+                $showText,
+                __('Query window'),
+                $showIcon,
+                'b_selboard.png',
+                'pma_open_querywindow',
+                true
+            );
+        }
+        $retval .= $this->_getLink(
+            PMA_Util::getDocuLink('index'),
+            $showText,
+            __('phpMyAdmin documentation'),
+            $showIcon,
+            'b_docs.png',
+            '',
+            false,
+            'documentation'
+        );
+        if ($showIcon) {
+            $retval .= PMA_Util::showMySQLDocu('', '', true);
+        }
+        if ($showText) {
+            // PMA_showMySQLDocu always spits out an icon,
+            // we just replace it with some perl regexp.
+            $link = preg_replace(
+                '/<img[^>]+>/i',
+                __('Documentation'),
+                PMA_Util::showMySQLDocu('', '', true)
+            );
+            $retval .= $link;
+            $retval .= '<br />';
+        }
+        $retval .= $this->_getLink(
+            '#',
+            $showText,
+            __('Reload navigation frame'),
+            $showIcon,
+            's_reload.png',
+            'pma_navigation_reload'
+        );
+        $retval .= '</div>';
+        $retval .= '<!-- LINKS ENDS -->';
+        return $retval;
+    }
+
+    /**
+     * Displays the MySQL servers choice form
+     *
+     * @return string HTML code for the MySQL servers choice
+     */
+    private function _serverChoice()
+    {
+        $retval = '';
+        if ($GLOBALS['cfg']['NavigationDisplayServers']
+            && count($GLOBALS['cfg']['Servers']) > 1
+        ) {
+            include_once './libraries/select_server.lib.php';
+            $retval .= '<!-- SERVER CHOICE START -->';
+            $retval .= '<div id="serverChoice">';
+            $retval .= PMA_selectServer(true, true);
+            $retval .= '</div>';
+            $retval .= '<!-- SERVER CHOICE END -->';
+        }
+        return $retval;
+    }
+
+    /**
+     * Displays a drop-down choice of most recently used tables
+     *
+     * @return string HTML code for the Recent tables
+     */
+    private function _recent()
+    {
+        $retval = '';
+        // display recently used tables
+        if ($GLOBALS['cfg']['NumRecentTables'] > 0) {
+            $retval .= '<!-- RECENT START -->';
+            $retval .= '<div id="recentTableList">';
+            $retval .= '<form method="post" ';
+            $retval .= 'action="' . $GLOBALS['cfg']['DefaultTabTable'] . '">';
+            $retval .= PMA_generate_common_hidden_inputs(
+                array(
+                    'db' => '',
+                    'table' => '',
+                    'server' => $GLOBALS['server']
+                )
+            );
+            $retval .= PMA_RecentTable::getInstance()->getHtmlSelect();
+            $retval .= '</form>';
+            $retval .= '</div>';
+            $retval .= '<!-- RECENT END -->';
+        }
+        return $retval;
+    }
+}
+?>
diff --git a/phpmyadmin/libraries/navigation/NavigationTree.class.php b/phpmyadmin/libraries/navigation/NavigationTree.class.php
new file mode 100644
index 0000000..d92c694
--- /dev/null
+++ b/phpmyadmin/libraries/navigation/NavigationTree.class.php
@@ -0,0 +1,1148 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * Functionality for the navigation tree
+ *
+ * @package PhpMyAdmin-Navigation
+ */
+if (! defined('PHPMYADMIN')) {
+    exit;
+}
+
+/**
+ * Displays a collapsible of database objects in the navigation frame
+ *
+ * @package PhpMyAdmin-Navigation
+ */
+class PMA_NavigationTree
+{
+    /**
+     * @var Node Reference to the root node of the tree
+     */
+    private $_tree;
+
+    /**
+     * @var array The actual paths to all expanded nodes in the tree
+     *            This does not include nodes created after the grouping
+     *            of nodes has been performed
+     */
+    private $_aPath = array();
+
+    /**
+     * @var array The virtual paths to all expanded nodes in the tree
+     *            This includes nodes created after the grouping of
+     *            nodes has been performed
+     */
+    private $_vPath = array();
+
+    /**
+     * @var int Position in the list of databases,
+     *          used for pagination
+     */
+    private $_pos;
+
+    /**
+     * @var int The names of the type of items that are being paginated on
+     *          the second level of the navigation tree. These may be
+     *          tables, views, functions, procedures or events.
+     */
+    private $_pos2_name = array();
+
+    /**
+     * @var int The positions of nodes in the lists of tables, views,
+     *          routines or events used for pagination
+     */
+    private $_pos2_value = array();
+
+    /**
+     * @var int The names of the type of items that are being paginated
+     *          on the second level of the navigation tree.
+     *          These may be columns or indexes
+     */
+    private $_pos3_name = array();
+
+    /**
+     * @var int The positions of nodes in the lists of columns or indexes
+     *          used for pagination
+     */
+    private $_pos3_value = array();
+
+    /**
+     * @var string The search clause to use in SQL queries for
+     *             fetching databases
+     *             Used by the asynchronous fast filter
+     */
+    private $_searchClause = '';
+
+    /**
+     * @var string The search clause to use in SQL queries for
+     *             fetching nodes
+     *             Used by the asynchronous fast filter
+     */
+    private $_searchClause2 = '';
+
+    /**
+     * Initialises the class
+     *
+     * @return void
+     */
+    public function __construct()
+    {
+        // Save the position at which we are in the database list
+        if (isset($_REQUEST['pos'])) {
+            $this->_pos = (int) $_REQUEST['pos'];
+        }
+        if (! isset($this->_pos)) {
+            $this->_pos = $this->_getNavigationDbPos();
+        }
+        // Get the active node
+        if (isset($_REQUEST['aPath'])) {
+            $this->_aPath[0]      = $this->_parsePath($_REQUEST['aPath']);
+            $this->_pos2_name[0]  = $_REQUEST['pos2_name'];
+            $this->_pos2_value[0] = $_REQUEST['pos2_value'];
+            if (isset($_REQUEST['pos3_name'])) {
+                $this->_pos3_name[0]  = $_REQUEST['pos3_name'];
+                $this->_pos3_value[0] = $_REQUEST['pos3_value'];
+            }
+        } else if (isset($_REQUEST['n0_aPath'])) {
+            $count = 0;
+            while (isset($_REQUEST['n' . $count . '_aPath'])) {
+                $this->_aPath[$count] = $this->_parsePath(
+                    $_REQUEST['n' . $count . '_aPath']
+                );
+                $index = 'n' . $count . '_pos2_';
+                $this->_pos2_name[$count]  = $_REQUEST[$index . 'name'];
+                $this->_pos2_value[$count] = $_REQUEST[$index . 'value'];
+                $index = 'n' . $count . '_pos3_';
+                if (isset($_REQUEST[$index])) {
+                    $this->_pos3_name[$count]  = $_REQUEST[$index . 'name'];
+                    $this->_pos3_value[$count] = $_REQUEST[$index . 'value'];
+                }
+                $count++;
+            }
+        }
+        if (isset($_REQUEST['vPath'])) {
+            $this->_vPath[0] = $this->_parsePath($_REQUEST['vPath']);
+        } else if (isset($_REQUEST['n0_vPath'])) {
+            $count = 0;
+            while (isset($_REQUEST['n' . $count . '_vPath'])) {
+                $this->_vPath[$count] = $this->_parsePath(
+                    $_REQUEST['n' . $count . '_vPath']
+                );
+                $count++;
+            }
+        }
+        if (isset($_REQUEST['searchClause'])) {
+            $this->_searchClause = $_REQUEST['searchClause'];
+        }
+        if (isset($_REQUEST['searchClause2'])) {
+            $this->_searchClause2 = $_REQUEST['searchClause2'];
+        }
+        // Initialise the tree by creating a root node
+        $node = PMA_NodeFactory::getInstance('Node', 'root', Node::CONTAINER);
+        $this->_tree = $node;
+        if ($GLOBALS['cfg']['NavigationTreeEnableGrouping']) {
+            $this->_tree->separator = $GLOBALS['cfg']['NavigationTreeDbSeparator'];
+            $this->_tree->separator_depth = 10000;
+        }
+    }
+
+    /**
+     * Returns the database position for the page selector
+     *
+     * @return int
+     */
+    private function _getNavigationDbPos()
+    {
+        $retval = 0;
+        if (! empty($GLOBALS['db'])) {
+            $query  = "SELECT (COUNT(`SCHEMA_NAME`) DIV %d) * %d ";
+            $query .= "FROM `INFORMATION_SCHEMA`.`SCHEMATA` ";
+            $query .= "WHERE `SCHEMA_NAME` < '%s' ";
+            $query .= "ORDER BY `SCHEMA_NAME` ASC";
+            $retval = PMA_DBI_fetch_value(
+                sprintf(
+                    $query,
+                    (int)$GLOBALS['cfg']['MaxNavigationItems'],
+                    (int)$GLOBALS['cfg']['MaxNavigationItems'],
+                    PMA_Util::sqlAddSlashes($GLOBALS['db'])
+                )
+            );
+        }
+        return $retval;
+    }
+
+    /**
+     * Converts an encoded path to a node in string format to an array
+     *
+     * @param string $string The path to parse
+     *
+     * @return array
+     */
+    private function _parsePath($string)
+    {
+        $path = explode('.', $string);
+        foreach ($path as $key => $value) {
+            $path[$key] = base64_decode($value);
+        }
+        return $path;
+    }
+
+    /**
+     * Generates the tree structure so that it can be rendered later
+     *
+     * @return Node|false The active node or false in case of failure
+     */
+    private function _buildPath()
+    {
+        $retval = $this->_tree;
+
+        // Add all databases unconditionally
+        $data = $this->_tree->getData(
+            'databases',
+            $this->_pos,
+            $this->_searchClause
+        );
+        foreach ($data as $db) {
+            $node = PMA_NodeFactory::getInstance('Node_Database', $db);
+            $this->_tree->addChild($node);
+        }
+
+        // Whether build other parts of the tree depends
+        // on whether we have any paths in $this->_aPath
+        foreach ($this->_aPath as $key => $path) {
+            $retval = $this->_buildPathPart(
+                $path,
+                $this->_pos2_name[$key],
+                $this->_pos2_value[$key],
+                isset($this->_pos3_name[$key]) ? $this->_pos3_name[$key] : '',
+                isset($this->_pos3_value[$key]) ? $this->_pos3_value[$key] : ''
+            );
+        }
+        return $retval;
+    }
+
+    /**
+     * Builds a branch of the tree
+     *
+     * @param array  $path  A paths pointing to the branch
+     *                      of the tree that needs to be built
+     * @param string $type2 The type of item being paginated on
+     *                      the second level of the tree
+     * @param int    $pos2  The position for the pagination of
+     *                      the branch at the second level of the tree
+     * @param string $type3 The type of item being paginated on
+     *                      the third level of the tree
+     * @param int    $pos3  The position for the pagination of
+     *                      the branch at the third level of the tree
+     *
+     * @return Node|false The active node or false in case of failure
+     */
+    private function _buildPathPart($path, $type2, $pos2, $type3, $pos3)
+    {
+        $retval = true;
+        if (count($path) > 1) {
+            array_shift($path); // remove 'root'
+            $db = $this->_tree->getChild($path[0]);
+            $retval = $db;
+
+            if ($db === false) {
+                return false;
+            }
+
+            $containers = $this->_addDbContainers($db, $type2, $pos2);
+
+            array_shift($path); // remove db
+
+            if ((count($path) > 0
+                && array_key_exists($path[0], $containers))
+                || count($containers) == 1
+            ) {
+                if (count($containers) == 1) {
+                    $container = array_shift($containers);
+                } else {
+                    $container = $db->getChild($path[0], true);
+                    if ($container === false) {
+                        return false;
+                    }
+                }
+                $retval = $container;
+
+                if (count($container->children) <= 1) {
+                    $dbData = $db->getData(
+                        $container->real_name,
+                        $pos2,
+                        $this->_searchClause2
+                    );
+                    foreach ($dbData as $item) {
+                        switch ($container->real_name) {
+                        case 'events':
+                            $node = PMA_NodeFactory::getInstance(
+                                'Node_Event',
+                                $item
+                            );
+                            break;
+                        case 'functions':
+                            $node = PMA_NodeFactory::getInstance(
+                                'Node_Function',
+                                $item
+                            );
+                            break;
+                        case 'procedures':
+                            $node = PMA_NodeFactory::getInstance(
+                                'Node_Procedure',
+                                $item
+                            );
+                            break;
+                        case 'tables':
+                            $node = PMA_NodeFactory::getInstance(
+                                'Node_Table',
+                                $item
+                            );
+                            break;
+                        case 'views':
+                            $node = PMA_NodeFactory::getInstance(
+                                'Node_View',
+                                $item
+                            );
+                            break;
+                        default:
+                            break;
+                        }
+                        if (isset($node)) {
+                            if ($type2 == $container->real_name) {
+                                $node->pos2 = $pos2;
+                            }
+                            $container->addChild($node);
+                        }
+                    }
+                }
+                if (count($path) > 1 && $path[0] != 'tables') {
+                    $retval = false;
+                } else {
+                    array_shift($path); // remove container
+                    if (count($path) > 0) {
+                        $table = $container->getChild($path[0], true);
+                        if ($table === false) {
+                            return false;
+                        }
+                        $retval = $table;
+                        $containers = $this->_addTableContainers(
+                            $table,
+                            $pos2,
+                            $type3,
+                            $pos3
+                        );
+                        array_shift($path); // remove table
+                        if (count($path) > 0
+                            && array_key_exists($path[0], $containers)
+                        ) {
+                            $container = $table->getChild($path[0], true);
+                            $retval = $container;
+                            $tableData = $table->getData(
+                                $container->real_name,
+                                $pos3
+                            );
+                            foreach ($tableData as $item) {
+                                switch ($container->real_name) {
+                                case 'indexes':
+                                    $node = PMA_NodeFactory::getInstance(
+                                        'Node_Index',
+                                        $item
+                                    );
+                                    break;
+                                case 'columns':
+                                    $node = PMA_NodeFactory::getInstance(
+                                        'Node_Column',
+                                        $item
+                                    );
+                                    break;
+                                case 'triggers':
+                                    $node = PMA_NodeFactory::getInstance(
+                                        'Node_Trigger',
+                                        $item
+                                    );
+                                    break;
+                                default:
+                                    break;
+                                }
+                                if (isset($node)) {
+                                    $node->pos2 = $container->parent->pos2;
+                                    if ($type3 == $container->real_name) {
+                                        $node->pos3 = $pos3;
+                                    }
+                                    $container->addChild($node);
+                                }
+                            }
+                        }
+                    }
+                }
+            }
+        }
+        return $retval;
+    }
+
+    /**
+     * Adds containers to a node that is a table
+     *
+     * References to existing children are returned
+     * if this function is called twice on the same node
+     *
+     * @param Node   $table The table node, new containers will be
+     *                      attached to this node
+     * @param int    $pos2  The position for the pagination of
+     *                      the branch at the second level of the tree
+     * @param string $type3 The type of item being paginated on
+     *                      the third level of the tree
+     * @param int    $pos3  The position for the pagination of
+     *                      the branch at the third level of the tree
+     *
+     * @return array An array of new nodes
+     */
+    private function _addTableContainers($table, $pos2, $type3, $pos3)
+    {
+        $retval = array();
+        if ($table->hasChildren(true) == 0) {
+            if ($table->getPresence('columns')) {
+                $retval['columns'] = PMA_NodeFactory::getInstance(
+                    'Node_Column_Container'
+                );
+            }
+            if ($table->getPresence('indexes')) {
+                $retval['indexes'] = PMA_NodeFactory::getInstance(
+                    'Node_Index_Container'
+                );
+            }
+            if ($table->getPresence('triggers')) {
+                $retval['triggers'] = PMA_NodeFactory::getInstance(
+                    'Node_Trigger_Container'
+                );
+            }
+            // Add all new Nodes to the tree
+            foreach ($retval as $node) {
+                $node->pos2 = $pos2;
+                if ($type3 == $node->real_name) {
+                    $node->pos3 = $pos3;
+                }
+                $table->addChild($node);
+            }
+        } else {
+            foreach ($table->children as $node) {
+                if ($type3 == $node->real_name) {
+                    $node->pos3 = $pos3;
+                }
+                $retval[$node->real_name] = $node;
+            }
+        }
+        return $retval;
+    }
+
+    /**
+     * Adds containers to a node that is a database
+     *
+     * References to existing children are returned
+     * if this function is called twice on the same node
+     *
+     * @param Node   $db   The database node, new containers will be
+     *                     attached to this node
+     * @param string $type The type of item being paginated on
+     *                     the second level of the tree
+     * @param int    $pos2 The position for the pagination of
+     *                     the branch at the second level of the tree
+     *
+     * @return array An array of new nodes
+     */
+    private function _addDbContainers($db, $type, $pos2)
+    {
+        $retval = array();
+        if ($db->hasChildren(true) == 0) {
+            if ($db->getPresence('tables')) {
+                $retval['tables'] = PMA_NodeFactory::getInstance(
+                    'Node_Table_Container'
+                );
+            }
+            if ($db->getPresence('views')) {
+                $retval['views'] = PMA_NodeFactory::getInstance(
+                    'Node_View_Container'
+                );
+            }
+            if ($db->getPresence('functions')) {
+                $retval['functions'] = PMA_NodeFactory::getInstance(
+                    'Node_Function_Container'
+                );
+            }
+            if ($db->getPresence('procedures')) {
+                $retval['procedures'] = PMA_NodeFactory::getInstance(
+                    'Node_Procedure_Container'
+                );
+            }
+            if ($db->getPresence('events')) {
+                $retval['events'] = PMA_NodeFactory::getInstance(
+                    'Node_Event_Container'
+                );
+            }
+            // Add all new Nodes to the tree
+            foreach ($retval as $node) {
+                if ($type == $node->real_name) {
+                    $node->pos2 = $pos2;
+                }
+                $db->addChild($node);
+            }
+        } else {
+            foreach ($db->children as $node) {
+                if ($type == $node->real_name) {
+                    $node->pos2 = $pos2;
+                }
+                $retval[$node->real_name] = $node;
+            }
+        }
+        return $retval;
+    }
+
+    /**
+     * Recursively groups tree nodes given a separator
+     *
+     * @param mixed $node The node to group or null
+     *                    to group the whole tree. If
+     *                    passed as an argument, $node
+     *                    must be of type CONTAINER
+     *
+     * @return void
+     */
+    public function groupTree($node = null)
+    {
+        if (! isset($node)) {
+            $node = $this->_tree;
+        }
+        $this->groupNode($node);
+        foreach ($node->children as $child) {
+            $this->groupTree($child);
+        }
+    }
+
+    /**
+     * Recursively groups tree nodes given a sperarator
+     *
+     * @param Node $node The node to group
+     *
+     * @return void
+     */
+    public function groupNode($node)
+    {
+        if ($node->type == Node::CONTAINER) {
+            $separators = array();
+            if (is_array($node->separator)) {
+                $separators = $node->separator;
+            } else if (strlen($node->separator)) {
+                $separators[] = $node->separator;
+            }
+            $prefixes = array();
+            if ($node->separator_depth > 0) {
+                foreach ($node->children as $child) {
+                    $prefix_pos = false;
+                    foreach ($separators as $separator) {
+                        $sep_pos = strpos($child->name, $separator);
+                        if ($sep_pos != false
+                            && $sep_pos != strlen($child->name)
+                            && $sep_pos != 0
+                            && ($prefix_pos == false || $sep_pos < $prefix_pos)
+                        ) {
+                            $prefix_pos = $sep_pos;
+                        }
+                    }
+                    if ($prefix_pos !== false) {
+                        $prefix = substr($child->name, 0, $prefix_pos);
+                        if (! isset($prefixes[$prefix])) {
+                            $prefixes[$prefix] = 1;
+                        } else {
+                            $prefixes[$prefix]++;
+                        }
+                    }
+                }
+            }
+            foreach ($prefixes as $key => $value) {
+                if ($value == 1) {
+                    unset($prefixes[$key]);
+                }
+            }
+            if (count($prefixes)) {
+                $groups = array();
+                foreach ($prefixes as $key => $value) {
+                    $groups[$key] = new Node(
+                        $key,
+                        Node::CONTAINER,
+                        true
+                    );
+                    $groups[$key]->separator = $node->separator;
+                    $groups[$key]->separator_depth = $node->separator_depth - 1;
+                    $groups[$key]->icon = '';
+                    if ($GLOBALS['cfg']['NavigationBarIconic']) {
+                        $groups[$key]->icon = PMA_Util::getImage(
+                            'b_group.png'
+                        );
+                    }
+                    $groups[$key]->pos2 = $node->pos2;
+                    $groups[$key]->pos3 = $node->pos3;
+                    $node->addChild($groups[$key]);
+                    foreach ($separators as $separator) {
+                        // FIXME: this could be more efficient
+                        foreach ($node->children as $child) {
+                            $name_substring = substr(
+                                $child->name, 0, strlen($key) + strlen($separator)
+                            );
+                            if ($name_substring == $key . $separator
+                                && $child->type == Node::OBJECT
+                            ) {
+                                $class = get_class($child);
+                                $new_child = PMA_NodeFactory::getInstance(
+                                    $class,
+                                    substr(
+                                        $child->name,
+                                        strlen($key) + strlen($separator)
+                                    )
+                                );
+                                $new_child->real_name = $child->real_name;
+                                $new_child->icon = $child->icon;
+                                $new_child->links = $child->links;
+                                $new_child->pos2 = $child->pos2;
+                                $new_child->pos3 = $child->pos3;
+                                $groups[$key]->addChild($new_child);
+                                foreach ($child->children as $elm) {
+                                    $new_child->addChild($elm);
+                                }
+                                $node->removeChild($child->name);
+                            }
+                        }
+                    }
+                }
+                foreach ($prefixes as $key => $value) {
+                    $this->groupNode($groups[$key]);
+                    $groups[$key]->classes = "navGroup";
+                }
+            }
+        }
+    }
+
+    /**
+     * Renders a state of the tree, used in light mode when
+     * either JavaScript and/or Ajax are disabled
+     *
+     * @return string HTML code for the navigation tree
+     */
+    public function renderState()
+    {
+        $this->_buildPath();
+        $retval  = $this->_fastFilterHtml($this->_tree);
+        $retval .= $this->_getPageSelector($this->_tree);
+        $this->groupTree();
+        $retval .= "<div><ul>";
+        $children = $this->_tree->children;
+        usort($children, array('PMA_NavigationTree', 'sortNode'));
+        $this->_setVisibility();
+        for ($i=0; $i<count($children); $i++) {
+            if ($i == 0) {
+                $retval .= $this->_renderNode($children[0], true, 'first');
+            } else if ($i + 1 != count($children)) {
+                $retval .= $this->_renderNode($children[$i], true);
+            } else {
+                $retval .= $this->_renderNode($children[$i], true, 'last');
+            }
+        }
+        $retval .= "</ul></div>";
+        return $retval;
+    }
+
+    /**
+     * Renders a part of the tree, used for Ajax
+     * requests in light mode
+     *
+     * @return string HTML code for the navigation tree
+     */
+    public function renderPath()
+    {
+        $node = $this->_buildPath();
+        if ($node === false) {
+            $retval = false;
+        } else {
+            $this->groupTree();
+            $retval  = "<div class='list_container' style='display: none;'>";
+            $retval .= "<ul>";
+            $retval .= $this->_fastFilterHtml($node);
+            $retval .= $this->_getPageSelector($node);
+            $children = $node->children;
+            usort($children, array('PMA_NavigationTree', 'sortNode'));
+            for ($i=0; $i<count($children); $i++) {
+                if ($i + 1 != count($children)) {
+                    $retval .= $this->_renderNode($children[$i], true);
+                } else {
+                    $retval .= $this->_renderNode($children[$i], true, 'last');
+                }
+            }
+            $retval .= "</ul>";
+            $retval .= "</div>";
+        }
+
+        if (! empty($this->_searchClause) || ! empty($this->_searchClause2)) {
+            if (! empty($this->_searchClause2)) {
+                $results = $node->realParent()->getPresence(
+                    $node->real_name,
+                    $this->_searchClause2
+                );
+            } else {
+                $results = $this->_tree->getPresence(
+                    'databases',
+                    $this->_searchClause
+                );
+            }
+
+            $clientResults = 0;
+            if (! empty($_REQUEST['results'])) {
+                $clientResults = (int)$_REQUEST['results'];
+            }
+            $otherResults = $results - $clientResults;
+            if ($otherResults < 1) {
+                $otherResults = '';
+            } else {
+                $otherResults = sprintf(
+                    _ngettext(
+                        '%s other result found',
+                        '%s other results found',
+                        $otherResults
+                    ),
+                    $otherResults
+                );
+            }
+            PMA_Response::getInstance()->addJSON(
+                'results',
+                $otherResults
+            );
+        }
+        return $retval;
+    }
+
+    /**
+     * Renders the parameters that are required on the client
+     * side to know which page(s) we will be requesting data from
+     *
+     * @param Node $node The node to create the pagination parameters for
+     *
+     * @return string
+     */
+    private function _getPaginationParamsHtml($node)
+    {
+        $retval = '';
+        $paths  = $node->getPaths();
+        if (isset($paths['aPath_clean'][2])) {
+            $retval .= "<span class='hide pos2_name'>";
+            $retval .= $paths['aPath_clean'][2];
+            $retval .= "</span>";
+            $retval .= "<span class='hide pos2_value'>";
+            $retval .= $node->pos2;
+            $retval .= "</span>";
+        }
+        if (isset($paths['aPath_clean'][4])) {
+            $retval .= "<span class='hide pos3_name'>";
+            $retval .= $paths['aPath_clean'][4];
+            $retval .= "</span>";
+            $retval .= "<span class='hide pos3_value'>";
+            $retval .= $node->pos3;
+            $retval .= "</span>";
+        }
+        return $retval;
+    }
+
+    /**
+     * Renders a single node or a branch of the tree
+     *
+     * @param Node     $node      The node to render
+     * @param int|bool $recursive Bool: Whether to render a single node or a branch
+     *                            Int: How many levels deep to render
+     * @param string   $class     An additional class for the list item
+     *
+     * @return string HTML code for the tree node or branch
+     */
+    private function _renderNode($node, $recursive = -1, $class = '')
+    {
+        $retval = '';
+        $paths  = $node->getPaths();
+        if ($node->hasSiblings()
+            || isset($_REQUEST['results'])
+            || $node->realParent() === false
+        ) {
+            if (   $node->type == Node::CONTAINER
+                && count($node->children) == 0
+                && $GLOBALS['is_ajax_request'] != true
+            ) {
+                return '';
+            }
+            $liClass = '';
+            if ($class || $node->classes) {
+                $liClass = " class='" . trim($class . ' ' . $node->classes) . "'";
+            }
+            $retval .= "<li$liClass>";
+            $sterile = array(
+                'events',
+                'triggers',
+                'functions',
+                'procedures',
+                'views',
+                'columns',
+                'indexes'
+            );
+            $parentName = '';
+            $parents = $node->parents(false, true);
+            if (count($parents)) {
+                $parentName = $parents[0]->real_name;
+            }
+            if ($node->is_group
+                || (! in_array($parentName, $sterile) && ! $node->isNew)
+            ) {
+                $loaded = '';
+                if ($node->is_group) {
+                    $loaded = ' loaded';
+                }
+                $container = '';
+                if ($node->type == Node::CONTAINER) {
+                    $container = ' container';
+                }
+                $retval .= "<div class='block'>";
+                $iClass = '';
+                if ($class == 'first') {
+                    $iClass = " class='first'";
+                }
+                $retval .= "<i$iClass></i>";
+                if (strpos($class, 'last') === false) {
+                    $retval .= "<b></b>";
+                }
+                $icon  = PMA_Util::getImage('b_plus.png');
+                $match = 1;
+                foreach ($this->_aPath as $path) {
+                    $match = 1;
+                    foreach ($paths['aPath_clean'] as $key => $part) {
+                        if (! isset($path[$key]) || $part != $path[$key]) {
+                            $match = 0;
+                            break;
+                        }
+                    }
+                    if ($match) {
+                        $loaded = ' loaded';
+                        if (! $node->is_group) {
+                            $icon = PMA_Util::getImage(
+                                'b_minus.png'
+                            );
+                        }
+                        break;
+                    }
+                }
+
+                foreach ($this->_vPath as $path) {
+                    $match = 1;
+                    foreach ($paths['vPath_clean'] as $key => $part) {
+                        if ((! isset($path[$key]) || $part != $path[$key])) {
+                            $match = 0;
+                            break;
+                        }
+                    }
+                    if ($match) {
+                        $loaded = ' loaded';
+                        $icon  = PMA_Util::getImage('b_minus.png');
+                        break;
+                    }
+                }
+
+                $retval .= "<a class='expander$loaded$container'";
+                $retval .= " href='#'>";
+                $retval .= "<span class='hide aPath'>";
+                $retval .= $paths['aPath'];
+                $retval .= "</span>";
+                $retval .= "<span class='hide vPath'>";
+                $retval .= $paths['vPath'];
+                $retval .= "</span>";
+                $retval .= "<span class='hide pos'>";
+                $retval .= $this->_pos;
+                $retval .= "</span>";
+                $retval .= $this->_getPaginationParamsHtml($node);
+                $retval .= $icon;
+
+                $retval .= "</a>";
+                $retval .= "</div>";
+            } else {
+                $retval .= "<div class='block'>";
+                $iClass  = '';
+                if ($class == 'first') {
+                    $iClass = " class='first'";
+                }
+                $retval .= "<i$iClass></i>";
+                $retval .= $this->_getPaginationParamsHtml($node);
+                $retval .= "</div>";
+            }
+
+            $linkClass = '';
+            $haveAjax = array(
+                'functions',
+                'procedures',
+                'events',
+                'triggers',
+                'indexes'
+            );
+            $parent = $node->parents(false, true);
+            if ($parent[0]->type == Node::CONTAINER
+                && (in_array($parent[0]->real_name, $haveAjax)
+                    || ($parent[0]->real_name == 'views'
+                        && $node->isNew == true
+                    )
+                )
+            ) {
+                $linkClass = ' class="ajax"';
+            }
+
+            if ($node->type == Node::CONTAINER) {
+                $retval .= "<i>";
+            }
+            if ($GLOBALS['cfg']['NavigationBarIconic']) {
+                $retval .= "<div class='block'>";
+                if (isset($node->links['icon'])) {
+                    $args = array();
+                    foreach ($node->parents(true) as $parent) {
+                        $args[] = urlencode($parent->real_name);
+                    }
+                    $link = vsprintf($node->links['icon'], $args);
+                    $retval .= "<a$linkClass href='$link'>{$node->icon}</a>";
+                } else {
+                    $retval .= "<u>{$node->icon}</u>";
+                }
+                $retval .= "</div>";
+            }
+            if (isset($node->links['text'])) {
+                $args = array();
+                foreach ($node->parents(true) as $parent) {
+                    $args[] = urlencode($parent->real_name);
+                }
+                $link = vsprintf($node->links['text'], $args);
+                if ($node->type == Node::CONTAINER) {
+                    $retval .= "<a href='$link'>";
+                    $retval .= htmlspecialchars($node->name);
+                    $retval .= "</a>";
+                } else {
+                    if ($GLOBALS['cfg']['ShowTooltip']) {
+                        $title = $node->getComment();
+                        if ($title) {
+                            $title = ' title="'
+                                . htmlentities($title, ENT_QUOTES, 'UTF-8') 
+                                . '"';
+                        }
+                    } else {
+                        $title = '';
+                    }
+                    $retval .= "<a$linkClass$title href='$link'>";
+                    $retval .= htmlspecialchars($node->real_name);
+                    $retval .= "</a>";
+                }
+            } else {
+                $retval .= "{$node->name}";
+            }
+            if ($node->type == Node::CONTAINER) {
+                $retval .= "</i>";
+            }
+            $wrap = true;
+        } else {
+            $node->visible = true;
+            $wrap = false;
+            $retval .= $this->_getPaginationParamsHtml($node);
+        }
+
+        if ($recursive) {
+            $hide = '';
+            if ($node->visible == false) {
+                $hide = " style='display: none;'";
+            }
+            $children = $node->children;
+            usort($children, array('PMA_NavigationTree', 'sortNode'));
+            $buffer = '';
+            for ($i=0; $i<count($children); $i++) {
+                if ($i + 1 != count($children)) {
+                    $buffer .= $this->_renderNode(
+                        $children[$i],
+                        true,
+                        $children[$i]->classes
+                    );
+                } else {
+                    $buffer .= $this->_renderNode(
+                        $children[$i],
+                        true,
+                        $children[$i]->classes . ' last'
+                    );
+                }
+            }
+            if (! empty($buffer)) {
+                if ($wrap) {
+                    $retval .= "<div$hide class='list_container'><ul>";
+                }
+                $retval .= $this->_fastFilterHtml($node);
+                $retval .= $this->_getPageSelector($node);
+                $retval .= $buffer;
+                if ($wrap) {
+                    $retval .= "</ul></div>";
+                }
+            }
+        }
+        if ($node->hasSiblings() || isset($_REQUEST['results'])) {
+            $retval .= "</li>";
+        }
+        return $retval;
+    }
+
+    /**
+     * Makes some nodes visible based on the which node is active
+     *
+     * @return nothing
+     */
+    private function _setVisibility()
+    {
+        foreach ($this->_vPath as $path) {
+            $node = $this->_tree;
+            foreach ($path as $value) {
+                $child = $node->getChild($value);
+                if ($child !== false) {
+                    $child->visible = true;
+                    $node = $child;
+                }
+            }
+        }
+    }
+
+    /**
+     * Generates the HTML code for displaying the fast filter for tables
+     *
+     * @param Node $node The node for which to generate the fast filter html
+     *
+     * @return string LI element used for the fast filter
+     */
+    private function _fastFilterHtml($node)
+    {
+        $retval = '';
+        if ($node === $this->_tree
+            && $this->_tree->getPresence() >= (int)$GLOBALS['cfg']['NavigationTreeDisplayDbFilterMinimum']
+        ) {
+            $url_params = array(
+                'pos' => 0
+            );
+            $retval .= "<ul>";
+            $retval .= "<li class='fast_filter db_fast_filter'>";
+            $retval .= "<form class='ajax fast_filter'>";
+            $retval .= PMA_getHiddenFields($url_params);
+            $retval .= "<input class='searchClause' name='searchClause'";
+            $retval .= " value='" . __('filter databases by name') . "' />";
+            $retval .= "<span title='" . __('Clear Fast Filter') . "'>X</span>";
+            $retval .= "</form>";
+            $retval .= "</li>";
+            $retval .= "</ul>";
+        } else if (($node->type == Node::CONTAINER
+            && (   $node->real_name == 'tables'
+                || $node->real_name == 'views'
+                || $node->real_name == 'functions'
+                || $node->real_name == 'procedures'
+                || $node->real_name == 'events')
+            )
+            && $node->realParent()->getPresence($node->real_name) >= (int)$GLOBALS['cfg']['NavigationTreeDisplayItemFilterMinimum']
+        ) {
+            $paths = $node->getPaths();
+            $url_params = array(
+                'pos' => $this->_pos,
+                'aPath' => $paths['aPath'],
+                'vPath' => $paths['vPath'],
+                'pos2_name' => $node->real_name,
+                'pos2_value' => 0
+            );
+            $retval .= "<li class='fast_filter'>";
+            $retval .= "<form class='ajax fast_filter'>";
+            $retval .= PMA_getHiddenFields($url_params);
+            $retval .= "<input class='searchClause' name='searchClause2'";
+            $retval .= " value='" . __('filter items by name') . "' />";
+            $retval .= "<span title='" . __('Clear Fast Filter') . "'>X</span>";
+            $retval .= "</form>";
+            $retval .= "</li>";
+        }
+        return $retval;
+    }
+
+    /**
+     * Generates the HTML code for displaying the list pagination
+     *
+     * @param Node $node The node for whose children the page
+     *                   selector will be created
+     *
+     * @return string
+     */
+    private function _getPageSelector($node)
+    {
+        $retval = '';
+        if ($node === $this->_tree) {
+             $retval .= PMA_Util::getListNavigator(
+                 $this->_tree->getPresence('databases', $this->_searchClause),
+                 $this->_pos,
+                 array('server' => $GLOBALS['server']),
+                 'navigation.php',
+                 'frame_navigation',
+                 $GLOBALS['cfg']['MaxNavigationItems'],
+                 'pos',
+                 array('dbselector')
+             );
+        } else if ($node->type == Node::CONTAINER && ! $node->is_group) {
+            $paths = $node->getPaths();
+
+            $level = isset($paths['aPath_clean'][4]) ? 3 : 2;
+            $_url_params = array(
+                'aPath' => $paths['aPath'],
+                'vPath' => $paths['vPath'],
+                'pos' => $this->_pos,
+                'server' => $GLOBALS['server'],
+                'pos2_name' => $paths['aPath_clean'][2]
+            );
+            if ($level == 3) {
+                $pos = $node->pos3;
+                $_url_params['pos2_value'] = $node->pos2;
+                $_url_params['pos3_name'] = $paths['aPath_clean'][4];
+            } else {
+                $pos = $node->pos2;
+            }
+            $num = $node->realParent()->getPresence(
+                $node->real_name,
+                $this->_searchClause2
+            );
+            $retval .= PMA_Util::getListNavigator(
+                $num,
+                $pos,
+                $_url_params,
+                'navigation.php',
+                'frame_navigation',
+                $GLOBALS['cfg']['MaxNavigationItems'],
+                'pos' . $level . '_value'
+            );
+        }
+        return $retval;
+    }
+
+    /**
+     * Called by usort() for sorting the nodes in a container
+     *
+     * @param Node $a The first element used in the comparison
+     * @param Node $b The second element used in the comparison
+     *
+     * @return int See strnatcmp() and strcmp()
+     */
+    static public function sortNode($a, $b)
+    {
+        if ($a->isNew) {
+            return -1;
+        } else if ($b->isNew) {
+            return 1;
+        }
+        if ($GLOBALS['cfg']['NaturalOrder']) {
+            return strnatcasecmp($a->name, $b->name);
+        } else {
+            return strcasecmp($a->name, $b->name);
+        }
+    }
+}
+?>
diff --git a/phpmyadmin/libraries/navigation/NodeFactory.class.php b/phpmyadmin/libraries/navigation/NodeFactory.class.php
new file mode 100644
index 0000000..7d8106a
--- /dev/null
+++ b/phpmyadmin/libraries/navigation/NodeFactory.class.php
@@ -0,0 +1,97 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * This class is responsible for creating Node objects
+ *
+ * @package PhpMyAdmin-navigation
+ */
+if (! defined('PHPMYADMIN')) {
+    exit;
+}
+
+require_once 'libraries/navigation/Nodes/Node.class.php';
+
+/**
+ * Node factory - instanciates Node objects or objects derived from the Node class
+ *
+ * @package PhpMyAdmin-Navigation
+ */
+class PMA_NodeFactory
+{
+    /**
+     * @var string $_path A template for generating paths to files
+     *                    that contain various Node classes
+     * @access private
+     */
+    private static $_path = 'libraries/navigation/Nodes/%s.class.php';
+    /**
+     * Sanitizes the name of a Node class
+     *
+     * @param string $class The class name to be sanitized
+     *
+     * @return string
+     */
+    private static function _sanitizeClass($class)
+    {
+        if ($class !== 'Node' && ! preg_match('@^Node_\w+(_\w+)?$@', $class)) {
+            $class = 'Node';
+            trigger_error(
+                sprintf(
+                    /* l10n: The word "Node" must not be translated here */
+                    __('Invalid class name "%1$s", using default of "Node"'),
+                    $class
+                ),
+                E_USER_ERROR
+            );
+        }
+        return self::_checkFile($class);
+    }
+    /**
+     * Checks if a file exists for a given class name
+     * Will return the default class name back if the
+     * file for some subclass is not available
+     *
+     * @param string $class The class name to check
+     *
+     * @return string
+     */
+    private static function _checkFile($class)
+    {
+        $path = sprintf(self::$_path, $class);
+        if (! is_readable($path)) {
+            $class = 'Node';
+            trigger_error(
+                sprintf(
+                    __('Could not include class "%1$s", file "%2$s" not found'),
+                    $class,
+                    'Nodes/' . $class . '.class.php'
+                ),
+                E_USER_ERROR
+            );
+        }
+        return $class;
+    }
+    /**
+     * Instanciates a Node object
+     *
+     * @param string $class    The name of the class to instanciate
+     * @param string $name     An identifier for the new node
+     * @param int    $type     Type of node, may be one of CONTAINER or OBJECT
+     * @param bool   $is_group Whether this object has been created
+     *                         while grouping nodes
+     *
+     * @return string
+     */
+    public static function getInstance(
+        $class = 'Node',
+        $name = 'default',
+        $type = Node::OBJECT,
+        $is_group = false
+    ) {
+        $class = self::_sanitizeClass($class);
+        include_once sprintf(self::$_path, $class);
+        return new $class($name, $type, $is_group);
+    }
+}
+
+?>
diff --git a/phpmyadmin/libraries/navigation/Nodes/Node.class.php b/phpmyadmin/libraries/navigation/Nodes/Node.class.php
new file mode 100644
index 0000000..a1f0e3b
--- /dev/null
+++ b/phpmyadmin/libraries/navigation/Nodes/Node.class.php
@@ -0,0 +1,455 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * Functionality for the navigation tree in the left frame
+ *
+ * @package PhpMyAdmin-Navigation
+ */
+if (! defined('PHPMYADMIN')) {
+    exit;
+}
+
+/**
+ * The Node is the building block for the collapsible navigation tree
+ *
+ * @package PhpMyAdmin-Navigation
+ */
+class Node
+{
+    /**
+     * @var int Defines a possible node type
+     */
+    const CONTAINER = 0;
+
+    /**
+     * @var int Defines a possible node type
+     */
+    const OBJECT = 1;
+
+    /**
+     * @var string A non-unique identifier for the node
+     *             This may be trimmed when grouping nodes
+     */
+    public $name = "";
+
+    /**
+     * @var string A non-unique identifier for the node
+     *             This will never change after being assigned
+     */
+    public $real_name = "";
+
+    /**
+     * @var int May be one of CONTAINER or OBJECT
+     */
+    public $type = Node::OBJECT;
+
+    /**
+     * @var bool Whether this object has been created while grouping nodes
+     *           Only relevant if the node is of type CONTAINER
+     */
+    public $is_group;
+
+    /**
+     * @var bool Whether to add a "display: none;" CSS
+     *           rule to the node when rendering it
+     */
+    public $visible = false;
+
+    /**
+     * @var Node A reference to the parent object of
+     *           this node, NULL for the root node.
+     */
+    public $parent;
+
+    /**
+     * @var array An array of Node objects that are
+     *            direct children of this node
+     */
+    public $children = array();
+
+    /**
+     * @var Mixed A string used to group nodes, or an array of strings
+     *            Only relevant if the node is of type CONTAINER
+     */
+    public $separator = '';
+
+    /**
+     * @var int How many time to recursively apply the grouping function
+     *          Only relevant if the node is of type CONTAINER
+     */
+    public $separator_depth = 1;
+
+    /**
+     * @var string An IMG tag, used when rendering the node
+     */
+    public $icon;
+
+    /**
+     * @var Array An array of A tags, used when rendering the node
+     *            The indexes in the array may be 'icon' and 'text'
+     */
+    public $links;
+
+    /**
+     * @var string Extra CSS classes for the node
+     */
+    public $classes = '';
+
+    /**
+     * @var string Whether this node is a link for creating new objects
+     */
+    public $isNew = false;
+
+    /**
+     * @var int The position for the pagination of
+     *          the branch at the second level of the tree
+     */
+    public $pos2 = 0;
+
+    /**
+     * @var int The position for the pagination of
+     *          the branch at the third level of the tree
+     */
+    public $pos3 = 0;
+
+    /**
+     * Initialises the class by setting the mandatory variables
+     *
+     * @param string $name     An identifier for the new node
+     * @param int    $type     Type of node, may be one of CONTAINER or OBJECT
+     * @param bool   $is_group Whether this object has been created
+     *                         while grouping nodes
+     *
+     * @return Node
+     */
+    public function __construct($name, $type = Node::OBJECT, $is_group = false)
+    {
+        if (! empty($name)) {
+            $this->name      = $name;
+            $this->real_name = $name;
+        }
+        if ($type === Node::CONTAINER) {
+            $this->type = Node::CONTAINER;
+        }
+        $this->is_group = (bool)$is_group;
+    }
+
+    /**
+     * Adds a child node to this node
+     *
+     * @param Node $child A child node
+     *
+     * @return nothing
+     */
+    public function addChild($child)
+    {
+        $this->children[] = $child;
+        $child->parent    = $this;
+    }
+
+    /**
+     * Returns a child node given it's name
+     *
+     * @param string $name      The name of requested child
+     * @param bool   $real_name Whether to use the "real_name"
+     *                          instead of "name" in comparisons
+     *
+     * @return false|Node The requested child node or false,
+     *                    if the requested node cannot be found
+     */
+    public function getChild($name, $real_name = false)
+    {
+        if ($real_name) {
+            foreach ($this->children as $child) {
+                if ($child->real_name == $name) {
+                    return $child;
+                }
+            }
+        } else {
+            foreach ($this->children as $child) {
+                if ($child->name == $name) {
+                    return $child;
+                }
+            }
+        }
+        return false;
+    }
+
+    /**
+     * Removes a child node from this node
+     *
+     * @param string $name The name of child to be removed
+     *
+     * @return nothing
+     */
+    public function removeChild($name)
+    {
+        foreach ($this->children as $key => $child) {
+            if ($child->name == $name) {
+                unset($this->children[$key]);
+                break;
+            }
+        }
+    }
+
+    /**
+     * Retreives the parents for a node
+     *
+     * @param bool $self       Whether to include the Node itself in the results
+     * @param bool $containers Whether to include nodes of type CONTAINER
+     * @param bool $groups     Whether to include nodes which have $group == true
+     *
+     * @return array An array of parent Nodes
+     */
+    public function parents($self = false, $containers = false, $groups = false)
+    {
+        $parents = array();
+        if ($self
+            && ($this->type != Node::CONTAINER || $containers)
+            && ($this->is_group != true || $groups)
+        ) {
+            $parents[] = $this;
+            $self      = false;
+        }
+        $parent = $this->parent;
+        while (isset($parent)) {
+            if (   ($parent->type != Node::CONTAINER || $containers)
+                && ($parent->is_group != true || $groups)
+            ) {
+                $parents[] = $parent;
+            }
+            $parent = $parent->parent;
+        }
+        return $parents;
+    }
+
+    /**
+     * Returns the actual parent of a node. If used twice on an index or columns
+     * node, it will return the table and database nodes. The names of the returned
+     * nodes can be used in SQL queries, etc...
+     *
+     * @return Node
+     */
+    public function realParent()
+    {
+        $retval = $this->parents();
+        if (count($retval) > 0) {
+            return $retval[0];
+        } else {
+            return false;
+        }
+    }
+
+    /**
+     * This function checks if the node has children nodes associated with it
+     *
+     * @param bool $count_empty_containers Whether to count empty child
+     *                                     containers as valid children
+     *
+     * @return bool Whether the node has child nodes
+     */
+    public function hasChildren($count_empty_containers = true)
+    {
+        $retval = false;
+        if ($count_empty_containers) {
+            if (count($this->children)) {
+                $retval = true;
+            }
+        } else {
+            foreach ($this->children as $child) {
+                if ($child->type == Node::OBJECT || $child->hasChildren(false)) {
+                    $retval = true;
+                    break;
+                }
+            }
+        }
+        return $retval;
+    }
+
+    /**
+     * Returns true the node has some siblings (other nodes on the same tree level,
+     * in the same branch), false otherwise. The only exception is for nodes on
+     * the third level of the tree (columns and indexes), for which the function
+     * always returns true. This is because we want to render the containers
+     * for these nodes
+     *
+     * @return bool
+     */
+    public function hasSiblings()
+    {
+        $retval = false;
+        $paths  = $this->getPaths();
+        if (count($paths['aPath_clean']) > 3) {
+            $retval = true;
+        } else {
+            foreach ($this->parent->children as $child) {
+                if ($child != $this
+                    && ($child->type == Node::OBJECT || $child->hasChildren(false))
+                ) {
+                    $retval = true;
+                    break;
+                }
+            }
+        }
+        return $retval;
+    }
+
+    /**
+     * Returns the number of child nodes that a node has associated with it
+     *
+     * @return int The number of children nodes
+     */
+    public function numChildren()
+    {
+        $retval = 0;
+        foreach ($this->children as $child) {
+            if ($child->type == Node::OBJECT) {
+                $retval++;
+            } else {
+                $retval += $child->numChildren();
+            }
+        }
+        return $retval;
+    }
+
+    /**
+     * Returns the actual path and the virtual paths for a node
+     * both as clean arrays and base64 encoded strings
+     *
+     * @return array
+     */
+    public function getPaths()
+    {
+        $aPath       = array();
+        $aPath_clean = array();
+        foreach ($this->parents(true, true, false) as $parent) {
+            $aPath[]       = base64_encode($parent->real_name);
+            $aPath_clean[] = $parent->real_name;
+        }
+        $aPath       = implode('.', array_reverse($aPath));
+        $aPath_clean = array_reverse($aPath_clean);
+
+        $vPath       = array();
+        $vPath_clean = array();
+        foreach ($this->parents(true, true, true) as $parent) {
+            $vPath[]       = base64_encode($parent->name);
+            $vPath_clean[] = $parent->name;
+        }
+        $vPath       = implode('.', array_reverse($vPath));
+        $vPath_clean = array_reverse($vPath_clean);
+
+        return array(
+            'aPath' => $aPath,
+            'aPath_clean' => $aPath_clean,
+            'vPath' => $vPath,
+            'vPath_clean' => $vPath_clean
+        );
+    }
+
+    /**
+     * Returns the names of children of type $type present inside this container
+     * This method is overridden by the Node_Database and Node_Table classes
+     *
+     * @param string $type         The type of item we are looking for
+     *                             ('tables', 'views', etc)
+     * @param int    $pos          The offset of the list within the results
+     * @param string $searchClause A string used to filter the results of the query
+     *
+     * @return array
+     */
+    public function getData($type, $pos, $searchClause = '')
+    {
+        // @todo obey the DisableIS directive
+        $query  = "SELECT `SCHEMA_NAME` ";
+        $query .= "FROM `INFORMATION_SCHEMA`.`SCHEMATA` ";
+        $query .= $this->_getWhereClause($searchClause); 
+        $query .= "ORDER BY `SCHEMA_NAME` ASC ";
+        $query .= "LIMIT $pos, {$GLOBALS['cfg']['MaxNavigationItems']}";
+        return PMA_DBI_fetch_result($query);
+    }
+
+    /**
+     * Returns the comment associated with node
+     * This method should be overridden by specific type of nodes
+     *
+     * @return string
+     */
+    public function getComment()
+    {
+        return '';
+    }
+
+    /**
+     * Returns the number of children of type $type present inside this container
+     * This method is overridden by the Node_Database and Node_Table classes
+     *
+     * @param string $type         The type of item we are looking for
+     *                             ('tables', 'views', etc)
+     * @param string $searchClause A string used to filter the results of the query
+     *
+     * @return int
+     */
+    public function getPresence($type = '', $searchClause = '')
+    {
+        if (! $GLOBALS['cfg']['Servers'][$GLOBALS['server']]['DisableIS']) {
+            $query  = "SELECT COUNT(*) ";
+            $query .= "FROM `INFORMATION_SCHEMA`.`SCHEMATA` ";
+            $query .= $this->_getWhereClause($searchClause); 
+            $retval = (int)PMA_DBI_fetch_value($query);
+        } else {
+            $query = "SHOW DATABASES ";
+            if (! empty($searchClause)) {
+                $query .= "LIKE '%";
+                $query .= PMA_Util::sqlAddSlashes(
+                    $searchClause, true
+                );
+                $query .= "%' ";
+            }
+            $retval = PMA_DBI_num_rows(PMA_DBI_try_query($query));
+        }
+        return $retval;
+    }
+
+    /**
+     * Returns the WHERE clause depending on the $searchClause parameter
+     * and the hide_db directive  
+     *
+     * @param string $searchClause A string used to filter the results of the query
+     *
+     * @return string 
+     */
+    private function _getWhereClause($searchClause = '')
+    {
+        $whereClause = "WHERE TRUE ";
+        if (! empty($searchClause)) {
+            $whereClause .= "AND `SCHEMA_NAME` LIKE '%";
+            $whereClause .= PMA_Util::sqlAddSlashes(
+                $searchClause, true
+            );
+            $whereClause .= "%' ";
+        }
+
+        if (! empty($GLOBALS['cfg']['Server']['hide_db'])) {
+            $whereClause .= "AND `SCHEMA_NAME` NOT REGEXP '"
+                . $GLOBALS['cfg']['Server']['hide_db'] . "' ";
+        }
+
+        if (! empty($GLOBALS['cfg']['Server']['only_db'])) {
+            if (is_string($GLOBALS['cfg']['Server']['only_db'])) {
+                $GLOBALS['cfg']['Server']['only_db'] = array(
+                    $GLOBALS['cfg']['Server']['only_db']
+                );
+            }
+            $whereClause .= "AND (";
+            $subClauses = array();
+            foreach ($GLOBALS['cfg']['Server']['only_db'] as $each_only_db) {
+                $subClauses[] = " `SCHEMA_NAME` LIKE '"
+                    . $each_only_db . "' ";
+            }
+            $whereClause .= implode("OR", $subClauses) . ")";
+        }
+        return $whereClause;
+    }
+
+}
+?>
diff --git a/phpmyadmin/libraries/navigation/Nodes/Node_Column.class.php b/phpmyadmin/libraries/navigation/Nodes/Node_Column.class.php
new file mode 100644
index 0000000..9c663e7
--- /dev/null
+++ b/phpmyadmin/libraries/navigation/Nodes/Node_Column.class.php
@@ -0,0 +1,71 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * Functionality for the navigation tree
+ *
+ * @package PhpMyAdmin-Navigation
+ */
+if (! defined('PHPMYADMIN')) {
+    exit;
+}
+
+/**
+ * Represents a columns node in the navigation tree
+ *
+ * @package PhpMyAdmin-Navigation
+ */
+class Node_Column extends Node
+{
+    /**
+     * Initialises the class
+     *
+     * @param string $name     An identifier for the new node
+     * @param int    $type     Type of node, may be one of CONTAINER or OBJECT
+     * @param bool   $is_group Whether this object has been created
+     *                         while grouping nodes
+     *
+     * @return Node_Column
+     */
+    public function __construct($name, $type = Node::OBJECT, $is_group = false)
+    {
+        parent::__construct($name, $type, $is_group);
+        $this->icon  = PMA_Util::getImage('pause.png', '');
+        $this->links = array(
+            'text' => 'tbl_structure.php?server=' . $GLOBALS['server']
+                    . '&db=%3$s&table=%2$s&field=%1$s'
+                    . '&change_column=1'
+                    . '&token=' . $GLOBALS['token'],
+            'icon' => 'tbl_structure.php?server=' . $GLOBALS['server']
+                    . '&db=%3$s&table=%2$s&field=%1$s'
+                    . '&change_column=1'
+                    . '&token=' . $GLOBALS['token']
+        );
+    }
+
+    /**
+     * Returns the comment associated with node
+     * This method should be overridden by specific type of nodes
+     *
+     * @return string
+     */
+    public function getComment()
+    {
+        $db     = PMA_Util::sqlAddSlashes(
+            $this->realParent()->realParent()->real_name
+        );
+        $table  = PMA_Util::sqlAddSlashes(
+            $this->realParent()->real_name
+        );
+        $column = PMA_Util::sqlAddSlashes(
+            $this->real_name
+        );
+        $query  = "SELECT `COLUMN_COMMENT` ";
+        $query .= "FROM `INFORMATION_SCHEMA`.`COLUMNS` ";
+        $query .= "WHERE `TABLE_SCHEMA`='$db' ";
+        $query .= "AND `TABLE_NAME`='$table' ";
+        $query .= "AND `COLUMN_NAME`='$column' ";
+        return PMA_DBI_fetch_value($query);
+    }
+}
+
+?>
diff --git a/phpmyadmin/libraries/navigation/Nodes/Node_Column_Container.class.php b/phpmyadmin/libraries/navigation/Nodes/Node_Column_Container.class.php
new file mode 100644
index 0000000..1ae57a8
--- /dev/null
+++ b/phpmyadmin/libraries/navigation/Nodes/Node_Column_Container.class.php
@@ -0,0 +1,56 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * Functionality for the navigation tree
+ *
+ * @package PhpMyAdmin-Navigation
+ */
+if (! defined('PHPMYADMIN')) {
+    exit;
+}
+
+/**
+ * Represents a container for column nodes in the navigation tree
+ *
+ * @package PhpMyAdmin-Navigation
+ */
+class Node_Column_Container extends Node
+{
+    /**
+     * Initialises the class
+     *
+     * @return Node_Column_Container
+     */
+    public function __construct()
+    {
+        parent::__construct(__('Columns'), Node::CONTAINER);
+        $this->icon  = PMA_Util::getImage('pause.png', '');
+        $this->links = array(
+            'text' => 'tbl_structure.php?server=' . $GLOBALS['server']
+                    . '&db=%2$s&table=%1$s'
+                    . '&token=' . $GLOBALS['token'],
+            'icon' => 'tbl_structure.php?server=' . $GLOBALS['server']
+                    . '&db=%2$s&table=%1$s'
+                    . '&token=' . $GLOBALS['token'],
+        );
+        $this->real_name = 'columns';
+
+        $new        = PMA_NodeFactory::getInstance('Node', _pgettext('Create new column', 'New'));
+        $new->isNew = true;
+        $new->icon  = PMA_Util::getImage('b_column_add.png', '');
+        $new->links = array(
+            'text' => 'tbl_addfield.php?server=' . $GLOBALS['server']
+                    . '&db=%3$s&table=%2$s'
+                    . '&field_where=last&after_field='
+                    . '&token=' . $GLOBALS['token'],
+            'icon' => 'tbl_addfield.php?server=' . $GLOBALS['server']
+                    . '&db=%3$s&table=%2$s'
+                    . '&field_where=last&after_field='
+                    . '&token=' . $GLOBALS['token'],
+        );
+        $new->classes = 'new_column italics';
+        $this->addChild($new);
+    }
+}
+
+?>
diff --git a/phpmyadmin/libraries/navigation/Nodes/Node_Database.class.php b/phpmyadmin/libraries/navigation/Nodes/Node_Database.class.php
new file mode 100644
index 0000000..5c0815f
--- /dev/null
+++ b/phpmyadmin/libraries/navigation/Nodes/Node_Database.class.php
@@ -0,0 +1,447 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * Functionality for the navigation tree
+ *
+ * @package PhpMyAdmin-Navigation
+ */
+if (! defined('PHPMYADMIN')) {
+    exit;
+}
+
+/**
+ * Represents a database node in the navigation tree
+ */
+class Node_Database extends Node
+{
+    /**
+     * Initialises the class
+     *
+     * @param string $name     An identifier for the new node
+     * @param int    $type     Type of node, may be one of CONTAINER or OBJECT
+     * @param bool   $is_group Whether this object has been created
+     *                         while grouping nodes
+     *
+     * @return Node_Database
+     */
+    public function __construct($name, $type = Node::OBJECT, $is_group = false)
+    {
+        parent::__construct($name, $type, $is_group);
+        $this->icon  = PMA_Util::getImage('s_db.png');
+        $this->links = array(
+            'text' => $GLOBALS['cfg']['DefaultTabDatabase']
+                    . '?server=' . $GLOBALS['server']
+                    . '&db=%1$s&token=' . $GLOBALS['token'],
+            'icon' => 'db_operations.php?server=' . $GLOBALS['server']
+                    . '&db=%1$s&token=' . $GLOBALS['token']
+        );
+    }
+
+    /**
+     * Returns the number of children of type $type present inside this container
+     * This method is overridden by the Node_Database and Node_Table classes
+     *
+     * @param string $type         The type of item we are looking for
+     *                             ('tables', 'views', etc)
+     * @param string $searchClause A string used to filter the results of the query
+     *
+     * @return int
+     */
+    public function getPresence($type = '', $searchClause = '')
+    {
+        $retval = 0;
+        $db     = $this->real_name;
+        switch ($type) {
+        case 'tables':
+            if (! $GLOBALS['cfg']['Servers'][$GLOBALS['server']]['DisableIS']) {
+                $db     = PMA_Util::sqlAddSlashes($db);
+                $query  = "SELECT COUNT(*) ";
+                $query .= "FROM `INFORMATION_SCHEMA`.`TABLES` ";
+                $query .= "WHERE `TABLE_SCHEMA`='$db' ";
+                $query .= "AND `TABLE_TYPE`='BASE TABLE' ";
+                if (! empty($searchClause)) {
+                    $query .= "AND `TABLE_NAME` LIKE '%";
+                    $query .= PMA_Util::sqlAddSlashes(
+                        $searchClause, true
+                    );
+                    $query .= "%'";
+                }
+                $retval = (int)PMA_DBI_fetch_value($query);
+            } else {
+                $query  = "SHOW FULL TABLES FROM ";
+                $query .= PMA_Util::backquote($db);
+                $query .= " WHERE `Table_type`='BASE TABLE' ";
+                if (! empty($searchClause)) {
+                    $query .= "AND " . PMA_Util::backquote(
+                        "Tables_in_" . $db
+                    );
+                    $query .= " LIKE '%" . PMA_Util::sqlAddSlashes(
+                        $searchClause, true
+                    );
+                    $query .= "%'";
+                }
+                $retval = PMA_DBI_num_rows(PMA_DBI_try_query($query));
+            }
+            break;
+        case 'views':
+            if (! $GLOBALS['cfg']['Servers'][$GLOBALS['server']]['DisableIS']) {
+                $db     = PMA_Util::sqlAddSlashes($db);
+                $query  = "SELECT COUNT(*) ";
+                $query .= "FROM `INFORMATION_SCHEMA`.`TABLES` ";
+                $query .= "WHERE `TABLE_SCHEMA`='$db' ";
+                $query .= "AND `TABLE_TYPE`!='BASE TABLE' ";
+                if (! empty($searchClause)) {
+                    $query .= "AND `TABLE_NAME` LIKE '%";
+                    $query .= PMA_Util::sqlAddSlashes(
+                        $searchClause, true
+                    );
+                    $query .= "%'";
+                }
+                $retval = (int)PMA_DBI_fetch_value($query);
+            } else {
+                $query  = "SHOW FULL TABLES FROM ";
+                $query .= PMA_Util::backquote($db);
+                $query .= " WHERE `Table_type`!='BASE TABLE' ";
+                if (! empty($searchClause)) {
+                    $query .= "AND " . PMA_Util::backquote(
+                        "Tables_in_" . $db
+                    );
+                    $query .= " LIKE '%" . PMA_Util::sqlAddSlashes(
+                        $searchClause, true
+                    );
+                    $query .= "%'";
+                }
+                $retval = PMA_DBI_num_rows(PMA_DBI_try_query($query));
+            }
+            break;
+        case 'procedures':
+            if (! $GLOBALS['cfg']['Servers'][$GLOBALS['server']]['DisableIS']) {
+                $db     = PMA_Util::sqlAddSlashes($db);
+                $query  = "SELECT COUNT(*) ";
+                $query .= "FROM `INFORMATION_SCHEMA`.`ROUTINES` ";
+                $query .= "WHERE `ROUTINE_SCHEMA`='$db'";
+                $query .= "AND `ROUTINE_TYPE`='PROCEDURE' ";
+                if (! empty($searchClause)) {
+                    $query .= "AND `ROUTINE_NAME` LIKE '%";
+                    $query .= PMA_Util::sqlAddSlashes(
+                        $searchClause, true
+                    );
+                    $query .= "%'";
+                }
+                $retval = (int)PMA_DBI_fetch_value($query);
+            } else {
+                $db    = PMA_Util::sqlAddSlashes($db);
+                $query = "SHOW PROCEDURE STATUS WHERE `Db`='$db' ";
+                if (! empty($searchClause)) {
+                    $query .= "AND `Name` LIKE '%";
+                    $query .= PMA_Util::sqlAddSlashes(
+                        $searchClause, true
+                    );
+                    $query .= "%'";
+                }
+                $retval = PMA_DBI_num_rows(PMA_DBI_try_query($query));
+            }
+            break;
+        case 'functions':
+            if (! $GLOBALS['cfg']['Servers'][$GLOBALS['server']]['DisableIS']) {
+                $db     = PMA_Util::sqlAddSlashes($db);
+                $query  = "SELECT COUNT(*) ";
+                $query .= "FROM `INFORMATION_SCHEMA`.`ROUTINES` ";
+                $query .= "WHERE `ROUTINE_SCHEMA`='$db' ";
+                $query .= "AND `ROUTINE_TYPE`='FUNCTION' ";
+                if (! empty($searchClause)) {
+                    $query .= "AND `ROUTINE_NAME` LIKE '%";
+                    $query .= PMA_Util::sqlAddSlashes(
+                        $searchClause, true
+                    );
+                    $query .= "%'";
+                }
+                $retval = (int)PMA_DBI_fetch_value($query);
+            } else {
+                $db    = PMA_Util::sqlAddSlashes($db);
+                $query = "SHOW FUNCTION STATUS WHERE `Db`='$db' ";
+                if (! empty($searchClause)) {
+                    $query .= "AND `Name` LIKE '%";
+                    $query .= PMA_Util::sqlAddSlashes(
+                        $searchClause, true
+                    );
+                    $query .= "%'";
+                }
+                $retval = PMA_DBI_num_rows(PMA_DBI_try_query($query));
+            }
+            break;
+        case 'events':
+            if (! $GLOBALS['cfg']['Servers'][$GLOBALS['server']]['DisableIS']) {
+                $db     = PMA_Util::sqlAddSlashes($db);
+                $query  = "SELECT COUNT(*) ";
+                $query .= "FROM `INFORMATION_SCHEMA`.`EVENTS` ";
+                $query .= "WHERE `EVENT_SCHEMA`='$db' ";
+                if (! empty($searchClause)) {
+                    $query .= "AND `EVENT_NAME` LIKE '%";
+                    $query .= PMA_Util::sqlAddSlashes(
+                        $searchClause, true
+                    );
+                    $query .= "%'";
+                }
+                $retval = (int)PMA_DBI_fetch_value($query);
+            } else {
+                $db    = PMA_Util::backquote($db);
+                $query = "SHOW EVENTS FROM $db ";
+                if (! empty($searchClause)) {
+                    $query .= "WHERE `Name` LIKE '%";
+                    $query .= PMA_Util::sqlAddSlashes(
+                        $searchClause, true
+                    );
+                    $query .= "%'";
+                }
+                $retval = PMA_DBI_num_rows(PMA_DBI_try_query($query));
+            }
+            break;
+        default:
+            break;
+        }
+        return $retval;
+    }
+
+    /**
+     * Returns the names of children of type $type present inside this container
+     * This method is overridden by the Node_Database and Node_Table classes
+     *
+     * @param string $type         The type of item we are looking for
+     *                             ('tables', 'views', etc)
+     * @param int    $pos          The offset of the list within the results
+     * @param string $searchClause A string used to filter the results of the query
+     *
+     * @return array
+     */
+    public function getData($type, $pos, $searchClause = '')
+    {
+        $maxItems = $GLOBALS['cfg']['MaxNavigationItems'];
+        $retval   = array();
+        $db       = $this->real_name;
+        switch ($type) {
+        case 'tables':
+            if (! $GLOBALS['cfg']['Servers'][$GLOBALS['server']]['DisableIS']) {
+                $db     = PMA_Util::sqlAddSlashes($db);
+                $query  = "SELECT `TABLE_NAME` AS `name` ";
+                $query .= "FROM `INFORMATION_SCHEMA`.`TABLES` ";
+                $query .= "WHERE `TABLE_SCHEMA`='$db' ";
+                $query .= "AND `TABLE_TYPE`='BASE TABLE' ";
+                if (! empty($searchClause)) {
+                    $query .= "AND `TABLE_NAME` LIKE '%";
+                    $query .= PMA_Util::sqlAddSlashes(
+                        $searchClause, true
+                    );
+                    $query .= "%'";
+                }
+                $query .= "ORDER BY `TABLE_NAME` ASC ";
+                $query .= "LIMIT " . intval($pos) . ", $maxItems";
+                $retval = PMA_DBI_fetch_result($query);
+            } else {
+                $query  = " SHOW FULL TABLES FROM ";
+                $query .= PMA_Util::backquote($db);
+                $query .= " WHERE `Table_type`='BASE TABLE' ";
+                if (! empty($searchClause)) {
+                    $query .= "AND " . PMA_Util::backquote(
+                        "Tables_in_" . $db
+                    );
+                    $query .= " LIKE '%" . PMA_Util::sqlAddSlashes(
+                        $searchClause, true
+                    );
+                    $query .= "%'";
+                }
+                $handle = PMA_DBI_try_query($query);
+                if ($handle !== false) {
+                    $count = 0;
+                    while ($arr = PMA_DBI_fetch_array($handle)) {
+                        if ($pos <= 0 && $count < $maxItems) {
+                            $retval[] = $arr[0];
+                            $count++;
+                        }
+                        $pos--;
+                    }
+                }
+            }
+            break;
+        case 'views':
+            if (! $GLOBALS['cfg']['Servers'][$GLOBALS['server']]['DisableIS']) {
+                $db     = PMA_Util::sqlAddSlashes($db);
+                $query  = "SELECT `TABLE_NAME` AS `name` ";
+                $query .= "FROM `INFORMATION_SCHEMA`.`TABLES` ";
+                $query .= "WHERE `TABLE_SCHEMA`='$db' ";
+                $query .= "AND `TABLE_TYPE`!='BASE TABLE' ";
+                if (! empty($searchClause)) {
+                    $query .= "AND `TABLE_NAME` LIKE '%";
+                    $query .= PMA_Util::sqlAddSlashes(
+                        $searchClause, true
+                    );
+                    $query .= "%'";
+                }
+                $query .= "ORDER BY `TABLE_NAME` ASC ";
+                $query .= "LIMIT " . intval($pos) . ", $maxItems";
+                $retval = PMA_DBI_fetch_result($query);
+            } else {
+                $query  = "SHOW FULL TABLES FROM ";
+                $query .= PMA_Util::backquote($db);
+                $query .= " WHERE `Table_type`!='BASE TABLE' ";
+                if (! empty($searchClause)) {
+                    $query .= "AND " . PMA_Util::backquote(
+                        "Tables_in_" . $db
+                    );
+                    $query .= " LIKE '%" . PMA_Util::sqlAddSlashes(
+                        $searchClause, true
+                    );
+                    $query .= "%'";
+                }
+                $handle = PMA_DBI_try_query($query);
+                if ($handle !== false) {
+                    $count = 0;
+                    while ($arr = PMA_DBI_fetch_array($handle)) {
+                        if ($pos <= 0 && $count < $maxItems) {
+                            $retval[] = $arr[0];
+                            $count++;
+                        }
+                        $pos--;
+                    }
+                }
+            }
+            break;
+        case 'procedures':
+            if (! $GLOBALS['cfg']['Servers'][$GLOBALS['server']]['DisableIS']) {
+                $db     = PMA_Util::sqlAddSlashes($db);
+                $query  = "SELECT `ROUTINE_NAME` AS `name` ";
+                $query .= "FROM `INFORMATION_SCHEMA`.`ROUTINES` ";
+                $query .= "WHERE `ROUTINE_SCHEMA`='$db'";
+                $query .= "AND `ROUTINE_TYPE`='PROCEDURE' ";
+                if (! empty($searchClause)) {
+                    $query .= "AND `ROUTINE_NAME` LIKE '%";
+                    $query .= PMA_Util::sqlAddSlashes(
+                        $searchClause, true
+                    );
+                    $query .= "%'";
+                }
+                $query .= "ORDER BY `ROUTINE_NAME` ASC ";
+                $query .= "LIMIT " . intval($pos) . ", $maxItems";
+                $retval = PMA_DBI_fetch_result($query);
+            } else {
+                $db    = PMA_Util::sqlAddSlashes($db);
+                $query = "SHOW PROCEDURE STATUS WHERE `Db`='$db' ";
+                if (! empty($searchClause)) {
+                    $query .= "AND `Name` LIKE '%";
+                    $query .= PMA_Util::sqlAddSlashes(
+                        $searchClause, true
+                    );
+                    $query .= "%'";
+                }
+                $handle = PMA_DBI_try_query($query);
+                if ($handle !== false) {
+                    $count = 0;
+                    while ($arr = PMA_DBI_fetch_array($handle)) {
+                        if ($pos <= 0 && $count < $maxItems) {
+                            $retval[] = $arr['Name'];
+                            $count++;
+                        }
+                        $pos--;
+                    }
+                }
+            }
+            break;
+        case 'functions':
+            if (! $GLOBALS['cfg']['Servers'][$GLOBALS['server']]['DisableIS']) {
+                $db     = PMA_Util::sqlAddSlashes($db);
+                $query  = "SELECT `ROUTINE_NAME` AS `name` ";
+                $query .= "FROM `INFORMATION_SCHEMA`.`ROUTINES` ";
+                $query .= "WHERE `ROUTINE_SCHEMA`='$db' ";
+                $query .= "AND `ROUTINE_TYPE`='FUNCTION' ";
+                if (! empty($searchClause)) {
+                    $query .= "AND `ROUTINE_NAME` LIKE '%";
+                    $query .= PMA_Util::sqlAddSlashes(
+                        $searchClause, true
+                    );
+                    $query .= "%'";
+                }
+                $query .= "ORDER BY `ROUTINE_NAME` ASC ";
+                $query .= "LIMIT " . intval($pos) . ", $maxItems";
+                $retval = PMA_DBI_fetch_result($query);
+            } else {
+                $db    = PMA_Util::sqlAddSlashes($db);
+                $query = "SHOW FUNCTION STATUS WHERE `Db`='$db' ";
+                if (! empty($searchClause)) {
+                    $query .= "AND `Name` LIKE '%";
+                    $query .= PMA_Util::sqlAddSlashes(
+                        $searchClause, true
+                    );
+                    $query .= "%'";
+                }
+                $handle = PMA_DBI_try_query($query);
+                if ($handle !== false) {
+                    $count = 0;
+                    while ($arr = PMA_DBI_fetch_array($handle)) {
+                        if ($pos <= 0 && $count < $maxItems) {
+                            $retval[] = $arr['Name'];
+                            $count++;
+                        }
+                        $pos--;
+                    }
+                }
+            }
+            break;
+        case 'events':
+            if (! $GLOBALS['cfg']['Servers'][$GLOBALS['server']]['DisableIS']) {
+                $db     = PMA_Util::sqlAddSlashes($db);
+                $query  = "SELECT `EVENT_NAME` AS `name` ";
+                $query .= "FROM `INFORMATION_SCHEMA`.`EVENTS` ";
+                $query .= "WHERE `EVENT_SCHEMA`='$db' ";
+                if (! empty($searchClause)) {
+                    $query .= "AND `EVENT_NAME` LIKE '%";
+                    $query .= PMA_Util::sqlAddSlashes(
+                        $searchClause, true
+                    );
+                    $query .= "%'";
+                }
+                $query .= "ORDER BY `EVENT_NAME` ASC ";
+                $query .= "LIMIT " . intval($pos) . ", $maxItems";
+                $retval = PMA_DBI_fetch_result($query);
+            } else {
+                $db    = PMA_Util::backquote($db);
+                $query = "SHOW EVENTS FROM $db ";
+                if (! empty($searchClause)) {
+                    $query .= "WHERE `Name` LIKE '%";
+                    $query .= PMA_Util::sqlAddSlashes(
+                        $searchClause, true
+                    );
+                    $query .= "%'";
+                }
+                $handle = PMA_DBI_try_query($query);
+                if ($handle !== false) {
+                    $count = 0;
+                    while ($arr = PMA_DBI_fetch_array($handle)) {
+                        if ($pos <= 0 && $count < $maxItems) {
+                            $retval[] = $arr['Name'];
+                            $count++;
+                        }
+                        $pos--;
+                    }
+                }
+            }
+            break;
+        default:
+            break;
+        }
+        return $retval;
+    }
+
+
+    /**
+     * Returns the comment associated with node
+     * This method should be overridden by specific type of nodes
+     *
+     * @return string
+     */
+    public function getComment()
+    {
+        return PMA_getDbComment($this->real_name);
+    }
+}
+
+?>
diff --git a/phpmyadmin/libraries/navigation/Nodes/Node_Event.class.php b/phpmyadmin/libraries/navigation/Nodes/Node_Event.class.php
new file mode 100644
index 0000000..5b82999
--- /dev/null
+++ b/phpmyadmin/libraries/navigation/Nodes/Node_Event.class.php
@@ -0,0 +1,66 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * Functionality for the navigation tree
+ *
+ * @package PhpMyAdmin-Navigation
+ */
+if (! defined('PHPMYADMIN')) {
+    exit;
+}
+
+/**
+ * Represents a event node in the navigation tree
+ *
+ * @package PhpMyAdmin-Navigation
+ */
+class Node_Event extends Node
+{
+    /**
+     * Initialises the class
+     *
+     * @param string $name     An identifier for the new node
+     * @param int    $type     Type of node, may be one of CONTAINER or OBJECT
+     * @param bool   $is_group Whether this object has been created
+     *                         while grouping nodes
+     *
+     * @return Node_Event
+     */
+    public function __construct($name, $type = Node::OBJECT, $is_group = false)
+    {
+        parent::__construct($name, $type, $is_group);
+        $this->icon  = PMA_Util::getImage('b_events.png');
+        $this->links = array(
+            'text' => 'db_events.php?server=' . $GLOBALS['server']
+                    . '&db=%2$s&item_name=%1$s&edit_item=1'
+                    . '&token=' . $GLOBALS['token'],
+            'icon' => 'db_events.php?server=' . $GLOBALS['server']
+                    . '&db=%2$s&item_name=%1$s&export_item=1'
+                    . '&token=' . $GLOBALS['token']
+        );
+        $this->classes = 'event';
+    }
+
+    /**
+     * Returns the comment associated with node
+     * This method should be overridden by specific type of nodes
+     *
+     * @return string
+     */
+    public function getComment()
+    {
+        $db    = PMA_Util::sqlAddSlashes(
+            $this->realParent()->real_name
+        );
+        $event = PMA_Util::sqlAddSlashes(
+            $this->real_name
+        );
+        $query  = "SELECT `EVENT_COMMENT` ";
+        $query .= "FROM `INFORMATION_SCHEMA`.`EVENTS` ";
+        $query .= "WHERE `EVENT_SCHEMA`='$db' ";
+        $query .= "AND `EVENT_NAME`='$event' ";
+        return PMA_DBI_fetch_value($query);
+    }
+}
+
+?>
diff --git a/phpmyadmin/libraries/navigation/Nodes/Node_Event_Container.class.php b/phpmyadmin/libraries/navigation/Nodes/Node_Event_Container.class.php
new file mode 100644
index 0000000..16bdd00
--- /dev/null
+++ b/phpmyadmin/libraries/navigation/Nodes/Node_Event_Container.class.php
@@ -0,0 +1,52 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * Functionality for the navigation tree
+ *
+ * @package PhpMyAdmin-Navigation
+ */
+if (! defined('PHPMYADMIN')) {
+    exit;
+}
+
+/**
+ * Represents a container for events nodes in the navigation tree
+ *
+ * @package PhpMyAdmin-Navigation
+ */
+class Node_Event_Container extends Node
+{
+    /**
+     * Initialises the class
+     *
+     * @return Node_Event_Container
+     */
+    public function __construct()
+    {
+        parent::__construct(__('Events'), Node::CONTAINER);
+        $this->icon  = PMA_Util::getImage('b_events.png', '');
+        $this->links = array(
+            'text' => 'db_events.php?server=' . $GLOBALS['server']
+                    . '&db=%1$s&token=' . $GLOBALS['token'],
+            'icon' => 'db_events.php?server=' . $GLOBALS['server']
+                    . '&db=%1$s&token=' . $GLOBALS['token'],
+        );
+        $this->real_name = 'events';
+
+        $new        = PMA_NodeFactory::getInstance('Node', _pgettext('Create new event', 'New'));
+        $new->isNew = true;
+        $new->icon  = PMA_Util::getImage('b_event_add.png', '');
+        $new->links = array(
+            'text' => 'db_events.php?server=' . $GLOBALS['server']
+                    . '&db=%2$s&token=' . $GLOBALS['token']
+                    . '&add_item=1',
+            'icon' => 'db_events.php?server=' . $GLOBALS['server']
+                    . '&db=%2$s&token=' . $GLOBALS['token']
+                    . '&add_item=1',
+        );
+        $new->classes = 'new_event italics';
+        $this->addChild($new);
+    }
+}
+
+?>
diff --git a/phpmyadmin/libraries/navigation/Nodes/Node_Function.class.php b/phpmyadmin/libraries/navigation/Nodes/Node_Function.class.php
new file mode 100644
index 0000000..f6e01a5
--- /dev/null
+++ b/phpmyadmin/libraries/navigation/Nodes/Node_Function.class.php
@@ -0,0 +1,67 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * Functionality for the navigation tree
+ *
+ * @package PhpMyAdmin-Navigation
+ */
+if (! defined('PHPMYADMIN')) {
+    exit;
+}
+
+/**
+ * Represents a function node in the navigation tree
+ *
+ * @package PhpMyAdmin-Navigation
+ */
+class Node_Function extends Node
+{
+    /**
+     * Initialises the class
+     *
+     * @param string $name     An identifier for the new node
+     * @param int    $type     Type of node, may be one of CONTAINER or OBJECT
+     * @param bool   $is_group Whether this object has been created
+     *                         while grouping nodes
+     *
+     * @return Node_Function
+     */
+    public function __construct($name, $type = Node::OBJECT, $is_group = false)
+    {
+        parent::__construct($name, $type, $is_group);
+        $this->icon  = PMA_Util::getImage('b_routines.png');
+        $this->links = array(
+            'text' => 'db_routines.php?server=' . $GLOBALS['server']
+                    . '&db=%2$s&item_name=%1$s&item_type=FUNCTION'
+                    . '&edit_item=1&token=' . $GLOBALS['token'],
+            'icon' => 'db_routines.php?server=' . $GLOBALS['server']
+                    . '&db=%2$s&item_name=%1$s&item_type=FUNCTION'
+                    . '&export_item=1&token=' . $GLOBALS['token']
+        );
+        $this->classes = 'function';
+    }
+
+    /**
+     * Returns the comment associated with node
+     * This method should be overridden by specific type of nodes
+     *
+     * @return string
+     */
+    public function getComment()
+    {
+        $db      = PMA_Util::sqlAddSlashes(
+            $this->realParent()->real_name
+        );
+        $routine = PMA_Util::sqlAddSlashes(
+            $this->real_name
+        );
+        $query  = "SELECT `ROUTINE_COMMENT` ";
+        $query .= "FROM `INFORMATION_SCHEMA`.`ROUTINES` ";
+        $query .= "WHERE `ROUTINE_SCHEMA`='$db' ";
+        $query .= "AND `ROUTINE_NAME`='$routine' ";
+        $query .= "AND `ROUTINE_TYPE`='FUNCTION' ";
+        return PMA_DBI_fetch_value($query);
+    }
+}
+
+?>
diff --git a/phpmyadmin/libraries/navigation/Nodes/Node_Function_Container.class.php b/phpmyadmin/libraries/navigation/Nodes/Node_Function_Container.class.php
new file mode 100644
index 0000000..1ddc313
--- /dev/null
+++ b/phpmyadmin/libraries/navigation/Nodes/Node_Function_Container.class.php
@@ -0,0 +1,52 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * Functionality for the navigation tree
+ *
+ * @package PhpMyAdmin-Navigation
+ */
+if (! defined('PHPMYADMIN')) {
+    exit;
+}
+
+/**
+ * Represents a container for functions nodes in the navigation tree
+ *
+ * @package PhpMyAdmin-Navigation
+ */
+class Node_Function_Container extends Node
+{
+    /**
+     * Initialises the class
+     *
+     * @return Node_Column_Container
+     */
+    public function __construct()
+    {
+        parent::__construct(__('Functions'), Node::CONTAINER);
+        $this->icon  = PMA_Util::getImage('b_routines.png');
+        $this->links = array(
+            'text' => 'db_routines.php?server=' . $GLOBALS['server']
+                    . '&db=%1$s&token=' . $GLOBALS['token'],
+            'icon' => 'db_routines.php?server=' . $GLOBALS['server']
+                    . '&db=%1$s&token=' . $GLOBALS['token'],
+        );
+        $this->real_name = 'functions';
+
+        $new        = PMA_NodeFactory::getInstance('Node', _pgettext('Create new function', 'New'));
+        $new->isNew = true;
+        $new->icon  = PMA_Util::getImage('b_routine_add.png', '');
+        $new->links = array(
+            'text' => 'db_routines.php?server=' . $GLOBALS['server']
+                    . '&db=%2$s&token=' . $GLOBALS['token']
+                    . '&add_item=1&item_type=FUNCTION',
+            'icon' => 'db_routines.php?server=' . $GLOBALS['server']
+                    . '&db=%2$s&token=' . $GLOBALS['token']
+                    . '&add_item=1&item_type=FUNCTION',
+        );
+        $new->classes = 'new_function italics';
+        $this->addChild($new);
+    }
+}
+
+?>
diff --git a/phpmyadmin/libraries/navigation/Nodes/Node_Index.class.php b/phpmyadmin/libraries/navigation/Nodes/Node_Index.class.php
new file mode 100644
index 0000000..918a212
--- /dev/null
+++ b/phpmyadmin/libraries/navigation/Nodes/Node_Index.class.php
@@ -0,0 +1,45 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * Functionality for the navigation tree
+ *
+ * @package PhpMyAdmin-Navigation
+ */
+if (! defined('PHPMYADMIN')) {
+    exit;
+}
+
+/**
+ * Represents a index node in the navigation tree
+ *
+ * @package PhpMyAdmin-Navigation
+ */
+class Node_Index extends Node
+{
+    /**
+     * Initialises the class
+     *
+     * @param string $name     An identifier for the new node
+     * @param int    $type     Type of node, may be one of CONTAINER or OBJECT
+     * @param bool   $is_group Whether this object has been created
+     *                         while grouping nodes
+     *
+     * @return Node_Index
+     */
+    public function __construct($name, $type = Node::OBJECT, $is_group = false)
+    {
+        parent::__construct($name, $type, $is_group);
+        $this->icon  = PMA_Util::getImage('b_index.png');
+        $this->links = array(
+            'text' => 'tbl_indexes.php?server=' . $GLOBALS['server']
+                    . '&db=%3$s&table=%2$s&index=%1$s'
+                    . '&token=' . $GLOBALS['token'],
+            'icon' => 'tbl_indexes.php?server=' . $GLOBALS['server']
+                    . '&db=%3$s&table=%2$s&index=%1$s'
+                    . '&token=' . $GLOBALS['token']
+        );
+        $this->classes = 'index';
+    }
+}
+
+?>
diff --git a/phpmyadmin/libraries/navigation/Nodes/Node_Index_Container.class.php b/phpmyadmin/libraries/navigation/Nodes/Node_Index_Container.class.php
new file mode 100644
index 0000000..732dfdd
--- /dev/null
+++ b/phpmyadmin/libraries/navigation/Nodes/Node_Index_Container.class.php
@@ -0,0 +1,54 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * Functionality for the navigation tree
+ *
+ * @package PhpMyAdmin-Navigation
+ */
+if (! defined('PHPMYADMIN')) {
+    exit;
+}
+
+/**
+ * Represents a container for index nodes in the navigation tree
+ *
+ * @package PhpMyAdmin-Navigation
+ */
+class Node_Index_Container extends Node
+{
+    /**
+     * Initialises the class
+     *
+     * @return Node_Index_Container
+     */
+    public function __construct()
+    {
+        parent::__construct(__('Indexes'), Node::CONTAINER);
+        $this->icon  = PMA_Util::getImage('b_index.png', '');
+        $this->links = array(
+            'text' => 'tbl_structure.php?server=' . $GLOBALS['server']
+                    . '&db=%2$s&table=%1$s'
+                    . '&token=' . $GLOBALS['token'],
+            'icon' => 'tbl_structure.php?server=' . $GLOBALS['server']
+                    . '&db=%2$s&table=%1$s'
+                    . '&token=' . $GLOBALS['token'],
+        );
+        $this->real_name = 'indexes';
+
+        $new        = PMA_NodeFactory::getInstance('Node', _pgettext('Create new index', 'New'));
+        $new->isNew = true;
+        $new->icon  = PMA_Util::getImage('b_index_add.png', '');
+        $new->links = array(
+            'text' => 'tbl_indexes.php?server=' . $GLOBALS['server']
+                    . '&create_index=1&added_fields=2'
+                    . '&db=%3$s&table=%2$s&token=' . $GLOBALS['token'],
+            'icon' => 'tbl_indexes.php?server=' . $GLOBALS['server']
+                    . '&create_index=1&added_fields=2'
+                    . '&db=%3$s&table=%2$s&token=' . $GLOBALS['token'],
+        );
+        $new->classes = 'new_index italics';
+        $this->addChild($new);
+    }
+}
+
+?>
diff --git a/phpmyadmin/libraries/navigation/Nodes/Node_Procedure.class.php b/phpmyadmin/libraries/navigation/Nodes/Node_Procedure.class.php
new file mode 100644
index 0000000..e89fe2f
--- /dev/null
+++ b/phpmyadmin/libraries/navigation/Nodes/Node_Procedure.class.php
@@ -0,0 +1,67 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * Functionality for the navigation tree
+ *
+ * @package PhpMyAdmin-Navigation
+ */
+if (! defined('PHPMYADMIN')) {
+    exit;
+}
+
+/**
+ * Represents a procedure node in the navigation tree
+ *
+ * @package PhpMyAdmin-Navigation
+ */
+class Node_Procedure extends Node
+{
+    /**
+     * Initialises the class
+     *
+     * @param string $name     An identifier for the new node
+     * @param int    $type     Type of node, may be one of CONTAINER or OBJECT
+     * @param bool   $is_group Whether this object has been created
+     *                         while grouping nodes
+     *
+     * @return Node_Procedure
+     */
+    public function __construct($name, $type = Node::OBJECT, $is_group = false)
+    {
+        parent::__construct($name, $type, $is_group);
+        $this->icon  = PMA_Util::getImage('b_routines.png');
+        $this->links = array(
+            'text' => 'db_routines.php?server=' . $GLOBALS['server']
+                    . '&db=%2$s&item_name=%1$s&item_type=PROCEDURE'
+                    . '&edit_item=1&token=' . $GLOBALS['token'],
+            'icon' => 'db_routines.php?server=' . $GLOBALS['server']
+                    . '&db=%2$s&item_name=%1$s&item_type=PROCEDURE'
+                    . '&export_item=1&token=' . $GLOBALS['token']
+        );
+        $this->classes = 'procedure';
+    }
+
+    /**
+     * Returns the comment associated with node
+     * This method should be overridden by specific type of nodes
+     *
+     * @return string
+     */
+    public function getComment()
+    {
+        $db    = PMA_Util::sqlAddSlashes(
+            $this->realParent()->real_name
+        );
+        $routine = PMA_Util::sqlAddSlashes(
+            $this->real_name
+        );
+        $query  = "SELECT `ROUTINE_COMMENT` ";
+        $query .= "FROM `INFORMATION_SCHEMA`.`ROUTINES` ";
+        $query .= "WHERE `ROUTINE_SCHEMA`='$db' ";
+        $query .= "AND `ROUTINE_NAME`='$routine' ";
+        $query .= "AND `ROUTINE_TYPE`='PROCEDURE' ";
+        return PMA_DBI_fetch_value($query);
+    }
+}
+
+?>
diff --git a/phpmyadmin/libraries/navigation/Nodes/Node_Procedure_Container.class.php b/phpmyadmin/libraries/navigation/Nodes/Node_Procedure_Container.class.php
new file mode 100644
index 0000000..8af1185
--- /dev/null
+++ b/phpmyadmin/libraries/navigation/Nodes/Node_Procedure_Container.class.php
@@ -0,0 +1,52 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * Functionality for the navigation tree
+ *
+ * @package PhpMyAdmin-Navigation
+ */
+if (! defined('PHPMYADMIN')) {
+    exit;
+}
+
+/**
+ * Represents a container for procedure nodes in the navigation tree
+ *
+ * @package PhpMyAdmin-Navigation
+ */
+class Node_Procedure_Container extends Node
+{
+    /**
+     * Initialises the class
+     *
+     * @return Node_Procedure_Container
+     */
+    public function __construct()
+    {
+        parent::__construct(__('Procedures'), Node::CONTAINER);
+        $this->icon  = PMA_Util::getImage('b_routines.png');
+        $this->links = array(
+            'text' => 'db_routines.php?server=' . $GLOBALS['server']
+                    . '&db=%1$s&token=' . $GLOBALS['token'],
+            'icon' => 'db_routines.php?server=' . $GLOBALS['server']
+                    . '&db=%1$s&token=' . $GLOBALS['token'],
+        );
+        $this->real_name = 'procedures';
+
+        $new        = PMA_NodeFactory::getInstance('Node', _pgettext('Create new procedure', 'New'));
+        $new->isNew = true;
+        $new->icon  = PMA_Util::getImage('b_routine_add.png', '');
+        $new->links = array(
+            'text' => 'db_routines.php?server=' . $GLOBALS['server']
+                    . '&db=%2$s&token=' . $GLOBALS['token']
+                    . '&add_item=1',
+            'icon' => 'db_routines.php?server=' . $GLOBALS['server']
+                    . '&db=%2$s&token=' . $GLOBALS['token']
+                    . '&add_item=1',
+        );
+        $new->classes = 'new_procedure italics';
+        $this->addChild($new);
+    }
+}
+
+?>
diff --git a/phpmyadmin/libraries/navigation/Nodes/Node_Table.class.php b/phpmyadmin/libraries/navigation/Nodes/Node_Table.class.php
new file mode 100644
index 0000000..c5449d9
--- /dev/null
+++ b/phpmyadmin/libraries/navigation/Nodes/Node_Table.class.php
@@ -0,0 +1,229 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * Functionality for the navigation tree
+ *
+ * @package PhpMyAdmin-Navigation
+ */
+if (! defined('PHPMYADMIN')) {
+    exit;
+}
+
+/**
+ * Represents a columns node in the navigation tree
+ *
+ * @package PhpMyAdmin-Navigation
+ */
+class Node_Table extends Node
+{
+    /**
+     * Initialises the class
+     *
+     * @param string $name     An identifier for the new node
+     * @param int    $type     Type of node, may be one of CONTAINER or OBJECT
+     * @param bool   $is_group Whether this object has been created
+     *                         while grouping nodes
+     *
+     * @return Node_Table
+     */
+    public function __construct($name, $type = Node::OBJECT, $is_group = false)
+    {
+        parent::__construct($name, $type, $is_group);
+        $this->icon  = PMA_Util::getImage('b_browse.png');
+        $this->links = array(
+            'text' => 'sql.php?server=' . $GLOBALS['server']
+                    . '&db=%2$s&table=%1$s'
+                    . '&pos=0&token=' . $GLOBALS['token'],
+            'icon' => $GLOBALS['cfg']['NavigationTreeDefaultTabTable']
+                    . '?server=' . $GLOBALS['server']
+                    . '&db=%2$s&table=%1$s&token=' . $GLOBALS['token']
+        );
+    }
+
+    /**
+     * Returns the number of children of type $type present inside this container
+     * This method is overridden by the Node_Database and Node_Table classes
+     *
+     * @param string $type         The type of item we are looking for
+     *                             ('columns' or 'indexes')
+     * @param string $searchClause A string used to filter the results of the query
+     *
+     * @return int
+     */
+    public function getPresence($type = '', $searchClause = '')
+    {
+        $retval = 0;
+        $db     = $this->realParent()->real_name;
+        $table  = $this->real_name;
+        switch ($type) {
+        case 'columns':
+            if (! $GLOBALS['cfg']['Servers'][$GLOBALS['server']]['DisableIS']) {
+                $db     = PMA_Util::sqlAddSlashes($db);
+                $table  = PMA_Util::sqlAddSlashes($table);
+                $query  = "SELECT COUNT(*) ";
+                $query .= "FROM `INFORMATION_SCHEMA`.`COLUMNS` ";
+                $query .= "WHERE `TABLE_NAME`='$table' ";
+                $query .= "AND `TABLE_SCHEMA`='$db'";
+                $retval = (int)PMA_DBI_fetch_value($query);
+            } else {
+                $db     = PMA_Util::backquote($db);
+                $table  = PMA_Util::backquote($table);
+                $query  = "SHOW COLUMNS FROM $table FROM $db";
+                $retval = (int)PMA_DBI_num_rows(PMA_DBI_try_query($query));
+            }
+            break;
+        case 'indexes':
+            $db     = PMA_Util::backquote($db);
+            $table  = PMA_Util::backquote($table);
+            $query  = "SHOW INDEXES FROM $table FROM $db";
+            $retval = (int)PMA_DBI_num_rows(PMA_DBI_try_query($query));
+            break;
+        case 'triggers':
+            if (! $GLOBALS['cfg']['Servers'][$GLOBALS['server']]['DisableIS']) {
+                $db     = PMA_Util::sqlAddSlashes($db);
+                $table  = PMA_Util::sqlAddSlashes($table);
+                $query  = "SELECT COUNT(*) ";
+                $query .= "FROM `INFORMATION_SCHEMA`.`TRIGGERS` ";
+                $query .= "WHERE `EVENT_OBJECT_SCHEMA`='$db' ";
+                $query .= "AND `EVENT_OBJECT_TABLE`='$table'";
+                $retval = (int)PMA_DBI_fetch_value($query);
+            } else {
+                $db     = PMA_Util::backquote($db);
+                $table  = PMA_Util::sqlAddSlashes($table);
+                $query  = "SHOW TRIGGERS FROM $db WHERE `Table` = '$table'";
+                $retval = (int)PMA_DBI_num_rows(PMA_DBI_try_query($query));
+            }
+            break;
+        default:
+            break;
+        }
+        return $retval;
+    }
+
+    /**
+     * Returns the names of children of type $type present inside this container
+     * This method is overridden by the Node_Database and Node_Table classes
+     *
+     * @param string $type         The type of item we are looking for
+     *                             ('tables', 'views', etc)
+     * @param int    $pos          The offset of the list within the results
+     * @param string $searchClause A string used to filter the results of the query
+     *
+     * @return array
+     */
+    public function getData($type, $pos, $searchClause = '')
+    {
+        $maxItems = $GLOBALS['cfg']['MaxNavigationItems'];
+        $retval   = array();
+        $db       = $this->realParent()->real_name;
+        $table    = $this->real_name;
+        switch ($type) {
+        case 'columns':
+            if (! $GLOBALS['cfg']['Servers'][$GLOBALS['server']]['DisableIS']) {
+                $db     = PMA_Util::sqlAddSlashes($db);
+                $table  = PMA_Util::sqlAddSlashes($table);
+                $query  = "SELECT `COLUMN_NAME` AS `name` ";
+                $query .= "FROM `INFORMATION_SCHEMA`.`COLUMNS` ";
+                $query .= "WHERE `TABLE_NAME`='$table' ";
+                $query .= "AND `TABLE_SCHEMA`='$db' ";
+                $query .= "ORDER BY `COLUMN_NAME` ASC ";
+                $query .= "LIMIT " . intval($pos) . ", $maxItems";
+                $retval = PMA_DBI_fetch_result($query);
+            } else {
+                $db     = PMA_Util::backquote($db);
+                $table  = PMA_Util::backquote($table);
+                $query  = "SHOW COLUMNS FROM $table FROM $db";
+                $handle = PMA_DBI_try_query($query);
+                if ($handle !== false) {
+                    $count = 0;
+                    while ($arr = PMA_DBI_fetch_array($handle)) {
+                        if ($pos <= 0 && $count < $maxItems) {
+                            $retval[] = $arr['Field'];
+                            $count++;
+                        }
+                        $pos--;
+                    }
+                }
+            }
+            break;
+        case 'indexes':
+            $db     = PMA_Util::backquote($db);
+            $table  = PMA_Util::backquote($table);
+            $query  = "SHOW INDEXES FROM $table FROM $db";
+            $handle = PMA_DBI_try_query($query);
+            if ($handle !== false) {
+                $count = 0;
+                while ($arr = PMA_DBI_fetch_array($handle)) {
+                    if (! in_array($arr['Key_name'], $retval)) {
+                        if ($pos <= 0 && $count < $maxItems) {
+                            $retval[] = $arr['Key_name'];
+                            $count++;
+                        }
+                        $pos--;
+                    }
+                }
+            }
+            break;
+        case 'triggers':
+            if (! $GLOBALS['cfg']['Servers'][$GLOBALS['server']]['DisableIS']) {
+                $db     = PMA_Util::sqlAddSlashes($db);
+                $table  = PMA_Util::sqlAddSlashes($table);
+                $query  = "SELECT `TRIGGER_NAME` AS `name` ";
+                $query .= "FROM `INFORMATION_SCHEMA`.`TRIGGERS` ";
+                $query .= "WHERE `EVENT_OBJECT_SCHEMA`='$db' ";
+                $query .= "AND `EVENT_OBJECT_TABLE`='$table' ";
+                $query .= "ORDER BY `TRIGGER_NAME` ASC ";
+                $query .= "LIMIT " . intval($pos) . ", $maxItems";
+                $retval = PMA_DBI_fetch_result($query);
+            } else {
+                $db     = PMA_Util::backquote($db);
+                $table  = PMA_Util::sqlAddSlashes($table);
+                $query  = "SHOW TRIGGERS FROM $db WHERE `Table` = '$table'";
+                $handle = PMA_DBI_try_query($query);
+                if ($handle !== false) {
+                    $count = 0;
+                    while ($arr = PMA_DBI_fetch_array($handle)) {
+                        if ($pos <= 0 && $count < $maxItems) {
+                            $retval[] = $arr['Trigger'];
+                            $count++;
+                        }
+                        $pos--;
+                    }
+                }
+            }
+            break;
+        default:
+            break;
+        }
+        return $retval;
+    }
+
+    /**
+     * Returns the comment associated with node
+     * This method should be overridden by specific type of nodes
+     *
+     * @return string
+     */
+    public function getComment()
+    {
+        $db    = $this->realParent()->real_name;
+        $table = PMA_Util::sqlAddSlashes($this->real_name);
+        if (! $GLOBALS['cfg']['Servers'][$GLOBALS['server']]['DisableIS']) {
+            $db     = PMA_Util::sqlAddSlashes($db);
+            $query  = "SELECT `TABLE_COMMENT` ";
+            $query .= "FROM `INFORMATION_SCHEMA`.`TABLES` ";
+            $query .= "WHERE `TABLE_SCHEMA`='$db' ";
+            $query .= "AND `TABLE_NAME`='$table' ";
+            $retval = PMA_DBI_fetch_value($query);
+        } else {
+            $db     = PMA_Util::backquote($db);
+            $query  = "SHOW TABLE STATUS FROM $db ";
+            $query .= "WHERE Name = '$table'";
+            $arr = PMA_DBI_fetch_assoc(PMA_DBI_try_query($query));
+            $retval = $arr['Comment'];
+        }
+        return $retval;
+    }
+}
+
+?>
diff --git a/phpmyadmin/libraries/navigation/Nodes/Node_Table_Container.class.php b/phpmyadmin/libraries/navigation/Nodes/Node_Table_Container.class.php
new file mode 100644
index 0000000..3d3ef14
--- /dev/null
+++ b/phpmyadmin/libraries/navigation/Nodes/Node_Table_Container.class.php
@@ -0,0 +1,54 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * Functionality for the navigation tree
+ *
+ * @package PhpMyAdmin-Navigation
+ */
+if (! defined('PHPMYADMIN')) {
+    exit;
+}
+
+/**
+ * Represents a container for table nodes in the navigation tree
+ *
+ * @package PhpMyAdmin-Navigation
+ */
+class Node_Table_Container extends Node
+{
+    /**
+     * Initialises the class
+     *
+     * @return Node_Table_Container
+     */
+    public function __construct()
+    {
+        parent::__construct(__('Tables'), Node::CONTAINER);
+        $this->icon  = PMA_Util::getImage('b_browse.png', '');
+        $this->links = array(
+            'text' => 'db_structure.php?server=' . $GLOBALS['server']
+                    . '&db=%1$s&token=' . $GLOBALS['token'],
+            'icon' => 'db_structure.php?server=' . $GLOBALS['server']
+                    . '&db=%1$s&token=' . $GLOBALS['token'],
+        );
+        if ($GLOBALS['cfg']['NavigationTreeEnableGrouping']) {
+            $this->separator       = $GLOBALS['cfg']['NavigationTreeTableSeparator'];
+            $this->separator_depth = (int)($GLOBALS['cfg']['NavigationTreeTableLevel']);
+        }
+        $this->real_name       = 'tables';
+
+        $new        = PMA_NodeFactory::getInstance('Node', _pgettext('Create new table', 'New'));
+        $new->isNew = true;
+        $new->icon  = PMA_Util::getImage('b_table_add.png', '');
+        $new->links = array(
+            'text' => 'tbl_create.php?server=' . $GLOBALS['server']
+                    . '&db=%2$s&token=' . $GLOBALS['token'],
+            'icon' => 'tbl_create.php?server=' . $GLOBALS['server']
+                    . '&db=%2$s&token=' . $GLOBALS['token'],
+        );
+        $new->classes = 'new_table italics';
+        $this->addChild($new);
+    }
+}
+
+?>
diff --git a/phpmyadmin/libraries/navigation/Nodes/Node_Trigger.class.php b/phpmyadmin/libraries/navigation/Nodes/Node_Trigger.class.php
new file mode 100644
index 0000000..bc51106
--- /dev/null
+++ b/phpmyadmin/libraries/navigation/Nodes/Node_Trigger.class.php
@@ -0,0 +1,45 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * Functionality for the navigation tree
+ *
+ * @package PhpMyAdmin-Navigation
+ */
+if (! defined('PHPMYADMIN')) {
+    exit;
+}
+
+/**
+ * Represents a trigger node in the navigation tree
+ *
+ * @package PhpMyAdmin-Navigation
+ */
+class Node_Trigger extends Node
+{
+    /**
+     * Initialises the class
+     *
+     * @param string $name     An identifier for the new node
+     * @param int    $type     Type of node, may be one of CONTAINER or OBJECT
+     * @param bool   $is_group Whether this object has been created
+     *                         while grouping nodes
+     *
+     * @return Node_Trigger
+     */
+    public function __construct($name, $type = Node::OBJECT, $is_group = false)
+    {
+        parent::__construct($name, $type, $is_group);
+        $this->icon  = PMA_Util::getImage('b_triggers.png');
+        $this->links = array(
+            'text' => 'db_triggers.php?server=' . $GLOBALS['server']
+                    . '&db=%3$s&item_name=%1$s&edit_item=1'
+                    . '&token=' . $GLOBALS['token'],
+            'icon' => 'db_triggers.php?server=' . $GLOBALS['server']
+                    . '&db=%3$s&item_name=%1$s&export_item=1'
+                    . '&token=' . $GLOBALS['token']
+        );
+        $this->classes = 'trigger';
+    }
+}
+
+?>
diff --git a/phpmyadmin/libraries/navigation/Nodes/Node_Trigger_Container.class.php b/phpmyadmin/libraries/navigation/Nodes/Node_Trigger_Container.class.php
new file mode 100644
index 0000000..7f8f3cb
--- /dev/null
+++ b/phpmyadmin/libraries/navigation/Nodes/Node_Trigger_Container.class.php
@@ -0,0 +1,53 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * Functionality for the navigation tree
+ *
+ * @package PhpMyAdmin-Navigation
+ */
+if (! defined('PHPMYADMIN')) {
+    exit;
+}
+
+/**
+ * Represents a container for trigger nodes in the navigation tree
+ *
+ * @package PhpMyAdmin-Navigation
+ */
+class Node_Trigger_Container extends Node
+{
+    /**
+     * Initialises the class
+     *
+     * @return Node_Trigger_Container
+     */
+    public function __construct()
+    {
+        parent::__construct(__('Triggers'), Node::CONTAINER);
+        $this->icon  = PMA_Util::getImage('b_triggers.png');
+        $this->links = array(
+            'text' => 'db_triggers.php?server=' . $GLOBALS['server']
+                    . '&db=%2$s&table=%1$s&token=' . $GLOBALS['token'],
+            'icon' => 'db_triggers.php?server=' . $GLOBALS['server']
+                    . '&db=%2$s&table=%1$s&token=' . $GLOBALS['token']
+        );
+        $this->real_name = 'triggers';
+
+        $new        = PMA_NodeFactory::getInstance('Node', _pgettext('Create new trigger', 'New'));
+        $new->isNew = true;
+        $new->icon  = PMA_Util::getImage('b_trigger_add.png', '');
+        $new->links = array(
+            'text' => 'db_triggers.php?server=' . $GLOBALS['server']
+                    . '&db=%3$s&token=' . $GLOBALS['token']
+                    . '&add_item=1',
+            'icon' => 'db_triggers.php?server=' . $GLOBALS['server']
+                    . '&db=%3$s&token=' . $GLOBALS['token']
+                    . '&add_item=1',
+        );
+        $new->classes = 'new_trigger italics';
+        $this->addChild($new);
+    }
+
+}
+
+?>
diff --git a/phpmyadmin/libraries/navigation/Nodes/Node_View.class.php b/phpmyadmin/libraries/navigation/Nodes/Node_View.class.php
new file mode 100644
index 0000000..3f47579
--- /dev/null
+++ b/phpmyadmin/libraries/navigation/Nodes/Node_View.class.php
@@ -0,0 +1,44 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * Functionality for the navigation tree
+ *
+ * @package PhpMyAdmin-Navigation
+ */
+if (! defined('PHPMYADMIN')) {
+    exit;
+}
+
+/**
+ * Represents a view node in the navigation tree
+ *
+ * @package PhpMyAdmin-Navigation
+ */
+class Node_View extends Node
+{
+    /**
+     * Initialises the class
+     *
+     * @param string $name     An identifier for the new node
+     * @param int    $type     Type of node, may be one of CONTAINER or OBJECT
+     * @param bool   $is_group Whether this object has been created
+     *                         while grouping nodes
+     *
+     * @return Node_View
+     */
+    public function __construct($name, $type = Node::OBJECT, $is_group = false)
+    {
+        parent::__construct($name, $type, $is_group);
+        $this->icon  = PMA_Util::getImage('b_views.png');
+        $this->links = array(
+            'text' => 'sql.php?server=' . $GLOBALS['server']
+                    . '&db=%2$s&table=%1$s&pos=0'
+                    . '&token=' . $GLOBALS['token'],
+            'icon' => 'tbl_structure.php?server=' . $GLOBALS['server']
+                    . '&db=%2$s&table=%1$s'
+                    . '&token=' . $GLOBALS['token']
+        );
+    }
+}
+
+?>
diff --git a/phpmyadmin/libraries/navigation/Nodes/Node_View_Container.class.php b/phpmyadmin/libraries/navigation/Nodes/Node_View_Container.class.php
new file mode 100644
index 0000000..ada9027
--- /dev/null
+++ b/phpmyadmin/libraries/navigation/Nodes/Node_View_Container.class.php
@@ -0,0 +1,50 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * Functionality for the navigation tree
+ *
+ * @package PhpMyAdmin-Navigation
+ */
+if (! defined('PHPMYADMIN')) {
+    exit;
+}
+
+/**
+ * Represents a container for view nodes in the navigation tree
+ *
+ * @package PhpMyAdmin-Navigation
+ */
+class Node_View_Container extends Node
+{
+    /**
+     * Initialises the class
+     *
+     * @return Node_View_Container
+     */
+    public function __construct()
+    {
+        parent::__construct(__('Views'), Node::CONTAINER);
+        $this->icon  = PMA_Util::getImage('b_views.png', '');
+        $this->links = array(
+            'text' => 'db_structure.php?server=' . $GLOBALS['server']
+                    . '&db=%1$s&token=' . $GLOBALS['token'],
+            'icon' => 'db_structure.php?server=' . $GLOBALS['server']
+                    . '&db=%1$s&token=' . $GLOBALS['token'],
+        );
+        $this->real_name = 'views';
+
+        $new        = PMA_NodeFactory::getInstance('Node', _pgettext('Create new view', 'New'));
+        $new->isNew = true;
+        $new->icon  = PMA_Util::getImage('b_view_add.png', '');
+        $new->links = array(
+            'text' => 'view_create.php?server=' . $GLOBALS['server']
+                    . '&db=%2$s&token=' . $GLOBALS['token'],
+            'icon' => 'view_create.php?server=' . $GLOBALS['server']
+                    . '&db=%2$s&token=' . $GLOBALS['token'],
+        );
+        $new->classes = 'new_view italics';
+        $this->addChild($new);
+    }
+}
+
+?>
diff --git a/phpmyadmin/libraries/opendocument.lib.php b/phpmyadmin/libraries/opendocument.lib.php
new file mode 100644
index 0000000..b132503
--- /dev/null
+++ b/phpmyadmin/libraries/opendocument.lib.php
@@ -0,0 +1,170 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * Simple interface for creating OASIS OpenDocument files.
+ *
+ * @package PhpMyAdmin
+ */
+if (! defined('PHPMYADMIN')) {
+    exit;
+}
+
+/**
+ * Load ZIP handler.
+ */
+require_once './libraries/zip.lib.php';
+
+$GLOBALS['OpenDocumentNS']
+    = 'xmlns:office="urn:oasis:names:tc:opendocument:xmlns:office:1.0" '
+    . 'xmlns:text="urn:oasis:names:tc:opendocument:xmlns:text:1.0" '
+    . 'xmlns:table="urn:oasis:names:tc:opendocument:xmlns:table:1.0" '
+    . 'xmlns:style="urn:oasis:names:tc:opendocument:xmlns:style:1.0" '
+    . 'xmlns:fo="urn:oasis:names:tc:opendocument:xmlns:xsl-fo-compatible:1.0" ';
+
+/**
+ * Minimalistic creator of OASIS OpenDocument
+ *
+ * @param string $mime desired MIME type
+ * @param string $data document content
+ *
+ * @return string  OASIS OpenDocument data
+ *
+ * @access  public
+ */
+function PMA_createOpenDocument($mime, $data)
+{
+    $zipfile = new ZipFile();
+    $zipfile -> addFile($mime, 'mimetype');
+    $zipfile -> addFile($data, 'content.xml');
+    $zipfile -> addFile(
+        '<?xml version="1.0" encoding="UTF-8"?'. '>'
+        . '<office:document-meta '
+        . 'xmlns:office="urn:oasis:names:tc:opendocument:xmlns:office:1.0" '
+        . 'xmlns:meta="urn:oasis:names:tc:opendocument:xmlns:meta:1.0" '
+        . 'office:version="1.0">'
+        . '<office:meta>'
+        . '<meta:generator>phpMyAdmin ' . PMA_VERSION . '</meta:generator>'
+        . '<meta:initial-creator>phpMyAdmin ' . PMA_VERSION
+        . '</meta:initial-creator>'
+        . '<meta:creation-date>' . strftime('%Y-%m-%dT%H:%M:%S')
+        . '</meta:creation-date>'
+        . '</office:meta>'
+        . '</office:document-meta>',
+        'meta.xml'
+    );
+    $zipfile -> addFile(
+        '<?xml version="1.0" encoding="UTF-8"?' . '>'
+        . '<office:document-styles '. $GLOBALS['OpenDocumentNS']
+        . 'office:version="1.0">'
+        . '<office:font-face-decls>'
+        . '<style:font-face style:name="Arial Unicode MS"'
+        . ' svg:font-family="\'Arial Unicode MS\'" style:font-pitch="variable"/>'
+        . '<style:font-face style:name="DejaVu Sans1"'
+        . ' svg:font-family="\'DejaVu Sans\'" style:font-pitch="variable"/>'
+        . '<style:font-face style:name="HG Mincho Light J"'
+        . ' svg:font-family="\'HG Mincho Light J\'" style:font-pitch="variable"/>'
+        . '<style:font-face style:name="DejaVu Serif"'
+        . ' svg:font-family="\'DejaVu Serif\'" style:font-family-generic="roman"'
+        . ' style:font-pitch="variable"/>'
+        . '<style:font-face style:name="Thorndale"'
+        . ' svg:font-family="Thorndale" style:font-family-generic="roman"'
+        . ' style:font-pitch="variable"/>'
+        . '<style:font-face style:name="DejaVu Sans"'
+        . ' svg:font-family="\'DejaVu Sans\'" style:font-family-generic="swiss"'
+        . ' style:font-pitch="variable"/>'
+        . '</office:font-face-decls>'
+        . '<office:styles>'
+        . '<style:default-style style:family="paragraph">'
+        . '<style:paragraph-properties fo:hyphenation-ladder-count="no-limit"'
+        . ' style:text-autospace="ideograph-alpha" style:punctuation-wrap="hanging"'
+        . ' style:line-break="strict" style:tab-stop-distance="0.4925in"'
+        . ' style:writing-mode="page"/>'
+        . '<style:text-properties style:use-window-font-color="true"'
+        . ' style:font-name="DejaVu Serif" fo:font-size="12pt" fo:language="en"'
+        . ' fo:country="US" style:font-name-asian="DejaVu Sans1"'
+        . ' style:font-size-asian="12pt" style:language-asian="none"'
+        . ' style:country-asian="none" style:font-name-complex="DejaVu Sans1"'
+        . ' style:font-size-complex="12pt" style:language-complex="none"'
+        . ' style:country-complex="none" fo:hyphenate="false"'
+        . ' fo:hyphenation-remain-char-count="2"'
+        . ' fo:hyphenation-push-char-count="2"/>'
+        . '</style:default-style>'
+        . '<style:style style:name="Standard" style:family="paragraph"'
+        . ' style:class="text"/>'
+        . '<style:style style:name="Text_body" style:display-name="Text body"'
+        . ' style:family="paragraph" style:parent-style-name="Standard"'
+        . ' style:class="text">'
+        . '<style:paragraph-properties fo:margin-top="0in"'
+        . ' fo:margin-bottom="0.0835in"/>'
+        . '</style:style>'
+        . '<style:style style:name="Heading" style:family="paragraph"'
+        . ' style:parent-style-name="Standard" style:next-style-name="Text_body"'
+        . ' style:class="text">'
+        . '<style:paragraph-properties fo:margin-top="0.1665in"'
+        . ' fo:margin-bottom="0.0835in" fo:keep-with-next="always"/>'
+        . '<style:text-properties style:font-name="DejaVu Sans" fo:font-size="14pt"'
+        . ' style:font-name-asian="DejaVu Sans1" style:font-size-asian="14pt"'
+        . ' style:font-name-complex="DejaVu Sans1" style:font-size-complex="14pt"/>'
+        . '</style:style>'
+        . '<style:style style:name="Heading_1" style:display-name="Heading 1"'
+        . ' style:family="paragraph" style:parent-style-name="Heading"'
+        . ' style:next-style-name="Text_body" style:class="text"'
+        . ' style:default-outline-level="1">'
+        . '<style:text-properties style:font-name="Thorndale" fo:font-size="24pt"'
+        . ' fo:font-weight="bold" style:font-name-asian="HG Mincho Light J"'
+        . ' style:font-size-asian="24pt" style:font-weight-asian="bold"'
+        . ' style:font-name-complex="Arial Unicode MS"'
+        . ' style:font-size-complex="24pt" style:font-weight-complex="bold"/>'
+        . '</style:style>'
+        . '<style:style style:name="Heading_2" style:display-name="Heading 2"'
+        . ' style:family="paragraph" style:parent-style-name="Heading"'
+        . ' style:next-style-name="Text_body" style:class="text"'
+        . ' style:default-outline-level="2">'
+        . '<style:text-properties style:font-name="DejaVu Serif"'
+        . ' fo:font-size="18pt" fo:font-weight="bold"'
+        . ' style:font-name-asian="DejaVu Sans1" style:font-size-asian="18pt"'
+        . ' style:font-weight-asian="bold" style:font-name-complex="DejaVu Sans1"'
+        . ' style:font-size-complex="18pt" style:font-weight-complex="bold"/>'
+        . '</style:style>'
+        . '</office:styles>'
+        . '<office:automatic-styles>'
+        . '<style:page-layout style:name="pm1">'
+        . '<style:page-layout-properties fo:page-width="8.2673in"'
+        . ' fo:page-height="11.6925in" style:num-format="1"'
+        . ' style:print-orientation="portrait" fo:margin-top="1in"'
+        . ' fo:margin-bottom="1in" fo:margin-left="1.25in"'
+        . ' fo:margin-right="1.25in" style:writing-mode="lr-tb"'
+        . ' style:footnote-max-height="0in">'
+        . '<style:footnote-sep style:width="0.0071in"'
+        . ' style:distance-before-sep="0.0398in"'
+        . ' style:distance-after-sep="0.0398in" style:adjustment="left"'
+        . ' style:rel-width="25%" style:color="#000000"/>'
+        . '</style:page-layout-properties>'
+        . '<style:header-style/>'
+        . '<style:footer-style/>'
+        . '</style:page-layout>'
+        . '</office:automatic-styles>'
+        . '<office:master-styles>'
+        . '<style:master-page style:name="Standard" style:page-layout-name="pm1"/>'
+        . '</office:master-styles>'
+        . '</office:document-styles>',
+        'styles.xml'
+    );
+    $zipfile -> addFile(
+        '<?xml version="1.0" encoding="UTF-8"?' . '>'
+        . '<manifest:manifest'
+        . ' xmlns:manifest="urn:oasis:names:tc:opendocument:xmlns:manifest:1.0">'
+        . '<manifest:file-entry manifest:media-type="' . $mime
+        . '" manifest:full-path="/"/>'
+        . '<manifest:file-entry manifest:media-type="text/xml"'
+        . ' manifest:full-path="content.xml"/>'
+        . '<manifest:file-entry manifest:media-type="text/xml"'
+        . ' manifest:full-path="meta.xml"/>'
+        . '<manifest:file-entry manifest:media-type="text/xml"'
+        . ' manifest:full-path="styles.xml"/>'
+        . '</manifest:manifest>',
+        'META-INF/manifest.xml'
+    );
+    return $zipfile -> file();
+}
+?>
diff --git a/phpmyadmin/libraries/operations.lib.php b/phpmyadmin/libraries/operations.lib.php
new file mode 100644
index 0000000..94be5a2
--- /dev/null
+++ b/phpmyadmin/libraries/operations.lib.php
@@ -0,0 +1,1609 @@
+<?php
+
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * set of functions with the operations section in pma
+ *
+ * @package PhpMyAdmin
+ */
+
+if (! defined('PHPMYADMIN')) {
+    exit;
+}
+
+/**
+ * Get HTML output for database comment
+ *
+ * @param string $db database name
+ *
+ * @return string $html_output
+ */
+function PMA_getHtmlForDatabaseComment($db)
+{
+    $html_output = '<div class="operations_half_width">'
+        . '<form method="post" action="db_operations.php">'
+        . PMA_generate_common_hidden_inputs($db)
+        . '<fieldset>'
+        . '<legend>';
+    if ($GLOBALS['cfg']['PropertiesIconic']) {
+        $html_output .= '<img class="icon ic_b_comment" '
+            . 'src="themes/dot.gif" alt="" />';
+    }
+    $html_output .=  __('Database comment: ');
+    $html_output .= '</legend>';
+    $html_output .= '<input type="text" name="comment" '
+        . 'class="textfield" size="30"'
+        . 'value="' . htmlspecialchars(PMA_getDBComment($db)) . '" />'
+        . '</fieldset>';
+    $html_output .= '<fieldset class="tblFooters">'
+        . '<input type="submit" value="' . __('Go') . '" />'
+        . '</fieldset>'
+        . '</form>'
+        . '</div>';
+
+    return $html_output;
+}
+
+/**
+ * Get HTML output for rename database
+ *
+ * @param string $db database name
+ *
+ * @return string $html_output
+ */
+function PMA_getHtmlForRenameDatabase($db)
+{
+    $html_output = '<div class="operations_half_width">'
+        . '<form id="rename_db_form" '
+        . 'class="ajax" '
+        . 'method="post" action="db_operations.php" '
+        . 'onsubmit="return emptyFormElements(this, \'newname\')">';
+    if (isset($_REQUEST['db_collation'])) {
+        $html_output .= '<input type="hidden" name="db_collation" '
+            . 'value="' . $_REQUEST['db_collation']
+            .'" />' . "\n";
+    }
+    $html_output .= '<input type="hidden" name="what" value="data" />'
+        . '<input type="hidden" name="db_rename" value="true" />'
+        . PMA_generate_common_hidden_inputs($db)
+        . '<fieldset>'
+        . '<legend>';
+
+    if ($GLOBALS['cfg']['PropertiesIconic']) {
+        $html_output .= PMA_Util::getImage('b_edit.png');
+    }
+    $html_output .= __('Rename database to') . ':'
+        . '</legend>';
+
+    $html_output .= '<input id="new_db_name" type="text" name="newname" '
+        . 'size="30" class="textfield" value="" />'
+        . '</fieldset>'
+        . '<fieldset class="tblFooters">'
+        . '<input id="rename_db_input" type="submit" value="' . __('Go') . '" />'
+        . '</fieldset>'
+        . '</form>'
+        . '</div>';
+
+    return $html_output;
+}
+
+/**
+ * Get HTML for database drop link
+ *
+ * @param string $db database name
+ *
+ * @return string $html_output
+ */
+function PMA_getHtmlForDropDatabaseLink($db)
+{
+    $this_sql_query = 'DROP DATABASE ' . PMA_Util::backquote($db);
+    $this_url_params = array(
+        'sql_query' => $this_sql_query,
+        'back' => 'db_operations.php',
+        'goto' => 'index.php',
+        'reload' => '1',
+        'purge' => '1',
+        'message_to_show' => sprintf(
+            __('Database %s has been dropped.'),
+            htmlspecialchars(PMA_Util::backquote($db))
+        ),
+        'db' => null,
+    );
+
+    $html_output = '<div class="operations_half_width">'
+        . '<fieldset class="caution">';
+    $html_output .= '<legend>';
+    if ($GLOBALS['cfg']['PropertiesIconic']) {
+        $html_output .= PMA_Util::getImage('b_deltbl.png');
+    }
+    $html_output .= __('Remove database')
+        . '</legend>';
+    $html_output .= '<ul>';
+    $html_output .= PMA_getDeleteDataOrTablelink(
+        $this_url_params,
+        'DROP_DATABASE',
+        __('Drop the database (DROP)'),
+        'drop_db_anchor'
+    );
+    $html_output .= '</ul></fieldset>'
+        . '</div>';
+
+    return $html_output;
+}
+
+/**
+ * Get HTML snippet for copy database
+ *
+ * @param string $db database name
+ *
+ * @return string $html_output
+ */
+function PMA_getHtmlForCopyDatabase($db)
+{
+    $drop_clause = 'DROP TABLE / DROP VIEW';
+    $choices = array(
+        'structure' => __('Structure only'),
+        'data'      => __('Structure and data'),
+        'dataonly'  => __('Data only')
+    );
+
+    if (isset($_COOKIE)
+        && isset($_COOKIE['pma_switch_to_new'])
+        && $_COOKIE['pma_switch_to_new'] == 'true'
+    ) {
+        $pma_switch_to_new = 'true';
+    }
+
+    $html_output = '<div class="operations_half_width clearfloat">';
+    $html_output .= '<form id="copy_db_form" '
+        . 'class="ajax" '
+        . 'method="post" action="db_operations.php"'
+        . 'onsubmit="return emptyFormElements(this, \'newname\')">';
+
+    if (isset($_REQUEST['db_collation'])) {
+        $html_output .= '<input type="hidden" name="db_collation" '
+        . 'value="' . $_REQUEST['db_collation'] .'" />' . "\n";
+    }
+    $html_output .= '<input type="hidden" name="db_copy" value="true" />' . "\n"
+        . PMA_generate_common_hidden_inputs($db);
+    $html_output .= '<fieldset>'
+        . '<legend>';
+
+    if ($GLOBALS['cfg']['PropertiesIconic']) {
+        $html_output .= PMA_Util::getImage('b_edit.png');
+    }
+    $html_output .= __('Copy database to') . ':'
+        . '</legend>'
+        . '<input type="text" name="newname" size="30" '
+        . 'class="textfield" value="" /><br />'
+        . PMA_Util::getRadioFields(
+            'what', $choices, 'data', true
+        );
+    $html_output .= '<input type="checkbox" name="create_database_before_copying" '
+        . 'value="1" id="checkbox_create_database_before_copying"'
+        . 'checked="checked" />';
+    $html_output .= '<label for="checkbox_create_database_before_copying">'
+        . __('CREATE DATABASE before copying') . '</label><br />';
+    $html_output .= '<input type="checkbox" name="drop_if_exists" value="true"'
+        . 'id="checkbox_drop" />';
+    $html_output .= '<label for="checkbox_drop">'
+        . sprintf(__('Add %s'), $drop_clause)
+        . '</label><br />';
+    $html_output .= '<input type="checkbox" name="sql_auto_increment" value="1" '
+        . 'checked="checked" id="checkbox_auto_increment" />';
+    $html_output .= '<label for="checkbox_auto_increment">'
+        . __('Add AUTO_INCREMENT value') . '</label><br />';
+    $html_output .= '<input type="checkbox" name="add_constraints" value="1"'
+        . 'id="checkbox_constraints" />';
+    $html_output .= '<label for="checkbox_constraints">'
+        . __('Add constraints') . '</label><br />';
+    $html_output .= '<input type="checkbox" name="switch_to_new" value="true"'
+        . 'id="checkbox_switch"'
+        . ((isset($pma_switch_to_new) && $pma_switch_to_new == 'true')
+            ? ' checked="checked"'
+            : '')
+        . '/>';
+    $html_output .= '<label for="checkbox_switch">'
+        . __('Switch to copied database') . '</label>'
+        . '</fieldset>';
+    $html_output .= '<fieldset class="tblFooters">'
+        . '<input type="submit" name="submit_copy" value="' . __('Go') . '" />'
+        . '</fieldset>'
+        . '</form>'
+        . '</div>';
+
+    return $html_output;
+}
+
+/**
+ * Get HTML snippet for change database charset
+ *
+ * @param string $db    database name
+ * @param string $table tabel name
+ *
+ * @return string $html_output
+ */
+function PMA_getHtmlForChangeDatabaseCharset($db, $table)
+{
+    $html_output = '<div class="operations_half_width">'
+        . '<form id="change_db_charset_form" ';
+    $html_output .= 'class="ajax" ';
+    $html_output .= 'method="post" action="db_operations.php">';
+
+    $html_output .= PMA_generate_common_hidden_inputs($db, $table);
+
+    $html_output .= '<fieldset>' . "\n"
+       . '    <legend>';
+    if ($GLOBALS['cfg']['PropertiesIconic']) {
+        $html_output .= PMA_Util::getImage('s_asci.png');
+    }
+    $html_output .= '<label for="select_db_collation">' . __('Collation')
+        . ':</label>' . "\n"
+        . '</legend>' . "\n"
+        . PMA_generateCharsetDropdownBox(
+            PMA_CSDROPDOWN_COLLATION,
+            'db_collation',
+            'select_db_collation',
+            isset($_REQUEST['db_collation']) ? $_REQUEST['db_collation'] : '',
+            false,
+            3
+        )
+        . '</fieldset>'
+        . '<fieldset class="tblFooters">'
+        . '<input type="submit" name="submitcollation"'
+        . ' value="' . __('Go') . '" />' . "\n"
+        . '</fieldset>' . "\n"
+        . '</form></div>' . "\n";
+
+    return $html_output;
+}
+
+/**
+ * Get HTML snippet for export relational schema view
+ *
+ * @param string $url_query
+ *
+ * @return string $html_output
+ */
+function PMA_getHtmlForExportRelationalSchemaView($url_query)
+{
+    $html_output = '<div class="operations_full_width">'
+        . '<fieldset><a href="schema_edit.php?' . $url_query . '">';
+    if ($GLOBALS['cfg']['PropertiesIconic']) {
+        $html_output .= PMA_Util::getImage(
+            'b_edit.png'
+        );
+    }
+    $html_output .= __('Edit or export relational schema')
+        . '</a></fieldset>'
+        . '</div>';
+
+    return $html_output;
+}
+
+/**
+ * Run the Procedure definitions and function definitions
+ *
+ * to avoid selecting alternatively the current and new db
+ * we would need to modify the CREATE definitions to qualify
+ * the db name
+ *
+ * @param string $db database name
+ *
+ * @return void
+ */
+function PMA_runProcedureAndFunctionDefinitions($db)
+{
+    $procedure_names = PMA_DBI_get_procedures_or_functions($db, 'PROCEDURE');
+    if ($procedure_names) {
+        foreach ($procedure_names as $procedure_name) {
+            PMA_DBI_select_db($db);
+            $tmp_query = PMA_DBI_get_definition(
+                $db, 'PROCEDURE', $procedure_name
+            );
+            // collect for later display
+            $GLOBALS['sql_query'] .= "\n" . $tmp_query;
+            PMA_DBI_select_db($_REQUEST['newname']);
+            PMA_DBI_query($tmp_query);
+        }
+    }
+
+    $function_names = PMA_DBI_get_procedures_or_functions($db, 'FUNCTION');
+    if ($function_names) {
+        foreach ($function_names as $function_name) {
+            PMA_DBI_select_db($db);
+            $tmp_query = PMA_DBI_get_definition($db, 'FUNCTION', $function_name);
+            // collect for later display
+            $GLOBALS['sql_query'] .= "\n" . $tmp_query;
+            PMA_DBI_select_db($_REQUEST['newname']);
+            PMA_DBI_query($tmp_query);
+        }
+    }
+}
+
+/**
+ * Get sql query and create database before copy
+ *
+ * @return string $sql_query
+ */
+function PMA_getSqlQueryAndCreateDbBeforeCopy()
+{
+    // lower_case_table_names=1 `DB` becomes `db`
+    if (! PMA_DRIZZLE) {
+        $lower_case_table_names = PMA_DBI_fetch_value(
+            'SHOW VARIABLES LIKE "lower_case_table_names"', 0, 1
+        );
+        if ($lower_case_table_names === '1') {
+            $_REQUEST['newname'] = PMA_strtolower($_REQUEST['newname']);
+        }
+    }
+
+    $local_query = 'CREATE DATABASE IF NOT EXISTS '
+        . PMA_Util::backquote($_REQUEST['newname']);
+    if (isset($_REQUEST['db_collation'])) {
+        $local_query .= ' DEFAULT'
+            . PMA_generateCharsetQueryPart($_REQUEST['db_collation']);
+    }
+    $local_query .= ';';
+    $sql_query = $local_query;
+    // save the original db name because Tracker.class.php which
+    // may be called under PMA_DBI_query() changes $GLOBALS['db']
+    // for some statements, one of which being CREATE DATABASE
+    $original_db = $GLOBALS['db'];
+    PMA_DBI_query($local_query);
+    $GLOBALS['db'] = $original_db;
+
+    // rebuild the database list because PMA_Table::moveCopy
+    // checks in this list if the target db exists
+    $GLOBALS['pma']->databases->build();
+
+    return $sql_query;
+}
+
+/**
+ * remove all foreign key constraints and return
+ * sql constraints query for full database
+ *
+ * @param array   $tables_full       array of all tables in given db or dbs
+ * @param object  $export_sql_plugin export plugin instance
+ * @param boolean $move              whether databse name is empty or not
+ * @param string  $db                database name
+ *
+ * @return string sql constraints query for full databases
+ */
+function PMA_getSqlConstraintsQueryForFullDb(
+    $tables_full, $export_sql_plugin, $move, $db
+) {
+    $sql_constraints_query_full_db = array();
+    foreach ($tables_full as $each_table => $tmp) {
+        $sql_constraints = '';
+        $sql_drop_foreign_keys = '';
+        $sql_structure = $export_sql_plugin->getTableDef(
+            $db, $each_table, "\n", '', false, false
+        );
+        if ($move && ! empty($sql_drop_foreign_keys)) {
+            PMA_DBI_query($sql_drop_foreign_keys);
+        }
+        // keep the constraint we just dropped
+        if (! empty($sql_constraints)) {
+            $sql_constraints_query_full_db[] = $sql_constraints;
+        }
+    }
+    return $sql_constraints_query_full_db;
+}
+
+/**
+ * Get views as an array and create SQL view stand-in
+ *
+ * @param array  $tables_full       array of all tables in given db or dbs
+ * @param object $export_sql_plugin export plugin instance
+ * @param strin  $db                database name
+ *
+ * @return array $views
+ */
+function PMA_getViewsAndCreateSqlViewStandIn(
+    $tables_full, $export_sql_plugin, $db
+) {
+    $views = array();
+    foreach ($tables_full as $each_table => $tmp) {
+        // to be able to rename a db containing views,
+        // first all the views are collected and a stand-in is created
+        // the real views are created after the tables
+        if (PMA_Table::isView($db, $each_table)) {
+            $views[] = $each_table;
+            // Create stand-in definition to resolve view dependencies
+            $sql_view_standin = $export_sql_plugin->getTableDefStandIn(
+                $db, $each_table, "\n"
+            );
+            PMA_DBI_select_db($_REQUEST['newname']);
+            PMA_DBI_query($sql_view_standin);
+            $GLOBALS['sql_query'] .= "\n" . $sql_view_standin;
+        }
+    }
+    return $views;
+}
+
+/**
+ * Get sql query for copy/rename table and boolean for whether copy/rename or not
+ *
+ * @param array   $tables_full array of all tables in given db or dbs
+ * @param string  $sql_query   sql query for all operations
+ * @param boolean $move        whether databse name is empty or not
+ * @param string  $db          database name
+ *
+ * @return array ($sql_query, $error)
+ */
+function PMA_getSqlQueryForCopyTable($tables_full, $sql_query, $move, $db)
+{
+    $error = false;
+    foreach ($tables_full as $each_table => $tmp) {
+        // skip the views; we have creted stand-in definitions
+        if (PMA_Table::isView($db, $each_table)) {
+            continue;
+        }
+        $back = $sql_query;
+        $sql_query = '';
+
+        // value of $what for this table only
+        $this_what = $_REQUEST['what'];
+
+        // do not copy the data from a Merge table
+        // note: on the calling FORM, 'data' means 'structure and data'
+        if (PMA_Table::isMerge($db, $each_table)) {
+            if ($this_what == 'data') {
+                $this_what = 'structure';
+            }
+            if ($this_what == 'dataonly') {
+                $this_what = 'nocopy';
+            }
+        }
+
+        if ($this_what != 'nocopy') {
+            // keep the triggers from the original db+table
+            // (third param is empty because delimiters are only intended
+            //  for importing via the mysql client or our Import feature)
+            $triggers = PMA_DBI_get_triggers($db, $each_table, '');
+
+            if (! PMA_Table::moveCopy(
+                $db, $each_table, $_REQUEST['newname'], $each_table,
+                (isset($this_what) ? $this_what : 'data'),
+                $move, 'db_copy'
+            )) {
+                $error = true;
+                // $sql_query is filled by PMA_Table::moveCopy()
+                $sql_query = $back . $sql_query;
+                break;
+            }
+            // apply the triggers to the destination db+table
+            if ($triggers) {
+                PMA_DBI_select_db($_REQUEST['newname']);
+                foreach ($triggers as $trigger) {
+                    PMA_DBI_query($trigger['create']);
+                    $GLOBALS['sql_query'] .= "\n" . $trigger['create'] . ';';
+                }
+            }
+
+            // this does not apply to a rename operation
+            if (isset($_REQUEST['add_constraints'])
+                && ! empty($GLOBALS['sql_constraints_query'])
+            ) {
+                $GLOBALS['sql_constraints_query_full_db'][]
+                    = $GLOBALS['sql_constraints_query'];
+                unset($GLOBALS['sql_constraints_query']);
+            }
+        }
+        // $sql_query is filled by PMA_Table::moveCopy()
+        $sql_query = $back . $sql_query;
+    }
+    return array($sql_query, $error);
+}
+
+/**
+ * Run the EVENT definition for selected database
+ *
+ * to avoid selecting alternatively the current and new db
+ * we would need to modify the CREATE definitions to qualify
+ * the db name
+ *
+ * @param string $db database name
+ *
+ * @return void
+ */
+function PMA_runEventDefinitionsForDb($db)
+{
+    $event_names = PMA_DBI_fetch_result(
+        'SELECT EVENT_NAME FROM information_schema.EVENTS WHERE EVENT_SCHEMA= \''
+        . PMA_Util::sqlAddSlashes($db, true) . '\';'
+    );
+    if ($event_names) {
+        foreach ($event_names as $event_name) {
+            PMA_DBI_select_db($db);
+            $tmp_query = PMA_DBI_get_definition($db, 'EVENT', $event_name);
+            // collect for later display
+            $GLOBALS['sql_query'] .= "\n" . $tmp_query;
+            PMA_DBI_select_db($_REQUEST['newname']);
+            PMA_DBI_query($tmp_query);
+        }
+    }
+}
+
+/**
+ * Handle the views, return the boolean value whether table rename/copy or not
+ *
+ * @param array   $views views as an array
+ * @param boolean $move  whether databse name is empty or not
+ * @param string  $db    database name
+ *
+ * @return boolean $_error whether table rename/copy or not
+ */
+function PMA_handleTheViews($views, $move, $db)
+{
+    $_error = false;
+    // temporarily force to add DROP IF EXIST to CREATE VIEW query,
+    // to remove stand-in VIEW that was created earlier
+    // ( $_REQUEST['drop_if_exists'] is used in moveCopy() )
+    if (isset($_REQUEST['drop_if_exists'])) {
+        $temp_drop_if_exists = $_REQUEST['drop_if_exists'];
+    }
+    $_REQUEST['drop_if_exists'] = 'true';
+
+    foreach ($views as $view) {
+        $copying_succeeded = PMA_Table::moveCopy(
+            $db, $view, $_REQUEST['newname'], $view, 'structure', $move, 'db_copy'
+        );
+        if (! $copying_succeeded) {
+            $_error = true;
+            break;
+        }
+    }
+    unset($_REQUEST['drop_if_exists']);
+    if (isset($temp_drop_if_exists)) {
+        // restore previous value
+        $_REQUEST['drop_if_exists'] = $temp_drop_if_exists;
+    }
+    return $_error;
+}
+
+/**
+ * Create all accumulated constraaints
+ *
+ * @return void
+ */
+function PMA_createAllAccumulatedConstraints()
+{
+    PMA_DBI_select_db($_REQUEST['newname']);
+    foreach ($GLOBALS['sql_constraints_query_full_db'] as $one_query) {
+        PMA_DBI_query($one_query);
+        // and prepare to display them
+        $GLOBALS['sql_query'] .= "\n" . $one_query;
+    }
+    unset($GLOBALS['sql_constraints_query_full_db']);
+}
+
+/**
+ * Duplicate the bookmarks for the db (done once for each db)
+ *
+ * @param boolean $_error whether table rename/copy or not
+ * @param string  $db     database name
+ *
+ * @return void
+ */
+function PMA_duplicateBookmarks($_error, $db)
+{
+    if (! $_error && $db != $_REQUEST['newname']) {
+        $get_fields = array('user', 'label', 'query');
+        $where_fields = array('dbase' => $db);
+        $new_fields = array('dbase' => $_REQUEST['newname']);
+        PMA_Table::duplicateInfo(
+            'bookmarkwork', 'bookmark', $get_fields,
+            $where_fields, $new_fields
+        );
+    }
+}
+
+/**
+ * Get the HTML snippet for order the table
+ *
+ * @param array $columns columns array
+ *
+ * @return string $html_out
+ */
+function PMA_getHtmlForOrderTheTable($columns)
+{
+    $html_output = '<div class="operations_half_width">';
+    $html_output .= '<form method="post" id="alterTableOrderby" '
+        . 'action="tbl_operations.php">';
+    $html_output .= PMA_generate_common_hidden_inputs(
+        $GLOBALS['db'], $GLOBALS['table']
+    );
+    $html_output .= '<fieldset id="fieldset_table_order">'
+        . '<legend>' . __('Alter table order by') . '</legend>'
+        . '<select name="order_field">';
+
+    foreach ($columns as $fieldname) {
+        $html_output .= '<option '
+            . 'value="' . htmlspecialchars($fieldname['Field']) . '">'
+            . htmlspecialchars($fieldname['Field']) . '</option>' . "\n";
+    }
+    $html_output .= '</select> ' . __('(singly)') . ' '
+        . '<select name="order_order">'
+        . '<option value="asc">' . __('Ascending') . '</option>'
+        . '<option value="desc">' . __('Descending') . '</option>'
+        . '</select>'
+        . '</fieldset>'
+        . '<fieldset class="tblFooters">'
+        . '<input type="hidden" name="submitorderby" value="1" />'
+        . '<input type="submit" value="' . __('Go') . '" />'
+        . '</fieldset>'
+        . '</form>'
+        . '</div>';
+
+     return $html_output;
+}
+
+/**
+ * Get the HTML snippet for move table
+ *
+ * @return string $html_output
+ */
+function PMA_getHtmlForMoveTable()
+{
+    $html_output = '<div class="operations_half_width">';
+    $html_output .= '<form method="post" action="tbl_operations.php"'
+        . ' id="moveTableForm" class="ajax"'
+        . ' onsubmit="return emptyFormElements(this, \'new_name\')">'
+        . PMA_generate_common_hidden_inputs($GLOBALS['db'], $GLOBALS['table']);
+
+    $html_output .= '<input type="hidden" name="reload" value="1" />'
+        . '<input type="hidden" name="what" value="data" />'
+        . '<fieldset id="fieldset_table_rename">';
+
+    $html_output .= '<legend>' . __('Move table to (database<b>.</b>table):')
+        . '</legend>';
+
+    if (count($GLOBALS['pma']->databases) > $GLOBALS['cfg']['MaxDbList']) {
+        $html_output .= '<input type="text" maxlength="100" size="30" '
+            . 'name="target_db" value="' . htmlspecialchars($GLOBALS['db'])
+            . '"/>';
+    } else {
+        $html_output .= '<select name="target_db">'
+            . $GLOBALS['pma']->databases->getHtmlOptions(true, false)
+            . '</select>';
+    }
+    $html_output .= ' <strong>.</strong> ';
+    $html_output .= '<input type="text" size="20" name="new_name"'
+        . ' onfocus="this.select()"'
+        . 'value="' . htmlspecialchars($GLOBALS['table']) . '" /><br />';
+
+    // starting with MySQL 5.0.24, SHOW CREATE TABLE includes the AUTO_INCREMENT
+    // next value but users can decide if they want it or not for the operation
+
+    $html_output .= '<input type="checkbox" name="sql_auto_increment" '
+        . 'value="1" id="checkbox_auto_increment_mv" checked="checked" />'
+        . '<label for="checkbox_auto_increment_mv">'
+        . __('Add AUTO_INCREMENT value')
+        . '</label><br />'
+        . '</fieldset>';
+
+    $html_output .= '<fieldset class="tblFooters">'
+        . '<input type="submit" name="submit_move" value="' . __('Go') . '" />'
+        . '</fieldset>'
+        . '</form>'
+        . '</div>';
+
+    return $html_output;
+}
+
+/**
+ * Get the HTML div for Table option
+ *
+ * @param string  $comment            Comment
+ * @param array   $tbl_collation      table collation
+ * @param string  $tbl_storage_engine table storage engine
+ * @param boolean $is_myisam_or_aria  whether MYISAM | ARIA or not
+ * @param boolean $is_isam            whether ISAM or not
+ * @param array   $pack_keys          pack keys
+ * @param string  $auto_increment     value of auto increment
+ * @param string  $delay_key_write    delay key write
+ * @param string  $transactional      value of transactional
+ * @param string  $page_checksum      value of page checksum
+ * @param boolean $is_innodb          whether INNODB or not
+ * @param boolean $is_pbxt            whether PBXT or not
+ * @param boolean $is_aria            whether ARIA or not
+ * @param string  $checksum           the checksum
+ *
+ * @return string $html_output
+ */
+function PMA_getTableOptionDiv($comment, $tbl_collation, $tbl_storage_engine,
+    $is_myisam_or_aria, $is_isam, $pack_keys, $auto_increment, $delay_key_write,
+    $transactional, $page_checksum, $is_innodb, $is_pbxt, $is_aria, $checksum
+) {
+    $html_output = '<div class="operations_half_width clearfloat">';
+    $html_output .= '<form method="post" action="tbl_operations.php"';
+    $html_output .= ' id="tableOptionsForm" class="ajax">';
+    $html_output .= PMA_generate_common_hidden_inputs(
+        $GLOBALS['db'], $GLOBALS['table']
+    );
+    $html_output .= '<input type="hidden" name="reload" value="1" />';
+
+    $html_output .= PMA_getTableOptionFieldset(
+        $comment, $tbl_collation,
+        $tbl_storage_engine, $is_myisam_or_aria, $is_isam, $pack_keys,
+        $delay_key_write, $auto_increment, $transactional, $page_checksum,
+        $is_innodb, $is_pbxt, $is_aria, $checksum
+    );
+
+    $html_output .= '<fieldset class="tblFooters">'
+        . '<input type="hidden" name="submitoptions" value="1" />'
+        . '<input type="submit" value="' . __('Go') . '" />'
+        . '</fieldset>'
+        . '</form>'
+        . '</div>';
+
+    return $html_output;
+}
+
+/**
+ * Get HTML fieldset for Table option, it contains HTML table for options
+ *
+ * @param string  $comment            Comment
+ * @param array   $tbl_collation      table collation
+ * @param string  $tbl_storage_engine table storage engine
+ * @param boolean $is_myisam_or_aria  whether MYISAM | ARIA or not
+ * @param boolean $is_isam            whether ISAM or not
+ * @param array   $pack_keys          pack keys
+ * @param string  $delay_key_write    delay key write
+ * @param string  $auto_increment     value of auto increment
+ * @param string  $transactional      value of transactional
+ * @param string  $page_checksum      value of page checksum
+ * @param boolean $is_innodb          whether INNODB or not
+ * @param boolean $is_pbxt            whether PBXT or not
+ * @param boolean $is_aria            whether ARIA or not
+ * @param string  $checksum           the checksum
+ *
+ * @return string $html_output
+ */
+function PMA_getTableOptionFieldset($comment, $tbl_collation,
+    $tbl_storage_engine, $is_myisam_or_aria, $is_isam, $pack_keys,
+    $delay_key_write, $auto_increment, $transactional,
+    $page_checksum, $is_innodb, $is_pbxt, $is_aria, $checksum
+) {
+    $html_output = '<fieldset>'
+        . '<legend>' . __('Table options') . '</legend>';
+
+    $html_output .= '<table>';
+    //Change table name
+    $html_output .= '<tr><td>' . __('Rename table to') . '</td>'
+        . '<td>'
+        . '<input type="text" size="20" name="new_name" onfocus="this.select()"'
+        . 'value="' . htmlspecialchars($GLOBALS['table']) . '" />'
+        . '</td>'
+        . '</tr>';
+
+    //Table comments
+    $html_output .= '<tr><td>' . __('Table comments') . '</td>'
+        . '<td><input type="text" name="comment" maxlength="60" size="30"'
+        . 'value="' . htmlspecialchars($comment) . '" onfocus="this.select()" />'
+        . '<input type="hidden" name="prev_comment" value="'
+        . htmlspecialchars($comment) . '" />'
+        . '</td>'
+        . '</tr>';
+
+    //Storage engine
+    $html_output .= '<tr><td>' . __('Storage Engine')
+        . PMA_Util::showMySQLDocu(
+            'Storage_engines', 'Storage_engines'
+        )
+        . '</td>'
+        . '<td>'
+        . PMA_StorageEngine::getHtmlSelect(
+            'new_tbl_storage_engine', null, $tbl_storage_engine
+        )
+        . '</td>'
+        . '</tr>';
+
+    //Table character set
+    $html_output .= '<tr><td>' . __('Collation') . '</td>'
+        . '<td>'
+        . PMA_generateCharsetDropdownBox(
+            PMA_CSDROPDOWN_COLLATION,
+            'tbl_collation', null, $tbl_collation, false, 3
+        )
+        . '</td>'
+        . '</tr>';
+
+    if ($is_myisam_or_aria || $is_isam) {
+        $html_output .= '<tr>'
+            . '<td><label for="new_pack_keys">PACK_KEYS</label></td>'
+            . '<td><select name="new_pack_keys" id="new_pack_keys">';
+
+        $html_output .= '<option value="DEFAULT"';
+        if ($pack_keys == 'DEFAULT') {
+            $html_output .= 'selected="selected"';
+        }
+        $html_output .= '>DEFAULT</option>
+                <option value="0"';
+        if ($pack_keys == '0') {
+            $html_output .= 'selected="selected"';
+        }
+        $html_output .= '>0</option>
+                <option value="1" ';
+        if ($pack_keys == '1') {
+            $html_output .= 'selected="selected"';
+        }
+        $html_output .= '>1</option>'
+            . '</select>'
+            . '</td>'
+            . '</tr>';
+    } // end if (MYISAM|ISAM)
+
+    if ($is_myisam_or_aria) {
+        $html_output .= PMA_getHtmlForTableRow(
+            'new_checksum',
+            'CHECKSUM',
+            $checksum
+        );
+
+        $html_output .= PMA_getHtmlForTableRow(
+            'new_delay_key_write',
+            'DELAY_KEY_WRITE',
+            $delay_key_write
+        );
+    } // end if (MYISAM)
+
+    if ($is_aria) {
+        $html_output .= PMA_getHtmlForTableRow(
+            'new_transactional',
+            'TRANSACTIONAL',
+            $transactional
+        );
+
+        $html_output .= PMA_getHtmlForTableRow(
+            'new_page_checksum',
+            'PAGE_CHECKSUM',
+            $page_checksum
+        );
+    } // end if (ARIA)
+
+    if (strlen($auto_increment) > 0
+        && ($is_myisam_or_aria || $is_innodb || $is_pbxt)
+    ) {
+        $html_output .= '<tr><td>'
+            . '<label for="auto_increment_opt">AUTO_INCREMENT</label></td>'
+            . '<td><input type="text" name="new_auto_increment" '
+            . 'id="auto_increment_opt"'
+            . 'value="' . $auto_increment . '" /></td>'
+            . '</tr> ';
+    } // end if (MYISAM|INNODB)
+
+    $possible_row_formats = PMA_getPossibleRowFormat();
+
+    // for MYISAM there is also COMPRESSED but it can be set only by the
+    // myisampack utility, so don't offer here the choice because if we
+    // try it inside an ALTER TABLE, MySQL (at least in 5.1.23-maria)
+    // does not return a warning
+    // (if the table was compressed, it can be seen on the Structure page)
+
+    if (isset($possible_row_formats[$tbl_storage_engine])) {
+        $current_row_format = strtoupper($GLOBALS['showtable']['Row_format']);
+        $html_output .= '<tr><td>'
+            . '<label for="new_row_format">ROW_FORMAT</label></td>'
+            . '<td>';
+        $html_output .= PMA_Util::getDropdown(
+            'new_row_format', $possible_row_formats[$tbl_storage_engine],
+            $current_row_format, 'new_row_format'
+        );
+        $html_output .= '</td></tr>';
+    }
+    $html_output .= '</table>'
+        . '</fieldset>';
+
+    return $html_output;
+}
+
+/**
+ * Get the common HTML table row (tr) for new_checksum, new_delay_key_write,
+ * new_transactional and new_page_checksum
+ *
+ * @param string $attribute class, name and id attribute
+ * @param string $label     label value
+ * @param string $val       checksum, delay_key_write, transactional, page_checksum
+ *
+ * @return string $html_output
+ */
+function PMA_getHtmlForTableRow($attribute, $label, $val)
+{
+    return '<tr>'
+        . '<td><label for="' . $attribute . '">' . $label . '</label></td>'
+        . '<td><input type="checkbox" name="'. $attribute .'"'
+        . ' id="' . $attribute .'"'
+        . ' value="1"'
+        . ((!empty($val) && $val == 1) ? ' checked="checked"' : '') . '/></td>'
+        . '</tr>';
+}
+
+/**
+ * Get array of possible row formats
+ *
+ * @return array $possible_row_formats
+ */
+function PMA_getPossibleRowFormat()
+{
+    // the outer array is for engines, the inner array contains the dropdown
+    // option values as keys then the dropdown option labels
+
+    $possible_row_formats = array(
+        'ARIA'  => array(
+            'FIXED'     => 'FIXED',
+            'DYNAMIC'   => 'DYNAMIC',
+            'PAGE'      => 'PAGE'
+        ),
+        'MARIA'  => array(
+            'FIXED'     => 'FIXED',
+            'DYNAMIC'   => 'DYNAMIC',
+            'PAGE'      => 'PAGE'
+        ),
+        'MYISAM' => array(
+             'FIXED'    => 'FIXED',
+             'DYNAMIC'  => 'DYNAMIC'
+        ),
+        'PBXT'   => array(
+             'FIXED'    => 'FIXED',
+             'DYNAMIC'  => 'DYNAMIC'
+        ),
+        'INNODB' => array(
+             'COMPACT'  => 'COMPACT',
+             'REDUNDANT' => 'REDUNDANT'
+        )
+    );
+
+    $innodb_engine_plugin = PMA_StorageEngine::getEngine('innodb');
+    $innodb_plugin_version = $innodb_engine_plugin->getInnodbPluginVersion();
+    if (!empty($innodb_plugin_version)) {
+        $innodb_file_format = $innodb_engine_plugin->getInnodbFileFormat();
+    } else {
+        $innodb_file_format = '';
+    }
+    if ('Barracuda' == $innodb_file_format
+        && $innodb_engine_plugin->supportsFilePerTable()
+    ) {
+        $possible_row_formats['INNODB']['DYNAMIC'] = 'DYNAMIC';
+        $possible_row_formats['INNODB']['COMPRESSED'] = 'COMPRESSED';
+    }
+
+    return $possible_row_formats;
+}
+
+/**
+ * Get HTML div for copy table
+ *
+ * @return string $html_output
+ */
+function PMA_getHtmlForCopytable()
+{
+    $html_output = '<div class="operations_half_width">';
+    $html_output .= '<form method="post" action="tbl_operations.php" '
+        . 'name="copyTable" '
+        . 'id="copyTable" '
+        . ' class="ajax" '
+        . 'onsubmit="return emptyFormElements(this, \'new_name\')">'
+        . PMA_generate_common_hidden_inputs($GLOBALS['db'], $GLOBALS['table'])
+        . '<input type="hidden" name="reload" value="1" />';
+
+    $html_output .= '<fieldset>';
+    $html_output .= '<legend>'
+        . __('Copy table to (database<b>.</b>table):') . '</legend>';
+
+    if (count($GLOBALS['pma']->databases) > $GLOBALS['cfg']['MaxDbList']) {
+        $html_output .= '<input type="text" maxlength="100" '
+            . 'size="30" name="target_db" '
+            . 'value="'. htmlspecialchars($GLOBALS['db']) . '"/>';
+    } else {
+        $html_output .= '<select name="target_db">'
+            . $GLOBALS['pma']->databases->getHtmlOptions(true, false)
+            . '</select>';
+    }
+    $html_output .= ' <strong>.</strong> ';
+    $html_output .= '<input type="text" size="20" name="new_name" '
+        . 'onfocus="this.select()" '
+        . 'value="'. htmlspecialchars($GLOBALS['table']) . '"/><br />';
+
+    $choices = array(
+            'structure' => __('Structure only'),
+            'data'      => __('Structure and data'),
+            'dataonly'  => __('Data only'));
+
+    $html_output .= PMA_Util::getRadioFields(
+        'what', $choices, 'data', true
+    );
+
+    $html_output .= '<input type="checkbox" name="drop_if_exists" '
+        . 'value="true" id="checkbox_drop" />'
+        . '<label for="checkbox_drop">'
+        . sprintf(__('Add %s'), 'DROP TABLE') . '</label><br />'
+        . '<input type="checkbox" name="sql_auto_increment" '
+        . 'value="1" id="checkbox_auto_increment_cp" />'
+        . '<label for="checkbox_auto_increment_cp">'
+        . __('Add AUTO_INCREMENT value') . '</label><br />';
+
+    // display "Add constraints" choice only if there are
+    // foreign keys
+    if (PMA_getForeigners($GLOBALS['db'], $GLOBALS['table'], '', 'foreign')) {
+        $html_output .= '<input type="checkbox" name="add_constraints" '
+            . 'value="1" id="checkbox_constraints" />';
+        $html_output .= '<label for="checkbox_constraints">'
+            .__('Add constraints') . '</label><br />';
+    } // endif
+
+    if (isset($_COOKIE['pma_switch_to_new'])
+        && $_COOKIE['pma_switch_to_new'] == 'true'
+    ) {
+        $pma_switch_to_new = 'true';
+    }
+
+    $html_output .= '<input type="checkbox" name="switch_to_new" value="true"'
+        . 'id="checkbox_switch"'
+        . ((isset($pma_switch_to_new) && $pma_switch_to_new == 'true')
+            ? ' checked="checked"'
+            : '' . '/>');
+    $html_output .= '<label for="checkbox_switch">'
+        . __('Switch to copied table') . '</label>'
+        . '</fieldset>';
+
+    $html_output .= '<fieldset class="tblFooters">'
+        . '<input type="submit" name="submit_copy" value="' .__('Go') . '" />'
+        . '</fieldset>'
+        . '</form>'
+        . '</div>';
+
+    return $html_output;
+}
+
+/**
+ * Get HTML snippet for table maintence
+ *
+ * @param boolean $is_myisam_or_aria whether MYISAM | ARIA or not
+ * @param boolean $is_innodb         whether innodb or not
+ * @param boolean $is_berkeleydb     whether  berkeleydb or not
+ * @param array   $url_params        array of URL parameters
+ *
+ * @return string $html_output
+ */
+function PMA_getHtmlForTableMaintenance(
+    $is_myisam_or_aria, $is_innodb, $is_berkeleydb, $url_params
+) {
+    $html_output = '<div class="operations_half_width">';
+    $html_output .= '<fieldset>'
+        . '<legend>' . __('Table maintenance') . '</legend>';
+    $html_output .= '<ul id="tbl_maintenance">';
+
+    // Note: BERKELEY (BDB) is no longer supported, starting with MySQL 5.1
+    $html_output .= PMA_getListofMaintainActionLink(
+        $is_myisam_or_aria, $is_innodb, $url_params, $is_berkeleydb
+    );
+
+    $html_output .= '</ul>'
+        . '</fieldset>'
+        . '</div>';
+
+    return $html_output;
+}
+
+/**
+ * Get HTML 'li' having a link of maintain action
+ *
+ * @param boolean $is_myisam_or_aria whether MYISAM | ARIA or not
+ * @param boolean $is_innodb         whether innodb or not
+ * @param array   $url_params        array of URL parameters
+ * @param boolean $is_berkeleydb     whether  berkeleydb or not
+ *
+ * @return string $html_output
+ */
+function PMA_getListofMaintainActionLink($is_myisam_or_aria,
+    $is_innodb, $url_params, $is_berkeleydb
+) {
+    $html_output = '';
+
+    if ($is_myisam_or_aria || $is_innodb || $is_berkeleydb) {
+        if ($is_myisam_or_aria || $is_innodb) {
+            $params = array(
+                'sql_query' => 'CHECK TABLE '
+                    . PMA_Util::backquote($GLOBALS['table']),
+                'table_maintenance' => 'Go',
+            );
+            $html_output .= PMA_getMaintainActionlink(
+                __('Check table'),
+                $params,
+                $url_params,
+                'CHECK_TABLE'
+            );
+        }
+        if ($is_innodb) {
+            $params = array(
+                'sql_query' => 'ALTER TABLE '
+                . PMA_Util::backquote($GLOBALS['table'])
+                . ' ENGINE = InnoDB;'
+            );
+            $html_output .= PMA_getMaintainActionlink(
+                __('Defragment table'),
+                $params,
+                $url_params,
+                'InnoDB_File_Defragmenting',
+                'Table_types'
+            );
+        }
+        if ($is_myisam_or_aria || $is_berkeleydb) {
+            $params = array(
+                'sql_query' => 'ANALYZE TABLE '
+                    . PMA_Util::backquote($GLOBALS['table']),
+                'table_maintenance' => 'Go',
+            );
+            $html_output .= PMA_getMaintainActionlink(
+                __('Analyze table'),
+                $params,
+                $url_params,
+                'ANALYZE_TABLE'
+            );
+        }
+        if ($is_myisam_or_aria && !PMA_DRIZZLE) {
+            $params = array(
+                'sql_query' => 'REPAIR TABLE '
+                    . PMA_Util::backquote($GLOBALS['table']),
+                'table_maintenance' => 'Go',
+            );
+            $html_output .= PMA_getMaintainActionlink(
+                __('Repair table'),
+                $params,
+                $url_params,
+                'REPAIR_TABLE'
+            );
+        }
+        if (($is_myisam_or_aria || $is_innodb || $is_berkeleydb)
+            && !PMA_DRIZZLE
+        ) {
+            $params = array(
+                'sql_query' => 'OPTIMIZE TABLE '
+                    . PMA_Util::backquote($GLOBALS['table']),
+                'table_maintenance' => 'Go',
+            );
+            $html_output .= PMA_getMaintainActionlink(
+                __('Optimize table'),
+                $params,
+                $url_params,
+                'OPTIMIZE_TABLE'
+            );
+        }
+    } // end MYISAM or BERKELEYDB case
+
+    $params = array(
+        'sql_query' => 'FLUSH TABLE '
+            . PMA_Util::backquote($GLOBALS['table']),
+        'message_to_show' => sprintf(
+            __('Table %s has been flushed'),
+            htmlspecialchars($GLOBALS['table'])
+        ),
+        'reload' => 1,
+    );
+
+    $html_output .= PMA_getMaintainActionlink(
+        __('Flush the table (FLUSH)'),
+        $params,
+        $url_params,
+        'FLUSH'
+    );
+
+    return $html_output;
+}
+
+/**
+ * Get maintain action HTML link
+ *
+ * @param string $action
+ * @param array  $params     url parameters array
+ * @param array  $url_params
+ * @param string $link       contains name of page/anchor that is being linked
+ * @param string $chapter    chapter of "HTML, one page per chapter" documentation
+ *
+ * @return string $html_output
+ */
+function PMA_getMaintainActionlink($action, $params, $url_params, $link,
+    $chapter = 'MySQL_Database_Administration'
+) {
+    return '<li>'
+        . '<a class="maintain_action ajax" '
+        . 'href="sql.php'
+        . PMA_generate_common_url(array_merge($url_params, $params)) .'">'
+        . $action
+        . '</a>'
+        . PMA_Util::showMySQLDocu($chapter, $link)
+        . '</li>';
+}
+
+/**
+ * Get HTML for Delete data or table (truncate table, drop table)
+ *
+ * @param array $truncate_table_url_params url parameter array for truncate table
+ * @param array $drop_table_url_params     url parameter array for drop table
+ *
+ * @return string $html_output
+ */
+function PMA_getHtmlForDeleteDataOrTable(
+    $truncate_table_url_params,
+    $drop_table_url_params
+) {
+    $html_output = '<div class="operations_half_width">'
+        . '<fieldset class="caution">'
+        . '<legend>' . __('Delete data or table') . '</legend>';
+
+    $html_output .= '<ul>';
+
+    if (! empty($truncate_table_url_params)) {
+        $html_output .= PMA_getDeleteDataOrTablelink(
+            $truncate_table_url_params,
+            'TRUNCATE_TABLE',
+            __('Empty the table (TRUNCATE)'),
+            'truncate_tbl_anchor'
+        );
+    }
+    if (!empty ($drop_table_url_params)) {
+        $html_output .= PMA_getDeleteDataOrTablelink(
+            $drop_table_url_params,
+            'DROP_TABLE',
+            __('Delete the table (DROP)'),
+            'drop_tbl_anchor'
+        );
+    }
+    $html_output .= '</ul></fieldset></div>';
+
+    return $html_output;
+}
+
+/**
+ * Get the HTML link for Truncate table, Drop table and Drop db
+ *
+ * @param array  $url_params url parameter array for delete data or table
+ * @param string $syntax     TRUNCATE_TABLE or DROP_TABLE or DROP_DATABASE
+ * @param string $link       link to be shown
+ * @param string $id         id of the link
+ *
+ * @return String html output
+ */
+function PMA_getDeleteDataOrTablelink($url_params, $syntax, $link, $id)
+{
+    return  '<li><a '
+        . 'href="sql.php' . PMA_generate_common_url($url_params) . '"'
+        . ' id="' . $id . '" class="ajax">'
+        . $link . '</a>'
+        . PMA_Util::showMySQLDocu(
+            'SQL-Syntax', $syntax
+        )
+        . '</li>';
+}
+
+/**
+ * Get HTML snippet for partition maintenance
+ *
+ * @param array $partition_names array of partition names for a specific db/table
+ * @param array $url_params      url parameters
+ *
+ * @return string $html_output
+ */
+function PMA_getHtmlForPartitionMaintenance($partition_names, $url_params)
+{
+    $choices = array(
+        'ANALYZE' => __('Analyze'),
+        'CHECK' => __('Check'),
+        'OPTIMIZE' => __('Optimize'),
+        'REBUILD' => __('Rebuild'),
+        'REPAIR' => __('Repair')
+    );
+
+    $html_output = '<div class="operations_half_width">'
+        . '<form method="post" action="tbl_operations.php">'
+        . PMA_generate_common_hidden_inputs($GLOBALS['db'], $GLOBALS['table'])
+        . '<fieldset>'
+        . '<legend>' . __('Partition maintenance') . '</legend>';
+
+    $html_select = '<select name="partition_name">' . "\n";
+    foreach ($partition_names as $one_partition) {
+        $one_partition = htmlspecialchars($one_partition);
+        $html_select .= '<option value="' . $one_partition . '">'
+            . $one_partition . '</option>' . "\n";
+    }
+    $html_select .= '</select>' . "\n";
+    $html_output .= sprintf(__('Partition %s'), $html_select);
+
+    $html_output .= PMA_Util::getRadioFields(
+        'partition_operation', $choices, '', false
+    );
+    $html_output .= PMA_Util::showMySQLDocu(
+        'partitioning_maintenance',
+        'partitioning_maintenance'
+    );
+    $this_url_params = array_merge(
+        $url_params,
+        array(
+            'sql_query' => 'ALTER TABLE '
+            . PMA_Util::backquote($GLOBALS['table'])
+            . ' REMOVE PARTITIONING;'
+        )
+    );
+    $html_output .= '<br /><a href="sql.php'
+        . PMA_generate_common_url($this_url_params) . '">'
+        . __('Remove partitioning') . '</a>';
+
+    $html_output .= '</fieldset>'
+        . '<fieldset class="tblFooters">'
+        . '<input type="submit" name="submit_partition" '
+        . 'value="' . __('Go') . '" />'
+        . '</fieldset>'
+        . '</form>'
+        . '</div>';
+
+    return $html_output;
+}
+
+/**
+ * Get the HTML for Referential Integrity check
+ *
+ * @param array $foreign    all Relations to foreign tables for a given table
+ *                          or optionally a given column in a table
+ * @param array $url_params array of url parameters
+ *
+ * @return string $html_output
+ */
+function PMA_getHtmlForReferentialIntegrityCheck($foreign, $url_params)
+{
+    $html_output = '<div class="operations_half_width">'
+        . '<fieldset>'
+        . '<legend>' . __('Check referential integrity:') . '</legend>';
+
+    $html_output .= '<ul>';
+
+    foreach ($foreign AS $master => $arr) {
+        $join_query  = 'SELECT '
+            . PMA_Util::backquote($GLOBALS['table']) . '.*'
+            . ' FROM ' . PMA_Util::backquote($GLOBALS['table'])
+            . ' LEFT JOIN ' 
+            . PMA_Util::backquote($arr['foreign_db'])
+            . '.'
+            . PMA_Util::backquote($arr['foreign_table']);
+        if ($arr['foreign_table'] == $GLOBALS['table']) {
+            $foreign_table = $GLOBALS['table'] . '1';
+            $join_query .= ' AS ' . PMA_Util::backquote($foreign_table);
+        } else {
+            $foreign_table = $arr['foreign_table'];
+        }
+        $join_query .= ' ON '
+            . PMA_Util::backquote($GLOBALS['table']) . '.'
+            . PMA_Util::backquote($master)
+            . ' = ' 
+            . PMA_Util::backquote($arr['foreign_db']) 
+            . '.'
+            . PMA_Util::backquote($foreign_table) . '.'
+            . PMA_Util::backquote($arr['foreign_field'])
+            . ' WHERE '
+            . PMA_Util::backquote($arr['foreign_db']) 
+            . '.'
+            . PMA_Util::backquote($foreign_table) . '.'
+            . PMA_Util::backquote($arr['foreign_field'])
+            . ' IS NULL AND '
+            . PMA_Util::backquote($GLOBALS['table']) . '.'
+            . PMA_Util::backquote($master)
+            . ' IS NOT NULL';
+        $this_url_params = array_merge(
+            $url_params,
+            array('sql_query' => $join_query)
+        );
+
+        $html_output .= '<li>'
+            . '<a href="sql.php'
+            . PMA_generate_common_url($this_url_params)
+            . '">'
+            . $master . ' -> ' . $arr['foreign_table'] . '.'
+            . $arr['foreign_field']
+            . '</a></li>' . "\n";
+    } //  foreach $foreign
+    $html_output .= '</ul></fieldset></div>';
+
+    return $html_output;
+}
+
+function PMA_getQueryAndResultForReorderingTable()
+{
+    $sql_query = 'ALTER TABLE '
+        . PMA_Util::backquote($GLOBALS['table'])
+        . ' ORDER BY '
+        . PMA_Util::backquote(urldecode($_REQUEST['order_field']));
+    if (isset($_REQUEST['order_order'])
+        && $_REQUEST['order_order'] === 'desc'
+    ) {
+        $sql_query .= ' DESC';
+    }
+    $sql_query .= ';';
+    $result = PMA_DBI_query($sql_query);
+
+    return array($sql_query, $result);
+}
+
+/**
+ * Get table alters array
+ *
+ * @param boolean $is_myisam_or_aria  whether MYISAM | ARIA or not
+ * @param boolean $is_isam            whether ISAM or not
+ * @param string  $pack_keys          pack keys
+ * @param string  $checksum           value of checksum
+ * @param boolean $is_aria            whether ARIA or not
+ * @param string  $page_checksum      value of page checksum
+ * @param string  $delay_key_write    delay key write
+ * @param boolean $is_innodb          whether INNODB or not
+ * @param boolean $is_pbxt            whether PBXT or not
+ * @param string  $row_format         row format
+ * @param string  $tbl_storage_engine table storage engine
+ * @param string  $transactional      value of transactional
+ * @param string  $tbl_collation      collation of the table
+ *
+ * @return array  $table_alters
+ */
+function PMA_getTableAltersArray($is_myisam_or_aria, $is_isam, $pack_keys,
+    $checksum, $is_aria, $page_checksum, $delay_key_write, $is_innodb,
+    $is_pbxt, $row_format, $new_tbl_storage_engine, $transactional, $tbl_collation
+) {
+    global $auto_increment;
+
+    $table_alters = array();
+
+    if (isset($_REQUEST['comment'])
+        && urldecode($_REQUEST['prev_comment']) !== $_REQUEST['comment']
+    ) {
+        $table_alters[] = 'COMMENT = \''
+            . PMA_Util::sqlAddSlashes($_REQUEST['comment']) . '\'';
+    }
+    if (! empty($new_tbl_storage_engine)
+        && strtolower($new_tbl_storage_engine) !== strtolower($GLOBALS['tbl_storage_engine'])
+    ) {
+        $table_alters[] = 'ENGINE = ' . $new_tbl_storage_engine;
+    }
+    if (! empty($_REQUEST['tbl_collation'])
+        && $_REQUEST['tbl_collation'] !== $tbl_collation
+    ) {
+        $table_alters[] = 'DEFAULT '
+            . PMA_generateCharsetQueryPart($_REQUEST['tbl_collation']);
+    }
+
+    if (($is_myisam_or_aria || $is_isam)
+        && isset($_REQUEST['new_pack_keys'])
+        && $_REQUEST['new_pack_keys'] != (string)$pack_keys
+    ) {
+        $table_alters[] = 'pack_keys = ' . $_REQUEST['new_pack_keys'];
+    }
+
+    $_REQUEST['new_checksum'] = empty($_REQUEST['new_checksum']) ? '0' : '1';
+    if ($is_myisam_or_aria
+        && $_REQUEST['new_checksum'] !== $checksum
+    ) {
+        $table_alters[] = 'checksum = ' . $_REQUEST['new_checksum'];
+    }
+
+    $_REQUEST['new_transactional']
+        = empty($_REQUEST['new_transactional']) ? '0' : '1';
+    if ($is_aria
+        && $_REQUEST['new_transactional'] !== $transactional
+    ) {
+        $table_alters[] = 'TRANSACTIONAL = ' . $_REQUEST['new_transactional'];
+    }
+
+    $_REQUEST['new_page_checksum']
+        = empty($_REQUEST['new_page_checksum']) ? '0' : '1';
+    if ($is_aria
+        && $_REQUEST['new_page_checksum'] !== $page_checksum
+    ) {
+        $table_alters[] = 'PAGE_CHECKSUM = ' . $_REQUEST['new_page_checksum'];
+    }
+
+    $_REQUEST['new_delay_key_write']
+        = empty($_REQUEST['new_delay_key_write']) ? '0' : '1';
+    if ($is_myisam_or_aria
+        && $_REQUEST['new_delay_key_write'] !== $delay_key_write
+    ) {
+        $table_alters[] = 'delay_key_write = ' . $_REQUEST['new_delay_key_write'];
+    }
+
+    if (($is_myisam_or_aria || $is_innodb || $is_pbxt)
+        && ! empty($_REQUEST['new_auto_increment'])
+        && (! isset($auto_increment)
+        || $_REQUEST['new_auto_increment'] !== $auto_increment)
+    ) {
+        $table_alters[] = 'auto_increment = '
+            . PMA_Util::sqlAddSlashes($_REQUEST['new_auto_increment']);
+    }
+
+    if (($is_myisam_or_aria || $is_innodb || $is_pbxt)
+        &&  ! empty($_REQUEST['new_row_format'])
+        && (!strlen($row_format)
+        || strtolower($_REQUEST['new_row_format']) !== strtolower($row_format))
+    ) {
+        $table_alters[] = 'ROW_FORMAT = '
+            . PMA_Util::sqlAddSlashes($_REQUEST['new_row_format']);
+    }
+
+    return $table_alters;
+}
+
+/**
+ * set initial value of the set of variables, based on the current table engine
+ *
+ * @param string $tbl_storage_engine table storage engine
+ *
+ * @return array ($is_myisam_or_aria, $is_innodb, $is_isam,
+ *                $is_berkeleydb, $is_aria, $is_pbxt)
+ */
+function PMA_setGlobalVariablesForEngine($tbl_storage_engine)
+{
+    $is_myisam_or_aria = $is_isam = $is_innodb = $is_berkeleydb
+        = $is_aria = $is_pbxt = false;
+    $upper_tbl_storage_engine = strtoupper($tbl_storage_engine);
+
+    //Options that apply to MYISAM usually apply to ARIA
+    $is_myisam_or_aria = ($upper_tbl_storage_engine == 'MYISAM'
+        || $upper_tbl_storage_engine == 'ARIA'
+        || $upper_tbl_storage_engine == 'MARIA'
+    );
+    $is_aria = ($upper_tbl_storage_engine == 'ARIA');
+
+    $is_isam = ($upper_tbl_storage_engine == 'ISAM');
+    $is_innodb = ($upper_tbl_storage_engine == 'INNODB');
+    $is_berkeleydb = ($upper_tbl_storage_engine == 'BERKELEYDB');
+    $is_pbxt = ($upper_tbl_storage_engine == 'PBXT');
+
+    return array(
+        $is_myisam_or_aria, $is_innodb, $is_isam,
+        $is_berkeleydb, $is_aria, $is_pbxt
+    );
+}
+
+/**
+ * Get warning messages array
+ *
+ * @return array  $warning_messages
+ */
+function PMA_getWarningMessagesArray()
+{
+    $warning_messages = array();
+    foreach (PMA_DBI_get_warnings() as $warning) {
+        // In MariaDB 5.1.44, when altering a table from Maria to MyISAM
+        // and if TRANSACTIONAL was set, the system reports an error;
+        // I discussed with a Maria developer and he agrees that this
+        // should not be reported with a Level of Error, so here
+        // I just ignore it. But there are other 1478 messages
+        // that it's better to show.
+        if (! ($_REQUEST['new_tbl_storage_engine'] == 'MyISAM'
+            && $warning['Code'] == '1478'
+            && $warning['Level'] == 'Error')
+        ) {
+            $warning_messages[] = $warning['Level'] . ': #' . $warning['Code']
+                . ' ' . $warning['Message'];
+        }
+    }
+    return $warning_messages;
+}
+
+/**
+ * Get SQL query and result after ran this SQL query for a partition operation
+ * has been requested by the user
+ *
+ * @return array $sql_query, $result
+ */
+function PMA_getQueryAndResultForPartition()
+{
+    $sql_query = 'ALTER TABLE '
+        . PMA_Util::backquote($GLOBALS['table']) . ' '
+        . $_REQUEST['partition_operation']
+        . ' PARTITION '
+        . $_REQUEST['partition_name'] . ';';
+    $result = PMA_DBI_query($sql_query);
+
+    return array($sql_query, $result);
+}
+
+?>
diff --git a/phpmyadmin/libraries/parse_analyze.lib.php b/phpmyadmin/libraries/parse_analyze.lib.php
new file mode 100644
index 0000000..9b9c800
--- /dev/null
+++ b/phpmyadmin/libraries/parse_analyze.lib.php
@@ -0,0 +1,61 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * Parse and analyse a SQL query
+ *
+ * @package PhpMyAdmin
+ */
+if (! defined('PHPMYADMIN')) {
+    exit;
+}
+
+/**
+ *
+ */
+$GLOBALS['unparsed_sql'] = $sql_query;
+$parsed_sql = PMA_SQP_parse($sql_query);
+$analyzed_sql = PMA_SQP_analyze($parsed_sql);
+
+// for bug 780516: now that we use case insensitive preg_match
+// or flags from the analyser, do not put back the reformatted query
+// into $sql_query, to make this kind of query work without
+// capitalizing keywords:
+//
+// CREATE TABLE SG_Persons (
+//  id int(10) unsigned NOT NULL auto_increment,
+//  first varchar(64) NOT NULL default '',
+//  PRIMARY KEY  (`id`)
+// )
+
+// check for a real SELECT ... FROM
+$is_select = isset($analyzed_sql[0]['queryflags']['select_from']);
+
+// If the query is a Select, extract the db and table names and modify
+// $db and $table, to have correct page headers, links and left frame.
+// db and table name may be enclosed with backquotes, db is optionnal,
+// query may contain aliases.
+
+/**
+ * @todo if there are more than one table name in the Select:
+ * - do not extract the first table name
+ * - do not show a table name in the page header
+ * - do not display the sub-pages links)
+ */
+if ($is_select) {
+    $prev_db = $db;
+    if (isset($analyzed_sql[0]['table_ref'][0]['table_true_name'])) {
+        $table = $analyzed_sql[0]['table_ref'][0]['table_true_name'];
+    }
+    if (isset($analyzed_sql[0]['table_ref'][0]['db'])
+        && strlen($analyzed_sql[0]['table_ref'][0]['db'])
+    ) {
+        $db    = $analyzed_sql[0]['table_ref'][0]['db'];
+    } else {
+        $db = $prev_db;
+    }
+    // Nijel: don't change reload, if we already decided to reload in import
+    if (empty($reload) && empty($GLOBALS['is_ajax_request'])) {
+        $reload  = ($db == $prev_db) ? 0 : 1;
+    }
+}
+?>
diff --git a/phpmyadmin/libraries/php-gettext/gettext.inc b/phpmyadmin/libraries/php-gettext/gettext.inc
new file mode 100644
index 0000000..00b9666
--- /dev/null
+++ b/phpmyadmin/libraries/php-gettext/gettext.inc
@@ -0,0 +1,536 @@
+<?php
+/*
+   Copyright (c) 2005 Steven Armstrong <sa at c-area dot ch>
+   Copyright (c) 2009 Danilo Segan <danilo at kvota.net>
+
+   Drop in replacement for native gettext.
+
+   This file is part of PHP-gettext.
+
+   PHP-gettext is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2 of the License, or
+   (at your option) any later version.
+
+   PHP-gettext is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with PHP-gettext; if not, write to the Free Software
+   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+
+*/
+/*
+LC_CTYPE        0
+LC_NUMERIC      1
+LC_TIME         2
+LC_COLLATE      3
+LC_MONETARY     4
+LC_MESSAGES     5
+LC_ALL          6
+*/
+
+// LC_MESSAGES is not available if php-gettext is not loaded
+// while the other constants are already available from session extension.
+if (!defined('LC_MESSAGES')) {
+  define('LC_MESSAGES',	5);
+}
+
+require('streams.php');
+require('gettext.php');
+
+
+// Variables
+
+global $text_domains, $default_domain, $LC_CATEGORIES, $EMULATEGETTEXT, $CURRENTLOCALE;
+$text_domains = array();
+$default_domain = 'messages';
+$LC_CATEGORIES = array('LC_CTYPE', 'LC_NUMERIC', 'LC_TIME', 'LC_COLLATE', 'LC_MONETARY', 'LC_MESSAGES', 'LC_ALL');
+$EMULATEGETTEXT = 0;
+$CURRENTLOCALE = '';
+
+/* Class to hold a single domain included in $text_domains. */
+class domain {
+  var $l10n;
+  var $path;
+  var $codeset;
+}
+
+// Utility functions
+
+/**
+ * Return a list of locales to try for any POSIX-style locale specification.
+ */
+function get_list_of_locales($locale) {
+  /* Figure out all possible locale names and start with the most
+   * specific ones.  I.e. for sr_CS.UTF-8 at latin, look through all of
+   * sr_CS.UTF-8 at latin, sr_CS at latin, sr at latin, sr_CS.UTF-8, sr_CS, sr.
+   */
+  $locale_names = array();
+  $lang = NULL;
+  $country = NULL;
+  $charset = NULL;
+  $modifier = NULL;
+  if ($locale) {
+    if (preg_match("/^(?P<lang>[a-z]{2,3})"              // language code
+                   ."(?:_(?P<country>[A-Z]{2}))?"           // country code
+                   ."(?:\.(?P<charset>[-A-Za-z0-9_]+))?"    // charset
+                   ."(?:@(?P<modifier>[-A-Za-z0-9_]+))?$/",  // @ modifier
+                   $locale, $matches)) {
+
+      if (isset($matches["lang"])) $lang = $matches["lang"];
+      if (isset($matches["country"])) $country = $matches["country"];
+      if (isset($matches["charset"])) $charset = $matches["charset"];
+      if (isset($matches["modifier"])) $modifier = $matches["modifier"];
+
+      if ($modifier) {
+        if ($country) {
+          if ($charset)
+            array_push($locale_names, "${lang}_$country.$charset@$modifier");
+          array_push($locale_names, "${lang}_$country@$modifier");
+        } elseif ($charset)
+            array_push($locale_names, "${lang}.$charset@$modifier");
+        array_push($locale_names, "$lang@$modifier");
+      }
+      if ($country) {
+        if ($charset)
+          array_push($locale_names, "${lang}_$country.$charset");
+        array_push($locale_names, "${lang}_$country");
+      } elseif ($charset)
+          array_push($locale_names, "${lang}.$charset");
+      array_push($locale_names, $lang);
+    }
+
+    // If the locale name doesn't match POSIX style, just include it as-is.
+    if (!in_array($locale, $locale_names))
+      array_push($locale_names, $locale);
+  }
+  return $locale_names;
+}
+
+/**
+ * Utility function to get a StreamReader for the given text domain.
+ */
+function _get_reader($domain=null, $category=5, $enable_cache=true) {
+    global $text_domains, $default_domain, $LC_CATEGORIES;
+    if (!isset($domain)) $domain = $default_domain;
+    if (!isset($text_domains[$domain]->l10n)) {
+        // get the current locale
+        $locale = _setlocale(LC_MESSAGES, 0);
+        $bound_path = isset($text_domains[$domain]->path) ?
+          $text_domains[$domain]->path : './';
+        $subpath = $LC_CATEGORIES[$category] ."/$domain.mo";
+
+        $locale_names = get_list_of_locales($locale);
+        $input = null;
+        foreach ($locale_names as $locale) {
+          $full_path = $bound_path . $locale . "/" . $subpath;
+          if (file_exists($full_path)) {
+            $input = new FileReader($full_path);
+            break;
+          }
+        }
+
+        if (!array_key_exists($domain, $text_domains)) {
+          // Initialize an empty domain object.
+          $text_domains[$domain] = new domain();
+        }
+        $text_domains[$domain]->l10n = new gettext_reader($input,
+                                                          $enable_cache);
+    }
+    return $text_domains[$domain]->l10n;
+}
+
+/**
+ * Returns whether we are using our emulated gettext API or PHP built-in one.
+ */
+function locale_emulation() {
+    global $EMULATEGETTEXT;
+    return $EMULATEGETTEXT;
+}
+
+/**
+ * Checks if the current locale is supported on this system.
+ */
+function _check_locale_and_function($function=false) {
+    global $EMULATEGETTEXT;
+    if ($function and !function_exists($function))
+        return false;
+    return !$EMULATEGETTEXT;
+}
+
+/**
+ * Get the codeset for the given domain.
+ */
+function _get_codeset($domain=null) {
+    global $text_domains, $default_domain, $LC_CATEGORIES;
+    if (!isset($domain)) $domain = $default_domain;
+    return (isset($text_domains[$domain]->codeset))? $text_domains[$domain]->codeset : ini_get('mbstring.internal_encoding');
+}
+
+/**
+ * Convert the given string to the encoding set by bind_textdomain_codeset.
+ */
+function _encode($text) {
+    $source_encoding = mb_detect_encoding($text);
+    $target_encoding = _get_codeset();
+    if ($source_encoding != $target_encoding) {
+        return mb_convert_encoding($text, $target_encoding, $source_encoding);
+    }
+    else {
+        return $text;
+    }
+}
+
+
+// Custom implementation of the standard gettext related functions
+
+/**
+ * Returns passed in $locale, or environment variable $LANG if $locale == ''.
+ */
+function _get_default_locale($locale) {
+  if ($locale == '') // emulate variable support
+    return getenv('LANG');
+  else
+    return $locale;
+}
+
+/**
+ * Sets a requested locale, if needed emulates it.
+ */
+function _setlocale($category, $locale) {
+    global $CURRENTLOCALE, $EMULATEGETTEXT;
+    if ($locale === 0) { // use === to differentiate between string "0"
+        if ($CURRENTLOCALE != '')
+            return $CURRENTLOCALE;
+        else
+            // obey LANG variable, maybe extend to support all of LC_* vars
+            // even if we tried to read locale without setting it first
+            return _setlocale($category, $CURRENTLOCALE);
+    } else {
+        if (function_exists('setlocale')) {
+          $ret = setlocale($category, $locale);
+          if (($locale == '' and !$ret) or // failed setting it by env
+              ($locale != '' and $ret != $locale)) { // failed setting it
+            // Failed setting it according to environment.
+            $CURRENTLOCALE = _get_default_locale($locale);
+            $EMULATEGETTEXT = 1;
+          } else {
+            $CURRENTLOCALE = $ret;
+            $EMULATEGETTEXT = 0;
+          }
+        } else {
+          // No function setlocale(), emulate it all.
+          $CURRENTLOCALE = _get_default_locale($locale);
+          $EMULATEGETTEXT = 1;
+        }
+        // Allow locale to be changed on the go for one translation domain.
+        global $text_domains, $default_domain;
+        if (array_key_exists($default_domain, $text_domains)) {
+            unset($text_domains[$default_domain]->l10n);
+        }
+        return $CURRENTLOCALE;
+    }
+}
+
+/**
+ * Sets the path for a domain.
+ */
+function _bindtextdomain($domain, $path) {
+    global $text_domains;
+    // ensure $path ends with a slash ('/' should work for both, but lets still play nice)
+    if (substr(php_uname(), 0, 7) == "Windows") {
+      if ($path[strlen($path)-1] != '\\' and $path[strlen($path)-1] != '/')
+        $path .= '\\';
+    } else {
+      if ($path[strlen($path)-1] != '/')
+        $path .= '/';
+    }
+    if (!array_key_exists($domain, $text_domains)) {
+      // Initialize an empty domain object.
+      $text_domains[$domain] = new domain();
+    }
+    $text_domains[$domain]->path = $path;
+}
+
+/**
+ * Specify the character encoding in which the messages from the DOMAIN message catalog will be returned.
+ */
+function _bind_textdomain_codeset($domain, $codeset) {
+    global $text_domains;
+    $text_domains[$domain]->codeset = $codeset;
+}
+
+/**
+ * Sets the default domain.
+ */
+function _textdomain($domain) {
+    global $default_domain;
+    $default_domain = $domain;
+}
+
+/**
+ * Lookup a message in the current domain.
+ */
+function _gettext($msgid) {
+    $l10n = _get_reader();
+    return _encode($l10n->translate($msgid));
+}
+
+/**
+ * Alias for gettext.
+ */
+function __($msgid) {
+    return _gettext($msgid);
+}
+
+/**
+ * Plural version of gettext.
+ */
+function _ngettext($singular, $plural, $number) {
+    $l10n = _get_reader();
+    return _encode($l10n->ngettext($singular, $plural, $number));
+}
+
+/**
+ * Override the current domain.
+ */
+function _dgettext($domain, $msgid) {
+    $l10n = _get_reader($domain);
+    return _encode($l10n->translate($msgid));
+}
+
+/**
+ * Plural version of dgettext.
+ */
+function _dngettext($domain, $singular, $plural, $number) {
+    $l10n = _get_reader($domain);
+    return _encode($l10n->ngettext($singular, $plural, $number));
+}
+
+/**
+ * Overrides the domain and category for a single lookup.
+ */
+function _dcgettext($domain, $msgid, $category) {
+    $l10n = _get_reader($domain, $category);
+    return _encode($l10n->translate($msgid));
+}
+/**
+ * Plural version of dcgettext.
+ */
+function _dcngettext($domain, $singular, $plural, $number, $category) {
+    $l10n = _get_reader($domain, $category);
+    return _encode($l10n->ngettext($singular, $plural, $number));
+}
+
+/**
+ * Context version of gettext.
+ */
+function _pgettext($context, $msgid) {
+    $l10n = _get_reader();
+    return _encode($l10n->pgettext($context, $msgid));
+}
+
+/**
+ * Override the current domain in a context gettext call.
+ */
+function _dpgettext($domain, $context, $msgid) {
+    $l10n = _get_reader($domain);
+    return _encode($l10n->pgettext($context, $msgid));
+}
+
+/**
+ * Overrides the domain and category for a single context-based lookup.
+ */
+function _dcpgettext($domain, $context, $msgid, $category) {
+    $l10n = _get_reader($domain, $category);
+    return _encode($l10n->pgettext($context, $msgid));
+}
+
+/**
+ * Context version of ngettext.
+ */
+function _npgettext($context, $singular, $plural) {
+    $l10n = _get_reader();
+    return _encode($l10n->npgettext($context, $singular, $plural));
+}
+
+/**
+ * Override the current domain in a context ngettext call.
+ */
+function _dnpgettext($domain, $context, $singular, $plural) {
+    $l10n = _get_reader($domain);
+    return _encode($l10n->npgettext($context, $singular, $plural));
+}
+
+/**
+ * Overrides the domain and category for a plural context-based lookup.
+ */
+function _dcnpgettext($domain, $context, $singular, $plural, $category) {
+    $l10n = _get_reader($domain, $category);
+    return _encode($l10n->npgettext($context, $singular, $plural));
+}
+
+
+
+// Wrappers to use if the standard gettext functions are available,
+// but the current locale is not supported by the system.
+// Use the standard impl if the current locale is supported, use the
+// custom impl otherwise.
+
+function T_setlocale($category, $locale) {
+    return _setlocale($category, $locale);
+}
+
+function T_bindtextdomain($domain, $path) {
+    if (_check_locale_and_function()) return bindtextdomain($domain, $path);
+    else return _bindtextdomain($domain, $path);
+}
+function T_bind_textdomain_codeset($domain, $codeset) {
+    // bind_textdomain_codeset is available only in PHP 4.2.0+
+    if (_check_locale_and_function('bind_textdomain_codeset'))
+        return bind_textdomain_codeset($domain, $codeset);
+    else return _bind_textdomain_codeset($domain, $codeset);
+}
+function T_textdomain($domain) {
+    if (_check_locale_and_function()) return textdomain($domain);
+    else return _textdomain($domain);
+}
+function T_gettext($msgid) {
+    if (_check_locale_and_function()) return gettext($msgid);
+    else return _gettext($msgid);
+}
+function T_($msgid) {
+    if (_check_locale_and_function()) return _($msgid);
+    return __($msgid);
+}
+function T_ngettext($singular, $plural, $number) {
+    if (_check_locale_and_function())
+        return ngettext($singular, $plural, $number);
+    else return _ngettext($singular, $plural, $number);
+}
+function T_dgettext($domain, $msgid) {
+    if (_check_locale_and_function()) return dgettext($domain, $msgid);
+    else return _dgettext($domain, $msgid);
+}
+function T_dngettext($domain, $singular, $plural, $number) {
+    if (_check_locale_and_function())
+        return dngettext($domain, $singular, $plural, $number);
+    else return _dngettext($domain, $singular, $plural, $number);
+}
+function T_dcgettext($domain, $msgid, $category) {
+    if (_check_locale_and_function())
+        return dcgettext($domain, $msgid, $category);
+    else return _dcgettext($domain, $msgid, $category);
+}
+function T_dcngettext($domain, $singular, $plural, $number, $category) {
+    if (_check_locale_and_function())
+      return dcngettext($domain, $singular, $plural, $number, $category);
+    else return _dcngettext($domain, $singular, $plural, $number, $category);
+}
+
+function T_pgettext($context, $msgid) {
+  if (_check_locale_and_function('pgettext'))
+      return pgettext($context, $msgid);
+  else
+      return _pgettext($context, $msgid);
+}
+
+function T_dpgettext($domain, $context, $msgid) {
+  if (_check_locale_and_function('dpgettext'))
+      return dpgettext($domain, $context, $msgid);
+  else
+      return _dpgettext($domain, $context, $msgid);
+}
+
+function T_dcpgettext($domain, $context, $msgid, $category) {
+  if (_check_locale_and_function('dcpgettext'))
+      return dcpgettext($domain, $context, $msgid, $category);
+  else
+      return _dcpgettext($domain, $context, $msgid, $category);
+}
+
+function T_npgettext($context, $singular, $plural, $number) {
+    if (_check_locale_and_function('npgettext'))
+        return npgettext($context, $singular, $plural, $number);
+    else
+        return _npgettext($context, $singular, $plural, $number);
+}
+
+function T_dnpgettext($domain, $context, $singular, $plural, $number) {
+  if (_check_locale_and_function('dnpgettext'))
+      return dnpgettext($domain, $context, $singular, $plural, $number);
+  else
+      return _dnpgettext($domain, $context, $singular, $plural, $number);
+}
+
+function T_dcnpgettext($domain, $context, $singular, $plural,
+                       $number, $category) {
+    if (_check_locale_and_function('dcnpgettext'))
+        return dcnpgettext($domain, $context, $singular,
+                           $plural, $number, $category);
+    else
+        return _dcnpgettext($domain, $context, $singular,
+                            $plural, $number, $category);
+}
+
+
+
+// Wrappers used as a drop in replacement for the standard gettext functions
+
+if (!function_exists('gettext')) {
+    function bindtextdomain($domain, $path) {
+        return _bindtextdomain($domain, $path);
+    }
+    function bind_textdomain_codeset($domain, $codeset) {
+        return _bind_textdomain_codeset($domain, $codeset);
+    }
+    function textdomain($domain) {
+        return _textdomain($domain);
+    }
+    function gettext($msgid) {
+        return _gettext($msgid);
+    }
+    function _($msgid) {
+        return __($msgid);
+    }
+    function ngettext($singular, $plural, $number) {
+        return _ngettext($singular, $plural, $number);
+    }
+    function dgettext($domain, $msgid) {
+        return _dgettext($domain, $msgid);
+    }
+    function dngettext($domain, $singular, $plural, $number) {
+        return _dngettext($domain, $singular, $plural, $number);
+    }
+    function dcgettext($domain, $msgid, $category) {
+        return _dcgettext($domain, $msgid, $category);
+    }
+    function dcngettext($domain, $singular, $plural, $number, $category) {
+        return _dcngettext($domain, $singular, $plural, $number, $category);
+    }
+    function pgettext($context, $msgid) {
+        return _pgettext($context, $msgid);
+    }
+    function npgettext($context, $singular, $plural, $number) {
+        return _npgettext($context, $singular, $plural, $number);
+    }
+    function dpgettext($domain, $context, $msgid) {
+        return _dpgettext($domain, $context, $msgid);
+    }
+    function dnpgettext($domain, $context, $singular, $plural, $number) {
+        return _dnpgettext($domain, $context, $singular, $plural, $number);
+    }
+    function dcpgettext($domain, $context, $msgid, $category) {
+        return _dcpgettext($domain, $context, $msgid, $category);
+    }
+    function dcnpgettext($domain, $context, $singular, $plural,
+                         $number, $category) {
+      return _dcnpgettext($domain, $context, $singular, $plural,
+                          $number, $category);
+    }
+}
+
+?>
diff --git a/phpmyadmin/libraries/php-gettext/gettext.php b/phpmyadmin/libraries/php-gettext/gettext.php
new file mode 100644
index 0000000..5064047
--- /dev/null
+++ b/phpmyadmin/libraries/php-gettext/gettext.php
@@ -0,0 +1,432 @@
+<?php
+/*
+   Copyright (c) 2003, 2009 Danilo Segan <danilo at kvota.net>.
+   Copyright (c) 2005 Nico Kaiser <nico at siriux.net>
+
+   This file is part of PHP-gettext.
+
+   PHP-gettext is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2 of the License, or
+   (at your option) any later version.
+
+   PHP-gettext is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with PHP-gettext; if not, write to the Free Software
+   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+
+*/
+
+/**
+ * Provides a simple gettext replacement that works independently from
+ * the system's gettext abilities.
+ * It can read MO files and use them for translating strings.
+ * The files are passed to gettext_reader as a Stream (see streams.php)
+ *
+ * This version has the ability to cache all strings and translations to
+ * speed up the string lookup.
+ * While the cache is enabled by default, it can be switched off with the
+ * second parameter in the constructor (e.g. whenusing very large MO files
+ * that you don't want to keep in memory)
+ */
+class gettext_reader {
+  //public:
+   var $error = 0; // public variable that holds error code (0 if no error)
+
+   //private:
+  var $BYTEORDER = 0;        // 0: low endian, 1: big endian
+  var $STREAM = NULL;
+  var $short_circuit = false;
+  var $enable_cache = false;
+  var $originals = NULL;      // offset of original table
+  var $translations = NULL;    // offset of translation table
+  var $pluralheader = NULL;    // cache header field for plural forms
+  var $total = 0;          // total string count
+  var $table_originals = NULL;  // table for original strings (offsets)
+  var $table_translations = NULL;  // table for translated strings (offsets)
+  var $cache_translations = NULL;  // original -> translation mapping
+
+
+  /* Methods */
+
+
+  /**
+   * Reads a 32bit Integer from the Stream
+   *
+   * @access private
+   * @return Integer from the Stream
+   */
+  function readint() {
+      if ($this->BYTEORDER == 0) {
+        // low endian
+        $input=unpack('V', $this->STREAM->read(4));
+        return array_shift($input);
+      } else {
+        // big endian
+        $input=unpack('N', $this->STREAM->read(4));
+        return array_shift($input);
+      }
+    }
+
+  function read($bytes) {
+    return $this->STREAM->read($bytes);
+  }
+
+  /**
+   * Reads an array of Integers from the Stream
+   *
+   * @param int count How many elements should be read
+   * @return Array of Integers
+   */
+  function readintarray($count) {
+    if ($this->BYTEORDER == 0) {
+        // low endian
+        return unpack('V'.$count, $this->STREAM->read(4 * $count));
+      } else {
+        // big endian
+        return unpack('N'.$count, $this->STREAM->read(4 * $count));
+      }
+  }
+
+  /**
+   * Constructor
+   *
+   * @param object Reader the StreamReader object
+   * @param boolean enable_cache Enable or disable caching of strings (default on)
+   */
+  function gettext_reader($Reader, $enable_cache = true) {
+    // If there isn't a StreamReader, turn on short circuit mode.
+    if (! $Reader || isset($Reader->error) ) {
+      $this->short_circuit = true;
+      return;
+    }
+
+    // Caching can be turned off
+    $this->enable_cache = $enable_cache;
+
+    $MAGIC1 = "\x95\x04\x12\xde";
+    $MAGIC2 = "\xde\x12\x04\x95";
+
+    $this->STREAM = $Reader;
+    $magic = $this->read(4);
+    if ($magic == $MAGIC1) {
+      $this->BYTEORDER = 1;
+    } elseif ($magic == $MAGIC2) {
+      $this->BYTEORDER = 0;
+    } else {
+      $this->error = 1; // not MO file
+      return false;
+    }
+
+    // FIXME: Do we care about revision? We should.
+    $revision = $this->readint();
+
+    $this->total = $this->readint();
+    $this->originals = $this->readint();
+    $this->translations = $this->readint();
+  }
+
+  /**
+   * Loads the translation tables from the MO file into the cache
+   * If caching is enabled, also loads all strings into a cache
+   * to speed up translation lookups
+   *
+   * @access private
+   */
+  function load_tables() {
+    if (is_array($this->cache_translations) &&
+      is_array($this->table_originals) &&
+      is_array($this->table_translations))
+      return;
+
+    /* get original and translations tables */
+    if (!is_array($this->table_originals)) {
+      $this->STREAM->seekto($this->originals);
+      $this->table_originals = $this->readintarray($this->total * 2);
+    }
+    if (!is_array($this->table_translations)) {
+      $this->STREAM->seekto($this->translations);
+      $this->table_translations = $this->readintarray($this->total * 2);
+    }
+
+    if ($this->enable_cache) {
+      $this->cache_translations = array ();
+      /* read all strings in the cache */
+      for ($i = 0; $i < $this->total; $i++) {
+        $this->STREAM->seekto($this->table_originals[$i * 2 + 2]);
+        $original = $this->STREAM->read($this->table_originals[$i * 2 + 1]);
+        $this->STREAM->seekto($this->table_translations[$i * 2 + 2]);
+        $translation = $this->STREAM->read($this->table_translations[$i * 2 + 1]);
+        $this->cache_translations[$original] = $translation;
+      }
+    }
+  }
+
+  /**
+   * Returns a string from the "originals" table
+   *
+   * @access private
+   * @param int num Offset number of original string
+   * @return string Requested string if found, otherwise ''
+   */
+  function get_original_string($num) {
+    $length = $this->table_originals[$num * 2 + 1];
+    $offset = $this->table_originals[$num * 2 + 2];
+    if (! $length)
+      return '';
+    $this->STREAM->seekto($offset);
+    $data = $this->STREAM->read($length);
+    return (string)$data;
+  }
+
+  /**
+   * Returns a string from the "translations" table
+   *
+   * @access private
+   * @param int num Offset number of original string
+   * @return string Requested string if found, otherwise ''
+   */
+  function get_translation_string($num) {
+    $length = $this->table_translations[$num * 2 + 1];
+    $offset = $this->table_translations[$num * 2 + 2];
+    if (! $length)
+      return '';
+    $this->STREAM->seekto($offset);
+    $data = $this->STREAM->read($length);
+    return (string)$data;
+  }
+
+  /**
+   * Binary search for string
+   *
+   * @access private
+   * @param string string
+   * @param int start (internally used in recursive function)
+   * @param int end (internally used in recursive function)
+   * @return int string number (offset in originals table)
+   */
+  function find_string($string, $start = -1, $end = -1) {
+    if (($start == -1) or ($end == -1)) {
+      // find_string is called with only one parameter, set start end end
+      $start = 0;
+      $end = $this->total;
+    }
+    if (abs($start - $end) <= 1) {
+      // We're done, now we either found the string, or it doesn't exist
+      $txt = $this->get_original_string($start);
+      if ($string == $txt)
+        return $start;
+      else
+        return -1;
+    } else if ($start > $end) {
+      // start > end -> turn around and start over
+      return $this->find_string($string, $end, $start);
+    } else {
+      // Divide table in two parts
+      $half = (int)(($start + $end) / 2);
+      $cmp = strcmp($string, $this->get_original_string($half));
+      if ($cmp == 0)
+        // string is exactly in the middle => return it
+        return $half;
+      else if ($cmp < 0)
+        // The string is in the upper half
+        return $this->find_string($string, $start, $half);
+      else
+        // The string is in the lower half
+        return $this->find_string($string, $half, $end);
+    }
+  }
+
+  /**
+   * Translates a string
+   *
+   * @access public
+   * @param string string to be translated
+   * @return string translated string (or original, if not found)
+   */
+  function translate($string) {
+    if ($this->short_circuit)
+      return $string;
+    $this->load_tables();
+
+    if ($this->enable_cache) {
+      // Caching enabled, get translated string from cache
+      if (array_key_exists($string, $this->cache_translations))
+        return $this->cache_translations[$string];
+      else
+        return $string;
+    } else {
+      // Caching not enabled, try to find string
+      $num = $this->find_string($string);
+      if ($num == -1)
+        return $string;
+      else
+        return $this->get_translation_string($num);
+    }
+  }
+
+  /**
+   * Sanitize plural form expression for use in PHP eval call.
+   *
+   * @access private
+   * @return string sanitized plural form expression
+   */
+  function sanitize_plural_expression($expr) {
+    // Get rid of disallowed characters.
+    $expr = preg_replace('@[^a-zA-Z0-9_:;\(\)\?\|\&=!<>+*/\%-]@', '', $expr);
+
+    // Add parenthesis for tertiary '?' operator.
+    $expr .= ';';
+    $res = '';
+    $p = 0;
+    for ($i = 0; $i < strlen($expr); $i++) {
+      $ch = $expr[$i];
+      switch ($ch) {
+      case '?':
+        $res .= ' ? (';
+        $p++;
+        break;
+      case ':':
+        $res .= ') : (';
+        break;
+      case ';':
+        $res .= str_repeat( ')', $p) . ';';
+        $p = 0;
+        break;
+      default:
+        $res .= $ch;
+      }
+    }
+    return $res;
+  }
+
+  /**
+   * Parse full PO header and extract only plural forms line.
+   *
+   * @access private
+   * @return string verbatim plural form header field
+   */
+  function extract_plural_forms_header_from_po_header($header) {
+    if (preg_match("/(^|\n)plural-forms: ([^\n]*)\n/i", $header, $regs))
+      $expr = $regs[2];
+    else
+      $expr = "nplurals=2; plural=n == 1 ? 0 : 1;";
+    return $expr;
+  }
+
+  /**
+   * Get possible plural forms from MO header
+   *
+   * @access private
+   * @return string plural form header
+   */
+  function get_plural_forms() {
+    // lets assume message number 0 is header
+    // this is true, right?
+    $this->load_tables();
+
+    // cache header field for plural forms
+    if (! is_string($this->pluralheader)) {
+      if ($this->enable_cache) {
+        $header = $this->cache_translations[""];
+      } else {
+        $header = $this->get_translation_string(0);
+      }
+      $expr = $this->extract_plural_forms_header_from_po_header($header);
+      $this->pluralheader = $this->sanitize_plural_expression($expr);
+    }
+    return $this->pluralheader;
+  }
+
+  /**
+   * Detects which plural form to take
+   *
+   * @access private
+   * @param n count
+   * @return int array index of the right plural form
+   */
+  function select_string($n) {
+    $string = $this->get_plural_forms();
+    $string = str_replace('nplurals',"\$total",$string);
+    $string = str_replace("n",$n,$string);
+    $string = str_replace('plural',"\$plural",$string);
+
+    $total = 0;
+    $plural = 0;
+
+    eval("$string");
+    if ($plural >= $total) $plural = $total - 1;
+    return $plural;
+  }
+
+  /**
+   * Plural version of gettext
+   *
+   * @access public
+   * @param string single
+   * @param string plural
+   * @param string number
+   * @return translated plural form
+   */
+  function ngettext($single, $plural, $number) {
+    if ($this->short_circuit) {
+      if ($number != 1)
+        return $plural;
+      else
+        return $single;
+    }
+
+    // find out the appropriate form
+    $select = $this->select_string($number);
+
+    // this should contains all strings separated by NULLs
+    $key = $single . chr(0) . $plural;
+
+
+    if ($this->enable_cache) {
+      if (! array_key_exists($key, $this->cache_translations)) {
+        return ($number != 1) ? $plural : $single;
+      } else {
+        $result = $this->cache_translations[$key];
+        $list = explode(chr(0), $result);
+        return $list[$select];
+      }
+    } else {
+      $num = $this->find_string($key);
+      if ($num == -1) {
+        return ($number != 1) ? $plural : $single;
+      } else {
+        $result = $this->get_translation_string($num);
+        $list = explode(chr(0), $result);
+        return $list[$select];
+      }
+    }
+  }
+
+  function pgettext($context, $msgid) {
+    $key = $context . chr(4) . $msgid;
+    $ret = $this->translate($key);
+    if (strpos($ret, "\004") !== FALSE) {
+      return $msgid;
+    } else {
+      return $ret;
+    }
+  }
+
+  function npgettext($context, $singular, $plural, $number) {
+    $key = $context . chr(4) . $singular;
+    $ret = $this->ngettext($key, $plural, $number);
+    if (strpos($ret, "\004") !== FALSE) {
+      return $singular;
+    } else {
+      return $ret;
+    }
+
+  }
+}
+
+?>
diff --git a/phpmyadmin/libraries/php-gettext/streams.php b/phpmyadmin/libraries/php-gettext/streams.php
new file mode 100644
index 0000000..3cdc158
--- /dev/null
+++ b/phpmyadmin/libraries/php-gettext/streams.php
@@ -0,0 +1,167 @@
+<?php
+/*
+   Copyright (c) 2003, 2005, 2006, 2009 Danilo Segan <danilo at kvota.net>.
+
+   This file is part of PHP-gettext.
+
+   PHP-gettext is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2 of the License, or
+   (at your option) any later version.
+
+   PHP-gettext is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with PHP-gettext; if not, write to the Free Software
+   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+
+*/
+
+
+  // Simple class to wrap file streams, string streams, etc.
+  // seek is essential, and it should be byte stream
+class StreamReader {
+  // should return a string [FIXME: perhaps return array of bytes?]
+  function read($bytes) {
+    return false;
+  }
+
+  // should return new position
+  function seekto($position) {
+    return false;
+  }
+
+  // returns current position
+  function currentpos() {
+    return false;
+  }
+
+  // returns length of entire stream (limit for seekto()s)
+  function length() {
+    return false;
+  }
+};
+
+class StringReader {
+  var $_pos;
+  var $_str;
+
+  function StringReader($str='') {
+    $this->_str = $str;
+    $this->_pos = 0;
+  }
+
+  function read($bytes) {
+    $data = substr($this->_str, $this->_pos, $bytes);
+    $this->_pos += $bytes;
+    if (strlen($this->_str)<$this->_pos)
+      $this->_pos = strlen($this->_str);
+
+    return $data;
+  }
+
+  function seekto($pos) {
+    $this->_pos = $pos;
+    if (strlen($this->_str)<$this->_pos)
+      $this->_pos = strlen($this->_str);
+    return $this->_pos;
+  }
+
+  function currentpos() {
+    return $this->_pos;
+  }
+
+  function length() {
+    return strlen($this->_str);
+  }
+
+};
+
+
+class FileReader {
+  var $_pos;
+  var $_fd;
+  var $_length;
+
+  function FileReader($filename) {
+    if (file_exists($filename)) {
+
+      $this->_length=filesize($filename);
+      $this->_pos = 0;
+      $this->_fd = fopen($filename,'rb');
+      if (!$this->_fd) {
+        $this->error = 3; // Cannot read file, probably permissions
+        return false;
+      }
+    } else {
+      $this->error = 2; // File doesn't exist
+      return false;
+    }
+  }
+
+  function read($bytes) {
+    if ($bytes) {
+      fseek($this->_fd, $this->_pos);
+
+      // PHP 5.1.1 does not read more than 8192 bytes in one fread()
+      // the discussions at PHP Bugs suggest it's the intended behaviour
+      $data = '';
+      while ($bytes > 0) {
+        $chunk  = fread($this->_fd, $bytes);
+        $data  .= $chunk;
+        $bytes -= strlen($chunk);
+      }
+      $this->_pos = ftell($this->_fd);
+
+      return $data;
+    } else return '';
+  }
+
+  function seekto($pos) {
+    fseek($this->_fd, $pos);
+    $this->_pos = ftell($this->_fd);
+    return $this->_pos;
+  }
+
+  function currentpos() {
+    return $this->_pos;
+  }
+
+  function length() {
+    return $this->_length;
+  }
+
+  function close() {
+    fclose($this->_fd);
+  }
+
+};
+
+// Preloads entire file in memory first, then creates a StringReader
+// over it (it assumes knowledge of StringReader internals)
+class CachedFileReader extends StringReader {
+  function CachedFileReader($filename) {
+    if (file_exists($filename)) {
+
+      $length=filesize($filename);
+      $fd = fopen($filename,'rb');
+
+      if (!$fd) {
+        $this->error = 3; // Cannot read file, probably permissions
+        return false;
+      }
+      $this->_str = fread($fd, $length);
+      fclose($fd);
+
+    } else {
+      $this->error = 2; // File doesn't exist
+      return false;
+    }
+  }
+};
+
+
+?>
diff --git a/phpmyadmin/libraries/phpseclib/Crypt/AES.php b/phpmyadmin/libraries/phpseclib/Crypt/AES.php
new file mode 100644
index 0000000..58c8b52
--- /dev/null
+++ b/phpmyadmin/libraries/phpseclib/Crypt/AES.php
@@ -0,0 +1,612 @@
+<?php
+/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
+
+/**
+ * Pure-PHP implementation of AES.
+ *
+ * Uses mcrypt, if available, and an internal implementation, otherwise.
+ *
+ * PHP versions 4 and 5
+ *
+ * If {@link Crypt_AES::setKeyLength() setKeyLength()} isn't called, it'll be calculated from
+ * {@link Crypt_AES::setKey() setKey()}.  ie. if the key is 128-bits, the key length will be 128-bits.  If it's 136-bits
+ * it'll be null-padded to 160-bits and 160 bits will be the key length until {@link Crypt_Rijndael::setKey() setKey()}
+ * is called, again, at which point, it'll be recalculated.
+ *
+ * Since Crypt_AES extends Crypt_Rijndael, some functions are available to be called that, in the context of AES, don't
+ * make a whole lot of sense.  {@link Crypt_AES::setBlockLength() setBlockLength()}, for instance.  Calling that function,
+ * however possible, won't do anything (AES has a fixed block length whereas Rijndael has a variable one).
+ *
+ * Here's a short example of how to use this library:
+ * <code>
+ * <?php
+ *    include('Crypt/AES.php');
+ *
+ *    $aes = new Crypt_AES();
+ *
+ *    $aes->setKey('abcdefghijklmnop');
+ *
+ *    $size = 10 * 1024;
+ *    $plaintext = '';
+ *    for ($i = 0; $i < $size; $i++) {
+ *        $plaintext.= 'a';
+ *    }
+ *
+ *    echo $aes->decrypt($aes->encrypt($plaintext));
+ * ?>
+ * </code>
+ *
+ * LICENSE: Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ *
+ * @category   Crypt
+ * @package    Crypt_AES
+ * @author     Jim Wigginton <terrafrost at php.net>
+ * @copyright  MMVIII Jim Wigginton
+ * @license    http://www.opensource.org/licenses/mit-license.html  MIT License
+ * @version    $Id: AES.php,v 1.7 2010/02/09 06:10:25 terrafrost Exp $
+ * @link       http://phpseclib.sourceforge.net
+ */
+
+/**
+ * Include Crypt_Rijndael
+ */
+if (!class_exists('Crypt_Rijndael')) {
+    require_once 'Rijndael.php';
+}
+
+/**#@+
+ * @access public
+ * @see Crypt_AES::encrypt()
+ * @see Crypt_AES::decrypt()
+ */
+/**
+ * Encrypt / decrypt using the Counter mode.
+ *
+ * Set to -1 since that's what Crypt/Random.php uses to index the CTR mode.
+ *
+ * @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Counter_.28CTR.29
+ */
+define('CRYPT_AES_MODE_CTR', -1);
+/**
+ * Encrypt / decrypt using the Electronic Code Book mode.
+ *
+ * @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Electronic_codebook_.28ECB.29
+ */
+define('CRYPT_AES_MODE_ECB', 1);
+/**
+ * Encrypt / decrypt using the Code Book Chaining mode.
+ *
+ * @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Cipher-block_chaining_.28CBC.29
+ */
+define('CRYPT_AES_MODE_CBC', 2);
+/**
+ * Encrypt / decrypt using the Cipher Feedback mode.
+ *
+ * @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Cipher_feedback_.28CFB.29
+ */
+define('CRYPT_AES_MODE_CFB', 3);
+/**
+ * Encrypt / decrypt using the Cipher Feedback mode.
+ *
+ * @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Output_feedback_.28OFB.29
+ */
+define('CRYPT_AES_MODE_OFB', 4);
+/**#@-*/
+
+/**#@+
+ * @access private
+ * @see Crypt_AES::Crypt_AES()
+ */
+/**
+ * Toggles the internal implementation
+ */
+define('CRYPT_AES_MODE_INTERNAL', 1);
+/**
+ * Toggles the mcrypt implementation
+ */
+define('CRYPT_AES_MODE_MCRYPT', 2);
+/**#@-*/
+
+/**
+ * Pure-PHP implementation of AES.
+ *
+ * @author  Jim Wigginton <terrafrost at php.net>
+ * @version 0.1.0
+ * @access  public
+ * @package Crypt_AES
+ */
+class Crypt_AES extends Crypt_Rijndael {
+    /**
+     * mcrypt resource for encryption
+     *
+     * The mcrypt resource can be recreated every time something needs to be created or it can be created just once.
+     * Since mcrypt operates in continuous mode, by default, it'll need to be recreated when in non-continuous mode.
+     *
+     * @see Crypt_AES::encrypt()
+     * @var String
+     * @access private
+     */
+    var $enmcrypt;
+
+    /**
+     * mcrypt resource for decryption
+     *
+     * The mcrypt resource can be recreated every time something needs to be created or it can be created just once.
+     * Since mcrypt operates in continuous mode, by default, it'll need to be recreated when in non-continuous mode.
+     *
+     * @see Crypt_AES::decrypt()
+     * @var String
+     * @access private
+     */
+    var $demcrypt;
+
+    /**
+     * mcrypt resource for CFB mode
+     *
+     * @see Crypt_AES::encrypt()
+     * @see Crypt_AES::decrypt()
+     * @var String
+     * @access private
+     */
+    var $ecb;
+
+    /**
+     * Default Constructor.
+     *
+     * Determines whether or not the mcrypt extension should be used.  $mode should only, at present, be
+     * CRYPT_AES_MODE_ECB or CRYPT_AES_MODE_CBC.  If not explictly set, CRYPT_AES_MODE_CBC will be used.
+     *
+     * @param optional Integer $mode
+     * @return Crypt_AES
+     * @access public
+     */
+    function Crypt_AES($mode = CRYPT_AES_MODE_CBC)
+    {
+        if ( !defined('CRYPT_AES_MODE') ) {
+            switch (true) {
+                case extension_loaded('mcrypt') && in_array('rijndael-128', mcrypt_list_algorithms()):
+                    define('CRYPT_AES_MODE', CRYPT_AES_MODE_MCRYPT);
+                    break;
+                default:
+                    define('CRYPT_AES_MODE', CRYPT_AES_MODE_INTERNAL);
+            }
+        }
+
+        switch ( CRYPT_AES_MODE ) {
+            case CRYPT_AES_MODE_MCRYPT:
+                switch ($mode) {
+                    case CRYPT_AES_MODE_ECB:
+                        $this->paddable = true;
+                        $this->mode = MCRYPT_MODE_ECB;
+                        break;
+                    case CRYPT_AES_MODE_CTR:
+                        // ctr doesn't have a constant associated with it even though it appears to be fairly widely
+                        // supported.  in lieu of knowing just how widely supported it is, i've, for now, opted not to
+                        // include a compatibility layer.  the layer has been implemented but, for now, is commented out.
+                        $this->mode = 'ctr';
+                        //$this->mode = in_array('ctr', mcrypt_list_modes()) ? 'ctr' : CRYPT_AES_MODE_CTR;
+                        break;
+                    case CRYPT_AES_MODE_CFB:
+                        $this->mode = 'ncfb';
+                        break;
+                    case CRYPT_AES_MODE_OFB:
+                        $this->mode = MCRYPT_MODE_NOFB;
+                        break;
+                    case CRYPT_AES_MODE_CBC:
+                    default:
+                        $this->paddable = true;
+                        $this->mode = MCRYPT_MODE_CBC;
+                }
+
+                $this->debuffer = $this->enbuffer = '';
+
+                break;
+            default:
+                switch ($mode) {
+                    case CRYPT_AES_MODE_ECB:
+                        $this->paddable = true;
+                        $this->mode = CRYPT_RIJNDAEL_MODE_ECB;
+                        break;
+                    case CRYPT_AES_MODE_CTR:
+                        $this->mode = CRYPT_RIJNDAEL_MODE_CTR;
+                        break;
+                    case CRYPT_AES_MODE_CFB:
+                        $this->mode = CRYPT_RIJNDAEL_MODE_CFB;
+                        break;
+                    case CRYPT_AES_MODE_OFB:
+                        $this->mode = CRYPT_RIJNDAEL_MODE_OFB;
+                        break;
+                    case CRYPT_AES_MODE_CBC:
+                    default:
+                        $this->paddable = true;
+                        $this->mode = CRYPT_RIJNDAEL_MODE_CBC;
+                }
+        }
+
+        if (CRYPT_AES_MODE == CRYPT_AES_MODE_INTERNAL) {
+            parent::Crypt_Rijndael($this->mode);
+        }
+    }
+
+    /**
+     * Dummy function
+     *
+     * Since Crypt_AES extends Crypt_Rijndael, this function is, technically, available, but it doesn't do anything.
+     *
+     * @access public
+     * @param Integer $length
+     */
+    function setBlockLength($length)
+    {
+        return;
+    }
+
+
+    /**
+     * Sets the initialization vector. (optional)
+     *
+     * SetIV is not required when CRYPT_RIJNDAEL_MODE_ECB is being used.  If not explictly set, it'll be assumed
+     * to be all zero's.
+     *
+     * @access public
+     * @param String $iv
+     */
+    function setIV($iv)
+    {
+        parent::setIV($iv);
+        if ( CRYPT_AES_MODE == CRYPT_AES_MODE_MCRYPT ) {
+            $this->changed = true;
+        }
+    }
+
+    /**
+     * Encrypts a message.
+     *
+     * $plaintext will be padded with up to 16 additional bytes.  Other AES implementations may or may not pad in the
+     * same manner.  Other common approaches to padding and the reasons why it's necessary are discussed in the following
+     * URL:
+     *
+     * {@link http://www.di-mgt.com.au/cryptopad.html http://www.di-mgt.com.au/cryptopad.html}
+     *
+     * An alternative to padding is to, separately, send the length of the file.  This is what SSH, in fact, does.
+     * strlen($plaintext) will still need to be a multiple of 16, however, arbitrary values can be added to make it that
+     * length.
+     *
+     * @see Crypt_AES::decrypt()
+     * @access public
+     * @param String $plaintext
+     */
+    function encrypt($plaintext)
+    {
+        if ( CRYPT_AES_MODE == CRYPT_AES_MODE_MCRYPT ) {
+            $changed = $this->changed;
+            $this->_mcryptSetup();
+            /*
+            if ($this->mode == CRYPT_AES_MODE_CTR) {
+                $iv = $this->encryptIV;
+                $xor = mcrypt_generic($this->enmcrypt, $this->_generate_xor(strlen($plaintext), $iv));
+                $ciphertext = $plaintext ^ $xor;
+                if ($this->continuousBuffer) {
+                    $this->encryptIV = $iv;
+                }
+                return $ciphertext;
+            }
+            */
+            // re: http://phpseclib.sourceforge.net/cfb-demo.phps
+            // using mcrypt's default handing of CFB the above would output two different things.  using phpseclib's
+            // rewritten CFB implementation the above outputs the same thing twice.
+            if ($this->mode == 'ncfb') {
+                if ($changed) {
+                    $this->ecb = mcrypt_module_open(MCRYPT_RIJNDAEL_128, '', MCRYPT_MODE_ECB, '');
+                    mcrypt_generic_init($this->ecb, $this->key, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0");
+                }
+
+                if (strlen($this->enbuffer)) {
+                    $ciphertext = $plaintext ^ substr($this->encryptIV, strlen($this->enbuffer));
+                    $this->enbuffer.= $ciphertext;
+                    if (strlen($this->enbuffer) == 16) {
+                        $this->encryptIV = $this->enbuffer;
+                        $this->enbuffer = '';
+                        mcrypt_generic_init($this->enmcrypt, $this->key, $this->encryptIV);
+                    }
+                    $plaintext = substr($plaintext, strlen($ciphertext));
+                } else {
+                    $ciphertext = '';
+                }
+
+                $last_pos = strlen($plaintext) & 0xFFFFFFF0;
+                $ciphertext.= $last_pos ? mcrypt_generic($this->enmcrypt, substr($plaintext, 0, $last_pos)) : '';
+
+                if (strlen($plaintext) & 0xF) {
+                    if (strlen($ciphertext)) {
+                        $this->encryptIV = substr($ciphertext, -16);
+                    }
+                    $this->encryptIV = mcrypt_generic($this->ecb, $this->encryptIV);
+                    $this->enbuffer = substr($plaintext, $last_pos) ^ $this->encryptIV;
+                    $ciphertext.= $this->enbuffer;
+                }
+
+                return $ciphertext;
+            }
+
+            if ($this->paddable) {
+                $plaintext = $this->_pad($plaintext);
+            }
+
+            $ciphertext = mcrypt_generic($this->enmcrypt, $plaintext);
+
+            if (!$this->continuousBuffer) {
+                mcrypt_generic_init($this->enmcrypt, $this->key, $this->iv);
+            }
+
+            return $ciphertext;
+        }
+
+        return parent::encrypt($plaintext);
+    }
+
+    /**
+     * Decrypts a message.
+     *
+     * If strlen($ciphertext) is not a multiple of 16, null bytes will be added to the end of the string until it is.
+     *
+     * @see Crypt_AES::encrypt()
+     * @access public
+     * @param String $ciphertext
+     */
+    function decrypt($ciphertext)
+    {
+        if ( CRYPT_AES_MODE == CRYPT_AES_MODE_MCRYPT ) {
+            $changed = $this->changed;
+            $this->_mcryptSetup();
+            /*
+            if ($this->mode == CRYPT_AES_MODE_CTR) {
+                $iv = $this->decryptIV;
+                $xor = mcrypt_generic($this->enmcrypt, $this->_generate_xor(strlen($ciphertext), $iv));
+                $plaintext = $ciphertext ^ $xor;
+                if ($this->continuousBuffer) {
+                    $this->decryptIV = $iv;
+                }
+                return $plaintext;
+            }
+            */
+            if ($this->mode == 'ncfb') {
+                if ($changed) {
+                    $this->ecb = mcrypt_module_open(MCRYPT_RIJNDAEL_128, '', MCRYPT_MODE_ECB, '');
+                    mcrypt_generic_init($this->ecb, $this->key, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0");
+                }
+
+                if (strlen($this->debuffer)) {
+                    $plaintext = $ciphertext ^ substr($this->decryptIV, strlen($this->debuffer));
+
+                    $this->debuffer.= substr($ciphertext, 0, strlen($plaintext));
+                    if (strlen($this->debuffer) == 16) {
+                        $this->decryptIV = $this->debuffer;
+                        $this->debuffer = '';
+                        mcrypt_generic_init($this->demcrypt, $this->key, $this->decryptIV);
+                    }
+                    $ciphertext = substr($ciphertext, strlen($plaintext));
+                } else {
+                    $plaintext = '';
+                }
+
+                $last_pos = strlen($ciphertext) & 0xFFFFFFF0;
+                $plaintext.= $last_pos ? mdecrypt_generic($this->demcrypt, substr($ciphertext, 0, $last_pos)) : '';
+
+                if (strlen($ciphertext) & 0xF) {
+                    if (strlen($plaintext)) {
+                        $this->decryptIV = substr($ciphertext, $last_pos - 16, 16);
+                    }
+                    $this->decryptIV = mcrypt_generic($this->ecb, $this->decryptIV);
+                    $this->debuffer = substr($ciphertext, $last_pos);
+                    $plaintext.= $this->debuffer ^ $this->decryptIV;
+                }
+
+                return $plaintext;
+            }
+
+            if ($this->paddable) {
+                // we pad with chr(0) since that's what mcrypt_generic does.  to quote from http://php.net/function.mcrypt-generic :
+                // "The data is padded with "\0" to make sure the length of the data is n * blocksize."
+                $ciphertext = str_pad($ciphertext, (strlen($ciphertext) + 15) & 0xFFFFFFF0, chr(0));
+            }
+
+            $plaintext = mdecrypt_generic($this->demcrypt, $ciphertext);
+
+            if (!$this->continuousBuffer) {
+                mcrypt_generic_init($this->demcrypt, $this->key, $this->iv);
+            }
+
+            return $this->paddable ? $this->_unpad($plaintext) : $plaintext;
+        }
+
+        return parent::decrypt($ciphertext);
+    }
+
+    /**
+     * Setup mcrypt
+     *
+     * Validates all the variables.
+     *
+     * @access private
+     */
+    function _mcryptSetup()
+    {
+        if (!$this->changed) {
+            return;
+        }
+
+        if (!$this->explicit_key_length) {
+            // this just copied from Crypt_Rijndael::_setup()
+            $length = strlen($this->key) >> 2;
+            if ($length > 8) {
+                $length = 8;
+            } else if ($length < 4) {
+                $length = 4;
+            }
+            $this->Nk = $length;
+            $this->key_size = $length << 2;
+        }
+
+        switch ($this->Nk) {
+            case 4: // 128
+                $this->key_size = 16;
+                break;
+            case 5: // 160
+            case 6: // 192
+                $this->key_size = 24;
+                break;
+            case 7: // 224
+            case 8: // 256
+                $this->key_size = 32;
+        }
+
+        $this->key = str_pad(substr($this->key, 0, $this->key_size), $this->key_size, chr(0));
+        $this->encryptIV = $this->decryptIV = $this->iv = str_pad(substr($this->iv, 0, 16), 16, chr(0));
+
+        if (!isset($this->enmcrypt)) {
+            $mode = $this->mode;
+            //$mode = $this->mode == CRYPT_AES_MODE_CTR ? MCRYPT_MODE_ECB : $this->mode;
+
+            $this->demcrypt = mcrypt_module_open(MCRYPT_RIJNDAEL_128, '', $mode, '');
+            $this->enmcrypt = mcrypt_module_open(MCRYPT_RIJNDAEL_128, '', $mode, '');
+        } // else should mcrypt_generic_deinit be called?
+
+        mcrypt_generic_init($this->demcrypt, $this->key, $this->iv);
+        mcrypt_generic_init($this->enmcrypt, $this->key, $this->iv);
+
+        $this->changed = false;
+    }
+
+    /**
+     * Encrypts a block
+     *
+     * Optimized over Crypt_Rijndael's implementation by means of loop unrolling.
+     *
+     * @see Crypt_Rijndael::_encryptBlock()
+     * @access private
+     * @param String $in
+     * @return String
+     */
+    function _encryptBlock($in)
+    {
+        $state = unpack('N*word', $in);
+
+        $Nr = $this->Nr;
+        $w = $this->w;
+        $t0 = $this->t0;
+        $t1 = $this->t1;
+        $t2 = $this->t2;
+        $t3 = $this->t3;
+
+        // addRoundKey and reindex $state
+        $state = array(
+            $state['word1'] ^ $w[0][0],
+            $state['word2'] ^ $w[0][1],
+            $state['word3'] ^ $w[0][2],
+            $state['word4'] ^ $w[0][3]
+        );
+
+        // shiftRows + subWord + mixColumns + addRoundKey
+        // we could loop unroll this and use if statements to do more rounds as necessary, but, in my tests, that yields
+        // only a marginal improvement.  since that also, imho, hinders the readability of the code, i've opted not to do it.
+        for ($round = 1; $round < $this->Nr; $round++) {
+            $state = array(
+                $t0[$state[0] & 0xFF000000] ^ $t1[$state[1] & 0x00FF0000] ^ $t2[$state[2] & 0x0000FF00] ^ $t3[$state[3] & 0x000000FF] ^ $w[$round][0],
+                $t0[$state[1] & 0xFF000000] ^ $t1[$state[2] & 0x00FF0000] ^ $t2[$state[3] & 0x0000FF00] ^ $t3[$state[0] & 0x000000FF] ^ $w[$round][1],
+                $t0[$state[2] & 0xFF000000] ^ $t1[$state[3] & 0x00FF0000] ^ $t2[$state[0] & 0x0000FF00] ^ $t3[$state[1] & 0x000000FF] ^ $w[$round][2],
+                $t0[$state[3] & 0xFF000000] ^ $t1[$state[0] & 0x00FF0000] ^ $t2[$state[1] & 0x0000FF00] ^ $t3[$state[2] & 0x000000FF] ^ $w[$round][3]
+            );
+
+        }
+
+        // subWord
+        $state = array(
+            $this->_subWord($state[0]),
+            $this->_subWord($state[1]),
+            $this->_subWord($state[2]),
+            $this->_subWord($state[3])
+        );
+
+        // shiftRows + addRoundKey
+        $state = array(
+            ($state[0] & 0xFF000000) ^ ($state[1] & 0x00FF0000) ^ ($state[2] & 0x0000FF00) ^ ($state[3] & 0x000000FF) ^ $this->w[$this->Nr][0],
+            ($state[1] & 0xFF000000) ^ ($state[2] & 0x00FF0000) ^ ($state[3] & 0x0000FF00) ^ ($state[0] & 0x000000FF) ^ $this->w[$this->Nr][1],
+            ($state[2] & 0xFF000000) ^ ($state[3] & 0x00FF0000) ^ ($state[0] & 0x0000FF00) ^ ($state[1] & 0x000000FF) ^ $this->w[$this->Nr][2],
+            ($state[3] & 0xFF000000) ^ ($state[0] & 0x00FF0000) ^ ($state[1] & 0x0000FF00) ^ ($state[2] & 0x000000FF) ^ $this->w[$this->Nr][3]
+        );
+
+        return pack('N*', $state[0], $state[1], $state[2], $state[3]);
+    }
+
+    /**
+     * Decrypts a block
+     *
+     * Optimized over Crypt_Rijndael's implementation by means of loop unrolling.
+     *
+     * @see Crypt_Rijndael::_decryptBlock()
+     * @access private
+     * @param String $in
+     * @return String
+     */
+    function _decryptBlock($in)
+    {
+        $state = unpack('N*word', $in);
+
+        $Nr = $this->Nr;
+        $dw = $this->dw;
+        $dt0 = $this->dt0;
+        $dt1 = $this->dt1;
+        $dt2 = $this->dt2;
+        $dt3 = $this->dt3;
+
+        // addRoundKey and reindex $state
+        $state = array(
+            $state['word1'] ^ $dw[$this->Nr][0],
+            $state['word2'] ^ $dw[$this->Nr][1],
+            $state['word3'] ^ $dw[$this->Nr][2],
+            $state['word4'] ^ $dw[$this->Nr][3]
+        );
+
+
+        // invShiftRows + invSubBytes + invMixColumns + addRoundKey
+        for ($round = $this->Nr - 1; $round > 0; $round--) {
+            $state = array(
+                $dt0[$state[0] & 0xFF000000] ^ $dt1[$state[3] & 0x00FF0000] ^ $dt2[$state[2] & 0x0000FF00] ^ $dt3[$state[1] & 0x000000FF] ^ $dw[$round][0],
+                $dt0[$state[1] & 0xFF000000] ^ $dt1[$state[0] & 0x00FF0000] ^ $dt2[$state[3] & 0x0000FF00] ^ $dt3[$state[2] & 0x000000FF] ^ $dw[$round][1],
+                $dt0[$state[2] & 0xFF000000] ^ $dt1[$state[1] & 0x00FF0000] ^ $dt2[$state[0] & 0x0000FF00] ^ $dt3[$state[3] & 0x000000FF] ^ $dw[$round][2],
+                $dt0[$state[3] & 0xFF000000] ^ $dt1[$state[2] & 0x00FF0000] ^ $dt2[$state[1] & 0x0000FF00] ^ $dt3[$state[0] & 0x000000FF] ^ $dw[$round][3]
+            );
+        }
+
+        // invShiftRows + invSubWord + addRoundKey
+        $state = array(
+            $this->_invSubWord(($state[0] & 0xFF000000) ^ ($state[3] & 0x00FF0000) ^ ($state[2] & 0x0000FF00) ^ ($state[1] & 0x000000FF)) ^ $dw[0][0],
+            $this->_invSubWord(($state[1] & 0xFF000000) ^ ($state[0] & 0x00FF0000) ^ ($state[3] & 0x0000FF00) ^ ($state[2] & 0x000000FF)) ^ $dw[0][1],
+            $this->_invSubWord(($state[2] & 0xFF000000) ^ ($state[1] & 0x00FF0000) ^ ($state[0] & 0x0000FF00) ^ ($state[3] & 0x000000FF)) ^ $dw[0][2],
+            $this->_invSubWord(($state[3] & 0xFF000000) ^ ($state[2] & 0x00FF0000) ^ ($state[1] & 0x0000FF00) ^ ($state[0] & 0x000000FF)) ^ $dw[0][3]
+        );
+
+        return pack('N*', $state[0], $state[1], $state[2], $state[3]);
+    }
+}
+
+// vim: ts=4:sw=4:et:
+// vim6: fdl=1:
+?>
diff --git a/phpmyadmin/libraries/phpseclib/Crypt/Rijndael.php b/phpmyadmin/libraries/phpseclib/Crypt/Rijndael.php
new file mode 100644
index 0000000..b5aef38
--- /dev/null
+++ b/phpmyadmin/libraries/phpseclib/Crypt/Rijndael.php
@@ -0,0 +1,1479 @@
+<?php
+/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
+
+/**
+ * Pure-PHP implementation of Rijndael.
+ *
+ * Does not use mcrypt, even when available, for reasons that are explained below.
+ *
+ * PHP versions 4 and 5
+ *
+ * If {@link Crypt_Rijndael::setBlockLength() setBlockLength()} isn't called, it'll be assumed to be 128 bits.  If 
+ * {@link Crypt_Rijndael::setKeyLength() setKeyLength()} isn't called, it'll be calculated from 
+ * {@link Crypt_Rijndael::setKey() setKey()}.  ie. if the key is 128-bits, the key length will be 128-bits.  If it's 
+ * 136-bits it'll be null-padded to 160-bits and 160 bits will be the key length until 
+ * {@link Crypt_Rijndael::setKey() setKey()} is called, again, at which point, it'll be recalculated.
+ *
+ * Not all Rijndael implementations may support 160-bits or 224-bits as the block length / key length.  mcrypt, for example,
+ * does not.  AES, itself, only supports block lengths of 128 and key lengths of 128, 192, and 256.
+ * {@link http://csrc.nist.gov/archive/aes/rijndael/Rijndael-ammended.pdf#page=10 Rijndael-ammended.pdf#page=10} defines the
+ * algorithm for block lengths of 192 and 256 but not for block lengths / key lengths of 160 and 224.  Indeed, 160 and 224
+ * are first defined as valid key / block lengths in 
+ * {@link http://csrc.nist.gov/archive/aes/rijndael/Rijndael-ammended.pdf#page=44 Rijndael-ammended.pdf#page=44}: 
+ * Extensions: Other block and Cipher Key lengths.
+ *
+ * {@internal The variable names are the same as those in 
+ * {@link http://www.csrc.nist.gov/publications/fips/fips197/fips-197.pdf#page=10 fips-197.pdf#page=10}.}}
+ *
+ * Here's a short example of how to use this library:
+ * <code>
+ * <?php
+ *    include('Crypt/Rijndael.php');
+ *
+ *    $rijndael = new Crypt_Rijndael();
+ *
+ *    $rijndael->setKey('abcdefghijklmnop');
+ *
+ *    $size = 10 * 1024;
+ *    $plaintext = '';
+ *    for ($i = 0; $i < $size; $i++) {
+ *        $plaintext.= 'a';
+ *    }
+ *
+ *    echo $rijndael->decrypt($rijndael->encrypt($plaintext));
+ * ?>
+ * </code>
+ *
+ * LICENSE: Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ *
+ * @category   Crypt
+ * @package    Crypt_Rijndael
+ * @author     Jim Wigginton <terrafrost at php.net>
+ * @copyright  MMVIII Jim Wigginton
+ * @license    http://www.opensource.org/licenses/mit-license.html  MIT License
+ * @version    $Id: Rijndael.php,v 1.12 2010/02/09 06:10:26 terrafrost Exp $
+ * @link       http://phpseclib.sourceforge.net
+ */
+
+/**#@+
+ * @access public
+ * @see Crypt_Rijndael::encrypt()
+ * @see Crypt_Rijndael::decrypt()
+ */
+/**
+ * Encrypt / decrypt using the Counter mode.
+ *
+ * Set to -1 since that's what Crypt/Random.php uses to index the CTR mode.
+ *
+ * @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Counter_.28CTR.29
+ */
+define('CRYPT_RIJNDAEL_MODE_CTR', -1);
+/**
+ * Encrypt / decrypt using the Electronic Code Book mode.
+ *
+ * @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Electronic_codebook_.28ECB.29
+ */
+define('CRYPT_RIJNDAEL_MODE_ECB', 1);
+/**
+ * Encrypt / decrypt using the Code Book Chaining mode.
+ *
+ * @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Cipher-block_chaining_.28CBC.29
+ */
+define('CRYPT_RIJNDAEL_MODE_CBC', 2);
+/**
+ * Encrypt / decrypt using the Cipher Feedback mode.
+ *
+ * @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Cipher_feedback_.28CFB.29
+ */
+define('CRYPT_RIJNDAEL_MODE_CFB', 3);
+/**
+ * Encrypt / decrypt using the Cipher Feedback mode.
+ *
+ * @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Output_feedback_.28OFB.29
+ */
+define('CRYPT_RIJNDAEL_MODE_OFB', 4);
+/**#@-*/
+
+/**#@+
+ * @access private
+ * @see Crypt_Rijndael::Crypt_Rijndael()
+ */
+/**
+ * Toggles the internal implementation
+ */
+define('CRYPT_RIJNDAEL_MODE_INTERNAL', 1);
+/**
+ * Toggles the mcrypt implementation
+ */
+define('CRYPT_RIJNDAEL_MODE_MCRYPT', 2);
+/**#@-*/
+
+/**
+ * Pure-PHP implementation of Rijndael.
+ *
+ * @author  Jim Wigginton <terrafrost at php.net>
+ * @version 0.1.0
+ * @access  public
+ * @package Crypt_Rijndael
+ */
+class Crypt_Rijndael {
+    /**
+     * The Encryption Mode
+     *
+     * @see Crypt_Rijndael::Crypt_Rijndael()
+     * @var Integer
+     * @access private
+     */
+    var $mode;
+
+    /**
+     * The Key
+     *
+     * @see Crypt_Rijndael::setKey()
+     * @var String
+     * @access private
+     */
+    var $key = "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0";
+
+    /**
+     * The Initialization Vector
+     *
+     * @see Crypt_Rijndael::setIV()
+     * @var String
+     * @access private
+     */
+    var $iv = '';
+
+    /**
+     * A "sliding" Initialization Vector
+     *
+     * @see Crypt_Rijndael::enableContinuousBuffer()
+     * @var String
+     * @access private
+     */
+    var $encryptIV = '';
+
+    /**
+     * A "sliding" Initialization Vector
+     *
+     * @see Crypt_Rijndael::enableContinuousBuffer()
+     * @var String
+     * @access private
+     */
+    var $decryptIV = '';
+
+    /**
+     * Continuous Buffer status
+     *
+     * @see Crypt_Rijndael::enableContinuousBuffer()
+     * @var Boolean
+     * @access private
+     */
+    var $continuousBuffer = false;
+
+    /**
+     * Padding status
+     *
+     * @see Crypt_Rijndael::enablePadding()
+     * @var Boolean
+     * @access private
+     */
+    var $padding = true;
+
+    /**
+     * Does the key schedule need to be (re)calculated?
+     *
+     * @see setKey()
+     * @see setBlockLength()
+     * @see setKeyLength()
+     * @var Boolean
+     * @access private
+     */
+    var $changed = true;
+
+    /**
+     * Has the key length explicitly been set or should it be derived from the key, itself?
+     *
+     * @see setKeyLength()
+     * @var Boolean
+     * @access private
+     */
+    var $explicit_key_length = false;
+
+    /**
+     * The Key Schedule
+     *
+     * @see _setup()
+     * @var Array
+     * @access private
+     */
+    var $w;
+
+    /**
+     * The Inverse Key Schedule
+     *
+     * @see _setup()
+     * @var Array
+     * @access private
+     */
+    var $dw;
+
+    /**
+     * The Block Length
+     *
+     * @see setBlockLength()
+     * @var Integer
+     * @access private
+     * @internal The max value is 32, the min value is 16.  All valid values are multiples of 4.  Exists in conjunction with
+     *     $Nb because we need this value and not $Nb to pad strings appropriately.  
+     */
+    var $block_size = 16;
+
+    /**
+     * The Block Length divided by 32
+     *
+     * @see setBlockLength()
+     * @var Integer
+     * @access private
+     * @internal The max value is 256 / 32 = 8, the min value is 128 / 32 = 4.  Exists in conjunction with $block_size 
+     *    because the encryption / decryption / key schedule creation requires this number and not $block_size.  We could 
+     *    derive this from $block_size or vice versa, but that'd mean we'd have to do multiple shift operations, so in lieu
+     *    of that, we'll just precompute it once.
+     *
+     */
+    var $Nb = 4;
+
+    /**
+     * The Key Length
+     *
+     * @see setKeyLength()
+     * @var Integer
+     * @access private
+     * @internal The max value is 256 / 8 = 32, the min value is 128 / 8 = 16.  Exists in conjunction with $key_size
+     *    because the encryption / decryption / key schedule creation requires this number and not $key_size.  We could 
+     *    derive this from $key_size or vice versa, but that'd mean we'd have to do multiple shift operations, so in lieu
+     *    of that, we'll just precompute it once.
+     */
+    var $key_size = 16;
+
+    /**
+     * The Key Length divided by 32
+     *
+     * @see setKeyLength()
+     * @var Integer
+     * @access private
+     * @internal The max value is 256 / 32 = 8, the min value is 128 / 32 = 4
+     */
+    var $Nk = 4;
+
+    /**
+     * The Number of Rounds
+     *
+     * @var Integer
+     * @access private
+     * @internal The max value is 14, the min value is 10.
+     */
+    var $Nr;
+
+    /**
+     * Shift offsets
+     *
+     * @var Array
+     * @access private
+     */
+    var $c;
+
+    /**
+     * Precomputed mixColumns table
+     *
+     * @see Crypt_Rijndael()
+     * @var Array
+     * @access private
+     */
+    var $t0;
+
+    /**
+     * Precomputed mixColumns table
+     *
+     * @see Crypt_Rijndael()
+     * @var Array
+     * @access private
+     */
+    var $t1;
+
+    /**
+     * Precomputed mixColumns table
+     *
+     * @see Crypt_Rijndael()
+     * @var Array
+     * @access private
+     */
+    var $t2;
+
+    /**
+     * Precomputed mixColumns table
+     *
+     * @see Crypt_Rijndael()
+     * @var Array
+     * @access private
+     */
+    var $t3;
+
+    /**
+     * Precomputed invMixColumns table
+     *
+     * @see Crypt_Rijndael()
+     * @var Array
+     * @access private
+     */
+    var $dt0;
+
+    /**
+     * Precomputed invMixColumns table
+     *
+     * @see Crypt_Rijndael()
+     * @var Array
+     * @access private
+     */
+    var $dt1;
+
+    /**
+     * Precomputed invMixColumns table
+     *
+     * @see Crypt_Rijndael()
+     * @var Array
+     * @access private
+     */
+    var $dt2;
+
+    /**
+     * Precomputed invMixColumns table
+     *
+     * @see Crypt_Rijndael()
+     * @var Array
+     * @access private
+     */
+    var $dt3;
+
+    /**
+     * Is the mode one that is paddable?
+     *
+     * @see Crypt_Rijndael::Crypt_Rijndael()
+     * @var Boolean
+     * @access private
+     */
+    var $paddable = false;
+
+    /**
+     * Encryption buffer for CTR, OFB and CFB modes
+     *
+     * @see Crypt_Rijndael::encrypt()
+     * @var String
+     * @access private
+     */
+    var $enbuffer = array('encrypted' => '', 'xor' => '');
+
+    /**
+     * Decryption buffer for CTR, OFB and CFB modes
+     *
+     * @see Crypt_Rijndael::decrypt()
+     * @var String
+     * @access private
+     */
+    var $debuffer = array('ciphertext' => '');
+
+    /**
+     * Default Constructor.
+     *
+     * Determines whether or not the mcrypt extension should be used.  $mode should only, at present, be
+     * CRYPT_RIJNDAEL_MODE_ECB or CRYPT_RIJNDAEL_MODE_CBC.  If not explictly set, CRYPT_RIJNDAEL_MODE_CBC will be used.
+     *
+     * @param optional Integer $mode
+     * @return Crypt_Rijndael
+     * @access public
+     */
+    function Crypt_Rijndael($mode = CRYPT_RIJNDAEL_MODE_CBC)
+    {
+        switch ($mode) {
+            case CRYPT_RIJNDAEL_MODE_ECB:
+            case CRYPT_RIJNDAEL_MODE_CBC:
+                $this->paddable = true;
+                $this->mode = $mode;
+                break;
+            case CRYPT_RIJNDAEL_MODE_CTR:
+            case CRYPT_RIJNDAEL_MODE_CFB:
+            case CRYPT_RIJNDAEL_MODE_OFB:
+                $this->mode = $mode;
+                break;
+            default:
+                $this->paddable = true;
+                $this->mode = CRYPT_RIJNDAEL_MODE_CBC;
+        }
+
+        $t3 = &$this->t3;
+        $t2 = &$this->t2;
+        $t1 = &$this->t1;
+        $t0 = &$this->t0;
+
+        $dt3 = &$this->dt3;
+        $dt2 = &$this->dt2;
+        $dt1 = &$this->dt1;
+        $dt0 = &$this->dt0;
+
+        // according to <http://csrc.nist.gov/archive/aes/rijndael/Rijndael-ammended.pdf#page=19> (section 5.2.1), 
+        // precomputed tables can be used in the mixColumns phase.  in that example, they're assigned t0...t3, so
+        // those are the names we'll use.
+        $t3 = array(
+            0x6363A5C6, 0x7C7C84F8, 0x777799EE, 0x7B7B8DF6, 0xF2F20DFF, 0x6B6BBDD6, 0x6F6FB1DE, 0xC5C55491, 
+            0x30305060, 0x01010302, 0x6767A9CE, 0x2B2B7D56, 0xFEFE19E7, 0xD7D762B5, 0xABABE64D, 0x76769AEC, 
+            0xCACA458F, 0x82829D1F, 0xC9C94089, 0x7D7D87FA, 0xFAFA15EF, 0x5959EBB2, 0x4747C98E, 0xF0F00BFB, 
+            0xADADEC41, 0xD4D467B3, 0xA2A2FD5F, 0xAFAFEA45, 0x9C9CBF23, 0xA4A4F753, 0x727296E4, 0xC0C05B9B, 
+            0xB7B7C275, 0xFDFD1CE1, 0x9393AE3D, 0x26266A4C, 0x36365A6C, 0x3F3F417E, 0xF7F702F5, 0xCCCC4F83, 
+            0x34345C68, 0xA5A5F451, 0xE5E534D1, 0xF1F108F9, 0x717193E2, 0xD8D873AB, 0x31315362, 0x15153F2A, 
+            0x04040C08, 0xC7C75295, 0x23236546, 0xC3C35E9D, 0x18182830, 0x9696A137, 0x05050F0A, 0x9A9AB52F, 
+            0x0707090E, 0x12123624, 0x80809B1B, 0xE2E23DDF, 0xEBEB26CD, 0x2727694E, 0xB2B2CD7F, 0x75759FEA, 
+            0x09091B12, 0x83839E1D, 0x2C2C7458, 0x1A1A2E34, 0x1B1B2D36, 0x6E6EB2DC, 0x5A5AEEB4, 0xA0A0FB5B, 
+            0x5252F6A4, 0x3B3B4D76, 0xD6D661B7, 0xB3B3CE7D, 0x29297B52, 0xE3E33EDD, 0x2F2F715E, 0x84849713, 
+            0x5353F5A6, 0xD1D168B9, 0x00000000, 0xEDED2CC1, 0x20206040, 0xFCFC1FE3, 0xB1B1C879, 0x5B5BEDB6, 
+            0x6A6ABED4, 0xCBCB468D, 0xBEBED967, 0x39394B72, 0x4A4ADE94, 0x4C4CD498, 0x5858E8B0, 0xCFCF4A85, 
+            0xD0D06BBB, 0xEFEF2AC5, 0xAAAAE54F, 0xFBFB16ED, 0x4343C586, 0x4D4DD79A, 0x33335566, 0x85859411, 
+            0x4545CF8A, 0xF9F910E9, 0x02020604, 0x7F7F81FE, 0x5050F0A0, 0x3C3C4478, 0x9F9FBA25, 0xA8A8E34B, 
+            0x5151F3A2, 0xA3A3FE5D, 0x4040C080, 0x8F8F8A05, 0x9292AD3F, 0x9D9DBC21, 0x38384870, 0xF5F504F1, 
+            0xBCBCDF63, 0xB6B6C177, 0xDADA75AF, 0x21216342, 0x10103020, 0xFFFF1AE5, 0xF3F30EFD, 0xD2D26DBF, 
+            0xCDCD4C81, 0x0C0C1418, 0x13133526, 0xECEC2FC3, 0x5F5FE1BE, 0x9797A235, 0x4444CC88, 0x1717392E, 
+            0xC4C45793, 0xA7A7F255, 0x7E7E82FC, 0x3D3D477A, 0x6464ACC8, 0x5D5DE7BA, 0x19192B32, 0x737395E6, 
+            0x6060A0C0, 0x81819819, 0x4F4FD19E, 0xDCDC7FA3, 0x22226644, 0x2A2A7E54, 0x9090AB3B, 0x8888830B, 
+            0x4646CA8C, 0xEEEE29C7, 0xB8B8D36B, 0x14143C28, 0xDEDE79A7, 0x5E5EE2BC, 0x0B0B1D16, 0xDBDB76AD, 
+            0xE0E03BDB, 0x32325664, 0x3A3A4E74, 0x0A0A1E14, 0x4949DB92, 0x06060A0C, 0x24246C48, 0x5C5CE4B8, 
+            0xC2C25D9F, 0xD3D36EBD, 0xACACEF43, 0x6262A6C4, 0x9191A839, 0x9595A431, 0xE4E437D3, 0x79798BF2, 
+            0xE7E732D5, 0xC8C8438B, 0x3737596E, 0x6D6DB7DA, 0x8D8D8C01, 0xD5D564B1, 0x4E4ED29C, 0xA9A9E049, 
+            0x6C6CB4D8, 0x5656FAAC, 0xF4F407F3, 0xEAEA25CF, 0x6565AFCA, 0x7A7A8EF4, 0xAEAEE947, 0x08081810, 
+            0xBABAD56F, 0x787888F0, 0x25256F4A, 0x2E2E725C, 0x1C1C2438, 0xA6A6F157, 0xB4B4C773, 0xC6C65197, 
+            0xE8E823CB, 0xDDDD7CA1, 0x74749CE8, 0x1F1F213E, 0x4B4BDD96, 0xBDBDDC61, 0x8B8B860D, 0x8A8A850F, 
+            0x707090E0, 0x3E3E427C, 0xB5B5C471, 0x6666AACC, 0x4848D890, 0x03030506, 0xF6F601F7, 0x0E0E121C, 
+            0x6161A3C2, 0x35355F6A, 0x5757F9AE, 0xB9B9D069, 0x86869117, 0xC1C15899, 0x1D1D273A, 0x9E9EB927, 
+            0xE1E138D9, 0xF8F813EB, 0x9898B32B, 0x11113322, 0x6969BBD2, 0xD9D970A9, 0x8E8E8907, 0x9494A733, 
+            0x9B9BB62D, 0x1E1E223C, 0x87879215, 0xE9E920C9, 0xCECE4987, 0x5555FFAA, 0x28287850, 0xDFDF7AA5, 
+            0x8C8C8F03, 0xA1A1F859, 0x89898009, 0x0D0D171A, 0xBFBFDA65, 0xE6E631D7, 0x4242C684, 0x6868B8D0, 
+            0x4141C382, 0x9999B029, 0x2D2D775A, 0x0F0F111E, 0xB0B0CB7B, 0x5454FCA8, 0xBBBBD66D, 0x16163A2C
+        );
+
+        $dt3 = array(
+            0xF4A75051, 0x4165537E, 0x17A4C31A, 0x275E963A, 0xAB6BCB3B, 0x9D45F11F, 0xFA58ABAC, 0xE303934B, 
+            0x30FA5520, 0x766DF6AD, 0xCC769188, 0x024C25F5, 0xE5D7FC4F, 0x2ACBD7C5, 0x35448026, 0x62A38FB5, 
+            0xB15A49DE, 0xBA1B6725, 0xEA0E9845, 0xFEC0E15D, 0x2F7502C3, 0x4CF01281, 0x4697A38D, 0xD3F9C66B, 
+            0x8F5FE703, 0x929C9515, 0x6D7AEBBF, 0x5259DA95, 0xBE832DD4, 0x7421D358, 0xE0692949, 0xC9C8448E, 
+            0xC2896A75, 0x8E7978F4, 0x583E6B99, 0xB971DD27, 0xE14FB6BE, 0x88AD17F0, 0x20AC66C9, 0xCE3AB47D, 
+            0xDF4A1863, 0x1A3182E5, 0x51336097, 0x537F4562, 0x6477E0B1, 0x6BAE84BB, 0x81A01CFE, 0x082B94F9, 
+            0x48685870, 0x45FD198F, 0xDE6C8794, 0x7BF8B752, 0x73D323AB, 0x4B02E272, 0x1F8F57E3, 0x55AB2A66, 
+            0xEB2807B2, 0xB5C2032F, 0xC57B9A86, 0x3708A5D3, 0x2887F230, 0xBFA5B223, 0x036ABA02, 0x16825CED, 
+            0xCF1C2B8A, 0x79B492A7, 0x07F2F0F3, 0x69E2A14E, 0xDAF4CD65, 0x05BED506, 0x34621FD1, 0xA6FE8AC4, 
+            0x2E539D34, 0xF355A0A2, 0x8AE13205, 0xF6EB75A4, 0x83EC390B, 0x60EFAA40, 0x719F065E, 0x6E1051BD, 
+            0x218AF93E, 0xDD063D96, 0x3E05AEDD, 0xE6BD464D, 0x548DB591, 0xC45D0571, 0x06D46F04, 0x5015FF60, 
+            0x98FB2419, 0xBDE997D6, 0x4043CC89, 0xD99E7767, 0xE842BDB0, 0x898B8807, 0x195B38E7, 0xC8EEDB79, 
+            0x7C0A47A1, 0x420FE97C, 0x841EC9F8, 0x00000000, 0x80868309, 0x2BED4832, 0x1170AC1E, 0x5A724E6C, 
+            0x0EFFFBFD, 0x8538560F, 0xAED51E3D, 0x2D392736, 0x0FD9640A, 0x5CA62168, 0x5B54D19B, 0x362E3A24, 
+            0x0A67B10C, 0x57E70F93, 0xEE96D2B4, 0x9B919E1B, 0xC0C54F80, 0xDC20A261, 0x774B695A, 0x121A161C, 
+            0x93BA0AE2, 0xA02AE5C0, 0x22E0433C, 0x1B171D12, 0x090D0B0E, 0x8BC7ADF2, 0xB6A8B92D, 0x1EA9C814, 
+            0xF1198557, 0x75074CAF, 0x99DDBBEE, 0x7F60FDA3, 0x01269FF7, 0x72F5BC5C, 0x663BC544, 0xFB7E345B, 
+            0x4329768B, 0x23C6DCCB, 0xEDFC68B6, 0xE4F163B8, 0x31DCCAD7, 0x63851042, 0x97224013, 0xC6112084, 
+            0x4A247D85, 0xBB3DF8D2, 0xF93211AE, 0x29A16DC7, 0x9E2F4B1D, 0xB230F3DC, 0x8652EC0D, 0xC1E3D077, 
+            0xB3166C2B, 0x70B999A9, 0x9448FA11, 0xE9642247, 0xFC8CC4A8, 0xF03F1AA0, 0x7D2CD856, 0x3390EF22, 
+            0x494EC787, 0x38D1C1D9, 0xCAA2FE8C, 0xD40B3698, 0xF581CFA6, 0x7ADE28A5, 0xB78E26DA, 0xADBFA43F, 
+            0x3A9DE42C, 0x78920D50, 0x5FCC9B6A, 0x7E466254, 0x8D13C2F6, 0xD8B8E890, 0x39F75E2E, 0xC3AFF582, 
+            0x5D80BE9F, 0xD0937C69, 0xD52DA96F, 0x2512B3CF, 0xAC993BC8, 0x187DA710, 0x9C636EE8, 0x3BBB7BDB, 
+            0x267809CD, 0x5918F46E, 0x9AB701EC, 0x4F9AA883, 0x956E65E6, 0xFFE67EAA, 0xBCCF0821, 0x15E8E6EF, 
+            0xE79BD9BA, 0x6F36CE4A, 0x9F09D4EA, 0xB07CD629, 0xA4B2AF31, 0x3F23312A, 0xA59430C6, 0xA266C035, 
+            0x4EBC3774, 0x82CAA6FC, 0x90D0B0E0, 0xA7D81533, 0x04984AF1, 0xECDAF741, 0xCD500E7F, 0x91F62F17, 
+            0x4DD68D76, 0xEFB04D43, 0xAA4D54CC, 0x9604DFE4, 0xD1B5E39E, 0x6A881B4C, 0x2C1FB8C1, 0x65517F46, 
+            0x5EEA049D, 0x8C355D01, 0x877473FA, 0x0B412EFB, 0x671D5AB3, 0xDBD25292, 0x105633E9, 0xD647136D, 
+            0xD7618C9A, 0xA10C7A37, 0xF8148E59, 0x133C89EB, 0xA927EECE, 0x61C935B7, 0x1CE5EDE1, 0x47B13C7A, 
+            0xD2DF599C, 0xF2733F55, 0x14CE7918, 0xC737BF73, 0xF7CDEA53, 0xFDAA5B5F, 0x3D6F14DF, 0x44DB8678, 
+            0xAFF381CA, 0x68C43EB9, 0x24342C38, 0xA3405FC2, 0x1DC37216, 0xE2250CBC, 0x3C498B28, 0x0D9541FF, 
+            0xA8017139, 0x0CB3DE08, 0xB4E49CD8, 0x56C19064, 0xCB84617B, 0x32B670D5, 0x6C5C7448, 0xB85742D0
+        );
+
+        for ($i = 0; $i < 256; $i++) {
+            $t2[$i <<  8] = (($t3[$i] <<  8) & 0xFFFFFF00) | (($t3[$i] >> 24) & 0x000000FF);
+            $t1[$i << 16] = (($t3[$i] << 16) & 0xFFFF0000) | (($t3[$i] >> 16) & 0x0000FFFF);
+            $t0[$i << 24] = (($t3[$i] << 24) & 0xFF000000) | (($t3[$i] >>  8) & 0x00FFFFFF);
+
+            $dt2[$i <<  8] = (($this->dt3[$i] <<  8) & 0xFFFFFF00) | (($dt3[$i] >> 24) & 0x000000FF);
+            $dt1[$i << 16] = (($this->dt3[$i] << 16) & 0xFFFF0000) | (($dt3[$i] >> 16) & 0x0000FFFF);
+            $dt0[$i << 24] = (($this->dt3[$i] << 24) & 0xFF000000) | (($dt3[$i] >>  8) & 0x00FFFFFF);
+        }
+    }
+
+    /**
+     * Sets the key.
+     *
+     * Keys can be of any length.  Rijndael, itself, requires the use of a key that's between 128-bits and 256-bits long and
+     * whose length is a multiple of 32.  If the key is less than 256-bits and the key length isn't set, we round the length
+     * up to the closest valid key length, padding $key with null bytes.  If the key is more than 256-bits, we trim the
+     * excess bits.
+     *
+     * If the key is not explicitly set, it'll be assumed to be all null bytes.
+     *
+     * @access public
+     * @param String $key
+     */
+    function setKey($key)
+    {
+        $this->key = $key;
+        $this->changed = true;
+    }
+
+    /**
+     * Sets the initialization vector. (optional)
+     *
+     * SetIV is not required when CRYPT_RIJNDAEL_MODE_ECB is being used.  If not explictly set, it'll be assumed
+     * to be all zero's.
+     *
+     * @access public
+     * @param String $iv
+     */
+    function setIV($iv)
+    {
+        $this->encryptIV = $this->decryptIV = $this->iv = str_pad(substr($iv, 0, $this->block_size), $this->block_size, chr(0));
+    }
+
+    /**
+     * Sets the key length
+     *
+     * Valid key lengths are 128, 160, 192, 224, and 256.  If the length is less than 128, it will be rounded up to
+     * 128.  If the length is greater then 128 and invalid, it will be rounded down to the closest valid amount.
+     *
+     * @access public
+     * @param Integer $length
+     */
+    function setKeyLength($length)
+    {
+        $length >>= 5;
+        if ($length > 8) {
+            $length = 8;
+        } else if ($length < 4) {
+            $length = 4;
+        }
+        $this->Nk = $length;
+        $this->key_size = $length << 2;
+
+        $this->explicit_key_length = true;
+        $this->changed = true;
+    }
+
+    /**
+     * Sets the password.
+     *
+     * Depending on what $method is set to, setPassword()'s (optional) parameters are as follows:
+     *     {@link http://en.wikipedia.org/wiki/PBKDF2 pbkdf2}:
+     *         $hash, $salt, $count
+     *     Set $dkLen by calling setKeyLength()
+     *
+     * @param String $password
+     * @param optional String $method
+     * @access public
+     */
+    function setPassword($password, $method = 'pbkdf2')
+    {
+        $key = '';
+
+        switch ($method) {
+            default: // 'pbkdf2'
+                list(, , $hash, $salt, $count) = func_get_args();
+                if (!isset($hash)) {
+                    $hash = 'sha1';
+                }
+                // WPA and WPA use the SSID as the salt
+                if (!isset($salt)) {
+                    $salt = 'phpseclib/salt';
+                }
+                // RFC2898#section-4.2 uses 1,000 iterations by default
+                // WPA and WPA2 use 4,096.
+                if (!isset($count)) {
+                    $count = 1000;
+                }
+
+                if (!class_exists('Crypt_Hash')) {
+                    require_once('Crypt/Hash.php');
+                }
+
+                $i = 1;
+                while (strlen($key) < $this->key_size) { // $dkLen == $this->key_size
+                    //$dk.= $this->_pbkdf($password, $salt, $count, $i++);
+                    $hmac = new Crypt_Hash();
+                    $hmac->setHash($hash);
+                    $hmac->setKey($password);
+                    $f = $u = $hmac->hash($salt . pack('N', $i++));
+                    for ($j = 2; $j <= $count; $j++) {
+                        $u = $hmac->hash($u);
+                        $f^= $u;
+                    }
+                    $key.= $f;
+                }
+        }
+
+        $this->setKey(substr($key, 0, $this->key_size));
+    }
+
+    /**
+     * Sets the block length
+     *
+     * Valid block lengths are 128, 160, 192, 224, and 256.  If the length is less than 128, it will be rounded up to
+     * 128.  If the length is greater then 128 and invalid, it will be rounded down to the closest valid amount.
+     *
+     * @access public
+     * @param Integer $length
+     */
+    function setBlockLength($length)
+    {
+        $length >>= 5;
+        if ($length > 8) {
+            $length = 8;
+        } else if ($length < 4) {
+            $length = 4;
+        }
+        $this->Nb = $length;
+        $this->block_size = $length << 2;
+        $this->changed = true;
+    }
+
+    /**
+     * Generate CTR XOR encryption key
+     *
+     * Encrypt the output of this and XOR it against the ciphertext / plaintext to get the
+     * plaintext / ciphertext in CTR mode.
+     *
+     * @see Crypt_Rijndael::decrypt()
+     * @see Crypt_Rijndael::encrypt()
+     * @access public
+     * @param Integer $length
+     * @param String $iv
+     */
+    function _generate_xor($length, &$iv)
+    {
+        $xor = '';
+        $block_size = $this->block_size;
+        $num_blocks = floor(($length + ($block_size - 1)) / $block_size);
+        for ($i = 0; $i < $num_blocks; $i++) {
+            $xor.= $iv;
+            for ($j = 4; $j <= $block_size; $j+=4) {
+                $temp = substr($iv, -$j, 4);
+                switch ($temp) {
+                    case "\xFF\xFF\xFF\xFF":
+                        $iv = substr_replace($iv, "\x00\x00\x00\x00", -$j, 4);
+                        break;
+                    case "\x7F\xFF\xFF\xFF":
+                        $iv = substr_replace($iv, "\x80\x00\x00\x00", -$j, 4);
+                        break 2;
+                    default:
+                        extract(unpack('Ncount', $temp));
+                        $iv = substr_replace($iv, pack('N', $count + 1), -$j, 4);
+                        break 2;
+                }
+            }
+        }
+
+        return $xor;
+    }
+
+    /**
+     * Encrypts a message.
+     *
+     * $plaintext will be padded with additional bytes such that it's length is a multiple of the block size.  Other Rjindael
+     * implementations may or may not pad in the same manner.  Other common approaches to padding and the reasons why it's
+     * necessary are discussed in the following
+     * URL:
+     *
+     * {@link http://www.di-mgt.com.au/cryptopad.html http://www.di-mgt.com.au/cryptopad.html}
+     *
+     * An alternative to padding is to, separately, send the length of the file.  This is what SSH, in fact, does.
+     * strlen($plaintext) will still need to be a multiple of 8, however, arbitrary values can be added to make it that
+     * length.
+     *
+     * @see Crypt_Rijndael::decrypt()
+     * @access public
+     * @param String $plaintext
+     */
+    function encrypt($plaintext)
+    {
+        $this->_setup();
+        if ($this->paddable) {
+            $plaintext = $this->_pad($plaintext);
+        }
+
+        $block_size = $this->block_size;
+        $buffer = &$this->enbuffer;
+        $continuousBuffer = $this->continuousBuffer;
+        $ciphertext = '';
+        switch ($this->mode) {
+            case CRYPT_RIJNDAEL_MODE_ECB:
+                for ($i = 0; $i < strlen($plaintext); $i+=$block_size) {
+                    $ciphertext.= $this->_encryptBlock(substr($plaintext, $i, $block_size));
+                }
+                break;
+            case CRYPT_RIJNDAEL_MODE_CBC:
+                $xor = $this->encryptIV;
+                for ($i = 0; $i < strlen($plaintext); $i+=$block_size) {
+                    $block = substr($plaintext, $i, $block_size);
+                    $block = $this->_encryptBlock($block ^ $xor);
+                    $xor = $block;
+                    $ciphertext.= $block;
+                }
+                if ($this->continuousBuffer) {
+                    $this->encryptIV = $xor;
+                }
+                break;
+            case CRYPT_RIJNDAEL_MODE_CTR:
+                $xor = $this->encryptIV;
+                if (!empty($buffer['encrypted'])) {
+                    for ($i = 0; $i < strlen($plaintext); $i+=$block_size) {
+                        $block = substr($plaintext, $i, $block_size);
+                        $buffer['encrypted'].= $this->_encryptBlock($this->_generate_xor($block_size, $xor));
+                        $key = $this->_string_shift($buffer['encrypted'], $block_size);
+                        $ciphertext.= $block ^ $key;
+                    }
+                } else {
+                    for ($i = 0; $i < strlen($plaintext); $i+=$block_size) {
+                        $block = substr($plaintext, $i, $block_size);
+                        $key = $this->_encryptBlock($this->_generate_xor($block_size, $xor));
+                        $ciphertext.= $block ^ $key;
+                    }
+                }
+                if ($this->continuousBuffer) {
+                    $this->encryptIV = $xor;
+                    if ($start = strlen($plaintext) % $block_size) {
+                        $buffer['encrypted'] = substr($key, $start) . $buffer['encrypted'];
+                    }
+                }
+                break;
+            case CRYPT_RIJNDAEL_MODE_CFB:
+                if (!empty($buffer['xor'])) {
+                    $ciphertext = $plaintext ^ $buffer['xor'];
+                    $iv = $buffer['encrypted'] . $ciphertext;
+                    $start = strlen($ciphertext);
+                    $buffer['encrypted'].= $ciphertext;
+                    $buffer['xor'] = substr($buffer['xor'], strlen($ciphertext));
+                } else {
+                    $ciphertext = '';
+                    $iv = $this->encryptIV;
+                    $start = 0;
+                }
+
+                for ($i = $start; $i < strlen($plaintext); $i+=$block_size) {
+                    $block = substr($plaintext, $i, $block_size);
+                    $xor = $this->_encryptBlock($iv);
+                    $iv = $block ^ $xor;
+                    if ($continuousBuffer && strlen($iv) != $block_size) {
+                        $buffer = array(
+                            'encrypted' => $iv,
+                            'xor' => substr($xor, strlen($iv))
+                        );
+                    }
+                    $ciphertext.= $iv;
+                }
+
+                if ($this->continuousBuffer) {
+                    $this->encryptIV = $iv;
+                }
+                break;
+            case CRYPT_RIJNDAEL_MODE_OFB:
+                $xor = $this->encryptIV;
+                if (strlen($buffer)) {
+                    for ($i = 0; $i < strlen($plaintext); $i+=$block_size) {
+                        $xor = $this->_encryptBlock($xor);
+                        $buffer.= $xor;
+                        $key = $this->_string_shift($buffer, $block_size);
+                        $ciphertext.= substr($plaintext, $i, $block_size) ^ $key;
+                    }
+                } else {
+                    for ($i = 0; $i < strlen($plaintext); $i+=$block_size) {
+                        $xor = $this->_encryptBlock($xor);
+                        $ciphertext.= substr($plaintext, $i, $block_size) ^ $xor;
+                    }
+                    $key = $xor;
+                }
+                if ($this->continuousBuffer) {
+                    $this->encryptIV = $xor;
+                    if ($start = strlen($plaintext) % $block_size) {
+                         $buffer = substr($key, $start) . $buffer;
+                    }
+                }
+        }
+
+        return $ciphertext;
+    }
+
+    /**
+     * Decrypts a message.
+     *
+     * If strlen($ciphertext) is not a multiple of the block size, null bytes will be added to the end of the string until
+     * it is.
+     *
+     * @see Crypt_Rijndael::encrypt()
+     * @access public
+     * @param String $ciphertext
+     */
+    function decrypt($ciphertext)
+    {
+        $this->_setup();
+
+        if ($this->paddable) {
+            // we pad with chr(0) since that's what mcrypt_generic does.  to quote from http://php.net/function.mcrypt-generic :
+            // "The data is padded with "\0" to make sure the length of the data is n * blocksize."
+            $ciphertext = str_pad($ciphertext, strlen($ciphertext) + ($this->block_size - strlen($ciphertext) % $this->block_size) % $this->block_size, chr(0));
+        }
+
+        $block_size = $this->block_size;
+        $buffer = &$this->debuffer;
+        $continuousBuffer = $this->continuousBuffer;
+        $plaintext = '';
+        switch ($this->mode) {
+            case CRYPT_RIJNDAEL_MODE_ECB:
+                for ($i = 0; $i < strlen($ciphertext); $i+=$block_size) {
+                    $plaintext.= $this->_decryptBlock(substr($ciphertext, $i, $block_size));
+                }
+                break;
+            case CRYPT_RIJNDAEL_MODE_CBC:
+                $xor = $this->decryptIV;
+                for ($i = 0; $i < strlen($ciphertext); $i+=$block_size) {
+                    $block = substr($ciphertext, $i, $block_size);
+                    $plaintext.= $this->_decryptBlock($block) ^ $xor;
+                    $xor = $block;
+                }
+                if ($this->continuousBuffer) {
+                    $this->decryptIV = $xor;
+                }
+                break;
+            case CRYPT_RIJNDAEL_MODE_CTR:
+                $xor = $this->decryptIV;
+                if (!empty($buffer['ciphertext'])) {
+                    for ($i = 0; $i < strlen($ciphertext); $i+=$block_size) {
+                        $block = substr($ciphertext, $i, $block_size);
+                        $buffer['ciphertext'].= $this->_encryptBlock($this->_generate_xor($block_size, $xor));
+                        $key = $this->_string_shift($buffer['ciphertext'], $block_size);
+                        $plaintext.= $block ^ $key;
+                    }
+                } else {
+                    for ($i = 0; $i < strlen($ciphertext); $i+=$block_size) {
+                        $block = substr($ciphertext, $i, $block_size);
+                        $key = $this->_encryptBlock($this->_generate_xor($block_size, $xor));
+                        $plaintext.= $block ^ $key;
+                    }
+                }
+                if ($this->continuousBuffer) {
+                    $this->decryptIV = $xor;
+                    if ($start = strlen($ciphertext) % $block_size) {
+                        $buffer['ciphertext'] = substr($key, $start) . $buffer['encrypted'];
+                    }
+                }
+                break;
+            case CRYPT_RIJNDAEL_MODE_CFB:
+                if (!empty($buffer['ciphertext'])) {
+                    $plaintext = $ciphertext ^ substr($this->decryptIV, strlen($buffer['ciphertext']));
+                    $buffer['ciphertext'].= substr($ciphertext, 0, strlen($plaintext));
+                    if (strlen($buffer['ciphertext']) == $block_size) {
+                        $xor = $this->_encryptBlock($buffer['ciphertext']);
+                        $buffer['ciphertext'] = '';
+                    }
+                    $start = strlen($plaintext);
+                    $block = $this->decryptIV;
+                } else {
+                    $plaintext = '';
+                    $xor = $this->_encryptBlock($this->decryptIV);
+                    $start = 0;
+                }
+
+                for ($i = $start; $i < strlen($ciphertext); $i+=$block_size) {
+                    $block = substr($ciphertext, $i, $block_size);
+                    $plaintext.= $block ^ $xor;
+                    if ($continuousBuffer && strlen($block) != $block_size) {
+                        $buffer['ciphertext'].= $block;
+                        $block = $xor;
+                    } else if (strlen($block) == $block_size) {
+                        $xor = $this->_encryptBlock($block);
+                    }
+                }
+                if ($this->continuousBuffer) {
+                    $this->decryptIV = $block;
+                }
+                break;
+            case CRYPT_RIJNDAEL_MODE_OFB:
+                $xor = $this->decryptIV;
+                if (strlen($buffer)) {
+                    for ($i = 0; $i < strlen($ciphertext); $i+=$block_size) {
+                        $xor = $this->_encryptBlock($xor);
+                        $buffer.= $xor;
+                        $key = $this->_string_shift($buffer, $block_size);
+                        $plaintext.= substr($ciphertext, $i, $block_size) ^ $key;
+                    }
+                } else {
+                    for ($i = 0; $i < strlen($ciphertext); $i+=$block_size) {
+                        $xor = $this->_encryptBlock($xor);
+                        $plaintext.= substr($ciphertext, $i, $block_size) ^ $xor;
+                    }
+                    $key = $xor;
+                }
+                if ($this->continuousBuffer) {
+                    $this->decryptIV = $xor;
+                    if ($start = strlen($ciphertext) % $block_size) {
+                         $buffer = substr($key, $start) . $buffer;
+                    }
+                }
+        }
+
+        return $this->paddable ? $this->_unpad($plaintext) : $plaintext;
+    }
+
+    /**
+     * Encrypts a block
+     *
+     * @access private
+     * @param String $in
+     * @return String
+     */
+    function _encryptBlock($in)
+    {
+        $state = array();
+        $words = unpack('N*word', $in);
+
+        $w = $this->w;
+        $t0 = $this->t0;
+        $t1 = $this->t1;
+        $t2 = $this->t2;
+        $t3 = $this->t3;
+        $Nb = $this->Nb;
+        $Nr = $this->Nr;
+        $c = $this->c;
+
+        // addRoundKey
+        $i = 0;
+        foreach ($words as $word) {
+            $state[] = $word ^ $w[0][$i++];
+        }
+
+        // fips-197.pdf#page=19, "Figure 5. Pseudo Code for the Cipher", states that this loop has four components - 
+        // subBytes, shiftRows, mixColumns, and addRoundKey. fips-197.pdf#page=30, "Implementation Suggestions Regarding 
+        // Various Platforms" suggests that performs enhanced implementations are described in Rijndael-ammended.pdf.
+        // Rijndael-ammended.pdf#page=20, "Implementation aspects / 32-bit processor", discusses such an optimization.
+        // Unfortunately, the description given there is not quite correct.  Per aes.spec.v316.pdf#page=19 [1], 
+        // equation (7.4.7) is supposed to use addition instead of subtraction, so we'll do that here, as well.
+
+        // [1] http://fp.gladman.plus.com/cryptography_technology/rijndael/aes.spec.v316.pdf
+        $temp = array();
+        for ($round = 1; $round < $Nr; $round++) {
+            $i = 0; // $c[0] == 0
+            $j = $c[1];
+            $k = $c[2];
+            $l = $c[3];
+
+            while ($i < $this->Nb) {
+                $temp[$i] = $t0[$state[$i] & 0xFF000000] ^ 
+                            $t1[$state[$j] & 0x00FF0000] ^ 
+                            $t2[$state[$k] & 0x0000FF00] ^ 
+                            $t3[$state[$l] & 0x000000FF] ^ 
+                            $w[$round][$i];
+                $i++;
+                $j = ($j + 1) % $Nb;
+                $k = ($k + 1) % $Nb;
+                $l = ($l + 1) % $Nb;
+            }
+
+            for ($i = 0; $i < $Nb; $i++) {
+                $state[$i] = $temp[$i];
+            }
+        }
+
+        // subWord
+        for ($i = 0; $i < $Nb; $i++) {
+            $state[$i] = $this->_subWord($state[$i]);
+        }
+
+        // shiftRows + addRoundKey
+        $i = 0; // $c[0] == 0
+        $j = $c[1];
+        $k = $c[2];
+        $l = $c[3];
+        while ($i < $this->Nb) {
+            $temp[$i] = ($state[$i] & 0xFF000000) ^ 
+                        ($state[$j] & 0x00FF0000) ^ 
+                        ($state[$k] & 0x0000FF00) ^ 
+                        ($state[$l] & 0x000000FF) ^
+                         $w[$Nr][$i];
+            $i++;
+            $j = ($j + 1) % $Nb;
+            $k = ($k + 1) % $Nb;
+            $l = ($l + 1) % $Nb;
+        }
+        $state = $temp;
+
+        array_unshift($state, 'N*');
+
+        return call_user_func_array('pack', $state);
+    }
+
+    /**
+     * Decrypts a block
+     *
+     * @access private
+     * @param String $in
+     * @return String
+     */
+    function _decryptBlock($in)
+    {
+        $state = array();
+        $words = unpack('N*word', $in);
+
+        $num_states = count($state);
+        $dw = $this->dw;
+        $dt0 = $this->dt0;
+        $dt1 = $this->dt1;
+        $dt2 = $this->dt2;
+        $dt3 = $this->dt3;
+        $Nb = $this->Nb;
+        $Nr = $this->Nr;
+        $c = $this->c;
+
+        // addRoundKey
+        $i = 0;
+        foreach ($words as $word) {
+            $state[] = $word ^ $dw[$Nr][$i++];
+        }
+
+        $temp = array();
+        for ($round = $Nr - 1; $round > 0; $round--) {
+            $i = 0; // $c[0] == 0
+            $j = $Nb - $c[1];
+            $k = $Nb - $c[2];
+            $l = $Nb - $c[3];
+
+            while ($i < $Nb) {
+                $temp[$i] = $dt0[$state[$i] & 0xFF000000] ^ 
+                            $dt1[$state[$j] & 0x00FF0000] ^ 
+                            $dt2[$state[$k] & 0x0000FF00] ^ 
+                            $dt3[$state[$l] & 0x000000FF] ^ 
+                            $dw[$round][$i];
+                $i++;
+                $j = ($j + 1) % $Nb;
+                $k = ($k + 1) % $Nb;
+                $l = ($l + 1) % $Nb;
+            }
+
+            for ($i = 0; $i < $Nb; $i++) {
+                $state[$i] = $temp[$i];
+            }
+        }
+
+        // invShiftRows + invSubWord + addRoundKey
+        $i = 0; // $c[0] == 0
+        $j = $Nb - $c[1];
+        $k = $Nb - $c[2];
+        $l = $Nb - $c[3];
+
+        while ($i < $Nb) {
+            $temp[$i] = $dw[0][$i] ^ 
+                        $this->_invSubWord(($state[$i] & 0xFF000000) | 
+                                           ($state[$j] & 0x00FF0000) | 
+                                           ($state[$k] & 0x0000FF00) | 
+                                           ($state[$l] & 0x000000FF));
+            $i++;
+            $j = ($j + 1) % $Nb;
+            $k = ($k + 1) % $Nb;
+            $l = ($l + 1) % $Nb;
+        }
+
+        $state = $temp;
+
+        array_unshift($state, 'N*');
+
+        return call_user_func_array('pack', $state);
+    }
+
+    /**
+     * Setup Rijndael
+     *
+     * Validates all the variables and calculates $Nr - the number of rounds that need to be performed - and $w - the key
+     * key schedule.
+     *
+     * @access private
+     */
+    function _setup()
+    {
+        // Each number in $rcon is equal to the previous number multiplied by two in Rijndael's finite field.
+        // See http://en.wikipedia.org/wiki/Finite_field_arithmetic#Multiplicative_inverse
+        static $rcon = array(0,
+            0x01000000, 0x02000000, 0x04000000, 0x08000000, 0x10000000,
+            0x20000000, 0x40000000, 0x80000000, 0x1B000000, 0x36000000,
+            0x6C000000, 0xD8000000, 0xAB000000, 0x4D000000, 0x9A000000,
+            0x2F000000, 0x5E000000, 0xBC000000, 0x63000000, 0xC6000000,
+            0x97000000, 0x35000000, 0x6A000000, 0xD4000000, 0xB3000000,
+            0x7D000000, 0xFA000000, 0xEF000000, 0xC5000000, 0x91000000
+        );
+
+        if (!$this->changed) {
+            return;
+        }
+
+        if (!$this->explicit_key_length) {
+            // we do >> 2, here, and not >> 5, as we do above, since strlen($this->key) tells us the number of bytes - not bits
+            $length = strlen($this->key) >> 2;
+            if ($length > 8) {
+                $length = 8;
+            } else if ($length < 4) {
+                $length = 4;
+            }
+            $this->Nk = $length;
+            $this->key_size = $length << 2;
+        }
+
+        $this->key = str_pad(substr($this->key, 0, $this->key_size), $this->key_size, chr(0));
+        $this->encryptIV = $this->decryptIV = $this->iv = str_pad(substr($this->iv, 0, $this->block_size), $this->block_size, chr(0));
+
+        // see Rijndael-ammended.pdf#page=44
+        $this->Nr = max($this->Nk, $this->Nb) + 6;
+
+        // shift offsets for Nb = 5, 7 are defined in Rijndael-ammended.pdf#page=44,
+        //     "Table 8: Shift offsets in Shiftrow for the alternative block lengths"
+        // shift offsets for Nb = 4, 6, 8 are defined in Rijndael-ammended.pdf#page=14,
+        //     "Table 2: Shift offsets for different block lengths"
+        switch ($this->Nb) {
+            case 4:
+            case 5:
+            case 6:
+                $this->c = array(0, 1, 2, 3);
+                break;
+            case 7:
+                $this->c = array(0, 1, 2, 4);
+                break;
+            case 8:
+                $this->c = array(0, 1, 3, 4);
+        }
+
+        $key = $this->key;
+
+        $w = array_values(unpack('N*words', $key));
+
+        $length = $this->Nb * ($this->Nr + 1);
+        for ($i = $this->Nk; $i < $length; $i++) {
+            $temp = $w[$i - 1];
+            if ($i % $this->Nk == 0) {
+                // according to <http://php.net/language.types.integer>, "the size of an integer is platform-dependent".
+                // on a 32-bit machine, it's 32-bits, and on a 64-bit machine, it's 64-bits. on a 32-bit machine,
+                // 0xFFFFFFFF << 8 == 0xFFFFFF00, but on a 64-bit machine, it equals 0xFFFFFFFF00. as such, doing 'and'
+                // with 0xFFFFFFFF (or 0xFFFFFF00) on a 32-bit machine is unnecessary, but on a 64-bit machine, it is.
+                $temp = (($temp << 8) & 0xFFFFFF00) | (($temp >> 24) & 0x000000FF); // rotWord
+                $temp = $this->_subWord($temp) ^ $rcon[$i / $this->Nk];
+            } else if ($this->Nk > 6 && $i % $this->Nk == 4) {
+                $temp = $this->_subWord($temp);
+            }
+            $w[$i] = $w[$i - $this->Nk] ^ $temp;
+        }
+
+        // convert the key schedule from a vector of $Nb * ($Nr + 1) length to a matrix with $Nr + 1 rows and $Nb columns
+        // and generate the inverse key schedule.  more specifically,
+        // according to <http://csrc.nist.gov/archive/aes/rijndael/Rijndael-ammended.pdf#page=23> (section 5.3.3), 
+        // "The key expansion for the Inverse Cipher is defined as follows:
+        //        1. Apply the Key Expansion.
+        //        2. Apply InvMixColumn to all Round Keys except the first and the last one."
+        // also, see fips-197.pdf#page=27, "5.3.5 Equivalent Inverse Cipher"
+        $temp = array();
+        for ($i = $row = $col = 0; $i < $length; $i++, $col++) {
+            if ($col == $this->Nb) {
+                if ($row == 0) {
+                    $this->dw[0] = $this->w[0];
+                } else {
+                    // subWord + invMixColumn + invSubWord = invMixColumn
+                    $j = 0;
+                    while ($j < $this->Nb) {
+                        $dw = $this->_subWord($this->w[$row][$j]);
+                        $temp[$j] = $this->dt0[$dw & 0xFF000000] ^ 
+                                    $this->dt1[$dw & 0x00FF0000] ^ 
+                                    $this->dt2[$dw & 0x0000FF00] ^ 
+                                    $this->dt3[$dw & 0x000000FF];
+                        $j++;
+                    }
+                    $this->dw[$row] = $temp;
+                }
+
+                $col = 0;
+                $row++;
+            }
+            $this->w[$row][$col] = $w[$i];
+        }
+
+        $this->dw[$row] = $this->w[$row];
+
+        $this->changed = false;
+    }
+
+    /**
+     * Performs S-Box substitutions
+     *
+     * @access private
+     */
+    function _subWord($word)
+    {
+        static $sbox0, $sbox1, $sbox2, $sbox3;
+
+        if (empty($sbox0)) {
+            $sbox0 = array(
+                0x63, 0x7C, 0x77, 0x7B, 0xF2, 0x6B, 0x6F, 0xC5, 0x30, 0x01, 0x67, 0x2B, 0xFE, 0xD7, 0xAB, 0x76,
+                0xCA, 0x82, 0xC9, 0x7D, 0xFA, 0x59, 0x47, 0xF0, 0xAD, 0xD4, 0xA2, 0xAF, 0x9C, 0xA4, 0x72, 0xC0,
+                0xB7, 0xFD, 0x93, 0x26, 0x36, 0x3F, 0xF7, 0xCC, 0x34, 0xA5, 0xE5, 0xF1, 0x71, 0xD8, 0x31, 0x15,
+                0x04, 0xC7, 0x23, 0xC3, 0x18, 0x96, 0x05, 0x9A, 0x07, 0x12, 0x80, 0xE2, 0xEB, 0x27, 0xB2, 0x75,
+                0x09, 0x83, 0x2C, 0x1A, 0x1B, 0x6E, 0x5A, 0xA0, 0x52, 0x3B, 0xD6, 0xB3, 0x29, 0xE3, 0x2F, 0x84,
+                0x53, 0xD1, 0x00, 0xED, 0x20, 0xFC, 0xB1, 0x5B, 0x6A, 0xCB, 0xBE, 0x39, 0x4A, 0x4C, 0x58, 0xCF,
+                0xD0, 0xEF, 0xAA, 0xFB, 0x43, 0x4D, 0x33, 0x85, 0x45, 0xF9, 0x02, 0x7F, 0x50, 0x3C, 0x9F, 0xA8,
+                0x51, 0xA3, 0x40, 0x8F, 0x92, 0x9D, 0x38, 0xF5, 0xBC, 0xB6, 0xDA, 0x21, 0x10, 0xFF, 0xF3, 0xD2,
+                0xCD, 0x0C, 0x13, 0xEC, 0x5F, 0x97, 0x44, 0x17, 0xC4, 0xA7, 0x7E, 0x3D, 0x64, 0x5D, 0x19, 0x73,
+                0x60, 0x81, 0x4F, 0xDC, 0x22, 0x2A, 0x90, 0x88, 0x46, 0xEE, 0xB8, 0x14, 0xDE, 0x5E, 0x0B, 0xDB,
+                0xE0, 0x32, 0x3A, 0x0A, 0x49, 0x06, 0x24, 0x5C, 0xC2, 0xD3, 0xAC, 0x62, 0x91, 0x95, 0xE4, 0x79,
+                0xE7, 0xC8, 0x37, 0x6D, 0x8D, 0xD5, 0x4E, 0xA9, 0x6C, 0x56, 0xF4, 0xEA, 0x65, 0x7A, 0xAE, 0x08,
+                0xBA, 0x78, 0x25, 0x2E, 0x1C, 0xA6, 0xB4, 0xC6, 0xE8, 0xDD, 0x74, 0x1F, 0x4B, 0xBD, 0x8B, 0x8A,
+                0x70, 0x3E, 0xB5, 0x66, 0x48, 0x03, 0xF6, 0x0E, 0x61, 0x35, 0x57, 0xB9, 0x86, 0xC1, 0x1D, 0x9E,
+                0xE1, 0xF8, 0x98, 0x11, 0x69, 0xD9, 0x8E, 0x94, 0x9B, 0x1E, 0x87, 0xE9, 0xCE, 0x55, 0x28, 0xDF,
+                0x8C, 0xA1, 0x89, 0x0D, 0xBF, 0xE6, 0x42, 0x68, 0x41, 0x99, 0x2D, 0x0F, 0xB0, 0x54, 0xBB, 0x16
+            );
+
+            $sbox1 = array();
+            $sbox2 = array();
+            $sbox3 = array();
+
+            for ($i = 0; $i < 256; $i++) {
+                $sbox1[$i <<  8] = $sbox0[$i] <<  8;
+                $sbox2[$i << 16] = $sbox0[$i] << 16;
+                $sbox3[$i << 24] = $sbox0[$i] << 24;
+            }
+        }
+
+        return $sbox0[$word & 0x000000FF] | 
+               $sbox1[$word & 0x0000FF00] | 
+               $sbox2[$word & 0x00FF0000] | 
+               $sbox3[$word & 0xFF000000];
+    }
+
+    /**
+     * Performs inverse S-Box substitutions
+     *
+     * @access private
+     */
+    function _invSubWord($word)
+    {
+        static $sbox0, $sbox1, $sbox2, $sbox3;
+
+        if (empty($sbox0)) {
+            $sbox0 = array(
+                0x52, 0x09, 0x6A, 0xD5, 0x30, 0x36, 0xA5, 0x38, 0xBF, 0x40, 0xA3, 0x9E, 0x81, 0xF3, 0xD7, 0xFB,
+                0x7C, 0xE3, 0x39, 0x82, 0x9B, 0x2F, 0xFF, 0x87, 0x34, 0x8E, 0x43, 0x44, 0xC4, 0xDE, 0xE9, 0xCB,
+                0x54, 0x7B, 0x94, 0x32, 0xA6, 0xC2, 0x23, 0x3D, 0xEE, 0x4C, 0x95, 0x0B, 0x42, 0xFA, 0xC3, 0x4E,
+                0x08, 0x2E, 0xA1, 0x66, 0x28, 0xD9, 0x24, 0xB2, 0x76, 0x5B, 0xA2, 0x49, 0x6D, 0x8B, 0xD1, 0x25,
+                0x72, 0xF8, 0xF6, 0x64, 0x86, 0x68, 0x98, 0x16, 0xD4, 0xA4, 0x5C, 0xCC, 0x5D, 0x65, 0xB6, 0x92,
+                0x6C, 0x70, 0x48, 0x50, 0xFD, 0xED, 0xB9, 0xDA, 0x5E, 0x15, 0x46, 0x57, 0xA7, 0x8D, 0x9D, 0x84,
+                0x90, 0xD8, 0xAB, 0x00, 0x8C, 0xBC, 0xD3, 0x0A, 0xF7, 0xE4, 0x58, 0x05, 0xB8, 0xB3, 0x45, 0x06,
+                0xD0, 0x2C, 0x1E, 0x8F, 0xCA, 0x3F, 0x0F, 0x02, 0xC1, 0xAF, 0xBD, 0x03, 0x01, 0x13, 0x8A, 0x6B,
+                0x3A, 0x91, 0x11, 0x41, 0x4F, 0x67, 0xDC, 0xEA, 0x97, 0xF2, 0xCF, 0xCE, 0xF0, 0xB4, 0xE6, 0x73,
+                0x96, 0xAC, 0x74, 0x22, 0xE7, 0xAD, 0x35, 0x85, 0xE2, 0xF9, 0x37, 0xE8, 0x1C, 0x75, 0xDF, 0x6E,
+                0x47, 0xF1, 0x1A, 0x71, 0x1D, 0x29, 0xC5, 0x89, 0x6F, 0xB7, 0x62, 0x0E, 0xAA, 0x18, 0xBE, 0x1B,
+                0xFC, 0x56, 0x3E, 0x4B, 0xC6, 0xD2, 0x79, 0x20, 0x9A, 0xDB, 0xC0, 0xFE, 0x78, 0xCD, 0x5A, 0xF4,
+                0x1F, 0xDD, 0xA8, 0x33, 0x88, 0x07, 0xC7, 0x31, 0xB1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xEC, 0x5F,
+                0x60, 0x51, 0x7F, 0xA9, 0x19, 0xB5, 0x4A, 0x0D, 0x2D, 0xE5, 0x7A, 0x9F, 0x93, 0xC9, 0x9C, 0xEF,
+                0xA0, 0xE0, 0x3B, 0x4D, 0xAE, 0x2A, 0xF5, 0xB0, 0xC8, 0xEB, 0xBB, 0x3C, 0x83, 0x53, 0x99, 0x61,
+                0x17, 0x2B, 0x04, 0x7E, 0xBA, 0x77, 0xD6, 0x26, 0xE1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0C, 0x7D
+            );
+
+            $sbox1 = array();
+            $sbox2 = array();
+            $sbox3 = array();
+
+            for ($i = 0; $i < 256; $i++) {
+                $sbox1[$i <<  8] = $sbox0[$i] <<  8;
+                $sbox2[$i << 16] = $sbox0[$i] << 16;
+                $sbox3[$i << 24] = $sbox0[$i] << 24;
+            }
+        }
+
+        return $sbox0[$word & 0x000000FF] | 
+               $sbox1[$word & 0x0000FF00] | 
+               $sbox2[$word & 0x00FF0000] | 
+               $sbox3[$word & 0xFF000000];
+    }
+
+    /**
+     * Pad "packets".
+     *
+     * Rijndael works by encrypting between sixteen and thirty-two bytes at a time, provided that number is also a multiple
+     * of four.  If you ever need to encrypt or decrypt something that isn't of the proper length, it becomes necessary to
+     * pad the input so that it is of the proper length.
+     *
+     * Padding is enabled by default.  Sometimes, however, it is undesirable to pad strings.  Such is the case in SSH,
+     * where "packets" are padded with random bytes before being encrypted.  Unpad these packets and you risk stripping
+     * away characters that shouldn't be stripped away. (SSH knows how many bytes are added because the length is
+     * transmitted separately)
+     *
+     * @see Crypt_Rijndael::disablePadding()
+     * @access public
+     */
+    function enablePadding()
+    {
+        $this->padding = true;
+    }
+
+    /**
+     * Do not pad packets.
+     *
+     * @see Crypt_Rijndael::enablePadding()
+     * @access public
+     */
+    function disablePadding()
+    {
+        $this->padding = false;
+    }
+
+    /**
+     * Pads a string
+     *
+     * Pads a string using the RSA PKCS padding standards so that its length is a multiple of the blocksize.
+     * $block_size - (strlen($text) % $block_size) bytes are added, each of which is equal to 
+     * chr($block_size - (strlen($text) % $block_size)
+     *
+     * If padding is disabled and $text is not a multiple of the blocksize, the string will be padded regardless
+     * and padding will, hence forth, be enabled.
+     *
+     * @see Crypt_Rijndael::_unpad()
+     * @access private
+     */
+    function _pad($text)
+    {
+        $length = strlen($text);
+
+        if (!$this->padding) {
+            if ($length % $this->block_size == 0) {
+                return $text;
+            } else {
+                user_error("The plaintext's length ($length) is not a multiple of the block size ({$this->block_size})", E_USER_NOTICE);
+                $this->padding = true;
+            }
+        }
+
+        $pad = $this->block_size - ($length % $this->block_size);
+
+        return str_pad($text, $length + $pad, chr($pad));
+    }
+
+    /**
+     * Unpads a string.
+     *
+     * If padding is enabled and the reported padding length is invalid the encryption key will be assumed to be wrong
+     * and false will be returned.
+     *
+     * @see Crypt_Rijndael::_pad()
+     * @access private
+     */
+    function _unpad($text)
+    {
+        if (!$this->padding) {
+            return $text;
+        }
+
+        $length = ord($text[strlen($text) - 1]);
+
+        if (!$length || $length > $this->block_size) {
+            return false;
+        }
+
+        return substr($text, 0, -$length);
+    }
+
+    /**
+     * Treat consecutive "packets" as if they are a continuous buffer.
+     *
+     * Say you have a 32-byte plaintext $plaintext.  Using the default behavior, the two following code snippets
+     * will yield different outputs:
+     *
+     * <code>
+     *    echo $rijndael->encrypt(substr($plaintext,  0, 16));
+     *    echo $rijndael->encrypt(substr($plaintext, 16, 16));
+     * </code>
+     * <code>
+     *    echo $rijndael->encrypt($plaintext);
+     * </code>
+     *
+     * The solution is to enable the continuous buffer.  Although this will resolve the above discrepancy, it creates
+     * another, as demonstrated with the following:
+     *
+     * <code>
+     *    $rijndael->encrypt(substr($plaintext, 0, 16));
+     *    echo $rijndael->decrypt($des->encrypt(substr($plaintext, 16, 16)));
+     * </code>
+     * <code>
+     *    echo $rijndael->decrypt($des->encrypt(substr($plaintext, 16, 16)));
+     * </code>
+     *
+     * With the continuous buffer disabled, these would yield the same output.  With it enabled, they yield different
+     * outputs.  The reason is due to the fact that the initialization vector's change after every encryption /
+     * decryption round when the continuous buffer is enabled.  When it's disabled, they remain constant.
+     *
+     * Put another way, when the continuous buffer is enabled, the state of the Crypt_Rijndael() object changes after each
+     * encryption / decryption round, whereas otherwise, it'd remain constant.  For this reason, it's recommended that
+     * continuous buffers not be used.  They do offer better security and are, in fact, sometimes required (SSH uses them),
+     * however, they are also less intuitive and more likely to cause you problems.
+     *
+     * @see Crypt_Rijndael::disableContinuousBuffer()
+     * @access public
+     */
+    function enableContinuousBuffer()
+    {
+        $this->continuousBuffer = true;
+    }
+
+    /**
+     * Treat consecutive packets as if they are a discontinuous buffer.
+     *
+     * The default behavior.
+     *
+     * @see Crypt_Rijndael::enableContinuousBuffer()
+     * @access public
+     */
+    function disableContinuousBuffer()
+    {
+        $this->continuousBuffer = false;
+        $this->encryptIV = $this->iv;
+        $this->decryptIV = $this->iv;
+    }
+
+    /**
+     * String Shift
+     *
+     * Inspired by array_shift
+     *
+     * @param String $string
+     * @param optional Integer $index
+     * @return String
+     * @access private
+     */
+    function _string_shift(&$string, $index = 1)
+    {
+        $substr = substr($string, 0, $index);
+        $string = substr($string, $index);
+        return $substr;
+    }
+}
+
+// vim: ts=4:sw=4:et:
+// vim6: fdl=1:
+?>
diff --git a/phpmyadmin/libraries/plugin_interface.lib.php b/phpmyadmin/libraries/plugin_interface.lib.php
new file mode 100644
index 0000000..b4fe7f6
--- /dev/null
+++ b/phpmyadmin/libraries/plugin_interface.lib.php
@@ -0,0 +1,508 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * Generic plugin interface.
+ *
+ * @package PhpMyAdmin
+ */
+
+/**
+ * Includes and instantiates the specified plugin type for a certain format
+ *
+ * @param string $plugin_type   the type of the plugin (import, export, etc)
+ * @param string $plugin_format the format of the plugin (sql, xml, et )
+ * @param string $plugins_dir   directrory with plugins
+ * @param mixed  $plugin_param  parameter to plugin by which they can
+ *                              decide whether they can work
+ *
+ * @return new plugin instance
+ */
+function PMA_getPlugin(
+    $plugin_type,
+    $plugin_format,
+    $plugins_dir,
+    $plugin_param = false
+) {
+    $GLOBALS['plugin_param'] = $plugin_param;
+    $class_name = strtoupper($plugin_type[0])
+        . strtolower(substr($plugin_type, 1))
+        . strtoupper($plugin_format[0])
+        . strtolower(substr($plugin_format, 1));
+    $file = $class_name . ".class.php";
+    if (is_file($plugins_dir . $file)) {
+        include_once $plugins_dir . $file;
+        return new $class_name;
+    }
+
+    return null;
+}
+
+/**
+ * Reads all plugin information from directory $plugins_dir
+ *
+ * @param string $plugin_type  the type of the plugin (import, export, etc)
+ * @param string $plugins_dir  directrory with plugins
+ * @param mixed  $plugin_param parameter to plugin by which they can
+ *                             decide whether they can work
+ *
+ * @return array list of plugin instances
+ */
+function PMA_getPlugins($plugin_type, $plugins_dir, $plugin_param)
+{
+    $GLOBALS['plugin_param'] = $plugin_param;
+    /* Scan for plugins */
+    $plugin_list = array();
+    if ($handle = @opendir($plugins_dir)) {
+        while ($file = @readdir($handle)) {
+            // In some situations, Mac OS creates a new file for each file
+            // (for example ._csv.php) so the following regexp
+            // matches a file which does not start with a dot but ends
+            // with ".php"
+            $class_type = strtoupper($plugin_type[0])
+                . strtolower(substr($plugin_type, 1));
+            if (is_file($plugins_dir . $file)
+                && preg_match(
+                    '@^' . $class_type . '(.+)\.class\.php$@i',
+                    $file,
+                    $matches
+                )
+            ) {
+                $GLOBALS['skip_import'] = false;
+                include_once $plugins_dir . $file;
+                if (! $GLOBALS['skip_import']) {
+                    $class_name = $class_type . $matches[1];
+                    $plugin_list [] = new $class_name;
+                }
+            }
+        }
+    }
+    ksort($plugin_list);
+    return $plugin_list;
+}
+
+/**
+ * Returns locale string for $name or $name if no locale is found
+ *
+ * @param string $name for local string
+ *
+ * @return string  locale string for $name
+ */
+function PMA_getString($name)
+{
+    return isset($GLOBALS[$name]) ? $GLOBALS[$name] : $name;
+}
+
+/**
+ * Returns html input tag option 'checked' if plugin $opt
+ * should be set by config or request
+ *
+ * @param string $section name of config section in
+ *                        $GLOBALS['cfg'][$section] for plugin
+ * @param string $opt     name of option
+ *
+ * @return string  hmtl input tag option 'checked'
+ */
+function PMA_pluginCheckboxCheck($section, $opt)
+{
+    // If the form is being repopulated using $_GET data, that is priority
+    if (isset($_GET[$opt])
+        || ! isset($_GET['repopulate'])
+        && ((isset($GLOBALS['timeout_passed'])
+        && $GLOBALS['timeout_passed']
+        && isset($_REQUEST[$opt]))
+        || (isset($GLOBALS['cfg'][$section][$opt])
+        && $GLOBALS['cfg'][$section][$opt]))
+    ) {
+        return ' checked="checked"';
+    }
+    return '';
+}
+
+/**
+ * Returns default value for option $opt
+ *
+ * @param string $section name of config section in
+ *                        $GLOBALS['cfg'][$section] for plugin
+ * @param string $opt     name of option
+ *
+ * @return string  default value for option $opt
+ */
+function PMA_pluginGetDefault($section, $opt)
+{
+    if (isset($_GET[$opt])) {
+        // If the form is being repopulated using $_GET data, that is priority
+        return htmlspecialchars($_GET[$opt]);
+    } elseif (isset($GLOBALS['timeout_passed'])
+        && $GLOBALS['timeout_passed']
+        && isset($_REQUEST[$opt])) {
+        return htmlspecialchars($_REQUEST[$opt]);
+    } elseif (isset($GLOBALS['cfg'][$section][$opt])) {
+        $matches = array();
+        /* Possibly replace localised texts */
+        if (preg_match_all(
+            '/(str[A-Z][A-Za-z0-9]*)/',
+            $GLOBALS['cfg'][$section][$opt],
+            $matches
+        )) {
+            $val = $GLOBALS['cfg'][$section][$opt];
+            foreach ($matches[0] as $match) {
+                if (isset($GLOBALS[$match])) {
+                    $val = str_replace($match, $GLOBALS[$match], $val);
+                }
+            }
+            return htmlspecialchars($val);
+        } else {
+            return htmlspecialchars($GLOBALS['cfg'][$section][$opt]);
+        }
+    }
+    return '';
+}
+
+/**
+ * Returns html select form element for plugin choice
+ * and hidden fields denoting whether each plugin must be exported as a file
+ *
+ * @param string $section name of config section in
+ *                        $GLOBALS['cfg'][$section] for plugin
+ * @param string $name    name of select element
+ * @param array  &$list   array with plugin instances
+ * @param string $cfgname name of config value, if none same as $name
+ *
+ * @return string  html select tag
+ */
+function PMA_pluginGetChoice($section, $name, &$list, $cfgname = null)
+{
+    if (! isset($cfgname)) {
+        $cfgname = $name;
+    }
+    $ret = '<select id="plugins" name="' . $name . '">';
+    $default = PMA_pluginGetDefault($section, $cfgname);
+    foreach ($list as $plugin) {
+        $plugin_name = strtolower(substr(get_class($plugin), strlen($section)));
+        $ret .= '<option';
+         // If the form is being repopulated using $_GET data, that is priority
+        if (isset($_GET[$name])
+            && $plugin_name == $_GET[$name]
+            || ! isset($_GET[$name])
+            && $plugin_name == $default
+        ) {
+            $ret .= ' selected="selected"';
+        }
+
+        $properties = $plugin->getProperties();
+        $text = null;
+        if ($properties != null) {
+            $text = $properties->getText();
+        }
+        $ret .= ' value="' . $plugin_name . '">'
+           . PMA_getString($text)
+           . '</option>' . "\n";
+    }
+    $ret .= '</select>' . "\n";
+
+    // Whether each plugin has to be saved as a file
+    foreach ($list as $plugin) {
+        $plugin_name = strtolower(substr(get_class($plugin), strlen($section)));
+        $ret .= '<input type="hidden" id="force_file_' . $plugin_name
+            . '" value="';
+        $properties = $plugin->getProperties();
+        if ( ! strcmp($section, 'Import')
+            || ($properties != null && $properties->getForceFile() != null)
+        ) {
+            $ret .= 'true';
+        } else {
+            $ret .= 'false';
+        }
+        $ret .= '" />'. "\n";
+    }
+
+    return $ret;
+}
+
+/**
+ * Returns single option in a list element
+ *
+ * @param string  $section        name of config section in
+ *                               $GLOBALS['cfg'][$section] for plugin
+ * @param string  $plugin_name    unique plugin name
+ * @param array   &$propertyGroup options property main group instance
+ * @param boolean $is_subgroup    if this group is a subgroup
+ *
+ * @return string  table row with option
+ */
+function PMA_pluginGetOneOption(
+    $section,
+    $plugin_name,
+    &$propertyGroup,
+    $is_subgroup = false
+) {
+    $ret = "\n";
+
+    if (! $is_subgroup) {
+        // for subgroup headers
+        if (strpos(get_class($propertyGroup), "PropertyItem")) {
+            $properties = array($propertyGroup);
+        } else {
+            // for main groups
+            $ret .= '<div class="export_sub_options" id="' . $plugin_name . '_'
+                . $propertyGroup->getName() . '">';
+
+            if (method_exists($propertyGroup, 'getText')) {
+                $text = $propertyGroup->getText();
+            }
+
+            if ($text != null) {
+                $ret .= '<h4>' . PMA_getString($text) . '</h4>';
+            }
+            $ret .= '<ul>';
+        }
+    }
+
+    if (! isset($properties)) {
+        $not_subgroup_header = true;
+        if (method_exists($propertyGroup, 'getProperties')) {
+            $properties = $propertyGroup->getProperties();
+        }
+    }
+
+    if (isset($properties)) {
+        foreach ($properties as $propertyItem) {
+            $property_class = get_class($propertyItem);
+            // if the property is a subgroup, we deal with it recursively
+            if (strpos($property_class, "Subgroup")) {
+                // for subgroups
+                // each subgroup can have a header, which may also be a form element
+                $subgroup_header = $propertyItem->getSubgroupHeader();
+                if (isset($subgroup_header)) {
+                    $ret .= PMA_pluginGetOneOption(
+                        $section,
+                        $plugin_name,
+                        $subgroup_header
+                    );
+                }
+
+                $ret .= '<li class="subgroup"><ul';
+                if (isset($subgroup_header)) {
+                    $ret .= ' id="ul_' . $subgroup_header->getName() . '">';
+                } else {
+                    $ret .= '>';
+                }
+
+                $ret .=  PMA_pluginGetOneOption(
+                    $section,
+                    $plugin_name,
+                    $propertyItem,
+                    true
+                );
+            } else {
+                // single property item
+                switch ($property_class) {
+                case "BoolPropertyItem":
+                    $ret .= '<li>' . "\n";
+                    $ret .= '<input type="checkbox" name="' . $plugin_name . '_'
+                        . $propertyItem->getName() . '"'
+                        . ' value="something" id="checkbox_' . $plugin_name . '_'
+                        . $propertyItem->getName() . '"'
+                        . ' '
+                        . PMA_pluginCheckboxCheck(
+                            $section,
+                            $plugin_name . '_' . $propertyItem->getName()
+                        );
+
+                    if ($propertyItem->getForce() != null) {
+                        // Same code is also few lines lower, update both if needed
+                        $ret .= ' onclick="if (!this.checked && '
+                            . '(!document.getElementById(\'checkbox_' . $plugin_name
+                            . '_' . $propertyItem->getForce() . '\') '
+                            . '|| !document.getElementById(\'checkbox_'
+                            . $plugin_name . '_' . $propertyItem->getForce()
+                            . '\').checked)) '
+                            . 'return false; else return true;"';
+                    }
+                    $ret .= ' />';
+                    $ret .= '<label for="checkbox_' . $plugin_name . '_'
+                        . $propertyItem->getName() . '">'
+                        . PMA_getString($propertyItem->getText()) . '</label>';
+                    break;
+                case "DocPropertyItem":
+                    echo "DocPropertyItem";
+                    break;
+                case "HiddenPropertyItem":
+                    $ret .= '<li><input type="hidden" name="' . $plugin_name . '_'
+                        . $propertyItem->getName() . '"'
+                        . ' value="' . PMA_pluginGetDefault(
+                            $section,
+                            $plugin_name . '_' . $propertyItem->getName()
+                        )
+                        . '"' . ' /></li>';
+                    break;
+                case "MessageOnlyPropertyItem":
+                    $ret .= '<li>' . "\n";
+                    $ret .= '<p>' . PMA_getString($propertyItem->getText()) . '</p>';
+                    break;
+                case "RadioPropertyItem":
+                    $default = PMA_pluginGetDefault(
+                        $section,
+                        $plugin_name . '_' . $propertyItem->getName()
+                    );
+                    foreach ($propertyItem->getValues() as $key => $val) {
+                        $ret .= '<li><input type="radio" name="' . $plugin_name
+                            . '_' . $propertyItem->getName() . '" value="' . $key
+                            . '" id="radio_' . $plugin_name . '_'
+                            . $propertyItem->getName() . '_' . $key . '"';
+                        if ($key == $default) {
+                            $ret .= ' checked="checked"';
+                        }
+                        $ret .= ' />' . '<label for="radio_' . $plugin_name . '_'
+                            . $propertyItem->getName() . '_' . $key . '">'
+                            . PMA_getString($val) . '</label></li>';
+                    }
+                    break;
+                case "SelectPropertyItem":
+                    $ret .= '<li>' . "\n";
+                    $ret .= '<label for="select_' . $plugin_name . '_'
+                        . $propertyItem->getName() . '" class="desc">'
+                        . PMA_getString($propertyItem->getText()) . '</label>';
+                    $ret .= '<select name="' . $plugin_name . '_'
+                        . $propertyItem->getName() . '"'
+                        . ' id="select_' . $plugin_name . '_'
+                        . $propertyItem->getName() . '">';
+                    $default = PMA_pluginGetDefault(
+                        $section,
+                        $plugin_name . '_' . $propertyItem->getName()
+                    );
+                    foreach ($propertyItem->getValues() as $key => $val) {
+                        $ret .= '<option value="' . $key . '"';
+                        if ($key == $default) {
+                            $ret .= ' selected="selected"';
+                        }
+                        $ret .= '>' . PMA_getString($val) . '</option>';
+                    }
+                    $ret .= '</select>';
+                    break;
+                case "TextPropertyItem":
+                    $ret .= '<li>' . "\n";
+                    $ret .= '<label for="text_' . $plugin_name . '_'
+                        . $propertyItem->getName() . '" class="desc">'
+                        . PMA_getString($propertyItem->getText()) . '</label>';
+                    $ret .= '<input type="text" name="' . $plugin_name . '_'
+                        . $propertyItem->getName() . '"'
+                        . ' value="' . PMA_pluginGetDefault(
+                            $section,
+                            $plugin_name . '_' . $propertyItem->getName()
+                        ) . '"'
+                        . ' id="text_' . $plugin_name . '_'
+                        . $propertyItem->getName() . '"'
+                        . ($propertyItem->getSize() != null
+                            ? ' size="' . $propertyItem->getSize() . '"'
+                            : '')
+                        . ($propertyItem->getLen() != null
+                            ? ' maxlength="' . $propertyItem->getLen() . '"'
+                            : '')
+                        . ' />';
+                    break;
+                default:;
+                }
+            }
+        }
+    }
+
+    if ($is_subgroup) {
+        // end subgroup
+        $ret .= '</ul></li>';
+    } else {
+        // end main group
+        if (! empty($not_subgroup_header)) {
+            $ret .= '</ul></div>';
+        }
+    }
+
+    if (method_exists($propertyGroup, "getDoc")) {
+        $doc = $propertyGroup->getDoc();
+        if ($doc != null) {
+            if (count($doc) == 3) {
+                $ret .= PMA_Util::showMySQLDocu(
+                    $doc[0],
+                    $doc[1],
+                    false,
+                    $doc[2]
+                );
+            } elseif (count($doc) == 1) {
+                $ret .= PMA_Util::showDocu('faq', $doc[0]);
+            } else {
+                $ret .= PMA_Util::showMySQLDocu(
+                    $doc[0],
+                    $doc[1]
+                );
+            }
+        }
+    }
+
+    // Close the list element after $doc link is displayed
+    if (isset($property_class)) {
+        if ($property_class == 'BoolPropertyItem'
+            || $property_class == 'MessageOnlyPropertyItem'
+            || $property_class == 'SelectPropertyItem'
+            || $property_class == 'TextPropertyItem'
+        ) {
+            $ret .= '</li>';
+        }
+    }
+    $ret .= "\n";
+    return $ret;
+}
+
+/**
+ * Returns html div with editable options for plugin
+ *
+ * @param string $section name of config section in $GLOBALS['cfg'][$section]
+ * @param array  &$list   array with plugin instances
+ *
+ * @return string  html fieldset with plugin options
+ */
+function PMA_pluginGetOptions($section, &$list)
+{
+    $ret = '';
+    $default = PMA_pluginGetDefault('Export', 'format');
+    // Options for plugins that support them
+    foreach ($list as $plugin) {
+        $properties = $plugin->getProperties();
+        if ($properties != null) {
+            $text = $properties->getText();
+            $options = $properties->getOptions();
+        }
+
+        $plugin_name = strtolower(substr(get_class($plugin), strlen($section)));
+        $ret .= '<div id="' . $plugin_name
+            . '_options" class="format_specific_options">';
+        $ret .= '<h3>' . PMA_getString($text) . '</h3>';
+
+        $no_options = true;
+        if ($options != null && count($options) > 0) {
+            foreach ($options->getProperties()
+                as $propertyMainGroup
+            ) {
+                // check for hidden properties
+                $no_options = true;
+                foreach ($propertyMainGroup->getProperties() as $propertyItem) {
+                    if (strcmp("HiddenPropertyItem", get_class($propertyItem))) {
+                        $no_options = false;
+                        break;
+                    }
+                }
+
+                $ret .= PMA_pluginGetOneOption(
+                    $section,
+                    $plugin_name,
+                    $propertyMainGroup
+                );
+            }
+        }
+
+        if ($no_options) {
+            $ret .= '<p>' . __('This format has no options') . '</p>';
+        }
+        $ret .= '</div>';
+    }
+    return $ret;
+}
diff --git a/phpmyadmin/libraries/plugins/AuthenticationPlugin.class.php b/phpmyadmin/libraries/plugins/AuthenticationPlugin.class.php
new file mode 100644
index 0000000..3ddf55e
--- /dev/null
+++ b/phpmyadmin/libraries/plugins/AuthenticationPlugin.class.php
@@ -0,0 +1,51 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * Abstract class for the authentication plugins
+ *
+ * @package PhpMyAdmin
+ */
+if (! defined('PHPMYADMIN')) {
+    exit;
+}
+
+/* This class extends the PluginObserver class */
+require_once 'PluginObserver.class.php';
+
+/**
+ * Provides a common interface that will have to be implemented by all of the
+ * authentication plugins.
+ *
+ * @package PhpMyAdmin
+ */
+abstract class AuthenticationPlugin extends PluginObserver
+{
+    /**
+     * Displays authentication form
+     *
+     * @return boolean
+     */
+    abstract public function auth();
+
+    /**
+     * Gets advanced authentication settings
+     *
+     * @return boolean
+     */
+    abstract public function authCheck();
+
+    /**
+     * Set the user and password after last checkings if required
+     *
+     * @return boolean
+     */
+    abstract public function authSetUser();
+
+    /**
+     * User is not allowed to login to MySQL -> authentication failed
+     *
+     * @return boolean
+     */
+    abstract public function authFails();
+}
+?>
\ No newline at end of file
diff --git a/phpmyadmin/libraries/plugins/ExportPlugin.class.php b/phpmyadmin/libraries/plugins/ExportPlugin.class.php
new file mode 100644
index 0000000..0af20d3
--- /dev/null
+++ b/phpmyadmin/libraries/plugins/ExportPlugin.class.php
@@ -0,0 +1,205 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * Abstract class for the export plugins
+ *
+ * @package PhpMyAdmin
+ */
+if (! defined('PHPMYADMIN')) {
+    exit;
+}
+
+/* This class extends the PluginObserver class */
+require_once 'PluginObserver.class.php';
+
+/**
+ * Provides a common interface that will have to be implemented by all of the
+ * export plugins. Some of the plugins will also implement other public
+ * methods, but those are not declared here, because they are not implemented
+ * by all export plugins.
+ *
+ * @package PhpMyAdmin
+ */
+abstract class ExportPlugin extends PluginObserver
+{
+    /**
+     * Array containing the specific export plugin type properties
+     *
+     * @var array
+     */
+    protected $properties;
+
+    /**
+     * Common methods, must be overwritten by all export plugins
+     */
+
+
+    /**
+     * Outputs export header
+     *
+     * @return bool Whether it succeeded
+     */
+    abstract public function exportHeader ();
+
+    /**
+     * Outputs export footer
+     *
+     * @return bool Whether it succeeded
+     */
+    abstract public function exportFooter ();
+
+    /**
+     * Outputs database header
+     *
+     * @param string $db Database name
+     *
+     * @return bool Whether it succeeded
+     */
+    abstract public function exportDBHeader ($db);
+
+    /**
+     * Outputs database footer
+     *
+     * @param string $db Database name
+     *
+     * @return bool Whether it succeeded
+     */
+    abstract public function exportDBFooter ($db);
+
+    /**
+     * Outputs CREATE DATABASE statement
+     *
+     * @param string $db Database name
+     *
+     * @return bool Whether it succeeded
+     */
+    abstract public function exportDBCreate($db);
+
+     /**
+     * Outputs the content of a table
+     *
+     * @param string $db        database name
+     * @param string $table     table name
+     * @param string $crlf      the end of line sequence
+     * @param string $error_url the url to go back in case of error
+     * @param string $sql_query SQL query for obtaining data
+     *
+     * @return bool Whether it succeeded
+     */
+    abstract public function exportData ($db, $table, $crlf, $error_url, $sql_query);
+
+
+    /**
+     * The following methods are used in export.php or in db_operations.php,
+     * but they are not implemented by all export plugins
+     */
+
+
+    /**
+     * Exports routines (procedures and functions)
+     *
+     * @param string $db Database
+     *
+     * @return bool Whether it succeeded
+     */
+    public function exportRoutines($db)
+    {
+        ;
+    }
+
+    /**
+     * Outputs table's structure
+     *
+     * @param string $db          database name
+     * @param string $table       table name
+     * @param string $crlf        the end of line sequence
+     * @param string $error_url   the url to go back in case of error
+     * @param string $export_mode 'create_table','triggers','create_view',
+     *                            'stand_in'
+     * @param string $export_type 'server', 'database', 'table'
+     * @param bool   $relation    whether to include relation comments
+     * @param bool   $comments    whether to include the pmadb-style column comments
+     *                            as comments in the structure; this is deprecated
+     *                            but the parameter is left here because export.php
+     *                            calls exportStructure() also for other export
+     *                            types which use this parameter
+     * @param bool   $mime        whether to include mime comments
+     * @param bool   $dates       whether to include creation/update/check dates
+     *
+     * @return bool Whether it succeeded
+     */
+    public function exportStructure(
+        $db,
+        $table,
+        $crlf,
+        $error_url,
+        $export_mode,
+        $export_type,
+        $relation = false,
+        $comments = false,
+        $mime = false,
+        $dates = false
+    ) {
+        ;
+    }
+
+    /**
+     * Returns a stand-in CREATE definition to resolve view dependencies
+     *
+     * @param string $db   the database name
+     * @param string $view the view name
+     * @param string $crlf the end of line sequence
+     *
+     * @return string resulting definition
+     */
+    public function getTableDefStandIn($db, $view, $crlf)
+    {
+        ;
+    }
+
+    /**
+     * Outputs triggers
+     *
+     * @param string $db    database name
+     * @param string $table table name
+     *
+     * @return string Formatted triggers list
+     */
+    protected function getTriggers($db, $table)
+    {
+        ;
+    }
+
+    /**
+     * Initialize the specific variables for each export plugin
+     *
+     * @return void
+     */
+    protected function initSpecificVariables()
+    {
+        ;
+    }
+
+
+    /* ~~~~~~~~~~~~~~~~~~~~ Getters and Setters ~~~~~~~~~~~~~~~~~~~~ */
+
+
+    /**
+     * Gets the export specific format plugin properties
+     *
+     * @return array
+     */
+    public function getProperties()
+    {
+        return $this->properties;
+    }
+
+    /**
+     * Sets the export plugins properties and is implemented by each export
+     * plugin
+     *
+     * @return void
+     */
+    abstract protected function setProperties();
+}
+?>
\ No newline at end of file
diff --git a/phpmyadmin/libraries/plugins/ImportPlugin.class.php b/phpmyadmin/libraries/plugins/ImportPlugin.class.php
new file mode 100644
index 0000000..0890dcf
--- /dev/null
+++ b/phpmyadmin/libraries/plugins/ImportPlugin.class.php
@@ -0,0 +1,59 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * Abstract class for the import plugins
+ *
+ * @package PhpMyAdmin
+ */
+if (! defined('PHPMYADMIN')) {
+    exit;
+}
+
+/* This class extends the PluginObserver class */
+require_once 'PluginObserver.class.php';
+
+/**
+ * Provides a common interface that will have to be implemented by all of the
+ * import plugins.
+ *
+ * @package PhpMyAdmin
+ */
+abstract class ImportPlugin extends PluginObserver
+{
+    /**
+     * Array containing the import plugin properties
+     *
+     * @var type array
+     */
+    protected $properties;
+
+    /**
+     * Handles the whole import logic
+     *
+     * @return void
+     */
+    abstract public function doImport();
+
+
+    /* ~~~~~~~~~~~~~~~~~~~~ Getters and Setters ~~~~~~~~~~~~~~~~~~~~ */
+
+
+    /**
+     * Gets the import specific format plugin properties
+     *
+     * @return array
+     */
+    public function getProperties()
+    {
+        return $this->properties;
+    }
+
+    /**
+     * Sets the export plugins properties and is implemented by each import
+     * plugin
+     *
+     * @return void
+     */
+    abstract protected function setProperties();
+}
+?>
\ No newline at end of file
diff --git a/phpmyadmin/libraries/plugins/PluginManager.class.php b/phpmyadmin/libraries/plugins/PluginManager.class.php
new file mode 100644
index 0000000..28400b7
--- /dev/null
+++ b/phpmyadmin/libraries/plugins/PluginManager.class.php
@@ -0,0 +1,132 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * The PluginManager class is used alongside PluginObserver to implement
+ * the Observer Design Pattern.
+ *
+ * @package PhpMyAdmin
+ */
+if (! defined('PHPMYADMIN')) {
+    exit;
+}
+
+/**
+ * This class implements the SplSubject interface
+ *
+ * @todo    implement all methods
+ * @package PhpMyAdmin
+ * @link    http://php.net/manual/en/class.splsubject.php
+ *
+ */
+class PluginManager implements SplSubject
+{
+    /**
+     * Contains a list with all the plugins that attach to it
+     *
+     * @var type SplObjectStorage
+     */
+    private $_storage;
+
+    /**
+     * Contains information about the current plugin state
+     *
+     * @var type string
+     */
+    private $_status;
+
+    /**
+     * Constructor
+     * Initializes $_storage with an empty SplObjectStorage
+     */
+    public function __construct()
+    {
+        $this->_storage = new SplObjectStorage();
+    }
+
+    /**
+     * Attaches an SplObserver so that it can be notified of updates
+     *
+     * @param SplObserver $observer The SplObserver to attach
+     *
+     * @return void
+     */
+    function attach (SplObserver $observer )
+    {
+        $this->_storage->attach($observer);
+    }
+
+    /**
+     * Detaches an observer from the subject to no longer notify it of updates
+     *
+     * @param SplObserver $observer The SplObserver to detach
+     *
+     * @return void
+     */
+    function detach (SplObserver $observer)
+    {
+         $this->_storage->detach($observer);
+    }
+
+    /**
+     * It is called after setStatus() was run by a certain plugin, and has
+     * the role of sending a notification to all of the plugins in $_storage,
+     * by calling the update() method for each of them.
+     *
+     * @todo implement
+     * @return void
+     */
+    function notify ()
+    {
+    }
+
+    /* ~~~~~~~~~~~~~~~~~~~~ Getters and Setters ~~~~~~~~~~~~~~~~~~~~ */
+
+    /**
+     * Gets the list with all the plugins that attach to it
+     *
+     * @return type SplObjectStorage
+     */
+    public function getStorage()
+    {
+        return $this->_storage;
+    }
+
+    /**
+     * Setter for $_storage
+     *
+     * @param SplObjectStorage $_storage the list with all the plugins that
+     *                                  attach to it
+     *
+     * @return void
+     */
+    public function setStorage($_storage)
+    {
+        $this->_storage = $_storage;
+    }
+
+    /**
+     * Gets the information about the current plugin state
+     * It is called by all the plugins in $_storage in their update() method
+     *
+     * @return type mixed
+     */
+    public function getStatus()
+    {
+        return $this->_status;
+    }
+
+    /**
+     * Setter for $_status
+     * If a plugin changes its status, this has to be remembered in order to
+     * notify the rest of the plugins that they should update
+     *
+     * @param mixed $_status contains information about the current plugin state
+     *
+     * @return void
+     */
+    public function setStatus($_status)
+    {
+        $this->_status = $_status;
+    }
+}
+?>
\ No newline at end of file
diff --git a/phpmyadmin/libraries/plugins/PluginObserver.class.php b/phpmyadmin/libraries/plugins/PluginObserver.class.php
new file mode 100644
index 0000000..520d62a
--- /dev/null
+++ b/phpmyadmin/libraries/plugins/PluginObserver.class.php
@@ -0,0 +1,90 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * The PluginObserver class is used alongside PluginManager to implement
+ * the Observer Design Pattern.
+ *
+ * @package PhpMyAdmin
+ */
+if (! defined('PHPMYADMIN')) {
+    exit;
+}
+
+/* Each PluginObserver instance contains a PluginManager instance */
+require_once 'PluginManager.class.php';
+
+/**
+ * This class implements the SplObserver interface
+ *
+ * @package PhpMyAdmin
+ * @link    http://php.net/manual/en/class.splobserver.php
+ */
+abstract class PluginObserver implements SplObserver
+{
+    /**
+     * PluginManager instance that contains a list with all the observer
+     * plugins that attach to it
+     *
+     * @var type PluginManager
+     */
+    private $_pluginManager;
+
+    /**
+     * Constructor
+     *
+     * @param PluginManager $pluginManager The Plugin Manager instance
+     */
+    public function __construct($pluginManager)
+    {
+        $this->_pluginManager = $pluginManager;
+    }
+
+    /**
+     * This method is called when any PluginManager to which the observer
+     * is attached calls PluginManager::notify()
+     *
+     * TODO Declare this function abstract, removing its body,
+     * as soon as we drop support for PHP 5.2.x.
+     * See bug #3538655.
+     *
+     * @param SplSubject $subject The PluginManager notifying the observer
+     *                            of an update.
+     *
+     * @return void
+     */
+    public function update (SplSubject $subject)
+    {
+        throw new Exception(
+            'PluginObserver::update must be overridden in child classes.'
+        );
+    }
+
+
+    /* ~~~~~~~~~~~~~~~~~~~~ Getters and Setters ~~~~~~~~~~~~~~~~~~~~ */
+
+
+    /**
+     * Gets the PluginManager instance that contains the list with all the
+     * plugins that attached to it
+     *
+     * @return type PluginManager
+     */
+    public function getPluginManager()
+    {
+        return $this->_pluginManager;
+    }
+
+    /**
+     * Setter for $_pluginManager
+     *
+     * @param PluginManager $_pluginManager the private instance that it will
+     *                                      attach to
+     *
+     * @return void
+     */
+    public function setPluginManager($_pluginManager)
+    {
+        $this->_pluginManager = $_pluginManager;
+    }
+}
+?>
diff --git a/phpmyadmin/libraries/plugins/TransformationsInterface.int.php b/phpmyadmin/libraries/plugins/TransformationsInterface.int.php
new file mode 100644
index 0000000..1bcb8af
--- /dev/null
+++ b/phpmyadmin/libraries/plugins/TransformationsInterface.int.php
@@ -0,0 +1,49 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * Interface for the transformations plugins
+ *
+ * @package PhpMyAdmin
+ */
+if (! defined('PHPMYADMIN')) {
+    exit;
+}
+
+/**
+ * Provides a common interface that will have to be implemented by all of the
+ * transformations plugins.
+ *
+ * @package PhpMyAdmin
+ */
+interface TransformationsInterface
+{
+    /**
+     * Gets the transformation description
+     *
+     * @return string
+     */
+    public static function getInfo();
+
+    /**
+     * Gets the specific MIME type
+     *
+     * @return string
+     */
+    public static function getMIMEType();
+
+    /**
+     * Gets the specific MIME subtype
+     *
+     * @return string
+     */
+    public static function getMIMESubtype();
+
+    /**
+     * Gets the transformation name of the specific plugin
+     *
+     * @return string
+     */
+    public static function getName();
+}
+
+?>
diff --git a/phpmyadmin/libraries/plugins/TransformationsPlugin.class.php b/phpmyadmin/libraries/plugins/TransformationsPlugin.class.php
new file mode 100644
index 0000000..959a8e1
--- /dev/null
+++ b/phpmyadmin/libraries/plugins/TransformationsPlugin.class.php
@@ -0,0 +1,49 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * Abstract class for the transformations plugins
+ *
+ * @package PhpMyAdmin
+ */
+if (! defined('PHPMYADMIN')) {
+    exit;
+}
+
+/* It extends the PluginObserver abstract class */
+require_once 'PluginObserver.class.php';
+/* It also implements the transformations interface */
+require_once 'TransformationsInterface.int.php';
+
+/**
+ * Extends PluginObserver and provides a common interface that will have to
+ * be implemented by all of the transformations plugins.
+ *
+ * @package PhpMyAdmin
+ */
+abstract class TransformationsPlugin extends PluginObserver
+    implements TransformationsInterface
+{
+    /**
+     * Does the actual work of each specific transformations plugin.
+     *
+     * @param array $options transformation options
+     *
+     * @return void
+     */
+    public function applyTransformationNoWrap($options = array())
+    {
+        ;
+    }
+
+    /**
+     * Does the actual work of each specific transformations plugin.
+     *
+     * @param string $buffer  text to be transformed
+     * @param array  $options transformation options
+     * @param string $meta    meta information
+     *
+     * @return void
+     */
+    abstract public function applyTransformation($buffer, $options = array(), $meta = '');
+}
+?>
diff --git a/phpmyadmin/libraries/plugins/UploadInterface.int.php b/phpmyadmin/libraries/plugins/UploadInterface.int.php
new file mode 100644
index 0000000..ab660d6
--- /dev/null
+++ b/phpmyadmin/libraries/plugins/UploadInterface.int.php
@@ -0,0 +1,36 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * Interface for the import->upload plugins
+ *
+ * @package PhpMyAdmin
+ */
+if (! defined('PHPMYADMIN')) {
+    exit;
+}
+
+/**
+ * Provides a common interface that will have to implemented by all of the
+ * import->upload plugins.
+ *
+ * @package PhpMyAdmin
+ */
+interface UploadInterface
+{
+    /**
+     * Gets the specific upload ID Key
+     *
+     * @return string ID Key
+     */
+    public static function getIdKey();
+
+    /**
+     * Returns upload status.
+     *
+     * @param string $id upload id
+     *
+     * @return array|null
+     */
+    public static function getUploadStatus($id);
+}
+?>
\ No newline at end of file
diff --git a/phpmyadmin/libraries/plugins/auth/AuthenticationConfig.class.php b/phpmyadmin/libraries/plugins/auth/AuthenticationConfig.class.php
new file mode 100644
index 0000000..07ad7cb
--- /dev/null
+++ b/phpmyadmin/libraries/plugins/auth/AuthenticationConfig.class.php
@@ -0,0 +1,172 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * Config Authentication plugin for phpMyAdmin
+ *
+ * @package    PhpMyAdmin-Authentication
+ * @subpackage Config
+ */
+if (! defined('PHPMYADMIN')) {
+    exit;
+}
+
+/* Get the authentication interface */
+require_once 'libraries/plugins/AuthenticationPlugin.class.php';
+
+/**
+ * Handles the config authentication method
+ *
+ * @package PhpMyAdmin-Authentication
+ */
+class AuthenticationConfig extends AuthenticationPlugin
+{
+    /**
+     * Displays authentication form
+     *
+     * @return boolean always true
+     */
+    public function auth()
+    {
+        return true;
+    }
+
+    /**
+     * Gets advanced authentication settings
+     *
+     * @return boolean always true
+     */
+    public function authCheck()
+    {
+        return true;
+    }
+
+    /**
+     * Set the user and password after last checkings if required
+     *
+     * @return boolean always true
+     */
+    public function authSetUser()
+    {
+        return true;
+    }
+
+    /**
+     * User is not allowed to login to MySQL -> authentication failed
+     *
+     * @global string  the MySQL error message PHP returns
+     * @global string  the connection type (persistent or not)
+     * @global string  the MySQL server port to use
+     * @global string  the MySQL socket port to use
+     * @global array   the current server settings
+     * @global string  the font face to use in case of failure
+     * @global string  the default font size to use in case of failure
+     * @global string  the big font size to use in case of failure
+     * @global boolean tell the "PMA_mysqlDie()" function headers have been
+     *                 sent
+     *
+     * @return boolean   always true (no return indeed)
+     */
+    public function authFails()
+    {
+        $conn_error = PMA_DBI_getError();
+        if (! $conn_error) {
+            $conn_error = __('Cannot connect: invalid settings.');
+        }
+
+        /* HTML header */
+        $response = PMA_Response::getInstance();
+        $response->getFooter()->setMinimal();
+        $header = $response->getHeader();
+        $header->setBodyId('loginform');
+        $header->setTitle(__('Access denied'));
+        $header->disableMenu();
+        echo '<br /><br />
+    <center>
+        <h1>';
+        echo sprintf(__('Welcome to %s'), ' phpMyAdmin ');
+        echo '</h1>
+    </center>
+    <br />
+    <table cellpadding="0" cellspacing="3" style="margin: 0 auto" width="80%">
+        <tr>
+            <td>';
+        if (isset($GLOBALS['allowDeny_forbidden'])
+            && $GLOBALS['allowDeny_forbidden']
+        ) {
+            trigger_error(__('Access denied'), E_USER_NOTICE);
+        } else {
+            // Check whether user has configured something
+            if ($GLOBALS['PMA_Config']->source_mtime == 0) {
+                echo '<p>' . sprintf(
+                    __(
+                        'You probably did not create a configuration file.'
+                        . ' You might want to use the %1$ssetup script%2$s to'
+                        . ' create one.'
+                    ),
+                    '<a href="setup/">',
+                    '</a>'
+                ) . '</p>' . "\n";
+            } elseif (! isset($GLOBALS['errno'])
+                || (isset($GLOBALS['errno']) && $GLOBALS['errno'] != 2002)
+                && $GLOBALS['errno'] != 2003
+            ) {
+                // if we display the "Server not responding" error, do not confuse
+                // users by telling them they have a settings problem
+                // (note: it's true that they could have a badly typed host name,
+                // but anyway the current message tells that the server
+                //  rejected the connection, which is not really what happened)
+                // 2002 is the error given by mysqli
+                // 2003 is the error given by mysql
+                trigger_error(
+                    __(
+                        'phpMyAdmin tried to connect to the MySQL server, and the'
+                        . ' server rejected the connection. You should check the'
+                        . ' host, username and password in your configuration and'
+                        . ' make sure that they correspond to the information given'
+                        . ' by the administrator of the MySQL server.'
+                    ), E_USER_WARNING
+                );
+            }
+            echo PMA_Util::mysqlDie(
+                $conn_error, '', true, '', false
+            );
+        }
+        $GLOBALS['error_handler']->dispUserErrors();
+        echo '</td>
+        </tr>
+        <tr>
+            <td>' . "\n";
+        echo '<a href="' 
+            . $GLOBALS['cfg']['DefaultTabServer']
+            . PMA_generate_common_url(array()) . '" class="button disableAjax">'
+            . __('Retry to connect')
+            . '</a>' . "\n";
+        echo '</td>
+        </tr>' . "\n";
+        if (count($GLOBALS['cfg']['Servers']) > 1) {
+            // offer a chance to login to other servers if the current one failed
+            include_once './libraries/select_server.lib.php';
+            echo '<tr>' . "\n";
+            echo ' <td>' . "\n";
+            echo PMA_selectServer(true, true);
+            echo ' </td>' . "\n";
+            echo '</tr>' . "\n";
+        }
+        echo '</table>' . "\n";
+        exit;
+        return true;
+    }
+
+    /**
+     * This method is called when any PluginManager to which the observer
+     * is attached calls PluginManager::notify()
+     *
+     * @param SplSubject $subject The PluginManager notifying the observer
+     *                            of an update.
+     *
+     * @return void
+     */
+    public function update (SplSubject $subject)
+    {
+    }
+}
diff --git a/phpmyadmin/libraries/plugins/auth/AuthenticationCookie.class.php b/phpmyadmin/libraries/plugins/auth/AuthenticationCookie.class.php
new file mode 100644
index 0000000..72274d9
--- /dev/null
+++ b/phpmyadmin/libraries/plugins/auth/AuthenticationCookie.class.php
@@ -0,0 +1,696 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * Cookie Authentication plugin for phpMyAdmin
+ *
+ * @package    PhpMyAdmin-Authentication
+ * @subpackage Cookie
+ */
+if (! defined('PHPMYADMIN')) {
+    exit;
+}
+
+/* Get the authentication interface */
+require_once 'libraries/plugins/AuthenticationPlugin.class.php';
+
+/**
+ * Remember where to redirect the user
+ * in case of an expired session.
+ */
+if (! empty($_REQUEST['target'])) {
+    $GLOBALS['target'] = $_REQUEST['target'];
+} else if (PMA_getenv('SCRIPT_NAME')) {
+    $GLOBALS['target'] = basename(PMA_getenv('SCRIPT_NAME'));
+}
+
+/**
+ * Swekey authentication functions.
+ */
+require './libraries/plugins/auth/swekey/swekey.auth.lib.php';
+
+/**
+ * Initialization
+ * Store the initialization vector because it will be needed for
+ * further decryption. I don't think necessary to have one iv
+ * per server so I don't put the server number in the cookie name.
+ */
+if (function_exists('mcrypt_encrypt')) {
+    if (empty($_COOKIE['pma_mcrypt_iv'])
+        || ! ($iv = base64_decode($_COOKIE['pma_mcrypt_iv'], true))
+    ) {
+        srand((double) microtime() * 1000000);
+        $td = mcrypt_module_open(MCRYPT_BLOWFISH, '', MCRYPT_MODE_CBC, '');
+        if ($td === false) {
+            PMA_fatalError(__('Failed to use Blowfish from mcrypt!'));
+        }
+        $iv = mcrypt_create_iv(mcrypt_enc_get_iv_size($td), MCRYPT_RAND);
+        $GLOBALS['PMA_Config']->setCookie(
+            'pma_mcrypt_iv',
+            base64_encode($iv)
+        );
+    }
+}
+
+/**
+ * Handles the cookie authentication method
+ *
+ * @package PhpMyAdmin-Authentication
+ */
+class AuthenticationCookie extends AuthenticationPlugin
+{
+    /**
+     * Displays authentication form
+     *
+     * this function MUST exit/quit the application
+     *
+     * @global string the last connection error
+     *
+     * @return void
+     */
+    public function auth()
+    {
+        global $conn_error;
+
+        $response = PMA_Response::getInstance();
+        if ($response->isAjax()) {
+            $response->isSuccess(false);
+
+            $login_link = '<br /><br />[ ' .
+                sprintf(
+                    '<a href="%s" class="ajax login-link">%s</a>', 
+                    $GLOBALS['cfg']['PmaAbsoluteUri'], 
+                    __('Log in')
+                )
+                . ' ]';
+
+            if (! empty($conn_error)) {
+
+                $conn_error .= $login_link;
+
+                $response->addJSON(
+                    'message',
+                    PMA_Message::error(
+                        $conn_error
+                    )
+                );
+            } else {
+                $response->addJSON(
+                    'message',
+                    PMA_Message::error(
+                        __('Your session has expired. Please log in again.') .
+                        $login_link
+                    )
+                );
+            }
+            exit;
+        }
+
+        /* Perform logout to custom URL */
+        if (! empty($_REQUEST['old_usr'])
+            && ! empty($GLOBALS['cfg']['Server']['LogoutURL'])
+        ) {
+            PMA_sendHeaderLocation($GLOBALS['cfg']['Server']['LogoutURL']);
+            exit;
+        }
+
+        // No recall if blowfish secret is not configured as it would produce
+        // garbage
+        if ($GLOBALS['cfg']['LoginCookieRecall']
+            && ! empty($GLOBALS['cfg']['blowfish_secret'])
+        ) {
+            $default_user   = $GLOBALS['PHP_AUTH_USER'];
+            $default_server = $GLOBALS['pma_auth_server'];
+            $autocomplete   = '';
+        } else {
+            $default_user   = '';
+            $default_server = '';
+            // skip the IE autocomplete feature.
+            $autocomplete   = ' autocomplete="off"';
+        }
+
+        $cell_align = ($GLOBALS['text_dir'] == 'ltr') ? 'left' : 'right';
+
+        $response->getFooter()->setMinimal();
+        $header = $response->getHeader();
+        $header->setBodyId('loginform');
+        $header->setTitle('phpMyAdmin');
+        $header->disableMenu();
+        $header->disableWarnings();
+
+        if (file_exists(CUSTOM_HEADER_FILE)) {
+            include CUSTOM_HEADER_FILE;
+        }
+        echo '
+    <div class="container">
+    <a href="';
+        echo PMA_linkURL('http://www.phpmyadmin.net/');
+        echo '" target="_blank" class="logo">';
+        $logo_image = $GLOBALS['pmaThemeImage'] . 'logo_right.png';
+        if (@file_exists($logo_image)) {
+            echo '<img src="' . $logo_image
+                . '" id="imLogo" name="imLogo" alt="phpMyAdmin" border="0" />';
+        } else {
+            echo '<img name="imLogo" id="imLogo" src="'
+                . $GLOBALS['pmaThemeImage'] . 'pma_logo.png' . '" '
+                . 'border="0" width="88" height="31" alt="phpMyAdmin" />';
+        }
+        echo '</a>
+       <h1>';
+        echo sprintf(
+            __('Welcome to %s'),
+            '<bdo dir="ltr" lang="en">phpMyAdmin</bdo>'
+        );
+        echo "</h1>";
+
+        // Show error message
+        if (! empty($conn_error)) {
+            PMA_Message::rawError($conn_error)->display();
+        }
+
+        echo "<noscript>\n";
+        PMA_message::error(
+            __("Javascript must be enabled past this point")
+        )->display();
+        echo "</noscript>\n";
+
+        echo "<div class='hide js-show'>";
+        // Displays the languages form
+        if (empty($GLOBALS['cfg']['Lang'])) {
+            include_once './libraries/display_select_lang.lib.php';
+            // use fieldset, don't show doc link
+            echo PMA_getLanguageSelectorHtml(true, false);
+        }
+        echo '</div>
+    <br />
+    <!-- Login form -->
+    <form method="post" action="index.php" name="login_form"' . $autocomplete .
+            ' class="disableAjax login hide js-show">
+        <fieldset>
+        <legend>';
+        echo __('Log in');
+        echo PMA_Util::showDocu('index');
+        echo '</legend>';
+        if ($GLOBALS['cfg']['AllowArbitraryServer']) {
+            echo '
+            <div class="item">
+                <label for="input_servername" title="';
+            echo __(
+                'You can enter hostname/IP address and port separated by space.'
+            );
+            echo '">';
+            echo __('Server:');
+            echo '</label>
+                <input type="text" name="pma_servername" id="input_servername"';
+            echo ' value="';
+            echo htmlspecialchars($default_server);
+            echo '" size="24" class="textfield" title="';
+            echo __(
+                'You can enter hostname/IP address and port separated by space.'
+            ); echo '" />
+            </div>';
+        }
+            echo '<div class="item">
+                <label for="input_username">' . __('Username:') . '</label>
+                <input type="text" name="pma_username" id="input_username" '
+                . 'value="' . htmlspecialchars($default_user) . '" size="24"'
+                . ' class="textfield"/>
+            </div>
+            <div class="item">
+                <label for="input_password">' . __('Password:') . '</label>
+                <input type="password" name="pma_password" id="input_password"'
+                . ' value="" size="24" class="textfield" />
+            </div>';
+        if (count($GLOBALS['cfg']['Servers']) > 1) {
+            echo '<div class="item">
+                <label for="select_server">' . __('Server Choice') .':</label>
+                <select name="server" id="select_server"';
+            if ($GLOBALS['cfg']['AllowArbitraryServer']) {
+                echo ' onchange="document.forms[\'login_form\'].'
+                    . 'elements[\'pma_servername\'].value = \'\'" ';
+            }
+            echo '>';
+
+            include_once './libraries/select_server.lib.php';
+            echo PMA_selectServer(false, false);
+
+            echo '</select></div>';
+        } else {
+            echo '    <input type="hidden" name="server" value="'
+                . $GLOBALS['server'] . '" />';
+        } // end if (server choice)
+
+        echo '</fieldset>
+        <fieldset class="tblFooters">
+            <input value="' . __('Go') . '" type="submit" id="input_go" />';
+        $_form_params = array();
+        if (! empty($GLOBALS['target'])) {
+            $_form_params['target'] = $GLOBALS['target'];
+        }
+        if (! empty($GLOBALS['db'])) {
+            $_form_params['db'] = $GLOBALS['db'];
+        }
+        if (! empty($GLOBALS['table'])) {
+            $_form_params['table'] = $GLOBALS['table'];
+        }
+        // do not generate a "server" hidden field as we want the "server"
+        // drop-down to have priority
+        echo PMA_generate_common_hidden_inputs($_form_params, '', 0, 'server');
+        echo '</fieldset>
+    </form>';
+
+        // BEGIN Swekey Integration
+        Swekey_login('input_username', 'input_go');
+        // END Swekey Integration
+
+        if ($GLOBALS['error_handler']->hasDisplayErrors()) {
+            echo '<div>';
+            $GLOBALS['error_handler']->dispErrors();
+            echo '</div>';
+        }
+        echo '</div>';
+        if (file_exists(CUSTOM_FOOTER_FILE)) {
+            include CUSTOM_FOOTER_FILE;
+        }
+        exit;
+    }
+
+    /**
+     * Gets advanced authentication settings
+     *
+     * this function DOES NOT check authentication - it just checks/provides
+     * authentication credentials required to connect to the MySQL server
+     * usually with PMA_DBI_connect()
+     *
+     * it returns false if something is missing - which usually leads to
+     * auth() which displays login form
+     *
+     * it returns true if all seems ok which usually leads to auth_set_user()
+     *
+     * it directly switches to authFails() if user inactivity timout is reached
+     *
+     * @todo    AllowArbitraryServer on does not imply that the user wants an
+     *          arbitrary server, or? so we should also check if this is filled
+     *          and not only if allowed
+     *
+     * @return boolean   whether we get authentication settings or not
+     */
+    public function authCheck()
+    {
+        // Initialization
+        /**
+         * @global $GLOBALS['pma_auth_server'] the user provided server to
+         * connect to
+         */
+        $GLOBALS['pma_auth_server'] = '';
+
+        $GLOBALS['PHP_AUTH_USER'] = $GLOBALS['PHP_AUTH_PW'] = '';
+        $GLOBALS['from_cookie'] = false;
+
+        // BEGIN Swekey Integration
+        if (! Swekey_auth_check()) {
+            return false;
+        }
+        // END Swekey Integration
+
+        if (defined('PMA_CLEAR_COOKIES')) {
+            foreach ($GLOBALS['cfg']['Servers'] as $key => $val) {
+                $GLOBALS['PMA_Config']->removeCookie('pmaPass-' . $key);
+                $GLOBALS['PMA_Config']->removeCookie('pmaServer-' . $key);
+                $GLOBALS['PMA_Config']->removeCookie('pmaUser-' . $key);
+            }
+            return false;
+        }
+
+        if (! empty($_REQUEST['old_usr'])) {
+            // The user wants to be logged out
+            // -> delete his choices that were stored in session
+
+            // according to the PHP manual we should do this before the destroy:
+            //$_SESSION = array();
+
+            session_destroy();
+            // -> delete password cookie(s)
+            if ($GLOBALS['cfg']['LoginCookieDeleteAll']) {
+                foreach ($GLOBALS['cfg']['Servers'] as $key => $val) {
+                    $GLOBALS['PMA_Config']->removeCookie('pmaPass-' . $key);
+                    if (isset($_COOKIE['pmaPass-' . $key])) {
+                        unset($_COOKIE['pmaPass-' . $key]);
+                    }
+                }
+            } else {
+                $GLOBALS['PMA_Config']->removeCookie(
+                    'pmaPass-' . $GLOBALS['server']
+                );
+                if (isset($_COOKIE['pmaPass-' . $GLOBALS['server']])) {
+                    unset($_COOKIE['pmaPass-' . $GLOBALS['server']]);
+                }
+            }
+        }
+
+        if (! empty($_REQUEST['pma_username'])) {
+            // The user just logged in
+            $GLOBALS['PHP_AUTH_USER'] = $_REQUEST['pma_username'];
+            $GLOBALS['PHP_AUTH_PW']   = empty($_REQUEST['pma_password'])
+                ? ''
+                : $_REQUEST['pma_password'];
+            if ($GLOBALS['cfg']['AllowArbitraryServer']
+                && isset($_REQUEST['pma_servername'])
+            ) {
+                $GLOBALS['pma_auth_server'] = $_REQUEST['pma_servername'];
+            }
+            return true;
+        }
+
+        // At the end, try to set the $GLOBALS['PHP_AUTH_USER']
+        // and $GLOBALS['PHP_AUTH_PW'] variables from cookies
+
+        // servername
+        if ($GLOBALS['cfg']['AllowArbitraryServer']
+            && ! empty($_COOKIE['pmaServer-' . $GLOBALS['server']])
+        ) {
+            $GLOBALS['pma_auth_server']
+                = $_COOKIE['pmaServer-' . $GLOBALS['server']];
+        }
+
+        // username
+        if (empty($_COOKIE['pmaUser-' . $GLOBALS['server']])) {
+            return false;
+        }
+
+        $GLOBALS['PHP_AUTH_USER'] = $this->blowfishDecrypt(
+            $_COOKIE['pmaUser-' . $GLOBALS['server']],
+            $this->_getBlowfishSecret()
+        );
+
+        // user was never logged in since session start
+        if (empty($_SESSION['last_access_time'])) {
+            return false;
+        }
+
+        // User inactive too long
+        $last_access_time = time() - $GLOBALS['cfg']['LoginCookieValidity'];
+        if ($_SESSION['last_access_time'] < $last_access_time
+        ) {
+            PMA_Util::cacheUnset('is_create_db_priv', true);
+            PMA_Util::cacheUnset('is_process_priv', true);
+            PMA_Util::cacheUnset('is_reload_priv', true);
+            PMA_Util::cacheUnset('db_to_create', true);
+            PMA_Util::cacheUnset('dbs_where_create_table_allowed', true);
+            $GLOBALS['no_activity'] = true;
+            $this->authFails();
+            exit;
+        }
+
+        // password
+        if (empty($_COOKIE['pmaPass-' . $GLOBALS['server']])) {
+            return false;
+        }
+
+        $GLOBALS['PHP_AUTH_PW'] = $this->blowfishDecrypt(
+            $_COOKIE['pmaPass-' . $GLOBALS['server']],
+            $this->_getBlowfishSecret()
+        );
+
+        if ($GLOBALS['PHP_AUTH_PW'] == "\xff(blank)") {
+            $GLOBALS['PHP_AUTH_PW'] = '';
+        }
+
+        $GLOBALS['from_cookie'] = true;
+
+        return true;
+    }
+
+    /**
+     * Set the user and password after last checkings if required
+     *
+     * @return boolean always true
+     */
+    public function authSetUser()
+    {
+        global $cfg;
+
+        // Ensures valid authentication mode, 'only_db', bookmark database and
+        // table names and relation table name are used
+        if ($cfg['Server']['user'] != $GLOBALS['PHP_AUTH_USER']) {
+            foreach ($cfg['Servers'] as $idx => $current) {
+                if ($current['host'] == $cfg['Server']['host']
+                    && $current['port'] == $cfg['Server']['port']
+                    && $current['socket'] == $cfg['Server']['socket']
+                    && $current['ssl'] == $cfg['Server']['ssl']
+                    && $current['connect_type'] == $cfg['Server']['connect_type']
+                    && $current['user'] == $GLOBALS['PHP_AUTH_USER']
+                ) {
+                    $GLOBALS['server'] = $idx;
+                    $cfg['Server']     = $current;
+                    break;
+                }
+            } // end foreach
+        } // end if
+
+        if ($GLOBALS['cfg']['AllowArbitraryServer']
+            && ! empty($GLOBALS['pma_auth_server'])
+        ) {
+            /* Allow to specify 'host port' */
+            $parts = explode(' ', $GLOBALS['pma_auth_server']);
+            if (count($parts) == 2) {
+                $tmp_host = $parts[0];
+                $tmp_port = $parts[1];
+            } else {
+                $tmp_host = $GLOBALS['pma_auth_server'];
+                $tmp_port = '';
+            }
+            if ($cfg['Server']['host'] != $GLOBALS['pma_auth_server']) {
+                $cfg['Server']['host'] = $tmp_host;
+                if (! empty($tmp_port)) {
+                    $cfg['Server']['port'] = $tmp_port;
+                }
+            }
+            unset($tmp_host, $tmp_port, $parts);
+        }
+        $cfg['Server']['user']     = $GLOBALS['PHP_AUTH_USER'];
+        $cfg['Server']['password'] = $GLOBALS['PHP_AUTH_PW'];
+
+        // Avoid showing the password in phpinfo()'s output
+        unset($GLOBALS['PHP_AUTH_PW']);
+        unset($_SERVER['PHP_AUTH_PW']);
+
+        $_SESSION['last_access_time'] = time();
+
+        // Name and password cookies need to be refreshed each time
+        // Duration = one month for username
+        $GLOBALS['PMA_Config']->setCookie(
+            'pmaUser-' . $GLOBALS['server'],
+            $this->blowfishEncrypt(
+                $cfg['Server']['user'],
+                $this->_getBlowfishSecret()
+            )
+        );
+
+        // Duration = as configured
+        $GLOBALS['PMA_Config']->setCookie(
+            'pmaPass-' . $GLOBALS['server'],
+            $this->blowfishEncrypt(
+                ! empty($cfg['Server']['password'])
+                ? $cfg['Server']['password'] : "\xff(blank)",
+                $this->_getBlowfishSecret()
+            ),
+            null,
+            $GLOBALS['cfg']['LoginCookieStore']
+        );
+
+        // Set server cookies if required (once per session) and, in this case,
+        // force reload to ensure the client accepts cookies
+        if (! $GLOBALS['from_cookie']) {
+            if ($GLOBALS['cfg']['AllowArbitraryServer']) {
+                if (! empty($GLOBALS['pma_auth_server'])) {
+                    // Duration = one month for servername
+                    $GLOBALS['PMA_Config']->setCookie(
+                        'pmaServer-' . $GLOBALS['server'],
+                        $cfg['Server']['host']
+                    );
+                } else {
+                    // Delete servername cookie
+                    $GLOBALS['PMA_Config']->removeCookie(
+                        'pmaServer-' . $GLOBALS['server']
+                    );
+                }
+            }
+
+            // URL where to go:
+            $redirect_url = $cfg['PmaAbsoluteUri'] . 'index.php';
+
+            // any parameters to pass?
+            $url_params = array();
+            if (strlen($GLOBALS['db'])) {
+                $url_params['db'] = $GLOBALS['db'];
+            }
+            if (strlen($GLOBALS['table'])) {
+                $url_params['table'] = $GLOBALS['table'];
+            }
+            // any target to pass?
+            if (! empty($GLOBALS['target'])
+                && $GLOBALS['target'] != 'index.php'
+            ) {
+                $url_params['target'] = $GLOBALS['target'];
+            }
+
+            /**
+             * Clear user cache.
+             */
+            PMA_Util::clearUserCache();
+
+            PMA_Response::getInstance()->disable();
+
+            PMA_sendHeaderLocation(
+                $redirect_url . PMA_generate_common_url($url_params, '&'),
+                true
+            );
+            exit;
+        } // end if
+
+        return true;
+
+    }
+
+    /**
+     * User is not allowed to login to MySQL -> authentication failed
+     *
+     * prepares error message and switches to auth() which display the error
+     * and the login form
+     *
+     * this function MUST exit/quit the application,
+     * currently doen by call to auth()
+     *
+     * @return void
+     */
+    public function authFails()
+    {
+        global $conn_error;
+
+        // Deletes password cookie and displays the login form
+        $GLOBALS['PMA_Config']->removeCookie('pmaPass-' . $GLOBALS['server']);
+
+        if (! empty($GLOBALS['login_without_password_is_forbidden'])) {
+            $conn_error = __(
+                'Login without a password is forbidden by configuration'
+                . ' (see AllowNoPassword)'
+            );
+        } elseif (! empty($GLOBALS['allowDeny_forbidden'])) {
+            $conn_error = __('Access denied');
+        } elseif (! empty($GLOBALS['no_activity'])) {
+            $conn_error = sprintf(
+                __('No activity within %s seconds; please log in again'),
+                $GLOBALS['cfg']['LoginCookieValidity']
+            );
+        } elseif (PMA_DBI_getError()) {
+            $conn_error = '#' . $GLOBALS['errno'] . ' '
+                . __('Cannot log in to the MySQL server');
+        } else {
+            $conn_error = __('Cannot log in to the MySQL server');
+        }
+
+        // needed for PHP-CGI (not need for FastCGI or mod-php)
+        header('Cache-Control: no-store, no-cache, must-revalidate');
+        header('Pragma: no-cache');
+
+        $this->auth();
+    }
+
+    /**
+     * Returns blowfish secret or generates one if needed.
+     *
+     * @return string
+     */
+    private function _getBlowfishSecret()
+    {
+        if (empty($GLOBALS['cfg']['blowfish_secret'])) {
+            if (empty($_SESSION['auto_blowfish_secret'])) {
+                // this returns 23 characters
+                $_SESSION['auto_blowfish_secret'] = uniqid('', true);
+            }
+            return $_SESSION['auto_blowfish_secret'];
+        } else {
+            // apply md5() to work around too long secrets (returns 32 characters)
+            return md5($GLOBALS['cfg']['blowfish_secret']);
+        }
+    }
+
+    /**
+     * Encryption using blowfish algorithm (mcrypt)
+     * or phpseclib's AES if mcrypt not available
+     *
+     * @param string $data   original data
+     * @param string $secret the secret
+     *
+     * @return string the encrypted result
+     */
+    public function blowfishEncrypt($data, $secret)
+    {
+        global $iv;
+        if (! function_exists('mcrypt_encrypt')) {
+            /**
+             * This library uses mcrypt when available, so
+             * we could always call it instead of having an
+             * if/then/else logic, however the include_once
+             * call is costly
+             */
+            include_once "./libraries/phpseclib/Crypt/AES.php";
+            $cipher = new Crypt_AES(CRYPT_AES_MODE_ECB);
+            $cipher->setKey($secret);
+            return base64_encode($cipher->encrypt($data));
+        } else {
+            return base64_encode(
+                mcrypt_encrypt(
+                    MCRYPT_BLOWFISH,
+                    $secret,
+                    $data,
+                    MCRYPT_MODE_CBC,
+                    $iv
+                )
+            );
+        }
+    }
+
+    /**
+     * Decryption using blowfish algorithm (mcrypt)
+     * or phpseclib's AES if mcrypt not available
+     *
+     * @param string $encdata encrypted data
+     * @param string $secret  the secret
+     *
+     * @return string original data
+     */
+    public function blowfishDecrypt($encdata, $secret)
+    {
+        global $iv;
+        if (! function_exists('mcrypt_encrypt')) {
+            include_once "./libraries/phpseclib/Crypt/AES.php";
+            $cipher = new Crypt_AES(CRYPT_AES_MODE_ECB);
+            $cipher->setKey($secret);
+            return $cipher->decrypt(base64_decode($encdata));
+        } else {
+            $data = base64_decode($encdata);
+            $decrypted = mcrypt_decrypt(
+                MCRYPT_BLOWFISH,
+                $secret,
+                $data,
+                MCRYPT_MODE_CBC,
+                $iv
+            );
+            return trim($decrypted);
+        }
+    }
+
+    /**
+     * This method is called when any PluginManager to which the observer
+     * is attached calls PluginManager::notify()
+     *
+     * @param SplSubject $subject The PluginManager notifying the observer
+     *                            of an update.
+     *
+     * @return void
+     */
+    public function update (SplSubject $subject)
+    {
+    }
+}
diff --git a/phpmyadmin/libraries/plugins/auth/AuthenticationHttp.class.php b/phpmyadmin/libraries/plugins/auth/AuthenticationHttp.class.php
new file mode 100644
index 0000000..f81ab92
--- /dev/null
+++ b/phpmyadmin/libraries/plugins/auth/AuthenticationHttp.class.php
@@ -0,0 +1,249 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * HTTP Authentication plugin for phpMyAdmin.
+ * NOTE: Requires PHP loaded as a Apache module.
+ *
+ * @package    PhpMyAdmin-Authentication
+ * @subpackage HTTP
+ */
+if (! defined('PHPMYADMIN')) {
+    exit;
+}
+
+/* Get the authentication interface */
+require_once 'libraries/plugins/AuthenticationPlugin.class.php';
+
+/**
+ * Handles the HTTP authentication methods
+ *
+ * @package PhpMyAdmin-Authentication
+ */
+class AuthenticationHttp extends AuthenticationPlugin
+{
+    /**
+     * Displays authentication form
+     *
+     * @global  string    the font face to use in case of failure
+     * @global  string    the default font size to use in case of failure
+     * @global  string    the big font size to use in case of failure
+     *
+     * @return boolean   always true (no return indeed)
+     */
+    public function auth()
+    {
+        /* Perform logout to custom URL */
+        if (! empty($_REQUEST['old_usr'])
+            && ! empty($GLOBALS['cfg']['Server']['LogoutURL'])
+        ) {
+            PMA_sendHeaderLocation($GLOBALS['cfg']['Server']['LogoutURL']);
+            exit;
+        }
+
+        if (empty($GLOBALS['cfg']['Server']['auth_http_realm'])) {
+            if (empty($GLOBALS['cfg']['Server']['verbose'])) {
+                $server_message = $GLOBALS['cfg']['Server']['host'];
+            } else {
+                $server_message = $GLOBALS['cfg']['Server']['verbose'];
+            }
+            $realm_message = 'phpMyAdmin ' . $server_message;
+        } else {
+            $realm_message = $GLOBALS['cfg']['Server']['auth_http_realm'];
+        }
+        // remove non US-ASCII to respect RFC2616
+        $realm_message = preg_replace('/[^\x20-\x7e]/i', '', $realm_message);
+        header('WWW-Authenticate: Basic realm="' . $realm_message .  '"');
+        header('HTTP/1.0 401 Unauthorized');
+        if (php_sapi_name() !== 'cgi-fcgi') {
+            header('status: 401 Unauthorized');
+        }
+
+        /* HTML header */
+        $response = PMA_Response::getInstance();
+        $response->getFooter()->setMinimal();
+        $header = $response->getHeader();
+        $header->setTitle(__('Access denied'));
+        $header->disableMenu();
+        $header->setBodyId('loginform');
+
+        $response->addHTML('<h1>');
+        $response->addHTML(sprintf(__('Welcome to %s'), ' phpMyAdmin'));
+        $response->addHTML('</h1>');
+        $response->addHTML('<h3>');
+        $response->addHTML(
+            PMA_Message::error(
+                __('Wrong username/password. Access denied.')
+            )
+        );
+        $response->addHTML('</h3>');
+
+        if (file_exists(CUSTOM_FOOTER_FILE)) {
+            include CUSTOM_FOOTER_FILE;
+        }
+
+        exit;
+    }
+
+    /**
+     * Gets advanced authentication settings
+     *
+     * @global  string    the username if register_globals is on
+     * @global  string    the password if register_globals is on
+     * @global  array     the array of server variables if register_globals is
+     *                    off
+     * @global  array     the array of environment variables if register_globals
+     *                    is off
+     * @global  string    the username for the ? server
+     * @global  string    the password for the ? server
+     * @global  string    the username for the WebSite Professional server
+     * @global  string    the password for the WebSite Professional server
+     * @global  string    the username of the user who logs out
+     *
+     * @return boolean   whether we get authentication settings or not
+     */
+    public function authCheck()
+    {
+        global $PHP_AUTH_USER, $PHP_AUTH_PW;
+
+        // Grabs the $PHP_AUTH_USER variable whatever are the values of the
+        // 'register_globals' and the 'variables_order' directives
+        if (empty($PHP_AUTH_USER)) {
+            if (PMA_getenv('PHP_AUTH_USER')) {
+                $PHP_AUTH_USER = PMA_getenv('PHP_AUTH_USER');
+            } elseif (PMA_getenv('REMOTE_USER')) {
+                // CGI, might be encoded, see below
+                $PHP_AUTH_USER = PMA_getenv('REMOTE_USER');
+            } elseif (PMA_getenv('REDIRECT_REMOTE_USER')) {
+                // CGI, might be encoded, see below
+                $PHP_AUTH_USER = PMA_getenv('REDIRECT_REMOTE_USER');
+            } elseif (PMA_getenv('AUTH_USER')) {
+                // WebSite Professional
+                $PHP_AUTH_USER = PMA_getenv('AUTH_USER');
+            } elseif (PMA_getenv('HTTP_AUTHORIZATION')
+                && false === strpos(PMA_getenv('HTTP_AUTHORIZATION'), '<')
+            ) {
+                // IIS, might be encoded, see below; also prevent XSS
+                $PHP_AUTH_USER = PMA_getenv('HTTP_AUTHORIZATION');
+            } elseif (PMA_getenv('Authorization')) {
+                // FastCGI, might be encoded, see below
+                $PHP_AUTH_USER = PMA_getenv('Authorization');
+            }
+        }
+        // Grabs the $PHP_AUTH_PW variable whatever are the values of the
+        // 'register_globals' and the 'variables_order' directives
+        if (empty($PHP_AUTH_PW)) {
+            if (PMA_getenv('PHP_AUTH_PW')) {
+                $PHP_AUTH_PW = PMA_getenv('PHP_AUTH_PW');
+            } elseif (PMA_getenv('REMOTE_PASSWORD')) {
+                // Apache/CGI
+                $PHP_AUTH_PW = PMA_getenv('REMOTE_PASSWORD');
+            } elseif (PMA_getenv('AUTH_PASSWORD')) {
+                // WebSite Professional
+                $PHP_AUTH_PW = PMA_getenv('AUTH_PASSWORD');
+            }
+        }
+
+        // Decode possibly encoded information (used by IIS/CGI/FastCGI)
+        // (do not use explode() because a user might have a colon in his password
+        if (strcmp(substr($PHP_AUTH_USER, 0, 6), 'Basic ') == 0) {
+            $usr_pass = base64_decode(substr($PHP_AUTH_USER, 6));
+            if (! empty($usr_pass)) {
+                $colon = strpos($usr_pass, ':');
+                if ($colon) {
+                    $PHP_AUTH_USER = substr($usr_pass, 0, $colon);
+                    $PHP_AUTH_PW = substr($usr_pass, $colon + 1);
+                }
+                unset($colon);
+            }
+            unset($usr_pass);
+        }
+
+        // User logged out -> ensure the new username is not the same
+        $old_usr = isset($_REQUEST['old_usr']) ? $_REQUEST['old_usr'] : '';
+        if (! empty($old_usr)
+            && (isset($PHP_AUTH_USER) && $old_usr == $PHP_AUTH_USER)
+        ) {
+            $PHP_AUTH_USER = '';
+            // -> delete user's choices that were stored in session
+            session_destroy();
+        }
+
+        // Returns whether we get authentication settings or not
+        if (empty($PHP_AUTH_USER)) {
+            return false;
+        } else {
+            return true;
+        }
+    }
+
+    /**
+     * Set the user and password after last checkings if required
+     *
+     * @global  array     the valid servers settings
+     * @global  integer   the id of the current server
+     * @global  array     the current server settings
+     * @global  string    the current username
+     * @global  string    the current password
+     *
+     * @return boolean   always true
+     */
+    public function authSetUser()
+    {
+        global $cfg, $server;
+        global $PHP_AUTH_USER, $PHP_AUTH_PW;
+
+        // Ensures valid authentication mode, 'only_db', bookmark database and
+        // table names and relation table name are used
+        if ($cfg['Server']['user'] != $PHP_AUTH_USER) {
+            $servers_cnt = count($cfg['Servers']);
+            for ($i = 1; $i <= $servers_cnt; $i++) {
+                if (isset($cfg['Servers'][$i])
+                    && ($cfg['Servers'][$i]['host'] == $cfg['Server']['host']
+                    && $cfg['Servers'][$i]['user'] == $PHP_AUTH_USER)
+                ) {
+                    $server        = $i;
+                    $cfg['Server'] = $cfg['Servers'][$i];
+                    break;
+                }
+            } // end for
+        } // end if
+
+        $cfg['Server']['user']     = $PHP_AUTH_USER;
+        $cfg['Server']['password'] = $PHP_AUTH_PW;
+
+        // Avoid showing the password in phpinfo()'s output
+        unset($GLOBALS['PHP_AUTH_PW']);
+        unset($_SERVER['PHP_AUTH_PW']);
+
+        return true;
+    }
+
+    /**
+     * User is not allowed to login to MySQL -> authentication failed
+     *
+     * @return boolean   always true (no return indeed)
+     */
+    public function authFails()
+    {
+        $error = PMA_DBI_getError();
+        if ($error && $GLOBALS['errno'] != 1045) {
+            PMA_fatalError($error);
+        } else {
+            $this->auth();
+            return true;
+        }
+    }
+
+    /**
+     * This method is called when any PluginManager to which the observer
+     * is attached calls PluginManager::notify()
+     *
+     * @param SplSubject $subject The PluginManager notifying the observer
+     *                            of an update.
+     *
+     * @return void
+     */
+    public function update (SplSubject $subject)
+    {
+    }
+}
diff --git a/phpmyadmin/libraries/plugins/auth/AuthenticationSignon.class.php b/phpmyadmin/libraries/plugins/auth/AuthenticationSignon.class.php
new file mode 100644
index 0000000..ee1cf36
--- /dev/null
+++ b/phpmyadmin/libraries/plugins/auth/AuthenticationSignon.class.php
@@ -0,0 +1,284 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * SignOn Authentication plugin for phpMyAdmin
+ *
+ * @package    PhpMyAdmin-Authentication
+ * @subpackage SignOn
+ */
+if (! defined('PHPMYADMIN')) {
+    exit;
+}
+
+/* Get the authentication interface */
+require_once 'libraries/plugins/AuthenticationPlugin.class.php';
+
+/**
+ * Handles the SignOn authentication method
+ *
+ * @package PhpMyAdmin-Authentication
+ */
+class AuthenticationSignon extends AuthenticationPlugin
+{
+    /**
+     * Displays authentication form
+     *
+     * @global  string    the font face to use in case of failure
+     * @global  string    the default font size to use in case of failure
+     * @global  string    the big font size to use in case of failure
+     *
+     * @return boolean   always true (no return indeed)
+     */
+    public function auth()
+    {
+        unset($_SESSION['LAST_SIGNON_URL']);
+        if (empty($GLOBALS['cfg']['Server']['SignonURL'])) {
+            PMA_fatalError('You must set SignonURL!');
+        } elseif (! empty($_REQUEST['old_usr'])
+            && ! empty($GLOBALS['cfg']['Server']['LogoutURL'])
+        ) {
+            /* Perform logout to custom URL */
+            PMA_sendHeaderLocation($GLOBALS['cfg']['Server']['LogoutURL']);
+        } else {
+            PMA_sendHeaderLocation($GLOBALS['cfg']['Server']['SignonURL']);
+        }
+        exit();
+    }
+
+     /**
+     * Gets advanced authentication settings
+     *
+     * @global  string    the username if register_globals is on
+     * @global  string    the password if register_globals is on
+     * @global  array     the array of server variables if register_globals is
+     *                    off
+     * @global  array     the array of environment variables if register_globals
+     *                    is off
+     * @global  string    the username for the ? server
+     * @global  string    the password for the ? server
+     * @global  string    the username for the WebSite Professional server
+     * @global  string    the password for the WebSite Professional server
+     * @global  string    the username of the user who logs out
+     *
+     * @return boolean   whether we get authentication settings or not
+     */
+    public function authCheck()
+    {
+        global $PHP_AUTH_USER, $PHP_AUTH_PW;
+
+        /* Check if we're using same sigon server */
+        $signon_url = $GLOBALS['cfg']['Server']['SignonURL'];
+        if (isset($_SESSION['LAST_SIGNON_URL'])
+            && $_SESSION['LAST_SIGNON_URL'] != $signon_url
+        ) {
+            return false;
+        }
+
+        /* Script name */
+        $script_name = $GLOBALS['cfg']['Server']['SignonScript'];
+
+        /* Session name */
+        $session_name = $GLOBALS['cfg']['Server']['SignonSession'];
+
+        /* Login URL */
+        $signon_url = $GLOBALS['cfg']['Server']['SignonURL'];
+
+        /* Current host */
+        $single_signon_host = $GLOBALS['cfg']['Server']['host'];
+
+        /* Current port */
+        $single_signon_port = $GLOBALS['cfg']['Server']['port'];
+
+        /* No configuration updates */
+        $single_signon_cfgupdate = array();
+
+        /* Are we requested to do logout? */
+        $do_logout = !empty($_REQUEST['old_usr']);
+
+        /* Handle script based auth */
+        if (!empty($script_name)) {
+            if (! file_exists($script_name)) {
+                PMA_fatalError(
+                    __('Can not find signon authentication script:')
+                    . ' '. $script_name
+                );
+            }
+            include $script_name;
+
+            list ($PHP_AUTH_USER, $PHP_AUTH_PW)
+                = get_login_credentials($cfg['Server']['user']);
+
+        } elseif (isset($_COOKIE[$session_name])) { /* Does session exist? */
+            /* End current session */
+            $old_session = session_name();
+            $old_id = session_id();
+            session_write_close();
+
+            /* Load single signon session */
+            session_name($session_name);
+            session_id($_COOKIE[$session_name]);
+            session_start();
+
+            /* Clear error message */
+            unset($_SESSION['PMA_single_signon_error_message']);
+
+            /* Grab credentials if they exist */
+            if (isset($_SESSION['PMA_single_signon_user'])) {
+                if ($do_logout) {
+                    $PHP_AUTH_USER = '';
+                } else {
+                    $PHP_AUTH_USER = $_SESSION['PMA_single_signon_user'];
+                }
+            }
+            if (isset($_SESSION['PMA_single_signon_password'])) {
+                if ($do_logout) {
+                    $PHP_AUTH_PW = '';
+                } else {
+                    $PHP_AUTH_PW = $_SESSION['PMA_single_signon_password'];
+                }
+            }
+            if (isset($_SESSION['PMA_single_signon_host'])) {
+                $single_signon_host = $_SESSION['PMA_single_signon_host'];
+            }
+
+            if (isset($_SESSION['PMA_single_signon_port'])) {
+                $single_signon_port = $_SESSION['PMA_single_signon_port'];
+            }
+
+            if (isset($_SESSION['PMA_single_signon_cfgupdate'])) {
+                $single_signon_cfgupdate = $_SESSION['PMA_single_signon_cfgupdate'];
+            }
+
+
+            /* Also get token as it is needed to access subpages */
+            if (isset($_SESSION['PMA_single_signon_token'])) {
+                /* No need to care about token on logout */
+                $pma_token = $_SESSION['PMA_single_signon_token'];
+            }
+
+            /* End single signon session */
+            session_write_close();
+
+            /* Restart phpMyAdmin session */
+            session_name($old_session);
+            if (!empty($old_id)) {
+                session_id($old_id);
+            }
+            session_start();
+
+            /* Set the single signon host */
+            $GLOBALS['cfg']['Server']['host'] = $single_signon_host;
+
+            /* Set the single signon port */
+            $GLOBALS['cfg']['Server']['port'] = $single_signon_port;
+
+            /* Configuration update */
+            $GLOBALS['cfg']['Server'] = array_merge(
+                $GLOBALS['cfg']['Server'],
+                $single_signon_cfgupdate
+            );
+
+            /* Restore our token */
+            if (!empty($pma_token)) {
+                $_SESSION[' PMA_token '] = $pma_token;
+            }
+
+            /**
+             * Clear user cache.
+             */
+            PMA_Util::clearUserCache();
+        }
+
+        // Returns whether we get authentication settings or not
+        if (empty($PHP_AUTH_USER)) {
+            unset($_SESSION['LAST_SIGNON_URL']);
+            return false;
+        } else {
+            $_SESSION['LAST_SIGNON_URL'] = $GLOBALS['cfg']['Server']['SignonURL'];
+            return true;
+        }
+    }
+
+    /**
+     * Set the user and password after last checkings if required
+     *
+     * @global  array     the valid servers settings
+     * @global  integer   the id of the current server
+     * @global  array     the current server settings
+     * @global  string    the current username
+     * @global  string    the current password
+     *
+     * @return boolean   always true
+     */
+    public function authSetUser()
+    {
+        global $cfg;
+        global $PHP_AUTH_USER, $PHP_AUTH_PW;
+
+        $cfg['Server']['user']     = $PHP_AUTH_USER;
+        $cfg['Server']['password'] = $PHP_AUTH_PW;
+
+        return true;
+    }
+
+    /**
+     * User is not allowed to login to MySQL -> authentication failed
+     *
+     * @return boolean   always true (no return indeed)
+     */
+    public function authFails()
+    {
+        /* Session name */
+        $session_name = $GLOBALS['cfg']['Server']['SignonSession'];
+
+        /* Does session exist? */
+        if (isset($_COOKIE[$session_name])) {
+            /* End current session */
+            $old_session = session_name();
+            $old_id = session_id();
+            session_write_close();
+
+            /* Load single signon session */
+            session_name($session_name);
+            session_id($_COOKIE[$session_name]);
+            session_start();
+
+            /* Set error message */
+            if (! empty($GLOBALS['login_without_password_is_forbidden'])) {
+                $_SESSION['PMA_single_signon_error_message'] = __(
+                    'Login without a password is forbidden by configuration '
+                    . '(see AllowNoPassword)'
+                );
+            } elseif (! empty($GLOBALS['allowDeny_forbidden'])) {
+                $_SESSION['PMA_single_signon_error_message'] = __('Access denied');
+            } elseif (! empty($GLOBALS['no_activity'])) {
+                $_SESSION['PMA_single_signon_error_message'] = sprintf(
+                    __('No activity within %s seconds; please log in again'),
+                    $GLOBALS['cfg']['LoginCookieValidity']
+                );
+            } elseif (PMA_DBI_getError()) {
+                $_SESSION['PMA_single_signon_error_message'] = PMA_sanitize(
+                    PMA_DBI_getError()
+                );
+            } else {
+                $_SESSION['PMA_single_signon_error_message'] = __(
+                    'Cannot log in to the MySQL server'
+                );
+            }
+        }
+        $this->auth();
+    }
+
+    /**
+     * This method is called when any PluginManager to which the observer
+     * is attached calls PluginManager::notify()
+     *
+     * @param SplSubject $subject The PluginManager notifying the observer
+     *                            of an update.
+     *
+     * @return void
+     */
+    public function update (SplSubject $subject)
+    {
+    }
+}
\ No newline at end of file
diff --git a/phpmyadmin/libraries/plugins/auth/swekey/authentication.inc.php b/phpmyadmin/libraries/plugins/auth/swekey/authentication.inc.php
new file mode 100644
index 0000000..1977f88
--- /dev/null
+++ b/phpmyadmin/libraries/plugins/auth/swekey/authentication.inc.php
@@ -0,0 +1,172 @@
+<?php
+/**
+ * @package Swekey
+ */
+?>
+
+<script>
+
+	var g_SwekeyPlugin = null;
+
+	// -------------------------------------------------------------------
+	// Create the swekey plugin if it does not exists
+	function Swekey_Plugin()
+	{
+		try
+		{
+			if (g_SwekeyPlugin != null)
+				return g_SwekeyPlugin;
+
+			if (window.ActiveXObject)
+			{
+    			g_SwekeyPlugin = document.getElementById("swekey_activex");
+    			if (g_SwekeyPlugin == null)
+    			{
+                    // we must create the activex that way instead of new ActiveXObject("FbAuthAx.FbAuthCtl");
+                    // ortherwise SetClientSite is not called and we can not get the url
+  			  		var div = document.createElement('div');
+	   				div.innerHTML='<object id="swekey_activex" style="display:none" CLASSID="CLSID:8E02E3F9-57AA-4EE1-AA68-A42DD7B0FADE"></object>';
+
+    				// Never append to the body because it may still loading and it breaks IE
+	   				document.body.insertBefore(div, document.body.firstChild);
+    				g_SwekeyPlugin = document.getElementById("swekey_activex");
+                }
+				return g_SwekeyPlugin;
+			}
+
+			g_SwekeyPlugin = document.getElementById("swekey_plugin");
+			if (g_SwekeyPlugin != null)
+				return g_SwekeyPlugin;
+
+			for (i = 0; i < navigator.plugins.length; i ++)
+			{
+				try
+				{
+				    if (navigator.plugins[i] == null)
+				    {
+				        navigator.plugins.refresh();
+                    }
+                    else if (navigator.plugins[i][0] != null && navigator.plugins[i][0].type == "application/fbauth-plugin")
+					{
+						var x = document.createElement('embed');
+						x.setAttribute('type', 'application/fbauth-plugin');
+						x.setAttribute('id', 'swekey_plugin');
+						x.setAttribute('width', '0');
+						x.setAttribute('height', '0');
+						x.style.dislay='none';
+
+						//document.body.appendChild(x);
+						document.body.insertBefore(x, document.body.firstChild);
+						g_SwekeyPlugin = document.getElementById("swekey_plugin");
+						return g_SwekeyPlugin;
+					}
+				}
+				catch (e)
+				{
+				    navigator.plugins.refresh();
+					//alert ('Failed to create plugin: ' + e);
+				}
+			}
+		}
+		catch (e)
+		{
+			//alert("Swekey_Plugin " + e);
+			g_SwekeyPlugin = null;
+		}
+		return null;
+	}
+
+	// -------------------------------------------------------------------
+	// Returns true if the swekey plugin is installed
+	function Swekey_Installed()
+	{
+		return (Swekey_Plugin() != null);
+	}
+
+	// -------------------------------------------------------------------
+	// List the id of the Swekey connected to the PC
+	// Returns a string containing comma separated Swekey Ids
+    // A Swekey is a 32 char hexadecimal value.
+	function Swekey_ListKeyIds()
+	{
+		try
+		{
+			return Swekey_Plugin().list();
+		}
+		catch (e)
+		{
+//			alert("Swekey_ListKeyIds " + e);
+		}
+		return "";
+	}
+
+	// -------------------------------------------------------------------
+	// Ask the Connected Swekey to generate an OTP
+	// id: The id of the connected Swekey (returne by Swekey_ListKeyIds())
+	// rt: A random token
+	// return: The calculated OTP encoded in a 64 chars hexadecimal value.
+	function Swekey_GetOtp(id, rt)
+	{
+		try
+		{
+			return Swekey_Plugin().getotp(id, rt);
+		}
+		catch (e)
+		{
+//			alert("Swekey_GetOtp " + e);
+		}
+		return "";
+	}
+
+	// -------------------------------------------------------------------
+	// Ask the Connected Swekey to generate a OTP linked to the current https host
+	// id: The id of the connected Swekey (returne by Swekey_ListKeyIds())
+	// rt: A random token
+	// return: The calculated OTP encoded in a 64 chars hexadecimal value.
+	// or "" if the current url does not start with https
+	function Swekey_GetLinkedOtp(id, rt)
+	{
+		try
+		{
+			return Swekey_Plugin().getlinkedotp(id, rt);
+		}
+		catch (e)
+		{
+//			alert("Swekey_GetSOtp " + e);
+		}
+		return "";
+	}
+
+	// -------------------------------------------------------------------
+    // Calls Swekey_GetOtp or Swekey_GetLinkedOtp depending if we are in
+    // an https page or not.
+	// id: The id of the connected Swekey (returne by Swekey_ListKeyIds())
+	// rt: A random token
+	// return: The calculated OTP encoded in a 64 chars hexadecimal value.
+	function Swekey_GetSmartOtp(id, rt)
+	{
+        var res = Swekey_GetLinkedOtp(id, rt);
+        if (res == "")
+            res = Swekey_GetOtp(id, rt);
+
+		return res;
+	}
+
+	// -------------------------------------------------------------------
+	// Set a unplug handler (url) to the specified connected feebee
+	// id: The id of the connected Swekey (returne by Swekey_ListKeyIds())
+	// key: The key that index that url, (aplhanumeric values only)
+	// url: The url that will be launched ("" deletes the url)
+	function Swekey_SetUnplugUrl(id, key, url)
+	{
+		try
+		{
+			return Swekey_Plugin().setunplugurl(id, key, url);
+		}
+		catch (e)
+		{
+//			alert("Swekey_SetUnplugUrl " + e);
+		}
+	}
+
+</script>
diff --git a/phpmyadmin/libraries/plugins/auth/swekey/musbe-ca.crt b/phpmyadmin/libraries/plugins/auth/swekey/musbe-ca.crt
new file mode 100644
index 0000000..2a31ad1
--- /dev/null
+++ b/phpmyadmin/libraries/plugins/auth/swekey/musbe-ca.crt
@@ -0,0 +1,25 @@
+-----BEGIN CERTIFICATE-----
+MIIEKjCCAxKgAwIBAgIJAMjw7QcLWCd6MA0GCSqGSIb3DQEBBQUAMGsxCzAJBgNV
+BAYTAlVTMRMwEQYDVQQIEwpDYWxpZm9ybmlhMRQwEgYDVQQKEwtNdXNiZSwgSW5j
+LjESMBAGA1UEAxMJbXVzYmUuY29tMR0wGwYJKoZIhvcNAQkBFg5pbmZvQG11c2Jl
+LmNvbTAeFw0wODA5MDQxNDE2MTNaFw0zNzEyMjExNDE2MTNaMGsxCzAJBgNVBAYT
+AlVTMRMwEQYDVQQIEwpDYWxpZm9ybmlhMRQwEgYDVQQKEwtNdXNiZSwgSW5jLjES
+MBAGA1UEAxMJbXVzYmUuY29tMR0wGwYJKoZIhvcNAQkBFg5pbmZvQG11c2JlLmNv
+bTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAOBhOljxVzQfK4gted2I
+d3BemcjW4abAUOzn3KYWXpPO5xIfVeXNDGkDbyH+X+7fo94sX25/ewuKNFDSOcvo
+tXHq7uQenTHB35r+a+LY81KceUHgW90a3XsqPAkwAjyYcgo3zmM2DtLvw+5Yod8T
+wAHk9m3qavnQ1uk99jBTwL7RZ9jIZHh9pFCL93uJc2obtd8O96Iycbn2q0w/AWbb
++eUVWIHzvLtfPvROeL3lJzr/Uz5LjKapxJ3qyqASflfHpnj9pU8l6g2TQ6Hg5KT5
+tLFkRe7uGhOfRtOQ/+NjaWrEuNCFnpyN4Q5Fv+5qA1Ip1IpH0200sWbAf/k2u0Qp
+Sx0CAwEAAaOB0DCBzTAdBgNVHQ4EFgQUczJrQ7hCvtsnzcqiDIZ/GSn/CiwwgZ0G
+A1UdIwSBlTCBkoAUczJrQ7hCvtsnzcqiDIZ/GSn/Ciyhb6RtMGsxCzAJBgNVBAYT
+AlVTMRMwEQYDVQQIEwpDYWxpZm9ybmlhMRQwEgYDVQQKEwtNdXNiZSwgSW5jLjES
+MBAGA1UEAxMJbXVzYmUuY29tMR0wGwYJKoZIhvcNAQkBFg5pbmZvQG11c2JlLmNv
+bYIJAMjw7QcLWCd6MAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEFBQADggEBAGxk
+8xzIljeBDQWWVRr0NEALVSv3i09V4jAKkyEOfmZ8lKMKJi0atwbtjrXTzLnNYj+Q
+pyUbyY/8ItWvV7pnVxMiF9qcer7e9X4vw358GZuMVE/da1nWxz+CwzTm5oO30RzA
+antM9bISFFr9lJq69bDWOnCUi1IG8DSL3TxtlABso7S4vqiZ+sB33l6k1K4a/Njb
+QkU9UejKhKkVVZTsOrumfnOJ4MCmPfX8Y/AY2o670y5HnzpxerIYziCVzApPVrW7
+sKH0tuVGturMfQOKgstYe4/m9glBTeTLMkjD+6MJC2ONBD7GAiOO95gNl5M1fzJQ
+FEe5CJ7DCYl0GdmLXXw=
+-----END CERTIFICATE-----
diff --git a/phpmyadmin/libraries/plugins/auth/swekey/swekey.auth.lib.php b/phpmyadmin/libraries/plugins/auth/swekey/swekey.auth.lib.php
new file mode 100644
index 0000000..2231de4
--- /dev/null
+++ b/phpmyadmin/libraries/plugins/auth/swekey/swekey.auth.lib.php
@@ -0,0 +1,293 @@
+<?php
+/**
+ * @package Swekey
+ */
+
+/**
+ * Checks Swekey authentication.
+ */
+function Swekey_auth_check()
+{
+    global $cfg;
+    $confFile = $cfg['Server']['auth_swekey_config'];
+
+    if (! isset($_SESSION['SWEKEY'])) {
+        $_SESSION['SWEKEY'] = array();
+    }
+
+    $_SESSION['SWEKEY']['ENABLED'] = (! empty($confFile) && file_exists($confFile));
+
+    // Load the swekey.conf file the first time
+    if ($_SESSION['SWEKEY']['ENABLED']
+        && empty($_SESSION['SWEKEY']['CONF_LOADED'])
+    ) {
+        $_SESSION['SWEKEY']['CONF_LOADED'] = true;
+        $_SESSION['SWEKEY']['VALID_SWEKEYS'] = array();
+        $valid_swekeys = explode("\n", @file_get_contents($confFile));
+        foreach ($valid_swekeys as $line) {
+            if (preg_match("/^[0-9A-F]{32}:.+$/", $line) != false) {
+                $items = explode(":", $line);
+                if (count($items) == 2) {
+                    $_SESSION['SWEKEY']['VALID_SWEKEYS'][$items[0]] = trim($items[1]);
+                }
+            } elseif (preg_match("/^[A-Z_]+=.*$/", $line) != false) {
+                $items = explode("=", $line);
+                $_SESSION['SWEKEY']['CONF_'.trim($items[0])] = trim($items[1]);
+            }
+        }
+
+        // Set default values for settings
+        if (! isset($_SESSION['SWEKEY']['CONF_SERVER_CHECK'])) {
+            $_SESSION['SWEKEY']['CONF_SERVER_CHECK'] = "";
+        }
+        if (! isset($_SESSION['SWEKEY']['CONF_SERVER_RNDTOKEN'])) {
+            $_SESSION['SWEKEY']['CONF_SERVER_RNDTOKEN'] = "";
+        }
+        if (! isset($_SESSION['SWEKEY']['CONF_SERVER_STATUS'])) {
+             $_SESSION['SWEKEY']['CONF_SERVER_STATUS'] = "";
+        }
+        if (! isset($_SESSION['SWEKEY']['CONF_CA_FILE'])) {
+            $_SESSION['SWEKEY']['CONF_CA_FILE'] = "";
+        }
+        if (! isset($_SESSION['SWEKEY']['CONF_ENABLE_TOKEN_CACHE'])) {
+            $_SESSION['SWEKEY']['CONF_ENABLE_TOKEN_CACHE'] = true;
+        }
+        if (! isset($_SESSION['SWEKEY']['CONF_DEBUG'])) {
+               $_SESSION['SWEKEY']['CONF_DEBUG'] = false;
+        }
+    }
+
+    // check if a web key has been authenticated
+    if ($_SESSION['SWEKEY']['ENABLED']) {
+        if (empty($_SESSION['SWEKEY']['AUTHENTICATED_SWEKEY'])) {
+            return false;
+        }
+    }
+
+    return true;
+}
+
+
+/**
+ * Handle Swekey authentication error.
+ */
+function Swekey_auth_error()
+{
+    if (! isset($_SESSION['SWEKEY'])) {
+        return null;
+    }
+
+    if (! $_SESSION['SWEKEY']['ENABLED']) {
+        return null;
+    }
+
+    include_once './libraries/plugins/auth/swekey/authentication.inc.php';
+
+    ?>
+    <script>
+    function Swekey_GetValidKey()
+    {
+        var valids = "<?php
+            foreach ($_SESSION['SWEKEY']['VALID_SWEKEYS'] as $key => $value) {
+                echo $key.',';
+            }
+        ?>";
+        var connected_keys = Swekey_ListKeyIds().split(",");
+        for (i in connected_keys) {
+            if (connected_keys[i] != null && connected_keys[i].length == 32) {
+                if (valids.indexOf(connected_keys[i]) >= 0) {
+                   return connected_keys[i];
+                }
+            }
+        }
+
+
+        if (connected_keys.length > 0) {
+            if (connected_keys[0].length == 32) {
+                return "unknown_key_" + connected_keys[0];
+            }
+        }
+
+        return "none";
+    }
+
+    var key = Swekey_GetValidKey();
+
+    function timedCheck()
+    {
+        if (key != Swekey_GetValidKey()) {
+            window.location.search = "?swekey_reset";
+        } else {
+            setTimeout("timedCheck()",1000);
+        }
+    }
+
+    setTimeout("timedCheck()",1000);
+    </script>
+     <?php
+
+    if (! empty($_SESSION['SWEKEY']['AUTHENTICATED_SWEKEY'])) {
+        return null;
+    }
+
+    if (count($_SESSION['SWEKEY']['VALID_SWEKEYS']) == 0) {
+        return sprintf(__('File %s does not contain any key id'), $GLOBALS['cfg']['Server']['auth_swekey_config']);
+    }
+
+    include_once "libraries/plugins/auth/swekey/swekey.php";
+
+    Swekey_SetCheckServer($_SESSION['SWEKEY']['CONF_SERVER_CHECK']);
+    Swekey_SetRndTokenServer($_SESSION['SWEKEY']['CONF_SERVER_RNDTOKEN']);
+    Swekey_SetStatusServer($_SESSION['SWEKEY']['CONF_SERVER_STATUS']);
+    Swekey_EnableTokenCache($_SESSION['SWEKEY']['CONF_ENABLE_TOKEN_CACHE']);
+
+    $caFile = $_SESSION['SWEKEY']['CONF_CA_FILE'];
+    if (empty($caFile)) {
+        $caFile = __FILE__;
+        $pos = strrpos($caFile, '/');
+        if ($pos === false) {
+            $pos = strrpos($caFile, '\\'); // windows
+        }
+        $caFile = substr($caFile, 0, $pos + 1).'musbe-ca.crt';
+//        echo "\n<!-- $caFile -->\n";
+//        if (file_exists($caFile))
+//            echo "<!-- exists -->\n";
+    }
+
+    if (file_exists($caFile)) {
+        Swekey_SetCAFile($caFile);
+    } elseif (! empty($caFile) && (substr($_SESSION['SWEKEY']['CONF_SERVER_CHECK'], 0, 8) == "https://")) {
+        return "Internal Error: CA File $caFile not found";
+    }
+
+    $result = null;
+    $swekey_id = $_GET['swekey_id'];
+    $swekey_otp = $_GET['swekey_otp'];
+
+    if (isset($swekey_id)) {
+        unset($_SESSION['SWEKEY']['AUTHENTICATED_SWEKEY']);
+        if (! isset($_SESSION['SWEKEY']['RND_TOKEN'])) {
+            unset($swekey_id);
+        } else {
+            if (strlen($swekey_id) == 32) {
+                $res = Swekey_CheckOtp($swekey_id, $_SESSION['SWEKEY']['RND_TOKEN'], $swekey_otp);
+                unset($_SESSION['SWEKEY']['RND_TOKEN']);
+                if (! $res) {
+                    $result = __('Hardware authentication failed') . ' (' . Swekey_GetLastError() . ')';
+                } else {
+                    $_SESSION['SWEKEY']['AUTHENTICATED_SWEKEY'] = $swekey_id;
+                    $_SESSION['SWEKEY']['FORCE_USER'] = $_SESSION['SWEKEY']['VALID_SWEKEYS'][$swekey_id];
+                    return null;
+                }
+            } else {
+                $result = __('No valid authentication key plugged');
+                if ($_SESSION['SWEKEY']['CONF_DEBUG']) {
+                    $result .= "<br/>" . htmlspecialchars($swekey_id);
+                }
+                unset($_SESSION['SWEKEY']['CONF_LOADED']); // reload the conf file
+            }
+        }
+    } else {
+        unset($_SESSION['SWEKEY']);
+    }
+
+    $_SESSION['SWEKEY']['RND_TOKEN'] = Swekey_GetFastRndToken();
+    if (strlen($_SESSION['SWEKEY']['RND_TOKEN']) != 64) {
+        $result = __('Hardware authentication failed') . ' (' . Swekey_GetLastError() . ')';
+        unset($_SESSION['SWEKEY']['CONF_LOADED']); // reload the conf file
+    }
+
+    if (! isset($swekey_id)) {
+        ?>
+        <script>
+        if (key.length != 32) {
+            window.location.search="?swekey_id=" + key + "&token=<?php echo $_SESSION[' PMA_token ']; ?>";
+        } else {
+            var url = "" + window.location;
+            if (url.indexOf("?") > 0) {
+                url = url.substr(0, url.indexOf("?"));
+            }
+            Swekey_SetUnplugUrl(key, "pma_login", url + "?session_to_unset=<?php echo session_id();?>&token=<?php echo $_SESSION[' PMA_token ']; ?>");
+            var otp = Swekey_GetOtp(key, <?php echo '"'.$_SESSION['SWEKEY']['RND_TOKEN'].'"';?>);
+            window.location.search="?swekey_id=" + key + "&swekey_otp=" + otp + "&token=<?php echo $_SESSION[' PMA_token ']; ?>";
+        }
+        </script>
+        <?php
+        return __('Authenticating…');
+    }
+
+    return $result;
+}
+
+
+/**
+ * Perform login using Swekey.
+ */
+function Swekey_login($input_name, $input_go)
+{
+    $swekeyErr = Swekey_auth_error();
+    if ($swekeyErr != null) {
+        PMA_Message::error($swekeyErr)->display();
+        if ($GLOBALS['error_handler']->hasDisplayErrors()) {
+            echo '<div>';
+            $GLOBALS['error_handler']->dispErrors();
+            echo '</div>';
+        }
+    }
+
+    if (isset($_SESSION['SWEKEY']) && $_SESSION['SWEKEY']['ENABLED']) {
+        echo '<script type="text/javascript">';
+        if (empty($_SESSION['SWEKEY']['FORCE_USER'])) {
+            echo 'var user = null;';
+        } else {
+            echo 'var user = "'.$_SESSION['SWEKEY']['FORCE_USER'].'";';
+        }
+
+        ?>
+            function open_swekey_site()
+            {
+                window.open("<?php echo PMA_linkURL('http://phpmyadmin.net/auth_key'); ?>");
+            }
+
+            var input_username = document.getElementById("<?php echo $input_name; ?>");
+            var input_go = document.getElementById("<?php echo $input_go; ?>");
+            var swekey_status = document.createElement('img');
+            swekey_status.setAttribute('onclick', 'open_swekey_site()');
+            swekey_status.setAttribute('style', 'width:8px; height:16px; border:0px; vspace:0px; hspace:0px; frameborder:no');
+            if (user == null) {
+                swekey_status.setAttribute('src', 'http://artwork.swekey.com/unplugged-8x16.png');
+                //swekey_status.setAttribute('title', 'No swekey plugged');
+                input_go.disabled = true;
+            } else {
+                swekey_status.setAttribute('src', 'http://artwork.swekey.com/plugged-8x16.png');
+                //swekey_status.setAttribute('title', 'swekey plugged');
+                input_username.value = user;
+            }
+            input_username.readOnly = true;
+
+            if (input_username.nextSibling == null) {
+                input_username.parentNode.appendChild(swekey_status);
+            } else {
+                input_username.parentNode.insertBefore(swekey_status, input_username.nextSibling);
+            }
+
+        <?php
+        echo '</script>';
+    }
+}
+
+if (!empty($_GET['session_to_unset'])) {
+    session_write_close();
+    session_id($_GET['session_to_unset']);
+    session_start();
+    $_SESSION = array();
+    session_write_close();
+    session_destroy();
+    exit;
+}
+
+if (isset($_GET['swekey_reset'])) {
+    unset($_SESSION['SWEKEY']);
+}
+
+?>
diff --git a/phpmyadmin/libraries/plugins/auth/swekey/swekey.php b/phpmyadmin/libraries/plugins/auth/swekey/swekey.php
new file mode 100644
index 0000000..d495d45
--- /dev/null
+++ b/phpmyadmin/libraries/plugins/auth/swekey/swekey.php
@@ -0,0 +1,522 @@
+<?php
+/**
+ * Library that provides common functions that are used to help integrating Swekey Authentication in a PHP web site
+ * Version 1.0
+ *
+ * History:
+ * 1.2 Use curl (widely installed) to query the server
+ *     Fixed a possible tempfile race attack
+ *     Random token cache can now be disabled
+ * 1.1 Added Swekey_HttpGet function that support faulty servers
+ *     Support for custom servers
+ * 1.0 First release
+ *
+ * @package Swekey
+ */
+
+
+/**
+ * Errors codes
+ */
+define("SWEKEY_ERR_INVALID_DEV_STATUS", 901);   // The satus of the device is not SWEKEY_STATUS_OK
+define("SWEKEY_ERR_INTERNAL", 902);             // Should never occurd
+define("SWEKEY_ERR_OUTDATED_RND_TOKEN", 910);   // You random token is too old
+define("SWEKEY_ERR_INVALID_OTP", 911);          // The otp was not correct
+
+/**
+ * Those errors are considered as an attack and your site will be blacklisted during one minute
+ * if you receive one of those errors
+ */
+define("SWEKEY_ERR_BADLY_ENCODED_REQUEST", 920);
+define("SWEKEY_ERR_INVALID_RND_TOKEN", 921);
+define("SWEKEY_ERR_DEV_NOT_FOUND", 922);
+
+/**
+ * Default values for configuration.
+ */
+define('SWEKEY_DEFAULT_CHECK_SERVER', 'https://auth-check.musbe.net');
+define('SWEKEY_DEFAULT_RND_SERVER', 'https://auth-rnd-gen.musbe.net');
+define('SWEKEY_DEFAULT_STATUS_SERVER', 'https://auth-status.musbe.net');
+
+/**
+ * The last error of an operation is alway put in this global var
+ */
+
+global $gSwekeyLastError;
+$gSwekeyLastError = 0;
+
+global $gSwekeyLastResult;
+$gSwekeyLastResult = "<not set>";
+
+/**
+ * Servers addresses
+ * Use the  Swekey_SetXxxServer($server) functions to set them
+ */
+
+global $gSwekeyCheckServer;
+if (! isset($gSwekeyCheckServer)) {
+    $gSwekeyCheckServer = SWEKEY_DEFAULT_CHECK_SERVER;
+}
+
+global $gSwekeyRndTokenServer;
+if (! isset($gSwekeyRndTokenServer)) {
+    $gSwekeyRndTokenServer = SWEKEY_DEFAULT_RND_SERVER;
+}
+
+global $gSwekeyStatusServer;
+if (! isset($gSwekeyStatusServer)) {
+    $gSwekeyStatusServer = SWEKEY_DEFAULT_STATUS_SERVER;
+}
+
+global $gSwekeyCA;
+
+global $gSwekeyTokenCacheEnabled;
+if (! isset($gSwekeyTokenCacheEnabled)) {
+    $gSwekeyTokenCacheEnabled = true;
+}
+
+/**
+ *  Change the address of the Check server.
+ *  If $server is empty the default value 'http://auth-check.musbe.net' will be used
+ *
+ * @param server              The protocol and hostname to use
+ *
+ * @access public
+ */
+function Swekey_SetCheckServer($server)
+{
+    global $gSwekeyCheckServer;
+    if (empty($server)) {
+        $gSwekeyCheckServer = SWEKEY_DEFAULT_CHECK_SERVER;
+    } else {
+        $gSwekeyCheckServer = $server;
+    }
+}
+
+/**
+ *  Change the address of the Random Token Generator server.
+ *  If $server is empty the default value 'http://auth-rnd-gen.musbe.net' will be used
+ *
+ * @param server              The protocol and hostname to use
+ *
+ * @access public
+ */
+function Swekey_SetRndTokenServer($server)
+{
+    global $gSwekeyRndTokenServer;
+    if (empty($server)) {
+        $gSwekeyRndTokenServer = SWEKEY_DEFAULT_RND_SERVER;
+    } else {
+        $gSwekeyRndTokenServer = $server;
+    }
+}
+
+/**
+ *  Change the address of the Satus server.
+ *  If $server is empty the default value 'http://auth-status.musbe.net' will be used
+ *
+ * @param server              The protocol and hostname to use
+ *
+ * @access public
+ */
+function Swekey_SetStatusServer($server)
+{
+    global $gSwekeyStatusServer;
+    if (empty($server)) {
+        $gSwekeyStatusServer = SWEKEY_DEFAULT_STATUS_SERVER;
+    } else {
+        $gSwekeyStatusServer = $server;
+    }
+}
+
+/**
+ *  Change the certificat file in case of the the severs use https instead of http
+ *
+ * @param cafile              The path of the crt file to use
+ *
+ * @access public
+ */
+function Swekey_SetCAFile($cafile)
+{
+    global $gSwekeyCA;
+    $gSwekeyCA = $cafile;
+}
+
+/**
+ *  Enable or disable the random token caching
+ *  Because everybody has full access to the cache file, it can be a DOS vulnerability
+ *  So disable it if you are running in a non secure enviromnement
+ *
+ * @param $enable
+ *
+ * @access public
+ */
+function Swekey_EnableTokenCache($enable)
+{
+    global $gSwekeyTokenCacheEnabled;
+    $gSwekeyTokenCacheEnabled = ! empty($enable);
+}
+
+
+/**
+ *  Return the last error.
+ *
+ * @return The Last Error
+ * @access public
+ */
+function Swekey_GetLastError()
+{
+    global $gSwekeyLastError;
+    return $gSwekeyLastError;
+}
+
+/**
+ *  Return the last result.
+ *
+ * @return The Last Error
+ * @access public
+ */
+function Swekey_GetLastResult()
+{
+    global $gSwekeyLastResult;
+    return $gSwekeyLastResult;
+}
+
+/**
+ *  Send a synchronous request to the  server.
+ *  This function manages timeout then will not block if one of the server is down
+ *
+ * @param url                 The url to get
+ * @param response_code       The response code
+ *
+ * @return The body of the response or "" in case of error
+ * @access private
+ */
+function Swekey_HttpGet($url, &$response_code)
+{
+    global $gSwekeyLastError;
+    $gSwekeyLastError = 0;
+    global $gSwekeyLastResult;
+    $gSwekeyLastResult = "<not set>";
+
+     // use curl if available
+    if (function_exists('curl_init')) {
+        $sess = curl_init($url);
+        if (substr($url, 0, 8) == "https://") {
+            global $gSwekeyCA;
+
+            if (! empty($gSwekeyCA)) {
+                if (file_exists($gSwekeyCA)) {
+                    if (! curl_setopt($sess, CURLOPT_CAINFO, $gSwekeyCA)) {
+                        error_log("SWEKEY_ERROR:Could not set CA file : ".curl_error($sess));
+                    } else {
+                        $caFileOk = true;
+                    }
+                } else {
+                    error_log("SWEKEY_ERROR:Could not find CA file $gSwekeyCA getting $url");
+                }
+            }
+
+            curl_setopt($sess, CURLOPT_SSL_VERIFYHOST, '2');
+            curl_setopt($sess, CURLOPT_SSL_VERIFYPEER, '2');
+            curl_setopt($sess, CURLOPT_CONNECTTIMEOUT, '20');
+            curl_setopt($sess, CURLOPT_TIMEOUT, '20');
+        } else {
+            curl_setopt($sess, CURLOPT_CONNECTTIMEOUT, '3');
+            curl_setopt($sess, CURLOPT_TIMEOUT, '5');
+        }
+
+        curl_setopt($sess, CURLOPT_RETURNTRANSFER, '1');
+        $res=curl_exec($sess);
+        $response_code = curl_getinfo($sess, CURLINFO_HTTP_CODE);
+        $curlerr = curl_error($sess);
+        curl_close($sess);
+
+        if ($response_code == 200) {
+            $gSwekeyLastResult = $res;
+            return $res;
+        }
+
+        if (! empty($response_code)) {
+            $gSwekeyLastError = $response_code;
+            error_log("SWEKEY_ERROR:Error $gSwekeyLastError ($curlerr) getting $url");
+            return "";
+        }
+
+        $response_code = 408; // Request Timeout
+        $gSwekeyLastError = $response_code;
+        error_log("SWEKEY_ERROR:Error $curlerr getting $url");
+        return "";
+    }
+
+    // use pecl_http if available
+    if (class_exists('HttpRequest')) {
+        // retry if one of the server is down
+        for ($num=1; $num <= 3; $num++ ) {
+            $r = new HttpRequest($url);
+            $options = array('timeout' => '3');
+
+            if (substr($url, 0, 6) == "https:") {
+                $sslOptions = array();
+                $sslOptions['verifypeer'] = true;
+                $sslOptions['verifyhost'] = true;
+
+                $capath = __FILE__;
+                $name = strrchr($capath, '/');
+                // windows
+                if (empty($name)) {
+                    $name = strrchr($capath, '\\');
+                }
+                $capath = substr($capath, 0, strlen($capath) - strlen($name) + 1).'musbe-ca.crt';
+
+                if (! empty($gSwekeyCA)) {
+                    $sslOptions['cainfo'] = $gSwekeyCA;
+                }
+
+                $options['ssl'] = $sslOptions;
+            }
+
+            $r->setOptions($options);
+
+ //           try
+            {
+               $reply = $r->send();
+               $res = $reply->getBody();
+               $info = $r->getResponseInfo();
+               $response_code = $info['response_code'];
+               if ($response_code != 200) {
+                    $gSwekeyLastError = $response_code;
+                    error_log("SWEKEY_ERROR:Error ".$gSwekeyLastError." getting ".$url);
+                    return "";
+               }
+
+
+               $gSwekeyLastResult = $res;
+               return $res;
+            }
+ //           catch (HttpException $e)
+ //           {
+ //               error_log("SWEKEY_WARNING:HttpException ".$e." getting ".$url);
+ //           }
+        }
+
+        $response_code = 408; // Request Timeout
+        $gSwekeyLastError = $response_code;
+        error_log("SWEKEY_ERROR:Error ".$gSwekeyLastError." getting ".$url);
+        return "";
+    }
+
+       global $http_response_header;
+    $res = @file_get_contents($url);
+    $response_code = substr($http_response_header[0], 9, 3); //HTTP/1.0
+    if ($response_code == 200) {
+        $gSwekeyLastResult = $res;
+        return $res;
+    }
+
+    $gSwekeyLastError = $response_code;
+    error_log("SWEKEY_ERROR:Error ".$response_code." getting ".$url);
+    return "";
+}
+
+/**
+ *  Get a Random Token from a Token Server
+ *  The RT is a 64 vhars hexadecimal value
+ *  You should better use Swekey_GetFastRndToken() for performance
+ * @access public
+ */
+function Swekey_GetRndToken()
+{
+    global $gSwekeyRndTokenServer;
+    return Swekey_HttpGet($gSwekeyRndTokenServer.'/FULL-RND-TOKEN', $response_code);
+}
+
+/**
+ *  Get a Half Random Token from a Token Server
+ *  The RT is a 64 vhars hexadecimal value
+ *  Use this value if you want to make your own Swekey_GetFastRndToken()
+ * @access public
+ */
+function Swekey_GetHalfRndToken()
+{
+    global $gSwekeyRndTokenServer;
+    return Swekey_HttpGet($gSwekeyRndTokenServer.'/HALF-RND-TOKEN', $response_code);
+}
+
+/**
+ *  Get a Half Random Token
+ *  The RT is a 64 vhars hexadecimal value
+ *  This function get a new random token and reuse it.
+ *  Token are refetched from the server only once every 30 seconds.
+ *  You should always use this function to get half random token.
+ * @access public
+ */
+function Swekey_GetFastHalfRndToken()
+{
+    global $gSwekeyTokenCacheEnabled;
+
+    $res = "";
+    $cachefile = "";
+
+    // We check if we have a valid RT is the session
+    if (isset($_SESSION['rnd-token-date'])) {
+        if (time() - $_SESSION['rnd-token-date'] < 30) {
+             $res = $_SESSION['rnd-token'];
+        }
+    }
+
+    // If not we try to get it from a temp file (PHP >= 5.2.1 only)
+    if (strlen($res) != 32 && $gSwekeyTokenCacheEnabled) {
+        if (function_exists('sys_get_temp_dir')) {
+            $tempdir = sys_get_temp_dir();
+            $cachefile = $tempdir."/swekey-rnd-token-".get_current_user();
+            $modif = filemtime($cachefile);
+            if ($modif != false) {
+                if (time() - $modif < 30) {
+                    $res = @file_get_contents($cachefile);
+                    if (strlen($res) != 32) {
+                         $res = "";
+                    } else {
+                         $_SESSION['rnd-token'] = $res;
+                         $_SESSION['rnd-token-date'] = $modif;
+                    }
+                }
+            }
+        }
+    }
+
+    // If we don't have a valid RT here we have to get it from the server
+    if (strlen($res) != 32) {
+        $res = substr(Swekey_GetHalfRndToken(), 0, 32);
+        $_SESSION['rnd-token'] = $res;
+        $_SESSION['rnd-token-date'] = time();
+        if (! empty($cachefile)) {
+            // we unlink the file so no possible tempfile race attack
+            unlink($cachefile);
+            $file = fopen($cachefile, "x");
+            if ($file != false) {
+                @fwrite($file, $res);
+                @fclose($file);
+            }
+        }
+    }
+
+    return $res."00000000000000000000000000000000";
+}
+
+/**
+ *  Get a Random Token
+ *  The RT is a 64 vhars hexadecimal value
+ *  This function generates a unique random token for each call but call the
+ *  server only once every 30 seconds.
+ *  You should always use this function to get random token.
+ * @access public
+ */
+function Swekey_GetFastRndToken()
+{
+    $res = Swekey_GetFastHalfRndToken();
+    if (strlen($res) == 64) {
+        return substr($res, 0, 32).strtoupper(md5("Musbe Authentication Key" . mt_rand() . date(DATE_ATOM)));
+    }
+    return "";
+}
+
+
+/**
+ *  Checks that an OTP generated by a Swekey is valid
+ *
+ * @param id                  The id of the swekey
+ * @param rt                   The random token used to generate the otp
+ * @param otp                  The otp generated by the swekey
+ *
+ * @return true or false
+ * @access public
+ */
+function Swekey_CheckOtp($id, $rt, $otp)
+{
+    global $gSwekeyCheckServer;
+    $res = Swekey_HttpGet($gSwekeyCheckServer.'/CHECK-OTP/'.$id.'/'.$rt.'/'.$otp, $response_code);
+    return $response_code == 200 && $res == "OK";
+}
+
+/**
+ * Values that are associated with a key.
+ * The following values can be returned by the Swekey_GetStatus() function
+ */
+define("SWEKEY_STATUS_OK", 0);
+define("SWEKEY_STATUS_NOT_FOUND", 1);  // The key does not exist in the db
+define("SWEKEY_STATUS_INACTIVE", 2);   // The key has never been activated
+define("SWEKEY_STATUS_LOST", 3);       // The user has lost his key
+define("SWEKEY_STATUS_STOLEN", 4);       // The key was stolen
+define("SWEKEY_STATUS_FEE_DUE", 5);       // The annual fee was not paid
+define("SWEKEY_STATUS_OBSOLETE", 6);   // The hardware is no longer supported
+define("SWEKEY_STATUS_UNKOWN", 201);   // We could not connect to the authentication server
+
+/**
+ * Values that are associated with a key.
+ * The Javascript Api can also return the following values
+ */
+define("SWEKEY_STATUS_REPLACED", 100);     // This key has been replaced by a backup key
+define("SWEKEY_STATUS_BACKUP_KEY", 101); // This key is a backup key that is not activated yet
+define("SWEKEY_STATUS_NOTPLUGGED", 200); // This key is not plugged in the computer
+
+
+/**
+ *  Return the text corresponding to the integer status of a key
+ *
+ * @param status              The status
+ *
+ * @return The text corresponding to the status
+ * @access public
+ */
+function Swekey_GetStatusStr($status)
+{
+    switch($status)
+    {
+    case SWEKEY_STATUS_OK :
+        return 'OK';
+    case SWEKEY_STATUS_NOT_FOUND :
+        return 'Key does not exist in the db';
+    case SWEKEY_STATUS_INACTIVE :
+        return 'Key not activated';
+    case SWEKEY_STATUS_LOST :
+        return 'Key was lost';
+    case SWEKEY_STATUS_STOLEN :
+        return 'Key was stolen';
+    case SWEKEY_STATUS_FEE_DUE :
+        return 'The annual fee was not paid';
+    case SWEKEY_STATUS_OBSOLETE :
+        return 'Key no longer supported';
+    case SWEKEY_STATUS_REPLACED :
+        return 'This key has been replaced by a backup key';
+    case SWEKEY_STATUS_BACKUP_KEY :
+        return 'This key is a backup key that is not activated yet';
+    case SWEKEY_STATUS_NOTPLUGGED :
+        return 'This key is not plugged in the computer';
+    case SWEKEY_STATUS_UNKOWN :
+        return 'Unknow Status, could not connect to the authentication server';
+    }
+    return 'unknown status '.$status;
+}
+
+/**
+ *  If your web site requires a key to login you should check that the key
+ *  is still valid (has not been lost or stolen) before requiring it.
+ *  A key can be authenticated only if its status is SWEKEY_STATUS_OK
+ *
+ * @param id                  The id of the swekey
+ *
+ * @return The status of the swekey
+ * @access public
+ */
+function Swekey_GetStatus($id)
+{
+    global $gSwekeyStatusServer;
+    $res = Swekey_HttpGet($gSwekeyStatusServer.'/GET-STATUS/'.$id, $response_code);
+    if ($response_code == 200) {
+        return intval($res);
+    }
+    return SWEKEY_STATUS_UNKOWN;
+}
+
+?>
diff --git a/phpmyadmin/libraries/plugins/export/ExportCodegen.class.php b/phpmyadmin/libraries/plugins/export/ExportCodegen.class.php
new file mode 100644
index 0000000..d0a2216
--- /dev/null
+++ b/phpmyadmin/libraries/plugins/export/ExportCodegen.class.php
@@ -0,0 +1,423 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * Set of functions used to build NHibernate dumps of tables
+ *
+ * @package    PhpMyAdmin-Export
+ * @subpackage CodeGen
+ */
+if (! defined('PHPMYADMIN')) {
+    exit;
+}
+
+/* Get the export interface */
+require_once 'libraries/plugins/ExportPlugin.class.php';
+/* Get the table property class */
+require_once 'libraries/plugins/export/TableProperty.class.php';
+
+/**
+ * Handles the export for the CodeGen class
+ *
+ * @package    PhpMyAdmin-Export
+ * @subpackage CodeGen
+ */
+class ExportCodegen extends ExportPlugin
+{
+    /**
+     * CodeGen Formats
+     *
+     * @var array
+     */
+    private $_cgFormats;
+
+    /**
+     * CodeGen Handlers
+     *
+     * @var array
+     */
+    private $_cgHandlers;
+
+    /**
+     * Constructor
+     */
+    public function __construct()
+    {
+        // initialize the specific export CodeGen variables
+        $this->initSpecificVariables();
+        $this->setProperties();
+    }
+
+    /**
+     * Initialize the local variables that are used for export CodeGen
+     *
+     * @return void
+     */
+    protected function initSpecificVariables()
+    {
+        $this->_setCgFormats(
+            array(
+                "NHibernate C# DO",
+                "NHibernate XML"
+            )
+        );
+
+        $this->_setCgHandlers(
+            array(
+                "_handleNHibernateCSBody",
+                "_handleNHibernateXMLBody"
+            )
+        );
+    }
+
+    /**
+     * Sets the export CodeGen properties
+     *
+     * @return void
+     */
+    protected function setProperties()
+    {
+        $props = 'libraries/properties/';
+        include_once "$props/plugins/ExportPluginProperties.class.php";
+        include_once "$props/options/groups/OptionsPropertyRootGroup.class.php";
+        include_once "$props/options/groups/OptionsPropertyMainGroup.class.php";
+        include_once "$props/options/items/HiddenPropertyItem.class.php";
+        include_once "$props/options/items/SelectPropertyItem.class.php";
+
+        $exportPluginProperties = new ExportPluginProperties();
+        $exportPluginProperties->setText('CodeGen');
+        $exportPluginProperties->setExtension('cs');
+        $exportPluginProperties->setMimeType('text/cs');
+        $exportPluginProperties->setOptionsText(__('Options'));
+
+        // create the root group that will be the options field for
+        // $exportPluginProperties
+        // this will be shown as "Format specific options"
+        $exportSpecificOptions = new OptionsPropertyRootGroup();
+        $exportSpecificOptions->setName("Format Specific Options");
+
+        // general options main group
+        $generalOptions = new OptionsPropertyMainGroup();
+        $generalOptions->setName("general_opts");
+        // create primary items and add them to the group
+        $leaf = new HiddenPropertyItem();
+        $leaf->setName("structure_or_data");
+        $generalOptions->addProperty($leaf);
+        $leaf = new SelectPropertyItem();
+        $leaf->setName("format");
+        $leaf->setText(__('Format:'));
+        $leaf->setValues($this->_getCgFormats());
+        $generalOptions->addProperty($leaf);
+        // add the main group to the root group
+        $exportSpecificOptions->addProperty($generalOptions);
+
+        // set the options for the export plugin property item
+        $exportPluginProperties->setOptions($exportSpecificOptions);
+        $this->properties = $exportPluginProperties;
+    }
+
+    /**
+     * This method is called when any PluginManager to which the observer
+     * is attached calls PluginManager::notify()
+     *
+     * @param SplSubject $subject The PluginManager notifying the observer
+     *                            of an update.
+     *
+     * @return void
+     */
+    public function update (SplSubject $subject)
+    {
+    }
+
+    /**
+     * Outputs export header
+     *
+     * @return bool Whether it succeeded
+     */
+    public function exportHeader ()
+    {
+        return true;
+    }
+
+    /**
+     * Outputs export footer
+     *
+     * @return bool Whether it succeeded
+     */
+    public function exportFooter ()
+    {
+        return true;
+    }
+
+    /**
+     * Outputs database header
+     *
+     * @param string $db Database name
+     *
+     * @return bool Whether it succeeded
+     */
+    public function exportDBHeader ($db)
+    {
+        return true;
+    }
+
+    /**
+     * Outputs database footer
+     *
+     * @param string $db Database name
+     *
+     * @return bool Whether it succeeded
+     */
+    public function exportDBFooter ($db)
+    {
+        return true;
+    }
+
+    /**
+     * Outputs CREATE DATABASE statement
+     *
+     * @param string $db Database name
+     *
+     * @return bool Whether it succeeded
+     */
+    public function exportDBCreate($db)
+    {
+        return true;
+    }
+
+    /**
+     * Outputs the content of a table in NHibernate format
+     *
+     * @param string $db        database name
+     * @param string $table     table name
+     * @param string $crlf      the end of line sequence
+     * @param string $error_url the url to go back in case of error
+     * @param string $sql_query SQL query for obtaining data
+     *
+     * @return bool Whether it succeeded
+     */
+    public function exportData($db, $table, $crlf, $error_url, $sql_query)
+    {
+        $CG_FORMATS = $this->_getCgFormats();
+        $CG_HANDLERS = $this->_getCgHandlers();
+
+        $format = $GLOBALS['codegen_format'];
+        if (isset($CG_FORMATS[$format])) {
+            return PMA_exportOutputHandler(
+                $this->$CG_HANDLERS[$format]($db, $table, $crlf)
+            );
+        }
+        return PMA_exportOutputHandler(sprintf("%s is not supported.", $format));
+    }
+
+    /**
+     * Used to make identifiers (from table or database names)
+     *
+     * @param string $str     name to be converted
+     * @param bool   $ucfirst whether to make the first character uppercase
+     *
+     * @return string identifier
+     */
+    public static function cgMakeIdentifier($str, $ucfirst = true)
+    {
+        // remove unsafe characters
+        $str = preg_replace('/[^\p{L}\p{Nl}_]/u', '', $str);
+        // make sure first character is a letter or _
+        if (! preg_match('/^\pL/u', $str)) {
+            $str = '_' . $str;
+        }
+        if ($ucfirst) {
+            $str = ucfirst($str);
+        }
+        return $str;
+    }
+
+    /**
+     * C# Handler
+     *
+     * @param string $db    database name
+     * @param string $table table name
+     * @param string $crlf  line separator
+     *
+     * @return string containing C# code lines, separated by "\n"
+     */
+    private function _handleNHibernateCSBody($db, $table, $crlf)
+    {
+        $lines = array();
+
+        $result = PMA_DBI_query(
+            sprintf(
+                'DESC %s.%s', PMA_Util::backquote($db),
+                PMA_Util::backquote($table)
+            )
+        );
+        if ($result) {
+            $tableProperties = array();
+            while ($row = PMA_DBI_fetch_row($result)) {
+                $tableProperties[] = new TableProperty($row);
+            }
+            PMA_DBI_free_result($result);
+            $lines[] = 'using System;';
+            $lines[] = 'using System.Collections;';
+            $lines[] = 'using System.Collections.Generic;';
+            $lines[] = 'using System.Text;';
+            $lines[] = 'namespace ' . ExportCodegen::cgMakeIdentifier($db);
+            $lines[] = '{';
+            $lines[] = '    #region ' . ExportCodegen::cgMakeIdentifier($table);
+            $lines[] = '    public class ' . ExportCodegen::cgMakeIdentifier($table);
+            $lines[] = '    {';
+            $lines[] = '        #region Member Variables';
+            foreach ($tableProperties as $tableProperty) {
+                $lines[] = $tableProperty->formatCs(
+                    '        protected #dotNetPrimitiveType# _#name#;'
+                );
+            }
+            $lines[] = '        #endregion';
+            $lines[] = '        #region Constructors';
+            $lines[] = '        public '
+                . ExportCodegen::cgMakeIdentifier($table) . '() { }';
+            $temp = array();
+            foreach ($tableProperties as $tableProperty) {
+                if (! $tableProperty->isPK()) {
+                    $temp[] = $tableProperty->formatCs(
+                        '#dotNetPrimitiveType# #name#'
+                    );
+                }
+            }
+            $lines[] = '        public '
+                . ExportCodegen::cgMakeIdentifier($table)
+                . '('
+                . implode(', ', $temp)
+                . ')';
+            $lines[] = '        {';
+            foreach ($tableProperties as $tableProperty) {
+                if (! $tableProperty->isPK()) {
+                    $lines[] = $tableProperty->formatCs(
+                        '            this._#name#=#name#;'
+                    );
+                }
+            }
+            $lines[] = '        }';
+            $lines[] = '        #endregion';
+            $lines[] = '        #region Public Properties';
+            foreach ($tableProperties as $tableProperty) {
+                $lines[] = $tableProperty->formatCs(
+                    '        public virtual #dotNetPrimitiveType# #ucfirstName#'
+                    . "\n"
+                    . '        {' . "\n"
+                    . '            get {return _#name#;}' . "\n"
+                    . '            set {_#name#=value;}' . "\n"
+                    . '        }'
+                );
+            }
+            $lines[] = '        #endregion';
+            $lines[] = '    }';
+            $lines[] = '    #endregion';
+            $lines[] = '}';
+        }
+        return implode("\n", $lines);
+    }
+
+    /**
+     * XML Handler
+     *
+     * @param string $db    database name
+     * @param string $table table name
+     * @param string $crlf  line separator
+     *
+     * @return string containing XML code lines, separated by "\n"
+     */
+    private function _handleNHibernateXMLBody($db, $table, $crlf)
+    {
+        $lines = array();
+        $lines[] = '<?xml version="1.0" encoding="utf-8" ?' . '>';
+        $lines[] = '<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" '
+            . 'namespace="' . ExportCodegen::cgMakeIdentifier($db) . '" '
+            . 'assembly="' . ExportCodegen::cgMakeIdentifier($db) . '">';
+        $lines[] = '    <class '
+            . 'name="' . ExportCodegen::cgMakeIdentifier($table) . '" '
+            . 'table="' . ExportCodegen::cgMakeIdentifier($table) . '">';
+        $result = PMA_DBI_query(
+            sprintf(
+                "DESC %s.%s", PMA_Util::backquote($db),
+                PMA_Util::backquote($table)
+            )
+        );
+        if ($result) {
+            while ($row = PMA_DBI_fetch_row($result)) {
+                $tableProperty = new TableProperty($row);
+                if ($tableProperty->isPK()) {
+                    $lines[] = $tableProperty->formatXml(
+                        '        <id name="#ucfirstName#" type="#dotNetObjectType#"'
+                        . ' unsaved-value="0">' . "\n"
+                        . '            <column name="#name#" sql-type="#type#"'
+                        . ' not-null="#notNull#" unique="#unique#"'
+                        . ' index="PRIMARY"/>' . "\n"
+                        . '            <generator class="native" />' . "\n"
+                        . '        </id>'
+                    );
+                } else {
+                    $lines[] = $tableProperty->formatXml(
+                        '        <property name="#ucfirstName#"'
+                        . ' type="#dotNetObjectType#">' . "\n"
+                        . '            <column name="#name#" sql-type="#type#"'
+                        . ' not-null="#notNull#" #indexName#/>' . "\n"
+                        . '        </property>'
+                    );
+                }
+            }
+            PMA_DBI_free_result($result);
+        }
+        $lines[] = '    </class>';
+        $lines[] = '</hibernate-mapping>';
+        return implode("\n", $lines);
+    }
+
+
+    /* ~~~~~~~~~~~~~~~~~~~~ Getters and Setters ~~~~~~~~~~~~~~~~~~~~ */
+
+
+    /**
+     * Getter for CodeGen formats
+     *
+     * @return array
+     */
+    private function _getCgFormats()
+    {
+        return $this->_cgFormats;
+    }
+
+    /**
+     * Setter for CodeGen formats
+     *
+     * @param array $CG_FORMATS contains CodeGen Formats
+     *
+     * @return void
+     */
+    private function _setCgFormats($CG_FORMATS)
+    {
+        $this->_cgFormats = $CG_FORMATS;
+    }
+
+    /**
+     * Getter for CodeGen handlers
+     *
+     * @return array
+     */
+    private function _getCgHandlers()
+    {
+        return $this->_cgHandlers;
+    }
+
+    /**
+     * Setter for CodeGen handlers
+     *
+     * @param array $CG_HANDLERS contains CodeGen handler methods
+     *
+     * @return void
+     */
+    private function _setCgHandlers($CG_HANDLERS)
+    {
+        $this->_cgHandlers = $CG_HANDLERS;
+    }
+}
+?>
\ No newline at end of file
diff --git a/phpmyadmin/libraries/plugins/export/ExportCsv.class.php b/phpmyadmin/libraries/plugins/export/ExportCsv.class.php
new file mode 100644
index 0000000..98558e9
--- /dev/null
+++ b/phpmyadmin/libraries/plugins/export/ExportCsv.class.php
@@ -0,0 +1,345 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * CSV export code
+ *
+ * @package    PhpMyAdmin-Export
+ * @subpackage CSV
+ */
+if (! defined('PHPMYADMIN')) {
+    exit;
+}
+
+/* Get the export interface */
+require_once 'libraries/plugins/ExportPlugin.class.php';
+
+/**
+ * Handles the export for the CSV format
+ *
+ * @package    PhpMyAdmin-Export
+ * @subpackage CSV
+ */
+class ExportCsv extends ExportPlugin
+{
+    /**
+     * The string used to end lines
+     *
+     * @var string
+     */
+    private $_csvTerminated;
+
+    /**
+     * The string used to separate columns
+     *
+     * @var string
+     */
+    private $_csvSeparator;
+
+    /**
+     * The string used to enclose columns
+     *
+     * @var string
+     */
+    private $_csvEnclosed;
+
+    /**
+     * The string used to escape columns
+     *
+     * @var string
+     */
+    private $_csvEscaped;
+
+    /**
+     * Constructor
+     */
+    public function __construct()
+    {
+        $this->setProperties();
+    }
+
+    /**
+     * Sets the export CSV properties
+     *
+     * @return void
+     */
+    protected function setProperties()
+    {
+        $props = 'libraries/properties/';
+        include_once "$props/plugins/ExportPluginProperties.class.php";
+        include_once "$props/options/groups/OptionsPropertyRootGroup.class.php";
+        include_once "$props/options/groups/OptionsPropertyMainGroup.class.php";
+        include_once "$props/options/items/TextPropertyItem.class.php";
+        include_once "$props/options/items/BoolPropertyItem.class.php";
+        include_once "$props/options/items/HiddenPropertyItem.class.php";
+
+        $exportPluginProperties = new ExportPluginProperties();
+        $exportPluginProperties->setText('CSV');
+        $exportPluginProperties->setExtension('csv');
+        $exportPluginProperties->setMimeType('text/comma-separated-values');
+        $exportPluginProperties->setOptionsText(__('Options'));
+
+        // create the root group that will be the options field for
+        // $exportPluginProperties
+        // this will be shown as "Format specific options"
+        $exportSpecificOptions = new OptionsPropertyRootGroup();
+        $exportSpecificOptions->setName("Format Specific Options");
+
+        // general options main group
+        $generalOptions = new OptionsPropertyMainGroup();
+        $generalOptions->setName("general_opts");
+        // create leaf items and add them to the group
+        $leaf = new TextPropertyItem();
+        $leaf->setName("separator");
+        $leaf->setText(__('Columns separated with:'));
+        $generalOptions->addProperty($leaf);
+        $leaf = new TextPropertyItem();
+        $leaf->setName("enclosed");
+        $leaf->setText(__('Columns enclosed with:'));
+        $generalOptions->addProperty($leaf);
+        $leaf = new TextPropertyItem();
+        $leaf->setName("escaped");
+        $leaf->setText(__('Columns escaped with:'));
+        $generalOptions->addProperty($leaf);
+        $leaf = new TextPropertyItem();
+        $leaf->setName("terminated");
+        $leaf->setText(__('Lines terminated with:'));
+        $generalOptions->addProperty($leaf);
+        $leaf = new TextPropertyItem();
+        $leaf->setName('null');
+        $leaf->setText(__('Replace NULL with:'));
+        $generalOptions->addProperty($leaf);
+        $leaf = new BoolPropertyItem();
+        $leaf->setName('removeCRLF');
+        $leaf->setText(
+            __('Remove carriage return/line feed characters within columns')
+        );
+        $generalOptions->addProperty($leaf);
+        $leaf = new BoolPropertyItem();
+        $leaf->setName('columns');
+        $leaf->setText(__('Put columns names in the first row'));
+        $generalOptions->addProperty($leaf);
+        $leaf = new HiddenPropertyItem();
+        $leaf->setName('structure_or_data');
+        $generalOptions->addProperty($leaf);
+        // add the main group to the root group
+        $exportSpecificOptions->addProperty($generalOptions);
+
+        // set the options for the export plugin property item
+        $exportPluginProperties->setOptions($exportSpecificOptions);
+        $this->properties = $exportPluginProperties;
+    }
+
+    /**
+     * This method is called when any PluginManager to which the observer
+     * is attached calls PluginManager::notify()
+     *
+     * @param SplSubject $subject The PluginManager notifying the observer
+     *                            of an update.
+     *
+     * @return void
+     */
+    public function update (SplSubject $subject)
+    {
+    }
+
+    /**
+     * Outputs export header
+     *
+     * @return bool Whether it succeeded
+     */
+    public function exportHeader ()
+    {
+        global $what, $csv_terminated, $csv_separator, $csv_enclosed, $csv_escaped;
+
+        // Here we just prepare some values for export
+        if ($what == 'excel') {
+            $csv_terminated = "\015\012";
+            switch($GLOBALS['excel_edition']) {
+            case 'win':
+                // as tested on Windows with Excel 2002 and Excel 2007
+                $csv_separator = ';';
+                break;
+            case 'mac_excel2003':
+                $csv_separator = ';';
+                break;
+            case 'mac_excel2008':
+                $csv_separator = ',';
+                break;
+            }
+            $csv_enclosed = '"';
+            $csv_escaped  = '"';
+            if (isset($GLOBALS['excel_columns'])) {
+                $GLOBALS['csv_columns'] = 'yes';
+            }
+        } else {
+            if (empty($csv_terminated) || strtolower($csv_terminated) == 'auto') {
+                $csv_terminated = $GLOBALS['crlf'];
+            } else {
+                $csv_terminated = str_replace('\\r', "\015", $csv_terminated);
+                $csv_terminated = str_replace('\\n', "\012", $csv_terminated);
+                $csv_terminated = str_replace('\\t', "\011", $csv_terminated);
+            } // end if
+            $csv_separator = str_replace('\\t', "\011", $csv_separator);
+        }
+
+        return true;
+    }
+
+    /**
+     * Outputs export footer
+     *
+     * @return bool Whether it succeeded
+     */
+    public function exportFooter ()
+    {
+        return true;
+    }
+
+    /**
+     * Outputs database header
+     *
+     * @param string $db Database name
+     *
+     * @return bool Whether it succeeded
+     */
+    public function exportDBHeader ($db)
+    {
+        return true;
+    }
+
+    /**
+     * Outputs database footer
+     *
+     * @param string $db Database name
+     *
+     * @return bool Whether it succeeded
+     */
+    public function exportDBFooter ($db)
+    {
+        return true;
+    }
+
+    /**
+     * Outputs CREATE DATABASE statement
+     *
+     * @param string $db Database name
+     *
+     * @return bool Whether it succeeded
+     */
+    public function exportDBCreate($db)
+    {
+        return true;
+    }
+
+    /**
+     * Outputs the content of a table in CSV format
+     *
+     * @param string $db        database name
+     * @param string $table     table name
+     * @param string $crlf      the end of line sequence
+     * @param string $error_url the url to go back in case of error
+     * @param string $sql_query SQL query for obtaining data
+     *
+     * @return bool Whether it succeeded
+     */
+    public function exportData($db, $table, $crlf, $error_url, $sql_query)
+    {
+        global $what, $csv_terminated, $csv_separator, $csv_enclosed, $csv_escaped;
+
+        // Gets the data from the database
+        $result = PMA_DBI_query($sql_query, null, PMA_DBI_QUERY_UNBUFFERED);
+        $fields_cnt = PMA_DBI_num_fields($result);
+
+        // If required, get fields name at the first line
+        if (isset($GLOBALS['csv_columns'])) {
+            $schema_insert = '';
+            for ($i = 0; $i < $fields_cnt; $i++) {
+                if ($csv_enclosed == '') {
+                    $schema_insert .= stripslashes(PMA_DBI_field_name($result, $i));
+                } else {
+                    $schema_insert .= $csv_enclosed
+                        . str_replace(
+                            $csv_enclosed,
+                            $csv_escaped . $csv_enclosed,
+                            stripslashes(PMA_DBI_field_name($result, $i))
+                        )
+                        .  $csv_enclosed;
+                }
+                $schema_insert .= $csv_separator;
+            } // end for
+            $schema_insert = trim(substr($schema_insert, 0, -1));
+            if (! PMA_exportOutputHandler($schema_insert . $csv_terminated)) {
+                return false;
+            }
+        } // end if
+
+        // Format the data
+        while ($row = PMA_DBI_fetch_row($result)) {
+            $schema_insert = '';
+            for ($j = 0; $j < $fields_cnt; $j++) {
+                if (! isset($row[$j]) || is_null($row[$j])) {
+                    $schema_insert .= $GLOBALS[$what . '_null'];
+                } elseif ($row[$j] == '0' || $row[$j] != '') {
+                    // always enclose fields
+                    if ($what == 'excel') {
+                        $row[$j] = preg_replace("/\015(\012)?/", "\012", $row[$j]);
+                    }
+                    // remove CRLF characters within field
+                    if (isset($GLOBALS[$what . '_removeCRLF'])
+                        && $GLOBALS[$what . '_removeCRLF']
+                    ) {
+                        $row[$j] = str_replace(
+                            "\n",
+                            "",
+                            str_replace(
+                                "\r",
+                                "",
+                                $row[$j]
+                            )
+                        );
+                    }
+                    if ($csv_enclosed == '') {
+                        $schema_insert .= $row[$j];
+                    } else {
+                        // also double the escape string if found in the data
+                        if ($csv_escaped != $csv_enclosed) {
+                            $schema_insert .= $csv_enclosed
+                                . str_replace(
+                                    $csv_enclosed,
+                                    $csv_escaped . $csv_enclosed,
+                                    str_replace(
+                                        $csv_escaped,
+                                        $csv_escaped . $csv_escaped,
+                                        $row[$j]
+                                    )
+                                )
+                                . $csv_enclosed;
+                        } else {
+                            // avoid a problem when escape string equals enclose
+                            $schema_insert .= $csv_enclosed
+                            . str_replace(
+                                $csv_enclosed,
+                                $csv_escaped . $csv_enclosed,
+                                $row[$j]
+                            )
+                            . $csv_enclosed;
+                        }
+                    }
+                } else {
+                    $schema_insert .= '';
+                }
+                if ($j < $fields_cnt-1) {
+                    $schema_insert .= $csv_separator;
+                }
+            } // end for
+
+            if (! PMA_exportOutputHandler($schema_insert . $csv_terminated)) {
+                return false;
+            }
+        } // end while
+        PMA_DBI_free_result($result);
+
+        return true;
+    }
+}
+?>
\ No newline at end of file
diff --git a/phpmyadmin/libraries/plugins/export/ExportExcel.class.php b/phpmyadmin/libraries/plugins/export/ExportExcel.class.php
new file mode 100644
index 0000000..1bb1060
--- /dev/null
+++ b/phpmyadmin/libraries/plugins/export/ExportExcel.class.php
@@ -0,0 +1,105 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * Class for exporting CSV dumps of tables for excel
+ *
+ * @package    PhpMyAdmin-Export
+ * @subpackage CSV-Excel
+ */
+if (! defined('PHPMYADMIN')) {
+    exit;
+}
+
+/* Extend the export CSV class */
+require_once 'libraries/plugins/export/ExportCsv.class.php';
+
+/**
+ * Handles the export for the CSV-Excel format
+ *
+ * @package    PhpMyAdmin-Export
+ * @subpackage CSV-Excel
+ */
+class ExportExcel extends ExportCsv
+{
+    /**
+     * Sets the export CSV for Excel properties
+     *
+     * @return void
+     */
+    protected function setProperties()
+    {
+        $props = 'libraries/properties/';
+        include_once "$props/plugins/ExportPluginProperties.class.php";
+        include_once "$props/options/groups/OptionsPropertyRootGroup.class.php";
+        include_once "$props/options/groups/OptionsPropertyMainGroup.class.php";
+        include_once "$props/options/items/TextPropertyItem.class.php";
+        include_once "$props/options/items/BoolPropertyItem.class.php";
+        include_once "$props/options/items/SelectPropertyItem.class.php";
+        include_once "$props/options/items/HiddenPropertyItem.class.php";
+
+        $exportPluginProperties = new ExportPluginProperties();
+        $exportPluginProperties->setText('CSV for MS Excel');
+        $exportPluginProperties->setExtension('csv');
+        $exportPluginProperties->setMimeType('text/comma-separated-values');
+        $exportPluginProperties->setOptionsText(__('Options'));
+
+        // create the root group that will be the options field for
+        // $exportPluginProperties
+        // this will be shown as "Format specific options"
+        $exportSpecificOptions = new OptionsPropertyRootGroup();
+        $exportSpecificOptions->setName("Format Specific Options");
+
+        // general options main group
+        $generalOptions = new OptionsPropertyMainGroup();
+        $generalOptions->setName("general_opts");
+        // create primary items and add them to the group
+        $leaf = new TextPropertyItem();
+        $leaf->setName('null');
+        $leaf->setText(__('Replace NULL with:'));
+        $generalOptions->addProperty($leaf);
+        $leaf = new BoolPropertyItem();
+        $leaf->setName('removeCRLF');
+        $leaf->setText(
+            __('Remove carriage return/line feed characters within columns')
+        );
+        $generalOptions->addProperty($leaf);
+        $leaf = new BoolPropertyItem();
+        $leaf->setName('columns');
+        $leaf->setText(__('Put columns names in the first row'));
+        $generalOptions->addProperty($leaf);
+        $leaf = new SelectPropertyItem();
+        $leaf->setName('edition');
+        $leaf->setValues(
+            array(
+                'win' => 'Windows',
+                'mac_excel2003' => 'Excel 2003 / Macintosh',
+                'mac_excel2008' => 'Excel 2008 / Macintosh'
+            )
+        );
+        $leaf->setText(__('Excel edition:'));
+        $generalOptions->addProperty($leaf);
+        $leaf = new HiddenPropertyItem();
+        $leaf->setName('structure_or_data');
+        $generalOptions->addProperty($leaf);
+        // add the main group to the root group
+        $exportSpecificOptions->addProperty($generalOptions);
+
+        // set the options for the export plugin property item
+        $exportPluginProperties->setOptions($exportSpecificOptions);
+        $this->properties = $exportPluginProperties;
+    }
+
+    /**
+     * This method is called when any PluginManager to which the observer
+     * is attached calls PluginManager::notify()
+     *
+     * @param SplSubject $subject The PluginManager notifying the observer
+     *                            of an update.
+     *
+     * @return void
+     */
+    public function update (SplSubject $subject)
+    {
+    }
+}
+?>
\ No newline at end of file
diff --git a/phpmyadmin/libraries/plugins/export/ExportHtmlword.class.php b/phpmyadmin/libraries/plugins/export/ExportHtmlword.class.php
new file mode 100644
index 0000000..cdd5ec6
--- /dev/null
+++ b/phpmyadmin/libraries/plugins/export/ExportHtmlword.class.php
@@ -0,0 +1,645 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * HTML-Word export code
+ *
+ * @package    PhpMyAdmin-Export
+ * @subpackage HTML-Word
+ */
+if (! defined('PHPMYADMIN')) {
+    exit;
+}
+
+/* Get the export interface */
+require_once 'libraries/plugins/ExportPlugin.class.php';
+
+/**
+ * Handles the export for the HTML-Word format
+ *
+ * @package    PhpMyAdmin-Export
+ * @subpackage HTML-Word
+ */
+class ExportHtmlword extends ExportPlugin
+{
+    /**
+     * Constructor
+     */
+    public function __construct()
+    {
+        $this->setProperties();
+    }
+
+    /**
+     * Sets the export HTML-Word properties
+     *
+     * @return void
+     */
+    protected function setProperties()
+    {
+        $props = 'libraries/properties/';
+        include_once "$props/plugins/ExportPluginProperties.class.php";
+        include_once "$props/options/groups/OptionsPropertyRootGroup.class.php";
+        include_once "$props/options/groups/OptionsPropertyMainGroup.class.php";
+        include_once "$props/options/items/RadioPropertyItem.class.php";
+        include_once "$props/options/items/TextPropertyItem.class.php";
+        include_once "$props/options/items/BoolPropertyItem.class.php";
+
+        $exportPluginProperties = new ExportPluginProperties();
+        $exportPluginProperties->setText('Microsoft Word 2000');
+        $exportPluginProperties->setExtension('doc');
+        $exportPluginProperties->setMimeType('application/vnd.ms-word');
+        $exportPluginProperties->setForceFile(true);
+        $exportPluginProperties->setOptionsText(__('Options'));
+
+        // create the root group that will be the options field for
+        // $exportPluginProperties
+        // this will be shown as "Format specific options"
+        $exportSpecificOptions = new OptionsPropertyRootGroup();
+        $exportSpecificOptions->setName("Format Specific Options");
+
+        // what to dump (structure/data/both)
+        $dumpWhat = new OptionsPropertyMainGroup();
+        $dumpWhat->setName("dump_what");
+        $dumpWhat->setText(__('Dump table'));
+        // create primary items and add them to the group
+        $leaf = new RadioPropertyItem();
+        $leaf->setName("structure_or_data");
+        $leaf->setValues(
+            array(
+                'structure' => __('structure'),
+                'data' => __('data'),
+                'structure_and_data' => __('structure and data')
+            )
+        );
+        $dumpWhat->addProperty($leaf);
+        // add the main group to the root group
+        $exportSpecificOptions->addProperty($dumpWhat);
+
+        // data options main group
+        $dataOptions = new OptionsPropertyMainGroup();
+        $dataOptions->setName("dump_what");
+        $dataOptions->setText(__('Data dump options'));
+        $dataOptions->setForce('structure');
+        // create primary items and add them to the group
+        $leaf = new TextPropertyItem();
+        $leaf->setName("null");
+        $leaf->setText(__('Replace NULL with:'));
+        $dataOptions->addProperty($leaf);
+        $leaf = new BoolPropertyItem();
+        $leaf->setName("columns");
+        $leaf->setText(__('Put columns names in the first row'));
+        $dataOptions->addProperty($leaf);
+        // add the main group to the root group
+        $exportSpecificOptions->addProperty($dataOptions);
+
+        // set the options for the export plugin property item
+        $exportPluginProperties->setOptions($exportSpecificOptions);
+        $this->properties = $exportPluginProperties;
+    }
+
+    /**
+     * This method is called when any PluginManager to which the observer
+     * is attached calls PluginManager::notify()
+     *
+     * @param SplSubject $subject The PluginManager notifying the observer
+     *                            of an update.
+     *
+     * @return void
+     */
+    public function update (SplSubject $subject)
+    {
+    }
+
+    /**
+     * Outputs export header
+     *
+     * @return bool Whether it succeeded
+     */
+    public function exportHeader ()
+    {
+        global $charset_of_file;
+
+        return PMA_exportOutputHandler(
+            '<html xmlns:o="urn:schemas-microsoft-com:office:office"
+            xmlns:x="urn:schemas-microsoft-com:office:word"
+            xmlns="http://www.w3.org/TR/REC-html40">
+
+            <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"'
+            . ' "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+            <html>
+            <head>
+                <meta http-equiv="Content-type" content="text/html;charset='
+            . (isset($charset_of_file) ? $charset_of_file : 'utf-8') . '" />
+            </head>
+            <body>'
+        );
+    }
+
+    /**
+     * Outputs export footer
+     *
+     * @return bool Whether it succeeded
+     */
+    public function exportFooter ()
+    {
+        return PMA_exportOutputHandler('</body></html>');
+    }
+
+    /**
+     * Outputs database header
+     *
+     * @param string $db Database name
+     *
+     * @return bool Whether it succeeded
+     */
+    public function exportDBHeader ($db)
+    {
+        return PMA_exportOutputHandler(
+            '<h1>' . __('Database') . ' ' . htmlspecialchars($db) . '</h1>'
+        );
+    }
+
+    /**
+     * Outputs database footer
+     *
+     * @param string $db Database name
+     *
+     * @return bool Whether it succeeded
+     */
+    public function exportDBFooter ($db)
+    {
+        return true;
+    }
+
+    /**
+     * Outputs CREATE DATABASE statement
+     *
+     * @param string $db Database name
+     *
+     * @return bool Whether it succeeded
+     */
+    public function exportDBCreate($db)
+    {
+        return true;
+    }
+
+    /**
+     * Outputs the content of a table in HTML-Word format
+     *
+     * @param string $db        database name
+     * @param string $table     table name
+     * @param string $crlf      the end of line sequence
+     * @param string $error_url the url to go back in case of error
+     * @param string $sql_query SQL query for obtaining data
+     *
+     * @return bool Whether it succeeded
+     */
+    public function exportData($db, $table, $crlf, $error_url, $sql_query)
+    {
+        global $what;
+
+        if (! PMA_exportOutputHandler(
+            '<h2>'
+            . __('Dumping data for table') . ' ' . htmlspecialchars($table)
+            . '</h2>'
+        )) {
+            return false;
+        }
+        if (! PMA_exportOutputHandler(
+            '<table class="width100" cellspacing="1">'
+        )) {
+            return false;
+        }
+
+        // Gets the data from the database
+        $result = PMA_DBI_query($sql_query, null, PMA_DBI_QUERY_UNBUFFERED);
+        $fields_cnt = PMA_DBI_num_fields($result);
+
+        // If required, get fields name at the first line
+        if (isset($GLOBALS['htmlword_columns'])) {
+            $schema_insert = '<tr class="print-category">';
+            for ($i = 0; $i < $fields_cnt; $i++) {
+                $schema_insert .= '<td class="print"><strong>'
+                    . htmlspecialchars(
+                        stripslashes(PMA_DBI_field_name($result, $i))
+                    )
+                    . '</strong></td>';
+            } // end for
+            $schema_insert .= '</tr>';
+            if (! PMA_exportOutputHandler($schema_insert)) {
+                return false;
+            }
+        } // end if
+
+        // Format the data
+        while ($row = PMA_DBI_fetch_row($result)) {
+            $schema_insert = '<tr class="print-category">';
+            for ($j = 0; $j < $fields_cnt; $j++) {
+                if (! isset($row[$j]) || is_null($row[$j])) {
+                    $value = $GLOBALS[$what . '_null'];
+                } elseif ($row[$j] == '0' || $row[$j] != '') {
+                    $value = $row[$j];
+                } else {
+                    $value = '';
+                }
+                $schema_insert .= '<td class="print">'
+                    . htmlspecialchars($value)
+                    . '</td>';
+            } // end for
+            $schema_insert .= '</tr>';
+            if (! PMA_exportOutputHandler($schema_insert)) {
+                return false;
+            }
+        } // end while
+        PMA_DBI_free_result($result);
+        if (! PMA_exportOutputHandler('</table>')) {
+            return false;
+        }
+
+        return true;
+    }
+
+    /**
+     * Returns a stand-in CREATE definition to resolve view dependencies
+     *
+     * @param string $db   the database name
+     * @param string $view the view name
+     * @param string $crlf the end of line sequence
+     *
+     * @return string resulting definition
+     */
+    public function getTableDefStandIn($db, $view, $crlf)
+    {
+        $schema_insert = '<table class="width100" cellspacing="1">'
+            . '<tr class="print-category">'
+            . '<th class="print">'
+            . __('Column')
+            . '</th>'
+            . '<td class="print"><strong>'
+            . __('Type')
+            . '</strong></td>'
+            . '<td class="print"><strong>'
+            . __('Null')
+            . '</strong></td>'
+            . '<td class="print"><strong>'
+            . __('Default')
+            . '</strong></td>'
+            . '</tr>';
+
+        /**
+         * Get the unique keys in the view
+         */
+        $unique_keys = array();
+        $keys = PMA_DBI_get_table_indexes($db, $view);
+        foreach ($keys as $key) {
+            if ($key['Non_unique'] == 0) {
+                $unique_keys[] = $key['Column_name'];
+            }
+        }
+
+        $columns = PMA_DBI_get_columns($db, $view);
+        foreach ($columns as $column) {
+            $schema_insert .= $this->formatOneColumnDefinition(
+                $column,
+                $unique_keys
+            );
+            $schema_insert .= '</tr>';
+        }
+
+        $schema_insert .= '</table>';
+        return $schema_insert;
+    }
+
+    /**
+     * Returns $table's CREATE definition
+     *
+     * @param string $db            the database name
+     * @param string $table         the table name
+     * @param string $crlf          the end of line sequence
+     * @param string $error_url     the url to go back in case of error
+     * @param bool   $do_relation   whether to include relation comments
+     * @param bool   $do_comments   whether to include the pmadb-style column
+     *                                comments as comments in the structure;
+     *                                this is deprecated but the parameter is
+     *                                left here because export.php calls
+     *                                PMA_exportStructure() also for other
+     *                                export types which use this parameter
+     * @param bool   $do_mime       whether to include mime comments
+     * @param bool   $show_dates    whether to include creation/update/check dates
+     * @param bool   $add_semicolon whether to add semicolon and end-of-line
+     *                                at the end
+     * @param bool   $view          whether we're handling a view
+     *
+     * @return string resulting schema
+     */
+    public function getTableDef(
+        $db,
+        $table,
+        $crlf,
+        $error_url,
+        $do_relation,
+        $do_comments,
+        $do_mime,
+        $show_dates = false,
+        $add_semicolon = true,
+        $view = false
+    ) {
+        // set $cfgRelation here, because there is a chance that it's modified
+        // since the class initialization
+        global $cfgRelation;
+
+        $schema_insert = '';
+
+        /**
+         * Gets fields properties
+         */
+        PMA_DBI_select_db($db);
+
+        // Check if we can use Relations
+        if ($do_relation && ! empty($cfgRelation['relation'])) {
+            // Find which tables are related with the current one and write it in
+            // an array
+            $res_rel = PMA_getForeigners($db, $table);
+
+            if ($res_rel && count($res_rel) > 0) {
+                $have_rel = true;
+            } else {
+                $have_rel = false;
+            }
+        } else {
+               $have_rel = false;
+        } // end if
+
+        /**
+         * Displays the table structure
+         */
+        $schema_insert .= '<table class="width100" cellspacing="1">';
+
+        $columns_cnt = 4;
+        if ($do_relation && $have_rel) {
+            $columns_cnt++;
+        }
+        if ($do_comments && $cfgRelation['commwork']) {
+            $columns_cnt++;
+        }
+        if ($do_mime && $cfgRelation['mimework']) {
+            $columns_cnt++;
+        }
+
+        $schema_insert .= '<tr class="print-category">';
+        $schema_insert .= '<th class="print">'
+            . __('Column')
+            . '</th>';
+        $schema_insert .= '<td class="print"><strong>'
+            . __('Type')
+            . '</strong></td>';
+        $schema_insert .= '<td class="print"><strong>'
+            . __('Null')
+            . '</strong></td>';
+        $schema_insert .= '<td class="print"><strong>'
+            . __('Default')
+            . '</strong></td>';
+        if ($do_relation && $have_rel) {
+            $schema_insert .= '<td class="print"><strong>'
+                . __('Links to')
+                . '</strong></td>';
+        }
+        if ($do_comments) {
+            $schema_insert .= '<td class="print"><strong>'
+                . __('Comments')
+                . '</strong></td>';
+            $comments = PMA_getComments($db, $table);
+        }
+        if ($do_mime && $cfgRelation['mimework']) {
+            $schema_insert .= '<td class="print"><strong>'
+                . htmlspecialchars('MIME')
+                . '</strong></td>';
+            $mime_map = PMA_getMIME($db, $table, true);
+        }
+        $schema_insert .= '</tr>';
+
+        $columns = PMA_DBI_get_columns($db, $table);
+        /**
+         * Get the unique keys in the table
+         */
+        $unique_keys = array();
+        $keys = PMA_DBI_get_table_indexes($db, $table);
+        foreach ($keys as $key) {
+            if ($key['Non_unique'] == 0) {
+                $unique_keys[] = $key['Column_name'];
+            }
+        }
+        foreach ($columns as $column) {
+            $schema_insert .= $this->formatOneColumnDefinition(
+                $column,
+                $unique_keys
+            );
+            $field_name = $column['Field'];
+
+            if ($do_relation && $have_rel) {
+                $schema_insert .= '<td class="print">'
+                    . (isset($res_rel[$field_name])
+                        ? htmlspecialchars(
+                            $res_rel[$field_name]['foreign_table']
+                            . ' (' . $res_rel[$field_name]['foreign_field']
+                            . ')'
+                        )
+                        : '') . '</td>';
+            }
+            if ($do_comments && $cfgRelation['commwork']) {
+                $schema_insert .= '<td class="print">'
+                    . (isset($comments[$field_name])
+                        ? htmlspecialchars($comments[$field_name])
+                        : '') . '</td>';
+            }
+            if ($do_mime && $cfgRelation['mimework']) {
+                $schema_insert .= '<td class="print">'
+                    . (isset($mime_map[$field_name]) ?
+                    htmlspecialchars(
+                        str_replace('_', '/', $mime_map[$field_name]['mimetype'])
+                    )
+                    : '') . '</td>';
+            }
+
+            $schema_insert .= '</tr>';
+        } // end foreach
+
+        $schema_insert .= '</table>';
+        return $schema_insert;
+    }
+
+    /**
+     * Outputs triggers
+     *
+     * @param string $db    database name
+     * @param string $table table name
+     *
+     * @return string Formatted triggers list
+     */
+    protected function getTriggers($db, $table)
+    {
+        $dump = '<table class="width100" cellspacing="1">';
+        $dump .= '<tr class="print-category">';
+        $dump .= '<th class="print">' . __('Name') . '</th>';
+        $dump .= '<td class="print"><strong>' . __('Time') . '</strong></td>';
+        $dump .= '<td class="print"><strong>' . __('Event') . '</strong></td>';
+        $dump .= '<td class="print"><strong>' . __('Definition') . '</strong></td>';
+        $dump .= '</tr>';
+
+        $triggers = PMA_DBI_get_triggers($db, $table);
+
+        foreach ($triggers as $trigger) {
+            $dump .= '<tr class="print-category">';
+            $dump .= '<td class="print">'
+                . htmlspecialchars($trigger['name'])
+                . '</td>'
+                . '<td class="print">'
+                . htmlspecialchars($trigger['action_timing'])
+                . '</td>'
+                . '<td class="print">'
+                . htmlspecialchars($trigger['event_manipulation'])
+                . '</td>'
+                . '<td class="print">'
+                . htmlspecialchars($trigger['definition'])
+                . '</td>'
+                . '</tr>';
+        }
+
+        $dump .= '</table>';
+        return $dump;
+    }
+
+    /**
+     * Outputs table's structure
+     *
+     * @param string $db          database name
+     * @param string $table       table name
+     * @param string $crlf        the end of line sequence
+     * @param string $error_url   the url to go back in case of error
+     * @param string $export_mode 'create_table', 'triggers', 'create_view',
+     *                            'stand_in'
+     * @param string $export_type 'server', 'database', 'table'
+     * @param bool   $do_relation whether to include relation comments
+     * @param bool   $do_comments whether to include the pmadb-style column
+     *                                comments as comments in the structure;
+     *                                this is deprecated but the parameter is
+     *                                left here because export.php calls
+     *                                PMA_exportStructure() also for other
+     *                                export types which use this parameter
+     * @param bool   $do_mime     whether to include mime comments
+     * @param bool   $dates       whether to include creation/update/check dates
+     *
+     * @return bool Whether it succeeded
+     */
+    public function exportStructure(
+        $db,
+        $table,
+        $crlf,
+        $error_url,
+        $export_mode,
+        $export_type,
+        $do_relation = false,
+        $do_comments = false,
+        $do_mime = false,
+        $dates = false
+    ) {
+        $dump = '';
+
+        switch($export_mode) {
+        case 'create_table':
+            $dump .= '<h2>'
+                . __('Table structure for table') . ' ' . htmlspecialchars($table)
+                . '</h2>';
+            $dump .= $this->getTableDef(
+                $db, $table, $crlf, $error_url, $do_relation, $do_comments, $do_mime,
+                $dates
+            );
+            break;
+        case 'triggers':
+            $dump = '';
+            $triggers = PMA_DBI_get_triggers($db, $table);
+            if ($triggers) {
+                $dump .= '<h2>'
+                    . __('Triggers') . ' ' . htmlspecialchars($table)
+                    . '</h2>';
+                $dump .= $this->getTriggers($db, $table);
+            }
+            break;
+        case 'create_view':
+            $dump .= '<h2>'
+                . __('Structure for view') . ' ' . htmlspecialchars($table)
+                . '</h2>';
+            $dump .= $this->getTableDef(
+                $db, $table, $crlf, $error_url, $do_relation, $do_comments, $do_mime,
+                $dates, true, true
+            );
+            break;
+        case 'stand_in':
+            $dump .=  '<h2>'
+                . __('Stand-in structure for view') . ' ' . htmlspecialchars($table)
+                . '</h2>';
+            // export a stand-in definition to resolve view dependencies
+            $dump .= $this->getTableDefStandIn($db, $table, $crlf);
+        } // end switch
+
+        return PMA_exportOutputHandler($dump);
+    }
+
+    /**
+     * Formats the definition for one column
+     *
+     * @param array $column      info about this column
+     * @param array $unique_keys unique keys of the table
+     *
+     * @return string Formatted column definition
+     */
+    protected function formatOneColumnDefinition(
+        $column, $unique_keys
+    ) {
+        $definition = '<tr class="print-category">';
+
+        $extracted_columnspec
+            = PMA_Util::extractColumnSpec($column['Type']);
+
+        $type = htmlspecialchars($extracted_columnspec['print_type']);
+        if (empty($type)) {
+            $type = ' ';
+        }
+
+        if (! isset($column['Default'])) {
+            if ($column['Null'] != 'NO') {
+                $column['Default'] = 'NULL';
+            }
+        }
+
+        $fmt_pre = '';
+        $fmt_post = '';
+        if (in_array($column['Field'], $unique_keys)) {
+            $fmt_pre = '<strong>' . $fmt_pre;
+            $fmt_post = $fmt_post . '</strong>';
+        }
+        if ($column['Key'] == 'PRI') {
+            $fmt_pre = '<em>' . $fmt_pre;
+            $fmt_post = $fmt_post . '</em>';
+        }
+        $definition .= '<td class="print">' . $fmt_pre
+            . htmlspecialchars($column['Field']) . $fmt_post . '</td>';
+        $definition .= '<td class="print">' . htmlspecialchars($type)
+            . '</td>';
+        $definition .= '<td class="print">'
+            . (($column['Null'] == '' || $column['Null'] == 'NO')
+                ? __('No')
+                : __('Yes'))
+            . '</td>';
+        $definition .= '<td class="print">'
+            . htmlspecialchars(
+                isset($column['Default'])
+                ? $column['Default']
+                : ''
+            )
+            . '</td>';
+
+        return $definition;
+    }
+}
+?>
\ No newline at end of file
diff --git a/phpmyadmin/libraries/plugins/export/ExportJson.class.php b/phpmyadmin/libraries/plugins/export/ExportJson.class.php
new file mode 100644
index 0000000..299e248
--- /dev/null
+++ b/phpmyadmin/libraries/plugins/export/ExportJson.class.php
@@ -0,0 +1,221 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * Set of methods used to build dumps of tables as JSON
+ *
+ * @package    PhpMyAdmin-Export
+ * @subpackage JSON
+ */
+if (! defined('PHPMYADMIN')) {
+    exit;
+}
+
+/* Get the export interface */
+require_once 'libraries/plugins/ExportPlugin.class.php';
+
+/**
+ * Handles the export for the JSON format
+ *
+ * @package    PhpMyAdmin-Export
+ * @subpackage JSON
+ */
+class ExportJson extends ExportPlugin
+{
+    /**
+     * Constructor
+     */
+    public function __construct()
+    {
+        $this->setProperties();
+    }
+
+    /**
+     * Sets the export JSON properties
+     *
+     * @return void
+     */
+    protected function setProperties()
+    {
+        $props = 'libraries/properties/';
+        include_once "$props/plugins/ExportPluginProperties.class.php";
+        include_once "$props/options/groups/OptionsPropertyRootGroup.class.php";
+        include_once "$props/options/groups/OptionsPropertyMainGroup.class.php";
+        include_once "$props/options/items/HiddenPropertyItem.class.php";
+
+        $exportPluginProperties = new ExportPluginProperties();
+        $exportPluginProperties->setText('JSON');
+        $exportPluginProperties->setExtension('json');
+        $exportPluginProperties->setMimeType('text/plain');
+        $exportPluginProperties->setOptionsText(__('Options'));
+
+        // create the root group that will be the options field for
+        // $exportPluginProperties
+        // this will be shown as "Format specific options"
+        $exportSpecificOptions = new OptionsPropertyRootGroup();
+        $exportSpecificOptions->setName("Format Specific Options");
+
+        // general options main group
+        $generalOptions = new OptionsPropertyMainGroup();
+        $generalOptions->setName("general_opts");
+        // create primary items and add them to the group
+        $leaf = new HiddenPropertyItem();
+        $leaf->setName("structure_or_data");
+        $generalOptions->addProperty($leaf);
+        // add the main group to the root group
+        $exportSpecificOptions->addProperty($generalOptions);
+
+        // set the options for the export plugin property item
+        $exportPluginProperties->setOptions($exportSpecificOptions);
+        $this->properties = $exportPluginProperties;
+    }
+
+    /**
+     * This method is called when any PluginManager to which the observer
+     * is attached calls PluginManager::notify()
+     *
+     * @param SplSubject $subject The PluginManager notifying the observer
+     *                            of an update.
+     *
+     * @return void
+     */
+    public function update (SplSubject $subject)
+    {
+    }
+
+    /**
+     * Outputs export header
+     *
+     * @return bool Whether it succeeded
+     */
+    public function exportHeader ()
+    {
+        PMA_exportOutputHandler(
+            '/**' . $GLOBALS['crlf']
+            . ' Export to JSON plugin for PHPMyAdmin' . $GLOBALS['crlf']
+            . ' @version 0.1' . $GLOBALS['crlf']
+            . ' */' . $GLOBALS['crlf'] . $GLOBALS['crlf']
+        );
+        return true;
+    }
+
+    /**
+     * Outputs export footer
+     *
+     * @return bool Whether it succeeded
+     */
+    public function exportFooter ()
+    {
+        return true;
+    }
+
+    /**
+     * Outputs database header
+     *
+     * @param string $db Database name
+     *
+     * @return bool Whether it succeeded
+     */
+    public function exportDBHeader ($db)
+    {
+        PMA_exportOutputHandler('// Database \'' . $db . '\'' . $GLOBALS['crlf']);
+        return true;
+    }
+
+    /**
+     * Outputs database footer
+     *
+     * @param string $db Database name
+     *
+     * @return bool Whether it succeeded
+     */
+    public function exportDBFooter ($db)
+    {
+        return true;
+    }
+
+    /**
+     * Outputs CREATE DATABASE statement
+     *
+     * @param string $db Database name
+     *
+     * @return bool Whether it succeeded
+     */
+    public function exportDBCreate($db)
+    {
+        return true;
+    }
+
+    /**
+     * Outputs the content of a table in JSON format
+     *
+     * @param string $db        database name
+     * @param string $table     table name
+     * @param string $crlf      the end of line sequence
+     * @param string $error_url the url to go back in case of error
+     * @param string $sql_query SQL query for obtaining data
+     *
+     * @return bool Whether it succeeded
+     */
+    public function exportData($db, $table, $crlf, $error_url, $sql_query)
+    {
+        $result = PMA_DBI_query($sql_query, null, PMA_DBI_QUERY_UNBUFFERED);
+        $columns_cnt = PMA_DBI_num_fields($result);
+
+        // Get field information
+        $fields_meta = PMA_DBI_get_fields_meta($result);
+
+        for ($i = 0; $i < $columns_cnt; $i++) {
+            $columns[$i] = stripslashes(PMA_DBI_field_name($result, $i));
+        }
+        unset($i);
+
+        $buffer = '';
+        $record_cnt = 0;
+        while ($record = PMA_DBI_fetch_row($result)) {
+
+            $record_cnt++;
+
+            // Output table name as comment if this is the first record of the table
+            if ($record_cnt == 1) {
+                $buffer .= '// ' . $db . '.' . $table . $crlf . $crlf;
+                $buffer .= '[{';
+            } else {
+                $buffer .= ', {';
+            }
+
+            for ($i = 0; $i < $columns_cnt; $i++) {
+                $isLastLine = ($i + 1 >= $columns_cnt);
+                $column = $columns[$i];
+                if (is_null($record[$i])) {
+                    $buffer .= '"' . addslashes($column)
+                        . '": null'
+                        . (! $isLastLine ? ',' : '');
+                } elseif ($fields_meta[$i]->numeric) {
+                    $buffer .= '"' . addslashes($column)
+                        . '": '
+                        . $record[$i]
+                        . (! $isLastLine ? ',' : '');
+                } else {
+                    $buffer .= '"' . addslashes($column)
+                        . '": "'
+                        . addslashes($record[$i])
+                        . '"'
+                        . (! $isLastLine ? ',' : '');
+                }
+            }
+
+            $buffer .= '}';
+        }
+
+        if ($record_cnt) {
+            $buffer .=  ']';
+        }
+        if (! PMA_exportOutputHandler($buffer)) {
+            return false;
+        }
+
+        PMA_DBI_free_result($result);
+        return true;
+    }
+}
+?>
\ No newline at end of file
diff --git a/phpmyadmin/libraries/plugins/export/ExportLatex.class.php b/phpmyadmin/libraries/plugins/export/ExportLatex.class.php
new file mode 100644
index 0000000..0f5c953
--- /dev/null
+++ b/phpmyadmin/libraries/plugins/export/ExportLatex.class.php
@@ -0,0 +1,655 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * Set of methods used to build dumps of tables as Latex
+ *
+ * @package    PhpMyAdmin-Export
+ * @subpackage Latex
+ */
+if (! defined('PHPMYADMIN')) {
+    exit;
+}
+
+/* Get the export interface */
+require_once 'libraries/plugins/ExportPlugin.class.php';
+
+/**
+ * Handles the export for the Latex format
+ *
+ * @package    PhpMyAdmin-Export
+ * @subpackage Latex
+ */
+class ExportLatex extends ExportPlugin
+{
+    /**
+     * Constructor
+     */
+    public function __construct()
+    {
+        // initialize the specific export sql variables
+        $this->initSpecificVariables();
+
+        $this->setProperties();
+    }
+
+    /**
+     * Initialize the local variables that are used for export Latex
+     *
+     * @return void
+     */
+    protected function initSpecificVariables()
+    {
+        /* Messages used in default captions */
+        $GLOBALS['strLatexContent'] = __('Content of table @TABLE@');
+        $GLOBALS['strLatexContinued'] = __('(continued)');
+        $GLOBALS['strLatexStructure'] = __('Structure of table @TABLE@');
+    }
+
+    /**
+     * Sets the export Latex properties
+     *
+     * @return void
+     */
+    protected function setProperties()
+    {
+        global $plugin_param;
+        $hide_structure = false;
+        if ($plugin_param['export_type'] == 'table'
+            && ! $plugin_param['single_table']
+        ) {
+            $hide_structure = true;
+        }
+
+        $props = 'libraries/properties/';
+        include_once "$props/plugins/ExportPluginProperties.class.php";
+        include_once "$props/options/groups/OptionsPropertyRootGroup.class.php";
+        include_once "$props/options/groups/OptionsPropertyMainGroup.class.php";
+        include_once "$props/options/items/BoolPropertyItem.class.php";
+        include_once "$props/options/items/RadioPropertyItem.class.php";
+        include_once "$props/options/items/TextPropertyItem.class.php";
+
+        $exportPluginProperties = new ExportPluginProperties();
+        $exportPluginProperties->setText('LaTeX');
+        $exportPluginProperties->setExtension('tex');
+        $exportPluginProperties->setMimeType('application/x-tex');
+        $exportPluginProperties->setOptionsText(__('Options'));
+
+        // create the root group that will be the options field for
+        // $exportPluginProperties
+        // this will be shown as "Format specific options"
+        $exportSpecificOptions = new OptionsPropertyRootGroup();
+        $exportSpecificOptions->setName("Format Specific Options");
+
+        // general options main group
+        $generalOptions = new OptionsPropertyMainGroup();
+        $generalOptions->setName("general_opts");
+        // create primary items and add them to the group
+        $leaf = new BoolPropertyItem();
+        $leaf->setName("caption");
+        $leaf->setText(__('Include table caption'));
+        $generalOptions->addProperty($leaf);
+        // add the main group to the root group
+        $exportSpecificOptions->addProperty($generalOptions);
+
+        // what to dump (structure/data/both) main group
+        $dumpWhat = new OptionsPropertyMainGroup();
+        $dumpWhat->setName("dump_what");
+        $dumpWhat->setText(__('Dump table'));
+        // create primary items and add them to the group
+        $leaf = new RadioPropertyItem();
+        $leaf->setName("structure_or_data");
+        $leaf->setValues(
+            array(
+                'structure' => __('structure'),
+                'data' => __('data'),
+                'structure_and_data' => __('structure and data')
+            )
+        );
+        $dumpWhat->addProperty($leaf);
+        // add the main group to the root group
+        $exportSpecificOptions->addProperty($dumpWhat);
+
+        // structure options main group
+        if (! $hide_structure) {
+            $structureOptions = new OptionsPropertyMainGroup();
+            $structureOptions->setName("structure");
+            $structureOptions->setText(__('Object creation options'));
+            $structureOptions->setForce('data');
+            // create primary items and add them to the group
+            $leaf = new TextPropertyItem();
+            $leaf->setName("structure_caption");
+            $leaf->setText(__('Table caption'));
+            $leaf->setDoc('faq6-27');
+            $structureOptions->addProperty($leaf);
+            $leaf = new TextPropertyItem();
+            $leaf->setName("structure_continued_caption");
+            $leaf->setText(__('Table caption (continued)'));
+            $leaf->setDoc('faq6-27');
+            $structureOptions->addProperty($leaf);
+            $leaf = new TextPropertyItem();
+            $leaf->setName("structure_label");
+            $leaf->setText(__('Label key'));
+            $leaf->setDoc('faq6-27');
+            $structureOptions->addProperty($leaf);
+            if (! empty($GLOBALS['cfgRelation']['relation'])) {
+                $leaf = new BoolPropertyItem();
+                $leaf->setName("relation");
+                $leaf->setText(__('Display foreign key relationships'));
+                $structureOptions->addProperty($leaf);
+            }
+            $leaf = new BoolPropertyItem();
+            $leaf->setName("comments");
+            $leaf->setText(__('Display comments'));
+            $structureOptions->addProperty($leaf);
+            if (! empty($GLOBALS['cfgRelation']['mimework'])) {
+                $leaf = new BoolPropertyItem();
+                $leaf->setName("mime");
+                $leaf->setText(__('Display MIME types'));
+                $structureOptions->addProperty($leaf);
+            }
+            // add the main group to the root group
+            $exportSpecificOptions->addProperty($structureOptions);
+        }
+
+        // data options main group
+        $dataOptions = new OptionsPropertyMainGroup();
+        $dataOptions->setName("data");
+        $dataOptions->setText(__('Data dump options'));
+        $dataOptions->setForce('structure');
+        // create primary items and add them to the group
+        $leaf = new BoolPropertyItem();
+        $leaf->setName("columns");
+        $leaf->setText(__('Put columns names in the first row'));
+        $dataOptions->addProperty($leaf);
+        $leaf = new TextPropertyItem();
+        $leaf->setName("data_caption");
+        $leaf->setText(__('Table caption'));
+        $leaf->setDoc('faq6-27');
+        $dataOptions->addProperty($leaf);
+        $leaf = new TextPropertyItem();
+        $leaf->setName("data_continued_caption");
+        $leaf->setText(__('Table caption (continued)'));
+        $leaf->setDoc('faq6-27');
+        $dataOptions->addProperty($leaf);
+        $leaf = new TextPropertyItem();
+        $leaf->setName("data_label");
+        $leaf->setText(__('Label key'));
+        $leaf->setDoc('faq6-27');
+        $dataOptions->addProperty($leaf);
+        $leaf = new TextPropertyItem();
+        $leaf->setName('null');
+        $leaf->setText(__('Replace NULL with:'));
+        $dataOptions->addProperty($leaf);
+        // add the main group to the root group
+        $exportSpecificOptions->addProperty($dataOptions);
+
+        // set the options for the export plugin property item
+        $exportPluginProperties->setOptions($exportSpecificOptions);
+        $this->properties = $exportPluginProperties;
+    }
+
+    /**
+     * This method is called when any PluginManager to which the observer
+     * is attached calls PluginManager::notify()
+     *
+     * @param SplSubject $subject The PluginManager notifying the observer
+     *                            of an update.
+     *
+     * @return void
+     */
+    public function update (SplSubject $subject)
+    {
+    }
+
+    /**
+     * Outputs export header
+     *
+     * @return bool Whether it succeeded
+     */
+    public function exportHeader ()
+    {
+        global $crlf;
+        global $cfg;
+
+        $head = '% phpMyAdmin LaTeX Dump' . $crlf
+            . '% version ' . PMA_VERSION . $crlf
+            . '% http://www.phpmyadmin.net' . $crlf
+            . '%' . $crlf
+            . '% ' . __('Host') . ': ' . $cfg['Server']['host'];
+        if (! empty($cfg['Server']['port'])) {
+             $head .= ':' . $cfg['Server']['port'];
+        }
+        $head .= $crlf
+            . '% ' . __('Generation Time') . ': '
+            . PMA_Util::localisedDate() . $crlf
+            . '% ' . __('Server version') . ': ' . PMA_MYSQL_STR_VERSION . $crlf
+            . '% ' . __('PHP Version') . ': ' . phpversion() . $crlf;
+        return PMA_exportOutputHandler($head);
+    }
+
+    /**
+     * Outputs export footer
+     *
+     * @return bool Whether it succeeded
+     */
+    public function exportFooter ()
+    {
+        return true;
+    }
+
+    /**
+     * Outputs database header
+     *
+     * @param string $db Database name
+     *
+     * @return bool Whether it succeeded
+     */
+    public function exportDBHeader ($db)
+    {
+        global $crlf;
+        $head = '% ' . $crlf
+            . '% ' . __('Database') . ': ' . '\'' . $db . '\'' . $crlf
+            . '% ' . $crlf;
+        return PMA_exportOutputHandler($head);
+    }
+
+    /**
+     * Outputs database footer
+     *
+     * @param string $db Database name
+     *
+     * @return bool Whether it succeeded
+     */
+    public function exportDBFooter ($db)
+    {
+        return true;
+    }
+
+    /**
+     * Outputs CREATE DATABASE statement
+     *
+     * @param string $db Database name
+     *
+     * @return bool Whether it succeeded
+     */
+    public function exportDBCreate($db)
+    {
+        return true;
+    }
+
+    /**
+     * Outputs the content of a table in JSON format
+     *
+     * @param string $db        database name
+     * @param string $table     table name
+     * @param string $crlf      the end of line sequence
+     * @param string $error_url the url to go back in case of error
+     * @param string $sql_query SQL query for obtaining data
+     *
+     * @return bool Whether it succeeded
+     */
+    public function exportData($db, $table, $crlf, $error_url, $sql_query)
+    {
+        $result      = PMA_DBI_try_query($sql_query, null, PMA_DBI_QUERY_UNBUFFERED);
+
+        $columns_cnt = PMA_DBI_num_fields($result);
+        for ($i = 0; $i < $columns_cnt; $i++) {
+            $columns[$i] = PMA_DBI_field_name($result, $i);
+        }
+        unset($i);
+
+        $buffer = $crlf . '%' . $crlf . '% ' . __('Data') . ': ' . $table
+            . $crlf . '%' . $crlf . ' \\begin{longtable}{|';
+
+        for ($index = 0; $index < $columns_cnt; $index++) {
+            $buffer .= 'l|';
+        }
+        $buffer .= '} ' . $crlf ;
+
+        $buffer .= ' \\hline \\endhead \\hline \\endfoot \\hline ' . $crlf;
+        if (isset($GLOBALS['latex_caption'])) {
+            $buffer .= ' \\caption{'
+                . PMA_Util::expandUserString(
+                    $GLOBALS['latex_data_caption'],
+                    array(
+                        'texEscape',
+                        get_class($this),
+                        'libraries/plugins/export/' . get_class($this) . ".class.php"
+                    ),
+                    array('table' => $table, 'database' => $db)
+                )
+                . '} \\label{'
+                . PMA_Util::expandUserString(
+                    $GLOBALS['latex_data_label'],
+                    null,
+                    array('table' => $table, 'database' => $db)
+                )
+                . '} \\\\';
+        }
+        if (! PMA_exportOutputHandler($buffer)) {
+            return false;
+        }
+
+        // show column names
+        if (isset($GLOBALS['latex_columns'])) {
+            $buffer = '\\hline ';
+            for ($i = 0; $i < $columns_cnt; $i++) {
+                $buffer .= '\\multicolumn{1}{|c|}{\\textbf{'
+                    . self::texEscape(stripslashes($columns[$i])) . '}} & ';
+            }
+
+            $buffer = substr($buffer, 0, -2) . '\\\\ \\hline \hline ';
+            if (! PMA_exportOutputHandler($buffer . ' \\endfirsthead ' . $crlf)) {
+                return false;
+            }
+            if (isset($GLOBALS['latex_caption'])) {
+                if (! PMA_exportOutputHandler(
+                    '\\caption{'
+                    . PMA_Util::expandUserString(
+                        $GLOBALS['latex_data_continued_caption'],
+                        array(
+                            'texEscape',
+                            get_class($this),
+                            'libraries/plugins/export/'
+                            . get_class($this) . ".class.php"
+                        ),
+                        array('table' => $table, 'database' => $db)
+                    )
+                    . '} \\\\ '
+                )) {
+                    return false;
+                }
+            }
+            if (! PMA_exportOutputHandler($buffer . '\\endhead \\endfoot' . $crlf)) {
+                return false;
+            }
+        } else {
+            if (! PMA_exportOutputHandler('\\\\ \hline')) {
+                return false;
+            }
+        }
+
+        // print the whole table
+        while ($record = PMA_DBI_fetch_assoc($result)) {
+            $buffer = '';
+            // print each row
+            for ($i = 0; $i < $columns_cnt; $i++) {
+                if ((! function_exists('is_null')
+                    || ! is_null($record[$columns[$i]]))
+                    && isset($record[$columns[$i]])
+                ) {
+                    $column_value = self::texEscape(
+                        stripslashes($record[$columns[$i]])
+                    );
+                } else {
+                    $column_value = $GLOBALS['latex_null'];
+                }
+
+                // last column ... no need for & character
+                if ($i == ($columns_cnt - 1)) {
+                    $buffer .= $column_value;
+                } else {
+                    $buffer .= $column_value . " & ";
+                }
+            }
+            $buffer .= ' \\\\ \\hline ' . $crlf;
+            if (! PMA_exportOutputHandler($buffer)) {
+                return false;
+            }
+        }
+
+        $buffer = ' \\end{longtable}' . $crlf;
+        if (! PMA_exportOutputHandler($buffer)) {
+            return false;
+        }
+
+        PMA_DBI_free_result($result);
+        return true;
+    } // end getTableLaTeX
+
+    /**
+     * Outputs table's structure
+     *
+     * @param string $db          database name
+     * @param string $table       table name
+     * @param string $crlf        the end of line sequence
+     * @param string $error_url   the url to go back in case of error
+     * @param string $export_mode 'create_table', 'triggers', 'create_view',
+     *                            'stand_in'
+     * @param string $export_type 'server', 'database', 'table'
+     * @param bool   $do_relation whether to include relation comments
+     * @param bool   $do_comments whether to include the pmadb-style column
+     *                                comments as comments in the structure;
+     *                                this is deprecated but the parameter is
+     *                                left here because export.php calls
+     *                                exportStructure() also for other
+     *                                export types which use this parameter
+     * @param bool   $do_mime     whether to include mime comments
+     * @param bool   $dates       whether to include creation/update/check dates
+     *
+     * @return bool Whether it succeeded
+     */
+    public function exportStructure(
+        $db,
+        $table,
+        $crlf,
+        $error_url,
+        $export_mode,
+        $export_type,
+        $do_relation = false,
+        $do_comments = false,
+        $do_mime = false,
+        $dates = false
+    ) {
+        global $cfgRelation;
+
+        /* We do not export triggers */
+        if ($export_mode == 'triggers') {
+            return true;
+        }
+
+        /**
+         * Get the unique keys in the table
+         */
+        $unique_keys = array();
+        $keys = PMA_DBI_get_table_indexes($db, $table);
+        foreach ($keys as $key) {
+            if ($key['Non_unique'] == 0) {
+                $unique_keys[] = $key['Column_name'];
+            }
+        }
+
+        /**
+         * Gets fields properties
+         */
+        PMA_DBI_select_db($db);
+
+        // Check if we can use Relations
+        if ($do_relation && ! empty($cfgRelation['relation'])) {
+            // Find which tables are related with the current one and write it in
+            // an array
+            $res_rel = PMA_getForeigners($db, $table);
+
+            if ($res_rel && count($res_rel) > 0) {
+                $have_rel = true;
+            } else {
+                $have_rel = false;
+            }
+        } else {
+               $have_rel = false;
+        } // end if
+
+        /**
+         * Displays the table structure
+         */
+        $buffer      = $crlf . '%' . $crlf . '% ' . __('Structure') . ': ' . $table
+            . $crlf . '%' . $crlf . ' \\begin{longtable}{';
+        if (! PMA_exportOutputHandler($buffer)) {
+            return false;
+        }
+
+        $columns_cnt = 4;
+        $alignment = '|l|c|c|c|';
+        if ($do_relation && $have_rel) {
+            $columns_cnt++;
+            $alignment .= 'l|';
+        }
+        if ($do_comments) {
+            $columns_cnt++;
+            $alignment .= 'l|';
+        }
+        if ($do_mime && $cfgRelation['mimework']) {
+            $columns_cnt++;
+            $alignment .='l|';
+        }
+        $buffer = $alignment . '} ' . $crlf ;
+
+        $header = ' \\hline ';
+        $header .= '\\multicolumn{1}{|c|}{\\textbf{' . __('Column')
+            . '}} & \\multicolumn{1}{|c|}{\\textbf{' . __('Type')
+            . '}} & \\multicolumn{1}{|c|}{\\textbf{' . __('Null')
+            . '}} & \\multicolumn{1}{|c|}{\\textbf{' . __('Default') . '}}';
+        if ($do_relation && $have_rel) {
+            $header .= ' & \\multicolumn{1}{|c|}{\\textbf{' . __('Links to') . '}}';
+        }
+        if ($do_comments) {
+            $header .= ' & \\multicolumn{1}{|c|}{\\textbf{' . __('Comments') . '}}';
+            $comments = PMA_getComments($db, $table);
+        }
+        if ($do_mime && $cfgRelation['mimework']) {
+            $header .= ' & \\multicolumn{1}{|c|}{\\textbf{MIME}}';
+            $mime_map = PMA_getMIME($db, $table, true);
+        }
+
+        // Table caption for first page and label
+        if (isset($GLOBALS['latex_caption'])) {
+            $buffer .= ' \\caption{'
+                . PMA_Util::expandUserString(
+                    $GLOBALS['latex_structure_caption'],
+                    array(
+                        'texEscape',
+                        get_class($this),
+                        'libraries/plugins/export/' . get_class($this) . ".class.php"
+                    ),
+                    array('table' => $table, 'database' => $db)
+                )
+                . '} \\label{'
+                . PMA_Util::expandUserString(
+                    $GLOBALS['latex_structure_label'],
+                    null,
+                    array('table' => $table, 'database' => $db)
+                )
+                . '} \\\\' . $crlf;
+        }
+        $buffer .= $header . ' \\\\ \\hline \\hline' . $crlf
+            . '\\endfirsthead' . $crlf;
+        // Table caption on next pages
+        if (isset($GLOBALS['latex_caption'])) {
+            $buffer .= ' \\caption{'
+                . PMA_Util::expandUserString(
+                    $GLOBALS['latex_structure_continued_caption'],
+                    array(
+                        'texEscape',
+                        get_class($this),
+                        'libraries/plugins/export/' . get_class($this) . ".class.php"
+                    ),
+                    array('table' => $table, 'database' => $db)
+                )
+                . '} \\\\ ' . $crlf;
+        }
+        $buffer .= $header . ' \\\\ \\hline \\hline \\endhead \\endfoot ' . $crlf;
+
+        if (! PMA_exportOutputHandler($buffer)) {
+            return false;
+        }
+
+        $fields = PMA_DBI_get_columns($db, $table);
+        foreach ($fields as $row) {
+            $extracted_columnspec
+                = PMA_Util::extractColumnSpec(
+                    $row['Type']
+                );
+            $type = $extracted_columnspec['print_type'];
+            if (empty($type)) {
+                $type = ' ';
+            }
+
+            if (! isset($row['Default'])) {
+                if ($row['Null'] != 'NO') {
+                    $row['Default'] = 'NULL';
+                }
+            }
+
+            $field_name = $row['Field'];
+
+            $local_buffer = $field_name . "\000" . $type . "\000"
+                . (($row['Null'] == '' || $row['Null'] == 'NO')
+                    ? __('No') : __('Yes'))
+                . "\000" . (isset($row['Default']) ? $row['Default'] : '');
+
+            if ($do_relation && $have_rel) {
+                $local_buffer .= "\000";
+                if (isset($res_rel[$field_name])) {
+                    $local_buffer .= $res_rel[$field_name]['foreign_table'] . ' ('
+                        . $res_rel[$field_name]['foreign_field'] . ')';
+                }
+            }
+            if ($do_comments && $cfgRelation['commwork']) {
+                $local_buffer .= "\000";
+                if (isset($comments[$field_name])) {
+                    $local_buffer .= $comments[$field_name];
+                }
+            }
+            if ($do_mime && $cfgRelation['mimework']) {
+                $local_buffer .= "\000";
+                if (isset($mime_map[$field_name])) {
+                    $local_buffer .= str_replace(
+                        '_',
+                        '/',
+                        $mime_map[$field_name]['mimetype']
+                    );
+                }
+            }
+            $local_buffer = self::texEscape($local_buffer);
+            if ($row['Key']=='PRI') {
+                $pos=strpos($local_buffer, "\000");
+                $local_buffer = '\\textit{'
+                    . substr($local_buffer, 0, $pos)
+                    . '}' . substr($local_buffer, $pos);
+            }
+            if (in_array($field_name, $unique_keys)) {
+                $pos=strpos($local_buffer, "\000");
+                $local_buffer = '\\textbf{'
+                    . substr($local_buffer, 0, $pos)
+                    . '}' . substr($local_buffer, $pos);
+            }
+            $buffer = str_replace("\000", ' & ', $local_buffer);
+            $buffer .= ' \\\\ \\hline ' . $crlf;
+
+            if (! PMA_exportOutputHandler($buffer)) {
+                return false;
+            }
+        } // end while
+
+        $buffer = ' \\end{longtable}' . $crlf;
+        return PMA_exportOutputHandler($buffer);
+    } // end of the 'exportStructure' method
+
+    /**
+     * Escapes some special characters for use in TeX/LaTeX
+     *
+     * @param string $string the string to convert
+     *
+     * @return string the converted string with escape codes
+     */
+    public static function texEscape($string)
+    {
+        $escape = array('$', '%', '{', '}',  '&',  '#', '_', '^');
+        $cnt_escape = count($escape);
+        for ($k = 0; $k < $cnt_escape; $k++) {
+            $string = str_replace($escape[$k], '\\' . $escape[$k], $string);
+        }
+        return $string;
+    }
+}
+?>
diff --git a/phpmyadmin/libraries/plugins/export/ExportMediawiki.class.php b/phpmyadmin/libraries/plugins/export/ExportMediawiki.class.php
new file mode 100644
index 0000000..89afe71
--- /dev/null
+++ b/phpmyadmin/libraries/plugins/export/ExportMediawiki.class.php
@@ -0,0 +1,364 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * Set of functions used to build MediaWiki dumps of tables
+ *
+ * @package    PhpMyAdmin-Export
+ * @subpackage MediaWiki
+ */
+if (! defined('PHPMYADMIN')) {
+    exit;
+}
+
+/* Get the export interface */
+require_once 'libraries/plugins/ExportPlugin.class.php';
+
+/**
+ * Handles the export for the MediaWiki class
+ *
+ * @package    PhpMyAdmin-Export
+ * @subpackage MediaWiki
+ */
+class ExportMediawiki extends ExportPlugin
+{
+    /**
+     * Constructor
+     */
+    public function __construct()
+    {
+        $this->setProperties();
+    }
+
+    /**
+     * Sets the export MediaWiki properties
+     *
+     * @return void
+     */
+    protected function setProperties()
+    {
+        $props = 'libraries/properties/';
+        include_once "$props/plugins/ExportPluginProperties.class.php";
+        include_once "$props/options/groups/OptionsPropertyRootGroup.class.php";
+        include_once "$props/options/groups/OptionsPropertyMainGroup.class.php";
+        include_once "$props/options/groups/OptionsPropertySubgroup.class.php";
+        include_once "$props/options/items/MessageOnlyPropertyItem.class.php";
+        include_once "$props/options/items/RadioPropertyItem.class.php";
+        include_once "$props/options/items/BoolPropertyItem.class.php";
+
+        $exportPluginProperties = new ExportPluginProperties();
+        $exportPluginProperties->setText('MediaWiki Table');
+        $exportPluginProperties->setExtension('mediawiki');
+        $exportPluginProperties->setMimeType('text/plain');
+        $exportPluginProperties->setOptionsText(__('Options'));
+
+        // create the root group that will be the options field for
+        // $exportPluginProperties
+        // this will be shown as "Format specific options"
+        $exportSpecificOptions = new OptionsPropertyRootGroup();
+        $exportSpecificOptions->setName("Format Specific Options");
+
+        // general options main group
+        $generalOptions = new OptionsPropertyMainGroup();
+        $generalOptions->setName("general_opts");
+        $generalOptions->setText(__('Dump table'));
+
+        // what to dump (structure/data/both)
+        $subgroup = new OptionsPropertySubgroup();
+        $subgroup->setName("dump_table");
+        $subgroup->setText("Dump table");
+        $leaf = new RadioPropertyItem();
+        $leaf->setName('structure_or_data');
+        $leaf->setValues(
+            array(
+                'structure' => __('structure'),
+                'data' => __('data'),
+                'structure_and_data' => __('structure and data')
+            )
+        );
+        $subgroup->setSubgroupHeader($leaf);
+        $generalOptions->addProperty($subgroup);
+
+        // export table name
+        $leaf = new BoolPropertyItem();
+        $leaf->setName("caption");
+        $leaf->setText(__('Export table names'));
+        $generalOptions->addProperty($leaf);
+
+        // export table headers
+        $leaf = new BoolPropertyItem();
+        $leaf->setName("headers");
+        $leaf->setText(__('Export table headers'));
+        $generalOptions->addProperty($leaf);
+        //add the main group to the root group
+        $exportSpecificOptions->addProperty($generalOptions);
+
+        // set the options for the export plugin property item
+        $exportPluginProperties->setOptions($exportSpecificOptions);
+        $this->properties = $exportPluginProperties;
+    }
+
+    /**
+     * This method is called when any PluginManager to which the observer
+     * is attached calls PluginManager::notify()
+     *
+     * @param SplSubject $subject The PluginManager notifying the observer
+     *                            of an update.
+     *
+     * @return void
+     */
+    public function update (SplSubject $subject)
+    {
+    }
+
+    /**
+     * Outputs export header
+     *
+     * @return bool Whether it succeeded
+     */
+    public function exportHeader ()
+    {
+        return true;
+    }
+
+    /**
+     * Outputs export footer
+     *
+     * @return bool Whether it succeeded
+     */
+    public function exportFooter ()
+    {
+        return true;
+    }
+
+    /**
+     * Outputs database header
+     *
+     * @param string $db Database name
+     *
+     * @return bool Whether it succeeded
+     */
+    public function exportDBHeader ($db)
+    {
+        return true;
+    }
+
+    /**
+     * Outputs database footer
+     *
+     * @param string $db Database name
+     *
+     * @return bool Whether it succeeded
+     */
+    public function exportDBFooter ($db)
+    {
+        return true;
+    }
+
+    /**
+     * Outputs CREATE DATABASE statement
+     *
+     * @param string $db Database name
+     *
+     * @return bool Whether it succeeded
+     */
+    public function exportDBCreate($db)
+    {
+        return true;
+    }
+
+    /**
+     * Outputs table's structure
+     *
+     * @param string $db          database name
+     * @param string $table       table name
+     * @param string $crlf        the end of line sequence
+     * @param string $error_url   the url to go back in case of error
+     * @param string $export_mode 'create_table','triggers','create_view',
+     *                            'stand_in'
+     * @param string $export_type 'server', 'database', 'table'
+     * @param bool   $do_relation whether to include relation comments
+     * @param bool   $do_comments whether to include the pmadb-style column
+     *                            comments as comments in the structure; this is
+     *                            deprecated but the parameter is left here
+     *                            because export.php calls exportStructure()
+     *                            also for other export types which use this
+     *                            parameter
+     * @param bool   $do_mime     whether to include mime comments
+     * @param bool   $dates       whether to include creation/update/check dates
+     *
+     * @return bool               Whether it succeeded
+     */
+    public function exportStructure(
+        $db,
+        $table,
+        $crlf,
+        $error_url,
+        $export_mode,
+        $export_type,
+        $do_relation = false,
+        $do_comments = false,
+        $do_mime = false,
+        $dates = false
+    ) {
+        switch($export_mode) {
+        case 'create_table':
+            $columns = PMA_DBI_get_columns($db, $table);
+            $columns = array_values($columns);
+            $row_cnt = count($columns);
+
+            // Print structure comment
+            $output = $this->_exportComment(
+                "Table structure for "
+                . PMA_Util::backquote($table)
+            );
+
+            // Begin the table construction
+            $output .= "{| class=\"wikitable\" style=\"text-align:center;\""
+                     . $this->_exportCRLF();
+
+            // Add the table name
+            if ($GLOBALS['mediawiki_caption']) {
+                $output .= "|+'''" . $table . "'''" . $this->_exportCRLF();
+            }
+
+            // Add the table headers
+            if ($GLOBALS['mediawiki_headers']) {
+                $output .= "|- style=\"background:#ffdead;\"" . $this->_exportCRLF();
+                $output .= "! style=\"background:#ffffff\" | "
+                    . $this->_exportCRLF();
+                for ($i = 0; $i < $row_cnt; ++$i) {
+                    $output .= " | " . $columns[$i]['Field']. $this->_exportCRLF();
+                }
+            }
+
+            // Add the table structure
+            $output .= "|-" .  $this->_exportCRLF();
+            $output .= "! Type" . $this->_exportCRLF();
+            for ($i = 0; $i < $row_cnt; ++$i) {
+                $output .= " | " . $columns[$i]['Type'] . $this->_exportCRLF();
+            }
+
+            $output .= "|-" .  $this->_exportCRLF();
+            $output .= "! Null" . $this->_exportCRLF();
+            for ($i = 0; $i < $row_cnt; ++$i) {
+                $output .= " | " . $columns[$i]['Null'] . $this->_exportCRLF();
+            }
+
+            $output .= "|-" .  $this->_exportCRLF();
+            $output .= "! Default" . $this->_exportCRLF();
+            for ($i = 0; $i < $row_cnt; ++$i) {
+                $output .= " | " . $columns[$i]['Default'] . $this->_exportCRLF();
+            }
+
+            $output .= "|-" .  $this->_exportCRLF();
+            $output .= "! Extra" . $this->_exportCRLF();
+            for ($i = 0; $i < $row_cnt; ++$i) {
+                $output .= " | " . $columns[$i]['Extra'] . $this->_exportCRLF();
+            }
+
+            $output .= "|}" .  str_repeat($this->_exportCRLF(), 2);
+            break;
+        } // end switch
+
+        return PMA_exportOutputHandler($output);
+    }
+
+    /**
+     * Outputs the content of a table in MediaWiki format
+     *
+     * @param string $db        database name
+     * @param string $table     table name
+     * @param string $crlf      the end of line sequence
+     * @param string $error_url the url to go back in case of error
+     * @param string $sql_query SQL query for obtaining data
+     *
+     * @return bool             Whether it succeeded
+     */
+    public function exportData(
+        $db,
+        $table,
+        $crlf,
+        $error_url,
+        $sql_query
+    ) {
+        // Print data comment
+        $output = $this->_exportComment(
+            "Table data for ". PMA_Util::backquote($table)
+        );
+
+        // Begin the table construction
+        // Use the "wikitable" class for style
+        // Use the "sortable"  class for allowing tables to be sorted by column
+        $output .= "{| class=\"wikitable sortable\" style=\"text-align:center;\""
+            . $this->_exportCRLF();
+
+        // Add the table name
+        if ($GLOBALS['mediawiki_caption']) {
+            $output .= "|+'''" . $table . "'''" . $this->_exportCRLF();
+        }
+
+        // Add the table headers
+        if ($GLOBALS['mediawiki_headers']) {
+            // Get column names
+            $column_names = PMA_DBI_get_column_names($db, $table);
+
+            // Add column names as table headers
+            if ( ! is_null($column_names) ) {
+                // Use '|-' for separating rows
+                $output .= "|-" . $this->_exportCRLF();
+
+                // Use '!' for separating table headers
+                foreach ($column_names as $column) {
+                    $output .= " ! " . $column . "" . $this->_exportCRLF();
+                }
+            }
+        }
+
+        // Get the table data from the database
+        $result = PMA_DBI_query($sql_query, null, PMA_DBI_QUERY_UNBUFFERED);
+        $fields_cnt = PMA_DBI_num_fields($result);
+
+        while ($row = PMA_DBI_fetch_row($result)) {
+            $output .= "|-" . $this->_exportCRLF();
+
+            // Use '|' for separating table columns
+            for ($i = 0; $i < $fields_cnt; ++ $i) {
+                $output .= " | " . $row[$i] . "" . $this->_exportCRLF();
+            }
+        }
+
+        // End table construction
+        $output .= "|}" . str_repeat($this->_exportCRLF(), 2);
+        return PMA_exportOutputHandler($output);
+    }
+
+    /**
+     * Outputs comments containing info about the exported tables
+     *
+     * @param string $text Text of comment
+     *
+     * @return string The formatted comment
+     */
+    private function _exportComment($text = '')
+    {
+        // see http://www.mediawiki.org/wiki/Help:Formatting
+        $comment = $this->_exportCRLF();
+        $comment .= '<!--' . $this->_exportCRLF();
+        $comment .= $text  . $this->_exportCRLF();
+        $comment .= '-->'  . str_repeat($this->_exportCRLF(), 2);
+
+        return $comment;
+    }
+
+    /**
+     * Outputs CRLF
+     *
+     * @return string CRLF
+     */
+    private function _exportCRLF()
+    {
+        // The CRLF expected by the mediawiki format is "\n"
+        return "\n";
+    }
+}
+?>
diff --git a/phpmyadmin/libraries/plugins/export/ExportOds.class.php b/phpmyadmin/libraries/plugins/export/ExportOds.class.php
new file mode 100644
index 0000000..b1e9f91
--- /dev/null
+++ b/phpmyadmin/libraries/plugins/export/ExportOds.class.php
@@ -0,0 +1,334 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * Set of functions used to build OpenDocument Spreadsheet dumps of tables
+ *
+ * @package    PhpMyAdmin-Export
+ * @subpackage ODS
+ */
+if (! defined('PHPMYADMIN')) {
+    exit;
+}
+
+/* Get the export interface */
+require_once 'libraries/plugins/ExportPlugin.class.php';
+
+$GLOBALS['ods_buffer'] = '';
+require_once 'libraries/opendocument.lib.php';
+
+/**
+ * Handles the export for the ODS class
+ *
+ * @package    PhpMyAdmin-Export
+ * @subpackage ODS
+ */
+class ExportOds extends ExportPlugin
+{
+    /**
+     * Constructor
+     */
+    public function __construct()
+    {
+        $this->setProperties();
+    }
+
+    /**
+     * Sets the export ODS properties
+     *
+     * @return void
+     */
+    protected function setProperties()
+    {
+        $props = 'libraries/properties/';
+        include_once "$props/plugins/ExportPluginProperties.class.php";
+        include_once "$props/options/groups/OptionsPropertyRootGroup.class.php";
+        include_once "$props/options/groups/OptionsPropertyMainGroup.class.php";
+        include_once "$props/options/items/TextPropertyItem.class.php";
+        include_once "$props/options/items/BoolPropertyItem.class.php";
+        include_once "$props/options/items/HiddenPropertyItem.class.php";
+
+        $exportPluginProperties = new ExportPluginProperties();
+        $exportPluginProperties->setText('OpenDocument Spreadsheet');
+        $exportPluginProperties->setExtension('ods');
+        $exportPluginProperties->setMimeType(
+            'application/vnd.oasis.opendocument.spreadsheet'
+        );
+        $exportPluginProperties->setForceFile(true);
+        $exportPluginProperties->setOptionsText(__('Options'));
+
+        // create the root group that will be the options field for
+        // $exportPluginProperties
+        // this will be shown as "Format specific options"
+        $exportSpecificOptions = new OptionsPropertyRootGroup();
+        $exportSpecificOptions->setName("Format Specific Options");
+
+        // general options main group
+        $generalOptions = new OptionsPropertyMainGroup();
+        $generalOptions->setName("general_opts");
+        // create primary items and add them to the group
+        $leaf = new TextPropertyItem();
+        $leaf->setName("null");
+        $leaf->setText(__('Replace NULL with:'));
+        $generalOptions->addProperty($leaf);
+        $leaf = new BoolPropertyItem();
+        $leaf->setName("columns");
+        $leaf->setText(__('Put columns names in the first row'));
+        $generalOptions->addProperty($leaf);
+        $leaf = new HiddenPropertyItem();
+        $leaf->setName("structure_or_data");
+        $generalOptions->addProperty($leaf);
+        // add the main group to the root group
+        $exportSpecificOptions->addProperty($generalOptions);
+
+        // set the options for the export plugin property item
+        $exportPluginProperties->setOptions($exportSpecificOptions);
+        $this->properties = $exportPluginProperties;
+    }
+
+    /**
+     * This method is called when any PluginManager to which the observer
+     * is attached calls PluginManager::notify()
+     *
+     * @param SplSubject $subject The PluginManager notifying the observer
+     *                            of an update.
+     *
+     * @return void
+     */
+    public function update (SplSubject $subject)
+    {
+    }
+
+    /**
+     * Outputs export header
+     *
+     * @return bool Whether it succeeded
+     */
+    public function exportHeader ()
+    {
+        $GLOBALS['ods_buffer'] .= '<?xml version="1.0" encoding="utf-8"?' . '>'
+            . '<office:document-content '
+                . $GLOBALS['OpenDocumentNS'] . 'office:version="1.0">'
+            . '<office:automatic-styles>'
+                . '<number:date-style style:name="N37"'
+                    .' number:automatic-order="true">'
+                . '<number:month number:style="long"/>'
+                . '<number:text>/</number:text>'
+                . '<number:day number:style="long"/>'
+                . '<number:text>/</number:text>'
+                . '<number:year/>'
+              . '</number:date-style>'
+              . '<number:time-style style:name="N43">'
+                . '<number:hours number:style="long"/>'
+                . '<number:text>:</number:text>'
+                . '<number:minutes number:style="long"/>'
+                . '<number:text>:</number:text>'
+                . '<number:seconds number:style="long"/>'
+                . '<number:text> </number:text>'
+                . '<number:am-pm/>'
+              . '</number:time-style>'
+              . '<number:date-style style:name="N50"'
+                    . ' number:automatic-order="true"'
+                    . ' number:format-source="language">'
+                . '<number:month/>'
+                . '<number:text>/</number:text>'
+                . '<number:day/>'
+                . '<number:text>/</number:text>'
+                . '<number:year/>'
+                . '<number:text> </number:text>'
+                . '<number:hours number:style="long"/>'
+                . '<number:text>:</number:text>'
+                . '<number:minutes number:style="long"/>'
+                . '<number:text> </number:text>'
+                . '<number:am-pm/>'
+              . '</number:date-style>'
+              . '<style:style style:name="DateCell" style:family="table-cell"'
+                . ' style:parent-style-name="Default" style:data-style-name="N37"/>'
+              . '<style:style style:name="TimeCell" style:family="table-cell"'
+                . ' style:parent-style-name="Default" style:data-style-name="N43"/>'
+              . '<style:style style:name="DateTimeCell" style:family="table-cell"'
+                . ' style:parent-style-name="Default" style:data-style-name="N50"/>'
+            . '</office:automatic-styles>'
+            . '<office:body>'
+            . '<office:spreadsheet>';
+        return true;
+    }
+
+    /**
+     * Outputs export footer
+     *
+     * @return bool Whether it succeeded
+     */
+    public function exportFooter ()
+    {
+        $GLOBALS['ods_buffer'] .= '</office:spreadsheet>'
+            . '</office:body>'
+            . '</office:document-content>';
+        if (! PMA_exportOutputHandler(
+            PMA_createOpenDocument(
+                'application/vnd.oasis.opendocument.spreadsheet',
+                $GLOBALS['ods_buffer']
+            )
+        )) {
+            return false;
+        }
+        return true;
+    }
+
+    /**
+     * Outputs database header
+     *
+     * @param string $db Database name
+     *
+     * @return bool Whether it succeeded
+     */
+    public function exportDBHeader ($db)
+    {
+        return true;
+    }
+
+    /**
+     * Outputs database footer
+     *
+     * @param string $db Database name
+     *
+     * @return bool Whether it succeeded
+     */
+    public function exportDBFooter ($db)
+    {
+        return true;
+    }
+
+    /**
+     * Outputs CREATE DATABASE statement
+     *
+     * @param string $db Database name
+     *
+     * @return bool Whether it succeeded
+     */
+    public function exportDBCreate($db)
+    {
+        return true;
+    }
+
+    /**
+     * Outputs the content of a table in NHibernate format
+     *
+     * @param string $db        database name
+     * @param string $table     table name
+     * @param string $crlf      the end of line sequence
+     * @param string $error_url the url to go back in case of error
+     * @param string $sql_query SQL query for obtaining data
+     *
+     * @return bool Whether it succeeded
+     */
+    public function exportData($db, $table, $crlf, $error_url, $sql_query)
+    {
+        global $what;
+
+        // Gets the data from the database
+        $result = PMA_DBI_query($sql_query, null, PMA_DBI_QUERY_UNBUFFERED);
+        $fields_cnt = PMA_DBI_num_fields($result);
+        $fields_meta = PMA_DBI_get_fields_meta($result);
+        $field_flags = array();
+        for ($j = 0; $j < $fields_cnt; $j++) {
+            $field_flags[$j] = PMA_DBI_field_flags($result, $j);
+        }
+
+        $GLOBALS['ods_buffer'] .=
+            '<table:table table:name="' . htmlspecialchars($table) . '">';
+
+        // If required, get fields name at the first line
+        if (isset($GLOBALS[$what . '_columns'])) {
+            $GLOBALS['ods_buffer'] .= '<table:table-row>';
+            for ($i = 0; $i < $fields_cnt; $i++) {
+                $GLOBALS['ods_buffer'] .=
+                    '<table:table-cell office:value-type="string">'
+                    . '<text:p>'
+                    . htmlspecialchars(
+                        stripslashes(PMA_DBI_field_name($result, $i))
+                    )
+                    . '</text:p>'
+                    . '</table:table-cell>';
+            } // end for
+            $GLOBALS['ods_buffer'] .= '</table:table-row>';
+        } // end if
+
+        // Format the data
+        while ($row = PMA_DBI_fetch_row($result)) {
+            $GLOBALS['ods_buffer'] .= '<table:table-row>';
+            for ($j = 0; $j < $fields_cnt; $j++) {
+                if (! isset($row[$j]) || is_null($row[$j])) {
+                    $GLOBALS['ods_buffer'] .=
+                        '<table:table-cell office:value-type="string">'
+                        . '<text:p>'
+                        . htmlspecialchars($GLOBALS[$what . '_null'])
+                        . '</text:p>'
+                        . '</table:table-cell>';
+                } elseif (stristr($field_flags[$j], 'BINARY')
+                    && $fields_meta[$j]->blob
+                ) {
+                    // ignore BLOB
+                    $GLOBALS['ods_buffer'] .=
+                        '<table:table-cell office:value-type="string">'
+                        . '<text:p></text:p>'
+                        . '</table:table-cell>';
+                } elseif ($fields_meta[$j]->type == "date") {
+                    $GLOBALS['ods_buffer'] .=
+                        '<table:table-cell office:value-type="date"'
+                            . ' office:date-value="'
+                            . date("Y-m-d", strtotime($row[$j]))
+                            . '" table:style-name="DateCell">'
+                        . '<text:p>'
+                        . htmlspecialchars($row[$j])
+                        . '</text:p>'
+                        . '</table:table-cell>';
+                } elseif ($fields_meta[$j]->type == "time") {
+                    $GLOBALS['ods_buffer'] .=
+                        '<table:table-cell office:value-type="time"'
+                            . ' office:time-value="'
+                            . date("\P\TH\Hi\Ms\S", strtotime($row[$j]))
+                            . '" table:style-name="TimeCell">'
+                        . '<text:p>'
+                        . htmlspecialchars($row[$j])
+                        . '</text:p>'
+                        . '</table:table-cell>';
+                } elseif ($fields_meta[$j]->type == "datetime") {
+                    $GLOBALS['ods_buffer'] .=
+                        '<table:table-cell office:value-type="date"'
+                            . ' office:date-value="'
+                            . date("Y-m-d\TH:i:s", strtotime($row[$j]))
+                            . '" table:style-name="DateTimeCell">'
+                        . '<text:p>'
+                        . htmlspecialchars($row[$j])
+                        . '</text:p>'
+                        . '</table:table-cell>';
+                } elseif (($fields_meta[$j]->numeric
+                    && $fields_meta[$j]->type != 'timestamp'
+                    && ! $fields_meta[$j]->blob) || $fields_meta[$j]->type == 'real'
+                ) {
+                    $GLOBALS['ods_buffer'] .=
+                        '<table:table-cell office:value-type="float"'
+                            . ' office:value="' . $row[$j] . '" >'
+                        . '<text:p>'
+                        . htmlspecialchars($row[$j])
+                        . '</text:p>'
+                        . '</table:table-cell>';
+                } else {
+                    $GLOBALS['ods_buffer'] .=
+                        '<table:table-cell office:value-type="string">'
+                        . '<text:p>'
+                        . htmlspecialchars($row[$j])
+                        . '</text:p>'
+                        . '</table:table-cell>';
+                }
+            } // end for
+            $GLOBALS['ods_buffer'] .= '</table:table-row>';
+        } // end while
+        PMA_DBI_free_result($result);
+
+        $GLOBALS['ods_buffer'] .= '</table:table>';
+
+        return true;
+    }
+}
+?>
diff --git a/phpmyadmin/libraries/plugins/export/ExportOdt.class.php b/phpmyadmin/libraries/plugins/export/ExportOdt.class.php
new file mode 100644
index 0000000..bb608f0
--- /dev/null
+++ b/phpmyadmin/libraries/plugins/export/ExportOdt.class.php
@@ -0,0 +1,734 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * Set of functions used to build OpenDocument Text dumps of tables
+ *
+ * @package    PhpMyAdmin-Export
+ * @subpackage ODT
+ */
+if (! defined('PHPMYADMIN')) {
+    exit;
+}
+
+/* Get the export interface */
+require_once 'libraries/plugins/ExportPlugin.class.php';
+
+$GLOBALS['odt_buffer'] = '';
+require_once 'libraries/opendocument.lib.php';
+
+/**
+ * Handles the export for the ODT class
+ *
+ * @package    PhpMyAdmin-Export
+ * @subpackage ODT
+ */
+class ExportOdt extends ExportPlugin
+{
+    /**
+     * Constructor
+     */
+    public function __construct()
+    {
+        $this->setProperties();
+    }
+
+    /**
+     * Sets the export ODT properties
+     *
+     * @return void
+     */
+    protected function setProperties()
+    {
+        global $plugin_param;
+        $hide_structure = false;
+        if ($plugin_param['export_type'] == 'table'
+            && ! $plugin_param['single_table']
+        ) {
+            $hide_structure = true;
+        }
+
+        $props = 'libraries/properties/';
+        include_once "$props/plugins/ExportPluginProperties.class.php";
+        include_once "$props/options/groups/OptionsPropertyRootGroup.class.php";
+        include_once "$props/options/groups/OptionsPropertyMainGroup.class.php";
+        include_once "$props/options/items/TextPropertyItem.class.php";
+        include_once "$props/options/items/BoolPropertyItem.class.php";
+        include_once "$props/options/items/HiddenPropertyItem.class.php";
+        include_once "$props/options/items/RadioPropertyItem.class.php";
+
+        $exportPluginProperties = new ExportPluginProperties();
+        $exportPluginProperties->setText('OpenDocument Text');
+        $exportPluginProperties->setExtension('odt');
+        $exportPluginProperties->setMimeType(
+            'application/vnd.oasis.opendocument.text'
+        );
+        $exportPluginProperties->setForceFile(true);
+        $exportPluginProperties->setOptionsText(__('Options'));
+
+        // create the root group that will be the options field for
+        // $exportPluginProperties
+        // this will be shown as "Format specific options"
+        $exportSpecificOptions = new OptionsPropertyRootGroup();
+        $exportSpecificOptions->setName("Format Specific Options");
+
+        // what to dump (structure/data/both) main group
+        $dumpWhat = new OptionsPropertyMainGroup();
+        $dumpWhat->setName("general_opts");
+        $dumpWhat->setText(__('Dump table'));
+        // create primary items and add them to the group
+        $leaf = new RadioPropertyItem();
+        $leaf->setName("structure_or_data");
+        $leaf->setValues(
+            array(
+                'structure' => __('structure'),
+                'data' => __('data'),
+                'structure_and_data' => __('structure and data')
+            )
+        );
+        $dumpWhat->addProperty($leaf);
+        // add the main group to the root group
+        $exportSpecificOptions->addProperty($dumpWhat);
+
+
+        // structure options main group
+        if (! $hide_structure) {
+            $structureOptions = new OptionsPropertyMainGroup();
+            $structureOptions->setName("structure");
+            $structureOptions->setText(__('Object creation options'));
+            $structureOptions->setForce('data');
+            // create primary items and add them to the group
+            if (! empty($GLOBALS['cfgRelation']['relation'])) {
+                $leaf = new BoolPropertyItem();
+                $leaf->setName("relation");
+                $leaf->setText(__('Display foreign key relationships'));
+                $structureOptions->addProperty($leaf);
+            }
+            $leaf = new BoolPropertyItem();
+            $leaf->setName("comments");
+            $leaf->setText(__('Display comments'));
+            $structureOptions->addProperty($leaf);
+            if (! empty($GLOBALS['cfgRelation']['mimework'])) {
+                $leaf = new BoolPropertyItem();
+                $leaf->setName("mime");
+                $leaf->setText(__('Display MIME types'));
+                $structureOptions->addProperty($leaf);
+            }
+            // add the main group to the root group
+            $exportSpecificOptions->addProperty($structureOptions);
+        }
+
+        // data options main group
+        $dataOptions = new OptionsPropertyMainGroup();
+        $dataOptions->setName("data");
+        $dataOptions->setText(__('Data dump options'));
+        $dataOptions->setForce('structure');
+        // create primary items and add them to the group
+        $leaf = new BoolPropertyItem();
+        $leaf->setName("columns");
+        $leaf->setText(__('Put columns names in the first row'));
+        $dataOptions->addProperty($leaf);
+        $leaf = new TextPropertyItem();
+        $leaf->setName('null');
+        $leaf->setText(__('Replace NULL with:'));
+        $dataOptions->addProperty($leaf);
+        // add the main group to the root group
+        $exportSpecificOptions->addProperty($dataOptions);
+
+        // set the options for the export plugin property item
+        $exportPluginProperties->setOptions($exportSpecificOptions);
+        $this->properties = $exportPluginProperties;
+    }
+
+    /**
+     * This method is called when any PluginManager to which the observer
+     * is attached calls PluginManager::notify()
+     *
+     * @param SplSubject $subject The PluginManager notifying the observer
+     *                            of an update.
+     *
+     * @return void
+     */
+    public function update (SplSubject $subject)
+    {
+    }
+
+    /**
+     * Outputs export header
+     *
+     * @return bool Whether it succeeded
+     */
+    public function exportHeader ()
+    {
+        $GLOBALS['odt_buffer'] .= '<?xml version="1.0" encoding="utf-8"?' . '>'
+            . '<office:document-content '
+                . $GLOBALS['OpenDocumentNS'] . 'office:version="1.0">'
+            . '<office:body>'
+            . '<office:text>';
+        return true;
+    }
+
+    /**
+     * Outputs export footer
+     *
+     * @return bool Whether it succeeded
+     */
+    public function exportFooter ()
+    {
+        $GLOBALS['odt_buffer'] .= '</office:text>'
+            . '</office:body>'
+            . '</office:document-content>';
+        if (! PMA_exportOutputHandler(
+            PMA_createOpenDocument(
+                'application/vnd.oasis.opendocument.text',
+                $GLOBALS['odt_buffer']
+            )
+        )) {
+            return false;
+        }
+        return true;
+    }
+
+    /**
+     * Outputs database header
+     *
+     * @param string $db Database name
+     *
+     * @return bool Whether it succeeded
+     */
+    public function exportDBHeader ($db)
+    {
+        $GLOBALS['odt_buffer'] .=
+            '<text:h text:outline-level="1" text:style-name="Heading_1"'
+                . ' text:is-list-header="true">'
+            . __('Database') . ' ' . htmlspecialchars($db)
+            . '</text:h>';
+        return true;
+    }
+
+    /**
+     * Outputs database footer
+     *
+     * @param string $db Database name
+     *
+     * @return bool Whether it succeeded
+     */
+    public function exportDBFooter ($db)
+    {
+        return true;
+    }
+
+    /**
+     * Outputs CREATE DATABASE statement
+     *
+     * @param string $db Database name
+     *
+     * @return bool Whether it succeeded
+     */
+    public function exportDBCreate($db)
+    {
+        return true;
+    }
+    /**
+     * Outputs the content of a table in NHibernate format
+     *
+     * @param string $db        database name
+     * @param string $table     table name
+     * @param string $crlf      the end of line sequence
+     * @param string $error_url the url to go back in case of error
+     * @param string $sql_query SQL query for obtaining data
+     *
+     * @return bool Whether it succeeded
+     */
+    public function exportData($db, $table, $crlf, $error_url, $sql_query)
+    {
+        global $what;
+
+        // Gets the data from the database
+        $result = PMA_DBI_query($sql_query, null, PMA_DBI_QUERY_UNBUFFERED);
+        $fields_cnt = PMA_DBI_num_fields($result);
+        $fields_meta = PMA_DBI_get_fields_meta($result);
+        $field_flags = array();
+        for ($j = 0; $j < $fields_cnt; $j++) {
+            $field_flags[$j] = PMA_DBI_field_flags($result, $j);
+        }
+
+        $GLOBALS['odt_buffer'] .=
+            '<text:h text:outline-level="2" text:style-name="Heading_2"'
+                . ' text:is-list-header="true">'
+                . __('Dumping data for table') . ' ' . htmlspecialchars($table)
+            . '</text:h>'
+            . '<table:table'
+            . ' table:name="' . htmlspecialchars($table) . '_structure">'
+            . '<table:table-column'
+            . ' table:number-columns-repeated="' . $fields_cnt . '"/>';
+
+        // If required, get fields name at the first line
+        if (isset($GLOBALS[$what . '_columns'])) {
+            $GLOBALS['odt_buffer'] .= '<table:table-row>';
+            for ($i = 0; $i < $fields_cnt; $i++) {
+                $GLOBALS['odt_buffer'] .=
+                    '<table:table-cell office:value-type="string">'
+                    . '<text:p>'
+                        . htmlspecialchars(
+                            stripslashes(PMA_DBI_field_name($result, $i))
+                        )
+                    . '</text:p>'
+                    . '</table:table-cell>';
+            } // end for
+            $GLOBALS['odt_buffer'] .= '</table:table-row>';
+        } // end if
+
+        // Format the data
+        while ($row = PMA_DBI_fetch_row($result)) {
+            $GLOBALS['odt_buffer'] .= '<table:table-row>';
+            for ($j = 0; $j < $fields_cnt; $j++) {
+                if (! isset($row[$j]) || is_null($row[$j])) {
+                    $GLOBALS['odt_buffer'] .=
+                        '<table:table-cell office:value-type="string">'
+                        . '<text:p>'
+                        . htmlspecialchars($GLOBALS[$what . '_null'])
+                        . '</text:p>'
+                        . '</table:table-cell>';
+                } elseif (stristr($field_flags[$j], 'BINARY')
+                    && $fields_meta[$j]->blob
+                ) {
+                    // ignore BLOB
+                    $GLOBALS['odt_buffer'] .=
+                        '<table:table-cell office:value-type="string">'
+                        . '<text:p></text:p>'
+                        . '</table:table-cell>';
+                } elseif ($fields_meta[$j]->numeric
+                    && $fields_meta[$j]->type != 'timestamp'
+                    && ! $fields_meta[$j]->blob
+                ) {
+                    $GLOBALS['odt_buffer'] .=
+                        '<table:table-cell office:value-type="float"'
+                            . ' office:value="' . $row[$j] . '" >'
+                        . '<text:p>'
+                        . htmlspecialchars($row[$j])
+                        . '</text:p>'
+                        . '</table:table-cell>';
+                } else {
+                    $GLOBALS['odt_buffer'] .=
+                        '<table:table-cell office:value-type="string">'
+                        . '<text:p>'
+                        . htmlspecialchars($row[$j])
+                        . '</text:p>'
+                        . '</table:table-cell>';
+                }
+            } // end for
+            $GLOBALS['odt_buffer'] .= '</table:table-row>';
+        } // end while
+        PMA_DBI_free_result($result);
+
+        $GLOBALS['odt_buffer'] .= '</table:table>';
+
+        return true;
+    }
+
+    /**
+     * Returns a stand-in CREATE definition to resolve view dependencies
+     *
+     * @param string $db   the database name
+     * @param string $view the view name
+     * @param string $crlf the end of line sequence
+     *
+     * @return bool true
+     */
+    public function getTableDefStandIn($db, $view, $crlf)
+    {
+        /**
+         * Gets fields properties
+         */
+        PMA_DBI_select_db($db);
+
+        /**
+         * Displays the table structure
+         */
+        $GLOBALS['odt_buffer'] .=
+            '<table:table table:name="'
+            . htmlspecialchars($view) . '_data">';
+        $columns_cnt = 4;
+        $GLOBALS['odt_buffer'] .=
+            '<table:table-column'
+            . ' table:number-columns-repeated="' . $columns_cnt . '"/>';
+        /* Header */
+        $GLOBALS['odt_buffer'] .= '<table:table-row>'
+            . '<table:table-cell office:value-type="string">'
+            . '<text:p>' . __('Column') . '</text:p>'
+            . '</table:table-cell>'
+            . '<table:table-cell office:value-type="string">'
+            . '<text:p>' . __('Type') . '</text:p>'
+            . '</table:table-cell>'
+            . '<table:table-cell office:value-type="string">'
+            . '<text:p>' . __('Null') . '</text:p>'
+            . '</table:table-cell>'
+            . '<table:table-cell office:value-type="string">'
+            . '<text:p>' . __('Default') . '</text:p>'
+            . '</table:table-cell>'
+            . '</table:table-row>';
+
+        $columns = PMA_DBI_get_columns($db, $view);
+        foreach ($columns as $column) {
+            $GLOBALS['odt_buffer'] .= $this->formatOneColumnDefinition($column);
+            $GLOBALS['odt_buffer'] .= '</table:table-row>';
+        } // end foreach
+
+        $GLOBALS['odt_buffer'] .= '</table:table>';
+        return true;
+    }
+
+    /**
+     * Returns $table's CREATE definition
+     *
+     * @param string $db            the database name
+     * @param string $table         the table name
+     * @param string $crlf          the end of line sequence
+     * @param string $error_url     the url to go back in case of error
+     * @param bool   $do_relation   whether to include relation comments
+     * @param bool   $do_comments   whether to include the pmadb-style column
+     *                                comments as comments in the structure;
+     *                                this is deprecated but the parameter is
+     *                                left here because export.php calls
+     *                                PMA_exportStructure() also for other
+     * @param bool   $do_mime       whether to include mime comments
+     * @param bool   $show_dates    whether to include creation/update/check dates
+     * @param bool   $add_semicolon whether to add semicolon and end-of-line at
+     *                              the end
+     * @param bool   $view          whether we're handling a view
+     *
+     * @return bool true
+     */
+    public function getTableDef(
+        $db,
+        $table,
+        $crlf,
+        $error_url,
+        $do_relation,
+        $do_comments,
+        $do_mime,
+        $show_dates = false,
+        $add_semicolon = true,
+        $view = false
+    ) {
+        global $cfgRelation;
+
+        /**
+         * Gets fields properties
+         */
+        PMA_DBI_select_db($db);
+
+        // Check if we can use Relations
+        if ($do_relation && ! empty($cfgRelation['relation'])) {
+            // Find which tables are related with the current one and write it in
+            // an array
+            $res_rel = PMA_getForeigners($db, $table);
+
+            if ($res_rel && count($res_rel) > 0) {
+                $have_rel = true;
+            } else {
+                $have_rel = false;
+            }
+        } else {
+               $have_rel = false;
+        } // end if
+
+        /**
+         * Displays the table structure
+         */
+        $GLOBALS['odt_buffer'] .= '<table:table table:name="'
+            . htmlspecialchars($table) . '_structure">';
+        $columns_cnt = 4;
+        if ($do_relation && $have_rel) {
+            $columns_cnt++;
+        }
+        if ($do_comments) {
+            $columns_cnt++;
+        }
+        if ($do_mime && $cfgRelation['mimework']) {
+            $columns_cnt++;
+        }
+        $GLOBALS['odt_buffer'] .= '<table:table-column'
+            . ' table:number-columns-repeated="' . $columns_cnt . '"/>';
+        /* Header */
+        $GLOBALS['odt_buffer'] .= '<table:table-row>'
+            . '<table:table-cell office:value-type="string">'
+            . '<text:p>' . __('Column') . '</text:p>'
+            . '</table:table-cell>'
+            . '<table:table-cell office:value-type="string">'
+            . '<text:p>' . __('Type') . '</text:p>'
+            . '</table:table-cell>'
+            . '<table:table-cell office:value-type="string">'
+            . '<text:p>' . __('Null') . '</text:p>'
+            . '</table:table-cell>'
+            . '<table:table-cell office:value-type="string">'
+            . '<text:p>' . __('Default') . '</text:p>'
+            . '</table:table-cell>';
+        if ($do_relation && $have_rel) {
+            $GLOBALS['odt_buffer'] .= '<table:table-cell office:value-type="string">'
+                . '<text:p>' . __('Links to') . '</text:p>'
+                . '</table:table-cell>';
+        }
+        if ($do_comments) {
+            $GLOBALS['odt_buffer'] .= '<table:table-cell office:value-type="string">'
+                . '<text:p>' . __('Comments') . '</text:p>'
+                . '</table:table-cell>';
+            $comments = PMA_getComments($db, $table);
+        }
+        if ($do_mime && $cfgRelation['mimework']) {
+            $GLOBALS['odt_buffer'] .= '<table:table-cell office:value-type="string">'
+                . '<text:p>' . __('MIME type') . '</text:p>'
+                . '</table:table-cell>';
+            $mime_map = PMA_getMIME($db, $table, true);
+        }
+        $GLOBALS['odt_buffer'] .= '</table:table-row>';
+
+        $columns = PMA_DBI_get_columns($db, $table);
+        foreach ($columns as $column) {
+            $field_name = $column['Field'];
+            $GLOBALS['odt_buffer'] .= $this->formatOneColumnDefinition($column);
+
+            if ($do_relation && $have_rel) {
+                if (isset($res_rel[$field_name])) {
+                    $GLOBALS['odt_buffer'] .=
+                        '<table:table-cell office:value-type="string">'
+                        . '<text:p>'
+                        . htmlspecialchars(
+                            $res_rel[$field_name]['foreign_table']
+                            . ' (' . $res_rel[$field_name]['foreign_field'] . ')'
+                        )
+                        . '</text:p>'
+                        . '</table:table-cell>';
+                }
+            }
+            if ($do_comments) {
+                if (isset($comments[$field_name])) {
+                    $GLOBALS['odt_buffer'] .=
+                        '<table:table-cell office:value-type="string">'
+                        . '<text:p>'
+                        . htmlspecialchars($comments[$field_name])
+                        . '</text:p>'
+                        . '</table:table-cell>';
+                } else {
+                    $GLOBALS['odt_buffer'] .=
+                        '<table:table-cell office:value-type="string">'
+                        . '<text:p></text:p>'
+                        . '</table:table-cell>';
+                }
+            }
+            if ($do_mime && $cfgRelation['mimework']) {
+                if (isset($mime_map[$field_name])) {
+                    $GLOBALS['odt_buffer'] .=
+                        '<table:table-cell office:value-type="string">'
+                        . '<text:p>'
+                        . htmlspecialchars(
+                            str_replace('_', '/', $mime_map[$field_name]['mimetype'])
+                        )
+                        . '</text:p>'
+                        . '</table:table-cell>';
+                } else {
+                    $GLOBALS['odt_buffer'] .=
+                        '<table:table-cell office:value-type="string">'
+                        . '<text:p></text:p>'
+                        . '</table:table-cell>';
+                }
+            }
+            $GLOBALS['odt_buffer'] .= '</table:table-row>';
+        } // end foreach
+
+        $GLOBALS['odt_buffer'] .= '</table:table>';
+        return true;
+    } // end of the '$this->getTableDef()' function
+
+    /**
+     * Outputs triggers
+     *
+     * @param string $db    database name
+     * @param string $table table name
+     *
+     * @return bool true
+     */
+    protected function getTriggers($db, $table)
+    {
+        $GLOBALS['odt_buffer'] .= '<table:table'
+            . ' table:name="' . htmlspecialchars($table) . '_triggers">'
+            . '<table:table-column'
+            . ' table:number-columns-repeated="4"/>'
+            . '<table:table-row>'
+            . '<table:table-cell office:value-type="string">'
+            . '<text:p>' . __('Name') . '</text:p>'
+            . '</table:table-cell>'
+            . '<table:table-cell office:value-type="string">'
+            . '<text:p>' . __('Time') . '</text:p>'
+            . '</table:table-cell>'
+            . '<table:table-cell office:value-type="string">'
+            . '<text:p>' . __('Event') . '</text:p>'
+            . '</table:table-cell>'
+            . '<table:table-cell office:value-type="string">'
+            . '<text:p>' . __('Definition') . '</text:p>'
+            . '</table:table-cell>'
+            . '</table:table-row>';
+
+        $triggers = PMA_DBI_get_triggers($db, $table);
+
+        foreach ($triggers as $trigger) {
+            $GLOBALS['odt_buffer'] .= '<table:table-row>';
+            $GLOBALS['odt_buffer'] .= '<table:table-cell office:value-type="string">'
+                . '<text:p>'
+                . htmlspecialchars($trigger['name'])
+                . '</text:p>'
+                . '</table:table-cell>';
+            $GLOBALS['odt_buffer'] .= '<table:table-cell office:value-type="string">'
+                . '<text:p>'
+                . htmlspecialchars($trigger['action_timing'])
+                . '</text:p>'
+                . '</table:table-cell>';
+            $GLOBALS['odt_buffer'] .= '<table:table-cell office:value-type="string">'
+                . '<text:p>'
+                . htmlspecialchars($trigger['event_manipulation'])
+                . '</text:p>'
+                . '</table:table-cell>';
+            $GLOBALS['odt_buffer'] .= '<table:table-cell office:value-type="string">'
+                . '<text:p>'
+                . htmlspecialchars($trigger['definition'])
+                . '</text:p>'
+                . '</table:table-cell>';
+            $GLOBALS['odt_buffer'] .= '</table:table-row>';
+        }
+
+        $GLOBALS['odt_buffer'] .= '</table:table>';
+        return true;
+    }
+
+    /**
+     * Outputs table's structure
+     *
+     * @param string $db          database name
+     * @param string $table       table name
+     * @param string $crlf        the end of line sequence
+     * @param string $error_url   the url to go back in case of error
+     * @param string $export_mode 'create_table', 'triggers', 'create_view',
+     *                            'stand_in'
+     * @param string $export_type 'server', 'database', 'table'
+     * @param bool   $do_relation whether to include relation comments
+     * @param bool   $do_comments whether to include the pmadb-style column
+     *                                comments as comments in the structure;
+     *                                this is deprecated but the parameter is
+     *                                left here because export.php calls
+     *                                PMA_exportStructure() also for other
+     * @param bool   $do_mime     whether to include mime comments
+     * @param bool   $dates       whether to include creation/update/check dates
+     *
+     * @return bool Whether it succeeded
+     */
+    public function exportStructure(
+        $db,
+        $table,
+        $crlf,
+        $error_url,
+        $export_mode,
+        $export_type,
+        $do_relation = false,
+        $do_comments = false,
+        $do_mime = false,
+        $dates = false
+    ) {
+        switch($export_mode) {
+        case 'create_table':
+            $GLOBALS['odt_buffer'] .=
+                '<text:h text:outline-level="2" text:style-name="Heading_2"'
+                . ' text:is-list-header="true">'
+                . __('Table structure for table') . ' ' .
+                htmlspecialchars($table)
+                . '</text:h>';
+            $this->getTableDef(
+                $db, $table, $crlf, $error_url, $do_relation, $do_comments,
+                $do_mime, $dates
+            );
+            break;
+        case 'triggers':
+            $triggers = PMA_DBI_get_triggers($db, $table);
+            if ($triggers) {
+                $GLOBALS['odt_buffer'] .=
+                    '<text:h text:outline-level="2" text:style-name="Heading_2"'
+                    . ' text:is-list-header="true">'
+                    . __('Triggers') . ' '
+                    . htmlspecialchars($table)
+                    . '</text:h>';
+                    $this->getTriggers($db, $table);
+            }
+            break;
+        case 'create_view':
+            $GLOBALS['odt_buffer'] .=
+                '<text:h text:outline-level="2" text:style-name="Heading_2"'
+                . ' text:is-list-header="true">'
+                . __('Structure for view') . ' '
+                . htmlspecialchars($table)
+                . '</text:h>';
+            $this->getTableDef(
+                $db, $table, $crlf, $error_url, $do_relation, $do_comments,
+                $do_mime, $dates, true, true
+            );
+            break;
+        case 'stand_in':
+            $GLOBALS['odt_buffer'] .=
+                '<text:h text:outline-level="2" text:style-name="Heading_2"'
+                    . ' text:is-list-header="true">'
+                . __('Stand-in structure for view') . ' '
+                . htmlspecialchars($table)
+                . '</text:h>';
+            // export a stand-in definition to resolve view dependencies
+            $this->getTableDefStandIn($db, $table, $crlf);
+        } // end switch
+
+        return true;
+    } // end of the '$this->exportStructure' function
+
+    /**
+     * Formats the definition for one column
+     *
+     * @param array $column info about this column
+     *
+     * @return string Formatted column definition
+     */
+    protected function formatOneColumnDefinition($column)
+    {
+        $field_name = $column['Field'];
+        $definition =  '<table:table-row>';
+        $definition .= '<table:table-cell office:value-type="string">'
+            . '<text:p>' . htmlspecialchars($field_name) . '</text:p>'
+            . '</table:table-cell>';
+
+        $extracted_columnspec
+            = PMA_Util::extractColumnSpec($column['Type']);
+        $type = htmlspecialchars($extracted_columnspec['print_type']);
+        if (empty($type)) {
+            $type = ' ';
+        }
+
+        $definition .= '<table:table-cell office:value-type="string">'
+            . '<text:p>' . htmlspecialchars($type) . '</text:p>'
+            . '</table:table-cell>';
+        if (! isset($column['Default'])) {
+            if ($column['Null'] != 'NO') {
+                $column['Default'] = 'NULL';
+            } else {
+                $column['Default'] = '';
+            }
+        } else {
+            $column['Default'] = $column['Default'];
+        }
+        $definition .= '<table:table-cell office:value-type="string">'
+            . '<text:p>'
+            . (($column['Null'] == '' || $column['Null'] == 'NO')
+                ? __('No')
+                : __('Yes'))
+            . '</text:p>'
+            . '</table:table-cell>';
+        $definition .= '<table:table-cell office:value-type="string">'
+            . '<text:p>' . htmlspecialchars($column['Default']) . '</text:p>'
+            . '</table:table-cell>';
+        return $definition;
+    }
+}
+?>
diff --git a/phpmyadmin/libraries/plugins/export/ExportPdf.class.php b/phpmyadmin/libraries/plugins/export/ExportPdf.class.php
new file mode 100644
index 0000000..ffabb96
--- /dev/null
+++ b/phpmyadmin/libraries/plugins/export/ExportPdf.class.php
@@ -0,0 +1,268 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * Produce a PDF report (export) from a query
+ *
+ * @package    PhpMyAdmin-Export
+ * @subpackage PDF
+ */
+if (! defined('PHPMYADMIN')) {
+    exit;
+}
+
+/* Get the export interface */
+require_once 'libraries/plugins/ExportPlugin.class.php';
+/* Get the PMA_ExportPdf class */
+require_once 'libraries/plugins/export/PMA_ExportPdf.class.php';
+
+/**
+ * Handles the export for the PDF class
+ *
+ * @package    PhpMyAdmin-Export
+ * @subpackage PDF
+ */
+class ExportPdf extends ExportPlugin
+{
+    /**
+     * PMA_ExportPdf instance
+     *
+     * @var PMA_ExportPdf
+     */
+    private $_pdf;
+
+    /**
+     * PDF Report Title
+     *
+     * @var string
+     */
+    private $_pdfReportTitle;
+
+    /**
+     * Constructor
+     */
+    public function __construct()
+    {
+        // initialize the specific export PDF variables
+        $this->initSpecificVariables();
+
+        $this->setProperties();
+    }
+
+    /**
+     * Initialize the local variables that are used for export PDF
+     *
+     * @return void
+     */
+    protected function initSpecificVariables()
+    {
+        $this->_setPdfReportTitle("");
+        $this->_setPdf(new PMA_ExportPdf('L', 'pt', 'A3'));
+    }
+
+    /**
+     * Sets the export PDF properties
+     *
+     * @return void
+     */
+    protected function setProperties()
+    {
+        $props = 'libraries/properties/';
+        include_once "$props/plugins/ExportPluginProperties.class.php";
+        include_once "$props/options/groups/OptionsPropertyRootGroup.class.php";
+        include_once "$props/options/groups/OptionsPropertyMainGroup.class.php";
+        include_once "$props/options/items/MessageOnlyPropertyItem.class.php";
+        include_once "$props/options/items/TextPropertyItem.class.php";
+        include_once "$props/options/items/HiddenPropertyItem.class.php";
+
+        $exportPluginProperties = new ExportPluginProperties();
+        $exportPluginProperties->setText('PDF');
+        $exportPluginProperties->setExtension('pdf');
+        $exportPluginProperties->setMimeType('application/pdf');
+        $exportPluginProperties->setForceFile(true);
+        $exportPluginProperties->setOptionsText(__('Options'));
+
+        // create the root group that will be the options field for
+        // $exportPluginProperties
+        // this will be shown as "Format specific options"
+        $exportSpecificOptions = new OptionsPropertyRootGroup();
+        $exportSpecificOptions->setName("Format Specific Options");
+
+        // general options main group
+        $generalOptions = new OptionsPropertyMainGroup();
+        $generalOptions->setName("general_opts");
+        // create primary items and add them to the group
+        $leaf = new MessageOnlyPropertyItem();
+        $leaf->setName("explanation");
+        $leaf->setText(
+            __('(Generates a report containing the data of a single table)')
+        );
+        $generalOptions->addProperty($leaf);
+        $leaf = new TextPropertyItem();
+        $leaf->setName("report_title");
+        $leaf->setText(__('Report title:'));
+        $generalOptions->addProperty($leaf);
+        $leaf = new HiddenPropertyItem();
+        $leaf->setName("structure_or_data");
+        $generalOptions->addProperty($leaf);
+        // add the main group to the root group
+        $exportSpecificOptions->addProperty($generalOptions);
+
+        // set the options for the export plugin property item
+        $exportPluginProperties->setOptions($exportSpecificOptions);
+        $this->properties = $exportPluginProperties;
+    }
+
+    /**
+     * This method is called when any PluginManager to which the observer
+     * is attached calls PluginManager::notify()
+     *
+     * @param SplSubject $subject The PluginManager notifying the observer
+     *                            of an update.
+     *
+     * @return void
+     */
+    public function update (SplSubject $subject)
+    {
+    }
+
+    /**
+     * Outputs export header
+     *
+     * @return bool Whether it succeeded
+     */
+    public function exportHeader ()
+    {
+        $pdf_report_title = $this->_getPdfReportTitle();
+        $pdf = $this->_getPdf();
+        $pdf->Open();
+
+        $attr = array('titleFontSize' => 18, 'titleText' => $pdf_report_title);
+        $pdf->setAttributes($attr);
+        $pdf->setTopMargin(30);
+
+        return true;
+    }
+
+    /**
+     * Outputs export footer
+     *
+     * @return bool Whether it succeeded
+     */
+    public function exportFooter ()
+    {
+        $pdf = $this->_getPdf();
+
+        // instead of $pdf->Output():
+        if (! PMA_exportOutputHandler($pdf->getPDFData())) {
+            return false;
+        }
+
+        return true;
+    }
+
+    /**
+     * Outputs database header
+     *
+     * @param string $db Database name
+     *
+     * @return bool Whether it succeeded
+     */
+    public function exportDBHeader ($db)
+    {
+        return true;
+    }
+
+    /**
+     * Outputs database footer
+     *
+     * @param string $db Database name
+     *
+     * @return bool Whether it succeeded
+     */
+    public function exportDBFooter ($db)
+    {
+        return true;
+    }
+
+    /**
+     * Outputs CREATE DATABASE statement
+     *
+     * @param string $db Database name
+     *
+     * @return bool Whether it succeeded
+     */
+    public function exportDBCreate($db)
+    {
+        return true;
+    }
+    /**
+     * Outputs the content of a table in NHibernate format
+     *
+     * @param string $db        database name
+     * @param string $table     table name
+     * @param string $crlf      the end of line sequence
+     * @param string $error_url the url to go back in case of error
+     * @param string $sql_query SQL query for obtaining data
+     *
+     * @return bool Whether it succeeded
+     */
+    public function exportData($db, $table, $crlf, $error_url, $sql_query)
+    {
+        $pdf = $this->_getPdf();
+
+        $attr = array('currentDb' => $db, 'currentTable' => $table);
+        $pdf->setAttributes($attr);
+        $pdf->mysqlReport($sql_query);
+
+        return true;
+    } // end of the 'PMA_exportData()' function
+
+
+    /* ~~~~~~~~~~~~~~~~~~~~ Getters and Setters ~~~~~~~~~~~~~~~~~~~~ */
+
+
+    /**
+     * Gets the PMA_ExportPdf instance
+     *
+     * @return PMA_ExportPdf
+     */
+    private function _getPdf()
+    {
+        return $this->_pdf;
+    }
+
+    /**
+     * Instantiates the PMA_ExportPdf class
+     *
+     * @param string $pdf PMA_ExportPdf instance
+     *
+     * @return void
+     */
+    private function _setPdf($pdf)
+    {
+        $this->_pdf = $pdf;
+    }
+
+    /**
+     * Gets the PDF report title
+     *
+     * @return string
+     */
+    private function _getPdfReportTitle()
+    {
+        return $this->_pdfReportTitle;
+    }
+
+    /**
+     * Sets the PDF report title
+     *
+     * @param string $pdfReportTitle PDF report title
+     *
+     * @return void
+     */
+    private function _setPdfReportTitle($pdfReportTitle)
+    {
+        $this->_pdfReportTitle = $pdfReportTitle;
+    }
+}
+?>
\ No newline at end of file
diff --git a/phpmyadmin/libraries/plugins/export/ExportPhparray.class.php b/phpmyadmin/libraries/plugins/export/ExportPhparray.class.php
new file mode 100644
index 0000000..2d3b73c
--- /dev/null
+++ b/phpmyadmin/libraries/plugins/export/ExportPhparray.class.php
@@ -0,0 +1,227 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * Set of functions used to build dumps of tables as PHP Arrays
+ *
+ * @package    PhpMyAdmin-Export
+ * @subpackage PHP
+ */
+if (! defined('PHPMYADMIN')) {
+    exit;
+}
+
+/* Get the export interface */
+require_once 'libraries/plugins/ExportPlugin.class.php';
+
+/**
+ * Handles the export for the PHP Array class
+ *
+ * @package    PhpMyAdmin-Export
+ * @subpackage PHP
+ */
+class ExportPhparray extends ExportPlugin
+{
+    /**
+     * Constructor
+     */
+    public function __construct()
+    {
+        $this->setProperties();
+    }
+
+    /**
+     * Sets the export PHP Array properties
+     *
+     * @return void
+     */
+    protected function setProperties()
+    {
+        $props = 'libraries/properties/';
+        include_once "$props/plugins/ExportPluginProperties.class.php";
+        include_once "$props/options/groups/OptionsPropertyRootGroup.class.php";
+        include_once "$props/options/groups/OptionsPropertyMainGroup.class.php";
+        include_once "$props/options/items/HiddenPropertyItem.class.php";
+
+        $exportPluginProperties = new ExportPluginProperties();
+        $exportPluginProperties->setText('PHP array');
+        $exportPluginProperties->setExtension('php');
+        $exportPluginProperties->setMimeType('text/plain');
+        $exportPluginProperties->setOptionsText(__('Options'));
+
+        // create the root group that will be the options field for
+        // $exportPluginProperties
+        // this will be shown as "Format specific options"
+        $exportSpecificOptions = new OptionsPropertyRootGroup();
+        $exportSpecificOptions->setName("Format Specific Options");
+
+        // general options main group
+        $generalOptions = new OptionsPropertyMainGroup();
+        $generalOptions->setName("general_opts");
+        // create primary items and add them to the group
+        $leaf = new HiddenPropertyItem();
+        $leaf->setName("structure_or_data");
+        $generalOptions->addProperty($leaf);
+        // add the main group to the root group
+        $exportSpecificOptions->addProperty($generalOptions);
+
+        // set the options for the export plugin property item
+        $exportPluginProperties->setOptions($exportSpecificOptions);
+        $this->properties = $exportPluginProperties;
+    }
+
+    /**
+     * This method is called when any PluginManager to which the observer
+     * is attached calls PluginManager::notify()
+     *
+     * @param SplSubject $subject The PluginManager notifying the observer
+     *                            of an update.
+     *
+     * @return void
+     */
+    public function update (SplSubject $subject)
+    {
+    }
+
+    /**
+     * Outputs export header
+     *
+     * @return bool Whether it succeeded
+     */
+    public function exportHeader ()
+    {
+        PMA_exportOutputHandler(
+            '<?php' . $GLOBALS['crlf']
+            . '/**' . $GLOBALS['crlf']
+            . ' * Export to PHP Array plugin for PHPMyAdmin' . $GLOBALS['crlf']
+            . ' * @version 0.2b' . $GLOBALS['crlf']
+            . ' */' . $GLOBALS['crlf'] . $GLOBALS['crlf']
+        );
+        return true;
+    }
+
+    /**
+     * Outputs export footer
+     *
+     * @return bool Whether it succeeded
+     */
+    public function exportFooter ()
+    {
+        return true;
+    }
+
+    /**
+     * Outputs database header
+     *
+     * @param string $db Database name
+     *
+     * @return bool Whether it succeeded
+     */
+    public function exportDBHeader ($db)
+    {
+        PMA_exportOutputHandler(
+            '//' . $GLOBALS['crlf']
+            . '// Database ' . PMA_Util::backquote($db)
+            . $GLOBALS['crlf'] . '//' . $GLOBALS['crlf']
+        );
+        return true;
+    }
+
+    /**
+     * Outputs database footer
+     *
+     * @param string $db Database name
+     *
+     * @return bool Whether it succeeded
+     */
+    public function exportDBFooter ($db)
+    {
+        return true;
+    }
+
+    /**
+     * Outputs CREATE DATABASE statement
+     *
+     * @param string $db Database name
+     *
+     * @return bool Whether it succeeded
+     */
+    public function exportDBCreate($db)
+    {
+        return true;
+    }
+
+    /**
+     * Outputs the content of a table in NHibernate format
+     *
+     * @param string $db        database name
+     * @param string $table     table name
+     * @param string $crlf      the end of line sequence
+     * @param string $error_url the url to go back in case of error
+     * @param string $sql_query SQL query for obtaining data
+     *
+     * @return bool Whether it succeeded
+     */
+    public function exportData($db, $table, $crlf, $error_url, $sql_query)
+    {
+        $result = PMA_DBI_query($sql_query, null, PMA_DBI_QUERY_UNBUFFERED);
+
+        $columns_cnt = PMA_DBI_num_fields($result);
+        for ($i = 0; $i < $columns_cnt; $i++) {
+            $columns[$i] = stripslashes(PMA_DBI_field_name($result, $i));
+        }
+        unset($i);
+
+        // fix variable names (based on
+        // http://www.php.net/manual/language.variables.basics.php)
+        if (! preg_match(
+            '/^[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*$/',
+            $table
+        )) {
+            // fix invalid characters in variable names by replacing them with
+            // underscores
+            $tablefixed = preg_replace('/[^a-zA-Z0-9_\x7f-\xff]/', '_', $table);
+
+            // variable name must not start with a number or dash...
+            if (preg_match('/^[a-zA-Z_\x7f-\xff]/', $tablefixed) == false) {
+                $tablefixed = '_' . $tablefixed;
+            }
+        } else {
+            $tablefixed = $table;
+        }
+
+        $buffer = '';
+        $record_cnt = 0;
+        // Output table name as comment
+        $buffer .= $crlf . '// '
+                    . PMA_Util::backquote($db) . '.'
+                    . PMA_Util::backquote($table) . $crlf;
+        $buffer .= '$' . $tablefixed . ' = array(';
+        
+        while ($record = PMA_DBI_fetch_row($result)) {
+            $record_cnt++;
+
+            if ($record_cnt == 1) {
+                $buffer .= $crlf . '  array(';
+            } else {
+                $buffer .= ',' . $crlf . '  array(';
+            }
+
+            for ($i = 0; $i < $columns_cnt; $i++) {
+                $buffer .= var_export($columns[$i], true)
+                    . " => " . var_export($record[$i], true)
+                    . (($i + 1 >= $columns_cnt) ? '' : ',');
+            }
+
+            $buffer .= ')';
+        }
+
+        $buffer .= $crlf . ');' . $crlf;
+        if (! PMA_exportOutputHandler($buffer)) {
+            return false;
+        }
+
+        PMA_DBI_free_result($result);
+        return true;
+    }
+}
+?>
diff --git a/phpmyadmin/libraries/plugins/export/ExportSql.class.php b/phpmyadmin/libraries/plugins/export/ExportSql.class.php
new file mode 100644
index 0000000..4481013
--- /dev/null
+++ b/phpmyadmin/libraries/plugins/export/ExportSql.class.php
@@ -0,0 +1,1876 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * Set of functions used to build SQL dumps of tables
+ *
+ * @package    PhpMyAdmin-Export
+ * @subpackage SQL
+ */
+if (! defined('PHPMYADMIN')) {
+    exit;
+}
+
+/* Get the export interface */
+require_once 'libraries/plugins/ExportPlugin.class.php';
+
+/**
+ * Handles the export for the SQL class
+ *
+ * @package    PhpMyAdmin-Export
+ * @subpackage SQL
+ */
+class ExportSql extends ExportPlugin
+{
+    /**
+     * Constructor
+     */
+    public function __construct()
+    {
+        $this->setProperties();
+
+        // Avoids undefined variables, use NULL so isset() returns false
+        if (! isset($GLOBALS['sql_backquotes'])) {
+            $GLOBALS['sql_backquotes'] = null;
+        }
+    }
+
+    /**
+     * Sets the export SQL properties
+     *
+     * @return void
+     */
+    protected function setProperties()
+    {
+        global $plugin_param;
+
+        $hide_sql = false;
+        $hide_structure = false;
+        if ($plugin_param['export_type'] == 'table'
+            && ! $plugin_param['single_table']
+        ) {
+            $hide_structure = true;
+            $hide_sql = true;
+        }
+
+        if (! $hide_sql) {
+            $props = 'libraries/properties/';
+            include_once "$props/plugins/ExportPluginProperties.class.php";
+            include_once "$props/options/groups/OptionsPropertyRootGroup.class.php";
+            include_once "$props/options/groups/OptionsPropertyMainGroup.class.php";
+            include_once "$props/options/groups/OptionsPropertySubgroup.class.php";
+            include_once "$props/options/items/BoolPropertyItem.class.php";
+            include_once "$props/options/items/MessageOnlyPropertyItem.class.php";
+            include_once "$props/options/items/RadioPropertyItem.class.php";
+            include_once "$props/options/items/SelectPropertyItem.class.php";
+            include_once "$props/options/items/TextPropertyItem.class.php";
+
+            $exportPluginProperties = new ExportPluginProperties();
+            $exportPluginProperties->setText('SQL');
+            $exportPluginProperties->setExtension('sql');
+            $exportPluginProperties->setMimeType('text/x-sql');
+            $exportPluginProperties->setOptionsText(__('Options'));
+
+            // create the root group that will be the options field for
+            // $exportPluginProperties
+            // this will be shown as "Format specific options"
+            $exportSpecificOptions = new OptionsPropertyRootGroup();
+            $exportSpecificOptions->setName("Format Specific Options");
+
+            // general options main group
+            $generalOptions = new OptionsPropertyMainGroup();
+            $generalOptions->setName("general_opts");
+
+            // comments
+            $subgroup = new OptionsPropertySubgroup();
+            $subgroup->setName("include_comments");
+            $leaf = new BoolPropertyItem();
+            $leaf->setName('include_comments');
+            $leaf->setText(
+                __(
+                    'Display comments <i>(includes info such as export'
+                    . ' timestamp, PHP version, and server version)</i>'
+                )
+            );
+            $subgroup->setSubgroupHeader($leaf);
+
+            $leaf = new TextPropertyItem();
+            $leaf->setName('header_comment');
+            $leaf->setText(
+                __('Additional custom header comment (\n splits lines):')
+            );
+            $subgroup->addProperty($leaf);
+            $leaf = new BoolPropertyItem();
+            $leaf->setName('dates');
+            $leaf->setText(
+                __(
+                    'Include a timestamp of when databases were created, last'
+                    . ' updated, and last checked'
+                )
+            );
+            $subgroup->addProperty($leaf);
+            if (! empty($GLOBALS['cfgRelation']['relation'])) {
+                $leaf = new BoolPropertyItem();
+                $leaf->setName('relation');
+                $leaf->setText(__('Display foreign key relationships'));
+                $subgroup->addProperty($leaf);
+            }
+            if (! empty($GLOBALS['cfgRelation']['mimework'])) {
+                $leaf = new BoolPropertyItem();
+                $leaf->setName('mime');
+                $leaf->setText(__('Display MIME types'));
+                $subgroup->addProperty($leaf);
+            }
+            $generalOptions->addProperty($subgroup);
+
+            // enclose in a transaction
+            $leaf = new BoolPropertyItem();
+            $leaf->setName("use_transaction");
+            $leaf->setText(__('Enclose export in a transaction'));
+            $leaf->setDoc(
+                array(
+                    'programs',
+                    'mysqldump',
+                    'option_mysqldump_single-transaction'
+                )
+            );
+            $generalOptions->addProperty($leaf);
+
+            // disable foreign key checks
+            $leaf = new BoolPropertyItem();
+            $leaf->setName("disable_fk");
+            $leaf->setText(__('Disable foreign key checks'));
+            $leaf->setDoc(
+                array(
+                    'manual_MySQL_Database_Administration',
+                    'server-system-variables',
+                    'sysvar_foreign_key_checks'
+                )
+            );
+            $generalOptions->addProperty($leaf);
+
+            // compatibility maximization
+            $compats = PMA_DBI_getCompatibilities();
+            if (count($compats) > 0) {
+                $values = array();
+                foreach ($compats as $val) {
+                    $values[$val] = $val;
+                }
+
+                $leaf = new SelectPropertyItem();
+                $leaf->setName("compatibility");
+                $leaf->setText(
+                    __(
+                        'Database system or older MySQL server to maximize output'
+                        . ' compatibility with:'
+                    )
+                );
+                $leaf->setValues($values);
+                $leaf->setDoc(
+                    array(
+                        'manual_MySQL_Database_Administration',
+                        'Server_SQL_mode'
+                    )
+                );
+                $generalOptions->addProperty($leaf);
+
+                unset($values);
+            }
+
+            // server export options
+            if ($plugin_param['export_type'] == 'server') {
+                $leaf = new BoolPropertyItem();
+                $leaf->setName("drop_database");
+                $leaf->setText(
+                    sprintf(__('Add %s statement'), '<code>DROP DATABASE</code>')
+                );
+                $generalOptions->addProperty($leaf);
+            }
+
+            // what to dump (structure/data/both)
+            $subgroup = new OptionsPropertySubgroup();
+            $subgroup->setName("dump_table");
+            $subgroup->setText("Dump table");
+            $leaf = new RadioPropertyItem();
+            $leaf->setName('structure_or_data');
+            $leaf->setValues(
+                array(
+                    'structure' => __('structure'),
+                    'data' => __('data'),
+                    'structure_and_data' => __('structure and data')
+                )
+            );
+            $subgroup->setSubgroupHeader($leaf);
+            $generalOptions->addProperty($subgroup);
+
+            // add the main group to the root group
+            $exportSpecificOptions->addProperty($generalOptions);
+
+
+            // structure options main group
+            if (! $hide_structure) {
+                $structureOptions = new OptionsPropertyMainGroup();
+                $structureOptions->setName("structure");
+                $structureOptions->setText(__('Object creation options'));
+                $structureOptions->setForce('data');
+
+                // begin SQL Statements
+                $subgroup = new OptionsPropertySubgroup();
+                $leaf = new MessageOnlyPropertyItem();
+                $leaf->setName('add_statements');
+                $leaf->setText(__('Add statements:'));
+                $subgroup->setSubgroupHeader($leaf);
+                if ($plugin_param['export_type'] == 'table') {
+                    if (PMA_Table::isView($GLOBALS['db'], $GLOBALS['table'])) {
+                        $drop_clause = '<code>DROP VIEW</code>';
+                    } else {
+                        $drop_clause = '<code>DROP TABLE</code>';
+                    }
+                } else {
+                    if (PMA_DRIZZLE) {
+                        $drop_clause = '<code>DROP TABLE</code>';
+                    } else {
+                        $drop_clause = '<code>DROP TABLE / VIEW / PROCEDURE'
+                            . ' / FUNCTION</code>';
+                        if (PMA_MYSQL_INT_VERSION > 50100) {
+                            $drop_clause .= '<code> / EVENT</code>';
+                        }
+                    }
+                }
+                $leaf = new BoolPropertyItem();
+                $leaf->setName('drop_table');
+                $leaf->setText(sprintf(__('Add %s statement'), $drop_clause));
+                $subgroup->addProperty($leaf);
+                // Drizzle doesn't support procedures and functions
+                if (! PMA_DRIZZLE) {
+                    $leaf = new BoolPropertyItem();
+                    $leaf->setName('procedure_function');
+                    $leaf->setText(
+                        sprintf(
+                            __('Add %s statement'),
+                            '<code>CREATE PROCEDURE / FUNCTION'
+                            . (PMA_MYSQL_INT_VERSION > 50100
+                            ? ' / EVENT</code>' : '</code>')
+                        )
+                    );
+                    $subgroup->addProperty($leaf);
+                }
+
+                // begin CREATE TABLE statements
+                $subgroup_create_table = new OptionsPropertySubgroup();
+                $leaf = new BoolPropertyItem();
+                $leaf->setName('create_table_statements');
+                $leaf->setText(__('<code>CREATE TABLE</code> options:'));
+                $subgroup_create_table->setSubgroupHeader($leaf);
+                $leaf = new BoolPropertyItem();
+                $leaf->setName('if_not_exists');
+                $leaf->setText('<code>IF NOT EXISTS</code>');
+                $subgroup_create_table->addProperty($leaf);
+                $leaf = new BoolPropertyItem();
+                $leaf->setName('auto_increment');
+                $leaf->setText('<code>AUTO_INCREMENT</code>');
+                $subgroup_create_table->addProperty($leaf);
+                $subgroup->addProperty($subgroup_create_table);
+                $structureOptions->addProperty($subgroup);
+
+                $leaf = new BoolPropertyItem();
+                $leaf->setName("backquotes");
+                $leaf->setText(
+                    __(
+                        'Enclose table and column names with backquotes '
+                        . '<i>(Protects column and table names formed with'
+                        . ' special characters or keywords)</i>'
+                    )
+                );
+
+                $structureOptions->addProperty($leaf);
+
+                // add the main group to the root group
+                $exportSpecificOptions->addProperty($structureOptions);
+            }
+
+
+            // begin Data options
+            $dataOptions = new OptionsPropertyMainGroup();
+            $dataOptions->setName("data");
+            $dataOptions->setText(__('Data creation options'));
+            $dataOptions->setForce('structure');
+            $leaf = new BoolPropertyItem();
+            $leaf->setName("truncate");
+            $leaf->setText(__('Truncate table before insert'));
+            $dataOptions->addProperty($leaf);
+
+            // begin SQL Statements
+            $subgroup = new OptionsPropertySubgroup();
+            $leaf = new MessageOnlyPropertyItem();
+            $leaf->setText(__('Instead of <code>INSERT</code> statements, use:'));
+            $subgroup->setSubgroupHeader($leaf);
+            // Not supported in Drizzle
+            if (! PMA_DRIZZLE) {
+                $leaf = new BoolPropertyItem();
+                $leaf->setName("delayed");
+                $leaf->setText(__('<code>INSERT DELAYED</code> statements'));
+                $leaf->setDoc(
+                    array(
+                        'manual_MySQL_Database_Administration',
+                        'insert_delayed'
+                    )
+                );
+                $subgroup->addProperty($leaf);
+            }
+            $leaf = new BoolPropertyItem();
+            $leaf->setName("ignore");
+            $leaf->setText(__('<code>INSERT IGNORE</code> statements'));
+            $leaf->setDoc(
+                array(
+                        'manual_MySQL_Database_Administration',
+                        'insert'
+                )
+            );
+            $subgroup->addProperty($leaf);
+            $dataOptions->addProperty($subgroup);
+
+            // Function to use when dumping dat
+            $leaf = new SelectPropertyItem();
+            $leaf->setName("type");
+            $leaf->setText(__('Function to use when dumping data:'));
+            $leaf->setValues(
+                array(
+                    'INSERT' => 'INSERT',
+                    'UPDATE' => 'UPDATE',
+                    'REPLACE' => 'REPLACE'
+                )
+            );
+            $dataOptions->addProperty($leaf);
+
+            /* Syntax to use when inserting data */
+            $subgroup = new OptionsPropertySubgroup();
+            $leaf = new MessageOnlyPropertyItem();
+            $leaf->setText(__('Syntax to use when inserting data:'));
+            $subgroup->setSubgroupHeader($leaf);
+            $leaf = new RadioPropertyItem();
+            $leaf->setName("insert_syntax");
+            $leaf->setText(__('<code>INSERT IGNORE</code> statements'));
+            $leaf->setValues(
+                array(
+                    'complete' => __(
+                        'include column names in every <code>INSERT</code> statement'
+                        . ' <br />       Example: <code>INSERT INTO'
+                        . ' tbl_name (col_A,col_B,col_C) VALUES (1,2,3)</code>'
+                    ),
+                    'extended' => __(
+                        'insert multiple rows in every <code>INSERT</code> statement'
+                        . '<br />       Example: <code>INSERT INTO'
+                        . ' tbl_name VALUES (1,2,3), (4,5,6), (7,8,9)</code>'
+                    ),
+                    'both' => __(
+                        'both of the above<br />       Example:'
+                        . ' <code>INSERT INTO tbl_name (col_A,col_B) VALUES (1,2,3),'
+                        . ' (4,5,6), (7,8,9)</code>'
+                    ),
+                    'none' => __(
+                        'neither of the above<br />       Example:'
+                        . ' <code>INSERT INTO tbl_name VALUES (1,2,3)</code>'
+                    )
+                )
+            );
+            $subgroup->addProperty($leaf);
+            $dataOptions->addProperty($subgroup);
+
+            // Max length of query
+            $leaf = new TextPropertyItem();
+            $leaf->setName("max_query_size");
+            $leaf->setText(__('Maximal length of created query'));
+            $dataOptions->addProperty($leaf);
+
+            // Dump binary columns in hexadecimal
+            $leaf = new BoolPropertyItem();
+            $leaf->setName("hex_for_blob");
+            $leaf->setText(
+                __(
+                    'Dump binary columns in hexadecimal notation'
+                    . ' <i>(for example, "abc" becomes 0x616263)</i>'
+                )
+            );
+            $dataOptions->addProperty($leaf);
+
+            // Drizzle works only with UTC timezone
+            if (! PMA_DRIZZLE) {
+                // Dump time in UTC
+                $leaf = new BoolPropertyItem();
+                $leaf->setName("utc_time");
+                $leaf->setText(
+                    __(
+                        'Dump TIMESTAMP columns in UTC <i>(enables TIMESTAMP columns'
+                        . ' to be dumped and reloaded between servers in different'
+                        . ' time zones)</i>'
+                    )
+                );
+                $dataOptions->addProperty($leaf);
+            }
+
+            // add the main group to the root group
+            $exportSpecificOptions->addProperty($dataOptions);
+
+            // set the options for the export plugin property item
+            $exportPluginProperties->setOptions($exportSpecificOptions);
+            $this->properties = $exportPluginProperties;
+        }
+    }
+
+    /**
+     * This method is called when any PluginManager to which the observer
+     * is attached calls PluginManager::notify()
+     *
+     * @param SplSubject $subject The PluginManager notifying the observer
+     *                            of an update.
+     *
+     * @return void
+     */
+    public function update (SplSubject $subject)
+    {
+    }
+
+    /**
+     * Exports routines (procedures and functions)
+     *
+     * @param string $db Database
+     *
+     * @return bool Whether it succeeded
+     */
+    public function exportRoutines($db)
+    {
+        global $crlf;
+
+        $text = '';
+        $delimiter = '$$';
+
+        $procedure_names = PMA_DBI_get_procedures_or_functions($db, 'PROCEDURE');
+        $function_names = PMA_DBI_get_procedures_or_functions($db, 'FUNCTION');
+
+        if ($procedure_names || $function_names) {
+            $text .= $crlf
+                . 'DELIMITER ' . $delimiter . $crlf;
+        }
+
+        if ($procedure_names) {
+            $text .=
+                $this->_exportComment()
+              . $this->_exportComment(__('Procedures'))
+              . $this->_exportComment();
+
+            foreach ($procedure_names as $procedure_name) {
+                if (! empty($GLOBALS['sql_drop_table'])) {
+                    $text .= 'DROP PROCEDURE IF EXISTS '
+                        . PMA_Util::backquote($procedure_name)
+                        . $delimiter . $crlf;
+                }
+                $text .= PMA_DBI_get_definition($db, 'PROCEDURE', $procedure_name)
+                    . $delimiter . $crlf . $crlf;
+            }
+        }
+
+        if ($function_names) {
+            $text .=
+                $this->_exportComment()
+              . $this->_exportComment(__('Functions'))
+              . $this->_exportComment();
+
+            foreach ($function_names as $function_name) {
+                if (! empty($GLOBALS['sql_drop_table'])) {
+                    $text .= 'DROP FUNCTION IF EXISTS '
+                        . PMA_Util::backquote($function_name)
+                        . $delimiter . $crlf;
+                }
+                $text .= PMA_DBI_get_definition($db, 'FUNCTION', $function_name)
+                    . $delimiter . $crlf . $crlf;
+            }
+        }
+
+        if ($procedure_names || $function_names) {
+            $text .= 'DELIMITER ;' . $crlf;
+        }
+
+        if (! empty($text)) {
+            return PMA_exportOutputHandler($text);
+        } else {
+            return false;
+        }
+    }
+
+    /**
+     * Possibly outputs comment
+     *
+     * @param string $text Text of comment
+     *
+     * @return string The formatted comment
+     */
+    private function _exportComment($text = '')
+    {
+        if (isset($GLOBALS['sql_include_comments'])
+            && $GLOBALS['sql_include_comments']
+        ) {
+            // see http://dev.mysql.com/doc/refman/5.0/en/ansi-diff-comments.html
+            return '--' . (empty($text) ? '' : ' ') . $text . $GLOBALS['crlf'];
+        } else {
+            return '';
+        }
+    }
+
+    /**
+     * Possibly outputs CRLF
+     *
+     * @return string $crlf or nothing
+     */
+    private function _possibleCRLF()
+    {
+        if (isset($GLOBALS['sql_include_comments'])
+            && $GLOBALS['sql_include_comments']
+        ) {
+            return $GLOBALS['crlf'];
+        } else {
+            return '';
+        }
+    }
+
+    /**
+     * Outputs export footer
+     *
+     * @return bool Whether it succeeded
+     */
+    public function exportFooter()
+    {
+        global $crlf, $mysql_charset_map;
+
+        $foot = '';
+
+        if (isset($GLOBALS['sql_disable_fk'])) {
+            $foot .=  'SET FOREIGN_KEY_CHECKS=1;' . $crlf;
+        }
+
+        if (isset($GLOBALS['sql_use_transaction'])) {
+            $foot .=  'COMMIT;' . $crlf;
+        }
+
+        // restore connection settings
+        $charset_of_file = isset($GLOBALS['charset_of_file'])
+            ? $GLOBALS['charset_of_file'] : '';
+        if (! empty($GLOBALS['asfile'])
+            && isset($mysql_charset_map[$charset_of_file])
+            && ! PMA_DRIZZLE
+        ) {
+            $foot .=  $crlf
+                . '/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;'
+                . $crlf
+                . '/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;'
+                . $crlf
+                . '/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;'
+                . $crlf;
+        }
+
+        /* Restore timezone */
+        if (isset($GLOBALS['sql_utc_time']) && $GLOBALS['sql_utc_time']) {
+            PMA_DBI_query('SET time_zone = "' . $GLOBALS['old_tz'] . '"');
+        }
+
+        return PMA_exportOutputHandler($foot);
+    }
+
+    /**
+     * Outputs export header. It is the first method to be called, so all
+     * the required variables are initialized here.
+     *
+     * @return bool Whether it succeeded
+     */
+    public function exportHeader()
+    {
+        global $crlf, $cfg;
+        global $mysql_charset_map;
+
+        if (isset($GLOBALS['sql_compatibility'])) {
+            $tmp_compat = $GLOBALS['sql_compatibility'];
+            if ($tmp_compat == 'NONE') {
+                $tmp_compat = '';
+            }
+            PMA_DBI_try_query('SET SQL_MODE="' . $tmp_compat . '"');
+            unset($tmp_compat);
+        }
+        $head  =  $this->_exportComment('phpMyAdmin SQL Dump')
+               .  $this->_exportComment('version ' . PMA_VERSION)
+               .  $this->_exportComment('http://www.phpmyadmin.net')
+               .  $this->_exportComment();
+        $host_string = __('Host') . ': ' .  $cfg['Server']['host'];
+        if (! empty($cfg['Server']['port'])) {
+            $host_string .= ':' . $cfg['Server']['port'];
+        }
+        $head .= $this->_exportComment($host_string);
+        $head .=
+            $this->_exportComment(
+                __('Generation Time') . ': '
+                .  PMA_Util::localisedDate()
+            )
+            .  $this->_exportComment(
+                __('Server version') . ': ' . PMA_MYSQL_STR_VERSION
+            )
+            .  $this->_exportComment(__('PHP Version') . ': ' . phpversion())
+            .  $this->_possibleCRLF();
+
+        if (isset($GLOBALS['sql_header_comment'])
+            && ! empty($GLOBALS['sql_header_comment'])
+        ) {
+            // '\n' is not a newline (like "\n" would be), it's the characters
+            // backslash and n, as explained on the export interface
+            $lines = explode('\n', $GLOBALS['sql_header_comment']);
+            $head .= $this->_exportComment();
+            foreach ($lines as $one_line) {
+                $head .= $this->_exportComment($one_line);
+            }
+            $head .= $this->_exportComment();
+        }
+
+        if (isset($GLOBALS['sql_disable_fk'])) {
+            $head .= 'SET FOREIGN_KEY_CHECKS=0;' . $crlf;
+        }
+
+        // We want exported AUTO_INCREMENT columns to have still same value,
+        // do this only for recent MySQL exports
+        if ((! isset($GLOBALS['sql_compatibility'])
+            || $GLOBALS['sql_compatibility'] == 'NONE')
+            && ! PMA_DRIZZLE
+        ) {
+            $head .= 'SET SQL_MODE = "NO_AUTO_VALUE_ON_ZERO";' . $crlf;
+        }
+
+        if (isset($GLOBALS['sql_use_transaction'])) {
+            $head .= 'SET AUTOCOMMIT = 0;' . $crlf
+                   . 'START TRANSACTION;' . $crlf;
+        }
+
+        /* Change timezone if we should export timestamps in UTC */
+        if (isset($GLOBALS['sql_utc_time']) && $GLOBALS['sql_utc_time']) {
+            $head .= 'SET time_zone = "+00:00";' . $crlf;
+            $GLOBALS['old_tz'] = PMA_DBI_fetch_value('SELECT @@session.time_zone');
+            PMA_DBI_query('SET time_zone = "+00:00"');
+        }
+
+        $head .= $this->_possibleCRLF();
+
+        if (! empty($GLOBALS['asfile']) && ! PMA_DRIZZLE) {
+            // we are saving as file, therefore we provide charset information
+            // so that a utility like the mysql client can interpret
+            // the file correctly
+            if (isset($GLOBALS['charset_of_file'])
+                && isset($mysql_charset_map[$GLOBALS['charset_of_file']])
+            ) {
+                // we got a charset from the export dialog
+                $set_names = $mysql_charset_map[$GLOBALS['charset_of_file']];
+            } else {
+                // by default we use the connection charset
+                $set_names = $mysql_charset_map['utf-8'];
+            }
+            $head .=  $crlf
+                . '/*!40101 SET @OLD_CHARACTER_SET_CLIENT='
+                . '@@CHARACTER_SET_CLIENT */;' . $crlf
+                . '/*!40101 SET @OLD_CHARACTER_SET_RESULTS='
+                . '@@CHARACTER_SET_RESULTS */;' . $crlf
+                . '/*!40101 SET @OLD_COLLATION_CONNECTION='
+                . '@@COLLATION_CONNECTION */;'. $crlf
+                . '/*!40101 SET NAMES ' . $set_names . ' */;' . $crlf . $crlf;
+        }
+
+        return PMA_exportOutputHandler($head);
+    }
+
+    /**
+     * Outputs CREATE DATABASE statement
+     *
+     * @param string $db Database name
+     *
+     * @return bool Whether it succeeded
+     */
+    public function exportDBCreate($db)
+    {
+        global $crlf;
+
+        if (isset($GLOBALS['sql_compatibility'])) {
+            $compat = $GLOBALS['sql_compatibility'];
+        } else {
+            $compat = 'NONE';
+        }
+        if (isset($GLOBALS['sql_drop_database'])) {
+            if (! PMA_exportOutputHandler(
+                'DROP DATABASE '
+                . (isset($GLOBALS['sql_backquotes'])
+                ? PMA_Util::backquoteCompat($db, $compat) : $db)
+                . ';' . $crlf
+            )) {
+                return false;
+            }
+        }
+        $create_query = 'CREATE DATABASE IF NOT EXISTS '
+            . (isset($GLOBALS['sql_backquotes'])
+            ? PMA_Util::backquoteCompat($db, $compat) : $db);
+        $collation = PMA_getDbCollation($db);
+        if (PMA_DRIZZLE) {
+            $create_query .= ' COLLATE ' . $collation;
+        } else {
+            if (strpos($collation, '_')) {
+                $create_query .= ' DEFAULT CHARACTER SET '
+                    . substr($collation, 0, strpos($collation, '_'))
+                    . ' COLLATE ' . $collation;
+            } else {
+                $create_query .= ' DEFAULT CHARACTER SET ' . $collation;
+            }
+        }
+        $create_query .= ';' . $crlf;
+        if (! PMA_exportOutputHandler($create_query)) {
+            return false;
+        }
+        if (isset($GLOBALS['sql_backquotes'])
+            && ((isset($GLOBALS['sql_compatibility'])
+            && $GLOBALS['sql_compatibility'] == 'NONE')
+            || PMA_DRIZZLE)
+        ) {
+            $result = PMA_exportOutputHandler(
+                'USE ' . PMA_Util::backquoteCompat($db, $compat)
+                . ';' . $crlf
+            );
+        } else {
+            $result = PMA_exportOutputHandler('USE ' . $db . ';' . $crlf);
+        }
+
+        return $result;
+    }
+
+    /**
+     * Outputs database header
+     *
+     * @param string $db Database name
+     *
+     * @return bool Whether it succeeded
+     */
+    public function exportDBHeader($db)
+    {
+        if (isset($GLOBALS['sql_compatibility'])) {
+            $compat = $GLOBALS['sql_compatibility'];
+        } else {
+            $compat = 'NONE';
+        }
+        $head = $this->_exportComment()
+            . $this->_exportComment(
+                __('Database') . ': '
+                . (isset($GLOBALS['sql_backquotes'])
+                ? PMA_Util::backquoteCompat($db, $compat)
+                : '\'' . $db . '\'')
+            )
+            . $this->_exportComment();
+        return PMA_exportOutputHandler($head);
+    }
+
+    /**
+     * Outputs database footer
+     *
+     * @param string $db Database name
+     *
+     * @return bool Whether it succeeded
+     */
+    public function exportDBFooter($db)
+    {
+        global $crlf;
+
+        $result = true;
+        if (isset($GLOBALS['sql_constraints'])) {
+            $result = PMA_exportOutputHandler($GLOBALS['sql_constraints']);
+            unset($GLOBALS['sql_constraints']);
+        }
+
+        if (($GLOBALS['sql_structure_or_data'] == 'structure'
+            || $GLOBALS['sql_structure_or_data'] == 'structure_and_data')
+            && isset($GLOBALS['sql_procedure_function'])
+        ) {
+            $text = '';
+            $delimiter = '$$';
+
+            if (PMA_MYSQL_INT_VERSION > 50100) {
+                $event_names = PMA_DBI_fetch_result(
+                    'SELECT EVENT_NAME FROM information_schema.EVENTS WHERE'
+                    . ' EVENT_SCHEMA= \''
+                    . PMA_Util::sqlAddSlashes($db, true)
+                    . '\';'
+                );
+            } else {
+                $event_names = array();
+            }
+
+            if ($event_names) {
+                $text .= $crlf
+                  . 'DELIMITER ' . $delimiter . $crlf;
+
+                $text .=
+                    $this->_exportComment()
+                    . $this->_exportComment(__('Events'))
+                    . $this->_exportComment();
+
+                foreach ($event_names as $event_name) {
+                    if (! empty($GLOBALS['sql_drop_table'])) {
+                        $text .= 'DROP EVENT '
+                            . PMA_Util::backquote($event_name)
+                            . $delimiter . $crlf;
+                    }
+                    $text .= PMA_DBI_get_definition($db, 'EVENT', $event_name)
+                        . $delimiter . $crlf . $crlf;
+                }
+
+                $text .= 'DELIMITER ;' . $crlf;
+            }
+
+            if (! empty($text)) {
+                $result = PMA_exportOutputHandler($text);
+            }
+        }
+        return $result;
+    }
+
+    /**
+     * Returns a stand-in CREATE definition to resolve view dependencies
+     *
+     * @param string $db   the database name
+     * @param string $view the view name
+     * @param string $crlf the end of line sequence
+     *
+     * @return string resulting definition
+     */
+    public function getTableDefStandIn($db, $view, $crlf)
+    {
+        $create_query = '';
+        if (! empty($GLOBALS['sql_drop_table'])) {
+            $create_query .= 'DROP VIEW IF EXISTS '
+                . PMA_Util::backquote($view)
+                . ';' . $crlf;
+        }
+
+        $create_query .= 'CREATE TABLE ';
+
+        if (isset($GLOBALS['sql_if_not_exists'])
+            && $GLOBALS['sql_if_not_exists']
+        ) {
+            $create_query .= 'IF NOT EXISTS ';
+        }
+        $create_query .= PMA_Util::backquote($view) . ' (' . $crlf;
+        $tmp = array();
+        $columns = PMA_DBI_get_columns_full($db, $view);
+        foreach ($columns as $column_name => $definition) {
+            $tmp[] = PMA_Util::backquote($column_name) . ' ' .
+                $definition['Type'] . $crlf;
+        }
+        $create_query .= implode(',', $tmp) . ');';
+        return($create_query);
+    }
+
+    /**
+     * Returns $table's CREATE definition
+     *
+     * @param string $db            the database name
+     * @param string $table         the table name
+     * @param string $crlf          the end of line sequence
+     * @param string $error_url     the url to go back in case of error
+     * @param bool   $show_dates    whether to include creation/update/check
+     *                              dates
+     * @param bool   $add_semicolon whether to add semicolon and end-of-line at
+     *                              the end
+     * @param bool   $view          whether we're handling a view
+     *
+     * @return string resulting schema
+     */
+    public function getTableDef(
+        $db,
+        $table,
+        $crlf,
+        $error_url,
+        $show_dates = false,
+        $add_semicolon = true,
+        $view = false
+    ) {
+        global $sql_drop_table, $sql_backquotes, $sql_constraints,
+            $sql_constraints_query, $sql_drop_foreign_keys;
+
+        $schema_create = '';
+        $auto_increment = '';
+        $new_crlf = $crlf;
+
+        if (isset($GLOBALS['sql_compatibility'])) {
+            $compat = $GLOBALS['sql_compatibility'];
+        } else {
+            $compat = 'NONE';
+        }
+
+        // need to use PMA_DBI_QUERY_STORE with PMA_DBI_num_rows() in mysqli
+        $result = PMA_DBI_query(
+            'SHOW TABLE STATUS FROM ' . PMA_Util::backquote($db)
+            . ' LIKE \'' . PMA_Util::sqlAddSlashes($table, true) . '\'',
+            null,
+            PMA_DBI_QUERY_STORE
+        );
+        if ($result != false) {
+            if (PMA_DBI_num_rows($result) > 0) {
+                $tmpres = PMA_DBI_fetch_assoc($result);
+                if (PMA_DRIZZLE && $show_dates) {
+                    // Drizzle doesn't give Create_time and Update_time in
+                    // SHOW TABLE STATUS, add it
+                    $sql ="SELECT
+                            TABLE_CREATION_TIME AS Create_time,
+                            TABLE_UPDATE_TIME AS Update_time
+                        FROM data_dictionary.TABLES
+                        WHERE TABLE_SCHEMA = '"
+                        . PMA_Util::sqlAddSlashes($db) . "'
+                          AND TABLE_NAME = '"
+                        . PMA_Util::sqlAddSlashes($table) . "'";
+                    $tmpres = array_merge(PMA_DBI_fetch_single_row($sql), $tmpres);
+                }
+                // Here we optionally add the AUTO_INCREMENT next value,
+                // but starting with MySQL 5.0.24, the clause is already included
+                // in SHOW CREATE TABLE so we'll remove it below
+                // It's required for Drizzle because SHOW CREATE TABLE uses
+                // the value from table's creation time
+                if (isset($GLOBALS['sql_auto_increment'])
+                    && ! empty($tmpres['Auto_increment'])
+                ) {
+                    $auto_increment .= ' AUTO_INCREMENT='
+                        . $tmpres['Auto_increment'] . ' ';
+                }
+
+                if ($show_dates
+                    && isset($tmpres['Create_time'])
+                    && ! empty($tmpres['Create_time'])
+                ) {
+                    $schema_create .= $this->_exportComment(
+                        __('Creation') . ': '
+                        . PMA_Util::localisedDate(
+                            strtotime($tmpres['Create_time'])
+                        )
+                    );
+                    $new_crlf = $this->_exportComment() . $crlf;
+                }
+
+                if ($show_dates
+                    && isset($tmpres['Update_time'])
+                    && ! empty($tmpres['Update_time'])
+                ) {
+                    $schema_create .= $this->_exportComment(
+                        __('Last update') . ': '
+                        . PMA_Util::localisedDate(
+                            strtotime($tmpres['Update_time'])
+                        )
+                    );
+                    $new_crlf = $this->_exportComment() . $crlf;
+                }
+
+                if ($show_dates
+                    && isset($tmpres['Check_time'])
+                    && ! empty($tmpres['Check_time'])
+                ) {
+                    $schema_create .= $this->_exportComment(
+                        __('Last check') . ': '
+                        . PMA_Util::localisedDate(
+                            strtotime($tmpres['Check_time'])
+                        )
+                    );
+                    $new_crlf = $this->_exportComment() . $crlf;
+                }
+            }
+            PMA_DBI_free_result($result);
+        }
+
+        $schema_create .= $new_crlf;
+
+        // no need to generate a DROP VIEW here, it was done earlier
+        if (! empty($sql_drop_table) && ! PMA_Table::isView($db, $table)) {
+            $schema_create .= 'DROP TABLE IF EXISTS '
+                . PMA_Util::backquote($table, $sql_backquotes) . ';'
+                . $crlf;
+        }
+
+        // Complete table dump,
+        // Whether to quote table and column names or not
+        // Drizzle always quotes names
+        if (! PMA_DRIZZLE) {
+            if ($sql_backquotes) {
+                PMA_DBI_query('SET SQL_QUOTE_SHOW_CREATE = 1');
+            } else {
+                PMA_DBI_query('SET SQL_QUOTE_SHOW_CREATE = 0');
+            }
+        }
+
+        // I don't see the reason why this unbuffered query could cause problems,
+        // because SHOW CREATE TABLE returns only one row, and we free the
+        // results below. Nonetheless, we got 2 user reports about this
+        // (see bug 1562533) so I removed the unbuffered mode.
+        // $result = PMA_DBI_query('SHOW CREATE TABLE ' . backquote($db)
+        // . '.' . backquote($table), null, PMA_DBI_QUERY_UNBUFFERED);
+        //
+        // Note: SHOW CREATE TABLE, at least in MySQL 5.1.23, does not
+        // produce a displayable result for the default value of a BIT
+        // column, nor does the mysqldump command. See MySQL bug 35796
+        $result = PMA_DBI_try_query(
+            'SHOW CREATE TABLE ' . PMA_Util::backquote($db) . '.'
+            . PMA_Util::backquote($table)
+        );
+        // an error can happen, for example the table is crashed
+        $tmp_error = PMA_DBI_getError();
+        if ($tmp_error) {
+            return $this->_exportComment(__('in use') . '(' . $tmp_error . ')');
+        }
+
+        if ($result != false && ($row = PMA_DBI_fetch_row($result))) {
+            $create_query = $row[1];
+            unset($row);
+
+            // Convert end of line chars to one that we want (note that MySQL
+            // doesn't return query it will accept in all cases)
+            if (strpos($create_query, "(\r\n ")) {
+                $create_query = str_replace("\r\n", $crlf, $create_query);
+            } elseif (strpos($create_query, "(\n ")) {
+                $create_query = str_replace("\n", $crlf, $create_query);
+            } elseif (strpos($create_query, "(\r ")) {
+                $create_query = str_replace("\r", $crlf, $create_query);
+            }
+
+            /*
+             * Drop database name from VIEW creation.
+             *
+             * This is a bit tricky, but we need to issue SHOW CREATE TABLE with
+             * database name, but we don't want name to show up in CREATE VIEW
+             * statement.
+             */
+            if ($view) {
+                $create_query = preg_replace(
+                    '/' . PMA_Util::backquote($db) . '\./',
+                    '',
+                    $create_query
+                );
+            }
+
+            // Should we use IF NOT EXISTS?
+            // It always must be OFF for MSSQL compatibility mode
+            if (isset($GLOBALS['sql_if_not_exists']) && $compat != 'MSSQL') {
+                $create_query = preg_replace(
+                    '/^CREATE TABLE/',
+                    'CREATE TABLE IF NOT EXISTS',
+                    $create_query
+                );
+            }
+
+            // In MSSQL
+            // 1. DATE field doesn't exists, we will use DATETIME instead
+            // 2. UNSIGNED attribute doesn't exist
+            // 3. No length on INT, TINYINT, SMALLINT, BIGINT and no precision on
+            //    FLOAT fields
+            // 4. No KEY and INDEX inside CREATE TABLE
+            // 5. DOUBLE field doesn't exists, we will use FLOAT instead
+            if ($compat == 'MSSQL') {
+                // first we need  to replace all lines ended with '" DATE ...,\n'
+                // last preg_replace preserve us from situation with date text
+                // inside DEFAULT field value
+                $create_query = preg_replace(
+                    "/\" date DEFAULT NULL(,)?\n/",
+                    '" datetime DEFAULT NULL$1' . "\n",
+                    $create_query
+                );
+                $create_query = preg_replace(
+                    "/\" date NOT NULL(,)?\n/",
+                    '" datetime NOT NULL$1' . "\n",
+                    $create_query
+                );
+                $create_query = preg_replace(
+                    '/" date NOT NULL DEFAULT \'([^\'])/',
+                    '" datetime NOT NULL DEFAULT \'$1',
+                    $create_query
+                );
+
+                // next we need to replace all lines ended with ') UNSIGNED ...,'
+                // last preg_replace preserve us from situation with unsigned text
+                // inside DEFAULT field value
+                $create_query = preg_replace(
+                    "/\) unsigned NOT NULL(,)?\n/",
+                    ') NOT NULL$1' . "\n",
+                    $create_query
+                );
+                $create_query = preg_replace(
+                    "/\) unsigned DEFAULT NULL(,)?\n/",
+                    ') DEFAULT NULL$1' . "\n",
+                    $create_query
+                );
+                $create_query = preg_replace(
+                    '/\) unsigned NOT NULL DEFAULT \'([^\'])/',
+                    ') NOT NULL DEFAULT \'$1',
+                    $create_query
+                );
+
+                // we need to replace all lines ended with
+                // '" INT|TINYINT([0-9]{1,}) ...,' last preg_replace preserve us
+                // from situation with int([0-9]{1,}) text inside DEFAULT field
+                // value
+                $create_query = preg_replace(
+                    '/" (int|tinyint|smallint|bigint)\([0-9]+\) DEFAULT NULL(,)?\n/',
+                    '" $1 DEFAULT NULL$2' . "\n",
+                    $create_query
+                );
+                $create_query = preg_replace(
+                    '/" (int|tinyint|smallint|bigint)\([0-9]+\) NOT NULL(,)?\n/',
+                    '" $1 NOT NULL$2' . "\n",
+                    $create_query
+                );
+                $create_query = preg_replace(
+                    '/" (int|tinyint|smallint|bigint)\([0-9]+\) NOT NULL DEFAULT \'([^\'])/',
+                    '" $1 NOT NULL DEFAULT \'$2',
+                    $create_query
+                );
+
+                // we need to replace all lines ended with
+                // '" FLOAT|DOUBLE([0-9,]{1,}) ...,'
+                // last preg_replace preserve us from situation with
+                // float([0-9,]{1,}) text inside DEFAULT field value
+                $create_query = preg_replace(
+                    '/" (float|double)(\([0-9]+,[0-9,]+\))? DEFAULT NULL(,)?\n/',
+                    '" float DEFAULT NULL$3' . "\n",
+                    $create_query
+                );
+                $create_query = preg_replace(
+                    '/" (float|double)(\([0-9,]+,[0-9,]+\))? NOT NULL(,)?\n/',
+                    '" float NOT NULL$3' . "\n",
+                    $create_query
+                );
+                $create_query = preg_replace(
+                    '/" (float|double)(\([0-9,]+,[0-9,]+\))? NOT NULL DEFAULT \'([^\'])/',
+                    '" float NOT NULL DEFAULT \'$3',
+                    $create_query
+                );
+
+                // @todo remove indexes from CREATE TABLE
+            }
+
+            // Drizzle (checked on 2011.03.13) returns ROW_FORMAT surrounded
+            // with quotes, which is not accepted by parser
+            if (PMA_DRIZZLE) {
+                $create_query = preg_replace(
+                    '/ROW_FORMAT=\'(\S+)\'/',
+                    'ROW_FORMAT=$1',
+                    $create_query
+                );
+            }
+
+            // are there any constraints to cut out?
+            if (preg_match('@CONSTRAINT|FOREIGN[\s]+KEY@', $create_query)) {
+
+                // Split the query into lines, so we can easily handle it.
+                // We know lines are separated by $crlf (done few lines above).
+                $sql_lines = explode($crlf, $create_query);
+                $sql_count = count($sql_lines);
+
+                // lets find first line with constraints
+                for ($i = 0; $i < $sql_count; $i++) {
+                    if (preg_match(
+                        '@^[\s]*(CONSTRAINT|FOREIGN[\s]+KEY)@',
+                        $sql_lines[$i]
+                    )) {
+                        break;
+                    }
+                }
+
+                // If we really found a constraint
+                if ($i != $sql_count) {
+
+                    // remove, from the end of create statement
+                    $sql_lines[$i - 1] = preg_replace(
+                        '@,$@',
+                        '',
+                        $sql_lines[$i - 1]
+                    );
+
+                    // prepare variable for constraints
+                    if (! isset($sql_constraints)) {
+                        if (isset($GLOBALS['no_constraints_comments'])) {
+                            $sql_constraints = '';
+                        } else {
+                            $sql_constraints = $crlf
+                                . $this->_exportComment()
+                                . $this->_exportComment(
+                                    __('Constraints for dumped tables')
+                                )
+                                . $this->_exportComment();
+                        }
+                    }
+
+                    // comments for current table
+                    if (! isset($GLOBALS['no_constraints_comments'])) {
+                        $sql_constraints .= $crlf
+                        . $this->_exportComment()
+                        . $this->_exportComment(
+                            __('Constraints for table')
+                            . ' '
+                            . PMA_Util::backquoteCompat($table, $compat)
+                        )
+                        . $this->_exportComment();
+                    }
+
+                    // let's do the work
+                    $sql_constraints_query .= 'ALTER TABLE '
+                        . PMA_Util::backquoteCompat($table, $compat)
+                        . $crlf;
+                    $sql_constraints .= 'ALTER TABLE '
+                        . PMA_Util::backquoteCompat($table,  $compat)
+                        . $crlf;
+                    $sql_drop_foreign_keys .= 'ALTER TABLE '
+                        . PMA_Util::backquoteCompat($db, $compat) . '.'
+                        . PMA_Util::backquoteCompat($table, $compat)
+                        . $crlf;
+
+                    $first = true;
+                    for ($j = $i; $j < $sql_count; $j++) {
+                        if (preg_match(
+                            '@CONSTRAINT|FOREIGN[\s]+KEY@',
+                            $sql_lines[$j]
+                        )) {
+                            if (! $first) {
+                                $sql_constraints .= $crlf;
+                            }
+                            if (strpos($sql_lines[$j], 'CONSTRAINT') === false) {
+                                $tmp_str = preg_replace(
+                                    '/(FOREIGN[\s]+KEY)/',
+                                    'ADD \1',
+                                    $sql_lines[$j]
+                                );
+                                $sql_constraints_query .= $tmp_str;
+                                $sql_constraints .= $tmp_str;
+                            } else {
+                                $tmp_str = preg_replace(
+                                    '/(CONSTRAINT)/',
+                                    'ADD \1',
+                                    $sql_lines[$j]
+                                );
+                                $sql_constraints_query .= $tmp_str;
+                                $sql_constraints .= $tmp_str;
+                                preg_match(
+                                    '/(CONSTRAINT)([\s])([\S]*)([\s])/',
+                                    $sql_lines[$j],
+                                    $matches
+                                );
+                                if (! $first) {
+                                    $sql_drop_foreign_keys .= ', ';
+                                }
+                                $sql_drop_foreign_keys .= 'DROP FOREIGN KEY '
+                                    . $matches[3];
+                            }
+                            $first = false;
+                        } else {
+                            break;
+                        }
+                    }
+                    $sql_constraints .= ';' . $crlf;
+                    $sql_constraints_query .= ';';
+
+                    $create_query = implode(
+                        $crlf,
+                        array_slice($sql_lines, 0, $i)
+                    )
+                    . $crlf
+                    . implode(
+                        $crlf,
+                        array_slice($sql_lines, $j, $sql_count - 1)
+                    );
+                    unset($sql_lines);
+                }
+            }
+            $schema_create .= $create_query;
+        }
+
+        // remove a possible "AUTO_INCREMENT = value" clause
+        // that could be there starting with MySQL 5.0.24
+        // in Drizzle it's useless as it contains the value given at table
+        // creation time
+        $schema_create = preg_replace(
+            '/AUTO_INCREMENT\s*=\s*([0-9])+/',
+            '',
+            $schema_create
+        );
+
+        $schema_create .= ($compat != 'MSSQL') ? $auto_increment : '';
+
+        PMA_DBI_free_result($result);
+        return $schema_create . ($add_semicolon ? ';' . $crlf : '');
+    } // end of the 'getTableDef()' function
+
+    /**
+     * Returns $table's comments, relations etc.
+     *
+     * @param string $db          database name
+     * @param string $table       table name
+     * @param string $crlf        end of line sequence
+     * @param bool   $do_relation whether to include relation comments
+     * @param bool   $do_mime     whether to include mime comments
+     *
+     * @return string resulting comments
+     */
+    private function _getTableComments(
+        $db,
+        $table,
+        $crlf,
+        $do_relation = false,
+        $do_mime = false
+    ) {
+        global $cfgRelation, $sql_backquotes;
+
+        $schema_create = '';
+
+        // Check if we can use Relations
+        if ($do_relation && ! empty($cfgRelation['relation'])) {
+            // Find which tables are related with the current one and write it in
+            // an array
+            $res_rel = PMA_getForeigners($db, $table);
+
+            if ($res_rel && count($res_rel) > 0) {
+                $have_rel = true;
+            } else {
+                $have_rel = false;
+            }
+        } else {
+               $have_rel = false;
+        } // end if
+
+        if ($do_mime && $cfgRelation['mimework']) {
+            if (! ($mime_map = PMA_getMIME($db, $table, true))) {
+                unset($mime_map);
+            }
+        }
+
+        if (isset($mime_map) && count($mime_map) > 0) {
+            $schema_create .= $this->_possibleCRLF()
+            . $this->_exportComment()
+            . $this->_exportComment(
+                __('MIME TYPES FOR TABLE'). ' '
+                . PMA_Util::backquote($table, $sql_backquotes) . ':'
+            );
+            @reset($mime_map);
+            foreach ($mime_map AS $mime_field => $mime) {
+                $schema_create .=
+                    $this->_exportComment(
+                        '  '
+                        . PMA_Util::backquote($mime_field, $sql_backquotes)
+                    )
+                    . $this->_exportComment(
+                        '      '
+                        . PMA_Util::backquote(
+                            $mime['mimetype'],
+                            $sql_backquotes
+                        )
+                    );
+            }
+            $schema_create .= $this->_exportComment();
+        }
+
+        if ($have_rel) {
+            $schema_create .= $this->_possibleCRLF()
+                . $this->_exportComment()
+                . $this->_exportComment(
+                    __('RELATIONS FOR TABLE') . ' '
+                    . PMA_Util::backquote($table, $sql_backquotes)
+                    . ':'
+                );
+            foreach ($res_rel AS $rel_field => $rel) {
+                $schema_create .=
+                    $this->_exportComment(
+                        '  '
+                        . PMA_Util::backquote($rel_field, $sql_backquotes)
+                    )
+                    . $this->_exportComment(
+                        '      '
+                        . PMA_Util::backquote(
+                            $rel['foreign_table'],
+                            $sql_backquotes
+                        )
+                        . ' -> '
+                        . PMA_Util::backquote(
+                            $rel['foreign_field'],
+                            $sql_backquotes
+                        )
+                    );
+            }
+            $schema_create .= $this->_exportComment();
+        }
+
+        return $schema_create;
+
+    } // end of the '_getTableComments()' function
+
+    /**
+     * Outputs table's structure
+     *
+     * @param string $db          database name
+     * @param string $table       table name
+     * @param string $crlf        the end of line sequence
+     * @param string $error_url   the url to go back in case of error
+     * @param string $export_mode 'create_table','triggers','create_view',
+     *                            'stand_in'
+     * @param string $export_type 'server', 'database', 'table'
+     * @param bool   $relation    whether to include relation comments
+     * @param bool   $comments    whether to include the pmadb-style column
+     *                            comments as comments in the structure; this is
+     *                            deprecated but the parameter is left here
+     *                            because export.php calls exportStructure()
+     *                            also for other export types which use this
+     *                            parameter
+     * @param bool   $mime        whether to include mime comments
+     * @param bool   $dates       whether to include creation/update/check dates
+     *
+     * @return bool Whether it succeeded
+     */
+    public function exportStructure(
+        $db,
+        $table,
+        $crlf,
+        $error_url,
+        $export_mode,
+        $export_type,
+        $relation = false,
+        $comments = false,
+        $mime = false,
+        $dates = false
+    ) {
+        if (isset($GLOBALS['sql_compatibility'])) {
+            $compat = $GLOBALS['sql_compatibility'];
+        } else {
+            $compat = 'NONE';
+        }
+
+        $formatted_table_name = (isset($GLOBALS['sql_backquotes']))
+            ? PMA_Util::backquoteCompat($table, $compat)
+            : '\'' . $table . '\'';
+        $dump = $this->_possibleCRLF()
+            . $this->_exportComment(str_repeat('-', 56))
+            . $this->_possibleCRLF()
+            . $this->_exportComment();
+
+        switch($export_mode) {
+        case 'create_table':
+            $dump .= $this->_exportComment(
+                __('Table structure for table') . ' '. $formatted_table_name
+            );
+            $dump .= $this->_exportComment();
+            $dump .= $this->getTableDef($db, $table, $crlf, $error_url, $dates);
+            $dump .= $this->_getTableComments($db, $table, $crlf, $relation, $mime);
+            break;
+        case 'triggers':
+            $dump = '';
+            $triggers = PMA_DBI_get_triggers($db, $table);
+            if ($triggers) {
+                $dump .=  $this->_possibleCRLF()
+                    . $this->_exportComment()
+                    . $this->_exportComment(
+                        __('Triggers') . ' ' . $formatted_table_name
+                    )
+                    . $this->_exportComment();
+                $delimiter = '//';
+                foreach ($triggers as $trigger) {
+                    $dump .= $trigger['drop'] . ';' . $crlf;
+                    $dump .= 'DELIMITER ' . $delimiter . $crlf;
+                    $dump .= $trigger['create'];
+                    $dump .= 'DELIMITER ;' . $crlf;
+                }
+            }
+            break;
+        case 'create_view':
+            $dump .=
+                $this->_exportComment(
+                    __('Structure for view')
+                    . ' '
+                    . $formatted_table_name
+                )
+                . $this->_exportComment();
+            // delete the stand-in table previously created (if any)
+            if ($export_type != 'table') {
+                $dump .= 'DROP TABLE IF EXISTS '
+                    . PMA_Util::backquote($table) . ';' . $crlf;
+            }
+            $dump .= $this->getTableDef(
+                $db, $table, $crlf, $error_url, $dates, true, true
+            );
+            break;
+        case 'stand_in':
+            $dump .=
+                $this->_exportComment(
+                    __('Stand-in structure for view') . ' ' . $formatted_table_name
+                )
+                . $this->_exportComment();
+            // export a stand-in definition to resolve view dependencies
+            $dump .= $this->getTableDefStandIn($db, $table, $crlf);
+        } // end switch
+
+        // this one is built by getTableDef() to use in table copy/move
+        // but not in the case of export
+        unset($GLOBALS['sql_constraints_query']);
+
+        return PMA_exportOutputHandler($dump);
+    }
+
+    /**
+     * Outputs the content of a table in SQL format
+     *
+     * @param string $db        database name
+     * @param string $table     table name
+     * @param string $crlf      the end of line sequence
+     * @param string $error_url the url to go back in case of error
+     * @param string $sql_query SQL query for obtaining data
+     *
+     * @return bool Whether it succeeded
+     */
+    public function exportData($db, $table, $crlf, $error_url, $sql_query)
+    {
+        global $current_row, $sql_backquotes;
+
+        if (isset($GLOBALS['sql_compatibility'])) {
+            $compat = $GLOBALS['sql_compatibility'];
+        } else {
+            $compat = 'NONE';
+        }
+
+        $formatted_table_name = (isset($GLOBALS['sql_backquotes']))
+            ? PMA_Util::backquoteCompat($table, $compat)
+            : '\'' . $table . '\'';
+
+        // Do not export data for a VIEW
+        // (For a VIEW, this is called only when exporting a single VIEW)
+        if (PMA_Table::isView($db, $table)) {
+            $head = $this->_possibleCRLF()
+              . $this->_exportComment()
+              . $this->_exportComment('VIEW ' . ' ' . $formatted_table_name)
+              . $this->_exportComment(__('Data') . ': ' . __('None'))
+              . $this->_exportComment()
+              . $this->_possibleCRLF();
+
+            if (! PMA_exportOutputHandler($head)) {
+                return false;
+            }
+            return true;
+        }
+
+        // analyze the query to get the true column names, not the aliases
+        // (this fixes an undefined index, also if Complete inserts
+        //  are used, we did not get the true column name in case of aliases)
+        $analyzed_sql = PMA_SQP_analyze(PMA_SQP_parse($sql_query));
+
+        $result = PMA_DBI_try_query($sql_query, null, PMA_DBI_QUERY_UNBUFFERED);
+        // a possible error: the table has crashed
+        $tmp_error = PMA_DBI_getError();
+        if ($tmp_error) {
+            return PMA_exportOutputHandler(
+                $this->_exportComment(
+                    __('Error reading data:') . ' (' . $tmp_error . ')'
+                )
+            );
+        }
+
+        if ($result != false) {
+            $fields_cnt = PMA_DBI_num_fields($result);
+
+            // Get field information
+            $fields_meta = PMA_DBI_get_fields_meta($result);
+            $field_flags = array();
+            for ($j = 0; $j < $fields_cnt; $j++) {
+                $field_flags[$j] = PMA_DBI_field_flags($result, $j);
+            }
+
+            for ($j = 0; $j < $fields_cnt; $j++) {
+                if (isset($analyzed_sql[0]['select_expr'][$j]['column'])) {
+                    $field_set[$j] = PMA_Util::backquoteCompat(
+                        $analyzed_sql[0]['select_expr'][$j]['column'],
+                        $compat,
+                        $sql_backquotes
+                    );
+                } else {
+                    $field_set[$j] = PMA_Util::backquoteCompat(
+                        $fields_meta[$j]->name,
+                        $compat,
+                        $sql_backquotes
+                    );
+                }
+            }
+
+            if (isset($GLOBALS['sql_type'])
+                && $GLOBALS['sql_type'] == 'UPDATE'
+            ) {
+                // update
+                $schema_insert  = 'UPDATE ';
+                if (isset($GLOBALS['sql_ignore'])) {
+                    $schema_insert .= 'IGNORE ';
+                }
+                // avoid EOL blank
+                $schema_insert .= PMA_Util::backquoteCompat(
+                    $table,
+                    $compat,
+                    $sql_backquotes
+                ) . ' SET';
+            } else {
+                // insert or replace
+                if (isset($GLOBALS['sql_type'])
+                    && $GLOBALS['sql_type'] == 'REPLACE'
+                ) {
+                    $sql_command = 'REPLACE';
+                } else {
+                    $sql_command = 'INSERT';
+                }
+
+                // delayed inserts?
+                if (isset($GLOBALS['sql_delayed'])) {
+                    $insert_delayed = ' DELAYED';
+                } else {
+                    $insert_delayed = '';
+                }
+
+                // insert ignore?
+                if (isset($GLOBALS['sql_type'])
+                    && $GLOBALS['sql_type'] == 'INSERT'
+                    && isset($GLOBALS['sql_ignore'])
+                ) {
+                    $insert_delayed .= ' IGNORE';
+                }
+                //truncate table before insert
+                if (isset($GLOBALS['sql_truncate'])
+                    && $GLOBALS['sql_truncate']
+                    && $sql_command == 'INSERT'
+                ) {
+                    $truncate = 'TRUNCATE TABLE '
+                        . PMA_Util::backquoteCompat(
+                            $table,
+                            $compat,
+                            $sql_backquotes
+                        ) . ";";
+                    $truncatehead = $this->_possibleCRLF()
+                        . $this->_exportComment()
+                        . $this->_exportComment(
+                            __('Truncate table before insert') . ' '
+                            . $formatted_table_name
+                        )
+                        . $this->_exportComment()
+                        . $crlf;
+                    PMA_exportOutputHandler($truncatehead);
+                    PMA_exportOutputHandler($truncate);
+                } else {
+                    $truncate = '';
+                }
+
+                // scheme for inserting fields
+                if ($GLOBALS['sql_insert_syntax'] == 'complete'
+                    || $GLOBALS['sql_insert_syntax'] == 'both'
+                ) {
+                    $fields        = implode(', ', $field_set);
+                    $schema_insert = $sql_command . $insert_delayed .' INTO '
+                        . PMA_Util::backquoteCompat(
+                            $table,
+                            $compat,
+                            $sql_backquotes
+                        )
+                        // avoid EOL blank
+                        . ' (' . $fields . ') VALUES';
+                } else {
+                    $schema_insert = $sql_command . $insert_delayed .' INTO '
+                        . PMA_Util::backquoteCompat(
+                            $table,
+                            $compat,
+                            $sql_backquotes
+                        )
+                        . ' VALUES';
+                }
+            }
+
+            //\x08\\x09, not required
+            $search      = array("\x00", "\x0a", "\x0d", "\x1a");
+            $replace     = array('\0', '\n', '\r', '\Z');
+            $current_row = 0;
+            $query_size  = 0;
+            if (($GLOBALS['sql_insert_syntax'] == 'extended'
+                || $GLOBALS['sql_insert_syntax'] == 'both')
+                && (! isset($GLOBALS['sql_type'])
+                || $GLOBALS['sql_type'] != 'UPDATE')
+            ) {
+                $separator      = ',';
+                $schema_insert .= $crlf;
+            } else {
+                $separator      = ';';
+            }
+
+            while ($row = PMA_DBI_fetch_row($result)) {
+                if ($current_row == 0) {
+                    $head = $this->_possibleCRLF()
+                        . $this->_exportComment()
+                        . $this->_exportComment(
+                            __('Dumping data for table') . ' '
+                            . $formatted_table_name
+                        )
+                        . $this->_exportComment()
+                        . $crlf;
+                    if (! PMA_exportOutputHandler($head)) {
+                        return false;
+                    }
+                }
+                 // We need to SET IDENTITY_INSERT ON for MSSQL
+                if (isset($GLOBALS['sql_compatibility'])
+                    && $GLOBALS['sql_compatibility'] == 'MSSQL'
+                    && $current_row == 0
+                ) {
+                    if (! PMA_exportOutputHandler(
+                        'SET IDENTITY_INSERT '
+                        . PMA_Util::backquoteCompat(
+                            $table,
+                            $compat
+                        )
+                        . ' ON ;'.$crlf
+                    )) {
+                        return false;
+                    }
+                }
+                $current_row++;
+                for ($j = 0; $j < $fields_cnt; $j++) {
+                    // NULL
+                    if (! isset($row[$j]) || is_null($row[$j])) {
+                        $values[] = 'NULL';
+                    } elseif ($fields_meta[$j]->numeric
+                        && $fields_meta[$j]->type != 'timestamp'
+                        && ! $fields_meta[$j]->blob
+                    ) {
+                        // a number
+                        // timestamp is numeric on some MySQL 4.1, BLOBs are
+                        // sometimes numeric
+                        $values[] = $row[$j];
+                    } elseif (stristr($field_flags[$j], 'BINARY')
+                        && $fields_meta[$j]->blob
+                        && isset($GLOBALS['sql_hex_for_blob'])
+                    ) {
+                        // a true BLOB
+                        // - mysqldump only generates hex data when the --hex-blob
+                        //   option is used, for fields having the binary attribute
+                        //   no hex is generated
+                        // - a TEXT field returns type blob but a real blob
+                        //   returns also the 'binary' flag
+
+                        // empty blobs need to be different, but '0' is also empty
+                        // :-(
+                        if (empty($row[$j]) && $row[$j] != '0') {
+                            $values[] = '\'\'';
+                        } else {
+                            $values[] = '0x' . bin2hex($row[$j]);
+                        }
+                    } elseif ($fields_meta[$j]->type == 'bit') {
+                        // detection of 'bit' works only on mysqli extension
+                        $values[] = "b'" . PMA_Util::sqlAddSlashes(
+                            PMA_Util::printableBitValue(
+                                $row[$j], $fields_meta[$j]->length
+                            )
+                        )
+                            . "'";
+                    } else {
+                        // something else -> treat as a string
+                        $values[] = '\''
+                            . str_replace(
+                                $search, $replace,
+                                PMA_Util::sqlAddSlashes($row[$j])
+                            )
+                            . '\'';
+                    } // end if
+                } // end for
+
+                // should we make update?
+                if (isset($GLOBALS['sql_type'])
+                    && $GLOBALS['sql_type'] == 'UPDATE'
+                ) {
+
+                    $insert_line = $schema_insert;
+                    for ($i = 0; $i < $fields_cnt; $i++) {
+                        if (0 == $i) {
+                            $insert_line .= ' ';
+                        }
+                        if ($i > 0) {
+                            // avoid EOL blank
+                            $insert_line .= ',';
+                        }
+                        $insert_line .= $field_set[$i] . ' = ' . $values[$i];
+                    }
+
+                    list($tmp_unique_condition, $tmp_clause_is_unique)
+                        = PMA_Util::getUniqueCondition(
+                            $result,
+                            $fields_cnt,
+                            $fields_meta,
+                            $row
+                        );
+                    $insert_line .= ' WHERE ' . $tmp_unique_condition;
+                    unset($tmp_unique_condition, $tmp_clause_is_unique);
+
+                } else {
+
+                    // Extended inserts case
+                    if ($GLOBALS['sql_insert_syntax'] == 'extended'
+                        || $GLOBALS['sql_insert_syntax'] == 'both'
+                    ) {
+                        if ($current_row == 1) {
+                            $insert_line  = $schema_insert . '('
+                                . implode(', ', $values) . ')';
+                        } else {
+                            $insert_line  = '(' . implode(', ', $values) . ')';
+                            $sql_max_size = $GLOBALS['sql_max_query_size'];
+                            if (isset($sql_max_size)
+                                && $sql_max_size > 0
+                                && $query_size + strlen($insert_line) > $sql_max_size
+                            ) {
+                                if (! PMA_exportOutputHandler(';' . $crlf)) {
+                                    return false;
+                                }
+                                $query_size  = 0;
+                                $current_row = 1;
+                                $insert_line = $schema_insert . $insert_line;
+                            }
+                        }
+                        $query_size += strlen($insert_line);
+                        // Other inserts case
+                    } else {
+                        $insert_line = $schema_insert
+                            . '('
+                            . implode(', ', $values)
+                            . ')';
+                    }
+                }
+                unset($values);
+
+                if (! PMA_exportOutputHandler(
+                    ($current_row == 1 ? '' : $separator . $crlf)
+                    . $insert_line
+                )) {
+                    return false;
+                }
+
+            } // end while
+
+            if ($current_row > 0) {
+                if (! PMA_exportOutputHandler(';' . $crlf)) {
+                    return false;
+                }
+            }
+
+            // We need to SET IDENTITY_INSERT OFF for MSSQL
+            if (isset($GLOBALS['sql_compatibility'])
+                && $GLOBALS['sql_compatibility'] == 'MSSQL'
+                && $current_row > 0
+            ) {
+                $outputSucceeded = PMA_exportOutputHandler(
+                    $crlf . 'SET IDENTITY_INSERT '
+                    . PMA_Util::backquoteCompat($table, $compat)
+                    . ' OFF;' . $crlf
+                );
+                if (! $outputSucceeded) {
+                    return false;
+                }
+            }
+        } // end if ($result != false)
+        PMA_DBI_free_result($result);
+
+        return true;
+    } // end of the 'exportData()' function
+}
diff --git a/phpmyadmin/libraries/plugins/export/ExportTexytext.class.php b/phpmyadmin/libraries/plugins/export/ExportTexytext.class.php
new file mode 100644
index 0000000..3aa609c
--- /dev/null
+++ b/phpmyadmin/libraries/plugins/export/ExportTexytext.class.php
@@ -0,0 +1,574 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * Export to Texy! text.
+ *
+ * @package    PhpMyAdmin-Export
+ * @subpackage Texy!text
+ */
+if (! defined('PHPMYADMIN')) {
+    exit;
+}
+
+/* Get the export interface */
+require_once 'libraries/plugins/ExportPlugin.class.php';
+
+/**
+ * Handles the export for the Texy! text class
+ *
+ * @package    PhpMyAdmin-Export
+ * @subpackage Texy!text
+ */
+class ExportTexytext extends ExportPlugin
+{
+    /**
+     * Constructor
+     */
+    public function __construct()
+    {
+        $this->setProperties();
+    }
+
+    /**
+     * Sets the export Texy! text properties
+     *
+     * @return void
+     */
+    protected function setProperties()
+    {
+        $props = 'libraries/properties/';
+        include_once "$props/plugins/ExportPluginProperties.class.php";
+        include_once "$props/options/groups/OptionsPropertyRootGroup.class.php";
+        include_once "$props/options/groups/OptionsPropertyMainGroup.class.php";
+        include_once "$props/options/items/RadioPropertyItem.class.php";
+        include_once "$props/options/items/BoolPropertyItem.class.php";
+        include_once "$props/options/items/TextPropertyItem.class.php";
+
+        $exportPluginProperties = new ExportPluginProperties();
+        $exportPluginProperties->setText('Texy! text');
+        $exportPluginProperties->setExtension('txt');
+        $exportPluginProperties->setMimeType('text/plain');
+        $exportPluginProperties->setOptionsText(__('Options'));
+
+        // create the root group that will be the options field for
+        // $exportPluginProperties
+        // this will be shown as "Format specific options"
+        $exportSpecificOptions = new OptionsPropertyRootGroup();
+        $exportSpecificOptions->setName("Format Specific Options");
+
+        // what to dump (structure/data/both) main group
+        $dumpWhat = new OptionsPropertyMainGroup();
+        $dumpWhat->setName("general_opts");
+        $dumpWhat->setText(__('Dump table'));
+        // create primary items and add them to the group
+        $leaf = new RadioPropertyItem();
+        $leaf->setName("structure_or_data");
+        $leaf->setValues(
+            array(
+                'structure' => __('structure'),
+                'data' => __('data'),
+                'structure_and_data' => __('structure and data')
+            )
+        );
+        $dumpWhat->addProperty($leaf);
+        // add the main group to the root group
+        $exportSpecificOptions->addProperty($dumpWhat);
+
+        // data options main group
+        $dataOptions = new OptionsPropertyMainGroup();
+        $dataOptions->setName("data");
+        $dataOptions->setText(__('Data dump options'));
+        $dataOptions->setForce('structure');
+        // create primary items and add them to the group
+        $leaf = new BoolPropertyItem();
+        $leaf->setName("columns");
+        $leaf->setText(__('Put columns names in the first row'));
+        $dataOptions->addProperty($leaf);
+        $leaf = new TextPropertyItem();
+        $leaf->setName('null');
+        $leaf->setText(__('Replace NULL with:'));
+        $dataOptions->addProperty($leaf);
+        // add the main group to the root group
+        $exportSpecificOptions->addProperty($dataOptions);
+
+        // set the options for the export plugin property item
+        $exportPluginProperties->setOptions($exportSpecificOptions);
+        $this->properties = $exportPluginProperties;
+    }
+
+    /**
+     * This method is called when any PluginManager to which the observer
+     * is attached calls PluginManager::notify()
+     *
+     * @param SplSubject $subject The PluginManager notifying the observer
+     *                            of an update.
+     *
+     * @return void
+     */
+    public function update (SplSubject $subject)
+    {
+    }
+
+    /**
+     * Outputs export header
+     *
+     * @return bool Whether it succeeded
+     */
+    public function exportHeader ()
+    {
+        return true;
+    }
+
+    /**
+     * Outputs export footer
+     *
+     * @return bool Whether it succeeded
+     */
+    public function exportFooter ()
+    {
+        return true;
+    }
+
+    /**
+     * Outputs database header
+     *
+     * @param string $db Database name
+     *
+     * @return bool Whether it succeeded
+     */
+    public function exportDBHeader ($db)
+    {
+        return PMA_exportOutputHandler(
+            '===' . __('Database') . ' ' . $db . "\n\n"
+        );
+    }
+
+    /**
+     * Outputs database footer
+     *
+     * @param string $db Database name
+     *
+     * @return bool Whether it succeeded
+     */
+    public function exportDBFooter ($db)
+    {
+        return true;
+    }
+
+    /**
+     * Outputs CREATE DATABASE statement
+     *
+     * @param string $db Database name
+     *
+     * @return bool Whether it succeeded
+     */
+    public function exportDBCreate($db)
+    {
+        return true;
+    }
+    /**
+     * Outputs the content of a table in NHibernate format
+     *
+     * @param string $db        database name
+     * @param string $table     table name
+     * @param string $crlf      the end of line sequence
+     * @param string $error_url the url to go back in case of error
+     * @param string $sql_query SQL query for obtaining data
+     *
+     * @return bool Whether it succeeded
+     */
+    public function exportData($db, $table, $crlf, $error_url, $sql_query)
+    {
+        global $what;
+
+        if (! PMA_exportOutputHandler(
+            '== ' . __('Dumping data for table') . ' ' . $table . "\n\n"
+        )) {
+            return false;
+        }
+
+        // Gets the data from the database
+        $result      = PMA_DBI_query($sql_query, null, PMA_DBI_QUERY_UNBUFFERED);
+        $fields_cnt  = PMA_DBI_num_fields($result);
+
+        // If required, get fields name at the first line
+        if (isset($GLOBALS[$what . '_columns'])) {
+            $text_output = "|------\n";
+            for ($i = 0; $i < $fields_cnt; $i++) {
+                $text_output .= '|'
+                    . htmlspecialchars(
+                        stripslashes(PMA_DBI_field_name($result, $i))
+                    );
+            } // end for
+            $text_output .= "\n|------\n";
+            if (! PMA_exportOutputHandler($text_output)) {
+                return false;
+            }
+        } // end if
+
+        // Format the data
+        while ($row = PMA_DBI_fetch_row($result)) {
+            $text_output = '';
+            for ($j = 0; $j < $fields_cnt; $j++) {
+                if (! isset($row[$j]) || is_null($row[$j])) {
+                    $value = $GLOBALS[$what . '_null'];
+                } elseif ($row[$j] == '0' || $row[$j] != '') {
+                    $value = $row[$j];
+                } else {
+                    $value = ' ';
+                }
+                $text_output .= '|'
+                    . str_replace(
+                        '|', '|', htmlspecialchars($value)
+                    );
+            } // end for
+            $text_output .= "\n";
+            if (! PMA_exportOutputHandler($text_output)) {
+                return false;
+            }
+        } // end while
+        PMA_DBI_free_result($result);
+
+        return true;
+    }
+
+    /**
+     * Returns a stand-in CREATE definition to resolve view dependencies
+     *
+     * @param string $db   the database name
+     * @param string $view the view name
+     * @param string $crlf the end of line sequence
+     *
+     * @return string resulting definition
+     */
+    function getTableDefStandIn($db, $view, $crlf)
+    {
+        $text_output = '';
+
+        /**
+         * Get the unique keys in the table
+         */
+        $unique_keys = array();
+        $keys = PMA_DBI_get_table_indexes($db, $view);
+        foreach ($keys as $key) {
+            if ($key['Non_unique'] == 0) {
+                $unique_keys[] = $key['Column_name'];
+            }
+        }
+
+        /**
+         * Gets fields properties
+         */
+        PMA_DBI_select_db($db);
+
+        /**
+         * Displays the table structure
+         */
+
+        $text_output .= "|------\n"
+            . '|' . __('Column')
+            . '|' . __('Type')
+            . '|' . __('Null')
+            . '|' . __('Default')
+            . "\n|------\n";
+
+        $columns = PMA_DBI_get_columns($db, $view);
+        foreach ($columns as $column) {
+            $text_output .= $this->formatOneColumnDefinition($column, $unique_keys);
+            $text_output .= "\n";
+        } // end foreach
+
+        return $text_output;
+    }
+
+    /**
+     * Returns $table's CREATE definition
+     *
+     * @param string $db            the database name
+     * @param string $table         the table name
+     * @param string $crlf          the end of line sequence
+     * @param string $error_url     the url to go back in case of error
+     * @param bool   $do_relation   whether to include relation comments
+     * @param bool   $do_comments   whether to include the pmadb-style column
+     *                                comments as comments in the structure;
+     *                                this is deprecated but the parameter is
+     *                                left here because export.php calls
+     *                                $this->exportStructure() also for other
+     *                                export types which use this parameter
+     * @param bool   $do_mime       whether to include mime comments
+     * @param bool   $show_dates    whether to include creation/update/check dates
+     * @param bool   $add_semicolon whether to add semicolon and end-of-line
+     *                              at the end
+     * @param bool   $view          whether we're handling a view
+     *
+     * @return string resulting schema
+     */
+    function getTableDef(
+        $db,
+        $table,
+        $crlf,
+        $error_url,
+        $do_relation,
+        $do_comments,
+        $do_mime,
+        $show_dates = false,
+        $add_semicolon = true,
+        $view = false
+    ) {
+        global $cfgRelation;
+
+        $text_output = '';
+
+        /**
+         * Get the unique keys in the table
+         */
+        $unique_keys = array();
+        $keys        = PMA_DBI_get_table_indexes($db, $table);
+        foreach ($keys as $key) {
+            if ($key['Non_unique'] == 0) {
+                $unique_keys[] = $key['Column_name'];
+            }
+        }
+
+        /**
+         * Gets fields properties
+         */
+        PMA_DBI_select_db($db);
+
+        // Check if we can use Relations
+        if ($do_relation && ! empty($cfgRelation['relation'])) {
+            // Find which tables are related with the current one and write it in
+            // an array
+            $res_rel = PMA_getForeigners($db, $table);
+
+            if ($res_rel && count($res_rel) > 0) {
+                $have_rel = true;
+            } else {
+                $have_rel = false;
+            }
+        } else {
+               $have_rel = false;
+        } // end if
+
+        /**
+         * Displays the table structure
+         */
+
+        $columns_cnt = 4;
+        if ($do_relation && $have_rel) {
+            $columns_cnt++;
+        }
+        if ($do_comments && $cfgRelation['commwork']) {
+            $columns_cnt++;
+        }
+        if ($do_mime && $cfgRelation['mimework']) {
+            $columns_cnt++;
+        }
+
+        $text_output .= "|------\n";
+        $text_output .= '|' . __('Column');
+        $text_output .= '|' . __('Type');
+        $text_output .= '|' . __('Null');
+        $text_output .= '|' . __('Default');
+        if ($do_relation && $have_rel) {
+            $text_output .= '|' . __('Links to');
+        }
+        if ($do_comments) {
+            $text_output .= '|' . __('Comments');
+            $comments = PMA_getComments($db, $table);
+        }
+        if ($do_mime && $cfgRelation['mimework']) {
+            $text_output .= '|' . htmlspecialchars('MIME');
+            $mime_map = PMA_getMIME($db, $table, true);
+        }
+        $text_output .= "\n|------\n";
+
+        $columns = PMA_DBI_get_columns($db, $table);
+        foreach ($columns as $column) {
+            $text_output .= $this->formatOneColumnDefinition($column, $unique_keys);
+            $field_name = $column['Field'];
+
+            if ($do_relation && $have_rel) {
+                $text_output .= '|'
+                    . (isset($res_rel[$field_name])
+                    ? htmlspecialchars(
+                        $res_rel[$field_name]['foreign_table']
+                        . ' (' . $res_rel[$field_name]['foreign_field'] . ')'
+                    )
+                    : '');
+            }
+            if ($do_comments && $cfgRelation['commwork']) {
+                $text_output .= '|'
+                    . (isset($comments[$field_name])
+                    ? htmlspecialchars($comments[$field_name])
+                    : '');
+            }
+            if ($do_mime && $cfgRelation['mimework']) {
+                $text_output .= '|'
+                    . (isset($mime_map[$field_name])
+                    ? htmlspecialchars(
+                        str_replace('_', '/', $mime_map[$field_name]['mimetype'])
+                    )
+                    : '');
+            }
+
+            $text_output .= "\n";
+        } // end foreach
+
+        return $text_output;
+    } // end of the '$this->getTableDef()' function
+
+    /**
+     * Outputs triggers
+     *
+     * @param string $db    database name
+     * @param string $table table name
+     *
+     * @return string Formatted triggers list
+     */
+    function getTriggers($db, $table)
+    {
+        $text_output .= "|------\n";
+        $text_output .= '|' . __('Column');
+        $dump = "|------\n";
+        $dump .= '|' . __('Name');
+        $dump .= '|' . __('Time');
+        $dump .= '|' . __('Event');
+        $dump .= '|' . __('Definition');
+        $dump .= "\n|------\n";
+
+        $triggers = PMA_DBI_get_triggers($db, $table);
+
+        foreach ($triggers as $trigger) {
+            $dump .= '|' . $trigger['name'];
+            $dump .= '|' . $trigger['action_timing'];
+            $dump .= '|' . $trigger['event_manipulation'];
+            $dump .= '|' .
+                str_replace(
+                    '|',
+                    '|',
+                    htmlspecialchars($trigger['definition'])
+                );
+            $dump .= "\n";
+        }
+
+        return $dump;
+    }
+
+    /**
+     * Outputs table's structure
+     *
+     * @param string $db          database name
+     * @param string $table       table name
+     * @param string $crlf        the end of line sequence
+     * @param string $error_url   the url to go back in case of error
+     * @param string $export_mode 'create_table', 'triggers', 'create_view',
+     *                            'stand_in'
+     * @param string $export_type 'server', 'database', 'table'
+     * @param bool   $do_relation whether to include relation comments
+     * @param bool   $do_comments whether to include the pmadb-style column
+     *                                comments as comments in the structure;
+     *                                this is deprecated but the parameter is
+     *                                left here because export.php calls
+     *                                $this->exportStructure() also for other
+     *                                export types which use this parameter
+     * @param bool   $do_mime     whether to include mime comments
+     * @param bool   $dates       whether to include creation/update/check dates
+     *
+     * @return bool Whether it succeeded
+     */
+    function exportStructure(
+        $db,
+        $table,
+        $crlf,
+        $error_url,
+        $export_mode,
+        $export_type,
+        $do_relation = false,
+        $do_comments = false,
+        $do_mime = false,
+        $dates = false
+    ) {
+        $dump = '';
+
+        switch($export_mode) {
+        case 'create_table':
+            $dump .= '== ' . __('Table structure for table') . ' ' .$table . "\n\n";
+            $dump .= $this->getTableDef(
+                $db, $table, $crlf, $error_url, $do_relation, $do_comments,
+                $do_mime, $dates
+            );
+            break;
+        case 'triggers':
+            $dump = '';
+            $triggers = PMA_DBI_get_triggers($db, $table);
+            if ($triggers) {
+                $dump .= '== ' . __('Triggers') . ' ' .$table . "\n\n";
+                $dump .= $this->getTriggers($db, $table);
+            }
+            break;
+        case 'create_view':
+            $dump .= '== ' . __('Structure for view') . ' ' .$table . "\n\n";
+            $dump .= $this->getTableDef(
+                $db, $table, $crlf, $error_url, $do_relation, $do_comments,
+                $do_mime, $dates, true, true
+            );
+            break;
+        case 'stand_in':
+            $dump .=  '== ' . __('Stand-in structure for view')
+                . ' ' .$table . "\n\n";
+            // export a stand-in definition to resolve view dependencies
+            $dump .= $this->getTableDefStandIn($db, $table, $crlf);
+        } // end switch
+
+        return PMA_exportOutputHandler($dump);
+    }
+
+    /**
+     * Formats the definition for one column
+     *
+     * @param array $column      info about this column
+     * @param array $unique_keys unique keys for this table
+     *
+     * @return string Formatted column definition
+     */
+    function formatOneColumnDefinition(
+        $column, $unique_keys
+    ) {
+        $extracted_columnspec
+            = PMA_Util::extractColumnSpec($column['Type']);
+        $type = $extracted_columnspec['print_type'];
+        if (empty($type)) {
+            $type     = ' ';
+        }
+
+        if (! isset($column['Default'])) {
+            if ($column['Null'] != 'NO') {
+                $column['Default'] = 'NULL';
+            }
+        }
+
+        $fmt_pre = '';
+        $fmt_post = '';
+        if (in_array($column['Field'], $unique_keys)) {
+            $fmt_pre = '**' . $fmt_pre;
+            $fmt_post = $fmt_post . '**';
+        }
+        if ($column['Key']=='PRI') {
+            $fmt_pre = '//' . $fmt_pre;
+            $fmt_post = $fmt_post . '//';
+        }
+        $definition = '|'
+            . $fmt_pre . htmlspecialchars($column['Field']) . $fmt_post;
+        $definition .= '|' . htmlspecialchars($type);
+        $definition .= '|'
+            . (($column['Null'] == '' || $column['Null'] == 'NO')
+            ? __('No') : __('Yes'));
+        $definition .= '|'
+            . htmlspecialchars(
+                isset($column['Default']) ? $column['Default'] : ''
+            );
+        return $definition;
+    }
+}
+?>
\ No newline at end of file
diff --git a/phpmyadmin/libraries/plugins/export/ExportXml.class.php b/phpmyadmin/libraries/plugins/export/ExportXml.class.php
new file mode 100644
index 0000000..711824c
--- /dev/null
+++ b/phpmyadmin/libraries/plugins/export/ExportXml.class.php
@@ -0,0 +1,536 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * Set of functions used to build XML dumps of tables
+ *
+ * @package    PhpMyAdmin-Export
+ * @subpackage XML
+ */
+if (! defined('PHPMYADMIN')) {
+    exit;
+}
+if (! strlen($GLOBALS['db'])) { /* Can't do server export */
+    $GLOBALS['skip_import'] = true;
+    return;
+}
+
+/* Get the export interface */
+require_once 'libraries/plugins/ExportPlugin.class.php';
+
+/**
+ * Handles the export for the XML class
+ *
+ * @package    PhpMyAdmin-Export
+ * @subpackage XML
+ */
+class ExportXml extends ExportPlugin
+{
+    /**
+     * Table name
+     *
+     * @var string
+     */
+    private $_table;
+
+    /**
+     * Table names
+     *
+     * @var array
+     */
+    private $_tables;
+
+    /**
+     * Constructor
+     */
+    public function __construct()
+    {
+        $this->setProperties();
+    }
+
+    /**
+     * Initialize the local variables that are used for export PDF
+     *
+     * @return void
+     */
+    protected function initSpecificVariables()
+    {
+        global $table, $tables;
+        $this->_setTable($table);
+        $this->_setTables($tables);
+    }
+
+    /**
+     * Sets the export XML properties
+     *
+     * @return void
+     */
+    protected function setProperties()
+    {
+        $props = 'libraries/properties/';
+        include_once "$props/plugins/ExportPluginProperties.class.php";
+        include_once "$props/options/groups/OptionsPropertyRootGroup.class.php";
+        include_once "$props/options/groups/OptionsPropertyMainGroup.class.php";
+        include_once "$props/options/items/HiddenPropertyItem.class.php";
+        include_once "$props/options/items/BoolPropertyItem.class.php";
+
+        // create the export plugin property item
+        $exportPluginProperties = new ExportPluginProperties();
+        $exportPluginProperties->setText('XML');
+        $exportPluginProperties->setExtension('xml');
+        $exportPluginProperties->setMimeType('text/xml');
+        $exportPluginProperties->setOptionsText(__('Options'));
+
+        // create the root group that will be the options field for
+        // $exportPluginProperties
+        // this will be shown as "Format specific options"
+        $exportSpecificOptions = new OptionsPropertyRootGroup();
+        $exportSpecificOptions->setName("Format Specific Options");
+
+        // general options main group
+        $generalOptions = new OptionsPropertyMainGroup();
+        $generalOptions->setName("general_opts");
+        // create primary items and add them to the group
+        $leaf = new HiddenPropertyItem();
+        $leaf->setName("structure_or_data");
+        $generalOptions->addProperty($leaf);
+        // add the main group to the root group
+        $exportSpecificOptions->addProperty($generalOptions);
+
+        // export structure main group
+        $structure = new OptionsPropertyMainGroup();
+        $structure->setName("structure");
+        $structure->setText(__('Object creation options (all are recommended)'));
+        // create primary items and add them to the group
+        if (! PMA_DRIZZLE) {
+            $leaf = new BoolPropertyItem();
+            $leaf->setName("export_functions");
+            $leaf->setText(__('Functions'));
+            $structure->addProperty($leaf);
+            $leaf = new BoolPropertyItem();
+            $leaf->setName("export_procedures");
+            $leaf->setText(__('Procedures'));
+            $structure->addProperty($leaf);
+        }
+        $leaf = new BoolPropertyItem();
+        $leaf->setName("export_tables");
+        $leaf->setText(__('Tables'));
+        $structure->addProperty($leaf);
+        if (! PMA_DRIZZLE) {
+            $leaf = new BoolPropertyItem();
+            $leaf->setName("export_triggers");
+            $leaf->setText(__('Triggers'));
+            $structure->addProperty($leaf);
+            $leaf = new BoolPropertyItem();
+            $leaf->setName("export_views");
+            $leaf->setText(__('Views'));
+            $structure->addProperty($leaf);
+        }
+        $exportSpecificOptions->addProperty($structure);
+
+        // data main group
+        $data = new OptionsPropertyMainGroup();
+        $data->setName("data");
+        $data->setText(__('Data dump options'));
+        // create primary items and add them to the group
+        $leaf = new BoolPropertyItem();
+        $leaf->setName("export_contents");
+        $leaf->setText(__('Export contents'));
+        $data->addProperty($leaf);
+        $exportSpecificOptions->addProperty($data);
+
+        // set the options for the export plugin property item
+        $exportPluginProperties->setOptions($exportSpecificOptions);
+        $this->properties = $exportPluginProperties;
+    }
+
+    /**
+     * This method is called when any PluginManager to which the observer
+     * is attached calls PluginManager::notify()
+     *
+     * @param SplSubject $subject The PluginManager notifying the observer
+     *                            of an update.
+     *
+     * @return void
+     */
+    public function update (SplSubject $subject)
+    {
+    }
+
+    /**
+     * Outputs export header. It is the first method to be called, so all
+     * the required variables are initialized here.
+     *
+     * @return bool Whether it succeeded
+     */
+    public function exportHeader ()
+    {
+        $this->initSpecificVariables();
+        global $crlf, $cfg, $db;
+        $table = $this->_getTable();
+        $tables = $this->_getTables();
+
+        $export_struct = isset($GLOBALS['xml_export_functions'])
+            || isset($GLOBALS['xml_export_procedures'])
+            || isset($GLOBALS['xml_export_tables'])
+            || isset($GLOBALS['xml_export_triggers'])
+            || isset($GLOBALS['xml_export_views']);
+        $export_data = isset($GLOBALS['xml_export_contents']) ? true : false;
+
+        if ($GLOBALS['output_charset_conversion']) {
+            $charset = $GLOBALS['charset_of_file'];
+        } else {
+            $charset = 'utf-8';
+        }
+
+        $head  =  '<?xml version="1.0" encoding="' . $charset . '"?>' . $crlf
+               .  '<!--' . $crlf
+               .  '- phpMyAdmin XML Dump' . $crlf
+               .  '- version ' . PMA_VERSION . $crlf
+               .  '- http://www.phpmyadmin.net' . $crlf
+               .  '-' . $crlf
+               .  '- ' . __('Host') . ': ' . $cfg['Server']['host'];
+        if (! empty($cfg['Server']['port'])) {
+             $head .= ':' . $cfg['Server']['port'];
+        }
+        $head .= $crlf
+            . '- ' . __('Generation Time') . ': '
+            . PMA_Util::localisedDate() . $crlf
+            . '- ' . __('Server version') . ': ' . PMA_MYSQL_STR_VERSION . $crlf
+            . '- ' . __('PHP Version') . ': ' . phpversion() . $crlf
+            . '-->' . $crlf . $crlf;
+
+        $head .= '<pma_xml_export version="1.0"'
+            . (($export_struct)
+            ? ' xmlns:pma="http://www.phpmyadmin.net/some_doc_url/"'
+            : '')
+            . '>' . $crlf;
+
+        if ($export_struct) {
+            if (PMA_DRIZZLE) {
+                $result = PMA_DBI_fetch_result(
+                    "SELECT
+                        'utf8' AS DEFAULT_CHARACTER_SET_NAME,
+                        DEFAULT_COLLATION_NAME
+                    FROM data_dictionary.SCHEMAS
+                    WHERE SCHEMA_NAME = '"
+                    . PMA_Util::sqlAddSlashes($db) . "'"
+                );
+            } else {
+                $result = PMA_DBI_fetch_result(
+                    'SELECT `DEFAULT_CHARACTER_SET_NAME`, `DEFAULT_COLLATION_NAME`'
+                    . ' FROM `information_schema`.`SCHEMATA` WHERE `SCHEMA_NAME`'
+                    . ' = \''.PMA_Util::sqlAddSlashes($db).'\' LIMIT 1'
+                );
+            }
+            $db_collation = $result[0]['DEFAULT_COLLATION_NAME'];
+            $db_charset = $result[0]['DEFAULT_CHARACTER_SET_NAME'];
+
+            $head .= '    <!--' . $crlf;
+            $head .= '    - Structure schemas' . $crlf;
+            $head .= '    -->' . $crlf;
+            $head .= '    <pma:structure_schemas>' . $crlf;
+            $head .= '        <pma:database name="' . htmlspecialchars($db)
+                . '" collation="' . $db_collation . '" charset="' . $db_charset
+                . '">' . $crlf;
+
+            if (count($tables) == 0) {
+                $tables[] = $table;
+            }
+
+            foreach ($tables as $table) {
+                // Export tables and views
+                $result = PMA_DBI_fetch_result(
+                    'SHOW CREATE TABLE ' . PMA_Util::backquote($db) . '.'
+                    . PMA_Util::backquote($table),
+                    0
+                );
+                $tbl =  $result[$table][1];
+
+                $is_view = PMA_Table::isView($db, $table);
+
+                if ($is_view) {
+                    $type = 'view';
+                } else {
+                    $type = 'table';
+                }
+
+                if ($is_view && ! isset($GLOBALS['xml_export_views'])) {
+                    continue;
+                }
+
+                if (! $is_view && ! isset($GLOBALS['xml_export_tables'])) {
+                    continue;
+                }
+
+                $head .= '            <pma:' . $type . ' name="' . $table . '">'
+                    . $crlf;
+
+                $tbl = "                " . htmlspecialchars($tbl);
+                $tbl = str_replace("\n", "\n                ", $tbl);
+
+                $head .= $tbl . ';' . $crlf;
+                $head .= '            </pma:' . $type . '>' . $crlf;
+
+                if (isset($GLOBALS['xml_export_triggers'])
+                    && $GLOBALS['xml_export_triggers']
+                ) {
+                    // Export triggers
+                    $triggers = PMA_DBI_get_triggers($db, $table);
+                    if ($triggers) {
+                        foreach ($triggers as $trigger) {
+                            $code = $trigger['create'];
+                            $head .= '            <pma:trigger name="'
+                                . $trigger['name'] . '">' . $crlf;
+
+                            // Do some formatting
+                            $code = substr(rtrim($code), 0, -3);
+                            $code = "                " . htmlspecialchars($code);
+                            $code = str_replace("\n", "\n                ", $code);
+
+                            $head .= $code . $crlf;
+                            $head .= '            </pma:trigger>' . $crlf;
+                        }
+
+                        unset($trigger);
+                        unset($triggers);
+                    }
+                }
+            }
+
+            if (isset($GLOBALS['xml_export_functions'])
+                && $GLOBALS['xml_export_functions']
+            ) {
+                // Export functions
+                $functions = PMA_DBI_get_procedures_or_functions($db, 'FUNCTION');
+                if ($functions) {
+                    foreach ($functions as $function) {
+                        $head .= '            <pma:function name="'
+                            . $function . '">' . $crlf;
+
+                        // Do some formatting
+                        $sql = PMA_DBI_get_definition($db, 'FUNCTION', $function);
+                        $sql = rtrim($sql);
+                        $sql = "                " . htmlspecialchars($sql);
+                        $sql = str_replace("\n", "\n                ", $sql);
+
+                        $head .= $sql . $crlf;
+                        $head .= '            </pma:function>' . $crlf;
+                    }
+
+                    unset($function);
+                    unset($functions);
+                }
+            }
+
+            if (isset($GLOBALS['xml_export_procedures'])
+                && $GLOBALS['xml_export_procedures']
+            ) {
+                // Export procedures
+                $procedures = PMA_DBI_get_procedures_or_functions($db, 'PROCEDURE');
+                if ($procedures) {
+                    foreach ($procedures as $procedure) {
+                        $head .= '            <pma:procedure name="'
+                            . $procedure . '">' . $crlf;
+
+                        // Do some formatting
+                        $sql = PMA_DBI_get_definition($db, 'PROCEDURE', $procedure);
+                        $sql = rtrim($sql);
+                        $sql = "                " . htmlspecialchars($sql);
+                        $sql = str_replace("\n", "\n                ", $sql);
+
+                        $head .= $sql . $crlf;
+                        $head .= '            </pma:procedure>' . $crlf;
+                    }
+
+                    unset($procedure);
+                    unset($procedures);
+                }
+            }
+
+            unset($result);
+
+            $head .= '        </pma:database>' . $crlf;
+            $head .= '    </pma:structure_schemas>' . $crlf;
+
+            if ($export_data) {
+                $head .= $crlf;
+            }
+        }
+
+        return PMA_exportOutputHandler($head);
+    }
+
+    /**
+     * Outputs export footer
+     *
+     * @return bool Whether it succeeded
+     */
+    public function exportFooter ()
+    {
+        $foot = '</pma_xml_export>';
+
+        return PMA_exportOutputHandler($foot);
+    }
+
+    /**
+     * Outputs database header
+     *
+     * @param string $db Database name
+     *
+     * @return bool Whether it succeeded
+     */
+    public function exportDBHeader ($db)
+    {
+        global $crlf;
+
+        if (isset($GLOBALS['xml_export_contents'])
+            && $GLOBALS['xml_export_contents']
+        ) {
+            $head = '    <!--' . $crlf
+                  . '    - ' . __('Database') . ': ' .  '\'' . $db . '\'' . $crlf
+                  . '    -->' . $crlf
+                  . '    <database name="' . htmlspecialchars($db) . '">' . $crlf;
+
+            return PMA_exportOutputHandler($head);
+        } else {
+            return true;
+        }
+    }
+
+    /**
+     * Outputs database footer
+     *
+     * @param string $db Database name
+     *
+     * @return bool Whether it succeeded
+     */
+    public function exportDBFooter ($db)
+    {
+        global $crlf;
+
+        if (isset($GLOBALS['xml_export_contents'])
+            && $GLOBALS['xml_export_contents']
+        ) {
+            return PMA_exportOutputHandler('    </database>' . $crlf);
+        } else {
+            return true;
+        }
+    }
+
+    /**
+     * Outputs CREATE DATABASE statement
+     *
+     * @param string $db Database name
+     *
+     * @return bool Whether it succeeded
+     */
+    public function exportDBCreate($db)
+    {
+        return true;
+    }
+
+    /**
+     * Outputs the content of a table in XML format
+     *
+     * @param string $db        database name
+     * @param string $table     table name
+     * @param string $crlf      the end of line sequence
+     * @param string $error_url the url to go back in case of error
+     * @param string $sql_query SQL query for obtaining data
+     *
+     * @return bool Whether it succeeded
+     */
+    public function exportData ($db, $table, $crlf, $error_url, $sql_query)
+    {
+        if (isset($GLOBALS['xml_export_contents'])
+            && $GLOBALS['xml_export_contents']
+        ) {
+            $result = PMA_DBI_query($sql_query, null, PMA_DBI_QUERY_UNBUFFERED);
+
+            $columns_cnt = PMA_DBI_num_fields($result);
+            $columns = array();
+            for ($i = 0; $i < $columns_cnt; $i++) {
+                $columns[$i] = stripslashes(PMA_DBI_field_name($result, $i));
+            }
+            unset($i);
+
+            $buffer = '        <!-- ' . __('Table') . ' ' . $table . ' -->' . $crlf;
+            if (! PMA_exportOutputHandler($buffer)) {
+                return false;
+            }
+
+            while ($record = PMA_DBI_fetch_row($result)) {
+                $buffer = '        <table name="'
+                    . htmlspecialchars($table) . '">' . $crlf;
+                for ($i = 0; $i < $columns_cnt; $i++) {
+                    // If a cell is NULL, still export it to preserve
+                    // the XML structure
+                    if (! isset($record[$i]) || is_null($record[$i])) {
+                        $record[$i] = 'NULL';
+                    }
+                    $buffer .= '            <column name="'
+                        . htmlspecialchars($columns[$i]) . '">'
+                        . htmlspecialchars((string)$record[$i])
+                        .  '</column>' . $crlf;
+                }
+                $buffer     .= '        </table>' . $crlf;
+
+                if (! PMA_exportOutputHandler($buffer)) {
+                    return false;
+                }
+            }
+            PMA_DBI_free_result($result);
+        }
+
+        return true;
+    }
+
+
+    /* ~~~~~~~~~~~~~~~~~~~~ Getters and Setters ~~~~~~~~~~~~~~~~~~~~ */
+
+
+    /**
+     * Gets the table name
+     *
+     * @return void
+     */
+    private function _getTable()
+    {
+        return $this->_table;
+    }
+
+    /**
+     * Sets the table name
+     *
+     * @param string $table table name
+     *
+     * @return void
+     */
+    private function _setTable($table)
+    {
+        $this->_table = $table;
+    }
+
+    /**
+     * Gets the table names
+     *
+     * @return array
+     */
+    private function _getTables()
+    {
+        return $this->_tables;
+    }
+
+    /**
+     * Sets the table names
+     *
+     * @param array $tables table names
+     *
+     * @return void
+     */
+    private function _setTables($tables)
+    {
+        $this->_tables = $tables;
+    }
+}
+?>
diff --git a/phpmyadmin/libraries/plugins/export/ExportYaml.class.php b/phpmyadmin/libraries/plugins/export/ExportYaml.class.php
new file mode 100644
index 0000000..044daee
--- /dev/null
+++ b/phpmyadmin/libraries/plugins/export/ExportYaml.class.php
@@ -0,0 +1,214 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * Set of functions used to build YAML dumps of tables
+ *
+ * @package    PhpMyAdmin-Export
+ * @subpackage YAML
+ */
+if (! defined('PHPMYADMIN')) {
+    exit;
+}
+
+/* Get the export interface */
+require_once 'libraries/plugins/ExportPlugin.class.php';
+
+/**
+ * Handles the export for the YAML format
+ *
+ * @package    PhpMyAdmin-Export
+ * @subpackage YAML
+ */
+class ExportYaml extends ExportPlugin
+{
+    /**
+     * Constructor
+     */
+    public function __construct()
+    {
+        $this->setProperties();
+    }
+
+    /**
+     * Sets the export YAML properties
+     *
+     * @return void
+     */
+    protected function setProperties()
+    {
+        $props = 'libraries/properties/';
+        include_once "$props/plugins/ExportPluginProperties.class.php";
+        include_once "$props/options/groups/OptionsPropertyRootGroup.class.php";
+        include_once "$props/options/groups/OptionsPropertyMainGroup.class.php";
+        include_once "$props/options/items/HiddenPropertyItem.class.php";
+
+        $exportPluginProperties = new ExportPluginProperties();
+        $exportPluginProperties->setText('YAML');
+        $exportPluginProperties->setExtension('yml');
+        $exportPluginProperties->setMimeType('text/yaml');
+        $exportPluginProperties->setForceFile(true);
+        $exportPluginProperties->setOptionsText(__('Options'));
+
+        // create the root group that will be the options field for
+        // $exportPluginProperties
+        // this will be shown as "Format specific options"
+        $exportSpecificOptions = new OptionsPropertyRootGroup();
+        $exportSpecificOptions->setName("Format Specific Options");
+
+        // general options main group
+        $generalOptions = new OptionsPropertyMainGroup();
+        $generalOptions->setName("general_opts");
+        // create primary items and add them to the group
+        $leaf = new HiddenPropertyItem();
+        $leaf->setName("structure_or_data");
+        $generalOptions->addProperty($leaf);
+        // add the main group to the root group
+        $exportSpecificOptions->addProperty($generalOptions);
+
+        // set the options for the export plugin property item
+        $exportPluginProperties->setOptions($exportSpecificOptions);
+        $this->properties = $exportPluginProperties;
+    }
+
+    /**
+     * This method is called when any PluginManager to which the observer
+     * is attached calls PluginManager::notify()
+     *
+     * @param SplSubject $subject The PluginManager notifying the observer
+     *                            of an update.
+     *
+     * @return void
+     */
+    public function update (SplSubject $subject)
+    {
+    }
+
+    /**
+     * Outputs export header
+     *
+     * @return bool Whether it succeeded
+     */
+    public function exportHeader ()
+    {
+        PMA_exportOutputHandler(
+            '%YAML 1.1' . $GLOBALS['crlf'] . '---' . $GLOBALS['crlf']
+        );
+        return true;
+    }
+
+    /**
+     * Outputs export footer
+     *
+     * @return bool Whether it succeeded
+     */
+    public function exportFooter ()
+    {
+        PMA_exportOutputHandler('...' . $GLOBALS['crlf']);
+        return true;
+    }
+
+    /**
+     * Outputs database header
+     *
+     * @param string $db Database name
+     *
+     * @return bool Whether it succeeded
+     */
+    public function exportDBHeader ($db)
+    {
+        return true;
+    }
+
+    /**
+     * Outputs database footer
+     *
+     * @param string $db Database name
+     *
+     * @return bool Whether it succeeded
+     */
+    public function exportDBFooter ($db)
+    {
+        return true;
+    }
+
+    /**
+     * Outputs CREATE DATABASE statement
+     *
+     * @param string $db Database name
+     *
+     * @return bool Whether it succeeded
+     */
+    public function exportDBCreate($db)
+    {
+        return true;
+    }
+
+    /**
+     * Outputs the content of a table in JSON format
+     *
+     * @param string $db        database name
+     * @param string $table     table name
+     * @param string $crlf      the end of line sequence
+     * @param string $error_url the url to go back in case of error
+     * @param string $sql_query SQL query for obtaining data
+     *
+     * @return bool Whether it succeeded
+     */
+    public function exportData($db, $table, $crlf, $error_url, $sql_query)
+    {
+        $result = PMA_DBI_query($sql_query, null, PMA_DBI_QUERY_UNBUFFERED);
+
+        $columns_cnt = PMA_DBI_num_fields($result);
+        for ($i = 0; $i < $columns_cnt; $i++) {
+            $columns[$i] = stripslashes(PMA_DBI_field_name($result, $i));
+        }
+        unset($i);
+
+        $buffer = '';
+        $record_cnt = 0;
+        while ($record = PMA_DBI_fetch_row($result)) {
+            $record_cnt++;
+
+            // Output table name as comment if this is the first record of the table
+            if ($record_cnt == 1) {
+                $buffer = '# ' . $db . '.' . $table . $crlf;
+                $buffer .= '-' . $crlf;
+            } else {
+                $buffer = '-' . $crlf;
+            }
+
+            for ($i = 0; $i < $columns_cnt; $i++) {
+                if (! isset($record[$i])) {
+                    continue;
+                }
+
+                $column = $columns[$i];
+
+                if (is_null($record[$i])) {
+                    $buffer .= '  ' . $column . ': null' . $crlf;
+                    continue;
+                }
+
+                if (is_numeric($record[$i])) {
+                    $buffer .= '  ' . $column . ': '  . $record[$i] . $crlf;
+                    continue;
+                }
+
+                $record[$i] = str_replace(
+                    array('\\', '"', "\n", "\r"),
+                    array('\\\\', '\"', '\n', '\r'),
+                    $record[$i]
+                );
+                $buffer .= '  ' . $column . ': "' . $record[$i] . '"' . $crlf;
+            }
+
+            if (! PMA_exportOutputHandler($buffer)) {
+                return false;
+            }
+        }
+        PMA_DBI_free_result($result);
+
+        return true;
+    } // end getTableYAML
+}
+?>
\ No newline at end of file
diff --git a/phpmyadmin/libraries/plugins/export/PMA_ExportPdf.class.php b/phpmyadmin/libraries/plugins/export/PMA_ExportPdf.class.php
new file mode 100644
index 0000000..1913d5e
--- /dev/null
+++ b/phpmyadmin/libraries/plugins/export/PMA_ExportPdf.class.php
@@ -0,0 +1,408 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * TableProperty class
+ *
+ * @package    PhpMyAdmin-Export
+ * @subpackage PDF
+ */
+if (! defined('PHPMYADMIN')) {
+    exit;
+}
+
+/* Get the PDF class */
+require_once 'libraries/PDF.class.php';
+
+/**
+ * Adapted from a LGPL script by Philip Clarke
+ *
+ * @package    PhpMyAdmin-Export
+ * @subpackage PDF
+ */
+class PMA_ExportPdf extends PMA_PDF
+{
+    var $tablewidths;
+    var $headerset;
+
+    /**
+     * Add page if needed.
+     *
+     * @param float   $h       cell height. Default value: 0
+     * @param mixed   $y       starting y position, leave empty for current position
+     * @param boolean $addpage if true add a page, otherwise only return
+     *                         the true/false state
+     *
+     * @return boolean true in case of page break, false otherwise.
+     */
+    function checkPageBreak($h = 0, $y = '', $addpage = true)
+    {
+        if ($this->empty_string($y)) {
+            $y = $this->y;
+        }
+        $current_page = $this->page;
+        if ((($y + $h) > $this->PageBreakTrigger)
+            AND (! $this->InFooter)
+            AND ($this->AcceptPageBreak())
+        ) {
+            if ($addpage) {
+                //Automatic page break
+                $x = $this->x;
+                $this->AddPage($this->CurOrientation);
+                $this->y = $this->dataY;
+                $oldpage = $this->page - 1;
+
+                $this_page_orm = $this->pagedim[$this->page]['orm'];
+                $old_page_orm = $this->pagedim[$oldpage]['orm'];
+                $this_page_olm = $this->pagedim[$this->page]['olm'];
+                $old_page_olm = $this->pagedim[$oldpage]['olm'];
+                if ($this->rtl) {
+                    if ($this_page_orm!= $old_page_orm) {
+                        $this->x = $x - ($this_page_orm - $old_page_orm);
+                    } else {
+                        $this->x = $x;
+                    }
+                } else {
+                    if ($this_page_olm != $old_page_olm) {
+                        $this->x = $x + ($this_page_olm - $old_page_olm);
+                    } else {
+                        $this->x = $x;
+                    }
+                }
+            }
+            return true;
+        }
+        if ($current_page != $this->page) {
+            // account for columns mode
+            return true;
+        }
+        return false;
+    }
+
+    /**
+     * This method is used to render the page header.
+     *
+     * @return void
+     */
+    function Header()
+    {
+        global $maxY;
+        // We don't want automatic page breaks while generating header
+        // as this can lead to infinite recursion as auto generated page
+        // will want header as well causing another page break
+        // FIXME: Better approach might be to try to compact the content
+        $this->SetAutoPageBreak(false);
+        // Check if header for this page already exists
+        if (! isset($this->headerset[$this->page])) {
+            $fullwidth = 0;
+            foreach ($this->tablewidths as $width) {
+                $fullwidth += $width;
+            }
+            $this->SetY(($this->tMargin) - ($this->FontSizePt / $this->k) * 5);
+            $this->cellFontSize = $this->FontSizePt ;
+            $this->SetFont(
+                PMA_PDF_FONT,
+                '',
+                ($this->titleFontSize
+                ? $this->titleFontSize
+                : $this->FontSizePt)
+            );
+            $this->Cell(0, $this->FontSizePt, $this->titleText, 0, 1, 'C');
+            $this->SetFont(PMA_PDF_FONT, '', $this->cellFontSize);
+            $this->SetY(($this->tMargin) - ($this->FontSizePt / $this->k) * 2.5);
+            $this->Cell(
+                0,
+                $this->FontSizePt,
+                __('Database') . ': ' . $this->currentDb . ',  '
+                . __('Table') . ': ' . $this->currentTable,
+                0, 1, 'L'
+            );
+            $l = ($this->lMargin);
+            foreach ($this->colTitles as $col => $txt) {
+                $this->SetXY($l, ($this->tMargin));
+                $this->MultiCell(
+                    $this->tablewidths[$col],
+                    $this->FontSizePt,
+                    $txt
+                );
+                $l += $this->tablewidths[$col] ;
+                $maxY = ($maxY < $this->getY()) ? $this->getY() : $maxY ;
+            }
+            $this->SetXY($this->lMargin, $this->tMargin);
+            $this->setFillColor(200, 200, 200);
+            $l = ($this->lMargin);
+            foreach ($this->colTitles as $col => $txt) {
+                $this->SetXY($l, $this->tMargin);
+                $this->cell(
+                    $this->tablewidths[$col],
+                    $maxY-($this->tMargin),
+                    '',
+                    1,
+                    0,
+                    'L',
+                    1
+                );
+                $this->SetXY($l, $this->tMargin);
+                $this->MultiCell(
+                    $this->tablewidths[$col],
+                    $this->FontSizePt,
+                    $txt,
+                    0,
+                    'C'
+                );
+                $l += $this->tablewidths[$col];
+            }
+            $this->setFillColor(255, 255, 255);
+            // set headerset
+            $this->headerset[$this->page] = 1;
+        }
+
+        $this->dataY = $maxY;
+        $this->SetAutoPageBreak(true);
+    }
+
+    function morepagestable($lineheight = 8)
+    {
+        // some things to set and 'remember'
+        $l = $this->lMargin;
+        $startheight = $h = $this->dataY;
+        $startpage = $currpage = $this->page;
+
+        // calculate the whole width
+        $fullwidth = 0;
+        foreach ($this->tablewidths as $width) {
+            $fullwidth += $width;
+        }
+
+        // Now let's start to write the table
+        $row = 0;
+        $tmpheight = array();
+        $maxpage = $this->page;
+
+        while ($data = PMA_DBI_fetch_row($this->results)) {
+            $this->page = $currpage;
+            // write the horizontal borders
+            $this->Line($l, $h, $fullwidth+$l, $h);
+            // write the content and remember the height of the highest col
+            foreach ($data as $col => $txt) {
+                $this->page = $currpage;
+                $this->SetXY($l, $h);
+                if ($this->tablewidths[$col] > 0) {
+                    $this->MultiCell(
+                        $this->tablewidths[$col],
+                        $lineheight,
+                        $txt,
+                        0,
+                        $this->colAlign[$col]
+                    );
+                    $l += $this->tablewidths[$col];
+                }
+
+                if (! isset($tmpheight[$row.'-'.$this->page])) {
+                    $tmpheight[$row.'-'.$this->page] = 0;
+                }
+                if ($tmpheight[$row.'-'.$this->page] < $this->GetY()) {
+                    $tmpheight[$row.'-'.$this->page] = $this->GetY();
+                }
+                if ($this->page > $maxpage) {
+                    $maxpage = $this->page;
+                }
+                unset($data[$col]);
+            }
+
+            // get the height we were in the last used page
+            $h = $tmpheight[$row.'-'.$maxpage];
+            // set the "pointer" to the left margin
+            $l = $this->lMargin;
+            // set the $currpage to the last page
+            $currpage = $maxpage;
+            unset($data[$row]);
+            $row++;
+        }
+        // draw the borders
+        // we start adding a horizontal line on the last page
+        $this->page = $maxpage;
+        $this->Line($l, $h, $fullwidth+$l, $h);
+        // now we start at the top of the document and walk down
+        for ($i = $startpage; $i <= $maxpage; $i++) {
+            $this->page = $i;
+            $l = $this->lMargin;
+            $t = ($i == $startpage) ? $startheight : $this->tMargin;
+            $lh = ($i == $maxpage) ? $h : $this->h-$this->bMargin;
+            $this->Line($l, $t, $l, $lh);
+            foreach ($this->tablewidths as $width) {
+                $l += $width;
+                $this->Line($l, $t, $l, $lh);
+            }
+        }
+        // set it to the last page, if not it'll cause some problems
+        $this->page = $maxpage;
+    }
+
+    /**
+     * Sets a set of attributes.
+     *
+     * @param array $attr array containing the attributes
+     *
+     * @return void
+     */
+    function setAttributes($attr = array())
+    {
+        foreach ($attr as $key => $val) {
+            $this->$key = $val ;
+        }
+    }
+
+    /**
+     * Defines the top margin.
+     * The method can be called before creating the first page.
+     *
+     * @param float $topMargin the margin
+     *
+     * @return void
+     */
+    function setTopMargin($topMargin)
+    {
+        $this->tMargin = $topMargin;
+    }
+
+    function mysqlReport($query)
+    {
+        unset($this->tablewidths);
+        unset($this->colTitles);
+        unset($this->titleWidth);
+        unset($this->colFits);
+        unset($this->display_column);
+        unset($this->colAlign);
+
+        /**
+         * Pass 1 for column widths
+         */
+        $this->results = PMA_DBI_query($query, null, PMA_DBI_QUERY_UNBUFFERED);
+        $this->numFields  = PMA_DBI_num_fields($this->results);
+        $this->fields = PMA_DBI_get_fields_meta($this->results);
+
+        // sColWidth = starting col width (an average size width)
+        $availableWidth = $this->w - $this->lMargin - $this->rMargin;
+        $this->sColWidth = $availableWidth / $this->numFields;
+        $totalTitleWidth = 0;
+
+        // loop through results header and set initial
+        // col widths/ titles/ alignment
+        // if a col title is less than the starting col width,
+        // reduce that column size
+        $colFits = array();
+        for ($i = 0; $i < $this->numFields; $i++) {
+            $stringWidth = $this->getstringwidth($this->fields[$i]->name) + 6 ;
+            // save the real title's width
+            $titleWidth[$i] = $stringWidth;
+            $totalTitleWidth += $stringWidth;
+
+            // set any column titles less than the start width to
+            // the column title width
+            if ($stringWidth < $this->sColWidth) {
+                $colFits[$i] = $stringWidth ;
+            }
+            $this->colTitles[$i] = $this->fields[$i]->name;
+            $this->display_column[$i] = true;
+
+            switch ($this->fields[$i]->type) {
+            case 'int':
+                $this->colAlign[$i] = 'R';
+                break;
+            case 'blob':
+            case 'tinyblob':
+            case 'mediumblob':
+            case 'longblob':
+                /**
+                 * @todo do not deactivate completely the display
+                 * but show the field's name and [BLOB]
+                 */
+                if (stristr($this->fields[$i]->flags, 'BINARY')) {
+                    $this->display_column[$i] = false;
+                    unset($this->colTitles[$i]);
+                }
+                $this->colAlign[$i] = 'L';
+                break;
+            default:
+                $this->colAlign[$i] = 'L';
+            }
+        }
+
+        // title width verification
+        if ($totalTitleWidth > $availableWidth) {
+            $adjustingMode = true;
+        } else {
+            $adjustingMode = false;
+            // we have enough space for all the titles at their
+            // original width so use the true title's width
+            foreach ($titleWidth as $key => $val) {
+                $colFits[$key] = $val;
+            }
+        }
+
+        // loop through the data; any column whose contents
+        // is greater than the column size is resized
+        /**
+          * @todo force here a LIMIT to avoid reading all rows
+          */
+        while ($row = PMA_DBI_fetch_row($this->results)) {
+            foreach ($colFits as $key => $val) {
+                $stringWidth = $this->getstringwidth($row[$key]) + 6 ;
+                if ($adjustingMode && ($stringWidth > $this->sColWidth)) {
+                    // any column whose data's width is bigger than
+                    // the start width is now discarded
+                    unset($colFits[$key]);
+                } else {
+                    // if data's width is bigger than the current column width,
+                    // enlarge the column (but avoid enlarging it if the
+                    // data's width is very big)
+                    if ($stringWidth > $val
+                        && $stringWidth < ($this->sColWidth * 3)
+                    ) {
+                        $colFits[$key] = $stringWidth ;
+                    }
+                }
+            }
+        }
+
+        $totAlreadyFitted = 0;
+        foreach ($colFits as $key => $val) {
+            // set fitted columns to smallest size
+            $this->tablewidths[$key] = $val;
+            // to work out how much (if any) space has been freed up
+            $totAlreadyFitted += $val;
+        }
+
+        if ($adjustingMode) {
+            $surplus = (sizeof($colFits) * $this->sColWidth) - $totAlreadyFitted;
+            $surplusToAdd = $surplus / ($this->numFields - sizeof($colFits));
+        } else {
+            $surplusToAdd = 0;
+        }
+
+        for ($i = 0; $i < $this->numFields; $i++) {
+            if (! in_array($i, array_keys($colFits))) {
+                $this->tablewidths[$i] = $this->sColWidth + $surplusToAdd;
+            }
+            if ($this->display_column[$i] == false) {
+                $this->tablewidths[$i] = 0;
+            }
+        }
+
+        ksort($this->tablewidths);
+
+        PMA_DBI_free_result($this->results);
+
+        // Pass 2
+
+        $this->results = PMA_DBI_query($query, null, PMA_DBI_QUERY_UNBUFFERED);
+        $this->setY($this->tMargin);
+        $this->AddPage();
+        $this->SetFont(PMA_PDF_FONT, '', 9);
+        $this->morepagestable($this->FontSizePt);
+        PMA_DBI_free_result($this->results);
+
+    } // end of mysqlReport function
+
+} // end of PMA_Export_PDF class
+?>
diff --git a/phpmyadmin/libraries/plugins/export/README b/phpmyadmin/libraries/plugins/export/README
new file mode 100644
index 0000000..68d5a26
--- /dev/null
+++ b/phpmyadmin/libraries/plugins/export/README
@@ -0,0 +1,276 @@
+This directory holds export plugins for phpMyAdmin. Any new plugin should
+basically follow the structure presented here. Official plugins need to
+have str* messages with their definition in language files, but if you build
+some plugins for your use, you can directly use texts in plugin.
+
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * [Name] export plugin for phpMyAdmin
+ *
+ * @package    PhpMyAdmin-Export
+ * @subpackage [Name]
+ */
+if (! defined('PHPMYADMIN')) {
+    exit;
+}
+
+/* Get the export interface */
+require_once 'libraries/plugins/ExportPlugin.class.php';
+
+/**
+ * Handles the export for the [Name] format
+ *
+ * @package PhpMyAdmin-Export
+ */
+class Export[Name] extends ExportPlugin
+{
+    /**
+     * optional - declare variables and descriptions
+     *
+     * @var type
+     */
+    private $_myOptionalVariable;
+
+    /**
+     * optional - declare global variables and descriptions
+     *
+     * @var type
+     */
+    private $_globalVariableName;
+
+    /**
+     * Constructor
+     */
+    public function __construct()
+    {
+        $this->setProperties();
+    }
+
+    // optional - declare global variables and use getters later
+    /**
+     * Initialize the local variables that are used specific for export SQL
+     *
+     * @global type $global_variable_name
+     * [..]
+     *
+     * @return void
+     */
+    protected function initSpecificVariables()
+    {
+        global $global_variable_name;
+        $this->_setGlobalVariableName($global_variable_name);
+    }
+
+    /**
+     * Sets the export plugin properties.
+     * Called in the constructor.
+     *
+     * @return void
+     */
+    protected function setProperties()
+    {
+        // set properties
+        $props = 'libraries/properties/';
+        // include the main class for properties for the export plug-ins
+        include_once "$props/plugins/ExportPluginProperties.class.php";
+        // include the group properties classes
+        include_once "$props/options/groups/OptionsPropertyRootGroup.class.php";
+        include_once "$props/options/groups/OptionsPropertyMainGroup.class.php";
+        // include the needed single property items
+        include_once "$props/options/items/RadioPropertyItem.class.php";
+
+        $exportPluginProperties = new ExportPluginProperties();
+        $exportPluginProperties->setText('[name]');             // the name of your plug-in
+        $exportPluginProperties->setExtension('[ext]');         // extension this plug-in can handle
+        $exportPluginProperties->setOptionsText(__('Options'));
+
+        // create the root group that will be the options field for
+        // $exportPluginProperties
+        // this will be shown as "Format specific options"
+        $exportSpecificOptions = new OptionsPropertyRootGroup();
+        $exportSpecificOptions->setName("Format Specific Options");
+
+        // general options main group
+        $generalOptions = new OptionsPropertyMainGroup();
+        $generalOptions->setName("general_opts");
+
+        // optional :
+        // create primary items and add them to the group
+        // type - one of the classes listed in libraries/properties/options/items/
+        // name - form element name
+        // text - description in GUI
+        // size - size of text element
+        // len  - maximal size of input
+        // values - possible values of the item
+        $leaf = new RadioPropertyItem();
+        $leaf->setName("structure_or_data");
+        $leaf->setValues(
+            array(
+                'structure' => __('structure'),
+                'data' => __('data'),
+                'structure_and_data' => __('structure and data')
+            )
+        );
+        $generalOptions->addProperty($leaf);
+
+        // add the main group to the root group
+        $exportSpecificOptions->addProperty($generalOptions);
+
+        // set the options for the export plugin property item
+        $exportPluginProperties->setOptions($exportSpecificOptions);
+        $this->properties = $exportPluginProperties;
+    }
+
+    /**
+     * This method is called when any PluginManager to which the observer
+     * is attached calls PluginManager::notify()
+     *
+     * @param SplSubject $subject The PluginManager notifying the observer
+     *                            of an update.
+     *
+     * @return void
+     */
+    public function update (SplSubject $subject)
+    {
+    }
+
+    /**
+     * Outputs export header
+     *
+     * @return bool Whether it succeeded
+     */
+    public function exportHeader ()
+    {
+        // implementation
+        return true;
+    }
+
+    /**
+     * Outputs export footer
+     *
+     * @return bool Whether it succeeded
+     */
+    public function exportFooter ()
+    {
+        // implementation
+        return true;
+    }
+
+    /**
+     * Outputs database header
+     *
+     * @param string $db Database name
+     *
+     * @return bool Whether it succeeded
+     */
+    public function exportDBHeader ($db)
+    {
+        // implementation
+        return true;
+    }
+
+    /**
+     * Outputs database footer
+     *
+     * @param string $db Database name
+     *
+     * @return bool Whether it succeeded
+     */
+    public function exportDBFooter ($db)
+    {
+        // implementation
+        return true;
+    }
+
+    /**
+     * Outputs CREATE DATABASE statement
+     *
+     * @param string $db Database name
+     *
+     * @return bool Whether it succeeded
+     */
+    public function exportDBCreate($db)
+    {
+        // implementation
+        return true;
+    }
+
+    /**
+     * Outputs the content of a table in [Name] format
+     *
+     * @param string $db        database name
+     * @param string $table     table name
+     * @param string $crlf      the end of line sequence
+     * @param string $error_url the url to go back in case of error
+     * @param string $sql_query SQL query for obtaining data
+     *
+     * @return bool Whether it succeeded
+     */
+    public function exportData($db, $table, $crlf, $error_url, $sql_query)
+    {
+        // implementation;
+        return true;
+    }
+
+    // optional - implement other methods defined in ExportPlugin.class.php:
+    //  - exportRoutines()
+    //  - exportStructure()
+    //  - getTableDefStandIn()
+    //  - getTriggers()
+
+    // optional - implement other private methods in order to avoid
+    // having huge methods or avoid duplicate code. Make use of them
+    // as well as of the getters and setters declared both here
+    // and in the ExportPlugin class
+
+
+    // optional:
+    /* ~~~~~~~~~~~~~~~~~~~~ Getters and Setters ~~~~~~~~~~~~~~~~~~~~ */
+
+
+    /**
+     * Getter description
+     *
+     * @return type
+     */
+    private function _getMyOptionalVariable()
+    {
+        return $this->_myOptionalVariable;
+    }
+
+    /**
+     * Setter description
+     *
+     * @param type $my_optional_variable description
+     *
+     * @return void
+     */
+    private function _setMyOptionalVariable($my_optional_variable)
+    {
+        $this->_myOptionalVariable = $my_optional_variable;
+    }
+
+    /**
+     * Getter description
+     *
+     * @return type
+     */
+    private function _getGlobalVariableName()
+    {
+        return $this->_globalVariableName;
+    }
+
+    /**
+     * Setter description
+     *
+     * @param type $global_variable_name description
+     *
+     * @return void
+     */
+    private function _setGlobalVariableName($global_variable_name)
+    {
+        $this->_globalVariableName = $global_variable_name;
+    }
+}
+?>
\ No newline at end of file
diff --git a/phpmyadmin/libraries/plugins/export/TableProperty.class.php b/phpmyadmin/libraries/plugins/export/TableProperty.class.php
new file mode 100644
index 0000000..a928a6c
--- /dev/null
+++ b/phpmyadmin/libraries/plugins/export/TableProperty.class.php
@@ -0,0 +1,288 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * Holds the TableProperty class
+ *
+ * @package    PhpMyAdmin-Export
+ * @subpackage CodeGen
+ */
+if (! defined('PHPMYADMIN')) {
+    exit;
+}
+
+/**
+ * TableProperty class
+ *
+ * @package    PhpMyAdmin-Export
+ * @subpackage CodeGen
+ */
+class TableProperty
+{
+    /**
+     * Name
+     *
+     * @var string
+     */
+    public $name;
+
+    /**
+     * Type
+     *
+     * @var string
+     */
+    public $type;
+
+    /**
+     * Wheter the key is nullable or not
+     *
+     * @var bool
+     */
+    public $nullable;
+
+    /**
+     * The key
+     *
+     * @var int
+     */
+    public $key;
+
+    /**
+     * Default value
+     *
+     * @var mixed
+     */
+    public $defaultValue;
+
+    /**
+     * Extension
+     *
+     * @var string
+     */
+    public $ext;
+
+    /**
+     * Constructor
+     *
+     * @param array $row table row
+     *
+     * @return void
+     */
+    function __construct($row)
+    {
+        $this->name = trim($row[0]);
+        $this->type = trim($row[1]);
+        $this->nullable = trim($row[2]);
+        $this->key = trim($row[3]);
+        $this->defaultValue = trim($row[4]);
+        $this->ext = trim($row[5]);
+    }
+
+    /**
+     * Gets the pure type
+     *
+     * @return string type
+     */
+    function getPureType()
+    {
+        $pos = strpos($this->type, "(");
+        if ($pos > 0) {
+            return substr($this->type, 0, $pos);
+        }
+        return $this->type;
+    }
+
+    /**
+     * Tells whether the key is null or not
+     *
+     * @return bool true if the key is not null, false otherwise
+     */
+    function isNotNull()
+    {
+        return $this->nullable == "NO" ? "true" : "false";
+    }
+
+    /**
+     * Tells whether the key is unique or not
+     *
+     * @return bool true if the key is unique, false otherwise
+     */
+    function isUnique()
+    {
+        return $this->key == "PRI" || $this->key == "UNI" ? "true" : "false";
+    }
+
+     /**
+     * Gets the .NET primitive type
+     *
+     * @return string type
+     */
+    function getDotNetPrimitiveType()
+    {
+        if (strpos($this->type, "int") === 0) {
+            return "int";
+        }
+        if (strpos($this->type, "long") === 0) {
+            return "long";
+        }
+        if (strpos($this->type, "char") === 0) {
+            return "string";
+        }
+        if (strpos($this->type, "varchar") === 0) {
+            return "string";
+        }
+        if (strpos($this->type, "text") === 0) {
+            return "string";
+        }
+        if (strpos($this->type, "longtext") === 0) {
+            return "string";
+        }
+        if (strpos($this->type, "tinyint") === 0) {
+            return "bool";
+        }
+        if (strpos($this->type, "datetime") === 0) {
+            return "DateTime";
+        }
+        return "unknown";
+    }
+
+    /**
+     * Gets the .NET object type
+     *
+     * @return string type
+     */
+    function getDotNetObjectType()
+    {
+        if (strpos($this->type, "int") === 0) {
+            return "Int32";
+        }
+        if (strpos($this->type, "long") === 0) {
+            return "Long";
+        }
+        if (strpos($this->type, "char") === 0) {
+            return "String";
+        }
+        if (strpos($this->type, "varchar") === 0) {
+            return "String";
+        }
+        if (strpos($this->type, "text") === 0) {
+            return "String";
+        }
+        if (strpos($this->type, "longtext") === 0) {
+            return "String";
+        }
+        if (strpos($this->type, "tinyint") === 0) {
+            return "Boolean";
+        }
+        if (strpos($this->type, "datetime") === 0) {
+            return "DateTime";
+        }
+        return "Unknown";
+    }
+
+    /**
+     * Gets the index name
+     *
+     * @return string containing the name of the index
+     */
+    function getIndexName()
+    {
+        if (strlen($this->key) > 0) {
+            return "index=\""
+                . htmlspecialchars($this->name, ENT_COMPAT, 'UTF-8')
+                . "\"";
+        }
+        return "";
+    }
+
+    /**
+     * Tells whether the key is primary or not
+     *
+     * @return bool true if the key is primary, false otherwise
+     */
+    function isPK()
+    {
+        return $this->key=="PRI";
+    }
+
+    /**
+     * Formats a string for C#
+     *
+     * @param string $text string to be formatted
+     *
+     * @return string formatted text
+     */
+    function formatCs($text)
+    {
+        $text = str_replace(
+            "#name#",
+            ExportCodegen::cgMakeIdentifier($this->name, false),
+            $text
+        );
+        return $this->format($text);
+    }
+
+    /**
+     * Formats a string for XML
+     *
+     * @param string $text string to be formatted
+     *
+     * @return string formatted text
+     */
+    function formatXml($text)
+    {
+        $text = str_replace(
+            "#name#",
+            htmlspecialchars($this->name, ENT_COMPAT, 'UTF-8'),
+            $text
+        );
+        $text = str_replace(
+            "#indexName#",
+            $this->getIndexName(),
+            $text
+        );
+        return $this->format($text);
+    }
+
+    /**
+     * Formats a string
+     *
+     * @param string $text string to be formatted
+     *
+     * @return string formatted text
+     */
+    function format($text)
+    {
+        $text = str_replace(
+            "#ucfirstName#",
+            ExportCodegen::cgMakeIdentifier($this->name),
+            $text
+        );
+        $text = str_replace(
+            "#dotNetPrimitiveType#",
+            $this->getDotNetPrimitiveType(),
+            $text
+        );
+        $text = str_replace(
+            "#dotNetObjectType#",
+            $this->getDotNetObjectType(),
+            $text
+        );
+        $text = str_replace(
+            "#type#",
+            $this->getPureType(),
+            $text
+        );
+        $text = str_replace(
+            "#notNull#",
+            $this->isNotNull(),
+            $text
+        );
+        $text = str_replace(
+            "#unique#",
+            $this->isUnique(),
+            $text
+        );
+        return $text;
+    }
+}
+?>
\ No newline at end of file
diff --git a/phpmyadmin/libraries/plugins/import/AbstractImportCsv.class.php b/phpmyadmin/libraries/plugins/import/AbstractImportCsv.class.php
new file mode 100644
index 0000000..62ca8bb
--- /dev/null
+++ b/phpmyadmin/libraries/plugins/import/AbstractImportCsv.class.php
@@ -0,0 +1,91 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * Super class of CSV import plugins for phpMyAdmin
+ *
+ * @package    PhpMyAdmin-Import
+ * @subpackage CSV
+ */
+if (! defined('PHPMYADMIN')) {
+    exit;
+}
+
+/* Get the import interface */
+require_once 'libraries/plugins/ImportPlugin.class.php';
+
+/**
+ * Super class of the import plugins for the CSV format
+ *
+ * @package    PhpMyAdmin-Import
+ * @subpackage CSV
+ */
+abstract class AbstractImportCsv extends ImportPlugin
+{
+    /**
+     * Sets the import plugin properties.
+     * Called in the constructor.
+     *
+     * @return object OptionsPropertyMainGroup object of the plugin
+     */
+    protected function setProperties()
+    {
+        $props = 'libraries/properties/';
+        include_once "$props/plugins/ImportPluginProperties.class.php";
+        include_once "$props/options/groups/OptionsPropertyRootGroup.class.php";
+        include_once "$props/options/groups/OptionsPropertyMainGroup.class.php";
+        include_once "$props/options/items/BoolPropertyItem.class.php";
+        include_once "$props/options/items/TextPropertyItem.class.php";
+
+        $importPluginProperties = new ImportPluginProperties();
+        $importPluginProperties->setOptionsText(__('Options'));
+
+        // create the root group that will be the options field for
+        // $importPluginProperties
+        // this will be shown as "Format specific options"
+        $importSpecificOptions = new OptionsPropertyRootGroup();
+        $importSpecificOptions->setName("Format Specific Options");
+
+        // general options main group
+        $generalOptions = new OptionsPropertyMainGroup();
+        $generalOptions->setName("general_opts");
+
+        // create common items and add them to the group
+        $leaf = new BoolPropertyItem();
+        $leaf->setName("replace");
+        $leaf->setText(__('Replace table data with file'));
+        $generalOptions->addProperty($leaf);
+        $leaf = new TextPropertyItem();
+        $leaf->setName("terminated");
+        $leaf->setText(__('Columns separated with:'));
+        $leaf->setSize(2);
+        $leaf->setLen(2);
+        $generalOptions->addProperty($leaf);
+        $leaf = new TextPropertyItem();
+        $leaf->setName("enclosed");
+        $leaf->setText(__('Columns enclosed with:'));
+        $leaf->setSize(2);
+        $leaf->setLen(2);
+        $generalOptions->addProperty($leaf);
+        $leaf = new TextPropertyItem();
+        $leaf->setName("escaped");
+        $leaf->setText(__('Columns escaped with:'));
+        $leaf->setSize(2);
+        $leaf->setLen(2);
+        $generalOptions->addProperty($leaf);
+        $leaf = new TextPropertyItem();
+        $leaf->setName("new_line");
+        $leaf->setText(__('Lines terminated with:'));
+        $leaf->setSize(2);
+        $generalOptions->addProperty($leaf);
+
+        // add the main group to the root group
+        $importSpecificOptions->addProperty($generalOptions);
+
+        // set the options for the import plugin property item
+        $importPluginProperties->setOptions($importSpecificOptions);
+        $this->properties = $importPluginProperties;
+
+        return $generalOptions;
+    }
+}
+?>
\ No newline at end of file
diff --git a/phpmyadmin/libraries/plugins/import/ImportCsv.class.php b/phpmyadmin/libraries/plugins/import/ImportCsv.class.php
new file mode 100644
index 0000000..d480564
--- /dev/null
+++ b/phpmyadmin/libraries/plugins/import/ImportCsv.class.php
@@ -0,0 +1,588 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * CSV import plugin for phpMyAdmin
+ *
+ * @todo       add an option for handling NULL values
+ * @package    PhpMyAdmin-Import
+ * @subpackage CSV
+ */
+if (! defined('PHPMYADMIN')) {
+    exit;
+}
+
+/* Get the import interface */
+require_once 'libraries/plugins/import/AbstractImportCsv.class.php';
+
+/**
+ * Handles the import for the CSV format
+ *
+ * @package    PhpMyAdmin-Import
+ * @subpackage CSV
+ */
+class ImportCsv extends AbstractImportCsv
+{
+    /**
+     * Whether to analyze tables
+     *
+     * @var bool
+     */
+    private $_analyze;
+
+    /**
+     * Constructor
+     */
+    public function __construct()
+    {
+        $this->setProperties();
+    }
+
+    /**
+     * Sets the import plugin properties.
+     * Called in the constructor.
+     *
+     * @return void
+     */
+    protected function setProperties()
+    {
+        $this->_setAnalyze(false);
+
+        if ($GLOBALS['plugin_param'] !== 'table') {
+            $this->_setAnalyze(true);
+        }
+
+        $generalOptions = parent::setProperties();
+        $this->properties->setText('CSV');
+        $this->properties->setExtension('csv');
+
+        if ($GLOBALS['plugin_param'] !== 'table') {
+            $leaf = new BoolPropertyItem();
+            $leaf->setName("col_names");
+            $leaf->setText(
+                __(
+                    'The first line of the file contains the table column names'
+                    . ' <i>(if this is unchecked, the first line will become part'
+                    . ' of the data)</i>'
+                )
+            );
+            $generalOptions->addProperty($leaf);
+        } else {
+            $hint = new PMA_Message(
+                __(
+                    'If the data in each row of the file is not'
+                    . ' in the same order as in the database, list the corresponding'
+                    . ' column names here. Column names must be separated by commas'
+                    . ' and not enclosed in quotations.'
+                )
+            );
+            $leaf = new TextPropertyItem();
+            $leaf->setName("columns");
+            $leaf->setText(
+                __('Column names: ')
+                . PMA_Util::showHint($hint)
+            );
+            $generalOptions->addProperty($leaf);
+        }
+
+        $leaf = new BoolPropertyItem();
+        $leaf->setName("ignore");
+        $leaf->setText(__('Do not abort on INSERT error'));
+        $generalOptions->addProperty($leaf);
+
+    }
+
+    /**
+     * This method is called when any PluginManager to which the observer
+     * is attached calls PluginManager::notify()
+     *
+     * @param SplSubject $subject The PluginManager notifying the observer
+     *                            of an update.
+     *
+     * @return void
+     */
+    public function update (SplSubject $subject)
+    {
+    }
+
+    /**
+     * Handles the whole import logic
+     *
+     * @return void
+     */
+    public function doImport()
+    {
+        global $db, $table, $csv_terminated, $csv_enclosed, $csv_escaped,
+            $csv_new_line, $csv_columns, $err_url;
+        // $csv_replace and $csv_ignore should have been here,
+        // but we use directly from $_POST
+        global $error, $timeout_passed, $finished, $message;
+
+        $replacements = array(
+            '\\n'   => "\n",
+            '\\t'   => "\t",
+            '\\r'   => "\r",
+        );
+        $csv_terminated = strtr($csv_terminated, $replacements);
+        $csv_enclosed = strtr($csv_enclosed,  $replacements);
+        $csv_escaped = strtr($csv_escaped, $replacements);
+        $csv_new_line = strtr($csv_new_line, $replacements);
+
+        $param_error = false;
+        if (strlen($csv_terminated) != 1) {
+            $message = PMA_Message::error(
+                __('Invalid parameter for CSV import: %s')
+            );
+            $message->addParam(__('Columns terminated by'), false);
+            $error = true;
+            $param_error = true;
+            // The default dialog of MS Excel when generating a CSV produces a
+            // semi-colon-separated file with no chance of specifying the
+            // enclosing character. Thus, users who want to import this file
+            // tend to remove the enclosing character on the Import dialog.
+            // I could not find a test case where having no enclosing characters
+            // confuses this script.
+            // But the parser won't work correctly with strings so we allow just
+            // one character.
+        } elseif (strlen($csv_enclosed) > 1) {
+            $message = PMA_Message::error(
+                __('Invalid parameter for CSV import: %s')
+            );
+            $message->addParam(__('Columns enclosed by'), false);
+            $error = true;
+            $param_error = true;
+        } elseif (strlen($csv_escaped) != 1) {
+            $message = PMA_Message::error(
+                __('Invalid parameter for CSV import: %s')
+            );
+            $message->addParam(__('Columns escaped by'), false);
+            $error = true;
+            $param_error = true;
+        } elseif (strlen($csv_new_line) != 1 && $csv_new_line != 'auto') {
+            $message = PMA_Message::error(
+                __('Invalid parameter for CSV import: %s')
+            );
+            $message->addParam(__('Lines terminated by'), false);
+            $error = true;
+            $param_error = true;
+        }
+
+        // If there is an error in the parameters entered,
+        // indicate that immediately.
+        if ($param_error) {
+            PMA_Util::mysqlDie($message->getMessage(), '', '', $err_url);
+        }
+
+        $buffer = '';
+        $required_fields = 0;
+
+        if (! $this->_getAnalyze()) {
+            if (isset($_POST['csv_replace'])) {
+                $sql_template = 'REPLACE';
+            } else {
+                $sql_template = 'INSERT';
+                if (isset($_POST['csv_ignore'])) {
+                    $sql_template .= ' IGNORE';
+                }
+            }
+            $sql_template .= ' INTO ' . PMA_Util::backquote($table);
+
+            $tmp_fields = PMA_DBI_get_columns($db, $table);
+
+            if (empty($csv_columns)) {
+                $fields = $tmp_fields;
+            } else {
+                $sql_template .= ' (';
+                $fields = array();
+                $tmp   = preg_split('/,( ?)/', $csv_columns);
+                foreach ($tmp as $key => $val) {
+                    if (count($fields) > 0) {
+                        $sql_template .= ', ';
+                    }
+                    /* Trim also `, if user already included backquoted fields */
+                    $val = trim($val, " \t\r\n\0\x0B`");
+                    $found = false;
+                    foreach ($tmp_fields as $field) {
+                        if ($field['Field'] == $val) {
+                            $found = true;
+                            break;
+                        }
+                    }
+                    if (! $found) {
+                        $message = PMA_Message::error(
+                            __(
+                                'Invalid column (%s) specified! Ensure that columns'
+                                . ' names are spelled correctly, separated by commas'
+                                . ', and not enclosed in quotes.'
+                            )
+                        );
+                        $message->addParam($val);
+                        $error = true;
+                        break;
+                    }
+                    $fields[] = $field;
+                    $sql_template .= PMA_Util::backquote($val);
+                }
+                $sql_template .= ') ';
+            }
+
+            $required_fields = count($fields);
+
+            $sql_template .= ' VALUES (';
+        }
+
+        // Defaults for parser
+        $i = 0;
+        $len = 0;
+        $line = 1;
+        $lasti = -1;
+        $values = array();
+        $csv_finish = false;
+
+        $tempRow = array();
+        $rows = array();
+        $col_names = array();
+        $tables = array();
+
+        $col_count = 0;
+        $max_cols = 0;
+
+        while (! ($finished && $i >= $len) && ! $error && ! $timeout_passed) {
+            $data = PMA_importGetNextChunk();
+            if ($data === false) {
+                // subtract data we didn't handle yet and stop processing
+                $offset -= strlen($buffer);
+                break;
+            } elseif ($data === true) {
+                // Handle rest of buffer
+            } else {
+                // Append new data to buffer
+                $buffer .= $data;
+                unset($data);
+                // Do not parse string when we're not at the end
+                // and don't have new line inside
+                if (($csv_new_line == 'auto'
+                    && strpos($buffer, "\r") === false
+                    && strpos($buffer, "\n") === false)
+                    || ($csv_new_line != 'auto'
+                    && strpos($buffer, $csv_new_line) === false)
+                ) {
+                    continue;
+                }
+            }
+
+            // Current length of our buffer
+            $len = strlen($buffer);
+            // Currently parsed char
+            $ch = $buffer[$i];
+            while ($i < $len) {
+                // Deadlock protection
+                if ($lasti == $i && $lastlen == $len) {
+                    $message = PMA_Message::error(
+                        __('Invalid format of CSV input on line %d.')
+                    );
+                    $message->addParam($line);
+                    $error = true;
+                    break;
+                }
+                $lasti = $i;
+                $lastlen = $len;
+
+                // This can happen with auto EOL and \r at the end of buffer
+                if (! $csv_finish) {
+                    // Grab empty field
+                    if ($ch == $csv_terminated) {
+                        if ($i == $len - 1) {
+                            break;
+                        }
+                        $values[] = '';
+                        $i++;
+                        $ch = $buffer[$i];
+                        continue;
+                    }
+
+                    // Grab one field
+                    $fallbacki = $i;
+                    if ($ch == $csv_enclosed) {
+                        if ($i == $len - 1) {
+                            break;
+                        }
+                        $need_end = true;
+                        $i++;
+                        $ch = $buffer[$i];
+                    } else {
+                        $need_end = false;
+                    }
+                    $fail = false;
+                    $value = '';
+                    while (($need_end
+                        && ( $ch != $csv_enclosed || $csv_enclosed == $csv_escaped ))
+                        || ( ! $need_end
+                        && ! ( $ch == $csv_terminated
+                        || $ch == $csv_new_line
+                        || ( $csv_new_line == 'auto'
+                        && ( $ch == "\r" || $ch == "\n" ) ) ) )
+                    ) {
+                        if ($ch == $csv_escaped) {
+                            if ($i == $len - 1) {
+                                $fail = true;
+                                break;
+                            }
+                            $i++;
+                            $ch = $buffer[$i];
+                            if ($csv_enclosed == $csv_escaped
+                                && ($ch == $csv_terminated
+                                || $ch == $csv_new_line
+                                || ($csv_new_line == 'auto'
+                                && ($ch == "\r" || $ch == "\n")))
+                            ) {
+                                break;
+                            }
+                        }
+                        $value .= $ch;
+                        if ($i == $len - 1) {
+                            if (! $finished) {
+                                $fail = true;
+                            }
+                            break;
+                        }
+                        $i++;
+                        $ch = $buffer[$i];
+                    }
+
+                    // unquoted NULL string
+                    if (false === $need_end && $value === 'NULL') {
+                        $value = null;
+                    }
+
+                    if ($fail) {
+                        $i = $fallbacki;
+                        $ch = $buffer[$i];
+                        break;
+                    }
+                    // Need to strip trailing enclosing char?
+                    if ($need_end && $ch == $csv_enclosed) {
+                        if ($finished && $i == $len - 1) {
+                            $ch = null;
+                        } elseif ($i == $len - 1) {
+                            $i = $fallbacki;
+                            $ch = $buffer[$i];
+                            break;
+                        } else {
+                            $i++;
+                            $ch = $buffer[$i];
+                        }
+                    }
+                    // Are we at the end?
+                    if ($ch == $csv_new_line
+                        || ($csv_new_line == 'auto' && ($ch == "\r" || $ch == "\n"))
+                        || ($finished && $i == $len - 1)
+                    ) {
+                        $csv_finish = true;
+                    }
+                    // Go to next char
+                    if ($ch == $csv_terminated) {
+                        if ($i == $len - 1) {
+                            $i = $fallbacki;
+                            $ch = $buffer[$i];
+                            break;
+                        }
+                        $i++;
+                        $ch = $buffer[$i];
+                    }
+                    // If everything went okay, store value
+                    $values[] = $value;
+                }
+
+                // End of line
+                if ($csv_finish
+                    || $ch == $csv_new_line
+                    || ($csv_new_line == 'auto' && ($ch == "\r" || $ch == "\n"))
+                ) {
+                    if ($csv_new_line == 'auto' && $ch == "\r") { // Handle "\r\n"
+                        if ($i >= ($len - 2) && ! $finished) {
+                            break; // We need more data to decide new line
+                        }
+                        if ($buffer[$i + 1] == "\n") {
+                            $i++;
+                        }
+                    }
+                    // We didn't parse value till the end of line, so there was
+                    // empty one
+                    if (! $csv_finish) {
+                        $values[] = '';
+                    }
+
+                    if ($this->_getAnalyze()) {
+                        foreach ($values as $val) {
+                            $tempRow[] = $val;
+                            ++$col_count;
+                        }
+
+                        if ($col_count > $max_cols) {
+                            $max_cols = $col_count;
+                        }
+                        $col_count = 0;
+
+                        $rows[] = $tempRow;
+                        $tempRow = array();
+                    } else {
+                        // Do we have correct count of values?
+                        if (count($values) != $required_fields) {
+
+                            // Hack for excel
+                            if ($values[count($values) - 1] == ';') {
+                                unset($values[count($values) - 1]);
+                            } else {
+                                $message = PMA_Message::error(
+                                    __('Invalid column count in CSV input on line %d.')
+                                );
+                                $message->addParam($line);
+                                $error = true;
+                                break;
+                            }
+                        }
+
+                        $first = true;
+                        $sql = $sql_template;
+                        foreach ($values as $key => $val) {
+                            if (! $first) {
+                                $sql .= ', ';
+                            }
+                            if ($val === null) {
+                                $sql .= 'NULL';
+                            } else {
+                                $sql .= '\''
+                                    . PMA_Util::sqlAddSlashes($val)
+                                    . '\'';
+                            }
+
+                            $first = false;
+                        }
+                        $sql .= ')';
+
+                        /**
+                         * @todo maybe we could add original line to verbose
+                         * SQL in comment
+                         */
+                        PMA_importRunQuery($sql, $sql);
+                    }
+
+                    $line++;
+                    $csv_finish = false;
+                    $values = array();
+                    $buffer = substr($buffer, $i + 1);
+                    $len = strlen($buffer);
+                    $i = 0;
+                    $lasti = -1;
+                    $ch = $buffer[0];
+                }
+            } // End of parser loop
+        } // End of import loop
+
+        if ($this->_getAnalyze()) {
+            /* Fill out all rows */
+            $num_rows = count($rows);
+            for ($i = 0; $i < $num_rows; ++$i) {
+                for ($j = count($rows[$i]); $j < $max_cols; ++$j) {
+                    $rows[$i][] = 'NULL';
+                }
+            }
+
+            if (isset($_REQUEST['csv_col_names'])) {
+                $col_names = array_splice($rows, 0, 1);
+                $col_names = $col_names[0];
+            }
+
+            if ((isset($col_names) && count($col_names) != $max_cols)
+                || ! isset($col_names)
+            ) {
+                // Fill out column names
+                for ($i = 0; $i < $max_cols; ++$i) {
+                    $col_names[] = 'COL '.($i+1);
+                }
+            }
+
+            if (strlen($db)) {
+                $result = PMA_DBI_fetch_result('SHOW TABLES');
+                $tbl_name = 'TABLE '.(count($result) + 1);
+            } else {
+                $tbl_name = 'TBL_NAME';
+            }
+
+            $tables[] = array($tbl_name, $col_names, $rows);
+
+            /* Obtain the best-fit MySQL types for each column */
+            $analyses = array();
+            $analyses[] = PMA_analyzeTable($tables[0]);
+
+            /**
+             * string $db_name (no backquotes)
+             *
+             * array $table = array(table_name, array() column_names, array()() rows)
+             * array $tables = array of "$table"s
+             *
+             * array $analysis = array(array() column_types, array() column_sizes)
+             * array $analyses = array of "$analysis"s
+             *
+             * array $create = array of SQL strings
+             *
+             * array $options = an associative array of options
+             */
+
+            /* Set database name to the currently selected one, if applicable */
+            if (strlen($db)) {
+                $db_name = $db;
+                $options = array('create_db' => false);
+            } else {
+                $db_name = 'CSV_DB';
+                $options = null;
+            }
+
+            /* Non-applicable parameters */
+            $create = null;
+
+            /* Created and execute necessary SQL statements from data */
+            PMA_buildSQL($db_name, $tables, $analyses, $create, $options);
+
+            unset($tables);
+            unset($analyses);
+        }
+
+        // Commit any possible data in buffers
+        PMA_importRunQuery();
+
+        if (count($values) != 0 && ! $error) {
+            $message = PMA_Message::error(
+                __('Invalid format of CSV input on line %d.')
+            );
+            $message->addParam($line);
+            $error = true;
+        }
+    }
+
+
+    /* ~~~~~~~~~~~~~~~~~~~~ Getters and Setters ~~~~~~~~~~~~~~~~~~~~ */
+
+
+    /**
+     * Returns true if the table should be analyzed, false otherwise
+     *
+     * @return bool
+     */
+    private function _getAnalyze()
+    {
+        return $this->_analyze;
+    }
+
+    /**
+     * Sets to true if the table should be analyzed, false otherwise
+     *
+     * @param bool $analyze status
+     *
+     * @return void
+     */
+    private function _setAnalyze($analyze)
+    {
+        $this->_analyze = $analyze;
+    }
+}
diff --git a/phpmyadmin/libraries/plugins/import/ImportLdi.class.php b/phpmyadmin/libraries/plugins/import/ImportLdi.class.php
new file mode 100644
index 0000000..e38def9
--- /dev/null
+++ b/phpmyadmin/libraries/plugins/import/ImportLdi.class.php
@@ -0,0 +1,172 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * CSV import plugin for phpMyAdmin using LOAD DATA
+ *
+ * @package    PhpMyAdmin-Import
+ * @subpackage LDI
+ */
+if (! defined('PHPMYADMIN')) {
+    exit;
+}
+
+/* Get the import interface */
+require_once 'libraries/plugins/import/AbstractImportCsv.class.php';
+
+// We need relations enabled and we work only on database
+if ($GLOBALS['plugin_param'] !== 'table') {
+    $GLOBALS['skip_import'] = true;
+    return;
+}
+
+/**
+ * Handles the import for the CSV format using load data
+ *
+ * @package    PhpMyAdmin-Import
+ * @subpackage LDI
+ */
+class ImportLdi extends AbstractImportCsv
+{
+    /**
+     * Constructor
+     */
+    public function __construct()
+    {
+        $this->setProperties();
+    }
+
+    /**
+     * Sets the import plugin properties.
+     * Called in the constructor.
+     *
+     * @return void
+     */
+    protected function setProperties()
+    {
+        if ($GLOBALS['cfg']['Import']['ldi_local_option'] == 'auto') {
+            $GLOBALS['cfg']['Import']['ldi_local_option'] = false;
+
+            $result = PMA_DBI_try_query('SHOW VARIABLES LIKE \'local\\_infile\';');
+            if ($result != false && PMA_DBI_num_rows($result) > 0) {
+                $tmp = PMA_DBI_fetch_row($result);
+                if ($tmp[1] == 'ON') {
+                    $GLOBALS['cfg']['Import']['ldi_local_option'] = true;
+                }
+            }
+            PMA_DBI_free_result($result);
+            unset($result);
+        }
+
+        $generalOptions = parent::setProperties();
+        $this->properties->setText('CSV using LOAD DATA');
+        $this->properties->setExtension('ldi');
+
+        $leaf = new TextPropertyItem();
+        $leaf->setName("columns");
+        $leaf->setText(__('Column names: '));
+        $generalOptions->addProperty($leaf);
+
+        $leaf = new BoolPropertyItem();
+        $leaf->setName("ignore");
+        $leaf->setText(__('Do not abort on INSERT error'));
+        $generalOptions->addProperty($leaf);
+
+        $leaf = new BoolPropertyItem();
+        $leaf->setName("local_option");
+        $leaf->setText(__('Use LOCAL keyword'));
+        $generalOptions->addProperty($leaf);
+    }
+
+    /**
+     * This method is called when any PluginManager to which the observer
+     * is attached calls PluginManager::notify()
+     *
+     * @param SplSubject $subject The PluginManager notifying the observer
+     *                            of an update.
+     *
+     * @return void
+     */
+    public function update (SplSubject $subject)
+    {
+    }
+
+    /**
+     * Handles the whole import logic
+     *
+     * @return void
+     */
+    public function doImport()
+    {
+        global $finished, $error, $import_file, $compression, $charset_conversion, $table;
+        global $ldi_local_option, $ldi_replace, $ldi_ignore, $ldi_terminated, $ldi_enclosed,
+            $ldi_escaped, $ldi_new_line, $skip_queries, $ldi_columns;
+
+        if ($import_file == 'none'
+            || $compression != 'none'
+            || $charset_conversion
+        ) {
+            // We handle only some kind of data!
+            $message = PMA_Message::error(
+                __('This plugin does not support compressed imports!')
+            );
+            $error = true;
+            return;
+        }
+
+        $sql = 'LOAD DATA';
+        if (isset($ldi_local_option)) {
+            $sql .= ' LOCAL';
+        }
+        $sql .= ' INFILE \'' . PMA_Util::sqlAddSlashes($import_file) . '\'';
+        if (isset($ldi_replace)) {
+            $sql .= ' REPLACE';
+        } elseif (isset($ldi_ignore)) {
+            $sql .= ' IGNORE';
+        }
+        $sql .= ' INTO TABLE ' . PMA_Util::backquote($table);
+
+        if (strlen($ldi_terminated) > 0) {
+            $sql .= ' FIELDS TERMINATED BY \'' . $ldi_terminated . '\'';
+        }
+        if (strlen($ldi_enclosed) > 0) {
+            $sql .= ' ENCLOSED BY \''
+                . PMA_Util::sqlAddSlashes($ldi_enclosed) . '\'';
+        }
+        if (strlen($ldi_escaped) > 0) {
+            $sql .= ' ESCAPED BY \''
+                . PMA_Util::sqlAddSlashes($ldi_escaped) . '\'';
+        }
+        if (strlen($ldi_new_line) > 0) {
+            if ($ldi_new_line == 'auto') {
+                $ldi_new_line
+                    = (PMA_Util::whichCrlf() == "\n")
+                        ? '\n'
+                        : '\r\n';
+            }
+            $sql .= ' LINES TERMINATED BY \'' . $ldi_new_line . '\'';
+        }
+        if ($skip_queries > 0) {
+            $sql .= ' IGNORE ' . $skip_queries . ' LINES';
+            $skip_queries = 0;
+        }
+        if (strlen($ldi_columns) > 0) {
+            $sql .= ' (';
+            $tmp   = preg_split('/,( ?)/', $ldi_columns);
+            $cnt_tmp = count($tmp);
+            for ($i = 0; $i < $cnt_tmp; $i++) {
+                if ($i > 0) {
+                    $sql .= ', ';
+                }
+                /* Trim also `, if user already included backquoted fields */
+                $sql .= PMA_Util::backquote(
+                    trim($tmp[$i], " \t\r\n\0\x0B`")
+                );
+            } // end for
+            $sql .= ')';
+        }
+
+        PMA_importRunQuery($sql, $sql);
+        PMA_importRunQuery();
+        $finished = true;
+    }
+}
\ No newline at end of file
diff --git a/phpmyadmin/libraries/plugins/import/ImportMediawiki.class.php b/phpmyadmin/libraries/plugins/import/ImportMediawiki.class.php
new file mode 100644
index 0000000..767c966
--- /dev/null
+++ b/phpmyadmin/libraries/plugins/import/ImportMediawiki.class.php
@@ -0,0 +1,573 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * MediaWiki import plugin for phpMyAdmin
+ *
+ * @package    PhpMyAdmin-Import
+ * @subpackage MediaWiki
+ */
+if (! defined('PHPMYADMIN')) {
+    exit;
+}
+
+/* Get the import interface */
+require_once 'libraries/plugins/ImportPlugin.class.php';
+
+/**
+ * Handles the import for the MediaWiki format
+ *
+ * @package    PhpMyAdmin-Import
+ * @subpackage MediaWiki
+ */
+class ImportMediawiki extends ImportPlugin
+{
+    /**
+     * Whether to analyze tables
+     *
+     * @var bool
+     */
+    private $_analyze;
+
+    /**
+     * Constructor
+     */
+    public function __construct()
+    {
+        $this->setProperties();
+    }
+
+    /**
+     * Sets the import plugin properties.
+     * Called in the constructor.
+     *
+     * @return void
+     */
+    protected function setProperties()
+    {
+        $this->_setAnalyze(false);
+        if ($GLOBALS['plugin_param'] !== 'table') {
+            $this->_setAnalyze(true);
+        }
+
+        $props = 'libraries/properties/';
+        include_once "$props/plugins/ImportPluginProperties.class.php";
+
+        $importPluginProperties = new ImportPluginProperties();
+        $importPluginProperties->setText(__('MediaWiki Table'));
+        $importPluginProperties->setExtension('txt');
+        $importPluginProperties->setMimeType('text/plain');
+        $importPluginProperties->setOptions(array());
+        $importPluginProperties->setOptionsText(__('Options'));
+
+        $this->properties = $importPluginProperties;
+    }
+
+    /**
+     * This method is called when any PluginManager to which the observer
+     * is attached calls PluginManager::notify()
+     *
+     * @param SplSubject $subject The PluginManager notifying the observer
+     *                            of an update.
+     *
+     * @return void
+     */
+    public function update (SplSubject $subject)
+    {
+    }
+
+    /**
+     * Handles the whole import logic
+     *
+     * @return void
+     */
+    public function doImport()
+    {
+        global $error, $timeout_passed, $finished;
+
+        // Defaults for parser
+
+        // The buffer that will be used to store chunks read from the imported file
+        $buffer = '';
+
+        // Used as storage for the last part of the current chunk data
+        // Will be appended to the first line of the next chunk, if there is one
+        $last_chunk_line = '';
+
+        // Remembers whether the current buffer line is part of a comment
+        $inside_comment = false;
+        // Remembers whether the current buffer line is part of a data comment
+        $inside_data_comment = false;
+        // Remembers whether the current buffer line is part of a structure comment
+        $inside_structure_comment = false;
+
+        // MediaWiki only accepts "\n" as row terminator
+        $mediawiki_new_line = "\n";
+
+        // Initialize the name of the current table
+        $cur_table_name = "";
+
+        while (! $finished && ! $error && ! $timeout_passed ) {
+            $data = PMA_importGetNextChunk();
+
+            if ($data === false) {
+                // Subtract data we didn't handle yet and stop processing
+                $offset -= strlen($buffer);
+                break;
+            } elseif ($data === true) {
+                // Handle rest of buffer
+            } else {
+                // Append new data to buffer
+                $buffer = $data;
+                unset($data);
+                // Don't parse string if we're not at the end
+                // and don't have a new line inside
+                if ( strpos($buffer, $mediawiki_new_line) === false ) {
+                    continue;
+                }
+            }
+
+            // Because of reading chunk by chunk, the first line from the buffer
+            // contains only a portion of an actual line from the imported file.
+            // Therefore, we have to append it to the last line from the previous
+            // chunk. If we are at the first chunk, $last_chunk_line should be empty.
+            $buffer = $last_chunk_line . $buffer;
+
+            // Process the buffer line by line
+            $buffer_lines = explode($mediawiki_new_line, $buffer);
+
+            $full_buffer_lines_count = count($buffer_lines);
+            // If the reading is not finalised, the final line of the current chunk
+            // will not be complete
+            if (! $finished) {
+                $full_buffer_lines_count -= 1;
+                $last_chunk_line = $buffer_lines[$full_buffer_lines_count];
+            }
+
+            for ($line_nr = 0; $line_nr < $full_buffer_lines_count; ++ $line_nr) {
+                $cur_buffer_line = trim($buffer_lines[$line_nr]);
+
+                // If the line is empty, go to the next one
+                if ( $cur_buffer_line === '' ) {
+                    continue;
+                }
+
+                $first_character = $cur_buffer_line[0];
+                $matches = array();
+
+                // Check beginnning of comment
+                if (! strcmp(substr($cur_buffer_line, 0, 4), "<!--")) {
+                    $inside_comment = true;
+                    continue;
+                } elseif ($inside_comment) {
+                    // Check end of comment
+                    if (! strcmp(substr($cur_buffer_line, 0, 4), "-->")) {
+                        // Only data comments are closed. The structure comments
+                        // will be closed when a data comment begins (in order to
+                        // skip structure tables)
+                        if ($inside_data_comment) {
+                            $inside_data_comment = false;
+                        }
+
+                        // End comments that are not related to table structure
+                        if (! $inside_structure_comment) {
+                            $inside_comment = false;
+                        }
+                    } else {
+                        // Check table name
+                        $match_table_name = array();
+                        if (preg_match(
+                            "/^Table data for `(.*)`$/",
+                            $cur_buffer_line,
+                            $match_table_name
+                        )
+                        ) {
+                            $cur_table_name = $match_table_name[1];
+                            $inside_data_comment = true;
+
+                            // End ignoring structure rows
+                            if ($inside_structure_comment) {
+                                $inside_structure_comment = false;
+                            }
+                        } elseif (preg_match(
+                            "/^Table structure for `(.*)`$/",
+                            $cur_buffer_line,
+                            $match_table_name
+                        )
+                        ) {
+                            // The structure comments will be ignored
+                            $inside_structure_comment = true;
+                        }
+                    }
+                    continue;
+                } elseif (preg_match('/^\{\|(.*)$/', $cur_buffer_line, $matches)) {
+                    // Check start of table
+
+                    // This will store all the column info on all rows from
+                    // the current table read from the buffer
+                    $cur_temp_table = array();
+
+                    // Will be used as storage for the current row in the buffer
+                    // Once all its columns are read, it will be added to
+                    // $cur_temp_table and then it will be emptied
+                    $cur_temp_line = array();
+
+                    // Helps us differentiate the header columns
+                    // from the normal columns
+                    $in_table_header = false;
+                    // End processing because the current line does not
+                    // contain any column information
+                } elseif (substr($cur_buffer_line, 0, 2) === '|-'
+                      || substr($cur_buffer_line, 0, 2) === '|+'
+                      || substr($cur_buffer_line, 0, 2) === '|}'
+                ) {
+                    // Check begin row or end table
+
+                    // Add current line to the values storage
+                    if (! empty($cur_temp_line)) {
+                        // If the current line contains header cells
+                        // ( marked with '!' ),
+                        // it will be marked as table header
+                        if ( $in_table_header ) {
+                            // Set the header columns
+                            $cur_temp_table_headers = $cur_temp_line;
+                        } else {
+                            // Normal line, add it to the table
+                            $cur_temp_table [] = $cur_temp_line;
+                        }
+                    }
+
+                    // Empty the temporary buffer
+                    $cur_temp_line = array();
+
+                    // No more processing required at the end of the table
+                    if (substr($cur_buffer_line, 0, 2) === '|}') {
+                        $current_table = array(
+                            $cur_table_name,
+                            $cur_temp_table_headers,
+                            $cur_temp_table
+                        );
+
+                        // Import the current table data into the database
+                        $this->_importDataOneTable($current_table);
+
+                        // Reset table name
+                        $cur_table_name = "";
+                    }
+                    // What's after the row tag is now only attributes
+
+                } elseif (($first_character === '|') || ($first_character === '!')) {
+                    // Check cell elements
+
+                    // Header cells
+                    if ($first_character === '!') {
+                        // Mark as table header, but treat as normal row
+                        $cur_buffer_line = str_replace('!!', '||', $cur_buffer_line);
+                        // Will be used to set $cur_temp_line as table header
+                        $in_table_header = true;
+                    } else {
+                        $in_table_header = false;
+                    }
+
+                    // Loop through each table cell
+                    $cells = $this->_explodeMarkup($cur_buffer_line);
+                    foreach ($cells as $cell) {
+                        // A cell could contain both parameters and data
+                        $cell_data = explode('|', $cell, 2);
+
+                        // A '|' inside an invalid link should not
+                        // be mistaken as delimiting cell parameters
+                        if (strpos($cell_data[0], '[[') === true ) {
+                            if (count($cell_data) == 1) {
+                                $cell = $cell_data[0];
+                            } else {
+                                $cell = $cell_data[1];
+                            }
+                        }
+
+                        // Delete the beginning of the column, if there is one
+                        $cell = trim($cell);
+                        $col_start_chars = array( "|", "!");
+                        foreach ($col_start_chars as $col_start_char) {
+                            if (strpos($cell, $col_start_char) === 0) {
+                                $cell = trim(substr($cell, 1));
+                            }
+                        }
+
+                        // Add the cell to the row
+                        $cur_temp_line [] = $cell;
+                    } // foreach $cells
+                } else {
+                    // If it's none of the above, then the current line has a bad
+                    // format
+                    $message = PMA_Message::error(
+                        __('Invalid format of mediawiki input on line: <br />%s.')
+                    );
+                    $message->addParam($cur_buffer_line);
+                    $error = true;
+                }
+            } // End treating full buffer lines
+        } // while - finished parsing buffer
+    }
+
+    /**
+     * Imports data from a single table
+     *
+     * @param array $table containing all table info:
+     *        <code>
+     *            $table[0] - string containing table name
+     *            $table[1] - array[]   of table headers
+     *            $table[2] - array[][] of table content rows
+     *        </code>
+     *
+     * @global bool  $analyze whether to scan for column types
+     *
+     * @return void
+     */
+    private function _importDataOneTable ($table)
+    {
+        $analyze = $this->_getAnalyze();
+        if ($analyze) {
+            // Set the table name
+            $this->_setTableName($table[0]);
+
+            // Set generic names for table headers if they don't exist
+            $this->_setTableHeaders($table[1], $table[2][0]);
+
+            // Create the tables array to be used in PMA_buildSQL()
+            $tables = array();
+            $tables [] = array($table[0], $table[1], $table[2]);
+
+            // Obtain the best-fit MySQL types for each column
+            $analyses = array();
+            $analyses [] = PMA_analyzeTable($tables[0]);
+
+            $this->_executeImportTables($tables, $analyses);
+        }
+
+        // Commit any possible data in buffers
+        PMA_importRunQuery();
+    }
+
+    /**
+     * Sets the table name
+     *
+     * @param string &$table_name reference to the name of the table
+     *
+     * @return void
+     */
+    private function _setTableName(&$table_name)
+    {
+        if (empty($table_name)) {
+            $result = PMA_DBI_fetch_result('SHOW TABLES');
+            // todo check if the name below already exists
+            $table_name = 'TABLE '.(count($result) + 1);
+        }
+    }
+
+    /**
+     * Set generic names for table headers, if they don't exist
+     *
+     * @param array &$table_headers reference to the array containing the headers
+     *                              of a table
+     * @param array $table_row      array containing the first content row
+     *
+     * @return void
+     */
+    private function _setTableHeaders(&$table_headers, $table_row)
+    {
+        if (empty($table_headers)) {
+            // The first table row should contain the number of columns
+            // If they are not set, generic names will be given (COL 1, COL 2, etc)
+            $num_cols = count($table_row);
+            for ($i = 0; $i < $num_cols; ++ $i) {
+                $table_headers [$i] = 'COL '. ($i + 1);
+            }
+        }
+    }
+
+    /**
+     * Sets the database name and additional options and calls PMA_buildSQL()
+     * Used in PMA_importDataAllTables() and $this->_importDataOneTable()
+     *
+     * @param array &$tables   structure:
+     *              array(
+     *                  array(table_name, array() column_names, array()() rows)
+     *              )
+     * @param array &$analyses structure:
+     *              $analyses = array(
+     *                  array(array() column_types, array() column_sizes)
+     *              )
+     *
+     * @global string $db name of the database to import in
+     *
+     * @return void
+     */
+    private function _executeImportTables(&$tables, &$analyses)
+    {
+        global $db;
+
+        // $db_name : The currently selected database name, if applicable
+        //            No backquotes
+        // $options : An associative array of options
+        if (strlen($db)) {
+            $db_name = $db;
+            $options = array('create_db' => false);
+        } else {
+            $db_name = 'mediawiki_DB';
+            $options = null;
+        }
+
+        // Array of SQL strings
+        // Non-applicable parameters
+        $create = null;
+
+        // Create and execute necessary SQL statements from data
+        PMA_buildSQL($db_name, $tables, $analyses, $create, $options);
+
+        unset($tables);
+        unset($analyses);
+    }
+
+
+    /**
+     * Replaces all instances of the '||' separator between delimiters
+     * in a given string
+     *
+     * @param string $start_delim start delimiter
+     * @param string $end_delim   end delimiter
+     * @param string $replace     the string to be replaced with
+     * @param string $subject     the text to be replaced
+     *
+     * @return string with replacements
+     */
+    private function _delimiterReplace($start_delim, $end_delim, $replace, $subject)
+    {
+        // String that will be returned
+        $cleaned = "";
+        // Possible states of current character
+        $inside_tag = false;
+        $inside_attribute = false;
+        // Attributes can be declared with either " or '
+        $start_attribute_character = false;
+
+        // The full separator is "||";
+        // This rembembers if the previous character was '|'
+        $partial_separator = false;
+
+        // Parse text char by char
+        for ($i = 0; $i < strlen($subject); $i ++) {
+            $cur_char = $subject[$i];
+            // Check for separators
+            if ($cur_char == '|') {
+                // If we're not inside a tag, then this is part of a real separator,
+                // so we append it to the current segment
+                if (! $inside_attribute) {
+                    $cleaned .= $cur_char;
+                    if ($partial_separator) {
+                        $inside_tag = false;
+                        $inside_attribute = false;
+                    }
+                } elseif ($partial_separator) {
+                    // If we are inside a tag, we replace the current char with
+                    // the placeholder and append that to the current segment
+                    $cleaned .= $replace;
+                }
+
+                // If the previous character was also '|', then this ends a
+                // full separator. If not, this may be the beginning of one
+                $partial_separator = ! $partial_separator;
+            } else {
+                // If we're inside a tag attribute and the current character is
+                // not '|', but the previous one was, it means that the single '|'
+                // was not appended, so we append it now
+                if ($partial_separator && $inside_attribute) {
+                    $cleaned .= "|";
+                }
+                // If the char is different from "|", no separator can be formed
+                $partial_separator = false;
+
+                // any other character should be appended to the current segment
+                $cleaned .= $cur_char;
+
+                if ($cur_char == '<' && ! $inside_attribute) {
+                    // start of a tag
+                    $inside_tag = true;
+                } elseif ($cur_char == '>' && ! $inside_attribute) {
+                    // end of a tag
+                    $inside_tag = false;
+                } elseif (($cur_char == '"' || $cur_char == "'") && $inside_tag) {
+                    // start or end of an attribute
+                    if (! $inside_attribute) {
+                        $inside_attribute = true;
+                        // remember the attribute`s declaration character (" or ')
+                        $start_attribute_character = $cur_char;
+                    } else {
+                        if ($cur_char == $start_attribute_character) {
+                            $inside_attribute = false;
+                            // unset attribute declaration character
+                            $start_attribute_character = false;
+                        }
+                    }
+                }
+            }
+        } // end for each character in $subject
+
+        return $cleaned;
+    }
+
+    /**
+     * Separates a string into items, similarly to explode
+     * Uses the '||' separator (which is standard in the mediawiki format)
+     * and ignores any instances of it inside markup tags
+     * Used in parsing buffer lines containing data cells
+     *
+     * @param string $text text to be split
+     *
+     * @return array
+     */
+    private function _explodeMarkup($text)
+    {
+        $separator = "||";
+        $placeholder = "\x00";
+
+        // Remove placeholder instances
+        $text = str_replace($placeholder, '', $text);
+
+        // Replace instances of the separator inside HTML-like
+        // tags with the placeholder
+        $cleaned = $this->_delimiterReplace("<", ">", $placeholder, $text);
+        // Explode, then put the replaced separators back in
+        $items = explode($separator, $cleaned);
+        foreach ($items as $i => $str) {
+            $items[$i] = str_replace($placeholder, $separator, $str);
+        }
+
+        return $items;
+    }
+
+
+    /* ~~~~~~~~~~~~~~~~~~~~ Getters and Setters ~~~~~~~~~~~~~~~~~~~~ */
+
+
+    /**
+     * Returns true if the table should be analyzed, false otherwise
+     *
+     * @return bool
+     */
+    private function _getAnalyze()
+    {
+        return $this->_analyze;
+    }
+
+    /**
+     * Sets to true if the table should be analyzed, false otherwise
+     *
+     * @param bool $analyze status
+     *
+     * @return void
+     */
+    private function _setAnalyze($analyze)
+    {
+        $this->_analyze = $analyze;
+    }
+}
\ No newline at end of file
diff --git a/phpmyadmin/libraries/plugins/import/ImportOds.class.php b/phpmyadmin/libraries/plugins/import/ImportOds.class.php
new file mode 100644
index 0000000..5a681e9
--- /dev/null
+++ b/phpmyadmin/libraries/plugins/import/ImportOds.class.php
@@ -0,0 +1,415 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * OpenDocument Spreadsheet import plugin for phpMyAdmin
+ *
+ * @todo    Pretty much everything
+ * @todo    Importing of accented characters seems to fail
+ * @package    PhpMyAdmin-Import
+ * @subpackage ODS
+ */
+if (! defined('PHPMYADMIN')) {
+    exit;
+}
+
+/**
+ * We need way to disable external XML entities processing.
+ */
+if (!function_exists('libxml_disable_entity_loader')) {
+    return;
+}
+
+/* Get the import interface */
+require_once 'libraries/plugins/ImportPlugin.class.php';
+
+/**
+ * Handles the import for the ODS format
+ *
+ * @package    PhpMyAdmin-Import
+ * @subpackage ODS
+ */
+class ImportOds extends ImportPlugin
+{
+    /**
+     * Constructor
+     */
+    public function __construct()
+    {
+        $this->setProperties();
+    }
+
+    /**
+     * Sets the import plugin properties.
+     * Called in the constructor.
+     *
+     * @return void
+     */
+    protected function setProperties()
+    {
+        $props = 'libraries/properties/';
+        include_once "$props/plugins/ImportPluginProperties.class.php";
+        include_once "$props/options/groups/OptionsPropertyRootGroup.class.php";
+        include_once "$props/options/groups/OptionsPropertyMainGroup.class.php";
+        include_once "$props/options/items/BoolPropertyItem.class.php";
+
+        $importPluginProperties = new ImportPluginProperties();
+        $importPluginProperties->setText('OpenDocument Spreadsheet');
+        $importPluginProperties->setExtension('ods');
+        $importPluginProperties->setOptionsText(__('Options'));
+
+        // create the root group that will be the options field for
+        // $importPluginProperties
+        // this will be shown as "Format specific options"
+        $importSpecificOptions = new OptionsPropertyRootGroup();
+        $importSpecificOptions->setName("Format Specific Options");
+
+        // general options main group
+        $generalOptions = new OptionsPropertyMainGroup();
+        $generalOptions->setName("general_opts");
+        // create primary items and add them to the group
+        $leaf = new BoolPropertyItem();
+        $leaf->setName("col_names");
+        $leaf->setText(
+            __(
+                'The first line of the file contains the table column names'
+                . ' <i>(if this is unchecked, the first line will become part'
+                . ' of the data)</i>'
+            )
+        );
+        $generalOptions->addProperty($leaf);
+        $leaf = new BoolPropertyItem();
+        $leaf->setName("empty_rows");
+        $leaf->setText(__('Do not import empty rows'));
+        $generalOptions->addProperty($leaf);
+        $leaf = new BoolPropertyItem();
+        $leaf->setName("recognize_percentages");
+        $leaf->setText(
+            __(
+                'Import percentages as proper decimals <i>(ex. 12.00% to .12)</i>'
+            )
+        );
+        $generalOptions->addProperty($leaf);
+        $leaf = new BoolPropertyItem();
+        $leaf->setName("recognize_currency");
+        $leaf->setText(__('Import currencies <i>(ex. $5.00 to 5.00)</i>'));
+        $generalOptions->addProperty($leaf);
+
+        // add the main group to the root group
+        $importSpecificOptions->addProperty($generalOptions);
+
+        // set the options for the import plugin property item
+        $importPluginProperties->setOptions($importSpecificOptions);
+        $this->properties = $importPluginProperties;
+    }
+
+    /**
+     * This method is called when any PluginManager to which the observer
+     * is attached calls PluginManager::notify()
+     *
+     * @param SplSubject $subject The PluginManager notifying the observer
+     *                            of an update.
+     *
+     * @return void
+     */
+    public function update (SplSubject $subject)
+    {
+    }
+
+    /**
+     * Handles the whole import logic
+     *
+     * @return void
+     */
+    public function doImport()
+    {
+        global $db, $error, $timeout_passed, $finished;
+
+        $i = 0;
+        $len = 0;
+        $buffer = "";
+
+        /**
+         * Read in the file via PMA_importGetNextChunk so that
+         * it can process compressed files
+         */
+        while (! ($finished && $i >= $len) && ! $error && ! $timeout_passed) {
+            $data = PMA_importGetNextChunk();
+            if ($data === false) {
+                /* subtract data we didn't handle yet and stop processing */
+                $offset -= strlen($buffer);
+                break;
+            } elseif ($data === true) {
+                /* Handle rest of buffer */
+            } else {
+                /* Append new data to buffer */
+                $buffer .= $data;
+                unset($data);
+            }
+        }
+
+        unset($data);
+
+        /**
+         * Disable loading of external XML entities.
+         */
+        libxml_disable_entity_loader();
+
+        /**
+         * Load the XML string
+         *
+         * The option LIBXML_COMPACT is specified because it can
+         * result in increased performance without the need to
+         * alter the code in any way. It's basically a freebee.
+         */
+        $xml = simplexml_load_string($buffer, "SimpleXMLElement", LIBXML_COMPACT);
+
+        unset($buffer);
+
+        if ($xml === false) {
+            $sheets = array();
+            $message = PMA_Message::error(
+                __(
+                    'The XML file specified was either malformed or incomplete.'
+                    . ' Please correct the issue and try again.'
+                )
+            );
+            $error = true;
+        } else {
+            $root = $xml->children('office', true)->{'body'}->{'spreadsheet'};
+            if (empty($root)) {
+                $sheets = array();
+                $message = PMA_Message::error(
+                    __('Could not parse OpenDocument Spreasheet!')
+                );
+                $error = true;
+            } else {
+                $sheets = $root->children('table', true);
+            }
+        }
+
+        $tables = array();
+
+        $max_cols = 0;
+
+        $row_count = 0;
+        $col_count = 0;
+        $col_names = array();
+
+        $tempRow = array();
+        $tempRows = array();
+        $rows = array();
+
+        /* Iterate over tables */
+        foreach ($sheets as $sheet) {
+            $col_names_in_first_row = isset($_REQUEST['ods_col_names']);
+
+            /* Iterate over rows */
+            foreach ($sheet as $row) {
+                $type = $row->getName();
+                if (! strcmp('table-row', $type)) {
+                    /* Iterate over columns */
+                    foreach ($row as $cell) {
+                        $text = $cell->children('text', true);
+                        $cell_attrs = $cell->attributes('office', true);
+
+                        if (count($text) != 0) {
+                            $attr = $cell->attributes('table', true);
+                            $num_repeat = (int) $attr['number-columns-repeated'];
+                            $num_iterations = $num_repeat ? $num_repeat : 1;
+
+                            for ($k = 0; $k < $num_iterations; $k++) {
+                                if ($_REQUEST['ods_recognize_percentages']
+                                    && ! strcmp(
+                                        'percentage',
+                                        $cell_attrs['value-type']
+                                    )
+                                ) {
+                                    $value = (double)$cell_attrs['value'];
+                                } elseif ($_REQUEST['ods_recognize_currency']
+                                    && !strcmp('currency', $cell_attrs['value-type'])
+                                ) {
+                                    $value = (double)$cell_attrs['value'];
+                                } else {
+                                    /* We need to concatenate all paragraphs */
+                                    $values = array();
+                                    foreach ($text as $paragraph) {
+                                        $values[] = (string)$paragraph;
+                                    }
+                                    $value = implode("\n", $values);
+                                }
+                                if (! $col_names_in_first_row) {
+                                    $tempRow[] = $value;
+                                } else {
+                                    $col_names[] = $value;
+                                }
+
+                                ++$col_count;
+                            }
+                        } else {
+                            /* Number of blank columns repeated */
+                            if ($col_count < count($row->children('table', true)) - 1
+                            ) {
+                                $attr = $cell->attributes('table', true);
+                                $num_null = (int)$attr['number-columns-repeated'];
+
+                                if ($num_null) {
+                                    if (! $col_names_in_first_row) {
+                                        for ($i = 0; $i < $num_null; ++$i) {
+                                            $tempRow[] = 'NULL';
+                                            ++$col_count;
+                                        }
+                                    } else {
+                                        for ($i = 0; $i < $num_null; ++$i) {
+                                            $col_names[] = PMA_getColumnAlphaName(
+                                                $col_count + 1
+                                            );
+                                            ++$col_count;
+                                        }
+                                    }
+                                } else {
+                                    if (! $col_names_in_first_row) {
+                                        $tempRow[] = 'NULL';
+                                    } else {
+                                        $col_names[] = PMA_getColumnAlphaName(
+                                            $col_count + 1
+                                        );
+                                    }
+
+                                    ++$col_count;
+                                }
+                            }
+                        }
+                    }
+
+                    /* Find the widest row */
+                    if ($col_count > $max_cols) {
+                        $max_cols = $col_count;
+                    }
+
+                    /* Don't include a row that is full of NULL values */
+                    if (! $col_names_in_first_row) {
+                        if ($_REQUEST['ods_empty_rows']) {
+                            foreach ($tempRow as $cell) {
+                                if (strcmp('NULL', $cell)) {
+                                    $tempRows[] = $tempRow;
+                                    break;
+                                }
+                            }
+                        } else {
+                            $tempRows[] = $tempRow;
+                        }
+                    }
+
+                    $col_count = 0;
+                    $col_names_in_first_row = false;
+                    $tempRow = array();
+                }
+            }
+
+            /* Skip over empty sheets */
+            if (count($tempRows) == 0 || count($tempRows[0]) == 0) {
+                $col_names = array();
+                $tempRow = array();
+                $tempRows = array();
+                continue;
+            }
+
+            /**
+             * Fill out each row as necessary to make
+             * every one exactly as wide as the widest
+             * row. This included column names.
+             */
+
+            /* Fill out column names */
+            for ($i = count($col_names); $i < $max_cols; ++$i) {
+                $col_names[] = PMA_getColumnAlphaName($i + 1);
+            }
+
+            /* Fill out all rows */
+            $num_rows = count($tempRows);
+            for ($i = 0; $i < $num_rows; ++$i) {
+                for ($j = count($tempRows[$i]); $j < $max_cols; ++$j) {
+                    $tempRows[$i][] = 'NULL';
+                }
+            }
+
+            /* Store the table name so we know where to place the row set */
+            $tbl_attr = $sheet->attributes('table', true);
+            $tables[] = array((string)$tbl_attr['name']);
+
+            /* Store the current sheet in the accumulator */
+            $rows[] = array((string)$tbl_attr['name'], $col_names, $tempRows);
+            $tempRows = array();
+            $col_names = array();
+            $max_cols = 0;
+        }
+
+        unset($tempRow);
+        unset($tempRows);
+        unset($col_names);
+        unset($sheets);
+        unset($xml);
+
+        /**
+         * Bring accumulated rows into the corresponding table
+         */
+        $num_tbls = count($tables);
+        for ($i = 0; $i < $num_tbls; ++$i) {
+            for ($j = 0; $j < count($rows); ++$j) {
+                if (! strcmp($tables[$i][TBL_NAME], $rows[$j][TBL_NAME])) {
+                    if (! isset($tables[$i][COL_NAMES])) {
+                        $tables[$i][] = $rows[$j][COL_NAMES];
+                    }
+
+                    $tables[$i][ROWS] = $rows[$j][ROWS];
+                }
+            }
+        }
+
+        /* No longer needed */
+        unset($rows);
+
+        /* Obtain the best-fit MySQL types for each column */
+        $analyses = array();
+
+        $len = count($tables);
+        for ($i = 0; $i < $len; ++$i) {
+            $analyses[] = PMA_analyzeTable($tables[$i]);
+        }
+
+        /**
+         * string $db_name (no backquotes)
+         *
+         * array $table = array(table_name, array() column_names, array()() rows)
+         * array $tables = array of "$table"s
+         *
+         * array $analysis = array(array() column_types, array() column_sizes)
+         * array $analyses = array of "$analysis"s
+         *
+         * array $create = array of SQL strings
+         *
+         * array $options = an associative array of options
+         */
+
+        /* Set database name to the currently selected one, if applicable */
+        if (strlen($db)) {
+            $db_name = $db;
+            $options = array('create_db' => false);
+        } else {
+            $db_name = 'ODS_DB';
+            $options = null;
+        }
+
+        /* Non-applicable parameters */
+        $create = null;
+
+        /* Created and execute necessary SQL statements from data */
+        PMA_buildSQL($db_name, $tables, $analyses, $create, $options);
+
+        unset($tables);
+        unset($analyses);
+
+        /* Commit any possible data in buffers */
+        PMA_importRunQuery();
+    }
+}
diff --git a/phpmyadmin/libraries/plugins/import/ImportShp.class.php b/phpmyadmin/libraries/plugins/import/ImportShp.class.php
new file mode 100644
index 0000000..39af954
--- /dev/null
+++ b/phpmyadmin/libraries/plugins/import/ImportShp.class.php
@@ -0,0 +1,342 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * ESRI Shape file import plugin for phpMyAdmin
+ *
+ * @package    PhpMyAdmin-Import
+ * @subpackage ESRI_Shape
+ */
+if (! defined('PHPMYADMIN')) {
+    exit;
+}
+
+// Drizzle does not support GIS data types
+if (PMA_DRIZZLE) {
+    return;
+}
+
+/* Get the import interface*/
+require_once 'libraries/plugins/ImportPlugin.class.php';
+/* Get the ShapeFile class */
+require_once 'libraries/bfShapeFiles/ShapeFile.lib.php';
+require_once 'libraries/plugins/import/ShapeFile.class.php';
+require_once 'libraries/plugins/import/ShapeRecord.class.php';
+
+/**
+ * Handles the import for ESRI Shape files
+ *
+ * @package    PhpMyAdmin-Import
+ * @subpackage ESRI_Shape
+ */
+class ImportShp extends ImportPlugin
+{
+    /**
+     * Constructor
+     */
+    public function __construct()
+    {
+        $this->setProperties();
+    }
+
+    /**
+     * Sets the import plugin properties.
+     * Called in the constructor.
+     *
+     * @return void
+     */
+    protected function setProperties()
+    {
+        $props = 'libraries/properties/';
+        include_once "$props/plugins/ImportPluginProperties.class.php";
+
+        $importPluginProperties = new ImportPluginProperties();
+        $importPluginProperties->setText(__('ESRI Shape File'));
+        $importPluginProperties->setExtension('shp');
+        $importPluginProperties->setOptions(array());
+        $importPluginProperties->setOptionsText(__('Options'));
+
+        $this->properties = $importPluginProperties;
+    }
+
+    /**
+     * This method is called when any PluginManager to which the observer
+     * is attached calls PluginManager::notify()
+     *
+     * @param SplSubject $subject The PluginManager notifying the observer
+     *                            of an update.
+     *
+     * @return void
+     */
+    public function update (SplSubject $subject)
+    {
+    }
+
+    /**
+     * Handles the whole import logic
+     *
+     * @return void
+     */
+    public function doImport()
+    {
+        global $db, $error, $finished, $compression,
+            $import_file, $local_import_file;
+
+        if ((int) ini_get('memory_limit') < 512) {
+            @ini_set('memory_limit', '512M');
+        }
+        @set_time_limit(300);
+
+        $GLOBALS['finished'] = false;
+        $buffer = '';
+        $eof = false;
+
+
+        $shp = new PMA_ShapeFile(1);
+        // If the zip archive has more than one file,
+        // get the correct content to the buffer from .shp file.
+        if ($compression == 'application/zip'
+            && PMA_getNoOfFilesInZip($import_file) > 1
+        ) {
+            $zip_content =  PMA_getZipContents($import_file, '/^.*\.shp$/i');
+            $GLOBALS['import_text'] = $zip_content['data'];
+        }
+
+        $temp_dbf_file = false;
+        // We need dbase extension to handle .dbf file
+        if (extension_loaded('dbase')) {
+            // If we can extract the zip archive to 'TempDir'
+            // and use the files in it for import
+            if ($compression == 'application/zip'
+                && ! empty($GLOBALS['cfg']['TempDir'])
+                && is_writable($GLOBALS['cfg']['TempDir'])
+            ) {
+                $dbf_file_name = PMA_findFileFromZipArchive(
+                    '/^.*\.dbf$/i', $import_file
+                );
+                // If the corresponding .dbf file is in the zip archive
+                if ($dbf_file_name) {
+                    // Extract the .dbf file and point to it.
+                    $extracted =  PMA_zipExtract(
+                        $import_file,
+                        realpath($GLOBALS['cfg']['TempDir']),
+                        array($dbf_file_name)
+                    );
+                    if ($extracted) {
+                        $dbf_file_path = realpath($GLOBALS['cfg']['TempDir'])
+                            . (PMA_IS_WINDOWS ? '\\' : '/') . $dbf_file_name;
+                        $temp_dbf_file = true;
+                        // Replace the .dbf with .*, as required
+                        // by the bsShapeFiles library.
+                        $file_name = substr(
+                            $dbf_file_path, 0, strlen($dbf_file_path) - 4
+                        ) . '.*';
+                        $shp->FileName = $file_name;
+                    }
+                }
+            } elseif (! empty($local_import_file)
+                && ! empty($GLOBALS['cfg']['UploadDir'])
+                && $compression == 'none'
+            ) {
+                // If file is in UploadDir, use .dbf file in the same UploadDir
+                // to load extra data.
+                // Replace the .shp with .*,
+                // so the bsShapeFiles library correctly locates .dbf file.
+                $file_name = substr($import_file, 0, strlen($import_file) - 4)
+                    . '.*';
+                $shp->FileName = $file_name;
+            }
+        }
+
+        // Load data
+        $shp->loadFromFile('');
+        if ($shp->lastError != "") {
+            $error = true;
+            $message = PMA_Message::error(
+                __('There was an error importing the ESRI shape file: "%s".')
+            );
+            $message->addParam($shp->lastError);
+            return;
+        }
+
+        // Delete the .dbf file extracted to 'TempDir'
+        if ($temp_dbf_file
+            && isset($dbf_file_path)
+            && file_exists($dbf_file_path)
+        ) {
+            unlink($dbf_file_path);
+        }
+
+        $esri_types = array(
+            0  => 'Null Shape',
+            1  => 'Point',
+            3  => 'PolyLine',
+            5  => 'Polygon',
+            8  => 'MultiPoint',
+            11 => 'PointZ',
+            13 => 'PolyLineZ',
+            15 => 'PolygonZ',
+            18 => 'MultiPointZ',
+            21 => 'PointM',
+            23 => 'PolyLineM',
+            25 => 'PolygonM',
+            28 => 'MultiPointM',
+            31 => 'MultiPatch',
+        );
+
+        switch ($shp->shapeType) {
+        // ESRI Null Shape
+        case 0:
+            break;
+        // ESRI Point
+        case 1:
+            $gis_type = 'point';
+            break;
+        // ESRI PolyLine
+        case 3:
+            $gis_type = 'multilinestring';
+            break;
+        // ESRI Polygon
+        case 5:
+            $gis_type = 'multipolygon';
+            break;
+        // ESRI MultiPoint
+        case 8:
+            $gis_type = 'multipoint';
+            break;
+        default:
+            $error = true;
+            if (! isset($esri_types[$shp->shapeType])) {
+                $message = PMA_Message::error(
+                    __(
+                        'You tried to import an invalid file or the imported file'
+                        . ' contains invalid data'
+                    )
+                );
+            } else {
+                $message = PMA_Message::error(
+                    __('MySQL Spatial Extension does not support ESRI type "%s".')
+                );
+                $message->addParam($param);
+            }
+            return;
+        }
+
+        if (isset($gis_type)) {
+            include_once './libraries/gis/pma_gis_factory.php';
+            $gis_obj =  PMA_GIS_Factory::factory($gis_type);
+        } else {
+            $gis_obj = null;
+        }
+
+        $num_rows = count($shp->records);
+        // If .dbf file is loaded, the number of extra data columns
+        $num_data_cols = isset($shp->DBFHeader) ? count($shp->DBFHeader) : 0;
+
+        $rows = array();
+        $col_names = array();
+        if ($num_rows != 0) {
+            foreach ($shp->records as $record) {
+                $tempRow = array();
+                if ($gis_obj == null) {
+                    $tempRow[] = null;
+                } else {
+                    $tempRow[] = "GeomFromText('"
+                        . $gis_obj->getShape($record->SHPData) . "')";
+                }
+
+                if (isset($shp->DBFHeader)) {
+                    foreach ($shp->DBFHeader as $c) {
+                        $cell = trim($record->DBFData[$c[0]]);
+
+                        if (! strcmp($cell, '')) {
+                            $cell = 'NULL';
+                        }
+
+                        $tempRow[] = $cell;
+                    }
+                }
+                $rows[] = $tempRow;
+            }
+        }
+
+        if (count($rows) == 0) {
+            $error = true;
+            $message = PMA_Message::error(
+                __('The imported file does not contain any data')
+            );
+            return;
+        }
+
+        // Column names for spatial column and the rest of the columns,
+        // if they are available
+        $col_names[] = 'SPATIAL';
+        for ($n = 0; $n < $num_data_cols; $n++) {
+            $col_names[] = $shp->DBFHeader[$n][0];
+        }
+
+        // Set table name based on the number of tables
+        if (strlen($db)) {
+            $result = PMA_DBI_fetch_result('SHOW TABLES');
+            $table_name = 'TABLE '.(count($result) + 1);
+        } else {
+            $table_name = 'TBL_NAME';
+        }
+        $tables = array(array($table_name, $col_names, $rows));
+
+        // Use data from shape file to chose best-fit MySQL types for each column
+        $analyses = array();
+        $analyses[] = PMA_analyzeTable($tables[0]);
+
+        $table_no = 0; $spatial_col = 0;
+        $analyses[$table_no][TYPES][$spatial_col] = GEOMETRY;
+        $analyses[$table_no][FORMATTEDSQL][$spatial_col] = true;
+
+        // Set database name to the currently selected one, if applicable
+        if (strlen($db)) {
+            $db_name = $db;
+            $options = array('create_db' => false);
+        } else {
+            $db_name = 'SHP_DB';
+            $options = null;
+        }
+
+        // Created and execute necessary SQL statements from data
+        $null_param = null;
+        PMA_buildSQL($db_name, $tables, $analyses, $null_param, $options);
+
+        unset($tables);
+        unset($analyses);
+
+        $finished = true;
+        $error = false;
+
+        // Commit any possible data in buffers
+        PMA_importRunQuery();
+    }
+
+    /**
+     * Returns specified number of bytes from the buffer.
+     * Buffer automatically fetches next chunk of data when the buffer
+     * falls short.
+     * Sets $eof when $GLOBALS['finished'] is set and the buffer falls short.
+     *
+     * @param int $length number of bytes
+     *
+     * @return string
+     */
+    public static function readFromBuffer($length)
+    {
+        global $buffer, $eof;
+
+        if (strlen($buffer) < $length) {
+            if ($GLOBALS['finished']) {
+                $eof = true;
+            } else {
+                $buffer .= PMA_importGetNextChunk();
+            }
+        }
+        $result = substr($buffer, 0, $length);
+        $buffer = substr($buffer, $length);
+        return $result;
+    }
+}
\ No newline at end of file
diff --git a/phpmyadmin/libraries/plugins/import/ImportSql.class.php b/phpmyadmin/libraries/plugins/import/ImportSql.class.php
new file mode 100644
index 0000000..146485a
--- /dev/null
+++ b/phpmyadmin/libraries/plugins/import/ImportSql.class.php
@@ -0,0 +1,440 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * SQL import plugin for phpMyAdmin
+ *
+ * @package    PhpMyAdmin-Import
+ * @subpackage SQL
+ */
+if (! defined('PHPMYADMIN')) {
+    exit;
+}
+
+/* Get the import interface */
+require_once 'libraries/plugins/ImportPlugin.class.php';
+
+/**
+ * Handles the import for the SQL format
+ *
+ * @package    PhpMyAdmin-Import
+ * @subpackage SQL
+ */
+class ImportSql extends ImportPlugin
+{
+    /**
+     * Constructor
+     */
+    public function __construct()
+    {
+        $this->setProperties();
+    }
+
+    /**
+     * Sets the import plugin properties.
+     * Called in the constructor.
+     *
+     * @return void
+     */
+    protected function setProperties()
+    {
+        $props = 'libraries/properties/';
+        include_once "$props/plugins/ImportPluginProperties.class.php";
+        include_once "$props/options/groups/OptionsPropertyRootGroup.class.php";
+        include_once "$props/options/groups/OptionsPropertyMainGroup.class.php";
+        include_once "$props/options/items/SelectPropertyItem.class.php";
+        include_once "$props/options/items/BoolPropertyItem.class.php";
+
+        $importPluginProperties = new ImportPluginProperties();
+        $importPluginProperties->setText('SQL');
+        $importPluginProperties->setExtension('sql');
+        $importPluginProperties->setOptionsText(__('Options'));
+
+        $compats = PMA_DBI_getCompatibilities();
+        if (count($compats) > 0) {
+            $values = array();
+            foreach ($compats as $val) {
+                $values[$val] = $val;
+            }
+
+            // create the root group that will be the options field for
+            // $importPluginProperties
+            // this will be shown as "Format specific options"
+            $importSpecificOptions = new OptionsPropertyRootGroup();
+            $importSpecificOptions->setName("Format Specific Options");
+
+            // general options main group
+            $generalOptions = new OptionsPropertyMainGroup();
+            $generalOptions->setName("general_opts");
+            // create primary items and add them to the group
+            $leaf = new SelectPropertyItem();
+            $leaf->setName("compatibility");
+            $leaf->setText(__('SQL compatibility mode:'));
+            $leaf->setValues($values);
+            $leaf->setDoc(
+                array(
+                    'manual_MySQL_Database_Administration',
+                    'Server_SQL_mode',
+                )
+            );
+            $generalOptions->addProperty($leaf);
+            $leaf = new BoolPropertyItem();
+            $leaf->setName("no_auto_value_on_zero");
+            $leaf->setText(
+                __('Do not use <code>AUTO_INCREMENT</code> for zero values')
+            );
+            $leaf->setDoc(
+                array(
+                    'manual_MySQL_Database_Administration',
+                    'Server_SQL_mode',
+                    'sqlmode_no_auto_value_on_zero'
+                )
+            );
+            $generalOptions->addProperty($leaf);
+
+            // add the main group to the root group
+            $importSpecificOptions->addProperty($generalOptions);
+            // set the options for the import plugin property item
+            $importPluginProperties->setOptions($importSpecificOptions);
+        }
+
+        $this->properties = $importPluginProperties;
+    }
+
+    /**
+     * This method is called when any PluginManager to which the observer
+     * is attached calls PluginManager::notify()
+     *
+     * @param SplSubject $subject The PluginManager notifying the observer
+     *                            of an update.
+     *
+     * @return void
+     */
+    public function update (SplSubject $subject)
+    {
+    }
+
+    /**
+     * Handles the whole import logic
+     *
+     * @param array &$sql_data 2-element array with sql data
+     *
+     * @return void
+     */
+    public function doImport(&$sql_data = array())
+    {
+        global $error, $timeout_passed;
+
+        $buffer = '';
+        // Defaults for parser
+        $sql = '';
+        $start_pos = 0;
+        $i = 0;
+        $len= 0;
+        $big_value = 2147483647;
+        // include the space because it's mandatory
+        $delimiter_keyword = 'DELIMITER ';
+        $length_of_delimiter_keyword = strlen($delimiter_keyword);
+
+        if (isset($_POST['sql_delimiter'])) {
+            $sql_delimiter = $_POST['sql_delimiter'];
+        } else {
+            $sql_delimiter = ';';
+        }
+
+        // Handle compatibility options
+        $sql_modes = array();
+        if (isset($_REQUEST['sql_compatibility'])
+            && 'NONE' != $_REQUEST['sql_compatibility']
+        ) {
+            $sql_modes[] = $_REQUEST['sql_compatibility'];
+        }
+        if (isset($_REQUEST['sql_no_auto_value_on_zero'])) {
+            $sql_modes[] = 'NO_AUTO_VALUE_ON_ZERO';
+        }
+        if (count($sql_modes) > 0) {
+            PMA_DBI_try_query('SET SQL_MODE="' . implode(',', $sql_modes) . '"');
+        }
+        unset($sql_modes);
+
+        /**
+         * will be set in PMA_importGetNextChunk()
+         *
+         * @global boolean $GLOBALS['finished']
+         */
+        $GLOBALS['finished'] = false;
+
+        while (! ($GLOBALS['finished'] && $i >= $len)
+            && ! $error
+            && ! $timeout_passed
+        ) {
+            $data = PMA_importGetNextChunk();
+            if ($data === false) {
+                // subtract data we didn't handle yet and stop processing
+                $offset -= strlen($buffer);
+                break;
+            } elseif ($data === true) {
+                // Handle rest of buffer
+            } else {
+                // Append new data to buffer
+                $buffer .= $data;
+                // free memory
+                unset($data);
+                // Do not parse string when we're not at the end
+                // and don't have ; inside
+                if ((strpos($buffer, $sql_delimiter, $i) === false)
+                    && ! $GLOBALS['finished']
+                ) {
+                    continue;
+                }
+            }
+            // Current length of our buffer
+            $len = strlen($buffer);
+
+            // Grab some SQL queries out of it
+            while ($i < $len) {
+                $found_delimiter = false;
+                // Find first interesting character
+                $old_i = $i;
+                // this is about 7 times faster that looking for each sequence i
+                // one by one with strpos()
+                $match = preg_match(
+                    '/(\'|"|#|-- |\/\*|`|(?i)(?<![A-Z0-9_])'
+                    . $delimiter_keyword . ')/',
+                    $buffer,
+                    $matches,
+                    PREG_OFFSET_CAPTURE,
+                    $i
+                );
+                if ($match) {
+                    // in $matches, index 0 contains the match for the complete
+                    // expression but we don't use it
+                    $first_position = $matches[1][1];
+                } else {
+                    $first_position = $big_value;
+                }
+                /**
+                 * @todo we should not look for a delimiter that might be
+                 *       inside quotes (or even double-quotes)
+                 */
+                // the cost of doing this one with preg_match() would be too high
+                $first_sql_delimiter = strpos($buffer, $sql_delimiter, $i);
+                if ($first_sql_delimiter === false) {
+                    $first_sql_delimiter = $big_value;
+                } else {
+                    $found_delimiter = true;
+                }
+
+                // set $i to the position of the first quote,
+                // comment.start or delimiter found
+                $i = min($first_position, $first_sql_delimiter);
+
+                if ($i == $big_value) {
+                    // none of the above was found in the string
+
+                    $i = $old_i;
+                    if (! $GLOBALS['finished']) {
+                        break;
+                    }
+                    // at the end there might be some whitespace...
+                    if (trim($buffer) == '') {
+                        $buffer = '';
+                        $len = 0;
+                        break;
+                    }
+                    // We hit end of query, go there!
+                    $i = strlen($buffer) - 1;
+                }
+
+                // Grab current character
+                $ch = $buffer[$i];
+
+                // Quotes
+                if (strpos('\'"`', $ch) !== false) {
+                    $quote = $ch;
+                    $endq = false;
+                    while (! $endq) {
+                        // Find next quote
+                        $pos = strpos($buffer, $quote, $i + 1);
+                        /*
+                         * Behave same as MySQL and accept end of query as end
+                         * of backtick.
+                         * I know this is sick, but MySQL behaves like this:
+                         *
+                         * SELECT * FROM `table
+                         *
+                         * is treated like
+                         *
+                         * SELECT * FROM `table`
+                         */
+                        if ($pos === false && $quote == '`' && $found_delimiter) {
+                            $pos = $first_sql_delimiter - 1;
+                        } elseif ($pos === false) { // No quote? Too short string
+                            // We hit end of string => unclosed quote,
+                            // but we handle it as end of query
+                            if ($GLOBALS['finished']) {
+                                $endq = true;
+                                $i = $len - 1;
+                            }
+                            $found_delimiter = false;
+                            break;
+                        }
+                        // Was not the quote escaped?
+                        $j = $pos - 1;
+                        while ($buffer[$j] == '\\') {
+                            $j--;
+                        }
+                        // Even count means it was not escaped
+                        $endq = (((($pos - 1) - $j) % 2) == 0);
+                        // Skip the string
+                        $i = $pos;
+
+                        if ($first_sql_delimiter < $pos) {
+                            $found_delimiter = false;
+                        }
+                    }
+                    if (! $endq) {
+                        break;
+                    }
+                    $i++;
+                    // Aren't we at the end?
+                    if ($GLOBALS['finished'] && $i == $len) {
+                        $i--;
+                    } else {
+                        continue;
+                    }
+                }
+
+                // Not enough data to decide
+                if ((($i == ($len - 1) && ($ch == '-' || $ch == '/'))
+                    || ($i == ($len - 2) && (($ch == '-' && $buffer[$i + 1] == '-')
+                    || ($ch == '/' && $buffer[$i + 1] == '*'))))
+                    && ! $GLOBALS['finished']
+                ) {
+                    break;
+                }
+
+                // Comments
+                if ($ch == '#'
+                    || ($i < ($len - 1) && $ch == '-' && $buffer[$i + 1] == '-'
+                    && (($i < ($len - 2) && $buffer[$i + 2] <= ' ')
+                    || ($i == ($len - 1)  && $GLOBALS['finished'])))
+                    || ($i < ($len - 1) && $ch == '/' && $buffer[$i + 1] == '*')
+                ) {
+                    // Copy current string to SQL
+                    if ($start_pos != $i) {
+                        $sql .= substr($buffer, $start_pos, $i - $start_pos);
+                    }
+                    // Skip the rest
+                    $start_of_comment = $i;
+                    // do not use PHP_EOL here instead of "\n", because the export
+                    // file might have been produced on a different system
+                    $i = strpos($buffer, $ch == '/' ? '*/' : "\n", $i);
+                    // didn't we hit end of string?
+                    if ($i === false) {
+                        if ($GLOBALS['finished']) {
+                            $i = $len - 1;
+                        } else {
+                            break;
+                        }
+                    }
+                    // Skip *
+                    if ($ch == '/') {
+                        $i++;
+                    }
+                    // Skip last char
+                    $i++;
+                    // We need to send the comment part in case we are defining
+                    // a procedure or function and comments in it are valuable
+                    $sql .= substr(
+                        $buffer,
+                        $start_of_comment,
+                        $i - $start_of_comment
+                    );
+                    // Next query part will start here
+                    $start_pos = $i;
+                    // Aren't we at the end?
+                    if ($i == $len) {
+                        $i--;
+                    } else {
+                        continue;
+                    }
+                }
+                // Change delimiter, if redefined, and skip it
+                // (don't send to server!)
+                if (($i + $length_of_delimiter_keyword < $len)
+                    && strtoupper(
+                        substr($buffer, $i, $length_of_delimiter_keyword)
+                    ) == $delimiter_keyword
+                ) {
+                     // look for EOL on the character immediately after 'DELIMITER '
+                     // (see previous comment about PHP_EOL)
+                    $new_line_pos = strpos(
+                        $buffer,
+                        "\n",
+                        $i + $length_of_delimiter_keyword
+                    );
+                    // it might happen that there is no EOL
+                    if (false === $new_line_pos) {
+                        $new_line_pos = $len;
+                    }
+                    $sql_delimiter = substr(
+                        $buffer,
+                        $i + $length_of_delimiter_keyword,
+                        $new_line_pos - $i - $length_of_delimiter_keyword
+                    );
+                    $i = $new_line_pos + 1;
+                    // Next query part will start here
+                    $start_pos = $i;
+                    continue;
+                }
+
+                // End of SQL
+                if ($found_delimiter
+                    || ($GLOBALS['finished']
+                    && ($i == $len - 1))
+                ) {
+                    $tmp_sql = $sql;
+                    if ($start_pos < $len) {
+                        $length_to_grab = $i - $start_pos;
+
+                        if (! $found_delimiter) {
+                            $length_to_grab++;
+                        }
+                        $tmp_sql .= substr($buffer, $start_pos, $length_to_grab);
+                        unset($length_to_grab);
+                    }
+                    // Do not try to execute empty SQL
+                    if (! preg_match('/^([\s]*;)*$/', trim($tmp_sql))) {
+                        $sql = $tmp_sql;
+                        PMA_importRunQuery(
+                            $sql,
+                            substr($buffer, 0, $i + strlen($sql_delimiter)),
+                            false,
+                            $sql_data
+                        );
+                        $buffer = substr($buffer, $i + strlen($sql_delimiter));
+                        // Reset parser:
+                        $len = strlen($buffer);
+                        $sql = '';
+                        $i = 0;
+                        $start_pos = 0;
+                        // Any chance we will get a complete query?
+                        //if ((strpos($buffer, ';') === false)
+                        //&& ! $GLOBALS['finished']) {
+                        if (strpos($buffer, $sql_delimiter) === false
+                            && ! $GLOBALS['finished']
+                        ) {
+                            break;
+                        }
+                    } else {
+                        $i++;
+                        $start_pos = $i;
+                    }
+                }
+            } // End of parser loop
+        } // End of import loop
+        // Commit any possible data in buffers
+        PMA_importRunQuery('', substr($buffer, 0, $len), false, $sql_data);
+        PMA_importRunQuery('', '', false, $sql_data);
+    }
+}
\ No newline at end of file
diff --git a/phpmyadmin/libraries/plugins/import/ImportXml.class.php b/phpmyadmin/libraries/plugins/import/ImportXml.class.php
new file mode 100644
index 0000000..9c0e999
--- /dev/null
+++ b/phpmyadmin/libraries/plugins/import/ImportXml.class.php
@@ -0,0 +1,379 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * XML import plugin for phpMyAdmin
+ *
+ * @todo       Improve efficiency
+ * @package    PhpMyAdmin-Import
+ * @subpackage XML
+ */
+
+if (! defined('PHPMYADMIN')) {
+    exit;
+}
+
+/**
+ * We need way to disable external XML entities processing.
+ */
+if (!function_exists('libxml_disable_entity_loader')) {
+    return;
+}
+
+/* Get the import interface */
+require_once 'libraries/plugins/ImportPlugin.class.php';
+
+/**
+ * Handles the import for the XML format
+ *
+ * @package    PhpMyAdmin-Import
+ * @subpackage XML
+ */
+class ImportXml extends ImportPlugin
+{
+    /**
+     * Constructor
+     */
+    public function __construct()
+    {
+        $this->setProperties();
+    }
+
+    /**
+     * Sets the import plugin properties.
+     * Called in the constructor.
+     *
+     * @return void
+     */
+    protected function setProperties()
+    {
+        $props = 'libraries/properties/';
+        include_once "$props/plugins/ImportPluginProperties.class.php";
+
+        $importPluginProperties = new ImportPluginProperties();
+        $importPluginProperties->setText(__('XML'));
+        $importPluginProperties->setExtension('xml');
+        $importPluginProperties->setMimeType('text/xml');
+        $importPluginProperties->setOptions(array());
+        $importPluginProperties->setOptionsText(__('Options'));
+
+        $this->properties = $importPluginProperties;
+    }
+
+    /**
+     * This method is called when any PluginManager to which the observer
+     * is attached calls PluginManager::notify()
+     *
+     * @param SplSubject $subject The PluginManager notifying the observer
+     *                            of an update.
+     *
+     * @return void
+     */
+    public function update (SplSubject $subject)
+    {
+    }
+
+    /**
+     * Handles the whole import logic
+     *
+     * @return void
+     */
+    public function doImport()
+    {
+        global $error, $timeout_passed, $finished, $db;
+
+        $i = 0;
+        $len = 0;
+        $buffer = "";
+
+        /**
+         * Read in the file via PMA_importGetNextChunk so that
+         * it can process compressed files
+         */
+        while (! ($finished && $i >= $len) && ! $error && ! $timeout_passed) {
+            $data = PMA_importGetNextChunk();
+            if ($data === false) {
+                /* subtract data we didn't handle yet and stop processing */
+                $offset -= strlen($buffer);
+                break;
+            } elseif ($data === true) {
+                /* Handle rest of buffer */
+            } else {
+                /* Append new data to buffer */
+                $buffer .= $data;
+                unset($data);
+            }
+        }
+
+        unset($data);
+
+        /**
+         * Disable loading of external XML entities.
+         */
+        libxml_disable_entity_loader();
+
+        /**
+         * Load the XML string
+         *
+         * The option LIBXML_COMPACT is specified because it can
+         * result in increased performance without the need to
+         * alter the code in any way. It's basically a freebee.
+         */
+        $xml = simplexml_load_string($buffer, "SimpleXMLElement", LIBXML_COMPACT);
+
+        unset($buffer);
+
+        /**
+         * The XML was malformed
+         */
+        if ($xml === false) {
+            PMA_Message::error(
+                __(
+                    'The XML file specified was either malformed or incomplete.'
+                    . ' Please correct the issue and try again.'
+                )
+            )->display();
+            unset($xml);
+            $GLOBALS['finished'] = false;
+            return;
+        }
+
+        /**
+         * Table accumulator
+         */
+        $tables = array();
+        /**
+         * Row accumulator
+         */
+        $rows = array();
+
+        /**
+         * Temp arrays
+         */
+        $tempRow = array();
+        $tempCells = array();
+
+        /**
+         * CREATE code included (by default: no)
+         */
+        $struct_present = false;
+
+        /**
+         * Analyze the data in each table
+         */
+        $namespaces = $xml->getNameSpaces(true);
+
+        /**
+         * Get the database name, collation and charset
+         */
+        $db_attr = $xml->children($namespaces['pma'])
+            ->{'structure_schemas'}->{'database'};
+
+        if ($db_attr instanceof SimpleXMLElement) {
+            $db_attr = $db_attr->attributes();
+            $db_name = (string)$db_attr['name'];
+            $collation = (string)$db_attr['collation'];
+            $charset = (string)$db_attr['charset'];
+        } else {
+            /**
+             * If the structure section is not present
+             * get the database name from the data section
+             */
+            $db_attr = $xml->children()->attributes();
+            $db_name = (string)$db_attr['name'];
+            $collation = null;
+            $charset = null;
+        }
+
+        /**
+         * The XML was malformed
+         */
+        if ($db_name === null) {
+            PMA_Message::error(
+                __(
+                    'The XML file specified was either malformed or incomplete.'
+                    . ' Please correct the issue and try again.'
+                )
+            )->display();
+            unset($xml);
+            $GLOBALS['finished'] = false;
+            return;
+        }
+
+        /**
+         * Retrieve the structure information
+         */
+        if (isset($namespaces['pma'])) {
+            /**
+             * Get structures for all tables
+             */
+            $struct = $xml->children($namespaces['pma']);
+
+            $create = array();
+
+            foreach ($struct as $tier1 => $val1) {
+                foreach ($val1 as $tier2 => $val2) {
+                    // Need to select the correct database for the creation of
+                    // tables, views, triggers, etc.
+                    /**
+                     * @todo    Generating a USE here blocks importing of a table
+                     *          into another database.
+                     */
+                    $attrs = $val2->attributes();
+                    $create[] = "USE "
+                        . PMA_Util::backquote(
+                            $attrs["name"]
+                        );
+
+                    foreach ($val2 as $val3) {
+                        /**
+                         * Remove the extra cosmetic spacing
+                         */
+                        $val3 = str_replace("                ", "", (string)$val3);
+                        $create[] = $val3;
+                    }
+                }
+            }
+
+            $struct_present = true;
+        }
+
+        /**
+         * Move down the XML tree to the actual data
+         */
+        $xml = $xml->children()->children();
+
+        $data_present = false;
+
+        /**
+         * Only attempt to analyze/collect data if there is data present
+         */
+        if ($xml && @count($xml->children())) {
+            $data_present = true;
+
+            /**
+             * Process all database content
+             */
+            foreach ($xml as $k1 => $v1) {
+                $tbl_attr = $v1->attributes();
+
+                $isInTables = false;
+                for ($i = 0; $i < count($tables); ++$i) {
+                    if (! strcmp($tables[$i][TBL_NAME], (string)$tbl_attr['name'])) {
+                        $isInTables = true;
+                        break;
+                    }
+                }
+
+                if ($isInTables == false) {
+                    $tables[] = array((string)$tbl_attr['name']);
+                }
+
+                foreach ($v1 as $k2 => $v2) {
+                    $row_attr = $v2->attributes();
+                    if (! array_search((string)$row_attr['name'], $tempRow)) {
+                        $tempRow[] = (string)$row_attr['name'];
+                    }
+                    $tempCells[] = (string)$v2;
+                }
+
+                $rows[] = array((string)$tbl_attr['name'], $tempRow, $tempCells);
+
+                $tempRow = array();
+                $tempCells = array();
+            }
+
+            unset($tempRow);
+            unset($tempCells);
+            unset($xml);
+
+            /**
+             * Bring accumulated rows into the corresponding table
+             */
+            $num_tbls = count($tables);
+            for ($i = 0; $i < $num_tbls; ++$i) {
+                for ($j = 0; $j < count($rows); ++$j) {
+                    if (! strcmp($tables[$i][TBL_NAME], $rows[$j][TBL_NAME])) {
+                        if (! isset($tables[$i][COL_NAMES])) {
+                            $tables[$i][] = $rows[$j][COL_NAMES];
+                        }
+
+                        $tables[$i][ROWS][] = $rows[$j][ROWS];
+                    }
+                }
+            }
+
+            unset($rows);
+
+            if (! $struct_present) {
+                $analyses = array();
+
+                $len = count($tables);
+                for ($i = 0; $i < $len; ++$i) {
+                    $analyses[] = PMA_analyzeTable($tables[$i]);
+                }
+            }
+        }
+
+        unset($xml);
+        unset($tempRows);
+        unset($tempCells);
+        unset($rows);
+
+        /**
+         * Only build SQL from data if there is data present
+         */
+        if ($data_present) {
+            /**
+             * Set values to NULL if they were not present
+             * to maintain PMA_buildSQL() call integrity
+             */
+            if (! isset($analyses)) {
+                $analyses = null;
+                if (! $struct_present) {
+                    $create = null;
+                }
+            }
+        }
+
+        /**
+         * string $db_name (no backquotes)
+         *
+         * array $table = array(table_name, array() column_names, array()() rows)
+         * array $tables = array of "$table"s
+         *
+         * array $analysis = array(array() column_types, array() column_sizes)
+         * array $analyses = array of "$analysis"s
+         *
+         * array $create = array of SQL strings
+         *
+         * array $options = an associative array of options
+         */
+
+        /* Set database name to the currently selected one, if applicable */
+        if (strlen($db)) {
+            /* Override the database name in the XML file, if one is selected */
+            $db_name = $db;
+            $options = array('create_db' => false);
+        } else {
+            if ($db_name === null) {
+                $db_name = 'XML_DB';
+            }
+
+            /* Set database collation/charset */
+            $options = array(
+                'db_collation' => $collation,
+                'db_charset'   => $charset,
+            );
+        }
+
+        /* Created and execute necessary SQL statements from data */
+        PMA_buildSQL($db_name, $tables, $analyses, $create, $options);
+
+        unset($analyses);
+        unset($tables);
+        unset($create);
+
+        /* Commit any possible data in buffers */
+        PMA_importRunQuery();
+    }
+}
\ No newline at end of file
diff --git a/phpmyadmin/libraries/plugins/import/README b/phpmyadmin/libraries/plugins/import/README
new file mode 100644
index 0000000..76d2b07
--- /dev/null
+++ b/phpmyadmin/libraries/plugins/import/README
@@ -0,0 +1,173 @@
+This directory holds import plugins for phpMyAdmin. Any new plugin should
+basically follow the structure presented here. Official plugins need to
+have str* messages with their definition in language files, but if you build
+some plugins for your use, you can directly use texts in plugin.
+
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * [Name] import plugin for phpMyAdmin
+ *
+ * @package    PhpMyAdmin-Import
+ * @subpackage [Name]
+ */
+if (! defined('PHPMYADMIN')) {
+    exit;
+}
+
+/* Get the import interface */
+require_once 'libraries/plugins/ImportPlugin.class.php';
+
+/**
+ * Handles the import for the [Name] format
+ *
+ * @package PhpMyAdmin-Import
+ */
+class Import[Name] extends ImportPlugin
+{
+    /**
+     * optional - declare variables and descriptions
+     *
+     * @var type
+     */
+    private $_myOptionalVariable;
+
+    /**
+     * Constructor
+     */
+    public function __construct()
+    {
+        $this->setProperties();
+    }
+
+    /**
+     * Sets the import plugin properties.
+     * Called in the constructor.
+     *
+     * @return void
+     */
+    protected function setProperties()
+    {
+        // set properties
+        $props = 'libraries/properties/';
+        // include the main class for properties for the import plug-ins
+        include_once "$props/plugins/ImportPluginProperties.class.php";
+        // include the group properties classes
+        include_once "$props/options/groups/OptionsPropertyRootGroup.class.php";
+        include_once "$props/options/groups/OptionsPropertyMainGroup.class.php";
+        // include the needed single property items
+        include_once "$props/options/items/RadioPropertyItem.class.php";
+
+        $importPluginProperties = new ImportPluginProperties();
+        $importPluginProperties->setText('[name]');             // the name of your plug-in
+        $importPluginProperties->setExtension('[ext]');         // extension this plug-in can handle
+        $importPluginProperties->setOptionsText(__('Options'));
+
+        // create the root group that will be the options field for
+        // $importPluginProperties
+        // this will be shown as "Format specific options"
+        $importSpecificOptions = new OptionsPropertyRootGroup();
+        $importSpecificOptions->setName("Format Specific Options");
+
+        // general options main group
+        $generalOptions = new OptionsPropertyMainGroup();
+        $generalOptions->setName("general_opts");
+
+        // optional :
+        // create primary items and add them to the group
+        // type - one of the classes listed in libraries/properties/options/items/
+        // name - form element name
+        // text - description in GUI
+        // size - size of text element
+        // len  - maximal size of input
+        // values - possible values of the item
+        $leaf = new RadioPropertyItem();
+        $leaf->setName("structure_or_data");
+        $leaf->setValues(
+            array(
+                'structure' => __('structure'),
+                'data' => __('data'),
+                'structure_and_data' => __('structure and data')
+            )
+        );
+        $generalOptions->addProperty($leaf);
+
+        // add the main group to the root group
+        $importSpecificOptions->addProperty($generalOptions);
+
+        // set the options for the import plugin property item
+        $importPluginProperties->setOptions($importSpecificOptions);
+        $this->properties = $importPluginProperties;
+    }
+
+    /**
+     * This method is called when any PluginManager to which the observer
+     * is attached calls PluginManager::notify()
+     *
+     * @param SplSubject $subject The PluginManager notifying the observer
+     *                            of an update.
+     *
+     * @return void
+     */
+    public function update (SplSubject $subject)
+    {
+    }
+
+    /**
+     * Handles the whole import logic
+     *
+     * @return void
+     */
+    public function doImport()
+    {
+        // get globals (others are optional)
+        global $error, $timeout_passed, $finished;
+
+        $buffer = '';
+        while (! ($finished && $i >= $len) && ! $error && ! $timeout_passed) {
+            $data = PMA_importGetNextChunk();
+            if ($data === false) {
+                // subtract data we didn't handle yet and stop processing
+                $offset -= strlen($buffer);
+                break;
+            } elseif ($data === true) {
+                // Handle rest of buffer
+            } else {
+                // Append new data to buffer
+                $buffer .= $data;
+            }
+            // PARSE $buffer here, post sql queries using:
+            PMA_importRunQuery($sql, $verbose_sql_with_comments);
+        } // End of import loop
+        // Commit any possible data in buffers
+        PMA_importRunQuery();
+    }
+
+
+    // optional:
+    /* ~~~~~~~~~~~~~~~~~~~~ Getters and Setters ~~~~~~~~~~~~~~~~~~~~ */
+
+
+    /**
+     * Getter description
+     *
+     * @return type
+     */
+    private function _getMyOptionalVariable()
+    {
+        return $this->_myOptionalVariable;
+    }
+
+    /**
+     * Setter description
+     *
+     * @param type $my_optional_variable description
+     *
+     * @return void
+     */
+    private function _setMyOptionalVariable($my_optional_variable)
+    {
+        $this->_myOptionalVariable = $my_optional_variable;
+    }
+}
+?>
\ No newline at end of file
diff --git a/phpmyadmin/libraries/plugins/import/ShapeFile.class.php b/phpmyadmin/libraries/plugins/import/ShapeFile.class.php
new file mode 100644
index 0000000..121bf12
--- /dev/null
+++ b/phpmyadmin/libraries/plugins/import/ShapeFile.class.php
@@ -0,0 +1,102 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * This class extends ShapeFile class to cater the following phpMyAdmin
+ * specific requirements.
+ *
+ * @package    PhpMyAdmin-Import
+ * @subpackage ESRI_Shape
+ */
+if (! defined('PHPMYADMIN')) {
+    exit;
+}
+
+/**
+ * 1) To load data from .dbf file only when the dBase extension is available.
+ * 2) To use PMA_importGetNextChunk() functionality to read data, rather than
+ *    reading directly from a file. Using ImportShp::readFromBuffer() in place
+ *    of fread(). This makes it possible to use compressions.
+ *
+ * @package    PhpMyAdmin-Import
+ * @subpackage ESRI_Shape
+ */
+class PMA_ShapeFile extends ShapeFile
+{
+    /**
+     * Returns whether the 'dbase' extension is loaded
+     *
+     * @return boolean whether the 'dbase' extension is loaded
+     */
+    function _isDbaseLoaded()
+    {
+        return extension_loaded('dbase');
+    }
+
+    /**
+     * Loads ESRI shape data from the imported file
+     *
+     * @param string $FileName not used, it's here only to match the method
+     *                         signature of the method being overidden
+     *
+     * @return void
+     * @see ShapeFile::loadFromFile()
+     */
+    function loadFromFile($FileName)
+    {
+        $this->_loadHeaders();
+        $this->_loadRecords();
+        if ($this->_isDbaseLoaded()) {
+            $this->_closeDBFFile();
+        }
+    }
+
+    /**
+     * Loads metadata from the ESRI shape file header
+     *
+     * @return void
+     * @see ShapeFile::_loadHeaders()
+     */
+    function _loadHeaders()
+    {
+        ImportShp::readFromBuffer(24);
+        $this->fileLength = loadData("N", ImportShp::readFromBuffer(4));
+
+        ImportShp::readFromBuffer(4);
+        $this->shapeType = loadData("V", ImportShp::readFromBuffer(4));
+
+        $this->boundingBox = array();
+        $this->boundingBox["xmin"] = loadData("d", ImportShp::readFromBuffer(8));
+        $this->boundingBox["ymin"] = loadData("d", ImportShp::readFromBuffer(8));
+        $this->boundingBox["xmax"] = loadData("d", ImportShp::readFromBuffer(8));
+        $this->boundingBox["ymax"] = loadData("d", ImportShp::readFromBuffer(8));
+
+        if ($this->_isDbaseLoaded() && $this->_openDBFFile()) {
+            $this->DBFHeader = $this->_loadDBFHeader();
+        }
+    }
+
+    /**
+     * Loads geometry data from the ESRI shape file
+     *
+     * @return void
+     * @see ShapeFile::_loadRecords()
+     */
+    function _loadRecords()
+    {
+        global $eof;
+        ImportShp::readFromBuffer(32);
+        while (true) {
+            $record = new PMA_ShapeRecord(-1);
+            $record->loadFromFile($this->SHPFile, $this->DBFFile);
+            if ($record->lastError != "") {
+                return false;
+            }
+            if ($eof) {
+                break;
+            }
+
+            $this->records[] = $record;
+        }
+    }
+}
+?>
diff --git a/phpmyadmin/libraries/plugins/import/ShapeRecord.class.php b/phpmyadmin/libraries/plugins/import/ShapeRecord.class.php
new file mode 100644
index 0000000..efefd0c
--- /dev/null
+++ b/phpmyadmin/libraries/plugins/import/ShapeRecord.class.php
@@ -0,0 +1,161 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * This class extends ShapeRecord class to cater the following phpMyAdmin
+ * specific requirements.
+ *
+ * @package    PhpMyAdmin-Import
+ * @subpackage ESRI_Shape
+ */
+if (! defined('PHPMYADMIN')) {
+    exit;
+}
+
+/**
+ * 1) To load data from .dbf file only when the dBase extension is available.
+ * 2) To use PMA_importGetNextChunk() functionality to read data, rather than
+ *    reading directly from a file. Using ImportShp::readFromBuffer() in place
+ *    of fread(). This makes it possible to use compressions.
+ *
+ * @package    PhpMyAdmin-Import
+ * @subpackage ESRI_Shape
+ */
+class PMA_ShapeRecord extends ShapeRecord
+{
+    /**
+     * Loads a geometry data record from the file
+     *
+     * @param object &$SHPFile .shp file
+     * @param object &$DBFFile .dbf file
+     *
+     * @return void
+     * @see ShapeRecord::loadFromFile()
+     */
+    function loadFromFile(&$SHPFile, &$DBFFile)
+    {
+        $this->DBFFile = $DBFFile;
+        $this->_loadHeaders();
+
+        switch ($this->shapeType) {
+        case 0:
+            $this->_loadNullRecord();
+            break;
+        case 1:
+            $this->_loadPointRecord();
+            break;
+        case 3:
+            $this->_loadPolyLineRecord();
+            break;
+        case 5:
+            $this->_loadPolygonRecord();
+            break;
+        case 8:
+            $this->_loadMultiPointRecord();
+            break;
+        default:
+            $this->setError(
+                sprintf(
+                    __("Geometry type '%s' is not supported by MySQL."),
+                    $this->shapeType
+                )
+            );
+            break;
+        }
+        if (extension_loaded('dbase') && isset($this->DBFFile)) {
+            $this->_loadDBFData();
+        }
+    }
+
+    /**
+     * Loads metadata from the ESRI shape record header
+     *
+     * @return void
+     * @see ShapeRecord::_loadHeaders()
+     */
+    function _loadHeaders()
+    {
+        $this->recordNumber = loadData("N", ImportShp::readFromBuffer(4));
+        ImportShp::readFromBuffer(4);
+        $this->shapeType = loadData("V", ImportShp::readFromBuffer(4));
+    }
+
+    /**
+     * Loads data from a point record
+     *
+     * @return void
+     * @see ShapeRecord::_loadPoint()
+     */
+    function _loadPoint()
+    {
+        $data = array();
+
+        $data["x"] = loadData("d", ImportShp::readFromBuffer(8));
+        $data["y"] = loadData("d", ImportShp::readFromBuffer(8));
+
+        return $data;
+    }
+
+    /**
+     * Loads data from a multipoint record
+     *
+     * @return void
+     * @see ShapeRecord::_loadMultiPointRecord()
+     */
+    function _loadMultiPointRecord()
+    {
+        $this->SHPData = array();
+        $this->SHPData["xmin"] = loadData("d", ImportShp::readFromBuffer(8));
+        $this->SHPData["ymin"] = loadData("d", ImportShp::readFromBuffer(8));
+        $this->SHPData["xmax"] = loadData("d", ImportShp::readFromBuffer(8));
+        $this->SHPData["ymax"] = loadData("d", ImportShp::readFromBuffer(8));
+
+        $this->SHPData["numpoints"] = loadData("V", ImportShp::readFromBuffer(4));
+
+        for ($i = 0; $i <= $this->SHPData["numpoints"]; $i++) {
+            $this->SHPData["points"][] = $this->_loadPoint();
+        }
+    }
+
+    /**
+     * Loads data from a polyline record
+     *
+     * @return void
+     * @see ShapeRecord::_loadPolyLineRecord()
+     */
+    function _loadPolyLineRecord()
+    {
+        $this->SHPData = array();
+        $this->SHPData["xmin"] = loadData("d", ImportShp::readFromBuffer(8));
+        $this->SHPData["ymin"] = loadData("d", ImportShp::readFromBuffer(8));
+        $this->SHPData["xmax"] = loadData("d", ImportShp::readFromBuffer(8));
+        $this->SHPData["ymax"] = loadData("d", ImportShp::readFromBuffer(8));
+
+        $this->SHPData["numparts"]  = loadData("V", ImportShp::readFromBuffer(4));
+        $this->SHPData["numpoints"] = loadData("V", ImportShp::readFromBuffer(4));
+
+        for ($i = 0; $i < $this->SHPData["numparts"]; $i++) {
+            $this->SHPData["parts"][$i] = loadData(
+                "V", ImportShp::readFromBuffer(4)
+            );
+        }
+
+        $readPoints = 0;
+        reset($this->SHPData["parts"]);
+        while (list($partIndex, $partData) = each($this->SHPData["parts"])) {
+            if (! isset($this->SHPData["parts"][$partIndex]["points"])
+                || !is_array($this->SHPData["parts"][$partIndex]["points"])
+            ) {
+                $this->SHPData["parts"][$partIndex] = array();
+                $this->SHPData["parts"][$partIndex]["points"] = array();
+            }
+            while (! in_array($readPoints, $this->SHPData["parts"])
+            && ($readPoints < ($this->SHPData["numpoints"]))
+            ) {
+                $this->SHPData["parts"][$partIndex]["points"][]
+                    = $this->_loadPoint();
+                $readPoints++;
+            }
+        }
+    }
+}
+?>
diff --git a/phpmyadmin/libraries/plugins/import/upload/UploadApc.class.php b/phpmyadmin/libraries/plugins/import/upload/UploadApc.class.php
new file mode 100644
index 0000000..881832f
--- /dev/null
+++ b/phpmyadmin/libraries/plugins/import/upload/UploadApc.class.php
@@ -0,0 +1,84 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * Provides upload functionalities for the import plugins
+ *
+ * @package PhpMyAdmin
+ */
+if (! defined('PHPMYADMIN')) {
+    exit;
+}
+
+/* Get the transformations interface */
+require_once 'libraries/plugins/UploadInterface.int.php';
+
+/**
+ * Implementation for the APC extension
+ *
+ * @package PhpMyAdmin
+ */
+class UploadApc implements UploadInterface
+{
+    /**
+     * Gets the specific upload ID Key
+     *
+     * @return string ID Key
+     */
+    public static function getIdKey()
+    {
+        return 'APC_UPLOAD_PROGRESS';
+    }
+
+    /**
+     * Returns upload status.
+     *
+     * This is implementation for APC extension.
+     *
+     * @param string $id upload id
+     *
+     * @return array|null
+     */
+    public static function getUploadStatus($id)
+    {
+        global $SESSION_KEY;
+
+        if (trim($id) == "") {
+            return null;
+        }
+        if (! array_key_exists($id, $_SESSION[$SESSION_KEY])) {
+            $_SESSION[$SESSION_KEY][$id] = array(
+                'id'       => $id,
+                'finished' => false,
+                'percent'  => 0,
+                'total'    => 0,
+                'complete' => 0,
+                'plugin'   => UploadApc::getIdKey()
+             );
+        }
+        $ret = $_SESSION[$SESSION_KEY][$id];
+
+        if (! PMA_import_apcCheck() || $ret['finished']) {
+            return $ret;
+        }
+        $status = apc_fetch('upload_' . $id);
+
+        if ($status) {
+            $ret['finished'] = (bool)$status['done'];
+            $ret['total']    = $status['total'];
+            $ret['complete'] = $status['current'];
+
+            if ($ret['total'] > 0) {
+                $ret['percent'] = $ret['complete'] / $ret['total'] * 100;
+            }
+
+            if ($ret['percent'] == 100) {
+                $ret['finished'] = (bool)true;
+            }
+
+            $_SESSION[$SESSION_KEY][$id] = $ret;
+        }
+
+        return $ret;
+    }
+}
+?>
\ No newline at end of file
diff --git a/phpmyadmin/libraries/plugins/import/upload/UploadNoplugin.class.php b/phpmyadmin/libraries/plugins/import/upload/UploadNoplugin.class.php
new file mode 100644
index 0000000..90148de
--- /dev/null
+++ b/phpmyadmin/libraries/plugins/import/upload/UploadNoplugin.class.php
@@ -0,0 +1,64 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * Provides upload functionalities for the import plugins
+ *
+ * @package PhpMyAdmin
+ */
+if (! defined('PHPMYADMIN')) {
+    exit;
+}
+
+/* Get the transformations interface */
+require_once 'libraries/plugins/UploadInterface.int.php';
+
+/**
+ * Implementation for no plugin
+ *
+ * @package PhpMyAdmin
+ */
+class UploadNoplugin implements UploadInterface
+{
+    /**
+     * Gets the specific upload ID Key
+     *
+     * @return string ID Key
+     */
+    public static function getIdKey()
+    {
+        return 'noplugin';
+    }
+
+    /**
+     * Returns upload status.
+     *
+     * This is implementation when no webserver support exists,
+     * so it returns just zeroes.
+     *
+     * @param string $id upload id
+     *
+     * @return array|null
+     */
+    public static function getUploadStatus($id)
+    {
+        global $SESSION_KEY;
+
+        if (trim($id) == "") {
+            return null;
+        }
+        if (! array_key_exists($id, $_SESSION[$SESSION_KEY])) {
+            $_SESSION[$SESSION_KEY][$id] = array(
+                'id'       => $id,
+                'finished' => false,
+                'percent'  => 0,
+                'total'    => 0,
+                'complete' => 0,
+                'plugin'   => UploadNoplugin::getIdKey()
+            );
+        }
+        $ret = $_SESSION[$SESSION_KEY][$id];
+
+        return $ret;
+    }
+}
+?>
\ No newline at end of file
diff --git a/phpmyadmin/libraries/plugins/import/upload/UploadProgress.class.php b/phpmyadmin/libraries/plugins/import/upload/UploadProgress.class.php
new file mode 100644
index 0000000..1a50776
--- /dev/null
+++ b/phpmyadmin/libraries/plugins/import/upload/UploadProgress.class.php
@@ -0,0 +1,94 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * Provides upload functionalities for the import plugins
+ *
+ * @package PhpMyAdmin
+ */
+if (! defined('PHPMYADMIN')) {
+    exit;
+}
+
+/* Get the transformations interface */
+require_once 'libraries/plugins/UploadInterface.int.php';
+
+/**
+ * Implementation for upload progress
+ *
+ * @package PhpMyAdmin
+ */
+class UploadProgress implements UploadInterface
+{
+    /**
+     * Gets the specific upload ID Key
+     *
+     * @return string ID Key
+     */
+    public static function getIdKey()
+    {
+        return 'UPLOAD_IDENTIFIER';
+    }
+
+    /**
+     * Returns upload status.
+     *
+     * This is implementation for upload progress
+     *
+     * @param string $id upload id
+     *
+     * @return array|null
+     */
+    public static function getUploadStatus($id)
+    {
+        global $SESSION_KEY;
+
+        if (trim($id) == "") {
+            return null;
+        }
+
+        if (! array_key_exists($id, $_SESSION[$SESSION_KEY])) {
+            $_SESSION[$SESSION_KEY][$id] = array(
+                'id'       => $id,
+                'finished' => false,
+                'percent'  => 0,
+                'total'    => 0,
+                'complete' => 0,
+                'plugin'   => UploadProgress::getIdKey()
+            );
+        }
+        $ret = $_SESSION[$SESSION_KEY][$id];
+
+        if (! PMA_import_progressCheck() || $ret['finished']) {
+            return $ret;
+        }
+
+        $status = uploadprogress_get_info($id);
+
+        if ($status) {
+            if ($status['bytes_uploaded'] == $status['bytes_total']) {
+                $ret['finished'] = true;
+            } else {
+                $ret['finished'] = false;
+            }
+            $ret['total']    = $status['bytes_total'];
+            $ret['complete'] = $status['bytes_uploaded'];
+
+            if ($ret['total'] > 0) {
+                $ret['percent'] = $ret['complete'] / $ret['total'] * 100;
+            }
+        } else {
+            $ret = array(
+                'id'       => $id,
+                'finished' => true,
+                'percent'  => 100,
+                'total'    => $ret['total'],
+                'complete' => $ret['total'],
+                'plugin'   => UploadProgress::getIdKey()
+            );
+        }
+
+        $_SESSION[$SESSION_KEY][$id] = $ret;
+        return $ret;
+    }
+}
+?>
\ No newline at end of file
diff --git a/phpmyadmin/libraries/plugins/import/upload/UploadSession.class.php b/phpmyadmin/libraries/plugins/import/upload/UploadSession.class.php
new file mode 100644
index 0000000..3640413
--- /dev/null
+++ b/phpmyadmin/libraries/plugins/import/upload/UploadSession.class.php
@@ -0,0 +1,96 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * Provides upload functionalities for the import plugins
+ *
+ * @package PhpMyAdmin
+ */
+if (! defined('PHPMYADMIN')) {
+    exit;
+}
+
+/* Get the transformations interface */
+require_once 'libraries/plugins/UploadInterface.int.php';
+
+/**
+ * Implementation for session
+ *
+ * @package PhpMyAdmin
+ */
+class UploadSession implements UploadInterface
+{
+    /**
+     * Gets the specific upload ID Key
+     *
+     * @return string ID Key
+     */
+    public static function getIdKey()
+    {
+        return ini_get('session.upload_progress.name');
+    }
+
+    /**
+     * Returns upload status.
+     *
+     * This is implementation for session.upload_progress in PHP 5.4+.
+     *
+     * @param string $id upload id
+     *
+     * @return array|null
+     */
+    public static function getUploadStatus($id)
+    {
+        global $SESSION_KEY;
+
+        if (trim($id) == '') {
+            return null;
+        }
+
+        if (! array_key_exists($id, $_SESSION[$SESSION_KEY])) {
+            $_SESSION[$SESSION_KEY][$id] = array(
+                'id'       => $id,
+                'finished' => false,
+                'percent'  => 0,
+                'total'    => 0,
+                'complete' => 0,
+                'plugin'   => UploadSession::getIdKey()
+            );
+        }
+        $ret = $_SESSION[$SESSION_KEY][$id];
+
+        if (! PMA_import_sessionCheck() || $ret['finished']) {
+            return $ret;
+        }
+
+        $status = false;
+        $sessionkey = ini_get('session.upload_progress.prefix') . $id;
+
+        if (isset($_SESSION[$sessionkey])) {
+            $status = $_SESSION[$sessionkey];
+        }
+
+        if ($status) {
+            $ret['finished'] = $status['done'];
+            $ret['total']    = $status['content_length'];
+            $ret['complete'] = $status['bytes_processed'];
+
+            if ($ret['total'] > 0) {
+                $ret['percent'] = $ret['complete'] / $ret['total'] * 100;
+            }
+        } else {
+            $ret = array(
+                'id'       => $id,
+                'finished' => true,
+                'percent'  => 100,
+                'total'    => $ret['total'],
+                'complete' => $ret['total'],
+                'plugin'   => UploadSession::getIdKey()
+            );
+        }
+
+        $_SESSION[$SESSION_KEY][$id] = $ret;
+
+        return $ret;
+    }
+}
+?>
\ No newline at end of file
diff --git a/phpmyadmin/libraries/plugins/transformations/Application_Octetstream_Download.class.php b/phpmyadmin/libraries/plugins/transformations/Application_Octetstream_Download.class.php
new file mode 100644
index 0000000..46bda70
--- /dev/null
+++ b/phpmyadmin/libraries/plugins/transformations/Application_Octetstream_Download.class.php
@@ -0,0 +1,64 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * Application OctetStream Download Transformations plugin for phpMyAdmin
+ *
+ * @package    PhpMyAdmin-Transformations
+ * @subpackage Download
+ */
+if (! defined('PHPMYADMIN')) {
+    exit;
+}
+/* Get the download transformations interface */
+require_once 'abstract/DownloadTransformationsPlugin.class.php';
+
+/**
+ * Handles the download transformation for application octetstream
+ *
+ * @package    PhpMyAdmin-Transformations
+ * @subpackage Download
+ */
+class Application_Octetstream_Download extends DownloadTransformationsPlugin
+{
+    /**
+     * Gets the plugin`s MIME type
+     *
+     * @return string
+     */
+    public static function getMIMEType()
+    {
+        return "Application";
+    }
+
+    /**
+     * Gets the plugin`s MIME subtype
+     *
+     * @return string
+     */
+    public static function getMIMESubtype()
+    {
+        return "OctetStream";
+    }
+}
+
+/**
+ * Function to call Application_Octetstream_Download::getInfo();
+ *
+ * Temporary workaround for bug #3783 :
+ * Calling a method from a variable class is not possible before PHP 5.3.
+ *
+ * This function is called by PMA_getTransformationDescription()
+ * in libraries/transformations.lib.php using a variable to construct it's name.
+ * This function then calls the static method.
+ *
+ * Don't use this function unless you are affected by the same issue.
+ * Call the static method directly instead.
+ *
+ * @deprecated
+ * @return string Info about transformation class
+ */
+function Application_Octetstream_Download_getInfo()
+{
+    return Application_Octetstream_Download::getInfo();
+}
+?>
diff --git a/phpmyadmin/libraries/plugins/transformations/Application_Octetstream_Hex.class.php b/phpmyadmin/libraries/plugins/transformations/Application_Octetstream_Hex.class.php
new file mode 100644
index 0000000..f876abb
--- /dev/null
+++ b/phpmyadmin/libraries/plugins/transformations/Application_Octetstream_Hex.class.php
@@ -0,0 +1,65 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * Application OctetStream Hex Transformations plugin for phpMyAdmin
+ *
+ * @package    PhpMyAdmin-Transformations
+ * @subpackage Hex
+ */
+if (! defined('PHPMYADMIN')) {
+    exit;
+}
+
+/* Get the hex transformations interface */
+require_once 'abstract/HexTransformationsPlugin.class.php';
+
+/**
+ * Handles the hex transformation for application octetstream
+ *
+ * @package    PhpMyAdmin-Transformations
+ * @subpackage Hex
+ */
+class Application_Octetstream_Hex extends HexTransformationsPlugin
+{
+    /**
+     * Gets the plugin`s MIME type
+     *
+     * @return string
+     */
+    public static function getMIMEType()
+    {
+        return "Application";
+    }
+
+    /**
+     * Gets the plugin`s MIME subtype
+     *
+     * @return string
+     */
+    public static function getMIMESubtype()
+    {
+        return "OctetStream";
+    }
+}
+
+/**
+ * Function to call Application_Octetstream_Hex::getInfo();
+ *
+ * Temporary workaround for bug #3783 :
+ * Calling a method from a variable class is not possible before PHP 5.3.
+ *
+ * This function is called by PMA_getTransformationDescription()
+ * in libraries/transformations.lib.php using a variable to construct it's name.
+ * This function then calls the static method.
+ *
+ * Don't use this function unless you are affected by the same issue.
+ * Call the static method directly instead.
+ *
+ * @deprecated
+ * @return string Info about transformation class
+ */
+function Application_Octetstream_Hex_getInfo()
+{
+    return Application_Octetstream_Hex::getInfo();
+}
+?>
diff --git a/phpmyadmin/libraries/plugins/transformations/Image_JPEG_Inline.class.php b/phpmyadmin/libraries/plugins/transformations/Image_JPEG_Inline.class.php
new file mode 100644
index 0000000..934df75
--- /dev/null
+++ b/phpmyadmin/libraries/plugins/transformations/Image_JPEG_Inline.class.php
@@ -0,0 +1,65 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * Image JPEG Inline Transformations plugin for phpMyAdmin
+ *
+ * @package    PhpMyAdmin-Transformations
+ * @subpackage Inline
+ */
+if (! defined('PHPMYADMIN')) {
+    exit;
+}
+
+/* Get the inline transformations interface */
+require_once 'abstract/InlineTransformationsPlugin.class.php';
+
+/**
+ * Handles the inline transformation for image jpeg
+ *
+ * @package    PhpMyAdmin-Transformations
+ * @subpackage Inline
+ */
+class Image_JPEG_Inline extends InlineTransformationsPlugin
+{
+    /**
+     * Gets the plugin`s MIME type
+     *
+     * @return string
+     */
+    public static function getMIMEType()
+    {
+        return "Image";
+    }
+
+    /**
+     * Gets the plugin`s MIME subtype
+     *
+     * @return string
+     */
+    public static function getMIMESubtype()
+    {
+        return "JPEG";
+    }
+}
+
+/**
+ * Function to call Image_JPEG_Inline::getInfo();
+ *
+ * Temporary workaround for bug #3783 :
+ * Calling a method from a variable class is not possible before PHP 5.3.
+ *
+ * This function is called by PMA_getTransformationDescription()
+ * in libraries/transformations.lib.php using a variable to construct it's name.
+ * This function then calls the static method.
+ *
+ * Don't use this function unless you are affected by the same issue.
+ * Call the static method directly instead.
+ *
+ * @deprecated
+ * @return string Info about transformation class
+ */
+function Image_JPEG_Inline_getInfo()
+{
+    return Image_JPEG_Inline::getInfo();
+}
+?>
diff --git a/phpmyadmin/libraries/plugins/transformations/Image_JPEG_Link.class.php b/phpmyadmin/libraries/plugins/transformations/Image_JPEG_Link.class.php
new file mode 100644
index 0000000..fc04040
--- /dev/null
+++ b/phpmyadmin/libraries/plugins/transformations/Image_JPEG_Link.class.php
@@ -0,0 +1,65 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * Image JPEG Link Transformations plugin for phpMyAdmin
+ *
+ * @package    PhpMyAdmin-Transformations
+ * @subpackage Link
+ */
+if (! defined('PHPMYADMIN')) {
+    exit;
+}
+
+/* Get the link transformations interface */
+require_once 'abstract/ImageLinkTransformationsPlugin.class.php';
+
+/**
+ * Handles the link transformation for image jpeg
+ *
+ * @package    PhpMyAdmin-Transformations
+ * @subpackage Link
+ */
+class Image_JPEG_Link extends ImageLinkTransformationsPlugin
+{
+    /**
+     * Gets the plugin`s MIME type
+     *
+     * @return string
+     */
+    public static function getMIMEType()
+    {
+        return "Image";
+    }
+
+    /**
+     * Gets the plugin`s MIME subtype
+     *
+     * @return string
+     */
+    public static function getMIMESubtype()
+    {
+        return "JPEG";
+    }
+}
+
+/**
+ * Function to call Image_JPEG_Link::getInfo();
+ *
+ * Temporary workaround for bug #3783 :
+ * Calling a method from a variable class is not possible before PHP 5.3.
+ *
+ * This function is called by PMA_getTransformationDescription()
+ * in libraries/transformations.lib.php using a variable to construct it's name.
+ * This function then calls the static method.
+ *
+ * Don't use this function unless you are affected by the same issue.
+ * Call the static method directly instead.
+ *
+ * @deprecated
+ * @return string Info about transformation class
+ */
+function Image_JPEG_Link_getInfo()
+{
+    return Image_JPEG_Link::getInfo();
+}
+?>
diff --git a/phpmyadmin/libraries/plugins/transformations/Image_PNG_Inline.class.php b/phpmyadmin/libraries/plugins/transformations/Image_PNG_Inline.class.php
new file mode 100644
index 0000000..e879c23
--- /dev/null
+++ b/phpmyadmin/libraries/plugins/transformations/Image_PNG_Inline.class.php
@@ -0,0 +1,65 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * Image PNG Inline Transformations plugin for phpMyAdmin
+ *
+ * @package    PhpMyAdmin-Transformations
+ * @subpackage Inline
+ */
+if (! defined('PHPMYADMIN')) {
+    exit;
+}
+
+/* Get the inline transformations interface */
+require_once 'abstract/InlineTransformationsPlugin.class.php';
+
+/**
+ * Handles the inline transformation for image png
+ *
+ * @package    PhpMyAdmin-Transformations
+ * @subpackage Inline
+ */
+class Image_PNG_Inline extends InlineTransformationsPlugin
+{
+    /**
+     * Gets the plugin`s MIME type
+     *
+     * @return string
+     */
+    public static function getMIMEType()
+    {
+        return "Image";
+    }
+
+    /**
+     * Gets the plugin`s MIME subtype
+     *
+     * @return string
+     */
+    public static function getMIMESubtype()
+    {
+        return "PNG";
+    }
+}
+
+/**
+ * Function to call Image_PNG_Inline::getInfo();
+ *
+ * Temporary workaround for bug #3783 :
+ * Calling a method from a variable class is not possible before PHP 5.3.
+ *
+ * This function is called by PMA_getTransformationDescription()
+ * in libraries/transformations.lib.php using a variable to construct it's name.
+ * This function then calls the static method.
+ *
+ * Don't use this function unless you are affected by the same issue.
+ * Call the static method directly instead.
+ *
+ * @deprecated
+ * @return string Info about transformation class
+ */
+function Image_PNG_Inline_getInfo()
+{
+    return Image_PNG_Inline::getInfo();
+}
+?>
diff --git a/phpmyadmin/libraries/plugins/transformations/README b/phpmyadmin/libraries/plugins/transformations/README
new file mode 100644
index 0000000..7d7a125
--- /dev/null
+++ b/phpmyadmin/libraries/plugins/transformations/README
@@ -0,0 +1,4 @@
+TRANSFORMATION USAGE (Garvin Hicking, <me at supergarv.de>)
+====================
+
+See the documentation for complete instructions on how to use transformation plugins.
diff --git a/phpmyadmin/libraries/plugins/transformations/TEMPLATE b/phpmyadmin/libraries/plugins/transformations/TEMPLATE
new file mode 100644
index 0000000..b0ce2f0
--- /dev/null
+++ b/phpmyadmin/libraries/plugins/transformations/TEMPLATE
@@ -0,0 +1,68 @@
+<?php
+// vim: expandtab sw=4 ts=4 sts=4:
+/**
+ * This file contains the basic structure for a specific MIME Type and Subtype
+ * transformations class.
+ * For instructions, read the documentation
+ *
+ * @package    PhpMyAdmin-Transformations
+ * @subpackage [TransformationName]
+ */
+if (! defined('PHPMYADMIN')) {
+    exit;
+}
+
+/* Get the [TransformationName] transformations interface */
+require_once 'abstract/[TransformationName]TransformationsPlugin.class.php';
+
+/**
+ * Handles the [TransformationName] transformation for [MIMEType] - [MIMESubtype]
+ *
+ * @package PhpMyAdmin
+ */
+class [MIMEType]_[MIMESubtype]_[TransformationName]
+    extends [TransformationName]TransformationsPlugin
+{
+    /**
+     * Gets the plugin`s MIME type
+     *
+     * @return string
+     */
+    public static function getMIMEType()
+    {
+        return "[MIMEType]";
+    }
+
+    /**
+     * Gets the plugin`s MIME subtype
+     *
+     * @return string
+     */
+    public static function getMIMESubtype()
+    {
+        return "[MIMESubtype]";
+    }
+}
+
+/**
+ * Function to call [MIMEType]_[MIMESubtype]_[TransformationName]::getInfo();
+ *
+ * Temporary workaround for bug #3783 :
+ * Calling a method from a variable class is not possible before PHP 5.3.
+ *
+ * This function is called by PMA_getTransformationDescription()
+ * in libraries/transformations.lib.php using a variable to construct it's name.
+ * This function then calls the static method.
+ *
+ * Don't use this function unless you are affected by the same issue.
+ * Call the static method directly instead.
+ *
+ * @deprecated
+ * @return string Info about transformation class
+ */
+
+function [MIMEType]_[MIMESubtype]_[TransformationName]_getInfo()
+{
+    return [MIMEType]_[MIMESubtype]_[TransformationName]::getInfo();
+}
+?>
diff --git a/phpmyadmin/libraries/plugins/transformations/TEMPLATE_ABSTRACT b/phpmyadmin/libraries/plugins/transformations/TEMPLATE_ABSTRACT
new file mode 100644
index 0000000..5cc1d26
--- /dev/null
+++ b/phpmyadmin/libraries/plugins/transformations/TEMPLATE_ABSTRACT
@@ -0,0 +1,89 @@
+<?php
+// vim: expandtab sw=4 ts=4 sts=4:
+/**
+ * This file contains the basic structure for an abstract class defining a
+ * transformation.
+ * For instructions, read the documentation
+ *
+ * @package    PhpMyAdmin-Transformations
+ * @subpackage [TransformationName]
+ */
+if (! defined('PHPMYADMIN')) {
+    exit;
+}
+
+/* Get the transformations interface */
+require_once 'libraries/plugins/TransformationsPlugin.class.php';
+
+/**
+ * Provides common methods for all of the [TransformationName] transformations plugins.
+ *
+ * @package PhpMyAdmin
+ */
+abstract class [TransformationName]TransformationsPlugin
+    extends TransformationsPlugin
+{
+    /**
+     * Gets the transformation description of the specific plugin
+     *
+     * @return string
+     */
+    public static function getInfo()
+    {
+        return __(
+            'Description of the transformation.'
+        );
+    }
+
+    /**
+     * Does the actual work of each specific transformations plugin.
+     *
+     * @param string $buffer  text to be transformed
+     * @param array  $options transformation options
+     * @param string $meta    meta information
+     *
+     * @return void
+     */
+    public function applyTransformation($buffer, $options = array(), $meta = '')
+    {
+        // possibly use a global transform and feed it with special options
+
+        // further operations on $buffer using the $options[] array.
+
+        // You can evaluate the propagated $meta Object. It's contained fields are described in http://www.php.net/mysql_fetch_field.
+        // This stored information can be used to get the field information about the transformed field.
+        // $meta->mimetype contains the original MimeType of the field (i.e. 'text/plain', 'image/jpeg' etc.)
+
+        return $buffer;
+    }
+
+    /**
+     * This method is called when any PluginManager to which the observer
+     * is attached calls PluginManager::notify()
+     *
+     * @param SplSubject $subject The PluginManager notifying the observer
+     *                            of an update.
+     *
+     * @todo implement
+     * @return void
+     */
+    public function update (SplSubject $subject)
+    {
+        ;
+    }
+
+
+    /* ~~~~~~~~~~~~~~~~~~~~ Getters and Setters ~~~~~~~~~~~~~~~~~~~~ */
+
+
+    /**
+     * Gets the TransformationName of the specific plugin
+     *
+     * @return string
+     */
+    public static function getName()
+    {
+        return "[TransformationName]";
+    }
+}
+?>
diff --git a/phpmyadmin/libraries/plugins/transformations/Text_Plain_Append.class.php b/phpmyadmin/libraries/plugins/transformations/Text_Plain_Append.class.php
new file mode 100644
index 0000000..8a102cb
--- /dev/null
+++ b/phpmyadmin/libraries/plugins/transformations/Text_Plain_Append.class.php
@@ -0,0 +1,66 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * Text Plain Append Transformations plugin for phpMyAdmin
+ *
+ * @package    PhpMyAdmin-Transformations
+ * @subpackage Append
+ */
+if (! defined('PHPMYADMIN')) {
+    exit;
+}
+
+/* Get the append transformations interface */
+require_once 'abstract/AppendTransformationsPlugin.class.php';
+
+/**
+ * Handles the append transformation for text plain.
+ * Has one option: the text to be appended (default '')
+ *
+ * @package    PhpMyAdmin-Transformations
+ * @subpackage Append
+ */
+class Text_Plain_Append extends AppendTransformationsPlugin
+{
+    /**
+     * Gets the plugin`s MIME type
+     *
+     * @return string
+     */
+    public static function getMIMEType()
+    {
+        return "Text";
+    }
+
+    /**
+     * Gets the plugin`s MIME subtype
+     *
+     * @return string
+     */
+    public static function getMIMESubtype()
+    {
+        return "Plain";
+    }
+}
+
+/**
+ * Function to call Text_Plain_Append::getInfo();
+ *
+ * Temporary workaround for bug #3783 :
+ * Calling a method from a variable class is not possible before PHP 5.3.
+ *
+ * This function is called by PMA_getTransformationDescription()
+ * in libraries/transformations.lib.php using a variable to construct it's name.
+ * This function then calls the static method.
+ *
+ * Don't use this function unless you are affected by the same issue.
+ * Call the static method directly instead.
+ *
+ * @deprecated
+ * @return string Info about transformation class
+ */
+function Text_Plain_Append_getInfo()
+{
+    return Text_Plain_Append::getInfo();
+}
+?>
diff --git a/phpmyadmin/libraries/plugins/transformations/Text_Plain_Dateformat.class.php b/phpmyadmin/libraries/plugins/transformations/Text_Plain_Dateformat.class.php
new file mode 100644
index 0000000..ed8c9e5
--- /dev/null
+++ b/phpmyadmin/libraries/plugins/transformations/Text_Plain_Dateformat.class.php
@@ -0,0 +1,65 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * Text Plain Date Format Transformations plugin for phpMyAdmin
+ *
+ * @package    PhpMyAdmin-Transformations
+ * @subpackage DateFormat
+ */
+if (! defined('PHPMYADMIN')) {
+    exit;
+}
+
+/* Get the date format transformations interface */
+require_once 'abstract/DateFormatTransformationsPlugin.class.php';
+
+/**
+ * Handles the date format transformation for text plain
+ *
+ * @package    PhpMyAdmin-Transformations
+ * @subpackage DateFormat
+ */
+class Text_Plain_Dateformat extends DateFormatTransformationsPlugin
+{
+    /**
+     * Gets the plugin`s MIME type
+     *
+     * @return string
+     */
+    public static function getMIMEType()
+    {
+        return "Text";
+    }
+
+    /**
+     * Gets the plugin`s MIME subtype
+     *
+     * @return string
+     */
+    public static function getMIMESubtype()
+    {
+        return "Plain";
+    }
+}
+
+/**
+ * Function to call Text_Plain_Dateformat::getInfo();
+ *
+ * Temporary workaround for bug #3783 :
+ * Calling a method from a variable class is not possible before PHP 5.3.
+ *
+ * This function is called by PMA_getTransformationDescription()
+ * in libraries/transformations.lib.php using a variable to construct it's name.
+ * This function then calls the static method.
+ *
+ * Don't use this function unless you are affected by the same issue.
+ * Call the static method directly instead.
+ *
+ * @deprecated
+ * @return string Info about transformation class
+ */
+function Text_Plain_Dateformat_getInfo()
+{
+    return Text_Plain_Dateformat::getInfo();
+}
+?>
diff --git a/phpmyadmin/libraries/plugins/transformations/Text_Plain_External.class.php b/phpmyadmin/libraries/plugins/transformations/Text_Plain_External.class.php
new file mode 100644
index 0000000..1aa321a
--- /dev/null
+++ b/phpmyadmin/libraries/plugins/transformations/Text_Plain_External.class.php
@@ -0,0 +1,65 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * Text Plain External Transformations plugin for phpMyAdmin
+ *
+ * @package    PhpMyAdmin-Transformations
+ * @subpackage External
+ */
+if (! defined('PHPMYADMIN')) {
+    exit;
+}
+
+/* Get the external transformations interface */
+require_once 'abstract/ExternalTransformationsPlugin.class.php';
+
+/**
+ * Handles the external transformation for text plain
+ *
+ * @package    PhpMyAdmin-Transformations
+ * @subpackage External
+ */
+class Text_Plain_External extends ExternalTransformationsPlugin
+{
+    /**
+     * Gets the plugin`s MIME type
+     *
+     * @return string
+     */
+    public static function getMIMEType()
+    {
+        return "Text";
+    }
+
+    /**
+     * Gets the plugin`s MIME subtype
+     *
+     * @return string
+     */
+    public static function getMIMESubtype()
+    {
+        return "Plain";
+    }
+}
+
+/**
+ * Function to call Text_Plain_External::getInfo();
+ *
+ * Temporary workaround for bug #3783 :
+ * Calling a method from a variable class is not possible before PHP 5.3.
+ *
+ * This function is called by PMA_getTransformationDescription()
+ * in libraries/transformations.lib.php using a variable to construct it's name.
+ * This function then calls the static method.
+ *
+ * Don't use this function unless you are affected by the same issue.
+ * Call the static method directly instead.
+ *
+ * @deprecated
+ * @return string Info about transformation class
+ */
+function Text_Plain_External_getInfo()
+{
+    return Text_Plain_External::getInfo();
+}
+?>
diff --git a/phpmyadmin/libraries/plugins/transformations/Text_Plain_Formatted.class.php b/phpmyadmin/libraries/plugins/transformations/Text_Plain_Formatted.class.php
new file mode 100644
index 0000000..5c6b683
--- /dev/null
+++ b/phpmyadmin/libraries/plugins/transformations/Text_Plain_Formatted.class.php
@@ -0,0 +1,65 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * Text Plain Formatted Transformations plugin for phpMyAdmin
+ *
+ * @package    PhpMyAdmin-Transformations
+ * @subpackage Formatted
+ */
+if (! defined('PHPMYADMIN')) {
+    exit;
+}
+
+/* Get the formatted transformations interface */
+require_once 'abstract/FormattedTransformationsPlugin.class.php';
+
+/**
+ * Handles the formatted transformation for text plain
+ *
+ * @package    PhpMyAdmin-Transformations
+ * @subpackage Formatted
+ */
+class Text_Plain_Formatted extends FormattedTransformationsPlugin
+{
+    /**
+     * Gets the plugin`s MIME type
+     *
+     * @return string
+     */
+    public static function getMIMEType()
+    {
+        return "Text";
+    }
+
+    /**
+     * Gets the plugin`s MIME subtype
+     *
+     * @return string
+     */
+    public static function getMIMESubtype()
+    {
+        return "Plain";
+    }
+}
+
+/**
+ * Function to call Text_Plain_Formatted::getInfo();
+ *
+ * Temporary workaround for bug #3783 :
+ * Calling a method from a variable class is not possible before PHP 5.3.
+ *
+ * This function is called by PMA_getTransformationDescription()
+ * in libraries/transformations.lib.php using a variable to construct it's name.
+ * This function then calls the static method.
+ *
+ * Don't use this function unless you are affected by the same issue.
+ * Call the static method directly instead.
+ *
+ * @deprecated
+ * @return string Info about transformation class
+ */
+function Text_Plain_Formatted_getInfo()
+{
+    return Text_Plain_Formatted::getInfo();
+}
+?>
diff --git a/phpmyadmin/libraries/plugins/transformations/Text_Plain_Imagelink.class.php b/phpmyadmin/libraries/plugins/transformations/Text_Plain_Imagelink.class.php
new file mode 100644
index 0000000..4cb1800
--- /dev/null
+++ b/phpmyadmin/libraries/plugins/transformations/Text_Plain_Imagelink.class.php
@@ -0,0 +1,65 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * Text Plain Image Link Transformations plugin for phpMyAdmin
+ *
+ * @package    PhpMyAdmin-Transformations
+ * @subpackage ImageLink
+ */
+if (! defined('PHPMYADMIN')) {
+    exit;
+}
+
+/* Get the image link transformations interface */
+require_once 'abstract/TextImageLinkTransformationsPlugin.class.php';
+
+/**
+ * Handles the image link transformation for text plain
+ *
+ * @package    PhpMyAdmin-Transformations
+ * @subpackage ImageLink
+ */
+class Text_Plain_Imagelink extends TextImageLinkTransformationsPlugin
+{
+    /**
+     * Gets the plugin`s MIME type
+     *
+     * @return string
+     */
+    public static function getMIMEType()
+    {
+        return "Text";
+    }
+
+    /**
+     * Gets the plugin`s MIME subtype
+     *
+     * @return string
+     */
+    public static function getMIMESubtype()
+    {
+        return "Plain";
+    }
+}
+
+/**
+ * Function to call Text_Plain_Imagelink::getInfo();
+ *
+ * Temporary workaround for bug #3783 :
+ * Calling a method from a variable class is not possible before PHP 5.3.
+ *
+ * This function is called by PMA_getTransformationDescription()
+ * in libraries/transformations.lib.php using a variable to construct it's name.
+ * This function then calls the static method.
+ *
+ * Don't use this function unless you are affected by the same issue.
+ * Call the static method directly instead.
+ *
+ * @deprecated
+ * @return string Info about transformation class
+ */
+function Text_Plain_Imagelink_getInfo()
+{
+    return Text_Plain_Imagelink::getInfo();
+}
+?>
diff --git a/phpmyadmin/libraries/plugins/transformations/Text_Plain_Link.class.php b/phpmyadmin/libraries/plugins/transformations/Text_Plain_Link.class.php
new file mode 100644
index 0000000..1e64203
--- /dev/null
+++ b/phpmyadmin/libraries/plugins/transformations/Text_Plain_Link.class.php
@@ -0,0 +1,65 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * Text Plain Link Transformations plugin for phpMyAdmin
+ *
+ * @package    PhpMyAdmin-Transformations
+ * @subpackage Link
+ */
+if (! defined('PHPMYADMIN')) {
+    exit;
+}
+
+/* Get the link transformations interface */
+require_once 'abstract/TextLinkTransformationsPlugin.class.php';
+
+/**
+ * Handles the link transformation for text plain
+ *
+ * @package    PhpMyAdmin-Transformations
+ * @subpackage Link
+ */
+class Text_Plain_Link extends TextLinkTransformationsPlugin
+{
+    /**
+     * Gets the plugin`s MIME type
+     *
+     * @return string
+     */
+    public static function getMIMEType()
+    {
+        return "Text";
+    }
+
+    /**
+     * Gets the plugin`s MIME subtype
+     *
+     * @return string
+     */
+    public static function getMIMESubtype()
+    {
+        return "Plain";
+    }
+}
+
+/**
+ * Function to call Text_Plain_Link::getInfo();
+ *
+ * Temporary workaround for bug #3783 :
+ * Calling a method from a variable class is not possible before PHP 5.3.
+ *
+ * This function is called by PMA_getTransformationDescription()
+ * in libraries/transformations.lib.php using a variable to construct it's name.
+ * This function then calls the static method.
+ *
+ * Don't use this function unless you are affected by the same issue.
+ * Call the static method directly instead.
+ *
+ * @deprecated
+ * @return string Info about transformation class
+ */
+function Text_Plain_Link_getInfo()
+{
+    return Text_Plain_Link::getInfo();
+}
+?>
diff --git a/phpmyadmin/libraries/plugins/transformations/Text_Plain_Longtoipv4.class.php b/phpmyadmin/libraries/plugins/transformations/Text_Plain_Longtoipv4.class.php
new file mode 100644
index 0000000..44eea50
--- /dev/null
+++ b/phpmyadmin/libraries/plugins/transformations/Text_Plain_Longtoipv4.class.php
@@ -0,0 +1,65 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * Text Plain Long To IPv4 Transformations plugin for phpMyAdmin
+ *
+ * @package    PhpMyAdmin-Transformations
+ * @subpackage LongToIPv4
+ */
+if (! defined('PHPMYADMIN')) {
+    exit;
+}
+
+/* Get the long to ipv4 transformations interface */
+require_once 'abstract/LongToIPv4TransformationsPlugin.class.php';
+
+/**
+ * Handles the long to ipv4 transformation for text plain
+ *
+ * @package    PhpMyAdmin-Transformations
+ * @subpackage LongToIPv4
+ */
+class Text_Plain_Longtoipv4 extends LongToIPv4TransformationsPlugin
+{
+    /**
+     * Gets the plugin`s MIME type
+     *
+     * @return string
+     */
+    public static function getMIMEType()
+    {
+        return "Text";
+    }
+
+    /**
+     * Gets the plugin`s MIME subtype
+     *
+     * @return string
+     */
+    public static function getMIMESubtype()
+    {
+        return "Plain";
+    }
+}
+
+/**
+ * Function to call Text_Plain_Longtoipv4::getInfo();
+ *
+ * Temporary workaround for bug #3783 :
+ * Calling a method from a variable class is not possible before PHP 5.3.
+ *
+ * This function is called by PMA_getTransformationDescription()
+ * in libraries/transformations.lib.php using a variable to construct it's name.
+ * This function then calls the static method.
+ *
+ * Don't use this function unless you are affected by the same issue.
+ * Call the static method directly instead.
+ *
+ * @deprecated
+ * @return string Info about transformation class
+ */
+function Text_Plain_Longtoipv4_getInfo()
+{
+    return Text_Plain_Longtoipv4::getInfo();
+}
+?>
diff --git a/phpmyadmin/libraries/plugins/transformations/Text_Plain_Sql.class.php b/phpmyadmin/libraries/plugins/transformations/Text_Plain_Sql.class.php
new file mode 100644
index 0000000..cc92491
--- /dev/null
+++ b/phpmyadmin/libraries/plugins/transformations/Text_Plain_Sql.class.php
@@ -0,0 +1,65 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * Text Plain SQL Transformations plugin for phpMyAdmin
+ *
+ * @package    PhpMyAdmin-Transformations
+ * @subpackage SQL
+ */
+if (! defined('PHPMYADMIN')) {
+    exit;
+}
+
+/* Get the sql transformations interface */
+require_once 'abstract/SQLTransformationsPlugin.class.php';
+
+/**
+ * Handles the sql transformation for text plain
+ *
+ * @package    PhpMyAdmin-Transformations
+ * @subpackage SQL
+ */
+class Text_Plain_Sql extends SQLTransformationsPlugin
+{
+    /**
+     * Gets the plugin`s MIME type
+     *
+     * @return string
+     */
+    public static function getMIMEType()
+    {
+        return "Text";
+    }
+
+    /**
+     * Gets the plugin`s MIME subtype
+     *
+     * @return string
+     */
+    public static function getMIMESubtype()
+    {
+        return "Plain";
+    }
+}
+
+/**
+ * Function to call Text_Plain_Sql::getInfo();
+ *
+ * Temporary workaround for bug #3783 :
+ * Calling a method from a variable class is not possible before PHP 5.3.
+ *
+ * This function is called by PMA_getTransformationDescription()
+ * in libraries/transformations.lib.php using a variable to construct it's name.
+ * This function then calls the static method.
+ *
+ * Don't use this function unless you are affected by the same issue.
+ * Call the static method directly instead.
+ *
+ * @deprecated
+ * @return string Info about transformation class
+ */
+function Text_Plain_Sql_getInfo()
+{
+    return Text_Plain_Sql::getInfo();
+}
+?>
diff --git a/phpmyadmin/libraries/plugins/transformations/Text_Plain_Substring.class.php b/phpmyadmin/libraries/plugins/transformations/Text_Plain_Substring.class.php
new file mode 100644
index 0000000..b04231f
--- /dev/null
+++ b/phpmyadmin/libraries/plugins/transformations/Text_Plain_Substring.class.php
@@ -0,0 +1,65 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * Text Plain Substring Transformations plugin for phpMyAdmin
+ *
+ * @package    PhpMyAdmin-Transformations
+ * @subpackage Substring
+ */
+if (! defined('PHPMYADMIN')) {
+    exit;
+}
+
+/* Get the substring transformations interface */
+require_once 'abstract/SubstringTransformationsPlugin.class.php';
+
+/**
+ * Handles the substring transformation for text plain
+ *
+ * @package    PhpMyAdmin-Transformations
+ * @subpackage Substring
+ */
+class Text_Plain_Substring extends SubstringTransformationsPlugin
+{
+    /**
+     * Gets the plugin`s MIME type
+     *
+     * @return string
+     */
+    public static function getMIMEType()
+    {
+        return "Text";
+    }
+
+    /**
+     * Gets the plugin`s MIME subtype
+     *
+     * @return string
+     */
+    public static function getMIMESubtype()
+    {
+        return "Plain";
+    }
+}
+
+/**
+ * Function to call Text_Plain_Substring::getInfo();
+ *
+ * Temporary workaround for bug #3783 :
+ * Calling a method from a variable class is not possible before PHP 5.3.
+ *
+ * This function is called by PMA_getTransformationDescription()
+ * in libraries/transformations.lib.php using a variable to construct it's name.
+ * This function then calls the static method.
+ *
+ * Don't use this function unless you are affected by the same issue.
+ * Call the static method directly instead.
+ *
+ * @deprecated
+ * @return string Info about transformation class
+ */
+function Text_Plain_Substring_getInfo()
+{
+    return Text_Plain_Substring::getInfo();
+}
+?>
diff --git a/phpmyadmin/libraries/plugins/transformations/abstract/AppendTransformationsPlugin.class.php b/phpmyadmin/libraries/plugins/transformations/abstract/AppendTransformationsPlugin.class.php
new file mode 100644
index 0000000..0fc3b4d
--- /dev/null
+++ b/phpmyadmin/libraries/plugins/transformations/abstract/AppendTransformationsPlugin.class.php
@@ -0,0 +1,86 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * Abstract class for the append transformations plugins
+ *
+ * @package    PhpMyAdmin-Transformations
+ * @subpackage Append
+ */
+if (! defined('PHPMYADMIN')) {
+    exit;
+}
+
+/* Get the transformations interface */
+require_once 'libraries/plugins/TransformationsPlugin.class.php';
+
+/**
+ * Provides common methods for all of the append transformations plugins.
+ *
+ * @package    PhpMyAdmin-Transformations
+ * @subpackage Append
+ */
+abstract class AppendTransformationsPlugin extends TransformationsPlugin
+{
+    /**
+     * Gets the transformation description of the specific plugin
+     *
+     * @return string
+     */
+    public static function getInfo()
+    {
+        return __(
+            'Appends text to a string. The only option is the text to be appended'
+            . ' (enclosed in single quotes, default empty string).'
+        );
+    }
+
+    /**
+     * Does the actual work of each specific transformations plugin.
+     *
+     * @param string $buffer  text to be transformed
+     * @param array  $options transformation options
+     * @param string $meta    meta information
+     *
+     * @return void
+     */
+    public function applyTransformation($buffer, $options = array(), $meta = '')
+    {
+        if (! isset($options[0]) ||  $options[0] == '') {
+            $options[0] = '';
+        }
+        //just append the option to the original text
+        $newtext = $buffer . htmlspecialchars($options[0]);
+
+        return $newtext;
+    }
+
+    /**
+     * This method is called when any PluginManager to which the observer
+     * is attached calls PluginManager::notify()
+     *
+     * @param SplSubject $subject The PluginManager notifying the observer
+     *                            of an update.
+     *
+     * @todo implement
+     * @return void
+     */
+    public function update (SplSubject $subject)
+    {
+        ;
+    }
+
+
+    /* ~~~~~~~~~~~~~~~~~~~~ Getters and Setters ~~~~~~~~~~~~~~~~~~~~ */
+
+
+    /**
+     * Gets the transformation name of the specific plugin
+     *
+     * @return string
+     */
+    public static function getName()
+    {
+        return "Append";
+    }
+}
+?>
\ No newline at end of file
diff --git a/phpmyadmin/libraries/plugins/transformations/abstract/DateFormatTransformationsPlugin.class.php b/phpmyadmin/libraries/plugins/transformations/abstract/DateFormatTransformationsPlugin.class.php
new file mode 100644
index 0000000..530379f
--- /dev/null
+++ b/phpmyadmin/libraries/plugins/transformations/abstract/DateFormatTransformationsPlugin.class.php
@@ -0,0 +1,178 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * Abstract class for the date format transformations plugins
+ *
+ * @package    PhpMyAdmin-Transformations
+ * @subpackage DateFormat
+ */
+if (! defined('PHPMYADMIN')) {
+    exit;
+}
+
+/* Get the transformations interface */
+require_once 'libraries/plugins/TransformationsPlugin.class.php';
+
+/**
+ * Provides common methods for all of the date format transformations plugins.
+ *
+ * @package PhpMyAdmin
+ */
+abstract class DateFormatTransformationsPlugin extends TransformationsPlugin
+{
+    /**
+     * Gets the transformation description of the specific plugin
+     *
+     * @return string
+     */
+    public static function getInfo()
+    {
+        return __(
+            'Displays a TIME, TIMESTAMP, DATETIME or numeric unix timestamp'
+            . ' column as formatted date. The first option is the offset (in'
+            . ' hours) which will be added to the timestamp (Default: 0). Use'
+            . ' second option to specify a different date/time format string.'
+            . ' Third option determines whether you want to see local date or'
+            . ' UTC one (use "local" or "utc" strings) for that. According to'
+            . ' that, date format has different value - for "local" see the'
+            . ' documentation for PHP\'s strftime() function and for "utc" it'
+            . ' is done using gmdate() function.'
+        );
+    }
+
+    /**
+     * Does the actual work of each specific transformations plugin.
+     *
+     * @param string $buffer  text to be transformed
+     * @param array  $options transformation options
+     * @param string $meta    meta information
+     *
+     * @return void
+     */
+    public function applyTransformation($buffer, $options = array(), $meta = '')
+    {
+        // possibly use a global transform and feed it with special options
+
+        // further operations on $buffer using the $options[] array.
+        if (empty($options[0])) {
+            $options[0] = 0;
+        }
+
+        if (empty($options[2])) {
+            $options[2] = 'local';
+        } else {
+            $options[2] = strtolower($options[2]);
+        }
+
+        if (empty($options[1])) {
+            if ($options[2] == 'local') {
+                $options[1] = __('%B %d, %Y at %I:%M %p');
+            } else {
+                $options[1] = 'Y-m-d  H:i:s';
+            }
+        }
+
+        $timestamp = -1;
+
+        // INT columns will be treated as UNIX timestamps
+        // and need to be detected before the verification for
+        // MySQL TIMESTAMP
+        if ($meta->type == 'int') {
+            $timestamp = $buffer;
+
+            // Detect TIMESTAMP(6 | 8 | 10 | 12 | 14)
+            // TIMESTAMP (2 | 4) not supported here.
+            // (Note: prior to MySQL 4.1, TIMESTAMP has a display size
+            // for example TIMESTAMP(8) means YYYYMMDD)
+        } else if (preg_match('/^(\d{2}){3,7}$/', $buffer)) {
+
+            if (strlen($buffer) == 14 || strlen($buffer) == 8) {
+                $offset = 4;
+            } else {
+                $offset = 2;
+            }
+
+            $d = array();
+            $d['year']   = substr($buffer, 0, $offset);
+            $d['month']  = substr($buffer, $offset, 2);
+            $d['day']    = substr($buffer, $offset + 2, 2);
+            $d['hour']   = substr($buffer, $offset + 4, 2);
+            $d['minute'] = substr($buffer, $offset + 6, 2);
+            $d['second'] = substr($buffer, $offset + 8, 2);
+
+            if (checkdate($d['month'], $d['day'], $d['year'])) {
+                $timestamp = mktime(
+                    $d['hour'],
+                    $d['minute'],
+                    $d['second'],
+                    $d['month'],
+                    $d['day'],
+                    $d['year']
+                );
+            }
+            // If all fails, assume one of the dozens of valid strtime() syntaxes
+            // (http://www.gnu.org/manual/tar-1.12/html_chapter/tar_7.html)
+        } else {
+            if (preg_match('/^[0-9]\d{1,9}$/', $buffer)) {
+                $timestamp = (int)$buffer;
+            } else {
+                $timestamp = strtotime($buffer);
+            }
+        }
+
+        // If all above failed, maybe it's a Unix timestamp already?
+        if ($timestamp < 0 && preg_match('/^[1-9]\d{1,9}$/', $buffer)) {
+            $timestamp = $buffer;
+        }
+
+        // Reformat a valid timestamp
+        if ($timestamp >= 0) {
+            $timestamp -= $options[0] * 60 * 60;
+            $source = $buffer;
+            if ($options[2] == 'local') {
+                $text = PMA_Util::localisedDate(
+                    $timestamp,
+                    $options[1]
+                );
+            } elseif ($options[2] == 'utc') {
+                $text = gmdate($options[1], $timestamp);
+            } else {
+                $text = 'INVALID DATE TYPE';
+            }
+            $buffer = '<dfn onclick="alert(\'' . $source . '\');" title="'
+                . $source . '">' . $text . '</dfn>';
+        }
+
+        return $buffer;
+    }
+
+    /**
+     * This method is called when any PluginManager to which the observer
+     * is attached calls PluginManager::notify()
+     *
+     * @param SplSubject $subject The PluginManager notifying the observer
+     *                            of an update.
+     *
+     * @todo implement
+     * @return void
+     */
+    public function update (SplSubject $subject)
+    {
+        ;
+    }
+
+
+    /* ~~~~~~~~~~~~~~~~~~~~ Getters and Setters ~~~~~~~~~~~~~~~~~~~~ */
+
+
+    /**
+     * Gets the transformation name of the specific plugin
+     *
+     * @return string
+     */
+    public static function getName()
+    {
+        return "Date Format";
+    }
+}
+?>
\ No newline at end of file
diff --git a/phpmyadmin/libraries/plugins/transformations/abstract/DownloadTransformationsPlugin.class.php b/phpmyadmin/libraries/plugins/transformations/abstract/DownloadTransformationsPlugin.class.php
new file mode 100644
index 0000000..82eda40
--- /dev/null
+++ b/phpmyadmin/libraries/plugins/transformations/abstract/DownloadTransformationsPlugin.class.php
@@ -0,0 +1,110 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * Abstract class for the download transformations plugins
+ *
+ * @package    PhpMyAdmin-Transformations
+ * @subpackage Download
+ */
+if (! defined('PHPMYADMIN')) {
+    exit;
+}
+
+/* Get the transformations interface */
+require_once 'libraries/plugins/TransformationsPlugin.class.php';
+
+/**
+ * Provides common methods for all of the download transformations plugins.
+ *
+ * @package PhpMyAdmin
+ */
+abstract class DownloadTransformationsPlugin extends TransformationsPlugin
+{
+    /**
+     * Gets the transformation description of the specific plugin
+     *
+     * @return string
+     */
+    public static function getInfo()
+    {
+        return __(
+            'Displays a link to download the binary data of the column. You can'
+            . ' use the first option to specify the filename, or use the second'
+            . ' option as the name of a column which contains the filename. If'
+            . ' you use the second option, you need to set the first option to'
+            . ' the empty string.'
+        );
+    }
+
+    /**
+     * Does the actual work of each specific transformations plugin.
+     *
+     * @param string $buffer  text to be transformed
+     * @param array  $options transformation options
+     * @param string $meta    meta information
+     *
+     * @return void
+     */
+    public function applyTransformation($buffer, $options = array(), $meta = '')
+    {
+        global $row, $fields_meta;
+
+        if (isset($options[0]) && !empty($options[0])) {
+            $cn = $options[0]; // filename
+        } else {
+            if (isset($options[1]) && !empty($options[1])) {
+                foreach ($fields_meta as $key => $val) {
+                    if ($val->name == $options[1]) {
+                        $pos = $key;
+                        break;
+                    }
+                }
+                if (isset($pos)) {
+                    $cn = $row[$pos];
+                }
+            }
+            if (empty($cn)) {
+                $cn = 'binary_file.dat';
+            }
+        }
+
+        return sprintf(
+            '<a href="transformation_wrapper.php%s&ct=application'
+            . '/octet-stream&cn=%s" title="%s">%s</a>',
+            $options['wrapper_link'],
+            urlencode($cn),
+            htmlspecialchars($cn),
+            htmlspecialchars($cn)
+        );
+    }
+
+    /**
+     * This method is called when any PluginManager to which the observer
+     * is attached calls PluginManager::notify()
+     *
+     * @param SplSubject $subject The PluginManager notifying the observer
+     *                            of an update.
+     *
+     * @todo implement
+     * @return void
+     */
+    public function update (SplSubject $subject)
+    {
+        ;
+    }
+
+
+    /* ~~~~~~~~~~~~~~~~~~~~ Getters and Setters ~~~~~~~~~~~~~~~~~~~~ */
+
+
+    /**
+     * Gets the transformation name of the specific plugin
+     *
+     * @return string
+     */
+    public static function getName()
+    {
+        return "Download";
+    }
+}
+?>
\ No newline at end of file
diff --git a/phpmyadmin/libraries/plugins/transformations/abstract/ExternalTransformationsPlugin.class.php b/phpmyadmin/libraries/plugins/transformations/abstract/ExternalTransformationsPlugin.class.php
new file mode 100644
index 0000000..f93f069
--- /dev/null
+++ b/phpmyadmin/libraries/plugins/transformations/abstract/ExternalTransformationsPlugin.class.php
@@ -0,0 +1,182 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * Abstract class for the external transformations plugins
+ *
+ * @package    PhpMyAdmin-Transformations
+ * @subpackage External
+ */
+if (! defined('PHPMYADMIN')) {
+    exit;
+}
+
+/* Get the transformations interface */
+require_once 'libraries/plugins/TransformationsPlugin.class.php';
+
+/**
+ * Provides common methods for all of the external transformations plugins.
+ *
+ * @package PhpMyAdmin
+ */
+abstract class ExternalTransformationsPlugin extends TransformationsPlugin
+{
+    /**
+     * Gets the transformation description of the specific plugin
+     *
+     * @return string
+     */
+    public static function getInfo()
+    {
+        return __(
+            'LINUX ONLY: Launches an external application and feeds it the column'
+            . ' data via standard input. Returns the standard output of the'
+            . ' application. The default is Tidy, to pretty-print HTML code.'
+            . ' For security reasons, you have to manually edit the file'
+            . ' libraries/plugins/transformations/Text_Plain_External'
+            . '.class.php and list the tools you want to make available.'
+            . ' The first option is then the number of the program you want to'
+            . ' use and the second option is the parameters for the program.'
+            . ' The third option, if set to 1, will convert the output using'
+            . ' htmlspecialchars() (Default 1). The fourth option, if set to 1,'
+            . ' will prevent wrapping and ensure that the output appears all on'
+            . ' one line (Default 1).'
+        );
+    }
+
+    /**
+     * Enables no-wrapping
+     *
+     * @param array $options transformation options
+     *
+     * @return bool
+     */
+    public function applyTransformationNoWrap($options = array())
+    {
+        if (! isset($options[3]) || $options[3] == '') {
+            $nowrap = true;
+        } elseif ($options[3] == '1' || $options[3] == 1) {
+            $nowrap = true;
+        } else {
+            $nowrap = false;
+        }
+
+        return $nowrap;
+    }
+
+    /**
+     * Does the actual work of each specific transformations plugin.
+     *
+     * @param string $buffer  text to be transformed
+     * @param array  $options transformation options
+     * @param string $meta    meta information
+     *
+     * @return void
+     */
+    public function applyTransformation($buffer, $options = array(), $meta = '')
+    {
+        // possibly use a global transform and feed it with special options
+
+        // further operations on $buffer using the $options[] array.
+
+        $allowed_programs = array();
+
+        //
+        // WARNING:
+        //
+        // It's up to administrator to allow anything here. Note that users may
+        // specify any parameters, so when programs allow output redirection or
+        // any other possibly dangerous operations, you should write wrapper
+        // script that will publish only functions you really want.
+        //
+        // Add here program definitions like (note that these are NOT safe
+        // programs):
+        //
+        //$allowed_programs[0] = '/usr/local/bin/tidy';
+        //$allowed_programs[1] = '/usr/local/bin/validate';
+
+        // no-op when no allowed programs
+        if (count($allowed_programs) == 0) {
+            return $buffer;
+        }
+
+        if (! isset($options[0])
+            || $options[0] == ''
+            || ! isset($allowed_programs[$options[0]])
+        ) {
+            $program = $allowed_programs[0];
+        } else {
+            $program = $allowed_programs[$options[0]];
+        }
+
+        if (!isset($options[1]) || $options[1] == '') {
+            $poptions = '-f /dev/null -i -wrap -q';
+        } else {
+            $poptions = $options[1];
+        }
+
+        if (!isset($options[2]) || $options[2] == '') {
+            $options[2] = 1;
+        }
+
+        if (!isset($options[3]) || $options[3] == '') {
+            $options[3] = 1;
+        }
+
+        // needs PHP >= 4.3.0
+        $newstring = '';
+        $descriptorspec = array(
+            0 => array("pipe", "r"),
+            1 => array("pipe", "w")
+        );
+        $process = proc_open($program . ' ' . $poptions, $descriptorspec, $pipes);
+        if (is_resource($process)) {
+            fwrite($pipes[0], $buffer);
+            fclose($pipes[0]);
+
+            while (!feof($pipes[1])) {
+                $newstring .= fgets($pipes[1], 1024);
+            }
+            fclose($pipes[1]);
+            // we don't currently use the return value
+            proc_close($process);
+        }
+
+        if ($options[2] == 1 || $options[2] == '2') {
+            $retstring = htmlspecialchars($newstring);
+        } else {
+            $retstring = $newstring;
+        }
+
+        return $retstring;
+    }
+
+    /**
+     * This method is called when any PluginManager to which the observer
+     * is attached calls PluginManager::notify()
+     *
+     * @param SplSubject $subject The PluginManager notifying the observer
+     *                            of an update.
+     *
+     * @todo implement
+     * @return void
+     */
+    public function update (SplSubject $subject)
+    {
+        ;
+    }
+
+
+    /* ~~~~~~~~~~~~~~~~~~~~ Getters and Setters ~~~~~~~~~~~~~~~~~~~~ */
+
+
+    /**
+     * Gets the transformation name of the specific plugin
+     *
+     * @return string
+     */
+    public static function getName()
+    {
+        return "External";
+    }
+}
+?>
\ No newline at end of file
diff --git a/phpmyadmin/libraries/plugins/transformations/abstract/FormattedTransformationsPlugin.class.php b/phpmyadmin/libraries/plugins/transformations/abstract/FormattedTransformationsPlugin.class.php
new file mode 100644
index 0000000..e6bb8d9
--- /dev/null
+++ b/phpmyadmin/libraries/plugins/transformations/abstract/FormattedTransformationsPlugin.class.php
@@ -0,0 +1,80 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * Abstract class for the formatted transformations plugins
+ *
+ * @package    PhpMyAdmin-Transformations
+ * @subpackage Formatted
+ */
+if (! defined('PHPMYADMIN')) {
+    exit;
+}
+
+/* Get the transformations interface */
+require_once 'libraries/plugins/TransformationsPlugin.class.php';
+
+/**
+ * Provides common methods for all of the formatted transformations plugins.
+ *
+ * @package PhpMyAdmin
+ */
+abstract class FormattedTransformationsPlugin extends TransformationsPlugin
+{
+    /**
+     * Gets the transformation description of the specific plugin
+     *
+     * @return string
+     */
+    public static function getInfo()
+    {
+        return __(
+            'Displays the contents of the column as-is, without running it'
+            . ' through htmlspecialchars(). That is, the column is assumed'
+            . ' to contain valid HTML.'
+        );
+    }
+
+    /**
+     * Does the actual work of each specific transformations plugin.
+     *
+     * @param string $buffer  text to be transformed
+     * @param array  $options transformation options
+     * @param string $meta    meta information
+     *
+     * @return void
+     */
+    public function applyTransformation($buffer, $options = array(), $meta = '')
+    {
+        return $buffer;
+    }
+
+    /**
+     * This method is called when any PluginManager to which the observer
+     * is attached calls PluginManager::notify()
+     *
+     * @param SplSubject $subject The PluginManager notifying the observer
+     *                            of an update.
+     *
+     * @todo implement
+     * @return void
+     */
+    public function update (SplSubject $subject)
+    {
+        ;
+    }
+
+
+    /* ~~~~~~~~~~~~~~~~~~~~ Getters and Setters ~~~~~~~~~~~~~~~~~~~~ */
+
+
+    /**
+     * Gets the transformation name of the specific plugin
+     *
+     * @return string
+     */
+    public static function getName()
+    {
+        return "Formatted";
+    }
+}
+?>
\ No newline at end of file
diff --git a/phpmyadmin/libraries/plugins/transformations/abstract/HexTransformationsPlugin.class.php b/phpmyadmin/libraries/plugins/transformations/abstract/HexTransformationsPlugin.class.php
new file mode 100644
index 0000000..8022da9
--- /dev/null
+++ b/phpmyadmin/libraries/plugins/transformations/abstract/HexTransformationsPlugin.class.php
@@ -0,0 +1,91 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * Abstract class for the hex transformations plugins
+ *
+ * @package    PhpMyAdmin-Transformations
+ * @subpackage Hex
+ */
+if (! defined('PHPMYADMIN')) {
+    exit;
+}
+
+/* Get the transformations interface */
+require_once 'libraries/plugins/TransformationsPlugin.class.php';
+
+/**
+ * Provides common methods for all of the hex transformations plugins.
+ *
+ * @package PhpMyAdmin
+ */
+abstract class HexTransformationsPlugin extends TransformationsPlugin
+{
+    /**
+     * Gets the transformation description of the specific plugin
+     *
+     * @return string
+     */
+    public static function getInfo()
+    {
+        return __(
+            'Displays hexadecimal representation of data. Optional first'
+            . ' parameter specifies how often space will be added (defaults'
+            . ' to 2 nibbles).'
+        );
+    }
+
+    /**
+     * Does the actual work of each specific transformations plugin.
+     *
+     * @param string $buffer  text to be transformed
+     * @param array  $options transformation options
+     * @param string $meta    meta information
+     *
+     * @return void
+     */
+    public function applyTransformation($buffer, $options = array(), $meta = '')
+    {
+        // possibly use a global transform and feed it with special options
+        if (!isset($options[0])) {
+            $options[0] = 2;
+        } else {
+            $options[0] = (int)$options[0];
+        }
+
+        if ($options[0] < 1) {
+            return bin2hex($buffer);
+        } else {
+            return chunk_split(bin2hex($buffer), $options[0], ' ');
+        }
+    }
+
+    /**
+     * This method is called when any PluginManager to which the observer
+     * is attached calls PluginManager::notify()
+     *
+     * @param SplSubject $subject The PluginManager notifying the observer
+     *                            of an update.
+     *
+     * @todo implement
+     * @return void
+     */
+    public function update (SplSubject $subject)
+    {
+        ;
+    }
+
+
+    /* ~~~~~~~~~~~~~~~~~~~~ Getters and Setters ~~~~~~~~~~~~~~~~~~~~ */
+
+
+    /**
+     * Gets the transformation name of the specific plugin
+     *
+     * @return string
+     */
+    public static function getName()
+    {
+        return "Hex";
+    }
+}
+?>
\ No newline at end of file
diff --git a/phpmyadmin/libraries/plugins/transformations/abstract/ImageLinkTransformationsPlugin.class.php b/phpmyadmin/libraries/plugins/transformations/abstract/ImageLinkTransformationsPlugin.class.php
new file mode 100644
index 0000000..456f102
--- /dev/null
+++ b/phpmyadmin/libraries/plugins/transformations/abstract/ImageLinkTransformationsPlugin.class.php
@@ -0,0 +1,89 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * Abstract class for the link transformations plugins
+ *
+ * @package    PhpMyAdmin-Transformations
+ * @subpackage Link
+ */
+if (! defined('PHPMYADMIN')) {
+    exit;
+}
+
+/* Get the transformations interface */
+require_once 'libraries/plugins/TransformationsPlugin.class.php';
+/* For PMA_transformation_global_html_replace */
+require_once 'libraries/transformations.lib.php';
+
+/**
+ * Provides common methods for all of the link transformations plugins.
+ *
+ * @package PhpMyAdmin
+ */
+abstract class ImageLinkTransformationsPlugin extends TransformationsPlugin
+{
+    /**
+     * Gets the transformation description of the specific plugin
+     *
+     * @return string
+     */
+    public static function getInfo()
+    {
+        return __(
+            'Displays a link to download this image.'
+        );
+    }
+
+    /**
+     * Does the actual work of each specific transformations plugin.
+     *
+     * @param string $buffer  text to be transformed
+     * @param array  $options transformation options
+     * @param string $meta    meta information
+     *
+     * @return void
+     */
+    public function applyTransformation($buffer, $options = array(), $meta = '')
+    {
+        $transform_options = array (
+            'string' => '<a href="transformation_wrapper.php'
+                . $options['wrapper_link'] . '" alt="[__BUFFER__]">[BLOB]</a>'
+        );
+        $buffer = PMA_transformation_global_html_replace(
+            $buffer,
+            $transform_options
+        );
+
+        return $buffer;
+    }
+
+    /**
+     * This method is called when any PluginManager to which the observer
+     * is attached calls PluginManager::notify()
+     *
+     * @param SplSubject $subject The PluginManager notifying the observer
+     *                            of an update.
+     *
+     * @todo implement
+     * @return void
+     */
+    public function update (SplSubject $subject)
+    {
+        ;
+    }
+
+
+    /* ~~~~~~~~~~~~~~~~~~~~ Getters and Setters ~~~~~~~~~~~~~~~~~~~~ */
+
+
+    /**
+     * Gets the transformation name of the specific plugin
+     *
+     * @return string
+     */
+    public static function getName()
+    {
+        return "Link";
+    }
+}
+?>
diff --git a/phpmyadmin/libraries/plugins/transformations/abstract/InlineTransformationsPlugin.class.php b/phpmyadmin/libraries/plugins/transformations/abstract/InlineTransformationsPlugin.class.php
new file mode 100644
index 0000000..b1ef0ae
--- /dev/null
+++ b/phpmyadmin/libraries/plugins/transformations/abstract/InlineTransformationsPlugin.class.php
@@ -0,0 +1,103 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * Abstract class for the inline transformations plugins
+ *
+ * @package    PhpMyAdmin-Transformations
+ * @subpackage Inline
+ */
+if (! defined('PHPMYADMIN')) {
+    exit;
+}
+
+/* Get the transformations interface */
+require_once 'libraries/plugins/TransformationsPlugin.class.php';
+/* For PMA_transformation_global_html_replace */
+require_once 'libraries/transformations.lib.php';
+
+/**
+ * Provides common methods for all of the inline transformations plugins.
+ *
+ * @package PhpMyAdmin
+ */
+abstract class InlineTransformationsPlugin extends TransformationsPlugin
+{
+    /**
+     * Gets the transformation description of the specific plugin
+     *
+     * @return string
+     */
+    public static function getInfo()
+    {
+        return __(
+            'Displays a clickable thumbnail. The options are the maximum width'
+            . ' and height in pixels. The original aspect ratio is preserved.'
+        );
+    }
+
+    /**
+     * Does the actual work of each specific transformations plugin.
+     *
+     * @param string $buffer  text to be transformed
+     * @param array  $options transformation options
+     * @param string $meta    meta information
+     *
+     * @return void
+     */
+    public function applyTransformation($buffer, $options = array(), $meta = '')
+    {
+        if (PMA_IS_GD2) {
+            $transform_options = array (
+                'string' => '<a href="transformation_wrapper.php'
+                    . $options['wrapper_link']
+                    . '" target="_blank"><img src="transformation_wrapper.php'
+                    . $options['wrapper_link'] . '&resize=jpeg&newWidth='
+                    . (isset($options[0]) ? $options[0] : '100') . '&newHeight='
+                    . (isset($options[1]) ? $options[1] : 100)
+                    . '" alt="[__BUFFER__]" border="0" /></a>'
+            );
+        } else {
+            $transform_options = array (
+                'string' => '<img src="transformation_wrapper.php'
+                . $options['wrapper_link']
+                . '" alt="[__BUFFER__]" width="320" height="240" />'
+            );
+        }
+        $buffer = PMA_transformation_global_html_replace(
+            $buffer,
+            $transform_options
+        );
+
+        return $buffer;
+    }
+
+    /**
+     * This method is called when any PluginManager to which the observer
+     * is attached calls PluginManager::notify()
+     *
+     * @param SplSubject $subject The PluginManager notifying the observer
+     *                            of an update.
+     *
+     * @todo implement
+     * @return void
+     */
+    public function update (SplSubject $subject)
+    {
+        ;
+    }
+
+
+    /* ~~~~~~~~~~~~~~~~~~~~ Getters and Setters ~~~~~~~~~~~~~~~~~~~~ */
+
+
+    /**
+     * Gets the transformation name of the specific plugin
+     *
+     * @return string
+     */
+    public static function getName()
+    {
+        return "Inline";
+    }
+}
+?>
diff --git a/phpmyadmin/libraries/plugins/transformations/abstract/LongToIPv4TransformationsPlugin.class.php b/phpmyadmin/libraries/plugins/transformations/abstract/LongToIPv4TransformationsPlugin.class.php
new file mode 100644
index 0000000..58dda95
--- /dev/null
+++ b/phpmyadmin/libraries/plugins/transformations/abstract/LongToIPv4TransformationsPlugin.class.php
@@ -0,0 +1,83 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * Abstract class for the long to IPv4 transformations plugins
+ *
+ * @package    PhpMyAdmin-Transformations
+ * @subpackage LongToIPv4
+ */
+if (! defined('PHPMYADMIN')) {
+    exit;
+}
+
+/* Get the transformations interface */
+require_once 'libraries/plugins/TransformationsPlugin.class.php';
+
+/**
+ * Provides common methods for all of the long to IPv4 transformations plugins.
+ *
+ * @package PhpMyAdmin
+ */
+abstract class LongToIPv4TransformationsPlugin extends TransformationsPlugin
+{
+    /**
+     * Gets the transformation description of the specific plugin
+     *
+     * @return string
+     */
+    public static function getInfo()
+    {
+        return __(
+            'Converts an (IPv4) Internet network address into a string in'
+            . ' Internet standard dotted format.'
+        );
+    }
+
+    /**
+     * Does the actual work of each specific transformations plugin.
+     *
+     * @param string $buffer  text to be transformed
+     * @param array  $options transformation options
+     * @param string $meta    meta information
+     *
+     * @return void
+     */
+    public function applyTransformation($buffer, $options = array(), $meta = '')
+    {
+        if ($buffer < 0 || $buffer > 4294967295) {
+            return $buffer;
+        }
+
+        return long2ip($buffer);
+    }
+
+    /**
+     * This method is called when any PluginManager to which the observer
+     * is attached calls PluginManager::notify()
+     *
+     * @param SplSubject $subject The PluginManager notifying the observer
+     *                            of an update.
+     *
+     * @todo implement
+     * @return void
+     */
+    public function update (SplSubject $subject)
+    {
+        ;
+    }
+
+
+    /* ~~~~~~~~~~~~~~~~~~~~ Getters and Setters ~~~~~~~~~~~~~~~~~~~~ */
+
+
+    /**
+     * Gets the transformation name of the specific plugin
+     *
+     * @return string
+     */
+    public static function getName()
+    {
+        return "Long To IPv4";
+    }
+}
+?>
\ No newline at end of file
diff --git a/phpmyadmin/libraries/plugins/transformations/abstract/SQLTransformationsPlugin.class.php b/phpmyadmin/libraries/plugins/transformations/abstract/SQLTransformationsPlugin.class.php
new file mode 100644
index 0000000..2123cdb
--- /dev/null
+++ b/phpmyadmin/libraries/plugins/transformations/abstract/SQLTransformationsPlugin.class.php
@@ -0,0 +1,81 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * Abstract class for the SQL transformations plugins
+ *
+ * @package    PhpMyAdmin-Transformations
+ * @subpackage SQL
+ */
+if (! defined('PHPMYADMIN')) {
+    exit;
+}
+
+/* Get the transformations interface */
+require_once 'libraries/plugins/TransformationsPlugin.class.php';
+
+/**
+ * Provides common methods for all of the SQL transformations plugins.
+ *
+ * @package PhpMyAdmin
+ */
+abstract class SQLTransformationsPlugin extends TransformationsPlugin
+{
+    /**
+     * Gets the transformation description of the specific plugin
+     *
+     * @return string
+     */
+    public static function getInfo()
+    {
+        return __(
+            'Formats text as SQL query with syntax highlighting.'
+        );
+    }
+
+    /**
+     * Does the actual work of each specific transformations plugin.
+     *
+     * @param string $buffer  text to be transformed
+     * @param array  $options transformation options
+     * @param string $meta    meta information
+     *
+     * @return void
+     */
+    public function applyTransformation($buffer, $options = array(), $meta = '')
+    {
+        $result = PMA_SQP_formatHtml(PMA_SQP_parse($buffer));
+        // Need to clear error state not to break subsequent queries display.
+        PMA_SQP_resetError();
+        return $result;
+    }
+
+    /**
+     * This method is called when any PluginManager to which the observer
+     * is attached calls PluginManager::notify()
+     *
+     * @param SplSubject $subject The PluginManager notifying the observer
+     *                            of an update.
+     *
+     * @todo implement
+     * @return void
+     */
+    public function update (SplSubject $subject)
+    {
+        ;
+    }
+
+
+    /* ~~~~~~~~~~~~~~~~~~~~ Getters and Setters ~~~~~~~~~~~~~~~~~~~~ */
+
+
+    /**
+     * Gets the transformation name of the specific plugin
+     *
+     * @return string
+     */
+    public static function getName()
+    {
+        return "SQL";
+    }
+}
+?>
\ No newline at end of file
diff --git a/phpmyadmin/libraries/plugins/transformations/abstract/SubstringTransformationsPlugin.class.php b/phpmyadmin/libraries/plugins/transformations/abstract/SubstringTransformationsPlugin.class.php
new file mode 100644
index 0000000..2de48e6
--- /dev/null
+++ b/phpmyadmin/libraries/plugins/transformations/abstract/SubstringTransformationsPlugin.class.php
@@ -0,0 +1,116 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * Abstract class for the substring transformations plugins
+ *
+ * @package    PhpMyAdmin-Transformations
+ * @subpackage Substring
+ */
+if (! defined('PHPMYADMIN')) {
+    exit;
+}
+
+/* Get the transformations interface */
+require_once 'libraries/plugins/TransformationsPlugin.class.php';
+
+/**
+ * Provides common methods for all of the substring transformations plugins.
+ *
+ * @package PhpMyAdmin
+ */
+abstract class SubstringTransformationsPlugin extends TransformationsPlugin
+{
+    /**
+     * Gets the transformation description of the specific plugin
+     *
+     * @return string
+     */
+    public static function getInfo()
+    {
+        return __(
+            'Displays a part of a string. The first option is the number of'
+            . ' characters to skip from the beginning of the string (Default 0).'
+            . ' The second option is the number of characters to return (Default:'
+            . ' until end of string). The third option is the string to append'
+            . ' and/or prepend when truncation occurs (Default: "…").'
+        );
+    }
+
+    /**
+     * Does the actual work of each specific transformations plugin.
+     *
+     * @param string $buffer  text to be transformed
+     * @param array  $options transformation options
+     * @param string $meta    meta information
+     *
+     * @return void
+     */
+    public function applyTransformation($buffer, $options = array(), $meta = '')
+    {
+        // possibly use a global transform and feed it with special options
+
+        // further operations on $buffer using the $options[] array.
+        if (!isset($options[0]) ||  $options[0] == '') {
+            $options[0] = 0;
+        }
+
+        if (!isset($options[1]) ||  $options[1] == '') {
+            $options[1] = 'all';
+        }
+
+        if (!isset($options[2]) || $options[2] == '') {
+            $options[2] = '…';
+        }
+
+        $newtext = '';
+        if ($options[1] != 'all') {
+            $newtext = PMA_substr($buffer, $options[0], $options[1]);
+        } else {
+            $newtext = PMA_substr($buffer, $options[0]);
+        }
+
+        $length = strlen($newtext);
+        $baselength = strlen($buffer);
+        if ($length != $baselength) {
+            if ($options[0] != 0) {
+                $newtext = $options[2] . $newtext;
+            }
+
+            if (($length + $options[0]) != $baselength) {
+                $newtext .= $options[2];
+            }
+        }
+
+        return $newtext;
+    }
+
+    /**
+     * This method is called when any PluginManager to which the observer
+     * is attached calls PluginManager::notify()
+     *
+     * @param SplSubject $subject The PluginManager notifying the observer
+     *                            of an update.
+     *
+     * @todo implement
+     * @return void
+     */
+    public function update (SplSubject $subject)
+    {
+        ;
+    }
+
+
+    /* ~~~~~~~~~~~~~~~~~~~~ Getters and Setters ~~~~~~~~~~~~~~~~~~~~ */
+
+
+    /**
+     * Gets the transformation name of the specific plugin
+     *
+     * @return string
+     */
+    public static function getName()
+    {
+        return "Substring";
+    }
+}
+?>
\ No newline at end of file
diff --git a/phpmyadmin/libraries/plugins/transformations/abstract/TextImageLinkTransformationsPlugin.class.php b/phpmyadmin/libraries/plugins/transformations/abstract/TextImageLinkTransformationsPlugin.class.php
new file mode 100644
index 0000000..054b2f9
--- /dev/null
+++ b/phpmyadmin/libraries/plugins/transformations/abstract/TextImageLinkTransformationsPlugin.class.php
@@ -0,0 +1,96 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * Abstract class for the image link transformations plugins
+ *
+ * @package    PhpMyAdmin-Transformations
+ * @subpackage ImageLink
+ */
+if (! defined('PHPMYADMIN')) {
+    exit;
+}
+
+/* Get the transformations interface */
+require_once 'libraries/plugins/TransformationsPlugin.class.php';
+/* For PMA_transformation_global_html_replace */
+require_once 'libraries/transformations.lib.php';
+
+/**
+ * Provides common methods for all of the image link transformations plugins.
+ *
+ * @package PhpMyAdmin
+ */
+abstract class TextImageLinkTransformationsPlugin extends TransformationsPlugin
+{
+    /**
+     * Gets the transformation description of the specific plugin
+     *
+     * @return string
+     */
+    public static function getInfo()
+    {
+        return __(
+            'Displays an image and a link; the column contains the filename. The'
+            . ' first option is a URL prefix like "http://www.example.com/". The'
+            . ' second and third options are the width and the height in pixels.'
+        );
+    }
+
+    /**
+     * Does the actual work of each specific transformations plugin.
+     *
+     * @param string $buffer  text to be transformed
+     * @param array  $options transformation options
+     * @param string $meta    meta information
+     *
+     * @return void
+     */
+    public function applyTransformation($buffer, $options = array(), $meta = '')
+    {
+        $transform_options = array (
+            'string' => '<a href="' . (isset($options[0]) ? $options[0] : '')
+                . $buffer . '" target="_blank"><img src="'
+                . (isset($options[0]) ? $options[0] : '') . $buffer
+                . '" border="0" width="' . (isset($options[1]) ? $options[1] : 100)
+                . '" height="' . (isset($options[2]) ? $options[2] : 50) . '" />'
+                . $buffer . '</a>'
+        );
+
+        $buffer = PMA_transformation_global_html_replace(
+            $buffer,
+            $transform_options
+        );
+
+        return $buffer;
+    }
+
+    /**
+     * This method is called when any PluginManager to which the observer
+     * is attached calls PluginManager::notify()
+     *
+     * @param SplSubject $subject The PluginManager notifying the observer
+     *                            of an update.
+     *
+     * @todo implement
+     * @return void
+     */
+    public function update (SplSubject $subject)
+    {
+        ;
+    }
+
+
+    /* ~~~~~~~~~~~~~~~~~~~~ Getters and Setters ~~~~~~~~~~~~~~~~~~~~ */
+
+
+    /**
+     * Gets the transformation name of the specific plugin
+     *
+     * @return string
+     */
+    public static function getName()
+    {
+        return "Image Link";
+    }
+}
+?>
diff --git a/phpmyadmin/libraries/plugins/transformations/abstract/TextLinkTransformationsPlugin.class.php b/phpmyadmin/libraries/plugins/transformations/abstract/TextLinkTransformationsPlugin.class.php
new file mode 100644
index 0000000..fdc33b2
--- /dev/null
+++ b/phpmyadmin/libraries/plugins/transformations/abstract/TextLinkTransformationsPlugin.class.php
@@ -0,0 +1,98 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * Abstract class for the link transformations plugins
+ *
+ * @package    PhpMyAdmin-Transformations
+ * @subpackage Link
+ */
+if (! defined('PHPMYADMIN')) {
+    exit;
+}
+
+/* Get the transformations interface */
+require_once 'libraries/plugins/TransformationsPlugin.class.php';
+/* For PMA_transformation_global_html_replace */
+require_once 'libraries/transformations.lib.php';
+
+/**
+ * Provides common methods for all of the link transformations plugins.
+ *
+ * @package PhpMyAdmin
+ */
+abstract class TextLinkTransformationsPlugin extends TransformationsPlugin
+{
+    /**
+     * Gets the transformation description of the specific plugin
+     *
+     * @return string
+     */
+    public static function getInfo()
+    {
+        return __(
+            'Displays a link; the column contains the filename. The first option'
+            . ' is a URL prefix like "http://www.example.com/". The second option'
+            . ' is a title for the link.'
+        );
+    }
+
+    /**
+     * Does the actual work of each specific transformations plugin.
+     *
+     * @param string $buffer  text to be transformed
+     * @param array  $options transformation options
+     * @param string $meta    meta information
+     *
+     * @return void
+     */
+    public function applyTransformation($buffer, $options = array(), $meta = '')
+    {
+
+        $append_part = (isset($options[2]) && $options[2]) ? '' : $buffer;
+
+        $transform_options = array (
+            'string' => '<a href="'
+                . PMA_linkURL((isset($options[0]) ? $options[0] : '') . $append_part)
+                . '" title="' . (isset($options[1]) ? $options[1] : '')
+                . '" target="_new">' . (isset($options[1]) ? $options[1] : $buffer)
+                . '</a>'
+        );
+
+        $buffer = PMA_transformation_global_html_replace(
+            $buffer,
+            $transform_options
+        );
+
+        return $buffer;
+    }
+
+    /**
+     * This method is called when any PluginManager to which the observer
+     * is attached calls PluginManager::notify()
+     *
+     * @param SplSubject $subject The PluginManager notifying the observer
+     *                            of an update.
+     *
+     * @todo implement
+     * @return void
+     */
+    public function update (SplSubject $subject)
+    {
+        ;
+    }
+
+
+    /* ~~~~~~~~~~~~~~~~~~~~ Getters and Setters ~~~~~~~~~~~~~~~~~~~~ */
+
+
+    /**
+     * Gets the transformation name of the specific plugin
+     *
+     * @return string
+     */
+    public static function getName()
+    {
+        return "Link";
+    }
+}
+?>
diff --git a/phpmyadmin/libraries/plugins/transformations/generator_main_class.sh b/phpmyadmin/libraries/plugins/transformations/generator_main_class.sh
new file mode 100755
index 0000000..0587667
--- /dev/null
+++ b/phpmyadmin/libraries/plugins/transformations/generator_main_class.sh
@@ -0,0 +1,16 @@
+#!/bin/bash
+#
+# Shell script that creates only the main class for a new transformation
+# plug-in, using a template
+#
+# $1: MIMEType
+# $2: MIMESubtype
+# $3: Transformation Name
+
+if [ $# != 3 ]
+then
+  echo -e "Usage: ./generator_main_class.sh MIMEType MIMESubtype TransformationName\n"
+  exit 65
+fi
+
+./generator_plugin.sh "$1" "$2" "$3" "--generate_only_main_class"
\ No newline at end of file
diff --git a/phpmyadmin/libraries/plugins/transformations/generator_plugin.sh b/phpmyadmin/libraries/plugins/transformations/generator_plugin.sh
new file mode 100755
index 0000000..225a2cb
--- /dev/null
+++ b/phpmyadmin/libraries/plugins/transformations/generator_plugin.sh
@@ -0,0 +1,64 @@
+#!/bin/bash
+#
+# Shell script that creates a new transformation plug-in (both main and
+# abstract class) using a template.
+#
+# The 'description' parameter will add a new entry in the language file.
+# Watch out for special escaping.
+#
+# $1: MIMEType
+# $2: MIMESubtype
+# $3: Transformation Name
+# $4: (optional) Description
+
+echo $#
+if [ $# -ne 3 -a $# -ne 4 ]; then
+  echo -e "Usage: ./generator_plugin.sh MIMEType MIMESubtype TransformationName [Description]\n"
+  exit 65
+fi
+
+# make sure that the MIME Type, MIME Subtype and Transformation names
+# are in the correct format
+
+# make all names lowercase
+MT="`echo $1 | tr [:upper:] [:lower:]`"
+MS="`echo $2 | tr [:upper:] [:lower:]`"
+TN="`echo $3 | tr [:upper:] [:lower:]`"
+# make first letter uppercase
+MT="${MT^}"
+MS="${MS^}"
+TN="${TN^}"
+# make the first letter after each underscore uppercase
+MT="`echo $MT`"
+MT="`echo $MT |  sed -e 's/_./\U&\E/g'`"
+MS="`echo $MS`"
+MS="`echo $MS |  sed -e 's/_./\U&\E/g'`"
+TN="`echo $TN`"
+TN="`echo $TN |  sed -e 's/_./\U&\E/g'`"
+
+# define the name of the main class file and of its template
+ClassFile=$MT\_$MS\_$TN.class.php
+Template=TEMPLATE
+# define the name of the abstract class file and its template
+AbstractClassFile=abstract/"$TN"TransformationsPlugin.class.php
+AbstractTemplate=TEMPLATE_ABSTRACT
+# replace template names with argument names
+sed "s/\[MIMEType]/$MT/; s/\[MIMESubtype\]/$MS/; s/\[TransformationName\]/$TN/;" < $Template > $ClassFile
+echo "Created $ClassFile"
+
+GenerateAbstractClass=1
+if [ -n $4 ]; then
+    if [ "$4" == "--generate_only_main_class" ]; then
+        if [ -e $AbstractClassFile ]; then
+            GenerateAbstractClass=0
+        fi
+    fi
+fi
+
+if [ $GenerateAbstractClass -eq 1 ]; then
+    # replace template names with argument names
+    sed "s/\[TransformationName\]/$TN/; s/Description of the transformation./$4/;" < $AbstractTemplate > $AbstractClassFile
+    echo "Created $AbstractClassFile"
+fi
+
+echo ""
\ No newline at end of file
diff --git a/phpmyadmin/libraries/pmd_common.php b/phpmyadmin/libraries/pmd_common.php
new file mode 100644
index 0000000..5bf7c58
--- /dev/null
+++ b/phpmyadmin/libraries/pmd_common.php
@@ -0,0 +1,262 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * @package PhpMyAdmin-Designer
+ */
+/**
+ *
+ */
+if (! defined('PHPMYADMIN')) {
+    exit;
+}
+
+$GLOBALS['PMD']['STYLE']          = 'default';
+
+$cfgRelation = PMA_getRelationsParam();
+
+/**
+ * retrieves table info and stores it in $GLOBALS['PMD']
+ *
+ * @return array with table info
+ */
+function get_tables_info()
+{
+    $retval = array();
+
+    $GLOBALS['PMD']['TABLE_NAME'] = array();// that foreach no error
+    $GLOBALS['PMD']['OWNER'] = array();
+    $GLOBALS['PMD']['TABLE_NAME_SMALL'] = array();
+
+    $tables = PMA_DBI_get_tables_full($GLOBALS['db']);
+    // seems to be needed later
+    PMA_DBI_select_db($GLOBALS['db']);
+    $i = 0;
+    foreach ($tables as $one_table) {
+        $GLOBALS['PMD']['TABLE_NAME'][$i]
+            = $GLOBALS['db'] . "." . $one_table['TABLE_NAME'];
+        $GLOBALS['PMD']['OWNER'][$i] = $GLOBALS['db'];
+        $GLOBALS['PMD']['TABLE_NAME_SMALL'][$i] = $one_table['TABLE_NAME'];
+
+        $GLOBALS['PMD_URL']['TABLE_NAME'][$i]
+            = urlencode($GLOBALS['db'] . "." . $one_table['TABLE_NAME']);
+        $GLOBALS['PMD_URL']['OWNER'][$i] = urlencode($GLOBALS['db']);
+        $GLOBALS['PMD_URL']['TABLE_NAME_SMALL'][$i]
+            = urlencode($one_table['TABLE_NAME']);
+
+        $GLOBALS['PMD_OUT']['TABLE_NAME'][$i] = htmlspecialchars(
+            $GLOBALS['db'] . "." . $one_table['TABLE_NAME'], ENT_QUOTES
+        );
+        $GLOBALS['PMD_OUT']['OWNER'][$i] = htmlspecialchars(
+            $GLOBALS['db'], ENT_QUOTES
+        );
+        $GLOBALS['PMD_OUT']['TABLE_NAME_SMALL'][$i] = htmlspecialchars(
+            $one_table['TABLE_NAME'], ENT_QUOTES
+        );
+
+        $GLOBALS['PMD']['TABLE_TYPE'][$i] = strtoupper($one_table['ENGINE']);
+
+        $DF = PMA_getDisplayField($GLOBALS['db'], $one_table['TABLE_NAME']);
+        if ($DF != '') {
+            $retval[$GLOBALS['PMD_URL']["TABLE_NAME_SMALL"][$i]] = urlencode($DF);
+        }
+
+        $i++;
+    }
+
+    return $retval;
+}
+
+/**
+ * retrieves table column info
+ *
+ * @return array   table column nfo
+ */
+function get_columns_info()
+{
+    PMA_DBI_select_db($GLOBALS['db']);
+    $tab_column = array();
+    for ($i = 0, $cnt = count($GLOBALS['PMD']["TABLE_NAME"]); $i < $cnt; $i++) {
+        $fields_rs = PMA_DBI_query(
+            PMA_DBI_get_columns_sql(
+                $GLOBALS['db'],
+                $GLOBALS['PMD']["TABLE_NAME_SMALL"][$i],
+                null,
+                true
+            ),
+            null,
+            PMA_DBI_QUERY_STORE
+        );
+        $tbl_name_i = $GLOBALS['PMD']['TABLE_NAME'][$i];
+        $j = 0;
+        while ($row = PMA_DBI_fetch_assoc($fields_rs)) {
+            $tab_column[$tbl_name_i]['COLUMN_ID'][$j]   = $j;
+            $tab_column[$tbl_name_i]['COLUMN_NAME'][$j] = $row['Field'];
+            $tab_column[$tbl_name_i]['TYPE'][$j]        = $row['Type'];
+            $tab_column[$tbl_name_i]['NULLABLE'][$j]    = $row['Null'];
+            $j++;
+        }
+    }
+    return $tab_column;
+}
+
+/**
+ * returns JavaScript code for intializing vars
+ *
+ * @return string   JavaScript code
+ */
+function get_script_contr()
+{
+    PMA_DBI_select_db($GLOBALS['db']);
+    $con["C_NAME"] = array();
+    $i = 0;
+    $alltab_rs = PMA_DBI_query(
+        'SHOW TABLES FROM ' . PMA_Util::backquote($GLOBALS['db']),
+        null,
+        PMA_DBI_QUERY_STORE
+    );
+    while ($val = @PMA_DBI_fetch_row($alltab_rs)) {
+        $row = PMA_getForeigners($GLOBALS['db'], $val[0], '', 'internal');
+        //echo "<br> internal ".$GLOBALS['db']." - ".$val[0]." - ";
+        //print_r($row);
+        if ($row !== false) {
+            foreach ($row as $field => $value) {
+                $con['C_NAME'][$i] = '';
+                $con['DTN'][$i]    = urlencode($GLOBALS['db'] . "." . $val[0]);
+                $con['DCN'][$i]    = urlencode($field);
+                $con['STN'][$i]    = urlencode(
+                    $value['foreign_db'] . "." . $value['foreign_table']
+                );
+                $con['SCN'][$i]    = urlencode($value['foreign_field']);
+                $i++;
+            }
+        }
+        $row = PMA_getForeigners($GLOBALS['db'], $val[0], '', 'foreign');
+        //echo "<br> INNO ";
+        //print_r($row);
+        if ($row !== false) {
+            foreach ($row as $field => $value) {
+                $con['C_NAME'][$i] = '';
+                $con['DTN'][$i]    = urlencode($GLOBALS['db'].".".$val[0]);
+                $con['DCN'][$i]    = urlencode($field);
+                $con['STN'][$i]    = urlencode(
+                    $value['foreign_db'].".".$value['foreign_table']
+                );
+                $con['SCN'][$i]    = urlencode($value['foreign_field']);
+                $i++;
+            }
+        }
+    }
+
+    $ti = 0;
+    $retval = array();
+    for ($i = 0, $cnt = count($con["C_NAME"]); $i < $cnt; $i++) {
+        $c_name_i = $con['C_NAME'][$i];
+        $dtn_i = $con['DTN'][$i];
+        $retval[$ti] = array();
+        $retval[$ti][$c_name_i] = array();
+        if (in_array($dtn_i, $GLOBALS['PMD_URL']["TABLE_NAME"])
+            && in_array($con['STN'][$i], $GLOBALS['PMD_URL']["TABLE_NAME"])
+        ) {
+            $retval[$ti][$c_name_i][$dtn_i] = array();
+            $retval[$ti][$c_name_i][$dtn_i][$con['DCN'][$i]] = array(
+                0 => $con['STN'][$i],
+                1 => $con['SCN'][$i]
+            );
+        }
+        $ti++;
+    }
+    return $retval;
+}
+
+/**
+ * Returns UNIQUE and PRIMARY indices
+ *
+ * @return array unique or primary indices
+ */
+function get_pk_or_unique_keys()
+{
+    return get_all_keys(true);
+}
+
+/**
+ * returns all indices
+ *
+ * @param bool $unique_only whether to include only unique ones
+ *
+ * @return array indices
+ */
+function get_all_keys($unique_only = false)
+{
+    include_once './libraries/Index.class.php';
+
+    $keys = array();
+
+    foreach ($GLOBALS['PMD']['TABLE_NAME_SMALL'] as $I => $table) {
+        $schema = $GLOBALS['PMD']['OWNER'][$I];
+        // for now, take into account only the first index segment
+        foreach (PMA_Index::getFromTable($table, $schema) as $index) {
+            if ($unique_only && ! $index->isUnique()) {
+                continue;
+            }
+            $columns = $index->getColumns();
+            foreach ($columns as $column_name => $dummy) {
+                $keys[$schema . '.' .$table . '.' . $column_name] = 1;
+            }
+        }
+    }
+    return $keys;
+}
+
+/**
+ * Return script to create j_tab and h_tab arrays
+ *
+ * @return string
+ */
+function get_script_tabs()
+{
+    $script_tabs = 'var j_tabs = new Array();' . "\n"
+        . 'var h_tabs = new Array();' . "\n" ;
+
+    $retval = array(
+        'j_tabs' => array(),
+        'h_tabs' => array()
+    );
+
+    for ($i = 0, $cnt = count($GLOBALS['PMD']['TABLE_NAME']); $i < $cnt; $i++) {
+        $j = 0;
+        if (PMA_Util::isForeignKeySupported($GLOBALS['PMD']['TABLE_TYPE'][$i])) {
+            $j = 1;
+        }
+        $retval['j_tabs'][$GLOBALS['PMD_URL']['TABLE_NAME'][$i]] = $j;
+        $retval['h_tabs'][$GLOBALS['PMD_URL']['TABLE_NAME'][$i]] = 1;
+    }
+    return $retval;
+}
+
+/**
+ * Returns table position
+ *
+ * @return array table positions and sizes
+ */
+function get_tab_pos()
+{
+    $cfgRelation = PMA_getRelationsParam();
+
+    if (! $cfgRelation['designerwork']) {
+        return null;
+    }
+
+    $query = "
+         SELECT CONCAT_WS('.', `db_name`, `table_name`) AS `name`,
+                `x` AS `X`,
+                `y` AS `Y`,
+                `v` AS `V`,
+                `h` AS `H`
+           FROM " . PMA_Util::backquote($cfgRelation['db'])
+        . "." . PMA_Util::backquote($cfgRelation['designer_coords']);
+    $tab_pos = PMA_DBI_fetch_result(
+        $query, 'name', null, $GLOBALS['controllink'], PMA_DBI_QUERY_STORE
+    );
+    return count($tab_pos) ? $tab_pos : null;
+}
+?>
diff --git a/phpmyadmin/libraries/properties/PropertyItem.class.php b/phpmyadmin/libraries/properties/PropertyItem.class.php
new file mode 100644
index 0000000..21d5068
--- /dev/null
+++ b/phpmyadmin/libraries/properties/PropertyItem.class.php
@@ -0,0 +1,49 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * The top-level class of the object-oriented properties system.
+ *
+ * @package PhpMyAdmin
+ */
+if (! defined('PHPMYADMIN')) {
+    exit;
+}
+
+/**
+ * Provides an interface for Property classes
+ *
+ * @package PhpMyAdmin
+ */
+abstract class PropertyItem
+{
+    /**
+     * Returns the property type ( either "Options", or "Plugin" ).
+     *
+     * @return string
+     */
+    public abstract function getPropertyType();
+
+    /**
+     * Returns the property item type of either an instance of
+     *  - OptionsPropertyOneItem ( f.e. "bool", "text", "radio", etc ) or
+     *  - OptionsPropertyGroup   ( "root", "main" or "subgroup" )
+     *  - PluginPropertyItem     ( "export", "import", "transformations" ) 
+     *
+     * @return string
+     */
+    public abstract function getItemType();
+
+    /**
+     * Only overwritten in the OptionsPropertyGroup class:
+     * Used to tell whether we can use the current item as a group by calling
+     * the addProperty() or removeProperty() methods, which are not available
+     * for simple OptionsPropertyOneItem subclasses.
+     *
+     * @return string
+     */
+    public function getGroup()
+    {
+        return null;
+    }
+}
+?>
\ No newline at end of file
diff --git a/phpmyadmin/libraries/properties/options/OptionsPropertyGroup.class.php b/phpmyadmin/libraries/properties/options/OptionsPropertyGroup.class.php
new file mode 100644
index 0000000..ebff9b3
--- /dev/null
+++ b/phpmyadmin/libraries/properties/options/OptionsPropertyGroup.class.php
@@ -0,0 +1,104 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * Superclass for the Property Group classes.
+ *
+ * @package PhpMyAdmin
+ */
+if (! defined('PHPMYADMIN')) {
+    exit;
+}
+
+/* This class extends the OptionsPropertyItem class */
+require_once 'OptionsPropertyItem.class.php';
+
+/**
+ * Parents group property items and provides methods to manage groups of
+ * properties.
+ *
+ * @todo modify descriptions if needed, when the options are integrated
+ * @package PhpMyAdmin
+ */
+abstract class OptionsPropertyGroup extends OptionsPropertyItem
+{
+    /**
+     * Holds a group of properties (OptionsPropertyItem instances)
+     *
+     * @var array
+     */
+    private $_properties;
+
+    /**
+     * Adds a property to the group of properties
+     *
+     * @param OptionsPropertyItem $property the property instance to be added
+     *                                      to the group
+     *
+     * @return void
+     */
+    public function addProperty($property)
+    {
+        if (! $this->getProperties() == null
+            && in_array($property, $this->getProperties(), true)
+        ) {
+            return;
+        }
+        $this->_properties [] = $property;
+    }
+
+    /**
+     * Removes a property from the group of properties
+     *
+     * @param OptionsPropertyItem $property the property instance to be removed
+     *                                      from the group
+     *
+     * @return void
+     */
+    public function removeProperty($property)
+    {
+        $this->_properties = array_udiff(
+            $this->getProperties(),
+            array($property),
+            // for PHP 5.2 compability 
+            create_function(
+                '$a, $b',
+                'return ($a === $b ) ? 0 : 1'
+            )
+        );
+    }
+
+
+    /* ~~~~~~~~~~~~~~~~~~~~ Getters and Setters ~~~~~~~~~~~~~~~~~~~~ */
+
+
+    /**
+     * Gets the instance of the class
+     *
+     * @return array
+     */
+    public function getGroup()
+    {
+        return $this;
+    }
+
+    /**
+     * Gets the group of properties
+     *
+     * @return array
+     */
+    public function getProperties()
+    {
+        return $this->_properties;
+    }
+
+    /**
+     * Gets the number of properties
+     *
+     * @return int
+     */
+    public function getNrOfProperties()
+    {
+        return count($this->_properties);
+    }
+}
+?>
diff --git a/phpmyadmin/libraries/properties/options/OptionsPropertyItem.class.php b/phpmyadmin/libraries/properties/options/OptionsPropertyItem.class.php
new file mode 100644
index 0000000..a1718a2
--- /dev/null
+++ b/phpmyadmin/libraries/properties/options/OptionsPropertyItem.class.php
@@ -0,0 +1,127 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * The top-level class of the "Options" subtree of the object-oriented
+ * properties system (the other subtree is "Plugin").
+ *
+ * @package PhpMyAdmin
+ */
+if (! defined('PHPMYADMIN')) {
+    exit;
+}
+
+/* This class extends the PropertyItem class */
+require_once 'libraries/properties/PropertyItem.class.php';
+
+/**
+ * Superclass for
+ *  - OptionsPropertyOneItem and
+ *  - OptionsProperty Group
+ *
+ * @package PhpMyAdmin
+ */
+abstract class OptionsPropertyItem extends PropertyItem
+{
+    /**
+     * Name
+     *
+     * @var string
+     */
+    private $_name;
+
+    /**
+     * Text
+     *
+     * @var string
+     */
+    private $_text;
+
+    /**
+     * What to force
+     *
+     * @var string
+     */
+    private $_force;
+
+
+
+    /* ~~~~~~~~~~~~~~~~~~~~ Getters and Setters ~~~~~~~~~~~~~~~~~~~~ */
+
+
+    /**
+     * Gets the name
+     *
+     * @return string
+     */
+    public function getName()
+    {
+        return $this->_name;
+    }
+
+    /**
+     * Sets the name
+     *
+     * @param string $name name
+     *
+     * @return void
+     */
+    public function setName($name)
+    {
+        $this->_name = $name;
+    }
+
+    /**
+     * Gets the text
+     *
+     * @return string
+     */
+    public function getText()
+    {
+        return $this->_text;
+    }
+
+    /**
+     * Sets the text
+     *
+     * @param string $text text
+     *
+     * @return void
+     */
+    public function setText($text)
+    {
+        $this->_text = $text;
+    }
+
+    /**
+     * Gets the force parameter
+     *
+     * @return string
+     */
+    public function getForce()
+    {
+        return $this->_force;
+    }
+
+    /**
+     * Sets the force paramter
+     *
+     * @param string $force force parameter
+     *
+     * @return void
+     */
+    public function setForce($force)
+    {
+        $this->_force = $force;
+    }
+
+    /**
+     * Returns the property type ( either "options", or "plugin" ).
+     *
+     * @return string
+     */
+    public function getPropertyType()
+    {
+        return "options";
+    }
+}
+?>
\ No newline at end of file
diff --git a/phpmyadmin/libraries/properties/options/OptionsPropertyOneItem.class.php b/phpmyadmin/libraries/properties/options/OptionsPropertyOneItem.class.php
new file mode 100644
index 0000000..e19c15c
--- /dev/null
+++ b/phpmyadmin/libraries/properties/options/OptionsPropertyOneItem.class.php
@@ -0,0 +1,172 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * Superclass for the single Property Item classes.
+ *
+ * @package PhpMyAdmin
+ */
+if (! defined('PHPMYADMIN')) {
+    exit;
+}
+
+/* This class extends the OptionsPropertyItem class */
+require_once 'OptionsPropertyItem.class.php';
+
+/**
+ * Parents only single property items (not groups).
+ * Defines possible options and getters and setters for them.
+ *
+ * @package PhpMyAdmin
+ */
+abstract class OptionsPropertyOneItem extends OptionsPropertyItem
+{
+    /**
+     * Whether to force or not
+     *
+     * @var bool
+     */
+    private $_force;
+
+    /**
+     * Values
+     *
+     * @var array
+     */
+    private $_values;
+
+    /**
+     * Doc
+     *
+     * @var string
+     */
+    private $_doc;
+
+    /**
+     * Length
+     *
+     * @var int
+     */
+    private $_len;
+
+    /**
+     * Size
+     *
+     * @var int
+     */
+    private $_size;
+
+
+    /* ~~~~~~~~~~~~~~~~~~~~ Getters and Setters ~~~~~~~~~~~~~~~~~~~~ */
+
+
+    /**
+     * Gets the force parameter
+     *
+     * @return string
+     */
+    public function getForce()
+    {
+        return $this->_force;
+    }
+
+    /**
+     * Sets the force parameter
+     *
+     * @param bool $force force parameter
+     *
+     * @return void
+     */
+    public function setForce($force)
+    {
+        $this->_force = $force;
+    }
+
+    /**
+     * Gets the values
+     *
+     * @return string
+     */
+    public function getValues()
+    {
+        return $this->_values;
+    }
+
+    /**
+     * Sets the values
+     *
+     * @param array $values values
+     *
+     * @return void
+     */
+    public function setValues($values)
+    {
+        $this->_values = $values;
+    }
+
+    /**
+     * Gets the type of the newline character
+     *
+     * @return string
+     */
+    public function getDoc()
+    {
+        return $this->_doc;
+    }
+
+    /**
+     * Sets the doc
+     *
+     * @param string $doc doc
+     *
+     * @return void
+     */
+    public function setDoc($doc)
+    {
+        $this->_doc = $doc;
+    }
+
+    /**
+     * Gets the length
+     *
+     * @return int
+     */
+    public function getLen()
+    {
+        return $this->_len;
+    }
+
+    /**
+     * Sets the length
+     *
+     * @param int $len length
+     *
+     * @return void
+     */
+    public function setLen($len)
+    {
+        $this->_len = $len;
+    }
+
+    /**
+     * Gets the size
+     *
+     * @return int
+     */
+    public function getSize()
+    {
+        return $this->_size;
+    }
+
+    /**
+     * Sets the size
+     *
+     * @param int $size size
+     *
+     * @return void
+     */
+    public function setSize($size)
+    {
+        $this->_size = $size;
+    }
+}
+?>
\ No newline at end of file
diff --git a/phpmyadmin/libraries/properties/options/groups/OptionsPropertyMainGroup.class.php b/phpmyadmin/libraries/properties/options/groups/OptionsPropertyMainGroup.class.php
new file mode 100644
index 0000000..4e69aa7
--- /dev/null
+++ b/phpmyadmin/libraries/properties/options/groups/OptionsPropertyMainGroup.class.php
@@ -0,0 +1,35 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * Holds the OptionsPropertyMainGroup class
+ *
+ * @package PhpMyAdmin
+ */
+if (! defined('PHPMYADMIN')) {
+    exit;
+}
+
+/* This class extends the OptionsPropertyGroup class */
+require_once 'libraries/properties/options/OptionsPropertyGroup.class.php';
+
+/**
+ * Group property item class of type main
+ *
+ * @package PhpMyAdmin
+ */
+class OptionsPropertyMainGroup extends OptionsPropertyGroup
+{
+    /**
+     * Returns the property item type of either an instance of
+     *  - OptionsPropertyOneItem ( f.e. "bool", "text", "radio", etc ) or
+     *  - OptionsPropertyGroup   ( "root", "main" or "subgroup" )
+     *  - PluginPropertyItem     ( "export", "import", "transformations" )
+     *
+     * @return string
+     */
+    public function getItemType()
+    {
+        return "main";
+    }
+}
+?>
\ No newline at end of file
diff --git a/phpmyadmin/libraries/properties/options/groups/OptionsPropertyRootGroup.class.php b/phpmyadmin/libraries/properties/options/groups/OptionsPropertyRootGroup.class.php
new file mode 100644
index 0000000..a081744
--- /dev/null
+++ b/phpmyadmin/libraries/properties/options/groups/OptionsPropertyRootGroup.class.php
@@ -0,0 +1,35 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * Holds the OptionsPropertyRootGroup class
+ *
+ * @package PhpMyAdmin
+ */
+if (! defined('PHPMYADMIN')) {
+    exit;
+}
+
+/* This class extends the OptionsPropertyGroup class */
+require_once 'libraries/properties/options/OptionsPropertyGroup.class.php';
+
+/**
+ * Group property item class of type root
+ *
+ * @package PhpMyAdmin
+ */
+class OptionsPropertyRootGroup extends OptionsPropertyGroup
+{
+    /**
+     * Returns the property item type of either an instance of
+     *  - OptionsPropertyOneItem ( f.e. "bool", "text", "radio", etc ) or
+     *  - OptionsPropertyGroup   ( "root", "main" or "subgroup" )
+     *  - PluginPropertyItem     ( "export", "import", "transformations" )
+     *
+     * @return string
+     */
+    public function getItemType()
+    {
+        return "root";
+    }
+}
+?>
\ No newline at end of file
diff --git a/phpmyadmin/libraries/properties/options/groups/OptionsPropertySubgroup.class.php b/phpmyadmin/libraries/properties/options/groups/OptionsPropertySubgroup.class.php
new file mode 100644
index 0000000..0eeb524
--- /dev/null
+++ b/phpmyadmin/libraries/properties/options/groups/OptionsPropertySubgroup.class.php
@@ -0,0 +1,68 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * Holds the OptionsPropertySubgroup class
+ *
+ * @package PhpMyAdmin
+ */
+if (! defined('PHPMYADMIN')) {
+    exit;
+}
+
+/* This class extends the OptionsPropertyGroup class */
+require_once 'libraries/properties/options/OptionsPropertyGroup.class.php';
+
+/**
+ * Group property item class of type subgroup
+ *
+ * @package PhpMyAdmin
+ */
+class OptionsPropertySubgroup extends OptionsPropertyGroup
+{
+    /**
+     * Subgroup Header
+     *
+     * @var string
+     */
+    private $_subgroupHeader;
+
+
+    /* ~~~~~~~~~~~~~~~~~~~~ Getters and Setters ~~~~~~~~~~~~~~~~~~~~ */
+
+
+    /**
+     * Returns the property item type of either an instance of
+     *  - OptionsPropertyOneItem ( f.e. "bool", "text", "radio", etc ) or
+     *  - OptionsPropertyGroup   ( "root", "main" or "subgroup" )
+     *  - PluginPropertyItem     ( "export", "import", "transformations" )
+     *
+     * @return string
+     */
+    public function getItemType()
+    {
+        return "subgroup";
+    }
+
+    /**
+     * Gets the subgroup header
+     *
+     * @return string
+     */
+    public function getSubgroupHeader()
+    {
+        return $this->_subgroupHeader;
+    }
+
+    /**
+     * Sets the subgroup header
+     *
+     * @param string $subgroupHeader subgroup header
+     *
+     * @return void
+     */
+    public function setSubgroupHeader($subgroupHeader)
+    {
+        $this->_subgroupHeader = $subgroupHeader;
+    }
+}
+?>
\ No newline at end of file
diff --git a/phpmyadmin/libraries/properties/options/items/BoolPropertyItem.class.php b/phpmyadmin/libraries/properties/options/items/BoolPropertyItem.class.php
new file mode 100644
index 0000000..f33067f
--- /dev/null
+++ b/phpmyadmin/libraries/properties/options/items/BoolPropertyItem.class.php
@@ -0,0 +1,35 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * Holds the BoolPropertyItem class
+ *
+ * @package PhpMyAdmin
+ */
+if (! defined('PHPMYADMIN')) {
+    exit;
+}
+
+/* This class extends the OptionsPropertyOneItem class */
+require_once 'libraries/properties/options/OptionsPropertyOneItem.class.php';
+
+/**
+ * Single property item class of type bool
+ *
+ * @package PhpMyAdmin
+ */
+class BoolPropertyItem extends OptionsPropertyOneItem
+{
+    /**
+     * Returns the property item type of either an instance of
+     *  - OptionsPropertyOneItem ( f.e. "bool", "text", "radio", etc ) or
+     *  - OptionsPropertyGroup   ( "root", "main" or "subgroup" )
+     *  - PluginPropertyItem     ( "export", "import", "transformations" )
+     *
+     * @return string
+     */
+    public function getItemType()
+    {
+        return "bool";
+    }
+}
+?>
\ No newline at end of file
diff --git a/phpmyadmin/libraries/properties/options/items/DocPropertyItem.class.php b/phpmyadmin/libraries/properties/options/items/DocPropertyItem.class.php
new file mode 100644
index 0000000..55aff61
--- /dev/null
+++ b/phpmyadmin/libraries/properties/options/items/DocPropertyItem.class.php
@@ -0,0 +1,35 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * Holds the DocPropertyItem class
+ *
+ * @package PhpMyAdmin
+ */
+if (! defined('PHPMYADMIN')) {
+    exit;
+}
+
+/* This class extends the OptionsPropertyOneItem class */
+require_once 'libraries/properties/options/OptionsPropertyOneItem.class.php';
+
+/**
+ * Single property item class of type doc
+ *
+ * @package PhpMyAdmin
+ */
+class DocPropertyItem extends OptionsPropertyOneItem
+{
+    /**
+     * Returns the property item type of either an instance of
+     *  - OptionsPropertyOneItem ( f.e. "bool", "text", "radio", etc ) or
+     *  - OptionsPropertyGroup   ( "root", "main" or "subgroup" )
+     *  - PluginPropertyItem     ( "export", "import", "transformations" )
+     *
+     * @return string
+     */
+    public function getItemType()
+    {
+        return "doc";
+    }
+}
+?>
\ No newline at end of file
diff --git a/phpmyadmin/libraries/properties/options/items/HiddenPropertyItem.class.php b/phpmyadmin/libraries/properties/options/items/HiddenPropertyItem.class.php
new file mode 100644
index 0000000..53bfe46
--- /dev/null
+++ b/phpmyadmin/libraries/properties/options/items/HiddenPropertyItem.class.php
@@ -0,0 +1,35 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * Holds the HiddenPropertyItem class
+ *
+ * @package PhpMyAdmin
+ */
+if (! defined('PHPMYADMIN')) {
+    exit;
+}
+
+/* This class extends the OptionsPropertyOneItem class */
+require_once 'libraries/properties/options/OptionsPropertyOneItem.class.php';
+
+/**
+ * Single property item class of type hidden
+ *
+ * @package PhpMyAdmin
+ */
+class HiddenPropertyItem extends OptionsPropertyOneItem
+{
+    /**
+     * Returns the property item type of either an instance of
+     *  - OptionsPropertyOneItem ( f.e. "bool", "text", "radio", etc ) or
+     *  - OptionsPropertyGroup   ( "root", "main" or "subgroup" )
+     *  - PluginPropertyItem     ( "export", "import", "transformations" )
+     *
+     * @return string
+     */
+    public function getItemType()
+    {
+        return "hidden";
+    }
+}
+?>
\ No newline at end of file
diff --git a/phpmyadmin/libraries/properties/options/items/MessageOnlyPropertyItem.class.php b/phpmyadmin/libraries/properties/options/items/MessageOnlyPropertyItem.class.php
new file mode 100644
index 0000000..98f2e70
--- /dev/null
+++ b/phpmyadmin/libraries/properties/options/items/MessageOnlyPropertyItem.class.php
@@ -0,0 +1,35 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * Holds the MessageOnlyPropertyItem class
+ *
+ * @package PhpMyAdmin
+ */
+if (! defined('PHPMYADMIN')) {
+    exit;
+}
+
+/* This class extends the OptionsPropertyOneItem class */
+require_once 'libraries/properties/options/OptionsPropertyOneItem.class.php';
+
+/**
+ * Single property item class of type messageOnly
+ *
+ * @package PhpMyAdmin
+ */
+class MessageOnlyPropertyItem extends OptionsPropertyOneItem
+{
+    /**
+     * Returns the property item type of either an instance of
+     *  - OptionsPropertyOneItem ( f.e. "bool", "text", "radio", etc ) or
+     *  - OptionsPropertyGroup   ( "root", "main" or "subgroup" )
+     *  - PluginPropertyItem     ( "export", "import", "transformations" )
+     *
+     * @return string
+     */
+    public function getItemType()
+    {
+        return "messageOnly";
+    }
+}
+?>
\ No newline at end of file
diff --git a/phpmyadmin/libraries/properties/options/items/RadioPropertyItem.class.php b/phpmyadmin/libraries/properties/options/items/RadioPropertyItem.class.php
new file mode 100644
index 0000000..4d8ed7a
--- /dev/null
+++ b/phpmyadmin/libraries/properties/options/items/RadioPropertyItem.class.php
@@ -0,0 +1,35 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * Holds the RadioPropertyItem class
+ *
+ * @package PhpMyAdmin
+ */
+if (! defined('PHPMYADMIN')) {
+    exit;
+}
+
+/* This class extends the OptionsPropertyOneItem class */
+require_once 'libraries/properties/options/OptionsPropertyOneItem.class.php';
+
+/**
+ * Single property item class of type radio
+ *
+ * @package PhpMyAdmin
+ */
+class RadioPropertyItem extends OptionsPropertyOneItem
+{
+    /**
+     * Returns the property item type of either an instance of
+     *  - OptionsPropertyOneItem ( f.e. "bool", "text", "radio", etc ) or
+     *  - OptionsPropertyGroup   ( "root", "main" or "subgroup" )
+     *  - PluginPropertyItem     ( "export", "import", "transformations" )
+     *
+     * @return string
+     */
+    public function getItemType()
+    {
+        return "radio";
+    }
+}
+?>
\ No newline at end of file
diff --git a/phpmyadmin/libraries/properties/options/items/SelectPropertyItem.class.php b/phpmyadmin/libraries/properties/options/items/SelectPropertyItem.class.php
new file mode 100644
index 0000000..28460c9
--- /dev/null
+++ b/phpmyadmin/libraries/properties/options/items/SelectPropertyItem.class.php
@@ -0,0 +1,35 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * Holds the SelectPropertyItem class
+ *
+ * @package PhpMyAdmin
+ */
+if (! defined('PHPMYADMIN')) {
+    exit;
+}
+
+/* This class extends the OptionsPropertyOneItem class */
+require_once 'libraries/properties/options/OptionsPropertyOneItem.class.php';
+
+/**
+ * Single property item class of type select
+ *
+ * @package PhpMyAdmin
+ */
+class SelectPropertyItem extends OptionsPropertyOneItem
+{
+    /**
+     * Returns the property item type of either an instance of
+     *  - OptionsPropertyOneItem ( f.e. "bool", "text", "radio", etc ) or
+     *  - OptionsPropertyGroup   ( "root", "main" or "subgroup" )
+     *  - PluginPropertyItem     ( "export", "import", "transformations" )
+     *
+     * @return string
+     */
+    public function getItemType()
+    {
+        return "select";
+    }
+}
+?>
\ No newline at end of file
diff --git a/phpmyadmin/libraries/properties/options/items/TextPropertyItem.class.php b/phpmyadmin/libraries/properties/options/items/TextPropertyItem.class.php
new file mode 100644
index 0000000..9339cdf
--- /dev/null
+++ b/phpmyadmin/libraries/properties/options/items/TextPropertyItem.class.php
@@ -0,0 +1,35 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * Holds the TextPropertyItem class
+ *
+ * @package PhpMyAdmin
+ */
+if (! defined('PHPMYADMIN')) {
+    exit;
+}
+
+/* This class extends the OptionsPropertyOneItem class */
+require_once 'libraries/properties/options/OptionsPropertyOneItem.class.php';
+
+/**
+ * Single property item class of type text
+ *
+ * @package PhpMyAdmin
+ */
+class TextPropertyItem extends OptionsPropertyOneItem
+{
+    /**
+     * Returns the property item type of either an instance of
+     *  - OptionsPropertyOneItem ( f.e. "bool", "text", "radio", etc ) or
+     *  - OptionsPropertyGroup   ( "root", "main" or "subgroup" )
+     *  - PluginPropertyItem     ( "export", "import", "transformations" )
+     *
+     * @return string
+     */
+    public function getItemType()
+    {
+        return "text";
+    }
+}
+?>
\ No newline at end of file
diff --git a/phpmyadmin/libraries/properties/plugins/ExportPluginProperties.class.php b/phpmyadmin/libraries/properties/plugins/ExportPluginProperties.class.php
new file mode 100644
index 0000000..6170897
--- /dev/null
+++ b/phpmyadmin/libraries/properties/plugins/ExportPluginProperties.class.php
@@ -0,0 +1,214 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * Properties class for the export plug-in
+ *
+ * @package PhpMyAdmin
+ */
+if (! defined('PHPMYADMIN')) {
+    exit;
+}
+
+/* This class extends the PluginPropertyItem class */
+require_once 'PluginPropertyItem.class.php';
+
+/**
+ * Defines possible options and getters and setters for them.
+ *
+ * @todo modify descriptions if needed, when the plug-in properties are integrated
+ * @package PhpMyAdmin
+ */
+class ExportPluginProperties extends PluginPropertyItem
+{
+    /**
+     * Text
+     *
+     * @var string
+     */
+    private $_text;
+
+    /**
+     * Extension
+     *
+     * @var string
+     */
+    private $_extension;
+
+    /**
+     * Options
+     *
+     * @var OptionsPropertyRootGroup
+     */
+    private $_options;
+
+    /**
+     * Options text
+     *
+     * @var string
+     */
+    private $_optionsText;
+
+    /**
+     * MIME Type
+     *
+     * @var string
+     */
+    private $_mimeType;
+
+    /**
+     * Whether to force or not
+     *
+     * @var bool
+     */
+    private $_forceFile;
+
+
+    /* ~~~~~~~~~~~~~~~~~~~~ Getters and Setters ~~~~~~~~~~~~~~~~~~~~ */
+
+
+    /**
+     * Returns the property item type of either an instance of
+     *  - OptionsPropertyOneItem ( f.e. "bool", "text", "radio", etc ) or
+     *  - OptionsPropertyGroup   ( "root", "main" or "subgroup" )
+     *  - PluginPropertyItem     ( "export", "import", "transformations" )
+     *
+     * @return string
+     */
+    public function getItemType()
+    {
+        return "export";
+    }
+
+    /**
+     * Gets the text
+     *
+     * @return string
+     */
+    public function getText()
+    {
+        return $this->_text;
+    }
+
+    /**
+     * Sets the text
+     *
+     * @param string $text text
+     *
+     * @return void
+     */
+    public function setText($text)
+    {
+        $this->_text = $text;
+    }
+
+    /**
+     * Gets the extension
+     *
+     * @return string
+     */
+    public function getExtension()
+    {
+        return $this->_extension;
+    }
+
+    /**
+     * Sets the extension
+     *
+     * @param string $extension extension
+     *
+     * @return void
+     */
+    public function setExtension($extension)
+    {
+        $this->_extension = $extension;
+    }
+
+    /**
+     * Gets the options
+     *
+     * @return OptionsPropertyRootGroup
+     */
+    public function getOptions()
+    {
+        return $this->_options;
+    }
+
+    /**
+     * Sets the options
+     *
+     * @param OptionsPropertyRootGroup $options options
+     *
+     * @return void
+     */
+    public function setOptions($options)
+    {
+        $this->_options = $options;
+    }
+
+    /**
+     * Gets the options text
+     *
+     * @return string
+     */
+    public function getOptionsText()
+    {
+        return $this->_optionsText;
+    }
+
+    /**
+     * Sets the options text
+     *
+     * @param string $optionsText optionsText
+     *
+     * @return void
+     */
+    public function setOptionsText($optionsText)
+    {
+        $this->_optionsText = $optionsText;
+    }
+
+    /**
+     * Gets the MIME type
+     *
+     * @return string
+     */
+    public function getMimeType()
+    {
+        return $this->_mimeType;
+    }
+
+    /**
+     * Sets the MIME type
+     *
+     * @param string $mimeType MIME type
+     *
+     * @return void
+     */
+    public function setMimeType($mimeType)
+    {
+        $this->_mimeType = $mimeType;
+    }
+
+    /**
+     * Gets the force file parameter
+     *
+     * @return bool
+     */
+    public function getForceFile()
+    {
+        return $this->_forceFile;
+    }
+
+    /**
+     * Sets the force file parameter
+     *
+     * @param bool $forceFile the force file parameter
+     *
+     * @return void
+     */
+    public function setForceFile($forceFile)
+    {
+        $this->_forceFile = $forceFile;
+    }
+}
+?>
\ No newline at end of file
diff --git a/phpmyadmin/libraries/properties/plugins/ImportPluginProperties.class.php b/phpmyadmin/libraries/properties/plugins/ImportPluginProperties.class.php
new file mode 100644
index 0000000..65c3092
--- /dev/null
+++ b/phpmyadmin/libraries/properties/plugins/ImportPluginProperties.class.php
@@ -0,0 +1,184 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * Properties class for the import plug-in
+ *
+ * @package PhpMyAdmin
+ */
+if (! defined('PHPMYADMIN')) {
+    exit;
+}
+
+/* This class extends the PluginPropertyItem class */
+require_once 'PluginPropertyItem.class.php';
+
+/**
+ * Defines possible options and getters and setters for them.
+ *
+ * @package PhpMyAdmin
+ */
+class ImportPluginProperties extends PluginPropertyItem
+{
+    /**
+     * Text
+     *
+     * @var string
+     */
+    private $_text;
+
+    /**
+     * Extension
+     *
+     * @var string
+     */
+    private $_extension;
+
+    /**
+     * Options
+     *
+     * @var OptionsPropertyRootGroup
+     */
+    private $_options;
+
+    /**
+     * Options text
+     *
+     * @var string
+     */
+    private $_optionsText;
+
+    /**
+     * MIME Type
+     *
+     * @var string
+     */
+    private $_mimeType;
+
+
+    /* ~~~~~~~~~~~~~~~~~~~~ Getters and Setters ~~~~~~~~~~~~~~~~~~~~ */
+
+
+    /**
+     * Returns the property item type of either an instance of
+     *  - OptionsPropertyOneItem ( f.e. "bool", "text", "radio", etc ) or
+     *  - OptionsPropertyGroup   ( "root", "main" or "subgroup" )
+     *  - PluginPropertyItem     ( "export", "import", "transformations" )
+     *
+     * @return string
+     */
+    public function getItemType()
+    {
+        return "import";
+    }
+
+    /**
+     * Gets the text
+     *
+     * @return string
+     */
+    public function getText()
+    {
+        return $this->_text;
+    }
+
+    /**
+     * Sets the text
+     *
+     * @param string $text text
+     *
+     * @return void
+     */
+    public function setText($text)
+    {
+        $this->_text = $text;
+    }
+
+    /**
+     * Gets the extension
+     *
+     * @return string
+     */
+    public function getExtension()
+    {
+        return $this->_extension;
+    }
+
+    /**
+     * Sets the extension
+     *
+     * @param string $extension extension
+     *
+     * @return void
+     */
+    public function setExtension($extension)
+    {
+        $this->_extension = $extension;
+    }
+
+    /**
+     * Gets the options
+     *
+     * @return OptionsPropertyRootGroup
+     */
+    public function getOptions()
+    {
+        return $this->_options;
+    }
+
+    /**
+     * Sets the options
+     *
+     * @param OptionsPropertyRootGroup $options options
+     *
+     * @return void
+     */
+    public function setOptions($options)
+    {
+        $this->_options = $options;
+    }
+
+    /**
+     * Gets the options text
+     *
+     * @return string
+     */
+    public function getOptionsText()
+    {
+        return $this->_optionsText;
+    }
+
+    /**
+     * Sets the options text
+     *
+     * @param string $optionsText options text
+     *
+     * @return void
+     */
+    public function setOptionsText($optionsText)
+    {
+        $this->_optionsText = $optionsText;
+    }
+
+    /**
+     * Gets the MIME type
+     *
+     * @return string
+     */
+    public function getMimeType()
+    {
+        return $this->_mimeType;
+    }
+
+    /**
+     * Sets the MIME type
+     *
+     * @param string $mimeType MIME type
+     *
+     * @return void
+     */
+    public function setMimeType($mimeType)
+    {
+        $this->_mimeType = $mimeType;
+    }
+}
+?>
\ No newline at end of file
diff --git a/phpmyadmin/libraries/properties/plugins/PluginPropertyItem.class.php b/phpmyadmin/libraries/properties/plugins/PluginPropertyItem.class.php
new file mode 100644
index 0000000..af46be2
--- /dev/null
+++ b/phpmyadmin/libraries/properties/plugins/PluginPropertyItem.class.php
@@ -0,0 +1,36 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * The top-level class of the "Plugin" subtree of the object-oriented
+ * properties system (the other subtree is "Options").
+ *
+ * @package PhpMyAdmin
+ */
+if (! defined('PHPMYADMIN')) {
+    exit;
+}
+
+/* This class extends the PropertyItem class */
+require_once 'libraries/properties/PropertyItem.class.php';
+
+/**
+ * Superclass for
+ *  - ExportPluginProperties,
+ *  - ImportPluginProperties and
+ *  - TransformationsPluginProperties
+ *
+ * @package PhpMyAdmin
+ */
+abstract class PluginPropertyItem extends PropertyItem
+{
+    /**
+     * Returns the property type ( either "options", or "plugin" ).
+     *
+     * @return string
+     */
+    public function getPropertyType()
+    {
+        return "plugin";
+    }
+}
+?>
\ No newline at end of file
diff --git a/phpmyadmin/libraries/relation.lib.php b/phpmyadmin/libraries/relation.lib.php
new file mode 100644
index 0000000..efa0211
--- /dev/null
+++ b/phpmyadmin/libraries/relation.lib.php
@@ -0,0 +1,1396 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * Set of functions used with the relation and pdf feature
+ *
+ * @package PhpMyAdmin
+ */
+if (! defined('PHPMYADMIN')) {
+    exit;
+}
+
+/**
+ * Executes a query as controluser if possible, otherwise as normal user
+ *
+ * @param string  $sql        the query to execute
+ * @param boolean $show_error whether to display SQL error messages or not
+ * @param int     $options    query options
+ *
+ * @return integer   the result set, or false if no result set
+ *
+ * @access  public
+ *
+ */
+function PMA_queryAsControlUser($sql, $show_error = true, $options = 0)
+{
+    // Avoid caching of the number of rows affected; for example, this function
+    // is called for tracking purposes but we want to display the correct number
+    // of rows affected by the original query, not by the query generated for
+    // tracking.
+    $cache_affected_rows = false;
+
+    if ($show_error) {
+        $result = PMA_DBI_query(
+            $sql,
+            $GLOBALS['controllink'],
+            $options,
+            $cache_affected_rows
+        );
+    } else {
+        $result = @PMA_DBI_try_query(
+            $sql,
+            $GLOBALS['controllink'],
+            $options,
+            $cache_affected_rows
+        );
+    } // end if... else...
+
+    if ($result) {
+        return $result;
+    } else {
+        return false;
+    }
+} // end of the "PMA_queryAsControlUser()" function
+
+/**
+ * Returns current relation parameters
+ *
+ * @return array   $cfgRelation
+ */
+function PMA_getRelationsParam()
+{
+    if (empty($_SESSION['relation'][$GLOBALS['server']])) {
+        $_SESSION['relation'][$GLOBALS['server']] = PMA__getRelationsParam();
+    }
+
+    // just for BC but needs to be before PMA_getRelationsParamDiagnostic()
+    // which uses it
+    $GLOBALS['cfgRelation'] = $_SESSION['relation'][$GLOBALS['server']];
+
+    return $_SESSION['relation'][$GLOBALS['server']];
+}
+
+/**
+ * prints out diagnostic info for pma relation feature
+ *
+ * @param array $cfgRelation Relation configuration
+ *
+ * @return string
+ */
+function PMA_getRelationsParamDiagnostic($cfgRelation)
+{
+    $retval = '';
+
+    $messages['error'] = '<font color="red"><strong>'
+        . __('not OK')
+        . '</strong></font>'
+        . ' [ <a href="%s" target="documentation">'
+        . __('Documentation')
+        . '</a> ]';
+
+    $messages['ok'] = '<font color="green"><strong>'
+        .  _pgettext('Correctly working', 'OK')
+        . '</strong></font>';
+
+    $messages['enabled']  = '<font color="green">' . __('Enabled') . '</font>';
+    $messages['disabled'] = '<font color="red">'   . __('Disabled') . '</font>';
+
+    if (false === $GLOBALS['cfg']['Server']['pmadb']) {
+        $retval .= 'PMA Database ... '
+             . sprintf($messages['error'], 'pmadb')
+             . '<br />' . "\n"
+             . __('General relation features')
+             . ' <font color="green">' . __('Disabled')
+             . '</font>' . "\n";
+    } else {
+        $retval .= '<table>' . "\n";
+        $retval .= PMA_getDiagMessageForParameter(
+            'pmadb',
+            $GLOBALS['cfg']['Server']['pmadb'],
+            $messages,
+            'pmadb'
+        );
+        $retval .= PMA_getDiagMessageForParameter(
+            'relation',
+            isset($cfgRelation['relation']),
+            $messages,
+            'relation'
+        );
+        $retval .= PMA_getDiagMessageForFeature(
+            __('General relation features'),
+            'relwork',
+            $messages
+        );
+        $retval .= PMA_getDiagMessageForParameter(
+            'table_info',
+            isset($cfgRelation['table_info']),
+            $messages,
+            'table_info'
+        );
+        $retval .= PMA_getDiagMessageForFeature(
+            __('Display Features'),
+            'displaywork',
+            $messages
+        );
+        $retval .= PMA_getDiagMessageForParameter(
+            'table_coords',
+            isset($cfgRelation['table_coords']),
+            $messages,
+            'table_coords'
+        );
+        $retval .= PMA_getDiagMessageForParameter(
+            'pdf_pages',
+            isset($cfgRelation['pdf_pages']),
+            $messages,
+            'pdf_pages'
+        );
+        $retval .= PMA_getDiagMessageForFeature(
+            __('Creation of PDFs'),
+            'pdfwork',
+            $messages
+        );
+        $retval .= PMA_getDiagMessageForParameter(
+            'column_info',
+            isset($cfgRelation['column_info']),
+            $messages,
+            'column_info'
+        );
+        $retval .= PMA_getDiagMessageForFeature(
+            __('Displaying Column Comments'),
+            'commwork',
+            $messages,
+            false
+        );
+        $retval .= PMA_getDiagMessageForFeature(
+            __('Browser transformation'),
+            'mimework',
+            $messages
+        );
+        if ($cfgRelation['commwork'] && ! $cfgRelation['mimework']) {
+            $retval .= '<tr><td colspan=2 class="left">';
+            $retval .=  __('Please see the documentation on how to update your column_comments table');
+            $retval .= '</td></tr>';
+        }
+        $retval .= PMA_getDiagMessageForParameter(
+            'bookmarktable',
+            isset($cfgRelation['bookmark']),
+            $messages,
+            'bookmark'
+        );
+        $retval .= PMA_getDiagMessageForFeature(
+            __('Bookmarked SQL query'),
+            'bookmarkwork',
+            $messages
+        );
+        $retval .= PMA_getDiagMessageForParameter(
+            'history',
+            isset($cfgRelation['history']),
+            $messages,
+            'history'
+        );
+        $retval .= PMA_getDiagMessageForFeature(
+            __('SQL history'),
+            'historywork',
+            $messages
+        );
+        $retval .= PMA_getDiagMessageForParameter(
+            'designer_coords',
+            isset($cfgRelation['designer_coords']),
+            $messages,
+            'designer_coords'
+        );
+        $retval .= PMA_getDiagMessageForFeature(
+            __('Designer'),
+            'designerwork',
+            $messages
+        );
+        $retval .= PMA_getDiagMessageForParameter(
+            'recent',
+            isset($cfgRelation['recent']),
+            $messages,
+            'recent'
+        );
+        $retval .= PMA_getDiagMessageForFeature(
+            __('Persistent recently used tables'),
+            'recentwork',
+            $messages
+        );
+        $retval .= PMA_getDiagMessageForParameter(
+            'table_uiprefs',
+            isset($cfgRelation['table_uiprefs']),
+            $messages,
+            'table_uiprefs'
+        );
+        $retval .= PMA_getDiagMessageForFeature(
+            __('Persistent tables\' UI preferences'),
+            'uiprefswork',
+            $messages
+        );
+        $retval .= PMA_getDiagMessageForParameter(
+            'tracking',
+            isset($cfgRelation['tracking']),
+            $messages,
+            'tracking'
+        );
+        $retval .= PMA_getDiagMessageForFeature(
+            __('Tracking'),
+            'trackingwork',
+            $messages
+        );
+        $retval .= PMA_getDiagMessageForParameter(
+            'userconfig',
+            isset($cfgRelation['userconfig']),
+            $messages,
+            'userconfig'
+        );
+        $retval .= PMA_getDiagMessageForFeature(
+            __('User preferences'),
+            'userconfigwork',
+            $messages
+        );
+        $retval .= '</table>' . "\n";
+
+        $retval .= '<p>' . __('Quick steps to setup advanced features:') . '</p>';
+        $retval .= '<ul>';
+        $retval .= '<li>';
+        $retval .= __(
+            'Create the needed tables with the '
+            . '<code>examples/create_tables.sql</code>.'
+        );
+        $retval .= ' ' . PMA_Util::showDocu('setup', 'linked-tables');
+        $retval .= '</li>';
+        $retval .= '<li>';
+        $retval .= __('Create a pma user and give access to these tables.');
+        $retval .= ' ' . PMA_Util::showDocu('config', 'cfg_Servers_controluser');
+        $retval .= '</li>';
+        $retval .= '<li>';
+        $retval .= __(
+            'Enable advanced features in configuration file '
+            . '(<code>config.inc.php</code>), for example by '
+            . 'starting from <code>config.sample.inc.php</code>.'
+        );
+        $retval .= ' ' . PMA_Util::showDocu('setup', 'quick-install');
+        $retval .= '</li>';
+        $retval .= '<li>';
+        $retval .= __(
+            'Re-login to phpMyAdmin to load the updated configuration file.'
+        );
+        $retval .= '</li>';
+        $retval .= '</ul>';
+    }
+
+    return $retval;
+}
+
+/**
+ * prints out one diagnostic message for a feature
+ *
+ * @param string  $feature_name       feature name in a message string
+ * @param string  $relation_parameter the $GLOBALS['cfgRelation'] parameter to check
+ * @param array   $messages           utility messages
+ * @param boolean $skip_line          whether to skip a line after the message
+ *
+ * @return string
+ */
+function PMA_getDiagMessageForFeature($feature_name,
+    $relation_parameter, $messages, $skip_line = true
+) {
+    $retval = '    <tr><td colspan=2 class="right">' . $feature_name . ': ';
+    if ($GLOBALS['cfgRelation'][$relation_parameter]) {
+        $retval .= $messages['enabled'];
+    } else {
+        $retval .= $messages['disabled'];
+    }
+    $retval .= '</td></tr>';
+    if ($skip_line) {
+        $retval .= '<tr><td> </td></tr>';
+    }
+    return $retval;
+}
+
+/**
+ * prints out one diagnostic message for a configuration parameter
+ *
+ * @param string  $parameter              config parameter name to display
+ * @param boolean $relation_parameter_set whether this parameter is set
+ * @param array   $messages               utility messages
+ * @param string  $doc_anchor             anchor in documentation
+ *
+ * @return void
+ */
+function PMA_getDiagMessageForParameter($parameter,
+    $relation_parameter_set, $messages, $doc_anchor
+) {
+    $retval = '<tr><th class="left">';
+    $retval .= '$cfg[\'Servers\'][$i][\'' . $parameter . '\']  ... ';
+    $retval .= '</th><td class="right">';
+    if ($relation_parameter_set) {
+        $retval .= $messages['ok'];
+    } else {
+        $retval .= sprintf(
+            $messages['error'],
+            PMA_Util::getDocuLink('config', 'cfg_Servers_' . $doc_anchor)
+        );
+    }
+    $retval .= '</td></tr>' . "\n";
+    return $retval;
+}
+
+
+/**
+ * Defines the relation parameters for the current user
+ * just a copy of the functions used for relations ;-)
+ * but added some stuff to check what will work
+ *
+ * @access  protected
+ * @return array    the relation parameters for the current user
+ */
+function PMA__getRelationsParam()
+{
+    $cfgRelation                = array();
+    $cfgRelation['relwork']     = false;
+    $cfgRelation['displaywork'] = false;
+    $cfgRelation['bookmarkwork']= false;
+    $cfgRelation['pdfwork']     = false;
+    $cfgRelation['commwork']    = false;
+    $cfgRelation['mimework']    = false;
+    $cfgRelation['historywork'] = false;
+    $cfgRelation['recentwork']  = false;
+    $cfgRelation['uiprefswork'] = false;
+    $cfgRelation['trackingwork'] = false;
+    $cfgRelation['designerwork'] = false;
+    $cfgRelation['userconfigwork'] = false;
+    $cfgRelation['allworks']    = false;
+    $cfgRelation['user']        = null;
+    $cfgRelation['db']          = null;
+
+    if ($GLOBALS['server'] == 0 || empty($GLOBALS['cfg']['Server']['pmadb'])
+        || ! PMA_DBI_select_db($GLOBALS['cfg']['Server']['pmadb'], $GLOBALS['controllink'])
+    ) {
+        // No server selected -> no bookmark table
+        // we return the array with the falses in it,
+        // to avoid some 'Unitialized string offset' errors later
+        $GLOBALS['cfg']['Server']['pmadb'] = false;
+        return $cfgRelation;
+    }
+
+
+    $cfgRelation['user']  = $GLOBALS['cfg']['Server']['user'];
+    $cfgRelation['db']    = $GLOBALS['cfg']['Server']['pmadb'];
+
+    //  Now I just check if all tables that i need are present so I can for
+    //  example enable relations but not pdf...
+    //  I was thinking of checking if they have all required columns but I
+    //  fear it might be too slow
+
+    $tab_query = 'SHOW TABLES FROM '
+        . PMA_Util::backquote(
+            $GLOBALS['cfg']['Server']['pmadb']
+        );
+    $tab_rs    = PMA_queryAsControlUser($tab_query, false, PMA_DBI_QUERY_STORE);
+
+    if (! $tab_rs) {
+        // query failed ... ?
+        //$GLOBALS['cfg']['Server']['pmadb'] = false;
+        return $cfgRelation;
+    }
+
+    while ($curr_table = @PMA_DBI_fetch_row($tab_rs)) {
+        if ($curr_table[0] == $GLOBALS['cfg']['Server']['bookmarktable']) {
+            $cfgRelation['bookmark']        = $curr_table[0];
+        } elseif ($curr_table[0] == $GLOBALS['cfg']['Server']['relation']) {
+            $cfgRelation['relation']        = $curr_table[0];
+        } elseif ($curr_table[0] == $GLOBALS['cfg']['Server']['table_info']) {
+            $cfgRelation['table_info']      = $curr_table[0];
+        } elseif ($curr_table[0] == $GLOBALS['cfg']['Server']['table_coords']) {
+            $cfgRelation['table_coords']    = $curr_table[0];
+        } elseif ($curr_table[0] == $GLOBALS['cfg']['Server']['designer_coords']) {
+            $cfgRelation['designer_coords']    = $curr_table[0];
+        } elseif ($curr_table[0] == $GLOBALS['cfg']['Server']['column_info']) {
+            $cfgRelation['column_info'] = $curr_table[0];
+        } elseif ($curr_table[0] == $GLOBALS['cfg']['Server']['pdf_pages']) {
+            $cfgRelation['pdf_pages']       = $curr_table[0];
+        } elseif ($curr_table[0] == $GLOBALS['cfg']['Server']['history']) {
+            $cfgRelation['history'] = $curr_table[0];
+        } elseif ($curr_table[0] == $GLOBALS['cfg']['Server']['recent']) {
+            $cfgRelation['recent'] = $curr_table[0];
+        } elseif ($curr_table[0] == $GLOBALS['cfg']['Server']['table_uiprefs']) {
+            $cfgRelation['table_uiprefs'] = $curr_table[0];
+        } elseif ($curr_table[0] == $GLOBALS['cfg']['Server']['tracking']) {
+            $cfgRelation['tracking'] = $curr_table[0];
+        } elseif ($curr_table[0] == $GLOBALS['cfg']['Server']['userconfig']) {
+            $cfgRelation['userconfig'] = $curr_table[0];
+        }
+    } // end while
+    PMA_DBI_free_result($tab_rs);
+
+    if (isset($cfgRelation['relation'])) {
+        $cfgRelation['relwork']         = true;
+        if (isset($cfgRelation['table_info'])) {
+                $cfgRelation['displaywork'] = true;
+        }
+    }
+
+    if (isset($cfgRelation['table_coords']) && isset($cfgRelation['pdf_pages'])) {
+        $cfgRelation['pdfwork']     = true;
+    }
+
+    if (isset($cfgRelation['column_info'])) {
+        $cfgRelation['commwork']    = true;
+        $cfgRelation['mimework'] = true;
+    }
+
+    if (isset($cfgRelation['history'])) {
+        $cfgRelation['historywork']     = true;
+    }
+
+    if (isset($cfgRelation['recent'])) {
+        $cfgRelation['recentwork']      = true;
+    }
+
+    if (isset($cfgRelation['table_uiprefs'])) {
+        $cfgRelation['uiprefswork']     = true;
+    }
+
+    if (isset($cfgRelation['tracking'])) {
+        $cfgRelation['trackingwork']     = true;
+    }
+
+    if (isset($cfgRelation['userconfig'])) {
+        $cfgRelation['userconfigwork']   = true;
+    }
+
+    // we do not absolutely need that the internal relations or the PDF
+    // schema feature be activated
+    if (isset($cfgRelation['designer_coords'])) {
+        $cfgRelation['designerwork']     = true;
+    }
+
+    if (isset($cfgRelation['bookmark'])) {
+        $cfgRelation['bookmarkwork']     = true;
+    }
+
+    if ($cfgRelation['relwork'] && $cfgRelation['displaywork']
+        && $cfgRelation['pdfwork'] && $cfgRelation['commwork']
+        && $cfgRelation['mimework'] && $cfgRelation['historywork']
+        && $cfgRelation['recentwork'] && $cfgRelation['uiprefswork']
+        && $cfgRelation['trackingwork'] && $cfgRelation['userconfigwork']
+        && $cfgRelation['bookmarkwork'] && $cfgRelation['designerwork']
+    ) {
+        $cfgRelation['allworks'] = true;
+    }
+
+    return $cfgRelation;
+} // end of the 'PMA_getRelationsParam()' function
+
+/**
+ * Gets all Relations to foreign tables for a given table or
+ * optionally a given column in a table
+ *
+ * @param string $db     the name of the db to check for
+ * @param string $table  the name of the table to check for
+ * @param string $column the name of the column to check for
+ * @param string $source the source for foreign key information
+ *
+ * @return array    db,table,column
+ *
+ * @access  public
+ */
+function PMA_getForeigners($db, $table, $column = '', $source = 'both')
+{
+    $cfgRelation = PMA_getRelationsParam();
+    $foreign = array();
+
+    if ($cfgRelation['relwork'] && ($source == 'both' || $source == 'internal')) {
+        $rel_query = '
+             SELECT `master_field`,
+                    `foreign_db`,
+                    `foreign_table`,
+                    `foreign_field`
+               FROM ' . PMA_Util::backquote($cfgRelation['db']) . '.' . PMA_Util::backquote($cfgRelation['relation']) . '
+              WHERE `master_db`    = \'' . PMA_Util::sqlAddSlashes($db) . '\'
+                AND `master_table` = \'' . PMA_Util::sqlAddSlashes($table) . '\' ';
+        if (strlen($column)) {
+            $rel_query .= ' AND `master_field` = \'' . PMA_Util::sqlAddSlashes($column) . '\'';
+        }
+        $foreign = PMA_DBI_fetch_result($rel_query, 'master_field', null, $GLOBALS['controllink']);
+    }
+
+    if (($source == 'both' || $source == 'foreign') && strlen($table)) {
+
+        $show_create_table_query = 'SHOW CREATE TABLE '
+            . PMA_Util::backquote($db) . '.' . PMA_Util::backquote($table);
+        $show_create_table = PMA_DBI_fetch_value($show_create_table_query, 0, 1);
+        $analyzed_sql = PMA_SQP_analyze(PMA_SQP_parse($show_create_table));
+
+        foreach ($analyzed_sql[0]['foreign_keys'] as $one_key) {
+            // The analyzer may return more than one column name in the
+            // index list or the ref_index_list; if this happens,
+            // the current logic just discards the whole index; having
+            // more than one index field is currently unsupported (see FAQ 3.6)
+            if (count($one_key['index_list']) == 1) {
+                foreach ($one_key['index_list'] as $i => $field) {
+                    // If a foreign key is defined in the 'internal' source (pmadb)
+                    // and as a native foreign key, we won't get it twice
+                    // if $source='both' because we use $field as key
+
+                    // The parser looks for a CONSTRAINT clause just before
+                    // the FOREIGN KEY clause. It finds it (as output from
+                    // SHOW CREATE TABLE) in MySQL 4.0.13, but not in older
+                    // versions like 3.23.58.
+                    // In those cases, the FOREIGN KEY parsing will put numbers
+                    // like -1, 0, 1... instead of the constraint number.
+
+                    if (isset($one_key['constraint'])) {
+                        $foreign[$field]['constraint'] = $one_key['constraint'];
+                    }
+
+                    if (isset($one_key['ref_db_name'])) {
+                        $foreign[$field]['foreign_db'] = $one_key['ref_db_name'];
+                    } else {
+                        $foreign[$field]['foreign_db'] = $db;
+                    }
+                    $foreign[$field]['foreign_table'] = $one_key['ref_table_name'];
+                    $foreign[$field]['foreign_field'] = $one_key['ref_index_list'][$i];
+                    if (isset($one_key['on_delete'])) {
+                        $foreign[$field]['on_delete'] = $one_key['on_delete'];
+                    }
+                    if (isset($one_key['on_update'])) {
+                        $foreign[$field]['on_update'] = $one_key['on_update'];
+                    }
+                }
+            }
+        }
+    }
+
+    /**
+     * Emulating relations for some information_schema and data_dictionary tables
+     */
+    $is_information_schema = strtolower($db) == 'information_schema';
+    $is_data_dictionary = PMA_DRIZZLE && strtolower($db) == 'data_dictionary';
+    if (($is_information_schema || $is_data_dictionary) && ($source == 'internal' || $source == 'both')) {
+        if ($is_information_schema) {
+            $relations_key = 'information_schema_relations';
+            include_once './libraries/information_schema_relations.lib.php';
+        } else {
+            $relations_key = 'data_dictionary_relations';
+            include_once './libraries/data_dictionary_relations.lib.php';
+        }
+        if (isset($GLOBALS[$relations_key][$table])) {
+            foreach ($GLOBALS[$relations_key][$table] as $field => $relations) {
+                if ((! strlen($column) || $column == $field)
+                    && (! isset($foreign[$field]) || ! strlen($foreign[$field]))
+                ) {
+                    $foreign[$field] = $relations;
+                }
+            }
+        }
+    }
+
+    return $foreign;
+} // end of the 'PMA_getForeigners()' function
+
+/**
+ * Gets the display field of a table
+ *
+ * @param string $db    the name of the db to check for
+ * @param string $table the name of the table to check for
+ *
+ * @return string   field name
+ *
+ * @access  public
+ */
+function PMA_getDisplayField($db, $table)
+{
+    $cfgRelation = PMA_getRelationsParam();
+
+    /**
+     * Try to fetch the display field from DB.
+     */
+    if ($cfgRelation['displaywork']) {
+        $disp_query = '
+             SELECT `display_field`
+               FROM ' . PMA_Util::backquote($cfgRelation['db']) . '.' . PMA_Util::backquote($cfgRelation['table_info']) . '
+              WHERE `db_name`    = \'' . PMA_Util::sqlAddSlashes($db) . '\'
+                AND `table_name` = \'' . PMA_Util::sqlAddSlashes($table) . '\'';
+
+        $row = PMA_DBI_fetch_single_row($disp_query, 'ASSOC', $GLOBALS['controllink']);
+        if (isset($row['display_field'])) {
+            return $row['display_field'];
+        }
+    }
+
+    /**
+     * Emulating the display field for some information_schema tables.
+     */
+    if ($db == 'information_schema') {
+        switch ($table) {
+        case 'CHARACTER_SETS':
+            return 'DESCRIPTION';
+        case 'TABLES':
+            return 'TABLE_COMMENT';
+        }
+    }
+
+    /**
+     * No Luck...
+     */
+    return false;
+
+} // end of the 'PMA_getDisplayField()' function
+
+/**
+ * Gets the comments for all columns of a table or the db itself
+ *
+ * @param string $db    the name of the db to check for
+ * @param string $table the name of the table to check for
+ *
+ * @return array    [column_name] = comment
+ *
+ * @access  public
+ */
+function PMA_getComments($db, $table = '')
+{
+    $comments = array();
+
+    if ($table != '') {
+        // MySQL native column comments
+        $columns = PMA_DBI_get_columns($db, $table, null, true);
+        if ($columns) {
+            foreach ($columns as $column) {
+                if (! empty($column['Comment'])) {
+                    $comments[$column['Field']] = $column['Comment'];
+                }
+            }
+        }
+    } else {
+        $comments[] = PMA_getDbComment($db);
+    }
+
+    return $comments;
+} // end of the 'PMA_getComments()' function
+
+/**
+ * Gets the comment for a db
+ *
+ * @param string $db the name of the db to check for
+ *
+ * @return string   comment
+ *
+ * @access  public
+ */
+function PMA_getDbComment($db)
+{
+    $cfgRelation = PMA_getRelationsParam();
+    $comment = '';
+
+    if ($cfgRelation['commwork']) {
+        // pmadb internal db comment
+        $com_qry = "
+             SELECT `comment`
+               FROM " . PMA_Util::backquote($cfgRelation['db']) . "." . PMA_Util::backquote($cfgRelation['column_info']) . "
+              WHERE db_name     = '" . PMA_Util::sqlAddSlashes($db) . "'
+                AND table_name  = ''
+                AND column_name = '(db_comment)'";
+        $com_rs = PMA_queryAsControlUser($com_qry, true, PMA_DBI_QUERY_STORE);
+
+        if ($com_rs && PMA_DBI_num_rows($com_rs) > 0) {
+            $row = PMA_DBI_fetch_assoc($com_rs);
+            $comment = $row['comment'];
+        }
+        PMA_DBI_free_result($com_rs);
+    }
+
+    return $comment;
+} // end of the 'PMA_getDbComment()' function
+
+/**
+ * Gets the comment for a db
+ *
+ * @access  public
+ *
+ * @return string   comment
+ */
+function PMA_getDbComments()
+{
+    $cfgRelation = PMA_getRelationsParam();
+    $comments = array();
+
+    if ($cfgRelation['commwork']) {
+        // pmadb internal db comment
+        $com_qry = "
+             SELECT `db_name`, `comment`
+               FROM " . PMA_Util::backquote($cfgRelation['db']) . "." . PMA_Util::backquote($cfgRelation['column_info']) . "
+              WHERE `column_name` = '(db_comment)'";
+        $com_rs = PMA_queryAsControlUser($com_qry, true, PMA_DBI_QUERY_STORE);
+
+        if ($com_rs && PMA_DBI_num_rows($com_rs) > 0) {
+            while ($row = PMA_DBI_fetch_assoc($com_rs)) {
+                $comments[$row['db_name']] = $row['comment'];
+            }
+        }
+        PMA_DBI_free_result($com_rs);
+    }
+
+    return $comments;
+} // end of the 'PMA_getDbComments()' function
+
+/**
+ * Set a database comment to a certain value.
+ *
+ * @param string $db      the name of the db
+ * @param string $comment the value of the column
+ *
+ * @return boolean  true, if comment-query was made.
+ *
+ * @access  public
+ */
+function PMA_setDbComment($db, $comment = '')
+{
+    $cfgRelation = PMA_getRelationsParam();
+
+    if (! $cfgRelation['commwork']) {
+        return false;
+    }
+
+    if (strlen($comment)) {
+        $upd_query = "
+             INSERT INTO
+                    " . PMA_Util::backquote($cfgRelation['db']) . "." . PMA_Util::backquote($cfgRelation['column_info']) . "
+                    (`db_name`, `table_name`, `column_name`, `comment`)
+             VALUES (
+                   '" . PMA_Util::sqlAddSlashes($db) . "',
+                   '',
+                   '(db_comment)',
+                   '" . PMA_Util::sqlAddSlashes($comment) . "')
+             ON DUPLICATE KEY UPDATE
+                `comment` = '" . PMA_Util::sqlAddSlashes($comment) . "'";
+    } else {
+        $upd_query = '
+             DELETE FROM
+                    ' . PMA_Util::backquote($cfgRelation['db']) . '.' . PMA_Util::backquote($cfgRelation['column_info']) . '
+              WHERE `db_name`     = \'' . PMA_Util::sqlAddSlashes($db) . '\'
+                AND `table_name`  = \'\'
+                AND `column_name` = \'(db_comment)\'';
+    }
+
+    if (isset($upd_query)) {
+        return PMA_queryAsControlUser($upd_query);
+    }
+
+    return false;
+} // end of 'PMA_setDbComment()' function
+
+/**
+ * Set a SQL history entry
+ *
+ * @param string $db       the name of the db
+ * @param string $table    the name of the table
+ * @param string $username the username
+ * @param string $sqlquery the sql query
+ *
+ * @return void
+ *
+ * @access  public
+ */
+function PMA_setHistory($db, $table, $username, $sqlquery)
+{
+    // Prevent to run this automatically on Footer class destroying in testsuite
+    if (defined('TESTSUITE') || strlen($sqlquery) > $GLOBALS['cfg']['MaxCharactersInDisplayedSQL']) {
+        return;
+    }
+
+    $cfgRelation = PMA_getRelationsParam();
+
+    if (! isset($_SESSION['sql_history'])) {
+        $_SESSION['sql_history'] = array();
+    }
+
+    $key = md5($sqlquery . $db . $table);
+
+    if (isset($_SESSION['sql_history'][$key])) {
+        unset($_SESSION['sql_history'][$key]);
+    }
+
+    $_SESSION['sql_history'][$key] = array(
+        'db' => $db,
+        'table' => $table,
+        'sqlquery' => $sqlquery,
+    );
+
+    if (count($_SESSION['sql_history']) > $GLOBALS['cfg']['QueryHistoryMax']) {
+        // history should not exceed a maximum count
+        array_shift($_SESSION['sql_history']);
+    }
+
+    if (! $cfgRelation['historywork'] || ! $GLOBALS['cfg']['QueryHistoryDB']) {
+        return;
+    }
+
+    PMA_queryAsControlUser(
+        'INSERT INTO
+                ' . PMA_Util::backquote($cfgRelation['db']) . '.' . PMA_Util::backquote($cfgRelation['history']) . '
+              (`username`,
+                `db`,
+                `table`,
+                `timevalue`,
+                `sqlquery`)
+        VALUES
+              (\'' . PMA_Util::sqlAddSlashes($username) . '\',
+               \'' . PMA_Util::sqlAddSlashes($db) . '\',
+               \'' . PMA_Util::sqlAddSlashes($table) . '\',
+               NOW(),
+               \'' . PMA_Util::sqlAddSlashes($sqlquery) . '\')'
+    );
+} // end of 'PMA_setHistory()' function
+
+/**
+ * Gets a SQL history entry
+ *
+ * @param string $username the username
+ *
+ * @return array    list of history items
+ *
+ * @access  public
+ */
+function PMA_getHistory($username)
+{
+    $cfgRelation = PMA_getRelationsParam();
+
+    if (! $cfgRelation['historywork']) {
+        return false;
+    }
+
+    $hist_query = '
+         SELECT `db`,
+                `table`,
+                `sqlquery`
+           FROM ' . PMA_Util::backquote($cfgRelation['db']) . '.' . PMA_Util::backquote($cfgRelation['history']) . '
+          WHERE `username` = \'' . PMA_Util::sqlAddSlashes($username) . '\'
+       ORDER BY `id` DESC';
+
+    return PMA_DBI_fetch_result($hist_query, null, null, $GLOBALS['controllink']);
+} // end of 'PMA_getHistory()' function
+
+/**
+ * purges SQL history
+ *
+ * deletes entries that exceeds $cfg['QueryHistoryMax'], oldest first, for the
+ * given user
+ *
+ * @param string $username the username
+ *
+ * @return void
+ *
+ * @access  public
+ */
+function PMA_purgeHistory($username)
+{
+    $cfgRelation = PMA_getRelationsParam();
+    if (! $GLOBALS['cfg']['QueryHistoryDB'] || ! $cfgRelation['historywork']) {
+        return;
+    }
+
+    if (! $cfgRelation['historywork']) {
+        return;
+    }
+
+    $search_query = '
+         SELECT `timevalue`
+           FROM ' . PMA_Util::backquote($cfgRelation['db']) . '.' . PMA_Util::backquote($cfgRelation['history']) . '
+          WHERE `username` = \'' . PMA_Util::sqlAddSlashes($username) . '\'
+       ORDER BY `timevalue` DESC
+          LIMIT ' . $GLOBALS['cfg']['QueryHistoryMax'] . ', 1';
+
+    if ($max_time = PMA_DBI_fetch_value($search_query, 0, 0, $GLOBALS['controllink'])) {
+        PMA_queryAsControlUser(
+            'DELETE FROM
+                    ' . PMA_Util::backquote($cfgRelation['db']) . '.' . PMA_Util::backquote($cfgRelation['history']) . '
+              WHERE `username` = \'' . PMA_Util::sqlAddSlashes($username) . '\'
+                AND `timevalue` <= \'' . $max_time . '\''
+        );
+    }
+} // end of 'PMA_purgeHistory()' function
+
+/**
+ * Prepares the dropdown for one mode
+ *
+ * @param array  $foreign the keys and values for foreigns
+ * @param string $data    the current data of the dropdown
+ * @param string $mode    the needed mode
+ *
+ * @return array   the <option value=""><option>s
+ *
+ * @access  protected
+ */
+function PMA__foreignDropdownBuild($foreign, $data, $mode)
+{
+    $reloptions = array();
+
+    // id-only is a special mode used when no foreign display column
+    // is available
+    if ($mode == 'id-content' || $mode == 'id-only') {
+        // sort for id-content
+        if ($GLOBALS['cfg']['NaturalOrder']) {
+            uksort($foreign, 'strnatcasecmp');
+        } else {
+            ksort($foreign);
+        }
+    } elseif ($mode == 'content-id') {
+        // sort for content-id
+        if ($GLOBALS['cfg']['NaturalOrder']) {
+            natcasesort($foreign);
+        } else {
+            asort($foreign);
+        }
+    }
+
+    foreach ($foreign as $key => $value) {
+        if (PMA_strlen($value) <= $GLOBALS['cfg']['LimitChars']) {
+            $vtitle = '';
+            $value  = htmlspecialchars($value);
+        } else {
+            $vtitle  = htmlspecialchars($value);
+            $value  = htmlspecialchars(substr($value, 0, $GLOBALS['cfg']['LimitChars']) . '...');
+        }
+
+        $reloption = '<option value="' . htmlspecialchars($key) . '"';
+        if ($vtitle != '') {
+            $reloption .= ' title="' . $vtitle . '"';
+        }
+
+        if ((string) $key == (string) $data) {
+            $reloption .= ' selected="selected"';
+        }
+
+        if ($mode == 'content-id') {
+            $reloptions[] = $reloption . '>' . $value . ' - ' . htmlspecialchars($key) .  '</option>';
+        } elseif ($mode == 'id-content') {
+            $reloptions[] = $reloption . '>' . htmlspecialchars($key) .  ' - ' . $value . '</option>';
+        } elseif ($mode == 'id-only') {
+            $reloptions[] = $reloption . '>' . htmlspecialchars($key) . '</option>';
+        }
+    } // end foreach
+
+    return $reloptions;
+} // end of 'PMA__foreignDropdownBuild' function
+
+/**
+ * Outputs dropdown with values of foreign fields
+ *
+ * @param array  $disp_row        array of the displayed row
+ * @param string $foreign_field   the foreign field
+ * @param string $foreign_display the foreign field to display
+ * @param string $data            the current data of the dropdown (field in row)
+ * @param int    $max             maximum number of items in the dropdown
+ *
+ * @return string   the <option value=""><option>s
+ *
+ * @access  public
+ */
+function PMA_foreignDropdown($disp_row, $foreign_field, $foreign_display, $data,
+    $max = null
+) {
+    if (null === $max) {
+        $max = $GLOBALS['cfg']['ForeignKeyMaxLimit'];
+    }
+
+    $foreign = array();
+
+    // collect the data
+    foreach ($disp_row as $relrow) {
+        $key   = $relrow[$foreign_field];
+
+        // if the display field has been defined for this foreign table
+        if ($foreign_display) {
+            $value  = $relrow[$foreign_display];
+        } else {
+            $value = '';
+        } // end if ($foreign_display)
+
+        $foreign[$key] = $value;
+    } // end foreach
+
+    // put the dropdown sections in correct order
+    $top = array();
+    $bottom = array();
+    if ($foreign_display) {
+        if (PMA_isValid($GLOBALS['cfg']['ForeignKeyDropdownOrder'], 'array')) {
+            if (PMA_isValid($GLOBALS['cfg']['ForeignKeyDropdownOrder'][0])) {
+                $top = PMA__foreignDropdownBuild(
+                    $foreign,
+                    $data,
+                    $GLOBALS['cfg']['ForeignKeyDropdownOrder'][0]
+                );
+            }
+            if (PMA_isValid($GLOBALS['cfg']['ForeignKeyDropdownOrder'][1])) {
+                $bottom = PMA__foreignDropdownBuild(
+                    $foreign,
+                    $data,
+                    $GLOBALS['cfg']['ForeignKeyDropdownOrder'][1]
+                );
+            }
+        } else {
+            $top = PMA__foreignDropdownBuild($foreign, $data, 'id-content');
+            $bottom = PMA__foreignDropdownBuild($foreign, $data, 'content-id');
+        }
+    } else {
+        $top = PMA__foreignDropdownBuild($foreign, $data, 'id-only');
+    }
+
+    // beginning of dropdown
+    $ret = '<option value=""> </option>';
+    $top_count = count($top);
+    if ($max == -1 || $top_count < $max) {
+        $ret .= implode('', $top);
+        if ($foreign_display && $top_count > 0) {
+            // this empty option is to visually mark the beginning of the
+            // second series of values (bottom)
+            $ret .= '<option value=""> </option>';
+        }
+    }
+    if ($foreign_display) {
+        $ret .= implode('', $bottom);
+    }
+
+    return $ret;
+} // end of 'PMA_foreignDropdown()' function
+
+/**
+ * Gets foreign keys in preparation for a drop-down selector
+ *
+ * @param array  $foreigners     array of the foreign keys
+ * @param string $field          the foreign field name
+ * @param bool   $override_total whether to override the total
+ * @param string $foreign_filter a possible filter
+ * @param string $foreign_limit  a possible LIMIT clause
+ *
+ * @return array    data about the foreign keys
+ *
+ * @access  public
+ */
+
+function PMA_getForeignData($foreigners, $field, $override_total, $foreign_filter, $foreign_limit)
+{
+    // we always show the foreign field in the drop-down; if a display
+    // field is defined, we show it besides the foreign field
+    $foreign_link = false;
+    if ($foreigners && isset($foreigners[$field])) {
+        $foreigner       = $foreigners[$field];
+        $foreign_db      = $foreigner['foreign_db'];
+        $foreign_table   = $foreigner['foreign_table'];
+        $foreign_field   = $foreigner['foreign_field'];
+
+        // Count number of rows in the foreign table. Currently we do
+        // not use a drop-down if more than ForeignKeyMaxLimit rows in the
+        // foreign table,
+        // for speed reasons and because we need a better interface for this.
+        //
+        // We could also do the SELECT anyway, with a LIMIT, and ensure that
+        // the current value of the field is one of the choices.
+
+        $the_total   = PMA_Table::countRecords($foreign_db, $foreign_table, true);
+
+        if ($override_total == true || $the_total < $GLOBALS['cfg']['ForeignKeyMaxLimit']) {
+            // foreign_display can be false if no display field defined:
+            $foreign_display = PMA_getDisplayField($foreign_db, $foreign_table);
+
+            $f_query_main = 'SELECT ' . PMA_Util::backquote($foreign_field)
+                        . (($foreign_display == false) ? '' : ', ' . PMA_Util::backquote($foreign_display));
+            $f_query_from = ' FROM ' . PMA_Util::backquote($foreign_db) . '.' . PMA_Util::backquote($foreign_table);
+            $f_query_filter = empty($foreign_filter) ? '' : ' WHERE ' . PMA_Util::backquote($foreign_field)
+                            . ' LIKE "%' . PMA_Util::sqlAddSlashes($foreign_filter, true) . '%"'
+                            . (($foreign_display == false) ? '' : ' OR ' . PMA_Util::backquote($foreign_display)
+                                . ' LIKE "%' . PMA_Util::sqlAddSlashes($foreign_filter, true) . '%"'
+                                );
+            $f_query_order = ($foreign_display == false) ? '' :' ORDER BY ' . PMA_Util::backquote($foreign_table) . '.' . PMA_Util::backquote($foreign_display);
+            $f_query_limit = isset($foreign_limit) ? $foreign_limit : '';
+
+            if (!empty($foreign_filter)) {
+                $res = PMA_DBI_query('SELECT COUNT(*)' . $f_query_from . $f_query_filter);
+                if ($res) {
+                    $the_total = PMA_DBI_fetch_value($res);
+                    @PMA_DBI_free_result($res);
+                } else {
+                    $the_total = 0;
+                }
+            }
+
+            $disp  = PMA_DBI_query($f_query_main . $f_query_from . $f_query_filter . $f_query_order . $f_query_limit);
+            if ($disp && PMA_DBI_num_rows($disp) > 0) {
+                // If a resultset has been created, pre-cache it in the $disp_row array
+                // This helps us from not needing to use mysql_data_seek by accessing a pre-cached
+                // PHP array. Usually those resultsets are not that big, so a performance hit should
+                // not be expected.
+                $disp_row = array();
+                while ($single_disp_row = @PMA_DBI_fetch_assoc($disp)) {
+                    $disp_row[] = $single_disp_row;
+                }
+                @PMA_DBI_free_result($disp);
+            }
+        } else {
+            $disp_row = null;
+            $foreign_link = true;
+        }
+    }  // end if $foreigners
+
+    $foreignData['foreign_link'] = $foreign_link;
+    $foreignData['the_total'] = isset($the_total) ? $the_total : null;
+    $foreignData['foreign_display'] = isset($foreign_display) ? $foreign_display : null;
+    $foreignData['disp_row'] = isset($disp_row) ? $disp_row : null;
+    $foreignData['foreign_field'] = isset($foreign_field) ? $foreign_field : null;
+    return $foreignData;
+} // end of 'PMA_getForeignData()' function
+
+/**
+ * Finds all related tables
+ *
+ * @param array  $all_tables All the involved tables
+ * @param string $master     The master table to form the LEFT JOIN clause
+ *
+ * @return string LEFT JOIN
+ * @access  private
+ */
+function PMA_getRelatives($all_tables, $master)
+{
+    $fromclause = '';
+    $emerg = '';
+
+    // The list of tables that we still couldn't connect
+    $remaining_tables = $all_tables;
+    unset($remaining_tables[$master]);
+    // The list of allready connected tables
+    $known_tables[$master] = $master;
+    $run = 0;
+    while (count($remaining_tables) > 0) {
+        // Whether to go from master to foreign or vice versa
+        if ($run % 2 == 0) {
+            $from = 'master';
+            $to    = 'foreign';
+        } else {
+            $from = 'foreign';
+            $to    = 'master';
+        }
+        $in_know = '(\'' . implode('\', \'', $known_tables) . '\')';
+        $in_left = '(\'' . implode('\', \'', $remaining_tables) . '\')';
+        $rel_query = 'SELECT *'
+                   . '  FROM ' . PMA_Util::backquote($GLOBALS['cfgRelation']['db'])
+                   .       '.' . PMA_Util::backquote($GLOBALS['cfgRelation']['relation'])
+                   . ' WHERE ' . $from . '_db = \'' . PMA_Util::sqlAddSlashes($GLOBALS['db']) . '\''
+                   . '   AND ' . $to   . '_db = \'' . PMA_Util::sqlAddSlashes($GLOBALS['db']) . '\''
+                   . '   AND ' . $from . '_table IN ' . $in_know
+                   . '   AND ' . $to   . '_table IN ' . $in_left;
+        $relations = @PMA_DBI_query($rel_query, $GLOBALS['controllink']);
+        while ($row = PMA_DBI_fetch_assoc($relations)) {
+            $found_table                = $row[$to . '_table'];
+            if (isset($remaining_tables[$found_table])) {
+                $fromclause
+                    .= "\n" . ' LEFT JOIN '
+                    . PMA_Util::backquote($GLOBALS['db']) . '.' . PMA_Util::backquote($row[$to . '_table']) . ' ON '
+                    . PMA_Util::backquote($row[$from . '_table']) . '.'
+                    . PMA_Util::backquote($row[$from . '_field']) . ' = '
+                    . PMA_Util::backquote($row[$to . '_table']) . '.'
+                    . PMA_Util::backquote($row[$to . '_field']) . ' ';
+                $known_tables[$found_table] = $found_table;
+                unset($remaining_tables[$found_table]);
+            }
+        } // end while
+        $run++;
+        if ($run > 5) {
+            foreach ($remaining_tables as $table) {
+                $emerg .= ', ' . PMA_Util::backquote($table);
+                unset($remaining_tables[$table]);
+            }
+        }
+    } // end while
+    $fromclause = $emerg . $fromclause;
+    return $fromclause;
+} // end of the "PMA_getRelatives()" function
+
+/**
+ * Rename a field in relation tables
+ *
+ * usually called after a column in a table was renamed
+ *
+ * @param string $db       databse name
+ * @param string $table    table name
+ * @param string $field    old field name
+ * @param string $new_name new field name
+ *
+ * @return void
+ */
+function PMA_REL_renameField($db, $table, $field, $new_name)
+{
+    $cfgRelation = PMA_getRelationsParam();
+
+    if ($cfgRelation['displaywork']) {
+        $table_query = 'UPDATE '
+            . PMA_Util::backquote($cfgRelation['db']) . '.'
+            . PMA_Util::backquote($cfgRelation['table_info'])
+            . '   SET display_field = \'' . PMA_Util::sqlAddSlashes($new_name) . '\''
+            . ' WHERE db_name       = \'' . PMA_Util::sqlAddSlashes($db) . '\''
+            . '   AND table_name    = \'' . PMA_Util::sqlAddSlashes($table) . '\''
+            . '   AND display_field = \'' . PMA_Util::sqlAddSlashes($field) . '\'';
+        PMA_queryAsControlUser($table_query);
+    }
+
+    if ($cfgRelation['relwork']) {
+        $table_query = 'UPDATE '
+            . PMA_Util::backquote($cfgRelation['db']) . '.'
+            . PMA_Util::backquote($cfgRelation['relation'])
+            . '   SET master_field = \'' . PMA_Util::sqlAddSlashes($new_name) . '\''
+            . ' WHERE master_db    = \'' . PMA_Util::sqlAddSlashes($db) . '\''
+            . '   AND master_table = \'' . PMA_Util::sqlAddSlashes($table) . '\''
+            . '   AND master_field = \'' . PMA_Util::sqlAddSlashes($field) . '\'';
+        PMA_queryAsControlUser($table_query);
+
+        $table_query = 'UPDATE '
+            . PMA_Util::backquote($cfgRelation['db']) . '.'
+            . PMA_Util::backquote($cfgRelation['relation'])
+            . '   SET foreign_field = \'' . PMA_Util::sqlAddSlashes($new_name) . '\''
+            . ' WHERE foreign_db    = \'' . PMA_Util::sqlAddSlashes($db) . '\''
+            . '   AND foreign_table = \'' . PMA_Util::sqlAddSlashes($table) . '\''
+            . '   AND foreign_field = \'' . PMA_Util::sqlAddSlashes($field) . '\'';
+        PMA_queryAsControlUser($table_query);
+
+    } // end if relwork
+}
+
+
+/**
+ * Performs SQL query used for renaming table.
+ *
+ * @param string $table        Relation table to use
+ * @param string $source_db    Source database name
+ * @param string $target_db    Target database name
+ * @param string $source_table Source table name
+ * @param string $target_table Target table name
+ * @param string $db_field     Name of database field
+ * @param string $table_field  Name of table field
+ *
+ * @return nothing.
+ */
+function PMA_REL_renameSingleTable($table,
+    $source_db, $target_db,
+    $source_table, $target_table,
+    $db_field, $table_field
+) {
+    $query = 'UPDATE '
+        . PMA_Util::backquote($GLOBALS['cfgRelation']['db']) . '.'
+        . PMA_Util::backquote($GLOBALS['cfgRelation'][$table])
+        . ' SET ' . $db_field . ' = \'' . PMA_Util::sqlAddSlashes($target_db) . '\', '
+        . ' ' . $table_field . ' = \'' . PMA_Util::sqlAddSlashes($target_table) . '\''
+        . ' WHERE '
+        . $db_field . '  = \'' . PMA_Util::sqlAddSlashes($source_db) . '\''
+        . ' AND '
+        . $table_field . ' = \'' . PMA_Util::sqlAddSlashes($source_table) . '\'';
+    PMA_queryAsControlUser($query);
+}
+
+
+/**
+ * Rename a table in relation tables
+ *
+ * usually called after table has been moved
+ *
+ * @param string $source_db    Source database name
+ * @param string $target_db    Target database name
+ * @param string $source_table Source table name
+ * @param string $target_table Target table name
+ *
+ * @return nothing
+ */
+function PMA_REL_renameTable($source_db, $target_db, $source_table, $target_table)
+{
+    // Move old entries from PMA-DBs to new table
+    if ($GLOBALS['cfgRelation']['commwork']) {
+        PMA_REL_renameSingleTable(
+            'column_info',
+            $source_db, $target_db,
+            $source_table, $target_table,
+            'db_name', 'table_name'
+        );
+    }
+
+    // updating bookmarks is not possible since only a single table is
+    // moved, and not the whole DB.
+
+    if ($GLOBALS['cfgRelation']['displaywork']) {
+        PMA_REL_renameSingleTable(
+            'table_info',
+            $source_db, $target_db,
+            $source_table, $target_table,
+            'db_name', 'table_name'
+        );
+    }
+
+    if ($GLOBALS['cfgRelation']['relwork']) {
+        PMA_REL_renameSingleTable(
+            'relation',
+            $source_db, $target_db,
+            $source_table, $target_table,
+            'foreign_db', 'foreign_table'
+        );
+
+        PMA_REL_renameSingleTable(
+            'relation',
+            $source_db, $target_db,
+            $source_table, $target_table,
+            'master_db', 'master_table'
+        );
+    }
+
+    /**
+     * @todo Can't get moving PDFs the right way. The page numbers
+     * always get screwed up independently from duplication because the
+     * numbers do not seem to be stored on a per-database basis. Would
+     * the author of pdf support please have a look at it?
+     */
+
+    if ($GLOBALS['cfgRelation']['pdfwork']) {
+        PMA_REL_renameSingleTable(
+            'table_coords',
+            $source_db, $target_db,
+            $source_table, $target_table,
+            'db_name', 'table_name'
+        );
+    }
+
+    if ($GLOBALS['cfgRelation']['designerwork']) {
+        PMA_REL_renameSingleTable(
+            'designer_coords',
+            $source_db, $target_db,
+            $source_table, $target_table,
+            'db_name', 'table_name'
+        );
+    }
+}
+
+/**
+ * Create a PDF page
+ *
+ * @param string $newpage     name of the new PDF page
+ * @param array  $cfgRelation Relation configuration
+ * @param string $db          database name
+ *
+ * @return string   $pdf_page_number
+ */
+function PMA_REL_createPage($newpage, $cfgRelation, $db)
+{
+    if (! isset($newpage) || $newpage == '') {
+        $newpage = __('no description');
+    }
+    $ins_query   = 'INSERT INTO '
+        . PMA_Util::backquote($GLOBALS['cfgRelation']['db']) . '.'
+        . PMA_Util::backquote($cfgRelation['pdf_pages'])
+        . ' (db_name, page_descr)'
+        . ' VALUES (\''
+        . PMA_Util::sqlAddSlashes($db) . '\', \''
+        . PMA_Util::sqlAddSlashes($newpage) . '\')';
+    PMA_queryAsControlUser($ins_query, false);
+
+    return PMA_DBI_insert_id(
+        isset($GLOBALS['controllink']) ? $GLOBALS['controllink'] : ''
+    );
+}
+?>
diff --git a/phpmyadmin/libraries/relation_cleanup.lib.php b/phpmyadmin/libraries/relation_cleanup.lib.php
new file mode 100644
index 0000000..1c86a4b
--- /dev/null
+++ b/phpmyadmin/libraries/relation_cleanup.lib.php
@@ -0,0 +1,165 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * Set of functions used for cleaning up phpMyAdmin tables
+ *
+ * @package PhpMyAdmin
+ */
+if (! defined('PHPMYADMIN')) {
+    exit;
+}
+
+/**
+ * Cleanup column related relation stuff
+ *
+ * @param string $db     database name
+ * @param string $table  table name
+ * @param string $column column name
+ *
+ * @return void
+ */
+function PMA_relationsCleanupColumn($db, $table, $column)
+{
+    $cfgRelation = PMA_getRelationsParam();
+
+    if ($cfgRelation['commwork']) {
+        $remove_query = 'DELETE FROM ' . PMA_Util::backquote($cfgRelation['db']) . '.' . PMA_Util::backquote($cfgRelation['column_info'])
+                    . ' WHERE db_name  = \'' . PMA_Util::sqlAddSlashes($db) . '\''
+                    . ' AND table_name = \'' . PMA_Util::sqlAddSlashes($table) . '\''
+                    . ' AND column_name = \'' . PMA_Util::sqlAddSlashes($column) . '\'';
+        PMA_queryAsControlUser($remove_query);
+    }
+
+    if ($cfgRelation['displaywork']) {
+        $remove_query = 'DELETE FROM ' . PMA_Util::backquote($cfgRelation['db']) . '.' . PMA_Util::backquote($cfgRelation['table_info'])
+                    . ' WHERE db_name  = \'' . PMA_Util::sqlAddSlashes($db) . '\''
+                    . ' AND table_name = \'' . PMA_Util::sqlAddSlashes($table) . '\''
+                    . ' AND display_field = \'' . PMA_Util::sqlAddSlashes($column) . '\'';
+        PMA_queryAsControlUser($remove_query);
+    }
+
+    if ($cfgRelation['relwork']) {
+        $remove_query = 'DELETE FROM ' . PMA_Util::backquote($cfgRelation['db']) . '.' . PMA_Util::backquote($cfgRelation['relation'])
+                    . ' WHERE master_db  = \'' . PMA_Util::sqlAddSlashes($db) . '\''
+                    . ' AND master_table = \'' . PMA_Util::sqlAddSlashes($table) . '\''
+                    . ' AND master_field = \'' . PMA_Util::sqlAddSlashes($column) . '\'';
+        PMA_queryAsControlUser($remove_query);
+
+        $remove_query = 'DELETE FROM ' . PMA_Util::backquote($cfgRelation['db']) . '.' . PMA_Util::backquote($cfgRelation['relation'])
+                    . ' WHERE foreign_db  = \'' . PMA_Util::sqlAddSlashes($db) . '\''
+                    . ' AND foreign_table = \'' . PMA_Util::sqlAddSlashes($table) . '\''
+                    . ' AND foreign_field = \'' . PMA_Util::sqlAddSlashes($column) . '\'';
+        PMA_queryAsControlUser($remove_query);
+    }
+}
+
+/**
+ * Cleanup table related relation stuff
+ *
+ * @param string $db    database name
+ * @param string $table table name
+ *
+ * @return void
+ */
+function PMA_relationsCleanupTable($db, $table)
+{
+    $cfgRelation = PMA_getRelationsParam();
+
+    if ($cfgRelation['commwork']) {
+        $remove_query = 'DELETE FROM ' . PMA_Util::backquote($cfgRelation['db']) . '.' . PMA_Util::backquote($cfgRelation['column_info'])
+                    . ' WHERE db_name  = \'' . PMA_Util::sqlAddSlashes($db) . '\''
+                    . ' AND table_name = \'' . PMA_Util::sqlAddSlashes($table) . '\'';
+        PMA_queryAsControlUser($remove_query);
+    }
+
+    if ($cfgRelation['displaywork']) {
+        $remove_query = 'DELETE FROM ' . PMA_Util::backquote($cfgRelation['db']) . '.' . PMA_Util::backquote($cfgRelation['table_info'])
+                    . ' WHERE db_name  = \'' . PMA_Util::sqlAddSlashes($db) . '\''
+                    . ' AND table_name = \'' . PMA_Util::sqlAddSlashes($table) . '\'';
+        PMA_queryAsControlUser($remove_query);
+    }
+
+    if ($cfgRelation['pdfwork']) {
+        $remove_query = 'DELETE FROM ' . PMA_Util::backquote($cfgRelation['db']) . '.' . PMA_Util::backquote($cfgRelation['table_coords'])
+                    . ' WHERE db_name  = \'' . PMA_Util::sqlAddSlashes($db) . '\''
+                    . ' AND table_name = \'' . PMA_Util::sqlAddSlashes($table) . '\'';
+        PMA_queryAsControlUser($remove_query);
+    }
+
+    if ($cfgRelation['designerwork']) {
+        $remove_query = 'DELETE FROM ' . PMA_Util::backquote($cfgRelation['db']) . '.' . PMA_Util::backquote($cfgRelation['designer_coords'])
+                    . ' WHERE db_name  = \'' . PMA_Util::sqlAddSlashes($db) . '\''
+                    . ' AND table_name = \'' . PMA_Util::sqlAddSlashes($table) . '\'';
+        PMA_queryAsControlUser($remove_query);
+    }
+
+    if ($cfgRelation['relwork']) {
+        $remove_query = 'DELETE FROM ' . PMA_Util::backquote($cfgRelation['db']) . '.' . PMA_Util::backquote($cfgRelation['relation'])
+                    . ' WHERE master_db  = \'' . PMA_Util::sqlAddSlashes($db) . '\''
+                    . ' AND master_table = \'' . PMA_Util::sqlAddSlashes($table) . '\'';
+        PMA_queryAsControlUser($remove_query);
+
+        $remove_query = 'DELETE FROM ' . PMA_Util::backquote($cfgRelation['db']) . '.' . PMA_Util::backquote($cfgRelation['relation'])
+                    . ' WHERE foreign_db  = \'' . PMA_Util::sqlAddSlashes($db) . '\''
+                    . ' AND foreign_table = \'' . PMA_Util::sqlAddSlashes($table) . '\'';
+        PMA_queryAsControlUser($remove_query);
+    }
+}
+
+/**
+ * Cleanup database related relation stuff
+ *
+ * @param string $db database name
+ *
+ * @return void
+ */
+function PMA_relationsCleanupDatabase($db)
+{
+    $cfgRelation = PMA_getRelationsParam();
+
+    if ($cfgRelation['commwork']) {
+        $remove_query = 'DELETE FROM ' . PMA_Util::backquote($cfgRelation['db']) . '.' . PMA_Util::backquote($cfgRelation['column_info'])
+                    . ' WHERE db_name  = \'' . PMA_Util::sqlAddSlashes($db) . '\'';
+        PMA_queryAsControlUser($remove_query);
+    }
+
+    if ($cfgRelation['bookmarkwork']) {
+        $remove_query = 'DELETE FROM ' . PMA_Util::backquote($cfgRelation['db']) . '.' . PMA_Util::backquote($cfgRelation['bookmark'])
+                    . ' WHERE dbase  = \'' . PMA_Util::sqlAddSlashes($db) . '\'';
+        PMA_queryAsControlUser($remove_query);
+    }
+
+    if ($cfgRelation['displaywork']) {
+        $remove_query = 'DELETE FROM ' . PMA_Util::backquote($cfgRelation['db']) . '.' . PMA_Util::backquote($cfgRelation['table_info'])
+                    . ' WHERE db_name  = \'' . PMA_Util::sqlAddSlashes($db) . '\'';
+        PMA_queryAsControlUser($remove_query);
+    }
+
+    if ($cfgRelation['pdfwork']) {
+        $remove_query = 'DELETE FROM ' . PMA_Util::backquote($cfgRelation['db']) . '.' . PMA_Util::backquote($cfgRelation['pdf_pages'])
+                    . ' WHERE db_name  = \'' . PMA_Util::sqlAddSlashes($db) . '\'';
+        PMA_queryAsControlUser($remove_query);
+
+        $remove_query = 'DELETE FROM ' . PMA_Util::backquote($cfgRelation['db']) . '.' . PMA_Util::backquote($cfgRelation['table_coords'])
+                    . ' WHERE db_name  = \'' . PMA_Util::sqlAddSlashes($db) . '\'';
+        PMA_queryAsControlUser($remove_query);
+    }
+
+    if ($cfgRelation['designerwork']) {
+        $remove_query = 'DELETE FROM ' . PMA_Util::backquote($cfgRelation['db']) . '.' . PMA_Util::backquote($cfgRelation['designer_coords'])
+                    . ' WHERE db_name  = \'' . PMA_Util::sqlAddSlashes($db) . '\'';
+        PMA_queryAsControlUser($remove_query);
+    }
+
+    if ($cfgRelation['relwork']) {
+        $remove_query = 'DELETE FROM ' . PMA_Util::backquote($cfgRelation['db']) . '.' . PMA_Util::backquote($cfgRelation['relation'])
+                    . ' WHERE master_db  = \'' . PMA_Util::sqlAddSlashes($db) . '\'';
+        PMA_queryAsControlUser($remove_query);
+
+        $remove_query = 'DELETE FROM ' . PMA_Util::backquote($cfgRelation['db']) . '.' . PMA_Util::backquote($cfgRelation['relation'])
+                    . ' WHERE foreign_db  = \'' . PMA_Util::sqlAddSlashes($db) . '\'';
+        PMA_queryAsControlUser($remove_query);
+    }
+}
+
+?>
diff --git a/phpmyadmin/libraries/replication.inc.php b/phpmyadmin/libraries/replication.inc.php
new file mode 100644
index 0000000..467b3d5
--- /dev/null
+++ b/phpmyadmin/libraries/replication.inc.php
@@ -0,0 +1,307 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * Replication helpers
+ *
+ * @package PhpMyAdmin
+ */
+
+if (! defined('PHPMYADMIN')) {
+    exit;
+}
+
+/**
+ * get master replication from server
+ */
+$server_master_replication = PMA_DBI_fetch_result('SHOW MASTER STATUS');
+
+/**
+ * get slave replication from server
+ */
+$server_slave_replication = PMA_DBI_fetch_result('SHOW SLAVE STATUS');
+
+/**
+ * replication types
+ */
+$replication_types = array('master', 'slave');
+
+
+/**
+ * define variables for master status
+ */
+$master_variables = array(
+    'File',
+    'Position',
+    'Binlog_Do_DB',
+    'Binlog_Ignore_DB',
+);
+
+/**
+ * Define variables for slave status
+ */
+$slave_variables  = array(
+    'Slave_IO_State',
+    'Master_Host',
+    'Master_User',
+    'Master_Port',
+    'Connect_Retry',
+    'Master_Log_File',
+    'Read_Master_Log_Pos',
+    'Relay_Log_File',
+    'Relay_Log_Pos',
+    'Relay_Master_Log_File',
+    'Slave_IO_Running',
+    'Slave_SQL_Running',
+    'Replicate_Do_DB',
+    'Replicate_Ignore_DB',
+    'Replicate_Do_Table',
+    'Replicate_Ignore_Table',
+    'Replicate_Wild_Do_Table',
+    'Replicate_Wild_Ignore_Table',
+    'Last_Errno',
+    'Last_Error',
+    'Skip_Counter',
+    'Exec_Master_Log_Pos',
+    'Relay_Log_Space',
+    'Until_Condition',
+    'Until_Log_File',
+    'Until_Log_Pos',
+    'Master_SSL_Allowed',
+    'Master_SSL_CA_File',
+    'Master_SSL_CA_Path',
+    'Master_SSL_Cert',
+    'Master_SSL_Cipher',
+    'Master_SSL_Key',
+    'Seconds_Behind_Master',
+);
+/**
+ * define important variables, which need to be watched for correct running of replication in slave mode
+ *
+ * @usedby PMA_replication_print_status_table()
+ */
+// TODO change to regexp or something, to allow for negative match.
+// To e.g. highlight 'Last_Error'
+//
+$slave_variables_alerts = array(
+    'Slave_IO_Running' => 'No',
+    'Slave_SQL_Running' => 'No',
+);
+$slave_variables_oks = array(
+    'Slave_IO_Running' => 'Yes',
+    'Slave_SQL_Running' => 'Yes',
+);
+
+// check which replication is available and
+// set $server_{master/slave}_status and assign values
+
+// replication info is more easily passed to functions
+/*
+ * @todo use $replication_info everywhere instead of the generated variable names
+ */
+$replication_info = array();
+
+foreach ($replication_types as $type) {
+    if (count(${"server_{$type}_replication"}) > 0) {
+        ${"server_{$type}_status"} = true;
+        $replication_info[$type]['status'] = true;
+    } else {
+        ${"server_{$type}_status"} = false;
+        $replication_info[$type]['status'] = false;
+    }
+    if (${"server_{$type}_status"}) {
+        if ($type == "master") {
+            ${"server_{$type}_Do_DB"} = explode(",", $server_master_replication[0]["Binlog_Do_DB"]);
+            $replication_info[$type]['Do_DB'] = ${"server_{$type}_Do_DB"};
+
+            ${"server_{$type}_Ignore_DB"} = explode(",", $server_master_replication[0]["Binlog_Ignore_DB"]);
+            $replication_info[$type]['Ignore_DB'] = ${"server_{$type}_Ignore_DB"};
+        } elseif ($type == "slave") {
+            ${"server_{$type}_Do_DB"} = explode(",", $server_slave_replication[0]["Replicate_Do_DB"]);
+            $replication_info[$type]['Do_DB'] = ${"server_{$type}_Do_DB"};
+
+            ${"server_{$type}_Ignore_DB"} = explode(",", $server_slave_replication[0]["Replicate_Ignore_DB"]);
+            $replication_info[$type]['Ignore_DB'] = ${"server_{$type}_Ignore_DB"};
+
+            ${"server_{$type}_Do_Table"} = explode(",", $server_slave_replication[0]["Replicate_Do_Table"]);
+            $replication_info[$type]['Do_Table'] = ${"server_{$type}_Do_Table"};
+
+            ${"server_{$type}_Ignore_Table"} = explode(",", $server_slave_replication[0]["Replicate_Ignore_Table"]);
+            $replication_info[$type]['Ignore_Table'] = ${"server_{$type}_Ignore_Table"};
+
+            ${"server_{$type}_Wild_Do_Table"} = explode(",", $server_slave_replication[0]["Replicate_Wild_Do_Table"]);
+            $replication_info[$type]['Wild_Do_Table'] = ${"server_{$type}_Wild_Do_Table"};
+
+            ${"server_{$type}_Wild_Ignore_Table"} = explode(",", $server_slave_replication[0]["Replicate_Wild_Ignore_Table"]);
+            $replication_info[$type]['Wild_Ignore_Table'] = ${"server_{$type}_Wild_Ignore_Table"};
+        }
+    }
+}
+
+/**
+ * Extracts database or table name from string
+ *
+ * @param string $string contains "dbname.tablename"
+ * @param string $what   what to extract (db|table)
+ *
+ * @return $string the extracted part
+ */
+function PMA_extract_db_or_table($string, $what = 'db')
+{
+    $list = explode(".", $string);
+    if ('db' == $what) {
+        return $list[0];
+    } else {
+        return $list[1];
+    }
+}
+
+/**
+ * Configures replication slave
+ *
+ * @param string $action  possible values: START or STOP
+ * @param string $control default: null, possible values: SQL_THREAD or IO_THREAD or null.
+ *                        If it is set to null, it controls both SQL_THREAD and IO_THREAD
+ * @param mixed  $link    mysql link
+ *
+ * @return mixed output of PMA_DBI_try_query
+ */
+function PMA_replication_slave_control($action, $control = null, $link = null)
+{
+    $action = strtoupper($action);
+    $control = strtoupper($control);
+
+    if ($action != "START" && $action != "STOP") {
+        return -1;
+    }
+    if ($control != "SQL_THREAD" && $control != "IO_THREAD" && $control != null) {
+        return -1;
+    }
+
+    return PMA_DBI_try_query($action . " SLAVE " . $control . ";", $link);
+}
+
+/**
+ * Changes master for replication slave
+ *
+ * @param string $user     replication user on master
+ * @param string $password password for the user
+ * @param string $host     master's hostname or IP
+ * @param int    $port     port, where mysql is running
+ * @param array  $pos      position of mysql replication,
+ *                         array should contain fields File and Position
+ * @param bool   $stop     shall we stop slave?
+ * @param bool   $start    shall we start slave?
+ * @param mixed  $link     mysql link
+ *
+ * @return output of CHANGE MASTER mysql command
+ */
+function PMA_replication_slave_change_master($user, $password, $host, $port,
+    $pos, $stop = true, $start = true, $link = null
+) {
+    if ($stop) {
+        PMA_replication_slave_control("STOP", null, $link);
+    }
+
+    $out = PMA_DBI_try_query(
+        'CHANGE MASTER TO ' .
+        'MASTER_HOST=\'' . $host . '\',' .
+        'MASTER_PORT=' . ($port * 1) . ',' .
+        'MASTER_USER=\'' . $user . '\',' .
+        'MASTER_PASSWORD=\'' . $password . '\',' .
+        'MASTER_LOG_FILE=\'' . $pos["File"] . '\',' .
+        'MASTER_LOG_POS=' . $pos["Position"] . ';', $link
+    );
+
+    if ($start) {
+        PMA_replication_slave_control("START", null, $link);
+    }
+
+    return $out;
+}
+
+/**
+ * This function provides connection to remote mysql server
+ *
+ * @param string $user     mysql username
+ * @param string $password password for the user
+ * @param string $host     mysql server's hostname or IP
+ * @param int    $port     mysql remote port
+ * @param string $socket   path to unix socket
+ *
+ * @return mixed $link mysql link on success
+ */
+function PMA_replication_connect_to_master($user, $password, $host = null, $port = null, $socket = null)
+{
+    $server = array();
+    $server["host"] = $host;
+    $server["port"] = $port;
+    $server["socket"] = $socket;
+
+    // 5th parameter set to true means that it's an auxiliary connection
+    // and we must not go back to login page if it fails
+    return PMA_DBI_connect($user, $password, false, $server, true);
+}
+/**
+ * Fetches position and file of current binary log on master
+ *
+ * @param mixed $link mysql link
+ *
+ * @return array an array containing File and Position in MySQL replication
+ * on master server, useful for PMA_replication_slave_change_master
+ */
+function PMA_replication_slave_bin_log_master($link = null)
+{
+    $data = PMA_DBI_fetch_result('SHOW MASTER STATUS', null, null, $link);
+    $output = array();
+
+    if (! empty($data)) {
+        $output["File"] = $data[0]["File"];
+        $output["Position"] = $data[0]["Position"];
+    }
+    return $output;
+}
+
+/**
+ * Get list of replicated databases on master server
+ *
+ * @param mixed $link mysql link
+ *
+ * @return array array of replicated databases
+ */
+
+function PMA_replication_master_replicated_dbs($link = null)
+{
+    // let's find out, which databases are replicated
+    $data = PMA_DBI_fetch_result('SHOW MASTER STATUS', null, null, $link);
+
+    $do_db     = array();
+    $ignore_db = array();
+
+    if (! empty($data[0]['Binlog_Do_DB'])) {
+        $do_db     = explode(',', $data[0]['Binlog_Do_DB']);
+    }
+    if (! empty($data[0]['Binlog_Ignore_DB'])) {
+        $ignore_db = explode(',', $data[0]['Binlog_Ignore_DB']);
+    }
+
+    $tmp_alldbs = PMA_DBI_query('SHOW DATABASES;', $link);
+    while ($tmp_row = PMA_DBI_fetch_row($tmp_alldbs)) {
+        if (PMA_is_system_schema($tmp_row[0])) {
+            continue;
+        }
+        if (count($do_db) == 0) {
+            if (array_search($tmp_row[0], $ignore_db) !== false) {
+                continue;
+            }
+            $dblist[] = $tmp_row[0];
+
+        } else {
+            if (array_search($tmp_row[0], $do_db) !== false) {
+                $dblist[] = $tmp_row[0];
+            }
+        }
+    } // end while
+
+    return $link;
+}
+?>
diff --git a/phpmyadmin/libraries/replication_gui.lib.php b/phpmyadmin/libraries/replication_gui.lib.php
new file mode 100644
index 0000000..3743f39
--- /dev/null
+++ b/phpmyadmin/libraries/replication_gui.lib.php
@@ -0,0 +1,401 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ *
+ * @package PhpMyAdmin
+ */
+if (! defined('PHPMYADMIN')) {
+    exit;
+}
+
+/**
+ * returns code for selecting databases
+ *
+ * @return String HTML code
+ */
+function PMA_replication_db_multibox()
+{
+    $multi_values = '';
+    $multi_values .= '<select name="db_select[]" size="6" multiple="multiple" id="db_select">';
+
+    foreach ($GLOBALS['pma']->databases as $current_db) {
+        if (PMA_is_system_schema($current_db)) {
+            continue;
+        }
+        if (! empty($selectall) || (isset($tmp_select) && strpos(' ' . $tmp_select, '|' . $current_db . '|'))) {
+            $is_selected = ' selected="selected"';
+        } else {
+            $is_selected = '';
+        }
+        $current_db = htmlspecialchars($current_db);
+        $multi_values .= '                <option value="' . $current_db . '" ' . $is_selected . '>' . $current_db . '</option>';
+    } // end while
+
+    $multi_values .= '</select>';
+    $multi_values .= '<br /><a href="#" id="db_reset_href">' . __('Uncheck All') . '</a>';
+
+    return $multi_values;
+}
+
+/**
+ * prints out code for changing master
+ *
+ * @param String $submitname - submit button name
+ *
+ * @return void
+ */
+
+function PMA_replication_gui_changemaster($submitname)
+{
+
+    list($username_length, $hostname_length) = PMA_replication_get_username_hostname_length();
+
+    echo '<form method="post" action="server_replication.php">';
+    echo PMA_generate_common_hidden_inputs('', '');
+    echo ' <fieldset id="fieldset_add_user_login">';
+    echo '  <legend>' . __('Slave configuration') . ' - ' . __('Change or reconfigure master server') . '</legend>';
+    echo __('Make sure, you have unique server-id in your configuration file (my.cnf). If not, please add the following line into [mysqld] section:') . '<br />';
+    echo '<pre>server-id=' . time() . '</pre>';
+    echo '  <div class="item">';
+    echo '    <label for="text_username">' . __('User name') . ':</label>';
+    echo '    <input type="text" name="username" id="text_username" maxlength="'. $username_length . '" title="' . __('User name') . '" />';
+    echo '  </div>';
+    echo '  <div class="item">';
+    echo '    <label for="text_pma_pw">' . __('Password') .' :</label>';
+    echo '    <input type="password" id="text_pma_pw" name="pma_pw" title="' . __('Password') . '" />';
+    echo '  </div>';
+    echo '  <div class="item">';
+    echo '    <label for="text_hostname">' . __('Host') . ' :</label>';
+    echo '    <input type="text" id="text_hostname" name="hostname" maxlength="' . $hostname_length . '" value="" />';
+    echo '  </div>';
+    echo '  <div class="item">';
+    echo '     <label for="text_port">' . __('Port') . ':</label>';
+    echo '     <input type="text" id="text_port" name="port" maxlength="6" value="3306"  />';
+    echo '  </div>';
+    echo ' </fieldset>';
+    echo ' <fieldset id="fieldset_user_privtable_footer" class="tblFooters">';
+    echo '    <input type="hidden" name="sr_take_action" value="true" />';
+    echo '     <input type="hidden" name="' . $submitname . '" value="1" />';
+    echo '     <input type="submit" id="confslave_submit" value="' . __('Go') . '" />';
+    echo ' </fieldset>';
+    echo '</form>';
+}
+
+/**
+ * This function prints out table with replication status.
+ *
+ * @param string  $type   either master or slave
+ * @param boolean $hidden if true, then default style is set to hidden, default value false
+ * @param boolen  $title  if true, then title is displayed, default true
+ *
+ * @return void
+ */
+function PMA_replication_print_status_table($type, $hidden = false, $title = true)
+{
+    global ${"{$type}_variables"};
+    global ${"{$type}_variables_alerts"};
+    global ${"{$type}_variables_oks"};
+    global ${"server_{$type}_replication"};
+    global ${"strReplicationStatus_{$type}"};
+
+    // TODO check the Masters server id?
+    // seems to default to '1' when queried via SHOW VARIABLES , but resulted in error on the master when slave connects
+    // [ERROR] Error reading packet from server: Misconfigured master - server id was not set ( server_errno=1236)
+    // [ERROR] Got fatal error 1236: 'Misconfigured master - server id was not set' from master when reading data from binary log
+    //
+    //$server_id = PMA_DBI_fetch_value("SHOW VARIABLES LIKE 'server_id'", 0, 1);
+
+    echo '<div id="replication_' . $type . '_section" style="' . ($hidden ? 'display: none;' : '') . '"> ';
+
+    if ($title) {
+        if ($type == 'master') {
+            echo '<h4><a name="replication_' . $type . '"></a>' . __('Master status') . '</h4>';
+        } else {
+            echo '<h4><a name="replication_' . $type . '"></a>' . __('Slave status') . '</h4>';
+        }
+    } else {
+        echo '<br />';
+    }
+
+    echo '   <table id="server' . $type . 'replicationsummary" class="data"> ';
+    echo '   <thead>';
+    echo '    <tr>';
+    echo '     <th>' . __('Variable') . '</th>';
+    echo '        <th>' . __('Value') . '</th>';
+    echo '    </tr>';
+    echo '   </thead>';
+    echo '   <tbody>';
+
+    $odd_row = true;
+    foreach (${"{$type}_variables"} as $variable) {
+        echo '   <tr class="' . ($odd_row ? 'odd' : 'even') . '">';
+        echo '     <td class="name">';
+        echo        $variable;
+        echo '     </td>';
+        echo '     <td class="value">';
+
+
+        // TODO change to regexp or something, to allow for negative match
+        if (isset(${"{$type}_variables_alerts"}[$variable])
+            && ${"{$type}_variables_alerts"}[$variable] == ${"server_{$type}_replication"}[0][$variable]
+        ) {
+            echo '<span class="attention">';
+
+        } elseif (isset(${"{$type}_variables_oks"}[$variable])
+            && ${"{$type}_variables_oks"}[$variable] == ${"server_{$type}_replication"}[0][$variable]
+        ) {
+            echo '<span class="allfine">';
+        } else {
+            echo '<span>';
+        }
+        // allow wrapping long table lists into multiple lines
+        static $variables_wrap = array(
+            'Replicate_Do_DB', 'Replicate_Ignore_DB',
+            'Replicate_Do_Table', 'Replicate_Ignore_Table',
+            'Replicate_Wild_Do_Table', 'Replicate_Wild_Ignore_Table');
+        if (in_array($variable, $variables_wrap)) {
+            echo str_replace(',', ', ', ${"server_{$type}_replication"}[0][$variable]);
+        } else {
+            echo ${"server_{$type}_replication"}[0][$variable];
+        }
+        echo '</span>';
+
+        echo '  </td>';
+        echo ' </tr>';
+
+        $odd_row = ! $odd_row;
+    }
+
+    echo '   </tbody>';
+    echo ' </table>';
+    echo ' <br />';
+    echo '</div>';
+
+}
+
+/**
+ * Prints table with slave users connected to this master
+ *
+ * @param boolean $hidden - if true, then default style is set to hidden, default value false
+ *
+ * @return void
+ */
+function PMA_replication_print_slaves_table($hidden = false)
+{
+
+    // Fetch data
+    $data = PMA_DBI_fetch_result('SHOW SLAVE HOSTS', null, null);
+
+    echo '  <br />';
+    echo '  <div id="replication_slaves_section" style="' . ($hidden ? 'display: none;' : '') . '"> ';
+    echo '    <table class="data">';
+    echo '    <thead>';
+    echo '      <tr>';
+    echo '        <th>' . __('Server ID') . '</th>';
+    echo '        <th>' . __('Host') . '</th>';
+    echo '      </tr>';
+    echo '    </thead>';
+    echo '    <tbody>';
+
+    $odd_row = true;
+    foreach ($data as $slave) {
+        echo '    <tr class="' . ($odd_row ? 'odd' : 'even') . '">';
+        echo '      <td class="value">' . $slave['Server_id'] . '</td>';
+        echo '      <td class="value">' . $slave['Host'] . '</td>';
+        echo '    </tr>';
+
+        $odd_row = ! $odd_row;
+    }
+
+    echo '    </tbody>';
+    echo '    </table>';
+    echo '    <br />';
+    PMA_Message::notice(__('Only slaves started with the --report-host=host_name option are visible in this list.'))->display();
+    echo '    <br />';
+    echo '  </div>';
+}
+
+/**
+ * get the correct username and hostname lengths for this MySQL server
+ *
+ * @return array   username length, hostname length
+ */
+
+function PMA_replication_get_username_hostname_length()
+{
+    $fields_info = PMA_DBI_get_columns('mysql', 'user');
+    $username_length = 16;
+    $hostname_length = 41;
+    foreach ($fields_info as $val) {
+        if ($val['Field'] == 'User') {
+            strtok($val['Type'], '()');
+            $v = strtok('()');
+            if (is_int($v)) {
+                $username_length = $v;
+            }
+        } elseif ($val['Field'] == 'Host') {
+            strtok($val['Type'], '()');
+            $v = strtok('()');
+            if (is_int($v)) {
+                $hostname_length = $v;
+            }
+        }
+    }
+    return array($username_length, $hostname_length);
+}
+
+/**
+ * Print code to add a replication slave user to the master
+ *
+ * @return void
+ */
+function PMA_replication_gui_master_addslaveuser()
+{
+
+    list($username_length, $hostname_length) = PMA_replication_get_username_hostname_length();
+
+    if (isset($GLOBALS['username']) && strlen($GLOBALS['username']) === 0) {
+        $GLOBALS['pred_username'] = 'any';
+    }
+    echo '<div id="master_addslaveuser_gui">';
+    echo '<form autocomplete="off" method="post" action="server_privileges.php" onsubmit="return checkAddUser(this);">';
+    echo PMA_generate_common_hidden_inputs('', '');
+    echo '<fieldset id="fieldset_add_user_login">'
+        . '<legend>'.__('Add slave replication user').'</legend>'
+    . '<input type="hidden" name="grant_count" value="25" />'
+    . '<input type="hidden" name="createdb" id="createdb_0" value="0" />'
+        . '<input id="checkbox_Repl_slave_priv" type="hidden" title="Needed for the replication slaves." value="Y" name="Repl_slave_priv"/>'
+        . '<input id="checkbox_Repl_client_priv" type="hidden" title="Needed for the replication slaves." value="Y" name="Repl_client_priv"/>'
+    . ''
+        . '<input type="hidden" name="sr_take_action" value="true" />'
+        . '<div class="item">'
+        . '<label for="select_pred_username">'
+        . '    ' . __('User name') . ':'
+        . '</label>'
+        . '<span class="options">'
+        . '    <select name="pred_username" id="select_pred_username" title="' . __('User name') . '"'
+        . '        onchange="if (this.value == \'any\') { username.value = \'\'; } else if (this.value == \'userdefined\') { username.focus(); username.select(); }">'
+        . '        <option value="any"' . ((isset($GLOBALS['pred_username']) && $GLOBALS['pred_username'] == 'any') ? ' selected="selected"' : '') . '>' . __('Any user') . '</option>'
+        . '        <option value="userdefined"' . ((! isset($GLOBALS['pred_username']) || $GLOBALS['pred_username'] == 'userdefined') ? ' selected="selected"' : '') . '>' . __('Use text field') . ':</option>'
+        . '    </select>'
+        . '</span>'
+        . '<input type="text" name="username" maxlength="'
+        . $username_length . '" title="' . __('User name') . '"'
+        . (empty($GLOBALS['username'])
+        ? ''
+        : ' value="' . (isset($GLOBALS['new_username'])
+        ? $GLOBALS['new_username']
+        : $GLOBALS['username']) . '"')
+        . ' onchange="pred_username.value = \'userdefined\';" />'
+        . '</div>'
+        . '<div class="item">'
+        . '<label for="select_pred_hostname">'
+        . '    ' . __('Host') . ':'
+        . '</label>'
+        . '<span class="options">'
+        . '    <select name="pred_hostname" id="select_pred_hostname" title="' . __('Host') . '"';
+    $_current_user = PMA_DBI_fetch_value('SELECT USER();');
+    if (! empty($_current_user)) {
+        $thishost = str_replace("'", '', substr($_current_user, (strrpos($_current_user, '@') + 1)));
+        if ($thishost == 'localhost' || $thishost == '127.0.0.1') {
+            unset($thishost);
+        }
+    }
+    echo '    onchange="if (this.value == \'any\') { hostname.value = \'%\'; } else if (this.value == \'localhost\') { hostname.value = \'localhost\'; } '
+        . (empty($thishost) ? '' : 'else if (this.value == \'thishost\') { hostname.value = \'' . addslashes(htmlspecialchars($thishost)) . '\'; } ')
+        . 'else if (this.value == \'hosttable\') { hostname.value = \'\'; } else if (this.value == \'userdefined\') { hostname.focus(); hostname.select(); }">' . "\n";
+    unset($_current_user);
+
+    // when we start editing a user, $GLOBALS['pred_hostname'] is not defined
+    if (! isset($GLOBALS['pred_hostname']) && isset($GLOBALS['hostname'])) {
+        switch (strtolower($GLOBALS['hostname'])) {
+        case 'localhost':
+        case '127.0.0.1':
+            $GLOBALS['pred_hostname'] = 'localhost';
+            break;
+        case '%':
+            $GLOBALS['pred_hostname'] = 'any';
+            break;
+        default:
+            $GLOBALS['pred_hostname'] = 'userdefined';
+            break;
+        }
+    }
+    echo '        <option value="any"'
+        . ((isset($GLOBALS['pred_hostname']) && $GLOBALS['pred_hostname'] == 'any')
+        ? ' selected="selected"' : '') . '>' . __('Any host')
+        . '</option>'
+        . '        <option value="localhost"'
+        . ((isset($GLOBALS['pred_hostname']) && $GLOBALS['pred_hostname'] == 'localhost')
+        ? ' selected="selected"' : '') . '>' . __('Local')
+        . '</option>';
+
+    if (!empty($thishost)) {
+        echo '        <option value="thishost"'
+            . ((isset($GLOBALS['pred_hostname']) && $GLOBALS['pred_hostname'] == 'thishost')
+            ? ' selected="selected"' : '') . '>' . __('This Host')
+            . '</option>';
+    }
+    unset($thishost);
+    echo '        <option value="hosttable"'
+        . ((isset($GLOBALS['pred_hostname']) && $GLOBALS['pred_hostname'] == 'hosttable')
+        ? ' selected="selected"' : '') . '>' . __('Use Host Table')
+        . '</option>'
+        . '        <option value="userdefined"'
+        . ((isset($GLOBALS['pred_hostname']) && $GLOBALS['pred_hostname'] == 'userdefined')
+        ? ' selected="selected"' : '')
+        . '>' . __('Use text field') . ':</option>'
+        . '    </select>'
+        . '</span>'
+        . '<input type="text" name="hostname" maxlength="'
+        . $hostname_length . '" value="'
+        . (isset($GLOBALS['hostname']) ? $GLOBALS['hostname'] : '')
+        . '" title="' . __('Host')
+        . '" onchange="pred_hostname.value = \'userdefined\';" />'
+        . PMA_Util::showHint(
+            __('When Host table is used, this field is ignored and values stored in Host table are used instead.')
+        )
+        . '</div>'
+        . '<div class="item">'
+        . '<label for="select_pred_password">'
+        . '    ' . __('Password') . ':'
+        . '</label>'
+        . '<span class="options">'
+        . '    <select name="pred_password" id="select_pred_password" title="'
+        . __('Password') . '"'
+        . '            onchange="if (this.value == \'none\') { pma_pw.value = \'\'; pma_pw2.value = \'\'; } else if (this.value == \'userdefined\') { pma_pw.focus(); pma_pw.select(); }">'
+        . '        <option value="none"';
+    if (isset($GLOBALS['username'])) {
+        echo '  selected="selected"';
+    }
+    echo '>' . __('No Password') . '</option>'
+        . '        <option value="userdefined"' . (isset($GLOBALS['username']) ? '' : ' selected="selected"') . '>' . __('Use text field') . ':</option>'
+        . '    </select>'
+        . '</span>'
+        . '<input type="password" id="text_pma_pw" name="pma_pw" title="' . __('Password') . '" onchange="pred_password.value = \'userdefined\';" />'
+        . '</div>'
+        . '<div class="item">'
+        . '<label for="text_pma_pw2">'
+        . '    ' . __('Re-type') . ':'
+        . '</label>'
+        . '<span class="options"> </span>'
+        . '<input type="password" name="pma_pw2" id="text_pma_pw2" title="' . __('Re-type') . '" onchange="pred_password.value = \'userdefined\';" />'
+        . '</div>'
+        . '<div class="item">'
+        . '<label for="button_generate_password">'
+        . '    ' . __('Generate Password') . ':'
+        . '</label>'
+        . '<span class="options">'
+        . '    <input type="button" class="button" id="button_generate_password" value="' . __('Generate') . '" onclick="suggestPassword(this.form)" />'
+        . '</span>'
+        . '<input type="text" name="generated_pw" id="generated_pw" />'
+        . '</div>'
+        . '</fieldset>';
+    echo '<fieldset id="fieldset_user_privtable_footer" class="tblFooters">'
+        . '    <input type="hidden" name="adduser_submit" value="1" />'
+        . '    <input type="submit" id="adduser_submit" value="' . __('Go') . '" />'
+        . '</fieldset>';
+    echo '</form>';
+    echo '</div>';
+}
+?>
diff --git a/phpmyadmin/libraries/rte/rte_events.lib.php b/phpmyadmin/libraries/rte/rte_events.lib.php
new file mode 100644
index 0000000..7d4ce6c
--- /dev/null
+++ b/phpmyadmin/libraries/rte/rte_events.lib.php
@@ -0,0 +1,637 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * Functions for event management.
+ *
+ * @package PhpMyAdmin
+ */
+if (! defined('PHPMYADMIN')) {
+    exit;
+}
+
+/**
+ * Sets required globals
+ *
+ * @return void
+ */
+function PMA_EVN_setGlobals()
+{
+    global $event_status, $event_type, $event_interval;
+
+    $event_status        = array(
+                               'query'   => array('ENABLE',
+                                                  'DISABLE',
+                                                  'DISABLE ON SLAVE'),
+                               'display' => array('ENABLED',
+                                                  'DISABLED',
+                                                  'SLAVESIDE_DISABLED')
+                           );
+    $event_type          = array('RECURRING',
+                                 'ONE TIME');
+    $event_interval      = array('YEAR',
+                                 'QUARTER',
+                                 'MONTH',
+                                 'DAY',
+                                 'HOUR',
+                                 'MINUTE',
+                                 'WEEK',
+                                 'SECOND',
+                                 'YEAR_MONTH',
+                                 'DAY_HOUR',
+                                 'DAY_MINUTE',
+                                 'DAY_SECOND',
+                                 'HOUR_MINUTE',
+                                 'HOUR_SECOND',
+                                 'MINUTE_SECOND');
+}
+
+/**
+ * Main function for the events functionality
+ *
+ * @return void
+ */
+function PMA_EVN_main()
+{
+    global $db;
+
+    PMA_EVN_setGlobals();
+    /**
+     * Process all requests
+     */
+    PMA_EVN_handleEditor();
+    PMA_EVN_handleExport();
+    /**
+     * Display a list of available events
+     */
+    $columns = "`EVENT_NAME`, `EVENT_TYPE`, `STATUS`";
+    $where   = "EVENT_SCHEMA='" . PMA_Util::sqlAddSlashes($db) . "'";
+    $query   = "SELECT $columns FROM `INFORMATION_SCHEMA`.`EVENTS` "
+             . "WHERE $where ORDER BY `EVENT_NAME` ASC;";
+    $items   = PMA_DBI_fetch_result($query);
+    echo PMA_RTE_getList('event', $items);
+    /**
+     * Display a link for adding a new event, if
+     * the user has the privileges and a link to
+     * toggle the state of the event scheduler.
+     */
+    echo PMA_EVN_getFooterLinks();
+} // end PMA_EVN_main()
+
+/**
+ * Handles editor requests for adding or editing an item
+ *
+ * @return void
+ */
+function PMA_EVN_handleEditor()
+{
+    global $_REQUEST, $_POST, $errors, $db;
+
+    if (! empty($_REQUEST['editor_process_add'])
+        || ! empty($_REQUEST['editor_process_edit'])
+    ) {
+        $sql_query = '';
+
+        $item_query = PMA_EVN_getQueryFromRequest();
+
+        if (! count($errors)) { // set by PMA_RTN_getQueryFromRequest()
+            // Execute the created query
+            if (! empty($_REQUEST['editor_process_edit'])) {
+                // Backup the old trigger, in case something goes wrong
+                $create_item = PMA_DBI_get_definition(
+                    $db,
+                    'EVENT',
+                    $_REQUEST['item_original_name']
+                );
+                $drop_item = "DROP EVENT "
+                    . PMA_Util::backquote($_REQUEST['item_original_name']) . ";\n";
+                $result = PMA_DBI_try_query($drop_item);
+                if (! $result) {
+                    $errors[] = sprintf(
+                        __('The following query has failed: "%s"'),
+                        htmlspecialchars($drop_item)
+                    )
+                    . '<br />'
+                    . __('MySQL said: ') . PMA_DBI_getError(null);
+                } else {
+                    $result = PMA_DBI_try_query($item_query);
+                    if (! $result) {
+                        $errors[] = sprintf(
+                            __('The following query has failed: "%s"'),
+                            htmlspecialchars($item_query)
+                        )
+                        . '<br />'
+                        . __('MySQL said: ') . PMA_DBI_getError(null);
+                        // We dropped the old item, but were unable to create
+                        // the new one. Try to restore the backup query
+                        $result = PMA_DBI_try_query($create_item);
+                        if (! $result) {
+                            // OMG, this is really bad! We dropped the query,
+                            // failed to create a new one
+                            // and now even the backup query does not execute!
+                            // This should not happen, but we better handle
+                            // this just in case.
+                            $errors[] = __(
+                                'Sorry, we failed to restore the dropped event.'
+                            )
+                            . '<br />'
+                            . __('The backed up query was:')
+                            . "\"" . htmlspecialchars($create_item) . "\""
+                            . '<br />'
+                            . __('MySQL said: ') . PMA_DBI_getError(null);
+                        }
+                    } else {
+                        $message = PMA_Message::success(
+                            __('Event %1$s has been modified.')
+                        );
+                        $message->addParam(
+                            PMA_Util::backquote($_REQUEST['item_name'])
+                        );
+                        $sql_query = $drop_item . $item_query;
+                    }
+                }
+            } else {
+                // 'Add a new item' mode
+                $result = PMA_DBI_try_query($item_query);
+                if (! $result) {
+                    $errors[] = sprintf(
+                        __('The following query has failed: "%s"'),
+                        htmlspecialchars($item_query)
+                    )
+                    . '<br /><br />'
+                    . __('MySQL said: ') . PMA_DBI_getError(null);
+                } else {
+                    $message = PMA_Message::success(
+                        __('Event %1$s has been created.')
+                    );
+                    $message->addParam(
+                        PMA_Util::backquote($_REQUEST['item_name'])
+                    );
+                    $sql_query = $item_query;
+                }
+            }
+        }
+
+        if (count($errors)) {
+            $message = PMA_Message::error(__('<b>One or more errors have occured while processing your request:</b>'));
+            $message->addString('<ul>');
+            foreach ($errors as $string) {
+                $message->addString('<li>' . $string . '</li>');
+            }
+            $message->addString('</ul>');
+        }
+
+        $output = PMA_Util::getMessage($message, $sql_query);
+        if ($GLOBALS['is_ajax_request']) {
+            $response = PMA_Response::getInstance();
+            if ($message->isSuccess()) {
+                $columns = "`EVENT_NAME`, `EVENT_TYPE`, `STATUS`";
+                $where   = "EVENT_SCHEMA='" . PMA_Util::sqlAddSlashes($db) . "' "
+                    . "AND EVENT_NAME='"
+                    . PMA_Util::sqlAddSlashes($_REQUEST['item_name']) . "'";
+                $query   = "SELECT " . $columns
+                    . " FROM `INFORMATION_SCHEMA`.`EVENTS` WHERE " . $where. ";";
+                $event   = PMA_DBI_fetch_single_row($query);
+                $response->addJSON(
+                    'name',
+                    htmlspecialchars(strtoupper($_REQUEST['item_name']))
+                );
+                $response->addJSON('new_row', PMA_EVN_getRowForList($event));
+                $response->addJSON('insert', ! empty($event));
+                $response->addJSON('message', $output);
+            } else {
+                $response->isSuccess(false);
+                $response->addJSON('message', $message);
+            }
+            exit;
+        }
+    }
+    /**
+     * Display a form used to add/edit a trigger, if necessary
+     */
+    if (count($errors)
+        || (empty($_REQUEST['editor_process_add'])
+        && empty($_REQUEST['editor_process_edit'])
+        && (! empty($_REQUEST['add_item'])
+        || ! empty($_REQUEST['edit_item'])
+        || ! empty($_REQUEST['item_changetype'])))
+    ) { // FIXME: this must be simpler than that
+        $operation = '';
+        if (! empty($_REQUEST['item_changetype'])) {
+            $operation = 'change';
+        }
+        // Get the data for the form (if any)
+        if (! empty($_REQUEST['add_item'])) {
+            $title = PMA_RTE_getWord('add');
+            $item = PMA_EVN_getDataFromRequest();
+            $mode = 'add';
+        } else if (! empty($_REQUEST['edit_item'])) {
+            $title = __("Edit event");
+            if (! empty($_REQUEST['item_name'])
+                && empty($_REQUEST['editor_process_edit'])
+                && empty($_REQUEST['item_changetype'])
+            ) {
+                $item = PMA_EVN_getDataFromName($_REQUEST['item_name']);
+                if ($item !== false) {
+                    $item['item_original_name'] = $item['item_name'];
+                }
+            } else {
+                $item = PMA_EVN_getDataFromRequest();
+            }
+            $mode = 'edit';
+        }
+        if ($item !== false) {
+            // Show form
+            $editor = PMA_EVN_getEditorForm($mode, $operation, $item);
+            if ($GLOBALS['is_ajax_request']) {
+                $response = PMA_Response::getInstance();
+                $response->addJSON('message', $editor);
+                $response->addJSON('title', $title);
+            } else {
+                echo "\n\n<h2>$title</h2>\n\n$editor";
+                unset($_POST);
+            }
+            exit;
+        } else {
+            $message  = __('Error in processing request') . ' : ';
+            $message .= sprintf(
+                PMA_RTE_getWord('not_found'),
+                htmlspecialchars(PMA_Util::backquote($_REQUEST['item_name'])),
+                htmlspecialchars(PMA_Util::backquote($db))
+            );
+            $message = PMA_message::error($message);
+            if ($GLOBALS['is_ajax_request']) {
+                $response = PMA_Response::getInstance();
+                $response->isSuccess(false);
+                $response->addJSON('message', $message);
+                exit;
+            } else {
+                $message->display();
+            }
+        }
+    }
+} // end PMA_EVN_handleEditor()
+
+/**
+ * This function will generate the values that are required to for the editor
+ *
+ * @return array    Data necessary to create the editor.
+ */
+function PMA_EVN_getDataFromRequest()
+{
+    $retval = array();
+    $indices = array('item_name',
+                     'item_original_name',
+                     'item_status',
+                     'item_execute_at',
+                     'item_interval_value',
+                     'item_interval_field',
+                     'item_starts',
+                     'item_ends',
+                     'item_definition',
+                     'item_preserve',
+                     'item_comment',
+                     'item_definer');
+    foreach ($indices as $index) {
+        $retval[$index] = isset($_REQUEST[$index]) ? $_REQUEST[$index] : '';
+    }
+    $retval['item_type']        = 'ONE TIME';
+    $retval['item_type_toggle'] = 'RECURRING';
+    if (isset($_REQUEST['item_type']) && $_REQUEST['item_type'] == 'RECURRING') {
+        $retval['item_type']        = 'RECURRING';
+        $retval['item_type_toggle'] = 'ONE TIME';
+    }
+    return $retval;
+} // end PMA_EVN_getDataFromRequest()
+
+/**
+ * This function will generate the values that are required to complete
+ * the "Edit event" form given the name of a event.
+ *
+ * @param string $name The name of the event.
+ *
+ * @return array Data necessary to create the editor.
+ */
+function PMA_EVN_getDataFromName($name)
+{
+    global $db;
+
+    $retval = array();
+    $columns = "`EVENT_NAME`, `STATUS`, `EVENT_TYPE`, `EXECUTE_AT`, "
+             . "`INTERVAL_VALUE`, `INTERVAL_FIELD`, `STARTS`, `ENDS`, "
+             . "`EVENT_DEFINITION`, `ON_COMPLETION`, `DEFINER`, `EVENT_COMMENT`";
+    $where   = "EVENT_SCHEMA='" . PMA_Util::sqlAddSlashes($db) . "' "
+             . "AND EVENT_NAME='" . PMA_Util::sqlAddSlashes($name) . "'";
+    $query   = "SELECT $columns FROM `INFORMATION_SCHEMA`.`EVENTS` WHERE $where;";
+    $item    = PMA_DBI_fetch_single_row($query);
+    if (! $item) {
+        return false;
+    }
+    $retval['item_name']   = $item['EVENT_NAME'];
+    $retval['item_status'] = $item['STATUS'];
+    $retval['item_type']   = $item['EVENT_TYPE'];
+    if ($retval['item_type'] == 'RECURRING') {
+        $retval['item_type_toggle'] = 'ONE TIME';
+    } else {
+        $retval['item_type_toggle'] = 'RECURRING';
+    }
+    $retval['item_execute_at']     = $item['EXECUTE_AT'];
+    $retval['item_interval_value'] = $item['INTERVAL_VALUE'];
+    $retval['item_interval_field'] = $item['INTERVAL_FIELD'];
+    $retval['item_starts']         = $item['STARTS'];
+    $retval['item_ends']           = $item['ENDS'];
+    $retval['item_preserve']       = '';
+    if ($item['ON_COMPLETION'] == 'PRESERVE') {
+        $retval['item_preserve']   = " checked='checked'";
+    }
+    $retval['item_definition'] = $item['EVENT_DEFINITION'];
+    $retval['item_definer']    = $item['DEFINER'];
+    $retval['item_comment']    = $item['EVENT_COMMENT'];
+
+    return $retval;
+} // end PMA_EVN_getDataFromName()
+
+/**
+ * Displays a form used to add/edit an event
+ *
+ * @param string $mode      If the editor will be used edit an event
+ *                              or add a new one: 'edit' or 'add'.
+ * @param string $operation If the editor was previously invoked with
+ *                              JS turned off, this will hold the name of
+ *                              the current operation
+ * @param array  $item      Data for the event returned by
+ *                              PMA_EVN_getDataFromRequest() or
+ *                              PMA_EVN_getDataFromName()
+ *
+ * @return string   HTML code for the editor.
+ */
+function PMA_EVN_getEditorForm($mode, $operation, $item)
+{
+    global $db, $table, $event_status, $event_type, $event_interval;
+
+    // Escape special characters
+    $need_escape = array(
+                       'item_original_name',
+                       'item_name',
+                       'item_type',
+                       'item_execute_at',
+                       'item_interval_value',
+                       'item_starts',
+                       'item_ends',
+                       'item_definition',
+                       'item_definer',
+                       'item_comment'
+                   );
+    foreach ($need_escape as $index) {
+        $item[$index] = htmlentities($item[$index], ENT_QUOTES);
+    }
+    $original_data = '';
+    if ($mode == 'edit') {
+        $original_data = "<input name='item_original_name' "
+                       . "type='hidden' value='{$item['item_original_name']}'/>\n";
+    }
+    // Handle some logic first
+    if ($operation == 'change') {
+        if ($item['item_type'] == 'RECURRING') {
+            $item['item_type']         = 'ONE TIME';
+            $item['item_type_toggle']  = 'RECURRING';
+        } else {
+            $item['item_type']         = 'RECURRING';
+            $item['item_type_toggle']  = 'ONE TIME';
+        }
+    }
+    if ($item['item_type'] == 'ONE TIME') {
+        $isrecurring_class = ' hide';
+        $isonetime_class   = '';
+    } else {
+        $isrecurring_class = '';
+        $isonetime_class   = ' hide';
+    }
+    // Create the output
+    $retval  = "";
+    $retval .= "<!-- START " . strtoupper($mode) . " EVENT FORM -->\n\n";
+    $retval .= "<form class='rte_form' action='db_events.php' method='post'>\n";
+    $retval .= "<input name='{$mode}_item' type='hidden' value='1' />\n";
+    $retval .= $original_data;
+    $retval .= PMA_generate_common_hidden_inputs($db, $table) . "\n";
+    $retval .= "<fieldset>\n";
+    $retval .= "<legend>" . __('Details') . "</legend>\n";
+    $retval .= "<table class='rte_table' style='width: 100%'>\n";
+    $retval .= "<tr>\n";
+    $retval .= "    <td style='width: 20%;'>" . __('Event name') . "</td>\n";
+    $retval .= "    <td><input type='text' name='item_name' \n";
+    $retval .= "               value='{$item['item_name']}'\n";
+    $retval .= "               maxlength='64' /></td>\n";
+    $retval .= "</tr>\n";
+    $retval .= "<tr>\n";
+    $retval .= "    <td>" . __('Status') . "</td>\n";
+    $retval .= "    <td>\n";
+    $retval .= "        <select name='item_status'>\n";
+    foreach ($event_status['display'] as $key => $value) {
+        $selected = "";
+        if (! empty($item['item_status']) && $item['item_status'] == $value) {
+            $selected = " selected='selected'";
+        }
+        $retval .= "<option$selected>$value</option>";
+    }
+    $retval .= "        </select>\n";
+    $retval .= "    </td>\n";
+    $retval .= "</tr>\n";
+
+    $retval .= "<tr>\n";
+    $retval .= "    <td>" . __('Event type') . "</td>\n";
+    $retval .= "    <td>\n";
+    if ($GLOBALS['is_ajax_request']) {
+        $retval .= "        <select name='item_type'>";
+        foreach ($event_type as $key => $value) {
+            $selected = "";
+            if (! empty($item['item_type']) && $item['item_type'] == $value) {
+                $selected = " selected='selected'";
+            }
+            $retval .= "<option$selected>$value</option>";
+        }
+        $retval .= "        </select>\n";
+    } else {
+        $retval .= "        <input name='item_type' type='hidden' \n";
+        $retval .= "               value='{$item['item_type']}' />\n";
+        $retval .= "        <div style='width: 49%; float: left; text-align: center;"
+                                . " font-weight: bold;'>\n";
+        $retval .= "            {$item['item_type']}\n";
+        $retval .= "        </div>\n";
+        $retval .= "        <input style='width: 49%;' type='submit'\n";
+        $retval .= "               name='item_changetype'\n";
+        $retval .= "               value='";
+        $retval .= sprintf(__('Change to %s'), $item['item_type_toggle']);
+        $retval .= "' />\n";
+    }
+    $retval .= "    </td>\n";
+    $retval .= "</tr>\n";
+    $retval .= "<tr class='onetime_event_row $isonetime_class'>\n";
+    $retval .= "    <td>" . __('Execute at') . "</td>\n";
+    $retval .= "    <td class='nowrap'>\n";
+    $retval .= "        <input type='text' name='item_execute_at'\n";
+    $retval .= "               value='{$item['item_execute_at']}'\n";
+    $retval .= "               class='datetimefield' />\n";
+    $retval .= "    </td>\n";
+    $retval .= "</tr>\n";
+    $retval .= "<tr class='recurring_event_row $isrecurring_class'>\n";
+    $retval .= "    <td>" . __('Execute every') . "</td>\n";
+    $retval .= "    <td>\n";
+    $retval .= "        <input style='width: 49%;' type='text'\n";
+    $retval .= "               name='item_interval_value'\n";
+    $retval .= "               value='{$item['item_interval_value']}' />\n";
+    $retval .= "        <select style='width: 49%;' name='item_interval_field'>";
+    foreach ($event_interval as $key => $value) {
+        $selected = "";
+        if (! empty($item['item_interval_field'])
+            && $item['item_interval_field'] == $value
+        ) {
+            $selected = " selected='selected'";
+        }
+        $retval .= "<option$selected>$value</option>";
+    }
+    $retval .= "        </select>\n";
+    $retval .= "    </td>\n";
+    $retval .= "</tr>\n";
+    $retval .= "<tr class='recurring_event_row$isrecurring_class'>\n";
+    $retval .= "    <td>" . _pgettext('Start of recurring event', 'Start');
+    $retval .= "    </td>\n";
+    $retval .= "    <td class='nowrap'>\n";
+    $retval .= "        <input type='text'\n name='item_starts'\n";
+    $retval .= "               value='{$item['item_starts']}'\n";
+    $retval .= "               class='datetimefield' />\n";
+    $retval .= "    </td>\n";
+    $retval .= "</tr>\n";
+    $retval .= "<tr class='recurring_event_row$isrecurring_class'>\n";
+    $retval .= "    <td>" . _pgettext('End of recurring event', 'End') . "</td>\n";
+    $retval .= "    <td class='nowrap'>\n";
+    $retval .= "        <input type='text' name='item_ends'\n";
+    $retval .= "               value='{$item['item_ends']}'\n";
+    $retval .= "               class='datetimefield' />\n";
+    $retval .= "    </td>\n";
+    $retval .= "</tr>\n";
+    $retval .= "<tr>\n";
+    $retval .= "    <td>" . __('Definition') . "</td>\n";
+    $retval .= "    <td><textarea name='item_definition' rows='15' cols='40'>";
+    $retval .= $item['item_definition'];
+    $retval .= "</textarea></td>\n";
+    $retval .= "</tr>\n";
+    $retval .= "<tr>\n";
+    $retval .= "    <td>" . __('On completion preserve') . "</td>\n";
+    $retval .= "    <td><input type='checkbox'\n";
+    $retval .= "             name='item_preserve'{$item['item_preserve']} /></td>\n";
+    $retval .= "</tr>\n";
+    $retval .= "<tr>\n";
+    $retval .= "    <td>" . __('Definer') . "</td>\n";
+    $retval .= "    <td><input type='text' name='item_definer'\n";
+    $retval .= "               value='{$item['item_definer']}' /></td>\n";
+    $retval .= "</tr>\n";
+    $retval .= "<tr>\n";
+    $retval .= "    <td>" . __('Comment') . "</td>\n";
+    $retval .= "    <td><input type='text' name='item_comment' maxlength='64'\n";
+    $retval .= "               value='{$item['item_comment']}' /></td>\n";
+    $retval .= "</tr>\n";
+    $retval .= "</table>\n";
+    $retval .= "</fieldset>\n";
+    if ($GLOBALS['is_ajax_request']) {
+        $retval .= "<input type='hidden' name='editor_process_{$mode}'\n";
+        $retval .= "       value='true' />\n";
+        $retval .= "<input type='hidden' name='ajax_request' value='true' />\n";
+    } else {
+        $retval .= "<fieldset class='tblFooters'>\n";
+        $retval .= "    <input type='submit' name='editor_process_{$mode}'\n";
+        $retval .= "           value='" . __('Go') . "' />\n";
+        $retval .= "</fieldset>\n";
+    }
+    $retval .= "</form>\n\n";
+    $retval .= "<!-- END " . strtoupper($mode) . " EVENT FORM -->\n\n";
+
+    return $retval;
+} // end PMA_EVN_getEditorForm()
+
+/**
+ * Composes the query necessary to create an event from an HTTP request.
+ *
+ * @return string  The CREATE EVENT query.
+ */
+function PMA_EVN_getQueryFromRequest()
+{
+    global $_REQUEST, $errors, $event_status, $event_type, $event_interval;
+
+    $query = 'CREATE ';
+    if (! empty($_REQUEST['item_definer'])) {
+        if (strpos($_REQUEST['item_definer'], '@') !== false) {
+            $arr = explode('@', $_REQUEST['item_definer']);
+            $query .= 'DEFINER=' . PMA_Util::backquote($arr[0]);
+            $query .= '@' . PMA_Util::backquote($arr[1]) . ' ';
+        } else {
+            $errors[] = __('The definer must be in the "username at hostname" format');
+        }
+    }
+    $query .= 'EVENT ';
+    if (! empty($_REQUEST['item_name'])) {
+        $query .= PMA_Util::backquote($_REQUEST['item_name']) . ' ';
+    } else {
+        $errors[] = __('You must provide an event name');
+    }
+    $query .= 'ON SCHEDULE ';
+    if (! empty($_REQUEST['item_type'])
+        && in_array($_REQUEST['item_type'], $event_type)
+    ) {
+        if ($_REQUEST['item_type'] == 'RECURRING') {
+            if (! empty($_REQUEST['item_interval_value'])
+                && !empty($_REQUEST['item_interval_field'])
+                && in_array($_REQUEST['item_interval_field'], $event_interval)
+            ) {
+                $query .= 'EVERY ' . intval($_REQUEST['item_interval_value']) . ' ';
+                $query .= $_REQUEST['item_interval_field'] . ' ';
+            } else {
+                $errors[] = __('You must provide a valid interval value for the event.');
+            }
+            if (! empty($_REQUEST['item_starts'])) {
+                $query .= "STARTS '"
+                    . PMA_Util::sqlAddSlashes($_REQUEST['item_starts']) . "' ";
+            }
+            if (! empty($_REQUEST['item_ends'])) {
+                $query .= "ENDS '"
+                    . PMA_Util::sqlAddSlashes($_REQUEST['item_ends']) . "' ";
+            }
+        } else {
+            if (! empty($_REQUEST['item_execute_at'])) {
+                $query .= "AT '"
+                    . PMA_Util::sqlAddSlashes($_REQUEST['item_execute_at']) . "' ";
+            } else {
+                $errors[] = __('You must provide a valid execution time for the event.');
+            }
+        }
+    } else {
+        $errors[] = __('You must provide a valid type for the event.');
+    }
+    $query .= 'ON COMPLETION ';
+    if (empty($_REQUEST['item_preserve'])) {
+        $query .= 'NOT ';
+    }
+    $query .= 'PRESERVE ';
+    if (! empty($_REQUEST['item_status'])) {
+        foreach ($event_status['display'] as $key => $value) {
+            if ($value == $_REQUEST['item_status']) {
+                $query .= $event_status['query'][$key] . ' ';
+                break;
+            }
+        }
+    }
+    if (! empty($_REQUEST['item_comment'])) {
+        $query .= "COMMENT '" . PMA_Util::sqlAddslashes(
+            $_REQUEST['item_comment']
+        ) . "' ";
+    }
+    $query .= 'DO ';
+    if (! empty($_REQUEST['item_definition'])) {
+        $query .= $_REQUEST['item_definition'];
+    } else {
+        $errors[] = __('You must provide an event definition.');
+    }
+
+    return $query;
+} // end PMA_EVN_getQueryFromRequest()
+
+?>
diff --git a/phpmyadmin/libraries/rte/rte_export.lib.php b/phpmyadmin/libraries/rte/rte_export.lib.php
new file mode 100644
index 0000000..a553ae9
--- /dev/null
+++ b/phpmyadmin/libraries/rte/rte_export.lib.php
@@ -0,0 +1,122 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * Common functions for the export functionality for Routines, Triggers and Events.
+ *
+ * @package PhpMyAdmin
+ */
+if (! defined('PHPMYADMIN')) {
+    exit;
+}
+
+/**
+ * This function is called from one of the other functions in this file
+ * and it completes the handling of the export functionality.
+ *
+ * @param string $item_name   The name of the item that we are exporting
+ * @param string $export_data The SQL query to create the requested item
+ *
+ * @return void
+ */
+function PMA_RTE_handleExport($item_name, $export_data)
+{
+    global $db;
+
+    $item_name = htmlspecialchars(PMA_Util::backquote($_GET['item_name']));
+    if ($export_data !== false) {
+        $export_data = '<textarea cols="40" rows="15" style="width: 100%;">'
+                     . htmlspecialchars(trim($export_data)) . '</textarea>';
+        $title = sprintf(PMA_RTE_getWord('export'), $item_name);
+        if ($GLOBALS['is_ajax_request'] == true) {
+            $response = PMA_Response::getInstance();
+            $response->addJSON('message', $export_data);
+            $response->addJSON('title', $title);
+            exit;
+        } else {
+            echo "<fieldset>\n"
+               . "<legend>$title</legend>\n"
+               . $export_data
+               . "</fieldset>\n";
+        }
+    } else {
+        $_db = htmlspecialchars(PMA_Util::backquote($db));
+        $response = __('Error in Processing Request') . ' : '
+                  . sprintf(PMA_RTE_getWord('not_found'), $item_name, $_db);
+        $response = PMA_message::error($response);
+        if ($GLOBALS['is_ajax_request'] == true) {
+            $response = PMA_Response::getInstance();
+            $response->isSuccess(false);
+            $response->addJSON('message', $response);
+            exit;
+        } else {
+            $response->display();
+        }
+    }
+} // end PMA_RTE_handleExport()
+
+/**
+ * If necessary, prepares event information and passes
+ * it to PMA_RTE_handleExport() for the actual export.
+ *
+ * @return void
+ */
+function PMA_EVN_handleExport()
+{
+    global $_GET, $db;
+
+    if (! empty($_GET['export_item']) && ! empty($_GET['item_name'])) {
+        $item_name = $_GET['item_name'];
+        $export_data = PMA_DBI_get_definition($db, 'EVENT', $item_name);
+        PMA_RTE_handleExport($item_name, $export_data);
+    }
+} // end PMA_EVN_handleExport()
+
+/**
+ * If necessary, prepares routine information and passes
+ * it to PMA_RTE_handleExport() for the actual export.
+ *
+ * @return void
+ */
+function PMA_RTN_handleExport()
+{
+    global $_GET, $db;
+
+    if (   ! empty($_GET['export_item'])
+        && ! empty($_GET['item_name'])
+        && ! empty($_GET['item_type'])
+    ) {
+        if ($_GET['item_type'] == 'FUNCTION' || $_GET['item_type'] == 'PROCEDURE') {
+            $export_data = PMA_DBI_get_definition(
+                $db,
+                $_GET['item_type'],
+                $_GET['item_name']
+            );
+            PMA_RTE_handleExport($_GET['item_name'], $export_data);
+        }
+    }
+} // end PMA_RTN_handleExport()
+
+/**
+ * If necessary, prepares trigger information and passes
+ * it to PMA_RTE_handleExport() for the actual export.
+ *
+ * @return void
+ */
+function PMA_TRI_handleExport()
+{
+    global $_GET, $db, $table;
+
+    if (! empty($_GET['export_item']) && ! empty($_GET['item_name'])) {
+        $item_name = $_GET['item_name'];
+        $triggers = PMA_DBI_get_triggers($db, $table, '');
+        $export_data = false;
+        foreach ($triggers as $trigger) {
+            if ($trigger['name'] === $item_name) {
+                $export_data = $trigger['create'];
+                break;
+            }
+        }
+        PMA_RTE_handleExport($item_name, $export_data);
+    }
+} // end PMA_TRI_handleExport()
+?>
diff --git a/phpmyadmin/libraries/rte/rte_footer.lib.php b/phpmyadmin/libraries/rte/rte_footer.lib.php
new file mode 100644
index 0000000..88d31d3
--- /dev/null
+++ b/phpmyadmin/libraries/rte/rte_footer.lib.php
@@ -0,0 +1,127 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * Common functions for generating the footer for Routines, Triggers and Events.
+ *
+ * @package PhpMyAdmin
+ */
+if (! defined('PHPMYADMIN')) {
+    exit;
+}
+
+/**
+ * Creates a fieldset for adding a new item, if the user has the privileges.
+ *
+ * @param string $docu String used to create a link to the MySQL docs
+ * @param string $priv Privilege to check for adding a new item
+ * @param string $name MySQL name of the item
+ *
+ * @return string An HTML snippet with the link to add a new item
+ */
+function PMA_RTE_getFooterLinks($docu, $priv, $name)
+{
+    global $db, $url_query, $ajax_class;
+
+    $icon = 'b_' . strtolower($name) . '_add.png';
+    $retval  = "";
+    $retval .= "<!-- ADD " . $name . " FORM START -->\n";
+    $retval .= "<fieldset class='left'>\n";
+    $retval .= "    <legend>" . _pgettext('Create new procedure', 'New') . "</legend>\n";
+    $retval .= "        <div class='wrap'>\n";
+    if (PMA_Util::currentUserHasPrivilege($priv, $db)) {
+        $retval .= "            <a {$ajax_class['add']} ";
+        $retval .= "href='db_" . strtolower($name) . "s.php";
+        $retval .= "?$url_query&add_item=1'>";
+        $retval .= PMA_Util::getIcon($icon);
+        $retval .= PMA_RTE_getWord('add') . "</a>\n";
+    } else {
+        $retval .= "            " . PMA_Util::getIcon($icon);
+        $retval .= PMA_RTE_getWord('no_create') . "\n";
+    }
+    $retval .= "            " . PMA_Util::showMySQLDocu('SQL-Syntax', $docu) . "\n";
+    $retval .= "        </div>\n";
+    $retval .= "</fieldset>\n";
+    $retval .= "<!-- ADD " . $name . " FORM END -->\n\n";
+
+    return $retval;
+} // end PMA_RTE_getFooterLinks()
+
+/**
+ * Creates a fieldset for adding a new routine, if the user has the privileges.
+ *
+ * @return string    HTML code with containing the fotter fieldset
+ */
+function PMA_RTN_getFooterLinks()
+{
+    return PMA_RTE_getFooterLinks('CREATE_PROCEDURE', 'CREATE ROUTINE', 'ROUTINE');
+}// end PMA_RTN_getFooterLinks()
+
+/**
+ * Creates a fieldset for adding a new trigger, if the user has the privileges.
+ *
+ * @return string    HTML code with containing the fotter fieldset
+ */
+function PMA_TRI_getFooterLinks()
+{
+    return PMA_RTE_getFooterLinks('CREATE_TRIGGER', 'TRIGGER', 'TRIGGER');
+} // end PMA_TRI_getFooterLinks()
+
+/**
+ * Creates a fieldset for adding a new event, if the user has the privileges.
+ *
+ * @return string    HTML code with containing the fotter fieldset
+ */
+function PMA_EVN_getFooterLinks()
+{
+    global $db, $url_query;
+
+    /**
+     * For events, we show the usual 'Add event' form and also
+     * a form for toggling the state of the event scheduler
+     */
+    // Init options for the event scheduler toggle functionality
+    $es_state = PMA_DBI_fetch_value(
+        "SHOW GLOBAL VARIABLES LIKE 'event_scheduler'",
+        0,
+        1
+    );
+    $es_state = strtolower($es_state);
+    $options = array(
+                    0 => array(
+                        'label' => __('OFF'),
+                        'value' => "SET GLOBAL event_scheduler=\"OFF\"",
+                        'selected' => ($es_state != 'on')
+                    ),
+                    1 => array(
+                        'label' => __('ON'),
+                        'value' => "SET GLOBAL event_scheduler=\"ON\"",
+                        'selected' => ($es_state == 'on')
+                    )
+               );
+    // Generate output
+    $retval  = "<!-- FOOTER LINKS START -->\n";
+    $retval .= "<div class='doubleFieldset'>\n";
+    // show the usual footer
+    $retval .= PMA_RTE_getFooterLinks('CREATE_EVENT', 'EVENT', 'EVENT');
+    $retval .= "    <fieldset class='right'>\n";
+    $retval .= "        <legend>\n";
+    $retval .= "            " . __('Event scheduler status') . "\n";
+    $retval .= "        </legend>\n";
+    $retval .= "        <div class='wrap'>\n";
+    // show the toggle button
+    $retval .= PMA_Util::toggleButton(
+        "sql.php?$url_query&goto=db_events.php" . urlencode("?db=$db"),
+        'sql_query',
+        $options,
+        'PMA_slidingMessage(data.sql_query);'
+    );
+    $retval .= "        </div>\n";
+    $retval .= "    </fieldset>\n";
+    $retval .= "    <div style='clear: both;'></div>\n";
+    $retval .= "</div>";
+    $retval .= "<!-- FOOTER LINKS END -->\n";
+
+    return $retval;
+} // end PMA_EVN_getFooterLinks()
+
+?>
diff --git a/phpmyadmin/libraries/rte/rte_list.lib.php b/phpmyadmin/libraries/rte/rte_list.lib.php
new file mode 100644
index 0000000..d531cd8
--- /dev/null
+++ b/phpmyadmin/libraries/rte/rte_list.lib.php
@@ -0,0 +1,366 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * Common functions for generating lists of Routines, Triggers and Events.
+ *
+ * @package PhpMyAdmin
+ */
+if (! defined('PHPMYADMIN')) {
+    exit;
+}
+
+/**
+ * Creates a list of items containing the relevant
+ * information and some action links.
+ *
+ * @param string $type  One of ['routine'|'trigger'|'event']
+ * @param array  $items An array of items
+ *
+ * @return string HTML code of the list of items
+ */
+function PMA_RTE_getList($type, $items)
+{
+    global $table;
+
+    /**
+     * Conditional classes switch the list on or off
+     */
+    $class1 = 'hide';
+    $class2 = '';
+    if (! $items) {
+        $class1 = '';
+        $class2 = ' hide';
+    }
+    /**
+     * Generate output
+     */
+    $retval  = "<!-- LIST OF " . PMA_RTE_getWord('docu') . " START -->\n";
+    $retval .= "<fieldset>\n";
+    $retval .= "    <legend>\n";
+    $retval .= "        " . PMA_RTE_getWord('title') . "\n";
+    $retval .= "        " . PMA_Util::showMySQLDocu('SQL-Syntax', PMA_RTE_getWord('docu')) . "\n";
+    $retval .= "    </legend>\n";
+    $retval .= "    <div class='$class1' id='nothing2display'>\n";
+    $retval .= "      " . PMA_RTE_getWord('nothing') . "\n";
+    $retval .= "    </div>\n";
+    $retval .= "    <table class='data$class2'>\n";
+    $retval .= "        <!-- TABLE HEADERS -->\n";
+    $retval .= "        <tr>\n";
+    // th cells with a colspan need corresponding td cells, according to W3C
+    switch ($type) {
+    case 'routine':
+        $retval .= "            <th>" . __('Name') . "</th>\n";
+        $retval .= "            <th colspan='4'>" . __('Action') . "</th>\n";
+        $retval .= "            <th>" . __('Type') . "</th>\n";
+        $retval .= "            <th>" . __('Returns') . "</th>\n";
+        $retval .= "        </tr>\n";
+        $retval .= "        <tr style='display: none'>\n"; // see comment above
+        for ($i = 0; $i < 7; $i++) {
+            $retval .= "            <td></td>\n";
+        }
+        break;
+    case 'trigger':
+        $retval .= "            <th>" . __('Name') . "</th>\n";
+        if (empty($table)) {
+            $retval .= "            <th>" . __('Table') . "</th>\n";
+        }
+        $retval .= "            <th colspan='3'>" . __('Action') . "</th>\n";
+        $retval .= "            <th>" . __('Time') . "</th>\n";
+        $retval .= "            <th>" . __('Event') . "</th>\n";
+        $retval .= "        </tr>\n";
+        $retval .= "        <tr style='display: none'>\n"; // see comment above
+        for ($i = 0; $i < (empty($table) ? 7 : 6); $i++) {
+            $retval .= "            <td></td>\n";
+        }
+        break;
+    case 'event':
+        $retval .= "            <th>" . __('Name') . "</th>\n";
+        $retval .= "            <th>" . __('Status') . "</th>\n";
+        $retval .= "            <th colspan='3'>" . __('Action') . "</th>\n";
+        $retval .= "            <th>" . __('Type') . "</th>\n";
+        $retval .= "        </tr>\n";
+        $retval .= "        <tr style='display: none'>\n"; // see comment above
+        for ($i = 0; $i < 6; $i++) {
+            $retval .= "            <td></td>\n";
+        }
+        break;
+    default:
+        break;
+    }
+    $retval .= "        </tr>\n";
+    $retval .= "        <!-- TABLE DATA -->\n";
+    $ct = 0;
+    foreach ($items as $item) {
+        $rowclass = ($ct % 2 == 0) ? 'odd' : 'even';
+        if ($GLOBALS['is_ajax_request'] && empty($_REQUEST['ajax_page_request'])) {
+            $rowclass .= ' ajaxInsert hide';
+        }
+        // Get each row from the correct function
+        switch ($type) {
+        case 'routine':
+            $retval .= PMA_RTN_getRowForList($item, $rowclass);
+            break;
+        case 'trigger':
+            $retval .= PMA_TRI_getRowForList($item, $rowclass);
+            break;
+        case 'event':
+            $retval .= PMA_EVN_getRowForList($item, $rowclass);
+            break;
+        default:
+            break;
+        }
+        $ct++;
+    }
+    $retval .= "    </table>\n";
+    $retval .= "</fieldset>\n";
+    $retval .= "<!-- LIST OF " . PMA_RTE_getWord('docu') . " END -->\n";
+
+    return $retval;
+} // end PMA_RTE_getList()
+
+/**
+ * Creates the contents for a row in the list of routines
+ *
+ * @param array  $routine  An array of routine data
+ * @param string $rowclass Empty or one of ['even'|'odd']
+ *
+ * @return string HTML code of a row for the list of routines
+ */
+function PMA_RTN_getRowForList($routine, $rowclass = '')
+{
+    global $ajax_class, $url_query, $db, $titles;
+
+    $sql_drop = sprintf(
+        'DROP %s IF EXISTS %s',
+        $routine['ROUTINE_TYPE'],
+        PMA_Util::backquote($routine['SPECIFIC_NAME'])
+    );
+    $type_link = "item_type={$routine['ROUTINE_TYPE']}";
+
+    $retval  = "        <tr class='noclick $rowclass'>\n";
+    $retval .= "            <td>\n";
+    $retval .= "                <span class='drop_sql hide'>" . htmlspecialchars($sql_drop) . "</span>\n";
+    $retval .= "                <strong>\n";
+    $retval .= "                    " . htmlspecialchars($routine['SPECIFIC_NAME']) . "\n";
+    $retval .= "                </strong>\n";
+    $retval .= "            </td>\n";
+    $retval .= "            <td>\n";
+    if ($routine['ROUTINE_DEFINITION'] !== null
+        && PMA_Util::currentUserHasPrivilege('ALTER ROUTINE', $db)
+        && PMA_Util::currentUserHasPrivilege('CREATE ROUTINE', $db)
+    ) {
+        $retval .= '                <a ' . $ajax_class['edit']
+                                         . ' href="db_routines.php?'
+                                         . $url_query
+                                         . '&edit_item=1'
+                                         . '&item_name=' . urlencode($routine['SPECIFIC_NAME'])
+                                         . '&' . $type_link
+                                         . '">' . $titles['Edit'] . "</a>\n";
+    } else {
+        $retval .= "                {$titles['NoEdit']}\n";
+    }
+    $retval .= "            </td>\n";
+    $retval .= "            <td>\n";
+    if ($routine['ROUTINE_DEFINITION'] !== null
+        && PMA_Util::currentUserHasPrivilege('EXECUTE', $db)
+    ) {
+        // Check if he routine has any input parameters. If it does,
+        // we will show a dialog to get values for these parameters,
+        // otherwise we can execute it directly.
+        $routine_details = PMA_RTN_getDataFromName(
+            $routine['SPECIFIC_NAME'],
+            $routine['ROUTINE_TYPE'],
+            false
+        );
+        if ($routine !== false) {
+            $execute_action = 'execute_routine';
+            for ($i=0; $i<$routine_details['item_num_params']; $i++) {
+                if ($routine_details['item_type'] == 'PROCEDURE'
+                    && $routine_details['item_param_dir'][$i] == 'OUT'
+                ) {
+                    continue;
+                }
+                $execute_action = 'execute_dialog';
+                break;
+            }
+            $retval .= '                <a ' . $ajax_class['exec']
+                                             . ' href="db_routines.php?'
+                                             . $url_query
+                                             . '&' . $execute_action . '=1'
+                                             . '&item_name=' . urlencode($routine['SPECIFIC_NAME'])
+                                             . '&' . $type_link
+                                             . '">' . $titles['Execute'] . "</a>\n";
+        }
+    } else {
+        $retval .= "                {$titles['NoExecute']}\n";
+    }
+    $retval .= "            </td>\n";
+    $retval .= "            <td>\n";
+    $retval .= '                <a ' . $ajax_class['export']
+                                     . ' href="db_routines.php?'
+                                     . $url_query
+                                     . '&export_item=1'
+                                     . '&item_name=' . urlencode($routine['SPECIFIC_NAME'])
+                                     . '&' . $type_link
+                                     . '">' . $titles['Export'] . "</a>\n";
+    $retval .= "            </td>\n";
+    $retval .= "            <td>\n";
+    if (PMA_Util::currentUserHasPrivilege('ALTER ROUTINE', $db)) {
+        $retval .= '                <a ' . $ajax_class['drop']
+                                         . ' href="sql.php?'
+                                         . $url_query
+                                         . '&sql_query=' . urlencode($sql_drop)
+                                         . '&goto=db_routines.php' . urlencode("?db={$db}")
+                                         . '" >' . $titles['Drop'] . "</a>\n";
+    } else {
+        $retval .= "                {$titles['NoDrop']}\n";
+    }
+    $retval .= "            </td>\n";
+    $retval .= "            <td>\n";
+    $retval .= "                 {$routine['ROUTINE_TYPE']}\n";
+    $retval .= "            </td>\n";
+    $retval .= "            <td>\n";
+    $retval .= "                " . htmlspecialchars($routine['DTD_IDENTIFIER']) . "\n";
+    $retval .= "            </td>\n";
+    $retval .= "        </tr>\n";
+
+    return $retval;
+} // end PMA_RTN_getRowForList()
+
+/**
+ * Creates the contents for a row in the list of triggers
+ *
+ * @param array  $trigger  An array of routine data
+ * @param string $rowclass Empty or one of ['even'|'odd']
+ *
+ * @return string HTML code of a cell for the list of triggers
+ */
+function PMA_TRI_getRowForList($trigger, $rowclass = '')
+{
+    global $ajax_class, $url_query, $db, $table, $titles;
+
+    $retval  = "        <tr class='noclick $rowclass'>\n";
+    $retval .= "            <td>\n";
+    $retval .= "                <span class='drop_sql hide'>" . htmlspecialchars($trigger['drop']) . "</span>\n";
+    $retval .= "                <strong>\n";
+    $retval .= "                    " . htmlspecialchars($trigger['name']) . "\n";
+    $retval .= "                </strong>\n";
+    $retval .= "            </td>\n";
+    if (empty($table)) {
+        $retval .= "            <td>\n";
+        $retval .= "                <a href='db_triggers.php?{$url_query}"
+                                     . "&table={$trigger['table']}'>"
+                                     . $trigger['table'] . "</a>\n";
+        $retval .= "            </td>\n";
+    }
+    $retval .= "            <td>\n";
+    if (PMA_Util::currentUserHasPrivilege('TRIGGER', $db, $table)) {
+        $retval .= '                <a ' . $ajax_class['edit']
+                                         . ' href="db_triggers.php?'
+                                         . $url_query
+                                         . '&edit_item=1'
+                                         . '&item_name=' . urlencode($trigger['name'])
+                                         . '">' . $titles['Edit'] . "</a>\n";
+    } else {
+        $retval .= "                {$titles['NoEdit']}\n";
+    }
+    $retval .= "            </td>\n";
+    $retval .= "            <td>\n";
+    $retval .= '                    <a ' . $ajax_class['export']
+                                         . ' href="db_triggers.php?'
+                                         . $url_query
+                                         . '&export_item=1'
+                                         . '&item_name=' . urlencode($trigger['name'])
+                                         . '">' . $titles['Export'] . "</a>\n";
+    $retval .= "            </td>\n";
+    $retval .= "            <td>\n";
+    if (PMA_Util::currentUserHasPrivilege('TRIGGER', $db)) {
+        $retval .= '                <a ' . $ajax_class['drop']
+                                         . ' href="sql.php?'
+                                         . $url_query
+                                         . '&sql_query=' . urlencode($trigger['drop'])
+                                         . '&goto=db_triggers.php' . urlencode("?db={$db}")
+                                         . '" >' . $titles['Drop'] . "</a>\n";
+    } else {
+        $retval .= "                {$titles['NoDrop']}\n";
+    }
+    $retval .= "            </td>\n";
+    $retval .= "            <td>\n";
+    $retval .= "                 {$trigger['action_timing']}\n";
+    $retval .= "            </td>\n";
+    $retval .= "            <td>\n";
+    $retval .= "                 {$trigger['event_manipulation']}\n";
+    $retval .= "            </td>\n";
+    $retval .= "        </tr>\n";
+
+    return $retval;
+} // end PMA_TRI_getRowForList()
+
+/**
+ * Creates the contents for a row in the list of events
+ *
+ * @param array  $event    An array of routine data
+ * @param string $rowclass Empty or one of ['even'|'odd']
+ *
+ * @return string HTML code of a cell for the list of events
+ */
+function PMA_EVN_getRowForList($event, $rowclass = '')
+{
+    global $ajax_class, $url_query, $db, $titles;
+
+    $sql_drop = sprintf(
+        'DROP EVENT IF EXISTS %s',
+        PMA_Util::backquote($event['EVENT_NAME'])
+    );
+
+    $retval  = "        <tr class='noclick $rowclass'>\n";
+    $retval .= "            <td>\n";
+    $retval .= "                <span class='drop_sql hide'>" . htmlspecialchars($sql_drop) . "</span>\n";
+    $retval .= "                <strong>\n";
+    $retval .= "                    " . htmlspecialchars($event['EVENT_NAME']) . "\n";
+    $retval .= "                </strong>\n";
+    $retval .= "            </td>\n";
+    $retval .= "            <td>\n";
+    $retval .= "                 {$event['STATUS']}\n";
+    $retval .= "            </td>\n";
+    $retval .= "            <td>\n";
+    if (PMA_Util::currentUserHasPrivilege('EVENT', $db)) {
+        $retval .= '                <a ' . $ajax_class['edit']
+                                         . ' href="db_events.php?'
+                                         . $url_query
+                                         . '&edit_item=1'
+                                         . '&item_name=' . urlencode($event['EVENT_NAME'])
+                                         . '">' . $titles['Edit'] . "</a>\n";
+    } else {
+        $retval .= "                {$titles['NoEdit']}\n";
+    }
+    $retval .= "            </td>\n";
+    $retval .= "            <td>\n";
+    $retval .= '                <a ' . $ajax_class['export']
+                                     . ' href="db_events.php?'
+                                     . $url_query
+                                     . '&export_item=1'
+                                     . '&item_name=' . urlencode($event['EVENT_NAME'])
+                                     . '">' . $titles['Export'] . "</a>\n";
+    $retval .= "            </td>\n";
+    $retval .= "            <td>\n";
+    if (PMA_Util::currentUserHasPrivilege('EVENT', $db)) {
+        $retval .= '                <a ' . $ajax_class['drop']
+                                         . ' href="sql.php?'
+                                         . $url_query
+                                         . '&sql_query=' . urlencode($sql_drop)
+                                         . '&goto=db_events.php' . urlencode("?db={$db}")
+                                         . '" >' . $titles['Drop'] . "</a>\n";
+    } else {
+        $retval .= "                {$titles['NoDrop']}\n";
+    }
+    $retval .= "            </td>\n";
+    $retval .= "            <td>\n";
+    $retval .= "                 {$event['EVENT_TYPE']}\n";
+    $retval .= "            </td>\n";
+    $retval .= "        </tr>\n";
+
+    return $retval;
+} // end PMA_EVN_getRowForList()
+
+?>
diff --git a/phpmyadmin/libraries/rte/rte_main.inc.php b/phpmyadmin/libraries/rte/rte_main.inc.php
new file mode 100644
index 0000000..355240f
--- /dev/null
+++ b/phpmyadmin/libraries/rte/rte_main.inc.php
@@ -0,0 +1,92 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * Common code for Routines, Triggers and Events.
+ *
+ * @package PhpMyAdmin
+ */
+if (! defined('PHPMYADMIN')) {
+    exit;
+}
+
+/**
+ * Include all other files that are common
+ * to routines, triggers and events.
+ */
+require_once './libraries/rte/rte_words.lib.php';
+require_once './libraries/rte/rte_export.lib.php';
+require_once './libraries/rte/rte_list.lib.php';
+require_once './libraries/rte/rte_footer.lib.php';
+
+if ($GLOBALS['is_ajax_request'] != true) {
+    /**
+     * Displays the header and tabs
+     */
+    if (! empty($table) && in_array($table, PMA_DBI_get_tables($db))) {
+        include_once './libraries/tbl_common.inc.php';
+    } else {
+        $table = '';
+        include_once './libraries/db_common.inc.php';
+        include_once './libraries/db_info.inc.php';
+    }
+} else {
+    /**
+     * Since we did not include some libraries, we need
+     * to manually select the required database and
+     * create the missing $url_query variable
+     */
+    if (strlen($db)) {
+        PMA_DBI_select_db($db);
+        if (! isset($url_query)) {
+            $url_query = PMA_generate_common_url($db, $table);
+        }
+    }
+}
+
+/**
+ * Generate the conditional classes that will
+ * be used to attach jQuery events to links
+ */
+$ajax_class = array(
+    'add'    => '',
+    'edit'   => '',
+    'exec'   => '',
+    'drop'   => '',
+    'export' => ''
+);
+$ajax_class = array(
+    'add'    => 'class="ajax add_anchor"',
+    'edit'   => 'class="ajax edit_anchor"',
+    'exec'   => 'class="ajax exec_anchor"',
+    'drop'   => 'class="ajax drop_anchor"',
+    'export' => 'class="ajax export_anchor"'
+);
+
+/**
+ * Create labels for the list
+ */
+$titles = PMA_Util::buildActionTitles();
+
+/**
+ * Keep a list of errors that occured while
+ * processing an 'Add' or 'Edit' operation.
+ */
+$errors = array();
+
+
+/**
+ * Call the appropriate main function
+ */
+switch ($_PMA_RTE) {
+case 'RTN':
+    PMA_RTN_main();
+    break;
+case 'TRI':
+    PMA_TRI_main();
+    break;
+case 'EVN':
+    PMA_EVN_main();
+    break;
+}
+
+?>
diff --git a/phpmyadmin/libraries/rte/rte_routines.lib.php b/phpmyadmin/libraries/rte/rte_routines.lib.php
new file mode 100644
index 0000000..b69c4bb
--- /dev/null
+++ b/phpmyadmin/libraries/rte/rte_routines.lib.php
@@ -0,0 +1,1676 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * Functions for routine management.
+ *
+ * @package PhpMyAdmin
+ */
+if (! defined('PHPMYADMIN')) {
+    exit;
+}
+
+/**
+ * Sets required globals
+ *
+ * @return nothing
+ */
+function PMA_RTN_setGlobals()
+{
+    global $param_directions, $param_opts_num, $param_sqldataaccess;
+
+    $param_directions    = array('IN',
+                                 'OUT',
+                                 'INOUT');
+    $param_opts_num      = array('UNSIGNED',
+                                 'ZEROFILL',
+                                 'UNSIGNED ZEROFILL');
+    $param_sqldataaccess = array('NO SQL',
+                                 'CONTAINS SQL',
+                                 'READS SQL DATA',
+                                 'MODIFIES SQL DATA');
+}
+
+/**
+ * Main function for the routines functionality
+ *
+ * @return nothing
+ */
+function PMA_RTN_main()
+{
+    global $db;
+
+    PMA_RTN_setGlobals();
+    /**
+     * Process all requests
+     */
+    PMA_RTN_handleEditor();
+    PMA_RTN_handleExecute();
+    PMA_RTN_handleExport();
+    /**
+     * Display a list of available routines
+     */
+    $columns  = "`SPECIFIC_NAME`, `ROUTINE_NAME`, `ROUTINE_TYPE`, ";
+    $columns .= "`DTD_IDENTIFIER`, `ROUTINE_DEFINITION`";
+    $where    = "ROUTINE_SCHEMA='" . PMA_Util::sqlAddSlashes($db) . "'";
+    $items    = PMA_DBI_fetch_result(
+        "SELECT $columns FROM `INFORMATION_SCHEMA`.`ROUTINES` WHERE $where;"
+    );
+    echo PMA_RTE_getList('routine', $items);
+    /**
+     * Display the form for adding a new routine, if the user has the privileges.
+     */
+    echo PMA_RTN_getFooterLinks();
+    /**
+     * Display a warning for users with PHP's old "mysql" extension.
+     */
+    if ($GLOBALS['cfg']['Server']['extension'] === 'mysql') {
+        trigger_error(
+            __(
+                'You are using PHP\'s deprecated \'mysql\' extension, '
+                . 'which is not capable of handling multi queries. '
+                . '[strong]The execution of some stored routines may fail![/strong] '
+                . 'Please use the improved \'mysqli\' extension to '
+                . 'avoid any problems.'
+            ),
+            E_USER_WARNING
+        );
+    }
+} // end PMA_RTN_main()
+
+/**
+ * This function parses a string containing one parameter of a routine,
+ * as returned by PMA_RTN_parseAllParameters() and returns an array containing
+ * the information about this parameter.
+ *
+ * @param string $value A string containing one parameter of a routine
+ *
+ * @return array             Parsed information about the input parameter
+ */
+function PMA_RTN_parseOneParameter($value)
+{
+    global $param_directions;
+
+    $retval = array(0 => '',
+                    1 => '',
+                    2 => '',
+                    3 => '',
+                    4 => '');
+    $parsed_param = PMA_SQP_parse($value);
+    $pos = 0;
+    if (in_array(strtoupper($parsed_param[$pos]['data']), $param_directions)) {
+        $retval[0] = strtoupper($parsed_param[0]['data']);
+        $pos++;
+    }
+    if ($parsed_param[$pos]['type'] == 'alpha_identifier'
+        || $parsed_param[$pos]['type'] == 'quote_backtick'
+    ) {
+        $retval[1] = PMA_Util::unQuote(
+            $parsed_param[$pos]['data']
+        );
+        $pos++;
+    }
+    $depth = 0;
+    $param_length = '';
+    $param_opts = array();
+    for ($i=$pos; $i<$parsed_param['len']; $i++) {
+        if (($parsed_param[$i]['type'] == 'alpha_columnType'
+            || $parsed_param[$i]['type'] == 'alpha_functionName') && $depth == 0
+        ) {
+            $retval[2] = strtoupper($parsed_param[$i]['data']);
+        } else if ($parsed_param[$i]['type'] == 'punct_bracket_open_round'
+            && $depth == 0
+        ) {
+            $depth = 1;
+        } else if ($parsed_param[$i]['type'] == 'punct_bracket_close_round'
+            && $depth == 1
+        ) {
+            $depth = 0;
+        } else if ($depth == 1) {
+            $param_length .= $parsed_param[$i]['data'];
+        } else if ($parsed_param[$i]['type'] == 'alpha_reservedWord'
+            && strtoupper($parsed_param[$i]['data']) == 'CHARSET' && $depth == 0
+        ) {
+            if ($parsed_param[$i+1]['type'] == 'alpha_charset'
+                || $parsed_param[$i+1]['type'] == 'alpha_identifier'
+            ) {
+                $param_opts[] = strtolower($parsed_param[$i+1]['data']);
+            }
+        } else if ($parsed_param[$i]['type'] == 'alpha_columnAttrib'
+            && $depth == 0
+        ) {
+            $param_opts[] = strtoupper($parsed_param[$i]['data']);
+        }
+    }
+    $retval[3] = $param_length;
+    sort($param_opts);
+    $retval[4] = implode(' ', $param_opts);
+
+    return $retval;
+} // end PMA_RTN_parseOneParameter()
+
+/**
+ * This function looks through the contents of a parsed
+ * SHOW CREATE [PROCEDURE | FUNCTION] query and extracts
+ * information about the routine's parameters.
+ *
+ * @param array  $parsed_query Parsed query, returned by by PMA_SQP_parse()
+ * @param string $routine_type Routine type: 'PROCEDURE' or 'FUNCTION'
+ *
+ * @return array   Information about the parameteres of a routine.
+ */
+function PMA_RTN_parseAllParameters($parsed_query, $routine_type)
+{
+    $retval = array();
+    $retval['num'] = 0;
+
+    // First get the list of parameters from the query
+    $buffer = '';
+    $params = array();
+    $fetching = false;
+    $depth = 0;
+    for ($i=0; $i<$parsed_query['len']; $i++) {
+        if ($parsed_query[$i]['type'] == 'alpha_reservedWord'
+            && $parsed_query[$i]['data'] == $routine_type
+        ) {
+            $fetching = true;
+        } else if ($fetching == true
+            && $parsed_query[$i]['type'] == 'punct_bracket_open_round'
+        ) {
+            $depth++;
+            if ($depth > 1) {
+                $buffer .= $parsed_query[$i]['data'] . ' ';
+            }
+        } else if ($fetching == true
+            && $parsed_query[$i]['type'] == 'punct_bracket_close_round'
+        ) {
+            $depth--;
+            if ($depth > 0) {
+                $buffer .= $parsed_query[$i]['data'] . ' ';
+            } else {
+                break;
+            }
+        } else if ($parsed_query[$i]['type'] == 'punct_listsep' && $depth == 1) {
+            $params[] = $buffer;
+            $retval['num']++;
+            $buffer = '';
+        } else if ($fetching == true && $depth > 0) {
+            $buffer .= $parsed_query[$i]['data'] . ' ';
+        }
+    }
+    if (! empty($buffer)) {
+        $params[] = $buffer;
+        $retval['num']++;
+    }
+    // Now parse each parameter individually
+    foreach ($params as $key => $value) {
+        list($retval['dir'][],
+             $retval['name'][],
+             $retval['type'][],
+             $retval['length'][],
+             $retval['opts'][]) = PMA_RTN_parseOneParameter($value);
+    }
+    // Since some indices of $retval may be still undefined, we fill
+    // them each with an empty array to avoid E_ALL errors in PHP.
+    foreach (array('dir', 'name', 'type', 'length', 'opts') as $key => $index) {
+        if (! isset($retval[$index])) {
+            $retval[$index] = array();
+        }
+    }
+
+    return $retval;
+} // end PMA_RTN_parseAllParameters()
+
+/**
+ * This function looks through the contents of a parsed
+ * SHOW CREATE [PROCEDURE | FUNCTION] query and extracts
+ * information about the routine's definer.
+ *
+ * @param array $parsed_query Parsed query, returned by PMA_SQP_parse()
+ *
+ * @return string  The definer of a routine.
+ */
+function PMA_RTN_parseRoutineDefiner($parsed_query)
+{
+    $retval = '';
+    $fetching = false;
+    for ($i=0; $i<$parsed_query['len']; $i++) {
+        if ($parsed_query[$i]['type'] == 'alpha_reservedWord'
+            && $parsed_query[$i]['data'] == 'DEFINER'
+        ) {
+            $fetching = true;
+        } else if ($fetching == true
+            && $parsed_query[$i]['type'] != 'quote_backtick'
+            && substr($parsed_query[$i]['type'], 0, 5) != 'punct'
+        ) {
+            break;
+        } else if ($fetching == true
+            && $parsed_query[$i]['type'] == 'quote_backtick'
+        ) {
+            $retval .= PMA_Util::unQuote(
+                $parsed_query[$i]['data']
+            );
+        } else if ($fetching == true && $parsed_query[$i]['type'] == 'punct_user') {
+            $retval .= $parsed_query[$i]['data'];
+        }
+    }
+    return $retval;
+} // end PMA_RTN_parseRoutineDefiner()
+
+/**
+ * Handles editor requests for adding or editing an item
+ *
+ * @return Does not return
+ */
+function PMA_RTN_handleEditor()
+{
+    global $_GET, $_POST, $_REQUEST, $GLOBALS, $db, $errors;
+
+    if (! empty($_REQUEST['editor_process_add'])
+        || ! empty($_REQUEST['editor_process_edit'])
+    ) {
+        /**
+         * Handle a request to create/edit a routine
+         */
+        $sql_query = '';
+        $routine_query = PMA_RTN_getQueryFromRequest();
+        if (! count($errors)) { // set by PMA_RTN_getQueryFromRequest()
+            // Execute the created query
+            if (! empty($_REQUEST['editor_process_edit'])) {
+                if (! in_array($_REQUEST['item_original_type'], array('PROCEDURE', 'FUNCTION'))) {
+                    $errors[] = sprintf(
+                        __('Invalid routine type: "%s"'),
+                        htmlspecialchars($_REQUEST['item_original_type'])
+                    );
+                } else {
+                    // Backup the old routine, in case something goes wrong
+                    $create_routine = PMA_DBI_get_definition(
+                        $db, $_REQUEST['item_original_type'],
+                        $_REQUEST['item_original_name']
+                    );
+                    $drop_routine = "DROP {$_REQUEST['item_original_type']} "
+                        . PMA_Util::backquote($_REQUEST['item_original_name'])
+                        . ";\n";
+                    $result = PMA_DBI_try_query($drop_routine);
+                    if (! $result) {
+                        $errors[] = sprintf(
+                            __('The following query has failed: "%s"'),
+                            htmlspecialchars($drop_routine)
+                        )
+                        . '<br />'
+                        . __('MySQL said: ') . PMA_DBI_getError(null);
+                    } else {
+                        $result = PMA_DBI_try_query($routine_query);
+                        if (! $result) {
+                            $errors[] = sprintf(
+                                __('The following query has failed: "%s"'),
+                                htmlspecialchars($routine_query)
+                            )
+                            . '<br />'
+                            . __('MySQL said: ') . PMA_DBI_getError(null);
+                            // We dropped the old routine,
+                            // but were unable to create the new one
+                            // Try to restore the backup query
+                            $result = PMA_DBI_try_query($create_routine);
+                            if (! $result) {
+                                // OMG, this is really bad! We dropped the query,
+                                // failed to create a new one
+                                // and now even the backup query does not execute!
+                                // This should not happen, but we better handle
+                                // this just in case.
+                                $errors[] = __(
+                                    'Sorry, we failed to restore'
+                                    . ' the dropped routine.'
+                                )
+                                . '<br />'
+                                . __('The backed up query was:')
+                                . "\"" . htmlspecialchars($create_routine) . "\""
+                                . '<br />'
+                                . __('MySQL said: ') . PMA_DBI_getError(null);
+                            }
+                        } else {
+                            $message = PMA_Message::success(
+                                __('Routine %1$s has been modified.')
+                            );
+                            $message->addParam(
+                                PMA_Util::backquote($_REQUEST['item_name'])
+                            );
+                            $sql_query = $drop_routine . $routine_query;
+                        }
+                    }
+                }
+            } else {
+                // 'Add a new routine' mode
+                $result = PMA_DBI_try_query($routine_query);
+                if (! $result) {
+                    $errors[] = sprintf(
+                        __('The following query has failed: "%s"'),
+                        htmlspecialchars($routine_query)
+                    )
+                    . '<br /><br />'
+                    . __('MySQL said: ') . PMA_DBI_getError(null);
+                } else {
+                    $message = PMA_Message::success(
+                        __('Routine %1$s has been created.')
+                    );
+                    $message->addParam(
+                        PMA_Util::backquote($_REQUEST['item_name'])
+                    );
+                    $sql_query = $routine_query;
+                }
+            }
+        }
+
+        if (count($errors)) {
+            $message = PMA_Message::error(
+                __(
+                    '<b>One or more errors have occured while'
+                    . ' processing your request:</b>'
+                )
+            );
+            $message->addString('<ul>');
+            foreach ($errors as $string) {
+                $message->addString('<li>' . $string . '</li>');
+            }
+            $message->addString('</ul>');
+        }
+
+        $output = PMA_Util::getMessage($message, $sql_query);
+        if ($GLOBALS['is_ajax_request']) {
+            $response = PMA_Response::getInstance();
+            if ($message->isSuccess()) {
+                $columns  = "`SPECIFIC_NAME`, `ROUTINE_NAME`, `ROUTINE_TYPE`,"
+                    . " `DTD_IDENTIFIER`, `ROUTINE_DEFINITION`";
+                $where    = "ROUTINE_SCHEMA='" . PMA_Util::sqlAddSlashes($db) . "' "
+                    . "AND ROUTINE_NAME='"
+                    . PMA_Util::sqlAddSlashes($_REQUEST['item_name']) . "'"
+                    . "AND ROUTINE_TYPE='"
+                    . PMA_Util::sqlAddSlashes($_REQUEST['item_type']) . "'";
+                $routine  = PMA_DBI_fetch_single_row(
+                    "SELECT $columns FROM `INFORMATION_SCHEMA`.`ROUTINES`"
+                    . " WHERE $where;"
+                );
+                $response->addJSON(
+                    'name', htmlspecialchars(strtoupper($_REQUEST['item_name']))
+                );
+                $response->addJSON('new_row', PMA_RTN_getRowForList($routine));
+                $response->addJSON('insert', ! empty($routine));
+                $response->addJSON('message', $output);
+            } else {
+                $response->isSuccess(false);
+                $response->addJSON('message', $output);
+            }
+            exit;
+        }
+    }
+
+    /**
+     * Display a form used to add/edit a routine, if necessary
+     */
+    // FIXME: this must be simpler than that
+    if (count($errors)
+        || ( empty($_REQUEST['editor_process_add'])
+        && empty($_REQUEST['editor_process_edit'])
+        && (! empty($_REQUEST['add_item']) || ! empty($_REQUEST['edit_item'])
+        || ! empty($_REQUEST['routine_addparameter'])
+        || ! empty($_REQUEST['routine_removeparameter'])
+        || ! empty($_REQUEST['routine_changetype'])))
+    ) {
+        // Handle requests to add/remove parameters and changing routine type
+        // This is necessary when JS is disabled
+        $operation = '';
+        if (! empty($_REQUEST['routine_addparameter'])) {
+            $operation = 'add';
+        } else if (! empty($_REQUEST['routine_removeparameter'])) {
+            $operation = 'remove';
+        } else if (! empty($_REQUEST['routine_changetype'])) {
+            $operation = 'change';
+        }
+        // Get the data for the form (if any)
+        if (! empty($_REQUEST['add_item'])) {
+            $title = PMA_RTE_getWord('add');
+            $routine = PMA_RTN_getDataFromRequest();
+            $mode = 'add';
+        } else if (! empty($_REQUEST['edit_item'])) {
+            $title = __("Edit routine");
+            if (! $operation && ! empty($_REQUEST['item_name'])
+                && empty($_REQUEST['editor_process_edit'])
+            ) {
+                $routine = PMA_RTN_getDataFromName(
+                    $_REQUEST['item_name'], $_REQUEST['item_type']
+                );
+                if ($routine !== false) {
+                    $routine['item_original_name'] = $routine['item_name'];
+                    $routine['item_original_type'] = $routine['item_type'];
+                }
+            } else {
+                $routine = PMA_RTN_getDataFromRequest();
+            }
+            $mode = 'edit';
+        }
+        if ($routine !== false) {
+            // Show form
+            $editor = PMA_RTN_getEditorForm($mode, $operation, $routine);
+            if ($GLOBALS['is_ajax_request']) {
+                $response = PMA_Response::getInstance();
+                $response->addJSON('message', $editor);
+                $response->addJSON('title', $title);
+                $response->addJSON('param_template', PMA_RTN_getParameterRow());
+                $response->addJSON('type', $routine['item_type']);
+            } else {
+                echo "\n\n<h2>$title</h2>\n\n$editor";
+            }
+            exit;
+        } else {
+            $message  = __('Error in processing request') . ' : ';
+            $message .= sprintf(
+                PMA_RTE_getWord('not_found'),
+                htmlspecialchars(PMA_Util::backquote($_REQUEST['item_name'])),
+                htmlspecialchars(PMA_Util::backquote($db))
+            );
+            $message = PMA_message::error($message);
+            if ($GLOBALS['is_ajax_request']) {
+                $response->isSuccess(false);
+                $response->addJSON('message', $message);
+                exit;
+            } else {
+                $message->display();
+            }
+        }
+    }
+} // end PMA_RTN_handleEditor()
+
+/**
+ * This function will generate the values that are required to
+ * complete the editor form. It is especially necessary to handle
+ * the 'Add another parameter', 'Remove last parameter' and
+ * 'Change routine type' functionalities when JS is disabled.
+ *
+ * @return array    Data necessary to create the routine editor.
+ */
+function PMA_RTN_getDataFromRequest()
+{
+    global $_REQUEST, $param_directions, $param_sqldataaccess;
+
+    $retval = array();
+    $indices = array('item_name',
+                     'item_original_name',
+                     'item_returnlength',
+                     'item_returnopts_num',
+                     'item_returnopts_text',
+                     'item_definition',
+                     'item_comment',
+                     'item_definer');
+    foreach ($indices as $key => $index) {
+        $retval[$index] = isset($_REQUEST[$index]) ? $_REQUEST[$index] : '';
+    }
+
+    $retval['item_type']         = 'PROCEDURE';
+    $retval['item_type_toggle']  = 'FUNCTION';
+    if (isset($_REQUEST['item_type']) && $_REQUEST['item_type'] == 'FUNCTION') {
+        $retval['item_type']         = 'FUNCTION';
+        $retval['item_type_toggle']  = 'PROCEDURE';
+    }
+    $retval['item_original_type'] = 'PROCEDURE';
+    if (isset($_REQUEST['item_original_type'])
+        && $_REQUEST['item_original_type'] == 'FUNCTION'
+    ) {
+        $retval['item_original_type'] = 'FUNCTION';
+    }
+    $retval['item_num_params']      = 0;
+    $retval['item_param_dir']       = array();
+    $retval['item_param_name']      = array();
+    $retval['item_param_type']      = array();
+    $retval['item_param_length']    = array();
+    $retval['item_param_opts_num']  = array();
+    $retval['item_param_opts_text'] = array();
+    if (   isset($_REQUEST['item_param_name'])
+        && isset($_REQUEST['item_param_type'])
+        && isset($_REQUEST['item_param_length'])
+        && isset($_REQUEST['item_param_opts_num'])
+        && isset($_REQUEST['item_param_opts_text'])
+        && is_array($_REQUEST['item_param_name'])
+        && is_array($_REQUEST['item_param_type'])
+        && is_array($_REQUEST['item_param_length'])
+        && is_array($_REQUEST['item_param_opts_num'])
+        && is_array($_REQUEST['item_param_opts_text'])
+    ) {
+        if ($_REQUEST['item_type'] == 'PROCEDURE') {
+            $retval['item_param_dir'] = $_REQUEST['item_param_dir'];
+            foreach ($retval['item_param_dir'] as $key => $value) {
+                if (! in_array($value, $param_directions, true)) {
+                    $retval['item_param_dir'][$key] = '';
+                }
+            }
+        }
+        $retval['item_param_name'] = $_REQUEST['item_param_name'];
+        $retval['item_param_type'] = $_REQUEST['item_param_type'];
+        foreach ($retval['item_param_type'] as $key => $value) {
+            if (! in_array($value, PMA_Util::getSupportedDatatypes(), true)) {
+                $retval['item_param_type'][$key] = '';
+            }
+        }
+        $retval['item_param_length']    = $_REQUEST['item_param_length'];
+        $retval['item_param_opts_num']  = $_REQUEST['item_param_opts_num'];
+        $retval['item_param_opts_text'] = $_REQUEST['item_param_opts_text'];
+        $retval['item_num_params'] = max(
+            count($retval['item_param_name']),
+            count($retval['item_param_type']),
+            count($retval['item_param_length']),
+            count($retval['item_param_opts_num']),
+            count($retval['item_param_opts_text'])
+        );
+    }
+    $retval['item_returntype'] = '';
+    if (isset($_REQUEST['item_returntype'])
+        && in_array($_REQUEST['item_returntype'], PMA_Util::getSupportedDatatypes())
+    ) {
+        $retval['item_returntype'] = $_REQUEST['item_returntype'];
+    }
+
+    $retval['item_isdeterministic'] = '';
+    if (isset($_REQUEST['item_isdeterministic'])
+        && strtolower($_REQUEST['item_isdeterministic']) == 'on'
+    ) {
+        $retval['item_isdeterministic'] = " checked='checked'";
+    }
+    $retval['item_securitytype_definer'] = '';
+    $retval['item_securitytype_invoker'] = '';
+    if (isset($_REQUEST['item_securitytype'])) {
+        if ($_REQUEST['item_securitytype'] === 'DEFINER') {
+            $retval['item_securitytype_definer'] = " selected='selected'";
+        } else if ($_REQUEST['item_securitytype'] === 'INVOKER') {
+            $retval['item_securitytype_invoker'] = " selected='selected'";
+        }
+    }
+    $retval['item_sqldataaccess'] = '';
+    if (isset($_REQUEST['item_sqldataaccess'])
+        && in_array($_REQUEST['item_sqldataaccess'], $param_sqldataaccess, true)
+    ) {
+        $retval['item_sqldataaccess'] = $_REQUEST['item_sqldataaccess'];
+    }
+
+    return $retval;
+} // end function PMA_RTN_getDataFromRequest()
+
+/**
+ * This function will generate the values that are required to complete
+ * the "Edit routine" form given the name of a routine.
+ *
+ * @param string $name The name of the routine.
+ * @param string $type Type of routine (ROUTINE|PROCEDURE)
+ * @param bool   $all  Whether to return all data or just
+ *                     the info about parameters.
+ *
+ * @return array    Data necessary to create the routine editor.
+ */
+function PMA_RTN_getDataFromName($name, $type, $all = true)
+{
+    global $db;
+
+    $retval  = array();
+
+    // Build and execute the query
+    $fields  = "SPECIFIC_NAME, ROUTINE_TYPE, DTD_IDENTIFIER, "
+             . "ROUTINE_DEFINITION, IS_DETERMINISTIC, SQL_DATA_ACCESS, "
+             . "ROUTINE_COMMENT, SECURITY_TYPE";
+    $where   = "ROUTINE_SCHEMA='" . PMA_Util::sqlAddSlashes($db) . "' "
+             . "AND SPECIFIC_NAME='" . PMA_Util::sqlAddSlashes($name) . "'"
+             . "AND ROUTINE_TYPE='" . PMA_Util::sqlAddSlashes($type) . "'";
+    $query   = "SELECT $fields FROM INFORMATION_SCHEMA.ROUTINES WHERE $where;";
+
+    $routine = PMA_DBI_fetch_single_row($query);
+
+    if (! $routine) {
+        return false;
+    }
+
+    // Get required data
+    $retval['item_name'] = $routine['SPECIFIC_NAME'];
+    $retval['item_type'] = $routine['ROUTINE_TYPE'];
+    $parsed_query = PMA_SQP_parse(
+        PMA_DBI_get_definition(
+            $db,
+            $routine['ROUTINE_TYPE'],
+            $routine['SPECIFIC_NAME']
+        )
+    );
+    $params = PMA_RTN_parseAllParameters($parsed_query, $routine['ROUTINE_TYPE']);
+    $retval['item_num_params']      = $params['num'];
+    $retval['item_param_dir']       = $params['dir'];
+    $retval['item_param_name']      = $params['name'];
+    $retval['item_param_type']      = $params['type'];
+    $retval['item_param_length']    = $params['length'];
+    $retval['item_param_opts_num']  = $params['opts'];
+    $retval['item_param_opts_text'] = $params['opts'];
+
+    // Get extra data
+    if ($all) {
+        if ($retval['item_type'] == 'FUNCTION') {
+            $retval['item_type_toggle'] = 'PROCEDURE';
+        } else {
+            $retval['item_type_toggle'] = 'FUNCTION';
+        }
+        $retval['item_returntype']   = '';
+        $retval['item_returnlength'] = '';
+        $retval['item_returnopts_num']  = '';
+        $retval['item_returnopts_text'] = '';
+        if (! empty($routine['DTD_IDENTIFIER'])) {
+            if (strlen($routine['DTD_IDENTIFIER']) > 63) {
+                // If the DTD_IDENTIFIER string from INFORMATION_SCHEMA is
+                // at least 64 characters, then it may actually have been
+                // chopped because that column is a varchar(64), so we will
+                // parse the output of SHOW CREATE query to get accurate
+                // information about the return variable.
+                $dtd = '';
+                $fetching = false;
+                for ($i=0; $i<$parsed_query['len']; $i++) {
+                    if ($parsed_query[$i]['type'] == 'alpha_reservedWord'
+                        && strtoupper($parsed_query[$i]['data']) == 'RETURNS'
+                    ) {
+                        $fetching = true;
+                    } else if ($fetching == true
+                        && $parsed_query[$i]['type'] == 'alpha_reservedWord'
+                    ) {
+                        // We will not be looking for options such as UNSIGNED
+                        // or ZEROFILL because there is no way that a numeric
+                        // field's DTD_IDENTIFIER can be longer than 64
+                        // characters. We can safely assume that the return
+                        // datatype is either ENUM or SET, so we only look
+                        // for CHARSET.
+                        $word = strtoupper($parsed_query[$i]['data']);
+                        if ($word == 'CHARSET'
+                            && ($parsed_query[$i+1]['type'] == 'alpha_charset'
+                            || $parsed_query[$i+1]['type'] == 'alpha_identifier')
+                        ) {
+                            $dtd .= $word . ' ' . $parsed_query[$i+1]['data'];
+                        }
+                        break;
+                    } else if ($fetching == true) {
+                        $dtd .= $parsed_query[$i]['data'] . ' ';
+                    }
+                }
+                $routine['DTD_IDENTIFIER'] = $dtd;
+            }
+            $returnparam = PMA_RTN_parseOneParameter($routine['DTD_IDENTIFIER']);
+            $retval['item_returntype']      = $returnparam[2];
+            $retval['item_returnlength']    = $returnparam[3];
+            $retval['item_returnopts_num']  = $returnparam[4];
+            $retval['item_returnopts_text'] = $returnparam[4];
+        }
+        $retval['item_definer'] = PMA_RTN_parseRoutineDefiner($parsed_query);
+        $retval['item_definition'] = $routine['ROUTINE_DEFINITION'];
+        $retval['item_isdeterministic'] = '';
+        if ($routine['IS_DETERMINISTIC'] == 'YES') {
+            $retval['item_isdeterministic'] = " checked='checked'";
+        }
+        $retval['item_securitytype_definer'] = '';
+        $retval['item_securitytype_invoker'] = '';
+        if ($routine['SECURITY_TYPE'] == 'DEFINER') {
+            $retval['item_securitytype_definer'] = " selected='selected'";
+        } else if ($routine['SECURITY_TYPE'] == 'INVOKER') {
+            $retval['item_securitytype_invoker'] = " selected='selected'";
+        }
+        $retval['item_sqldataaccess'] = $routine['SQL_DATA_ACCESS'];
+        $retval['item_comment']       = $routine['ROUTINE_COMMENT'];
+    }
+
+    return $retval;
+} // PMA_RTN_getDataFromName()
+
+/**
+ * Creates one row for the parameter table used in the routine editor.
+ *
+ * @param array  $routine Data for the routine returned by
+ *                        PMA_RTN_getDataFromRequest() or
+ *                        PMA_RTN_getDataFromName()
+ * @param mixed  $index   Either a numeric index of the row being processed
+ *                        or NULL to create a template row for AJAX request
+ * @param string $class   Class used to hide the direction column, if the
+ *                        row is for a stored function.
+ *
+ * @return string    HTML code of one row of parameter table for the editor.
+ */
+function PMA_RTN_getParameterRow($routine = array(), $index = null, $class = '')
+{
+    global $param_directions, $param_opts_num, $titles;
+
+    if ($index === null) {
+        // template row for AJAX request
+        $i = 0;
+        $index = '%s';
+        $drop_class = '';
+        $routine = array(
+            'item_param_dir'       => array(0 => ''),
+            'item_param_name'      => array(0 => ''),
+            'item_param_type'      => array(0 => ''),
+            'item_param_length'    => array(0 => ''),
+            'item_param_opts_num'  => array(0 => ''),
+            'item_param_opts_text' => array(0 => '')
+        );
+    } else if (! empty($routine)) {
+        // regular row for routine editor
+        $drop_class = ' hide';
+        $i = $index;
+    } else {
+        // No input data. This shouldn't happen,
+        // but better be safe than sorry.
+        return '';
+    }
+
+    // Create the output
+    $retval  = "";
+    $retval .= "        <tr>\n";
+    $retval .= "            <td class='routine_direction_cell$class'>\n";
+    $retval .= "                <select name='item_param_dir[$index]'>\n";
+    foreach ($param_directions as $key => $value) {
+        $selected = "";
+        if (! empty($routine['item_param_dir'][$i])
+            && $routine['item_param_dir'][$i] == $value
+        ) {
+            $selected = " selected='selected'";
+        }
+        $retval .= "                    <option$selected>$value</option>\n";
+    }
+    $retval .= "                </select>\n";
+    $retval .= "            </td>\n";
+    $retval .= "            <td><input name='item_param_name[$index]' type='text'\n"
+        . " value='{$routine['item_param_name'][$i]}' /></td>\n";
+    $retval .= "            <td><select name='item_param_type[$index]'>";
+    $retval .= PMA_Util::getSupportedDatatypes(
+        true, $routine['item_param_type'][$i]
+    ) . "\n";
+    $retval .= "            </select></td>\n";
+    $retval .= "            <td>\n";
+    $retval .= "                <input id='item_param_length_$index'\n"
+        . " name='item_param_length[$index]' type='text'\n"
+        . " value='{$routine['item_param_length'][$i]}' />\n";
+    $retval .= "                <div class='enum_hint'>\n";
+    $retval .= "                    <a href='#' class='open_enum_editor'>\n";
+    $retval .= "                        "
+        . PMA_Util::getImage('b_edit', '', array('title'=>__('ENUM/SET editor')))
+        . "\n";
+    $retval .= "                    </a>\n";
+    $retval .= "                </div>\n";
+    $retval .= "            </td>\n";
+    $retval .= "            <td class='hide no_len'>---</td>\n";
+    $retval .= "            <td class='routine_param_opts_text'>\n";
+    $retval .= PMA_generateCharsetDropdownBox(
+        PMA_CSDROPDOWN_CHARSET,
+        "item_param_opts_text[$index]",
+        null,
+        $routine['item_param_opts_text'][$i]
+    );
+    $retval .= "            </td>\n";
+    $retval .= "            <td class='hide no_opts'>---</td>\n";
+    $retval .= "            <td class='routine_param_opts_num'>\n";
+    $retval .= "                <select name='item_param_opts_num[$index]'>\n";
+    $retval .= "                    <option value=''></option>";
+    foreach ($param_opts_num as $key => $value) {
+        $selected = "";
+        if (! empty($routine['item_param_opts_num'][$i])
+            && $routine['item_param_opts_num'][$i] == $value
+        ) {
+            $selected = " selected='selected'";
+        }
+        $retval .= "<option$selected>$value</option>";
+    }
+    $retval .= "\n                </select>\n";
+    $retval .= "            </td>\n";
+    $retval .= "            <td class='routine_param_remove$drop_class'>\n";
+    $retval .= "                <a href='#' class='routine_param_remove_anchor'>\n";
+    $retval .= "                    {$titles['Drop']}\n";
+    $retval .= "                </a>\n";
+    $retval .= "            </td>\n";
+    $retval .= "        </tr>\n";
+
+    return $retval;
+} // end PMA_RTN_getParameterRow()
+
+/**
+ * Displays a form used to add/edit a routine
+ *
+ * @param string $mode      If the editor will be used edit a routine
+ *                          or add a new one: 'edit' or 'add'.
+ * @param string $operation If the editor was previously invoked with
+ *                          JS turned off, this will hold the name of
+ *                          the current operation
+ * @param array  $routine   Data for the routine returned by
+ *                          PMA_RTN_getDataFromRequest() or
+ *                          PMA_RTN_getDataFromName()
+ *
+ * @return string   HTML code for the editor.
+ */
+function PMA_RTN_getEditorForm($mode, $operation, $routine)
+{
+    global $db, $errors, $param_sqldataaccess, $param_opts_num;
+
+    // Escape special characters
+    $need_escape = array(
+        'item_original_name',
+        'item_name',
+        'item_returnlength',
+        'item_definition',
+        'item_definer',
+        'item_comment'
+    );
+    foreach ($need_escape as $key => $index) {
+        $routine[$index] = htmlentities($routine[$index], ENT_QUOTES, 'UTF-8');
+    }
+    for ($i=0; $i<$routine['item_num_params']; $i++) {
+        $routine['item_param_name'][$i]   = htmlentities(
+            $routine['item_param_name'][$i],
+            ENT_QUOTES
+        );
+        $routine['item_param_length'][$i] = htmlentities(
+            $routine['item_param_length'][$i],
+            ENT_QUOTES
+        );
+    }
+
+    // Handle some logic first
+    if ($operation == 'change') {
+        if ($routine['item_type'] == 'PROCEDURE') {
+            $routine['item_type']        = 'FUNCTION';
+            $routine['item_type_toggle'] = 'PROCEDURE';
+        } else {
+            $routine['item_type']        = 'PROCEDURE';
+            $routine['item_type_toggle'] = 'FUNCTION';
+        }
+    } else if ($operation == 'add'
+        || ($routine['item_num_params'] == 0 && $mode == 'add' && ! $errors)
+    ) {
+        $routine['item_param_dir'][]       = '';
+        $routine['item_param_name'][]      = '';
+        $routine['item_param_type'][]      = '';
+        $routine['item_param_length'][]    = '';
+        $routine['item_param_opts_num'][]  = '';
+        $routine['item_param_opts_text'][] = '';
+        $routine['item_num_params']++;
+    } else if ($operation == 'remove') {
+        unset($routine['item_param_dir'][$routine['item_num_params']-1]);
+        unset($routine['item_param_name'][$routine['item_num_params']-1]);
+        unset($routine['item_param_type'][$routine['item_num_params']-1]);
+        unset($routine['item_param_length'][$routine['item_num_params']-1]);
+        unset($routine['item_param_opts_num'][$routine['item_num_params']-1]);
+        unset($routine['item_param_opts_text'][$routine['item_num_params']-1]);
+        $routine['item_num_params']--;
+    }
+    $disable_remove_parameter = '';
+    if (! $routine['item_num_params']) {
+        $disable_remove_parameter = " color: gray;' disabled='disabled";
+    }
+    $original_routine = '';
+    if ($mode == 'edit') {
+        $original_routine = "<input name='item_original_name' "
+                          . "type='hidden' "
+                          . "value='{$routine['item_original_name']}'/>\n"
+                          . "<input name='item_original_type' "
+                          . "type='hidden' "
+                          . "value='{$routine['item_original_type']}'/>\n";
+    }
+    $isfunction_class   = '';
+    $isprocedure_class  = '';
+    $isfunction_select  = '';
+    $isprocedure_select = '';
+    if ($routine['item_type'] == 'PROCEDURE') {
+        $isfunction_class   = ' hide';
+        $isprocedure_select = " selected='selected'";
+    } else {
+        $isprocedure_class = ' hide';
+        $isfunction_select = " selected='selected'";
+    }
+
+    // Create the output
+    $retval  = "";
+    $retval .= "<!-- START " . strtoupper($mode) . " ROUTINE FORM -->\n\n";
+    $retval .= "<form class='rte_form' action='db_routines.php' method='post'>\n";
+    $retval .= "<input name='{$mode}_item' type='hidden' value='1' />\n";
+    $retval .= $original_routine;
+    $retval .= PMA_generate_common_hidden_inputs($db) . "\n";
+    $retval .= "<fieldset>\n";
+    $retval .= "<legend>" . __('Details') . "</legend>\n";
+    $retval .= "<table class='rte_table' style='width: 100%'>\n";
+    $retval .= "<tr>\n";
+    $retval .= "    <td style='width: 20%;'>" . __('Routine name') . "</td>\n";
+    $retval .= "    <td><input type='text' name='item_name' maxlength='64'\n";
+    $retval .= "               value='{$routine['item_name']}' /></td>\n";
+    $retval .= "</tr>\n";
+    $retval .= "<tr>\n";
+    $retval .= "    <td>" . __('Type') . "</td>\n";
+    $retval .= "    <td>\n";
+    if ($GLOBALS['is_ajax_request']) {
+        $retval .= "        <select name='item_type'>\n"
+            . "<option value='PROCEDURE'$isprocedure_select>PROCEDURE</option>\n"
+            . "<option value='FUNCTION'$isfunction_select>FUNCTION</option>\n"
+            . "</select>\n";
+    } else {
+        $retval .= "<input name='item_type' type='hidden'"
+            . " value='{$routine['item_type']}' />\n"
+            . "<div style='width: 49%; float: left; text-align: center;"
+            . " font-weight: bold;'>\n"
+            . $routine['item_type'] . "\n"
+            . "</div>\n"
+            . "<input style='width: 49%;' type='submit' name='routine_changetype'\n"
+            . " value='" . sprintf(__('Change to %s'), $routine['item_type_toggle'])
+            . "' />\n";
+    }
+    $retval .= "    </td>\n";
+    $retval .= "</tr>\n";
+    $retval .= "<tr>\n";
+    $retval .= "    <td>" . __('Parameters') . "</td>\n";
+    $retval .= "    <td>\n";
+    // parameter handling start
+    $retval .= "        <table class='routine_params_table'>\n";
+    $retval .= "        <tr>\n";
+    $retval .= "            <th class='routine_direction_cell$isprocedure_class'>"
+        . __('Direction') . "</th>\n";
+    $retval .= "            <th>" . __('Name') . "</th>\n";
+    $retval .= "            <th>" . __('Type') . "</th>\n";
+    $retval .= "            <th>" . __('Length/Values') . "</th>\n";
+    $retval .= "            <th colspan='2'>" . __('Options') . "</th>\n";
+    $retval .= "            <th class='routine_param_remove hide'> </th>\n";
+    $retval .= "        </tr>";
+    for ($i=0; $i<$routine['item_num_params']; $i++) { // each parameter
+        $retval .= PMA_RTN_getParameterRow($routine, $i, $isprocedure_class);
+    }
+    $retval .= "        </table>\n";
+    $retval .= "    </td>\n";
+    $retval .= "</tr>\n";
+    $retval .= "<tr>\n";
+    $retval .= "    <td> </td>\n";
+    $retval .= "    <td>\n";
+    $retval .= "        <input style='width: 49%;' type='submit' \n";
+    $retval .= "               name='routine_addparameter'\n";
+    $retval .= "               value='" . __('Add parameter') . "' />\n";
+    $retval .= "        <input style='width: 49%;$disable_remove_parameter'\n";
+    $retval .= "               type='submit' \n";
+    $retval .= "               name='routine_removeparameter'\n";
+    $retval .= "               value='" . __('Remove last parameter') . "' />\n";
+    $retval .= "    </td>\n";
+    $retval .= "</tr>\n";
+    // parameter handling end
+    $retval .= "<tr class='routine_return_row$isfunction_class'>\n";
+    $retval .= "    <td>" . __('Return type') . "</td>\n";
+    $retval .= "    <td><select name='item_returntype'>\n";
+    $retval .= PMA_Util::getSupportedDatatypes(true, $routine['item_returntype'])
+        . "\n";
+    $retval .= "    </select></td>\n";
+    $retval .= "</tr>\n";
+    $retval .= "<tr class='routine_return_row$isfunction_class'>\n";
+    $retval .= "    <td>" . __('Return length/values') . "</td>\n";
+    $retval .= "    <td><input type='text' name='item_returnlength'\n";
+    $retval .= "               value='{$routine['item_returnlength']}' /></td>\n";
+    $retval .= "    <td class='hide no_len'>---</td>\n";
+    $retval .= "</tr>\n";
+    $retval .= "<tr class='routine_return_row$isfunction_class'>\n";
+    $retval .= "    <td>" . __('Return options') . "</td>\n";
+    $retval .= "    <td><div>\n";
+    $retval .= PMA_generateCharsetDropdownBox(
+        PMA_CSDROPDOWN_CHARSET,
+        "item_returnopts_text",
+        null,
+        $routine['item_returnopts_text']
+    );
+    $retval .= "\n    </div>\n";
+    $retval .= "    <div><select name='item_returnopts_num'>\n";
+    $retval .= "        <option value=''></option>";
+    foreach ($param_opts_num as $key => $value) {
+        $selected = "";
+        if (! empty($routine['item_returnopts_num'])
+            && $routine['item_returnopts_num'] == $value
+        ) {
+            $selected = " selected='selected'";
+        }
+        $retval .= "<option$selected>$value</option>";
+    }
+    $retval .= "\n    </select></div>\n";
+    $retval .= "    <div class='hide no_opts'>---</div>\n";
+    $retval .= "</td>\n";
+    $retval .= "</tr>\n";
+    $retval .= "<tr>\n";
+    $retval .= "    <td>" . __('Definition') . "</td>\n";
+    $retval .= "    <td><textarea name='item_definition' rows='15' cols='40'>";
+    $retval .= $routine['item_definition'];
+    $retval .= "</textarea></td>\n";
+    $retval .= "</tr>\n";
+    $retval .= "<tr>\n";
+    $retval .= "    <td>" . __('Is deterministic') . "</td>\n";
+    $retval .= "    <td><input type='checkbox' name='item_isdeterministic'"
+        . $routine['item_isdeterministic'] . " /></td>\n";
+    $retval .= "</tr>\n";
+    $retval .= "<tr>\n";
+    $retval .= "    <td>" . __('Definer') . "</td>\n";
+    $retval .= "    <td><input type='text' name='item_definer'\n";
+    $retval .= "               value='{$routine['item_definer']}' /></td>\n";
+    $retval .= "</tr>\n";
+    $retval .= "<tr>\n";
+    $retval .= "    <td>" . __('Security type') . "</td>\n";
+    $retval .= "    <td><select name='item_securitytype'>\n";
+    $retval .= "        <option value='DEFINER'"
+        . $routine['item_securitytype_definer'] . ">DEFINER</option>\n";
+    $retval .= "        <option value='INVOKER'"
+        . $routine['item_securitytype_invoker'] . ">INVOKER</option>\n";
+    $retval .= "    </select></td>\n";
+    $retval .= "</tr>\n";
+    $retval .= "<tr>\n";
+    $retval .= "    <td>" . __('SQL data access') . "</td>\n";
+    $retval .= "    <td><select name='item_sqldataaccess'>\n";
+    foreach ($param_sqldataaccess as $key => $value) {
+        $selected = "";
+        if ($routine['item_sqldataaccess'] == $value) {
+            $selected = " selected='selected'";
+        }
+        $retval .= "        <option$selected>$value</option>\n";
+    }
+    $retval .= "    </select></td>\n";
+    $retval .= "</tr>\n";
+    $retval .= "<tr>\n";
+    $retval .= "    <td>" . __('Comment') . "</td>\n";
+    $retval .= "    <td><input type='text' name='item_comment' maxlength='64'\n";
+    $retval .= "               value='{$routine['item_comment']}' /></td>\n";
+    $retval .= "</tr>\n";
+    $retval .= "</table>\n";
+    $retval .= "</fieldset>\n";
+    if ($GLOBALS['is_ajax_request']) {
+        $retval .= "<input type='hidden' name='editor_process_{$mode}'\n";
+        $retval .= "       value='true' />\n";
+        $retval .= "<input type='hidden' name='ajax_request' value='true' />\n";
+    } else {
+        $retval .= "<fieldset class='tblFooters'>\n";
+        $retval .= "    <input type='submit' name='editor_process_{$mode}'\n";
+        $retval .= "           value='" . __('Go') . "' />\n";
+        $retval .= "</fieldset>\n";
+    }
+    $retval .= "</form>\n\n";
+    $retval .= "<!-- END " . strtoupper($mode) . " ROUTINE FORM -->\n\n";
+
+    return $retval;
+} // end PMA_RTN_getEditorForm()
+
+/**
+ * Composes the query necessary to create a routine from an HTTP request.
+ *
+ * @return string  The CREATE [ROUTINE | PROCEDURE] query.
+ */
+function PMA_RTN_getQueryFromRequest()
+{
+    global $_REQUEST, $errors, $param_sqldataaccess, $param_directions;
+
+    $_REQUEST['item_type'] = isset($_REQUEST['item_type'])
+        ? $_REQUEST['item_type'] : '';
+
+    $query = 'CREATE ';
+    if (! empty($_REQUEST['item_definer'])) {
+        if (strpos($_REQUEST['item_definer'], '@') !== false) {
+            $arr = explode('@', $_REQUEST['item_definer']);
+            $query .= 'DEFINER=' . PMA_Util::backquote($arr[0]);
+            $query .= '@' . PMA_Util::backquote($arr[1]) . ' ';
+        } else {
+            $errors[] = __('The definer must be in the "username at hostname" format');
+        }
+    }
+    if ($_REQUEST['item_type'] == 'FUNCTION'
+        || $_REQUEST['item_type'] == 'PROCEDURE'
+    ) {
+        $query .= $_REQUEST['item_type'] . ' ';
+    } else {
+        $errors[] = sprintf(
+            __('Invalid routine type: "%s"'),
+            htmlspecialchars($_REQUEST['item_type'])
+        );
+    }
+    if (! empty($_REQUEST['item_name'])) {
+        $query .= PMA_Util::backquote($_REQUEST['item_name']);
+    } else {
+        $errors[] = __('You must provide a routine name');
+    }
+    $params = '';
+    $warned_about_dir    = false;
+    $warned_about_name   = false;
+    $warned_about_length = false;
+    if (   ! empty($_REQUEST['item_param_name'])
+        && ! empty($_REQUEST['item_param_type'])
+        && ! empty($_REQUEST['item_param_length'])
+        && is_array($_REQUEST['item_param_name'])
+        && is_array($_REQUEST['item_param_type'])
+        && is_array($_REQUEST['item_param_length'])
+    ) {
+        for ($i=0; $i<count($_REQUEST['item_param_name']); $i++) {
+            if (! empty($_REQUEST['item_param_name'][$i])
+                && ! empty($_REQUEST['item_param_type'][$i])
+            ) {
+                if ($_REQUEST['item_type'] == 'PROCEDURE'
+                    && ! empty($_REQUEST['item_param_dir'][$i])
+                    && in_array($_REQUEST['item_param_dir'][$i], $param_directions)
+                ) {
+                    $params .= $_REQUEST['item_param_dir'][$i] . " "
+                        . PMA_Util::backquote($_REQUEST['item_param_name'][$i])
+                        . " " . $_REQUEST['item_param_type'][$i];
+                } else if ($_REQUEST['item_type'] == 'FUNCTION') {
+                    $params .= PMA_Util::backquote($_REQUEST['item_param_name'][$i])
+                        . " " . $_REQUEST['item_param_type'][$i];
+                } else if (! $warned_about_dir) {
+                    $warned_about_dir = true;
+                    $errors[] = sprintf(
+                        __('Invalid direction "%s" given for parameter.'),
+                        htmlspecialchars($_REQUEST['item_param_dir'][$i])
+                    );
+                }
+                if ($_REQUEST['item_param_length'][$i] != ''
+                    && !preg_match(
+                        '@^(DATE|DATETIME|TIME|TINYBLOB|TINYTEXT|BLOB|TEXT|MEDIUMBLOB|MEDIUMTEXT|LONGBLOB|LONGTEXT|SERIAL|BOOLEAN)$@i',
+                        $_REQUEST['item_param_type'][$i]
+                    )
+                ) {
+                    $params .= "(" . $_REQUEST['item_param_length'][$i] . ")";
+                } else if ($_REQUEST['item_param_length'][$i] == ''
+                    && preg_match(
+                        '@^(ENUM|SET|VARCHAR|VARBINARY)$@i',
+                        $_REQUEST['item_param_type'][$i]
+                    )
+                ) {
+                    if (! $warned_about_length) {
+                        $warned_about_length = true;
+                        $errors[] = __(
+                            'You must provide length/values for routine parameters'
+                            . ' of type ENUM, SET, VARCHAR and VARBINARY.'
+                        );
+                    }
+                }
+                if (! empty($_REQUEST['item_param_opts_text'][$i])) {
+                    if ($GLOBALS['PMA_Types']->getTypeClass($_REQUEST['item_param_type'][$i]) == 'CHAR') {
+                        $params .= ' CHARSET ' 
+                            . strtolower($_REQUEST['item_param_opts_text'][$i]);
+                    }
+                }
+                if (! empty($_REQUEST['item_param_opts_num'][$i])) {
+                    if ($GLOBALS['PMA_Types']->getTypeClass($_REQUEST['item_param_type'][$i]) == 'NUMBER') {
+                        $params .= ' '
+                            . strtoupper($_REQUEST['item_param_opts_num'][$i]);
+                    }
+                }
+                if ($i != count($_REQUEST['item_param_name'])-1) {
+                    $params .= ", ";
+                }
+            } else if (! $warned_about_name) {
+                $warned_about_name = true;
+                $errors[] = __(
+                    'You must provide a name and a type for each routine parameter.'
+                );
+                break;
+            }
+        }
+    }
+    $query .= "(" . $params . ") ";
+    if ($_REQUEST['item_type'] == 'FUNCTION') {
+        if (! empty($_REQUEST['item_returntype'])
+            && in_array(
+                $_REQUEST['item_returntype'], PMA_Util::getSupportedDatatypes()
+            )
+        ) {
+            $query .= "RETURNS {$_REQUEST['item_returntype']}";
+        } else {
+            $errors[] = __('You must provide a valid return type for the routine.');
+        }
+        if (! empty($_REQUEST['item_returnlength'])
+            && !preg_match(
+                '@^(DATE|DATETIME|TIME|TINYBLOB|TINYTEXT|BLOB|TEXT|MEDIUMBLOB|MEDIUMTEXT|LONGBLOB|LONGTEXT|SERIAL|BOOLEAN)$@i',
+                $_REQUEST['item_returntype']
+            )
+        ) {
+            $query .= "(" . $_REQUEST['item_returnlength'] . ")";
+        } else if (empty($_REQUEST['item_returnlength'])
+            && preg_match(
+                '@^(ENUM|SET|VARCHAR|VARBINARY)$@i', $_REQUEST['item_returntype']
+            )
+        ) {
+            if (! $warned_about_length) {
+                $warned_about_length = true;
+                $errors[] = __(
+                    'You must provide length/values for routine parameters'
+                    . ' of type ENUM, SET, VARCHAR and VARBINARY.'
+                );
+            }
+        }
+        if (! empty($_REQUEST['item_returnopts_text'])) {
+            if ($GLOBALS['PMA_Types']->getTypeClass($_REQUEST['item_returntype']) == 'CHAR') {
+                $query .= ' CHARSET '
+                    . strtolower($_REQUEST['item_returnopts_text']);
+            }
+        }
+        if (! empty($_REQUEST['item_returnopts_num'])) {
+            if ($GLOBALS['PMA_Types']->getTypeClass($_REQUEST['item_returntype']) == 'NUMBER') {
+                $query .= ' ' . strtoupper($_REQUEST['item_returnopts_num']);
+            }
+        }
+        $query .= ' ';
+    }
+    if (! empty($_REQUEST['item_comment'])) {
+        $query .= "COMMENT '" . PMA_Util::sqlAddslashes($_REQUEST['item_comment'])
+            . "' ";
+    }
+    if (isset($_REQUEST['item_isdeterministic'])) {
+        $query .= 'DETERMINISTIC ';
+    } else {
+        $query .= 'NOT DETERMINISTIC ';
+    }
+    if (! empty($_REQUEST['item_sqldataaccess'])
+        && in_array($_REQUEST['item_sqldataaccess'], $param_sqldataaccess)
+    ) {
+        $query .= $_REQUEST['item_sqldataaccess'] . ' ';
+    }
+    if (! empty($_REQUEST['item_securitytype'])) {
+        if ($_REQUEST['item_securitytype'] == 'DEFINER'
+            || $_REQUEST['item_securitytype'] == 'INVOKER'
+        ) {
+            $query .= 'SQL SECURITY ' . $_REQUEST['item_securitytype'] . ' ';
+        }
+    }
+    if (! empty($_REQUEST['item_definition'])) {
+        $query .= $_REQUEST['item_definition'];
+    } else {
+        $errors[] = __('You must provide a routine definition.');
+    }
+
+    return $query;
+} // end PMA_RTN_getQueryFromRequest()
+
+/**
+ * Handles requests for executing a routine
+ *
+ * @return Does not return
+ */
+function PMA_RTN_handleExecute()
+{
+    global $_GET, $_POST, $_REQUEST, $GLOBALS, $db;
+
+    /**
+     * Handle all user requests other than the default of listing routines
+     */
+    if (! empty($_REQUEST['execute_routine']) && ! empty($_REQUEST['item_name'])) {
+        // Build the queries
+        $routine = PMA_RTN_getDataFromName(
+            $_REQUEST['item_name'], $_REQUEST['item_type'], false
+        );
+        if ($routine !== false) {
+            $queries   = array();
+            $end_query = array();
+            $args      = array();
+            $all_functions = $GLOBALS['PMA_Types']->getAllFunctions();
+            for ($i=0; $i<$routine['item_num_params']; $i++) {
+                if (isset($_REQUEST['params'][$routine['item_param_name'][$i]])) {
+                    $value = $_REQUEST['params'][$routine['item_param_name'][$i]];
+                    if (is_array($value)) { // is SET type
+                        $value = implode(',', $value);
+                    }
+                    $value = PMA_Util::sqlAddSlashes($value);
+                    if (! empty($_REQUEST['funcs'][$routine['item_param_name'][$i]])
+                        && in_array(
+                            $_REQUEST['funcs'][$routine['item_param_name'][$i]],
+                            $all_functions
+                        )
+                    ) {
+                        $queries[] = "SET @p$i="
+                            . $_REQUEST['funcs'][$routine['item_param_name'][$i]]
+                            . "('$value');\n";
+                    } else {
+                        $queries[] = "SET @p$i='$value';\n";
+                    }
+                    $args[] = "@p$i";
+                } else {
+                    $args[] = "@p$i";
+                }
+                if ($routine['item_type'] == 'PROCEDURE') {
+                    if ($routine['item_param_dir'][$i] == 'OUT'
+                        || $routine['item_param_dir'][$i] == 'INOUT'
+                    ) {
+                        $end_query[] = "@p$i AS "
+                            . PMA_Util::backquote($routine['item_param_name'][$i]);
+                    }
+                }
+            }
+            if ($routine['item_type'] == 'PROCEDURE') {
+                $queries[] = "CALL " . PMA_Util::backquote($routine['item_name'])
+                           . "(" . implode(', ', $args) . ");\n";
+                if (count($end_query)) {
+                    $queries[] = "SELECT " . implode(', ', $end_query) . ";\n";
+                }
+            } else {
+                $queries[] = "SELECT " . PMA_Util::backquote($routine['item_name'])
+                           . "(" . implode(', ', $args) . ") "
+                           . "AS " . PMA_Util::backquote($routine['item_name'])
+                            . ";\n";
+            }
+
+            // Get all the queries as one SQL statement
+            $multiple_query = implode("", $queries);
+
+            $outcome = true;
+            $affected = 0;
+
+            // Execute query
+            if (! PMA_DBI_try_multi_query($multiple_query)) {
+                $outcome = false;
+            }
+
+            // Generate output
+            if ($outcome) {
+
+                // Pass the SQL queries through the "pretty printer"
+                $output  = '<code class="sql" style="margin-bottom: 1em;">';
+                $output .= PMA_SQP_formatHtml(PMA_SQP_parse(implode($queries)));
+                $output .= '</code>';
+
+                // Display results
+                $output .= "<fieldset><legend>";
+                $output .= sprintf(
+                    __('Execution results of routine %s'),
+                    PMA_Util::backquote(htmlspecialchars($routine['item_name']))
+                );
+                $output .= "</legend>";
+
+                $num_of_rusults_set_to_display = 0;
+
+                do {
+
+                    $result = PMA_DBI_store_result();
+                    $num_rows = PMA_DBI_num_rows($result);
+
+                    if (($result !== false) && ($num_rows > 0)) {
+
+                        $output .= "<table><tr>";
+                        foreach (PMA_DBI_get_fields_meta($result) as $key => $field) {
+                            $output .= "<th>";
+                            $output .= htmlspecialchars($field->name);
+                            $output .= "</th>";
+                        }
+                        $output .= "</tr>";
+
+                        $color_class = 'odd';
+
+                        while ($row = PMA_DBI_fetch_assoc($result)) {
+                            $output .= "<tr>";
+                            foreach ($row as $key => $value) {
+                                if ($value === null) {
+                                    $value = '<i>NULL</i>';
+                                } else {
+                                    $value = htmlspecialchars($value);
+                                }
+                                $output .= "<td class='" . $color_class . "'>"
+                                    . $value . "</td>";
+                            }
+                            $output .= "</tr>";
+                            $color_class = ($color_class == 'odd') ? 'even' : 'odd';
+                        }
+
+                        $output .= "</table>";
+                        $num_of_rusults_set_to_display++;
+                        $affected = $num_rows;
+
+                    }
+
+                    if (! PMA_DBI_more_results()) {
+                        break;
+                    }
+
+                    $output .= "<br/>";
+
+                    PMA_DBI_free_result($result);
+
+                } while (PMA_DBI_next_result());
+
+                $output .= "</fieldset>";
+
+                $message = __('Your SQL query has been executed successfully');
+                if ($routine['item_type'] == 'PROCEDURE') {
+                    $message .= '<br />';
+
+                    // TODO : message need to be modified according to the
+                    // output from the routine
+                    $message .= sprintf(
+                        _ngettext(
+                            '%d row affected by the last statement inside the procedure',
+                            '%d rows affected by the last statement inside the procedure',
+                            $affected
+                        ),
+                        $affected
+                    );
+                }
+                $message = PMA_message::success($message);
+
+                if ($num_of_rusults_set_to_display == 0) {
+                    $notice = __(
+                        'MySQL returned an empty result set (i.e. zero rows).'
+                    );
+                    $output .= PMA_message::notice($notice)->getDisplay();
+                }
+
+            } else {
+                $output = '';
+                $message = PMA_message::error(
+                    sprintf(
+                        __('The following query has failed: "%s"'),
+                        htmlspecialchars($multiple_query)
+                    )
+                    . '<br /><br />'
+                    . __('MySQL said: ') . PMA_DBI_getError(null)
+                );
+            }
+
+            // Print/send output
+            if ($GLOBALS['is_ajax_request']) {
+                $response = PMA_Response::getInstance();
+                $response->isSuccess($message->isSuccess());
+                $response->addJSON('message', $message->getDisplay() . $output);
+                $response->addJSON('dialog', false);
+                exit;
+            } else {
+                echo $message->getDisplay() . $output;
+                if ($message->isError()) {
+                    // At least one query has failed, so shouldn't
+                    // execute any more queries, so we quit.
+                    exit;
+                }
+                unset($_POST);
+                // Now deliberately fall through to displaying the routines list
+            }
+        } else {
+            $message  = __('Error in processing request') . ' : ';
+            $message .= sprintf(
+                PMA_RTE_getWord('not_found'),
+                htmlspecialchars(PMA_Util::backquote($_REQUEST['item_name'])),
+                htmlspecialchars(PMA_Util::backquote($db))
+            );
+            $message = PMA_message::error($message);
+            if ($GLOBALS['is_ajax_request']) {
+                $response = PMA_Response::getInstance();
+                $response->isSuccess(false);
+                $response->addJSON('message', $message);
+                exit;
+            } else {
+                echo $message->getDisplay();
+                unset($_POST);
+            }
+        }
+    } else if (! empty($_GET['execute_dialog']) && ! empty($_GET['item_name'])) {
+        /**
+         * Display the execute form for a routine.
+         */
+        $routine = PMA_RTN_getDataFromName(
+            $_GET['item_name'], $_GET['item_type'], true
+        );
+        if ($routine !== false) {
+            $form = PMA_RTN_getExecuteForm($routine);
+            if ($GLOBALS['is_ajax_request'] == true) {
+                $title = __("Execute routine") . " " . PMA_Util::backquote(
+                    htmlentities($_GET['item_name'], ENT_QUOTES)
+                );
+                $response = PMA_Response::getInstance();
+                $response->addJSON('message', $form);
+                $response->addJSON('title', $title);
+                $response->addJSON('dialog', true);
+            } else {
+                echo "\n\n<h2>" . __("Execute routine") . "</h2>\n\n";
+                echo $form;
+            }
+            exit;
+        } else if (($GLOBALS['is_ajax_request'] == true)) {
+            $message  = __('Error in processing request') . ' : ';
+            $message .= sprintf(
+                PMA_RTE_getWord('not_found'),
+                htmlspecialchars(PMA_Util::backquote($_REQUEST['item_name'])),
+                htmlspecialchars(PMA_Util::backquote($db))
+            );
+            $message = PMA_message::error($message);
+
+            $response = PMA_Response::getInstance();
+            $response->isSuccess(false);
+            $response->addJSON('message', $message);
+            exit;
+        }
+    }
+}
+
+/**
+ * Creates the HTML code that shows the routine execution dialog.
+ *
+ * @param array $routine Data for the routine returned by
+ *                       PMA_RTN_getDataFromName()
+ *
+ * @return string   HTML code for the routine execution dialog.
+ */
+function PMA_RTN_getExecuteForm($routine)
+{
+    global $db, $cfg;
+
+    // Escape special characters
+    $routine['item_name'] = htmlentities($routine['item_name'], ENT_QUOTES);
+    for ($i=0; $i<$routine['item_num_params']; $i++) {
+        $routine['item_param_name'][$i] = htmlentities(
+            $routine['item_param_name'][$i],
+            ENT_QUOTES
+        );
+    }
+
+    // Create the output
+    $retval  = "";
+    $retval .= "<!-- START ROUTINE EXECUTE FORM -->\n\n";
+    $retval .= "<form action='db_routines.php' method='post' class='rte_form'>\n";
+    $retval .= "<input type='hidden' name='item_name'\n";
+    $retval .= "       value='{$routine['item_name']}' />\n";
+    $retval .= "<input type='hidden' name='item_type'\n";
+    $retval .= "       value='{$routine['item_type']}' />\n";
+    $retval .= PMA_generate_common_hidden_inputs($db) . "\n";
+    $retval .= "<fieldset>\n";
+    if ($GLOBALS['is_ajax_request'] != true) {
+        $retval .= "<legend>{$routine['item_name']}</legend>\n";
+        $retval .= "<table class='rte_table'>\n";
+        $retval .= "<caption class='tblHeaders'>\n";
+        $retval .= __('Routine parameters');
+        $retval .= "</caption>\n";
+    } else {
+        $retval .= "<legend>" . __('Routine parameters') . "</legend>\n";
+        $retval .= "<table class='rte_table' style='width: 100%;'>\n";
+    }
+    $retval .= "<tr>\n";
+    $retval .= "<th>" . __('Name') . "</th>\n";
+    $retval .= "<th>" . __('Type') . "</th>\n";
+    if ($cfg['ShowFunctionFields']) {
+        $retval .= "<th>" . __('Function') . "</th>\n";
+    }
+    $retval .= "<th>" . __('Value')    . "</th>\n";
+    $retval .= "</tr>\n";
+    // Get a list of data types that are not yet supported.
+    $no_support_types = PMA_Util::unsupportedDatatypes();
+    for ($i=0; $i<$routine['item_num_params']; $i++) { // Each parameter
+        if ($routine['item_type'] == 'PROCEDURE'
+            && $routine['item_param_dir'][$i] == 'OUT'
+        ) {
+            continue;
+        }
+        $rowclass = ($i % 2 == 0) ? 'even' : 'odd';
+        $retval .= "\n<tr class='$rowclass'>\n";
+        $retval .= "<td>{$routine['item_param_name'][$i]}</td>\n";
+        $retval .= "<td>{$routine['item_param_type'][$i]}</td>\n";
+        if ($cfg['ShowFunctionFields']) {
+            $retval .= "<td>\n";
+            if (stristr($routine['item_param_type'][$i], 'enum')
+                || stristr($routine['item_param_type'][$i], 'set')
+                || in_array(
+                    strtolower($routine['item_param_type'][$i]), $no_support_types
+                )
+            ) {
+                $retval .= "--\n";
+            } else {
+                $field = array(
+                    'True_Type'       => strtolower($routine['item_param_type'][$i]),
+                    'Type'            => '',
+                    'Key'             => '',
+                    'Field'           => '',
+                    'Default'         => '',
+                    'first_timestamp' => false
+                );
+                $retval .= "<select name='funcs[{$routine['item_param_name'][$i]}]'>";
+                $retval .= PMA_Util::getFunctionsForField($field, false);
+                $retval .= "</select>";
+            }
+            $retval .= "</td>\n";
+        }
+        // Append a class to date/time fields so that
+        // jQuery can attach a datepicker to them
+        $class = '';
+        if ($routine['item_param_type'][$i] == 'DATETIME'
+            || $routine['item_param_type'][$i] == 'TIMESTAMP'
+        ) {
+            $class = 'datetimefield';
+        } else if ($routine['item_param_type'][$i] == 'DATE') {
+            $class = 'datefield';
+        }
+        $retval .= "<td class='nowrap'>\n";
+        if (in_array($routine['item_param_type'][$i], array('ENUM', 'SET'))) {
+            $tokens = PMA_SQP_parse($routine['item_param_length'][$i]);
+            if ($routine['item_param_type'][$i] == 'ENUM') {
+                $input_type = 'radio';
+            } else {
+                $input_type = 'checkbox';
+            }
+            for ($j=0; $j<$tokens['len']; $j++) {
+                if ($tokens[$j]['type'] != 'punct_listsep') {
+                    $tokens[$j]['data'] = htmlentities(
+                        PMA_Util::unquote($tokens[$j]['data']),
+                        ENT_QUOTES
+                    );
+                    $retval .= "<input name='params[{$routine['item_param_name'][$i]}][]' "
+                             . "value='{$tokens[$j]['data']}' type='$input_type' />"
+                             . "{$tokens[$j]['data']}<br />\n";
+                }
+            }
+        } else if (in_array(
+            strtolower($routine['item_param_type'][$i]), $no_support_types
+        )) {
+            $retval .= "\n";
+        } else {
+            $retval .= "<input class='$class' type='text' name='params["
+                . $routine['item_param_name'][$i] . "]' />\n";
+        }
+        $retval .= "</td>\n";
+        $retval .= "</tr>\n";
+    }
+    $retval .= "\n</table>\n";
+    if ($GLOBALS['is_ajax_request'] != true) {
+        $retval .= "</fieldset>\n\n";
+        $retval .= "<fieldset class='tblFooters'>\n";
+        $retval .= "    <input type='submit' name='execute_routine'\n";
+        $retval .= "           value='" . __('Go') . "' />\n";
+        $retval .= "</fieldset>\n";
+    } else {
+        $retval .= "<input type='hidden' name='execute_routine' value='true' />";
+        $retval .= "<input type='hidden' name='ajax_request' value='true' />";
+    }
+    $retval .= "</form>\n\n";
+    $retval .= "<!-- END ROUTINE EXECUTE FORM -->\n\n";
+
+    return $retval;
+} // end PMA_RTN_getExecuteForm()
+
+?>
diff --git a/phpmyadmin/libraries/rte/rte_triggers.lib.php b/phpmyadmin/libraries/rte/rte_triggers.lib.php
new file mode 100644
index 0000000..504eb98
--- /dev/null
+++ b/phpmyadmin/libraries/rte/rte_triggers.lib.php
@@ -0,0 +1,486 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * Functions for trigger management.
+ *
+ * @package PhpMyAdmin
+ */
+if (! defined('PHPMYADMIN')) {
+    exit;
+}
+
+/**
+ * Sets required globals
+ *
+ * @return void
+ */
+function PMA_TRI_setGlobals()
+{
+    global $action_timings, $event_manipulations;
+
+    // Some definitions for triggers
+    $action_timings      = array('BEFORE',
+                                 'AFTER');
+    $event_manipulations = array('INSERT',
+                                 'UPDATE',
+                                 'DELETE');
+}
+
+/**
+ * Main function for the triggers functionality
+ *
+ * @return void
+ */
+function PMA_TRI_main()
+{
+    global $db, $table;
+
+    PMA_TRI_setGlobals();
+    /**
+     * Process all requests
+     */
+    PMA_TRI_handleEditor();
+    PMA_TRI_handleExport();
+    /**
+     * Display a list of available triggers
+     */
+    $items = PMA_DBI_get_triggers($db, $table);
+    echo PMA_RTE_getList('trigger', $items);
+    /**
+     * Display a link for adding a new trigger,
+     * if the user has the necessary privileges
+     */
+    echo PMA_TRI_getFooterLinks();
+} // end PMA_TRI_main()
+
+/**
+ * Handles editor requests for adding or editing an item
+ *
+ * @return void
+ */
+function PMA_TRI_handleEditor()
+{
+    global $_REQUEST, $_POST, $errors, $db, $table;
+
+    if (! empty($_REQUEST['editor_process_add'])
+        || ! empty($_REQUEST['editor_process_edit'])
+    ) {
+        $sql_query = '';
+
+        $item_query = PMA_TRI_getQueryFromRequest();
+
+        if (! count($errors)) { // set by PMA_RTN_getQueryFromRequest()
+            // Execute the created query
+            if (! empty($_REQUEST['editor_process_edit'])) {
+                // Backup the old trigger, in case something goes wrong
+                $trigger = PMA_TRI_getDataFromName($_REQUEST['item_original_name']);
+                $create_item = $trigger['create'];
+                $drop_item = $trigger['drop'] . ';';
+                $result = PMA_DBI_try_query($drop_item);
+                if (! $result) {
+                    $errors[] = sprintf(
+                        __('The following query has failed: "%s"'),
+                        htmlspecialchars($drop_item)
+                    )
+                    . '<br />'
+                    . __('MySQL said: ') . PMA_DBI_getError(null);
+                } else {
+                    $result = PMA_DBI_try_query($item_query);
+                    if (! $result) {
+                        $errors[] = sprintf(
+                            __('The following query has failed: "%s"'),
+                            htmlspecialchars($item_query)
+                        )
+                        . '<br />'
+                        . __('MySQL said: ') . PMA_DBI_getError(null);
+                        // We dropped the old item, but were unable to create the new one
+                        // Try to restore the backup query
+                        $result = PMA_DBI_try_query($create_item);
+                        if (! $result) {
+                            // OMG, this is really bad! We dropped the query,
+                            // failed to create a new one
+                            // and now even the backup query does not execute!
+                            // This should not happen, but we better handle
+                            // this just in case.
+                            $errors[] = __(
+                                'Sorry, we failed to restore the dropped trigger.'
+                            )
+                            . '<br />'
+                            . __('The backed up query was:')
+                            . "\"" . htmlspecialchars($create_item) . "\""
+                            . '<br />'
+                            . __('MySQL said: ') . PMA_DBI_getError(null);
+                        }
+                    } else {
+                        $message = PMA_Message::success(
+                            __('Trigger %1$s has been modified.')
+                        );
+                        $message->addParam(
+                            PMA_Util::backquote($_REQUEST['item_name'])
+                        );
+                        $sql_query = $drop_item . $item_query;
+                    }
+                }
+            } else {
+                // 'Add a new item' mode
+                $result = PMA_DBI_try_query($item_query);
+                if (! $result) {
+                    $errors[] = sprintf(
+                        __('The following query has failed: "%s"'),
+                        htmlspecialchars($item_query)
+                    )
+                    . '<br /><br />'
+                    . __('MySQL said: ') . PMA_DBI_getError(null);
+                } else {
+                    $message = PMA_Message::success(
+                        __('Trigger %1$s has been created.')
+                    );
+                    $message->addParam(
+                        PMA_Util::backquote($_REQUEST['item_name'])
+                    );
+                    $sql_query = $item_query;
+                }
+            }
+        }
+
+        if (count($errors)) {
+            $message = PMA_Message::error(__('<b>One or more errors have occured while processing your request:</b>'));
+            $message->addString('<ul>');
+            foreach ($errors as $string) {
+                $message->addString('<li>' . $string . '</li>');
+            }
+            $message->addString('</ul>');
+        }
+
+        $output = PMA_Util::getMessage($message, $sql_query);
+        if ($GLOBALS['is_ajax_request']) {
+            $response = PMA_Response::getInstance();
+            if ($message->isSuccess()) {
+                $items = PMA_DBI_get_triggers($db, $table, '');
+                $trigger = false;
+                foreach ($items as $value) {
+                    if ($value['name'] == $_REQUEST['item_name']) {
+                        $trigger = $value;
+                    }
+                }
+                $insert = false;
+                if (empty($table)
+                    || ($trigger !== false && $table == $trigger['table'])
+                ) {
+                    $insert = true;
+                    $response->addJSON('new_row', PMA_TRI_getRowForList($trigger));
+                    $response->addJSON(
+                        'name',
+                        htmlspecialchars(
+                            strtoupper($_REQUEST['item_name'])
+                        )
+                    );
+                }
+                $response->addJSON('insert', $insert);
+                $response->addJSON('message', $output);
+            } else {
+                $response->addJSON('message', $message);
+                $response->isSuccess(false);
+            }
+            exit;
+        }
+    }
+
+    /**
+     * Display a form used to add/edit a trigger, if necessary
+     */
+    if (count($errors)
+        || (empty($_REQUEST['editor_process_add'])
+        && empty($_REQUEST['editor_process_edit'])
+        && (! empty($_REQUEST['add_item'])
+        || ! empty($_REQUEST['edit_item']))) // FIXME: this must be simpler than that
+    ) {
+        // Get the data for the form (if any)
+        if (! empty($_REQUEST['add_item'])) {
+            $title = PMA_RTE_getWord('add');
+            $item = PMA_TRI_getDataFromRequest();
+            $mode = 'add';
+        } else if (! empty($_REQUEST['edit_item'])) {
+            $title = __("Edit trigger");
+            if (! empty($_REQUEST['item_name'])
+                && empty($_REQUEST['editor_process_edit'])
+            ) {
+                $item = PMA_TRI_getDataFromName($_REQUEST['item_name']);
+                if ($item !== false) {
+                    $item['item_original_name'] = $item['item_name'];
+                }
+            } else {
+                $item = PMA_TRI_getDataFromRequest();
+            }
+            $mode = 'edit';
+        }
+        if ($item !== false) {
+            // Show form
+            $editor = PMA_TRI_getEditorForm($mode, $item);
+            if ($GLOBALS['is_ajax_request']) {
+                $response = PMA_Response::getInstance();
+                $response->addJSON('message', $editor);
+                $response->addJSON('title', $title);
+            } else {
+                echo "\n\n<h2>$title</h2>\n\n$editor";
+                unset($_POST);
+            }
+            exit;
+        } else {
+            $message  = __('Error in processing request') . ' : ';
+            $message .= sprintf(
+                PMA_RTE_getWord('not_found'),
+                htmlspecialchars(PMA_Util::backquote($_REQUEST['item_name'])),
+                htmlspecialchars(PMA_Util::backquote($db))
+            );
+            $message = PMA_message::error($message);
+            if ($GLOBALS['is_ajax_request']) {
+                $response = PMA_Response::getInstance();
+                $response->isSuccess(false);
+                $response->addJSON('message', $message);
+                exit;
+            } else {
+                $message->display();
+            }
+        }
+    }
+} // end PMA_TRI_handleEditor()
+
+/**
+ * This function will generate the values that are required to for the editor
+ *
+ * @return array    Data necessary to create the editor.
+ */
+function PMA_TRI_getDataFromRequest()
+{
+    $retval = array();
+    $indices = array('item_name',
+                     'item_table',
+                     'item_original_name',
+                     'item_action_timing',
+                     'item_event_manipulation',
+                     'item_definition',
+                     'item_definer');
+    foreach ($indices as $index) {
+        $retval[$index] = isset($_REQUEST[$index]) ? $_REQUEST[$index] : '';
+    }
+    return $retval;
+} // end PMA_TRI_getDataFromRequest()
+
+/**
+ * This function will generate the values that are required to complete
+ * the "Edit trigger" form given the name of a trigger.
+ *
+ * @param string $name The name of the trigger.
+ *
+ * @return array Data necessary to create the editor.
+ */
+function PMA_TRI_getDataFromName($name)
+{
+    global $db, $table, $_REQUEST;
+
+    $temp = array();
+    $items = PMA_DBI_get_triggers($db, $table, '');
+    foreach ($items as $value) {
+        if ($value['name'] == $name) {
+            $temp = $value;
+        }
+    }
+    if (empty($temp)) {
+        return false;
+    } else {
+        $retval = array();
+        $retval['create']                  = $temp['create'];
+        $retval['drop']                    = $temp['drop'];
+        $retval['item_name']               = $temp['name'];
+        $retval['item_table']              = $temp['table'];
+        $retval['item_action_timing']      = $temp['action_timing'];
+        $retval['item_event_manipulation'] = $temp['event_manipulation'];
+        $retval['item_definition']         = $temp['definition'];
+        $retval['item_definer']            = $temp['definer'];
+        return $retval;
+    }
+} // end PMA_TRI_getDataFromName()
+
+/**
+ * Displays a form used to add/edit a trigger
+ *
+ * @param string $mode If the editor will be used edit a trigger
+ *                     or add a new one: 'edit' or 'add'.
+ * @param array  $item Data for the trigger returned by PMA_TRI_getDataFromRequest()
+ *                     or PMA_TRI_getDataFromName()
+ *
+ * @return string HTML code for the editor.
+ */
+function PMA_TRI_getEditorForm($mode, $item)
+{
+    global $db, $table, $event_manipulations, $action_timings;
+
+    // Escape special characters
+    $need_escape = array(
+                       'item_original_name',
+                       'item_name',
+                       'item_definition',
+                       'item_definer'
+                   );
+    foreach ($need_escape as $key => $index) {
+        $item[$index] = htmlentities($item[$index], ENT_QUOTES, 'UTF-8');
+    }
+    $original_data = '';
+    if ($mode == 'edit') {
+        $original_data = "<input name='item_original_name' "
+                       . "type='hidden' value='{$item['item_original_name']}'/>\n";
+    }
+    $query  = "SELECT `TABLE_NAME` FROM `INFORMATION_SCHEMA`.`TABLES` ";
+    $query .= "WHERE `TABLE_SCHEMA`='" . PMA_Util::sqlAddSlashes($db) . "' ";
+    $query .= "AND `TABLE_TYPE`='BASE TABLE'";
+    $tables = PMA_DBI_fetch_result($query);
+
+    // Create the output
+    $retval  = "";
+    $retval .= "<!-- START " . strtoupper($mode) . " TRIGGER FORM -->\n\n";
+    $retval .= "<form class='rte_form' action='db_triggers.php' method='post'>\n";
+    $retval .= "<input name='{$mode}_item' type='hidden' value='1' />\n";
+    $retval .= $original_data;
+    $retval .= PMA_generate_common_hidden_inputs($db, $table) . "\n";
+    $retval .= "<fieldset>\n";
+    $retval .= "<legend>" . __('Details') . "</legend>\n";
+    $retval .= "<table class='rte_table' style='width: 100%'>\n";
+    $retval .= "<tr>\n";
+    $retval .= "    <td style='width: 20%;'>" . __('Trigger name') . "</td>\n";
+    $retval .= "    <td><input type='text' name='item_name' maxlength='64'\n";
+    $retval .= "               value='{$item['item_name']}' /></td>\n";
+    $retval .= "</tr>\n";
+    $retval .= "<tr>\n";
+    $retval .= "    <td>" . __('Table') . "</td>\n";
+    $retval .= "    <td>\n";
+    $retval .= "        <select name='item_table'>\n";
+    foreach ($tables as $key => $value) {
+        $selected = "";
+        if ($mode == 'add' && $value == $table) {
+            $selected = " selected='selected'";
+        } else if ($mode == 'edit' && $value == $item['item_table']) {
+            $selected = " selected='selected'";
+        }
+        $retval .= "<option$selected>";
+        $retval .= htmlspecialchars($value);
+        $retval .= "</option>\n";
+    }
+    $retval .= "        </select>\n";
+    $retval .= "    </td>\n";
+    $retval .= "</tr>\n";
+    $retval .= "<tr>\n";
+    $retval .= "    <td>" . _pgettext('Trigger action time', 'Time') . "</td>\n";
+    $retval .= "    <td><select name='item_timing'>\n";
+    foreach ($action_timings as $key => $value) {
+        $selected = "";
+        if (! empty($item['item_action_timing'])
+            && $item['item_action_timing'] == $value
+        ) {
+            $selected = " selected='selected'";
+        }
+        $retval .= "<option$selected>$value</option>";
+    }
+    $retval .= "    </select></td>\n";
+    $retval .= "</tr>\n";
+    $retval .= "<tr>\n";
+    $retval .= "    <td>" . __('Event') . "</td>\n";
+    $retval .= "    <td><select name='item_event'>\n";
+    foreach ($event_manipulations as $key => $value) {
+        $selected = "";
+        if (! empty($item['item_event_manipulation'])
+            && $item['item_event_manipulation'] == $value
+        ) {
+            $selected = " selected='selected'";
+        }
+        $retval .= "<option$selected>$value</option>";
+    }
+    $retval .= "    </select></td>\n";
+    $retval .= "</tr>\n";
+    $retval .= "<tr>\n";
+    $retval .= "    <td>" . __('Definition') . "</td>\n";
+    $retval .= "    <td><textarea name='item_definition' rows='15' cols='40'>";
+    $retval .= $item['item_definition'];
+    $retval .= "</textarea></td>\n";
+    $retval .= "</tr>\n";
+    $retval .= "<tr>\n";
+    $retval .= "    <td>" . __('Definer') . "</td>\n";
+    $retval .= "    <td><input type='text' name='item_definer'\n";
+    $retval .= "               value='{$item['item_definer']}' /></td>\n";
+    $retval .= "</tr>\n";
+    $retval .= "</table>\n";
+    $retval .= "</fieldset>\n";
+    if ($GLOBALS['is_ajax_request']) {
+        $retval .= "<input type='hidden' name='editor_process_{$mode}'\n";
+        $retval .= "       value='true' />\n";
+        $retval .= "<input type='hidden' name='ajax_request' value='true' />\n";
+    } else {
+        $retval .= "<fieldset class='tblFooters'>\n";
+        $retval .= "    <input type='submit' name='editor_process_{$mode}'\n";
+        $retval .= "           value='" . __('Go') . "' />\n";
+        $retval .= "</fieldset>\n";
+    }
+    $retval .= "</form>\n\n";
+    $retval .= "<!-- END " . strtoupper($mode) . " TRIGGER FORM -->\n\n";
+
+    return $retval;
+} // end PMA_TRI_getEditorForm()
+
+/**
+ * Composes the query necessary to create a trigger from an HTTP request.
+ *
+ * @return string  The CREATE TRIGGER query.
+ */
+function PMA_TRI_getQueryFromRequest()
+{
+    global $_REQUEST, $db, $errors, $action_timings, $event_manipulations;
+
+    $query = 'CREATE ';
+    if (! empty($_REQUEST['item_definer'])) {
+        if (strpos($_REQUEST['item_definer'], '@') !== false) {
+            $arr = explode('@', $_REQUEST['item_definer']);
+            $query .= 'DEFINER=' . PMA_Util::backquote($arr[0]);
+            $query .= '@' . PMA_Util::backquote($arr[1]) . ' ';
+        } else {
+            $errors[] = __('The definer must be in the "username at hostname" format');
+        }
+    }
+    $query .= 'TRIGGER ';
+    if (! empty($_REQUEST['item_name'])) {
+        $query .= PMA_Util::backquote($_REQUEST['item_name']) . ' ';
+    } else {
+        $errors[] = __('You must provide a trigger name');
+    }
+    if (! empty($_REQUEST['item_timing'])
+        && in_array($_REQUEST['item_timing'], $action_timings)
+    ) {
+        $query .= $_REQUEST['item_timing'] . ' ';
+    } else {
+        $errors[] = __('You must provide a valid timing for the trigger');
+    }
+    if (! empty($_REQUEST['item_event'])
+        && in_array($_REQUEST['item_event'], $event_manipulations)
+    ) {
+        $query .= $_REQUEST['item_event'] . ' ';
+    } else {
+        $errors[] = __('You must provide a valid event for the trigger');
+    }
+    $query .= 'ON ';
+    if (! empty($_REQUEST['item_table'])
+        && in_array($_REQUEST['item_table'], PMA_DBI_get_tables($db))
+    ) {
+        $query .= PMA_Util::backquote($_REQUEST['item_table']);
+    } else {
+        $errors[] = __('You must provide a valid table name');
+    }
+    $query .= ' FOR EACH ROW ';
+    if (! empty($_REQUEST['item_definition'])) {
+        $query .= $_REQUEST['item_definition'];
+    } else {
+        $errors[] = __('You must provide a trigger definition.');
+    }
+
+    return $query;
+} // end PMA_TRI_getQueryFromRequest()
+
+?>
diff --git a/phpmyadmin/libraries/rte/rte_words.lib.php b/phpmyadmin/libraries/rte/rte_words.lib.php
new file mode 100644
index 0000000..2aabfde
--- /dev/null
+++ b/phpmyadmin/libraries/rte/rte_words.lib.php
@@ -0,0 +1,64 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+if (! defined('PHPMYADMIN')) {
+    exit;
+}
+
+/**
+ * This function is used to retreive some language strings that are used
+ * in functionalities that are common to routines, triggers and events.
+ *
+ * @param string $index The index of the string to get
+ *
+ * @return string The requested string or an empty string, if not available
+ */
+function PMA_RTE_getWord($index)
+{
+    global $_PMA_RTE;
+
+    switch ($_PMA_RTE) {
+    case 'RTN':
+        $words = array(
+            'add'       => __('Add routine'),
+            'docu'      => 'STORED_ROUTINES',
+            'export'    => __('Export of routine %s'),
+            'human'     => __('routine'),
+            'no_create' => __('You do not have the necessary privileges to create a routine'),
+            'not_found' => __('No routine with name %1$s found in database %2$s'),
+            'nothing'   => __('There are no routines to display.'),
+            'title'     => __('Routines'),
+        );
+        break;
+    case 'TRI':
+        $words = array(
+            'add'       => __('Add trigger'),
+            'docu'      => 'TRIGGERS',
+            'export'    => __('Export of trigger %s'),
+            'human'     => __('trigger'),
+            'no_create' => __('You do not have the necessary privileges to create a trigger'),
+            'not_found' => __('No trigger with name %1$s found in database %2$s'),
+            'nothing'   => __('There are no triggers to display.'),
+            'title'     => __('Triggers'),
+        );
+        break;
+    case 'EVN':
+        $words = array(
+            'add'       => __('Add event'),
+            'docu'      => 'EVENTS',
+            'export'    => __('Export of event %s'),
+            'human'     => __('event'),
+            'no_create' => __('You do not have the necessary privileges to create an event'),
+            'not_found' => __('No event with name %1$s found in database %2$s'),
+            'nothing'   => __('There are no events to display.'),
+            'title'     => __('Events'),
+        );
+        break;
+    default:
+        $words = array();
+        break;
+    }
+
+    return isset($words[$index]) ? $words[$index] : '';
+} // end PMA_RTE_getWord()
+
+?>
diff --git a/phpmyadmin/libraries/sanitizing.lib.php b/phpmyadmin/libraries/sanitizing.lib.php
new file mode 100644
index 0000000..edfb397
--- /dev/null
+++ b/phpmyadmin/libraries/sanitizing.lib.php
@@ -0,0 +1,190 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * This is in a separate script because it's called from a number of scripts
+ *
+ * @package PhpMyAdmin
+ */
+if (! defined('PHPMYADMIN')) {
+    exit;
+}
+
+/**
+ * Checks whether given link is valid
+ *
+ * @param string $url URL to check
+ *
+ * @return boolean True if string can be used as link
+ */
+function PMA_checkLink($url)
+{
+    $valid_starts = array(
+        'http://',
+        'https://',
+        './url.php?url=http%3A%2F%2F',
+        './url.php?url=https%3A%2F%2F',
+    );
+    if (defined('PMA_SETUP')) {
+        $valid_starts[] = '?page=form&';
+        $valid_starts[] = '?page=servers&';
+    }
+    foreach ($valid_starts as $val) {
+        if (substr($url, 0, strlen($val)) == $val) {
+            return true;
+        }
+    }
+    return false;
+}
+
+/**
+ * Callback function for replacing [a at link@target] links in bb code.
+ *
+ * @param array $found Array of preg matches
+ *
+ * @return string Replaced string
+ */
+function PMA_replaceBBLink($found)
+{
+    /* Check for valid link */
+    if (! PMA_checkLink($found[1])) {
+        return $found[0];
+    }
+    /* a-z and _ allowed in target */
+    if (! empty($found[3]) && preg_match('/[^a-z_]+/i', $found[3])) {
+        return $found[0];
+    }
+
+    /* Construct target */
+    $target = '';
+    if (! empty($found[3])) {
+        $target = ' target="' . $found[3] . '"';
+    }
+
+    /* Construct url */
+    if (substr($found[1], 0, 4) == 'http') {
+        $url = PMA_linkURL($found[1]);
+    } else {
+        $url = $found[1];
+    }
+
+    return '<a href="' . $url . '"' . $target . '>';
+}
+
+/**
+ * Callback function for replacing [doc at anchor] links in bb code.
+ *
+ * @param array $found Array of preg matches
+ *
+ * @return string Replaced string
+ */
+function PMA_replaceDocLink($found)
+{
+    $anchor = $found[1];
+    if (strncmp('faq', $anchor, 3) == 0) {
+        $page = 'faq';
+    } else if (strncmp('cfg', $anchor, 3) == 0) {
+        $page = 'cfg';
+    } else {
+        /* Guess */
+        $page = 'setup';
+    }
+    $link = PMA_Util::getDocuLink($page, $anchor);
+    return '<a href="' . $link . '" target="documentation">';
+}
+
+/**
+ * Sanitizes $message, taking into account our special codes
+ * for formatting.
+ *
+ * If you want to include result in element attribute, you should escape it.
+ *
+ * Examples:
+ *
+ * <p><?php echo PMA_sanitize($foo); ?></p>
+ *
+ * <a title="<?php echo PMA_sanitize($foo, true); ?>">bar</a>
+ *
+ * @param string  $message the message
+ * @param boolean $escape  whether to escape html in result
+ * @param boolean $safe    whether string is safe (can keep < and > chars)
+ *
+ * @return string   the sanitized message
+ */
+function PMA_sanitize($message, $escape = false, $safe = false)
+{
+    if (!$safe) {
+        $message = strtr($message, array('<' => '<', '>' => '>'));
+    }
+
+    /* Interpret bb code */
+    $replace_pairs = array(
+        '[em]'      => '<em>',
+        '[/em]'     => '</em>',
+        '[strong]'  => '<strong>',
+        '[/strong]' => '</strong>',
+        '[code]'    => '<code>',
+        '[/code]'   => '</code>',
+        '[kbd]'     => '<kbd>',
+        '[/kbd]'    => '</kbd>',
+        '[br]'      => '<br />',
+        '[/a]'      => '</a>',
+        '[/doc]'      => '</a>',
+        '[sup]'     => '<sup>',
+        '[/sup]'    => '</sup>',
+         // used in common.inc.php:
+        '[conferr]' => '<iframe src="show_config_errors.php" />',
+    );
+
+    $message = strtr($message, $replace_pairs);
+
+    /* Match links in bb code ([a at url@target], where @target is options) */
+    $pattern = '/\[a@([^]"@]*)(@([^]"]*))?\]/';
+
+    /* Find and replace all links */
+    $message = preg_replace_callback($pattern, 'PMA_replaceBBLink', $message);
+
+    /* Replace documentation links */
+    $message = preg_replace_callback(
+        '/\[doc@([a-zA-Z0-9_-]+)\]/',
+        'PMA_replaceDocLink',
+        $message
+    );
+
+    /* Possibly escape result */
+    if ($escape) {
+        $message = htmlspecialchars($message);
+    }
+
+    return $message;
+}
+
+
+/**
+ * Sanitize a filename by removing anything besides legit characters
+ *
+ * Intended usecase:
+ *    When using a filename in a Content-Disposition header
+ *    the value should not contain ; or "
+ *
+ *    When exporting, avoiding generation of an unexpected double-extension file
+ *
+ * @param string  $filename    The filename
+ * @param boolean $replaceDots Whether to also replace dots 
+ *
+ * @return string  the sanitized filename
+ *
+ */
+function PMA_sanitizeFilename($filename, $replaceDots = false)
+{
+    $pattern = '/[^A-Za-z0-9_';
+    // if we don't have to replace dots
+    if (! $replaceDots) {
+        // then add the dot to the list of legit characters
+        $pattern .= '.';
+    }
+    $pattern .= '-]/';
+    $filename = preg_replace($pattern, '_', $filename);
+    return $filename;
+}
+
+?>
diff --git a/phpmyadmin/libraries/schema/Dia_Relation_Schema.class.php b/phpmyadmin/libraries/schema/Dia_Relation_Schema.class.php
new file mode 100644
index 0000000..6be71fd
--- /dev/null
+++ b/phpmyadmin/libraries/schema/Dia_Relation_Schema.class.php
@@ -0,0 +1,835 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ *
+ * @package PhpMyAdmin
+ */
+if (! defined('PHPMYADMIN')) {
+    exit;
+}
+
+require_once 'Export_Relation_Schema.class.php';
+
+/**
+ * This Class inherits the XMLwriter class and
+ * helps in developing structure of DIA Schema Export
+ *
+ * @access public
+ * @see http://php.net/manual/en/book.xmlwriter.php
+ */
+class PMA_DIA extends XMLWriter
+{
+    public $title;
+    public $author;
+    public $font;
+    public $fontSize;
+
+    /**
+     * The "PMA_DIA" constructor
+     *
+     * Upon instantiation This starts writing the Dia XML document
+     *
+     * @return void
+     * @see XMLWriter::openMemory(),XMLWriter::setIndent(),XMLWriter::startDocument()
+     */
+    function __construct()
+    {
+        $this->openMemory();
+        /*
+         * Set indenting using three spaces,
+         * so output is formatted
+         */
+
+        $this->setIndent(true);
+        $this->setIndentString('   ');
+        /*
+         * Create the XML document
+         */
+
+        $this->startDocument('1.0', 'UTF-8');
+    }
+
+    /**
+     * Starts Dia Document
+     *
+     * dia document starts by first initializing dia:diagram tag
+     * then dia:diagramdata contains all the attributes that needed
+     * to define the document, then finally a Layer starts which
+     * holds all the objects.
+     *
+     * @param string $paper        the size of the paper/document
+     * @param float  $topMargin    top margin of the paper/document in cm
+     * @param float  $bottomMargin bottom margin of the paper/document in cm
+     * @param float  $leftMargin   left margin of the paper/document in cm
+     * @param float  $rightMargin  right margin of the paper/document in cm
+     * @param string $portrait     document will be portrait or landscape
+     *
+     * @return void
+     *
+     * @access public
+     * @see XMLWriter::startElement(),XMLWriter::writeAttribute(),
+     *      XMLWriter::writeRaw()
+     */
+    function startDiaDoc($paper, $topMargin, $bottomMargin, $leftMargin,
+        $rightMargin, $portrait
+    ) {
+        if ($portrait == 'P') {
+            $isPortrait='true';
+        } else {
+            $isPortrait='false';
+        }
+        $this->startElement('dia:diagram');
+        $this->writeAttribute('xmlns:dia', 'http://www.lysator.liu.se/~alla/dia/');
+        $this->startElement('dia:diagramdata');
+        $this->writeRaw(
+            '<dia:attribute name="background">
+              <dia:color val="#ffffff"/>
+            </dia:attribute>
+            <dia:attribute name="pagebreak">
+              <dia:color val="#000099"/>
+            </dia:attribute>
+            <dia:attribute name="paper">
+              <dia:composite type="paper">
+                <dia:attribute name="name">
+                  <dia:string>#' . $paper . '#</dia:string>
+                </dia:attribute>
+                <dia:attribute name="tmargin">
+                  <dia:real val="' . $topMargin . '"/>
+                </dia:attribute>
+                <dia:attribute name="bmargin">
+                  <dia:real val="' . $bottomMargin . '"/>
+                </dia:attribute>
+                <dia:attribute name="lmargin">
+                  <dia:real val="' . $leftMargin . '"/>
+                </dia:attribute>
+                <dia:attribute name="rmargin">
+                  <dia:real val="' . $rightMargin . '"/>
+                </dia:attribute>
+                <dia:attribute name="is_portrait">
+                  <dia:boolean val="' . $isPortrait . '"/>
+                </dia:attribute>
+                <dia:attribute name="scaling">
+                  <dia:real val="1"/>
+                </dia:attribute>
+                <dia:attribute name="fitto">
+                  <dia:boolean val="false"/>
+                </dia:attribute>
+              </dia:composite>
+            </dia:attribute>
+            <dia:attribute name="grid">
+              <dia:composite type="grid">
+                <dia:attribute name="width_x">
+                  <dia:real val="1"/>
+                </dia:attribute>
+                <dia:attribute name="width_y">
+                  <dia:real val="1"/>
+                </dia:attribute>
+                <dia:attribute name="visible_x">
+                  <dia:int val="1"/>
+                </dia:attribute>
+                <dia:attribute name="visible_y">
+                  <dia:int val="1"/>
+                </dia:attribute>
+                <dia:composite type="color"/>
+              </dia:composite>
+            </dia:attribute>
+            <dia:attribute name="color">
+              <dia:color val="#d8e5e5"/>
+            </dia:attribute>
+            <dia:attribute name="guides">
+              <dia:composite type="guides">
+                <dia:attribute name="hguides"/>
+                <dia:attribute name="vguides"/>
+              </dia:composite>
+            </dia:attribute>'
+        );
+        $this->endElement();
+        $this->startElement('dia:layer');
+        $this->writeAttribute('name', 'Background');
+        $this->writeAttribute('visible', 'true');
+        $this->writeAttribute('active', 'true');
+    }
+
+    /**
+     * Ends Dia Document
+     *
+     * @return void
+     * @access public
+     * @see XMLWriter::endElement(),XMLWriter::endDocument()
+     */
+    function endDiaDoc()
+    {
+        $this->endElement();
+        $this->endDocument();
+    }
+
+    /**
+     * Output Dia Document for download
+     *
+     * @param string $fileName name of the dia document
+     *
+     * @return void
+     * @access public
+     * @see XMLWriter::flush()
+     */
+    function showOutput($fileName)
+    {
+        if (ob_get_clean()) {
+            ob_end_clean();
+        }
+        $output = $this->flush();
+        PMA_Response::getInstance()->disable();
+        PMA_downloadHeader(
+            $fileName . '.dia', 'application/x-dia-diagram', strlen($output)
+        );
+        print $output;
+    }
+}
+
+/**
+ * Table preferences/statistics
+ *
+ * This class preserves the table co-ordinates,fields
+ * and helps in drawing/generating the Tables in dia XML document.
+ *
+ * @name Table_Stats
+ * @see PMA_DIA
+ */
+class Table_Stats
+{
+    /**
+     * Defines properties
+     */
+    public $tableName;
+    public $fields = array();
+    public $x, $y;
+    public $primary = array();
+    public $tableId;
+    public $tableColor;
+
+    /**
+     * The "Table_Stats" constructor
+     *
+     * @param string  $tableName  The table name
+     * @param integer $pageNumber The current page number (from the
+     *                            $cfg['Servers'][$i]['table_coords'] table)
+     * @param boolean $showKeys   Whether to display ONLY keys or not
+     *
+     * @return void
+     *
+     * @global object    The current dia document
+     * @global array     The relations settings
+     * @global string    The current db name
+     *
+     * @see PMA_DIA
+     */
+    function __construct($tableName, $pageNumber, $showKeys = false)
+    {
+        global $dia, $cfgRelation, $db;
+        
+        $this->tableName = $tableName;
+        $sql = 'DESCRIBE ' . PMA_Util::backquote($tableName);
+        $result = PMA_DBI_try_query($sql, null, PMA_DBI_QUERY_STORE);
+        if (!$result || !PMA_DBI_num_rows($result)) {
+            $dia->dieSchema(
+                $pageNumber, "DIA",
+                sprintf(__('The %s table doesn\'t exist!'), $tableName)
+            );
+        }
+        /*
+         * load fields
+         * check to see if it will load all fields or only the foreign keys
+         */
+        if ($showKeys) {
+            $indexes = PMA_Index::getFromTable($this->tableName, $db);
+            $all_columns = array();
+            foreach ($indexes as $index) {
+                $all_columns = array_merge(
+                    $all_columns,
+                    array_flip(array_keys($index->getColumns()))
+                );
+            }
+            $this->fields = array_keys($all_columns);
+        } else {
+            while ($row = PMA_DBI_fetch_row($result)) {
+                $this->fields[] = $row[0];
+            }
+        }
+
+        $sql = 'SELECT x, y FROM '
+            . PMA_Util::backquote($GLOBALS['cfgRelation']['db']) . '.'
+            . PMA_Util::backquote($cfgRelation['table_coords'])
+            . ' WHERE db_name = \'' . PMA_Util::sqlAddSlashes($db) . '\''
+            . ' AND table_name = \''
+            . PMA_Util::sqlAddSlashes($tableName) . '\''
+            . ' AND pdf_page_number = ' . $pageNumber;
+        $result = PMA_queryAsControlUser($sql, false, PMA_DBI_QUERY_STORE);
+        if (! $result || ! PMA_DBI_num_rows($result)) {
+            $dia->dieSchema(
+                $pageNumber,
+                "DIA",
+                sprintf(
+                    __('Please configure the coordinates for table %s'),
+                    $tableName
+                )
+            );
+        }
+        list($this->x, $this->y) = PMA_DBI_fetch_row($result);
+        $this->x = (double) $this->x;
+        $this->y = (double) $this->y;
+        /*
+         * displayfield
+         */
+        $this->displayfield = PMA_getDisplayField($db, $tableName);
+        /*
+         * index
+         */
+        $result = PMA_DBI_query(
+            'SHOW INDEX FROM ' . PMA_Util::backquote($tableName) . ';',
+            null,
+            PMA_DBI_QUERY_STORE
+        );
+        if (PMA_DBI_num_rows($result) > 0) {
+            while ($row = PMA_DBI_fetch_assoc($result)) {
+                if ($row['Key_name'] == 'PRIMARY') {
+                    $this->primary[] = $row['Column_name'];
+                }
+            }
+        }
+        /**
+         * Every object in Dia document needs an ID to identify
+         * so, we used a static variable to keep the things unique
+         */
+        PMA_Dia_Relation_Schema::$objectId += 1;
+        $this->tableId = PMA_Dia_Relation_Schema::$objectId;
+    }
+
+    /**
+     * Do draw the table
+     *
+     * Tables are generated using object type Database - Table
+     * primary fields are underlined in tables. Dia object
+     * is used to generate the XML of Dia Document. Database Table
+     * Object and their attributes are involved in the combination
+     * of displaing Database - Table on Dia Document.
+     *
+     * @param boolean $changeColor Whether to show color for tables text or not
+     * if changeColor is true then an array of $listOfColors will be used to choose
+     * the random colors for tables text we can change/add more colors to this array
+     *
+     * @return void
+     *
+     * @global object The current Dia document
+     *
+     * @access public
+     * @see PMA_DIA
+     */
+    public function tableDraw($changeColor)
+    {
+        global $dia;
+
+        if ($changeColor) {
+            $listOfColors = array(
+                'FF0000',
+                '000099',
+                '00FF00'
+            );
+            shuffle($listOfColors);
+            $this->tableColor =  '#' . $listOfColors[0] . '';
+        } else {
+            $this->tableColor = '#000000';
+        }
+
+        $factor = 0.1;
+
+        $dia->startElement('dia:object');
+        $dia->writeAttribute('type', 'Database - Table');
+        $dia->writeAttribute('version', '0');
+        $dia->writeAttribute('id', '' . $this->tableId . '');
+        $dia->writeRaw(
+            '<dia:attribute name="obj_pos">
+                <dia:point val="'
+            . ($this->x * $factor) . ',' . ($this->y * $factor) . '"/>
+            </dia:attribute>
+            <dia:attribute name="obj_bb">
+                <dia:rectangle val="'
+            .($this->x * $factor) . ',' . ($this->y * $factor) . ';9.97,9.2"/>
+            </dia:attribute>
+            <dia:attribute name="meta">
+                <dia:composite type="dict"/>
+            </dia:attribute>
+            <dia:attribute name="elem_corner">
+                <dia:point val="'
+            . ($this->x * $factor) . ',' . ($this->y * $factor) . '"/>
+            </dia:attribute>
+            <dia:attribute name="elem_width">
+                <dia:real val="5.9199999999999999"/>
+            </dia:attribute>
+            <dia:attribute name="elem_height">
+                <dia:real val="3.5"/>
+            </dia:attribute>
+            <dia:attribute name="text_colour">
+                <dia:color val="' . $this->tableColor . '"/>
+            </dia:attribute>
+            <dia:attribute name="line_colour">
+                <dia:color val="#000000"/>
+            </dia:attribute>
+            <dia:attribute name="fill_colour">
+                <dia:color val="#ffffff"/>
+            </dia:attribute>
+            <dia:attribute name="line_width">
+                <dia:real val="0.10000000000000001"/>
+            </dia:attribute>
+            <dia:attribute name="name">
+                <dia:string>#' . $this->tableName . '#</dia:string>
+            </dia:attribute>
+            <dia:attribute name="comment">
+                <dia:string>##</dia:string>
+            </dia:attribute>
+            <dia:attribute name="visible_comment">
+                <dia:boolean val="false"/>
+            </dia:attribute>
+            <dia:attribute name="tagging_comment">
+                <dia:boolean val="false"/>
+            </dia:attribute>
+            <dia:attribute name="underline_primary_key">
+                <dia:boolean val="true"/>
+            </dia:attribute>
+            <dia:attribute name="bold_primary_keys">
+                <dia:boolean val="true"/>
+            </dia:attribute>
+            <dia:attribute name="normal_font">
+                <dia:font family="monospace" style="0" name="Courier"/>
+            </dia:attribute>
+            <dia:attribute name="name_font">
+                <dia:font family="sans" style="80" name="Helvetica-Bold"/>
+            </dia:attribute>
+            <dia:attribute name="comment_font">
+                <dia:font family="sans" style="0" name="Helvetica"/>
+            </dia:attribute>
+            <dia:attribute name="normal_font_height">
+                <dia:real val="0.80000000000000004"/>
+            </dia:attribute>
+            <dia:attribute name="name_font_height">
+                <dia:real val="0.69999999999999996"/>
+            </dia:attribute>
+            <dia:attribute name="comment_font_height">
+                <dia:real val="0.69999999999999996"/>
+            </dia:attribute>'
+        );
+
+        $dia->startElement('dia:attribute');
+        $dia->writeAttribute('name', 'attributes');
+
+        foreach ($this->fields as $field) {
+            $dia->writeRaw(
+                '<dia:composite type="table_attribute">
+                    <dia:attribute name="name">
+                <dia:string>#' . $field . '#</dia:string>
+                </dia:attribute>
+                <dia:attribute name="type">
+                    <dia:string>##</dia:string>
+                </dia:attribute>
+                    <dia:attribute name="comment">
+                <dia:string>##</dia:string>
+                </dia:attribute>'
+            );
+            unset($pm);
+            $pm = 'false';
+            if (in_array($field, $this->primary)) {
+                $pm = 'true';
+            }
+            if ($field == $this->displayfield) {
+                $pm = 'false';
+            }
+            $dia->writeRaw(
+                '<dia:attribute name="primary_key">
+                    <dia:boolean val="' . $pm . '"/>
+                </dia:attribute>
+                <dia:attribute name="nullable">
+                    <dia:boolean val="false"/>
+                </dia:attribute>
+                <dia:attribute name="unique">
+                    <dia:boolean val="' . $pm . '"/>
+                </dia:attribute>
+                </dia:composite>'
+            );
+        }
+        $dia->endElement();
+        $dia->endElement();
+    }
+}
+
+/**
+ * Relation preferences/statistics
+ *
+ * This class fetches the table master and foreign fields positions
+ * and helps in generating the Table references and then connects
+ * master table's master field to foreign table's foreign key
+ * in dia XML document.
+ *
+ * @name Relation_Stats
+ * @see PMA_DIA
+ */
+class Relation_Stats
+{
+    /**
+     * Defines properties
+     */
+    public $srcConnPointsRight;
+    public $srcConnPointsLeft;
+    public $destConnPointsRight;
+    public $destConnPointsLeft;
+    public $masterTableId;
+    public $foreignTableId;
+    public $masterTablePos;
+    public $foreignTablePos;
+    public $referenceColor;
+
+    /**
+     * The "Relation_Stats" constructor
+     *
+     * @param string $master_table  The master table name
+     * @param string $master_field  The relation field in the master table
+     * @param string $foreign_table The foreign table name
+     * @param string $foreign_field The relation field in the foreign table
+     *
+     * @return void
+     *
+     * @see Relation_Stats::_getXy
+     */
+    function __construct($master_table, $master_field, $foreign_table,
+        $foreign_field
+    ) {
+        $src_pos  = $this->_getXy($master_table, $master_field);
+        $dest_pos = $this->_getXy($foreign_table, $foreign_field);
+        $this->srcConnPointsLeft = $src_pos[0];
+        $this->srcConnPointsRight = $src_pos[1];
+        $this->destConnPointsLeft = $dest_pos[0];
+        $this->destConnPointsRight = $dest_pos[1];
+        $this->masterTablePos = $src_pos[2];
+        $this->foreignTablePos = $dest_pos[2];
+        $this->masterTableId = $master_table->tableId;
+        $this->foreignTableId = $foreign_table->tableId;
+    }
+
+    /**
+     * Each Table object have connection points
+     * which is used to connect to other objects in Dia
+     * we detect the position of key in fields and
+     * then determines its left and right connection
+     * points.
+     *
+     * @param string $table  The current table name
+     * @param string $column The relation column name
+     *
+     * @return array Table right,left connection points and key position
+     *
+     * @access private
+     */
+    private function _getXy($table, $column)
+    {
+        $pos = array_search($column, $table->fields);
+        // left, right, position
+        $value = 12;
+        if ($pos != 0) {
+            return array($pos + $value + $pos, $pos + $value + $pos + 1, $pos);
+        }
+        return array($pos + $value , $pos + $value + 1, $pos);
+    }
+
+    /**
+     * Draws relation references
+     *
+     * connects master table's master field to foreign table's
+     * forein field using Dia object type Database - Reference
+     * Dia object is used to generate the XML of Dia Document.
+     * Database reference Object and their attributes are involved
+     * in the combination of displaing Database - reference on Dia Document.
+     *
+     * @param boolean $changeColor Whether to use one color per relation or not
+     * if changeColor is true then an array of $listOfColors will be used to choose
+     * the random colors for references lines. we can change/add more colors to this
+     *
+     * @return void
+     *
+     * @global object The current Dia document
+     *
+     * @access public
+     * @see PMA_PDF
+     */
+    public function relationDraw($changeColor)
+    {
+        global $dia;
+
+        PMA_Dia_Relation_Schema::$objectId += 1;
+        /*
+         * if source connection points and destination connection
+         * points are same then return it false and don't draw that
+         * relation
+         */
+        if ( $this->srcConnPointsRight == $this->destConnPointsRight) {
+            if ( $this->srcConnPointsLeft == $this->destConnPointsLeft) {
+                return false;
+            }
+        }
+
+        if ($changeColor) {
+            $listOfColors = array(
+                'FF0000',
+                '000099',
+                '00FF00'
+            );
+            shuffle($listOfColors);
+            $this->referenceColor =  '#' . $listOfColors[0] . '';
+        } else {
+            $this->referenceColor = '#000000';
+        }
+
+        $dia->writeRaw(
+            '<dia:object type="Database - Reference" version="0" id="'
+            . PMA_Dia_Relation_Schema::$objectId . '">
+            <dia:attribute name="obj_pos">
+                <dia:point val="3.27,18.9198"/>
+            </dia:attribute>
+            <dia:attribute name="obj_bb">
+                <dia:rectangle val="2.27,8.7175;17.7679,18.9198"/>
+            </dia:attribute>
+            <dia:attribute name="meta">
+                <dia:composite type="dict"/>
+            </dia:attribute>
+            <dia:attribute name="orth_points">
+                <dia:point val="3.27,18.9198"/>
+                <dia:point val="2.27,18.9198"/>
+                <dia:point val="2.27,14.1286"/>
+                <dia:point val="17.7679,14.1286"/>
+                <dia:point val="17.7679,9.3375"/>
+                <dia:point val="16.7679,9.3375"/>
+            </dia:attribute>
+            <dia:attribute name="orth_orient">
+                <dia:enum val="0"/>
+                <dia:enum val="1"/>
+                <dia:enum val="0"/>
+                <dia:enum val="1"/>
+                <dia:enum val="0"/>
+            </dia:attribute>
+            <dia:attribute name="orth_autoroute">
+                <dia:boolean val="true"/>
+            </dia:attribute>
+            <dia:attribute name="text_colour">
+                <dia:color val="#000000"/>
+            </dia:attribute>
+            <dia:attribute name="line_colour">
+                <dia:color val="' . $this->referenceColor . '"/>
+            </dia:attribute>
+            <dia:attribute name="line_width">
+                <dia:real val="0.10000000000000001"/>
+            </dia:attribute>
+            <dia:attribute name="line_style">
+                <dia:enum val="0"/>
+                <dia:real val="1"/>
+            </dia:attribute>
+            <dia:attribute name="corner_radius">
+                <dia:real val="0"/>
+            </dia:attribute>
+            <dia:attribute name="end_arrow">
+                <dia:enum val="22"/>
+            </dia:attribute>
+            <dia:attribute name="end_arrow_length">
+                <dia:real val="0.5"/>
+            </dia:attribute>
+            <dia:attribute name="end_arrow_width">
+                <dia:real val="0.5"/>
+            </dia:attribute>
+            <dia:attribute name="start_point_desc">
+                <dia:string>#1#</dia:string>
+            </dia:attribute>
+            <dia:attribute name="end_point_desc">
+                <dia:string>#n#</dia:string>
+            </dia:attribute>
+            <dia:attribute name="normal_font">
+                <dia:font family="monospace" style="0" name="Courier"/>
+            </dia:attribute>
+            <dia:attribute name="normal_font_height">
+                <dia:real val="0.59999999999999998"/>
+            </dia:attribute>
+            <dia:connections>
+                <dia:connection handle="0" to="'
+            . $this->masterTableId . '" connection="'
+            . $this->srcConnPointsRight . '"/>
+                <dia:connection handle="1" to="'
+            . $this->foreignTableId . '" connection="'
+            . $this->destConnPointsRight . '"/>
+            </dia:connections>
+            </dia:object>'
+        );
+    }
+}
+
+/**
+ * Dia Relation Schema Class
+ *
+ * Purpose of this class is to generate the Dia XML Document
+ * which is used for representing the database diagrams in Dia IDE
+ * This class uses Database Table and Reference Objects of Dia and with
+ * the combination of these objects actually helps in preparing Dia XML.
+ *
+ * Dia XML is generated by using XMLWriter php extension and this class
+ * inherits Export_Relation_Schema class has common functionality added
+ * to this class
+ *
+ * @name Dia_Relation_Schema
+ */
+class PMA_Dia_Relation_Schema extends PMA_Export_Relation_Schema
+{
+    /**
+     * Defines properties
+     */
+    private $_tables = array();
+    private $_relations = array();
+    private $_topMargin = 2.8222000598907471;
+    private $_bottomMargin = 2.8222000598907471;
+    private $_leftMargin = 2.8222000598907471;
+    private $_rightMargin = 2.8222000598907471;
+    public static $objectId = 0;
+
+    /**
+     * The "PMA_Dia_Relation_Schema" constructor
+     *
+     * Upon instantiation This outputs the Dia XML document
+     * that user can download
+     *
+     * @return void
+     * @see PMA_DIA,Table_Stats,Relation_Stats
+     */
+    function __construct()
+    {
+        global $dia,$db;
+
+        $this->setPageNumber($_POST['pdf_page_number']);
+        $this->setShowGrid(isset($_POST['show_grid']));
+        $this->setShowColor($_POST['show_color']);
+        $this->setShowKeys(isset($_POST['show_keys']));
+        $this->setOrientation(isset($_POST['orientation']));
+        $this->setPaper($_POST['paper']);
+        $this->setExportType($_POST['export_type']);
+
+        $dia = new PMA_DIA();
+        $dia->startDiaDoc(
+            $this->paper, $this->_topMargin, $this->_bottomMargin,
+            $this->_leftMargin, $this->_rightMargin, $this->orientation
+        );
+        $alltables = $this->getAllTables($db, $this->pageNumber);
+        foreach ($alltables as $table) {
+            if (! isset($this->tables[$table])) {
+                $this->_tables[$table] = new Table_Stats(
+                    $table, $this->pageNumber, $this->showKeys
+                );
+            }
+        }
+
+        $seen_a_relation = false;
+        foreach ($alltables as $one_table) {
+            $exist_rel = PMA_getForeigners($db, $one_table, '', 'both');
+            if ($exist_rel) {
+                $seen_a_relation = true;
+                foreach ($exist_rel as $master_field => $rel) {
+                    /* put the foreign table on the schema only if selected
+                     * by the user
+                     * (do not use array_search() because we would have to
+                     * to do a === false and this is not PHP3 compatible)
+                     */
+                    if (in_array($rel['foreign_table'], $alltables)) {
+                        $this->_addRelation(
+                            $one_table, $master_field, $rel['foreign_table'],
+                            $rel['foreign_field'], $this->showKeys
+                        );
+                    }
+                }
+            }
+        }
+        $this->_drawTables($this->showColor);
+
+        if ($seen_a_relation) {
+            $this->_drawRelations($this->showColor);
+        }
+        $dia->endDiaDoc();
+        $dia->showOutput($db . '-' . $this->pageNumber);
+        exit();
+    }
+
+    /**
+     * Defines relation objects
+     *
+     * @param string $masterTable  The master table name
+     * @param string $masterField  The relation field in the master table
+     * @param string $foreignTable The foreign table name
+     * @param string $foreignField The relation field in the foreign table
+     * @param bool   $showKeys     Whether to display ONLY keys or not
+     *
+     * @return void
+     *
+     * @access private
+     * @see Table_Stats::__construct(),Relation_Stats::__construct()
+     */
+    private function _addRelation($masterTable, $masterField, $foreignTable,
+        $foreignField, $showKeys
+    ) {
+        if (! isset($this->_tables[$masterTable])) {
+            $this->_tables[$masterTable] = new Table_Stats(
+                $masterTable, $this->pageNumber, $showKeys
+            );
+        }
+        if (! isset($this->_tables[$foreignTable])) {
+            $this->_tables[$foreignTable] = new Table_Stats(
+                $foreignTable, $this->pageNumber, $showKeys
+            );
+        }
+        $this->_relations[] = new Relation_Stats(
+            $this->_tables[$masterTable], $masterField,
+            $this->_tables[$foreignTable], $foreignField
+        );
+    }
+
+    /**
+     * Draws relation references
+     *
+     * connects master table's master field to
+     * foreign table's forein field using Dia object
+     * type Database - Reference
+     *
+     * @param boolean $changeColor Whether to use one color per relation or not
+     *
+     * @return void
+     *
+     * @access private
+     * @see Relation_Stats::relationDraw()
+     */
+    private function _drawRelations($changeColor)
+    {
+        foreach ($this->_relations as $relation) {
+            $relation->relationDraw($changeColor);
+        }
+    }
+
+    /**
+     * Draws tables
+     *
+     * Tables are generated using Dia object type Database - Table
+     * primary fields are underlined and bold in tables
+     *
+     * @param boolean $changeColor Whether to show color for tables text or not
+     *
+     * @return void
+     *
+     * @access private
+     * @see Table_Stats::tableDraw()
+     */
+    private function _drawTables($changeColor)
+    {
+        foreach ($this->_tables as $table) {
+            $table->tableDraw($changeColor);
+        }
+    }
+}
+?>
diff --git a/phpmyadmin/libraries/schema/Eps_Relation_Schema.class.php b/phpmyadmin/libraries/schema/Eps_Relation_Schema.class.php
new file mode 100644
index 0000000..57a91c0
--- /dev/null
+++ b/phpmyadmin/libraries/schema/Eps_Relation_Schema.class.php
@@ -0,0 +1,957 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ *
+ * @package PhpMyAdmin
+ */
+if (! defined('PHPMYADMIN')) {
+    exit;
+}
+
+require_once 'Export_Relation_Schema.class.php';
+
+/**
+ * This Class is EPS Library and
+ * helps in developing structure of EPS Schema Export
+ *
+ * @access public
+ * @see http://php.net/manual/en/book.xmlwriter.php
+ */
+
+class PMA_EPS
+{
+    public $font;
+    public $fontSize;
+    public $stringCommands;
+
+    /**
+     * The "PMA_EPS" constructor
+     *
+     * Upon instantiation This starts writing the EPS Document.
+     * %!PS-Adobe-3.0 EPSF-3.0 This is the MUST first comment to include
+     * it shows/tells that the Post Script document is purely under
+     * Document Structuring Convention [DSC] and is Compliant
+     * Encapsulated Post Script Document
+     *
+     * @return void
+     * @access public
+     */
+    function __construct()
+    {
+        $this->stringCommands = "";
+        $this->stringCommands .= "%!PS-Adobe-3.0 EPSF-3.0 \n";
+    }
+
+    /**
+     * Set document title
+     *
+     * @param string $value sets the title text
+     *
+     * @return void
+     *
+     * @access public
+     */
+    function setTitle($value)
+    {
+        $this->stringCommands .= '%%Title: ' . $value . "\n";
+    }
+
+    /**
+     * Set document author
+     *
+     * @param string $value sets the author
+     *
+     * @return void
+     *
+     * @access public
+     */
+    function setAuthor($value)
+    {
+        $this->stringCommands .= '%%Creator: ' . $value . "\n";
+    }
+
+    /**
+     * Set document creation date
+     *
+     * @param string $value sets the date
+     *
+     * @return void
+     *
+     * @access public
+     */
+    function setDate($value)
+    {
+        $this->stringCommands .= '%%CreationDate: ' . $value . "\n";
+    }
+
+    /**
+     * Set document orientation
+     *
+     * @param string $value sets the author
+     *
+     * @return void
+     *
+     * @access public
+     */
+    function setOrientation($value)
+    {
+        $this->stringCommands .= "%%PageOrder: Ascend \n";
+        if ($value == "L") {
+            $value = "Landscape";
+            $this->stringCommands .= '%%Orientation: ' . $value . "\n";
+        } else {
+            $value = "Portrait";
+            $this->stringCommands .= '%%Orientation: ' . $value . "\n";
+        }
+        $this->stringCommands .= "%%EndComments \n";
+        $this->stringCommands .= "%%Pages 1 \n";
+        $this->stringCommands .= "%%BoundingBox: 72 150 144 170 \n";
+    }
+
+    /**
+     * Set the font and size
+     *
+     * font can be set whenever needed in EPS
+     *
+     * @param string  $value sets the font name e.g Arial
+     * @param integer $size  sets the size of the font e.g 10
+     *
+     * @return void
+     *
+     * @access public
+     */
+    function setFont($value, $size)
+    {
+        $this->font = $value;
+        $this->fontSize = $size;
+        $this->stringCommands .= "/" . $value . " findfont   % Get the basic font\n";
+        $this->stringCommands .= "" . $size . " scalefont            % Scale the font to $size points\n";
+        $this->stringCommands .= "setfont                 % Make it the current font\n";
+    }
+
+    /**
+     * Get the font
+     *
+     * @return string return the font name e.g Arial
+     * @access public
+     */
+    function getFont()
+    {
+        return $this->font;
+    }
+
+    /**
+     * Get the font Size
+     *
+     * @return string return the size of the font e.g 10
+     * @access public
+     */
+    function getFontSize()
+    {
+        return $this->fontSize;
+    }
+
+    /**
+     * Draw the line
+     *
+     * drawing the lines from x,y source to x,y destination and set the
+     * width of the line. lines helps in showing relationships of tables
+     *
+     * @param integer $x_from    The x_from attribute defines the start
+     *                           left position of the element
+     * @param integer $y_from    The y_from attribute defines the start
+     *                           right position of the element
+     * @param integer $x_to      The x_to attribute defines the end
+     *                           left position of the element
+     * @param integer $y_to      The y_to attribute defines the end
+     *                           right position of the element
+     * @param integer $lineWidth Sets the width of the line e.g 2
+     *
+     * @return void
+     *
+     * @access public
+     */
+    function line($x_from = 0, $y_from = 0, $x_to = 0, $y_to = 0, $lineWidth = 0)
+    {
+        $this->stringCommands .= $lineWidth . " setlinewidth  \n";
+        $this->stringCommands .= $x_from . ' ' . $y_from  . " moveto \n";
+        $this->stringCommands .= $x_to . ' ' . $y_to  . " lineto \n";
+        $this->stringCommands .= "stroke \n";
+    }
+
+    /**
+     * Draw the rectangle
+     *
+     * drawing the rectangle from x,y source to x,y destination and set the
+     * width of the line. rectangles drawn around the text shown of fields
+     *
+     * @param integer $x_from    The x_from attribute defines the start
+                                 left position of the element
+     * @param integer $y_from    The y_from attribute defines the start
+                                 right position of the element
+     * @param integer $x_to      The x_to attribute defines the end
+                                 left position of the element
+     * @param integer $y_to      The y_to attribute defines the end
+                                 right position of the element
+     * @param integer $lineWidth Sets the width of the line e.g 2
+     *
+     * @return void
+     *
+     * @access public
+     */
+    function rect($x_from, $y_from, $x_to, $y_to, $lineWidth)
+    {
+        $this->stringCommands .= $lineWidth . " setlinewidth  \n";
+        $this->stringCommands .= "newpath \n";
+        $this->stringCommands .= $x_from . " " . $y_from  . " moveto \n";
+        $this->stringCommands .= "0 " . $y_to  . " rlineto \n";
+        $this->stringCommands .= $x_to . " 0 rlineto \n";
+        $this->stringCommands .= "0 -" . $y_to  . " rlineto \n";
+        $this->stringCommands .= "closepath \n";
+        $this->stringCommands .= "stroke \n";
+    }
+
+    /**
+     * Set the current point
+     *
+     * The moveto operator takes two numbers off the stack and treats
+     * them as x and y coordinates to which to move. The coordinates
+     * specified become the current point.
+     *
+     * @param integer $x The x attribute defines the left position of the element
+     * @param integer $y The y attribute defines the right position of the element
+     *
+     * @return void
+     *
+     * @access public
+     */
+    function moveTo($x, $y)
+    {
+        $this->stringCommands .= $x . ' ' . $y . " moveto \n";
+    }
+
+    /**
+     * Output/Display the text
+     *
+     * @param string $text The string to be displayed
+     *
+     * @return void
+     *
+     * @access public
+     */
+    function show($text)
+    {
+        $this->stringCommands .=  '(' . $text  . ") show \n";
+    }
+
+    /**
+     * Output the text at specified co-ordinates
+     *
+     * @param string  $text String to be displayed
+     * @param integer $x    X attribute defines the left position of the element
+     * @param integer $y    Y attribute defines the right position of the element
+     *
+     * @return void
+     *
+     * @access public
+     */
+    function showXY($text, $x, $y)
+    {
+        $this->moveTo($x, $y);
+        $this->show($text);
+    }
+
+    /**
+     * get width of string/text
+     *
+     * EPS text width is calcualted depending on font name
+     * and font size. It is very important to know the width of text
+     * because rectangle is drawn around it.
+     *
+     * This is a bit hardcore method. I didn't found any other better than this.
+     * if someone found better than this. would love to hear that method
+     *
+     * @param string  $text     string that width will be calculated
+     * @param integer $font     name of the font like Arial,sans-serif etc
+     * @param integer $fontSize size of font
+     *
+     * @return integer width of the text
+     *
+     * @access public
+     */
+    function getStringWidth($text,$font,$fontSize)
+    {
+        /*
+         * Start by counting the width, giving each character a modifying value
+         */
+        $count = 0;
+        $count = $count + ((strlen($text) - strlen(str_replace(array("i", "j", "l"), "", $text))) * 0.23);//ijl
+        $count = $count + ((strlen($text) - strlen(str_replace(array("f"), "", $text))) * 0.27);//f
+        $count = $count + ((strlen($text) - strlen(str_replace(array("t", "I"), "", $text))) * 0.28);//tI
+        $count = $count + ((strlen($text) - strlen(str_replace(array("r"), "", $text))) * 0.34);//r
+        $count = $count + ((strlen($text) - strlen(str_replace(array("1"), "", $text))) * 0.49);//1
+        $count = $count + ((strlen($text) - strlen(str_replace(array("c", "k", "s", "v", "x", "y", "z", "J"), "", $text))) * 0.5);//cksvxyzJ
+        $count = $count + ((strlen($text) - strlen(str_replace(array("a", "b", "d", "e", "g", "h", "n", "o", "p", "q", "u", "L", "0", "2", "3", "4", "5", "6", "7", "8", "9"), "", $text))) * 0.56);//abdeghnopquL023456789
+        $count = $count + ((strlen($text) - strlen(str_replace(array("F", "T", "Z"), "", $text))) * 0.61);//FTZ
+        $count = $count + ((strlen($text) - strlen(str_replace(array("A", "B", "E", "K", "P", "S", "V", "X", "Y"), "", $text))) * 0.67);//ABEKPSVXY
+        $count = $count + ((strlen($text) - strlen(str_replace(array("w", "C", "D", "H", "N", "R", "U"), "", $text))) * 0.73);//wCDHNRU
+        $count = $count + ((strlen($text) - strlen(str_replace(array("G", "O", "Q"), "", $text))) * 0.78);//GOQ
+        $count = $count + ((strlen($text) - strlen(str_replace(array("m", "M"), "", $text))) * 0.84);//mM
+        $count = $count + ((strlen($text) - strlen(str_replace("W", "", $text))) * .95);//W
+        $count = $count + ((strlen($text) - strlen(str_replace(" ", "", $text))) * .28);//" "
+        $text  = str_replace(" ", "", $text);//remove the " "'s
+        $count = $count + (strlen(preg_replace("/[a-z0-9]/i", "", $text)) * 0.3); //all other chrs
+
+        $modifier = 1;
+        $font = strtolower($font);
+        switch ($font) {
+        /*
+         * no modifier for arial and sans-serif
+         */
+        case 'arial':
+        case 'sans-serif':
+            break;
+        /*
+         * .92 modifer for time, serif, brushscriptstd, and californian fb
+         */
+        case 'times':
+        case 'serif':
+        case 'brushscriptstd':
+        case 'californian fb':
+            $modifier = .92;
+            break;
+        /*
+         * 1.23 modifier for broadway
+         */
+        case 'broadway':
+            $modifier = 1.23;
+            break;
+        }
+        $textWidth = $count*$fontSize;
+        return ceil($textWidth*$modifier);
+    }
+
+    /**
+     * Ends EPS Document
+     *
+     * @return void
+     * @access public
+     */
+    function endEpsDoc()
+    {
+        $this->stringCommands .= "showpage \n";
+    }
+
+    /**
+     * Output EPS Document for download
+     *
+     * @param string $fileName name of the eps document
+     *
+     * @return void
+     *
+     * @access public
+     */
+    function showOutput($fileName)
+    {
+        // if(ob_get_clean()){
+            //ob_end_clean();
+        //}
+        $output = $this->stringCommands;
+        PMA_Response::getInstance()->disable();
+        PMA_downloadHeader($fileName . '.eps', 'image/x-eps', strlen($output));
+        print $output;
+    }
+}
+
+/**
+ * Table preferences/statistics
+ *
+ * This class preserves the table co-ordinates,fields
+ * and helps in drawing/generating the Tables in EPS.
+ *
+ * @name Table_Stats
+ * @see PMA_EPS
+ */
+class Table_Stats
+{
+    /**
+     * Defines properties
+     */
+
+    private $_tableName;
+    private $_showInfo = false;
+
+    public $width = 0;
+    public $height;
+    public $fields = array();
+    public $heightCell = 0;
+    public $currentCell = 0;
+    public $x, $y;
+    public $primary = array();
+
+    /**
+     * The "Table_Stats" constructor
+     *
+     * @param string  $tableName        The table name
+     * @param string  $font             The font  name
+     * @param integer $fontSize         The font size
+     * @param integer $pageNumber       Page number
+     * @param integer &$same_wide_width The max width among tables
+     * @param boolean $showKeys         Whether to display keys or not
+     * @param boolean $showInfo         Whether to display table position or not
+     *
+     * @global object    The current eps document
+     * @global integer   The current page number (from the
+     *                     $cfg['Servers'][$i]['table_coords'] table)
+     * @global array     The relations settings
+     * @global string    The current db name
+     *
+     * @access private
+     * @see PMA_EPS, Table_Stats::Table_Stats_setWidth,
+     *      Table_Stats::Table_Stats_setHeight
+     */
+    function __construct(
+        $tableName, $font, $fontSize, $pageNumber, &$same_wide_width,
+        $showKeys = false, $showInfo = false
+    ) {
+        global $eps, $cfgRelation, $db;
+
+        $this->_tableName = $tableName;
+        $sql = 'DESCRIBE ' . PMA_Util::backquote($tableName);
+        $result = PMA_DBI_try_query($sql, null, PMA_DBI_QUERY_STORE);
+        if (! $result || ! PMA_DBI_num_rows($result)) {
+            $eps->dieSchema(
+                $pageNumber, "EPS",
+                sprintf(__('The %s table doesn\'t exist!'), $tableName)
+            );
+        }
+
+        /*
+        * load fields
+        * check to see if it will load all fields or only the foreign keys
+        */
+        if ($showKeys) {
+            $indexes = PMA_Index::getFromTable($this->_tableName, $db);
+            $all_columns = array();
+            foreach ($indexes as $index) {
+                $all_columns = array_merge(
+                    $all_columns,
+                    array_flip(array_keys($index->getColumns()))
+                );
+            }
+            $this->fields = array_keys($all_columns);
+        } else {
+            while ($row = PMA_DBI_fetch_row($result)) {
+                $this->fields[] = $row[0];
+            }
+        }
+
+        $this->_showInfo = $showInfo;
+
+        // height and width
+        $this->_setHeightTable($fontSize);
+
+        // setWidth must me after setHeight, because title
+        // can include table height which changes table width
+        $this->_setWidthTable($font, $fontSize);
+        if ($same_wide_width < $this->width) {
+            $same_wide_width = $this->width;
+        }
+
+        // x and y
+        $sql = 'SELECT x, y FROM '
+            . PMA_Util::backquote($GLOBALS['cfgRelation']['db']) . '.'
+            . PMA_Util::backquote($cfgRelation['table_coords'])
+            . ' WHERE db_name = \'' . PMA_Util::sqlAddSlashes($db) . '\''
+            . ' AND   table_name = \'' . PMA_Util::sqlAddSlashes($tableName) . '\''
+            . ' AND   pdf_page_number = ' . $pageNumber;
+        $result = PMA_queryAsControlUser($sql, false, PMA_DBI_QUERY_STORE);
+
+        if (! $result || ! PMA_DBI_num_rows($result)) {
+            $eps->dieSchema(
+                $pageNumber, "EPS",
+                sprintf(
+                    __('Please configure the coordinates for table %s'),
+                    $tableName
+                )
+            );
+        }
+        list($this->x, $this->y) = PMA_DBI_fetch_row($result);
+        $this->x = (double) $this->x;
+        $this->y = (double) $this->y;
+        // displayfield
+        $this->displayfield = PMA_getDisplayField($db, $tableName);
+        // index
+        $result = PMA_DBI_query(
+            'SHOW INDEX FROM ' . PMA_Util::backquote($tableName) . ';',
+            null, PMA_DBI_QUERY_STORE
+        );
+        if (PMA_DBI_num_rows($result) > 0) {
+            while ($row = PMA_DBI_fetch_assoc($result)) {
+                if ($row['Key_name'] == 'PRIMARY') {
+                    $this->primary[] = $row['Column_name'];
+                }
+            }
+        }
+    }
+
+    /**
+     * Returns title of the current table,
+     * title can have the dimensions/co-ordinates of the table
+     *
+     * @return string The relation/table name
+     * @access private
+     */
+    private function _getTitle()
+    {
+        return ($this->_showInfo
+            ? sprintf('%.0f', $this->width) . 'x' . sprintf('%.0f', $this->heightCell)
+            : '') . ' ' . $this->_tableName;
+    }
+
+    /**
+     * Sets the width of the table
+     *
+     * @param string  $font     The font name
+     * @param integer $fontSize The font size
+     *
+     * @global object    The current eps document
+     *
+     * @return void
+     *
+     * @access private
+     * @see PMA_EPS
+     */
+    private function _setWidthTable($font,$fontSize)
+    {
+        global $eps;
+
+        foreach ($this->fields as $field) {
+            $this->width = max(
+                $this->width,
+                $eps->getStringWidth($field, $font, $fontSize)
+            );
+        }
+        $this->width += $eps->getStringWidth('      ', $font, $fontSize);
+        /*
+         * it is unknown what value must be added, because
+         * table title is affected by the tabe width value
+         */
+        while ($this->width < $eps->getStringWidth($this->_getTitle(), $font, $fontSize)) {
+            $this->width += 7;
+        }
+    }
+
+    /**
+     * Sets the height of the table
+     *
+     * @param integer $fontSize The font size
+     *
+     * @return void
+     * @access private
+     */
+    private function _setHeightTable($fontSize)
+    {
+        $this->heightCell = $fontSize + 4;
+        $this->height = (count($this->fields) + 1) * $this->heightCell;
+    }
+
+    /**
+     * Draw the table
+     *
+     * @param boolean $showColor Whether to display color
+     *
+     * @global object The current eps document
+     *
+     * @return void
+     *
+     * @access public
+     * @see PMA_EPS,PMA_EPS::line,PMA_EPS::rect
+     */
+    public function tableDraw($showColor)
+    {
+        global $eps;
+        //echo $this->_tableName.'<br />';
+        $eps->rect($this->x, $this->y + 12, $this->width, $this->heightCell, 1);
+        $eps->showXY($this->_getTitle(), $this->x + 5, $this->y + 14);
+        foreach ($this->fields as $field) {
+            $this->currentCell += $this->heightCell;
+            $showColor    = 'none';
+            if ($showColor) {
+                if (in_array($field, $this->primary)) {
+                    $showColor = '#0c0';
+                }
+                if ($field == $this->displayfield) {
+                    $showColor = 'none';
+                }
+            }
+            $eps->rect(
+                $this->x, $this->y + 12  + $this->currentCell,
+                $this->width, $this->heightCell, 1
+            );
+            $eps->showXY($field, $this->x + 5, $this->y + 14 + $this->currentCell);
+        }
+    }
+}
+
+/**
+ * Relation preferences/statistics
+ *
+ * This class fetches the table master and foreign fields positions
+ * and helps in generating the Table references and then connects
+ * master table's master field to foreign table's foreign key
+ * in EPS document.
+ *
+ * @name Relation_Stats
+ * @see PMA_EPS
+ */
+class Relation_Stats
+{
+    /**
+     * Defines properties
+     */
+    public $xSrc, $ySrc;
+    public $srcDir ;
+    public $destDir;
+    public $xDest, $yDest;
+    public $wTick = 10;
+
+    /**
+     * The "Relation_Stats" constructor
+     *
+     * @param string $master_table  The master table name
+     * @param string $master_field  The relation field in the master table
+     * @param string $foreign_table The foreign table name
+     * @param string $foreign_field The relation field in the foreign table
+     *
+     * @see Relation_Stats::_getXy
+     */
+    function __construct($master_table, $master_field, $foreign_table, $foreign_field)
+    {
+        $src_pos  = $this->_getXy($master_table, $master_field);
+        $dest_pos = $this->_getXy($foreign_table, $foreign_field);
+        /*
+        * [0] is x-left
+        * [1] is x-right
+        * [2] is y
+        */
+        $src_left   = $src_pos[0] - $this->wTick;
+        $src_right  = $src_pos[1] + $this->wTick;
+        $dest_left  = $dest_pos[0] - $this->wTick;
+        $dest_right = $dest_pos[1] + $this->wTick;
+
+        $d1 = abs($src_left - $dest_left);
+        $d2 = abs($src_right - $dest_left);
+        $d3 = abs($src_left - $dest_right);
+        $d4 = abs($src_right - $dest_right);
+        $d  = min($d1, $d2, $d3, $d4);
+
+        if ($d == $d1) {
+            $this->xSrc    = $src_pos[0];
+            $this->srcDir  = -1;
+            $this->xDest   = $dest_pos[0];
+            $this->destDir = -1;
+        } elseif ($d == $d2) {
+            $this->xSrc    = $src_pos[1];
+            $this->srcDir  = 1;
+            $this->xDest   = $dest_pos[0];
+            $this->destDir = -1;
+        } elseif ($d == $d3) {
+            $this->xSrc    = $src_pos[0];
+            $this->srcDir  = -1;
+            $this->xDest   = $dest_pos[1];
+            $this->destDir = 1;
+        } else {
+            $this->xSrc    = $src_pos[1];
+            $this->srcDir  = 1;
+            $this->xDest   = $dest_pos[1];
+            $this->destDir = 1;
+        }
+        $this->ySrc   = $src_pos[2] + 10;
+        $this->yDest = $dest_pos[2] + 10;
+    }
+
+    /**
+     * Gets arrows coordinates
+     *
+     * @param string $table  The current table name
+     * @param string $column The relation column name
+     *
+     * @return array Arrows coordinates
+     *
+     * @access private
+     */
+    private function _getXy($table, $column)
+    {
+        $pos = array_search($column, $table->fields);
+        // x_left, x_right, y
+        return array(
+            $table->x,
+            $table->x + $table->width,
+            $table->y + ($pos + 1.5) * $table->heightCell
+        );
+    }
+
+    /**
+     * draws relation links and arrows
+     * shows foreign key relations
+     *
+     * @param boolean $changeColor Whether to use one color per relation or not
+     *
+     * @global object The current EPS document
+     *
+     * @access public
+     * @see PMA_EPS
+     *
+     * @return void
+     */
+    public function relationDraw($changeColor)
+    {
+        global $eps;
+
+        if ($changeColor) {
+            $listOfColors = array(
+                'red',
+                'grey',
+                'black',
+                'yellow',
+                'green',
+                'cyan',
+            '    orange'
+            );
+            shuffle($listOfColors);
+            $color =  $listOfColors[0];
+        } else {
+            $color = 'black';
+        }
+        // draw a line like -- to foreign field
+        $eps->line(
+            $this->xSrc,
+            $this->ySrc,
+            $this->xSrc + $this->srcDir * $this->wTick,
+            $this->ySrc,
+            1
+        );
+        // draw a line like -- to master field
+        $eps->line(
+            $this->xDest + $this->destDir * $this->wTick,
+            $this->yDest,
+            $this->xDest,
+            $this->yDest,
+            1
+        );
+        // draw a line that connects to master field line and foreign field line
+        $eps->line(
+            $this->xSrc + $this->srcDir * $this->wTick,
+            $this->ySrc,
+            $this->xDest + $this->destDir * $this->wTick,
+            $this->yDest,
+            1
+        );
+        $root2 = 2 * sqrt(2);
+        $eps->line(
+            $this->xSrc + $this->srcDir * $this->wTick * 0.75,
+            $this->ySrc,
+            $this->xSrc + $this->srcDir * (0.75 - 1 / $root2) * $this->wTick,
+            $this->ySrc + $this->wTick / $root2,
+            1
+        );
+        $eps->line(
+            $this->xSrc + $this->srcDir * $this->wTick * 0.75,
+            $this->ySrc,
+            $this->xSrc + $this->srcDir * (0.75 - 1 / $root2) * $this->wTick,
+            $this->ySrc - $this->wTick / $root2,
+            1
+        );
+        $eps->line(
+            $this->xDest + $this->destDir * $this->wTick / 2,
+            $this->yDest,
+            $this->xDest + $this->destDir * (0.5 + 1 / $root2) * $this->wTick,
+            $this->yDest + $this->wTick / $root2,
+            1
+        );
+        $eps->line(
+            $this->xDest + $this->destDir * $this->wTick / 2,
+            $this->yDest,
+            $this->xDest + $this->destDir * (0.5 + 1 / $root2) * $this->wTick,
+            $this->yDest - $this->wTick / $root2,
+            1
+        );
+    }
+}
+/*
+* end of the "Relation_Stats" class
+*/
+
+/**
+ * EPS Relation Schema Class
+ *
+ * Purpose of this class is to generate the EPS Document
+ * which is used for representing the database diagrams.
+ * This class uses post script commands and with
+ * the combination of these commands actually helps in preparing EPS Document.
+ *
+ * This class inherits Export_Relation_Schema class has common functionality added
+ * to this class
+ *
+ * @name Eps_Relation_Schema
+ */
+class PMA_Eps_Relation_Schema extends PMA_Export_Relation_Schema
+{
+    private $_tables = array();
+    private $_relations = array();
+
+    /**
+     * The "PMA_EPS_Relation_Schema" constructor
+     *
+     * Upon instantiation This starts writing the EPS document
+     * user will be prompted for download as .eps extension
+     *
+     * @return void
+     * @see PMA_EPS
+     */
+    function __construct()
+    {
+        global $eps,$db;
+
+        $this->setPageNumber($_POST['pdf_page_number']);
+        $this->setShowColor(isset($_POST['show_color']));
+        $this->setShowKeys(isset($_POST['show_keys']));
+        $this->setTableDimension(isset($_POST['show_table_dimension']));
+        $this->setAllTablesSameWidth(isset($_POST['all_tables_same_width']));
+        $this->setOrientation($_POST['orientation']);
+        $this->setExportType($_POST['export_type']);
+
+        $eps = new PMA_EPS();
+        $eps->setTitle(
+            sprintf(
+                __('Schema of the %s database - Page %s'),
+                $db,
+                $this->pageNumber
+            )
+        );
+        $eps->setAuthor('phpMyAdmin ' . PMA_VERSION);
+        $eps->setDate(date("j F Y, g:i a"));
+        $eps->setOrientation($this->orientation);
+        $eps->setFont('Verdana', '10');
+
+        $alltables = $this->getAllTables($db, $this->pageNumber);
+
+        foreach ($alltables AS $table) {
+            if (! isset($this->_tables[$table])) {
+                $this->_tables[$table] = new Table_Stats(
+                    $table, $eps->getFont(), $eps->getFontSize(), $this->pageNumber,
+                    $this->_tablewidth, $this->showKeys, $this->tableDimension
+                );
+            }
+
+            if ($this->sameWide) {
+                $this->_tables[$table]->width = $this->_tablewidth;
+            }
+        }
+
+        $seen_a_relation = false;
+        foreach ($alltables as $one_table) {
+            $exist_rel = PMA_getForeigners($db, $one_table, '', 'both');
+            if ($exist_rel) {
+                $seen_a_relation = true;
+                foreach ($exist_rel as $master_field => $rel) {
+                    /* put the foreign table on the schema only if selected
+                    * by the user
+                    * (do not use array_search() because we would have to
+                    * to do a === false and this is not PHP3 compatible)
+                    */
+                    if (in_array($rel['foreign_table'], $alltables)) {
+                        $this->_addRelation(
+                            $one_table, $eps->getFont(), $eps->getFontSize(),
+                            $master_field, $rel['foreign_table'],
+                            $rel['foreign_field'], $this->tableDimension
+                        );
+                    }
+                }
+            }
+        }
+        if ($seen_a_relation) {
+            $this->_drawRelations($this->showColor);
+        }
+
+        $this->_drawTables($this->showColor);
+        $eps->endEpsDoc();
+        $eps->showOutput($db.'-'.$this->pageNumber);
+        exit();
+    }
+
+    /**
+     * Defines relation objects
+     *
+     * @param string  $masterTable  The master table name
+     * @param string  $font         The font
+     * @param int     $fontSize     The font size
+     * @param string  $masterField  The relation field in the master table
+     * @param string  $foreignTable The foreign table name
+     * @param string  $foreignField The relation field in the foreign table
+     * @param boolean $showInfo     Whether to display table position or not
+     *
+     * @return void
+     *
+     * @access private
+     * @see _setMinMax,Table_Stats::__construct(),Relation_Stats::__construct()
+     */
+    private function _addRelation(
+        $masterTable, $font, $fontSize, $masterField,
+        $foreignTable, $foreignField, $showInfo
+    ) {
+        if (! isset($this->_tables[$masterTable])) {
+            $this->_tables[$masterTable] = new Table_Stats(
+                $masterTable, $font, $fontSize, $this->pageNumber,
+                $this->_tablewidth, false, $showInfo
+            );
+        }
+        if (! isset($this->_tables[$foreignTable])) {
+            $this->_tables[$foreignTable] = new Table_Stats(
+                $foreignTable, $font, $fontSize, $this->pageNumber,
+                $this->_tablewidth, false, $showInfo
+            );
+        }
+        $this->_relations[] = new Relation_Stats(
+            $this->_tables[$masterTable], $masterField,
+            $this->_tables[$foreignTable], $foreignField
+        );
+    }
+
+    /**
+     * Draws relation arrows and lines connects master table's master field to
+     * foreign table's forein field
+     *
+     * @param boolean $changeColor Whether to use one color per relation or not
+     *
+     * @return void
+     *
+     * @access private
+     * @see Relation_Stats::relationDraw()
+     */
+    private function _drawRelations($changeColor)
+    {
+        foreach ($this->_relations as $relation) {
+            $relation->relationDraw($changeColor);
+        }
+    }
+
+    /**
+     * Draws tables
+     *
+     * @param boolean $changeColor Whether to show color for primary fields or not
+     *
+     * @return void
+     *
+     * @access private
+     * @see Table_Stats::Table_Stats_tableDraw()
+     */
+    private function _drawTables($changeColor)
+    {
+        foreach ($this->_tables as $table) {
+            $table->tableDraw($changeColor);
+        }
+    }
+}
+?>
diff --git a/phpmyadmin/libraries/schema/Export_Relation_Schema.class.php b/phpmyadmin/libraries/schema/Export_Relation_Schema.class.php
new file mode 100644
index 0000000..27a9b40
--- /dev/null
+++ b/phpmyadmin/libraries/schema/Export_Relation_Schema.class.php
@@ -0,0 +1,244 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ *
+ * @package PhpMyAdmin
+ */
+if (! defined('PHPMYADMIN')) {
+    exit;
+}
+
+/**
+ * This class is inherited by all schema classes
+ * It contains those methods which are common in them
+ * it works like factory pattern
+ */
+class PMA_Export_Relation_Schema
+{
+    private $_pageTitle;
+    public $showGrid;
+    public $showColor;
+    public $tableDimension;
+    public $sameWide;
+    public $withDoc;
+    public $showKeys;
+    public $orientation;
+    public $paper;
+    public $pageNumber;
+
+    /**
+     * Set Page Number
+     *
+     * @param integer $value Page Number of the document to be created
+     *
+     * @return void
+     *
+     * @access public
+     */
+    public function setPageNumber($value)
+    {
+        $this->pageNumber = isset($value) ? $value : 1;
+    }
+
+    /**
+     * Set Show Grid
+     *
+     * @param boolean $value show grid of the document or not
+     *
+     * @return void
+     *
+     * @access public
+     */
+    public function setShowGrid($value)
+    {
+        $this->showGrid = (isset($value) && $value == 'on') ? 1 : 0;
+    }
+
+    /**
+     * Sets showColor
+     *
+     * @param string $value 'on' to set the the variable
+     *
+     * @return void
+     */
+    public function setShowColor($value)
+    {
+        $this->showColor = (isset($value) && $value == 'on') ? 1 : 0;
+    }
+
+    /**
+     * Set Table Dimension
+     *
+     * @param boolean $value show table co-ordinates or not
+     *
+     * @return void
+     *
+     * @access public
+     */
+    public function setTableDimension($value)
+    {
+        $this->tableDimension = (isset($value) && $value == 'on') ? 1 : 0;
+    }
+
+    /**
+     * Set same width of All Tables
+     *
+     * @param boolean $value set same width of all tables or not
+     *
+     * @return void
+     *
+     * @access public
+     */
+    public function setAllTablesSameWidth($value)
+    {
+        $this->sameWide = (isset($value) && $value == 'on') ? 1 : 0;
+    }
+
+    /**
+     * Set Data Dictionary
+     *
+     * @param boolean $value show selected database data dictionary or not
+     *
+     * @return void
+     *
+     * @access public
+     */
+    public function setWithDataDictionary($value)
+    {
+        $this->withDoc = (isset($value) && $value == 'on') ? 1 : 0;
+    }
+
+    /**
+     * Set Show only keys
+     *
+     * @param boolean $value show only keys or not
+     *
+     * @return void
+     *
+     * @access public
+     */
+    public function setShowKeys($value)
+    {
+        $this->showKeys = (isset($value) && $value == 'on') ? 1 : 0;
+    }
+
+    /**
+     * Set Orientation
+     *
+     * @param string $value Orientation will be portrait or landscape
+     *
+     * @return void
+     *
+     * @access public
+     */
+    public function setOrientation($value)
+    {
+        $this->orientation = (isset($value) && $value == 'P') ? 'P' : 'L';
+    }
+
+    /**
+     * Set type of paper
+     *
+     * @param string $value paper type can be A4 etc
+     *
+     * @return void
+     *
+     * @access public
+     */
+    public function setPaper($value)
+    {
+        $this->paper = isset($value) ? $value : 'A4';
+    }
+
+    /**
+     * Set title of the page
+     *
+     * @param string $title title of the page displayed at top of the document
+     *
+     * @return void
+     *
+     * @access public
+     */
+    public function setPageTitle($title)
+    {
+        $this->_pageTitle=$title;
+    }
+
+    /**
+     * Set type of export relational schema
+     *
+     * @param string $value can be pdf,svg,dia,eps etc
+     *
+     * @return void
+     *
+     * @access public
+     */
+    public function setExportType($value)
+    {
+        $this->exportType=$value;
+    }
+
+    /**
+     * get all tables involved or included in page
+     *
+     * @param string  $db         name of the database
+     * @param integer $pageNumber page no. whose tables will be fetched in an array
+     *
+     * @return Array an array of tables
+     *
+     * @access public
+     */
+    public function getAllTables($db, $pageNumber)
+    {
+        global $cfgRelation;
+
+        // Get All tables
+        $tab_sql = 'SELECT table_name FROM '
+            . PMA_Util::backquote($GLOBALS['cfgRelation']['db']) . '.'
+            . PMA_Util::backquote($cfgRelation['table_coords'])
+            . ' WHERE db_name = \'' . PMA_Util::sqlAddSlashes($db) . '\''
+            . ' AND pdf_page_number = ' . $pageNumber;
+
+        $tab_rs = PMA_queryAsControlUser($tab_sql, null, PMA_DBI_QUERY_STORE);
+        if (!$tab_rs || !PMA_DBI_num_rows($tab_rs) > 0) {
+            $this->dieSchema('', __('This page does not contain any tables!'));
+        }
+        while ($curr_table = @PMA_DBI_fetch_assoc($tab_rs)) {
+            $alltables[] = PMA_Util::sqlAddSlashes($curr_table['table_name']);
+        }
+        return $alltables;
+    }
+
+    /**
+     * Displays an error message
+     *
+     * @param integer $pageNumber    ID of the chosen page
+     * @param string  $type          Schema Type
+     * @param string  $error_message The error mesage
+     *
+     * @global array    the PMA configuration array
+     * @global string   the current database name
+     *
+     * @access public
+     *
+     * @return void
+     */
+    function dieSchema($pageNumber, $type = '', $error_message = '')
+    {
+        global $db;
+
+        echo "<p><strong>" . __("SCHEMA ERROR: ") .  $type . "</strong></p>" . "\n";
+        if (!empty($error_message)) {
+            $error_message = htmlspecialchars($error_message);
+        }
+        echo '<p>' . "\n";
+        echo '    ' . $error_message . "\n";
+        echo '</p>' . "\n";
+        echo '<a href="schema_edit.php?' . PMA_generate_common_url($db)
+            . '&do=selectpage&chpage=' . $pageNumber . '&action_choose=0'
+            . '">' . __('Back') . '</a>';
+        echo "\n";
+        exit;
+    }
+}
+?>
diff --git a/phpmyadmin/libraries/schema/Pdf_Relation_Schema.class.php b/phpmyadmin/libraries/schema/Pdf_Relation_Schema.class.php
new file mode 100644
index 0000000..5bd36eb
--- /dev/null
+++ b/phpmyadmin/libraries/schema/Pdf_Relation_Schema.class.php
@@ -0,0 +1,1443 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * PDF schema handling
+ *
+ * @package PhpMyAdmin
+ */
+if (! defined('PHPMYADMIN')) {
+    exit;
+}
+
+require_once 'Export_Relation_Schema.class.php';
+require_once './libraries/PDF.class.php';
+
+/**
+ * Extends the "TCPDF" class and helps
+ * in developing the structure of PDF Schema Export
+ *
+ * @access  public
+ * @package PhpMyAdmin
+ * @see     TCPDF
+ */
+class PMA_Schema_PDF extends PMA_PDF
+{
+    /**
+     * Defines properties
+     */
+    var $_xMin;
+    var $_yMin;
+    var $leftMargin = 10;
+    var $topMargin = 10;
+    var $scale;
+    var $PMA_links;
+    var $Outlines = array();
+    var $def_outlines;
+    var $widths;
+    private $_ff = PMA_PDF_FONT;
+
+    /**
+     * Sets the value for margins
+     *
+     * @param float $c_margin margin
+     *
+     * @return void
+     */
+    public function setCMargin($c_margin)
+    {
+        $this->cMargin = $c_margin;
+    }
+
+    /**
+     * Sets the scaling factor, defines minimum coordinates and margins
+     *
+     * @param float $scale      The scaling factor
+     * @param float $xMin       The minimum X coordinate
+     * @param float $yMin       The minimum Y coordinate
+     * @param float $leftMargin The left margin
+     * @param float $topMargin  The top margin
+     *
+     * @access public
+     *
+     * @return void
+     */
+    function setScale($scale = 1, $xMin = 0, $yMin = 0,
+        $leftMargin = -1, $topMargin = -1
+    ) {
+        $this->scale = $scale;
+        $this->_xMin = $xMin;
+        $this->_yMin = $yMin;
+        if ($this->leftMargin != -1) {
+            $this->leftMargin = $leftMargin;
+        }
+        if ($this->topMargin != -1) {
+            $this->topMargin = $topMargin;
+        }
+    }
+
+    /**
+     * Outputs a scaled cell
+     *
+     * @param float   $w      The cell width
+     * @param float   $h      The cell height
+     * @param string  $txt    The text to output
+     * @param mixed   $border Whether to add borders or not
+     * @param integer $ln     Where to put the cursor once the output is done
+     * @param string  $align  Align mode
+     * @param integer $fill   Whether to fill the cell with a color or not
+     * @param string  $link   Link
+     *
+     * @access public
+     *
+     * @return void
+     *
+     * @see TCPDF::Cell()
+     */
+    function cellScale($w, $h = 0, $txt = '', $border = 0, $ln = 0,
+        $align = '', $fill = 0, $link = ''
+    ) {
+        $h = $h / $this->scale;
+        $w = $w / $this->scale;
+        $this->Cell($w, $h, $txt, $border, $ln, $align, $fill, $link);
+    }
+
+    /**
+     * Draws a scaled line
+     *
+     * @param float $x1 The horizontal position of the starting point
+     * @param float $y1 The vertical position of the starting point
+     * @param float $x2 The horizontal position of the ending point
+     * @param float $y2 The vertical position of the ending point
+     *
+     * @access public
+     *
+     * @return void
+     *
+     * @see TCPDF::Line()
+     */
+    function lineScale($x1, $y1, $x2, $y2)
+    {
+        $x1 = ($x1 - $this->_xMin) / $this->scale + $this->leftMargin;
+        $y1 = ($y1 - $this->_yMin) / $this->scale + $this->topMargin;
+        $x2 = ($x2 - $this->_xMin) / $this->scale + $this->leftMargin;
+        $y2 = ($y2 - $this->_yMin) / $this->scale + $this->topMargin;
+        $this->Line($x1, $y1, $x2, $y2);
+    }
+
+    /**
+     * Sets x and y scaled positions
+     *
+     * @param float $x The x position
+     * @param float $y The y position
+     *
+     * @access public
+     *
+     * @return void
+     *
+     * @see TCPDF::SetXY()
+     */
+    function setXyScale($x, $y)
+    {
+        $x = ($x - $this->_xMin) / $this->scale + $this->leftMargin;
+        $y = ($y - $this->_yMin) / $this->scale + $this->topMargin;
+        $this->SetXY($x, $y);
+    }
+
+    /**
+     * Sets the X scaled positions
+     *
+     * @param float $x The x position
+     *
+     * @access public
+     *
+     * @return void
+     *
+     * @see TCPDF::SetX()
+     */
+    function setXScale($x)
+    {
+        $x = ($x - $this->_xMin) / $this->scale + $this->leftMargin;
+        $this->SetX($x);
+    }
+
+    /**
+     * Sets the scaled font size
+     *
+     * @param float $size The font size (in points)
+     *
+     * @access public
+     *
+     * @return void
+     *
+     * @see TCPDF::SetFontSize()
+     */
+    function setFontSizeScale($size)
+    {
+        // Set font size in points
+        $size = $size / $this->scale;
+        $this->SetFontSize($size);
+    }
+
+    /**
+     * Sets the scaled line width
+     *
+     * @param float $width The line width
+     *
+     * @access public
+     *
+     * @return void
+     *
+     * @see TCPDF::SetLineWidth()
+     */
+    function setLineWidthScale($width)
+    {
+        $width = $width / $this->scale;
+        $this->SetLineWidth($width);
+    }
+
+    /**
+     * This method is used to render the page header.
+     *
+     * @return void
+     *
+     * @see TCPDF::Header()
+     */
+    function Header()
+    {
+        // We only show this if we find something in the new pdf_pages table
+
+        // This function must be named "Header" to work with the TCPDF library
+        global $cfgRelation, $db, $pdf_page_number, $with_doc;
+        if ($with_doc) {
+            $test_query = 'SELECT * FROM '
+                . PMA_Util::backquote($GLOBALS['cfgRelation']['db']) . '.'
+                . PMA_Util::backquote($cfgRelation['pdf_pages'])
+                . ' WHERE db_name = \'' . PMA_Util::sqlAddSlashes($db) . '\''
+                . ' AND page_nr = \'' . $pdf_page_number . '\'';
+            $test_rs = PMA_queryAsControlUser($test_query);
+            $pages = @PMA_DBI_fetch_assoc($test_rs);
+            $this->SetFont($this->_ff, 'B', 14);
+            $this->Cell(0, 6, ucfirst($pages['page_descr']), 'B', 1, 'C');
+            $this->SetFont($this->_ff, '');
+            $this->Ln();
+        }
+    }
+
+    /**
+     * This function must be named "Footer" to work with the TCPDF library
+     *
+     * @return void
+     *
+     * @see PMA_PDF::Footer()
+     */
+    function Footer()
+    {
+        global $with_doc;
+        if ($with_doc) {
+            parent::Footer();
+        }
+    }
+
+    /**
+     * Sets widths
+     *
+     * @param array $w array of widths
+     *
+     * @return void
+     */
+    function SetWidths($w)
+    {
+        // column widths
+        $this->widths = $w;
+    }
+
+    /**
+     * Generates table row.
+     *
+     * @param array $data  Data for table
+     * @param array $links Links for table cells
+     *
+     * @return void
+     */
+    function Row($data, $links)
+    {
+        // line height
+        $nb = 0;
+        $data_cnt = count($data);
+        for ($i = 0;$i < $data_cnt;$i++) {
+            $nb = max($nb, $this->NbLines($this->widths[$i], $data[$i]));
+        }
+        $il = $this->FontSize;
+        $h = ($il + 1) * $nb;
+        // page break if necessary
+        $this->CheckPageBreak($h);
+        // draw the cells
+        $data_cnt = count($data);
+        for ($i = 0;$i < $data_cnt;$i++) {
+            $w = $this->widths[$i];
+            // save current position
+            $x = $this->GetX();
+            $y = $this->GetY();
+            // draw the border
+            $this->Rect($x, $y, $w, $h);
+            if (isset($links[$i])) {
+                $this->Link($x, $y, $w, $h, $links[$i]);
+            }
+            // print text
+            $this->MultiCell($w, $il + 1, $data[$i], 0, 'L');
+            // go to right side
+            $this->SetXY($x + $w, $y);
+        }
+        // go to line
+        $this->Ln($h);
+    }
+
+    /**
+     * Compute number of lines used by a multicell of width w
+     *
+     * @param int    $w   width
+     * @param string $txt text
+     *
+     * @return int
+     */
+    function NbLines($w, $txt)
+    {
+        $cw = &$this->CurrentFont['cw'];
+        if ($w == 0) {
+            $w = $this->w - $this->rMargin - $this->x;
+        }
+        $wmax = ($w-2 * $this->cMargin) * 1000 / $this->FontSize;
+        $s = str_replace("\r", '', $txt);
+        $nb = strlen($s);
+        if ($nb > 0 and $s[$nb-1] == "\n") {
+            $nb--;
+        }
+        $sep = -1;
+        $i = 0;
+        $j = 0;
+        $l = 0;
+        $nl = 1;
+        while ($i < $nb) {
+            $c = $s[$i];
+            if ($c == "\n") {
+                $i++;
+                $sep = -1;
+                $j = $i;
+                $l = 0;
+                $nl++;
+                continue;
+            }
+            if ($c == ' ') {
+                $sep = $i;
+            }
+            $l += isset($cw[ord($c)])?$cw[ord($c)]:0 ;
+            if ($l > $wmax) {
+                if ($sep == -1) {
+                    if ($i == $j) {
+                        $i++;
+                    }
+                } else {
+                    $i = $sep + 1;
+                }
+                $sep = -1;
+                $j = $i;
+                $l = 0;
+                $nl++;
+            } else {
+                $i++;
+            }
+        }
+        return $nl;
+    }
+}
+
+/**
+ * Table preferences/statistics
+ *
+ * This class preserves the table co-ordinates,fields
+ * and helps in drawing/generating the Tables in PDF document.
+ *
+ * @name    Table_Stats
+ * @package PhpMyAdmin
+ * @see     PMA_Schema_PDF
+ */
+class Table_Stats
+{
+    /**
+     * Defines properties
+     */
+    private $_tableName;
+    private $_showInfo = false;
+
+    public $nb_fiels;
+    public $width = 0;
+    public $height;
+    public $fields = array();
+    public $heightCell = 6;
+    public $x, $y;
+    public $primary = array();
+    private $_ff = PMA_PDF_FONT;
+
+    /**
+     * The "Table_Stats" constructor
+     *
+     * @param string  $tableName      The table name
+     * @param integer $fontSize       The font size
+     * @param integer $pageNumber     The current page number (from the
+     *                                $cfg['Servers'][$i]['table_coords'] table)
+     * @param integer &$sameWideWidth The max. with among tables
+     * @param boolean $showKeys       Whether to display keys or not
+     * @param boolean $showInfo       Whether to display table position or not
+     *
+     * @global object    The current PDF document
+     * @global array     The relations settings
+     * @global string    The current db name
+     *
+     * @return void
+     *
+     * @see PMA_Schema_PDF, Table_Stats::Table_Stats_setWidth,
+     *     Table_Stats::Table_Stats_setHeight
+     */
+    function __construct($tableName, $fontSize, $pageNumber, &$sameWideWidth,
+        $showKeys = false, $showInfo = false
+    ) {
+        global $pdf, $cfgRelation, $db;
+
+        $this->_tableName = $tableName;
+        $sql = 'DESCRIBE ' . PMA_Util::backquote($tableName);
+        $result = PMA_DBI_try_query($sql, null, PMA_DBI_QUERY_STORE);
+        if (! $result || ! PMA_DBI_num_rows($result)) {
+            $pdf->Error(sprintf(__('The %s table doesn\'t exist!'), $tableName));
+        }
+        // load fields
+        //check to see if it will load all fields or only the foreign keys
+        if ($showKeys) {
+            $indexes = PMA_Index::getFromTable($this->_tableName, $db);
+            $all_columns = array();
+            foreach ($indexes as $index) {
+                $all_columns = array_merge(
+                    $all_columns,
+                    array_flip(array_keys($index->getColumns()))
+                );
+            }
+            $this->fields = array_keys($all_columns);
+        } else {
+            while ($row = PMA_DBI_fetch_row($result)) {
+                $this->fields[] = $row[0];
+            }
+        }
+
+        $this->_showInfo = $showInfo;
+        $this->_setHeight();
+        /*
+         * setWidth must me after setHeight, because title
+         * can include table height which changes table width
+         */
+        $this->_setWidth($fontSize);
+        if ($sameWideWidth < $this->width) {
+            $sameWideWidth = $this->width;
+        }
+        $sql = 'SELECT x, y FROM '
+             . PMA_Util::backquote($GLOBALS['cfgRelation']['db']) . '.'
+             . PMA_Util::backquote($cfgRelation['table_coords'])
+             . ' WHERE db_name = \'' . PMA_Util::sqlAddSlashes($db) . '\''
+             . ' AND   table_name = \'' . PMA_Util::sqlAddSlashes($tableName) . '\''
+             . ' AND   pdf_page_number = ' . $pageNumber;
+        $result = PMA_queryAsControlUser($sql, false, PMA_DBI_QUERY_STORE);
+        if (! $result || ! PMA_DBI_num_rows($result)) {
+            $pdf->Error(
+                sprintf(
+                    __('Please configure the coordinates for table %s'),
+                    $tableName
+                )
+            );
+        }
+        list($this->x, $this->y) = PMA_DBI_fetch_row($result);
+        $this->x = (double) $this->x;
+        $this->y = (double) $this->y;
+        /*
+         * displayfield
+         */
+        $this->displayfield = PMA_getDisplayField($db, $tableName);
+        /*
+         * index
+         */
+        $result = PMA_DBI_query(
+            'SHOW INDEX FROM ' . PMA_Util::backquote($tableName) . ';',
+            null, PMA_DBI_QUERY_STORE
+        );
+        if (PMA_DBI_num_rows($result) > 0) {
+            while ($row = PMA_DBI_fetch_assoc($result)) {
+                if ($row['Key_name'] == 'PRIMARY') {
+                    $this->primary[] = $row['Column_name'];
+                }
+            }
+        }
+    }
+
+    /**
+     * Returns title of the current table,
+     * title can have the dimensions of the table
+     *
+     * @return string
+     */
+    private function _getTitle()
+    {
+        $ret = '';
+        if ($this->_showInfo) {
+            $ret = sprintf('%.0fx%0.f', $this->width, $this->height);
+        }
+        return $ret . ' ' . $this->_tableName;
+    }
+
+    /**
+     * Sets the width of the table
+     *
+     * @param integer $fontSize The font size
+     *
+     * @global object    The current PDF document
+     *
+     * @access private
+     *
+     * @return void
+     *
+     * @see PMA_Schema_PDF
+     */
+    private function _setWidth($fontSize)
+    {
+        global $pdf;
+
+        foreach ($this->fields as $field) {
+            $this->width = max($this->width, $pdf->GetStringWidth($field));
+        }
+        $this->width += $pdf->GetStringWidth('      ');
+        $pdf->SetFont($this->_ff, 'B', $fontSize);
+        /*
+         * it is unknown what value must be added, because
+         * table title is affected by the tabe width value
+         */
+        while ($this->width < $pdf->GetStringWidth($this->_getTitle())) {
+            $this->width += 5;
+        }
+        $pdf->SetFont($this->_ff, '', $fontSize);
+    }
+
+    /**
+     * Sets the height of the table
+     *
+     * @return void
+     *
+     * @access private
+     */
+    private function _setHeight()
+    {
+        $this->height = (count($this->fields) + 1) * $this->heightCell;
+    }
+
+    /**
+     * Do draw the table
+     *
+     * @param integer $fontSize The font size
+     * @param boolean $withDoc  Whether to include links to documentation
+     * @param boolean $setColor Whether to display color
+     *
+     * @global object The current PDF document
+     *
+     * @access public
+     *
+     * @return void
+     *
+     * @see PMA_Schema_PDF
+     */
+    public function tableDraw($fontSize, $withDoc, $setColor = 0)
+    {
+        global $pdf, $withDoc;
+
+        $pdf->setXyScale($this->x, $this->y);
+        $pdf->SetFont($this->_ff, 'B', $fontSize);
+        if ($setColor) {
+            $pdf->SetTextColor(200);
+            $pdf->SetFillColor(0, 0, 128);
+        }
+        if ($withDoc) {
+            $pdf->SetLink($pdf->PMA_links['RT'][$this->_tableName]['-'], -1);
+        } else {
+            $pdf->PMA_links['doc'][$this->_tableName]['-'] = '';
+        }
+
+        $pdf->cellScale(
+            $this->width,
+            $this->heightCell,
+            $this->_getTitle(),
+            1,
+            1,
+            'C',
+            $setColor,
+            $pdf->PMA_links['doc'][$this->_tableName]['-']
+        );
+        $pdf->setXScale($this->x);
+        $pdf->SetFont($this->_ff, '', $fontSize);
+        $pdf->SetTextColor(0);
+        $pdf->SetFillColor(255);
+
+        foreach ($this->fields as $field) {
+            if ($setColor) {
+                if (in_array($field, $this->primary)) {
+                    $pdf->SetFillColor(215, 121, 123);
+                }
+                if ($field == $this->displayfield) {
+                    $pdf->SetFillColor(142, 159, 224);
+                }
+            }
+            if ($withDoc) {
+                $pdf->SetLink($pdf->PMA_links['RT'][$this->_tableName][$field], -1);
+            } else {
+                $pdf->PMA_links['doc'][$this->_tableName][$field] = '';
+            }
+
+            $pdf->cellScale(
+                $this->width,
+                $this->heightCell,
+                ' ' . $field,
+                1,
+                1,
+                'L',
+                $setColor,
+                $pdf->PMA_links['doc'][$this->_tableName][$field]
+            );
+            $pdf->setXScale($this->x);
+            $pdf->SetFillColor(255);
+        }
+    }
+}
+
+/**
+ * Relation preferences/statistics
+ *
+ * This class fetches the table master and foreign fields positions
+ * and helps in generating the Table references and then connects
+ * master table's master field to foreign table's foreign key
+ * in PDF document.
+ *
+ * @name    Relation_Stats
+ * @package PhpMyAdmin
+ * @see     PMA_Schema_PDF::SetDrawColor, PMA_Schema_PDF::setLineWidthScale,
+ *          PMA_Schema_PDF::lineScale
+ */
+class Relation_Stats
+{
+    /**
+     * Defines properties
+     */
+    public $xSrc, $ySrc;
+    public $srcDir;
+    public $destDir;
+    public $xDest, $yDest;
+    public $wTick = 5;
+
+    /**
+     * The "Relation_Stats" constructor
+     *
+     * @param string $master_table  The master table name
+     * @param string $master_field  The relation field in the master table
+     * @param string $foreign_table The foreign table name
+     * @param string $foreign_field The relation field in the foreign table
+     *
+     * @return void
+     *
+     * @see Relation_Stats::_getXy
+     */
+    function __construct($master_table, $master_field, $foreign_table,
+        $foreign_field
+    ) {
+        $src_pos  = $this->_getXy($master_table, $master_field);
+        $dest_pos = $this->_getXy($foreign_table, $foreign_field);
+        /*
+        * [0] is x-left
+        * [1] is x-right
+        * [2] is y
+        */
+        $src_left   = $src_pos[0] - $this->wTick;
+        $src_right  = $src_pos[1] + $this->wTick;
+        $dest_left  = $dest_pos[0] - $this->wTick;
+        $dest_right = $dest_pos[1] + $this->wTick;
+
+        $d1 = abs($src_left - $dest_left);
+        $d2 = abs($src_right - $dest_left);
+        $d3 = abs($src_left - $dest_right);
+        $d4 = abs($src_right - $dest_right);
+        $d  = min($d1, $d2, $d3, $d4);
+
+        if ($d == $d1) {
+            $this->xSrc    = $src_pos[0];
+            $this->srcDir  = -1;
+            $this->xDest   = $dest_pos[0];
+            $this->destDir = -1;
+        } elseif ($d == $d2) {
+            $this->xSrc    = $src_pos[1];
+            $this->srcDir  = 1;
+            $this->xDest   = $dest_pos[0];
+            $this->destDir = -1;
+        } elseif ($d == $d3) {
+            $this->xSrc    = $src_pos[0];
+            $this->srcDir  = -1;
+            $this->xDest   = $dest_pos[1];
+            $this->destDir = 1;
+        } else {
+            $this->xSrc    = $src_pos[1];
+            $this->srcDir  = 1;
+            $this->xDest   = $dest_pos[1];
+            $this->destDir = 1;
+        }
+        $this->ySrc   = $src_pos[2];
+        $this->yDest = $dest_pos[2];
+    }
+
+    /**
+     * Gets arrows coordinates
+     *
+     * @param string $table  The current table name
+     * @param string $column The relation column name
+     *
+     * @return array Arrows coordinates
+     *
+     * @access private
+     */
+    private function _getXy($table, $column)
+    {
+        $pos = array_search($column, $table->fields);
+        // x_left, x_right, y
+        return array(
+            $table->x,
+            $table->x + $table->width,
+            $table->y + ($pos + 1.5) * $table->heightCell
+        );
+    }
+
+    /**
+     * draws relation links and arrows shows foreign key relations
+     *
+     * @param boolean $changeColor Whether to use one color per relation or not
+     * @param integer $i           The id of the link to draw
+     *
+     * @global object    The current PDF document
+     *
+     * @access public
+     *
+     * @return void
+     *
+     * @see PMA_Schema_PDF
+     */
+    public function relationDraw($changeColor, $i)
+    {
+        global $pdf;
+
+        if ($changeColor) {
+            $d = $i % 6;
+            $j = ($i - $d) / 6;
+            $j = $j % 4;
+            $j++;
+            $case = array(
+                array(1, 0, 0),
+                array(0, 1, 0),
+                array(0, 0, 1),
+                array(1, 1, 0),
+                array(1, 0, 1),
+                array(0, 1, 1)
+            );
+            list ($a, $b, $c) = $case[$d];
+            $e = (1 - ($j - 1) / 6);
+            $pdf->SetDrawColor($a * 255 * $e, $b * 255 * $e, $c * 255 * $e);
+        } else {
+            $pdf->SetDrawColor(0);
+        }
+        $pdf->setLineWidthScale(0.2);
+        $pdf->lineScale(
+            $this->xSrc,
+            $this->ySrc,
+            $this->xSrc + $this->srcDir * $this->wTick,
+            $this->ySrc
+        );
+        $pdf->lineScale(
+            $this->xDest + $this->destDir * $this->wTick,
+            $this->yDest,
+            $this->xDest,
+            $this->yDest
+        );
+        $pdf->setLineWidthScale(0.1);
+        $pdf->lineScale(
+            $this->xSrc + $this->srcDir * $this->wTick,
+            $this->ySrc,
+            $this->xDest + $this->destDir * $this->wTick,
+            $this->yDest
+        );
+        /*
+         * Draws arrows ->
+         */
+        $root2 = 2 * sqrt(2);
+        $pdf->lineScale(
+            $this->xSrc + $this->srcDir * $this->wTick * 0.75,
+            $this->ySrc,
+            $this->xSrc + $this->srcDir * (0.75 - 1 / $root2) * $this->wTick,
+            $this->ySrc + $this->wTick / $root2
+        );
+        $pdf->lineScale(
+            $this->xSrc + $this->srcDir * $this->wTick * 0.75,
+            $this->ySrc,
+            $this->xSrc + $this->srcDir * (0.75 - 1 / $root2) * $this->wTick,
+            $this->ySrc - $this->wTick / $root2
+        );
+
+        $pdf->lineScale(
+            $this->xDest + $this->destDir * $this->wTick / 2,
+            $this->yDest,
+            $this->xDest + $this->destDir * (0.5 + 1 / $root2) * $this->wTick,
+            $this->yDest + $this->wTick / $root2
+        );
+        $pdf->lineScale(
+            $this->xDest + $this->destDir * $this->wTick / 2,
+            $this->yDest,
+            $this->xDest + $this->destDir * (0.5 + 1 / $root2) * $this->wTick,
+            $this->yDest - $this->wTick / $root2
+        );
+        $pdf->SetDrawColor(0);
+    }
+}
+
+/**
+ * Pdf Relation Schema Class
+ *
+ * Purpose of this class is to generate the PDF Document. PDF is widely
+ * used format for documenting text,fonts,images and 3d vector graphics.
+ *
+ * This class inherits Export_Relation_Schema class has common functionality added
+ * to this class
+ *
+ * @name Pdf_Relation_Schema
+ * @package PhpMyAdmin
+ */
+class PMA_Pdf_Relation_Schema extends PMA_Export_Relation_Schema
+{
+    /**
+     * Defines properties
+     */
+    private $_tables = array();
+    private $_ff = PMA_PDF_FONT;
+    private $_xMax = 0;
+    private $_yMax = 0;
+    private $_scale;
+    private $_xMin = 100000;
+    private $_yMin = 100000;
+    private $_topMargin = 10;
+    private $_bottomMargin = 10;
+    private $_leftMargin = 10;
+    private $_rightMargin = 10;
+    private $_tablewidth;
+
+    /**
+     * The "PMA_Pdf_Relation_Schema" constructor
+     *
+     * @global object   The current PDF Schema document
+     * @global string   The current db name
+     * @global array    The relations settings
+     * @access private
+     * @see PMA_Schema_PDF
+     */
+    function __construct()
+    {
+        global $pdf, $db;
+
+        $this->setPageNumber($_POST['pdf_page_number']);
+        $this->setShowGrid(isset($_POST['show_grid']));
+        $this->setShowColor(isset($_POST['show_color']));
+        $this->setShowKeys(isset($_POST['show_keys']));
+        $this->setTableDimension(isset($_POST['show_table_dimension']));
+        $this->setAllTablesSameWidth(isset($_POST['all_tables_same_width']));
+        $this->setWithDataDictionary($_POST['with_doc']);
+        $this->setOrientation($_POST['orientation']);
+        $this->setPaper($_POST['paper']);
+        $this->setExportType($_POST['export_type']);
+
+         // Initializes a new document
+        $pdf = new PMA_Schema_PDF($this->orientation, 'mm', $this->paper);
+        $pdf->SetTitle(
+            sprintf(
+                __('Schema of the %s database - Page %s'),
+                $GLOBALS['db'],
+                $this->pageNumber
+            )
+        );
+        $pdf->setCMargin(0);
+        $pdf->Open();
+        $pdf->SetAutoPageBreak('auto');
+        $alltables = $this->getAllTables($db, $this->pageNumber);
+
+        if ($this->withDoc) {
+            $pdf->SetAutoPageBreak('auto', 15);
+            $pdf->setCMargin(1);
+            $this->dataDictionaryDoc($alltables);
+            $pdf->SetAutoPageBreak('auto');
+            $pdf->setCMargin(0);
+        }
+
+        $pdf->Addpage();
+
+        if ($this->withDoc) {
+            $pdf->SetLink($pdf->PMA_links['RT']['-'], -1);
+            $pdf->Bookmark(__('Relational schema'));
+            $pdf->SetAlias('{00}', $pdf->PageNo());
+            $this->_topMargin = 28;
+            $this->_bottomMargin = 28;
+        }
+
+        /* snip */
+        foreach ($alltables as $table) {
+            if (! isset($this->_tables[$table])) {
+                $this->_tables[$table] = new Table_Stats(
+                    $table,
+                    null,
+                    $this->pageNumber,
+                    $this->_tablewidth,
+                    $this->showKeys,
+                    $this->tableDimension
+                );
+            }
+            if ($this->sameWide) {
+                $this->_tables[$table]->width = $this->_tablewidth;
+            }
+            $this->_setMinMax($this->_tables[$table]);
+        }
+
+        // Defines the scale factor
+        $this->_scale = ceil(
+            max(
+                ($this->_xMax - $this->_xMin)
+                / ($pdf->getPageWidth() - $this->_rightMargin - $this->_leftMargin),
+                ($this->_yMax - $this->_yMin)
+                / ($pdf->getPageHeight() - $this->_topMargin - $this->_bottomMargin)
+            ) * 100
+        ) / 100;
+
+        $pdf->setScale(
+            $this->_scale,
+            $this->_xMin,
+            $this->_yMin,
+            $this->_leftMargin,
+            $this->_topMargin
+        );
+        // Builds and save the PDF document
+        $pdf->setLineWidthScale(0.1);
+
+        if ($this->showGrid) {
+            $pdf->SetFontSize(10);
+            $this->_strokeGrid();
+        }
+        $pdf->setFontSizeScale(14);
+        // previous logic was checking master tables and foreign tables
+        // but I think that looping on every table of the pdf page as a master
+        // and finding its foreigns is OK (then we can support innodb)
+        $seen_a_relation = false;
+        foreach ($alltables as $one_table) {
+            $exist_rel = PMA_getForeigners($db, $one_table, '', 'both');
+            if ($exist_rel) {
+                $seen_a_relation = true;
+                foreach ($exist_rel as $master_field => $rel) {
+                    // put the foreign table on the schema only if selected
+                    // by the user
+                    // (do not use array_search() because we would have to
+                    // to do a === false and this is not PHP3 compatible)
+                    if (in_array($rel['foreign_table'], $alltables)) {
+                        $this->_addRelation(
+                            $one_table,
+                            $master_field,
+                            $rel['foreign_table'],
+                            $rel['foreign_field'],
+                            $this->tableDimension
+                        );
+                    }
+                } // end while
+            } // end if
+        } // end while
+
+        if ($seen_a_relation) {
+            $this->_drawRelations($this->showColor);
+        }
+        $this->_drawTables($this->showColor);
+        $this->_showOutput($this->pageNumber);
+        exit();
+    }
+
+    /**
+     * Sets X and Y minimum and maximum for a table cell
+     *
+     * @param string $table The table name of which sets XY co-ordinates
+     *
+     * @return void
+     *
+     * @access private
+     */
+    private function _setMinMax($table)
+    {
+        $this->_xMax = max($this->_xMax, $table->x + $table->width);
+        $this->_yMax = max($this->_yMax, $table->y + $table->height);
+        $this->_xMin = min($this->_xMin, $table->x);
+        $this->_yMin = min($this->_yMin, $table->y);
+    }
+
+    /**
+     * Defines relation objects
+     *
+     * @param string  $masterTable  The master table name
+     * @param string  $masterField  The relation field in the master table
+     * @param string  $foreignTable The foreign table name
+     * @param string  $foreignField The relation field in the foreign table
+     * @param boolean $showInfo     Whether to display table position or not
+     *
+     * @access private
+     *
+     * @return void
+     *
+     * @see _setMinMax
+     */
+    private function _addRelation($masterTable, $masterField, $foreignTable,
+        $foreignField, $showInfo
+    ) {
+        if (! isset($this->_tables[$masterTable])) {
+            $this->_tables[$masterTable] = new Table_Stats(
+                $masterTable, null, $this->pageNumber,
+                $this->_tablewidth, false, $showInfo
+            );
+            $this->_setMinMax($this->_tables[$masterTable]);
+        }
+        if (! isset($this->_tables[$foreignTable])) {
+            $this->_tables[$foreignTable] = new Table_Stats(
+                $foreignTable, null, $this->pageNumber,
+                $this->_tablewidth, false, $showInfo
+            );
+            $this->_setMinMax($this->_tables[$foreignTable]);
+        }
+        $this->relations[] = new Relation_Stats(
+            $this->_tables[$masterTable], $masterField,
+            $this->_tables[$foreignTable], $foreignField
+        );
+    }
+
+    /**
+     * Draws the grid
+     *
+     * @global object  the current PMA_Schema_PDF instance
+     *
+     * @access private
+     *
+     * @return void
+     *
+     * @see PMA_Schema_PDF
+     */
+    private function _strokeGrid()
+    {
+        global $pdf;
+
+        $gridSize = 10;
+        $labelHeight = 4;
+        $labelWidth = 5;
+        if ($this->withDoc) {
+            $topSpace = 6;
+            $bottomSpace = 15;
+        } else {
+            $topSpace = 0;
+            $bottomSpace = 0;
+        }
+
+        $pdf->SetMargins(0, 0);
+        $pdf->SetDrawColor(200, 200, 200);
+        // Draws horizontal lines
+        for ($l = 0; $l <= intval(($pdf->getPageHeight() - $topSpace - $bottomSpace) / $gridSize); $l++) {
+            $pdf->line(
+                0, $l * $gridSize + $topSpace,
+                $pdf->getPageWidth(), $l * $gridSize + $topSpace
+            );
+            // Avoid duplicates
+            if ($l > 0
+                && $l <= intval(($pdf->getPageHeight() - $topSpace - $bottomSpace - $labelHeight) / $gridSize)
+            ) {
+                $pdf->SetXY(0, $l * $gridSize + $topSpace);
+                $label = (string) sprintf(
+                    '%.0f',
+                    ($l * $gridSize + $topSpace - $this->_topMargin)
+                    * $this->_scale + $this->_yMin
+                );
+                $pdf->Cell($labelWidth, $labelHeight, ' ' . $label);
+            } // end if
+        } // end for
+        // Draws vertical lines
+        for ($j = 0; $j <= intval($pdf->getPageWidth() / $gridSize); $j++) {
+            $pdf->line(
+                $j * $gridSize,
+                $topSpace,
+                $j * $gridSize,
+                $pdf->getPageHeight() - $bottomSpace
+            );
+            $pdf->SetXY($j * $gridSize, $topSpace);
+            $label = (string) sprintf(
+                '%.0f',
+                ($j * $gridSize - $this->_leftMargin) * $this->_scale + $this->_xMin
+            );
+            $pdf->Cell($labelWidth, $labelHeight, $label);
+        }
+    }
+
+    /**
+     * Draws relation arrows
+     *
+     * @param boolean $changeColor Whether to use one color per relation or not
+     *
+     * @access private
+     *
+     * @return void
+     *
+     * @see Relation_Stats::relationdraw()
+     */
+    private function _drawRelations($changeColor)
+    {
+        $i = 0;
+        foreach ($this->relations as $relation) {
+            $relation->relationDraw($changeColor, $i);
+            $i++;
+        }
+    }
+
+    /**
+     * Draws tables
+     *
+     * @param boolean $changeColor Whether to display table position or not
+     *
+     * @access private
+     *
+     * @return void
+     *
+     * @see Table_Stats::tableDraw()
+     */
+    private function _drawTables($changeColor = 0)
+    {
+        foreach ($this->_tables as $table) {
+            $table->tableDraw(null, $this->withDoc, $changeColor);
+        }
+    }
+
+    /**
+     * Ouputs the PDF document to a file
+     * or sends the output to browser
+     *
+     * @param integer $pageNumber page number
+     *
+     * @global object   The current PDF document
+     * @global string   The current database name
+     * @global integer  The current page number (from the
+     *                  $cfg['Servers'][$i]['table_coords'] table)
+     * @access private
+     *
+     * @return void
+     *
+     * @see PMA_Schema_PDF
+     */
+    private function _showOutput($pageNumber)
+    {
+        global $pdf, $cfgRelation;
+
+        // Get the name of this pdfpage to use as filename
+        $_name_sql = 'SELECT page_descr FROM '
+            . PMA_Util::backquote($GLOBALS['cfgRelation']['db']) . '.'
+            . PMA_Util::backquote($cfgRelation['pdf_pages'])
+            . ' WHERE page_nr = ' . $pageNumber;
+        $_name_rs = PMA_queryAsControlUser($_name_sql);
+        if ($_name_rs) {
+            $_name_row = PMA_DBI_fetch_row($_name_rs);
+            $filename = $_name_row[0] . '.pdf';
+        }
+        if (empty($filename)) {
+            $filename = $pageNumber . '.pdf';
+        }
+        $pdf->Download($filename);
+    }
+
+    /**
+     * Generates data dictionary pages.
+     *
+     * @param bool $alltables Tables to document.
+     *
+     * @return void
+     */
+    public function dataDictionaryDoc($alltables)
+    {
+        global $db, $pdf, $orientation, $paper;
+        // TOC
+        $pdf->addpage($_POST['orientation']);
+        $pdf->Cell(0, 9, __('Table of contents'), 1, 0, 'C');
+        $pdf->Ln(15);
+        $i = 1;
+        foreach ($alltables as $table) {
+            $pdf->PMA_links['doc'][$table]['-'] = $pdf->AddLink();
+            $pdf->SetX(10);
+            // $pdf->Ln(1);
+            $pdf->Cell(
+                0, 6, __('Page number:') . ' {' . sprintf("%02d", $i) . '}', 0, 0,
+                'R', 0, $pdf->PMA_links['doc'][$table]['-']
+            );
+            $pdf->SetX(10);
+            $pdf->Cell(
+                0, 6, $i . ' ' . $table, 0, 1,
+                'L', 0, $pdf->PMA_links['doc'][$table]['-']
+            );
+            // $pdf->Ln(1);
+            $fields = PMA_DBI_get_columns($GLOBALS['db'], $table);
+            foreach ($fields as $row) {
+                $pdf->SetX(20);
+                $field_name = $row['Field'];
+                $pdf->PMA_links['doc'][$table][$field_name] = $pdf->AddLink();
+                //$pdf->Cell(
+                //    0, 6, $field_name, 0, 1,
+                //    'L', 0, $pdf->PMA_links['doc'][$table][$field_name]
+                //);
+            }
+            $i++;
+        }
+        $pdf->PMA_links['RT']['-'] = $pdf->AddLink();
+        $pdf->SetX(10);
+        $pdf->Cell(
+            0, 6, __('Page number:') . ' {00}', 0, 0,
+            'R', 0, $pdf->PMA_links['RT']['-']
+        );
+        $pdf->SetX(10);
+        $pdf->Cell(
+            0, 6, $i . ' ' . __('Relational schema'), 0, 1,
+            'L', 0, $pdf->PMA_links['RT']['-']
+        );
+        $z = 0;
+        foreach ($alltables as $table) {
+            $z++;
+            $pdf->SetAutoPageBreak(true, 15);
+            $pdf->addpage($_POST['orientation']);
+            $pdf->Bookmark($table);
+            $pdf->SetAlias('{' . sprintf("%02d", $z) . '}', $pdf->PageNo());
+            $pdf->PMA_links['RT'][$table]['-'] = $pdf->AddLink();
+            $pdf->SetLink($pdf->PMA_links['doc'][$table]['-'], -1);
+            $pdf->SetFont($this->_ff, 'B', 18);
+            $pdf->Cell(
+                0, 8, $z . ' ' . $table, 1, 1,
+                'C', 0, $pdf->PMA_links['RT'][$table]['-']
+            );
+            $pdf->SetFont($this->_ff, '', 8);
+            $pdf->ln();
+
+            $cfgRelation = PMA_getRelationsParam();
+            $comments = PMA_getComments($db, $table);
+            if ($cfgRelation['mimework']) {
+                $mime_map = PMA_getMIME($db, $table, true);
+            }
+
+            /**
+             * Gets table informations
+             */
+            $showtable    = PMA_Table::sGetStatusInfo($db, $table);
+            $show_comment = isset($showtable['Comment'])
+                ? $showtable['Comment']
+                : '';
+            $create_time  = isset($showtable['Create_time'])
+                ? PMA_Util::localisedDate(
+                    strtotime($showtable['Create_time'])
+                )
+                : '';
+            $update_time  = isset($showtable['Update_time'])
+                ? PMA_Util::localisedDate(
+                    strtotime($showtable['Update_time'])
+                )
+                : '';
+            $check_time   = isset($showtable['Check_time'])
+                ? PMA_Util::localisedDate(
+                    strtotime($showtable['Check_time'])
+                )
+                : '';
+
+            /**
+             * Gets table keys and retains them
+             */
+            $result = PMA_DBI_query(
+                'SHOW KEYS FROM ' . PMA_Util::backquote($table) . ';'
+            );
+            $primary = '';
+            $indexes = array();
+            $lastIndex = '';
+            $indexes_info = array();
+            $indexes_data = array();
+            $pk_array = array(); // will be use to emphasis prim. keys in the table
+            // view
+            while ($row = PMA_DBI_fetch_assoc($result)) {
+                // Backups the list of primary keys
+                if ($row['Key_name'] == 'PRIMARY') {
+                    $primary .= $row['Column_name'] . ', ';
+                    $pk_array[$row['Column_name']] = 1;
+                }
+                // Retains keys informations
+                if ($row['Key_name'] != $lastIndex) {
+                    $indexes[] = $row['Key_name'];
+                    $lastIndex = $row['Key_name'];
+                }
+                $indexes_info[$row['Key_name']]['Sequences'][]
+                    = $row['Seq_in_index'];
+                $indexes_info[$row['Key_name']]['Non_unique'] = $row['Non_unique'];
+                if (isset($row['Cardinality'])) {
+                    $indexes_info[$row['Key_name']]['Cardinality']
+                        = $row['Cardinality'];
+                }
+                // I don't know what does following column mean....
+                // $indexes_info[$row['Key_name']]['Packed'] = $row['Packed'];
+                $indexes_info[$row['Key_name']]['Comment'] = $row['Comment'];
+
+                $indexes_data[$row['Key_name']][$row['Seq_in_index']]['Column_name']
+                    = $row['Column_name'];
+                if (isset($row['Sub_part'])) {
+                    $indexes_data[$row['Key_name']][$row['Seq_in_index']]['Sub_part']
+                        = $row['Sub_part'];
+                }
+            } // end while
+            if ($result) {
+                PMA_DBI_free_result($result);
+            }
+
+            /**
+             * Gets fields properties
+             */
+            $columns = PMA_DBI_get_columns($db, $table);
+            // Check if we can use Relations
+            if (!empty($cfgRelation['relation'])) {
+                // Find which tables are related with the current one and write it in
+                // an array
+                $res_rel = PMA_getForeigners($db, $table);
+
+                if (count($res_rel) > 0) {
+                    $have_rel = true;
+                } else {
+                    $have_rel = false;
+                }
+            } else {
+                $have_rel = false;
+            } // end if
+
+            /**
+             * Displays the comments of the table if MySQL >= 3.23
+             */
+
+            $break = false;
+            if (! empty($show_comment)) {
+                $pdf->Cell(0, 3, __('Table comments') . ' : ' . $show_comment, 0, 1);
+                $break = true;
+            }
+
+            if (! empty($create_time)) {
+                $pdf->Cell(0, 3, __('Creation') . ': ' . $create_time, 0, 1);
+                $break = true;
+            }
+
+            if (! empty($update_time)) {
+                $pdf->Cell(0, 3, __('Last update') . ': ' . $update_time, 0, 1);
+                $break = true;
+            }
+
+            if (! empty($check_time)) {
+                $pdf->Cell(0, 3, __('Last check') . ': ' . $check_time, 0, 1);
+                $break = true;
+            }
+
+            if ($break == true) {
+                $pdf->Cell(0, 3, '', 0, 1);
+                $pdf->Ln();
+            }
+
+            $pdf->SetFont($this->_ff, 'B');
+            if (isset($orientation) && $orientation == 'L') {
+                $pdf->Cell(25, 8, __('Column'), 1, 0, 'C');
+                $pdf->Cell(20, 8, __('Type'), 1, 0, 'C');
+                $pdf->Cell(20, 8, __('Attributes'), 1, 0, 'C');
+                $pdf->Cell(10, 8, __('Null'), 1, 0, 'C');
+                $pdf->Cell(20, 8, __('Default'), 1, 0, 'C');
+                $pdf->Cell(25, 8, __('Extra'), 1, 0, 'C');
+                $pdf->Cell(45, 8, __('Links to'), 1, 0, 'C');
+
+                if ($paper == 'A4') {
+                    $comments_width = 67;
+                } else {
+                    // this is really intended for 'letter'
+                    /**
+                     * @todo find optimal width for all formats
+                     */
+                    $comments_width = 50;
+                }
+                $pdf->Cell($comments_width, 8, __('Comments'), 1, 0, 'C');
+                $pdf->Cell(45, 8, 'MIME', 1, 1, 'C');
+                $pdf->SetWidths(
+                    array(25, 20, 20, 10, 20, 25, 45, $comments_width, 45)
+                );
+            } else {
+                $pdf->Cell(20, 8, __('Column'), 1, 0, 'C');
+                $pdf->Cell(20, 8, __('Type'), 1, 0, 'C');
+                $pdf->Cell(20, 8, __('Attributes'), 1, 0, 'C');
+                $pdf->Cell(10, 8, __('Null'), 1, 0, 'C');
+                $pdf->Cell(15, 8, __('Default'), 1, 0, 'C');
+                $pdf->Cell(15, 8, __('Extra'), 1, 0, 'C');
+                $pdf->Cell(30, 8, __('Links to'), 1, 0, 'C');
+                $pdf->Cell(30, 8, __('Comments'), 1, 0, 'C');
+                $pdf->Cell(30, 8, 'MIME', 1, 1, 'C');
+                $pdf->SetWidths(array(20, 20, 20, 10, 15, 15, 30, 30, 30));
+            }
+            $pdf->SetFont($this->_ff, '');
+
+            foreach ($columns as $row) {
+                $extracted_columnspec
+                    = PMA_Util::extractColumnSpec($row['Type']);
+                $type                = $extracted_columnspec['print_type'];
+                $attribute           = $extracted_columnspec['attribute'];
+                if (! isset($row['Default'])) {
+                    if ($row['Null'] != '' && $row['Null'] != 'NO') {
+                        $row['Default'] = 'NULL';
+                    }
+                }
+                $field_name = $row['Field'];
+                // $pdf->Ln();
+                $pdf->PMA_links['RT'][$table][$field_name] = $pdf->AddLink();
+                $pdf->Bookmark($field_name, 1, -1);
+                $pdf->SetLink($pdf->PMA_links['doc'][$table][$field_name], -1);
+                $pdf_row = array(
+                    $field_name,
+                    $type,
+                    $attribute,
+                    ($row['Null'] == '' || $row['Null'] == 'NO')
+                    ? __('No')
+                    : __('Yes'),
+                    (isset($row['Default']) ? $row['Default'] : ''),
+                    $row['Extra'],
+                    (isset($res_rel[$field_name])
+                        ? $res_rel[$field_name]['foreign_table'] . ' -> ' . $res_rel[$field_name]['foreign_field']
+                        : ''),
+                    (isset($comments[$field_name])
+                        ? $comments[$field_name]
+                        : ''),
+                    (isset($mime_map) && isset($mime_map[$field_name])
+                        ? str_replace('_', '/', $mime_map[$field_name]['mimetype'])
+                        : '')
+                );
+                $links[0] = $pdf->PMA_links['RT'][$table][$field_name];
+                if (isset($res_rel[$field_name]['foreign_table'])
+                    && isset($res_rel[$field_name]['foreign_field'])
+                    && isset($pdf->PMA_links['doc'][$res_rel[$field_name]['foreign_table']][$res_rel[$field_name]['foreign_field']])
+                ) {
+                    $links[6] = $pdf->PMA_links['doc'][$res_rel[$field_name]['foreign_table']][$res_rel[$field_name]['foreign_field']];
+                } else {
+                    unset($links[6]);
+                }
+                $pdf->Row($pdf_row, $links);
+            } // end foreach
+            $pdf->SetFont($this->_ff, '', 14);
+        } //end each
+    }
+}
+?>
diff --git a/phpmyadmin/libraries/schema/Svg_Relation_Schema.class.php b/phpmyadmin/libraries/schema/Svg_Relation_Schema.class.php
new file mode 100644
index 0000000..5151029
--- /dev/null
+++ b/phpmyadmin/libraries/schema/Svg_Relation_Schema.class.php
@@ -0,0 +1,950 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ *
+ * @package PhpMyAdmin
+ */
+if (! defined('PHPMYADMIN')) {
+    exit;
+}
+
+require_once 'Export_Relation_Schema.class.php';
+
+/**
+ * This Class inherits the XMLwriter class and
+ * helps in developing structure of SVG Schema Export
+ *
+ * @access public
+ * @see http://php.net/manual/en/book.xmlwriter.php
+ */
+class PMA_SVG extends XMLWriter
+{
+    public $title;
+    public $author;
+    public $font;
+    public $fontSize;
+
+    /**
+     * The "PMA_SVG" constructor
+     *
+     * Upon instantiation This starts writing the Svg XML document
+     *
+     * @return void
+     * @see XMLWriter::openMemory(),XMLWriter::setIndent(),XMLWriter::startDocument()
+     */
+    function __construct()
+    {
+        $this->openMemory();
+        /*
+         * Set indenting using three spaces,
+         * so output is formatted
+         */
+
+        $this->setIndent(true);
+        $this->setIndentString('   ');
+        /*
+         * Create the XML document
+         */
+
+        $this->startDocument('1.0', 'UTF-8');
+        $this->startDtd(
+            'svg', '-//W3C//DTD SVG 1.1//EN',
+            'http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd'
+        );
+        $this->endDtd();
+    }
+
+    /**
+     * Set document title
+     *
+     * @param string $value sets the title text
+     *
+     * @return void
+     * @access public
+     */
+    function setTitle($value)
+    {
+        $this->title = $value;
+    }
+
+    /**
+     * Set document author
+     *
+     * @param string $value sets the author
+     *
+     * @return void
+     * @access public
+     */
+    function setAuthor($value)
+    {
+        $this->author = $value;
+    }
+
+    /**
+     * Set document font
+     *
+     * @param string $value sets the font e.g Arial, Sans-serif etc
+     *
+     * @return void
+     * @access public
+     */
+    function setFont($value)
+    {
+        $this->font = $value;
+    }
+
+    /**
+     * Get document font
+     *
+     * @return string returns the font name
+     * @access public
+     */
+    function getFont()
+    {
+        return $this->font;
+    }
+
+    /**
+     * Set document font size
+     *
+     * @param string $value sets the font size in pixels
+     *
+     * @return void
+     * @access public
+     */
+    function setFontSize($value)
+    {
+        $this->fontSize = $value;
+    }
+
+    /**
+     * Get document font size
+     *
+     * @return string returns the font size
+     * @access public
+     */
+    function getFontSize()
+    {
+        return $this->fontSize;
+    }
+
+    /**
+     * Starts Svg Document
+     *
+     * svg document starts by first initializing svg tag
+     * which contains all the attributes and namespace that needed
+     * to define the svg document
+     *
+     * @param integer $width  total width of the Svg document
+     * @param integer $height total height of the Svg document
+     *
+     * @return void
+     * @access public
+     *
+     * @see XMLWriter::startElement(),XMLWriter::writeAttribute()
+     */
+    function startSvgDoc($width,$height)
+    {
+        $this->startElement('svg');
+        $this->writeAttribute('width', $width);
+        $this->writeAttribute('height', $height);
+        $this->writeAttribute('xmlns', 'http://www.w3.org/2000/svg');
+        $this->writeAttribute('version', '1.1');
+    }
+
+    /**
+     * Ends Svg Document
+     *
+     * @return void
+     * @access public
+     * @see XMLWriter::endElement(),XMLWriter::endDocument()
+     */
+    function endSvgDoc()
+    {
+        $this->endElement();
+        $this->endDocument();
+    }
+
+    /**
+     * output Svg Document
+     *
+     * svg document prompted to the user for download
+     * Svg document saved in .svg extension and can be
+     * easily changeable by using any svg IDE
+     *
+     * @param string $fileName file name
+     *
+     * @return void
+     * @access public
+     * @see XMLWriter::startElement(),XMLWriter::writeAttribute()
+     */
+    function showOutput($fileName)
+    {
+        //ob_get_clean();
+        $output = $this->flush();
+        PMA_Response::getInstance()->disable();
+        PMA_downloadHeader($fileName . '.svg', 'image/svg+xml', strlen($output));
+        print $output;
+    }
+
+    /**
+     * Draws Svg elements
+     *
+     * SVG has some predefined shape elements like rectangle & text
+     * and other elements who have x,y co-ordinates are drawn.
+     * specify their width and height and can give styles too.
+     *
+     * @param string  $name   Svg element name
+     * @param integer $x      The x attr defines the left position of the element
+     * (e.g. x="0" places the element 0 pixels from the left of the browser window)
+     * @param integer $y      The y attribute defines the top position of the element
+     * (e.g. y="0" places the element 0 pixels from the top of the browser window)
+     * @param integer $width  The width attribute defines the width the element
+     * @param integer $height The height attribute defines the height the element
+     * @param string  $text   The text attribute defines the text the element
+     * @param string  $styles The style attribute defines the style the element
+     *  styles can be defined like CSS styles
+     *
+     * @return void
+     * @access public
+     *
+     * @see XMLWriter::startElement(), XMLWriter::writeAttribute(),
+     * XMLWriter::text(), XMLWriter::endElement()
+     */
+    function printElement($name, $x, $y, $width = '', $height = '', $text = '', $styles = '')
+    {
+        $this->startElement($name);
+        $this->writeAttribute('width', $width);
+        $this->writeAttribute('height', $height);
+        $this->writeAttribute('x', $x);
+        $this->writeAttribute('y', $y);
+        $this->writeAttribute('style', $styles);
+        if (isset($text)) {
+            $this->writeAttribute('font-family', $this->font);
+            $this->writeAttribute('font-size', $this->fontSize);
+            $this->text($text);
+        }
+        $this->endElement();
+    }
+
+    /**
+     * Draws Svg Line element
+     *
+     * Svg line element is drawn for connecting the tables.
+     * arrows are also drawn by specify its start and ending
+     * co-ordinates
+     *
+     * @param string  $name   Svg element name i.e line
+     * @param integer $x1     Defines the start of the line on the x-axis
+     * @param integer $y1     Defines the start of the line on the y-axis
+     * @param integer $x2     Defines the end of the line on the x-axis
+     * @param integer $y2     Defines the end of the line on the y-axis
+     * @param string  $styles The style attribute defines the style the element
+     *                        styles can be defined like CSS styles
+     *
+     * @return void
+     * @access public
+     *
+     * @see XMLWriter::startElement(), XMLWriter::writeAttribute(),
+     * XMLWriter::endElement()
+     */
+    function printElementLine($name,$x1,$y1,$x2,$y2,$styles)
+    {
+        $this->startElement($name);
+        $this->writeAttribute('x1', $x1);
+        $this->writeAttribute('y1', $y1);
+        $this->writeAttribute('x2', $x2);
+        $this->writeAttribute('y2', $y2);
+        $this->writeAttribute('style', $styles);
+        $this->endElement();
+    }
+
+    /**
+     * get width of string/text
+     *
+     * Svg text element width is calcualted depending on font name
+     * and font size. It is very important to know the width of text
+     * because rectangle is drawn around it.
+     *
+     * This is a bit hardcore method. I didn't found any other than this.
+     *
+     * @param string  $text     string that width will be calculated
+     * @param integer $font     name of the font like Arial,sans-serif etc
+     * @param integer $fontSize size of font
+     *
+     * @return integer width of the text
+     * @access public
+     */
+    function getStringWidth($text,$font,$fontSize)
+    {
+        /*
+         * Start by counting the width, giving each character a modifying value
+         */
+        $count = 0;
+        $count = $count + ((strlen($text) - strlen(str_replace(array("i", "j", "l"), "", $text))) * 0.23);//ijl
+        $count = $count + ((strlen($text) - strlen(str_replace(array("f"), "", $text))) * 0.27);//f
+        $count = $count + ((strlen($text) - strlen(str_replace(array("t", "I"), "", $text))) * 0.28);//tI
+        $count = $count + ((strlen($text) - strlen(str_replace(array("r"), "", $text))) * 0.34);//r
+        $count = $count + ((strlen($text) - strlen(str_replace(array("1"), "", $text))) * 0.49);//1
+        $count = $count + ((strlen($text) - strlen(str_replace(array("c", "k", "s", "v", "x", "y", "z", "J"), "", $text))) * 0.5);//cksvxyzJ
+        $count = $count + ((strlen($text) - strlen(str_replace(array("a", "b", "d", "e", "g", "h", "n", "o", "p", "q", "u", "L", "0", "2", "3", "4", "5", "6", "7", "8", "9"), "", $text))) * 0.56);//abdeghnopquL023456789
+        $count = $count + ((strlen($text) - strlen(str_replace(array("F", "T", "Z"), "", $text))) * 0.61);//FTZ
+        $count = $count + ((strlen($text) - strlen(str_replace(array("A", "B", "E", "K", "P", "S", "V", "X", "Y"), "", $text))) * 0.67);//ABEKPSVXY
+        $count = $count + ((strlen($text) - strlen(str_replace(array("w", "C", "D", "H", "N", "R", "U"), "", $text))) * 0.73);//wCDHNRU
+        $count = $count + ((strlen($text) - strlen(str_replace(array("G", "O", "Q"), "", $text))) * 0.78);//GOQ
+        $count = $count + ((strlen($text) - strlen(str_replace(array("m", "M"), "", $text))) * 0.84);//mM
+        $count = $count + ((strlen($text) - strlen(str_replace("W", "", $text))) * .95);//W
+        $count = $count + ((strlen($text) - strlen(str_replace(" ", "", $text))) * .28);//" "
+        $text  = str_replace(" ", "", $text);//remove the " "'s
+        $count = $count + (strlen(preg_replace("/[a-z0-9]/i", "", $text)) * 0.3); //all other chrs
+
+        $modifier = 1;
+        $font = strtolower($font);
+        switch ($font) {
+        /*
+         * no modifier for arial and sans-serif
+         */
+        case 'arial':
+        case 'sans-serif':
+            break;
+        /*
+         * .92 modifer for time, serif, brushscriptstd, and californian fb
+         */
+        case 'times':
+        case 'serif':
+        case 'brushscriptstd':
+        case 'californian fb':
+            $modifier = .92;
+            break;
+        /*
+         * 1.23 modifier for broadway
+         */
+        case 'broadway':
+            $modifier = 1.23;
+            break;
+        }
+        $textWidth = $count*$fontSize;
+        return ceil($textWidth*$modifier);
+    }
+}
+
+/**
+ * Table preferences/statistics
+ *
+ * This class preserves the table co-ordinates,fields
+ * and helps in drawing/generating the Tables in SVG XML document.
+ *
+ * @name Table_Stats
+ * @see PMA_SVG
+ */
+class Table_Stats
+{
+    /**
+     * Defines properties
+     */
+
+    private $_tableName;
+    private $_showInfo = false;
+
+    public $width = 0;
+    public $height;
+    public $fields = array();
+    public $heightCell = 0;
+    public $currentCell = 0;
+    public $x, $y;
+    public $primary = array();
+
+    /**
+     * The "Table_Stats" constructor
+     *
+     * @param string  $tableName        The table name
+     * @param string  $font             Font face
+     * @param integer $fontSize         The font size
+     * @param integer $pageNumber       Page number
+     * @param integer &$same_wide_width The max. with among tables
+     * @param boolean $showKeys         Whether to display keys or not
+     * @param boolean $showInfo         Whether to display table position or not
+     *
+     * @global object    The current SVG image document
+     * @global integer   The current page number (from the
+     *                   $cfg['Servers'][$i]['table_coords'] table)
+     * @global array     The relations settings
+     * @global string    The current db name
+     *
+     * @access private
+     *
+     * @see PMA_SVG, Table_Stats::Table_Stats_setWidth,
+     *       Table_Stats::Table_Stats_setHeight
+     */
+    function __construct(
+        $tableName, $font, $fontSize, $pageNumber,
+        &$same_wide_width, $showKeys = false, $showInfo = false
+    ) {
+        global $svg, $cfgRelation, $db;
+
+        $this->_tableName = $tableName;
+        $sql = 'DESCRIBE ' . PMA_Util::backquote($tableName);
+        $result = PMA_DBI_try_query($sql, null, PMA_DBI_QUERY_STORE);
+        if (! $result || ! PMA_DBI_num_rows($result)) {
+            $svg->dieSchema(
+                $pageNumber,
+                "SVG",
+                sprintf(__('The %s table doesn\'t exist!'), $tableName)
+            );
+        }
+
+        /*
+        * load fields
+        * check to see if it will load all fields or only the foreign keys
+        */
+
+        if ($showKeys) {
+            $indexes = PMA_Index::getFromTable($this->_tableName, $db);
+            $all_columns = array();
+            foreach ($indexes as $index) {
+                $all_columns = array_merge(
+                    $all_columns,
+                    array_flip(array_keys($index->getColumns()))
+                );
+            }
+            $this->fields = array_keys($all_columns);
+        } else {
+            while ($row = PMA_DBI_fetch_row($result)) {
+                $this->fields[] = $row[0];
+            }
+        }
+
+        $this->_showInfo = $showInfo;
+
+        // height and width
+        $this->_setHeightTable($fontSize);
+
+        // setWidth must me after setHeight, because title
+        // can include table height which changes table width
+        $this->_setWidthTable($font, $fontSize);
+        if ($same_wide_width < $this->width) {
+            $same_wide_width = $this->width;
+        }
+
+        // x and y
+        $sql = 'SELECT x, y FROM '
+         . PMA_Util::backquote($GLOBALS['cfgRelation']['db']) . '.'
+         . PMA_Util::backquote($cfgRelation['table_coords'])
+         . ' WHERE db_name = \'' . PMA_Util::sqlAddSlashes($db) . '\''
+         . ' AND   table_name = \'' . PMA_Util::sqlAddSlashes($tableName) . '\''
+         . ' AND   pdf_page_number = ' . $pageNumber;
+        $result = PMA_queryAsControlUser($sql, false, PMA_DBI_QUERY_STORE);
+
+        if (!$result || !PMA_DBI_num_rows($result)) {
+            $svg->dieSchema(
+                $pageNumber,
+                "SVG",
+                sprintf(
+                    __('Please configure the coordinates for table %s'),
+                    $tableName
+                )
+            );
+        }
+        list($this->x, $this->y) = PMA_DBI_fetch_row($result);
+        $this->x = (double) $this->x;
+        $this->y = (double) $this->y;
+        // displayfield
+        $this->displayfield = PMA_getDisplayField($db, $tableName);
+        // index
+        $result = PMA_DBI_query(
+            'SHOW INDEX FROM ' . PMA_Util::backquote($tableName) . ';',
+            null,
+            PMA_DBI_QUERY_STORE
+        );
+        if (PMA_DBI_num_rows($result) > 0) {
+            while ($row = PMA_DBI_fetch_assoc($result)) {
+                if ($row['Key_name'] == 'PRIMARY') {
+                    $this->primary[] = $row['Column_name'];
+                }
+            }
+        }
+    }
+
+    /**
+     * Returns title of the current table,
+     * title can have the dimensions/co-ordinates of the table
+     *
+     * @access private
+     */
+    private function _getTitle()
+    {
+        return ($this->_showInfo
+            ? sprintf('%.0f', $this->width) . 'x' . sprintf('%.0f', $this->heightCell)
+            : ''
+        ) . ' ' . $this->_tableName;
+    }
+
+    /**
+     * Sets the width of the table
+     *
+     * @param string  $font     The font size
+     * @param integer $fontSize The font size
+     *
+     * @global object    The current SVG image document
+     *
+     * @return void
+     * @access private
+     *
+     * @see PMA_SVG
+     */
+    private function _setWidthTable($font,$fontSize)
+    {
+        global $svg;
+
+        foreach ($this->fields as $field) {
+            $this->width = max(
+                $this->width,
+                $svg->getStringWidth($field, $font, $fontSize)
+            );
+        }
+        $this->width += $svg->getStringWidth('  ', $font, $fontSize);
+
+        /*
+         * it is unknown what value must be added, because
+         * table title is affected by the tabe width value
+         */
+        while ($this->width < $svg->getStringWidth($this->_getTitle(), $font, $fontSize)) {
+            $this->width += 7;
+        }
+    }
+
+    /**
+     * Sets the height of the table
+     *
+     * @param integer $fontSize font size
+     *
+     * @return void
+     * @access private
+     */
+    function _setHeightTable($fontSize)
+    {
+        $this->heightCell = $fontSize + 4;
+        $this->height = (count($this->fields) + 1) * $this->heightCell;
+    }
+
+    /**
+     * draw the table
+     *
+     * @param boolean $showColor Whether to display color
+     *
+     * @global object The current SVG image document
+     *
+     * @access public
+     * @return void
+     *
+     * @see PMA_SVG,PMA_SVG::printElement
+     */
+    public function tableDraw($showColor)
+    {
+        global $svg;
+        //echo $this->_tableName.'<br />';
+        $svg->printElement(
+            'rect', $this->x, $this->y, $this->width,
+            $this->heightCell, null, 'fill:red;stroke:black;'
+        );
+        $svg->printElement(
+            'text', $this->x + 5, $this->y+ 14, $this->width, $this->heightCell,
+            $this->_getTitle(), 'fill:none;stroke:black;'
+        );
+        foreach ($this->fields as $field) {
+            $this->currentCell += $this->heightCell;
+            $showColor    = 'none';
+            if ($showColor) {
+                if (in_array($field, $this->primary)) {
+                    $showColor = '#0c0';
+                }
+                if ($field == $this->displayfield) {
+                    $showColor = 'none';
+                }
+            }
+            $svg->printElement(
+                'rect', $this->x, $this->y + $this->currentCell, $this->width,
+                $this->heightCell, null, 'fill:'.$showColor.';stroke:black;'
+            );
+            $svg->printElement(
+                'text', $this->x + 5, $this->y + 14 + $this->currentCell,
+                $this->width, $this->heightCell, $field, 'fill:none;stroke:black;'
+            );
+        }
+    }
+}
+
+
+/**
+ * Relation preferences/statistics
+ *
+ * This class fetches the table master and foreign fields positions
+ * and helps in generating the Table references and then connects
+ * master table's master field to foreign table's foreign key
+ * in SVG XML document.
+ *
+ * @name Relation_Stats
+ * @see PMA_SVG::printElementLine
+ */
+class Relation_Stats
+{
+    /**
+     * Defines properties
+     */
+    public $xSrc, $ySrc;
+    public $srcDir ;
+    public $destDir;
+    public $xDest, $yDest;
+    public $wTick = 10;
+
+    /**
+     * The "Relation_Stats" constructor
+     *
+     * @param string $master_table  The master table name
+     * @param string $master_field  The relation field in the master table
+     * @param string $foreign_table The foreign table name
+     * @param string $foreign_field The relation field in the foreign table
+     *
+     * @return void
+     *
+     * @see Relation_Stats::_getXy
+     */
+    function __construct($master_table, $master_field, $foreign_table, $foreign_field)
+    {
+        $src_pos  = $this->_getXy($master_table, $master_field);
+        $dest_pos = $this->_getXy($foreign_table, $foreign_field);
+        /*
+        * [0] is x-left
+        * [1] is x-right
+        * [2] is y
+        */
+        $src_left   = $src_pos[0] - $this->wTick;
+        $src_right  = $src_pos[1] + $this->wTick;
+        $dest_left  = $dest_pos[0] - $this->wTick;
+        $dest_right = $dest_pos[1] + $this->wTick;
+
+        $d1 = abs($src_left - $dest_left);
+        $d2 = abs($src_right - $dest_left);
+        $d3 = abs($src_left - $dest_right);
+        $d4 = abs($src_right - $dest_right);
+        $d  = min($d1, $d2, $d3, $d4);
+
+        if ($d == $d1) {
+            $this->xSrc    = $src_pos[0];
+            $this->srcDir  = -1;
+            $this->xDest   = $dest_pos[0];
+            $this->destDir = -1;
+        } elseif ($d == $d2) {
+            $this->xSrc    = $src_pos[1];
+            $this->srcDir  = 1;
+            $this->xDest   = $dest_pos[0];
+            $this->destDir = -1;
+        } elseif ($d == $d3) {
+            $this->xSrc    = $src_pos[0];
+            $this->srcDir  = -1;
+            $this->xDest   = $dest_pos[1];
+            $this->destDir = 1;
+        } else {
+            $this->xSrc    = $src_pos[1];
+            $this->srcDir  = 1;
+            $this->xDest   = $dest_pos[1];
+            $this->destDir = 1;
+        }
+        $this->ySrc   = $src_pos[2];
+        $this->yDest = $dest_pos[2];
+    }
+
+    /**
+     * Gets arrows coordinates
+     *
+     * @param string $table  The current table name
+     * @param string $column The relation column name
+     *
+     * @return array Arrows coordinates
+     * @access private
+     */
+    function _getXy($table, $column)
+    {
+        $pos = array_search($column, $table->fields);
+        // x_left, x_right, y
+        return array(
+            $table->x,
+            $table->x + $table->width,
+            $table->y + ($pos + 1.5) * $table->heightCell
+        );
+    }
+
+    /**
+     * draws relation links and arrows shows foreign key relations
+     *
+     * @param boolean $changeColor Whether to use one color per relation or not
+     *
+     * @global object The current SVG image document
+     *
+     * @return void
+     * @access public
+     *
+     * @see PMA_SVG
+     */
+    public function relationDraw($changeColor)
+    {
+        global $svg;
+
+        if ($changeColor) {
+            $listOfColors = array(
+                'red',
+                'grey',
+                'black',
+                'yellow',
+                'green',
+                'cyan',
+            '    orange'
+            );
+            shuffle($listOfColors);
+            $color =  $listOfColors[0];
+        } else {
+            $color = 'black';
+        }
+
+        $svg->printElementLine(
+            'line', $this->xSrc, $this->ySrc,
+            $this->xSrc + $this->srcDir * $this->wTick, $this->ySrc,
+            'fill:' . $color . ';stroke:black;stroke-width:2;'
+        );
+        $svg->printElementLine(
+            'line', $this->xDest + $this->destDir * $this->wTick,
+            $this->yDest, $this->xDest, $this->yDest,
+            'fill:' . $color . ';stroke:black;stroke-width:2;'
+        );
+        $svg->printElementLine(
+            'line', $this->xSrc + $this->srcDir * $this->wTick, $this->ySrc,
+            $this->xDest + $this->destDir * $this->wTick, $this->yDest,
+            'fill:' . $color . ';stroke:' . $color . ';stroke-width:1;'
+        );
+        $root2 = 2 * sqrt(2);
+        $svg->printElementLine(
+            'line', $this->xSrc + $this->srcDir * $this->wTick * 0.75, $this->ySrc,
+            $this->xSrc + $this->srcDir * (0.75 - 1 / $root2) * $this->wTick,
+            $this->ySrc + $this->wTick / $root2,
+            'fill:' . $color . ';stroke:black;stroke-width:2;'
+        );
+        $svg->printElementLine(
+            'line', $this->xSrc + $this->srcDir * $this->wTick * 0.75, $this->ySrc,
+            $this->xSrc + $this->srcDir * (0.75 - 1 / $root2) * $this->wTick,
+            $this->ySrc - $this->wTick / $root2,
+            'fill:' . $color . ';stroke:black;stroke-width:2;'
+        );
+        $svg->printElementLine(
+            'line', $this->xDest + $this->destDir * $this->wTick / 2, $this->yDest,
+            $this->xDest + $this->destDir * (0.5 + 1 / $root2) * $this->wTick,
+            $this->yDest + $this->wTick / $root2,
+            'fill:' . $color . ';stroke:black;stroke-width:2;'
+        );
+        $svg->printElementLine(
+            'line', $this->xDest + $this->destDir * $this->wTick / 2, $this->yDest,
+            $this->xDest + $this->destDir * (0.5 + 1 / $root2) * $this->wTick,
+            $this->yDest - $this->wTick / $root2,
+            'fill:' . $color . ';stroke:black;stroke-width:2;'
+        );
+    }
+}
+/*
+* end of the "Relation_Stats" class
+*/
+
+/**
+ * Svg Relation Schema Class
+ *
+ * Purpose of this class is to generate the SVG XML Document because
+ * SVG defines the graphics in XML format which is used for representing
+ * the database diagrams as vector image. This class actually helps
+ *  in preparing SVG XML format.
+ *
+ * SVG XML is generated by using XMLWriter php extension and this class
+ * inherits Export_Relation_Schema class has common functionality added
+ * to this class
+ *
+ * @name Svg_Relation_Schema
+ */
+class PMA_Svg_Relation_Schema extends PMA_Export_Relation_Schema
+{
+
+    private $_tables = array();
+    private $_relations = array();
+    private $_xMax = 0;
+    private $_yMax = 0;
+    private $_xMin = 100000;
+    private $_yMin = 100000;
+    private $_tablewidth;
+
+    /**
+     * The "PMA_Svg_Relation_Schema" constructor
+     *
+     * Upon instantiation This starts writing the SVG XML document
+     * user will be prompted for download as .svg extension
+     *
+     * @return void
+     * @see PMA_SVG
+     */
+    function __construct()
+    {
+        global $svg,$db;
+
+        $this->setPageNumber($_POST['pdf_page_number']);
+        $this->setShowColor(isset($_POST['show_color']));
+        $this->setShowKeys(isset($_POST['show_keys']));
+        $this->setTableDimension(isset($_POST['show_table_dimension']));
+        $this->setAllTablesSameWidth(isset($_POST['all_tables_same_width']));
+        $this->setExportType($_POST['export_type']);
+
+        $svg = new PMA_SVG();
+        $svg->setTitle(
+            sprintf(
+                __('Schema of the %s database - Page %s'),
+                $db,
+                $this->pageNumber
+            )
+        );
+        $svg->SetAuthor('phpMyAdmin ' . PMA_VERSION);
+        $svg->setFont('Arial');
+        $svg->setFontSize('16px');
+        $svg->startSvgDoc('1000px', '1000px');
+        $alltables = $this->getAllTables($db, $this->pageNumber);
+
+        foreach ($alltables AS $table) {
+            if (! isset($this->_tables[$table])) {
+                $this->_tables[$table] = new Table_Stats(
+                    $table, $svg->getFont(), $svg->getFontSize(), $this->pageNumber,
+                    $this->_tablewidth, $this->showKeys, $this->tableDimension
+                );
+            }
+
+            if ($this->sameWide) {
+                $this->_tables[$table]->width = $this->_tablewidth;
+            }
+            $this->_setMinMax($this->_tables[$table]);
+        }
+        $seen_a_relation = false;
+        foreach ($alltables as $one_table) {
+            $exist_rel = PMA_getForeigners($db, $one_table, '', 'both');
+            if ($exist_rel) {
+                $seen_a_relation = true;
+                foreach ($exist_rel as $master_field => $rel) {
+                    /* put the foreign table on the schema only if selected
+                    * by the user
+                    * (do not use array_search() because we would have to
+                    * to do a === false and this is not PHP3 compatible)
+                    */
+                    if (in_array($rel['foreign_table'], $alltables)) {
+                        $this->_addRelation(
+                            $one_table, $svg->getFont(), $svg->getFontSize(),
+                            $master_field, $rel['foreign_table'],
+                            $rel['foreign_field'], $this->tableDimension
+                        );
+                    }
+                }
+            }
+        }
+        if ($seen_a_relation) {
+            $this->_drawRelations($this->showColor);
+        }
+
+        $this->_drawTables($this->showColor);
+        $svg->endSvgDoc();
+        $svg->showOutput($db.'-'.$this->pageNumber);
+        exit();
+    }
+
+    /**
+     * Sets X and Y minimum and maximum for a table cell
+     *
+     * @param string $table The table name
+     *
+     * @return void
+     * @access private
+     */
+    private function _setMinMax($table)
+    {
+        $this->_xMax = max($this->_xMax, $table->x + $table->width);
+        $this->_yMax = max($this->_yMax, $table->y + $table->height);
+        $this->_xMin = min($this->_xMin, $table->x);
+        $this->_yMin = min($this->_yMin, $table->y);
+    }
+
+    /**
+     * Defines relation objects
+     *
+     * @param string  $masterTable  The master table name
+     * @param string  $font         The font face
+     * @param int     $fontSize     Font size
+     * @param string  $masterField  The relation field in the master table
+     * @param string  $foreignTable The foreign table name
+     * @param string  $foreignField The relation field in the foreign table
+     * @param boolean $showInfo     Whether to display table position or not
+     *
+     * @access private
+     * @return void
+     *
+     * @see _setMinMax,Table_Stats::__construct(),Relation_Stats::__construct()
+     */
+    private function _addRelation(
+        $masterTable,$font,$fontSize, $masterField,
+        $foreignTable, $foreignField, $showInfo
+    ) {
+        if (! isset($this->_tables[$masterTable])) {
+            $this->_tables[$masterTable] = new Table_Stats(
+                $masterTable, $font, $fontSize, $this->pageNumber,
+                $this->_tablewidth, false, $showInfo
+            );
+            $this->_setMinMax($this->_tables[$masterTable]);
+        }
+        if (! isset($this->_tables[$foreignTable])) {
+            $this->_tables[$foreignTable] = new Table_Stats(
+                $foreignTable, $font, $fontSize, $this->pageNumber,
+                $this->_tablewidth, false, $showInfo
+            );
+            $this->_setMinMax($this->_tables[$foreignTable]);
+        }
+        $this->_relations[] = new Relation_Stats(
+            $this->_tables[$masterTable], $masterField,
+            $this->_tables[$foreignTable], $foreignField
+        );
+    }
+
+    /**
+     * Draws relation arrows and lines
+     * connects master table's master field to
+     * foreign table's forein field
+     *
+     * @param boolean $changeColor Whether to use one color per relation or not
+     *
+     * @return void
+     * @access private
+     *
+     * @see Relation_Stats::relationDraw()
+     */
+    private function _drawRelations($changeColor)
+    {
+        foreach ($this->_relations as $relation) {
+            $relation->relationDraw($changeColor);
+        }
+    }
+
+    /**
+     * Draws tables
+     *
+     * @param boolean $changeColor Whether to show color for primary fields or not
+     *
+     * @return void
+     * @access private
+     *
+     * @see Table_Stats::Table_Stats_tableDraw()
+     */
+    private function _drawTables($changeColor)
+    {
+        foreach ($this->_tables as $table) {
+            $table->tableDraw($changeColor);
+        }
+    }
+}
+?>
diff --git a/phpmyadmin/libraries/schema/User_Schema.class.php b/phpmyadmin/libraries/schema/User_Schema.class.php
new file mode 100644
index 0000000..95321b3
--- /dev/null
+++ b/phpmyadmin/libraries/schema/User_Schema.class.php
@@ -0,0 +1,933 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * Schema support library
+ *
+ * @package PhpMyAdmin-schema
+ */
+if (! defined('PHPMYADMIN')) {
+    exit;
+}
+
+/**
+ * This Class interacts with the user to gather the information
+ * about their tables for which they want to export the relational schema
+ * export options are shown to user from they can choose
+ *
+ * @package PhpMyAdmin-schema
+ */
+
+class PMA_User_Schema
+{
+
+    public $chosenPage;
+    public $autoLayoutForeign;
+    public $autoLayoutInternal;
+    public $pageNumber;
+    public $c_table_rows;
+    public $action;
+
+    /**
+     * Sets action to be performed with schema.
+     *
+     * @param string $value action name
+     *
+     * @return void
+     */
+    public function setAction($value)
+    {
+        $this->action = $value;
+    }
+
+    /**
+     * This function will process the user defined pages
+     * and tables which will be exported as Relational schema
+     * you can set the table positions on the paper via scratchboard
+     * for table positions, put the x,y co-ordinates
+     *
+     * $this->action tells what the Schema is supposed to do
+     * create and select a page, generate schema etc
+     *
+     * @access public
+     * @return void
+     */
+    public function processUserChoice()
+    {
+        global $db, $cfgRelation;
+
+        if (isset($this->action)) {
+            switch ($this->action) {
+            case 'selectpage':
+                $this->chosenPage = $_REQUEST['chpage'];
+                if ('1' == $_REQUEST['action_choose']) {
+                    $this->deleteCoordinates(
+                        $db,
+                        $cfgRelation,
+                        $this->chosenPage
+                    );
+                    $this->deletePages(
+                        $db,
+                        $cfgRelation,
+                        $this->chosenPage
+                    );
+                    $this->chosenPage = 0;
+                }
+                break;
+            case 'createpage':
+                $this->pageNumber = PMA_REL_createPage(
+                    $_POST['newpage'],
+                    $cfgRelation,
+                    $db
+                );
+                $this->autoLayoutForeign = isset($_POST['auto_layout_foreign'])
+                    ? "1"
+                    : null;
+                $this->autoLayoutInternal = isset($_POST['auto_layout_internal'])
+                    ? "1"
+                    : null;
+                $this->processRelations(
+                    $db,
+                    $this->pageNumber,
+                    $cfgRelation
+                );
+                break;
+            case 'edcoord':
+                $this->chosenPage = $_POST['chpage'];
+                $this->c_table_rows = $_POST['c_table_rows'];
+                $this->_editCoordinates($db, $cfgRelation);
+                break;
+            case 'delete_old_references':
+                $this->_deleteTableRows(
+                    $_POST['delrow'],
+                    $cfgRelation,
+                    $db,
+                    $_POST['chpage']
+                );
+                break;
+            case 'process_export':
+                $this->_processExportSchema();
+                break;
+
+            } // end switch
+        } // end if (isset($do))
+
+    }
+
+    /**
+     * shows/displays the HTML FORM to create the page
+     *
+     * @param string $db name of the selected database
+     *
+     * @return void
+     * @access public
+     */
+    public function showCreatePageDialog($db)
+    {
+        ?>
+        <form method="post" action="schema_edit.php" name="frm_create_page">
+        <fieldset>
+        <legend>
+        <?php echo __('Create a page') . "\n"; ?>
+        </legend>
+        <?php echo PMA_generate_common_hidden_inputs($db); ?>
+        <input type="hidden" name="do" value="createpage" />
+        <table>
+        <tr>
+        <td><label for="id_newpage"><?php echo __('Page name'); ?></label></td>
+        <td>
+        <input type="text" name="newpage" id="id_newpage" size="20" maxlength="50" />
+        </td>
+        </tr>
+        <tr>
+        <td><?php echo __('Automatic layout based on'); ?></td>
+        <td>
+        <input type="checkbox" name="auto_layout_internal" id="id_auto_layout_internal" /><label for="id_auto_layout_internal">
+        <?php echo __('Internal relations'); ?></label><br />
+        <?php
+        /*
+         * Check to see whether INNODB and PBXT storage engines
+         * are Available in MYSQL PACKAGE
+         * If available, then provide AutoLayout for Foreign Keys in Schema View
+         */
+
+        if (PMA_StorageEngine::isValid('InnoDB') || PMA_StorageEngine::isValid('PBXT')) {
+            ?>
+            <input type="checkbox" name="auto_layout_foreign" id="id_auto_layout_foreign" /><label for="id_auto_layout_foreign">
+            <?php echo __('FOREIGN KEY'); ?></label><br />
+            <?php
+        }
+        ?>
+        </td></tr>
+        </table>
+        </fieldset>
+        <fieldset class="tblFooters">
+        <input type="submit" value="<?php echo __('Go'); ?>" />
+        </fieldset>
+        </form>
+        <?php
+    }
+
+    /**
+     * shows/displays the created page names in a drop down list
+     * User can select any page number and edit it using dashboard etc
+     *
+     * @return void
+     * @access public
+     */
+    public function selectPage()
+    {
+        global $db,$table,$cfgRelation;
+        $page_query = 'SELECT * FROM '
+            . PMA_Util::backquote($GLOBALS['cfgRelation']['db']) . '.'
+            . PMA_Util::backquote($cfgRelation['pdf_pages'])
+            . ' WHERE db_name = \'' . PMA_Util::sqlAddSlashes($db) . '\'';
+        $page_rs    = PMA_queryAsControlUser(
+            $page_query, false, PMA_DBI_QUERY_STORE
+        );
+
+        if ($page_rs && PMA_DBI_num_rows($page_rs) > 0) {
+            ?>
+            <form method="get" action="schema_edit.php" name="frm_select_page">
+            <fieldset>
+            <legend>
+            <?php echo __('Please choose a page to edit') . "\n"; ?>
+            </legend>
+            <?php echo PMA_generate_common_hidden_inputs($db, $table); ?>
+            <input type="hidden" name="do" value="selectpage" />
+            <select name="chpage" id="chpage" class="autosubmit">
+            <option value="0"><?php echo __('Select page'); ?></option>
+            <?php
+            while ($curr_page = PMA_DBI_fetch_assoc($page_rs)) {
+                echo "\n" . '        '
+                    . '<option value="' . $curr_page['page_nr'] . '"';
+                if (isset($this->chosenPage)
+                    && $this->chosenPage == $curr_page['page_nr']
+                ) {
+                    echo ' selected="selected"';
+                }
+                echo '>' . $curr_page['page_nr'] . ': '
+                    . htmlspecialchars($curr_page['page_descr']) . '</option>';
+            } // end while
+            echo "\n";
+            ?>
+            </select>
+            <?php
+            $choices = array(
+                 '0' => __('Edit'),
+                 '1' => __('Delete')
+            );
+            echo PMA_Util::getRadioFields(
+                'action_choose', $choices, '0', false
+            );
+            unset($choices);
+            ?>
+            </fieldset>
+            <fieldset class="tblFooters">
+            <input type="submit" value="<?php echo __('Go'); ?>" /><br />
+            </fieldset>
+            </form>
+            <?php
+        } // end IF
+        echo "\n";
+    } // end function
+
+    /**
+     * A dashboard is displayed to AutoLayout the position of tables
+     * users can drag n drop the tables and change their positions
+     *
+     * @return void
+     * @access public
+     */
+    public function showTableDashBoard()
+    {
+        global $db, $cfgRelation, $table, $with_field_names;
+        /*
+         * We will need an array of all tables in this db
+         */
+        $selectboxall = array('--');
+        $alltab_rs    = PMA_DBI_query(
+            'SHOW TABLES FROM ' . PMA_Util::backquote($db) . ';',
+            null,
+            PMA_DBI_QUERY_STORE
+        );
+        while ($val = @PMA_DBI_fetch_row($alltab_rs)) {
+               $selectboxall[] = $val[0];
+        }
+
+        $tabExist = array();
+
+        /*
+         * Now if we already have chosen a page number then we should
+         * show the tables involved
+         */
+        if (isset($this->chosenPage) && $this->chosenPage > 0) {
+            echo "\n";
+            echo "<h2>" . __('Select Tables') . "</h2>";
+            $page_query = 'SELECT * FROM '
+                . PMA_Util::backquote($GLOBALS['cfgRelation']['db'])
+                . '.' . PMA_Util::backquote($cfgRelation['table_coords'])
+                . ' WHERE db_name = \'' . PMA_Util::sqlAddSlashes($db) . '\''
+                . ' AND pdf_page_number = \''
+                . PMA_Util::sqlAddSlashes($this->chosenPage) . '\'';
+            $page_rs    = PMA_queryAsControlUser($page_query, false);
+            $array_sh_page = array();
+            while ($temp_sh_page = @PMA_DBI_fetch_assoc($page_rs)) {
+                   $array_sh_page[] = $temp_sh_page;
+            }
+            /*
+             * Display WYSIWYG parts
+             */
+
+            if (! isset($_POST['with_field_names'])
+                && ! isset($_POST['showwysiwyg'])
+            ) {
+                $with_field_names = true;
+            } elseif (isset($_POST['with_field_names'])) {
+                $with_field_names = true;
+            }
+            $this->_displayScratchboardTables($array_sh_page);
+
+            echo '<form method="post" action="schema_edit.php" name="edcoord">';
+
+            echo PMA_generate_common_hidden_inputs($db, $table);
+            echo '<input type="hidden" name="chpage" '
+                . 'value="' . htmlspecialchars($this->chosenPage) . '" />';
+            echo '<input type="hidden" name="do" value="edcoord" />';
+            echo '<table>';
+            echo '<tr>';
+            echo '<th>' . __('Table') . '</th>';
+            echo '<th>' . __('Delete') . '</th>';
+            echo '<th>X</th>';
+            echo '<th>Y</th>';
+            echo '</tr>';
+
+            if (isset($ctable)) {
+                unset($ctable);
+            }
+
+            /*
+             * Add one more empty row
+             */
+            $array_sh_page[] = array(
+                'table_name' => '',
+                'x' => '0',
+                'y' => '0',
+            );
+
+            $i = 0;
+            $odd_row = true;
+            foreach ($array_sh_page as $sh_page) {
+                $_mtab  = $sh_page['table_name'];
+                if (! empty($_mtab)) {
+                    $tabExist[$_mtab] = false;
+                }
+
+                echo '<tr class="noclick ';
+                if ($odd_row) {
+                    echo 'odd';
+                } else {
+                    echo 'even';
+                }
+                echo '">';
+                $odd_row = !$odd_row;
+
+                echo '<td>';
+                echo '<select name="c_table_' . $i . '[name]">';
+
+                foreach ($selectboxall as $value) {
+                    echo '<option value="' . htmlspecialchars($value) . '"';
+                    if (! empty($_mtab) && $value == $_mtab) {
+                        echo ' selected="selected"';
+                        $tabExist[$_mtab] = true;
+                    }
+                    echo '>' . htmlspecialchars($value) . '</option>';
+                }
+                echo '</select>';
+                echo '</td>';
+
+                echo '<td>';
+                echo '<input type="checkbox" id="id_c_table_' . $i .'" '
+                    . 'name="c_table_' . $i . '[delete]" value="y" />';
+                echo '<label for="id_c_table_' . $i .'">'
+                    . __('Delete') . '</label>';
+                echo '</td>';
+
+                echo '<td>';
+                echo '<input type="text" class="position-change" data-axis="left" '
+                    . 'data-number="' . $i . '" id="c_table_' . $i . '_x" '
+                    . 'name="c_table_' . $i . '[x]" value="'
+                    . $sh_page['x'] . '" />';
+                echo '</td>';
+
+                echo '<td>';
+                echo '<input type="text" class="position-change" data-axis="top" '
+                    . 'data-number="' . $i . '" id="c_table_' . $i . '_y" '
+                    . 'name="c_table_' . $i . '[y]" value="'
+                    . $sh_page['y'] . '" />';
+                echo '</td>';
+                echo '</tr>';
+                $i++;
+            }
+
+            echo '</table>';
+
+            echo '<input type="hidden" name="c_table_rows" value="' . $i . '" />';
+            echo '<input type="hidden" id="showwysiwyg" name="showwysiwyg" value="'
+                . ((isset($showwysiwyg) && $showwysiwyg == '1') ? '1' : '0')
+                . '" />';
+            echo '<input type="checkbox" id="id_with_field_names" '
+                . 'name="with_field_names" '
+                . (isset($with_field_names) ? 'checked="checked"' : ''). ' />';
+            echo '<label for="id_with_field_names">'
+                . __('Column names') . '</label><br />';
+            echo '<input type="submit" value="' . __('Save') . '" />';
+            echo '</form>' . "\n\n";
+        } // end if
+
+        if (isset($tabExist)) {
+            $this->_deleteTables($db, $this->chosenPage, $tabExist);
+        }
+    }
+
+    /**
+     * show Export relational schema generation options
+     * user can select export type of his own choice
+     * and the attributes related to it
+     *
+     * @return void
+     * @access public
+     */
+
+    public function displaySchemaGenerationOptions()
+    {
+        global $cfg,$db,$test_rs,$chpage;
+        ?>
+        <form method="post" action="schema_export.php" class="disableAjax">
+            <fieldset>
+            <legend>
+            <?php
+            echo PMA_generate_common_hidden_inputs($db);
+            if ($cfg['PropertiesIconic']) {
+                echo PMA_Util::getImage('b_views.png');
+            }
+            echo __('Display relational schema');
+            ?>:
+            </legend>
+            <select name="export_type" id="export_type">
+                <option value="pdf" selected="selected">PDF</option>
+                <option value="svg">SVG</option>
+                <option value="dia">DIA</option>
+                <option value="eps">EPS</option>
+            </select>
+            <label><?php echo __('Select Export Relational Type');?></label><br />
+            <?php
+            if (isset($test_rs)) {
+            ?>
+            <label for="pdf_page_number_opt"><?php echo __('Page number:'); ?></label>
+            <select name="pdf_page_number" id="pdf_page_number_opt">
+                <?php
+                while ($pages = @PMA_DBI_fetch_assoc($test_rs)) {
+                    echo '                <option value="' . $pages['page_nr'] . '">'
+                        . $pages['page_nr'] . ': ' . htmlspecialchars($pages['page_descr']) . '</option>' . "\n";
+                } // end while
+                PMA_DBI_free_result($test_rs);
+                unset($test_rs);
+                ?>
+            </select><br />
+            <?php
+            } else {
+            ?>
+            <input type="hidden" name="pdf_page_number" value="<?php echo htmlspecialchars($this->chosenPage); ?>" />
+            <?php
+            }
+            ?>
+            <input type="hidden" name="do" value="process_export" />
+            <input type="hidden" name="chpage" value="<?php echo $chpage; ?>" />
+            <input type="checkbox" name="show_grid" id="show_grid_opt" />
+            <label for="show_grid_opt"><?php echo __('Show grid'); ?></label><br />
+            <input type="checkbox" name="show_color" id="show_color_opt" checked="checked" />
+            <label for="show_color_opt"><?php echo __('Show color'); ?></label>
+            <br />
+            <input type="checkbox" name="show_table_dimension" id="show_table_dim_opt" />
+            <label for="show_table_dim_opt">
+            <?php echo __('Show dimension of tables'); ?>
+            </label><br />
+            <input type="checkbox" name="all_tables_same_width" id="all_tables_same_width" />
+            <label for="all_tables_same_width">
+            <?php echo __('Display all tables with the same width'); ?>
+            </label><br />
+            <input type="checkbox" name="with_doc" id="with_doc" checked="checked" />
+            <label for="with_doc"><?php echo __('Data Dictionary'); ?></label><br />
+            <input type="checkbox" name="show_keys" id="show_keys" />
+            <label for="show_keys"><?php echo __('Only show keys'); ?></label><br />
+            <select name="orientation" id="orientation_opt" class="paper-change">
+                <option value="L"><?php echo __('Landscape');?></option>
+                <option value="P"><?php echo __('Portrait');?></option>
+            </select>
+            <label for="orientation_opt"><?php echo __('Orientation'); ?></label>
+            <br />
+            <select name="paper" id="paper_opt" class="paper-change">
+                <?php
+                foreach ($cfg['PDFPageSizes'] as $val) {
+                        echo '<option value="' . $val . '"';
+                        if ($val == $cfg['PDFDefaultPageSize']) {
+                            echo ' selected="selected"';
+                        }
+                        echo ' >' . $val . '</option>' . "\n";
+                }
+                ?>
+            </select>
+            <label for="paper_opt"><?php echo __('Paper size'); ?></label>
+            </fieldset>
+            <fieldset class="tblFooters">
+            <input type="submit" value="<?php echo __('Go'); ?>" />
+            </fieldset>
+        </form>
+        <?php
+    }
+
+    /**
+    * Check if there are tables that need to be deleted in dashboard,
+    * if there are, ask the user for allowance
+    *
+    * @param string  $db       name of database selected
+    * @param integer $chpage   selected page
+    * @param array   $tabExist array of booleans
+    *
+    * @return void
+    * @access private
+    */
+    private function _deleteTables($db, $chpage, $tabExist)
+    {
+        $_strtrans  = '';
+        $_strname   = '';
+        $shoot      = false;
+        if (empty($tabExist) || ! is_array($tabExist)) {
+            return;
+        }
+        foreach ($tabExist as $key => $value) {
+            if (! $value) {
+                $_strtrans  .= '<input type="hidden" name="delrow[]" value="'
+                    . htmlspecialchars($key) . '" />' . "\n";
+                $_strname   .= '<li>' . htmlspecialchars($key) . '</li>' . "\n";
+                $shoot       = true;
+            }
+        }
+        if (!$shoot) {
+            return;
+        }
+        echo '<br /><form action="schema_edit.php" method="post">' . "\n"
+            . PMA_generate_common_hidden_inputs($db)
+            . '<input type="hidden" name="do" value="delete_old_references" />'
+            . "\n"
+            . '<input type="hidden" name="chpage" value="'
+            . htmlspecialchars($chpage) . '" />' . "\n"
+            . __(
+                'The current page has references to tables that no longer exist.'
+                . ' Would you like to delete those references?'
+            )
+            . '<ul>' . "\n"
+            . $_strname
+            . '</ul>' . "\n"
+            . $_strtrans
+            . '<input type="submit" value="' . __('Go') . '" />' . "\n"
+            . '</form>';
+    }
+
+    /**
+     * Check if there are tables that need to be deleted in dashboard,
+     * if there are, ask the user for allowance
+     *
+     * @param array $array_sh_page array of tables on page
+     *
+     * @return void
+     * @access private
+     */
+    private function _displayScratchboardTables($array_sh_page)
+    {
+        global $with_field_names, $db;
+
+        echo '<form method="post" action="schema_edit.php" name="dragdrop">';
+        echo '<input type="button" name="dragdrop" id="toggle-dragdrop" '
+            . 'value="' . __('Toggle scratchboard') . '" />';
+        echo '<input type="button" name="dragdropreset" id="reset-dragdrop" '
+            . 'value="' . __('Reset') . '" />';
+        echo '</form>';
+        echo '<div id="pdflayout" class="pdflayout" style="visibility: hidden;">';
+
+        $i = 0;
+
+        foreach ($array_sh_page as $temp_sh_page) {
+            $drag_x = $temp_sh_page['x'];
+            $drag_y = $temp_sh_page['y'];
+
+            echo '<div id="table_' . $i . '" '
+                . 'data-number="' . $i .'" '
+                . 'data-x="' . $drag_x . '" '
+                . 'data-y="' . $drag_y . '" '
+                . 'class="pdflayout_table"'
+                . '>'
+                . '<u>'
+                . htmlspecialchars($temp_sh_page['table_name'])
+                . '</u>';
+
+            if (isset($with_field_names)) {
+                $fields = PMA_DBI_get_columns($db, $temp_sh_page['table_name']);
+                // if the table has been dropped from outside phpMyAdmin,
+                // we can no longer obtain its columns list
+                if ($fields) {
+                    foreach ($fields as $row) {
+                        echo '<br />' . htmlspecialchars($row['Field']) . "\n";
+                    }
+                }
+            }
+            echo '</div>' . "\n";
+            $i++;
+        }
+
+        echo '</div>';
+    }
+
+    /**
+     * delete the table rows with table co-ordinates
+     *
+     * @param int     $delrow      delete selected table from list of tables
+     * @param array   $cfgRelation relation settings
+     * @param string  $db          database name
+     * @param integer $chpage      selected page for adding relations etc
+     *
+     * @return void
+     * @access private
+     */
+    private function _deleteTableRows($delrow,$cfgRelation,$db,$chpage)
+    {
+        foreach ($delrow as $current_row) {
+            $del_query = 'DELETE FROM '
+                . PMA_Util::backquote($GLOBALS['cfgRelation']['db']) . '.'
+                . PMA_Util::backquote($cfgRelation['table_coords']) . ' ' . "\n"
+                .   ' WHERE db_name = \''
+                . PMA_Util::sqlAddSlashes($db) . '\'' . "\n"
+                .   ' AND table_name = \''
+                . PMA_Util::sqlAddSlashes($current_row) . '\'' . "\n"
+                .   ' AND pdf_page_number = \''
+                . PMA_Util::sqlAddSlashes($chpage) . '\'';
+            PMA_queryAsControlUser($del_query, false);
+        }
+    }
+
+    /**
+     * get all the export options and verify
+     * call and include the appropriate Schema Class depending on $export_type
+     *
+     * @return void
+     * @access private
+     */
+    private function _processExportSchema()
+    {
+        /**
+        * Settings for relation stuff
+        */
+        include_once './libraries/transformations.lib.php';
+        include_once './libraries/Index.class.php';
+        /**
+         * default is PDF, otherwise validate it's only letters a-z
+         */
+        global  $db,$export_type;
+        if (!isset($export_type) || !preg_match('/^[a-zA-Z]+$/', $export_type)) {
+            $export_type = 'pdf';
+        }
+
+        PMA_DBI_select_db($db);
+
+        include "libraries/schema/" . ucfirst($export_type)
+            . "_Relation_Schema.class.php";
+        eval("new PMA_" . ucfirst($export_type) . "_Relation_Schema();");
+    }
+
+    /**
+     * delete X and Y coordinates
+     *
+     * @param string  $db          The database name
+     * @param array   $cfgRelation relation settings
+     * @param integer $choosePage  selected page for adding relations etc
+     *
+     * @return void
+     * @access private
+     */
+    public function deleteCoordinates($db, $cfgRelation, $choosePage)
+    {
+        $query = 'DELETE FROM '
+            . PMA_Util::backquote($GLOBALS['cfgRelation']['db']) . '.'
+            . PMA_Util::backquote($cfgRelation['table_coords'])
+            . ' WHERE db_name = \'' . PMA_Util::sqlAddSlashes($db) . '\''
+            . ' AND   pdf_page_number = \''
+            . PMA_Util::sqlAddSlashes($choosePage) . '\'';
+        PMA_queryAsControlUser($query, false);
+    }
+
+    /**
+     * delete pages
+     *
+     * @param string  $db          The database name
+     * @param array   $cfgRelation relation settings
+     * @param integer $choosePage  selected page for adding relations etc
+     *
+     * @return void
+     * @access private
+     */
+    public function deletePages($db, $cfgRelation, $choosePage)
+    {
+        $query = 'DELETE FROM '
+            . PMA_Util::backquote($GLOBALS['cfgRelation']['db']) . '.'
+            . PMA_Util::backquote($cfgRelation['pdf_pages'])
+            . ' WHERE db_name = \'' . PMA_Util::sqlAddSlashes($db) . '\''
+            . ' AND   page_nr = \'' . PMA_Util::sqlAddSlashes($choosePage) . '\'';
+        PMA_queryAsControlUser($query, false);
+    }
+
+    /**
+     * process internal and foreign key relations
+     *
+     * @param string  $db          The database name
+     * @param integer $pageNumber  document number/Id
+     * @param array   $cfgRelation relation settings
+     *
+     * @return void
+     * @access private
+     */
+    public function processRelations($db, $pageNumber, $cfgRelation)
+    {
+        /*
+         * A u t o m a t i c    l a y o u t
+         *
+         * There are 2 kinds of relations in PMA
+         * 1) Internal Relations 2) Foreign Key Relations
+         */
+        if (isset($this->autoLayoutInternal) || isset($this->autoLayoutForeign)) {
+            $all_tables = array();
+        }
+
+        if (isset($this->autoLayoutForeign)) {
+            /*
+             * get the tables list
+             * who support FOREIGN KEY, it's not
+             * important that we group together InnoDB tables
+             * and PBXT tables, as this logic is just to put
+             * the tables on the layout, not to determine relations
+             */
+            $tables = PMA_DBI_get_tables_full($db);
+            $foreignkey_tables = array();
+            foreach ($tables as $table_name => $table_properties) {
+                if (PMA_Util::isForeignKeySupported($table_properties['ENGINE'])) {
+                    $foreignkey_tables[] = $table_name;
+                }
+            }
+            $all_tables = $foreignkey_tables;
+            /*
+             * could be improved by finding the tables which have the
+             * most references keys and placing them at the beginning
+             * of the array (so that they are all center of schema)
+             */
+            unset($tables, $foreignkey_tables);
+        }
+
+        if (isset($this->autoLayoutInternal)) {
+            /*
+             * get the tables list who support Internal Relations;
+             * This type of relations will be created when
+             * you setup the PMA tables correctly
+             */
+            $master_tables = 'SELECT COUNT(master_table), master_table'
+                . ' FROM ' . PMA_Util::backquote($GLOBALS['cfgRelation']['db']) . '.'
+                . PMA_Util::backquote($cfgRelation['relation'])
+                . ' WHERE master_db = \'' . PMA_Util::sqlAddSlashes($db) . '\''
+                . ' GROUP BY master_table'
+                . ' ORDER BY COUNT(master_table) DESC';
+            $master_tables_rs = PMA_queryAsControlUser(
+                $master_tables, false, PMA_DBI_QUERY_STORE
+            );
+            if ($master_tables_rs && PMA_DBI_num_rows($master_tables_rs) > 0) {
+                /* first put all the master tables at beginning
+                 * of the list, so they are near the center of
+                 * the schema
+                 */
+                while (list(, $master_table) = PMA_DBI_fetch_row($master_tables_rs)) {
+                       $all_tables[] = $master_table;
+                }
+
+                /* Now for each master, add its foreigns into an array
+                 * of foreign tables, if not already there
+                 * (a foreign might be foreign for more than
+                 * one table, and might be a master itself)
+                 */
+
+                $foreign_tables = array();
+                foreach ($all_tables as $master_table) {
+                    $foreigners = PMA_getForeigners($db, $master_table);
+                    foreach ($foreigners as $foreigner) {
+                        if (! in_array($foreigner['foreign_table'], $foreign_tables)) {
+                            $foreign_tables[] = $foreigner['foreign_table'];
+                        }
+                    }
+                }
+
+                /*
+                 * Now merge the master and foreign arrays/tables
+                 */
+                foreach ($foreign_tables as $foreign_table) {
+                    if (! in_array($foreign_table, $all_tables)) {
+                        $all_tables[] = $foreign_table;
+                    }
+                }
+            }
+        }
+
+        if (isset($this->autoLayoutInternal) || isset($this->autoLayoutForeign)) {
+            $this->addRelationCoordinates(
+                $all_tables, $pageNumber, $db, $cfgRelation
+            );
+        }
+
+        $this->chosenPage = $pageNumber;
+    }
+
+    /**
+     * Add X and Y coordinates for a table
+     *
+     * @param array   $all_tables  A list of all tables involved
+     * @param integer $pageNumber  document number/Id
+     * @param string  $db          The database name
+     * @param array   $cfgRelation relation settings
+     *
+     * @return void
+     * @access private
+     */
+    public function addRelationCoordinates(
+        $all_tables, $pageNumber, $db, $cfgRelation
+    ) {
+        /*
+         * Now generate the coordinates for the schema
+         * in a clockwise spiral and add to co-ordinates table
+         */
+        $pos_x = 300;
+        $pos_y = 300;
+        $delta = 110;
+        $delta_mult = 1.10;
+        $direction = "right";
+        foreach ($all_tables as $current_table) {
+            /*
+            * save current table's coordinates
+            */
+            $insert_query = 'INSERT INTO '
+                . PMA_Util::backquote($GLOBALS['cfgRelation']['db']) . '.'
+                . PMA_Util::backquote($cfgRelation['table_coords']) . ' '
+                . '(db_name, table_name, pdf_page_number, x, y) '
+                . 'VALUES (\'' . PMA_Util::sqlAddSlashes($db) . '\', \''
+                . PMA_Util::sqlAddSlashes($current_table) . '\',' . $pageNumber
+                . ',' . $pos_x . ',' . $pos_y . ')';
+            PMA_queryAsControlUser($insert_query, false);
+
+            /*
+             * compute for the next table
+             */
+            switch ($direction) {
+            case 'right':
+                $pos_x    += $delta;
+                $direction = "down";
+                $delta    *= $delta_mult;
+                break;
+            case 'down':
+                $pos_y    += $delta;
+                $direction = "left";
+                $delta    *= $delta_mult;
+                break;
+            case 'left':
+                $pos_x    -= $delta;
+                $direction = "up";
+                $delta    *= $delta_mult;
+                break;
+            case 'up':
+                $pos_y    -= $delta;
+                $direction = "right";
+                $delta    *= $delta_mult;
+                break;
+            }
+        }
+    }
+
+    /**
+     * update X and Y coordinates for a table
+     *
+     * @param string $db          The database name
+     * @param array  $cfgRelation relation settings
+     *
+     * @return void
+     * @access private
+     */
+    private function _editCoordinates($db, $cfgRelation)
+    {
+        for ($i = 0; $i < $this->c_table_rows; $i++) {
+            $arrvalue = $_POST['c_table_' . $i];
+
+            if (! isset($arrvalue['x']) || $arrvalue['x'] == '') {
+                $arrvalue['x'] = 0;
+            }
+            if (! isset($arrvalue['y']) || $arrvalue['y'] == '') {
+                $arrvalue['y'] = 0;
+            }
+            if (isset($arrvalue['name']) && $arrvalue['name'] != '--') {
+                $test_query = 'SELECT * FROM '
+                    . PMA_Util::backquote($GLOBALS['cfgRelation']['db']) . '.'
+                    . PMA_Util::backquote($cfgRelation['table_coords'])
+                    . ' WHERE db_name = \'' .  PMA_Util::sqlAddSlashes($db) . '\''
+                    . ' AND   table_name = \''
+                    . PMA_Util::sqlAddSlashes($arrvalue['name']) . '\''
+                    . ' AND   pdf_page_number = \''
+                    . PMA_Util::sqlAddSlashes($this->chosenPage) . '\'';
+                $test_rs = PMA_queryAsControlUser(
+                    $test_query, false, PMA_DBI_QUERY_STORE
+                );
+                //echo $test_query;
+                if ($test_rs && PMA_DBI_num_rows($test_rs) > 0) {
+                    if (isset($arrvalue['delete']) && $arrvalue['delete'] == 'y') {
+                        $ch_query = 'DELETE FROM '
+                            . PMA_Util::backquote($GLOBALS['cfgRelation']['db'])
+                            . '.'
+                            . PMA_Util::backquote($cfgRelation['table_coords'])
+                            . ' WHERE db_name = \''
+                            . PMA_Util::sqlAddSlashes($db) . '\''
+                            . ' AND   table_name = \''
+                            . PMA_Util::sqlAddSlashes($arrvalue['name']) . '\''
+                            . ' AND   pdf_page_number = \''
+                            . PMA_Util::sqlAddSlashes($this->chosenPage) . '\'';
+                    } else {
+                        $ch_query = 'UPDATE '
+                            . PMA_Util::backquote($GLOBALS['cfgRelation']['db'])
+                            . '.' . PMA_Util::backquote($cfgRelation['table_coords'])
+                            . ' '
+                            . 'SET x = ' . $arrvalue['x'] . ', y= ' . $arrvalue['y']
+                            . ' WHERE db_name = \''
+                            . PMA_Util::sqlAddSlashes($db) . '\''
+                            . ' AND   table_name = \''
+                            . PMA_Util::sqlAddSlashes($arrvalue['name']) . '\''
+                            . ' AND   pdf_page_number = \''
+                            . PMA_Util::sqlAddSlashes($this->chosenPage) . '\'';
+                    }
+                } else {
+                    $ch_query = 'INSERT INTO '
+                        . PMA_Util::backquote($GLOBALS['cfgRelation']['db'])
+                        . '.' . PMA_Util::backquote($cfgRelation['table_coords'])
+                        . ' '
+                        . '(db_name, table_name, pdf_page_number, x, y) '
+                        . 'VALUES (\'' . PMA_Util::sqlAddSlashes($db) . '\', \''
+                        . PMA_Util::sqlAddSlashes($arrvalue['name']) . '\', \''
+                        . PMA_Util::sqlAddSlashes($this->chosenPage) . '\','
+                        . $arrvalue['x'] . ',' . $arrvalue['y'] . ')';
+                }
+                //echo $ch_query;
+                PMA_queryAsControlUser($ch_query, false);
+            } // end if
+        } // end for
+    }
+}
+?>
diff --git a/phpmyadmin/libraries/select_lang.lib.php b/phpmyadmin/libraries/select_lang.lib.php
new file mode 100644
index 0000000..97e3302
--- /dev/null
+++ b/phpmyadmin/libraries/select_lang.lib.php
@@ -0,0 +1,556 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * phpMyAdmin Language Loading File
+ *
+ * @package PhpMyAdmin
+ */
+if (! defined('PHPMYADMIN')) {
+    exit;
+}
+
+/**
+ * Returns language name
+ *
+ * @param string $tmplang
+ *
+ * @return string
+ */
+function PMA_langName($tmplang)
+{
+    $lang_name = ucfirst(substr(strrchr($tmplang[0], '|'), 1));
+
+    // Include native name if non empty
+    if (!empty($tmplang[2])) {
+        $lang_name = $tmplang[2] . ' - ' . $lang_name;
+    }
+
+    return $lang_name;
+}
+
+/**
+ * Tries to find the language to use
+ *
+ * @return bool  success if valid lang is found, otherwise false
+ */
+function PMA_langCheck()
+{
+    // check forced language
+    if (! empty($GLOBALS['cfg']['Lang'])) {
+        if (PMA_langSet($GLOBALS['cfg']['Lang'])) {
+            return true;
+        } else {
+            $GLOBALS['lang_failed_cfg'] = $GLOBALS['cfg']['Lang'];
+        }
+    }
+
+    // Don't use REQUEST in following code as it might be confused by cookies
+    // with same name. Check user requested language (POST)
+    if (! empty($_POST['lang'])) {
+        if (PMA_langSet($_POST['lang'])) {
+            return true;
+        } elseif (!is_string($_POST['lang'])) {
+            /* Faked request, don't care on localisation */
+            $GLOBALS['lang_failed_request'] = 'Yes';
+        } else {
+            $GLOBALS['lang_failed_request'] = $_POST['lang'];
+        }
+    }
+
+    // check user requested language (GET)
+    if (! empty($_GET['lang'])) {
+        if (PMA_langSet($_GET['lang'])) {
+            return true;
+        } elseif (!is_string($_GET['lang'])) {
+            /* Faked request, don't care on localisation */
+            $GLOBALS['lang_failed_request'] = 'Yes';
+        } else {
+            $GLOBALS['lang_failed_request'] = $_GET['lang'];
+        }
+    }
+
+    // check previous set language
+    if (! empty($_COOKIE['pma_lang'])) {
+        if (PMA_langSet($_COOKIE['pma_lang'])) {
+            return true;
+        } elseif (!is_string($_COOKIE['pma_lang'])) {
+            /* Faked request, don't care on localisation */
+            $GLOBALS['lang_failed_cookie'] = 'Yes';
+        } else {
+            $GLOBALS['lang_failed_cookie'] = $_COOKIE['pma_lang'];
+        }
+    }
+
+    // try to find out user's language by checking its HTTP_ACCEPT_LANGUAGE variable;
+    // prevent XSS
+    $accepted_languages = PMA_getenv('HTTP_ACCEPT_LANGUAGE');
+    if ($accepted_languages && false === strpos($accepted_languages, '<')) {
+        foreach (explode(',', $accepted_languages) as $lang) {
+            if (PMA_langDetect($lang, 1)) {
+                return true;
+            }
+        }
+    }
+    unset($accepted_languages);
+
+    // try to find out user's language by checking its HTTP_USER_AGENT variable
+    if (PMA_langDetect(PMA_getenv('HTTP_USER_AGENT'), 2)) {
+        return true;
+    }
+
+    // Didn't catch any valid lang : we use the default settings
+    if (PMA_langSet($GLOBALS['cfg']['DefaultLang'])) {
+        return true;
+    }
+
+    return false;
+}
+
+/**
+ * checks given lang and sets it if valid
+ * returns true on success, otherwise false
+ *
+ * @param string &$lang language to set
+ *
+ * @return bool  success
+ */
+function PMA_langSet(&$lang)
+{
+    /* Partial backward compatibility with 3.3 and older branches */
+    $lang = str_replace('-utf-8', '', $lang);
+
+    if (!is_string($lang) || empty($lang) || empty($GLOBALS['available_languages'][$lang])) {
+        return false;
+    }
+    $GLOBALS['lang'] = $lang;
+    return true;
+}
+
+/**
+ * Analyzes some PHP environment variables to find the most probable language
+ * that should be used
+ *
+ * @param string  $str     string to analyze
+ * @param integer $envType type of the PHP environment variable which value is $str
+ *
+ * @return bool    true on success, otherwise false
+ *
+ * @access  private
+ */
+function PMA_langDetect($str, $envType)
+{
+    if (empty($str)) {
+        return false;
+    }
+    if (empty($GLOBALS['available_languages'])) {
+        return false;
+    }
+
+    foreach ($GLOBALS['available_languages'] as $lang => $value) {
+        // $envType =  1 for the 'HTTP_ACCEPT_LANGUAGE' environment variable,
+        //             2 for the 'HTTP_USER_AGENT' one
+        $expr = $value[0];
+        if (strpos($expr, '[-_]') === false) {
+            $expr = str_replace('|', '([-_][[:alpha:]]{2,3})?|', $expr);
+        }
+        if (($envType == 1 && preg_match('/^(' . addcslashes($expr, '/') . ')(;q=[0-9]\\.[0-9])?$/i', $str))
+            || ($envType == 2 && preg_match('/(\(|\[|;[[:space:]])(' . addcslashes($expr, '/') . ')(;|\]|\))/i', $str))
+        ) {
+            if (PMA_langSet($lang)) {
+                return true;
+            }
+        }
+    }
+
+    return false;
+} // end of the 'PMA_langDetect()' function
+
+
+/**
+ * All the supported languages have to be listed in the array below.
+ * 1. The key must be the "official" ISO 639 language code and, if required,
+ *    the dialect code. It can also contain some information about the
+ *    charset (see the Russian case).
+ * 2. The first of the values associated to the key is used in a regular
+ *    expression to find some keywords corresponding to the language inside two
+ *    environment variables.
+ *    These values contain:
+ *    - the "official" ISO language code and, if required, the dialect code
+ *      too ('bu' for Bulgarian, 'fr([-_][[:alpha:]]{2})?' for all French
+ *      dialects, 'zh[-_]tw' for Chinese traditional...), the dialect has to
+ *      be specified first;
+ *    - the '|' character (it means 'OR');
+ *    - the full language name.
+ * 3. The second value associated to the key is the language code as defined by
+ *    the RFC1766.
+ * 4. The third value is its native name in html entities or UTF-8.
+ *
+ * Beware that the sorting order (first values associated to keys by
+ * alphabetical reverse order in the array) is important: 'zh-tw' (chinese
+ * traditional) must be detected before 'zh' (chinese simplified) for
+ * example.
+ *
+ * @param string $lang language
+ *
+ * @return array
+ */
+function PMA_langDetails($lang)
+{
+    switch ($lang) {
+    case 'af':
+        return array('af|afrikaans', 'af', '');
+    case 'ar':
+        return array('ar|arabic', 'ar', 'العربية');
+    case 'az':
+        return array('az|azerbaijani', 'az', 'Azərbaycanca');
+    case 'bn':
+        return array('bn|bangla', 'bn', 'বাংলা');
+    case 'be':
+        return array('be|belarusian', 'be', 'Беларуская');
+    case 'be at latin':
+        return array('be[-_]lat|belarusian latin', 'be-lat', 'Biełaruskaja');
+    case 'bg':
+        return array('bg|bulgarian', 'bg', 'Български');
+    case 'bs':
+        return array('bs|bosnian', 'bs', 'Bosanski');
+    case 'br':
+        return array('br|breton', 'br', 'Brezhoneg');
+    case 'ca':
+        return array('ca|catalan', 'ca', 'Català');
+    case 'ckb':
+        return array('ckb', 'ckb', 'سۆرانی');
+    case 'cs':
+        return array('cs|czech', 'cs', 'Čeština');
+    case 'cy':
+        return array('cy|welsh', 'cy', 'Cymraeg');
+    case 'da':
+        return array('da|danish', 'da', 'Dansk');
+    case 'de':
+        return array('de|german', 'de', 'Deutsch');
+    case 'el':
+        return array('el|greek', 'el', 'Ελληνικά');
+    case 'en':
+        return array('en|english', 'en', '');
+    case 'en_GB':
+        return array('en[_-]gb|english (United Kingdom)', 'en-gb', '');
+    case 'es':
+        return array('es|spanish', 'es', 'Español');
+    case 'et':
+        return array('et|estonian', 'et', 'Eesti');
+    case 'eu':
+        return array('eu|basque', 'eu', 'Euskara');
+    case 'fa':
+        return array('fa|persian', 'fa', 'فارسی');
+    case 'fi':
+        return array('fi|finnish', 'fi', 'Suomi');
+    case 'fr':
+        return array('fr|french', 'fr', 'Français');
+    case 'gl':
+        return array('gl|galician', 'gl', 'Galego');
+    case 'he':
+        return array('he|hebrew', 'he', 'עברית');
+    case 'hi':
+        return array('hi|hindi', 'hi', 'हिन्दी');
+    case 'hr':
+        return array('hr|croatian', 'hr', 'Hrvatski');
+    case 'hu':
+        return array('hu|hungarian', 'hu', 'Magyar');
+    case 'hy':
+        return array('hy|armenian', 'hy', 'Հայերէն');
+    case 'id':
+        return array('id|indonesian', 'id', 'Bahasa Indonesia');
+    case 'it':
+        return array('it|italian', 'it', 'Italiano');
+    case 'ja':
+        return array('ja|japanese', 'ja', '日本語');
+    case 'ko':
+        return array('ko|korean', 'ko', '한국어');
+    case 'ka':
+        return array('ka|georgian', 'ka', 'ქართული');
+    case 'kk':
+        return array('kk|kazakh', 'kk', 'Қазақ');
+    case 'lt':
+        return array('lt|lithuanian', 'lt', 'Lietuvių');
+    case 'lv':
+        return array('lv|latvian', 'lv', 'Latviešu');
+    case 'mk':
+        return array('mk|macedonian', 'mk', 'Macedonian');
+    case 'ml':
+        return array('ml|malayalam', 'ml', 'Malayalam');
+    case 'mn':
+        return array('mn|mongolian', 'mn', 'Монгол');
+    case 'ms':
+        return array('ms|malay', 'ms', 'Bahasa Melayu');
+    case 'nl':
+        return array('nl|dutch', 'nl', 'Nederlands');
+    case 'nb':
+        return array('nb|norwegian', 'nb', 'Norsk');
+    case 'pa':
+        return array('pa|punjabi', 'pa', 'ਪੰਜਾਬੀ');
+    case 'pl':
+        return array('pl|polish', 'pl', 'Polski');
+    case 'pt_BR':
+        return array('pt[-_]br|brazilian portuguese', 'pt-BR', 'Português');
+    case 'pt':
+        return array('pt|portuguese', 'pt', 'Português');
+    case 'ro':
+        return array('ro|romanian', 'ro', 'Română');
+    case 'ru':
+        return array('ru|russian', 'ru', 'Русский');
+    case 'si':
+        return array('si|sinhala', 'si', 'සිංහල');
+    case 'sk':
+        return array('sk|slovak', 'sk', 'Slovenčina');
+    case 'sl':
+        return array('sl|slovenian', 'sl', 'Slovenščina');
+    case 'sq':
+        return array('sq|albanian', 'sq', 'Shqip');
+    case 'sr at latin':
+        return array('sr[-_]lat|serbian latin', 'sr-lat', 'Srpski');
+    case 'sr':
+        return array('sr|serbian', 'sr', 'Српски');
+    case 'sv':
+        return array('sv|swedish', 'sv', 'Svenska');
+    case 'ta':
+        return array('ta|tamil', 'ta', 'தமிழ்');
+    case 'te':
+        return array('te|telugu', 'te', 'తెలుగు');
+    case 'th':
+        return array('th|thai', 'th', 'ภาษาไทย');
+    case 'tk':
+        return array('tk|turkmen', 'tk', 'türkmençe');
+    case 'tr':
+        return array('tr|turkish', 'tr', 'Türkçe');
+    case 'tt':
+        return array('tt|tatarish', 'tt', 'Tatarça');
+    case 'ug':
+        return array('ug|uyghur', 'ug', 'ئۇيغۇرچە');
+    case 'uk':
+        return array('uk|ukrainian', 'uk', 'Українська');
+    case 'ur':
+        return array('ur|urdu', 'ur', 'اُردوُ');
+    case 'uz at latin':
+        return array('uz[-_]lat|uzbek-latin', 'uz-lat', 'O‘zbekcha');
+    case 'uz':
+        return array('uz[-_]cyr|uzbek-cyrillic', 'uz-cyr', 'Ўзбекча');
+    case 'zh_TW':
+        return array('zh[-_](tw|hk)|chinese traditional', 'zh-TW', '中文');
+    case 'zh_CN':
+        // only TW and HK use traditional Chinese while others (CN, SG, MY)
+        // use simplified Chinese
+        return array(
+            'zh(?![-_](tw|hk))([-_][[:alpha:]]{2,3})?|chinese simplified', 
+            'zh', 
+            '中文'
+        );
+    }
+    return array("$lang|$lang", $lang, $lang);
+}
+
+/**
+ * Returns list of languages supported by phpMyAdmin
+ *
+ * @return array
+ */
+function PMA_langList()
+{
+    /* We can always speak English */
+    $result = array('en' => PMA_langDetails('en'));
+
+    /* Check for existing directory */
+    if (!is_dir($GLOBALS['lang_path'])) {
+        return $result;
+    }
+
+    /* Open the directory */
+    $handle = @opendir($GLOBALS['lang_path']);
+    /* This can happen if the kit is English-only */
+    if ($handle === false) {
+        return $result;
+    }
+
+    /* Process all files */
+    while (false !== ($file = readdir($handle))) {
+        if ($file != "."
+            && $file != ".."
+            && file_exists($GLOBALS['lang_path'] . '/' . $file . '/LC_MESSAGES/phpmyadmin.mo')
+        ) {
+            $result[$file] = PMA_langDetails($file);
+        }
+    }
+    /* Close the handle */
+    closedir($handle);
+
+    return $result;
+}
+
+/**
+ * @global string  path to the translations directory; may be absent if the kit is English-only
+ */
+$GLOBALS['lang_path'] = './locale/';
+
+/**
+ * Load gettext functions.
+ */
+require_once GETTEXT_INC;
+
+/**
+ * @global string  interface language
+ */
+$GLOBALS['lang'] = 'en';
+/**
+ * @global boolean whether loading lang from cfg failed
+ */
+$GLOBALS['lang_failed_cfg'] = false;
+/**
+ * @global boolean whether loading lang from cookie failed
+ */
+$GLOBALS['lang_failed_cookie'] = false;
+/**
+ * @global boolean whether loading lang from user request failed
+ */
+$GLOBALS['lang_failed_request'] = false;
+/**
+ * @global string text direction ltr or rtl
+ */
+$GLOBALS['text_dir'] = 'ltr';
+
+/**
+ * @global array supported languages
+ */
+$GLOBALS['available_languages'] = PMA_langList();
+
+// Language filtering support
+if (! empty($GLOBALS['cfg']['FilterLanguages'])) {
+    $new_lang = array();
+    foreach ($GLOBALS['available_languages'] as $key => $val) {
+        if (preg_match('@' . $GLOBALS['cfg']['FilterLanguages'] . '@', $key)) {
+            $new_lang[$key] = $val;
+        }
+    }
+    if (count($new_lang) > 0) {
+        $GLOBALS['available_languages'] = $new_lang;
+    }
+    unset($key, $val, $new_lang);
+}
+
+/**
+ * @global array MySQL charsets map
+ */
+$GLOBALS['mysql_charset_map'] = array(
+    'big5'         => 'big5',
+    'cp-866'       => 'cp866',
+    'euc-jp'       => 'ujis',
+    'euc-kr'       => 'euckr',
+    'gb2312'       => 'gb2312',
+    'gbk'          => 'gbk',
+    'iso-8859-1'   => 'latin1',
+    'iso-8859-2'   => 'latin2',
+    'iso-8859-7'   => 'greek',
+    'iso-8859-8'   => 'hebrew',
+    'iso-8859-8-i' => 'hebrew',
+    'iso-8859-9'   => 'latin5',
+    'iso-8859-13'  => 'latin7',
+    'iso-8859-15'  => 'latin1',
+    'koi8-r'       => 'koi8r',
+    'shift_jis'    => 'sjis',
+    'tis-620'      => 'tis620',
+    'utf-8'        => 'utf8',
+    'windows-1250' => 'cp1250',
+    'windows-1251' => 'cp1251',
+    'windows-1252' => 'latin1',
+    'windows-1256' => 'cp1256',
+    'windows-1257' => 'cp1257',
+);
+
+/*
+ * Do the work!
+ */
+
+if (! PMA_langCheck()) {
+    // fallback language
+    $fall_back_lang = 'en';
+    $line = __LINE__;
+    if (! PMA_langSet($fall_back_lang)) {
+        trigger_error(
+            'phpMyAdmin-ERROR: invalid lang code: '
+            . __FILE__ . '#' . $line . ', check hard coded fall back language.',
+            E_USER_WARNING
+        );
+        // stop execution
+        // and tell the user that his chosen language is invalid
+        PMA_fatalError('Could not load any language, please check your language settings and folder.');
+    }
+}
+
+// Set locale
+_setlocale(LC_MESSAGES, $GLOBALS['lang']);
+_bindtextdomain('phpmyadmin', $GLOBALS['lang_path']);
+_bind_textdomain_codeset('phpmyadmin', 'UTF-8');
+_textdomain('phpmyadmin');
+
+/**
+ * Messages for phpMyAdmin.
+ *
+ * These messages are here for easy transition to Gettext.
+ * You should not add any messages here, use instead gettext directly
+ * in your template/PHP file.
+ */
+
+if (! function_exists('__')) {
+    PMA_fatalError('Bad invocation!');
+}
+
+/* Text direction for language */
+if (in_array($GLOBALS['lang'], array('ar', 'fa', 'he', 'ur'))) {
+    $GLOBALS['text_dir'] = 'rtl';
+} else {
+    $GLOBALS['text_dir'] = 'ltr';
+}
+
+/* TCPDF */
+$GLOBALS['l'] = array();
+
+/* TCPDF settings */
+$GLOBALS['l']['a_meta_charset'] = 'UTF-8';
+$GLOBALS['l']['a_meta_dir'] = $GLOBALS['text_dir'];
+$GLOBALS['l']['a_meta_language'] = $GLOBALS['lang'];
+
+/* TCPDF translations */
+$GLOBALS['l']['w_page'] = __('Page number:');
+
+
+// now, that we have loaded the language strings we can send the errors
+if ($GLOBALS['lang_failed_cfg']) {
+    trigger_error(
+        sprintf(
+            __('Unknown language: %1$s.'),
+            htmlspecialchars($GLOBALS['lang_failed_cfg'])
+        ),
+        E_USER_ERROR
+    );
+}
+if ($GLOBALS['lang_failed_cookie']) {
+    trigger_error(
+        sprintf(
+            __('Unknown language: %1$s.'),
+            htmlspecialchars($GLOBALS['lang_failed_cookie'])
+        ),
+        E_USER_ERROR
+    );
+}
+if ($GLOBALS['lang_failed_request']) {
+    trigger_error(
+        sprintf(
+            __('Unknown language: %1$s.'),
+            htmlspecialchars($GLOBALS['lang_failed_request'])
+        ),
+        E_USER_ERROR
+    );
+}
+
+unset(
+    $line, $fall_back_lang, $GLOBALS['lang_failed_cfg'],
+    $GLOBALS['lang_failed_cookie'], $GLOBALS['lang_failed_request']
+);
+?>
diff --git a/phpmyadmin/libraries/select_server.lib.php b/phpmyadmin/libraries/select_server.lib.php
new file mode 100644
index 0000000..dfaba53
--- /dev/null
+++ b/phpmyadmin/libraries/select_server.lib.php
@@ -0,0 +1,108 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * Code for displaying server selection
+ *
+ * @package PhpMyAdmin
+ */
+if (! defined('PHPMYADMIN')) {
+    exit;
+}
+
+/**
+ * Renders the server selection in list or selectbox form, or option tags only
+ *
+ * @param boolean $not_only_options whether to include form tags or not
+ * @param boolean $ommit_fieldset   whether to ommit fieldset tag or not
+ *
+ * @return string
+ */
+function PMA_selectServer($not_only_options, $ommit_fieldset)
+{
+    $retval = '';
+
+    // Show as list?
+    if ($not_only_options) {
+        $list = $GLOBALS['cfg']['DisplayServersList'];
+        $not_only_options =! $list;
+    } else {
+        $list = false;
+    }
+
+    if ($not_only_options) {
+        $retval .= '<form method="post" action="' . $GLOBALS['cfg']['DefaultTabServer'] . '" class="disableAjax">';
+        $retval .= PMA_generate_common_hidden_inputs();
+
+        if (! $ommit_fieldset) {
+            $retval .= '<fieldset>';
+        }
+        $retval .= '<label for="select_server">' . __('Current Server') . ':</label> ';
+
+        $retval .= '<select name="server" id="select_server" class="autosubmit">';
+        $retval .= '<option value="">(' . __('Servers') . ') ...</option>' . "\n";
+    } elseif ($list) {
+        $retval .= __('Current Server') . ':<br />';
+        $retval .= '<ul id="list_server">';
+    }
+
+    foreach ($GLOBALS['cfg']['Servers'] as $key => $server) {
+        if (empty($server['host'])) {
+            continue;
+        }
+
+        if (!empty($GLOBALS['server']) && (int) $GLOBALS['server'] === (int) $key) {
+            $selected = 1;
+        } else {
+            $selected = 0;
+        }
+        if (!empty($server['verbose'])) {
+            $label = $server['verbose'];
+        } else {
+            $label = $server['host'];
+            if (!empty($server['port'])) {
+                $label .= ':' . $server['port'];
+            }
+        }
+        if (! empty($server['only_db'])) {
+            if (! is_array($server['only_db'])) {
+                $label .= ' - ' . $server['only_db'];
+                // try to avoid displaying a too wide selector
+            } elseif (count($server['only_db']) < 4) {
+                $label .= ' - ' . implode(', ', $server['only_db']);
+            }
+        }
+        if (!empty($server['user']) && $server['auth_type'] == 'config') {
+            $label .= '  (' . $server['user'] . ')';
+        }
+
+        if ($list) {
+            $retval .= '<li>';
+            if ($selected) {
+                $retval .= '<strong>' . htmlspecialchars($label) . '</strong>';
+            } else {
+
+                $retval .= '<a class="disableAjax item" href="' . $GLOBALS['cfg']['DefaultTabServer']
+                    . PMA_generate_common_url(array('server' => $key))
+                    . '" >' . htmlspecialchars($label) . '</a>';
+            }
+            $retval .= '</li>';
+        } else {
+            $retval .= '<option value="' . $key . '" '
+                . ($selected ? ' selected="selected"' : '') . '>'
+                . htmlspecialchars($label) . '</option>' . "\n";
+        }
+    } // end while
+
+    if ($not_only_options) {
+        $retval .= '</select>';
+        if (! $ommit_fieldset) {
+            $retval .= '</fieldset>';
+        }
+        $retval .= '</form>';
+    } elseif ($list) {
+        $retval .= '</ul>';
+    }
+
+    return $retval;
+}
+?>
diff --git a/phpmyadmin/libraries/server_common.inc.php b/phpmyadmin/libraries/server_common.inc.php
new file mode 100644
index 0000000..39cc838
--- /dev/null
+++ b/phpmyadmin/libraries/server_common.inc.php
@@ -0,0 +1,56 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * @package PhpMyAdmin
+ */
+if (! defined('PHPMYADMIN')) {
+    exit;
+}
+
+/**
+ * Handles some variables that may have been sent by the calling script
+ * Note: this can be called also from the db panel to get the privileges of
+ *       a db, in which case we want to keep displaying the tabs of
+ *       the Database panel
+ */
+if (empty($viewing_mode)) {
+    $db = $table = '';
+}
+
+/**
+ * Set parameters for links
+ */
+$url_query = PMA_generate_common_url($db);
+
+/**
+ * Defines the urls to return to in case of error in a sql statement
+ */
+$err_url = 'index.php' . $url_query;
+
+/**
+ * @global boolean Checks for superuser privileges
+ */
+$is_superuser = PMA_isSuperuser();
+
+// now, select the mysql db
+if ($is_superuser && ! PMA_DRIZZLE) {
+    PMA_DBI_select_db('mysql', $userlink);
+}
+
+/**
+ * @global array binary log files
+ */
+$binary_logs = PMA_DRIZZLE
+    ? null
+    : PMA_DBI_fetch_result(
+        'SHOW MASTER LOGS',
+        'Log_name',
+        null,
+        null,
+        PMA_DBI_QUERY_STORE
+    );
+
+PMA_Util::checkParameters(
+    array('is_superuser', 'url_query'), false
+);
+?>
diff --git a/phpmyadmin/libraries/server_privileges.lib.php b/phpmyadmin/libraries/server_privileges.lib.php
new file mode 100644
index 0000000..44e16d3
--- /dev/null
+++ b/phpmyadmin/libraries/server_privileges.lib.php
@@ -0,0 +1,3355 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * set of functions with the Privileges section in pma
+ *
+ * @package PhpMyAdmin
+ */
+
+if (! defined('PHPMYADMIN')) {
+    exit;
+}
+/**
+ * Escapes wildcard in a database+table specification
+ * before using it in a GRANT statement.
+ *
+ * Escaping a wildcard character in a GRANT is only accepted at the global
+ * or database level, not at table level; this is why I remove
+ * the escaping character. Internally, in mysql.tables_priv.Db there are
+ * no escaping (for example test_db) but in mysql.db you'll see test\_db
+ * for a db-specific privilege.
+ *
+ * @param string $dbname    Database name
+ * @param string $tablename Table name
+ *
+ * @return string the escaped (if necessary) database.table
+ */
+function PMA_wildcardEscapeForGrant($dbname, $tablename)
+{
+    if (! strlen($dbname)) {
+        $db_and_table = '*.*';
+    } else {
+        if (strlen($tablename)) {
+            $db_and_table = PMA_Util::backquote(
+                PMA_Util::unescapeMysqlWildcards($dbname)
+            )
+            . '.' . PMA_Util::backquote($tablename);
+        } else {
+            $db_and_table = PMA_Util::backquote($dbname) . '.*';
+        }
+    }
+    return $db_and_table;
+}
+
+/**
+ * Generates a condition on the user name
+ *
+ * @param string $initial the user's initial
+ *
+ * @return string   the generated condition
+ */
+function PMA_rangeOfUsers($initial = '')
+{
+    // strtolower() is used because the User field
+    // might be BINARY, so LIKE would be case sensitive
+    if (! empty($initial)) {
+        $ret = " WHERE `User` LIKE '"
+            . PMA_Util::sqlAddSlashes($initial, true) . "%'"
+            . " OR `User` LIKE '"
+            . PMA_Util::sqlAddSlashes(strtolower($initial), true) . "%'";
+    } else {
+        $ret = '';
+    }
+    return $ret;
+} // end function
+
+/**
+ * Extracts the privilege information of a priv table row
+ *
+ * @param array   $row        the row
+ * @param boolean $enableHTML add <dfn> tag with tooltips
+ *
+ * @global  resource $user_link the database connection
+ *
+ * @return array
+ */
+function PMA_extractPrivInfo($row = '', $enableHTML = false)
+{
+    $grants = PMA_getGrantsArray();
+
+    if (! empty($row) && isset($row['Table_priv'])) {
+        $row1 = PMA_DBI_fetch_single_row(
+            'SHOW COLUMNS FROM `mysql`.`tables_priv` LIKE \'Table_priv\';',
+            'ASSOC', $GLOBALS['userlink']
+        );
+        $av_grants = explode(
+            '\',\'',
+            substr($row1['Type'], 5, strlen($row1['Type']) - 7)
+        );
+        unset($row1);
+        $users_grants = explode(',', $row['Table_priv']);
+        foreach ($av_grants as $current_grant) {
+            $row[$current_grant . '_priv']
+                = in_array($current_grant, $users_grants) ? 'Y' : 'N';
+        }
+        unset($current_grant);
+    }
+
+    $privs = array();
+    $allPrivileges = true;
+    foreach ($grants as $current_grant) {
+        if ((! empty($row) && isset($row[$current_grant[0]]))
+            || (empty($row) && isset($GLOBALS[$current_grant[0]]))
+        ) {
+            if ((! empty($row) && $row[$current_grant[0]] == 'Y')
+                || (empty($row)
+                && ($GLOBALS[$current_grant[0]] == 'Y'
+                || (is_array($GLOBALS[$current_grant[0]])
+                && count($GLOBALS[$current_grant[0]]) == $_REQUEST['column_count']
+                && empty($GLOBALS[$current_grant[0] . '_none']))))
+            ) {
+                if ($enableHTML) {
+                    $privs[] = '<dfn title="' . $current_grant[2] . '">'
+                        . $current_grant[1] . '</dfn>';
+                } else {
+                    $privs[] = $current_grant[1];
+                }
+            } elseif (! empty($GLOBALS[$current_grant[0]])
+             && is_array($GLOBALS[$current_grant[0]])
+             && empty($GLOBALS[$current_grant[0] . '_none'])) {
+                if ($enableHTML) {
+                    $priv_string = '<dfn title="' . $current_grant[2] . '">'
+                        . $current_grant[1] . '</dfn>';
+                } else {
+                    $priv_string = $current_grant[1];
+                }
+                $privs[] = $priv_string . ' (`'
+                    . join('`, `', $GLOBALS[$current_grant[0]]) . '`)';
+            } else {
+                $allPrivileges = false;
+            }
+        }
+    }
+    if (empty($privs)) {
+        if ($enableHTML) {
+            $privs[] = '<dfn title="' . __('No privileges.') . '">USAGE</dfn>';
+        } else {
+            $privs[] = 'USAGE';
+        }
+    } elseif ($allPrivileges
+            && (! isset($_POST['grant_count'])
+            || count($privs) == $_POST['grant_count'])
+        ) {
+        if ($enableHTML) {
+            $privs = array('<dfn title="'
+                . __('Includes all privileges except GRANT.')
+                . '">ALL PRIVILEGES</dfn>'
+            );
+        } else {
+            $privs = array('ALL PRIVILEGES');
+        }
+    }
+    return $privs;
+} // end of the 'PMA_extractPrivInfo()' function
+
+/**
+ * Get the grants array which contains all the privilege types
+ * and relevent grant messages
+ *
+ * @return array
+ */
+function PMA_getGrantsArray()
+{
+    return array(
+        array(
+            'Select_priv',
+            'SELECT',
+            __('Allows reading data.')),
+        array(
+            'Insert_priv',
+            'INSERT',
+            __('Allows inserting and replacing data.')),
+        array(
+            'Update_priv',
+            'UPDATE',
+            __('Allows changing data.')),
+        array(
+            'Delete_priv',
+            'DELETE',
+            __('Allows deleting data.')),
+        array(
+            'Create_priv',
+            'CREATE',
+            __('Allows creating new databases and tables.')),
+        array(
+            'Drop_priv',
+            'DROP',
+            __('Allows dropping databases and tables.')),
+        array(
+            'Reload_priv',
+            'RELOAD',
+            __('Allows reloading server settings and flushing the server\'s caches.')),
+        array(
+            'Shutdown_priv',
+            'SHUTDOWN',
+            __('Allows shutting down the server.')),
+        array(
+            'Process_priv',
+            'PROCESS',
+            __('Allows viewing processes of all users')),
+        array(
+            'File_priv',
+            'FILE',
+            __('Allows importing data from and exporting data into files.')),
+        array(
+            'References_priv',
+            'REFERENCES',
+            __('Has no effect in this MySQL version.')),
+        array(
+            'Index_priv',
+            'INDEX',
+            __('Allows creating and dropping indexes.')),
+        array(
+            'Alter_priv',
+            'ALTER',
+            __('Allows altering the structure of existing tables.')),
+        array(
+            'Show_db_priv',
+            'SHOW DATABASES',
+            __('Gives access to the complete list of databases.')),
+        array(
+            'Super_priv',
+            'SUPER',
+            __('Allows connecting, even if maximum number of connections is reached; required for most administrative operations like setting global variables or killing threads of other users.')),
+        array(
+            'Create_tmp_table_priv',
+            'CREATE TEMPORARY TABLES',
+            __('Allows creating temporary tables.')),
+        array(
+            'Lock_tables_priv',
+            'LOCK TABLES',
+            __('Allows locking tables for the current thread.')),
+        array(
+            'Repl_slave_priv',
+            'REPLICATION SLAVE',
+            __('Needed for the replication slaves.')),
+        array(
+            'Repl_client_priv',
+            'REPLICATION CLIENT',
+            __('Allows the user to ask where the slaves / masters are.')),
+        array(
+            'Create_view_priv',
+            'CREATE VIEW',
+            __('Allows creating new views.')),
+        array(
+            'Event_priv',
+            'EVENT',
+            __('Allows to set up events for the event scheduler')),
+        array(
+            'Trigger_priv',
+            'TRIGGER',
+            __('Allows creating and dropping triggers')),
+        // for table privs:
+        array(
+            'Create View_priv',
+            'CREATE VIEW',
+            __('Allows creating new views.')),
+        array(
+            'Show_view_priv',
+            'SHOW VIEW',
+            __('Allows performing SHOW CREATE VIEW queries.')),
+        // for table privs:
+        array(
+            'Show view_priv',
+            'SHOW VIEW',
+            __('Allows performing SHOW CREATE VIEW queries.')),
+        array(
+            'Create_routine_priv',
+            'CREATE ROUTINE',
+            __('Allows creating stored routines.')),
+        array(
+            'Alter_routine_priv',
+            'ALTER ROUTINE',
+            __('Allows altering and dropping stored routines.')),
+        array(
+            'Create_user_priv',
+            'CREATE USER',
+            __('Allows creating, dropping and renaming user accounts.')),
+        array(
+            'Execute_priv',
+            'EXECUTE',
+            __('Allows executing stored routines.')),
+    );
+}
+
+/**
+ * Displays on which column(s) a table-specific privilege is granted
+ *
+ * @param array  $columns          columns array
+ * @param array  $row              first row from result or boolean false
+ * @param string $name_for_select  privilege types - Select_priv, Insert_priv
+ *                                 Update_priv, References_priv
+ * @param string $priv_for_header  privilege for header
+ * @param string $name             privilege name: insert, select, update, references
+ * @param string $name_for_dfn     name for dfn
+ * @param string $name_for_current name for current
+ *
+ * @return $html_output             html snippet
+ */
+function PMA_getHtmlForDisplayColumnPrivileges($columns, $row, $name_for_select,
+    $priv_for_header, $name, $name_for_dfn, $name_for_current
+) {
+    $html_output = '<div class="item" id="div_item_' . $name . '">' . "\n"
+        . '<label for="select_' . $name . '_priv">' . "\n"
+        . '<code><dfn title="' . $name_for_dfn . '">'
+        . $priv_for_header . '</dfn></code>' . "\n"
+        . '</label><br />' . "\n"
+        . '<select id="select_' . $name . '_priv" name="'
+        . $name_for_select . '[]" multiple="multiple" size="8">' . "\n";
+
+    foreach ($columns as $current_column => $current_column_privileges) {
+        $html_output .= '<option '
+            . 'value="' . htmlspecialchars($current_column) . '"';
+        if ($row[$name_for_select] == 'Y'
+            || $current_column_privileges[$name_for_current]
+        ) {
+            $html_output .= ' selected="selected"';
+        }
+        $html_output .= '>'
+            . htmlspecialchars($current_column) . '</option>' . "\n";
+    }
+
+    $html_output .= '</select>' . "\n"
+        . '<i>' . __('Or') . '</i>' . "\n"
+        . '<label for="checkbox_' . $name_for_select
+        . '_none"><input type="checkbox"'
+        . ' name="' . $name_for_select . '_none" id="checkbox_'
+        . $name_for_select . '_none" title="'
+        . _pgettext('None privileges', 'None') . '" />'
+        . _pgettext('None privileges', 'None') . '</label>' . "\n"
+        . '</div>' . "\n";
+    return $html_output;
+} // end function
+
+/**
+ * Get sql query for display privileges table
+ *
+ * @param string $db       the database
+ * @param string $table    the table
+ * @param string $username username for database connection
+ * @param string $hostname hostname for database connection
+ *
+ * @return string sql query
+ */
+function PMA_getSqlQueryForDisplayPrivTable($db, $table, $username, $hostname)
+{
+    if ($db == '*') {
+        return "SELECT * FROM `mysql`.`user`"
+            ." WHERE `User` = '" . PMA_Util::sqlAddSlashes($username) . "'"
+            ." AND `Host` = '" . PMA_Util::sqlAddSlashes($hostname) . "';";
+    } elseif ($table == '*') {
+        return "SELECT * FROM `mysql`.`db`"
+            ." WHERE `User` = '" . PMA_Util::sqlAddSlashes($username) . "'"
+            ." AND `Host` = '" . PMA_Util::sqlAddSlashes($hostname) . "'"
+            ." AND '" . PMA_Util::unescapeMysqlWildcards($db) . "'"
+            ." LIKE `Db`;";
+    }
+    return "SELECT `Table_priv`"
+        ." FROM `mysql`.`tables_priv`"
+        ." WHERE `User` = '" . PMA_Util::sqlAddSlashes($username) . "'"
+        ." AND `Host` = '" . PMA_Util::sqlAddSlashes($hostname) . "'"
+        ." AND `Db` = '" . PMA_Util::unescapeMysqlWildcards($db) . "'"
+        ." AND `Table_name` = '" . PMA_Util::sqlAddSlashes($table) . "';";
+}
+/**
+ * Displays the privileges form table
+ *
+ * @param string  $db       the database
+ * @param string  $table    the table
+ * @param boolean $submit   wheather to display the submit button or not
+ *
+ * @global  array      $cfg         the phpMyAdmin configuration
+ * @global  ressource  $user_link   the database connection
+ *
+ * @return string html snippet
+ */
+function PMA_getHtmlToDisplayPrivilegesTable($db = '*',
+    $table = '*', $submit = true
+) {
+    $html_output = '';
+
+    if ($db == '*') {
+        $table = '*';
+    }
+
+    if (isset($GLOBALS['username'])) {
+        $username = $GLOBALS['username'];
+        $hostname = $GLOBALS['hostname'];
+        $sql_query = PMA_getSqlQueryForDisplayPrivTable(
+            $db, $table, $username, $hostname
+        );
+        $row = PMA_DBI_fetch_single_row($sql_query);
+    }
+    if (empty($row)) {
+        if ($table == '*') {
+            if ($db == '*') {
+                $sql_query = 'SHOW COLUMNS FROM `mysql`.`user`;';
+            } elseif ($table == '*') {
+                $sql_query = 'SHOW COLUMNS FROM `mysql`.`db`;';
+            }
+            $res = PMA_DBI_query($sql_query);
+            while ($row1 = PMA_DBI_fetch_row($res)) {
+                if (substr($row1[0], 0, 4) == 'max_') {
+                    $row[$row1[0]] = 0;
+                } else {
+                    $row[$row1[0]] = 'N';
+                }
+            }
+            PMA_DBI_free_result($res);
+        } else {
+            $row = array('Table_priv' => '');
+        }
+    }
+    if (isset($row['Table_priv'])) {
+        $row1 = PMA_DBI_fetch_single_row(
+            'SHOW COLUMNS FROM `mysql`.`tables_priv` LIKE \'Table_priv\';',
+            'ASSOC', $GLOBALS['userlink']
+        );
+        // note: in MySQL 5.0.3 we get "Create View', 'Show view';
+        // the View for Create is spelled with uppercase V
+        // the view for Show is spelled with lowercase v
+        // and there is a space between the words
+
+        $av_grants = explode(
+            '\',\'',
+            substr(
+                $row1['Type'],
+                strpos($row1['Type'], '(') + 2,
+                strpos($row1['Type'], ')') - strpos($row1['Type'], '(') - 3
+            )
+        );
+        unset($row1);
+        $users_grants = explode(',', $row['Table_priv']);
+
+        foreach ($av_grants as $current_grant) {
+            $row[$current_grant . '_priv']
+                = in_array($current_grant, $users_grants) ? 'Y' : 'N';
+        }
+        unset($row['Table_priv'], $current_grant, $av_grants, $users_grants);
+
+        // get columns
+        $res = PMA_DBI_try_query(
+            'SHOW COLUMNS FROM '
+            . PMA_Util::backquote(
+                PMA_Util::unescapeMysqlWildcards($db)
+            )
+            . '.' . PMA_Util::backquote($table) . ';'
+        );
+        $columns = array();
+        if ($res) {
+            while ($row1 = PMA_DBI_fetch_row($res)) {
+                $columns[$row1[0]] = array(
+                    'Select' => false,
+                    'Insert' => false,
+                    'Update' => false,
+                    'References' => false
+                );
+            }
+            PMA_DBI_free_result($res);
+        }
+        unset($res, $row1);
+    }
+    // t a b l e - s p e c i f i c    p r i v i l e g e s
+    if (! empty($columns)) {
+        $html_output .= PMA_getHtmlForTableSpecificPrivileges(
+            $username, $hostname, $db, $table, $columns, $row
+        );
+    } else {
+        // g l o b a l    o r    d b - s p e c i f i c
+        $html_output .= PMA_getHtmlForGlobalOrDbSpecificPrivs($db, $table, $row);
+    }
+    $html_output .= '</fieldset>' . "\n";
+    if ($submit) {
+        $html_output .= '<fieldset id="fieldset_user_privtable_footer" '
+            . 'class="tblFooters">' . "\n"
+           . '<input type="submit" name="update_privs" '
+            . 'value="' . __('Go') . '" />' . "\n"
+           . '</fieldset>' . "\n";
+    }
+    return $html_output;
+} // end of the 'PMA_displayPrivTable()' function
+
+/**
+ * Get HTML for "Resource limits"
+ *
+ * @param array $row first row from result or boolean false
+ *
+ * @return string html snippet
+ */
+function PMA_getHtmlForDisplayResourceLimits($row)
+{
+    $html_output = '<fieldset>' . "\n"
+        . '<legend>' . __('Resource limits') . '</legend>' . "\n"
+        . '<p><small>'
+        . '<i>' . __('Note: Setting these options to 0 (zero) removes the limit.')
+        . '</i></small></p>' . "\n";
+
+    $html_output .= '<div class="item">' . "\n"
+        . '<label for="text_max_questions">'
+        . '<code><dfn title="'
+        . __('Limits the number of queries the user may send to the server per hour.')
+        . '">'
+        . 'MAX QUERIES PER HOUR'
+        . '</dfn></code></label>' . "\n"
+        . '<input type="text" name="max_questions" id="text_max_questions" '
+        . 'value="' . $row['max_questions'] . '" '
+        . 'size="11" maxlength="11" '
+        . 'title="'
+        . __('Limits the number of queries the user may send to the server per hour.')
+        . '" />' . "\n"
+        . '</div>' . "\n";
+
+    $html_output .= '<div class="item">' . "\n"
+        . '<label for="text_max_updates">'
+        . '<code><dfn title="'
+        . __('Limits the number of commands that change any table or database the user may execute per hour.') . '">'
+        . 'MAX UPDATES PER HOUR'
+        . '</dfn></code></label>' . "\n"
+        . '<input type="text" name="max_updates" id="text_max_updates" '
+        . 'value="' . $row['max_updates'] . '" size="11" maxlength="11" '
+        . 'title="'
+        . __('Limits the number of commands that change any table or database the user may execute per hour.')
+        . '" />' . "\n"
+        . '</div>' . "\n";
+
+    $html_output .= '<div class="item">' . "\n"
+        . '<label for="text_max_connections">'
+        . '<code><dfn title="'
+        . __('Limits the number of new connections the user may open per hour.') . '">'
+        . 'MAX CONNECTIONS PER HOUR'
+        . '</dfn></code></label>' . "\n"
+        . '<input type="text" name="max_connections" id="text_max_connections" '
+        . 'value="' . $row['max_connections'] . '" size="11" maxlength="11" '
+        . 'title="' . __('Limits the number of new connections the user may open per hour.')
+        . '" />' . "\n"
+        . '</div>' . "\n";
+
+    $html_output .= '<div class="item">' . "\n"
+        . '<label for="text_max_user_connections">'
+        . '<code><dfn title="'
+        . __('Limits the number of simultaneous connections the user may have.')
+        . '">'
+        . 'MAX USER_CONNECTIONS'
+        . '</dfn></code></label>' . "\n"
+        . '<input type="text" name="max_user_connections" '
+        . 'id="text_max_user_connections" '
+        . 'value="' . $row['max_user_connections'] . '" size="11" maxlength="11" '
+        . 'title="'
+        . __('Limits the number of simultaneous connections the user may have.')
+        . '" />' . "\n"
+        . '</div>' . "\n";
+
+    $html_output .= '</fieldset>' . "\n";
+
+    return $html_output;
+}
+
+/**
+ * Get the HTML snippet for table specific privileges
+ *
+ * @param string  $username username for database connection
+ * @param string  $hostname hostname for database connection
+ * @param string  $db       the database
+ * @param string  $table    the table
+ * @param boolean $columns  columns array
+ * @param         $row
+ *
+ * @return string $html_output
+ */
+function PMA_getHtmlForTableSpecificPrivileges($username, $hostname, $db,
+    $table, $columns, $row
+) {
+    $res = PMA_DBI_query(
+        'SELECT `Column_name`, `Column_priv`'
+        .' FROM `mysql`.`columns_priv`'
+        .' WHERE `User`'
+        .' = \'' . PMA_Util::sqlAddSlashes($username) . "'"
+        .' AND `Host`'
+        .' = \'' . PMA_Util::sqlAddSlashes($hostname) . "'"
+        .' AND `Db`'
+        .' = \'' . PMA_Util::sqlAddSlashes(
+            PMA_Util::unescapeMysqlWildcards($db)
+        ) . "'"
+        .' AND `Table_name`'
+        .' = \'' . PMA_Util::sqlAddSlashes($table) . '\';'
+    );
+
+    while ($row1 = PMA_DBI_fetch_row($res)) {
+        $row1[1] = explode(',', $row1[1]);
+        foreach ($row1[1] as $current) {
+            $columns[$row1[0]][$current] = true;
+        }
+    }
+    PMA_DBI_free_result($res);
+    unset($res, $row1, $current);
+
+    $html_output = '<input type="hidden" name="grant_count" '
+        . 'value="' . count($row) . '" />' . "\n"
+        . '<input type="hidden" name="column_count" '
+        . 'value="' . count($columns) . '" />' . "\n"
+        . '<fieldset id="fieldset_user_priv">' . "\n"
+        . '<legend>' . __('Table-specific privileges')
+        . PMA_Util::showHint(
+            __('Note: MySQL privilege names are expressed in English')
+        )
+        . '</legend>' . "\n";
+
+    // privs that are attached to a specific column
+    $html_output .= PMA_getHtmlForAttachedPrivilegesToTableSpecificColumn(
+        $columns, $row
+    );
+
+    // privs that are not attached to a specific column
+    $html_output .= '<div class="item">' . "\n"
+        . PMA_getHtmlForNotAttachedPrivilegesToTableSpecificColumn($row)
+        . '</div>' . "\n";
+
+    // for Safari 2.0.2
+    $html_output .= '<div class="clearfloat"></div>' . "\n";
+
+    return $html_output;
+}
+
+/**
+ * Get HTML snippet for privileges that are attached to a specific column
+ *
+ * @param string $columns olumns array
+ * @param array  $row     first row from result or boolean false
+ *
+ * @return string $html_output
+ */
+function PMA_getHtmlForAttachedPrivilegesToTableSpecificColumn($columns, $row)
+{
+    $html_output = PMA_getHtmlForDisplayColumnPrivileges(
+        $columns, $row, 'Select_priv', 'SELECT',
+        'select', __('Allows reading data.'), 'Select'
+    );
+
+    $html_output .= PMA_getHtmlForDisplayColumnPrivileges(
+        $columns, $row, 'Insert_priv', 'INSERT',
+        'insert', __('Allows inserting and replacing data.'), 'Insert'
+    );
+
+    $html_output .= PMA_getHtmlForDisplayColumnPrivileges(
+        $columns, $row, 'Update_priv', 'UPDATE',
+        'update', __('Allows changing data.'), 'Update'
+    );
+
+    $html_output .= PMA_getHtmlForDisplayColumnPrivileges(
+        $columns, $row, 'References_priv', 'REFERENCES', 'references',
+        __('Has no effect in this MySQL version.'), 'References'
+    );
+    return $html_output;
+}
+
+/**
+ * Get HTML for privileges that are not attached to a specific column
+ *
+ * @param array $row first row from result or boolean false
+ *
+ * @return string $html_output
+ */
+function PMA_getHtmlForNotAttachedPrivilegesToTableSpecificColumn($row)
+{
+    $html_output = '';
+    foreach ($row as $current_grant => $current_grant_value) {
+        $grant_type = substr($current_grant, 0, (strlen($current_grant) - 5));
+        if (in_array($grant_type, array('Select', 'Insert', 'Update', 'References'))) {
+            continue;
+        }
+        // make a substitution to match the messages variables;
+        // also we must substitute the grant we get, because we can't generate
+        // a form variable containing blanks (those would get changed to
+        // an underscore when receiving the POST)
+        if ($current_grant == 'Create View_priv') {
+            $tmp_current_grant = 'CreateView_priv';
+            $current_grant = 'Create_view_priv';
+        } elseif ($current_grant == 'Show view_priv') {
+            $tmp_current_grant = 'ShowView_priv';
+            $current_grant = 'Show_view_priv';
+        } else {
+            $tmp_current_grant = $current_grant;
+        }
+
+        $html_output .= '<div class="item">' . "\n"
+           . '<input type="checkbox"'
+           . ' name="' . $current_grant . '" id="checkbox_' . $current_grant
+           . '" value="Y" '
+           . ($current_grant_value == 'Y' ? 'checked="checked" ' : '')
+           . 'title="';
+
+        $html_output .= (isset($GLOBALS[
+                    'strPrivDesc' . substr(
+                        $tmp_current_grant, 0, (strlen($tmp_current_grant) - 5)
+                    )
+                ] )
+                ? $GLOBALS[
+                    'strPrivDesc' . substr(
+                        $tmp_current_grant, 0, (strlen($tmp_current_grant) - 5)
+                    )
+                ]
+                : $GLOBALS[
+                    'strPrivDesc' . substr(
+                        $tmp_current_grant, 0, (strlen($tmp_current_grant) - 5)
+                    ) . 'Tbl'
+                ]
+            )
+            . '"/>' . "\n";
+
+        $html_output .= '<label for="checkbox_' . $current_grant
+            . '"><code><dfn title="'
+            . (isset($GLOBALS[
+                    'strPrivDesc' . substr(
+                        $tmp_current_grant, 0, (strlen($tmp_current_grant) - 5)
+                    )
+                ])
+                ? $GLOBALS[
+                    'strPrivDesc' . substr(
+                        $tmp_current_grant, 0, (strlen($tmp_current_grant) - 5)
+                    )
+                ]
+                : $GLOBALS[
+                    'strPrivDesc' . substr(
+                        $tmp_current_grant, 0, (strlen($tmp_current_grant) - 5)
+                    ) . 'Tbl'
+                ]
+            )
+            . '">'
+            . strtoupper(
+                substr($current_grant, 0, strlen($current_grant) - 5)
+            )
+            . '</dfn></code></label>' . "\n"
+            . '</div>' . "\n";
+    } // end foreach ()
+    return $html_output;
+}
+
+/**
+ * Get HTML for global or database specific privileges
+ *
+ * @param string $db       the database
+ * @param string $table    the table
+ * @param string $row      first row from result or boolean false
+ *
+ * @return string $html_output
+ */
+function PMA_getHtmlForGlobalOrDbSpecificPrivs($db, $table, $row)
+{
+    $privTable_names = array(0 => __('Data'),
+        1 => __('Structure'),
+        2 => __('Administration')
+    );
+    $privTable = array();
+    // d a t a
+    $privTable[0] = PMA_getDataPrivilegeTable($db);
+
+    // s t r u c t u r e
+    $privTable[1] = PMA_getStructurePrivilegeTable($table, $row);
+
+    // a d m i n i s t r a t i o n
+    $privTable[2] = PMA_getAdministrationPrivilegeTable($db);
+
+    $html_output = '<input type="hidden" name="grant_count" value="'
+        . (count($privTable[0])
+            + count($privTable[1])
+            + count($privTable[2])
+            - (isset($row['Grant_priv']) ? 1 : 0)
+        )
+        . '" />';
+    $html_output .= '<fieldset id="fieldset_user_global_rights"><legend>';
+    if ($db == '*') {
+        $html_output .= __('Global privileges');
+    } else if ($table == '*') {
+        $html_output .= __('Database-specific privileges');
+    } else {
+        $html_output .= __('Table-specific privileges');
+    }
+    $html_output .= ' (<a href="#" '
+        . 'onclick="setCheckboxes(\'fieldset_user_global_rights\', true); '
+        . 'return false;">' . __('Check All') . '</a> /'
+        . '<a href="#" '
+        . 'onclick="setCheckboxes(\'fieldset_user_global_rights\', false); '
+        . 'return false;">' . __('Uncheck All') . '</a>)';
+    $html_output .= '</legend>';
+    $html_output .= '<p><small><i>'
+        . __('Note: MySQL privilege names are expressed in English')
+        . '</i></small></p>';
+
+    // Output the Global privilege tables with checkboxes
+    $html_output .= PMA_getHtmlForGlobalPrivTableWithCheckboxes(
+        $privTable, $privTable_names, $row
+    );
+
+    // The "Resource limits" box is not displayed for db-specific privs
+    if ($db == '*') {
+        $html_output .= PMA_getHtmlForDisplayResourceLimits($row);
+    }
+    // for Safari 2.0.2
+    $html_output .= '<div class="clearfloat"></div>';
+
+    return $html_output;
+}
+
+/**
+ * Get data privilege table as an array
+ *
+ * @param string $db the database
+ *
+ * @return string data privilege table
+ */
+function PMA_getDataPrivilegeTable($db)
+{
+    $data_privTable = array(
+        array('Select', 'SELECT', __('Allows reading data.')),
+        array('Insert', 'INSERT', __('Allows inserting and replacing data.')),
+        array('Update', 'UPDATE', __('Allows changing data.')),
+        array('Delete', 'DELETE', __('Allows deleting data.'))
+    );
+    if ($db == '*') {
+        $data_privTable[]
+            = array('File',
+                'FILE',
+                __('Allows importing data from and exporting data into files.')
+            );
+    }
+    return $data_privTable;
+}
+
+/**
+ * Get structure privilege table as an array
+ *
+ * @param string $table the table
+ * @param array  $row   first row from result or boolean false
+ *
+ * @return string structure privilege table
+ */
+function PMA_getStructurePrivilegeTable($table, $row)
+{
+    $structure_privTable = array(
+        array('Create',
+            'CREATE',
+            ($table == '*'
+                ? __('Allows creating new databases and tables.')
+                : __('Allows creating new tables.')
+            )
+        ),
+        array('Alter',
+            'ALTER',
+            __('Allows altering the structure of existing tables.')
+        ),
+        array('Index', 'INDEX', __('Allows creating and dropping indexes.')),
+        array('Drop',
+            'DROP',
+            ($table == '*'
+                ? __('Allows dropping databases and tables.')
+                : __('Allows dropping tables.')
+            )
+        ),
+        array('Create_tmp_table',
+            'CREATE TEMPORARY TABLES',
+            __('Allows creating temporary tables.')
+        ),
+        array('Show_view',
+            'SHOW VIEW',
+            __('Allows performing SHOW CREATE VIEW queries.')
+        ),
+        array('Create_routine',
+            'CREATE ROUTINE',
+            __('Allows creating stored routines.')
+        ),
+        array('Alter_routine',
+            'ALTER ROUTINE',
+            __('Allows altering and dropping stored routines.')
+        ),
+        array('Execute', 'EXECUTE', __('Allows executing stored routines.')),
+    );
+    // this one is for a db-specific priv: Create_view_priv
+    if (isset($row['Create_view_priv'])) {
+        $structure_privTable[] = array('Create_view',
+            'CREATE VIEW',
+            __('Allows creating new views.')
+        );
+    }
+    // this one is for a table-specific priv: Create View_priv
+    if (isset($row['Create View_priv'])) {
+        $structure_privTable[] = array('Create View',
+            'CREATE VIEW',
+            __('Allows creating new views.')
+        );
+    }
+    if (isset($row['Event_priv'])) {
+        // MySQL 5.1.6
+        $structure_privTable[] = array('Event',
+            'EVENT',
+            __('Allows to set up events for the event scheduler')
+        );
+        $structure_privTable[] = array('Trigger',
+            'TRIGGER',
+            __('Allows creating and dropping triggers')
+        );
+    }
+    return $structure_privTable;
+}
+
+/**
+ * Get administration privilege table as an array
+ *
+ * @param string $db the table
+ *
+ * @return string administration privilege table
+ */
+function PMA_getAdministrationPrivilegeTable($db)
+{
+    $administration_privTable = array(
+        array('Grant',
+            'GRANT',
+            __('Allows adding users and privileges without reloading the privilege tables.')
+        ),
+    );
+    if ($db == '*') {
+        $administration_privTable[] = array('Super',
+            'SUPER',
+            __('Allows connecting, even if maximum number of connections is reached; required for most administrative operations like setting global variables or killing threads of other users.')
+        );
+        $administration_privTable[] = array('Process',
+            'PROCESS',
+            __('Allows viewing processes of all users')
+        );
+        $administration_privTable[] = array('Reload',
+            'RELOAD',
+            __('Allows reloading server settings and flushing the server\'s caches.')
+        );
+        $administration_privTable[] = array('Shutdown',
+            'SHUTDOWN',
+            __('Allows shutting down the server.')
+        );
+        $administration_privTable[] = array('Show_db',
+            'SHOW DATABASES',
+            __('Gives access to the complete list of databases.')
+        );
+    }
+    $administration_privTable[] = array('Lock_tables',
+        'LOCK TABLES',
+        __('Allows locking tables for the current thread.')
+    );
+    $administration_privTable[] = array('References',
+        'REFERENCES',
+        __('Has no effect in this MySQL version.')
+    );
+    if ($db == '*') {
+        $administration_privTable[] = array('Repl_client',
+            'REPLICATION CLIENT',
+            __('Allows the user to ask where the slaves / masters are.')
+        );
+        $administration_privTable[] = array('Repl_slave',
+            'REPLICATION SLAVE',
+            __('Needed for the replication slaves.')
+        );
+        $administration_privTable[] = array('Create_user',
+            'CREATE USER',
+            __('Allows creating, dropping and renaming user accounts.')
+        );
+    }
+    return $administration_privTable;
+}
+
+/**
+ * Get HTML snippet for global privileges table with check boxes
+ *
+ * @param array $privTable       privileges table array
+ * @param array $privTable_names names of the privilege tables
+ *                               (Data, Structure, Administration)
+ * @param array $row             first row from result or boolean false
+ *
+ * @return string $html_output
+ */
+function PMA_getHtmlForGlobalPrivTableWithCheckboxes(
+    $privTable, $privTable_names, $row
+) {
+    $html_output = '';
+    foreach ($privTable as $i => $table) {
+        $html_output .= '<fieldset>' . "\n"
+            . '<legend>' . $privTable_names[$i] . '</legend>' . "\n";
+        foreach ($table as $priv) {
+            $html_output .= '<div class="item">' . "\n"
+                . '<input type="checkbox"'
+                . ' name="' . $priv[0] . '_priv" '
+                . 'id="checkbox_' . $priv[0] . '_priv"'
+                . ' value="Y" title="' . $priv[2] . '"'
+                . (($row[$priv[0] . '_priv'] == 'Y')
+                    ?  ' checked="checked"'
+                    : ''
+                )
+                . '/>' . "\n"
+                . '<label for="checkbox_' . $priv[0] . '_priv">'
+                . '<code><dfn title="' . $priv[2] . '">'
+                . $priv[1] . '</dfn></code></label>' . "\n"
+                . '</div>' . "\n";
+        }
+        $html_output .= '</fieldset>' . "\n";
+    }
+    return $html_output;
+}
+
+/**
+ * Displays the fields used by the "new user" form as well as the
+ * "change login information / copy user" form.
+ *
+ * @param string $mode are we creating a new user or are we just
+ *                     changing  one? (allowed values: 'new', 'change')
+ *
+ * @global  array      $cfg     the phpMyAdmin configuration
+ * @global  ressource  $user_link the database connection
+ *
+ * @return string $html_output  a HTML snippet
+ */
+function PMA_getHtmlForDisplayLoginInformationFields($mode = 'new')
+{
+    list($username_length, $hostname_length) = PMA_getUsernameAndHostnameLength();
+
+    if (isset($GLOBALS['username']) && strlen($GLOBALS['username']) === 0) {
+        $GLOBALS['pred_username'] = 'any';
+    }
+    $html_output = '<fieldset id="fieldset_add_user_login">' . "\n"
+        . '<legend>' . __('Login Information') . '</legend>' . "\n"
+        . '<div class="item">' . "\n"
+        . '<label for="select_pred_username">' . "\n"
+        . '    ' . __('User name') . ':' . "\n"
+        . '</label>' . "\n"
+        . '<span class="options">' . "\n";
+
+    $html_output .= '<select name="pred_username" id="select_pred_username" '
+        . 'title="' . __('User name') . '"' . "\n";
+
+
+    $html_output .= '        onchange="'
+        . 'if (this.value == \'any\') {'
+        . '    username.value = \'\'; '
+        . '} else if (this.value == \'userdefined\') {'
+        . '    username.focus(); username.select(); '
+        . '}">' . "\n";
+
+    $html_output .= '<option value="any"'
+        . ((isset($GLOBALS['pred_username']) && $GLOBALS['pred_username'] == 'any')
+            ? ' selected="selected"'
+            : '') . '>'
+        . __('Any user')
+        . '</option>' . "\n";
+
+    $html_output .= '<option value="userdefined"'
+        . ((! isset($GLOBALS['pred_username'])
+                || $GLOBALS['pred_username'] == 'userdefined'
+            )
+            ? ' selected="selected"'
+            : '') . '>'
+        . __('Use text field')
+        . ':</option>' . "\n";
+
+    $html_output .= '</select>' . "\n"
+        . '</span>' . "\n";
+
+    $html_output .= '<input type="text" name="username" class="autofocus"'
+        . ' maxlength="' . $username_length . '" title="' . __('User name') . '"'
+        . (empty($GLOBALS['username'])
+           ? ''
+           : ' value="' . htmlspecialchars(
+               isset($GLOBALS['new_username'])
+               ? $GLOBALS['new_username']
+               : $GLOBALS['username']
+           ) . '"'
+        )
+        . ' onchange="pred_username.value = \'userdefined\';" />' . "\n"
+        . '</div>' . "\n";
+
+    $html_output .= '<div class="item">' . "\n"
+        . '<label for="select_pred_hostname">' . "\n"
+        . '    ' . __('Host') . ':' . "\n"
+        . '</label>' . "\n";
+
+    $html_output .= '<span class="options">' . "\n"
+        . '    <select name="pred_hostname" id="select_pred_hostname" '
+        . 'title="' . __('Host') . '"' . "\n";
+    $_current_user = PMA_DBI_fetch_value('SELECT USER();');
+    if (! empty($_current_user)) {
+        $thishost = str_replace(
+            "'",
+            '',
+            substr($_current_user, (strrpos($_current_user, '@') + 1))
+        );
+        if ($thishost == 'localhost' || $thishost == '127.0.0.1') {
+            unset($thishost);
+        }
+    }
+    $html_output .= '    onchange="'
+        . 'if (this.value == \'any\') { '
+        . '     hostname.value = \'%\'; '
+        . '} else if (this.value == \'localhost\') { '
+        . '    hostname.value = \'localhost\'; '
+        . '} '
+        . (empty($thishost)
+            ? ''
+            : 'else if (this.value == \'thishost\') { '
+            . '    hostname.value = \'' . addslashes(htmlspecialchars($thishost))
+            . '\'; '
+            . '} '
+        )
+        . 'else if (this.value == \'hosttable\') { '
+        . '    hostname.value = \'\'; '
+        . '} else if (this.value == \'userdefined\') {'
+        . '    hostname.focus(); hostname.select(); '
+        . '}">' . "\n";
+    unset($_current_user);
+
+    // when we start editing a user, $GLOBALS['pred_hostname'] is not defined
+    if (! isset($GLOBALS['pred_hostname']) && isset($GLOBALS['hostname'])) {
+        switch (strtolower($GLOBALS['hostname'])) {
+        case 'localhost':
+        case '127.0.0.1':
+            $GLOBALS['pred_hostname'] = 'localhost';
+            break;
+        case '%':
+            $GLOBALS['pred_hostname'] = 'any';
+            break;
+        default:
+            $GLOBALS['pred_hostname'] = 'userdefined';
+            break;
+        }
+    }
+    $html_output .=  '<option value="any"'
+        . ((isset($GLOBALS['pred_hostname'])
+                && $GLOBALS['pred_hostname'] == 'any'
+            )
+            ? ' selected="selected"'
+            : '') . '>'
+        . __('Any host')
+        . '</option>' . "\n"
+        . '<option value="localhost"'
+        . ((isset($GLOBALS['pred_hostname'])
+                && $GLOBALS['pred_hostname'] == 'localhost'
+            )
+            ? ' selected="selected"'
+            : '') . '>'
+        . __('Local')
+        . '</option>' . "\n";
+    if (! empty($thishost)) {
+        $html_output .= '<option value="thishost"'
+            . ((isset($GLOBALS['pred_hostname'])
+                    && $GLOBALS['pred_hostname'] == 'thishost'
+                )
+                ? ' selected="selected"'
+                : '') . '>'
+            . __('This Host')
+            . '</option>' . "\n";
+    }
+    unset($thishost);
+    $html_output .= '<option value="hosttable"'
+        . ((isset($GLOBALS['pred_hostname'])
+                && $GLOBALS['pred_hostname'] == 'hosttable'
+            )
+            ? ' selected="selected"'
+            : '') . '>'
+        . __('Use Host Table')
+        . '</option>' . "\n";
+
+    $html_output .= '<option value="userdefined"'
+        . ((isset($GLOBALS['pred_hostname'])
+                && $GLOBALS['pred_hostname'] == 'userdefined'
+            )
+            ? ' selected="selected"'
+            : '') . '>'
+        . __('Use text field') . ':</option>' . "\n"
+        . '</select>' . "\n"
+        . '</span>' . "\n";
+
+    $html_output .= '<input type="text" name="hostname" maxlength="'
+        . $hostname_length . '" value="'
+        . htmlspecialchars(isset($GLOBALS['hostname']) ? $GLOBALS['hostname'] : '')
+        . '" title="' . __('Host')
+        . '" onchange="pred_hostname.value = \'userdefined\';" />' . "\n"
+        . PMA_Util::showHint(
+            __('When Host table is used, this field is ignored and values stored in Host table are used instead.')
+        )
+        . '</div>' . "\n";
+
+    $html_output .= '<div class="item">' . "\n"
+        . '<label for="select_pred_password">' . "\n"
+        . '    ' . __('Password') . ':' . "\n"
+        . '</label>' . "\n"
+        . '<span class="options">' . "\n"
+        . '<select name="pred_password" id="select_pred_password" title="'
+        . __('Password') . '"' . "\n";
+
+    $html_output .= '            onchange="'
+        . 'if (this.value == \'none\') { '
+        . '    pma_pw.value = \'\'; pma_pw2.value = \'\'; '
+        . '} else if (this.value == \'userdefined\') { '
+        . '    pma_pw.focus(); pma_pw.select(); '
+        . '}">' . "\n"
+        . ($mode == 'change' ? '<option value="keep" selected="selected">'
+            . __('Do not change the password')
+            . '</option>' . "\n" : '')
+        . '<option value="none"';
+
+    if (isset($GLOBALS['username']) && $mode != 'change') {
+        $html_output .= '  selected="selected"';
+    }
+    $html_output .= '>' . __('No Password') . '</option>' . "\n"
+        . '<option value="userdefined"'
+        . (isset($GLOBALS['username']) ? '' : ' selected="selected"') . '>'
+        . __('Use text field')
+        . ':</option>' . "\n"
+        . '</select>' . "\n"
+        . '</span>' . "\n"
+        . '<input type="password" id="text_pma_pw" name="pma_pw" '
+        . 'title="' . __('Password') . '" '
+        . 'onchange="pred_password.value = \'userdefined\';" />' . "\n"
+        . '</div>' . "\n";
+
+    $html_output .= '<div class="item" '
+        . 'id="div_element_before_generate_password">' . "\n"
+        . '<label for="text_pma_pw2">' . "\n"
+        . '    ' . __('Re-type') . ':' . "\n"
+        . '</label>' . "\n"
+        . '<span class="options"> </span>' . "\n"
+        . '<input type="password" name="pma_pw2" id="text_pma_pw2" '
+        . 'title="' . __('Re-type') . '" '
+        . 'onchange="pred_password.value = \'userdefined\';" />' . "\n"
+        . '</div>' . "\n"
+       // Generate password added here via jQuery
+       . '</fieldset>' . "\n";
+
+    return $html_output;
+} // end of the 'PMA_displayUserAndHostFields()' function
+
+/**
+ * Get username and hostname length
+ *
+ * @return array username length and hostname length
+ */
+function PMA_getUsernameAndHostnameLength()
+{
+    $fields_info = PMA_DBI_get_columns('mysql', 'user', null, true);
+    $username_length = 16;
+    $hostname_length = 41;
+    foreach ($fields_info as $val) {
+        if ($val['Field'] == 'User') {
+            strtok($val['Type'], '()');
+            $value = strtok('()');
+            if (is_int($value)) {
+                $username_length = $value;
+            }
+        } elseif ($val['Field'] == 'Host') {
+            strtok($val['Type'], '()');
+            $value = strtok('()');
+            if (is_int($value)) {
+                $hostname_length = $value;
+            }
+        }
+    }
+    return array($username_length, $hostname_length);
+}
+
+/**
+ * Returns all the grants for a certain user on a certain host
+ * Used in the export privileges for all users section
+ *
+ * @param string $user User name
+ * @param string $host Host name
+ *
+ * @return string containing all the grants text
+ */
+function PMA_getGrants($user, $host)
+{
+    $grants = PMA_DBI_fetch_result(
+        "SHOW GRANTS FOR '"
+        . PMA_Util::sqlAddSlashes($user) . "'@'"
+        . PMA_Util::sqlAddSlashes($host) . "'"
+    );
+    $response = '';
+    foreach ($grants as $one_grant) {
+        $response .= $one_grant . ";\n\n";
+    }
+    return $response;
+} // end of the 'PMA_getGrants()' function
+
+/**
+ * Update password and get message for password updating
+ *
+ * @param string $err_url  error url
+ * @param string $username username
+ * @param string $hostname hostname
+ *
+ * @return string $message  success or error message after updating password
+ */
+function PMA_getMessageForUpdatePassword($err_url, $username, $hostname)
+{
+    // similar logic in user_password.php
+    $message = '';
+
+    if (empty($_REQUEST['nopass'])
+        && isset($_POST['pma_pw'])
+        && isset($_POST['pma_pw2'])
+    ) {
+        if ($_POST['pma_pw'] != $_POST['pma_pw2']) {
+            $message = PMA_Message::error(__('The passwords aren\'t the same!'));
+        } elseif (empty($_POST['pma_pw']) || empty($_POST['pma_pw2'])) {
+            $message = PMA_Message::error(__('The password is empty!'));
+        }
+    }
+
+    // here $nopass could be == 1
+    if (empty($message)) {
+
+        $hashing_function
+            = (! empty($_REQUEST['pw_hash']) && $_REQUEST['pw_hash'] == 'old'
+                ? 'OLD_'
+                : ''
+            )
+            . 'PASSWORD';
+
+        // in $sql_query which will be displayed, hide the password
+        $sql_query        = 'SET PASSWORD FOR \''
+            . PMA_Util::sqlAddSlashes($username)
+            . '\'@\'' . PMA_Util::sqlAddSlashes($hostname) . '\' = '
+            . (($_POST['pma_pw'] == '')
+                ? '\'\''
+                : $hashing_function . '(\''
+                . preg_replace('@. at s', '*', $_POST['pma_pw']) . '\')');
+
+        $local_query      = 'SET PASSWORD FOR \''
+            . PMA_Util::sqlAddSlashes($username)
+            . '\'@\'' . PMA_Util::sqlAddSlashes($hostname) . '\' = '
+            . (($_POST['pma_pw'] == '') ? '\'\'' : $hashing_function
+            . '(\'' . PMA_Util::sqlAddSlashes($_POST['pma_pw']) . '\')');
+
+        PMA_DBI_try_query($local_query)
+            or PMA_Util::mysqlDie(
+                PMA_DBI_getError(), $sql_query, false, $err_url
+            );
+        $message = PMA_Message::success(
+            __('The password for %s was changed successfully.')
+        );
+        $message->addParam(
+            '\'' . htmlspecialchars($username)
+            . '\'@\'' . htmlspecialchars($hostname) . '\''
+        );
+    }
+    return $message;
+}
+
+/**
+ * Revokes privileges and get message and SQL query for privileges revokes
+ *
+ * @param string $db_and_table wildcard Escaped database+table specification
+ * @param string $dbname       database name
+ * @param string $tablename    table name
+ * @param string $username     username
+ * @param string $hostname     host name
+ *
+ * @return array ($message, $sql_query)
+ */
+function PMA_getMessageAndSqlQueryForPrivilegesRevoke($db_and_table, $dbname,
+    $tablename, $username, $hostname
+) {
+    $db_and_table = PMA_wildcardEscapeForGrant($dbname, $tablename);
+
+    $sql_query0 = 'REVOKE ALL PRIVILEGES ON ' . $db_and_table
+        . ' FROM \''
+        . PMA_Util::sqlAddSlashes($username) . '\'@\''
+        . PMA_Util::sqlAddSlashes($hostname) . '\';';
+
+    $sql_query1 = 'REVOKE GRANT OPTION ON ' . $db_and_table
+        . ' FROM \'' . PMA_Util::sqlAddSlashes($username) . '\'@\''
+        . PMA_Util::sqlAddSlashes($hostname) . '\';';
+
+    PMA_DBI_query($sql_query0);
+    if (! PMA_DBI_try_query($sql_query1)) {
+        // this one may fail, too...
+        $sql_query1 = '';
+    }
+    $sql_query = $sql_query0 . ' ' . $sql_query1;
+    $message = PMA_Message::success(
+        __('You have revoked the privileges for %s')
+    );
+    $message->addParam(
+        '\'' . htmlspecialchars($username)
+        . '\'@\'' . htmlspecialchars($hostname) . '\''
+    );
+
+    return array($message, $sql_query);
+}
+
+/**
+ * Get a WITH clause for 'update privileges' and 'add user'
+ *
+ * @return string $sql_query
+ */
+function PMA_getWithClauseForAddUserAndUpdatePrivs()
+{
+    $sql_query = '';
+    if (isset($_POST['Grant_priv']) && $_POST['Grant_priv'] == 'Y') {
+        $sql_query .= ' GRANT OPTION';
+    }
+    if (isset($_POST['max_questions'])) {
+        $max_questions = max(0, (int)$_POST['max_questions']);
+        $sql_query .= ' MAX_QUERIES_PER_HOUR ' . $max_questions;
+    }
+    if (isset($_POST['max_connections'])) {
+        $max_connections = max(0, (int)$_POST['max_connections']);
+        $sql_query .= ' MAX_CONNECTIONS_PER_HOUR ' . $max_connections;
+    }
+    if (isset($_POST['max_updates'])) {
+        $max_updates = max(0, (int)$_POST['max_updates']);
+        $sql_query .= ' MAX_UPDATES_PER_HOUR ' . $max_updates;
+    }
+    if (isset($_POST['max_user_connections'])) {
+        $max_user_connections = max(0, (int)$_POST['max_user_connections']);
+        $sql_query .= ' MAX_USER_CONNECTIONS ' . $max_user_connections;
+    }
+    return ((!empty($sql_query)) ? 'WITH' . $sql_query : '');
+}
+
+/**
+ * Get HTML for addUsersForm, This function call if isset($_REQUEST['adduser'])
+ *
+ * @param string $dbname
+ *
+ * @return string HTML for addUserForm
+ */
+function PMA_getHtmlForAddUser($dbname)
+{
+    $GLOBALS['url_query'] .= '&adduser=1';
+
+    $html_output = '<h2>' . "\n"
+       . PMA_Util::getIcon('b_usradd.png') . __('Add user') . "\n"
+       . '</h2>' . "\n"
+       . '<form name="usersForm" class="ajax" id="addUsersForm"'
+       . ' action="server_privileges.php" method="post">' . "\n"
+       . PMA_generate_common_hidden_inputs('', '')
+       . PMA_getHtmlForDisplayLoginInformationFields('new');
+
+    $html_output .= '<fieldset id="fieldset_add_user_database">' . "\n"
+        . '<legend>' . __('Database for user') . '</legend>' . "\n";
+
+    $html_output .= PMA_Util::getCheckbox(
+        'createdb-1',
+        __('Create database with same name and grant all privileges'),
+        false, false
+    );
+    $html_output .= '<br />' . "\n";
+    $html_output .= PMA_Util::getCheckbox(
+        'createdb-2',
+        __('Grant all privileges on wildcard name (username\\_%)'),
+        false, false
+    );
+    $html_output .= '<br />' . "\n";
+
+    if (! empty($dbname) ) {
+        $html_output .= PMA_Util::getCheckbox(
+            'createdb-3',
+            sprintf(__('Grant all privileges on database "%s"'), htmlspecialchars($dbname)),
+            true,
+            false
+        );
+        $html_output .= '<input type="hidden" name="dbname" value="'
+            . htmlspecialchars($dbname) . '" />' . "\n";
+        $html_output .= '<br />' . "\n";
+    }
+
+    $html_output .= '</fieldset>' . "\n";
+    $html_output .= PMA_getHtmlToDisplayPrivilegesTable('*', '*', false);
+    $html_output .= '<fieldset id="fieldset_add_user_footer" class="tblFooters">'
+        . "\n"
+        . '<input type="submit" name="adduser_submit" '
+        . 'value="' . __('Go') . '" />' . "\n"
+        . '</fieldset>' . "\n"
+        . '</form>' . "\n";
+
+    return $html_output;
+}
+
+/**
+ * Get the list of privileges and list of compared privileges as strings
+ * and return a array that contains both strings
+ *
+ * @return array $list_of_privileges, $list_of_compared_privileges
+ */
+function PMA_getListOfPrivilegesAndComparedPrivileges()
+{
+    $list_of_privileges
+        = '`User`, '
+        . '`Host`, '
+        . '`Select_priv`, '
+        . '`Insert_priv`, '
+        . '`Update_priv`, '
+        . '`Delete_priv`, '
+        . '`Create_priv`, '
+        . '`Drop_priv`, '
+        . '`Grant_priv`, '
+        . '`Index_priv`, '
+        . '`Alter_priv`, '
+        . '`References_priv`, '
+        . '`Create_tmp_table_priv`, '
+        . '`Lock_tables_priv`, '
+        . '`Create_view_priv`, '
+        . '`Show_view_priv`, '
+        . '`Create_routine_priv`, '
+        . '`Alter_routine_priv`, '
+        . '`Execute_priv`';
+
+    $list_of_compared_privileges
+        = '`Select_priv` = \'N\''
+        . ' AND `Insert_priv` = \'N\''
+        . ' AND `Update_priv` = \'N\''
+        . ' AND `Delete_priv` = \'N\''
+        . ' AND `Create_priv` = \'N\''
+        . ' AND `Drop_priv` = \'N\''
+        . ' AND `Grant_priv` = \'N\''
+        . ' AND `References_priv` = \'N\''
+        . ' AND `Create_tmp_table_priv` = \'N\''
+        . ' AND `Lock_tables_priv` = \'N\''
+        . ' AND `Create_view_priv` = \'N\''
+        . ' AND `Show_view_priv` = \'N\''
+        . ' AND `Create_routine_priv` = \'N\''
+        . ' AND `Alter_routine_priv` = \'N\''
+        . ' AND `Execute_priv` = \'N\'';
+
+    if (PMA_MYSQL_INT_VERSION >= 50106) {
+        $list_of_privileges .=
+            ', `Event_priv`, '
+            . '`Trigger_priv`';
+        $list_of_compared_privileges .=
+            ' AND `Event_priv` = \'N\''
+            . ' AND `Trigger_priv` = \'N\'';
+    }
+    return array($list_of_privileges, $list_of_compared_privileges);
+}
+
+/**
+ * Get the HTML for user form and check the privileges for a particular database.
+ *
+ * @param string $link_edit         standard link for edit
+ * @param string $conditional_class if ajaxable 'Ajax' otherwise ''
+ *
+ * @return string $html_output
+ */
+function PMA_getHtmlForSpecificDbPrivileges($link_edit, $conditional_class)
+{
+    // check the privileges for a particular database.
+    $html_output = '<form id="usersForm" action="server_privileges.php">'
+        . '<fieldset>' . "\n";
+    $html_output .= '<legend>' . "\n"
+        . PMA_Util::getIcon('b_usrcheck.png')
+        . '    '
+        . sprintf(
+            __('Users having access to "%s"'),
+            '<a href="' . $GLOBALS['cfg']['DefaultTabDatabase'] . '?'
+            . PMA_generate_common_url($_REQUEST['checkprivs']) . '">'
+            .  htmlspecialchars($_REQUEST['checkprivs'])
+            . '</a>'
+        )
+        . "\n"
+        . '</legend>' . "\n";
+
+    $html_output .= '<table id="dbspecificuserrights" class="data">' . "\n"
+        . '<thead>' . "\n"
+        . '<tr><th>' . __('User') . '</th>' . "\n"
+        . '<th>' . __('Host') . '</th>' . "\n"
+        . '<th>' . __('Type') . '</th>' . "\n"
+        . '<th>' . __('Privileges') . '</th>' . "\n"
+        . '<th>' . __('Grant') . '</th>' . "\n"
+        . '<th>' . __('Action') . '</th>' . "\n"
+        . '</tr>' . "\n"
+        . '</thead>' . "\n";
+    $odd_row = true;
+    // now, we build the table...
+    list($list_of_privileges, $list_of_compared_privileges)
+        = PMA_getListOfPrivilegesAndComparedPrivileges();
+
+    $sql_query = '(SELECT ' . $list_of_privileges . ', `Db`'
+        .' FROM `mysql`.`db`'
+        .' WHERE \'' . PMA_Util::sqlAddSlashes($_REQUEST['checkprivs'])
+        . "'"
+        .' LIKE `Db`'
+        .' AND NOT (' . $list_of_compared_privileges. ')) '
+        .'UNION '
+        .'(SELECT ' . $list_of_privileges . ', \'*\' AS `Db`'
+        .' FROM `mysql`.`user` '
+        .' WHERE NOT (' . $list_of_compared_privileges . ')) '
+        .' ORDER BY `User` ASC,'
+        .'  `Host` ASC,'
+        .'  `Db` ASC;';
+    $res = PMA_DBI_query($sql_query);
+    $row = PMA_DBI_fetch_assoc($res);
+    if ($row) {
+        $found = true;
+    }
+    $html_output .= PMA_getHtmlTableBodyForSpecificDbPrivs(
+        $found, $row, $odd_row, $link_edit, $res
+    );
+    $html_output .= '</table>'
+        . '</fieldset>'
+        . '</form>' . "\n";
+
+    if ($GLOBALS['is_ajax_request'] == true && empty($_REQUEST['ajax_page_request'])) {
+        $message = PMA_Message::success(__('User has been added.'));
+        $response = PMA_Response::getInstance();
+        $response->addJSON('message', $message);
+        $response->addJSON('user_form', $html_output);
+        exit;
+    } else {
+        // Offer to create a new user for the current database
+        $html_output .= '<fieldset id="fieldset_add_user">' . "\n"
+           . '<legend>' . _pgettext('Create new user', 'New') . '</legend>' . "\n";
+
+        $html_output .= '<a href="server_privileges.php?'
+            . $GLOBALS['url_query'] . '&adduser=1&'
+            . 'dbname=' . htmlspecialchars($_REQUEST['checkprivs'])
+            .'" rel="'
+            .'checkprivs='.htmlspecialchars($_REQUEST['checkprivs'])
+            . '&'.$GLOBALS['url_query']
+            . '" class="'.$conditional_class
+            .'" name="db_specific">' . "\n"
+            . PMA_Util::getIcon('b_usradd.png')
+            . '        ' . __('Add user') . '</a>' . "\n";
+
+        $html_output .= '</fieldset>' . "\n";
+    }
+    return $html_output;
+}
+
+/**
+ * Get HTML snippet for table body of specific database privileges
+ *
+ * @param boolean $found     whether user found or not
+ * @param array   $row       array of rows from mysql,
+ *                           db table with list of privileges
+ * @param boolean $odd_row   whether odd or not
+ * @param string  $link_edit standard link for edit
+ * @param string  $res       ran sql query
+ *
+ * @return string $html_output
+ */
+function PMA_getHtmlTableBodyForSpecificDbPrivs($found, $row, $odd_row,
+    $link_edit, $res
+) {
+    $html_output = '<tbody>' . "\n";
+    if ($found) {
+        while (true) {
+            // prepare the current user
+            $current_privileges = array();
+            $current_user = $row['User'];
+            $current_host = $row['Host'];
+            while ($row
+                    && $current_user == $row['User']
+                    && $current_host == $row['Host']
+            ) {
+                $current_privileges[] = $row;
+                $row = PMA_DBI_fetch_assoc($res);
+            }
+            $html_output .= '<tr '
+                . 'class="noclick ' . ($odd_row ? 'odd' : 'even')
+                . '">' . "\n"
+                . '<td';
+            if (count($current_privileges) > 1) {
+                $html_output .= ' rowspan="' . count($current_privileges) . '"';
+            }
+            $html_output .= '>'
+                . (empty($current_user)
+                    ? '<span style="color: #FF0000">' . __('Any') . '</span>'
+                    : htmlspecialchars($current_user)) . "\n"
+                . '</td>' . "\n";
+
+            $html_output .= '<td';
+            if (count($current_privileges) > 1) {
+                $html_output .= ' rowspan="' . count($current_privileges) . '"';
+            }
+            $html_output .= '>'
+                . htmlspecialchars($current_host) . '</td>' . "\n";
+            for ($i = 0; $i < count($current_privileges); $i++) {
+                $current = $current_privileges[$i];
+                $html_output .= '<td>' . "\n"
+                   . '            ';
+                if (! isset($current['Db']) || $current['Db'] == '*') {
+                    $html_output .= __('global');
+                } elseif (
+                    $current['Db'] == PMA_Util::escapeMysqlWildcards(
+                        $_REQUEST['checkprivs']
+                    )
+                ) {
+                    $html_output .= __('database-specific');
+                } else {
+                    $html_output .= __('wildcard'). ': '
+                        . '<code>' . htmlspecialchars($current['Db']) . '</code>';
+                }
+                $html_output .= "\n"
+                   . '</td>' . "\n";
+
+                $html_output .='<td>' . "\n"
+                   . '<code>' . "\n"
+                   . ''
+                   . join(
+                       ',' . "\n" . '                ',
+                       PMA_extractPrivInfo($current, true)
+                   )
+                   . "\n"
+                   . '</code>' . "\n"
+                   . '</td>' . "\n";
+
+                $html_output .= '<td>' . "\n"
+                    . '' . ($current['Grant_priv'] == 'Y' ? __('Yes') : __('No'))
+                    . "\n"
+                    . '</td>' . "\n"
+                    . '<td>' . "\n";
+                $html_output .= sprintf(
+                    $link_edit,
+                    urlencode($current_user),
+                    urlencode($current_host),
+                    urlencode(
+                        ! (isset($current['Db']) || $current['Db'] == '*') ? '' : $current['Db']
+                    ),
+                    ''
+                );
+                $html_output .= '</td>' . "\n"
+                   . '    </tr>' . "\n";
+                if (($i + 1) < count($current_privileges)) {
+                    $html_output .= '<tr '
+                        . 'class="noclick ' . ($odd_row ? 'odd' : 'even') . '">'
+                        . "\n";
+                }
+            }
+            if (empty($row)) {
+                break;
+            }
+            $odd_row = ! $odd_row;
+        }
+    } else {
+        $html_output .= '<tr class="odd">' . "\n"
+           . '<td colspan="6">' . "\n"
+           . '            ' . __('No user found.') . "\n"
+           . '</td>' . "\n"
+           . '</tr>' . "\n";
+    }
+    $html_output .= '</tbody>' . "\n";
+
+    return $html_output;
+}
+
+/**
+ * Define some standard links
+ * $link_edit, $link_revoke, $link_export
+ *
+ * @param string $conditional_class if ajaxable 'Ajax' otherwise ''
+ *
+ * @return array with some standard links
+ */
+function PMA_getStandardLinks($conditional_class)
+{
+    $link_edit = '<a class="edit_user_anchor ' . $conditional_class . '"'
+        . ' href="server_privileges.php?'
+        . str_replace('%', '%%', $GLOBALS['url_query'])
+        . '&username=%s'
+        . '&hostname=%s'
+        . '&dbname=%s'
+        . '&tablename=%s">'
+        . PMA_Util::getIcon('b_usredit.png', __('Edit Privileges'))
+        . '</a>';
+
+    $link_revoke = '<a href='
+        .'"server_privileges.php?'
+        . str_replace('%', '%%', $GLOBALS['url_query'])
+        . '&username=%s'
+        . '&hostname=%s'
+        . '&dbname=%s'
+        . '&tablename=%s'
+        . '&revokeall=1">'
+        . PMA_Util::getIcon('b_usrdrop.png', __('Revoke'))
+        . '</a>';
+
+    $link_export = '<a class="export_user_anchor ' . $conditional_class . '"'
+        . ' href="server_privileges.php?'
+        . str_replace('%', '%%', $GLOBALS['url_query'])
+        . '&username=%s'
+        . '&hostname=%s'
+        . '&initial=%s'
+        . '&export=1">'
+        . PMA_Util::getIcon('b_tblexport.png', __('Export'))
+        . '</a>';
+
+    return array($link_edit, $link_revoke, $link_export);
+}
+
+/**
+ * This function return the extra data array for the ajax behavior
+ *
+ * @param string $password    password
+ * @param string $link_export export link
+ * @param string $sql_query   sql query
+ * @param string $link_edit   standard link for edit
+ * @param string $hostname    hostname
+ * @param string $username    username
+ *
+ * @return array $extra_data
+ */
+function PMA_getExtraDataForAjaxBehavior($password, $link_export, $sql_query,
+    $link_edit, $hostname, $username
+) {
+    if (isset($GLOBALS['dbname'])) {
+        //if (preg_match('/\\\\(?:_|%)/i', $dbname)) {
+        if (preg_match('/(?<!\\\\)(?:_|%)/i', $GLOBALS['dbname'])) {
+            $dbname_is_wildcard = true;
+        } else {
+            $dbname_is_wildcard = false;
+        }
+    }
+
+    $extra_data = array();
+    if (strlen($sql_query)) {
+        $extra_data['sql_query']
+            = PMA_Util::getMessage(null, $sql_query);
+    }
+
+    if (isset($_REQUEST['adduser_submit']) || isset($_REQUEST['change_copy'])) {
+        /**
+         * generate html on the fly for the new user that was just created.
+         */
+        $new_user_string = '<tr>'."\n"
+            . '<td> <input type="checkbox" name="selected_usr[]" '
+            . 'id="checkbox_sel_users_"'
+            . 'value="'
+            . htmlspecialchars($username)
+            . '&#27;' . htmlspecialchars($hostname) . '" />'
+            . '</td>' . "\n"
+            . '<td><label for="checkbox_sel_users_">'
+            . (empty($_REQUEST['username'])
+                    ? '<span style="color: #FF0000">' . __('Any') . '</span>'
+                    : htmlspecialchars($username) ) . '</label></td>' . "\n"
+            . '<td>' . htmlspecialchars($hostname) . '</td>' . "\n";
+
+        $new_user_string .= '<td>';
+
+        if (! empty($password) || isset($_POST['pma_pw'])) {
+            $new_user_string .= __('Yes');
+        } else {
+            $new_user_string .= '<span style="color: #FF0000">'
+                . __('No')
+            . '</span>';
+        };
+
+        $new_user_string .= '</td>'."\n";
+        $new_user_string .= '<td>'
+            . '<code>' . join(', ', PMA_extractPrivInfo('', true)) . '</code>'
+            . '</td>'; //Fill in privileges here
+        $new_user_string .= '<td>';
+
+        if ((isset($_POST['Grant_priv']) && $_POST['Grant_priv'] == 'Y')) {
+            $new_user_string .= __('Yes');
+        } else {
+            $new_user_string .= __('No');
+        }
+
+        $new_user_string .='</td>';
+
+        $new_user_string .= '<td>'
+            . sprintf(
+                $link_edit,
+                urlencode($username),
+                urlencode($hostname),
+                '',
+                ''
+            )
+            . '</td>' . "\n";
+        $new_user_string .= '<td>'
+            . sprintf(
+                $link_export,
+                urlencode($username),
+                urlencode($hostname),
+                (isset($_GET['initial']) ? $_GET['initial'] : '')
+            )
+            . '</td>' . "\n";
+
+        $new_user_string .= '</tr>';
+
+        $extra_data['new_user_string'] = $new_user_string;
+
+        /**
+         * Generate the string for this alphabet's initial, to update the user
+         * pagination
+         */
+        $new_user_initial = strtoupper(substr($username, 0, 1));
+        $new_user_initial_string = '<a href="server_privileges.php?'
+            . $GLOBALS['url_query'] . '&initial=' . $new_user_initial .'">'
+            . $new_user_initial . '</a>';
+        $extra_data['new_user_initial'] = $new_user_initial;
+        $extra_data['new_user_initial_string'] = $new_user_initial_string;
+    }
+
+    if (isset($_POST['update_privs'])) {
+        $extra_data['db_specific_privs'] = false;
+        $extra_data['db_wildcard_privs'] = false;
+        if (isset($dbname_is_wildcard)) {
+            $extra_data['db_specific_privs'] = ! $dbname_is_wildcard;
+            $extra_data['db_wildcard_privs'] = $dbname_is_wildcard;
+        }
+        $new_privileges = join(', ', PMA_extractPrivInfo('', true));
+
+        $extra_data['new_privileges'] = $new_privileges;
+    }
+    return $extra_data;
+}
+
+/**
+ * Get the HTML snippet for change user login information
+ *
+ * @param string $username username
+ * @param string $hostname host name
+ *
+ * @return string HTML snippet
+ */
+function PMA_getChangeLoginInformationHtmlForm($username, $hostname)
+{
+    $choices = array(
+        '4' => __('… keep the old one.'),
+        '1' => __('… delete the old one from the user tables.'),
+        '2' => __('… revoke all active privileges from the old one and delete it afterwards.'),
+        '3' => __('… delete the old one from the user tables and reload the privileges afterwards.'));
+
+    $class = ' ajax';
+    $html_output = '<form action="server_privileges.php" '
+        . 'method="post" class="copyUserForm' . $class .'">' . "\n"
+        . PMA_generate_common_hidden_inputs('', '')
+        . '<input type="hidden" name="old_username" '
+        . 'value="' . htmlspecialchars($username) . '" />' . "\n"
+        . '<input type="hidden" name="old_hostname" '
+        . 'value="' . htmlspecialchars($hostname) . '" />' . "\n"
+        . '<fieldset id="fieldset_change_copy_user">' . "\n"
+        . '<legend>' . __('Change Login Information / Copy User')
+        . '</legend>' . "\n"
+        . PMA_getHtmlForDisplayLoginInformationFields('change');
+
+    $html_output .= '<fieldset id="fieldset_mode">' . "\n"
+        . ' <legend>'
+        . __('Create a new user with the same privileges and …')
+        . '</legend>' . "\n";
+    $html_output .= PMA_Util::getRadioFields(
+        'mode', $choices, '4', true
+    );
+    $html_output .= '</fieldset>' . "\n"
+       . '</fieldset>' . "\n";
+
+    $html_output .= '<fieldset id="fieldset_change_copy_user_footer" '
+        . 'class="tblFooters">' . "\n"
+        . '<input type="submit" name="change_copy" '
+        . 'value="' . __('Go') . '" />' . "\n"
+        . '</fieldset>' . "\n"
+        . '</form>' . "\n";
+
+    return $html_output;
+}
+
+/**
+ * Provide a line with links to the relevant database and table
+ *
+ * @param string $url_dbname url database name that urlencode() string
+ * @param string $dbname     database name
+ * @param string $tablename  table name
+ *
+ * @return string HTML snippet
+ */
+function PMA_getLinkToDbAndTable($url_dbname, $dbname, $tablename)
+{
+    $html_output = '[ ' . __('Database')
+        . ' <a href="' . $GLOBALS['cfg']['DefaultTabDatabase'] . '?'
+        . $GLOBALS['url_query'] . '&db=' . $url_dbname . '&reload=1">'
+        . htmlspecialchars($dbname) . ': '
+        . PMA_Util::getTitleForTarget(
+            $GLOBALS['cfg']['DefaultTabDatabase']
+        )
+        . "</a> ]\n";
+
+    if (strlen($tablename)) {
+        $html_output .= ' [ ' . __('Table') . ' <a href="'
+            . $GLOBALS['cfg']['DefaultTabTable'] . '?' . $GLOBALS['url_query']
+            . '&db=' . $url_dbname
+            . '&table=' . htmlspecialchars(urlencode($tablename))
+            . '&reload=1">' . htmlspecialchars($tablename) . ': '
+            . PMA_Util::getTitleForTarget(
+                $GLOBALS['cfg']['DefaultTabTable']
+            )
+            . "</a> ]\n";
+    }
+    return $html_output;
+}
+
+/**
+ * no db name given, so we want all privs for the given user
+ * db name was given, so we want all user specific rights for this db
+ * So this function returns user rights as an array
+ *
+ * @param array  $tables              tables
+ * @param string $user_host_condition a where clause that containd user's host condition
+ * @param string $dbname              database name
+ *
+ * @return array $db_rights database rights
+ */
+function PMA_getUserSpecificRights($tables, $user_host_condition, $dbname)
+{
+    if (! strlen($dbname)) {
+        $tables_to_search_for_users = array(
+            'tables_priv', 'columns_priv',
+        );
+        $dbOrTableName = 'Db';
+    } else {
+        $user_host_condition .=
+            ' AND `Db`'
+            .' LIKE \''
+            . PMA_Util::sqlAddSlashes($dbname, true) . "'";
+        $tables_to_search_for_users = array('columns_priv',);
+        $dbOrTableName = 'Table_name';
+    }
+
+    $db_rights_sqls = array();
+    foreach ($tables_to_search_for_users as $table_search_in) {
+        if (in_array($table_search_in, $tables)) {
+            $db_rights_sqls[] = '
+                SELECT DISTINCT `' . $dbOrTableName .'`
+                FROM `mysql`.' . PMA_Util::backquote($table_search_in)
+               . $user_host_condition;
+        }
+    }
+
+    $user_defaults = array(
+        $dbOrTableName  => '',
+        'Grant_priv'    => 'N',
+        'privs'         => array('USAGE'),
+        'Column_priv'   => true,
+    );
+
+    // for the rights
+    $db_rights = array();
+
+    $db_rights_sql = '(' . implode(') UNION (', $db_rights_sqls) . ')'
+        .' ORDER BY `' . $dbOrTableName .'` ASC';
+
+    $db_rights_result = PMA_DBI_query($db_rights_sql);
+
+    while ($db_rights_row = PMA_DBI_fetch_assoc($db_rights_result)) {
+        $db_rights_row = array_merge($user_defaults, $db_rights_row);
+        if (! strlen($dbname)) {
+            // only Db names in the table `mysql`.`db` uses wildcards
+            // as we are in the db specific rights display we want
+            // all db names escaped, also from other sources
+            $db_rights_row['Db'] = PMA_Util::escapeMysqlWildcards(
+                $db_rights_row['Db']
+            );
+        }
+        $db_rights[$db_rights_row[$dbOrTableName]] = $db_rights_row;
+    }
+
+    PMA_DBI_free_result($db_rights_result);
+
+    if (! strlen($dbname)) {
+        $sql_query = 'SELECT * FROM `mysql`.`db`'
+            . $user_host_condition . ' ORDER BY `Db` ASC';
+    } else {
+        $sql_query = 'SELECT `Table_name`,'
+            .' `Table_priv`,'
+            .' IF(`Column_priv` = _latin1 \'\', 0, 1)'
+            .' AS \'Column_priv\''
+            .' FROM `mysql`.`tables_priv`'
+            . $user_host_condition
+            .' ORDER BY `Table_name` ASC;';
+    }
+
+    $result = PMA_DBI_query($sql_query);
+    $sql_query = '';
+
+    while ($row = PMA_DBI_fetch_assoc($result)) {
+        if (isset($db_rights[$row[$dbOrTableName]])) {
+            $db_rights[$row[$dbOrTableName]]
+                = array_merge($db_rights[$row[$dbOrTableName]], $row);
+        } else {
+            $db_rights[$row[$dbOrTableName]] = $row;
+        }
+        if (! strlen($dbname)) {
+            // there are db specific rights for this user
+            // so we can drop this db rights
+            $db_rights[$row['Db']]['can_delete'] = true;
+        }
+    }
+    PMA_DBI_free_result($result);
+    return $db_rights;
+}
+
+/**
+ * Display user rights in table rows(Table specific or database specific privs)
+ *
+ * @param array  $db_rights   user's database rights array
+ * @param string $link_edit   standard link to edit privileges
+ * @param string $dbname      database name
+ * @param string $link_revoke standard link to revoke
+ * @param string $hostname    host name
+ * @param string $username    username
+ *
+ * @return array $found_rows, $html_output
+ */
+function PMA_getHtmlForDisplayUserRightsInRows($db_rights, $link_edit, $dbname,
+    $link_revoke, $hostname, $username
+) {
+    $html_output = '';
+    $found_rows = array();
+    // display rows
+    if (count($db_rights) < 1) {
+        $html_output .= '<tr class="odd">' . "\n"
+           . '<td colspan="6"><center><i>' . __('None') . '</i></center></td>' . "\n"
+           . '</tr>' . "\n";
+    } else {
+        $odd_row = true;
+        //while ($row = PMA_DBI_fetch_assoc($res)) {
+        foreach ($db_rights as $row) {
+            $found_rows[] = (! strlen($dbname)) ? $row['Db'] : $row['Table_name'];
+
+            $html_output .= '<tr class="' . ($odd_row ? 'odd' : 'even') . '">' . "\n"
+                . '<td>'
+                . htmlspecialchars(
+                    (! strlen($dbname)) ? $row['Db'] : $row['Table_name']
+                )
+                . '</td>' . "\n"
+                . '<td><code>' . "\n"
+                . '        '
+                . join(
+                    ',' . "\n" . '            ',
+                    PMA_extractPrivInfo($row, true)
+                ) . "\n"
+                . '</code></td>' . "\n"
+                . '<td>'
+                    . ((((! strlen($dbname)) && $row['Grant_priv'] == 'Y')
+                        || (strlen($dbname) && in_array('Grant', explode(',', $row['Table_priv']))))
+                    ? __('Yes')
+                    : __('No'))
+                . '</td>' . "\n"
+                . '<td>';
+            if (! empty($row['Table_privs']) || ! empty ($row['Column_priv'])) {
+                $html_output .= __('Yes');
+            } else {
+                $html_output .= __('No');
+            }
+            $html_output .= '</td>' . "\n"
+               . '<td>';
+            $html_output .= sprintf(
+                $link_edit,
+                htmlspecialchars(urlencode($username)),
+                urlencode(htmlspecialchars($hostname)),
+                urlencode(
+                    (! strlen($dbname)) ? $row['Db'] : htmlspecialchars($dbname)
+                ),
+                urlencode((! strlen($dbname)) ? '' : $row['Table_name'])
+            );
+            $html_output .= '</td>' . "\n"
+               . '    <td>';
+            if (! empty($row['can_delete'])
+                || isset($row['Table_name'])
+                && strlen($row['Table_name'])
+            ) {
+                $html_output .= sprintf(
+                    $link_revoke,
+                    htmlspecialchars(urlencode($username)),
+                    urlencode(htmlspecialchars($hostname)),
+                    urlencode(
+                        (! strlen($dbname)) ? $row['Db'] : htmlspecialchars($dbname)
+                    ),
+                    urlencode((! strlen($dbname)) ? '' : $row['Table_name'])
+                );
+            }
+            $html_output .= '</td>' . "\n"
+               . '</tr>' . "\n";
+            $odd_row = ! $odd_row;
+        } // end while
+    } //end if
+    return array($found_rows, $html_output);
+}
+
+/**
+ * Get a HTML table for display user's tabel specific or database specific rights
+ *
+ * @param string $username    username
+ * @param string $hostname    host name
+ * @param string $link_edit   standard link to edit privileges
+ * @param string $link_revoke standard link to revoke
+ * @param string $dbname      database name
+ *
+ * @return array $html_output, $found_rows
+ */
+function PMA_getTableForDisplayAllTableSpecificRights($username, $hostname
+    , $link_edit, $link_revoke, $dbname
+) {
+    // table header
+    $html_output = PMA_generate_common_hidden_inputs('', '')
+        . '<input type="hidden" name="username" '
+        . 'value="' . htmlspecialchars($username) . '" />' . "\n"
+        . '<input type="hidden" name="hostname" '
+        . 'value="' . htmlspecialchars($hostname) . '" />' . "\n"
+        . '<fieldset>' . "\n"
+        . '<legend>'
+        . (! strlen($dbname)
+            ? __('Database-specific privileges')
+            : __('Table-specific privileges')
+        )
+        . '</legend>' . "\n"
+        . '<table class="data">' . "\n"
+        . '<thead>' . "\n"
+        . '<tr><th>'
+        . (! strlen($dbname) ? __('Database') : __('Table'))
+        . '</th>' . "\n"
+        . '<th>' . __('Privileges') . '</th>' . "\n"
+        . '<th>' . __('Grant') . '</th>' . "\n"
+        . '<th>'
+        . (! strlen($dbname)
+            ? __('Table-specific privileges')
+            : __('Column-specific privileges')
+        )
+        . '</th>' . "\n"
+        . '<th colspan="2">' . __('Action') . '</th>' . "\n"
+        . '</tr>' . "\n"
+        . '</thead>' . "\n";
+
+    $user_host_condition = ' WHERE `User`'
+        . ' = \'' . PMA_Util::sqlAddSlashes($username) . "'"
+        . ' AND `Host`'
+        . ' = \'' . PMA_Util::sqlAddSlashes($hostname) . "'";
+
+    // table body
+    // get data
+
+    // we also want privielgs for this user not in table `db` but in other table
+    $tables = PMA_DBI_fetch_result('SHOW TABLES FROM `mysql`;');
+
+    /**
+     * no db name given, so we want all privs for the given user
+     * db name was given, so we want all user specific rights for this db
+     */
+    $db_rights = PMA_getUserSpecificRights($tables, $user_host_condition, $dbname);
+
+    ksort($db_rights);
+
+    $html_output .= '<tbody>' . "\n";
+    // display rows
+    list ($found_rows, $html_out) =  PMA_getHtmlForDisplayUserRightsInRows(
+        $db_rights, $link_edit, $dbname, $link_revoke, $hostname, $username
+    );
+
+    $html_output .= $html_out;
+    $html_output .= '</tbody>' . "\n";
+    $html_output .='</table>' . "\n";
+
+    return array($html_output, $found_rows);
+}
+
+/**
+ * Get HTML for display select db
+ *
+ * @param array $found_rows isset($dbname)) ? $row['Db'] : $row['Table_name']
+ *
+ * @return string HTML snippet
+ */
+function PMA_getHtmlForDisplaySelectDbInEditPrivs($found_rows)
+{
+    $pred_db_array = PMA_DBI_fetch_result('SHOW DATABASES;');
+
+    $html_output = '<label for="text_dbname">'
+        . __('Add privileges on the following database') . ':</label>' . "\n";
+    if (! empty($pred_db_array)) {
+        $html_output .= '<select name="pred_dbname" class="autosubmit">' . "\n"
+            . '<option value="" selected="selected">'
+            . __('Use text field') . ':</option>' . "\n";
+        foreach ($pred_db_array as $current_db) {
+            $current_db_show = $current_db;
+            $current_db = PMA_Util::escapeMysqlWildcards($current_db);
+            // cannot use array_diff() once, outside of the loop,
+            // because the list of databases has special characters
+            // already escaped in $found_rows,
+            // contrary to the output of SHOW DATABASES
+            if (empty($found_rows) || ! in_array($current_db, $found_rows)) {
+                $html_output .= '<option value="' . htmlspecialchars($current_db) . '">'
+                    . htmlspecialchars($current_db_show) . '</option>' . "\n";
+            }
+        }
+        $html_output .= '</select>' . "\n";
+    }
+    $html_output .= '<input type="text" id="text_dbname" name="dbname" />' . "\n"
+        . PMA_Util::showHint(
+            __('Wildcards % and _ should be escaped with a \ to use them literally')
+        );
+    return $html_output;
+}
+
+/**
+ * Get HTML for display table in edit privilege
+ *
+ * @param string $dbname     database naame
+ * @param array  $found_rows isset($dbname)) ? $row['Db'] : $row['Table_name']
+ *
+ * @return string HTML snippet
+ */
+function PMA_displayTablesInEditPrivs($dbname, $found_rows)
+{
+    $html_output = '<input type="hidden" name="dbname"
+        '. 'value="' . htmlspecialchars($dbname) . '"/>' . "\n";
+    $html_output .= '<label for="text_tablename">'
+        . __('Add privileges on the following table') . ':</label>' . "\n";
+
+    $result = @PMA_DBI_try_query(
+        'SHOW TABLES FROM ' . PMA_Util::backquote(
+            PMA_Util::unescapeMysqlWildcards($dbname)
+        ) . ';',
+        null,
+        PMA_DBI_QUERY_STORE
+    );
+
+    if ($result) {
+        $pred_tbl_array = array();
+        while ($row = PMA_DBI_fetch_row($result)) {
+            if (! isset($found_rows) || ! in_array($row[0], $found_rows)) {
+                $pred_tbl_array[] = $row[0];
+            }
+        }
+        PMA_DBI_free_result($result);
+
+        if (! empty($pred_tbl_array)) {
+            $html_output .= '<select name="pred_tablename" '
+                . 'class="autosubmit">' . "\n"
+                . '<option value="" selected="selected">' . __('Use text field')
+                . ':</option>' . "\n";
+            foreach ($pred_tbl_array as $current_table) {
+                $html_output .= '<option '
+                    . 'value="' . htmlspecialchars($current_table) . '">'
+                    . htmlspecialchars($current_table)
+                    . '</option>' . "\n";
+            }
+            $html_output .= '</select>' . "\n";
+        }
+    }
+    $html_output .= '<input type="text" id="text_tablename" name="tablename" />'
+        . "\n";
+
+    return $html_output;
+}
+
+/**
+ * Get HTML for display the users overview
+ * (if less than 50 users, display them immediately)
+ *
+ * @param array  $result            ran sql query
+ * @param array  $db_rights         user's database rights array
+ * @param string $link_edit         standard link to edit privileges
+ * @param string $pmaThemeImage     a image source link
+ * @param string $text_dir          text directory
+ * @param string $conditional_class if ajaxable 'Ajax' otherwise ''
+ * @param string $link_export       standard link to export privileges
+ *
+ * @return string HTML snippet
+ */
+function PMA_getUsersOverview($result, $db_rights, $link_edit, $pmaThemeImage,
+    $text_dir, $conditional_class, $link_export
+) {
+    while ($row = PMA_DBI_fetch_assoc($result)) {
+        $row['privs'] = PMA_extractPrivInfo($row, true);
+        $db_rights[$row['User']][$row['Host']] = $row;
+    }
+    @PMA_DBI_free_result($result);
+
+    $html_output
+        = '<form name="usersForm" id="usersForm" action="server_privileges.php" '
+        . 'method="post">' . "\n"
+        . PMA_generate_common_hidden_inputs('', '')
+        . '<table id="tableuserrights" class="data">' . "\n"
+        . '<thead>' . "\n"
+        . '<tr><th></th>' . "\n"
+        . '<th>' . __('User') . '</th>' . "\n"
+        . '<th>' . __('Host') . '</th>' . "\n"
+        . '<th>' . __('Password') . '</th>' . "\n"
+        . '<th>' . __('Global privileges') . ' '
+        . PMA_Util::showHint(
+            __('Note: MySQL privilege names are expressed in English')
+        )
+        . '</th>' . "\n"
+        . '<th>' . __('Grant') . '</th>' . "\n"
+        . '<th colspan="2">' . __('Action') . '</th>' . "\n"
+        . '</tr>' . "\n"
+        . '</thead>' . "\n";
+
+    $html_output .= '<tbody>' . "\n";
+    $html_output .= PMA_getTableBodyForUserRightsTable(
+        $db_rights, $link_edit, $link_export
+    );
+    $html_output .= '</tbody>'
+        . '</table>' . "\n";
+
+    $html_output .= '<div style="float:left;">'
+        .'<img class="selectallarrow"'
+        .' src="' . $pmaThemeImage . 'arrow_' . $text_dir . '.png"'
+        .' width="38" height="22"'
+        .' alt="' . __('With selected:') . '" />' . "\n"
+        .'<input type="checkbox" id="checkall" title="' . __('Check All') . '" /> '
+        .'<label for="checkall">' . __('Check All') . '</label> '
+        .'<i style="margin-left: 2em">' . __('With selected:') . '</i>' . "\n";
+
+    $html_output .= PMA_Util::getButtonOrImage(
+        'submit_mult', 'mult_submit', 'submit_mult_export',
+        __('Export'), 'b_tblexport.png', 'export'
+    );
+    $html_output .= '<input type="hidden" name="initial" '
+        . 'value="' . (isset($_GET['initial']) ? $_GET['initial'] : '') . '" />';
+    $html_output .= '</div>'
+        . '<div class="clear_both" style="clear:both"></div>';
+
+    // add/delete user fieldset
+    $html_output .= PMA_getFieldsetForAddDeleteUser($conditional_class);
+    $html_output .= '</form>' . "\n";
+
+    return $html_output;
+}
+
+/**
+ * Get table body for 'tableuserrights' table in userform
+ *
+ * @param array  $db_rights   user's database rights array
+ * @param string $link_edit   standard link to edit privileges
+ * @param string $link_export Link for export all users
+ *
+ * @return string HTML snippet
+ */
+function PMA_getTableBodyForUserRightsTable($db_rights, $link_edit, $link_export)
+{
+    $odd_row = true;
+    $index_checkbox = -1;
+    $html_output = '';
+    foreach ($db_rights as $user) {
+        $index_checkbox++;
+        ksort($user);
+        foreach ($user as $host) {
+            $index_checkbox++;
+            $html_output .= '<tr class="' . ($odd_row ? 'odd' : 'even') . '">'
+                . "\n";
+            $html_output .= '<td>'
+                . '<input type="checkbox" class="checkall" name="selected_usr[]" '
+                . 'id="checkbox_sel_users_'
+                . $index_checkbox . '" value="'
+                . htmlspecialchars($host['User'] . '&#27;' . $host['Host'])
+                . '"'
+                . ' /></td>' . "\n";
+
+            $html_output .= '<td><label '
+                . 'for="checkbox_sel_users_' . $index_checkbox . '">'
+                . (empty($host['User'])
+                    ? '<span style="color: #FF0000">' . __('Any') . '</span>'
+                    : htmlspecialchars($host['User'])) . '</label></td>' . "\n"
+                . '<td>' . htmlspecialchars($host['Host']) . '</td>' . "\n";
+
+            $html_output .= '<td>';
+            switch ($host['Password']) {
+            case 'Y':
+                $html_output .= __('Yes');
+                break;
+            case 'N':
+                $html_output .= '<span style="color: #FF0000">' . __('No')
+                    . '</span>';
+                break;
+            // this happens if this is a definition not coming from mysql.user
+            default:
+                $html_output .= '--'; // in future version, replace by "not present"
+                break;
+            } // end switch
+            $html_output .= '</td>' . "\n";
+
+            $html_output .= '<td><code>' . "\n"
+                . '' . implode(',' . "\n" . '            ', $host['privs']) . "\n"
+                . '</code></td>' . "\n"
+                . '<td>'
+                . ($host['Grant_priv'] == 'Y' ? __('Yes') : __('No'))
+                . '</td>' . "\n"
+                . '<td class="center">'
+                . sprintf(
+                    $link_edit,
+                    urlencode($host['User']),
+                    urlencode($host['Host']),
+                    '',
+                    ''
+                );
+            $html_output .= '</td>';
+
+            $html_output .= '<td class="center">';
+            $html_output .= sprintf(
+                $link_export,
+                urlencode($host['User']),
+                urlencode($host['Host']),
+                (isset($_GET['initial']) ? $_GET['initial'] : '')
+            );
+            $html_output .= '</td>';
+            $html_output .= '</tr>';
+            $odd_row = ! $odd_row;
+        }
+    }
+    return $html_output;
+}
+
+/**
+ * Get HTML fieldset for Add/Delete user
+ *
+ * @param string $conditional_class if ajaxable 'Ajax' otherwise ''
+ *
+ * @return string HTML snippet
+ */
+function PMA_getFieldsetForAddDeleteUser($conditional_class)
+{
+    $html_output = '<fieldset id="fieldset_add_user">' . "\n";
+    $html_output .= '<a href="server_privileges.php?'
+        . $GLOBALS['url_query'] . '&adduser=1"'
+        . 'class="' . $conditional_class . '">' . "\n"
+        . PMA_Util::getIcon('b_usradd.png')
+        . '            ' . __('Add user') . '</a>' . "\n";
+    $html_output .= '</fieldset>' . "\n";
+
+    $html_output .= '<fieldset id="fieldset_delete_user">'
+        . '<legend>' . "\n"
+        . PMA_Util::getIcon('b_usrdrop.png')
+        . '            ' . __('Remove selected users') . '' . "\n"
+        . '</legend>' . "\n";
+
+    $html_output .= '<input type="hidden" name="mode" value="2" />' . "\n"
+        . '(' . __('Revoke all active privileges from the users and delete them afterwards.') . ')'
+        . '<br />' . "\n";
+
+    $html_output .= '<input type="checkbox" '
+        . 'title="' . __('Drop the databases that have the same names as the users.') . '" '
+        . 'name="drop_users_db" id="checkbox_drop_users_db" />' . "\n";
+
+    $html_output .= '<label for="checkbox_drop_users_db" '
+        . 'title="' . __('Drop the databases that have the same names as the users.') . '">' . "\n"
+        . '            ' . __('Drop the databases that have the same names as the users.') . "\n"
+        . '</label>' . "\n"
+        . '</fieldset>' . "\n";
+
+    $html_output .= '<fieldset id="fieldset_delete_user_footer" class="tblFooters">' . "\n";
+    $html_output .= '<input type="submit" name="delete" '
+        . 'value="' . __('Go') . '" id="buttonGo" '
+        . 'class="' . $conditional_class . '"/>' . "\n";
+
+    $html_output .= '</fieldset>' . "\n";
+
+    return $html_output;
+}
+
+/**
+ * Get HTML for Displays the initials
+ *
+ * @param array  $array_initials    array for all initials, even non A-Z
+ * @param string $conditional_class if ajaxable 'Ajax' otherwise ''
+ *
+ * @return string HTML snippet
+ */
+function PMA_getHtmlForDisplayTheInitials($array_initials, $conditional_class)
+{
+    // initialize to false the letters A-Z
+    for ($letter_counter = 1; $letter_counter < 27; $letter_counter++) {
+        if (! isset($array_initials[chr($letter_counter + 64)])) {
+            $array_initials[chr($letter_counter + 64)] = false;
+        }
+    }
+
+    $initials = PMA_DBI_try_query(
+        'SELECT DISTINCT UPPER(LEFT(`User`,1)) FROM `user` ORDER BY `User` ASC',
+        null,
+        PMA_DBI_QUERY_STORE
+    );
+    while (list($tmp_initial) = PMA_DBI_fetch_row($initials)) {
+        $array_initials[$tmp_initial] = true;
+    }
+
+    // Display the initials, which can be any characters, not
+    // just letters. For letters A-Z, we add the non-used letters
+    // as greyed out.
+
+    uksort($array_initials, "strnatcasecmp");
+
+    $html_output = '<table id="initials_table" <cellspacing="5">'
+        . '<tr>';
+    foreach ($array_initials as $tmp_initial => $initial_was_found) {
+        if (! empty($tmp_initial)) {
+            if ($initial_was_found) {
+                $html_output .= '<td>'
+                    . '<a class="' . $conditional_class . '"'
+                    . ' href="server_privileges.php?'
+                    . $GLOBALS['url_query'] . '&'
+                    . 'initial=' . urlencode($tmp_initial) . '">' . $tmp_initial
+                    . '</a>'
+                    . '</td>' . "\n";
+            } else {
+                $html_output .= '<td>' . $tmp_initial . '</td>';
+            }
+        }
+    }
+    $html_output .= '<td>'
+        . '<a href="server_privileges.php?' . $GLOBALS['url_query']
+        . '&showall=1" '
+        . 'class="nowrap">[' . __('Show all') . ']</a></td>' . "\n";
+    $html_output .= '</tr></table>';
+
+    return $html_output;
+}
+
+/**
+ * Get the database rigths array for Display user overview
+ *
+ * @return array  $db_rights    database rights array
+ */
+function PMA_getDbRightsForUserOverview()
+{
+    // we also want users not in table `user` but in other table
+    $tables = PMA_DBI_fetch_result('SHOW TABLES FROM `mysql`;');
+
+    $tables_to_search_for_users = array(
+        'user', 'db', 'tables_priv', 'columns_priv', 'procs_priv',
+    );
+
+    $db_rights_sqls = array();
+    foreach ($tables_to_search_for_users as $table_search_in) {
+        if (in_array($table_search_in, $tables)) {
+            $db_rights_sqls[] = 'SELECT DISTINCT `User`, `Host` FROM `mysql`.`'
+                . $table_search_in . '` '
+                . (isset($_GET['initial']) ? PMA_rangeOfUsers($_GET['initial']) : '');
+        }
+    }
+    $user_defaults = array(
+        'User'       => '',
+        'Host'       => '%',
+        'Password'   => '?',
+        'Grant_priv' => 'N',
+        'privs'      => array('USAGE'),
+    );
+
+    // for the rights
+    $db_rights = array();
+
+    $db_rights_sql = '(' . implode(') UNION (', $db_rights_sqls) . ')'
+        .' ORDER BY `User` ASC, `Host` ASC';
+
+    $db_rights_result = PMA_DBI_query($db_rights_sql);
+
+    while ($db_rights_row = PMA_DBI_fetch_assoc($db_rights_result)) {
+        $db_rights_row = array_merge($user_defaults, $db_rights_row);
+        $db_rights[$db_rights_row['User']][$db_rights_row['Host']]
+            = $db_rights_row;
+    }
+    PMA_DBI_free_result($db_rights_result);
+    ksort($db_rights);
+
+    return $db_rights;
+}
+
+/**
+ * Delete user and get message and sql query for delete user in privileges
+ *
+ * @param string $queries queries
+ *
+ * @return PMA_message
+ */
+function PMA_deleteUser($queries)
+{
+    if (empty($queries)) {
+        $message = PMA_Message::error(__('No users selected for deleting!'));
+    } else {
+        if ($_REQUEST['mode'] == 3) {
+            $queries[] = '# ' . __('Reloading the privileges') . ' …';
+            $queries[] = 'FLUSH PRIVILEGES;';
+        }
+        $drop_user_error = '';
+        foreach ($queries as $sql_query) {
+            if ($sql_query{0} != '#') {
+                if (! PMA_DBI_try_query($sql_query, $GLOBALS['userlink'])) {
+                    $drop_user_error .= PMA_DBI_getError() . "\n";
+                }
+            }
+        }
+        // tracking sets this, causing the deleted db to be shown in navi
+        unset($GLOBALS['db']);
+
+        $sql_query = join("\n", $queries);
+        if (! empty($drop_user_error)) {
+            $message = PMA_Message::rawError($drop_user_error);
+        } else {
+            $message = PMA_Message::success(
+                __('The selected users have been deleted successfully.')
+            );
+        }
+    }
+    return array($sql_query, $message);
+}
+
+/**
+ * Update the privileges and return the success or error message
+ *
+ * @param string $username  username
+ * @param string $hostname  host name
+ * @param string $tablename table name
+ * @param string $dbname    database name
+ *
+ * @return PMA_message success message or error message for update
+ */
+function PMA_updatePrivileges($username, $hostname, $tablename, $dbname)
+{
+    $db_and_table = PMA_wildcardEscapeForGrant($dbname, $tablename);
+
+    $sql_query0 = 'REVOKE ALL PRIVILEGES ON ' . $db_and_table
+        . ' FROM \'' . PMA_Util::sqlAddSlashes($username)
+        . '\'@\'' . PMA_Util::sqlAddSlashes($hostname) . '\';';
+
+    if (! isset($_POST['Grant_priv']) || $_POST['Grant_priv'] != 'Y') {
+        $sql_query1 = 'REVOKE GRANT OPTION ON ' . $db_and_table
+            . ' FROM \'' . PMA_Util::sqlAddSlashes($username) . '\'@\''
+            . PMA_Util::sqlAddSlashes($hostname) . '\';';
+    } else {
+        $sql_query1 = '';
+    }
+
+    // Should not do a GRANT USAGE for a table-specific privilege, it
+    // causes problems later (cannot revoke it)
+    if (! (strlen($tablename) && 'USAGE' == implode('', PMA_extractPrivInfo()))) {
+        $sql_query2 = 'GRANT ' . join(', ', PMA_extractPrivInfo())
+            . ' ON ' . $db_and_table
+            . ' TO \'' . PMA_Util::sqlAddSlashes($username) . '\'@\''
+            . PMA_Util::sqlAddSlashes($hostname) . '\'';
+
+        if ((isset($_POST['Grant_priv']) && $_POST['Grant_priv'] == 'Y')
+            || (! strlen($dbname)
+            && (isset($_POST['max_questions']) || isset($_POST['max_connections'])
+            || isset($_POST['max_updates']) || isset($_POST['max_user_connections'])))
+        ) {
+            $sql_query2 .= PMA_getWithClauseForAddUserAndUpdatePrivs();
+        }
+        $sql_query2 .= ';';
+    }
+    if (! PMA_DBI_try_query($sql_query0)) {
+        // This might fail when the executing user does not have
+        // ALL PRIVILEGES himself.
+        // See https://sourceforge.net/p/phpmyadmin/bugs/3270/
+        $sql_query0 = '';
+    }
+    if (isset($sql_query1) && ! PMA_DBI_try_query($sql_query1)) {
+        // this one may fail, too...
+        $sql_query1 = '';
+    }
+    if (isset($sql_query2)) {
+        PMA_DBI_query($sql_query2);
+    } else {
+        $sql_query2 = '';
+    }
+    $sql_query = $sql_query0 . ' ' . $sql_query1 . ' ' . $sql_query2;
+    $message = PMA_Message::success(__('You have updated the privileges for %s.'));
+    $message->addParam(
+        '\'' . htmlspecialchars($username) . '\'@\'' . htmlspecialchars($hostname) . '\''
+    );
+
+    return array($sql_query, $message);
+}
+
+/**
+ * Get title and textarea for export user definition in Privileges
+ *
+ * @param string $username username
+ * @param string $hostname host name
+ *
+ * @return array ($title, $export)
+ */
+function PMA_getHtmlForExportUserDefinition($username, $hostname)
+{
+    $export = '<textarea class="export" cols="' . $GLOBALS['cfg']['TextareaCols']
+        . '" rows="' . $GLOBALS['cfg']['TextareaRows'] . '">';
+
+    if (isset($_REQUEST['selected_usr'])) {
+        // export privileges for selected users
+        $title = __('Privileges');
+        foreach ($_REQUEST['selected_usr'] as $export_user) {
+            $export_username = substr($export_user, 0, strpos($export_user, '&'));
+            $export_hostname = substr($export_user, strrpos($export_user, ';') + 1);
+            $export .= '# '
+                . sprintf(
+                    __('Privileges for %s'),
+                    '`' . htmlspecialchars($export_username)
+                    . '`@`' . htmlspecialchars($export_hostname) . '`'
+                )
+                . "\n\n";
+            $export .= PMA_getGrants($export_username, $export_hostname) . "\n";
+        }
+    } else {
+        // export privileges for a single user
+        $title = __('User') . ' `' . htmlspecialchars($username)
+            . '`@`' . htmlspecialchars($hostname) . '`';
+        $export .= PMA_getGrants($username, $hostname);
+    }
+    // remove trailing whitespace
+    $export = trim($export);
+
+    $export .= '</textarea>';
+
+    return array($title, $export);
+}
+
+/**
+ * Get HTML for display Add userfieldset
+ *
+ * @param string $conditional_class if ajaxable 'Ajax' otherwise ''
+ *
+ * @return string html output
+ */
+function PMA_getAddUserHtmlFieldset($conditional_class)
+{
+    return '<fieldset id="fieldset_add_user">' . "\n"
+        . '<a href="server_privileges.php?' . $GLOBALS['url_query']
+        . '&adduser=1" '
+        . 'class="' . $conditional_class . '">' . "\n"
+        . PMA_Util::getIcon('b_usradd.png')
+        . '            ' . __('Add user') . '</a>' . "\n"
+        . '</fieldset>' . "\n";
+}
+
+/**
+ * Get HTML header for display User's properties
+ *
+ * @param boolean $dbname_is_wildcard whether database name is wildcard or not
+ * @param string  $url_dbname         url database name that urlencode() string
+ * @param string  $dbname             database name
+ * @param string  $username           username
+ * @param string  $hostname           host name
+ * @param string  $tablename          table name
+ *
+ * @return string $html_output
+ */
+function PMA_getHtmlHeaderForDisplayUserProperties(
+    $dbname_is_wildcard, $url_dbname, $dbname, $username, $hostname, $tablename
+) {
+    $html_output = '<h2>' . "\n"
+       . PMA_Util::getIcon('b_usredit.png')
+       . __('Edit Privileges') . ': '
+       . __('User');
+
+    if (isset($dbname)) {
+        $html_output .= ' <i><a href="server_privileges.php?'
+            . $GLOBALS['url_query']
+            . '&username=' . htmlspecialchars(urlencode($username))
+            . '&hostname=' . htmlspecialchars(urlencode($hostname))
+            . '&dbname=&tablename=">\'' . htmlspecialchars($username)
+            . '\'@\'' . htmlspecialchars($hostname)
+            . '\'</a></i>' . "\n";
+
+        $html_output .= ' - ' . ($dbname_is_wildcard ? __('Databases') : __('Database') );
+        if (isset($_REQUEST['tablename'])) {
+            $html_output .= ' <i><a href="server_privileges.php?' . $GLOBALS['url_query']
+                . '&username=' . htmlspecialchars(urlencode($username))
+                . '&hostname=' . htmlspecialchars(urlencode($hostname))
+                . '&dbname=' . htmlspecialchars($url_dbname)
+                . '&tablename=">' . htmlspecialchars($dbname)
+                . '</a></i>';
+
+            $html_output .= ' - ' . __('Table')
+                . ' <i>' . htmlspecialchars($tablename) . '</i>';
+        } else {
+            $html_output .= ' <i>' . htmlspecialchars($dbname) . '</i>';
+        }
+
+    } else {
+        $html_output .= ' <i>\'' . htmlspecialchars($username)
+            . '\'@\'' . htmlspecialchars($hostname)
+            . '\'</i>' . "\n";
+
+    }
+    $html_output .= '</h2>' . "\n";
+
+    return $html_output;
+}
+
+/**
+ * Get HTML snippet for display user overview page
+ *
+ * @param string $link_edit         standard link to edit privileges
+ * @param string $pmaThemeImage     a image source link
+ * @param string $text_dir          text directory
+ * @param string $conditional_class if ajaxable 'Ajax' otherwise ''
+ * @param string $link_export       standard link to export privileges
+ *
+ * @return string $html_output
+ */
+function PMA_getHtmlForDisplayUserOverviewPage($link_edit, $pmaThemeImage,
+    $text_dir, $conditional_class, $link_export
+) {
+    $html_output = '<h2>' . "\n"
+       . PMA_Util::getIcon('b_usrlist.png')
+       . __('Users overview') . "\n"
+       . '</h2>' . "\n";
+
+    $sql_query = 'SELECT *,' .
+        "       IF(`Password` = _latin1 '', 'N', 'Y') AS 'Password'" .
+        '  FROM `mysql`.`user`';
+
+    $sql_query .= (isset($_REQUEST['initial'])
+        ? PMA_rangeOfUsers($_REQUEST['initial'])
+        : '');
+
+    $sql_query .= ' ORDER BY `User` ASC, `Host` ASC;';
+    $res = PMA_DBI_try_query($sql_query, null, PMA_DBI_QUERY_STORE);
+
+    if (! $res) {
+        // the query failed! This may have two reasons:
+        // - the user does not have enough privileges
+        // - the privilege tables use a structure of an earlier version.
+        // so let's try a more simple query
+
+        $sql_query = 'SELECT * FROM `mysql`.`user`';
+        $res = PMA_DBI_try_query($sql_query, null, PMA_DBI_QUERY_STORE);
+
+        if (! $res) {
+            $html_output .= PMA_Message::error(__('No Privileges'))->getDisplay();
+            PMA_DBI_free_result($res);
+            unset($res);
+        } else {
+            // This message is hardcoded because I will replace it by
+            // a automatic repair feature soon.
+            $raw = 'Your privilege table structure seems to be older than'
+                . ' this MySQL version!<br />'
+                . 'Please run the <code>mysql_upgrade</code> command'
+                . '(<code>mysql_fix_privilege_tables</code> on older systems)'
+                . ' that should be included in your MySQL server distribution'
+                . ' to solve this problem!';
+            $html_output .= PMA_Message::rawError($raw)->getDisplay();
+        }
+    } else {
+        $db_rights = PMA_getDbRightsForUserOverview();
+        // for all initials, even non A-Z
+        $array_initials = array();
+
+        /**
+         * Displays the initials
+         * Also not necassary if there is less than 20 privileges
+         */
+        if (PMA_DBI_num_rows($res) > 20 ) {
+            $html_output .= PMA_getHtmlForDisplayTheInitials(
+                $array_initials, $conditional_class
+            );
+        }
+
+        /**
+        * Display the user overview
+        * (if less than 50 users, display them immediately)
+        */
+        if (isset($_REQUEST['initial'])
+            || isset($_REQUEST['showall'])
+            || PMA_DBI_num_rows($res) < 50
+        ) {
+            $html_output .= PMA_getUsersOverview(
+                $res, $db_rights, $link_edit, $pmaThemeImage,
+                $text_dir, $conditional_class, $link_export
+            );
+        } else {
+            $html_output .= PMA_getAddUserHtmlFieldset($conditional_class);
+        } // end if (display overview)
+
+        if (! $GLOBALS['is_ajax_request'] || ! empty($_REQUEST['ajax_page_request'])) {
+            $flushnote = new PMA_Message(
+                __('Note: phpMyAdmin gets the users\' privileges directly from MySQL\'s privilege tables. The content of these tables may differ from the privileges the server uses, if they have been changed manually. In this case, you should %sreload the privileges%s before you continue.'),
+                PMA_Message::NOTICE
+            );
+            $flushLink = '<a href="server_privileges.php?' . $GLOBALS['url_query'] . '&'
+                . 'flush_privileges=1" id="reload_privileges_anchor" '
+                . 'class="' . $conditional_class . '">';
+            $flushnote->addParam(
+                $flushLink,
+                false
+            );
+            $flushnote->addParam('</a>', false);
+            $html_output .= $flushnote->getDisplay();
+        }
+        return $html_output;
+    }
+}
+
+/**
+ * Get HTML snippet for display user properties
+ *
+ * @param boolean $dbname_is_wildcard whether database name is wildcard or not
+ * @param type    $url_dbname         url database name that urlencode() string
+ * @param string  $username           username
+ * @param string  $hostname           host name
+ * @param string  $link_edit          standard link to edit privileges
+ * @param string  $link_revoke        standard link to revoke
+ * @param string  $dbname             database name
+ * @param string  $tablename          table name
+ *
+ * @return string $html_output
+ */
+function PMA_getHtmlForDisplayUserProperties($dbname_is_wildcard,$url_dbname,
+    $username, $hostname, $link_edit, $link_revoke, $dbname, $tablename
+) {
+    $html_output = PMA_getHtmlHeaderForDisplayUserProperties(
+        $dbname_is_wildcard, $url_dbname, $dbname, $username, $hostname, $tablename
+    );
+
+    $sql = "SELECT '1' FROM `mysql`.`user`"
+        . " WHERE `User` = '" . PMA_Util::sqlAddSlashes($username) . "'"
+        . " AND `Host` = '" . PMA_Util::sqlAddSlashes($hostname) . "';";
+
+    $user_does_not_exists = (bool) ! PMA_DBI_fetch_value($sql);
+
+    if ($user_does_not_exists) {
+        $html_output .= PMA_Message::error(
+            __('The selected user was not found in the privilege table.')
+        )->getDisplay();
+        $html_output .= PMA_getHtmlForDisplayLoginInformationFields();
+            //exit;
+    }
+
+    $class = ' class="ajax"';
+    $html_output .= '<form' . $class . ' name="usersForm" id="addUsersForm"'
+        . ' action="server_privileges.php" method="post">' . "\n";
+
+    $_params = array(
+        'username' => $username,
+        'hostname' => $hostname,
+    );
+    if (strlen($dbname)) {
+        $_params['dbname'] = $dbname;
+        if (strlen($tablename)) {
+            $_params['tablename'] = $tablename;
+        }
+    }
+    $html_output .= PMA_generate_common_hidden_inputs($_params);
+
+    $html_output .= PMA_getHtmlToDisplayPrivilegesTable(
+        PMA_ifSetOr($dbname, '*', 'length'),
+        PMA_ifSetOr($tablename, '*', 'length')
+    );
+
+    $html_output .= '</form>' . "\n";
+
+    if (! strlen($tablename) && empty($dbname_is_wildcard)) {
+
+        // no table name was given, display all table specific rights
+        // but only if $dbname contains no wildcards
+
+        $html_output .= '<form action="server_privileges.php" '
+            . 'id="db_or_table_specific_priv" method="post">' . "\n";
+
+        // unescape wildcards in dbname at table level
+        $unescaped_db = PMA_Util::unescapeMysqlWildcards($dbname);
+        list($html_rightsTable, $found_rows)
+            = PMA_getTableForDisplayAllTableSpecificRights(
+                $username, $hostname, $link_edit, $link_revoke, $unescaped_db
+            );
+        $html_output .= $html_rightsTable;
+
+        if (! strlen($dbname)) {
+            // no database name was given, display select db
+            $html_output .= PMA_getHtmlForDisplaySelectDbInEditPrivs($found_rows);
+
+        } else {
+            $html_output .= PMA_displayTablesInEditPrivs($dbname, $found_rows);
+        }
+        $html_output .= '</fieldset>' . "\n";
+
+        $html_output .= '<fieldset class="tblFooters">' . "\n"
+           . '    <input type="submit" value="' . __('Go') . '" />'
+           . '</fieldset>' . "\n"
+           . '</form>' . "\n";
+    }
+
+    // Provide a line with links to the relevant database and table
+    if (strlen($dbname) && empty($dbname_is_wildcard)) {
+        $html_output .= PMA_getLinkToDbAndTable($url_dbname, $dbname, $tablename);
+
+    }
+
+    if (! strlen($dbname) && ! $user_does_not_exists) {
+        //change login information
+        $html_output .= PMA_getHtmlForChangePassword($username, $hostname);
+        $html_output .= PMA_getChangeLoginInformationHtmlForm($username, $hostname);
+    }
+
+    return $html_output;
+}
+
+/**
+ * Get queries for Table privileges to change or copy user
+ *
+ * @param string $user_host_condition user host condition to select relevent table privileges
+ * @param array  $queries             queries array
+ * @param string $username            username
+ * @param string $hostname            host name
+ *
+ * @return array  $queries
+ */
+function PMA_getTablePrivsQueriesForChangeOrCopyUser($user_host_condition,
+    $queries, $username, $hostname
+) {
+    $res = PMA_DBI_query(
+        'SELECT `Db`, `Table_name`, `Table_priv` FROM `mysql`.`tables_priv`' . $user_host_condition,
+        $GLOBALS['userlink'],
+        PMA_DBI_QUERY_STORE
+    );
+    while ($row = PMA_DBI_fetch_assoc($res)) {
+
+        $res2 = PMA_DBI_QUERY(
+            'SELECT `Column_name`, `Column_priv`'
+            .' FROM `mysql`.`columns_priv`'
+            .' WHERE `User`'
+            .' = \'' . PMA_Util::sqlAddSlashes($_REQUEST['old_username']) . "'"
+            .' AND `Host`'
+            .' = \'' . PMA_Util::sqlAddSlashes($_REQUEST['old_username']) . '\''
+            .' AND `Db`'
+            .' = \'' . PMA_Util::sqlAddSlashes($row['Db']) . "'"
+            .' AND `Table_name`'
+            .' = \'' . PMA_Util::sqlAddSlashes($row['Table_name']) . "'"
+            .';',
+            null,
+            PMA_DBI_QUERY_STORE
+        );
+
+        $tmp_privs1 = PMA_extractPrivInfo($row);
+        $tmp_privs2 = array(
+            'Select' => array(),
+            'Insert' => array(),
+            'Update' => array(),
+            'References' => array()
+        );
+
+        while ($row2 = PMA_DBI_fetch_assoc($res2)) {
+            $tmp_array = explode(',', $row2['Column_priv']);
+            if (in_array('Select', $tmp_array)) {
+                $tmp_privs2['Select'][] = $row2['Column_name'];
+            }
+            if (in_array('Insert', $tmp_array)) {
+                $tmp_privs2['Insert'][] = $row2['Column_name'];
+            }
+            if (in_array('Update', $tmp_array)) {
+                $tmp_privs2['Update'][] = $row2['Column_name'];
+            }
+            if (in_array('References', $tmp_array)) {
+                $tmp_privs2['References'][] = $row2['Column_name'];
+            }
+        }
+        if (count($tmp_privs2['Select']) > 0 && ! in_array('SELECT', $tmp_privs1)) {
+            $tmp_privs1[] = 'SELECT (`' . join('`, `', $tmp_privs2['Select']) . '`)';
+        }
+        if (count($tmp_privs2['Insert']) > 0 && ! in_array('INSERT', $tmp_privs1)) {
+            $tmp_privs1[] = 'INSERT (`' . join('`, `', $tmp_privs2['Insert']) . '`)';
+        }
+        if (count($tmp_privs2['Update']) > 0 && ! in_array('UPDATE', $tmp_privs1)) {
+            $tmp_privs1[] = 'UPDATE (`' . join('`, `', $tmp_privs2['Update']) . '`)';
+        }
+        if (count($tmp_privs2['References']) > 0 && ! in_array('REFERENCES', $tmp_privs1)) {
+            $tmp_privs1[] = 'REFERENCES (`' . join('`, `', $tmp_privs2['References']) . '`)';
+        }
+
+        $queries[] = 'GRANT ' . join(', ', $tmp_privs1)
+            . ' ON ' . PMA_Util::backquote($row['Db']) . '.'
+            . PMA_Util::backquote($row['Table_name'])
+            . ' TO \'' . PMA_Util::sqlAddSlashes($username)
+            . '\'@\'' . PMA_Util::sqlAddSlashes($hostname) . '\''
+            . (in_array('Grant', explode(',', $row['Table_priv'])) ? ' WITH GRANT OPTION;' : ';');
+    }
+    return $queries;
+}
+
+/**
+ * Get queries for database specific privileges for change or copy user
+ *
+ * @param array  $queries  queries array with string
+ * @param string $username username
+ * @param string $hostname host name
+ *
+ * @return array $queries
+ */
+function PMA_getDbSpecificPrivsQueriesForChangeOrCopyUser(
+    $queries, $username, $hostname
+) {
+    $user_host_condition = ' WHERE `User`'
+        .' = \'' . PMA_Util::sqlAddSlashes($_REQUEST['old_username']) . "'"
+        .' AND `Host`'
+        .' = \'' . PMA_Util::sqlAddSlashes($_REQUEST['old_username']) . '\';';
+
+    $res = PMA_DBI_query('SELECT * FROM `mysql`.`db`' . $user_host_condition);
+
+    while ($row = PMA_DBI_fetch_assoc($res)) {
+        $queries[] = 'GRANT ' . join(', ', PMA_extractPrivInfo($row))
+            .' ON ' . PMA_Util::backquote($row['Db']) . '.*'
+            .' TO \'' . PMA_Util::sqlAddSlashes($username)
+            . '\'@\'' . PMA_Util::sqlAddSlashes($hostname) . '\''
+            . ($row['Grant_priv'] == 'Y' ? ' WITH GRANT OPTION;' : ';');
+    }
+    PMA_DBI_free_result($res);
+
+    $queries = PMA_getTablePrivsQueriesForChangeOrCopyUser(
+        $user_host_condition, $queries, $username, $hostname
+    );
+
+    return $queries;
+}
+
+/**
+ * Prepares queries for adding users and
+ * also create database and return query and message
+ *
+ * @param boolean $_error         whether user create or not
+ * @param string  $real_sql_query SQL query for add a user
+ * @param string  $sql_query      SQL query to be displayed
+ * @param string  $username       username
+ * @param string  $hostname       host name
+ * @param string  $dbname         database name
+ *
+ * @return array  $sql_query, $message
+ */
+function PMA_addUserAndCreateDatabase($_error, $real_sql_query, $sql_query,
+    $username, $hostname, $dbname
+) {
+    if ($_error || ! PMA_DBI_try_query($real_sql_query)) {
+        $_REQUEST['createdb-1'] = $_REQUEST['createdb-2']
+            = $_REQUEST['createdb-3'] = false;
+        $message = PMA_Message::rawError(PMA_DBI_getError());
+    } else {
+        $message = PMA_Message::success(__('You have added a new user.'));
+    }
+
+    if (isset($_REQUEST['createdb-1'])) {
+        // Create database with same name and grant all privileges
+        $q = 'CREATE DATABASE IF NOT EXISTS '
+            . PMA_Util::backquote(
+                PMA_Util::sqlAddSlashes($username)
+            ) . ';';
+        $sql_query .= $q;
+        if (! PMA_DBI_try_query($q)) {
+            $message = PMA_Message::rawError(PMA_DBI_getError());
+        }
+
+        /**
+         * Reload the navigation
+         */
+        $GLOBALS['reload'] = true;
+        $GLOBALS['db'] = $username;
+
+        $q = 'GRANT ALL PRIVILEGES ON '
+            . PMA_Util::backquote(
+                PMA_Util::escapeMysqlWildcards(
+                    PMA_Util::sqlAddSlashes($username)
+                )
+            ) . '.* TO \''
+            . PMA_Util::sqlAddSlashes($username)
+            . '\'@\'' . PMA_Util::sqlAddSlashes($hostname) . '\';';
+        $sql_query .= $q;
+        if (! PMA_DBI_try_query($q)) {
+            $message = PMA_Message::rawError(PMA_DBI_getError());
+        }
+    }
+
+    if (isset($_REQUEST['createdb-2'])) {
+        // Grant all privileges on wildcard name (username\_%)
+        $q = 'GRANT ALL PRIVILEGES ON '
+            . PMA_Util::backquote(
+                PMA_Util::sqlAddSlashes($username) . '\_%'
+            ) . '.* TO \''
+            . PMA_Util::sqlAddSlashes($username)
+            . '\'@\'' . PMA_Util::sqlAddSlashes($hostname) . '\';';
+        $sql_query .= $q;
+        if (! PMA_DBI_try_query($q)) {
+            $message = PMA_Message::rawError(PMA_DBI_getError());
+        }
+    }
+
+    if (isset($_REQUEST['createdb-3'])) {
+        // Grant all privileges on the specified database to the new user
+        $q = 'GRANT ALL PRIVILEGES ON '
+        . PMA_Util::backquote(
+            PMA_Util::sqlAddSlashes($dbname)
+        ) . '.* TO \''
+        . PMA_Util::sqlAddSlashes($username)
+        . '\'@\'' . PMA_Util::sqlAddSlashes($hostname) . '\';';
+        $sql_query .= $q;
+        if (! PMA_DBI_try_query($q)) {
+            $message = PMA_Message::rawError(PMA_DBI_getError());
+        }
+    }
+    return array($sql_query, $message);
+}
+
+/**
+ * Get SQL queries for Display and Add user
+ *
+ * @param string $username usernam
+ * @param string $hostname host name
+ * @param string $password password
+ *
+ * @return array ($create_user_real, $create_user_show,$real_sql_query, $sql_query)
+ */
+function PMA_getSqlQueriesForDisplayAndAddUser($username, $hostname, $password)
+{
+    $sql_query = '';
+    $create_user_real = 'CREATE USER \''
+        . PMA_Util::sqlAddSlashes($username) . '\'@\''
+        . PMA_Util::sqlAddSlashes($hostname) . '\'';
+
+    $real_sql_query = 'GRANT ' . join(', ', PMA_extractPrivInfo()) . ' ON *.* TO \''
+        . PMA_Util::sqlAddSlashes($username) . '\'@\''
+        . PMA_Util::sqlAddSlashes($hostname) . '\'';
+
+    if ($_POST['pred_password'] != 'none' && $_POST['pred_password'] != 'keep') {
+        $sql_query = $real_sql_query . ' IDENTIFIED BY \'***\'';
+        $real_sql_query .= ' IDENTIFIED BY \''
+            . PMA_Util::sqlAddSlashes($_POST['pma_pw']) . '\'';
+        if (isset($create_user_real)) {
+            $create_user_show = $create_user_real . ' IDENTIFIED BY \'***\'';
+            $create_user_real .= ' IDENTIFIED BY \''
+                . PMA_Util::sqlAddSlashes($_POST['pma_pw']) . '\'';
+        }
+    } else {
+        if ($_POST['pred_password'] == 'keep' && ! empty($password)) {
+            $real_sql_query .= ' IDENTIFIED BY PASSWORD \'' . $password . '\'';
+            if (isset($create_user_real)) {
+                $create_user_real .= ' IDENTIFIED BY PASSWORD \'' . $password . '\'';
+            }
+        }
+        $sql_query = $real_sql_query;
+        if (isset($create_user_real)) {
+            $create_user_show = $create_user_real;
+        }
+    }
+
+    if ((isset($_POST['Grant_priv']) && $_POST['Grant_priv'] == 'Y')
+        || (isset($_POST['max_questions']) || isset($_POST['max_connections'])
+        || isset($_POST['max_updates']) || isset($_POST['max_user_connections']))
+    ) {
+        $with_clause = PMA_getWithClauseForAddUserAndUpdatePrivs();
+        $real_sql_query .= ' ' . $with_clause;
+        $sql_query .= ' ' . $with_clause;
+    }
+
+    if (isset($create_user_real)) {
+        $create_user_real .= ';';
+        $create_user_show .= ';';
+    }
+    $real_sql_query .= ';';
+    $sql_query .= ';';
+
+    return array($create_user_real,
+        $create_user_show,
+        $real_sql_query,
+        $sql_query
+    );
+}
+?>
diff --git a/phpmyadmin/libraries/server_variables_doc.php b/phpmyadmin/libraries/server_variables_doc.php
new file mode 100644
index 0000000..9656936
--- /dev/null
+++ b/phpmyadmin/libraries/server_variables_doc.php
@@ -0,0 +1,1403 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * Used to create server variables documentation links
+ * $VARIABLE_DOC_LINKS[string $name] = array(
+ *    string $anchor,
+ *    string $chapter,
+ *    string $type);
+ * string $name: name of the system variable
+ * string $anchor: anchor to the documentation page
+ * string $chapter: chapter of "HTML, one page per chapter" documentation
+ * string $type: type of system variable
+ * string $format: if set to 'byte' it will format the variable
+ * with PMA_Util::formatByteDown()
+ *
+ * @package PhpMyAdmin
+ */
+if (! defined('PHPMYADMIN')) {
+    exit;
+}
+
+$VARIABLE_DOC_LINKS = array();
+$VARIABLE_DOC_LINKS['auto_increment_increment'] = array(
+    'auto_increment_increment',
+    'replication-options-master',
+    'sysvar');
+$VARIABLE_DOC_LINKS['auto_increment_offset'] = array(
+    'auto_increment_offset',
+    'replication-options-master',
+    'sysvar');
+$VARIABLE_DOC_LINKS['autocommit'] = array(
+    'autocommit',
+    'server-system-variables',
+    'sysvar');
+$VARIABLE_DOC_LINKS['automatic_sp_privileges'] = array(
+    'automatic_sp_privileges',
+    'server-system-variables',
+    'sysvar');
+$VARIABLE_DOC_LINKS['back_log'] = array(
+    'back_log',
+    'server-system-variables',
+    'sysvar');
+$VARIABLE_DOC_LINKS['basedir'] = array(
+    'basedir',
+    'server-options',
+    'option_mysqld');
+$VARIABLE_DOC_LINKS['big_tables'] = array(
+    'big-tables',
+    'server-options',
+    'option_mysqld');
+$VARIABLE_DOC_LINKS['bind_address'] = array(
+    'bind-address',
+    'server-options',
+    'option_mysqld');
+$VARIABLE_DOC_LINKS['binlog_cache_size'] = array(
+    'binlog_cache_size',
+    'replication-options-binary-log',
+    'sysvar',
+    'byte');
+$VARIABLE_DOC_LINKS['binlog_direct_non_transactional_updates'] = array(
+    'binlog_direct_non_transactional_updates',
+    'replication-options-binary-log',
+    'sysvar');
+$VARIABLE_DOC_LINKS['binlog_format'] = array(
+    'binlog-format',
+    'server-options',
+    'sysvar');
+$VARIABLE_DOC_LINKS['binlog_stmt_cache_size'] = array(
+    'binlog_stmt_cache_size',
+    'replication-options-binary-log',
+    'sysvar',
+    'byte');
+$VARIABLE_DOC_LINKS['bulk_insert_buffer_size'] = array(
+    'bulk_insert_buffer_size',
+    'server-system-variables',
+    'sysvar',
+    'byte');
+$VARIABLE_DOC_LINKS['character_set_client'] = array(
+    'character_set_client',
+    'server-system-variables',
+    'sysvar');
+$VARIABLE_DOC_LINKS['character_set_connection'] = array(
+    'character_set_connection',
+    'server-system-variables',
+    'sysvar');
+$VARIABLE_DOC_LINKS['character_set_database'] = array(
+    'character_set_database',
+    'server-system-variables',
+    'sysvar');
+$VARIABLE_DOC_LINKS['character_set_filesystem'] = array(
+    'character-set-filesystem',
+    'server-options',
+    'option_mysqld');
+$VARIABLE_DOC_LINKS['character_set_results'] = array(
+    'character_set_results',
+    'server-system-variables',
+    'sysvar');
+$VARIABLE_DOC_LINKS['character_set_server'] = array(
+    'character-set-server',
+    'server-options',
+    'option_mysqld');
+$VARIABLE_DOC_LINKS['character_set_system'] = array(
+    'character_set_system',
+    'server-system-variables',
+    'sysvar');
+$VARIABLE_DOC_LINKS['character_sets_dir'] = array(
+    'character-sets-dir',
+    'server-options',
+    'option_mysqld');
+$VARIABLE_DOC_LINKS['collation_connection'] = array(
+    'collation_connection',
+    'server-system-variables',
+    'sysvar');
+$VARIABLE_DOC_LINKS['collation_database'] = array(
+    'collation_database',
+    'server-system-variables',
+    'sysvar');
+$VARIABLE_DOC_LINKS['collation_server'] = array(
+    'collation-server',
+    'server-options',
+    'option_mysqld');
+$VARIABLE_DOC_LINKS['completion_type'] = array(
+    'completion_type',
+    'server-system-variables',
+    'sysvar');
+$VARIABLE_DOC_LINKS['concurrent_insert'] = array(
+    'concurrent_insert',
+    'server-system-variables',
+    'sysvar');
+$VARIABLE_DOC_LINKS['connect_timeout'] = array(
+    'connect_timeout',
+    'server-system-variables',
+    'sysvar');
+$VARIABLE_DOC_LINKS['datadir'] = array(
+    'datadir',
+    'server-options',
+    'option_mysqld');
+$VARIABLE_DOC_LINKS['date_format'] = array(
+    'date_format',
+    'server-system-variables',
+    'sysvar');
+$VARIABLE_DOC_LINKS['datetime_format'] = array(
+    'datetime_format',
+    'server-system-variables',
+    'sysvar');
+$VARIABLE_DOC_LINKS['debug'] = array(
+    'debug',
+    'server-options',
+    'option_mysqld');
+$VARIABLE_DOC_LINKS['debug_sync'] = array(
+    'debug_sync',
+    'server-system-variables',
+    'sysvar');
+$VARIABLE_DOC_LINKS['default_storage_engine'] = array(
+    'default-storage-engine',
+    'server-options',
+    'option_mysqld');
+$VARIABLE_DOC_LINKS['default_week_format'] = array(
+    'default_week_format',
+    'server-system-variables',
+    'sysvar');
+$VARIABLE_DOC_LINKS['delay_key_write'] = array(
+    'delay-key-write',
+    'server-options',
+    'option_mysqld');
+$VARIABLE_DOC_LINKS['delayed_insert_limit'] = array(
+    'delayed_insert_limit',
+    'server-system-variables',
+    'sysvar');
+$VARIABLE_DOC_LINKS['delayed_insert_timeout'] = array(
+    'delayed_insert_timeout',
+    'server-system-variables',
+    'sysvar');
+$VARIABLE_DOC_LINKS['delayed_queue_size'] = array(
+    'delayed_queue_size',
+    'server-system-variables',
+    'sysvar');
+$VARIABLE_DOC_LINKS['div_precision_increment'] = array(
+    'div_precision_increment',
+    'server-system-variables',
+    'sysvar');
+$VARIABLE_DOC_LINKS['engine_condition_pushdown'] = array(
+    'engine-condition-pushdown',
+    'server-options',
+    'option_mysqld');
+$VARIABLE_DOC_LINKS['error_count'] = array(
+    'error_count',
+    'server-system-variables',
+    'sysvar');
+$VARIABLE_DOC_LINKS['event_scheduler'] = array(
+    'event-scheduler',
+    'server-options',
+    'option_mysqld');
+$VARIABLE_DOC_LINKS['expire_logs_days'] = array(
+    'expire_logs_days',
+    'server-system-variables',
+    'sysvar');
+$VARIABLE_DOC_LINKS['external_user'] = array(
+    'external_user',
+    'server-system-variables',
+    'sysvar');
+$VARIABLE_DOC_LINKS['flush'] = array(
+    'flush',
+    'server-system-variables',
+    'sysvar');
+$VARIABLE_DOC_LINKS['flush_time'] = array(
+    'flush_time',
+    'server-system-variables',
+    'sysvar');
+$VARIABLE_DOC_LINKS['foreign_key_checks'] = array(
+    'foreign_key_checks',
+    'server-system-variables',
+    'sysvar');
+$VARIABLE_DOC_LINKS['ft_boolean_syntax'] = array(
+    'ft_boolean_syntax',
+    'server-system-variables',
+    'sysvar');
+$VARIABLE_DOC_LINKS['ft_max_word_len'] = array(
+    'ft_max_word_len',
+    'server-system-variables',
+    'sysvar');
+$VARIABLE_DOC_LINKS['ft_min_word_len'] = array(
+    'ft_min_word_len',
+    'server-system-variables',
+    'sysvar');
+$VARIABLE_DOC_LINKS['ft_query_expansion_limit'] = array(
+    'ft_query_expansion_limit',
+    'server-system-variables',
+    'sysvar');
+$VARIABLE_DOC_LINKS['ft_stopword_file'] = array(
+    'ft_stopword_file',
+    'server-system-variables',
+    'sysvar');
+$VARIABLE_DOC_LINKS['general_log'] = array(
+    'general-log',
+    'server-options',
+    'option_mysqld');
+$VARIABLE_DOC_LINKS['general_log_file'] = array(
+    'general_log_file',
+    'server-system-variables',
+    'sysvar');
+$VARIABLE_DOC_LINKS['group_concat_max_len'] = array(
+    'group_concat_max_len',
+    'server-system-variables',
+    'sysvar');
+$VARIABLE_DOC_LINKS['have_compress'] = array(
+    'have_compress',
+    'server-system-variables',
+    'sysvar');
+$VARIABLE_DOC_LINKS['have_crypt'] = array(
+    'have_crypt',
+    'server-system-variables',
+    'sysvar');
+$VARIABLE_DOC_LINKS['have_csv'] = array(
+    'have_csv',
+    'server-system-variables',
+    'sysvar');
+$VARIABLE_DOC_LINKS['have_dynamic_loading'] = array(
+    'have_dynamic_loading',
+    'server-system-variables',
+    'sysvar');
+$VARIABLE_DOC_LINKS['have_geometry'] = array(
+    'have_geometry',
+    'server-system-variables',
+    'sysvar');
+$VARIABLE_DOC_LINKS['have_innodb'] = array(
+    'have_innodb',
+    'server-system-variables',
+    'sysvar');
+$VARIABLE_DOC_LINKS['have_openssl'] = array(
+    'have_openssl',
+    'server-system-variables',
+    'sysvar');
+$VARIABLE_DOC_LINKS['have_partitioning'] = array(
+    'have_partitioning',
+    'server-system-variables',
+    'sysvar');
+$VARIABLE_DOC_LINKS['have_profiling'] = array(
+    'have_profiling',
+    'server-system-variables',
+    'sysvar');
+$VARIABLE_DOC_LINKS['have_query_cache'] = array(
+    'have_query_cache',
+    'server-system-variables',
+    'sysvar');
+$VARIABLE_DOC_LINKS['have_rtree_keys'] = array(
+    'have_rtree_keys',
+    'server-system-variables',
+    'sysvar');
+$VARIABLE_DOC_LINKS['have_ssl'] = array(
+    'have_ssl',
+    'server-system-variables',
+    'sysvar');
+$VARIABLE_DOC_LINKS['have_symlink'] = array(
+    'have_symlink',
+    'server-system-variables',
+    'sysvar');
+$VARIABLE_DOC_LINKS['hostname'] = array(
+    'hostname',
+    'server-system-variables',
+    'sysvar');
+$VARIABLE_DOC_LINKS['identity'] = array(
+    'identity',
+    'server-system-variables',
+    'sysvar');
+$VARIABLE_DOC_LINKS['ignore_builtin_innodb'] = array(
+    'ignore-builtin-innodb',
+    'innodb-parameters',
+    'option_mysqld');
+$VARIABLE_DOC_LINKS['init_connect'] = array(
+    'init_connect',
+    'server-system-variables',
+    'sysvar');
+$VARIABLE_DOC_LINKS['init_file'] = array(
+    'init-file',
+    'server-options',
+    'option_mysqld');
+$VARIABLE_DOC_LINKS['init_slave'] = array(
+    'init_slave',
+    'replication-options-slave',
+    'sysvar');
+$VARIABLE_DOC_LINKS['innodb_adaptive_flushing'] = array(
+    'innodb_adaptive_flushing',
+    'innodb-parameters',
+    'sysvar');
+$VARIABLE_DOC_LINKS['innodb_adaptive_hash_index'] = array(
+    'innodb_adaptive_hash_index',
+    'innodb-parameters',
+    'sysvar');
+$VARIABLE_DOC_LINKS['innodb_additional_mem_pool_size'] = array(
+    'innodb_additional_mem_pool_size',
+    'innodb-parameters',
+    'sysvar',
+    'byte');
+$VARIABLE_DOC_LINKS['innodb_autoextend_increment'] = array(
+    'innodb_autoextend_increment',
+    'innodb-parameters',
+    'sysvar');
+$VARIABLE_DOC_LINKS['innodb_autoinc_lock_mode'] = array(
+    'innodb_autoinc_lock_mode',
+    'innodb-parameters',
+    'sysvar');
+$VARIABLE_DOC_LINKS['innodb_buffer_pool_instances'] = array(
+    'innodb_buffer_pool_instances',
+    'innodb-parameters',
+    'sysvar');
+$VARIABLE_DOC_LINKS['innodb_buffer_pool_size'] = array(
+    'innodb_buffer_pool_size',
+    'innodb-parameters',
+    'sysvar',
+    'byte');
+$VARIABLE_DOC_LINKS['innodb_change_buffering'] = array(
+    'innodb_change_buffering',
+    'innodb-parameters',
+    'sysvar');
+$VARIABLE_DOC_LINKS['innodb_checksums'] = array(
+    'innodb_checksums',
+    'innodb-parameters',
+    'sysvar');
+$VARIABLE_DOC_LINKS['innodb_commit_concurrency'] = array(
+    'innodb_commit_concurrency',
+    'innodb-parameters',
+    'sysvar');
+$VARIABLE_DOC_LINKS['innodb_concurrency_tickets'] = array(
+    'innodb_concurrency_tickets',
+    'innodb-parameters',
+    'sysvar');
+$VARIABLE_DOC_LINKS['innodb_data_file_path'] = array(
+    'innodb_data_file_path',
+    'innodb-parameters',
+    'sysvar');
+$VARIABLE_DOC_LINKS['innodb_data_home_dir'] = array(
+    'innodb_data_home_dir',
+    'innodb-parameters',
+    'sysvar');
+$VARIABLE_DOC_LINKS['innodb_doublewrite'] = array(
+    'innodb_doublewrite',
+    'innodb-parameters',
+    'sysvar');
+$VARIABLE_DOC_LINKS['innodb_fast_shutdown'] = array(
+    'innodb_fast_shutdown',
+    'innodb-parameters',
+    'sysvar');
+$VARIABLE_DOC_LINKS['innodb_file_format'] = array(
+    'innodb_file_format',
+    'innodb-parameters',
+    'sysvar');
+$VARIABLE_DOC_LINKS['innodb_file_format_check'] = array(
+    'innodb_file_format_check',
+    'innodb-parameters',
+    'sysvar');
+$VARIABLE_DOC_LINKS['innodb_file_format_max'] = array(
+    'innodb_file_format_max',
+    'innodb-parameters',
+    'sysvar');
+$VARIABLE_DOC_LINKS['innodb_file_per_table'] = array(
+    'innodb_file_per_table',
+    'innodb-parameters',
+    'sysvar');
+$VARIABLE_DOC_LINKS['innodb_flush_log_at_trx_commit'] = array(
+    'innodb_flush_log_at_trx_commit',
+    'innodb-parameters',
+    'sysvar');
+$VARIABLE_DOC_LINKS['innodb_flush_method'] = array(
+    'innodb_flush_method',
+    'innodb-parameters',
+    'sysvar');
+$VARIABLE_DOC_LINKS['innodb_force_recovery'] = array(
+    'innodb_force_recovery',
+    'innodb-parameters',
+    'sysvar');
+$VARIABLE_DOC_LINKS['innodb_io_capacity'] = array(
+    'innodb_io_capacity',
+    'innodb-parameters',
+    'sysvar');
+$VARIABLE_DOC_LINKS['innodb_lock_wait_timeout'] = array(
+    'innodb_lock_wait_timeout',
+    'innodb-parameters',
+    'sysvar');
+$VARIABLE_DOC_LINKS['innodb_locks_unsafe_for_binlog'] = array(
+    'innodb_locks_unsafe_for_binlog',
+    'innodb-parameters',
+    'sysvar');
+$VARIABLE_DOC_LINKS['innodb_log_buffer_size'] = array(
+    'innodb_log_buffer_size',
+    'innodb-parameters',
+    'sysvar',
+    'byte');
+$VARIABLE_DOC_LINKS['innodb_log_file_size'] = array(
+    'innodb_log_file_size',
+    'innodb-parameters',
+    'sysvar',
+    'byte');
+$VARIABLE_DOC_LINKS['innodb_log_files_in_group'] = array(
+    'innodb_log_files_in_group',
+    'innodb-parameters',
+    'sysvar');
+$VARIABLE_DOC_LINKS['innodb_log_group_home_dir'] = array(
+    'innodb_log_group_home_dir',
+    'innodb-parameters',
+    'sysvar');
+$VARIABLE_DOC_LINKS['innodb_max_dirty_pages_pct'] = array(
+    'innodb_max_dirty_pages_pct',
+    'innodb-parameters',
+    'sysvar');
+$VARIABLE_DOC_LINKS['innodb_max_purge_lag'] = array(
+    'innodb_max_purge_lag',
+    'innodb-parameters',
+    'sysvar');
+$VARIABLE_DOC_LINKS['innodb_mirrored_log_groups'] = array(
+    'innodb_mirrored_log_groups',
+    'innodb-parameters',
+    'sysvar');
+$VARIABLE_DOC_LINKS['innodb_old_blocks_pct'] = array(
+    'innodb_old_blocks_pct',
+    'innodb-parameters',
+    'sysvar');
+$VARIABLE_DOC_LINKS['innodb_old_blocks_time'] = array(
+    'innodb_old_blocks_time',
+    'innodb-parameters',
+    'sysvar');
+$VARIABLE_DOC_LINKS['innodb_open_files'] = array(
+    'innodb_open_files',
+    'innodb-parameters',
+    'sysvar');
+$VARIABLE_DOC_LINKS['innodb_purge_batch_size'] = array(
+    'innodb_purge_batch_size',
+    'innodb-parameters',
+    'sysvar');
+$VARIABLE_DOC_LINKS['innodb_purge_threads'] = array(
+    'innodb_purge_threads',
+    'innodb-parameters',
+    'sysvar');
+$VARIABLE_DOC_LINKS['innodb_read_ahead_threshold'] = array(
+    'innodb_read_ahead_threshold',
+    'innodb-parameters',
+    'sysvar');
+$VARIABLE_DOC_LINKS['innodb_read_io_threads'] = array(
+    'innodb_read_io_threads',
+    'innodb-parameters',
+    'sysvar');
+$VARIABLE_DOC_LINKS['innodb_replication_delay'] = array(
+    'innodb_replication_delay',
+    'innodb-parameters',
+    'sysvar');
+$VARIABLE_DOC_LINKS['innodb_rollback_on_timeout'] = array(
+    'innodb_rollback_on_timeout',
+    'innodb-parameters',
+    'sysvar');
+$VARIABLE_DOC_LINKS['innodb_spin_wait_delay'] = array(
+    'innodb_spin_wait_delay',
+    'innodb-parameters',
+    'sysvar');
+$VARIABLE_DOC_LINKS['innodb_stats_on_metadata'] = array(
+    'innodb_stats_on_metadata',
+    'innodb-parameters',
+    'sysvar');
+$VARIABLE_DOC_LINKS['innodb_stats_sample_pages'] = array(
+    'innodb_stats_sample_pages',
+    'innodb-parameters',
+    'sysvar');
+$VARIABLE_DOC_LINKS['innodb_strict_mode'] = array(
+    'innodb_strict_mode',
+    'innodb-parameters',
+    'sysvar');
+$VARIABLE_DOC_LINKS['innodb_support_xa'] = array(
+    'innodb_support_xa',
+    'innodb-parameters',
+    'sysvar');
+$VARIABLE_DOC_LINKS['innodb_sync_spin_loops'] = array(
+    'innodb_sync_spin_loops',
+    'innodb-parameters',
+    'sysvar');
+$VARIABLE_DOC_LINKS['innodb_table_locks'] = array(
+    'innodb_table_locks',
+    'innodb-parameters',
+    'sysvar');
+$VARIABLE_DOC_LINKS['innodb_thread_concurrency'] = array(
+    'innodb_thread_concurrency',
+    'innodb-parameters',
+    'sysvar');
+$VARIABLE_DOC_LINKS['innodb_thread_sleep_delay'] = array(
+    'innodb_thread_sleep_delay',
+    'innodb-parameters',
+    'sysvar');
+$VARIABLE_DOC_LINKS['innodb_use_native_aio'] = array(
+    'innodb_use_native_aio',
+    'innodb-parameters',
+    'sysvar');
+$VARIABLE_DOC_LINKS['innodb_use_sys_malloc'] = array(
+    'innodb_use_sys_malloc',
+    'innodb-parameters',
+    'sysvar');
+$VARIABLE_DOC_LINKS['innodb_version'] = array(
+    'innodb_version',
+    'innodb-parameters',
+    'sysvar');
+$VARIABLE_DOC_LINKS['innodb_write_io_threads'] = array(
+    'innodb_write_io_threads',
+    'innodb-parameters',
+    'sysvar');
+$VARIABLE_DOC_LINKS['insert_id'] = array(
+    'insert_id',
+    'server-system-variables',
+    'sysvar');
+$VARIABLE_DOC_LINKS['interactive_timeout'] = array(
+    'interactive_timeout',
+    'server-system-variables',
+    'sysvar');
+$VARIABLE_DOC_LINKS['join_buffer_size'] = array(
+    'join_buffer_size',
+    'server-system-variables',
+    'sysvar',
+    'byte');
+$VARIABLE_DOC_LINKS['keep_files_on_create'] = array(
+    'keep_files_on_create',
+    'server-system-variables',
+    'sysvar');
+$VARIABLE_DOC_LINKS['key_buffer_size'] = array(
+    'key_buffer_size',
+    'server-system-variables',
+    'sysvar',
+    'byte');
+$VARIABLE_DOC_LINKS['key_cache_age_threshold'] = array(
+    'key_cache_age_threshold',
+    'server-system-variables',
+    'sysvar');
+$VARIABLE_DOC_LINKS['key_cache_block_size'] = array(
+    'key_cache_block_size',
+    'server-system-variables',
+    'sysvar',
+    'byte');
+$VARIABLE_DOC_LINKS['key_cache_division_limit'] = array(
+    'key_cache_division_limit',
+    'server-system-variables',
+    'sysvar');
+$VARIABLE_DOC_LINKS['language'] = array(
+    'language',
+    'server-options',
+    'option_mysqld');
+$VARIABLE_DOC_LINKS['large_files_support'] = array(
+    'large_files_support',
+    'server-system-variables',
+    'sysvar');
+$VARIABLE_DOC_LINKS['large_page_size'] = array(
+    'large_page_size',
+    'server-system-variables',
+    'sysvar',
+    'byte');
+$VARIABLE_DOC_LINKS['large_pages'] = array(
+    'large-pages',
+    'server-options',
+    'option_mysqld');
+$VARIABLE_DOC_LINKS['last_insert_id'] = array(
+    'last_insert_id',
+    'server-system-variables',
+    'sysvar');
+$VARIABLE_DOC_LINKS['lc_messages'] = array(
+    'lc-messages',
+    'server-options',
+    'option_mysqld');
+$VARIABLE_DOC_LINKS['lc_messages_dir'] = array(
+    'lc-messages-dir',
+    'server-options',
+    'option_mysqld');
+$VARIABLE_DOC_LINKS['lc_time_names'] = array(
+    'lc_time_names',
+    'server-system-variables',
+    'sysvar');
+$VARIABLE_DOC_LINKS['license'] = array(
+    'license',
+    'server-system-variables',
+    'sysvar');
+$VARIABLE_DOC_LINKS['local_infile'] = array(
+    'local_infile',
+    'server-system-variables',
+    'sysvar');
+$VARIABLE_DOC_LINKS['lock_wait_timeout'] = array(
+    'lock_wait_timeout',
+    'server-system-variables',
+    'sysvar');
+$VARIABLE_DOC_LINKS['locked_in_memory'] = array(
+    'locked_in_memory',
+    'server-system-variables',
+    'sysvar');
+$VARIABLE_DOC_LINKS['log'] = array(
+    'log',
+    'server-options',
+    'option_mysqld');
+$VARIABLE_DOC_LINKS['log_bin'] = array(
+    'log_bin',
+    'server-system-variables',
+    'sysvar');
+$VARIABLE_DOC_LINKS['log-bin'] = array(
+    'log-bin',
+    'replication-options-binary-log',
+    'option_mysqld');
+$VARIABLE_DOC_LINKS['log_bin_trust_function_creators'] = array(
+    'log-bin-trust-function-creators',
+    'replication-options-binary-log',
+    'option_mysqld');
+$VARIABLE_DOC_LINKS['log_error'] = array(
+    'log-error',
+    'server-options',
+    'option_mysqld');
+$VARIABLE_DOC_LINKS['log_output'] = array(
+    'log-output',
+    'server-options',
+    'option_mysqld');
+$VARIABLE_DOC_LINKS['log_queries_not_using_indexes'] = array(
+    'log-queries-not-using-indexes',
+    'server-options',
+    'option_mysqld');
+$VARIABLE_DOC_LINKS['log_slave_updates'] = array(
+    'log-slave-updates',
+    'replication-options-slave',
+    'option_mysqld');
+$VARIABLE_DOC_LINKS['log_slow_queries'] = array(
+    'log-slow-queries',
+    'server-options',
+    'option_mysqld');
+$VARIABLE_DOC_LINKS['log_warnings'] = array(
+    'log-warnings',
+    'server-options',
+    'option_mysqld');
+$VARIABLE_DOC_LINKS['long_query_time'] = array(
+    'long_query_time',
+    'server-system-variables',
+    'sysvar');
+$VARIABLE_DOC_LINKS['low_priority_updates'] = array(
+    'low-priority-updates',
+    'server-options',
+    'option_mysqld');
+$VARIABLE_DOC_LINKS['lower_case_file_system'] = array(
+    'lower_case_file_system',
+    'server-system-variables',
+    'sysvar');
+$VARIABLE_DOC_LINKS['lower_case_table_names'] = array(
+    'lower_case_table_names',
+    'server-system-variables',
+    'sysvar');
+$VARIABLE_DOC_LINKS['master-bind'] = array(
+    '',
+    'replication-options',
+    0);
+$VARIABLE_DOC_LINKS['max_allowed_packet'] = array(
+    'max_allowed_packet',
+    'server-system-variables',
+    'sysvar');
+$VARIABLE_DOC_LINKS['max_binlog_cache_size'] = array(
+    'max_binlog_cache_size',
+    'replication-options-binary-log',
+    'sysvar',
+    'byte');
+$VARIABLE_DOC_LINKS['max_binlog_size'] = array(
+    'max_binlog_size',
+    'replication-options-binary-log',
+    'sysvar',
+    'byte');
+$VARIABLE_DOC_LINKS['max_binlog_stmt_cache_size'] = array(
+    'max_binlog_stmt_cache_size',
+    'replication-options-binary-log',
+    'sysvar',
+    'byte');
+$VARIABLE_DOC_LINKS['max_connect_errors'] = array(
+    'max_connect_errors',
+    'server-system-variables',
+    'sysvar');
+$VARIABLE_DOC_LINKS['max_connections'] = array(
+    'max_connections',
+    'server-system-variables',
+    'sysvar');
+$VARIABLE_DOC_LINKS['max_delayed_threads'] = array(
+    'max_delayed_threads',
+    'server-system-variables',
+    'sysvar');
+$VARIABLE_DOC_LINKS['max_error_count'] = array(
+    'max_error_count',
+    'server-system-variables',
+    'sysvar');
+$VARIABLE_DOC_LINKS['max_heap_table_size'] = array(
+    'max_heap_table_size',
+    'server-system-variables',
+    'sysvar',
+    'byte');
+$VARIABLE_DOC_LINKS['max_insert_delayed_threads'] = array(
+    'max_insert_delayed_threads',
+    'server-system-variables',
+    'sysvar');
+$VARIABLE_DOC_LINKS['max_join_size'] = array(
+    'max_join_size',
+    'server-system-variables',
+    'sysvar');
+$VARIABLE_DOC_LINKS['max_length_for_sort_data'] = array(
+    'max_length_for_sort_data',
+    'server-system-variables',
+    'sysvar');
+$VARIABLE_DOC_LINKS['max_prepared_stmt_count'] = array(
+    'max_prepared_stmt_count',
+    'server-system-variables',
+    'sysvar');
+$VARIABLE_DOC_LINKS['max_relay_log_size'] = array(
+    'max_relay_log_size',
+    'server-system-variables',
+    'sysvar',
+    'byte');
+$VARIABLE_DOC_LINKS['max_seeks_for_key'] = array(
+    'max_seeks_for_key',
+    'server-system-variables',
+    'sysvar');
+$VARIABLE_DOC_LINKS['max_sort_length'] = array(
+    'max_sort_length',
+    'server-system-variables',
+    'sysvar');
+$VARIABLE_DOC_LINKS['max_sp_recursion_depth'] = array(
+    'max_sp_recursion_depth',
+    'server-system-variables',
+    'sysvar');
+$VARIABLE_DOC_LINKS['max_tmp_tables'] = array(
+    'max_tmp_tables',
+    'server-system-variables',
+    'sysvar');
+$VARIABLE_DOC_LINKS['max_user_connections'] = array(
+    'max_user_connections',
+    'server-system-variables',
+    'sysvar');
+$VARIABLE_DOC_LINKS['max_write_lock_count'] = array(
+    'max_write_lock_count',
+    'server-system-variables',
+    'sysvar');
+$VARIABLE_DOC_LINKS['memlock'] = array(
+    'memlock',
+    'server-options',
+    'option_mysqld');
+$VARIABLE_DOC_LINKS['min_examined_row_limit'] = array(
+    'min-examined-row-limit',
+    'server-options',
+    'option_mysqld');
+$VARIABLE_DOC_LINKS['myisam_data_pointer_size'] = array(
+    'myisam_data_pointer_size',
+    'server-system-variables',
+    'sysvar',
+    'byte');
+$VARIABLE_DOC_LINKS['myisam_max_sort_file_size'] = array(
+    'myisam_max_sort_file_size',
+    'server-system-variables',
+    'sysvar',
+    'byte');
+$VARIABLE_DOC_LINKS['myisam_mmap_size'] = array(
+    'myisam_mmap_size',
+    'server-system-variables',
+    'sysvar',
+    'byte');
+$VARIABLE_DOC_LINKS['myisam_recover_options'] = array(
+    'myisam_recover_options',
+    'server-system-variables',
+    'sysvar');
+$VARIABLE_DOC_LINKS['myisam_repair_threads'] = array(
+    'myisam_repair_threads',
+    'server-system-variables',
+    'sysvar');
+$VARIABLE_DOC_LINKS['myisam_sort_buffer_size'] = array(
+    'myisam_sort_buffer_size',
+    'server-system-variables',
+    'sysvar',
+    'byte');
+$VARIABLE_DOC_LINKS['myisam_stats_method'] = array(
+    'myisam_stats_method',
+    'server-system-variables',
+    'sysvar');
+$VARIABLE_DOC_LINKS['myisam_use_mmap'] = array(
+    'myisam_use_mmap',
+    'server-system-variables',
+    'sysvar');
+$VARIABLE_DOC_LINKS['named_pipe'] = array(
+    'named_pipe',
+    'server-system-variables',
+    'sysvar');
+$VARIABLE_DOC_LINKS['net_buffer_length'] = array(
+    'net_buffer_length',
+    'server-system-variables',
+    'sysvar');
+$VARIABLE_DOC_LINKS['net_read_timeout'] = array(
+    'net_read_timeout',
+    'server-system-variables',
+    'sysvar');
+$VARIABLE_DOC_LINKS['net_retry_count'] = array(
+    'net_retry_count',
+    'server-system-variables',
+    'sysvar');
+$VARIABLE_DOC_LINKS['net_write_timeout'] = array(
+    'net_write_timeout',
+    'server-system-variables',
+    'sysvar');
+$VARIABLE_DOC_LINKS['new'] = array(
+    'new',
+    'server-system-variables',
+    'sysvar');
+$VARIABLE_DOC_LINKS['old'] = array(
+    'old',
+    'server-system-variables',
+    'sysvar');
+$VARIABLE_DOC_LINKS['old_alter_table'] = array(
+    'old-alter-table',
+    'server-options',
+    'option_mysqld');
+$VARIABLE_DOC_LINKS['old_passwords'] = array(
+    'old-passwords',
+    'server-options',
+    'option_mysqld');
+$VARIABLE_DOC_LINKS['open_files_limit'] = array(
+    'open-files-limit',
+    'server-options',
+    'option_mysqld');
+$VARIABLE_DOC_LINKS['optimizer_prune_level'] = array(
+    'optimizer_prune_level',
+    'server-system-variables',
+    'sysvar');
+$VARIABLE_DOC_LINKS['optimizer_search_depth'] = array(
+    'optimizer_search_depth',
+    'server-system-variables',
+    'sysvar');
+$VARIABLE_DOC_LINKS['optimizer_switch'] = array(
+    'optimizer_switch',
+    'server-system-variables',
+    'sysvar');
+$VARIABLE_DOC_LINKS['partition'] = array(
+    'partition',
+    'server-options',
+    'option_mysqld');
+$VARIABLE_DOC_LINKS['performance_schema'] = array(
+    'performance_schema',
+    'performance-schema-system-variables',
+    'sysvar');
+$VARIABLE_DOC_LINKS['performance_schema_events_waits_history_long_size'] = array(
+    'performance_schema_events_waits_history_long_size',
+    'performance-schema-system-variables',
+    'sysvar');
+$VARIABLE_DOC_LINKS['performance_schema_events_waits_history_size'] = array(
+    'performance_schema_events_waits_history_size',
+    'performance-schema-system-variables',
+    'sysvar');
+$VARIABLE_DOC_LINKS['performance_schema_max_cond_classes'] = array(
+    'performance_schema_max_cond_classes',
+    'performance-schema-system-variables',
+    'sysvar');
+$VARIABLE_DOC_LINKS['performance_schema_max_cond_instances'] = array(
+    'performance_schema_max_cond_instances',
+    'performance-schema-system-variables',
+    'sysvar');
+$VARIABLE_DOC_LINKS['performance_schema_max_file_classes'] = array(
+    'performance_schema_max_file_classes',
+    'performance-schema-system-variables',
+    'sysvar');
+$VARIABLE_DOC_LINKS['performance_schema_max_file_handles'] = array(
+    'performance_schema_max_file_handles',
+    'performance-schema-system-variables',
+    'sysvar');
+$VARIABLE_DOC_LINKS['performance_schema_max_file_instances'] = array(
+    'performance_schema_max_file_instances',
+    'performance-schema-system-variables',
+    'sysvar');
+$VARIABLE_DOC_LINKS['performance_schema_max_mutex_classes'] = array(
+    'performance_schema_max_mutex_classes',
+    'performance-schema-system-variables',
+    'sysvar');
+$VARIABLE_DOC_LINKS['performance_schema_max_mutex_instances'] = array(
+    'performance_schema_max_mutex_instances',
+    'performance-schema-system-variables',
+    'sysvar');
+$VARIABLE_DOC_LINKS['performance_schema_max_rwlock_classes'] = array(
+    'performance_schema_max_rwlock_classes',
+    'performance-schema-system-variables',
+    'sysvar');
+$VARIABLE_DOC_LINKS['performance_schema_max_rwlock_instances'] = array(
+    'performance_schema_max_rwlock_instances',
+    'performance-schema-system-variables',
+    'sysvar');
+$VARIABLE_DOC_LINKS['performance_schema_max_table_handles'] = array(
+    'performance_schema_max_table_handles',
+    'performance-schema-system-variables',
+    'sysvar');
+$VARIABLE_DOC_LINKS['performance_schema_max_table_instances'] = array(
+    'performance_schema_max_table_instances',
+    'performance-schema-system-variables',
+    'sysvar');
+$VARIABLE_DOC_LINKS['performance_schema_max_thread_classes'] = array(
+    'performance_schema_max_thread_classes',
+    'performance-schema-system-variables',
+    'sysvar');
+$VARIABLE_DOC_LINKS['performance_schema_max_thread_instances'] = array(
+    'performance_schema_max_thread_instances',
+    'performance-schema-system-variables',
+    'sysvar');
+$VARIABLE_DOC_LINKS['pid_file'] = array(
+    'pid-file',
+    'server-options',
+    'option_mysqld');
+$VARIABLE_DOC_LINKS['plugin_dir'] = array(
+    'plugin_dir',
+    'server-system-variables',
+    'sysvar');
+$VARIABLE_DOC_LINKS['port'] = array(
+    'port',
+    'server-options',
+    'option_mysqld');
+$VARIABLE_DOC_LINKS['preload_buffer_size'] = array(
+    'preload_buffer_size',
+    'server-system-variables',
+    'sysvar',
+    'byte');
+$VARIABLE_DOC_LINKS['profiling'] = array(
+    'profiling',
+    'server-system-variables',
+    'sysvar');
+$VARIABLE_DOC_LINKS['profiling_history_size'] = array(
+    'profiling_history_size',
+    'server-system-variables',
+    'sysvar');
+$VARIABLE_DOC_LINKS['protocol_version'] = array(
+    'protocol_version',
+    'server-system-variables',
+    'sysvar');
+$VARIABLE_DOC_LINKS['proxy_user'] = array(
+    'proxy_user',
+    'server-system-variables',
+    'sysvar');
+$VARIABLE_DOC_LINKS['pseudo_thread_id'] = array(
+    'pseudo_thread_id',
+    'server-system-variables',
+    'sysvar');
+$VARIABLE_DOC_LINKS['query_alloc_block_size'] = array(
+    'query_alloc_block_size',
+    'server-system-variables',
+    'sysvar',
+    'byte');
+$VARIABLE_DOC_LINKS['query_cache_limit'] = array(
+    'query_cache_limit',
+    'server-system-variables',
+    'sysvar',
+    'byte');
+$VARIABLE_DOC_LINKS['query_cache_min_res_unit'] = array(
+    'query_cache_min_res_unit',
+    'server-system-variables',
+    'sysvar');
+$VARIABLE_DOC_LINKS['query_cache_size'] = array(
+    'query_cache_size',
+    'server-system-variables',
+    'sysvar',
+    'byte');
+$VARIABLE_DOC_LINKS['query_cache_type'] = array(
+    'query_cache_type',
+    'server-system-variables',
+    'sysvar');
+$VARIABLE_DOC_LINKS['query_cache_wlock_invalidate'] = array(
+    'query_cache_wlock_invalidate',
+    'server-system-variables',
+    'sysvar');
+$VARIABLE_DOC_LINKS['query_prealloc_size'] = array(
+    'query_prealloc_size',
+    'server-system-variables',
+    'sysvar',
+    'byte');
+$VARIABLE_DOC_LINKS['rand_seed1'] = array(
+    'rand_seed1',
+    'server-system-variables',
+    'sysvar');
+$VARIABLE_DOC_LINKS['rand_seed2'] = array(
+    'rand_seed2',
+    'server-system-variables',
+    'sysvar');
+$VARIABLE_DOC_LINKS['range_alloc_block_size'] = array(
+    'range_alloc_block_size',
+    'server-system-variables',
+    'sysvar',
+    'byte');
+$VARIABLE_DOC_LINKS['read_buffer_size'] = array(
+    'read_buffer_size',
+    'server-system-variables',
+    'sysvar',
+    'byte');
+$VARIABLE_DOC_LINKS['read_only'] = array(
+    'read_only',
+    'server-system-variables',
+    'sysvar');
+$VARIABLE_DOC_LINKS['read_rnd_buffer_size'] = array(
+    'read_rnd_buffer_size',
+    'server-system-variables',
+    'sysvar',
+    'byte');
+$VARIABLE_DOC_LINKS['relay-log-index'] = array(
+    'relay-log-index',
+    'replication-options-slave',
+    'option_mysqld');
+$VARIABLE_DOC_LINKS['relay_log_index'] = array(
+    'relay_log_index',
+    'replication-options-slave',
+    'sysvar');
+$VARIABLE_DOC_LINKS['relay_log_info_file'] = array(
+    'relay_log_info_file',
+    'replication-options-slave',
+    'sysvar');
+$VARIABLE_DOC_LINKS['relay_log_purge'] = array(
+    'relay_log_purge',
+    'server-system-variables',
+    'sysvar');
+$VARIABLE_DOC_LINKS['relay_log_recovery'] = array(
+    'relay_log_recovery',
+    'replication-options-slave',
+    'sysvar');
+$VARIABLE_DOC_LINKS['relay_log_space_limit'] = array(
+    'relay_log_space_limit',
+    'server-system-variables',
+    'sysvar');
+$VARIABLE_DOC_LINKS['report_host'] = array(
+    'report-host',
+    'replication-options-slave',
+    'option_mysqld');
+$VARIABLE_DOC_LINKS['report_password'] = array(
+    'report-password',
+    'replication-options-slave',
+    'option_mysqld');
+$VARIABLE_DOC_LINKS['report_port'] = array(
+    'report-port',
+    'replication-options-slave',
+    'option_mysqld');
+$VARIABLE_DOC_LINKS['report_user'] = array(
+    'report-user',
+    'replication-options-slave',
+    'option_mysqld');
+$VARIABLE_DOC_LINKS['rpl_recovery_rank'] = array(
+    'rpl_recovery_rank',
+    'replication-options-slave',
+    'option_mysqld');
+$VARIABLE_DOC_LINKS['rpl_semi_sync_master_enabled'] = array(
+    'rpl_semi_sync_master_enabled',
+    'server-system-variables',
+    'sysvar');
+$VARIABLE_DOC_LINKS['rpl_semi_sync_master_timeout'] = array(
+    'rpl_semi_sync_master_timeout',
+    'server-system-variables',
+    'sysvar');
+$VARIABLE_DOC_LINKS['rpl_semi_sync_master_trace_level'] = array(
+    'rpl_semi_sync_master_trace_level',
+    'server-system-variables',
+    'sysvar');
+$VARIABLE_DOC_LINKS['rpl_semi_sync_master_wait_no_slave'] = array(
+    'rpl_semi_sync_master_wait_no_slave',
+    'server-system-variables',
+    'sysvar');
+$VARIABLE_DOC_LINKS['rpl_semi_sync_slave_enabled'] = array(
+    'rpl_semi_sync_slave_enabled',
+    'server-system-variables',
+    'sysvar');
+$VARIABLE_DOC_LINKS['rpl_semi_sync_slave_trace_level'] = array(
+    'rpl_semi_sync_slave_trace_level',
+    'server-system-variables',
+    'sysvar');
+$VARIABLE_DOC_LINKS['safe_show_database'] = array(
+    'safe-show-database',
+    'server-options',
+    'option_mysqld');
+$VARIABLE_DOC_LINKS['secure_auth'] = array(
+    'secure-auth',
+    'server-options',
+    'option_mysqld');
+$VARIABLE_DOC_LINKS['secure_file_priv'] = array(
+    'secure-file-priv',
+    'server-options',
+    'option_mysqld');
+$VARIABLE_DOC_LINKS['server_id'] = array(
+    'server-id',
+    'replication-options',
+    'option_mysqld');
+$VARIABLE_DOC_LINKS['shared_memory'] = array(
+    'shared_memory',
+    'server-system-variables',
+    'sysvar');
+$VARIABLE_DOC_LINKS['shared_memory_base_name'] = array(
+    'shared_memory_base_name',
+    'server-system-variables',
+    'sysvar');
+$VARIABLE_DOC_LINKS['skip_external_locking'] = array(
+    'skip-external-locking',
+    'server-options',
+    'option_mysqld');
+$VARIABLE_DOC_LINKS['skip_name_resolve'] = array(
+    'skip-name-resolve',
+    'server-options',
+    'option_mysqld');
+$VARIABLE_DOC_LINKS['skip_networking'] = array(
+    'skip-networking',
+    'server-options',
+    'option_mysqld');
+$VARIABLE_DOC_LINKS['skip_show_database'] = array(
+    'skip-show-database',
+    'server-options',
+    'option_mysqld');
+$VARIABLE_DOC_LINKS['slave_compressed_protocol'] = array(
+    'slave_compressed_protocol',
+    'replication-options-slave',
+    'sysvar');
+$VARIABLE_DOC_LINKS['slave_exec_mode'] = array(
+    'slave_exec_mode',
+    'replication-options-slave',
+    'sysvar');
+$VARIABLE_DOC_LINKS['slave_load_tmpdir'] = array(
+    'slave-load-tmpdir',
+    'replication-options-slave',
+    'option_mysqld');
+$VARIABLE_DOC_LINKS['slave_net_timeout'] = array(
+    'slave-net-timeout',
+    'replication-options-slave',
+    'option_mysqld');
+$VARIABLE_DOC_LINKS['slave_skip_errors'] = array(
+    'slave-skip-errors',
+    'replication-options-slave',
+    'option_mysqld');
+$VARIABLE_DOC_LINKS['slave_transaction_retries'] = array(
+    'slave_transaction_retries',
+    'replication-options-slave',
+    'sysvar');
+$VARIABLE_DOC_LINKS['slave_type_conversions'] = array(
+    'slave_type_conversions',
+    'replication-options-slave',
+    'sysvar');
+$VARIABLE_DOC_LINKS['slow_launch_time'] = array(
+    'slow_launch_time',
+    'server-system-variables',
+    'sysvar');
+$VARIABLE_DOC_LINKS['slow_query_log'] = array(
+    'slow-query-log',
+    'server-options',
+    'server-system-variables');
+$VARIABLE_DOC_LINKS['slow_query_log_file'] = array(
+    'slow_query_log_file',
+    'server-system-variables',
+    'sysvar');
+$VARIABLE_DOC_LINKS['socket'] = array(
+    'socket',
+    'server-options',
+    'option_mysqld');
+$VARIABLE_DOC_LINKS['sort_buffer_size'] = array(
+    'sort_buffer_size',
+    'server-system-variables',
+    'sysvar',
+    'byte');
+$VARIABLE_DOC_LINKS['sql_auto_is_null'] = array(
+    'sql_auto_is_null',
+    'server-system-variables',
+    'sysvar');
+$VARIABLE_DOC_LINKS['sql_big_selects'] = array(
+    'sql_big_selects',
+    'server-system-variables',
+    'sysvar');
+$VARIABLE_DOC_LINKS['sql_big_tables'] = array(
+    'big-tables',
+    'server-options',
+    'server-system-variables');
+$VARIABLE_DOC_LINKS['sql_buffer_result'] = array(
+    'sql_buffer_result',
+    'server-system-variables',
+    'sysvar');
+$VARIABLE_DOC_LINKS['sql_log_bin'] = array(
+    'sql_log_bin',
+    'server-system-variables',
+    'sysvar');
+$VARIABLE_DOC_LINKS['sql_log_off'] = array(
+    'sql_log_off',
+    'server-system-variables',
+    'sysvar');
+$VARIABLE_DOC_LINKS['sql_log_update'] = array(
+    'sql_log_update',
+    'server-system-variables',
+    'sysvar');
+$VARIABLE_DOC_LINKS['sql_low_priority_updates'] = array(
+    'sql_low_priority_updates',
+    'server-system-variables',
+    'sysvar');
+$VARIABLE_DOC_LINKS['sql_max_join_size'] = array(
+    'sql_max_join_size',
+    'server-system-variables',
+    'sysvar');
+$VARIABLE_DOC_LINKS['sql_mode'] = array(
+    'sql-mode',
+    'server-options',
+    'option_mysqld');
+$VARIABLE_DOC_LINKS['sql_notes'] = array(
+    'sql_notes',
+    'server-system-variables',
+    'sysvar');
+$VARIABLE_DOC_LINKS['sql_quote_show_create'] = array(
+    'sql_quote_show_create',
+    'server-system-variables',
+    'sysvar');
+$VARIABLE_DOC_LINKS['sql_safe_updates'] = array(
+    'sql_safe_updates',
+    'server-system-variables',
+    'sysvar');
+$VARIABLE_DOC_LINKS['sql_select_limit'] = array(
+    'sql_select_limit',
+    'server-system-variables',
+    'sysvar');
+$VARIABLE_DOC_LINKS['sql_slave_skip_counter'] = array(
+    'sql_slave_skip_counter',
+    'replication-options-slave',
+    'sysvar');
+$VARIABLE_DOC_LINKS['sql_warnings'] = array(
+    'sql_warnings',
+    'server-system-variables',
+    'sysvar');
+$VARIABLE_DOC_LINKS['ssl_ca'] = array(
+    'ssl-ca',
+    'ssl-options',
+    'option_general');
+$VARIABLE_DOC_LINKS['ssl_capath'] = array(
+    'ssl-capath',
+    'ssl-options',
+    'option_general');
+$VARIABLE_DOC_LINKS['ssl_cert'] = array(
+    'ssl-cert',
+    'ssl-options',
+    'option_general');
+$VARIABLE_DOC_LINKS['ssl_cipher'] = array(
+    'ssl-cipher',
+    'ssl-options',
+    'option_general');
+$VARIABLE_DOC_LINKS['ssl_key'] = array(
+    'ssl-key',
+    'ssl-options',
+    'option_general');
+$VARIABLE_DOC_LINKS['storage_engine'] = array(
+    'storage_engine',
+    'server-system-variables',
+    'sysvar');
+$VARIABLE_DOC_LINKS['sync_binlog'] = array(
+    'sync_binlog',
+    'replication-options-binary-log',
+    'sysvar');
+$VARIABLE_DOC_LINKS['sync_frm'] = array(
+    'sync_frm',
+    'server-system-variables',
+    'sysvar');
+$VARIABLE_DOC_LINKS['sync_master_info'] = array(
+    'sync_master_info',
+    'replication-options-slave',
+    'sysvar');
+$VARIABLE_DOC_LINKS['sync_relay_log'] = array(
+    'sync_relay_log',
+    'replication-options-slave',
+    'sysvar');
+$VARIABLE_DOC_LINKS['sync_relay_log_info'] = array(
+    'sync_relay_log_info',
+    'replication-options-slave',
+    'sysvar');
+$VARIABLE_DOC_LINKS['system_time_zone'] = array(
+    'system_time_zone',
+    'server-system-variables',
+    'sysvar');
+$VARIABLE_DOC_LINKS['table_definition_cache'] = array(
+    'table_definition_cache',
+    'server-system-variables',
+    'sysvar');
+$VARIABLE_DOC_LINKS['table_lock_wait_timeout'] = array(
+    'table_lock_wait_timeout',
+    'server-system-variables',
+    'sysvar');
+$VARIABLE_DOC_LINKS['table_open_cache'] = array(
+    'table_open_cache',
+    'server-system-variables',
+    'sysvar');
+$VARIABLE_DOC_LINKS['table_type'] = array(
+    'table_type',
+    'server-system-variables',
+    'sysvar');
+$VARIABLE_DOC_LINKS['thread_cache_size'] = array(
+    'thread_cache_size',
+    'server-system-variables',
+    'sysvar');
+$VARIABLE_DOC_LINKS['thread_concurrency'] = array(
+    'thread_concurrency',
+    'server-system-variables',
+    'sysvar');
+$VARIABLE_DOC_LINKS['thread_handling'] = array(
+    'thread_handling',
+    'server-system-variables',
+    'sysvar');
+$VARIABLE_DOC_LINKS['thread_stack'] = array(
+    'thread_stack',
+    'server-system-variables',
+    'sysvar');
+$VARIABLE_DOC_LINKS['time_format'] = array(
+    'time_format',
+    'server-system-variables',
+    'sysvar');
+$VARIABLE_DOC_LINKS['time_zone'] = array(
+    'time_zone',
+    'server-system-variables',
+    'sysvar');
+$VARIABLE_DOC_LINKS['timed_mutexes'] = array(
+    'timed_mutexes',
+    'server-system-variables',
+    'sysvar');
+$VARIABLE_DOC_LINKS['timestamp'] = array(
+    'timestamp',
+    'server-system-variables',
+    'sysvar');
+$VARIABLE_DOC_LINKS['tmp_table_size'] = array(
+    'tmp_table_size',
+    'server-system-variables',
+    'sysvar',
+    'byte');
+$VARIABLE_DOC_LINKS['tmpdir'] = array(
+    'tmpdir',
+    'server-options',
+    'option_mysqld');
+$VARIABLE_DOC_LINKS['transaction_alloc_block_size'] = array(
+    'transaction_alloc_block_size',
+    'server-system-variables',
+    'sysvar',
+    'byte');
+$VARIABLE_DOC_LINKS['transaction_prealloc_size'] = array(
+    'transaction_prealloc_size',
+    'server-system-variables',
+    'sysvar',
+    'byte');
+$VARIABLE_DOC_LINKS['tx_isolation'] = array(
+    'tx_isolation',
+    'server-system-variables',
+    'sysvar');
+$VARIABLE_DOC_LINKS['unique_checks'] = array(
+    'unique_checks',
+    'server-system-variables',
+    'sysvar');
+$VARIABLE_DOC_LINKS['updatable_views_with_limit'] = array(
+    'updatable_views_with_limit',
+    'server-system-variables',
+    'sysvar');
+$VARIABLE_DOC_LINKS['version'] = array(
+    'version',
+    'server-system-variables',
+    'sysvar');
+$VARIABLE_DOC_LINKS['version_comment'] = array(
+    'version_comment',
+    'server-system-variables',
+    'sysvar');
+$VARIABLE_DOC_LINKS['version_compile_machine'] = array(
+    'version_compile_machine',
+    'server-system-variables',
+    'sysvar');
+$VARIABLE_DOC_LINKS['version_compile_os'] = array(
+    'version_compile_os',
+    'server-system-variables',
+    'sysvar');
+$VARIABLE_DOC_LINKS['wait_timeout'] = array(
+    'wait_timeout',
+    'server-system-variables',
+    'sysvar');
+$VARIABLE_DOC_LINKS['warning_count'] = array(
+    'warning_count',
+    'server-system-variables',
+    'sysvar');
+?>
diff --git a/phpmyadmin/libraries/session.inc.php b/phpmyadmin/libraries/session.inc.php
new file mode 100644
index 0000000..7f416ea
--- /dev/null
+++ b/phpmyadmin/libraries/session.inc.php
@@ -0,0 +1,120 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * session handling
+ *
+ * @todo    add failover or warn if sessions are not configured properly
+ * @todo    add an option to use mm-module for session handler
+ *
+ * @package PhpMyAdmin
+ * @see     http://www.php.net/session
+ */
+if (! defined('PHPMYADMIN')) {
+    exit;
+}
+
+// verify if PHP supports session, die if it does not
+
+if (!@function_exists('session_name')) {
+    PMA_warnMissingExtension('session', true);
+} elseif (ini_get('session.auto_start') == true && session_name() != 'phpMyAdmin') {
+    // Do not delete the existing session, it might be used by other
+    // applications; instead just close it.
+    session_write_close();
+}
+
+// disable starting of sessions before all settings are done
+// does not work, besides how it is written in php manual
+//ini_set('session.auto_start', 0);
+
+// session cookie settings
+session_set_cookie_params(
+    0, $GLOBALS['PMA_Config']->getCookiePath(),
+    '', $GLOBALS['PMA_Config']->isHttps(), true
+);
+
+// cookies are safer (use @ini_set() in case this function is disabled)
+ at ini_set('session.use_cookies', true);
+
+// optionally set session_save_path
+$path = $GLOBALS['PMA_Config']->get('SessionSavePath');
+if (!empty($path)) {
+    session_save_path($path);
+}
+
+// but not all user allow cookies
+ at ini_set('session.use_only_cookies', false);
+// do not force transparent session ids, see bug #3398788
+//@ini_set('session.use_trans_sid', true);
+ at ini_set(
+    'url_rewriter.tags',
+    'a=href,frame=src,input=src,form=fakeentry,fieldset='
+);
+//ini_set('arg_separator.output', '&');
+
+// delete session/cookies when browser is closed
+ at ini_set('session.cookie_lifetime', 0);
+
+// warn but dont work with bug
+ at ini_set('session.bug_compat_42', false);
+ at ini_set('session.bug_compat_warn', true);
+
+// use more secure session ids
+ at ini_set('session.hash_function', 1);
+
+// some pages (e.g. stylesheet) may be cached on clients, but not in shared
+// proxy servers
+session_cache_limiter('private');
+
+// start the session
+// on some servers (for example, sourceforge.net), we get a permission error
+// on the session data directory, so I add some "@"
+
+// See bug #1538132. This would block normal behavior on a cluster
+//ini_set('session.save_handler', 'files');
+
+$session_name = 'OpenEMR';
+ at session_name($session_name);
+
+if (! isset($_COOKIE[$session_name])) {
+    // on first start of session we check for errors
+    // f.e. session dir cannot be accessed - session file not created
+    $orig_error_count = $GLOBALS['error_handler']->countErrors();
+    $r = session_start();
+    if ($r !== true
+        || $orig_error_count != $GLOBALS['error_handler']->countErrors()
+    ) {
+        setcookie($session_name, '', 1);
+        /*
+         * Session initialization is done before selecting language, so we
+         * can not use translations here.
+         */
+        PMA_fatalError('Cannot start session without errors, please check errors given in your PHP and/or webserver log file and configure your PHP installation properly. Also ensure that cookies are enabled in your browser.');
+    }
+    unset($orig_error_count);
+} else {
+    session_start();
+}
+
+/**
+ * Token which is used for authenticating access queries.
+ * (we use "space PMA_token space" to prevent overwriting)
+ */
+if (! isset($_SESSION[' PMA_token '])) {
+    $_SESSION[' PMA_token '] = md5(uniqid(rand(), true));
+}
+
+/**
+ * tries to secure session from hijacking and fixation
+ * should be called before login and after successfull login
+ * (only required if sensitive information stored in session)
+ *
+ * @return void
+ */
+function PMA_secureSession()
+{
+    // prevent session fixation and XSS
+    session_regenerate_id(true);
+    $_SESSION[' PMA_token '] = md5(uniqid(rand(), true));
+}
+?>
diff --git a/phpmyadmin/libraries/special_schema_links.lib.php b/phpmyadmin/libraries/special_schema_links.lib.php
new file mode 100644
index 0000000..d012f4b
--- /dev/null
+++ b/phpmyadmin/libraries/special_schema_links.lib.php
@@ -0,0 +1,323 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ *
+ * @package PhpMyAdmin
+ */
+if (! defined('PHPMYADMIN')) {
+    exit;
+}
+
+/**
+ * This global variable represent the details for generating links inside
+ * special schemas like mysql, information_schema etc.
+ * Major element represent a schema.
+ * All the strings in this array represented in lower case
+ * This global variable has not modified anywhere
+ * 
+ * Variable structure ex:
+ * $GLOBALS['special_schema_links'] = array(
+ *     // Database name is the major element
+ *     'mysql' => array(
+ *         // Table name
+ *         'db' => array(
+ *             // Column name
+ *             'user' => array(
+ *                 // Main url param (can be an array where represent sql)
+ *                 'link_param' => 'username',
+ *                 // Other url params
+ *                 'link_dependancy_params' => array(
+ *                     0 => array(
+ *                         // URL parameter name
+ *                         // (can be array where url param has static value)
+ *                         'param_info' => 'hostname',
+ *                         // Column name related to url param
+ *                         'column_name' => 'host'                        
+ *                     )
+ *                 ),
+ *                 // Page to link
+ *                 'default_page' => 'server_privileges.php'
+ *             )
+ *         )
+ *     )
+ * );
+ * 
+ */
+$GLOBALS['special_schema_links'] = array(
+    'mysql' => array(
+        'db' => array(
+            'db' => array(
+                'link_param' => 'db',
+                'default_page' => 'index.php'
+            ),
+            'user' => array(
+                'link_param' => 'username',
+                'link_dependancy_params' => array(
+                    0 => array(
+                        'param_info' => 'hostname',
+                        'column_name' => 'host'                        
+                    )
+                ),
+                'default_page' => 'server_privileges.php'
+            )
+        ),
+        'proc' => array(
+            'db' => array(
+                'link_param' => 'db',
+                'default_page' => 'index.php'
+            )
+
+        ),
+        'user' => array(
+            'user' => array(
+                'link_param' => 'username',
+                'link_dependancy_params' => array(
+                    0 => array(
+                        'param_info' => 'hostname',
+                        'column_name' => 'host'                        
+                    )
+                ),
+                'default_page' => 'server_privileges.php'
+            )
+
+        )
+    ),
+    'information_schema' => array(
+        'columns' => array(
+            'table_name' => array(
+                'link_param' => 'table',
+                'link_dependancy_params' => array(
+                    0 => array(
+                        'param_info' => 'db',
+                        'column_name' => 'table_schema'
+                    )
+                ),
+                'default_page' => 'index.php'
+            ),
+            'column_name' => array(
+                'link_param' => array(
+                    'sql_query',
+                    'table_schema',
+                    'table_name'
+                ),
+                'link_dependancy_params' => array(
+                    0 => array(
+                        'param_info' => 'db',
+                        'column_name' => 'table_schema'     
+                    ),
+                    1 => array(
+                        'param_info' => 'table',
+                        'column_name' => 'table_name' 
+                    )
+                ),
+                'default_page' => 'index.php'
+            )
+        ),
+        'key_column_usage' => array(
+            'table_name' => array(
+                'link_param' => 'table',
+                'link_dependancy_params' => array(
+                    0 => array(
+                        'param_info' => 'db',
+                        'column_name' => 'constraint_schema'                        
+                    )
+                ),
+                'default_page' => 'index.php'
+            ),
+            'column_name' => array(
+                'link_param' => array(
+                    'sql_query',
+                    'table_schema',
+                    'table_name'
+                ),
+                'link_dependancy_params' => array(
+                    0 => array(
+                        'param_info' => 'db',
+                        'column_name' => 'table_schema'     
+                    ),
+                    1 => array(
+                        'param_info' => 'table',
+                        'column_name' => 'table_name' 
+                    )
+                ),
+                'default_page' => 'index.php'
+            ),
+            'referenced_table_schema' => array(
+                'link_param' => 'db',
+                'default_page' => 'index.php'
+            ),
+            'referenced_table_name' => array(
+                'link_param' => 'table',
+                'link_dependancy_params' => array(
+                    0 => array(
+                        'param_info' => 'db',
+                        'column_name' => 'referenced_table_schema'                        
+                    )
+                ),
+                'default_page' => 'index.php'
+            ),
+            'referenced_column_name' => array(
+                'link_param' => array(
+                    'sql_query',
+                    'referenced_table_schema',
+                    'referenced_table_name'
+                ),
+                'link_dependancy_params' => array(
+                    0 => array(
+                        'param_info' => 'db',
+                        'column_name' => 'referenced_table_schema'     
+                    ),
+                    1 => array(
+                        'param_info' => 'table',
+                        'column_name' => 'referenced_table_name' 
+                    )
+                ),
+                'default_page' => 'index.php'
+            )
+        ),
+        'partitions' => array(
+            'table_schema' => array(
+                'link_param' => 'db',
+                'default_page' => 'index.php'
+            ),
+            'table_name' => array(
+                'link_param' => 'table',
+                'link_dependancy_params' => array(
+                    0 => array(
+                        'param_info' => 'db',
+                        'column_name' => 'table_schema'                        
+                    )
+                ),
+                'default_page' => 'index.php'
+            )
+        ),
+        'processlist' => array(
+            'db' => array(
+                'link_param' => 'db',
+                'default_page' => 'index.php'
+            ),
+            'user' => array(
+                'link_param' => 'username',
+                'link_dependancy_params' => array(
+                    0 => array(
+                        'param_info' => 'hostname',
+                        'column_name' => 'host'                        
+                    )
+                ),
+                'default_page' => 'server_privileges.php'
+            )
+        ),
+        'referential_constraints' => array(
+            'constraint_schema' => array(
+                'link_param' => 'db',
+                'default_page' => 'index.php'
+            ),
+            'unique_constraint_schema' => array(
+                'link_param' => 'db',
+                'default_page' => 'index.php'
+            ),
+            'table_name' => array(
+                'link_param' => 'table',
+                'link_dependancy_params' => array(
+                    0 => array(
+                        'param_info' => 'db',
+                        'column_name' => 'constraint_schema'                        
+                    )
+                ),
+                'default_page' => 'index.php'
+            ),
+            'referenced_table_name' => array(
+                'link_param' => 'table',
+                'link_dependancy_params' => array(
+                    0 => array(
+                        'param_info' => 'db',
+                        'column_name' => 'constraint_schema'                        
+                    )
+                ),
+                'default_page' => 'index.php'
+            )            
+        ),
+        'routines' => array(
+            'routine_name' => array(
+                'link_param' => 'item_name',
+                'link_dependancy_params' => array(
+                    0 => array(
+                        'param_info' => 'db',
+                        'column_name' => 'routine_schema'                        
+                    ),
+                    1 => array(
+                        'param_info' => 'item_type',
+                        'column_name' => 'routine_type'
+                    )
+                ),
+                'default_page' => 'db_routines.php'
+            )
+        ),
+        'schemata' => array(
+            'schema_name' => array(
+                'link_param' => 'db',
+                'default_page' => 'index.php'
+            )
+        ),
+        'statistics' => array(
+            'table_schema' => array(
+                'link_param' => 'db',
+                'default_page' => 'index.php'
+            ),
+            'table_name' => array(
+                'link_param' => 'table',
+                'link_dependancy_params' => array(
+                    0 => array(
+                        'param_info' => 'db',
+                        'column_name' => 'table_schema'                        
+                    )
+                ),
+                'default_page' => 'index.php'
+            ),
+            'column_name' => array(
+                'link_param' => array(
+                    'sql_query',
+                    'table_schema',
+                    'table_name'
+                ),
+                'link_dependancy_params' => array(
+                    0 => array(
+                        'param_info' => 'db',
+                        'column_name' => 'table_schema'     
+                    ),
+                    1 => array(
+                        'param_info' => 'table',
+                        'column_name' => 'table_name' 
+                    )
+                ),
+                'default_page' => 'index.php'
+            )
+        ),
+        'tables' => array(
+            'table_name' => array(
+                'link_param' => 'table',
+                'link_dependancy_params' => array(
+                    0 => array(
+                        'param_info' => 'db',
+                        'column_name' => 'table_schema'                        
+                    )
+                ),
+                'default_page' => 'index.php'
+            )
+        ),
+        'table_constraints' => array(
+            'table_name' => array(
+                'link_param' => 'table',
+                'link_dependancy_params' => array(
+                    0 => array(
+                        'param_info' => 'db',
+                        'column_name' => 'table_schema'                        
+                    )
+                ),
+                'default_page' => 'index.php'
+            )
+        )
+    )
+);
+
+?>
diff --git a/phpmyadmin/libraries/sql_query_form.lib.php b/phpmyadmin/libraries/sql_query_form.lib.php
new file mode 100644
index 0000000..bf2e81c
--- /dev/null
+++ b/phpmyadmin/libraries/sql_query_form.lib.php
@@ -0,0 +1,496 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * functions for displaying the sql query form
+ *
+ * @usedby  server_sql.php
+ * @usedby  db_sql.php
+ * @usedby  tbl_sql.php
+ * @usedby  tbl_structure.php
+ * @usedby  tbl_tracking.php
+ * @usedby  querywindow.php
+ * @package PhpMyAdmin
+ */
+if (! defined('PHPMYADMIN')) {
+    exit;
+}
+
+/**
+ *
+ */
+require_once './libraries/file_listing.lib.php'; // used for file listing
+require_once './libraries/bookmark.lib.php'; // used for bookmarks
+
+/**
+ * Prints the sql query boxes
+ *
+ * @param boolean|string $query       query to display in the textarea
+ *                                    or true to display last executed
+ * @param boolean|string $display_tab sql|files|history|full|false
+ *                                    what part to display
+ *                                    false if not inside querywindow
+ * @param string         $delimiter   delimeter
+ *
+ * @return void
+ *
+ * @usedby  server_sql.php
+ * @usedby  db_sql.php
+ * @usedby  tbl_sql.php
+ * @usedby  tbl_structure.php
+ * @usedby  tbl_tracking.php
+ * @usedby  querywindow.php
+ */
+function PMA_sqlQueryForm($query = true, $display_tab = false, $delimiter = ';')
+{
+    // check tab to display if inside querywindow
+    if (! $display_tab) {
+        $display_tab = 'full';
+        $is_querywindow = false;
+    } else {
+        $is_querywindow = true;
+    }
+
+    // query to show
+    if (true === $query) {
+        $query = $GLOBALS['sql_query'];
+    }
+
+    // set enctype to multipart for file uploads
+    if ($GLOBALS['is_upload']) {
+        $enctype = ' enctype="multipart/form-data"';
+    } else {
+        $enctype = '';
+    }
+
+    $table  = '';
+    $db     = '';
+    if (! strlen($GLOBALS['db'])) {
+        // prepare for server related
+        $goto   = empty($GLOBALS['goto']) ?
+                    'server_sql.php' : $GLOBALS['goto'];
+    } elseif (! strlen($GLOBALS['table'])) {
+        // prepare for db related
+        $db     = $GLOBALS['db'];
+        $goto   = empty($GLOBALS['goto']) ?
+                    'db_sql.php' : $GLOBALS['goto'];
+    } else {
+        $table  = $GLOBALS['table'];
+        $db     = $GLOBALS['db'];
+        $goto   = empty($GLOBALS['goto']) ?
+                    'tbl_sql.php' : $GLOBALS['goto'];
+    }
+
+
+    // start output
+    if ($is_querywindow) {
+        ?>
+        <form method="post" id="sqlqueryform" target="frame_content"
+              action="import.php"<?php echo $enctype; ?> name="sqlform"
+              onsubmit="var save_name = window.opener.parent.frame_content.name;
+              window.opener.parent.frame_content.name = save_name + '<?php echo time(); ?>';
+              this.target = window.opener.parent.frame_content.name;
+              return checkSqlQuery(this)">
+        <?php
+    } else {
+        echo '<form method="post" action="import.php" ' . $enctype;
+        echo ' class="ajax"';
+        echo ' id="sqlqueryform" name="sqlform">' . "\n";
+    }
+
+    if ($is_querywindow) {
+        echo '<input type="hidden" name="focus_querywindow" value="true" />'
+            ."\n";
+        if ($display_tab != 'sql' && $display_tab != 'full') {
+            echo '<input type="hidden" name="sql_query" value="" />' . "\n";
+            echo '<input type="hidden" name="show_query" value="1" />' . "\n";
+        }
+    }
+    echo '<input type="hidden" name="is_js_confirmed" value="0" />' . "\n"
+        .PMA_generate_common_hidden_inputs($db, $table) . "\n"
+        .'<input type="hidden" name="pos" value="0" />' . "\n"
+        .'<input type="hidden" name="goto" value="'
+        .htmlspecialchars($goto) . '" />' . "\n"
+        .'<input type="hidden" name="message_to_show" value="'
+        . __('Your SQL query has been executed successfully') . '" />' . "\n"
+        .'<input type="hidden" name="prev_sql_query" value="'
+        . htmlspecialchars($query) . '" />' . "\n";
+
+    // display querybox
+    if ($display_tab === 'full' || $display_tab === 'sql') {
+        PMA_sqlQueryFormInsert($query, $is_querywindow, $delimiter);
+    }
+
+    // display uploads
+    if ($display_tab === 'files' && $GLOBALS['is_upload']) {
+        PMA_sqlQueryFormUpload();
+    }
+
+    // Bookmark Support
+    if ($display_tab === 'full' || $display_tab === 'history') {
+        if (! empty($GLOBALS['cfg']['Bookmark'])) {
+            PMA_sqlQueryFormBookmark();
+        }
+    }
+
+    // Encoding setting form appended by Y.Kawada
+    if (function_exists('PMA_set_enc_form')) {
+        echo PMA_set_enc_form('    ');
+    }
+
+    echo '</form>' . "\n";
+
+    // print an empty div, which will be later filled with
+    // the sql query results by ajax
+    echo '<div id="sqlqueryresults"></div>';
+}
+
+/**
+ * Prints querybox fieldset
+ *
+ * @param string  $query          query to display in the textarea
+ * @param boolean $is_querywindow if inside querywindow or not
+ * @param string  $delimiter      default delimiter to use
+ *
+ * @return void
+ *
+ * @usedby  PMA_sqlQueryForm()
+ */
+function PMA_sqlQueryFormInsert(
+    $query = '', $is_querywindow = false, $delimiter = ';'
+) {
+    // enable auto select text in textarea
+    if ($GLOBALS['cfg']['TextareaAutoSelect']) {
+        $auto_sel = ' onclick="selectContent(this, sql_box_locked, true)"';
+    } else {
+        $auto_sel = '';
+    }
+
+    // enable locking if inside query window
+    if ($is_querywindow) {
+        $locking = ' onkeypress="document.sqlform.elements[\'LockFromUpdate\'].'
+            .'checked = true;"';
+        $height = $GLOBALS['cfg']['TextareaRows'] * 1.25;
+    } else {
+        $locking = '';
+        $height = $GLOBALS['cfg']['TextareaRows'] * 2;
+    }
+
+    $table          = '';
+    $db             = '';
+    $fields_list    = array();
+    if (! strlen($GLOBALS['db'])) {
+        // prepare for server related
+        $legend = sprintf(
+            __('Run SQL query/queries on server %s'),
+            '"' . htmlspecialchars(
+                ! empty($GLOBALS['cfg']['Servers'][$GLOBALS['server']]['verbose'])
+                ? $GLOBALS['cfg']['Servers'][$GLOBALS['server']]['verbose']
+                : $GLOBALS['cfg']['Servers'][$GLOBALS['server']]['host']
+            ) . '"'
+        );
+    } elseif (! strlen($GLOBALS['table'])) {
+        // prepare for db related
+        $db     = $GLOBALS['db'];
+        // if you want navigation:
+        $tmp_db_link = '<a href="' . $GLOBALS['cfg']['DefaultTabDatabase']
+            . '?' . PMA_generate_common_url($db) . '"';
+        if ($is_querywindow) {
+            $tmp_db_link .= ' target="_self"'
+                . ' onclick="this.target=window.opener.frame_content.name"';
+        }
+        $tmp_db_link .= '>'
+            . htmlspecialchars($db) . '</a>';
+        // else use
+        // $tmp_db_link = htmlspecialchars($db);
+        $legend = sprintf(__('Run SQL query/queries on database %s'), $tmp_db_link);
+        if (empty($query)) {
+            $query = PMA_Util::expandUserString(
+                $GLOBALS['cfg']['DefaultQueryDatabase'], 'backquote'
+            );
+        }
+    } else {
+        $table  = $GLOBALS['table'];
+        $db     = $GLOBALS['db'];
+        // Get the list and number of fields
+        // we do a try_query here, because we could be in the query window,
+        // trying to synchonize and the table has not yet been created
+        $fields_list = PMA_DBI_get_columns($db, $GLOBALS['table'], null, true);
+
+        $tmp_db_link = '<a href="' . $GLOBALS['cfg']['DefaultTabDatabase']
+            . '?' . PMA_generate_common_url($db) . '"';
+        if ($is_querywindow) {
+            $tmp_db_link .= ' target="_self"'
+                . ' onclick="this.target=window.opener.frame_content.name"';
+        }
+        $tmp_db_link .= '>'
+            . htmlspecialchars($db) . '</a>';
+        // else use
+        // $tmp_db_link = htmlspecialchars($db);
+        $legend = sprintf(__('Run SQL query/queries on database %s'), $tmp_db_link);
+        if (empty($query)) {
+            $query = PMA_Util::expandUserString(
+                $GLOBALS['cfg']['DefaultQueryTable'], 'backquote'
+            );
+        }
+    }
+    $legend .= ': ' . PMA_Util::showMySQLDocu('SQL-Syntax', 'SELECT');
+
+    if (count($fields_list)) {
+        $sqlquerycontainer_id = 'sqlquerycontainer';
+    } else {
+        $sqlquerycontainer_id = 'sqlquerycontainerfull';
+    }
+
+    echo '<a id="querybox"></a>' . "\n"
+        .'<div id="queryboxcontainer">' . "\n"
+        .'<fieldset id="queryboxf">' . "\n";
+    echo '<legend>' . $legend . '</legend>' . "\n";
+    echo '<div id="queryfieldscontainer">' . "\n";
+    echo '<div id="' . $sqlquerycontainer_id . '">' . "\n"
+        .'<textarea tabindex="100" name="sql_query" id="sqlquery"'
+        .'  cols="' . $GLOBALS['cfg']['TextareaCols'] . '"'
+        .'  rows="' . $height . '"'
+        .'  dir="' . $GLOBALS['text_dir'] . '"'
+        .$auto_sel . $locking . '>'
+        . htmlspecialchars($query)
+        . '</textarea>' . "\n";
+    // Add buttons to generate query easily for
+    // select all, single select, insert, update and delete
+    if (count($fields_list)) {
+        echo '<input type="button" value="SELECT *" id="selectall" class="button sqlbutton" />';
+        echo '<input type="button" value="SELECT" id="select" class="button sqlbutton" />';
+        echo '<input type="button" value="INSERT" id="insert" class="button sqlbutton" />';
+        echo '<input type="button" value="UPDATE" id="update" class="button sqlbutton" />';
+        echo '<input type="button" value="DELETE" id="delete" class="button sqlbutton" />';
+    }
+    echo '<input type="button" value="' . __('Clear') . '" id="clear" class="button sqlbutton" />';
+    echo '</div>' . "\n";
+
+    if (count($fields_list)) {
+        echo '<div id="tablefieldscontainer">' . "\n"
+            .'<label>' . __('Columns') . '</label>' . "\n"
+            .'<select id="tablefields" name="dummy" '
+            .'size="' . ($GLOBALS['cfg']['TextareaRows'] - 2) . '" '
+            .'multiple="multiple" ondblclick="insertValueQuery()">' . "\n";
+        foreach ($fields_list as $field) {
+            echo '<option value="'
+                .PMA_Util::backquote(htmlspecialchars($field['Field'])) . '"';
+            if (isset($field['Field'])
+                && strlen($field['Field'])
+                && isset($field['Comment'])
+            ) {
+                echo ' title="' . htmlspecialchars($field['Comment']) . '"';
+            }
+            echo '>' . htmlspecialchars($field['Field']) . '</option>' . "\n";
+        }
+        echo '</select>' . "\n"
+            .'<div id="tablefieldinsertbuttoncontainer">' . "\n";
+        if ($GLOBALS['cfg']['PropertiesIconic']) {
+            echo '<input type="button" class="button" name="insert" value="<<"'
+                .' onclick="insertValueQuery()"'
+                .' title="' . __('Insert') . '" />' . "\n";
+        } else {
+            echo '<input type="button" class="button" name="insert"'
+                .' value="' . __('Insert') . '"'
+                .' onclick="insertValueQuery()" />' . "\n";
+        }
+        echo '</div>' . "\n"
+            .'</div>' . "\n";
+    }
+
+    echo '<div class="clearfloat"></div>' . "\n";
+    echo '</div>' . "\n";
+
+    if (! empty($GLOBALS['cfg']['Bookmark'])) {
+        ?>
+        <div id="bookmarkoptions">
+        <div class="formelement">
+        <label for="bkm_label">
+            <?php echo __('Bookmark this SQL query'); ?>:</label>
+        <input type="text" name="bkm_label" id="bkm_label" tabindex="110" value="" />
+        </div>
+        <div class="formelement">
+        <input type="checkbox" name="bkm_all_users" tabindex="111" id="id_bkm_all_users" value="true" />
+        <label for="id_bkm_all_users">
+            <?php echo __('Let every user access this bookmark'); ?></label>
+        </div>
+        <div class="formelement">
+        <input type="checkbox" name="bkm_replace" tabindex="112" id="id_bkm_replace"
+            value="true" />
+        <label for="id_bkm_replace">
+            <?php echo __('Replace existing bookmark of same name'); ?></label>
+        </div>
+        </div>
+        <?php
+    }
+
+    echo '<div class="clearfloat"></div>' . "\n";
+    echo '</fieldset>' . "\n"
+        .'</div>' . "\n";
+
+    echo '<fieldset id="queryboxfooter" class="tblFooters">' . "\n";
+    echo '<div class="formelement">' . "\n";
+    if ($is_querywindow) {
+        ?>
+        <script type="text/javascript">
+        //<![CDATA[
+            document.writeln(' <input type="checkbox" name="LockFromUpdate" checked="checked" tabindex="120" id="checkbox_lock" /> <label for="checkbox_lock"><?php echo __('Do not overwrite this query from outside the window'); ?></label> ');
+        //]]>
+        </script>
+        <?php
+    }
+    echo '</div>' . "\n";
+    echo '<div class="formelement">' . "\n";
+    echo '<label for="id_sql_delimiter">[ ' . __('Delimiter')
+        .'</label>' . "\n";
+    echo '<input type="text" name="sql_delimiter" tabindex="131" size="3" '
+        .'value="' . $delimiter . '" '
+        .'id="id_sql_delimiter" /> ]' . "\n";
+
+    echo '<input type="checkbox" name="show_query" value="1" '
+        .'id="checkbox_show_query" tabindex="132" checked="checked" />' . "\n"
+        .'<label for="checkbox_show_query">' . __('Show this query here again')
+        .'</label>' . "\n";
+
+    if (! $is_querywindow) {
+        echo '<input type="checkbox" name="retain_query_box" value="1" '
+            . 'id="retain_query_box" tabindex="133" '
+            . ($GLOBALS['cfg']['RetainQueryBox'] === false
+                ? '' : ' checked="checked"')
+            . ' />'
+            . '<label for="retain_query_box">' . __('Retain query box')
+            . '</label>';
+    }
+    echo '</div>' . "\n";
+    echo '<input type="submit" id="button_submit_query" name="SQL" tabindex="200" value="' . __('Go') . '" />'
+        ."\n";
+    echo '<div class="clearfloat"></div>' . "\n";
+    echo '</fieldset>' . "\n";
+}
+
+/**
+ * Prints bookmark fieldset
+ *
+ * @return void
+ *
+ * @usedby  PMA_sqlQueryForm()
+ */
+function PMA_sqlQueryFormBookmark()
+{
+    $bookmark_list = PMA_Bookmark_getList($GLOBALS['db']);
+    if (! $bookmark_list || count($bookmark_list) < 1) {
+        return;
+    }
+
+    echo '<fieldset id="bookmarkoptions">';
+    echo '<legend>';
+    echo __('Bookmarked SQL query') . '</legend>' . "\n";
+    echo '<div class="formelement">';
+    echo '<select name="id_bookmark" id="id_bookmark">' . "\n";
+    echo '<option value=""> </option>' . "\n";
+    foreach ($bookmark_list as $key => $value) {
+        echo '<option value="' . htmlspecialchars($key) . '">'
+            .htmlspecialchars($value) . '</option>' . "\n";
+    }
+    //   is required for correct display with styles/line height
+    echo '</select> ' . "\n";
+    echo '</div>' . "\n";
+    echo '<div class="formelement">' . "\n";
+    echo __('Variable');
+    echo PMA_Util::showDocu('faq', 'faqbookmark');
+    echo '<input type="text" name="bookmark_variable" class="textfield"'
+        .' size="10" />' . "\n";
+    echo '</div>' . "\n";
+    echo '<div class="formelement">' . "\n";
+    echo '<input type="radio" name="action_bookmark" value="0"'
+        .' id="radio_bookmark_exe" checked="checked" />'
+        .'<label for="radio_bookmark_exe">' . __('Submit')
+        .'</label>' . "\n";
+    echo '<input type="radio" name="action_bookmark" value="1"'
+        .' id="radio_bookmark_view" />'
+        .'<label for="radio_bookmark_view">' . __('View only')
+        .'</label>' . "\n";
+    echo '<input type="radio" name="action_bookmark" value="2"'
+        .' id="radio_bookmark_del" />'
+        .'<label for="radio_bookmark_del">' . __('Delete')
+        .'</label>' . "\n";
+    echo '</div>' . "\n";
+    echo '<div class="clearfloat"></div>' . "\n";
+    echo '</fieldset>' . "\n";
+
+    echo '<fieldset id="bookmarkoptionsfooter" class="tblFooters">' . "\n";
+    echo '<input type="submit" name="SQL" id="button_submit_bookmark" value="' . __('Go') . '" />';
+    echo '<div class="clearfloat"></div>' . "\n";
+    echo '</fieldset>' . "\n";
+}
+
+/**
+ * Prints bookmark fieldset
+ *
+ * @return void
+ *
+ * @usedby  PMA_sqlQueryForm()
+ */
+function PMA_sqlQueryFormUpload()
+{
+    global $timeout_passed, $local_import_file;
+
+    $errors = array();
+
+    // we allow only SQL here
+    $matcher = '@\.sql(\.(' . PMA_supportedDecompressions() . '))?$@';
+
+    if (!empty($GLOBALS['cfg']['UploadDir'])) {
+        $files = PMA_getFileSelectOptions(
+            PMA_Util::userDir($GLOBALS['cfg']['UploadDir']), $matcher,
+            (isset($timeout_passed) && $timeout_passed && isset($local_import_file))
+            ? $local_import_file
+            : ''
+        );
+    } else {
+        $files = '';
+    }
+
+    // start output
+    echo '<fieldset id="">';
+    echo '<legend>';
+    echo __('Browse your computer:') . '</legend>';
+    echo '<div class="formelement">';
+    echo '<input type="file" name="sql_file" class="textfield" /> ';
+    echo PMA_Util::getFormattedMaximumUploadSize($GLOBALS['max_upload_size']);
+    // some browsers should respect this :)
+    echo PMA_Util::generateHiddenMaxFileSize($GLOBALS['max_upload_size']) . "\n";
+    echo '</div>';
+
+    if ($files === false) {
+        $errors[] = PMA_Message::error(__('The directory you set for upload work cannot be reached'));
+    } elseif (!empty($files)) {
+        echo '<div class="formelement">';
+        echo '<strong>' . __('web server upload directory') .':</strong>' . "\n";
+        echo '<select size="1" name="sql_localfile">' . "\n";
+        echo '<option value="" selected="selected"></option>' . "\n";
+        echo $files;
+        echo '</select>' . "\n";
+        echo '</div>';
+    }
+
+    echo '<div class="clearfloat"></div>' . "\n";
+    echo '</fieldset>';
+
+
+    echo '<fieldset id="" class="tblFooters">';
+    echo __('Character set of the file:') . "\n";
+    echo PMA_generateCharsetDropdownBox(
+        PMA_CSDROPDOWN_CHARSET,
+        'charset_of_file', null, 'utf8', false
+    );
+    echo '<input type="submit" name="SQL" value="' . __('Go')
+        .'" />' . "\n";
+    echo '<div class="clearfloat"></div>' . "\n";
+    echo '</fieldset>';
+
+    foreach ($errors as $error) {
+        $error->display();
+    }
+}
+?>
diff --git a/phpmyadmin/libraries/sqlparser.data.php b/phpmyadmin/libraries/sqlparser.data.php
new file mode 100644
index 0000000..fab1177
--- /dev/null
+++ b/phpmyadmin/libraries/sqlparser.data.php
@@ -0,0 +1,2016 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * SQL Parser Matching Data
+ *
+ * Copyright 2002 Robin Johnson <robbat2 at users.sourceforge.net>
+ * http://www.orbis-terrarum.net/?l=people.robbat2
+ *
+ * This data is used by the SQL Parser to recognize keywords
+ *
+ * It has been extracted from the lex.h file in the MySQL BK tree
+ * (around 4.0.2) as well as the MySQL documentation.
+ *
+ * It's easier to use only uppercase for proper sorting. In case of
+ * doubt, use the test case to verify.
+ *
+ * @package PhpMyAdmin
+ */
+if (! defined('PHPMYADMIN')) {
+    exit;
+}
+
+if (! isset($GLOBALS['sql_delimiter'])) {
+        $GLOBALS['sql_delimiter'] = ';';
+}
+
+/**
+ * @global array MySQL function names
+ */
+$PMA_SQPdata_function_name = array (
+    'ABS',
+    'ACOS',
+    'ADDDATE',
+    'ADDTIME',
+    'AES_DECRYPT',
+    'AES_ENCRYPT',
+    'AREA',                     // polygon-property-functions.html
+    'ASBINARY',
+    'ASCII',
+    'ASIN',
+    'ASTEXT',
+    'ATAN',
+    'ATAN2',
+    'AVG',
+    'BDMPOLYFROMTEXT',
+    'BDMPOLYFROMWKB',
+    'BDPOLYFROMTEXT',
+    'BDPOLYFROMWKB',
+    'BENCHMARK',
+    'BIN',
+    'BIT_AND',
+    'BIT_COUNT',
+    'BIT_LENGTH',
+    'BIT_OR',
+    'BIT_XOR',                  // group-by-functions.html
+    'BOUNDARY',                 // general-geometry-property-functions.html
+    'BUFFER',
+    'CAST',
+    'CEIL',
+    'CEILING',
+    'CENTROID',                 // multipolygon-property-functions.html
+    'CHAR',                     // string-functions.html
+    'CHARACTER_LENGTH',
+    'CHARSET',                  // information-functions.html
+    'CHAR_LENGTH',
+    'COALESCE',
+    'COERCIBILITY',             // information-functions.html
+    'COLLATION',                // information-functions.html
+    'COMPRESS',                 // string-functions.html
+    'CONCAT',
+    'CONCAT_WS',
+    'CONNECTION_ID',
+    'CONTAINS',
+    'CONV',
+    'CONVERT',
+    'CONVERT_TZ',
+    'CONVEXHULL',
+    'COS',
+    'COT',
+    'COUNT',
+    'CRC32',                    // mathematical-functions.html
+    'CROSSES',
+    'CURDATE',
+    'CURRENT_DATE',
+    'CURRENT_TIME',
+    'CURRENT_TIMESTAMP',
+    'CURRENT_USER',
+    'CURTIME',
+    'DATABASE',
+    'DATE',                     // date-and-time-functions.html
+    'DATEDIFF',                 // date-and-time-functions.html
+    'DATE_ADD',
+    'DATE_DIFF',
+    'DATE_FORMAT',
+    'DATE_SUB',
+    'DAY',
+    'DAYNAME',
+    'DAYOFMONTH',
+    'DAYOFWEEK',
+    'DAYOFYEAR',
+    'DECODE',
+    'DEFAULT',                  // miscellaneous-functions.html
+    'DEGREES',
+    'DES_DECRYPT',
+    'DES_ENCRYPT',
+    'DIFFERENCE',
+    'DIMENSION',                // general-geometry-property-functions.html
+    'DISJOINT',
+    'DISTANCE',
+    'ELT',
+    'ENCODE',
+    'ENCRYPT',
+    'ENDPOINT',                 // linestring-property-functions.html
+    'ENVELOPE',                 // general-geometry-property-functions.html
+    'EQUALS',
+    'EXP',
+    'EXPORT_SET',
+    'EXTERIORRING',             // polygon-property-functions.html
+    'EXTRACT',
+    'EXTRACTVALUE',             // xml-functions.html
+    'FIELD',
+    'FIND_IN_SET',
+    'FLOOR',
+    'FORMAT',
+    'FOUND_ROWS',
+    'FROM_DAYS',
+    'FROM_UNIXTIME',
+    'GEOMCOLLFROMTEXT',
+    'GEOMCOLLFROMWKB',
+    'GEOMETRYCOLLECTION',
+    'GEOMETRYCOLLECTIONFROMTEXT',
+    'GEOMETRYCOLLECTIONFROMWKB',
+    'GEOMETRYFROMTEXT',
+    'GEOMETRYFROMWKB',
+    'GEOMETRYN',                // geometrycollection-property-functions.html
+    'GEOMETRYTYPE',             // general-geometry-property-functions.html
+    'GEOMFROMTEXT',
+    'GEOMFROMWKB',
+    'GET_FORMAT',
+    'GET_LOCK',
+    'GLENGTH',                  // linestring-property-functions.html
+    'GREATEST',
+    'GROUP_CONCAT',
+    'GROUP_UNIQUE_USERS',
+    'HEX',
+    'HOUR',
+    'IF',                       //control-flow-functions.html
+    'IFNULL',
+    'INET_ATON',
+    'INET_NTOA',
+    'INSERT',                   // string-functions.html
+    'INSTR',
+    'INTERIORRINGN',            // polygon-property-functions.html
+    'INTERSECTION',
+    'INTERSECTS',
+    'INTERVAL',
+    'ISCLOSED',                 // multilinestring-property-functions.html
+    'ISEMPTY',                  // general-geometry-property-functions.html
+    'ISNULL',
+    'ISRING',                   // linestring-property-functions.html
+    'ISSIMPLE',                 // general-geometry-property-functions.html
+    'IS_FREE_LOCK',
+    'IS_USED_LOCK',             // miscellaneous-functions.html
+    'LAST_DAY',
+    'LAST_INSERT_ID',
+    'LCASE',
+    'LEAST',
+    'LEFT',
+    'LENGTH',
+    'LINEFROMTEXT',
+    'LINEFROMWKB',
+    'LINESTRING',
+    'LINESTRINGFROMTEXT',
+    'LINESTRINGFROMWKB',
+    'LN',
+    'LOAD_FILE',
+    'LOCALTIME',
+    'LOCALTIMESTAMP',
+    'LOCATE',
+    'LOG',
+    'LOG10',
+    'LOG2',
+    'LOWER',
+    'LPAD',
+    'LTRIM',
+    'MAKEDATE',
+    'MAKETIME',
+    'MAKE_SET',
+    'MASTER_POS_WAIT',
+    'MAX',
+    'MBRCONTAINS',
+    'MBRDISJOINT',
+    'MBREQUAL',
+    'MBRINTERSECTS',
+    'MBROVERLAPS',
+    'MBRTOUCHES',
+    'MBRWITHIN',
+    'MD5',
+    'MICROSECOND',
+    'MID',
+    'MIN',
+    'MINUTE',
+    'MLINEFROMTEXT',
+    'MLINEFROMWKB',
+    'MOD',
+    'MONTH',
+    'MONTHNAME',
+    'MPOINTFROMTEXT',
+    'MPOINTFROMWKB',
+    'MPOLYFROMTEXT',
+    'MPOLYFROMWKB',
+    'MULTILINESTRING',
+    'MULTILINESTRINGFROMTEXT',
+    'MULTILINESTRINGFROMWKB',
+    'MULTIPOINT',
+    'MULTIPOINTFROMTEXT',
+    'MULTIPOINTFROMWKB',
+    'MULTIPOLYGON',
+    'MULTIPOLYGONFROMTEXT',
+    'MULTIPOLYGONFROMWKB',
+    'NAME_CONST',               // NAME_CONST()
+    'NOW',
+    'NULLIF',
+    'NUMGEOMETRIES',            // geometrycollection-property-functions.html
+    'NUMINTERIORRINGS',         // polygon-property-functions.html
+    'NUMPOINTS',                // linestring-property-functions.html
+    'OCT',
+    'OCTET_LENGTH',
+    'OLD_PASSWORD',
+    'ORD',
+    'OVERLAPS',
+    'PASSWORD',
+    'PERIOD_ADD',
+    'PERIOD_DIFF',
+    'PI',
+    'POINT',
+    'POINTFROMTEXT',
+    'POINTFROMWKB',
+    'POINTN',                   // inestring-property-functions.html
+    'POINTONSURFACE',           // multipolygon-property-functions.html
+    'POLYFROMTEXT',
+    'POLYFROMWKB',
+    'POLYGON',
+    'POLYGONFROMTEXT',
+    'POLYGONFROMWKB',
+    'POSITION',
+    'POW',
+    'POWER',
+    'QUARTER',
+    'QUOTE',
+    'RADIANS',
+    'RAND',
+    'RELATED',
+    'RELEASE_LOCK',
+    'REPEAT',
+    'REPLACE',                  // string-functions.html
+    'REVERSE',
+    'RIGHT',
+    'ROUND',
+    'ROW_COUNT',                // information-functions.html
+    'RPAD',
+    'RTRIM',
+    'SCHEMA',                   // information-functions.html
+    'SECOND',
+    'SEC_TO_TIME',
+    'SESSION_USER',
+    'SHA',
+    'SHA1',
+    'SIGN',
+    'SIN',
+    'SLEEP',                    // miscellaneous-functions.html
+    'SOUNDEX',
+    'SPACE',
+    'SQRT',
+    'SRID',                     // general-geometry-property-functions.html
+    'STARTPOINT',               // linestring-property-functions.html
+    'STD',
+    'STDDEV',
+    'STDDEV_POP',               // group-by-functions.html
+    'STDDEV_SAMP',              // group-by-functions.html
+    'STRCMP',
+    'STR_TO_DATE',
+    'SUBDATE',
+    'SUBSTR',
+    'SUBSTRING',
+    'SUBSTRING_INDEX',
+    'SUBTIME',
+    'SUM',
+    'SYMDIFFERENCE',
+    'SYSDATE',
+    'SYSTEM_USER',
+    'TAN',
+    'TIME',
+    'TIMEDIFF',
+    'TIMESTAMP',
+    'TIMESTAMPADD',
+    'TIMESTAMPDIFF',
+    'TIME_FORMAT',
+    'TIME_TO_SEC',
+    'TOUCHES',
+    'TO_DAYS',
+    'TRIM',
+    'TRUNCATE',                 // mathematical-functions.html
+    'UCASE',
+    'UNCOMPRESS',               // string-functions.html
+    'UNCOMPRESSED_LENGTH',      // string-functions.html
+    'UNHEX',                    // string-functions.html
+    'UNIQUE_USERS',
+    'UNIX_TIMESTAMP',
+    'UPDATEXML',                // xml-functions.html
+    'UPPER',
+    'USER',
+    'UTC_DATE',
+    'UTC_TIME',
+    'UTC_TIMESTAMP',
+    'UUID',                     // miscellaneous-functions.html
+    'VARIANCE',                 // group-by-functions.html
+    'VAR_POP',                  // group-by-functions.html
+    'VAR_SAMP',                 // group-by-functions.html
+    'VERSION',
+    'WEEK',
+    'WEEKDAY',
+    'WEEKOFYEAR',
+    'WITHIN',
+    'X',                        // point-property-functions.html
+    'Y',                        // point-property-functions.html
+    'YEAR',
+    'YEARWEEK'
+);
+
+/**
+ * @global array MySQL attributes
+ */
+$PMA_SQPdata_column_attrib = array (
+    'ARCHIVE',          // Engine
+    'ASCII',
+    'AUTO_INCREMENT',
+    'BDB',              // Engine
+    'BERKELEYDB',       // Engine alias BDB
+    'BINARY',
+    'BLACKHOLE',        // Engine
+    'CSV',              // Engine
+    'DEFAULT',
+    'EXAMPLE',          // Engine
+    'FEDERATED',        // Engine
+    'HEAP',             // Engine
+    'INNOBASE',         // Engine alias InnoDB
+    'INNODB',           // Engine InnoDB
+    'ISAM',             // Engine
+    'MARIA',            // Engine
+    'MEMORY',           // Engine alias HEAP, but preferred
+    'MERGE',            // Engine
+    'MRG_ISAM',         // Engine
+    'MRG_MYISAM',       // Engine alias MERGE
+    'MYISAM',           // Engine MyISAM
+    'NATIONAL',
+    'NDB',              // Engine alias NDBCLUSTER
+    'NDBCLUSTER',       // Engine
+    'PRECISION',
+    'UNDEFINED',
+    'UNICODE',
+    'UNSIGNED',
+    'VARYING',
+    'ZEROFILL'
+);
+
+/**
+ * words that are reserved by MySQL and may not be used as identifiers without
+ * quotes
+ *
+ * @see http://dev.mysql.com/doc/refman/5.5/en/reserved-words.html
+ *
+ * @global array MySQL reserved words
+ */
+$PMA_SQPdata_reserved_word = array (
+    'ACCESSIBLE',       // 5.1
+    'ACTION',
+    'ADD',
+    'AFTER',
+    'AGAINST',
+    'AGGREGATE',
+    'ALGORITHM',
+    'ALL',
+    'ALTER',
+    'ANALYSE',
+    'ANALYZE',
+    'AND',
+    'AS',
+    'ASC',
+    'AUTOCOMMIT',
+    'AUTO_INCREMENT',
+    'AVG_ROW_LENGTH',
+    'BACKUP',
+    'BEGIN',
+    'BETWEEN',
+    'BINLOG',
+    'BOTH',
+    'BY',
+    'CASCADE',
+    'CASE',
+    'CHANGE',
+    'CHANGED',
+    'CHARSET',
+    'CHECK',
+    'CHECKSUM',
+    'COLLATE',
+    'COLLATION',
+    'COLUMN',
+    'COLUMNS',
+    'COMMENT',
+    'COMMIT',
+    'COMMITTED',
+    'COMPRESSED',
+    'CONCURRENT',
+    'CONSTRAINT',
+    'CONTAINS',
+    'CONVERT',
+    'CREATE',
+    'CROSS',
+    'CURRENT_TIMESTAMP',
+    'DATABASE',
+    'DATABASES',
+    'DAY',
+    'DAY_HOUR',
+    'DAY_MINUTE',
+    'DAY_SECOND',
+    'DECLARE',
+    'DEFINER',
+    'DELAYED',
+    'DELAY_KEY_WRITE',
+    'DELETE',
+    'DESC',
+    'DESCRIBE',
+    'DETERMINISTIC',
+    'DISTINCT',
+    'DISTINCTROW',
+    'DIV',
+    'DO',
+    'DROP',
+    'DUMPFILE',
+    'DUPLICATE',
+    'DYNAMIC',
+    'ELSE',
+    'ENCLOSED',
+    'END',
+    'ENGINE',
+    'ENGINES',
+    'ESCAPE',
+    'ESCAPED',
+    'EVENTS',
+    'EXECUTE',
+    'EXISTS',
+    'EXPLAIN',
+    'EXTENDED',
+    'FALSE',
+    'FAST',
+    'FIELDS',
+    'FILE',
+    'FIRST',
+    'FIXED',
+    'FLUSH',
+    'FOR',
+    'FORCE',
+    'FOREIGN',
+    'FROM',
+    'FULL',
+    'FULLTEXT',
+    'FUNCTION',
+    'GEMINI',
+    'GEMINI_SPIN_RETRIES',
+    'GENERAL',
+    'GLOBAL',
+    'GRANT',
+    'GRANTS',
+    'GROUP',
+    'HAVING',
+    'HEAP',
+    'HIGH_PRIORITY',
+    'HOSTS',
+    'HOUR',
+    'HOUR_MINUTE',
+    'HOUR_SECOND',
+    'IDENTIFIED',
+    'IF',
+    'IGNORE',
+    'IGNORE_SERVER_IDS',
+    'IN',
+    'INDEX',
+    'INDEXES',
+    'INFILE',
+    'INNER',
+    'INSERT',
+    'INSERT_ID',
+    'INSERT_METHOD',
+    'INTERVAL',
+    'INTO',
+    'INVOKER',
+    'IS',
+    'ISOLATION',
+    'JOIN',
+    'KEY',
+    'KEYS',
+    'KILL',
+    'LAST_INSERT_ID',
+    'LEADING',
+    'LEFT',
+    'LIKE',
+    'LIMIT',
+    'LINEAR',               // 5.1
+    'LINES',
+    'LOAD',
+    'LOCAL',
+    'LOCK',
+    'LOCKS',
+    'LOGS',
+    'LOW_PRIORITY',
+    'MARIA',                // 5.1 ?
+    'MASTER_CONNECT_RETRY',
+    'MASTER_HEARTBEAT_PERIOD',
+    'MASTER_HOST',
+    'MASTER_LOG_FILE',
+    'MASTER_LOG_POS',
+    'MASTER_PASSWORD',
+    'MASTER_PORT',
+    'MASTER_USER',
+    'MATCH',
+    'MAXVALUE',
+    'MAX_CONNECTIONS_PER_HOUR',
+    'MAX_QUERIES_PER_HOUR',
+    'MAX_ROWS',
+    'MAX_UPDATES_PER_HOUR',
+    'MAX_USER_CONNECTIONS',
+    'MEDIUM',
+    'MERGE',
+    'MINUTE',
+    'MINUTE_SECOND',
+    'MIN_ROWS',
+    'MODE',
+    'MODIFY',
+    'MONTH',
+    'MRG_MYISAM',
+    'MYISAM',
+    'NAMES',
+    'NATURAL',
+    // 'NO' is not allowed in SQL-99 but is allowed in MySQL
+    //'NO',
+    'NOT',
+    'NULL',
+    'OFFSET',
+    'ON',
+    'OPEN',
+    'OPTIMIZE',
+    'OPTION',
+    'OPTIONALLY',
+    'OR',
+    'ORDER',
+    'OUTER',
+    'OUTFILE',
+    'PACK_KEYS',
+    'PAGE',                 // 5.1-maria ?
+    'PAGE_CHECKSUM',        // 5.1
+    'PARTIAL',
+    'PARTITION',            // 5.1
+    'PARTITIONS',           // 5.1
+    'PASSWORD',
+    'PRIMARY',
+    'PRIVILEGES',
+    'PROCEDURE',
+    'PROCESS',
+    'PROCESSLIST',
+    'PURGE',
+    'QUICK',
+    'RAID0',
+    'RAID_CHUNKS',
+    'RAID_CHUNKSIZE',
+    'RAID_TYPE',
+    'RANGE',                // 5.1
+    'READ',
+    'READ_ONLY',            // 5.1
+    'READ_WRITE',           // 5.1
+    'REFERENCES',
+    'REGEXP',
+    'RELOAD',
+    'RENAME',
+    'REPAIR',
+    'REPEATABLE',
+    'REPLACE',
+    'REPLICATION',
+    'RESET',
+    'RESIGNAL',
+    'RESTORE',
+    'RESTRICT',
+    'RETURN',
+    'RETURNS',
+    'REVOKE',
+    'RIGHT',
+    'RLIKE',
+    'ROLLBACK',
+    'ROW',
+    'ROWS',
+    'ROW_FORMAT',
+    'SECOND',
+    'SECURITY',
+    'SELECT',
+    'SEPARATOR',
+    'SERIALIZABLE',
+    'SESSION',
+    'SHARE',
+    'SHOW',
+    'SHUTDOWN',
+    'SIGNAL',
+    'SLAVE',
+    'SLOW',
+    'SONAME',
+    'SOUNDS',                   // string-functions.html
+    'SQL',
+    'SQL_AUTO_IS_NULL',
+    'SQL_BIG_RESULT',
+    'SQL_BIG_SELECTS',
+    'SQL_BIG_TABLES',
+    'SQL_BUFFER_RESULT',
+    'SQL_CACHE',
+    'SQL_CALC_FOUND_ROWS',
+    'SQL_LOG_BIN',
+    'SQL_LOG_OFF',
+    'SQL_LOG_UPDATE',
+    'SQL_LOW_PRIORITY_UPDATES',
+    'SQL_MAX_JOIN_SIZE',
+    'SQL_NO_CACHE',
+    'SQL_QUOTE_SHOW_CREATE',
+    'SQL_SAFE_UPDATES',
+    'SQL_SELECT_LIMIT',
+    'SQL_SLAVE_SKIP_COUNTER',
+    'SQL_SMALL_RESULT',
+    'SQL_WARNINGS',
+    'START',
+    'STARTING',
+    'STATUS',
+    'STOP',
+    'STORAGE',
+    'STRAIGHT_JOIN',
+    'STRING',
+    'STRIPED',
+    'SUPER',
+    'TABLE',
+    'TABLES',
+    'TEMPORARY',
+    'TERMINATED',
+    'THEN',
+    'TO',
+    'TRAILING',
+    'TRANSACTIONAL',    // 5.1 ?
+    'TRUE',
+    'TRUNCATE',
+    'TYPE',
+    'TYPES',
+    'UNCOMMITTED',
+    'UNION',
+    'UNIQUE',
+    'UNLOCK',
+    'UPDATE',
+    'USAGE',
+    'USE',
+    'USING',
+    'VALUES',
+    'VARIABLES',
+    'VIEW',
+    'WHEN',
+    'WHERE',
+    'WITH',
+    'WORK',
+    'WRITE',
+    'XOR',
+    'YEAR_MONTH'
+);
+
+/**
+ * words forbidden to be used as column or table name without quotes
+ * as seen in http://dev.mysql.com/doc/refman/5.6/en/reserved-words.html
+ *
+ * @global array MySQL forbidden words
+ */
+$PMA_SQPdata_forbidden_word = array (
+    'ACCESSIBLE',
+    'ADD',
+    'ALL',
+    'ALTER',
+    'ANALYZE',
+    'AND',
+    'AS',
+    'ASC',
+    'ASENSITIVE',
+    'BEFORE',
+    'BETWEEN',
+    'BIGINT',
+    'BINARY',
+    'BLOB',
+    'BOTH',
+    'BY',
+    'CALL',
+    'CASCADE',
+    'CASE',
+    'CHANGE',
+    'CHAR',
+    'CHARACTER',
+    'CHECK',
+    'COLLATE',
+    'COLUMN',
+    'CONDITION',
+    'CONSTRAINT',
+    'CONTINUE',
+    'CONVERT',
+    'CREATE',
+    'CROSS',
+    'CURRENT_DATE',
+    'CURRENT_TIME',
+    'CURRENT_TIMESTAMP',
+    'CURRENT_USER',
+    'CURSOR',
+    'DATABASE',
+    'DATABASES',
+    'DAY_HOUR',
+    'DAY_MICROSECOND',
+    'DAY_MINUTE',
+    'DAY_SECOND',
+    'DEC',
+    'DECIMAL',
+    'DECLARE',
+    'DEFAULT',
+    'DELAYED',
+    'DELETE',
+    'DESC',
+    'DESCRIBE',
+    'DETERMINISTIC',
+    'DISTINCT',
+    'DISTINCTROW',
+    'DIV',
+    'DOUBLE',
+    'DROP',
+    'DUAL',
+    'EACH',
+    'ELSE',
+    'ELSEIF',
+    'ENCLOSED',
+    'ESCAPED',
+    'EXISTS',
+    'EXIT',
+    'EXPLAIN',
+    'FALSE',
+    'FETCH',
+    'FLOAT',
+    'FLOAT4',
+    'FLOAT8',
+    'FOR',
+    'FORCE',
+    'FOREIGN',
+    'FROM',
+    'FULLTEXT',
+    'GENERAL',
+    'GET',
+    'GRANT',
+    'GROUP',
+    'HAVING',
+    'HIGH_PRIORITY',
+    'HOUR_MICROSECOND',
+    'HOUR_MINUTE',
+    'HOUR_SECOND',
+    'IF',
+    'IGNORE',
+    'IGNORE_SERVER_IDS',
+    'IN',
+    'INDEX',
+    'INFILE',
+    'INNER',
+    'INOUT',
+    'INSENSITIVE',
+    'INSERT',
+    'INT',
+    'INT1',
+    'INT2',
+    'INT3',
+    'INT4',
+    'INT8',
+    'INTEGER',
+    'INTERVAL',
+    'INTO',
+    'IO_AFTER_GTIDS',
+    'IO_BEFORE_GTIDS',
+    'IS',
+    'ITERATE',
+    'JOIN',
+    'KEY',
+    'KEYS',
+    'KILL',
+    'LEADING',
+    'LEAVE',
+    'LEFT',
+    'LIKE',
+    'LIMIT',
+    'LINEAR',
+    'LINES',
+    'LOAD',
+    'LOCALTIME',
+    'LOCALTIMESTAMP',
+    'LOCK',
+    'LONG',
+    'LONGBLOB',
+    'LONGTEXT',
+    'LOOP',
+    'LOW_PRIORITY',
+    'MASTER_BIND',
+    'MASTER_HEARTBEAT_PERIOD',
+    'MASTER_SSL_VERIFY_SERVER_CERT',
+    'MATCH',
+    'MAXVALUE',
+    'MEDIUMBLOB',
+    'MEDIUMINT',
+    'MEDIUMTEXT',
+    'MIDDLEINT',
+    'MINUTE_MICROSECOND',
+    'MINUTE_SECOND',
+    'MOD',
+    'MODIFIES',
+    'NATURAL',
+    'NOT',
+    'NO_WRITE_TO_BINLOG',
+    'NULL',
+    'NUMERIC',
+    'ON',
+    'ONE_SHOT',
+    'OPTIMIZE',
+    'OPTION',
+    'OPTIONALLY',
+    'OR',
+    'ORDER',
+    'OUT',
+    'OUTER',
+    'OUTFILE',
+    'PARTITION',
+    'PRECISION',
+    'PRIMARY',
+    'PROCEDURE',
+    'PURGE',
+    'RANGE',
+    'READ',
+    'READS',
+    'READ_WRITE',
+    'REAL',
+    'REFERENCES',
+    'REGEXP',
+    'RELEASE',
+    'RENAME',
+    'REPEAT',
+    'REPLACE',
+    'REQUIRE',
+    'RESIGNAL',
+    'RESTRICT',
+    'RETURN',
+    'REVOKE',
+    'RIGHT',
+    'RLIKE',
+    'SCHEMA',
+    'SCHEMAS',
+    'SECOND_MICROSECOND',
+    'SELECT',
+    'SENSITIVE',
+    'SEPARATOR',
+    'SET',
+    'SHOW',
+    'SIGNAL',
+    'SLOW',
+    'SMALLINT',
+    'SPATIAL',
+    'SPECIFIC',
+    'SQL',
+    'SQLEXCEPTION',
+    'SQLSTATE',
+    'SQLWARNING',
+    'SQL_AFTER_GTIDS',
+    'SQL_BEFORE_GTIDS',
+    'SQL_BIG_RESULT',
+    'SQL_CALC_FOUND_ROWS',
+    'SQL_SMALL_RESULT',
+    'SSL',
+    'STARTING',
+    'STRAIGHT_JOIN',
+    'TABLE',
+    'TERMINATED',
+    'THEN',
+    'TINYBLOB',
+    'TINYINT',
+    'TINYTEXT',
+    'TO',
+    'TRAILING',
+    'TRIGGER',
+    'TRUE',
+    'UNDO',
+    'UNION',
+    'UNIQUE',
+    'UNLOCK',
+    'UNSIGNED',
+    'UPDATE',
+    'USAGE',
+    'USE',
+    'USING',
+    'UTC_DATE',
+    'UTC_TIME',
+    'UTC_TIMESTAMP',
+    'VALUES',
+    'VARBINARY',
+    'VARCHAR',
+    'VARCHARACTER',
+    'VARYING',
+    'WHEN',
+    'WHERE',
+    'WHILE',
+    'WITH',
+    'WRITE',
+    'XOR',
+    'YEAR_MONTH',
+    'ZEROFILL'
+);
+
+/**
+ * the MySQL column/data types
+ *
+ * @see http://dev.mysql.com/doc/refman/5.1/en/data-types.html
+ * @see http://dev.mysql.com/doc/refman/5.1/en/mysql-spatial-datatypes.html
+ *
+ * @global array MySQL column types
+ */
+$PMA_SQPdata_column_type = array (
+    'BIGINT',
+    'BINARY',
+    'BIT',
+    'BLOB',
+    'BOOL',
+    'BOOLEAN',              // numeric-type-overview.html
+    'CHAR',
+    'CHARACTER',
+    'DATE',
+    'DATETIME',
+    'DEC',
+    'DECIMAL',
+    'DOUBLE',
+    'ENUM',
+    'FLOAT',
+    'FLOAT4',
+    'FLOAT8',
+    'GEOMETRY',             // spatial
+    'GEOMETRYCOLLECTION',   // spatial
+    'INT',
+    'INT1',
+    'INT2',
+    'INT3',
+    'INT4',
+    'INT8',
+    'INTEGER',
+    'LINESTRING',           // spatial
+    'LONG',
+    'LONGBLOB',
+    'LONGTEXT',
+    'MEDIUMBLOB',
+    'MEDIUMINT',
+    'MEDIUMTEXT',
+    'MIDDLEINT',
+    'MULTILINESTRING',      // spatial
+    'MULTIPOINT',           // spatial
+    'MULTIPOLYGON',         // spatial
+    'NCHAR',
+    'NUMERIC',
+    'POINT',                // spatial
+    'POLYGON',              // spatial
+    'REAL',
+    'SERIAL',               // alias
+    'SET',
+    'SMALLINT',
+    'TEXT',
+    'TIME',
+    'TIMESTAMP',
+    'TINYBLOB',
+    'TINYINT',
+    'TINYTEXT',
+    'VARBINARY',
+    'VARCHAR',
+    'YEAR'
+);
+
+/**
+ * Documentation links for operators.
+ */
+$PMA_SQPdata_operators_docs = array(
+   '!=' => array(
+        'link' => 'comparison-operators',
+        'anchor' => 'operator_not-equal',
+    ),
+   '<>' => array(
+        'link' => 'comparison-operators',
+        'anchor' => 'operator_not-equal',
+    ),
+   '!' => array(
+        'link' => 'logical-operators',
+        'anchor' => 'operator_not',
+    ),
+   '||' => array(
+        'link' => 'logical-operators',
+        'anchor' => 'operator_or',
+    ),
+   '+' => array(
+        'link' => 'arithmetic-functions',
+        'anchor' => 'operator_plus',
+    ),
+   '>>' => array(
+        'link' => 'bit-functions',
+        'anchor' => 'operator_right-shift',
+    ),
+   '-' => array(
+        'link' => 'arithmetic-functions',
+        'anchor' => 'operator_minus',
+    ),
+   '*' => array(
+        'link' => 'arithmetic-functions',
+        'anchor' => 'operator_times',
+    ),
+   '&&' => array(
+        'link' => 'logical-operators',
+        'anchor' => 'operator_and',
+    ),
+   '&' => array(
+        'link' => 'bit-functions',
+        'anchor' => 'operator_bitwise-and',
+    ),
+   '~' => array(
+        'link' => 'bit-functions',
+        'anchor' => 'operator_bitwise-invert',
+    ),
+   '|' => array(
+        'link' => 'bit-functions',
+        'anchor' => 'operator_bitwise-or',
+    ),
+   '^' => array(
+        'link' => 'bit-functions',
+        'anchor' => 'operator_bitwise-xor',
+    ),
+   //FIXME:duplicated key "="
+   '=' => array(
+       'link' => 'assignment-operators',
+       'anchor' => 'operator_assign-equal',
+   ),
+   ':=' => array(
+        'link' => 'assignment-operators',
+        'anchor' => 'operator_assign-value',
+    ),
+   '/' => array(
+        'link' => 'arithmetic-functions',
+        'anchor' => 'operator_divide',
+    ),
+   '<=>' => array(
+        'link' => 'comparison-operators',
+        'anchor' => 'operator_equal-to',
+    ),
+   //FIXME:duplicated key "="
+   '=' => array(
+        'link' => 'comparison-operators',
+        'anchor' => 'operator_equal',
+    ),
+   '>=' => array(
+        'link' => 'comparison-operators',
+        'anchor' => 'operator_greater-than-or-equal',
+    ),
+   '>' => array(
+        'link' => 'comparison-operators',
+        'anchor' => 'operator_greater-than',
+    ),
+   '<<' => array(
+        'link' => 'bit-functions',
+        'anchor' => 'operator_left-shift',
+    ),
+   '<=' => array(
+        'link' => 'comparison-operators',
+        'anchor' => 'operator_less-than-or-equal',
+    ),
+   '<' => array(
+        'link' => 'comparison-operators',
+        'anchor' => 'operator_less-than',
+    ),
+   '%' => array(
+        'link' => 'arithmetic-functions',
+        'anchor' => 'operator_mod',
+    )
+);
+
+/**
+ * Documentation links for functions.
+ */
+$PMA_SQPdata_functions_docs = array(
+   'ABS' => array(
+        'link' => 'mathematical-functions',
+        'anchor' => 'function_abs',
+    ),
+   'ACOS' => array(
+        'link' => 'mathematical-functions',
+        'anchor' => 'function_acos',
+    ),
+   'ADDDATE' => array(
+        'link' => 'date-and-time-functions',
+        'anchor' => 'function_adddate',
+    ),
+   'ADDTIME' => array(
+        'link' => 'date-and-time-functions',
+        'anchor' => 'function_addtime',
+    ),
+   'AES_DECRYPT' => array(
+        'link' => 'encryption-functions',
+        'anchor' => 'function_aes_decrypt',
+    ),
+   'AES_ENCRYPT' => array(
+        'link' => 'encryption-functions',
+        'anchor' => 'function_aes_encrypt',
+    ),
+   'AND' => array(
+        'link' => 'logical-operators',
+        'anchor' => 'operator_and',
+    ),
+   'ASCII' => array(
+        'link' => 'string-functions',
+        'anchor' => 'function_ascii',
+    ),
+   'ASIN' => array(
+        'link' => 'mathematical-functions',
+        'anchor' => 'function_asin',
+    ),
+   'ATAN2' => array(
+        'link' => 'mathematical-functions',
+        'anchor' => 'function_atan2',
+    ),
+   'ATAN' => array(
+        'link' => 'mathematical-functions',
+        'anchor' => 'function_atan',
+    ),
+   'AVG' => array(
+        'link' => 'group-by-functions',
+        'anchor' => 'function_avg',
+    ),
+   'BENCHMARK' => array(
+        'link' => 'information-functions',
+        'anchor' => 'function_benchmark',
+    ),
+   'BIN' => array(
+        'link' => 'string-functions',
+        'anchor' => 'function_bin',
+    ),
+   'BINARY' => array(
+        'link' => 'cast-functions',
+        'anchor' => 'operator_binary',
+    ),
+   'BIT_AND' => array(
+        'link' => 'group-by-functions',
+        'anchor' => 'function_bit_and',
+    ),
+   'BIT_COUNT' => array(
+        'link' => 'bit-functions',
+        'anchor' => 'function_bit_count',
+    ),
+   'BIT_LENGTH' => array(
+        'link' => 'string-functions',
+        'anchor' => 'function_bit_length',
+    ),
+   'BIT_OR' => array(
+        'link' => 'group-by-functions',
+        'anchor' => 'function_bit_or',
+    ),
+   'BIT_XOR' => array(
+        'link' => 'group-by-functions',
+        'anchor' => 'function_bit_xor',
+    ),
+   'CASE' => array(
+        'link' => 'control-flow-functions',
+        'anchor' => 'operator_case',
+    ),
+   'CAST' => array(
+        'link' => 'cast-functions',
+        'anchor' => 'function_cast',
+    ),
+   'CEIL' => array(
+        'link' => 'mathematical-functions',
+        'anchor' => 'function_ceil',
+    ),
+   'CEILING' => array(
+        'link' => 'mathematical-functions',
+        'anchor' => 'function_ceiling',
+    ),
+   'CHAR_LENGTH' => array(
+        'link' => 'string-functions',
+        'anchor' => 'function_char_length',
+    ),
+   'CHAR' => array(
+        'link' => 'string-functions',
+        'anchor' => 'function_char',
+    ),
+   'CHARACTER_LENGTH' => array(
+        'link' => 'string-functions',
+        'anchor' => 'function_character_length',
+    ),
+   'CHARSET' => array(
+        'link' => 'information-functions',
+        'anchor' => 'function_charset',
+    ),
+   'COALESCE' => array(
+        'link' => 'comparison-operators',
+        'anchor' => 'function_coalesce',
+    ),
+   'COERCIBILITY' => array(
+        'link' => 'information-functions',
+        'anchor' => 'function_coercibility',
+    ),
+   'COLLATION' => array(
+        'link' => 'information-functions',
+        'anchor' => 'function_collation',
+    ),
+   'COMPRESS' => array(
+        'link' => 'encryption-functions',
+        'anchor' => 'function_compress',
+    ),
+   'CONCAT_WS' => array(
+        'link' => 'string-functions',
+        'anchor' => 'function_concat_ws',
+    ),
+   'CONCAT' => array(
+        'link' => 'string-functions',
+        'anchor' => 'function_concat',
+    ),
+   'CONNECTION_ID' => array(
+        'link' => 'information-functions',
+        'anchor' => 'function_connection_id',
+    ),
+   'CONV' => array(
+        'link' => 'mathematical-functions',
+        'anchor' => 'function_conv',
+    ),
+   'CONVERT_TZ' => array(
+        'link' => 'date-and-time-functions',
+        'anchor' => 'function_convert_tz',
+    ),
+   'Convert' => array(
+        'link' => 'cast-functions',
+        'anchor' => 'function_convert',
+    ),
+   'COS' => array(
+        'link' => 'mathematical-functions',
+        'anchor' => 'function_cos',
+    ),
+   'COT' => array(
+        'link' => 'mathematical-functions',
+        'anchor' => 'function_cot',
+    ),
+   'COUNT' => array(
+        'link' => 'group-by-functions',
+        'anchor' => 'function_count',
+    ),
+   'CRC32' => array(
+        'link' => 'mathematical-functions',
+        'anchor' => 'function_crc32',
+    ),
+   'CURDATE' => array(
+        'link' => 'date-and-time-functions',
+        'anchor' => 'function_curdate',
+    ),
+   'CURRENT_DATE' => array(
+        'link' => 'date-and-time-functions',
+        'anchor' => 'function_current_date',
+    ),
+   'CURRENT_TIME' => array(
+        'link' => 'date-and-time-functions',
+        'anchor' => 'function_current_time',
+    ),
+   'CURRENT_TIMESTAMP' => array(
+        'link' => 'date-and-time-functions',
+        'anchor' => 'function_current_timestamp',
+    ),
+   'CURRENT_USER' => array(
+        'link' => 'information-functions',
+        'anchor' => 'function_current_user',
+    ),
+   'CURTIME' => array(
+        'link' => 'date-and-time-functions',
+        'anchor' => 'function_curtime',
+    ),
+   'DATABASE' => array(
+        'link' => 'information-functions',
+        'anchor' => 'function_database',
+    ),
+   'DATE_ADD' => array(
+        'link' => 'date-and-time-functions',
+        'anchor' => 'function_date_add',
+    ),
+   'DATE_FORMAT' => array(
+        'link' => 'date-and-time-functions',
+        'anchor' => 'function_date_format',
+    ),
+   'DATE_SUB' => array(
+        'link' => 'date-and-time-functions',
+        'anchor' => 'function_date_sub',
+    ),
+   'DATE' => array(
+        'link' => 'date-and-time-functions',
+        'anchor' => 'function_date',
+    ),
+   'DATEDIFF' => array(
+        'link' => 'date-and-time-functions',
+        'anchor' => 'function_datediff',
+    ),
+   'DAY' => array(
+        'link' => 'date-and-time-functions',
+        'anchor' => 'function_day',
+    ),
+   'DAYNAME' => array(
+        'link' => 'date-and-time-functions',
+        'anchor' => 'function_dayname',
+    ),
+   'DAYOFMONTH' => array(
+        'link' => 'date-and-time-functions',
+        'anchor' => 'function_dayofmonth',
+    ),
+   'DAYOFWEEK' => array(
+        'link' => 'date-and-time-functions',
+        'anchor' => 'function_dayofweek',
+    ),
+   'DAYOFYEAR' => array(
+        'link' => 'date-and-time-functions',
+        'anchor' => 'function_dayofyear',
+    ),
+   'DECLARE' => array('link' => 'declare', 'anchor' => 'declare'),
+   'DECODE' => array(
+        'link' => 'encryption-functions',
+        'anchor' => 'function_decode',
+    ),
+   'DEFAULT' => array(
+        'link' => 'miscellaneous-functions',
+        'anchor' => 'function_default',
+    ),
+   'DEGREES' => array(
+        'link' => 'mathematical-functions',
+        'anchor' => 'function_degrees',
+    ),
+   'DES_DECRYPT' => array(
+        'link' => 'encryption-functions',
+        'anchor' => 'function_des_decrypt',
+    ),
+   'DES_ENCRYPT' => array(
+        'link' => 'encryption-functions',
+        'anchor' => 'function_des_encrypt',
+    ),
+   'DIV' => array(
+        'link' => 'arithmetic-functions',
+        'anchor' => 'operator_div',
+    ),
+   'ELT' => array(
+        'link' => 'string-functions',
+        'anchor' => 'function_elt',
+    ),
+   'ENCODE' => array(
+        'link' => 'encryption-functions',
+        'anchor' => 'function_encode',
+    ),
+   'ENCRYPT' => array(
+        'link' => 'encryption-functions',
+        'anchor' => 'function_encrypt',
+    ),
+   'EXP' => array(
+        'link' => 'mathematical-functions',
+        'anchor' => 'function_exp',
+    ),
+   'EXPORT_SET' => array(
+        'link' => 'string-functions',
+        'anchor' => 'function_export_set',
+    ),
+   'EXTRACT' => array(
+        'link' => 'date-and-time-functions',
+        'anchor' => 'function_extract',
+    ),
+   'ExtractValue' => array(
+        'link' => 'xml-functions',
+        'anchor' => 'function_extractvalue',
+    ),
+   'FIELD' => array(
+        'link' => 'string-functions',
+        'anchor' => 'function_field',
+    ),
+   'FIND_IN_SET' => array(
+        'link' => 'string-functions',
+        'anchor' => 'function_find_in_set',
+    ),
+   'FLOOR' => array(
+        'link' => 'mathematical-functions',
+        'anchor' => 'function_floor',
+    ),
+   'FORMAT' => array(
+        'link' => 'string-functions',
+        'anchor' => 'function_format',
+    ),
+   'FOUND_ROWS' => array(
+        'link' => 'information-functions',
+        'anchor' => 'function_found_rows',
+    ),
+   'FROM_DAYS' => array(
+        'link' => 'date-and-time-functions',
+        'anchor' => 'function_from_days',
+    ),
+   'FROM_UNIXTIME' => array(
+        'link' => 'date-and-time-functions',
+        'anchor' => 'function_from_unixtime',
+    ),
+   'GET_FORMAT' => array(
+        'link' => 'date-and-time-functions',
+        'anchor' => 'function_get_format',
+    ),
+   'GET_LOCK' => array(
+        'link' => 'miscellaneous-functions',
+        'anchor' => 'function_get_lock',
+    ),
+   'GREATEST' => array(
+        'link' => 'comparison-operators',
+        'anchor' => 'function_greatest',
+    ),
+   'GROUP_CONCAT' => array(
+        'link' => 'group-by-functions',
+        'anchor' => 'function_group_concat',
+    ),
+   'HEX' => array(
+        'link' => 'string-functions',
+        'anchor' => 'function_hex',
+    ),
+   'HOUR' => array(
+        'link' => 'date-and-time-functions',
+        'anchor' => 'function_hour',
+    ),
+   'IF' => array(
+        'link' => 'control-flow-functions',
+        'anchor' => 'function_if',
+    ),
+   'IFNULL' => array(
+        'link' => 'control-flow-functions',
+        'anchor' => 'function_ifnull',
+    ),
+   'IN' => array(
+        'link' => 'comparison-operators',
+        'anchor' => 'function_in',
+    ),
+   'INET_ATON' => array(
+        'link' => 'miscellaneous-functions',
+        'anchor' => 'function_inet_aton',
+    ),
+   'INET_NTOA' => array(
+        'link' => 'miscellaneous-functions',
+        'anchor' => 'function_inet_ntoa',
+    ),
+   'INSERT' => array(
+        'link' => 'string-functions',
+        'anchor' => 'function_insert',
+    ),
+   'INSTR' => array(
+        'link' => 'string-functions',
+        'anchor' => 'function_instr',
+    ),
+   'INTERVAL' => array(
+        'link' => 'comparison-operators',
+        'anchor' => 'function_interval',
+    ),
+   'IS_FREE_LOCK' => array(
+        'link' => 'miscellaneous-functions',
+        'anchor' => 'function_is_free_lock',
+    ),
+   'IS_USED_LOCK' => array(
+        'link' => 'miscellaneous-functions',
+        'anchor' => 'function_is_used_lock',
+    ),
+   'IS' => array(
+        'link' => 'comparison-operators',
+        'anchor' => 'operator_is',
+    ),
+   'ISNULL' => array(
+        'link' => 'comparison-operators',
+        'anchor' => 'function_isnull',
+    ),
+   'LAST_DAY' => array(
+        'link' => 'date-and-time-functions',
+        'anchor' => 'function_last_day',
+    ),
+   'LAST_INSERT_ID' => array(
+        'link' => 'information-functions',
+        'anchor' => 'function_last_insert_id',
+    ),
+   'LCASE' => array(
+        'link' => 'string-functions',
+        'anchor' => 'function_lcase',
+    ),
+   'LEAST' => array(
+        'link' => 'comparison-operators',
+        'anchor' => 'function_least',
+    ),
+   'LEFT' => array(
+        'link' => 'string-functions',
+        'anchor' => 'function_left',
+    ),
+   'LENGTH' => array(
+        'link' => 'string-functions',
+        'anchor' => 'function_length',
+    ),
+   'LIKE' => array(
+        'link' => 'string-comparison-functions',
+        'anchor' => 'operator_like',
+    ),
+   'LN' => array(
+        'link' => 'mathematical-functions',
+        'anchor' => 'function_ln',
+    ),
+   'LOAD_FILE' => array(
+        'link' => 'string-functions',
+        'anchor' => 'function_load_file',
+    ),
+   'LOCALTIME' => array(
+        'link' => 'date-and-time-functions',
+        'anchor' => 'function_localtime',
+    ),
+   'LOCALTIMESTAMP' => array(
+        'link' => 'date-and-time-functions',
+        'anchor' => 'function_localtimestamp',
+    ),
+   'LOCATE' => array(
+        'link' => 'string-functions',
+        'anchor' => 'function_locate',
+    ),
+   'LOG10' => array(
+        'link' => 'mathematical-functions',
+        'anchor' => 'function_log10',
+    ),
+   'LOG2' => array(
+        'link' => 'mathematical-functions',
+        'anchor' => 'function_log2',
+    ),
+   'LOG' => array(
+        'link' => 'mathematical-functions',
+        'anchor' => 'function_log',
+    ),
+   'LOWER' => array(
+        'link' => 'string-functions',
+        'anchor' => 'function_lower',
+    ),
+   'LPAD' => array(
+        'link' => 'string-functions',
+        'anchor' => 'function_lpad',
+    ),
+   'LTRIM' => array(
+        'link' => 'string-functions',
+        'anchor' => 'function_ltrim',
+    ),
+   'MAKE_SET' => array(
+        'link' => 'string-functions',
+        'anchor' => 'function_make_set',
+    ),
+   'MAKEDATE' => array(
+        'link' => 'date-and-time-functions',
+        'anchor' => 'function_makedate',
+    ),
+   'MAKETIME' => array(
+        'link' => 'date-and-time-functions',
+        'anchor' => 'function_maketime',
+    ),
+   'MASTER_POS_WAIT' => array(
+        'link' => 'miscellaneous-functions',
+        'anchor' => 'function_master_pos_wait',
+    ),
+   'MATCH' => array(
+        'link' => 'fulltext-search',
+        'anchor' => 'function_match',
+    ),
+   'MAX' => array(
+        'link' => 'group-by-functions',
+        'anchor' => 'function_max',
+    ),
+   'MD5' => array(
+        'link' => 'encryption-functions',
+        'anchor' => 'function_md5',
+    ),
+   'MICROSECOND' => array(
+        'link' => 'date-and-time-functions',
+        'anchor' => 'function_microsecond',
+    ),
+   'MID' => array(
+        'link' => 'string-functions',
+        'anchor' => 'function_mid',
+    ),
+   'MIN' => array(
+        'link' => 'group-by-functions',
+        'anchor' => 'function_min',
+    ),
+   'MINUTE' => array(
+        'link' => 'date-and-time-functions',
+        'anchor' => 'function_minute',
+    ),
+   'MOD' => array(
+        'link' => 'mathematical-functions',
+        'anchor' => 'function_mod',
+    ),
+   'MONTH' => array(
+        'link' => 'date-and-time-functions',
+        'anchor' => 'function_month',
+    ),
+   'MONTHNAME' => array(
+        'link' => 'date-and-time-functions',
+        'anchor' => 'function_monthname',
+    ),
+   'NAME_CONST' => array(
+        'link' => 'miscellaneous-functions',
+        'anchor' => 'function_name_const',
+    ),
+   'NOT' => array(
+        'link' => 'logical-operators',
+        'anchor' => 'operator_not',
+    ),
+   'NOW' => array(
+        'link' => 'date-and-time-functions',
+        'anchor' => 'function_now',
+    ),
+   'NULLIF' => array(
+        'link' => 'control-flow-functions',
+        'anchor' => 'function_nullif',
+    ),
+   'OCT' => array(
+        'link' => 'mathematical-functions',
+        'anchor' => 'function_oct',
+    ),
+   'OCTET_LENGTH' => array(
+        'link' => 'string-functions',
+        'anchor' => 'function_octet_length',
+    ),
+   'OLD_PASSWORD' => array(
+        'link' => 'encryption-functions',
+        'anchor' => 'function_old_password',
+    ),
+   'OR' => array(
+        'link' => 'logical-operators',
+        'anchor' => 'operator_or',
+    ),
+   'ORD' => array(
+        'link' => 'string-functions',
+        'anchor' => 'function_ord',
+    ),
+   'PASSWORD' => array(
+        'link' => 'encryption-functions',
+        'anchor' => 'function_password',
+    ),
+   'PERIOD_ADD' => array(
+        'link' => 'date-and-time-functions',
+        'anchor' => 'function_period_add',
+    ),
+   'PERIOD_DIFF' => array(
+        'link' => 'date-and-time-functions',
+        'anchor' => 'function_period_diff',
+    ),
+   'PI' => array(
+        'link' => 'mathematical-functions',
+        'anchor' => 'function_pi',
+    ),
+   'POSITION' => array(
+        'link' => 'string-functions',
+        'anchor' => 'function_position',
+    ),
+   'POW' => array(
+        'link' => 'mathematical-functions',
+        'anchor' => 'function_pow',
+    ),
+   'POWER' => array(
+        'link' => 'mathematical-functions',
+        'anchor' => 'function_power',
+    ),
+   'QUARTER' => array(
+        'link' => 'date-and-time-functions',
+        'anchor' => 'function_quarter',
+    ),
+   'QUOTE' => array(
+        'link' => 'string-functions',
+        'anchor' => 'function_quote',
+    ),
+   'RADIANS' => array(
+        'link' => 'mathematical-functions',
+        'anchor' => 'function_radians',
+    ),
+   'RAND' => array(
+        'link' => 'mathematical-functions',
+        'anchor' => 'function_rand',
+    ),
+   'REGEXP' => array(
+        'link' => 'regexp',
+        'anchor' => 'operator_regexp',
+    ),
+   'RELEASE_LOCK' => array(
+        'link' => 'miscellaneous-functions',
+        'anchor' => 'function_release_lock',
+    ),
+   'REPEAT' => array(
+        'link' => 'string-functions',
+        'anchor' => 'function_repeat',
+    ),
+   'REPLACE' => array(
+        'link' => 'string-functions',
+        'anchor' => 'function_replace',
+    ),
+   'REVERSE' => array(
+        'link' => 'string-functions',
+        'anchor' => 'function_reverse',
+    ),
+   'RIGHT' => array(
+        'link' => 'string-functions',
+        'anchor' => 'function_right',
+    ),
+   'RLIKE' => array(
+        'link' => 'regexp',
+        'anchor' => 'operator_rlike',
+    ),
+   'ROUND' => array(
+        'link' => 'mathematical-functions',
+        'anchor' => 'function_round',
+    ),
+   'ROW_COUNT' => array(
+        'link' => 'information-functions',
+        'anchor' => 'function_row_count',
+    ),
+   'RPAD' => array(
+        'link' => 'string-functions',
+        'anchor' => 'function_rpad',
+    ),
+   'RTRIM' => array(
+        'link' => 'string-functions',
+        'anchor' => 'function_rtrim',
+    ),
+   'SCHEMA' => array(
+        'link' => 'information-functions',
+        'anchor' => 'function_schema',
+    ),
+   'SEC_TO_TIME' => array(
+        'link' => 'date-and-time-functions',
+        'anchor' => 'function_sec_to_time',
+    ),
+   'SECOND' => array(
+        'link' => 'date-and-time-functions',
+        'anchor' => 'function_second',
+    ),
+   'SESSION_USER' => array(
+        'link' => 'information-functions',
+        'anchor' => 'function_session_user',
+    ),
+   'SHA' => array(
+        'link' => 'encryption-functions',
+        'anchor' => 'function_sha1',
+    ),
+   'SHA1' => array(
+        'link' => 'encryption-functions',
+        'anchor' => 'function_sha1',
+    ),
+   'SIGN' => array(
+        'link' => 'mathematical-functions',
+        'anchor' => 'function_sign',
+    ),
+   'SIN' => array(
+        'link' => 'mathematical-functions',
+        'anchor' => 'function_sin',
+    ),
+   'SLEEP' => array(
+        'link' => 'miscellaneous-functions',
+        'anchor' => 'function_sleep',
+    ),
+   'SOUNDEX' => array(
+        'link' => 'string-functions',
+        'anchor' => 'function_soundex',
+    ),
+   'SPACE' => array(
+        'link' => 'string-functions',
+        'anchor' => 'function_space',
+    ),
+   'SQRT' => array(
+        'link' => 'mathematical-functions',
+        'anchor' => 'function_sqrt',
+    ),
+   'STD' => array(
+        'link' => 'group-by-functions',
+        'anchor' => 'function_std',
+    ),
+   'STDDEV_POP' => array(
+        'link' => 'group-by-functions',
+        'anchor' => 'function_stddev_pop',
+    ),
+   'STDDEV_SAMP' => array(
+        'link' => 'group-by-functions',
+        'anchor' => 'function_stddev_samp',
+    ),
+   'STDDEV' => array(
+        'link' => 'group-by-functions',
+        'anchor' => 'function_stddev',
+    ),
+   'STR_TO_DATE' => array(
+        'link' => 'date-and-time-functions',
+        'anchor' => 'function_str_to_date',
+    ),
+   'STRCMP' => array(
+        'link' => 'string-comparison-functions',
+        'anchor' => 'function_strcmp',
+    ),
+   'SUBDATE' => array(
+        'link' => 'date-and-time-functions',
+        'anchor' => 'function_subdate',
+    ),
+   'SUBSTR' => array(
+        'link' => 'string-functions',
+        'anchor' => 'function_substr',
+    ),
+   'SUBSTRING_INDEX' => array(
+        'link' => 'string-functions',
+        'anchor' => 'function_substring_index',
+    ),
+   'SUBSTRING' => array(
+        'link' => 'string-functions',
+        'anchor' => 'function_substring',
+    ),
+   'SUBTIME' => array(
+        'link' => 'date-and-time-functions',
+        'anchor' => 'function_subtime',
+    ),
+   'SUM' => array(
+        'link' => 'group-by-functions',
+        'anchor' => 'function_sum',
+    ),
+   'SYSDATE' => array(
+        'link' => 'date-and-time-functions',
+        'anchor' => 'function_sysdate',
+    ),
+   'SYSTEM_USER' => array(
+        'link' => 'information-functions',
+        'anchor' => 'function_system_user',
+    ),
+   'TAN' => array(
+        'link' => 'mathematical-functions',
+        'anchor' => 'function_tan',
+    ),
+   'TIME_FORMAT' => array(
+        'link' => 'date-and-time-functions',
+        'anchor' => 'function_time_format',
+    ),
+   'TIME_TO_SEC' => array(
+        'link' => 'date-and-time-functions',
+        'anchor' => 'function_time_to_sec',
+    ),
+   'TIME' => array(
+        'link' => 'date-and-time-functions',
+        'anchor' => 'function_time',
+    ),
+   'TIMEDIFF' => array(
+        'link' => 'date-and-time-functions',
+        'anchor' => 'function_timediff',
+    ),
+   'TIMESTAMP' => array(
+        'link' => 'date-and-time-functions',
+        'anchor' => 'function_timestamp',
+    ),
+   'TIMESTAMPADD' => array(
+        'link' => 'date-and-time-functions',
+        'anchor' => 'function_timestampadd',
+    ),
+   'TIMESTAMPDIFF' => array(
+        'link' => 'date-and-time-functions',
+        'anchor' => 'function_timestampdiff',
+    ),
+   'TO_DAYS' => array(
+        'link' => 'date-and-time-functions',
+        'anchor' => 'function_to_days',
+    ),
+   'TRIM' => array(
+        'link' => 'string-functions',
+        'anchor' => 'function_trim',
+    ),
+   'TRUNCATE' => array(
+        'link' => 'mathematical-functions',
+        'anchor' => 'function_truncate',
+    ),
+   'UCASE' => array(
+        'link' => 'string-functions',
+        'anchor' => 'function_ucase',
+    ),
+   'UNCOMPRESS' => array(
+        'link' => 'encryption-functions',
+        'anchor' => 'function_uncompress',
+    ),
+   'UNCOMPRESSED_LENGTH' => array(
+        'link' => 'encryption-functions',
+        'anchor' => 'function_uncompressed_length',
+    ),
+   'UNHEX' => array(
+        'link' => 'string-functions',
+        'anchor' => 'function_unhex',
+    ),
+   'UNIX_TIMESTAMP' => array(
+        'link' => 'date-and-time-functions',
+        'anchor' => 'function_unix_timestamp',
+    ),
+   'UpdateXML' => array(
+        'link' => 'xml-functions',
+        'anchor' => 'function_updatexml',
+    ),
+   'UPPER' => array(
+        'link' => 'string-functions',
+        'anchor' => 'function_upper',
+    ),
+   'USER' => array(
+        'link' => 'information-functions',
+        'anchor' => 'function_user',
+    ),
+   'UTC_DATE' => array(
+        'link' => 'date-and-time-functions',
+        'anchor' => 'function_utc_date',
+    ),
+   'UTC_TIME' => array(
+        'link' => 'date-and-time-functions',
+        'anchor' => 'function_utc_time',
+    ),
+   'UTC_TIMESTAMP' => array(
+        'link' => 'date-and-time-functions',
+        'anchor' => 'function_utc_timestamp',
+    ),
+   'UUID_SHORT' => array(
+        'link' => 'miscellaneous-functions',
+        'anchor' => 'function_uuid_short',
+    ),
+   'UUID' => array(
+        'link' => 'miscellaneous-functions',
+        'anchor' => 'function_uuid',
+    ),
+   'VALUES' => array(
+        'link' => 'miscellaneous-functions',
+        'anchor' => 'function_values',
+    ),
+   'VAR_POP' => array(
+        'link' => 'group-by-functions',
+        'anchor' => 'function_var_pop',
+    ),
+   'VAR_SAMP' => array(
+        'link' => 'group-by-functions',
+        'anchor' => 'function_var_samp',
+    ),
+   'VARIANCE' => array(
+        'link' => 'group-by-functions',
+        'anchor' => 'function_variance',
+    ),
+   'VERSION' => array(
+        'link' => 'information-functions',
+        'anchor' => 'function_version',
+    ),
+   'WEEK' => array(
+        'link' => 'date-and-time-functions',
+        'anchor' => 'function_week',
+    ),
+   'WEEKDAY' => array(
+        'link' => 'date-and-time-functions',
+        'anchor' => 'function_weekday',
+    ),
+   'WEEKOFYEAR' => array(
+        'link' => 'date-and-time-functions',
+        'anchor' => 'function_weekofyear',
+    ),
+   'XOR' => array(
+        'link' => 'logical-operators',
+        'anchor' => 'operator_xor',
+    ),
+   'YEAR' => array(
+        'link' => 'date-and-time-functions',
+        'anchor' => 'function_year',
+    ),
+   'YEARWEEK' => array(
+        'link' => 'date-and-time-functions',
+        'anchor' => 'function_yearweek',
+    ),
+   'SOUNDS_LIKE' => array(
+        'link' => 'string-functions',
+        'anchor' => 'operator_sounds-like',
+    ),
+   'IS_NOT_NULL' => array(
+        'link' => 'comparison-operators',
+        'anchor' => 'operator_is-not-null',
+    ),
+   'IS_NOT' => array(
+        'link' => 'comparison-operators',
+        'anchor' => 'operator_is-not',
+    ),
+   'IS_NULL' => array(
+        'link' => 'comparison-operators',
+        'anchor' => 'operator_is-null',
+    ),
+   'NOT_LIKE' => array(
+        'link' => 'string-comparison-functions',
+        'anchor' => 'operator_not-like',
+    ),
+   'NOT_REGEXP' => array(
+        'link' => 'regexp',
+        'anchor' => 'operator_not-regexp',
+    ),
+   'COUNT_DISTINCT' => array(
+        'link' => 'group-by-functions',
+        'anchor' => 'function_count-distinct',
+    ),
+   'NOT_IN' => array(
+        'link' => 'comparison-operators',
+        'anchor' => 'function_not-in',
+    )
+);
+
+?>
diff --git a/phpmyadmin/libraries/sqlparser.lib.php b/phpmyadmin/libraries/sqlparser.lib.php
new file mode 100644
index 0000000..0f1caa0
--- /dev/null
+++ b/phpmyadmin/libraries/sqlparser.lib.php
@@ -0,0 +1,2906 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/** SQL Parser Functions for phpMyAdmin
+ *
+ * These functions define an SQL parser system, capable of understanding and
+ * extracting data from a MySQL type SQL query.
+ *
+ * The basic procedure for using the new SQL parser:
+ * On any page that needs to extract data from a query or to pretty-print a
+ * query, you need code like this up at the top:
+ *
+ * ($sql contains the query)
+ * $parsed_sql = PMA_SQP_parse($sql);
+ *
+ * If you want to extract data from it then, you just need to run
+ * $sql_info = PMA_SQP_analyze($parsed_sql);
+ *
+ * See comments in PMA_SQP_analyze for the returned info
+ * from the analyzer.
+ *
+ * If you want a pretty-printed version of the query, do:
+ * $string = PMA_SQP_formatHtml($parsed_sql);
+ * (note that that you need to have syntax.css.php included somehow in your
+ * page for it to work, I recommend '<link rel="stylesheet" type="text/css"
+ * href="syntax.css.php" />' at the moment.)
+ *
+ * @package PhpMyAdmin
+ */
+if (! defined('PHPMYADMIN')) {
+    exit;
+}
+
+/**
+ * Include the string library as we use it heavily
+ */
+require_once './libraries/string.lib.php';
+
+/**
+ * Include data for the SQL Parser
+ */
+require_once './libraries/sqlparser.data.php';
+
+/**
+ * Charset information
+ */
+if (!defined('TESTSUITE')) {
+    include_once './libraries/mysql_charsets.lib.php';
+}
+if (! isset($mysql_charsets)) {
+    $mysql_charsets = array();
+    $mysql_collations_flat = array();
+}
+
+/**
+ * Stores parsed elemented of query to array.
+ *
+ * Currently we don't need the $pos (token position in query)
+ * for other purposes than LIMIT clause verification,
+ * so many calls to this function do not include the 4th parameter
+ *
+ * @param array  &$arr     Array to store element
+ * @param string $type     Type of element
+ * @param string $data     Data (text) of element
+ * @param int    &$arrsize Size of array
+ * @param int    $pos      Position of an element
+ *
+ * @return nothing
+ */
+function PMA_SQP_arrayAdd(&$arr, $type, $data, &$arrsize, $pos = 0)
+{
+    $arr[] = array('type' => $type, 'data' => $data, 'pos' => $pos);
+    $arrsize++;
+} // end of the "PMA_SQP_arrayAdd()" function
+
+/**
+ * Reset the error variable for the SQL parser
+ *
+ * @access public
+ *
+ * @return nothing
+ */
+function PMA_SQP_resetError()
+{
+    global $SQP_errorString;
+    $SQP_errorString = '';
+    unset($SQP_errorString);
+}
+
+/**
+ * Get the contents of the error variable for the SQL parser
+ *
+ * @return string Error string from SQL parser
+ *
+ * @access public
+ */
+function PMA_SQP_getErrorString()
+{
+    global $SQP_errorString;
+    return isset($SQP_errorString) ? $SQP_errorString : '';
+}
+
+/**
+ * Check if the SQL parser hit an error
+ *
+ * @return boolean error state
+ *
+ * @access public
+ */
+function PMA_SQP_isError()
+{
+    global $SQP_errorString;
+    return isset($SQP_errorString) && !empty($SQP_errorString);
+}
+
+/**
+ * Set an error message for the system
+ *
+ * @param string $message The error message
+ * @param string $sql     The failing SQL query
+ *
+ * @return nothing
+ *
+ * @access private
+ * @scope SQL Parser internal
+ */
+function PMA_SQP_throwError($message, $sql)
+{
+    global $SQP_errorString;
+    $SQP_errorString = '<p>'.__('There seems to be an error in your SQL query. The MySQL server error output below, if there is any, may also help you in diagnosing the problem') . '</p>' . "\n"
+        . '<pre>' . "\n"
+        . 'ERROR: ' . $message . "\n"
+        . 'SQL: ' . htmlspecialchars($sql) .  "\n"
+        . '</pre>' . "\n";
+
+} // end of the "PMA_SQP_throwError()" function
+
+
+/**
+ * Do display the bug report
+ *
+ * @param string $message The error message
+ * @param string $sql     The failing SQL query
+ *
+ * @return nothing
+ *
+ * @access public
+ */
+function PMA_SQP_bug($message, $sql)
+{
+    global $SQP_errorString;
+    $debugstr = 'ERROR: ' . $message . "\n";
+    $debugstr .= 'MySQL: '.PMA_MYSQL_STR_VERSION . "\n";
+    $debugstr .= 'USR OS, AGENT, VER: ' . PMA_USR_OS . ' ';
+    $debugstr .= PMA_USR_BROWSER_AGENT . ' ' . PMA_USR_BROWSER_VER . "\n";
+    $debugstr .= 'PMA: ' . PMA_VERSION . "\n";
+    $debugstr .= 'PHP VER,OS: ' . PMA_PHP_STR_VERSION . ' ' . PHP_OS . "\n";
+    $debugstr .= 'LANG: ' . $GLOBALS['lang'] . "\n";
+    $debugstr .= 'SQL: ' . htmlspecialchars($sql);
+
+    $encodedstr     = $debugstr;
+    if (@function_exists('gzcompress')) {
+        $encodedstr = gzcompress($debugstr, 9);
+    }
+    $encodedstr     = preg_replace(
+        "/(\015\012)|(\015)|(\012)/",
+        '<br />' . "\n",
+        chunk_split(base64_encode($encodedstr))
+    );
+
+
+    $SQP_errorString .= __('There is a chance that you may have found a bug in the SQL parser. Please examine your query closely, and check that the quotes are correct and not mis-matched. Other possible failure causes may be that you are uploading a file with binary outside of a quoted text area. You can also try your query on the MySQL command line interface. The MySQL server error output below, if there is any, may also help you in diagnosing the problem. If you still have problems or [...]
+         . '<br />' . "\n"
+         . '----' . __('BEGIN CUT') . '----' . '<br />' . "\n"
+         . $encodedstr . "\n"
+         . '----' . __('END CUT') . '----' . '<br />' . "\n";
+
+    $SQP_errorString .= '----' . __('BEGIN RAW') . '----<br />' . "\n"
+         . '<pre>' . "\n"
+         . $debugstr
+         . '</pre>' . "\n"
+         . '----' . __('END RAW') . '----<br />' . "\n";
+
+} // end of the "PMA_SQP_bug()" function
+
+
+/**
+ * Parses the SQL queries
+ *
+ * @param string $sql The SQL query list
+ *
+ * @return mixed Most of times, nothing...
+ *
+ * @global array    The current PMA configuration
+ * @global array    MySQL column attributes
+ * @global array    MySQL reserved words
+ * @global array    MySQL column types
+ * @global array    MySQL function names
+ * @global array    List of available character sets
+ * @global array    List of available collations
+ *
+ * @access public
+ */
+function PMA_SQP_parse($sql)
+{
+    static $PMA_SQPdata_column_attrib, $PMA_SQPdata_reserved_word;
+    static $PMA_SQPdata_column_type;
+    static $PMA_SQPdata_function_name, $PMA_SQPdata_forbidden_word;
+    global $mysql_charsets, $mysql_collations_flat;
+
+    // Convert all line feeds to Unix style
+    $sql = str_replace("\r\n", "\n", $sql);
+    $sql = str_replace("\r", "\n", $sql);
+
+    $len = PMA_strlen($sql);
+    if ($len == 0) {
+        return array();
+    }
+
+    // Create local hashtables
+    if (!isset($PMA_SQPdata_column_attrib)) {
+        $PMA_SQPdata_column_attrib  = array_flip(
+            $GLOBALS['PMA_SQPdata_column_attrib']
+        );
+        $PMA_SQPdata_function_name  = array_flip(
+            $GLOBALS['PMA_SQPdata_function_name']
+        );
+        $PMA_SQPdata_reserved_word  = array_flip(
+            $GLOBALS['PMA_SQPdata_reserved_word']
+        );
+        $PMA_SQPdata_forbidden_word = array_flip(
+            $GLOBALS['PMA_SQPdata_forbidden_word']
+        );
+        $PMA_SQPdata_column_type    = array_flip(
+            $GLOBALS['PMA_SQPdata_column_type']
+        );
+    }
+
+    $sql_array               = array();
+    $sql_array['raw']        = $sql;
+    $count1                  = 0;
+    $count2                  = 0;
+    $punct_queryend          = ';';
+    $punct_qualifier         = '.';
+    $punct_listsep           = ',';
+    $punct_level_plus        = '(';
+    $punct_level_minus       = ')';
+    $punct_user              = '@';
+    $digit_floatdecimal      = '.';
+    $digit_hexset            = 'x';
+    $bracket_list            = '()[]{}';
+    $allpunct_list           =  '-,;:!?/.^~\*&%+<=>|';
+    $allpunct_list_pair      = array(
+        '!=' => 1,
+        '&&' => 1,
+        ':=' => 1,
+        '<<' => 1,
+        '<=' => 1,
+        '<=>' => 1,
+        '<>' => 1,
+        '>=' => 1,
+        '>>' => 1,
+        '||' => 1,
+        '==' => 1
+    );
+    $quote_list              = '\'"`';
+    $arraysize               = 0;
+
+    $previous_was_space   = false;
+    $this_was_space       = false;
+    $previous_was_bracket = false;
+    $this_was_bracket     = false;
+    $previous_was_punct   = false;
+    $this_was_punct       = false;
+    $previous_was_listsep = false;
+    $this_was_listsep     = false;
+    $previous_was_quote   = false;
+    $this_was_quote       = false;
+
+    while ($count2 < $len) {
+        $c      = PMA_substr($sql, $count2, 1);
+        $count1 = $count2;
+
+        $previous_was_space = $this_was_space;
+        $this_was_space = false;
+        $previous_was_bracket = $this_was_bracket;
+        $this_was_bracket = false;
+        $previous_was_punct = $this_was_punct;
+        $this_was_punct = false;
+        $previous_was_listsep = $this_was_listsep;
+        $this_was_listsep = false;
+        $previous_was_quote = $this_was_quote;
+        $this_was_quote = false;
+
+        if (($c == "\n")) {
+            $this_was_space = true;
+            $count2++;
+            PMA_SQP_arrayAdd($sql_array, 'white_newline', '', $arraysize);
+            continue;
+        }
+
+        // Checks for white space
+        if (PMA_STR_isSpace($c)) {
+            $this_was_space = true;
+            $count2++;
+            continue;
+        }
+
+        // Checks for comment lines.
+        // MySQL style #
+        // C style /* */
+        // ANSI style --
+        $next_c = PMA_substr($sql, $count2 + 1, 1);
+        if (($c == '#')
+            || (($count2 + 1 < $len) && ($c == '/') && ($next_c == '*'))
+            || (($count2 + 2 == $len) && ($c == '-') && ($next_c == '-'))
+            || (($count2 + 2 < $len) && ($c == '-') && ($next_c == '-') && ((PMA_substr($sql, $count2 + 2, 1) <= ' ')))
+        ) {
+            $count2++;
+            $pos  = 0;
+            $type = 'bad';
+            switch ($c) {
+            case '#':
+                $type = 'mysql';
+            case '-':
+                $type = 'ansi';
+                $pos  = PMA_strpos($sql, "\n", $count2);
+                break;
+            case '/':
+                $type = 'c';
+                $pos  = PMA_strpos($sql, '*/', $count2);
+                $pos  += 2;
+                break;
+            default:
+                break;
+            } // end switch
+            $count2 = ($pos < $count2) ? $len : $pos;
+            $str    = PMA_substr($sql, $count1, $count2 - $count1);
+            PMA_SQP_arrayAdd($sql_array, 'comment_' . $type, $str, $arraysize);
+            continue;
+        } // end if
+
+        // Checks for something inside quotation marks
+        if (PMA_strpos($quote_list, $c) !== false) {
+            $startquotepos   = $count2;
+            $quotetype       = $c;
+            $count2++;
+            $pos             = $count2;
+            $oldpos          = 0;
+            do {
+                $oldpos = $pos;
+                $pos    = PMA_strpos(' ' . $sql, $quotetype, $oldpos + 1) - 1;
+                // ($pos === false)
+                if ($pos < 0) {
+                    if ($c == '`') {
+                        /*
+                         * Behave same as MySQL and accept end of query as end of backtick.
+                         * I know this is sick, but MySQL behaves like this:
+                         *
+                         * SELECT * FROM `table
+                         *
+                         * is treated like
+                         *
+                         * SELECT * FROM `table`
+                         */
+                        $pos_quote_separator = PMA_strpos(' ' . $sql, $GLOBALS['sql_delimiter'], $oldpos + 1) - 1;
+                        if ($pos_quote_separator < 0) {
+                            $len += 1;
+                            $sql .= '`';
+                            $sql_array['raw'] .= '`';
+                            $pos = $len;
+                        } else {
+                            $len += 1;
+                            $sql = PMA_substr($sql, 0, $pos_quote_separator) . '`' . PMA_substr($sql, $pos_quote_separator);
+                            $sql_array['raw'] = $sql;
+                            $pos = $pos_quote_separator;
+                        }
+                        if (class_exists('PMA_Message') && $GLOBALS['is_ajax_request'] != true) {
+                            PMA_Message::notice(__('Automatically appended backtick to the end of query!'))->display();
+                        }
+                    } else {
+                        $debugstr = __('Unclosed quote') . ' @ ' . $startquotepos. "\n"
+                                  . 'STR: ' . htmlspecialchars($quotetype);
+                        PMA_SQP_throwError($debugstr, $sql);
+                        return $sql_array;
+                    }
+                }
+
+                // If the quote is the first character, it can't be
+                // escaped, so don't do the rest of the code
+                if ($pos == 0) {
+                    break;
+                }
+
+                // Checks for MySQL escaping using a \
+                // And checks for ANSI escaping using the $quotetype character
+                if (($pos < $len) && PMA_STR_charIsEscaped($sql, $pos) && $c != '`') {
+                    $pos ++;
+                    continue;
+                } elseif (($pos + 1 < $len) && (PMA_substr($sql, $pos, 1) == $quotetype) && (PMA_substr($sql, $pos + 1, 1) == $quotetype)) {
+                    $pos = $pos + 2;
+                    continue;
+                } else {
+                    break;
+                }
+            } while ($len > $pos); // end do
+
+            $count2       = $pos;
+            $count2++;
+            $type         = 'quote_';
+            switch ($quotetype) {
+            case '\'':
+                $type .= 'single';
+                $this_was_quote = true;
+                break;
+            case '"':
+                $type .= 'double';
+                $this_was_quote = true;
+                break;
+            case '`':
+                $type .= 'backtick';
+                $this_was_quote = true;
+                break;
+            default:
+                break;
+            } // end switch
+            $data = PMA_substr($sql, $count1, $count2 - $count1);
+            PMA_SQP_arrayAdd($sql_array, $type, $data, $arraysize);
+            continue;
+        }
+
+        // Checks for brackets
+        if (PMA_strpos($bracket_list, $c) !== false) {
+            // All bracket tokens are only one item long
+            $this_was_bracket = true;
+            $count2++;
+            $type_type     = '';
+            if (PMA_strpos('([{', $c) !== false) {
+                $type_type = 'open';
+            } else {
+                $type_type = 'close';
+            }
+
+            $type_style     = '';
+            if (PMA_strpos('()', $c) !== false) {
+                $type_style = 'round';
+            } elseif (PMA_strpos('[]', $c) !== false) {
+                $type_style = 'square';
+            } else {
+                $type_style = 'curly';
+            }
+
+            $type = 'punct_bracket_' . $type_type . '_' . $type_style;
+            PMA_SQP_arrayAdd($sql_array, $type, $c, $arraysize);
+            continue;
+        }
+
+        /* DEBUG
+        echo '<pre>1';
+        var_dump(PMA_STR_isSqlIdentifier($c, false));
+        var_dump($c == '@');
+        var_dump($c == '.');
+        var_dump(PMA_STR_isDigit(PMA_substr($sql, $count2 + 1, 1)));
+        var_dump($previous_was_space);
+        var_dump($previous_was_bracket);
+        var_dump($previous_was_listsep);
+        echo '</pre>';
+        */
+
+        // Checks for identifier (alpha or numeric)
+        if (PMA_STR_isSqlIdentifier($c, false)
+            || $c == '@'
+            || ($c == '.'
+            && PMA_STR_isDigit(PMA_substr($sql, $count2 + 1, 1))
+            && ($previous_was_space || $previous_was_bracket || $previous_was_listsep))
+        ) {
+            /* DEBUG
+            echo PMA_substr($sql, $count2);
+            echo '<hr />';
+            */
+
+            $count2++;
+
+            /**
+             * @todo a @ can also be present in expressions like
+             * FROM 'user'@'%' or  TO 'user'@'%'
+             * in this case, the @ is wrongly marked as alpha_variable
+             */
+            $is_identifier           = $previous_was_punct;
+            $is_sql_variable         = $c == '@' && ! $previous_was_quote;
+            $is_user                 = $c == '@' && $previous_was_quote;
+            $is_digit                = !$is_identifier && !$is_sql_variable && PMA_STR_isDigit($c);
+            $is_hex_digit            = $is_digit && $c == '0' && $count2 < $len && PMA_substr($sql, $count2, 1) == 'x';
+            $is_float_digit          = $c == '.';
+            $is_float_digit_exponent = false;
+
+            /* DEBUG
+            echo '<pre>2';
+            var_dump($is_identifier);
+            var_dump($is_sql_variable);
+            var_dump($is_digit);
+            var_dump($is_float_digit);
+            echo '</pre>';
+             */
+
+            // Fast skip is especially needed for huge BLOB data
+            if ($is_hex_digit) {
+                $count2++;
+                $pos = strspn($sql, '0123456789abcdefABCDEF', $count2);
+                if ($pos > $count2) {
+                    $count2 = $pos;
+                }
+                unset($pos);
+            } elseif ($is_digit) {
+                $pos = strspn($sql, '0123456789', $count2);
+                if ($pos > $count2) {
+                    $count2 = $pos;
+                }
+                unset($pos);
+            }
+
+            while (($count2 < $len) && PMA_STR_isSqlIdentifier(PMA_substr($sql, $count2, 1), ($is_sql_variable || $is_digit))) {
+                $c2 = PMA_substr($sql, $count2, 1);
+                if ($is_sql_variable && ($c2 == '.')) {
+                    $count2++;
+                    continue;
+                }
+                if ($is_digit && (!$is_hex_digit) && ($c2 == '.')) {
+                    $count2++;
+                    if (!$is_float_digit) {
+                        $is_float_digit = true;
+                        continue;
+                    } else {
+                        $debugstr = __('Invalid Identifer') . ' @ ' . ($count1+1) . "\n"
+                                  . 'STR: ' . htmlspecialchars(PMA_substr($sql, $count1, $count2 - $count1));
+                        PMA_SQP_throwError($debugstr, $sql);
+                        return $sql_array;
+                    }
+                }
+                if ($is_digit && (!$is_hex_digit) && (($c2 == 'e') || ($c2 == 'E'))) {
+                    if (!$is_float_digit_exponent) {
+                        $is_float_digit_exponent = true;
+                        $is_float_digit          = true;
+                        $count2++;
+                        continue;
+                    } else {
+                        $is_digit                = false;
+                        $is_float_digit          = false;
+                    }
+                }
+                if (($is_hex_digit && PMA_STR_isHexDigit($c2)) || ($is_digit && PMA_STR_isDigit($c2))) {
+                    $count2++;
+                    continue;
+                } else {
+                    $is_digit     = false;
+                    $is_hex_digit = false;
+                }
+
+                $count2++;
+            } // end while
+
+            $l    = $count2 - $count1;
+            $str  = PMA_substr($sql, $count1, $l);
+
+            $type = '';
+            if ($is_digit || $is_float_digit || $is_hex_digit) {
+                $type     = 'digit';
+                if ($is_float_digit) {
+                    $type .= '_float';
+                } elseif ($is_hex_digit) {
+                    $type .= '_hex';
+                } else {
+                    $type .= '_integer';
+                }
+            } elseif ($is_user) {
+                $type = 'punct_user';
+            } elseif ($is_sql_variable != false) {
+                $type = 'alpha_variable';
+            } else {
+                $type = 'alpha';
+            } // end if... else....
+            PMA_SQP_arrayAdd($sql_array, $type, $str, $arraysize, $count2);
+
+            continue;
+        }
+
+        // Checks for punct
+        if (PMA_strpos($allpunct_list, $c) !== false) {
+            while (($count2 < $len) && PMA_strpos($allpunct_list, PMA_substr($sql, $count2, 1)) !== false) {
+                $count2++;
+            }
+            $l = $count2 - $count1;
+            if ($l == 1) {
+                $punct_data = $c;
+            } else {
+                $punct_data = PMA_substr($sql, $count1, $l);
+            }
+
+            // Special case, sometimes, althought two characters are
+            // adjectent directly, they ACTUALLY need to be seperate
+            /* DEBUG
+            echo '<pre>';
+            var_dump($l);
+            var_dump($punct_data);
+            echo '</pre>';
+            */
+
+            if ($l == 1) {
+                $t_suffix         = '';
+                switch ($punct_data) {
+                case $punct_queryend:
+                    $t_suffix = '_queryend';
+                    break;
+                case $punct_qualifier:
+                    $t_suffix = '_qualifier';
+                    $this_was_punct = true;
+                    break;
+                case $punct_listsep:
+                    $this_was_listsep = true;
+                    $t_suffix = '_listsep';
+                    break;
+                default:
+                    break;
+                }
+                PMA_SQP_arrayAdd($sql_array, 'punct' . $t_suffix, $punct_data, $arraysize);
+            } elseif ($punct_data == $GLOBALS['sql_delimiter'] || isset($allpunct_list_pair[$punct_data])) {
+                // Ok, we have one of the valid combined punct expressions
+                PMA_SQP_arrayAdd($sql_array, 'punct', $punct_data, $arraysize);
+            } else {
+                // Bad luck, lets split it up more
+                $first  = $punct_data[0];
+                $last2  = $punct_data[$l - 2] . $punct_data[$l - 1];
+                $last   = $punct_data[$l - 1];
+                if (($first == ',') || ($first == ';') || ($first == '.') || ($first == '*')) {
+                    $count2     = $count1 + 1;
+                    $punct_data = $first;
+                } elseif (($last2 == '/*') || (($last2 == '--') && ($count2 == $len || PMA_substr($sql, $count2, 1) <= ' '))) {
+                    $count2     -= 2;
+                    $punct_data = PMA_substr($sql, $count1, $count2 - $count1);
+                } elseif (($last == '-') || ($last == '+') || ($last == '!')) {
+                    $count2--;
+                    $punct_data = PMA_substr($sql, $count1, $count2 - $count1);
+                } elseif ($last != '~') {
+                    /**
+                     * @todo for negation operator, split in 2 tokens ?
+                     * "select x&~1 from t"
+                     * becomes "select x & ~ 1 from t" ?
+                     */
+                    $debugstr =  __('Unknown Punctuation String') . ' @ ' . ($count1+1) . "\n"
+                              . 'STR: ' . htmlspecialchars($punct_data);
+                    PMA_SQP_throwError($debugstr, $sql);
+                    return $sql_array;
+                }
+                PMA_SQP_arrayAdd($sql_array, 'punct', $punct_data, $arraysize);
+                continue;
+            } // end if... elseif... else
+            continue;
+        }
+
+        // DEBUG
+        $count2++;
+
+        $debugstr = 'C1 C2 LEN: ' . $count1 . ' ' . $count2 . ' ' . $len .  "\n"
+                  . 'STR: ' . PMA_substr($sql, $count1, $count2 - $count1) . "\n";
+        PMA_SQP_bug($debugstr, $sql);
+        return $sql_array;
+
+    } // end while ($count2 < $len)
+
+    /*
+    echo '<pre>';
+    print_r($sql_array);
+    echo '</pre>';
+    */
+
+    if ($arraysize > 0) {
+        $t_next           = $sql_array[0]['type'];
+        $t_prev           = '';
+        $t_bef_prev       = '';
+        $t_cur            = '';
+        $d_next           = $sql_array[0]['data'];
+        $d_prev           = '';
+        $d_bef_prev       = '';
+        $d_cur            = '';
+        $d_next_upper     = $t_next == 'alpha' ? strtoupper($d_next) : $d_next;
+        $d_prev_upper     = '';
+        $d_bef_prev_upper = '';
+        $d_cur_upper      = '';
+    }
+
+    for ($i = 0; $i < $arraysize; $i++) {
+        $t_bef_prev       = $t_prev;
+        $t_prev           = $t_cur;
+        $t_cur            = $t_next;
+        $d_bef_prev       = $d_prev;
+        $d_prev           = $d_cur;
+        $d_cur            = $d_next;
+        $d_bef_prev_upper = $d_prev_upper;
+        $d_prev_upper     = $d_cur_upper;
+        $d_cur_upper      = $d_next_upper;
+        if (($i + 1) < $arraysize) {
+            $t_next = $sql_array[$i + 1]['type'];
+            $d_next = $sql_array[$i + 1]['data'];
+            $d_next_upper = $t_next == 'alpha' ? strtoupper($d_next) : $d_next;
+        } else {
+            $t_next       = '';
+            $d_next       = '';
+            $d_next_upper = '';
+        }
+
+        //DEBUG echo "[prev: <strong>".$d_prev."</strong> ".$t_prev."][cur: <strong>".$d_cur."</strong> ".$t_cur."][next: <strong>".$d_next."</strong> ".$t_next."]<br />";
+
+        if ($t_cur == 'alpha') {
+            $t_suffix     = '_identifier';
+            // for example: `thebit` bit(8) NOT NULL DEFAULT b'0'
+            if ($t_prev == 'alpha' && $d_prev == 'DEFAULT' && $d_cur == 'b' && $t_next == 'quote_single') {
+                $t_suffix = '_bitfield_constant_introducer';
+            } elseif (($t_next == 'punct_qualifier') || ($t_prev == 'punct_qualifier')) {
+                $t_suffix = '_identifier';
+            } elseif (($t_next == 'punct_bracket_open_round')
+              && isset($PMA_SQPdata_function_name[$d_cur_upper])) {
+                /**
+                 * @todo 2005-10-16: in the case of a CREATE TABLE containing
+                 * a TIMESTAMP, since TIMESTAMP() is also a function, it's
+                 * found here and the token is wrongly marked as alpha_functionName.
+                 * But we compensate for this when analysing for timestamp_not_null
+                 * later in this script.
+                 *
+                 * Same applies to CHAR vs. CHAR() function.
+                 */
+                $t_suffix = '_functionName';
+                /* There are functions which might be as well column types */
+            } elseif (isset($PMA_SQPdata_column_type[$d_cur_upper])) {
+                $t_suffix = '_columnType';
+
+                /**
+                 * Temporary fix for bugs #621357 and #2027720
+                 *
+                 * @todo FIX PROPERLY NEEDS OVERHAUL OF SQL TOKENIZER
+                 */
+                if (($d_cur_upper == 'SET' || $d_cur_upper == 'BINARY') && $t_next != 'punct_bracket_open_round') {
+                    $t_suffix = '_reservedWord';
+                }
+                //END OF TEMPORARY FIX
+
+                // CHARACTER is a synonym for CHAR, but can also be meant as
+                // CHARACTER SET. In this case, we have a reserved word.
+                if ($d_cur_upper == 'CHARACTER' && $d_next_upper == 'SET') {
+                    $t_suffix = '_reservedWord';
+                }
+
+                // experimental
+                // current is a column type, so previous must not be
+                // a reserved word but an identifier
+                // CREATE TABLE SG_Persons (first varchar(64))
+
+                //if ($sql_array[$i-1]['type'] =='alpha_reservedWord') {
+                //    $sql_array[$i-1]['type'] = 'alpha_identifier';
+                //}
+
+            } elseif (isset($PMA_SQPdata_reserved_word[$d_cur_upper])) {
+                $t_suffix = '_reservedWord';
+            } elseif (isset($PMA_SQPdata_column_attrib[$d_cur_upper])) {
+                $t_suffix = '_columnAttrib';
+                // INNODB is a MySQL table type, but in "SHOW INNODB STATUS",
+                // it should be regarded as a reserved word.
+                if ($d_cur_upper == 'INNODB'
+                    && $d_prev_upper == 'SHOW'
+                    && $d_next_upper == 'STATUS'
+                ) {
+                    $t_suffix = '_reservedWord';
+                }
+
+                if ($d_cur_upper == 'DEFAULT' && $d_next_upper == 'CHARACTER') {
+                    $t_suffix = '_reservedWord';
+                }
+                // Binary as character set
+                if ($d_cur_upper == 'BINARY'
+                    && (($d_bef_prev_upper == 'CHARACTER' && $d_prev_upper == 'SET')
+                    || ($d_bef_prev_upper == 'SET' && $d_prev_upper == '=')
+                    || ($d_bef_prev_upper == 'CHARSET' && $d_prev_upper == '=')
+                    || $d_prev_upper == 'CHARSET')
+                    && in_array($d_cur, $mysql_charsets)
+                ) {
+                    $t_suffix = '_charset';
+                }
+            } elseif (in_array($d_cur, $mysql_charsets)
+              || in_array($d_cur, $mysql_collations_flat)
+              || ($d_cur{0} == '_' && in_array(substr($d_cur, 1), $mysql_charsets))) {
+                $t_suffix = '_charset';
+            } else {
+                // Do nothing
+            }
+            // check if present in the list of forbidden words
+            if ($t_suffix == '_reservedWord'
+                && isset($PMA_SQPdata_forbidden_word[$d_cur_upper])
+            ) {
+                $sql_array[$i]['forbidden'] = true;
+            } else {
+                $sql_array[$i]['forbidden'] = false;
+            }
+            $sql_array[$i]['type'] .= $t_suffix;
+        }
+    } // end for
+
+    // Stores the size of the array inside the array, as count() is a slow
+    // operation.
+    $sql_array['len'] = $arraysize;
+
+    // DEBUG echo 'After parsing<pre>'; print_r($sql_array); echo '</pre>';
+    // Sends the data back
+    return $sql_array;
+} // end of the "PMA_SQP_parse()" function
+
+/**
+ * Checks for token types being what we want...
+ *
+ * @param string $toCheck    String of type that we have
+ * @param string $whatWeWant String of type that we want
+ *
+ * @return boolean result of check
+ *
+ * @access private
+ */
+function PMA_SQP_typeCheck($toCheck, $whatWeWant)
+{
+    $typeSeparator = '_';
+    if (strcmp($whatWeWant, $toCheck) == 0) {
+        return true;
+    } else {
+        if (strpos($whatWeWant, $typeSeparator) === false) {
+            return strncmp(
+                $whatWeWant, $toCheck,
+                strpos($toCheck, $typeSeparator)
+            ) == 0;
+        } else {
+            return false;
+        }
+    }
+}
+
+
+/**
+ * Analyzes SQL queries
+ *
+ * @param array $arr The SQL queries
+ *
+ * @return array   The analyzed SQL queries
+ *
+ * @access public
+ */
+function PMA_SQP_analyze($arr)
+{
+    if ($arr == array() || ! isset($arr['len'])) {
+        return array();
+    }
+    $result          = array();
+    $size            = $arr['len'];
+    $subresult       = array(
+        'querytype'      => '',
+        'select_expr_clause'=> '', // the whole stuff between SELECT and FROM , except DISTINCT
+        'position_of_first_select' => '', // the array index
+        'from_clause'=> '',
+        'group_by_clause'=> '',
+        'order_by_clause'=> '',
+        'having_clause'  => '',
+        'limit_clause'  => '',
+        'where_clause'   => '',
+        'where_clause_identifiers'   => array(),
+        'unsorted_query' => '',
+        'queryflags'     => array(),
+        'select_expr'    => array(),
+        'table_ref'      => array(),
+        'foreign_keys'   => array(),
+        'create_table_fields' => array()
+    );
+    $subresult_empty = $subresult;
+    $seek_queryend         = false;
+    $seen_end_of_table_ref = false;
+    $number_of_brackets_in_extract = 0;
+    $number_of_brackets_in_group_concat = 0;
+
+    $number_of_brackets = 0;
+    $in_subquery = false;
+    $seen_subquery = false;
+    $seen_from = false;
+
+    // for SELECT EXTRACT(YEAR_MONTH FROM CURDATE())
+    // we must not use CURDATE as a table_ref
+    // so we track whether we are in the EXTRACT()
+    $in_extract          = false;
+
+    // for GROUP_CONCAT(...)
+    $in_group_concat     = false;
+
+    /* Description of analyzer results
+     *
+     * db, table, column, alias
+     * ------------------------
+     *
+     * Inside the $subresult array, we create ['select_expr'] and ['table_ref']
+     * arrays.
+     *
+     * The SELECT syntax (simplified) is
+     *
+     * SELECT
+     *    select_expression,...
+     *    [FROM [table_references]
+     *
+     *
+     * ['select_expr'] is filled with each expression, the key represents the
+     * expression position in the list (0-based) (so we don't lose track of
+     * multiple occurences of the same column).
+     *
+     * ['table_ref'] is filled with each table ref, same thing for the key.
+     *
+     * I create all sub-values empty, even if they are
+     * not present (for example no select_expression alias).
+     *
+     * There is a debug section at the end of loop #1, if you want to
+     * see the exact contents of select_expr and table_ref
+     *
+     * queryflags
+     * ----------
+     *
+     * In $subresult, array 'queryflags' is filled, according to what we
+     * find in the query.
+     *
+     * Currently, those are generated:
+     *
+     * ['queryflags']['need_confirm'] = 1; if the query needs confirmation
+     * ['queryflags']['select_from'] = 1;  if this is a real SELECT...FROM
+     * ['queryflags']['distinct'] = 1;     for a DISTINCT
+     * ['queryflags']['union'] = 1;        for a UNION
+     * ['queryflags']['join'] = 1;         for a JOIN
+     * ['queryflags']['offset'] = 1;       for the presence of OFFSET
+     * ['queryflags']['procedure'] = 1;    for the presence of PROCEDURE
+     *
+     * query clauses
+     * -------------
+     *
+     * The select is splitted in those clauses:
+     * ['select_expr_clause']
+     * ['from_clause']
+     * ['group_by_clause']
+     * ['order_by_clause']
+     * ['having_clause']
+     * ['limit_clause']
+     * ['where_clause']
+     *
+     * The identifiers of the WHERE clause are put into the array
+     * ['where_clause_identifier']
+     *
+     * For a SELECT, the whole query without the ORDER BY clause is put into
+     * ['unsorted_query']
+     *
+     * foreign keys
+     * ------------
+     * The CREATE TABLE may contain FOREIGN KEY clauses, so they get
+     * analyzed and ['foreign_keys'] is an array filled with
+     * the constraint name, the index list,
+     * the REFERENCES table name and REFERENCES index list,
+     * and ON UPDATE | ON DELETE clauses
+     *
+     * position_of_first_select
+     * ------------------------
+     *
+     * The array index of the first SELECT we find. Will be used to
+     * insert a SQL_CALC_FOUND_ROWS.
+     *
+     * create_table_fields
+     * -------------------
+     *
+     * Used to detect the DEFAULT CURRENT_TIMESTAMP and
+     * ON UPDATE CURRENT_TIMESTAMP clauses of the CREATE TABLE query.
+     * Also used to store the default value of the field.
+     * An array, each element is the identifier name.
+     * Note that for now, the timestamp_not_null element is created
+     * even for non-TIMESTAMP fields.
+     *
+     * Sub-elements: ['type'] which contains the column type
+     *               optional (currently they are never false but can be absent):
+     *               ['default_current_timestamp'] boolean
+     *               ['on_update_current_timestamp'] boolean
+     *               ['timestamp_not_null'] boolean
+     *
+     * section_before_limit, section_after_limit
+     * -----------------------------------------
+     *
+     * Marks the point of the query where we can insert a LIMIT clause;
+     * so the section_before_limit will contain the left part before
+     * a possible LIMIT clause
+     *
+     *
+     * End of description of analyzer results
+     */
+
+    // must be sorted
+    // TODO: current logic checks for only one word, so I put only the
+    // first word of the reserved expressions that end a table ref;
+    // maybe this is not ok (the first word might mean something else)
+    //        $words_ending_table_ref = array(
+    //            'FOR UPDATE',
+    //            'GROUP BY',
+    //            'HAVING',
+    //            'LIMIT',
+    //            'LOCK IN SHARE MODE',
+    //            'ORDER BY',
+    //            'PROCEDURE',
+    //            'UNION',
+    //            'WHERE'
+    //        );
+    $words_ending_table_ref = array(
+        'FOR' => 1,
+        'GROUP' => 1,
+        'HAVING' => 1,
+        'LIMIT' => 1,
+        'LOCK' => 1,
+        'ORDER' => 1,
+        'PROCEDURE' => 1,
+        'UNION' => 1,
+        'WHERE' => 1
+    );
+
+    $words_ending_clauses = array(
+        'FOR' => 1,
+        'LIMIT' => 1,
+        'LOCK' => 1,
+        'PROCEDURE' => 1,
+        'UNION' => 1
+    );
+
+    $supported_query_types = array(
+        'SELECT' => 1,
+        /*
+        // Support for these additional query types will come later on.
+        'DELETE' => 1,
+        'INSERT' => 1,
+        'REPLACE' => 1,
+        'TRUNCATE' => 1,
+        'UPDATE' => 1,
+        'EXPLAIN' => 1,
+        'DESCRIBE' => 1,
+        'SHOW' => 1,
+        'CREATE' => 1,
+        'SET' => 1,
+        'ALTER' => 1
+        */
+    );
+
+    // loop #1 for each token: select_expr, table_ref for SELECT
+
+    for ($i = 0; $i < $size; $i++) {
+        //DEBUG echo "Loop1 <strong>"  . $arr[$i]['data']
+        //. "</strong> (" . $arr[$i]['type'] . ")<br />";
+
+        // High speed seek for locating the end of the current query
+        if ($seek_queryend == true) {
+            if ($arr[$i]['type'] == 'punct_queryend') {
+                $seek_queryend = false;
+            } else {
+                continue;
+            } // end if (type == punct_queryend)
+        } // end if ($seek_queryend)
+
+        /**
+         * Note: do not split if this is a punct_queryend for the first and only
+         * query
+         * @todo when we find a UNION, should we split in another subresult?
+         */
+        if ($arr[$i]['type'] == 'punct_queryend' && ($i + 1 != $size)) {
+            $result[]  = $subresult;
+            $subresult = $subresult_empty;
+            continue;
+        } // end if (type == punct_queryend)
+
+        // ==============================================================
+        if ($arr[$i]['type'] == 'punct_bracket_open_round') {
+            $number_of_brackets++;
+            if ($in_extract) {
+                $number_of_brackets_in_extract++;
+            }
+            if ($in_group_concat) {
+                $number_of_brackets_in_group_concat++;
+            }
+        }
+        // ==============================================================
+        if ($arr[$i]['type'] == 'punct_bracket_close_round') {
+            $number_of_brackets--;
+            if ($number_of_brackets == 0) {
+                $in_subquery = false;
+            }
+            if ($in_extract) {
+                $number_of_brackets_in_extract--;
+                if ($number_of_brackets_in_extract == 0) {
+                    $in_extract = false;
+                }
+            }
+            if ($in_group_concat) {
+                $number_of_brackets_in_group_concat--;
+                if ($number_of_brackets_in_group_concat == 0) {
+                    $in_group_concat = false;
+                }
+            }
+        }
+
+        if ($in_subquery) {
+            /**
+             * skip the subquery to avoid setting
+             * select_expr or table_ref with the contents
+             * of this subquery; this is to avoid a bug when
+             * trying to edit the results of
+             * select * from child where not exists (select id from
+             * parent where child.parent_id = parent.id);
+             */
+            continue;
+        }
+        // ==============================================================
+        if ($arr[$i]['type'] == 'alpha_functionName') {
+            $upper_data = strtoupper($arr[$i]['data']);
+            if ($upper_data =='EXTRACT') {
+                $in_extract = true;
+                $number_of_brackets_in_extract = 0;
+            }
+            if ($upper_data =='GROUP_CONCAT') {
+                $in_group_concat = true;
+                $number_of_brackets_in_group_concat = 0;
+            }
+        }
+
+        // ==============================================================
+        if ($arr[$i]['type'] == 'alpha_reservedWord') {
+            // We don't know what type of query yet, so run this
+            if ($subresult['querytype'] == '') {
+                $subresult['querytype'] = strtoupper($arr[$i]['data']);
+            } // end if (querytype was empty)
+
+            // Check if we support this type of query
+            if (!isset($supported_query_types[$subresult['querytype']])) {
+                // Skip ahead to the next one if we don't
+                $seek_queryend = true;
+                continue;
+            } // end if (query not supported)
+
+            // upper once
+            $upper_data = strtoupper($arr[$i]['data']);
+            /**
+             * @todo reset for each query?
+             */
+
+            if ($upper_data == 'SELECT') {
+                if ($number_of_brackets > 0) {
+                    $in_subquery = true;
+                    $seen_subquery = true;
+                    // this is a subquery so do not analyze inside it
+                    continue;
+                }
+                $seen_from = false;
+                $previous_was_identifier = false;
+                $current_select_expr = -1;
+                $seen_end_of_table_ref = false;
+            } // end if (data == SELECT)
+
+            if ($upper_data =='FROM' && !$in_extract) {
+                $current_table_ref = -1;
+                $seen_from = true;
+                $previous_was_identifier = false;
+                $save_table_ref = true;
+            } // end if (data == FROM)
+
+            // here, do not 'continue' the loop, as we have more work for
+            // reserved words below
+        } // end if (type == alpha_reservedWord)
+
+        // ==============================
+        if ($arr[$i]['type'] == 'quote_backtick'
+            || $arr[$i]['type'] == 'quote_double'
+            || $arr[$i]['type'] == 'quote_single'
+            || $arr[$i]['type'] == 'alpha_identifier'
+            || ($arr[$i]['type'] == 'alpha_reservedWord'
+            && $arr[$i]['forbidden'] == false)
+        ) {
+            switch ($arr[$i]['type']) {
+            case 'alpha_identifier':
+            case 'alpha_reservedWord':
+                /**
+                 * this is not a real reservedWord, because it's not
+                 * present in the list of forbidden words, for example
+                 * "storage" which can be used as an identifier
+                 *
+                 * @todo avoid the pretty printing in color in this case
+                 */
+                $identifier = $arr[$i]['data'];
+                break;
+
+            case 'quote_backtick':
+            case 'quote_double':
+            case 'quote_single':
+                $identifier = PMA_Util::unQuote($arr[$i]['data']);
+                break;
+            } // end switch
+
+            if ($subresult['querytype'] == 'SELECT'
+                && ! $in_group_concat
+                && ! ($seen_subquery && $arr[$i - 1]['type'] == 'punct_bracket_close_round')
+            ) {
+                if (!$seen_from) {
+                    if ($previous_was_identifier && isset($chain)) {
+                        // found alias for this select_expr, save it
+                        // but only if we got something in $chain
+                        // (for example, SELECT COUNT(*) AS cnt
+                        // puts nothing in $chain, so we avoid
+                        // setting the alias)
+                        $alias_for_select_expr = $identifier;
+                    } else {
+                        $chain[] = $identifier;
+                        $previous_was_identifier = true;
+
+                    } // end if !$previous_was_identifier
+                } else {
+                    // ($seen_from)
+                    if ($save_table_ref && !$seen_end_of_table_ref) {
+                        if ($previous_was_identifier) {
+                            // found alias for table ref
+                            // save it for later
+                            $alias_for_table_ref = $identifier;
+                        } else {
+                            $chain[] = $identifier;
+                            $previous_was_identifier = true;
+
+                        } // end if ($previous_was_identifier)
+                    } // end if ($save_table_ref &&!$seen_end_of_table_ref)
+                } // end if (!$seen_from)
+            } // end if (querytype SELECT)
+        } // end if (quote_backtick or double quote or alpha_identifier)
+
+        // ===================================
+        if ($arr[$i]['type'] == 'punct_qualifier') {
+            // to be able to detect an identifier following another
+            $previous_was_identifier = false;
+            continue;
+        } // end if (punct_qualifier)
+
+        /**
+         * @todo check if 3 identifiers following one another -> error
+         */
+
+        //    s a v e    a    s e l e c t    e x p r
+        // finding a list separator or FROM
+        // means that we must save the current chain of identifiers
+        // into a select expression
+
+        // for now, we only save a select expression if it contains
+        // at least one identifier, as we are interested in checking
+        // the columns and table names, so in "select * from persons",
+        // the "*" is not saved
+
+        if (isset($chain) && !$seen_end_of_table_ref
+            && ((!$seen_from && $arr[$i]['type'] == 'punct_listsep')
+            || ($arr[$i]['type'] == 'alpha_reservedWord' && $upper_data == 'FROM'))
+        ) {
+            $size_chain = count($chain);
+            $current_select_expr++;
+            $subresult['select_expr'][$current_select_expr] = array(
+              'expr' => '',
+              'alias' => '',
+              'db'   => '',
+              'table_name' => '',
+              'table_true_name' => '',
+              'column' => ''
+             );
+
+            if (isset($alias_for_select_expr) && strlen($alias_for_select_expr)) {
+                // we had found an alias for this select expression
+                $subresult['select_expr'][$current_select_expr]['alias'] = $alias_for_select_expr;
+                unset($alias_for_select_expr);
+            }
+            // there is at least a column
+            $subresult['select_expr'][$current_select_expr]['column'] = $chain[$size_chain - 1];
+            $subresult['select_expr'][$current_select_expr]['expr'] = $chain[$size_chain - 1];
+
+            // maybe a table
+            if ($size_chain > 1) {
+                $subresult['select_expr'][$current_select_expr]['table_name'] = $chain[$size_chain - 2];
+                // we assume for now that this is also the true name
+                $subresult['select_expr'][$current_select_expr]['table_true_name'] = $chain[$size_chain - 2];
+                $subresult['select_expr'][$current_select_expr]['expr']
+                    = $subresult['select_expr'][$current_select_expr]['table_name']
+                    . '.' . $subresult['select_expr'][$current_select_expr]['expr'];
+            } // end if ($size_chain > 1)
+
+            // maybe a db
+            if ($size_chain > 2) {
+                $subresult['select_expr'][$current_select_expr]['db'] = $chain[$size_chain - 3];
+                $subresult['select_expr'][$current_select_expr]['expr']
+                    = $subresult['select_expr'][$current_select_expr]['db']
+                    . '.' . $subresult['select_expr'][$current_select_expr]['expr'];
+            } // end if ($size_chain > 2)
+            unset($chain);
+
+            /**
+             * @todo explain this:
+             */
+            if (($arr[$i]['type'] == 'alpha_reservedWord')
+                && ($upper_data != 'FROM')
+            ) {
+                $previous_was_identifier = true;
+            }
+
+        } // end if (save a select expr)
+
+
+        //======================================
+        //    s a v e    a    t a b l e    r e f
+        //======================================
+
+        // maybe we just saw the end of table refs
+        // but the last table ref has to be saved
+        // or we are at the last token
+        // or we just got a reserved word
+        /**
+         * @todo there could be another query after this one
+         */
+
+        if (isset($chain) && $seen_from && $save_table_ref
+            && ($arr[$i]['type'] == 'punct_listsep'
+            || ($arr[$i]['type'] == 'alpha_reservedWord' && $upper_data != "AS")
+            || $seen_end_of_table_ref
+            || $i == $size - 1)
+        ) {
+
+            $size_chain = count($chain);
+            $current_table_ref++;
+            $subresult['table_ref'][$current_table_ref] = array(
+              'expr'            => '',
+              'db'              => '',
+              'table_name'      => '',
+              'table_alias'     => '',
+              'table_true_name' => ''
+             );
+            if (isset($alias_for_table_ref) && strlen($alias_for_table_ref)) {
+                $subresult['table_ref'][$current_table_ref]['table_alias'] = $alias_for_table_ref;
+                unset($alias_for_table_ref);
+            }
+            $subresult['table_ref'][$current_table_ref]['table_name'] = $chain[$size_chain - 1];
+            // we assume for now that this is also the true name
+            $subresult['table_ref'][$current_table_ref]['table_true_name'] = $chain[$size_chain - 1];
+            $subresult['table_ref'][$current_table_ref]['expr']
+                = $subresult['table_ref'][$current_table_ref]['table_name'];
+            // maybe a db
+            if ($size_chain > 1) {
+                $subresult['table_ref'][$current_table_ref]['db'] = $chain[$size_chain - 2];
+                $subresult['table_ref'][$current_table_ref]['expr']
+                    = $subresult['table_ref'][$current_table_ref]['db']
+                    . '.' . $subresult['table_ref'][$current_table_ref]['expr'];
+            } // end if ($size_chain > 1)
+
+            // add the table alias into the whole expression
+            $subresult['table_ref'][$current_table_ref]['expr']
+             .= ' ' . $subresult['table_ref'][$current_table_ref]['table_alias'];
+
+            unset($chain);
+            $previous_was_identifier = true;
+            //continue;
+
+        } // end if (save a table ref)
+
+
+        // when we have found all table refs,
+        // for each table_ref alias, put the true name of the table
+        // in the corresponding select expressions
+
+        if (isset($current_table_ref)
+            && ($seen_end_of_table_ref || $i == $size-1)
+            && $subresult != $subresult_empty
+        ) {
+            for ($tr=0; $tr <= $current_table_ref; $tr++) {
+                $alias = $subresult['table_ref'][$tr]['table_alias'];
+                $truename = $subresult['table_ref'][$tr]['table_true_name'];
+                for ($se=0; $se <= $current_select_expr; $se++) {
+                    if (isset($alias)
+                        && strlen($alias)
+                        && $subresult['select_expr'][$se]['table_true_name'] == $alias
+                    ) {
+                        $subresult['select_expr'][$se]['table_true_name'] = $truename;
+                    } // end if (found the alias)
+                } // end for (select expressions)
+
+            } // end for (table refs)
+        } // end if (set the true names)
+
+
+        // e n d i n g    l o o p  #1
+        // set the $previous_was_identifier to false if the current
+        // token is not an identifier
+        if (($arr[$i]['type'] != 'alpha_identifier')
+            && ($arr[$i]['type'] != 'quote_double')
+            && ($arr[$i]['type'] != 'quote_single')
+            && ($arr[$i]['type'] != 'quote_backtick')
+        ) {
+            $previous_was_identifier = false;
+        } // end if
+
+        // however, if we are on AS, we must keep the $previous_was_identifier
+        if (($arr[$i]['type'] == 'alpha_reservedWord')
+            && ($upper_data == 'AS')
+        ) {
+            $previous_was_identifier = true;
+        }
+
+        if (($arr[$i]['type'] == 'alpha_reservedWord')
+            && ($upper_data =='ON' || $upper_data =='USING')
+        ) {
+            $save_table_ref = false;
+        } // end if (data == ON)
+
+        if (($arr[$i]['type'] == 'alpha_reservedWord')
+            && ($upper_data =='JOIN' || $upper_data =='FROM')
+        ) {
+            $save_table_ref = true;
+        } // end if (data == JOIN)
+
+        /**
+         * no need to check the end of table ref if we already did
+         *
+         * @todo maybe add "&& $seen_from"
+         */
+        if (!$seen_end_of_table_ref) {
+            // if this is the last token, it implies that we have
+            // seen the end of table references
+            // Check for the end of table references
+            //
+            // Note: if we are analyzing a GROUP_CONCAT clause,
+            // we might find a word that seems to indicate that
+            // we have found the end of table refs (like ORDER)
+            // but it's a modifier of the GROUP_CONCAT so
+            // it's not the real end of table refs
+            if (($i == $size-1)
+                || ($arr[$i]['type'] == 'alpha_reservedWord'
+                && !$in_group_concat
+                && isset($words_ending_table_ref[$upper_data]))
+            ) {
+                $seen_end_of_table_ref = true;
+                // to be able to save the last table ref, but do not
+                // set it true if we found a word like "ON" that has
+                // already set it to false
+                if (isset($save_table_ref) && $save_table_ref != false) {
+                    $save_table_ref = true;
+                } //end if
+
+            } // end if (check for end of table ref)
+        } //end if (!$seen_end_of_table_ref)
+
+        if ($seen_end_of_table_ref) {
+            $save_table_ref = false;
+        } // end if
+
+    } // end for $i (loop #1)
+
+    //DEBUG
+    /*
+      if (isset($current_select_expr)) {
+       for ($trace=0; $trace<=$current_select_expr; $trace++) {
+           echo "<br />";
+           reset ($subresult['select_expr'][$trace]);
+           while (list ($key, $val) = each ($subresult['select_expr'][$trace]))
+               echo "sel expr $trace $key => $val<br />\n";
+           }
+      }
+
+      if (isset($current_table_ref)) {
+       echo "current_table_ref = " . $current_table_ref . "<br>";
+       for ($trace=0; $trace<=$current_table_ref; $trace++) {
+
+           echo "<br />";
+           reset ($subresult['table_ref'][$trace]);
+           while (list ($key, $val) = each ($subresult['table_ref'][$trace]))
+           echo "table ref $trace $key => $val<br />\n";
+           }
+      }
+    */
+    // -------------------------------------------------------
+
+
+    // loop #2: - queryflags
+    //          - querytype (for queries != 'SELECT')
+    //          - section_before_limit, section_after_limit
+    //
+    // we will also need this queryflag in loop 2
+    // so set it here
+    if (isset($current_table_ref) && $current_table_ref > -1) {
+        $subresult['queryflags']['select_from'] = 1;
+    }
+
+    $section_before_limit = '';
+    $section_after_limit = ''; // truly the section after the limit clause
+    $seen_reserved_word = false;
+    $seen_group = false;
+    $seen_order = false;
+    $seen_order_by = false;
+    $in_group_by = false; // true when we are inside the GROUP BY clause
+    $in_order_by = false; // true when we are inside the ORDER BY clause
+    $in_having = false; // true when we are inside the HAVING clause
+    $in_select_expr = false; // true when we are inside the select expr clause
+    $in_where = false; // true when we are inside the WHERE clause
+    $seen_limit = false; // true if we have seen a LIMIT clause
+    $in_limit = false; // true when we are inside the LIMIT clause
+    $after_limit = false; // true when we are after the LIMIT clause
+    $in_from = false; // true when we are in the FROM clause
+    $in_group_concat = false;
+    $first_reserved_word = '';
+    $current_identifier = '';
+    $unsorted_query = $arr['raw']; // in case there is no ORDER BY
+    $number_of_brackets = 0;
+    $in_subquery = false;
+
+    for ($i = 0; $i < $size; $i++) {
+        //DEBUG echo "Loop2 <strong>"  . $arr[$i]['data']
+        //. "</strong> (" . $arr[$i]['type'] . ")<br />";
+
+        // need_confirm
+        //
+        // check for reserved words that will have to generate
+        // a confirmation request later in sql.php
+        // the cases are:
+        //   DROP TABLE
+        //   DROP DATABASE
+        //   ALTER TABLE... DROP
+        //   DELETE FROM...
+        //
+        // this code is not used for confirmations coming from functions.js
+
+        if ($arr[$i]['type'] == 'punct_bracket_open_round') {
+            $number_of_brackets++;
+        }
+
+        if ($arr[$i]['type'] == 'punct_bracket_close_round') {
+            $number_of_brackets--;
+            if ($number_of_brackets == 0) {
+                $in_subquery = false;
+            }
+        }
+
+        if ($arr[$i]['type'] == 'alpha_reservedWord') {
+            $upper_data = strtoupper($arr[$i]['data']);
+
+            if ($upper_data == 'SELECT' && $number_of_brackets > 0) {
+                $in_subquery = true;
+            }
+
+            if (!$seen_reserved_word) {
+                $first_reserved_word = $upper_data;
+                $subresult['querytype'] = $upper_data;
+                $seen_reserved_word = true;
+
+                // if the first reserved word is DROP or DELETE,
+                // we know this is a query that needs to be confirmed
+                if ($first_reserved_word=='DROP'
+                    || $first_reserved_word == 'DELETE'
+                    || $first_reserved_word == 'TRUNCATE'
+                ) {
+                    $subresult['queryflags']['need_confirm'] = 1;
+                }
+
+                if ($first_reserved_word=='SELECT') {
+                    $position_of_first_select = $i;
+                }
+
+            } else {
+                if ($upper_data == 'DROP' && $first_reserved_word == 'ALTER') {
+                    $subresult['queryflags']['need_confirm'] = 1;
+                }
+            }
+
+            if ($upper_data == 'LIMIT' && ! $in_subquery) {
+                $section_before_limit = substr($arr['raw'], 0, $arr[$i]['pos'] - 5);
+                $in_limit = true;
+                $seen_limit = true;
+                $limit_clause = '';
+                $in_order_by = false; // @todo maybe others to set false
+            }
+
+            if ($upper_data == 'PROCEDURE') {
+                $subresult['queryflags']['procedure'] = 1;
+                $in_limit = false;
+                $after_limit = true;
+            }
+            /**
+             * @todo set also to false if we find FOR UPDATE or LOCK IN SHARE MODE
+             */
+            if ($upper_data == 'SELECT') {
+                $in_select_expr = true;
+                $select_expr_clause = '';
+            }
+            if ($upper_data == 'DISTINCT' && !$in_group_concat) {
+                $subresult['queryflags']['distinct'] = 1;
+            }
+
+            if ($upper_data == 'UNION') {
+                $subresult['queryflags']['union'] = 1;
+            }
+
+            if ($upper_data == 'JOIN') {
+                $subresult['queryflags']['join'] = 1;
+            }
+
+            if ($upper_data == 'OFFSET') {
+                $subresult['queryflags']['offset'] = 1;
+            }
+
+            // if this is a real SELECT...FROM
+            if ($upper_data == 'FROM'
+                && isset($subresult['queryflags']['select_from'])
+                && $subresult['queryflags']['select_from'] == 1
+            ) {
+                $in_from = true;
+                $from_clause = '';
+                $in_select_expr = false;
+            }
+
+
+            // (we could have less resetting of variables to false
+            // if we trust that the query respects the standard
+            // MySQL order for clauses)
+
+            // we use $seen_group and $seen_order because we are looking
+            // for the BY
+            if ($upper_data == 'GROUP') {
+                $seen_group = true;
+                $seen_order = false;
+                $in_having = false;
+                $in_order_by = false;
+                $in_where = false;
+                $in_select_expr = false;
+                $in_from = false;
+            }
+            if ($upper_data == 'ORDER' && !$in_group_concat) {
+                $seen_order = true;
+                $seen_group = false;
+                $in_having = false;
+                $in_group_by = false;
+                $in_where = false;
+                $in_select_expr = false;
+                $in_from = false;
+            }
+            if ($upper_data == 'HAVING') {
+                $in_having = true;
+                $having_clause = '';
+                $seen_group = false;
+                $seen_order = false;
+                $in_group_by = false;
+                $in_order_by = false;
+                $in_where = false;
+                $in_select_expr = false;
+                $in_from = false;
+            }
+
+            if ($upper_data == 'WHERE') {
+                $in_where = true;
+                $where_clause = '';
+                $where_clause_identifiers = array();
+                $seen_group = false;
+                $seen_order = false;
+                $in_group_by = false;
+                $in_order_by = false;
+                $in_having = false;
+                $in_select_expr = false;
+                $in_from = false;
+            }
+
+            if ($upper_data == 'BY') {
+                if ($seen_group) {
+                    $in_group_by = true;
+                    $group_by_clause = '';
+                }
+                if ($seen_order) {
+                    $seen_order_by = true;
+                    // Here we assume that the ORDER BY keywords took
+                    // exactly 8 characters.
+                    // We use PMA_substr() to be charset-safe; otherwise
+                    // if the table name contains accents, the unsorted
+                    // query would be missing some characters.
+                    $unsorted_query = PMA_substr(
+                        $arr['raw'], 0, $arr[$i]['pos'] - 8
+                    );
+                    $in_order_by = true;
+                    $order_by_clause = '';
+                }
+            }
+
+            // if we find one of the words that could end the clause
+            if (isset($words_ending_clauses[$upper_data])) {
+
+                $in_group_by = false;
+                $in_order_by = false;
+                $in_having   = false;
+                $in_where    = false;
+                $in_select_expr = false;
+                $in_from = false;
+            }
+
+        } // endif (reservedWord)
+
+
+        // do not add a space after a function name
+        /**
+         * @todo can we combine loop 2 and loop 1? some code is repeated here...
+         */
+
+        $sep = ' ';
+        if ($arr[$i]['type'] == 'alpha_functionName') {
+            $sep='';
+            $upper_data = strtoupper($arr[$i]['data']);
+            if ($upper_data =='GROUP_CONCAT') {
+                $in_group_concat = true;
+                $number_of_brackets_in_group_concat = 0;
+            }
+        }
+
+        if ($arr[$i]['type'] == 'punct_bracket_open_round') {
+            if ($in_group_concat) {
+                $number_of_brackets_in_group_concat++;
+            }
+        }
+        if ($arr[$i]['type'] == 'punct_bracket_close_round') {
+            if ($in_group_concat) {
+                $number_of_brackets_in_group_concat--;
+                if ($number_of_brackets_in_group_concat == 0) {
+                    $in_group_concat = false;
+                }
+            }
+        }
+
+        // do not add a space after an identifier if followed by a dot
+        if ($arr[$i]['type'] == 'alpha_identifier'
+            && $i < $size - 1 && $arr[$i + 1]['data'] == '.'
+        ) {
+            $sep = '';
+        }
+
+        // do not add a space after a dot if followed by an identifier
+        if ($arr[$i]['data'] == '.' && $i < $size - 1
+            && $arr[$i + 1]['type'] == 'alpha_identifier'
+        ) {
+            $sep = '';
+        }
+
+        if ($in_select_expr && $upper_data != 'SELECT'
+            && $upper_data != 'DISTINCT'
+        ) {
+            $select_expr_clause .= $arr[$i]['data'] . $sep;
+        }
+        if ($in_from && $upper_data != 'FROM') {
+            $from_clause .= $arr[$i]['data'] . $sep;
+        }
+        if ($in_group_by && $upper_data != 'GROUP' && $upper_data != 'BY') {
+            $group_by_clause .= $arr[$i]['data'] . $sep;
+        }
+        if ($in_order_by && $upper_data != 'ORDER' && $upper_data != 'BY') {
+            // add a space only before ASC or DESC
+            // not around the dot between dbname and tablename
+            if ($arr[$i]['type'] == 'alpha_reservedWord') {
+                $order_by_clause .= $sep;
+            }
+            $order_by_clause .= $arr[$i]['data'];
+        }
+        if ($in_having && $upper_data != 'HAVING') {
+            $having_clause .= $arr[$i]['data'] . $sep;
+        }
+        if ($in_where && $upper_data != 'WHERE') {
+            $where_clause .= $arr[$i]['data'] . $sep;
+
+            if (($arr[$i]['type'] == 'quote_backtick')
+                || ($arr[$i]['type'] == 'alpha_identifier')
+            ) {
+                $where_clause_identifiers[] = $arr[$i]['data'];
+            }
+        }
+
+        // to grab the rest of the query after the ORDER BY clause
+        if (isset($subresult['queryflags']['select_from'])
+            && $subresult['queryflags']['select_from'] == 1
+            && ! $in_order_by
+            && $seen_order_by
+            && $upper_data != 'BY'
+        ) {
+            $unsorted_query .= $arr[$i]['data'];
+            if ($arr[$i]['type'] != 'punct_bracket_open_round'
+                && $arr[$i]['type'] != 'punct_bracket_close_round'
+                && $arr[$i]['type'] != 'punct'
+            ) {
+                $unsorted_query .= $sep;
+            }
+        }
+
+        if ($in_limit) {
+            if ($upper_data == 'OFFSET') {
+                $limit_clause .= $sep;
+            }
+            $limit_clause .= $arr[$i]['data'];
+            if ($upper_data == 'LIMIT' || $upper_data == 'OFFSET') {
+                $limit_clause .= $sep;
+            }
+        }
+        if ($after_limit && $seen_limit) {
+            $section_after_limit .= $arr[$i]['data'] . $sep;
+        }
+
+        // clear $upper_data for next iteration
+        $upper_data='';
+    } // end for $i (loop #2)
+    if (empty($section_before_limit)) {
+        $section_before_limit = $arr['raw'];
+    }
+
+    // -----------------------------------------------------
+    // loop #3: foreign keys and MySQL 4.1.2+ TIMESTAMP options
+    // (for now, check only the first query)
+    // (for now, identifiers are assumed to be backquoted)
+
+    // If we find that we are dealing with a CREATE TABLE query,
+    // we look for the next punct_bracket_open_round, which
+    // introduces the fields list. Then, when we find a
+    // quote_backtick, it must be a field, so we put it into
+    // the create_table_fields array. Even if this field is
+    // not a timestamp, it will be useful when logic has been
+    // added for complete field attributes analysis.
+
+    $seen_foreign = false;
+    $seen_references = false;
+    $seen_constraint = false;
+    $foreign_key_number = -1;
+    $seen_create_table = false;
+    $seen_create = false;
+    $seen_alter = false;
+    $in_create_table_fields = false;
+    $brackets_level = 0;
+    $in_timestamp_options = false;
+    $seen_default = false;
+
+    for ($i = 0; $i < $size; $i++) {
+        if ($arr[$i]['type'] == 'alpha_reservedWord') {
+            $upper_data = strtoupper($arr[$i]['data']);
+
+            if ($upper_data == 'NOT' && $in_timestamp_options) {
+                $create_table_fields[$current_identifier]['timestamp_not_null'] = true;
+
+            }
+
+            if ($upper_data == 'CREATE') {
+                $seen_create = true;
+            }
+
+            if ($upper_data == 'ALTER') {
+                $seen_alter = true;
+            }
+
+            if ($upper_data == 'TABLE' && $seen_create) {
+                $seen_create_table = true;
+                $create_table_fields = array();
+            }
+
+            if ($upper_data == 'CURRENT_TIMESTAMP') {
+                if ($in_timestamp_options) {
+                    if ($seen_default) {
+                        $create_table_fields[$current_identifier]['default_current_timestamp'] = true;
+                    }
+                }
+            }
+
+            if ($upper_data == 'CONSTRAINT') {
+                $foreign_key_number++;
+                $seen_foreign = false;
+                $seen_references = false;
+                $seen_constraint = true;
+            }
+            if ($upper_data == 'FOREIGN') {
+                $seen_foreign = true;
+                $seen_references = false;
+                $seen_constraint = false;
+            }
+            if ($upper_data == 'REFERENCES') {
+                $seen_foreign = false;
+                $seen_references = true;
+                $seen_constraint = false;
+            }
+
+
+            // Cases covered:
+
+            // [ON DELETE {CASCADE | SET NULL | NO ACTION | RESTRICT}]
+            // [ON UPDATE {CASCADE | SET NULL | NO ACTION | RESTRICT}]
+
+            // but we set ['on_delete'] or ['on_cascade'] to
+            // CASCADE | SET_NULL | NO_ACTION | RESTRICT
+
+            // ON UPDATE CURRENT_TIMESTAMP
+
+            if ($upper_data == 'ON') {
+                if (isset($arr[$i+1]) && $arr[$i+1]['type'] == 'alpha_reservedWord') {
+                    $second_upper_data = strtoupper($arr[$i+1]['data']);
+                    if ($second_upper_data == 'DELETE') {
+                        $clause = 'on_delete';
+                    }
+                    if ($second_upper_data == 'UPDATE') {
+                        $clause = 'on_update';
+                    }
+                    if (isset($clause)
+                        && ($arr[$i+2]['type'] == 'alpha_reservedWord'
+                        // ugly workaround because currently, NO is not
+                        // in the list of reserved words in sqlparser.data
+                        // (we got a bug report about not being able to use
+                        // 'no' as an identifier)
+                        || ($arr[$i+2]['type'] == 'alpha_identifier'
+                        && strtoupper($arr[$i+2]['data'])=='NO'))
+                    ) {
+                        $third_upper_data = strtoupper($arr[$i+2]['data']);
+                        if ($third_upper_data == 'CASCADE'
+                            || $third_upper_data == 'RESTRICT'
+                        ) {
+                            $value = $third_upper_data;
+                        } elseif ($third_upper_data == 'SET'
+                            || $third_upper_data == 'NO'
+                        ) {
+                            if ($arr[$i+3]['type'] == 'alpha_reservedWord') {
+                                $value = $third_upper_data . '_' . strtoupper($arr[$i+3]['data']);
+                            }
+                        } elseif ($third_upper_data == 'CURRENT_TIMESTAMP') {
+                            if ($clause == 'on_update'
+                                && $in_timestamp_options
+                            ) {
+                                $create_table_fields[$current_identifier]['on_update_current_timestamp'] = true;
+                                $seen_default = false;
+                            }
+
+                        } else {
+                            $value = '';
+                        }
+                        if (!empty($value)) {
+                            $foreign[$foreign_key_number][$clause] = $value;
+                        }
+                        unset($clause);
+                    } // endif (isset($clause))
+                }
+            }
+
+        } // end of reserved words analysis
+
+
+        if ($arr[$i]['type'] == 'punct_bracket_open_round') {
+            $brackets_level++;
+            if ($seen_create_table && $brackets_level == 1) {
+                $in_create_table_fields = true;
+            }
+        }
+
+
+        if ($arr[$i]['type'] == 'punct_bracket_close_round') {
+            $brackets_level--;
+            if ($seen_references) {
+                $seen_references = false;
+            }
+            if ($seen_create_table && $brackets_level == 0) {
+                $in_create_table_fields = false;
+            }
+        }
+
+        if (($arr[$i]['type'] == 'alpha_columnAttrib')) {
+            $upper_data = strtoupper($arr[$i]['data']);
+            if ($seen_create_table && $in_create_table_fields) {
+                if ($upper_data == 'DEFAULT') {
+                    $seen_default = true;
+                    $create_table_fields[$current_identifier]['default_value'] = $arr[$i + 1]['data'];
+                }
+            }
+        }
+
+        /**
+         * @see @todo 2005-10-16 note: the "or" part here is a workaround for a bug
+         */
+        if (($arr[$i]['type'] == 'alpha_columnType')
+            || ($arr[$i]['type'] == 'alpha_functionName' && $seen_create_table)
+        ) {
+            $upper_data = strtoupper($arr[$i]['data']);
+            if ($seen_create_table && $in_create_table_fields
+                && isset($current_identifier)
+            ) {
+                $create_table_fields[$current_identifier]['type'] = $upper_data;
+                if ($upper_data == 'TIMESTAMP') {
+                    $arr[$i]['type'] = 'alpha_columnType';
+                    $in_timestamp_options = true;
+                } else {
+                    $in_timestamp_options = false;
+                    if ($upper_data == 'CHAR') {
+                        $arr[$i]['type'] = 'alpha_columnType';
+                    }
+                }
+            }
+        }
+
+
+        if ($arr[$i]['type'] == 'quote_backtick'
+            || $arr[$i]['type'] == 'alpha_identifier'
+        ) {
+
+            if ($arr[$i]['type'] == 'quote_backtick') {
+                // remove backquotes
+                $identifier = PMA_Util::unQuote($arr[$i]['data']);
+            } else {
+                $identifier = $arr[$i]['data'];
+            }
+
+            if ($seen_create_table && $in_create_table_fields) {
+                $current_identifier = $identifier;
+                // we set this one even for non TIMESTAMP type
+                $create_table_fields[$current_identifier]['timestamp_not_null'] = false;
+            }
+
+            if ($seen_constraint) {
+                $foreign[$foreign_key_number]['constraint'] = $identifier;
+            }
+
+            if ($seen_foreign && $brackets_level > 0) {
+                $foreign[$foreign_key_number]['index_list'][] = $identifier;
+            }
+
+            if ($seen_references) {
+                if ($seen_alter && $brackets_level > 0) {
+                    $foreign[$foreign_key_number]['ref_index_list'][] = $identifier;
+                    // here, the first bracket level corresponds to the
+                    // bracket of CREATE TABLE
+                    // so if we are on level 2, it must be the index list
+                    // of the foreign key REFERENCES
+                } elseif ($brackets_level > 1) {
+                    $foreign[$foreign_key_number]['ref_index_list'][] = $identifier;
+                } elseif ($arr[$i+1]['type'] == 'punct_qualifier') {
+                    // identifier is `db`.`table`
+                    // the first pass will pick the db name
+                    // the next pass will pick the table name
+                    $foreign[$foreign_key_number]['ref_db_name'] = $identifier;
+                } else {
+                    // identifier is `table`
+                    $foreign[$foreign_key_number]['ref_table_name'] = $identifier;
+                }
+            }
+        }
+    } // end for $i (loop #3)
+
+
+    // Fill the $subresult array
+
+    if (isset($create_table_fields)) {
+        $subresult['create_table_fields'] = $create_table_fields;
+    }
+
+    if (isset($foreign)) {
+        $subresult['foreign_keys'] = $foreign;
+    }
+
+    if (isset($select_expr_clause)) {
+        $subresult['select_expr_clause'] = $select_expr_clause;
+    }
+    if (isset($from_clause)) {
+        $subresult['from_clause'] = $from_clause;
+    }
+    if (isset($group_by_clause)) {
+        $subresult['group_by_clause'] = $group_by_clause;
+    }
+    if (isset($order_by_clause)) {
+        $subresult['order_by_clause'] = $order_by_clause;
+    }
+    if (isset($having_clause)) {
+        $subresult['having_clause'] = $having_clause;
+    }
+    if (isset($limit_clause)) {
+        $subresult['limit_clause'] = $limit_clause;
+    }
+    if (isset($where_clause)) {
+        $subresult['where_clause'] = $where_clause;
+    }
+    if (isset($unsorted_query) && !empty($unsorted_query)) {
+        $subresult['unsorted_query'] = $unsorted_query;
+    }
+    if (isset($where_clause_identifiers)) {
+        $subresult['where_clause_identifiers'] = $where_clause_identifiers;
+    }
+
+    if (isset($position_of_first_select)) {
+        $subresult['position_of_first_select'] = $position_of_first_select;
+        $subresult['section_before_limit'] = $section_before_limit;
+        $subresult['section_after_limit'] = $section_after_limit;
+    }
+
+    // They are naughty and didn't have a trailing semi-colon,
+    // then still handle it properly
+    if ($subresult['querytype'] != '') {
+        $result[] = $subresult;
+    }
+    return $result;
+} // end of the "PMA_SQP_analyze()" function
+
+
+/**
+ * Colorizes SQL queries html formatted
+ *
+ * @param array $arr The SQL queries html formatted
+ *
+ * @return array   The colorized SQL queries
+ *
+ * @todo check why adding a "\n" after the </span> would cause extra blanks
+ * to be displayed: SELECT p . person_name
+ *
+ * @access public
+ */
+function PMA_SQP_formatHtml_colorize($arr)
+{
+    $i         = PMA_strpos($arr['type'], '_');
+    $class     = '';
+    if ($i > 0) {
+        $class = 'syntax_' . PMA_substr($arr['type'], 0, $i) . ' ';
+    }
+
+    $class     .= 'syntax_' . $arr['type'];
+
+    return '<span class="' . $class . '">'
+        . htmlspecialchars($arr['data']) . '</span>';
+} // end of the "PMA_SQP_formatHtml_colorize()" function
+
+
+/**
+ * Formats SQL queries to html
+ *
+ * @param array   $arr              The SQL queries
+ * @param string  $mode             mode of printing
+ * @param integer $start_token      starting token
+ * @param integer $number_of_tokens number of tokens to format, -1 = all
+ *
+ * @return string  The formatted SQL queries
+ *
+ * @access public
+ */
+function PMA_SQP_formatHtml(
+    $arr, $mode='color', $start_token=0,
+    $number_of_tokens=-1
+) {
+    global $PMA_SQPdata_operators_docs, $PMA_SQPdata_functions_docs;
+
+    //DEBUG echo 'in Format<pre>'; print_r($arr); echo '</pre>';
+    // then check for an array
+    if (! is_array($arr)) {
+        return htmlspecialchars($arr);
+    }
+    // first check for the SQL parser having hit an error
+    if (PMA_SQP_isError()) {
+        return htmlspecialchars($arr['raw']);
+    }
+    // else do it properly
+    switch ($mode) {
+    case 'color':
+        $str                                = '<span class="syntax">';
+        $html_line_break                    = '<br />';
+        $docu                               = true;
+        break;
+    case 'query_only':
+        $str                                = '';
+        $html_line_break                    = "\n";
+        $docu                               = false;
+        break;
+    case 'text':
+        $str                                = '';
+        $html_line_break                    = '<br />';
+        $docu                               = true;
+        break;
+    } // end switch
+    // inner_sql is a span that exists for all cases, except query_only
+    // of $cfg['SQP']['fmtType'] to make possible a replacement
+    // for inline editing
+    if ($mode!='query_only') {
+        $str .= '<span class="inner_sql">';
+    }
+    $close_docu_link = false;
+    $indent                                     = 0;
+    $bracketlevel                               = 0;
+    $functionlevel                              = 0;
+    $infunction                                 = false;
+    $space_punct_listsep                        = ' ';
+    $space_punct_listsep_function_name          = ' ';
+    // $space_alpha_reserved_word = '<br />'."\n";
+    $space_alpha_reserved_word                  = ' ';
+
+    $keywords_with_brackets_1before            = array(
+        'INDEX' => 1,
+        'KEY' => 1,
+        'ON' => 1,
+        'USING' => 1
+    );
+
+    $keywords_with_brackets_2before            = array(
+        'IGNORE' => 1,
+        'INDEX' => 1,
+        'INTO' => 1,
+        'KEY' => 1,
+        'PRIMARY' => 1,
+        'PROCEDURE' => 1,
+        'REFERENCES' => 1,
+        'UNIQUE' => 1,
+        'USE' => 1
+    );
+
+    // These reserved words do NOT get a newline placed near them.
+    $keywords_no_newline               = array(
+        'AS' => 1,
+        'ASC' => 1,
+        'DESC' => 1,
+        'DISTINCT' => 1,
+        'DUPLICATE' => 1,
+        'HOUR' => 1,
+        'INTERVAL' => 1,
+        'IS' => 1,
+        'LIKE' => 1,
+        'NOT' => 1,
+        'NULL' => 1,
+        'ON' => 1,
+        'REGEXP' => 1
+    );
+
+    // These reserved words introduce a privilege list
+    $keywords_priv_list                = array(
+        'GRANT' => 1,
+        'REVOKE' => 1
+    );
+
+    if ($number_of_tokens == -1) {
+        $number_of_tokens = $arr['len'];
+    }
+    $typearr   = array();
+    if ($number_of_tokens >= 0) {
+        $typearr[0] = '';
+        $typearr[1] = '';
+        $typearr[2] = '';
+        $typearr[3] = $arr[$start_token]['type'];
+    }
+
+    $in_priv_list = false;
+    for ($i = $start_token; $i < $number_of_tokens; $i++) {
+        // DEBUG echo "Loop format <strong>" . $arr[$i]['data']
+        // . "</strong> " . $arr[$i]['type'] . "<br />";
+        $before = '';
+        $after  = '';
+        // array_shift($typearr);
+        /*
+        0 prev2
+        1 prev
+        2 current
+        3 next
+        */
+        if (($i + 1) < $number_of_tokens) {
+            $typearr[4] = $arr[$i + 1]['type'];
+        } else {
+            $typearr[4] = '';
+        }
+
+        for ($j=0; $j<4; $j++) {
+            $typearr[$j] = $typearr[$j + 1];
+        }
+
+        switch ($typearr[2]) {
+        case 'alpha_bitfield_constant_introducer':
+            $before     = ' ';
+            $after      = '';
+            break;
+        case 'white_newline':
+            $before     = '';
+            break;
+        case 'punct_bracket_open_round':
+            $bracketlevel++;
+            $infunction = false;
+            $keyword_brackets_2before = isset(
+                $keywords_with_brackets_2before[strtoupper($arr[$i - 2]['data'])]
+            );
+            $keyword_brackets_1before = isset(
+                $keywords_with_brackets_1before[strtoupper($arr[$i - 1]['data'])]
+            );
+            // Make sure this array is sorted!
+            if (($typearr[1] == 'alpha_functionName')
+                || ($typearr[1] == 'alpha_columnType') || ($typearr[1] == 'punct')
+                || ($typearr[3] == 'digit_integer') || ($typearr[3] == 'digit_hex')
+                || ($typearr[3] == 'digit_float')
+                || ($typearr[0] == 'alpha_reservedWord' && $keyword_brackets_2before)
+                || ($typearr[1] == 'alpha_reservedWord' && $keyword_brackets_1before)
+            ) {
+                $functionlevel++;
+                $infunction = true;
+                $after      .= ' ';
+            } else {
+                $indent++;
+                if ($mode != 'query_only') {
+                    $after .= '<div class="syntax_indent' . $indent . '">';
+                } else {
+                    $after .= ' ';
+                }
+            }
+            break;
+        case 'alpha_identifier':
+            if (($typearr[1] == 'punct_qualifier')
+                || ($typearr[3] == 'punct_qualifier')
+            ) {
+                $after      = '';
+                $before     = '';
+            }
+            // for example SELECT 1 somealias
+            if ($typearr[1] == 'digit_integer') {
+                $before     = ' ';
+            }
+            if (($typearr[3] == 'alpha_columnType')
+                || ($typearr[3] == 'alpha_identifier')
+            ) {
+                $after      .= ' ';
+            }
+            break;
+        case 'punct_user':
+        case 'punct_qualifier':
+            $before         = '';
+            $after          = '';
+            break;
+        case 'punct_listsep':
+            if ($infunction == true) {
+                $after      .= $space_punct_listsep_function_name;
+            } else {
+                $after      .= $space_punct_listsep;
+            }
+            break;
+        case 'punct_queryend':
+            if (($typearr[3] != 'comment_mysql')
+                && ($typearr[3] != 'comment_ansi')
+                && $typearr[3] != 'comment_c'
+            ) {
+                $after     .= $html_line_break;
+                $after     .= $html_line_break;
+            }
+            $space_punct_listsep               = ' ';
+            $space_punct_listsep_function_name = ' ';
+            $space_alpha_reserved_word         = ' ';
+            $in_priv_list                      = false;
+            break;
+        case 'comment_mysql':
+        case 'comment_ansi':
+            $after         .= $html_line_break;
+            break;
+        case 'punct':
+            $before         .= ' ';
+            if ($docu && isset($PMA_SQPdata_operators_docs[$arr[$i]['data']])
+                && ($arr[$i]['data'] != '*' || in_array($arr[$i]['type'], array('digit_integer','digit_float','digit_hex')))
+            ) {
+                $before .= PMA_Util::showMySQLDocu(
+                    'functions',
+                    $PMA_SQPdata_operators_docs[$arr[$i]['data']]['link'],
+                    false,
+                    $PMA_SQPdata_operators_docs[$arr[$i]['data']]['anchor'],
+                    true
+                );
+                $after .= '</a>';
+            }
+
+            // workaround for
+            // select * from mytable limit 0,-1
+            // (a side effect of this workaround is that
+            // select 20 - 9
+            // becomes
+            // select 20 -9
+            // )
+            if ($typearr[3] != 'digit_integer') {
+                $after        .= ' ';
+            }
+            break;
+        case 'punct_bracket_close_round':
+            // only close bracket level when it was opened before
+            if ($bracketlevel > 0) {
+                $bracketlevel--;
+                if ($infunction == true) {
+                    $functionlevel--;
+                    $after     .= ' ';
+                    $before    .= ' ';
+                } else {
+                    $indent--;
+                    $before    .= ($mode != 'query_only' ? '</div>' : ' ');
+                }
+                $infunction    = ($functionlevel > 0) ? true : false;
+            }
+            break;
+        case 'alpha_columnType':
+            if ($docu) {
+                switch ($arr[$i]['data']) {
+                case 'tinyint':
+                case 'smallint':
+                case 'mediumint':
+                case 'int':
+                case 'bigint':
+                case 'decimal':
+                case 'float':
+                case 'double':
+                case 'real':
+                case 'bit':
+                case 'boolean':
+                case 'serial':
+                    $before .= PMA_Util::showMySQLDocu(
+                        'data-types',
+                        'numeric-types',
+                        false,
+                        '',
+                        true
+                    );
+                    $after = '</a>' . $after;
+                    break;
+                case 'date':
+                case 'datetime':
+                case 'timestamp':
+                case 'time':
+                case 'year':
+                    $before .= PMA_Util::showMySQLDocu(
+                        'data-types',
+                        'date-and-time-types',
+                        false,
+                        '',
+                        true
+                    );
+                    $after = '</a>' . $after;
+                    break;
+                case 'char':
+                case 'varchar':
+                case 'tinytext':
+                case 'text':
+                case 'mediumtext':
+                case 'longtext':
+                case 'binary':
+                case 'varbinary':
+                case 'tinyblob':
+                case 'mediumblob':
+                case 'blob':
+                case 'longblob':
+                case 'enum':
+                case 'set':
+                    $before .= PMA_Util::showMySQLDocu(
+                        'data-types',
+                        'string-types',
+                        false,
+                        '',
+                        true
+                    );
+                    $after = '</a>' . $after;
+                    break;
+                }
+            }
+            if ($typearr[3] == 'alpha_columnAttrib') {
+                $after     .= ' ';
+            }
+            if ($typearr[1] == 'alpha_columnType') {
+                $before    .= ' ';
+            }
+            break;
+        case 'alpha_columnAttrib':
+
+            // ALTER TABLE tbl_name AUTO_INCREMENT = 1
+            // COLLATE LATIN1_GENERAL_CI DEFAULT
+            if ($typearr[1] == 'alpha_identifier'
+                || $typearr[1] == 'alpha_charset'
+            ) {
+                $before .= ' ';
+            }
+            if (($typearr[3] == 'alpha_columnAttrib')
+                || ($typearr[3] == 'quote_single')
+                || ($typearr[3] == 'digit_integer')
+            ) {
+                $after     .= ' ';
+            }
+            // workaround for
+            // AUTO_INCREMENT = 31DEFAULT_CHARSET = utf-8
+
+            if ($typearr[2] == 'alpha_columnAttrib'
+                && $typearr[3] == 'alpha_reservedWord'
+            ) {
+                $before .= ' ';
+            }
+            // workaround for
+            // select * from mysql.user where binary user="root"
+            // binary is marked as alpha_columnAttrib
+            // but should be marked as a reserved word
+            if (strtoupper($arr[$i]['data']) == 'BINARY'
+                && $typearr[3] == 'alpha_identifier'
+            ) {
+                $after     .= ' ';
+            }
+            break;
+        case 'alpha_functionName':
+            $funcname = strtoupper($arr[$i]['data']);
+            if ($docu && isset($PMA_SQPdata_functions_docs[$funcname])) {
+                $before .= PMA_Util::showMySQLDocu(
+                    'functions',
+                    $PMA_SQPdata_functions_docs[$funcname]['link'],
+                    false,
+                    $PMA_SQPdata_functions_docs[$funcname]['anchor'],
+                    true
+                );
+                $after .= '</a>';
+            }
+            break;
+        case 'alpha_reservedWord':
+            // do not uppercase the reserved word if we are calling
+            // this function in query_only mode, because we need
+            // the original query (otherwise we get problems with
+            // semi-reserved words like "storage" which is legal
+            // as an identifier name)
+
+            if ($mode != 'query_only') {
+                $arr[$i]['data'] = strtoupper($arr[$i]['data']);
+            }
+
+            if ((($typearr[1] != 'alpha_reservedWord')
+                || (($typearr[1] == 'alpha_reservedWord')
+                && isset($keywords_no_newline[strtoupper($arr[$i - 1]['data'])])))
+                && ($typearr[1] != 'punct_level_plus')
+                && (!isset($keywords_no_newline[$arr[$i]['data']]))
+            ) {
+                // do not put a space before the first token, because
+                // we use a lot of pattern matching checking for the
+                // first reserved word at beginning of query
+                // so do not put a newline before
+                //
+                // also we must not be inside a privilege list
+                if ($i > 0) {
+                    // the alpha_identifier exception is there to
+                    // catch cases like
+                    // GRANT SELECT ON mydb.mytable TO myuser at localhost
+                    // (else, we get mydb.mytableTO)
+                    //
+                    // the quote_single exception is there to
+                    // catch cases like
+                    // GRANT ... TO 'marc'@'domain.com' IDENTIFIED...
+                    /**
+                     * @todo fix all cases and find why this happens
+                     */
+
+                    if (!$in_priv_list
+                        || $typearr[1] == 'alpha_identifier'
+                        || $typearr[1] == 'quote_single'
+                        || $typearr[1] == 'white_newline'
+                    ) {
+                        $before    .= $space_alpha_reserved_word;
+                    }
+                } else {
+                    // on first keyword, check if it introduces a
+                    // privilege list
+                    if (isset($keywords_priv_list[$arr[$i]['data']])) {
+                        $in_priv_list = true;
+                    }
+                }
+            } else {
+                $before    .= ' ';
+            }
+
+            switch ($arr[$i]['data']) {
+            case 'CREATE':
+            case 'ALTER':
+            case 'DROP':
+            case 'RENAME';
+            case 'TRUNCATE':
+            case 'ANALYZE':
+            case 'ANALYSE':
+            case 'OPTIMIZE':
+                if ($docu) {
+                    switch ($arr[$i + 1]['data']) {
+                    case 'EVENT':
+                    case 'TABLE':
+                    case 'TABLESPACE':
+                    case 'FUNCTION':
+                    case 'INDEX':
+                    case 'PROCEDURE':
+                    case 'TRIGGER':
+                    case 'SERVER':
+                    case 'DATABASE':
+                    case 'VIEW':
+                        $before .= PMA_Util::showMySQLDocu(
+                            'SQL-Syntax',
+                            $arr[$i]['data'] . '_' . $arr[$i + 1]['data'],
+                            false,
+                            '',
+                            true
+                        );
+                        $close_docu_link = true;
+                        break;
+                    }
+                    if ($arr[$i + 1]['data'] == 'LOGFILE'
+                        && $arr[$i + 2]['data'] == 'GROUP'
+                    ) {
+                        $before .= PMA_Util::showMySQLDocu(
+                            'SQL-Syntax',
+                            $arr[$i]['data'] . '_LOGFILE_GROUP',
+                            false,
+                            '',
+                            true
+                        );
+                        $close_docu_link = true;
+                    }
+                }
+                if (!$in_priv_list) {
+                    $space_punct_listsep       = $html_line_break;
+                    $space_alpha_reserved_word = ' ';
+                }
+                break;
+            case 'EVENT':
+            case 'TABLESPACE':
+            case 'TABLE':
+            case 'FUNCTION':
+            case 'INDEX':
+            case 'PROCEDURE':
+            case 'SERVER':
+            case 'TRIGGER':
+            case 'DATABASE':
+            case 'VIEW':
+            case 'GROUP':
+                if ($close_docu_link) {
+                    $after = '</a>' . $after;
+                    $close_docu_link = false;
+                }
+                break;
+            case 'SET':
+                if ($docu && ($i == 0 || $arr[$i - 1]['data'] != 'CHARACTER')) {
+                    $before .= PMA_Util::showMySQLDocu(
+                        'SQL-Syntax',
+                        $arr[$i]['data'],
+                        false,
+                        '',
+                        true
+                    );
+                    $after = '</a>' . $after;
+                }
+                if (!$in_priv_list) {
+                    $space_punct_listsep       = $html_line_break;
+                    $space_alpha_reserved_word = ' ';
+                }
+                break;
+            case 'EXPLAIN':
+            case 'DESCRIBE':
+            case 'DELETE':
+            case 'SHOW':
+            case 'UPDATE':
+                if ($docu) {
+                    $before .= PMA_Util::showMySQLDocu(
+                        'SQL-Syntax',
+                        $arr[$i]['data'],
+                        false,
+                        '',
+                        true
+                    );
+                    $after = '</a>' . $after;
+                }
+                if (!$in_priv_list) {
+                    $space_punct_listsep       = $html_line_break;
+                    $space_alpha_reserved_word = ' ';
+                }
+                break;
+            case 'INSERT':
+            case 'REPLACE':
+                if ($docu) {
+                    $before .= PMA_Util::showMySQLDocu(
+                        'SQL-Syntax',
+                        $arr[$i]['data'],
+                        false,
+                        '',
+                        true
+                    );
+                    $after = '</a>' . $after;
+                }
+                if (!$in_priv_list) {
+                    $space_punct_listsep       = $html_line_break;
+                    $space_alpha_reserved_word = $html_line_break;
+                }
+                break;
+            case 'VALUES':
+                $space_punct_listsep       = ' ';
+                $space_alpha_reserved_word = $html_line_break;
+                break;
+            case 'SELECT':
+                if ($docu) {
+                    $before .= PMA_Util::showMySQLDocu(
+                        'SQL-Syntax',
+                        'SELECT',
+                        false,
+                        '',
+                        true
+                    );
+                    $after = '</a>' . $after;
+                }
+                $space_punct_listsep       = ' ';
+                $space_alpha_reserved_word = $html_line_break;
+                break;
+            case 'CALL':
+            case 'DO':
+            case 'HANDLER':
+                if ($docu) {
+                    $before .= PMA_Util::showMySQLDocu(
+                        'SQL-Syntax',
+                        $arr[$i]['data'],
+                        false,
+                        '',
+                        true
+                    );
+                    $after = '</a>' . $after;
+                }
+                break;
+            default:
+                if ($close_docu_link
+                    && in_array(
+                        $arr[$i]['data'],
+                        array('LIKE', 'NOT', 'IN', 'REGEXP', 'NULL')
+                    )
+                ) {
+                    $after .= '</a>';
+                    $close_docu_link = false;
+                } else if ($docu
+                    && isset($PMA_SQPdata_functions_docs[$arr[$i]['data']])
+                ) {
+                    /* Handle multi word statements first */
+                    if (isset($typearr[4])
+                        && $typearr[4] == 'alpha_reservedWord'
+                        && $typearr[3] == 'alpha_reservedWord'
+                        && isset($PMA_SQPdata_functions_docs[strtoupper(
+                            $arr[$i]['data'] . '_'
+                            . $arr[$i + 1]['data'] . '_'
+                            . $arr[$i + 2]['data']
+                        )])
+                    ) {
+                        $tempname = strtoupper(
+                            $arr[$i]['data'] . '_'
+                            . $arr[$i + 1]['data'] . '_'
+                            . $arr[$i + 2]['data']
+                        );
+                        $before .= PMA_Util::showMySQLDocu(
+                            'functions',
+                            $PMA_SQPdata_functions_docs[$tempname]['link'],
+                            false,
+                            $PMA_SQPdata_functions_docs[$tempname]['anchor'],
+                            true
+                        );
+                        $close_docu_link = true;
+                    } else if (isset($typearr[3])
+                        && $typearr[3] == 'alpha_reservedWord'
+                        && isset($PMA_SQPdata_functions_docs[strtoupper(
+                            $arr[$i]['data'] . '_' . $arr[$i + 1]['data']
+                        )])
+                    ) {
+                        $tempname = strtoupper(
+                            $arr[$i]['data'] . '_' . $arr[$i + 1]['data']
+                        );
+                        $before .= PMA_Util::showMySQLDocu(
+                            'functions',
+                            $PMA_SQPdata_functions_docs[$tempname]['link'],
+                            false,
+                            $PMA_SQPdata_functions_docs[$tempname]['anchor'],
+                            true
+                        );
+                        $close_docu_link = true;
+                    } else {
+                        $before .= PMA_Util::showMySQLDocu(
+                            'functions',
+                            $PMA_SQPdata_functions_docs[$arr[$i]['data']]['link'],
+                            false,
+                            $PMA_SQPdata_functions_docs[$arr[$i]['data']]['anchor'],
+                            true
+                        );
+                        $after .= '</a>';
+                    }
+                }
+                break;
+            } // end switch ($arr[$i]['data'])
+
+            $after         .= ' ';
+            break;
+        case 'digit_integer':
+        case 'digit_float':
+        case 'digit_hex':
+            /**
+             * @todo could there be other types preceding a digit?
+             */
+            if ($typearr[1] == 'alpha_reservedWord') {
+                $after .= ' ';
+            }
+            if ($infunction && $typearr[3] == 'punct_bracket_close_round') {
+                $after     .= ' ';
+            }
+            if ($typearr[1] == 'alpha_columnAttrib') {
+                $before .= ' ';
+            }
+            break;
+        case 'alpha_variable':
+            $after      = ' ';
+            break;
+        case 'quote_double':
+        case 'quote_single':
+            // workaround: for the query
+            // REVOKE SELECT ON `base2\_db`.* FROM 'user'@'%'
+            // the @ is incorrectly marked as alpha_variable
+            // in the parser, and here, the '%' gets a blank before,
+            // which is a syntax error
+            if ($typearr[1] != 'punct_user'
+                && $typearr[1] != 'alpha_bitfield_constant_introducer'
+            ) {
+                $before        .= ' ';
+            }
+            if ($infunction && $typearr[3] == 'punct_bracket_close_round') {
+                $after     .= ' ';
+            }
+            break;
+        case 'quote_backtick':
+            // here we check for punct_user to handle correctly
+            // DEFINER = `username`@`%`
+            // where @ is the punct_user and `%` is the quote_backtick
+            if ($typearr[3] != 'punct_qualifier'
+                && $typearr[3] != 'alpha_variable'
+                && $typearr[3] != 'punct_user'
+            ) {
+                $after     .= ' ';
+            }
+            if ($typearr[1] != 'punct_qualifier'
+                && $typearr[1] != 'alpha_variable'
+                && $typearr[1] != 'punct_user'
+            ) {
+                $before    .= ' ';
+            }
+            break;
+        default:
+            break;
+        } // end switch ($typearr[2])
+
+        /*
+        if ($typearr[3] != 'punct_qualifier') {
+            $after             .= ' ';
+        }
+        $after                 .= "\n";
+        */
+        $str .= $before;
+        if ($mode=='color') {
+            $str .= PMA_SQP_formatHTML_colorize($arr[$i]);
+        } elseif ($mode == 'text') {
+            $str .= htmlspecialchars($arr[$i]['data']);
+        } else {
+            $str .= $arr[$i]['data'];
+        }
+        $str .= $after;
+    } // end for
+    // close unclosed indent levels
+    while ($indent > 0) {
+        $indent--;
+        $str .= ($mode != 'query_only' ? '</div>' : ' ');
+    }
+    /* End possibly unclosed documentation link */
+    if ($close_docu_link) {
+        $str .= '</a>';
+        $close_docu_link = false;
+    }
+    if ($mode!='query_only') {
+        // close inner_sql span
+            $str .= '</span>';
+    }
+    if ($mode=='color') {
+        // close syntax span
+        $str .= '</span>';
+    }
+
+    return $str;
+} // end of the "PMA_SQP_formatHtml()" function
+
+/**
+ * Gets SQL queries with no format
+ *
+ * @param array $arr The SQL queries list
+ *
+ * @return string  The SQL queries with no format
+ *
+ * @access public
+ */
+function PMA_SQP_formatNone($arr)
+{
+    $formatted_sql = htmlspecialchars($arr['raw']);
+    $formatted_sql = preg_replace(
+        "@((\015\012)|(\015)|(\012)){3,}@",
+        "\n\n",
+        $formatted_sql
+    );
+
+    return $formatted_sql;
+} // end of the "PMA_SQP_formatNone()" function
+
+/**
+ * Checks whether a given name is MySQL reserved word
+ *
+ * @param string $column The word to be checked
+ *
+ * @return boolean whether true or false
+ */
+function PMA_SQP_isKeyWord($column)
+{
+    global $PMA_SQPdata_forbidden_word;
+    return in_array(strtoupper($column), $PMA_SQPdata_forbidden_word);
+}
+
+?>
diff --git a/phpmyadmin/libraries/sqlvalidator.class.php b/phpmyadmin/libraries/sqlvalidator.class.php
new file mode 100644
index 0000000..6c1fb59
--- /dev/null
+++ b/phpmyadmin/libraries/sqlvalidator.class.php
@@ -0,0 +1,457 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * PHP interface to MimerSQL Validator
+ *
+ * Copyright 2002, 2003 Robin Johnson <robbat2 at users.sourceforge.net>
+ * http://www.orbis-terrarum.net/?l=people.robbat2
+ *
+ * All data is transported over HTTP-SOAP
+ * And uses either the PEAR SOAP Module or PHP SOAP extension
+ *
+ * Install instructions for PEAR SOAP:
+ * Make sure you have a really recent PHP with PEAR support
+ * run this: "pear install Mail_Mime Net_DIME SOAP"
+ *
+ * @access   public
+ *
+ * @package PhpMyAdmin
+ */
+if (! defined('PHPMYADMIN')) {
+    exit;
+}
+
+/**
+ * Load SOAP client.
+ */
+if (class_exists('SOAPClient')) {
+    $GLOBALS['sqlvalidator_error'] = false;
+    $GLOBALS['sqlvalidator_soap'] = 'PHP';
+} else {
+    @include_once 'SOAP/Client.php';
+    if (class_exists('SOAP_Client')) {
+        $GLOBALS['sqlvalidator_soap'] = 'PEAR';
+        $GLOBALS['sqlvalidator_error'] = false;
+    } else {
+        $GLOBALS['sqlvalidator_soap'] = 'NONE';
+        $GLOBALS['sqlvalidator_error'] = true;
+        PMA_warnMissingExtension('soap');
+    }
+}
+
+if (!$GLOBALS['sqlvalidator_error']) {
+    // Ok, we have SOAP Support, so let's use it!
+
+    /**
+     * @package PhpMyAdmin
+     */
+    class PMA_SQLValidator
+    {
+        var $url;
+        var $service_name;
+        var $wsdl;
+        var $output_type;
+
+        var $username;
+        var $password;
+        var $calling_program;
+        var $calling_program_version;
+        var $target_dbms;
+        var $target_dbms_version;
+        var $connectionTechnology;
+        var $connection_technology_version;
+        var $interactive;
+
+        var $service_link = null;
+        var $session_data = null;
+
+
+        /**
+         * Private functions - You don't need to mess with these
+         */
+
+        /**
+         * Service opening
+         *
+         * @param string $url URL of Mimer SQL Validator WSDL file
+         *
+         * @return object  Object to use
+         *
+         * @access private
+         */
+        function _openService($url)
+        {
+            if ($GLOBALS['sqlvalidator_soap'] == 'PHP') {
+                $obj = new SOAPClient($url);
+            } else {
+                $obj = new SOAP_Client($url, true);
+            }
+            return $obj;
+        } // end of the "openService()" function
+
+
+        /**
+         * Service initializer to connect to server
+         *
+         * @param object  $obj                           Service object
+         * @param string  $username                      Username
+         * @param string  $password                      Password
+         * @param string  $calling_program               Name of calling program
+         * @param string  $calling_program_version       Version of calling program
+         * @param string  $target_dbms                   Target DBMS
+         * @param string  $target_dbms_version           Version of target DBMS
+         * @param string  $connection_technology         Connection Technology
+         * @param string  $connection_technology_version Con. Technology version
+         * @param integer $interactive                   boolean 1/0 to specify if
+         *                                               we are an interactive system
+         *
+         * @return object   stdClass return object with data
+         *
+         * @access private
+         */
+        function _openSession($obj, $username, $password, $calling_program,
+            $calling_program_version, $target_dbms, $target_dbms_version,
+            $connection_technology, $connection_technology_version, $interactive
+        ) {
+            $use_array = array(
+                "a_userName" => $username,
+                "a_password" => $password,
+                "a_callingProgram" => $calling_program,
+                "a_callingProgramVersion" => $calling_program_version,
+                "a_targetDbms" => $target_dbms,
+                "a_targetDbmsVersion" => $target_dbms_version,
+                "a_connectionTechnology" => $connection_technology,
+                "a_connectionTechnologyVersion" => $connection_technology_version,
+                "a_interactive" => $interactive,
+            );
+
+            if ($GLOBALS['sqlvalidator_soap'] == 'PHP') {
+                $ret = $obj->__soapCall("openSession", $use_array);
+            } else {
+                $ret = $obj->call("openSession", $use_array);
+            }
+
+            return $ret;
+        } // end of the "_openSession()" function
+
+
+        /**
+         * Validator sytem call
+         *
+         * @param object $obj     Service object
+         * @param object $session Session object
+         * @param string $sql     SQL Query to validate
+         * @param string $method  Data return type
+         *
+         * @return object  stClass return with data
+         *
+         * @access private
+         */
+        function _validateSQL($obj, $session, $sql, $method)
+        {
+            $use_array = array(
+                "a_sessionId" => $session->sessionId,
+                "a_sessionKey" => $session->sessionKey,
+                "a_SQL" => $sql,
+                "a_resultType" => $this->output_type,
+            );
+
+            if ($GLOBALS['sqlvalidator_soap'] == 'PHP') {
+                $res = $obj->__soapCall("validateSQL", $use_array);
+            } else {
+                $res = $obj->call("validateSQL", $use_array);
+            }
+
+            return $res;
+        } // end of the "validateSQL()" function
+
+
+        /**
+         * Validator sytem call
+         *
+         * @param string $sql SQL Query to validate
+         *
+         * @return object  stdClass return with data
+         *
+         * @access private
+         *
+         * @see    validateSQL()
+         */
+        function _validate($sql)
+        {
+            $ret = $this->_validateSQL(
+                $this->service_link, $this->session_data, $sql, $this->output_type
+            );
+            return $ret;
+        } // end of the "validate()" function
+
+
+        /**
+         * Public functions
+         */
+
+        /**
+         * Constructor
+         *
+         * @access public
+         */
+        function __construct()
+        {
+            $this->url                           = 'http://sqlvalidator.mimer.com/v1/services';
+            $this->service_name                  = 'SQL99Validator';
+            $this->wsdl                          = '?wsdl';
+
+            $this->output_type                   = 'html';
+
+            $this->username                      = 'anonymous';
+            $this->password                      = '';
+            $this->calling_program               = 'PHP_SQLValidator';
+            $this->calling_program_version       = PMA_VERSION;
+            $this->target_dbms                   = 'N/A';
+            $this->target_dbms_version           = 'N/A';
+            $this->connection_technology         = 'PHP';
+            $this->connection_technology_version = phpversion();
+            $this->interactive = 1;
+
+            $this->service_link = null;
+            $this->session_data = null;
+        } // end of the "PMA_SQLValidator()" function
+
+
+        /**
+         * Sets credentials
+         *
+         * @param string $username the username
+         * @param string $password the password
+         *
+         * @return void
+         * @access public
+         */
+        function setCredentials($username, $password)
+        {
+            $this->username = $username;
+            $this->password = $password;
+        } // end of the "setCredentials()" function
+
+
+        /**
+         * Sets the calling program
+         *
+         * @param string $calling_program         the calling program name
+         * @param string $calling_program_version the calling program revision
+         *
+         * @return void
+         * @access public
+         */
+        function setCallingProgram($calling_program, $calling_program_version)
+        {
+            $this->calling_program         = $calling_program;
+            $this->calling_program_version = $calling_program_version;
+        } // end of the "setCallingProgram()" function
+
+
+        /**
+         * Appends the calling program
+         *
+         * @param string $calling_program         the calling program name
+         * @param string $calling_program_version the calling program revision
+         *
+         * @return void
+         * @access public
+         */
+        function appendCallingProgram($calling_program, $calling_program_version)
+        {
+            $this->calling_program         .= ' - ' . $calling_program;
+            $this->calling_program_version .= ' - ' . $calling_program_version;
+        } // end of the "appendCallingProgram()" function
+
+
+        /**
+         * Sets the target DBMS
+         *
+         * @param string $target_dbms         the target DBMS name
+         * @param string $target_dbms_version the target DBMS revision
+         *
+         * @return void
+         * @access public
+         */
+        function setTargetDbms($target_dbms, $target_dbms_version)
+        {
+            $this->target_dbms         = $target_dbms;
+            $this->target_dbms_version = $target_dbms_version;
+        } // end of the "setTargetDbms()" function
+
+
+        /**
+         * Appends the target DBMS
+         *
+         * @param string $target_dbms         the target DBMS name
+         * @param string $target_dbms_version the target DBMS revision
+         *
+         * @return void
+         * @access public
+         */
+        function appendTargetDbms($target_dbms, $target_dbms_version)
+        {
+            $this->target_dbms         .= ' - ' . $target_dbms;
+            $this->target_dbms_version .= ' - ' . $target_dbms_version;
+        } // end of the "appendTargetDbms()" function
+
+
+        /**
+         * Sets the connection technology used
+         *
+         * @param string $connection_technology         the con. technology name
+         * @param string $connection_technology_version the con. technology revision
+         *
+         * @return void
+         * @access public
+         */
+        function setConnectionTechnology(
+            $connection_technology, $connection_technology_version
+        ) {
+            $this->connection_technology         = $connection_technology;
+            $this->connection_technology_version = $connection_technology_version;
+        } // end of the "setConnectionTechnology()" function
+
+
+        /**
+         * Appends the connection technology used
+         *
+         * @param string $connection_technology         the con. technology name
+         * @param string $connection_technology_version the con. technology revision
+         *
+         * @return void
+         * @access public
+         */
+        function appendConnectionTechnology(
+            $connection_technology, $connection_technology_version
+        ) {
+            $this->connection_technology         .= ' - ' . $connection_technology;
+            $this->connection_technology_version .= ' - ' . $connection_technology_version;
+        } // end of the "appendConnectionTechnology()" function
+
+
+        /**
+         * Sets whether interactive mode should be used or not
+         *
+         * @param integer $interactive whether interactive mode should be used or not
+         *
+         * @return void
+         * @access public
+         */
+        function setInteractive($interactive)
+        {
+            $this->interactive = $interactive;
+        } // end of the "setInteractive()" function
+
+
+        /**
+         * Sets the output type to use
+         *
+         * @param string $output_type the output type to use
+         *
+         * @return void
+         * @access public
+         */
+        function setOutputType($output_type)
+        {
+            $this->output_type = $output_type;
+        } // end of the "setOutputType()" function
+
+
+        /**
+         * Starts service
+         *
+         * @return void
+         * @access public
+         */
+        function startService()
+        {
+            $this->service_link = $this->_openService(
+                $this->url . '/' . $this->service_name . $this->wsdl
+            );
+        } // end of the "startService()" function
+
+
+        /**
+         * Starts session
+         *
+         * @return void
+         * @access public
+         */
+        function startSession()
+        {
+            $this->session_data = $this->_openSession(
+                $this->service_link, $this->username, $this->password,
+                $this->calling_program, $this->calling_program_version,
+                $this->target_dbms, $this->target_dbms_version,
+                $this->connection_technology, $this->connection_technology_version,
+                true // FIXME: Are we to tell them that we are interactive?
+            );
+
+            if (isset($this->session_data)
+                && ($this->session_data != null)
+                && ($this->session_data->target != $this->url)
+            ) {
+                // Reopens the service on the new URL that was provided
+                $url = $this->session_data->target;
+                $this->startService();
+            }
+        } // end of the "startSession()" function
+
+
+        /**
+         * Do start service and session
+         *
+         * @return void
+         * @access public
+         */
+        function start()
+        {
+            $this->startService();
+            $this->startSession();
+        } // end of the "start()" function
+
+
+        /**
+         * Call to determine just if a query is valid or not.
+         *
+         * @param string $sql SQL statement to validate
+         *
+         * @return string Validator string from Mimer
+         *
+         * @see _validate
+         */
+        function isValid($sql)
+        {
+            $res = $this->_validate($sql);
+            return $res->standard;
+        } // end of the "isValid()" function
+
+
+        /**
+         * Call for complete validator response
+         *
+         * @param string $sql SQL statement to validate
+         *
+         * @return string Validator string from Mimer
+         *
+         * @see _validate
+         */
+        function validationString($sql)
+        {
+            $res = $this->_validate($sql);
+            return $res->data;
+
+        } // end of the "validationString()" function
+    } // end class PMA_SQLValidator
+
+    //add an extra check to ensure that the class was defined without errors
+    if (!class_exists('PMA_SQLValidator')) {
+        $GLOBALS['sqlvalidator_error'] = true;
+    }
+
+} // end else
+
+?>
diff --git a/phpmyadmin/libraries/sqlvalidator.lib.php b/phpmyadmin/libraries/sqlvalidator.lib.php
new file mode 100644
index 0000000..de55e9a
--- /dev/null
+++ b/phpmyadmin/libraries/sqlvalidator.lib.php
@@ -0,0 +1,106 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * SQL Validator interface for phpMyAdmin
+ *
+ * Copyright 2002 Robin Johnson <robbat2 at users.sourceforge.net>
+ * http://www.orbis-terrarum.net/?l=people.robbat2
+ *
+ * This function uses the Mimer SQL Validator service
+ * <http://developer.mimer.com/validator/index.htm> from phpMyAdmin
+ *
+ * Copyright for Server side validator systems:
+ * "All SQL statements are stored anonymously for statistical purposes.
+ * Mimer SQL Validator, Copyright 2002 Upright Database Technology.
+ * All rights reserved."
+ *
+ * All data is transported over HTTP-SOAP
+ * And uses the PEAR SOAP Module
+ *
+ * Install instructions for PEAR SOAP
+ * Make sure you have a really recent PHP with PEAR support
+ * run this: "pear install Mail_Mime Net_DIME SOAP"
+ *
+ * Enable the SQL Validator options in the configuration file
+ * $cfg['SQLQuery']['Validate'] = true;
+ * $cfg['SQLValidator']['use']  = true;
+ *
+ * Also set a username and password if you have a private one
+ *
+ * @package PhpMyAdmin
+ */
+if (! defined('PHPMYADMIN')) {
+    exit;
+}
+
+/**
+ * We need the PEAR libraries, so do a minimum version check first
+ * I'm not sure if PEAR was available before this point
+ * For now we actually use a configuration flag
+ */
+if ($cfg['SQLValidator']['use'] == true) {
+    include_once './libraries/sqlvalidator.class.php';
+} // if ($cfg['SQLValidator']['use'] == true)
+
+
+/**
+ * This function utilizes the Mimer SQL Validator service
+ * to validate an SQL query
+ *
+ * <http://developer.mimer.com/validator/index.htm>
+ *
+ * @param string $sql SQL query to validate
+ *
+ * @return string Validator result string
+ *
+ * @global array The PMA configuration array
+ */
+function PMA_validateSQL($sql)
+{
+    global $cfg;
+
+    $str = '';
+
+    if ($cfg['SQLValidator']['use']) {
+        if (isset($GLOBALS['sqlvalidator_error'])
+            && $GLOBALS['sqlvalidator_error']
+        ) {
+            $str = sprintf(
+                __('The SQL validator could not be initialized. Please check if you have installed the necessary PHP extensions as described in the %sdocumentation%s.'),
+                '<a href="' . PMA_Util::getDocuLink('faq', 'faqsqlvalidator') .  '" target="documentation">',
+                '</a>'
+            );
+        } else {
+            // create new class instance
+            $srv = new PMA_SQLValidator();
+
+            // Checks for username settings
+            // The class defaults to anonymous with an empty password
+            // automatically
+            if ($cfg['SQLValidator']['username'] != '') {
+                $srv->setCredentials(
+                    $cfg['SQLValidator']['username'],
+                    $cfg['SQLValidator']['password']
+                );
+            }
+
+            // Identify ourselves to the server properly...
+            $srv->appendCallingProgram('phpMyAdmin', PMA_VERSION);
+
+            // ... and specify what database system we are using
+            $srv->setTargetDbms('MySQL', PMA_MYSQL_STR_VERSION);
+
+            // Log on to service
+            $srv->start();
+
+            // Do service validation
+            $str = $srv->validationString($sql);
+        }
+
+    } // end if
+
+    // Gives string back to caller
+    return $str;
+} // end of the "PMA_validateSQL()" function
+
+?>
diff --git a/phpmyadmin/libraries/string.lib.php b/phpmyadmin/libraries/string.lib.php
new file mode 100644
index 0000000..6045016
--- /dev/null
+++ b/phpmyadmin/libraries/string.lib.php
@@ -0,0 +1,101 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * Specialized String Functions for phpMyAdmin
+ *
+ * Defines a set of function callbacks that have a pure C version available if
+ * the "ctype" extension is available, but otherwise have PHP versions to use
+ * (that are slower).
+ *
+ * The SQL Parser code relies heavily on these functions.
+ *
+ * @todo a .lib filename should not have code in main(), split or rename file
+ * @package PhpMyAdmin-String
+ */
+if (! defined('PHPMYADMIN')) {
+    exit;
+}
+
+/**
+ * Load proper code for handling input.
+ */
+if (@function_exists('mb_strlen')) {
+    mb_internal_encoding('utf-8');
+    include './libraries/string_mb.lib.php';
+} else {
+    include './libraries/string_native.lib.php';
+}
+
+/**
+ * Load ctype handler.
+ */
+if (@extension_loaded('ctype')) {
+    include './libraries/string_type_ctype.lib.php';
+} else {
+    include './libraries/string_type_native.lib.php';
+}
+
+/**
+ * Checks if a given character position in the string is escaped or not
+ *
+ * @param string  $string string to check for
+ * @param integer $pos    the character to check for
+ * @param integer $start  starting position in the string
+ *
+ * @return boolean  whether the character is escaped or not
+ */
+function PMA_STR_charIsEscaped($string, $pos, $start = 0)
+{
+    $pos = max(intval($pos), 0);
+    $start = max(intval($start), 0);
+    $len = PMA_strlen($string);
+    // Base case:
+    // Check for string length or invalid input or special case of input
+    // (pos == $start)
+    if ($pos <= $start || $len <= max($pos, $start)) {
+        return false;
+    }
+
+    $pos--;
+    $escaped     = false;
+    while ($pos >= $start && PMA_substr($string, $pos, 1) == '\\') {
+        $escaped = !$escaped;
+        $pos--;
+    } // end while
+
+    return $escaped;
+} // end of the "PMA_STR_charIsEscaped()" function
+
+
+/**
+ * Checks if a number is in a range
+ *
+ * @param integer $num   number to check for
+ * @param integer $lower lower bound
+ * @param integer $upper upper bound
+ *
+ * @return boolean  whether the number is in the range or not
+ */
+function PMA_STR_numberInRangeInclusive($num, $lower, $upper)
+{
+    return ($num >= $lower && $num <= $upper);
+} // end of the "PMA_STR_numberInRangeInclusive()" function
+
+/**
+ * Checks if a character is an SQL identifier
+ *
+ * @param string  $c            character to check for
+ * @param boolean $dot_is_valid whether the dot character is valid or not
+ *
+ * @return boolean  whether the character is an SQL identifier or not
+ */
+function PMA_STR_isSqlIdentifier($c, $dot_is_valid = false)
+{
+    return (PMA_STR_isAlnum($c)
+        || ($ord_c = ord($c)) && $ord_c >= 192 && $ord_c != 215 && $ord_c != 249
+        || $c == '_'
+        || $c == '$'
+        || ($dot_is_valid != false && $c == '.'));
+} // end of the "PMA_STR_isSqlIdentifier()" function
+
+?>
diff --git a/phpmyadmin/libraries/string_mb.lib.php b/phpmyadmin/libraries/string_mb.lib.php
new file mode 100644
index 0000000..452debf
--- /dev/null
+++ b/phpmyadmin/libraries/string_mb.lib.php
@@ -0,0 +1,71 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * Specialized String Functions for phpMyAdmin
+ *
+ * Defines a set of function callbacks that have a pure C version available if
+ * the "ctype" extension is available, but otherwise have PHP versions to use
+ * (that are slower).
+ *
+ * The SQL Parser code relies heavily on these functions.
+ *
+ * @package    PhpMyAdmin-String
+ * @subpackage MB
+ */
+if (! defined('PHPMYADMIN')) {
+    exit;
+}
+
+/**
+ * Returns length of string depending on current charset.
+ *
+ * @param string $string string to count
+ *
+ * @return int string length
+ */
+function PMA_strlen($string)
+{
+    return mb_strlen($string);
+}
+
+/**
+ * Returns substring from string, works depending on current charset.
+ *
+ * @param string $string string to count
+ * @param int    $start  start of substring
+ * @param int    $length length of substring
+ *
+ * @return string the sub string
+ */
+function PMA_substr($string, $start, $length = 2147483647)
+{
+    return mb_substr($string, $start, $length);
+}
+
+/**
+ * Returns postion of $needle in $haystack or false if not found
+ *
+ * @param string $haystack the string being checked
+ * @param string $needle   the string to find in haystack
+ * @param int    $offset   the search offset
+ *
+ * @return integer position of $needle in $haystack or false
+ */
+function PMA_strpos($haystack, $needle, $offset = 0)
+{
+    return mb_strpos($haystack, $needle, $offset);
+}
+
+/**
+ * Make a string lowercase
+ *
+ * @param string $string the string being lowercased
+ *
+ * @return string the lower case string
+ */
+function PMA_strtolower($string)
+{
+    return mb_strtolower($string);
+}
+
+?>
diff --git a/phpmyadmin/libraries/string_native.lib.php b/phpmyadmin/libraries/string_native.lib.php
new file mode 100644
index 0000000..4154959
--- /dev/null
+++ b/phpmyadmin/libraries/string_native.lib.php
@@ -0,0 +1,71 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * Specialized String Functions for phpMyAdmin
+ *
+ * Defines a set of function callbacks that have a pure C version available if
+ * the "ctype" extension is available, but otherwise have PHP versions to use
+ * (that are slower).
+ *
+ * The SQL Parser code relies heavily on these functions.
+ *
+ * @package    PhpMyAdmin-String
+ * @subpackage Native
+ */
+if (! defined('PHPMYADMIN')) {
+    exit;
+}
+
+/**
+ * Returns length of string depending on current charset.
+ *
+ * @param string $string string to count
+ *
+ * @return int string length
+ */
+function PMA_strlen($string)
+{
+    return strlen($string);
+}
+
+/**
+ * Returns substring from string, works depending on current charset.
+ *
+ * @param string $string string to count
+ * @param int    $start  start of substring
+ * @param int    $length length of substring
+ *
+ * @return string the sub string
+ */
+function PMA_substr($string, $start, $length = 2147483647)
+{
+    return substr($string, $start, $length);
+}
+
+/**
+ * Returns postion of $needle in $haystack or false if not found
+ *
+ * @param string $haystack the string being checked
+ * @param string $needle   the string to find in haystack
+ * @param int    $offset   the search offset
+ *
+ * @return integer position of $needle in $haystack or false
+ */
+function PMA_strpos($haystack, $needle, $offset = 0)
+{
+    return strpos($haystack, $needle, $offset);
+}
+
+/**
+ * Make a string lowercase
+ *
+ * @param string $string the string being lowercased
+ *
+ * @return string the lower case string
+ */
+function PMA_strtolower($string)
+{
+    return strtolower($string);
+}
+
+?>
diff --git a/phpmyadmin/libraries/string_type_ctype.lib.php b/phpmyadmin/libraries/string_type_ctype.lib.php
new file mode 100644
index 0000000..12469ba
--- /dev/null
+++ b/phpmyadmin/libraries/string_type_ctype.lib.php
@@ -0,0 +1,104 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * Specialized String Functions for phpMyAdmin
+ *
+ * Defines a set of function callbacks that have a pure C version available if
+ * the "ctype" extension is available, but otherwise have PHP versions to use
+ * (that are slower).
+ *
+ * The SQL Parser code relies heavily on these functions.
+ *
+ * @package    PhpMyAdmin-String
+ * @subpackage CType
+ */
+if (! defined('PHPMYADMIN')) {
+    exit;
+}
+
+/**
+ * Checks if a character is an alphanumeric one
+ *
+ * @param string $c character to check for
+ *
+ * @return boolean whether the character is an alphanumeric one or not
+ */
+function PMA_STR_isAlnum($c)
+{
+    return ctype_alnum($c);
+} // end of the "PMA_STR_isAlnum()" function
+
+/**
+ * Checks if a character is an alphabetic one
+ *
+ * @param string $c character to check for
+ *
+ * @return boolean whether the character is an alphabetic one or not
+ */
+function PMA_STR_isAlpha($c)
+{
+    return ctype_alpha($c);
+} // end of the "PMA_STR_isAlpha()" function
+
+/**
+ * Checks if a character is a digit
+ *
+ * @param string $c character to check for
+ *
+ * @return boolean whether the character is a digit or not
+ */
+function PMA_STR_isDigit($c)
+{
+    return ctype_digit($c);
+} // end of the "PMA_STR_isDigit()" function
+
+/**
+ * Checks if a character is an upper alphabetic one
+ *
+ * @param string $c character to check for
+ *
+ * @return boolean whether the character is an upper alphabetic one or not
+ */
+function PMA_STR_isUpper($c)
+{
+    return ctype_upper($c);
+} // end of the "PMA_STR_isUpper()" function
+
+
+/**
+ * Checks if a character is a lower alphabetic one
+ *
+ * @param string $c character to check for
+ *
+ * @return boolean whether the character is a lower alphabetic one or not
+ */
+function PMA_STR_isLower($c)
+{
+    return ctype_lower($c);
+} // end of the "PMA_STR_isLower()" function
+
+/**
+ * Checks if a character is a space one
+ *
+ * @param string $c character to check for
+ *
+ * @return boolean whether the character is a space one or not
+ */
+function PMA_STR_isSpace($c)
+{
+    return ctype_space($c);
+} // end of the "PMA_STR_isSpace()" function
+
+/**
+ * Checks if a character is an hexadecimal digit
+ *
+ * @param string $c character to check for
+ *
+ * @return boolean whether the character is an hexadecimal digit or not
+ */
+function PMA_STR_isHexDigit($c)
+{
+    return ctype_xdigit($c);
+} // end of the "PMA_STR_isHexDigit()" function
+
+?>
diff --git a/phpmyadmin/libraries/string_type_native.lib.php b/phpmyadmin/libraries/string_type_native.lib.php
new file mode 100644
index 0000000..4267a19
--- /dev/null
+++ b/phpmyadmin/libraries/string_type_native.lib.php
@@ -0,0 +1,133 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * Specialized String Functions for phpMyAdmin
+ *
+ * Defines a set of function callbacks that have a pure C version available if
+ * the "ctype" extension is available, but otherwise have PHP versions to use
+ * (that are slower).
+ *
+ * The SQL Parser code relies heavily on these functions.
+ *
+ * @package    PhpMyAdmin-String
+ * @subpackage Native
+ */
+if (! defined('PHPMYADMIN')) {
+    exit;
+}
+
+/**
+ * Checks if a character is an alphanumeric one
+ *
+ * @param string $c character to check for
+ *
+ * @return boolean whether the character is an alphanumeric one or not
+ */
+function PMA_STR_isAlnum($c)
+{
+    return (PMA_STR_isUpper($c) || PMA_STR_isLower($c) || PMA_STR_isDigit($c));
+} // end of the "PMA_STR_isAlnum()" function
+
+/**
+ * Checks if a character is an alphabetic one
+ *
+ * @param string $c character to check for
+ *
+ * @return boolean whether the character is an alphabetic one or not
+ */
+function PMA_STR_isAlpha($c)
+{
+    return (PMA_STR_isUpper($c) || PMA_STR_isLower($c));
+} // end of the "PMA_STR_isAlpha()" function
+
+/**
+ * Checks if a character is a digit
+ *
+ * @param string $c character to check for
+ *
+ * @return boolean whether the character is a digit or not
+ */
+function PMA_STR_isDigit($c)
+{
+    $ord_zero = 48; //ord('0');
+    $ord_nine = 57; //ord('9');
+    $ord_c    = ord($c);
+
+    return PMA_STR_numberInRangeInclusive($ord_c, $ord_zero, $ord_nine);
+} // end of the "PMA_STR_isDigit()" function
+
+/**
+ * Checks if a character is an upper alphabetic one
+ *
+ * @param string $c character to check for
+ *
+ * @return boolean whether the character is an upper alphabetic one or not
+ */
+function PMA_STR_isUpper($c)
+{
+    $ord_zero = 65; //ord('A');
+    $ord_nine = 90; //ord('Z');
+    $ord_c    = ord($c);
+
+    return PMA_STR_numberInRangeInclusive($ord_c, $ord_zero, $ord_nine);
+} // end of the "PMA_STR_isUpper()" function
+
+/**
+ * Checks if a character is a lower alphabetic one
+ *
+ * @param string $c character to check for
+ *
+ * @return boolean whether the character is a lower alphabetic one or not
+ */
+function PMA_STR_isLower($c)
+{
+    $ord_zero = 97;  //ord('a');
+    $ord_nine = 122; //ord('z');
+    $ord_c    = ord($c);
+
+    return PMA_STR_numberInRangeInclusive($ord_c, $ord_zero, $ord_nine);
+} // end of the "PMA_STR_isLower()" function
+
+/**
+ * Checks if a character is a space one
+ *
+ * @param string $c character to check for
+ *
+ * @return boolean whether the character is a space one or not
+ */
+function PMA_STR_isSpace($c)
+{
+    $ord_space = 32;    //ord(' ')
+    $ord_tab   = 9;     //ord('\t')
+    $ord_CR    = 13;    //ord('\n')
+    $ord_NOBR  = 160;   //ord('U+00A0);
+    $ord_c     = ord($c);
+
+    return ($ord_c == $ord_space
+        || $ord_c == $ord_NOBR
+        || PMA_STR_numberInRangeInclusive($ord_c, $ord_tab, $ord_CR));
+} // end of the "PMA_STR_isSpace()" function
+
+/**
+ * Checks if a character is an hexadecimal digit
+ *
+ * @param string $c character to check for
+ *
+ * @return boolean whether the character is an hexadecimal digit or not
+ */
+function PMA_STR_isHexDigit($c)
+{
+    $ord_Aupper = 65;  //ord('A');
+    $ord_Fupper = 70;  //ord('F');
+    $ord_Alower = 97;  //ord('a');
+    $ord_Flower = 102; //ord('f');
+    $ord_zero   = 48;  //ord('0');
+    $ord_nine   = 57;  //ord('9');
+    $ord_c      = ord($c);
+
+    return (PMA_STR_numberInRangeInclusive($ord_c, $ord_zero, $ord_nine)
+        || PMA_STR_numberInRangeInclusive($ord_c, $ord_Aupper, $ord_Fupper)
+        || PMA_STR_numberInRangeInclusive($ord_c, $ord_Alower, $ord_Flower));
+} // end of the "PMA_STR_isHexDigit()" function
+
+?>
diff --git a/phpmyadmin/libraries/structure.lib.php b/phpmyadmin/libraries/structure.lib.php
new file mode 100644
index 0000000..e6d76dd
--- /dev/null
+++ b/phpmyadmin/libraries/structure.lib.php
@@ -0,0 +1,2513 @@
+<?php
+
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * set of functions for structure section in pma
+ *
+ * @package PhpMyAdmin
+ */
+if (!defined('PHPMYADMIN')) {
+    exit;
+}
+
+/**
+ * Get the HTML links for action links
+ * Actions are, Browse, Search, Browse table label, empty table
+ *
+ * @param array   $current_table            current table
+ * @param boolean $table_is_view            Is table view or not
+ * @param string  $tbl_url_query            table url query
+ * @param array   $titles                   titles and icons for action links
+ * @param string  $truename                 table name
+ * @param boolean $db_is_information_schema is database information schema or not
+ * @param string  $url_query                url query
+ *
+ * @return array ($browse_table, $search_table, $browse_table_label, $empty_table,
+ *                $tracking_icon)
+ */
+function PMA_getHtmlForActionLinks($current_table, $table_is_view, $tbl_url_query,
+    $titles, $truename, $db_is_information_schema, $url_query
+) {
+    $empty_table = '';
+
+    if ($current_table['TABLE_ROWS'] > 0 || $table_is_view) {
+        $may_have_rows = true;
+    } else {
+        $may_have_rows = false;
+    }
+
+    $browse_table = '<a href="sql.php?' . $tbl_url_query . '&pos=0">';
+    if ($may_have_rows) {
+        $browse_table .= $titles['Browse'];
+    } else {
+        $browse_table .= $titles['NoBrowse'];
+    }
+    $browse_table .= '</a>';
+
+    $search_table = '<a href="tbl_select.php?' . $tbl_url_query . '">';
+    if ($may_have_rows) {
+        $search_table .= $titles['Search'];
+    } else {
+        $search_table .= $titles['NoSearch'];
+    }
+    $search_table .= '</a>';
+
+    $browse_table_label = '<a href="sql.php?' . $tbl_url_query . '&pos=0">'
+        . $truename . '</a>';
+
+    if (!$db_is_information_schema) {
+        $empty_table = '<a class="truncate_table_anchor ajax"';
+        $empty_table .= ' href="sql.php?' . $tbl_url_query
+            . '&sql_query=';
+        $empty_table .= urlencode(
+            'TRUNCATE ' . PMA_Util::backquote($current_table['TABLE_NAME'])
+        );
+        $empty_table .= '&message_to_show='
+            . urlencode(
+                sprintf(
+                    __('Table %s has been emptied'),
+                    htmlspecialchars($current_table['TABLE_NAME'])
+                )
+            )
+            . '">';
+        if ($may_have_rows) {
+            $empty_table .= $titles['Empty'];
+        } else {
+            $empty_table .= $titles['NoEmpty'];
+        }
+        $empty_table .= '</a>';
+        // truncating views doesn't work
+        if ($table_is_view) {
+            $empty_table = ' ';
+        }
+    }
+
+    $tracking_icon = '';
+    if (PMA_Tracker::isActive()) {
+        if (PMA_Tracker::isTracked($GLOBALS["db"], $truename)) {
+            $tracking_icon = '<a href="tbl_tracking.php?' . $url_query
+                . '&table=' . $truename . '">'
+                . PMA_Util::getImage(
+                    'eye.png', __('Tracking is active.')
+                )
+                . '</a>';
+        } elseif (PMA_Tracker::getVersion($GLOBALS["db"], $truename) > 0) {
+            $tracking_icon = '<a href="tbl_tracking.php?' . $url_query
+                . '&table=' . $truename . '">'
+                . PMA_Util::getImage(
+                    'eye_grey.png', __('Tracking is not active.')
+                )
+                . '</a>';
+        }
+    }
+
+    return array($browse_table,
+        $search_table,
+        $browse_table_label,
+        $empty_table,
+        $tracking_icon
+    );
+}
+
+/**
+ * Get table drop query and drop message
+ *
+ * @param boolean $table_is_view Is table view or not
+ * @param string  $current_table current table
+ *
+ * @return array    ($drop_query, $drop_message)
+ */
+function PMA_getTableDropQueryAndMessage($table_is_view, $current_table)
+{
+    $drop_query = 'DROP '
+        . (($table_is_view || $current_table['ENGINE'] == null) ? 'VIEW' : 'TABLE')
+        . ' ' . PMA_Util::backquote(
+            $current_table['TABLE_NAME']
+        );
+    $drop_message = sprintf(
+        (($table_is_view || $current_table['ENGINE'] == null)
+            ? __('View %s has been dropped')
+            : __('Table %s has been dropped')),
+        str_replace(
+            ' ',
+            ' ',
+            htmlspecialchars($current_table['TABLE_NAME'])
+        )
+    );
+    return array($drop_query, $drop_message);
+}
+
+/**
+ * Get HTML body for table summery
+ *
+ * @param integer $num_tables               number of tables
+ * @param boolean $server_slave_status      server slave state
+ * @param boolean $db_is_information_schema whether database is information
+ *                                          schema or not
+ * @param integer $sum_entries              sum entries
+ * @param string  $db_collation             collation of given db
+ * @param boolean $is_show_stats            whether stats is show or not
+ * @param double  $sum_size                 sum size
+ * @param double  $overhead_size            overhead size
+ * @param string  $create_time_all          create time
+ * @param string  $update_time_all          update time
+ * @param string  $check_time_all           check time
+ * @param integer $sum_row_count_pre        sum row count pre
+ *
+ * @return string $html_output
+ */
+function PMA_getHtmlBodyForTableSummary($num_tables, $server_slave_status,
+    $db_is_information_schema, $sum_entries, $db_collation, $is_show_stats,
+    $sum_size, $overhead_size, $create_time_all, $update_time_all,
+    $check_time_all, $sum_row_count_pre
+) {
+    if ($is_show_stats) {
+        list($sum_formatted, $unit) = PMA_Util::formatByteDown(
+            $sum_size, 3, 1
+        );
+        list($overhead_formatted, $overhead_unit)
+            = PMA_Util::formatByteDown($overhead_size, 3, 1);
+    }
+
+    $html_output = '<tbody id="tbl_summary_row">'
+        . '<tr><th></th>';
+    $html_output .= '<th class="tbl_num nowrap">';
+    $html_output .= sprintf(
+        _ngettext('%s table', '%s tables', $num_tables),
+        PMA_Util::formatNumber($num_tables, 0)
+    );
+    $html_output .= '</th>';
+
+    if ($server_slave_status) {
+        $html_output .= '<th>' . __('Replication') . '</th>' . "\n";
+    }
+    $html_output .= '<th colspan="'. ($db_is_information_schema ? 3 : 6) . '">'
+        . __('Sum')
+        . '</th>';
+    $html_output .= '<th class="value tbl_rows">'
+        . $sum_row_count_pre . PMA_Util::formatNumber($sum_entries, 0)
+        . '</th>';
+
+    if (!($GLOBALS['cfg']['PropertiesNumColumns'] > 1)) {
+        $default_engine = PMA_DBI_fetch_value(
+            'SHOW VARIABLES LIKE \'storage_engine\';',
+            0,
+            1
+        );
+        $html_output .=  '<th class="center">' . "\n"
+            . '<dfn title="'
+            . sprintf(
+                __('%s is the default storage engine on this MySQL server.'),
+                $default_engine
+            )
+            . '">' .$default_engine . '</dfn></th>' . "\n";
+        // we got a case where $db_collation was empty
+        $html_output .= '<th>' . "\n";
+
+        if (! empty($db_collation)) {
+            $html_output .= '<dfn title="'
+                . PMA_getCollationDescr($db_collation)
+                . ' (' . __('Default') . ')">'
+                . $db_collation
+                . '</dfn>';
+        }
+        $html_output .= '</th>';
+    }
+    if ($is_show_stats) {
+        $html_output .= '<th class="value tbl_size">'
+            . $sum_formatted . ' ' . $unit
+            . '</th>';
+        $html_output .= '<th class="value tbl_overhead">'
+            . $overhead_formatted . ' ' . $overhead_unit
+            . '</th>';
+    }
+
+    if ($GLOBALS['cfg']['ShowDbStructureCreation']) {
+        $html_output .= '<th class="value tbl_creation">' . "\n"
+            . '        '
+            . ($create_time_all
+                ? PMA_Util::localisedDate(strtotime($create_time_all))
+                : '-'
+            )
+            . '</th>';
+    }
+
+    if ($GLOBALS['cfg']['ShowDbStructureLastUpdate']) {
+        $html_output .= '<th class="value tbl_last_update">' . "\n"
+            . '        '
+            . ($update_time_all
+                ? PMA_Util::localisedDate(strtotime($update_time_all))
+                : '-'
+            )
+            . '</th>';
+    }
+
+    if ($GLOBALS['cfg']['ShowDbStructureLastCheck']) {
+        $html_output .= '<th class="value tbl_last_check">' . "\n"
+            . '        '
+            . ($check_time_all
+                ? PMA_Util::localisedDate(strtotime($check_time_all))
+                : '-'
+            )
+            . '</th>';
+    }
+    $html_output .= '</tr>'
+        . '</tbody>';
+
+    return $html_output;
+}
+
+/**
+ * Get HTML for "check all" check box with "with selected" dropdown
+ *
+ * @param string  $pmaThemeImage            pma theme image url
+ * @param string  $text_dir                 url for text directory
+ * @param string  $overhead_check           overhead check
+ * @param boolean $db_is_information_schema whether database is information
+ *                                          schema or not
+ * @param string  $hidden_fields            hidden fields
+ *
+ * @return string $html_output
+ */
+function PMA_getHtmlForCheckAllTables($pmaThemeImage, $text_dir,
+    $overhead_check, $db_is_information_schema, $hidden_fields
+) {
+    $html_output = '<div class="clearfloat">';
+    $html_output .= '<img class="selectallarrow" '
+        . 'src="' .$pmaThemeImage .'arrow_'.$text_dir.'.png' . '"'
+        . 'width="38" height="22" alt="' . __('With selected:') . '" />';
+
+    $html_output .= '<input type="checkbox" id="checkall" '
+        . 'title="' . __('Check All') .'" />';
+    $html_output .= '<label for="checkall">' .__('Check All') . '</label>';
+
+    if ($overhead_check != '') {
+        $html_output .= PMA_getHtmlForCheckTablesHavingOverheadlink(
+            $overhead_check
+        );
+    }
+
+    $html_output .= '<select name="submit_mult" class="autosubmit" '
+        . 'style="margin: 0 3em 0 3em;">';
+
+    $html_output .= '<option value="' . __('With selected:')
+        . '" selected="selected">'
+        . __('With selected:') . '</option>' . "\n";
+    $html_output .= '<option value="export" >'
+        . __('Export') . '</option>' . "\n";
+    $html_output .= '<option value="print" >'
+        . __('Print view') . '</option>' . "\n";
+
+    if (!$db_is_information_schema
+        && !$GLOBALS['cfg']['DisableMultiTableMaintenance']
+    ) {
+        $html_output .= '<option value="empty_tbl" >'
+            . __('Empty') . '</option>' . "\n";
+        $html_output .= '<option value="drop_tbl" >'
+            . __('Drop') . '</option>' . "\n";
+        $html_output .= '<option value="check_tbl" >'
+            . __('Check table') . '</option>' . "\n";
+        if (!PMA_DRIZZLE) {
+            $html_output .= '<option value="optimize_tbl" >'
+                . __('Optimize table') . '</option>' . "\n";
+            $html_output .= '<option value="repair_tbl" >'
+                . __('Repair table') . '</option>' . "\n";
+        }
+        $html_output .= '<option value="analyze_tbl" >'
+            . __('Analyze table') . '</option>' . "\n";
+        $html_output .= '<option value="add_prefix_tbl" >'
+            . __('Add prefix to table') . '</option>' . "\n";
+        $html_output .= '<option value="replace_prefix_tbl" >'
+            . __('Replace table prefix') . '</option>' . "\n";
+        $html_output .= '<option value="copy_tbl_change_prefix" >'
+            . __('Copy table with prefix') . '</option>' . "\n";
+    }
+    $html_output .= '</select>'
+        . implode("\n", $hidden_fields) . "\n";
+    $html_output .= '</div>';
+
+    return $html_output;
+}
+
+/**
+ * Get HTML code for "Check tables having overhead" link
+ *
+ * @param string $overhead_check overhead check
+ *
+ * @return string $html_output
+ */
+function PMA_getHtmlForCheckTablesHavingOverheadlink($overhead_check)
+{
+    return ' / '
+        . '<a href="#" onclick="unMarkAllRows(\'tablesForm\');'
+        . $overhead_check . 'return false;">'
+        . __('Check tables having overhead')
+        . '</a>';
+}
+
+
+/**
+ * Get HTML links for "Print view" options
+ *
+ * @param string $url_query url query
+ *
+ * @return string $html_output
+ */
+function PMA_getHtmlForTablePrintViewLink($url_query)
+{
+    return '<p>'
+        . '<a href="db_printview.php?' . $url_query . '" target="print_view">'
+        . PMA_Util::getIcon(
+            'b_print.png',
+            __('Print view'),
+            true
+        ) . '</a>';
+}
+
+/**
+ * Get HTML links "Data Dictionary" options
+ *
+ * @param string $url_query url query
+ *
+ * @return string $html_output
+ */
+function PMA_getHtmlForDataDictionaryLink($url_query)
+{
+    return '<a href="db_datadict.php?' . $url_query . '" target="print_view">'
+        . PMA_Util::getIcon(
+            'b_tblanalyse.png',
+            __('Data Dictionary'),
+            true
+        ) . '</a>'
+        . '</p>';
+}
+
+/**
+ * Get Time for Create time, update time and check time
+ *
+ * @param array   $current_table current table
+ * @param string  $time_label    Create_time, Update_time, Check_time
+ * @param integer $time_all      time
+ *
+ * @return array ($time, $time_all)
+ */
+function PMA_getTimeForCreateUpdateCheck($current_table, $time_label, $time_all)
+{
+    $showtable = PMA_Table::sGetStatusInfo(
+        $GLOBALS['db'],
+        $current_table['TABLE_NAME'],
+        null,
+        true
+    );
+    $time = isset($showtable[$time_label])
+        ? $showtable[$time_label]
+        : false;
+
+    // show oldest creation date in summary row
+    if ($time && (!$time_all || $time < $time_all)) {
+        $time_all = $time;
+    }
+    return array($time, $time_all);
+}
+
+/**
+ * Get HTML for each table row of the database structure table,
+ * And this function returns $odd_row param also
+ *
+ * @param integer $curr                     current entry
+ * @param boolean $odd_row                  whether row is odd or not
+ * @param boolean $table_is_view            whether table is view or not
+ * @param array   $current_table            current table
+ * @param string  $browse_table_label       browse table label action link
+ * @param string  $tracking_icon            tracking icon
+ * @param boolean $server_slave_status      server slave state
+ * @param string  $browse_table             browse table action link
+ * @param string  $tbl_url_query            table url query
+ * @param string  $search_table             search table action link
+ * @param boolean $db_is_information_schema whether db is information schema or not
+ * @param array   $titles                   titles array
+ * @param string  $empty_table              empty table action link
+ * @param string  $drop_query               table dropt query
+ * @param string  $drop_message             table drop message
+ * @param string  $collation                collation
+ * @param string  $formatted_size           formatted size
+ * @param string  $unit                     unit
+ * @param string  $overhead                 overhead
+ * @param string  $create_time              create time
+ * @param string  $update_time              last update time
+ * @param string  $check_time               last check time
+ * @param boolean $is_show_stats            whether stats is show or not
+ * @param boolean $ignored                  ignored
+ * @param boolean $do                       do
+ * @param intger  $colspan_for_structure    colspan for structure
+ *
+ * @return array $html_output, $odd_row
+ */
+function PMA_getHtmlForStructureTableRow(
+    $curr, $odd_row, $table_is_view, $current_table,
+    $browse_table_label, $tracking_icon,$server_slave_status,
+    $browse_table, $tbl_url_query, $search_table,
+    $db_is_information_schema,$titles, $empty_table, $drop_query, $drop_message,
+    $collation, $formatted_size, $unit, $overhead, $create_time, $update_time,
+    $check_time,$is_show_stats, $ignored, $do, $colspan_for_structure
+) {
+    $html_output = '<tr class="' . ($odd_row ? 'odd' : 'even');
+    $odd_row = ! $odd_row;
+    $html_output .= ($table_is_view ? ' is_view' : '')
+    .'" id="row_tbl_' . $curr . '">';
+
+    $html_output .= '<td class="center">'
+        . '<input type="checkbox" name="selected_tbl[]" class="checkall" '
+        . 'value="' . htmlspecialchars($current_table['TABLE_NAME']) . '" '
+        . 'id="checkbox_tbl_' . $curr .'" /></td>';
+
+    $html_output .= '<th>'
+        . $browse_table_label
+        . (! empty($tracking_icon) ? $tracking_icon : '')
+        . '</th>';
+
+    if ($server_slave_status) {
+        $html_output .= '<td class="center">'
+            . ($ignored
+                ? PMA_Util::getImage('s_cancel.png', 'NOT REPLICATED')
+                : '')
+            . ($do
+                ? PMA_Util::getImage('s_success.png', 'REPLICATED')
+                : '')
+            . '</td>';
+    }
+
+    $html_output .= '<td class="center">' . $browse_table . '</td>';
+    $html_output .= '<td class="center">'
+        . '<a href="tbl_structure.php?' . $tbl_url_query . '">'
+        . $titles['Structure'] . '</a></td>';
+    $html_output .= '<td class="center">' . $search_table . '</td>';
+
+    if (! $db_is_information_schema) {
+        $html_output .= PMA_getHtmlForInsertEmptyDropActionLinks(
+            $tbl_url_query, $table_is_view,
+            $titles, $empty_table, $current_table, $drop_query, $drop_message
+        );
+    } // end if (! $db_is_information_schema)
+
+    // there is a null value in the ENGINE
+    // - when the table needs to be repaired, or
+    // - when it's a view
+    //  so ensure that we'll display "in use" below for a table
+    //  that needs to be repaired
+    if (isset($current_table['TABLE_ROWS'])
+        && ($current_table['ENGINE'] != null
+        || $table_is_view)
+    ) {
+        $html_output .= PMA_getHtmlForNotNullEngineViewTable(
+            $table_is_view, $current_table, $collation, $is_show_stats,
+            $tbl_url_query, $formatted_size, $unit, $overhead, $create_time,
+            $update_time, $check_time
+        );
+    } elseif ($table_is_view) {
+        $html_output .= PMA_getHtmlForViewTable($is_show_stats);
+    } else {
+        $html_output .= PMA_getHtmlForRepairtable(
+            $colspan_for_structure,
+            $db_is_information_schema
+        );
+    } // end if (isset($current_table['TABLE_ROWS'])) else
+    $html_output .= '</tr>';
+
+    return array($html_output, $odd_row);
+}
+
+/**
+ * Get HTML for Insert/Empty/Drop action links
+ *
+ * @param string  $tbl_url_query table url query
+ * @param boolean $table_is_view whether table is view or not
+ * @param array   $titles        titles array
+ * @param string  $empty_table   HTML link for empty table
+ * @param array   $current_table current table
+ * @param string  $drop_query    query for drop table
+ * @param string  $drop_message  table drop message
+ *
+ * @return string $html_output
+ */
+function PMA_getHtmlForInsertEmptyDropActionLinks($tbl_url_query, $table_is_view,
+    $titles, $empty_table, $current_table, $drop_query, $drop_message
+) {
+    $html_output = '<td class="insert_table center">'
+        . '<a href="tbl_change.php?' . $tbl_url_query . '">'
+        . $titles['Insert']
+        . '</a></td>';
+    $html_output .= '<td class="center">' . $empty_table . '</td>';
+    $html_output .= '<td class="center">';
+    $html_output .= '<a ';
+    $html_output .= 'class="ajax drop_table_anchor';
+    if ($table_is_view || $current_table['ENGINE'] == null) {
+        // this class is used in db_structure.js to display the
+        // correct confirmation message
+        $html_output .= ' view';
+    }
+    $html_output .= '"';
+    $html_output .= 'href="sql.php?' . $tbl_url_query
+        . '&reload=1&purge=1&sql_query='
+        . urlencode($drop_query) . '&message_to_show='
+        . urlencode($drop_message) . '" >'
+        . $titles['Drop'] . '</a></td>';
+
+    return $html_output;
+}
+
+/**
+ * Get HTML for show stats
+ *
+ * @param string $tbl_url_query  tabel url query
+ * @param string $formatted_size formatted size
+ * @param string $unit           unit
+ * @param string $overhead       overhead
+ *
+ * @return string $html_output
+ */
+function PMA_getHtmlForShowStats($tbl_url_query, $formatted_size,
+    $unit, $overhead
+) {
+     $html_output = '<td class="value tbl_size"><a'
+        . 'href="tbl_structure.php?' . $tbl_url_query . '#showusage" >'
+        . '<span>' . $formatted_size . '</span> '
+        . '<span class="unit">' . $unit . '</span>'
+        . '</a></td>';
+    $html_output .= '<td class="value tbl_overhead">' . $overhead . '</td>';
+
+    return $html_output;
+}
+
+/**
+ * Get HTML to show database structure creation, last update and last checkx time
+ *
+ * @param string $create_time create time
+ * @param string $update_time last update time
+ * @param string $check_time  last check time
+ *
+ * @return string $html_output
+ */
+function PMA_getHtmlForStructureTimes($create_time, $update_time, $check_time)
+{
+    $html_output = '';
+    if ($GLOBALS['cfg']['ShowDbStructureCreation']) {
+        $html_output .= '<td class="value tbl_creation">'
+            . ($create_time
+                ? PMA_Util::localisedDate(strtotime($create_time))
+                : '-' )
+            . '</td>';
+    } // end if
+    if ($GLOBALS['cfg']['ShowDbStructureLastUpdate']) {
+        $html_output .= '<td class="value tbl_last_update">'
+            . ($update_time
+                ? PMA_Util::localisedDate(strtotime($update_time))
+                : '-' )
+            . '</td>';
+    } // end if
+    if ($GLOBALS['cfg']['ShowDbStructureLastCheck']) {
+        $html_output .= '<td class="value tbl_last_check">'
+            . ($check_time
+                ? PMA_Util::localisedDate(strtotime($check_time))
+                : '-' )
+            . '</td>';
+    }
+    return $html_output;
+}
+
+/**
+ * Get HTML for ENGINE value not null or view tables that are not empty tables
+ *
+ * @param boolean $table_is_view  whether table is view
+ * @param array   $current_table  current table
+ * @param string  $collation      collation
+ * @param boolean $is_show_stats  whether atats show or not
+ * @param string  $tbl_url_query  table url query
+ * @param string  $formatted_size formatted size
+ * @param string  $unit           unit
+ * @param string  $overhead       overhead
+ * @param string  $create_time    create time
+ * @param string  $update_time    update time
+ * @param string  $check_time     check time
+ *
+ * @return string $html_output
+ */
+function PMA_getHtmlForNotNullEngineViewTable($table_is_view, $current_table,
+    $collation, $is_show_stats, $tbl_url_query, $formatted_size, $unit,
+    $overhead, $create_time, $update_time, $check_time
+) {
+    $html_output = '';
+    $row_count_pre = '';
+    $show_superscript = '';
+    if ($table_is_view) {
+        // Drizzle views use FunctionEngine, and the only place where they are
+        // available are I_S and D_D schemas, where we do exact counting
+        if ($current_table['TABLE_ROWS'] >= $GLOBALS['cfg']['MaxExactCountViews']
+            && $current_table['ENGINE'] != 'FunctionEngine'
+        ) {
+            $row_count_pre = '~';
+            $sum_row_count_pre = '~';
+            $show_superscript = PMA_Util::showHint(
+                PMA_sanitize(
+                    sprintf(
+                        __('This view has at least this number of rows. Please refer to %sdocumentation%s.'),
+                        '[doc at cfg_MaxExactCountViews]',
+                        '[/doc]'
+                    )
+                )
+            );
+        }
+    } elseif ($current_table['ENGINE'] == 'InnoDB'
+        && (! $current_table['COUNTED'])
+    ) {
+        // InnoDB table: we did not get an accurate row count
+        $row_count_pre = '~';
+        $sum_row_count_pre = '~';
+        $show_superscript = '';
+    }
+
+    $html_output .= '<td class="value tbl_rows">'
+        . $row_count_pre . PMA_Util::formatNumber(
+            $current_table['TABLE_ROWS'], 0
+        )
+        . $show_superscript . '</td>';
+
+    if (!($GLOBALS['cfg']['PropertiesNumColumns'] > 1)) {
+        $html_output .= '<td class="nowrap">'
+            . ($table_is_view ? __('View') : $current_table['ENGINE'])
+            . '</td>';
+        if (strlen($collation)) {
+            $html_output .= '<td class="nowrap">' . $collation . '</td>';
+        }
+    }
+
+    if ($is_show_stats) {
+        $html_output .= PMA_getHtmlForShowStats(
+            $tbl_url_query, $formatted_size, $unit, $overhead
+        );
+    }
+
+    $html_output .= PMA_getHtmlForStructureTimes(
+        $create_time, $update_time, $check_time
+    );
+
+    return $html_output;
+}
+
+/**
+ * Get HTML snippet view table
+ *
+ * @param type $is_show_stats whether stats show or not
+ *
+ * @return string $html_output
+ */
+function PMA_getHtmlForViewTable($is_show_stats)
+{
+    $html_output = '<td class="value">-</td>'
+        . '<td>' . __('View') . '</td>'
+        . '<td>---</td>';
+    if ($is_show_stats) {
+        $html_output .= '<td class="value">-</td>'
+            . '<td class="value">-</td>';
+    }
+    return $html_output;
+}
+
+/**
+ * display "in use" below for a table that needs to be repaired
+ *
+ * @param integer $colspan_for_structure    colspan for structure
+ * @param boolean $db_is_information_schema whether db is information schema or not
+ *
+ * @return string HTML snippet
+ */
+function PMA_getHtmlForRepairtable(
+    $colspan_for_structure,
+    $db_is_information_schema
+) {
+    return '<td colspan="'
+        . ($colspan_for_structure - ($db_is_information_schema ? 5 : 8)) . '"'
+        . 'class="center">'
+        . __('in use')
+        . '</td>';
+}
+
+/**
+ * display table header (<table><thead>...</thead><tbody>)
+ *
+ * @param boolean $db_is_information_schema whether db is information schema or not
+ * @param boolean $replication              whether to sho replication status
+ *
+ * @return html data
+ */
+function PMA_TableHeader($db_is_information_schema = false, $replication = false)
+{
+    $cnt = 0; // Let's count the columns...
+
+    if ($db_is_information_schema) {
+        $action_colspan = 3;
+    } else {
+        $action_colspan = 6;
+    }
+
+    $html_output = '<table class="data">' . "\n"
+        .'<thead>' . "\n"
+        .'<tr><th></th>' . "\n"
+        .'<th>'
+        . PMA_sortableTableHeader(__('Table'), 'table')
+        . '</th>' . "\n";
+    if ($replication) {
+        $html_output .= '<th>' . "\n"
+            .'        ' . __('Replication') . "\n"
+            .'</th>';
+    }
+    $html_output .= '<th colspan="' . $action_colspan . '">' . "\n"
+        .'        ' . __('Action') . "\n"
+        .'</th>'
+        // larger values are more interesting so default sort order is DESC
+        .'<th>' . PMA_sortableTableHeader(__('Rows'), 'records', 'DESC')
+        . PMA_Util::showHint(
+            PMA_sanitize(
+                __('May be approximate. See [doc at faq3-11]FAQ 3.11[/doc]')
+            )
+        ) . "\n"
+        .'</th>' . "\n";
+    if (!($GLOBALS['cfg']['PropertiesNumColumns'] > 1)) {
+        $html_output .= '<th>' . PMA_sortableTableHeader(__('Type'), 'type')
+            . '</th>' . "\n";
+        $cnt++;
+        $html_output .= '<th>'
+            . PMA_sortableTableHeader(__('Collation'), 'collation')
+            . '</th>' . "\n";
+        $cnt++;
+    }
+    if ($GLOBALS['is_show_stats']) {
+        // larger values are more interesting so default sort order is DESC
+        $html_output .= '<th>'
+            . PMA_sortableTableHeader(__('Size'), 'size', 'DESC')
+            . '</th>' . "\n"
+        // larger values are more interesting so default sort order is DESC
+            . '<th>'
+            . PMA_sortableTableHeader(__('Overhead'), 'overhead', 'DESC')
+            . '</th>' . "\n";
+        $cnt += 2;
+    }
+    if ($GLOBALS['cfg']['ShowDbStructureCreation']) {
+        // larger values are more interesting so default sort order is DESC
+        $html_output .= '<th>'
+            . PMA_sortableTableHeader(__('Creation'), 'creation', 'DESC')
+            . '</th>' . "\n";
+        $cnt += 2;
+    }
+    if ($GLOBALS['cfg']['ShowDbStructureLastUpdate']) {
+        // larger values are more interesting so default sort order is DESC
+        $html_output .= '<th>'
+            . PMA_sortableTableHeader(__('Last update'), 'last_update', 'DESC')
+            . '</th>' . "\n";
+        $cnt += 2;
+    }
+    if ($GLOBALS['cfg']['ShowDbStructureLastCheck']) {
+        // larger values are more interesting so default sort order is DESC
+        $html_output .= '<th>'
+            . PMA_sortableTableHeader(__('Last check'), 'last_check', 'DESC')
+            . '</th>' . "\n";
+        $cnt += 2;
+    }
+    $html_output .= '</tr>' . "\n";
+    $html_output .= '</thead>' . "\n";
+    $html_output .= '<tbody>' . "\n";
+    $GLOBALS['colspan_for_structure'] = $cnt + $action_colspan + 3;
+
+    return $html_output;
+}
+
+/**
+ * Creates a clickable column header for table information
+ *
+ * @param string $title              title to use for the link
+ * @param string $sort               corresponds to sortable data name mapped in
+ *                                   libraries/db_info.inc.php
+ * @param string $initial_sort_order initial sort order
+ *
+ * @return string link to be displayed in the table header
+ */
+function PMA_sortableTableHeader($title, $sort, $initial_sort_order = 'ASC')
+{
+    // Set some defaults
+    $requested_sort = 'table';
+    $requested_sort_order = $future_sort_order = $initial_sort_order;
+
+    // If the user requested a sort
+    if (isset($_REQUEST['sort'])) {
+        $requested_sort = $_REQUEST['sort'];
+
+        if (isset($_REQUEST['sort_order'])) {
+            $requested_sort_order = $_REQUEST['sort_order'];
+        }
+    }
+
+    $order_img = '';
+    $order_link_params = array();
+    $order_link_params['title'] = __('Sort');
+
+    // If this column was requested to be sorted.
+    if ($requested_sort == $sort) {
+        if ($requested_sort_order == 'ASC') {
+            $future_sort_order = 'DESC';
+            // current sort order is ASC
+            $order_img  = ' ' . PMA_Util::getImage(
+                's_asc.png',
+                __('Ascending'),
+                array('class' => 'sort_arrow', 'title' => '')
+            );
+            $order_img .= ' ' . PMA_Util::getImage(
+                's_desc.png',
+                __('Descending'),
+                array('class' => 'sort_arrow hide', 'title' => '')
+            );
+            // but on mouse over, show the reverse order (DESC)
+            $order_link_params['onmouseover'] = "$('.sort_arrow').toggle();";
+            // on mouse out, show current sort order (ASC)
+            $order_link_params['onmouseout'] = "$('.sort_arrow').toggle();";
+        } else {
+            $future_sort_order = 'ASC';
+            // current sort order is DESC
+            $order_img  = ' ' . PMA_Util::getImage(
+                's_asc.png',
+                __('Ascending'),
+                array('class' => 'sort_arrow hide', 'title' => '')
+            );
+            $order_img .= ' ' . PMA_Util::getImage(
+                's_desc.png',
+                __('Descending'),
+                array('class' => 'sort_arrow', 'title' => '')
+            );
+            // but on mouse over, show the reverse order (ASC)
+            $order_link_params['onmouseover'] = "$('.sort_arrow').toggle();";
+            // on mouse out, show current sort order (DESC)
+            $order_link_params['onmouseout'] = "$('.sort_arrow').toggle();";
+        }
+    }
+
+    $_url_params = array(
+        'db' => $_REQUEST['db'],
+    );
+
+    $url = 'db_structure.php'.PMA_generate_common_url($_url_params);
+    // We set the position back to 0 every time they sort.
+    $url .= "&pos=0&sort=$sort&sort_order=$future_sort_order";
+
+    return PMA_Util::linkOrButton(
+        $url, $title . $order_img, $order_link_params
+    );
+}
+
+/**
+ * Get the alias ant truname
+ *
+ * @param string $tooltip_aliasname tooltip alias name
+ * @param array  $current_table     current table
+ * @param string $tooltip_truename  tooltip true name
+ *
+ * @return array ($alias, $truename)
+ */
+function PMA_getAliasAndTrueName($tooltip_aliasname, $current_table,
+    $tooltip_truename
+) {
+    $alias = (! empty($tooltip_aliasname)
+            && isset($tooltip_aliasname[$current_table['TABLE_NAME']])
+        )
+        ? str_replace(
+            ' ', ' ',
+            htmlspecialchars($tooltip_truename[$current_table['TABLE_NAME']])
+        )
+        : str_replace(
+            ' ', ' ',
+            htmlspecialchars($current_table['TABLE_NAME'])
+        );
+    $truename = (! empty($tooltip_truename)
+            && isset($tooltip_truename[$current_table['TABLE_NAME']])
+        )
+        ? str_replace(
+            ' ', ' ',
+            htmlspecialchars($tooltip_truename[$current_table['TABLE_NAME']])
+        )
+        : str_replace(
+            ' ', ' ',
+            htmlspecialchars($current_table['TABLE_NAME'])
+        );
+
+    return array($alias, $truename);
+}
+
+/**
+ * Get the server slave state
+ *
+ * @param boolean $server_slave_status server slave state
+ * @param string  $truename            true name
+ *
+ * @return array ($do, $ignored)
+ */
+function PMA_getServerSlaveStatus($server_slave_status, $truename)
+{
+    $ignored = false;
+    $do = false;
+    include_once 'libraries/replication.inc.php';
+    if ($server_slave_status) {
+        if ((strlen(array_search($truename, $server_slave_Do_Table)) > 0)
+            || (strlen(array_search($GLOBALS['db'], $server_slave_Do_DB)) > 0)
+            || (count($server_slave_Do_DB) == 1 && count($server_slave_Ignore_DB) == 1)
+        ) {
+            $do = true;
+        }
+        foreach ($server_slave_Wild_Do_Table as $db_table) {
+            $table_part = PMA_extract_db_or_table($db_table, 'table');
+            if (($GLOBALS['db'] == PMA_extract_db_or_table($db_table, 'db'))
+                && (preg_match("@^" . substr($table_part, 0, strlen($table_part) - 1) . "@", $truename))
+            ) {
+                $do = true;
+            }
+        }
+
+        if ((strlen(array_search($truename, $server_slave_Ignore_Table)) > 0)
+            || (strlen(array_search($GLOBALS['db'], $server_slave_Ignore_DB)) > 0)
+        ) {
+            $ignored = true;
+        }
+        foreach ($server_slave_Wild_Ignore_Table as $db_table) {
+            $table_part = PMA_extract_db_or_table($db_table, 'table');
+            if (($db == PMA_extract_db_or_table($db_table))
+                && (preg_match("@^" . substr($table_part, 0, strlen($table_part) - 1) . "@", $truename))
+            ) {
+                $ignored = true;
+            }
+        }
+    }
+    return array($do, $ignored);
+}
+
+/**
+ * Get the value set for ENGINE table,
+ * $current_table, $formatted_size, $unit, $formatted_overhead,
+ * $overhead_unit, $overhead_size, $table_is_view
+ *
+ * @param array   $current_table            current table
+ * @param boolean $db_is_information_schema whether db is information schema or not
+ * @param boolean $is_show_stats            whether stats show or not
+ * @param boolean $table_is_view            whether table is view or not
+ * @param double  $sum_size                 totle table size
+ * @param double  $overhead_size            overhead size
+ *
+ * @return array
+ */
+function PMA_getStuffForEngineTypeTable($current_table, $db_is_information_schema,
+    $is_show_stats, $table_is_view, $sum_size, $overhead_size
+) {
+    $formatted_size = '-';
+    $unit = '';
+    $formatted_overhead = '';
+    $overhead_unit = '';
+
+    switch ( $current_table['ENGINE']) {
+        // MyISAM, ISAM or Heap table: Row count, data size and index size
+        // are accurate; data size is accurate for ARCHIVE
+    case 'MyISAM' :
+    case 'ISAM' :
+    case 'HEAP' :
+    case 'MEMORY' :
+    case 'ARCHIVE' :
+    case 'Aria' :
+    case 'Maria' :
+        list($current_table, $formatted_size, $unit, $formatted_overhead,
+        $overhead_unit, $overhead_size, $sum_size) = PMA_getValuesForAriaTable(
+            $db_is_information_schema, $current_table, $is_show_stats,
+            $sum_size, $overhead_size, $formatted_size, $unit,
+            $formatted_overhead, $overhead_unit
+        );
+        break;
+    case 'InnoDB' :
+    case 'PBMS' :
+        // InnoDB table: Row count is not accurate but data and index sizes are.
+        // PBMS table in Drizzle: TABLE_ROWS is taken from table cache,
+        // so it may be unavailable
+        list($current_table, $formatted_size, $unit, $sum_size)
+            = PMA_getValuesForPbmsTable($current_table, $is_show_stats, $sum_size);
+        //$display_rows                   =  ' - ';
+        break;
+    // Mysql 5.0.x (and lower) uses MRG_MyISAM
+    // and MySQL 5.1.x (and higher) uses MRG_MYISAM
+    // Both are aliases for MERGE
+    case 'MRG_MyISAM' :
+    case 'MRG_MYISAM' :
+    case 'MERGE' :
+    case 'BerkeleyDB' :
+        // Merge or BerkleyDB table: Only row count is accurate.
+        if ($is_show_stats) {
+            $formatted_size =  ' - ';
+            $unit          =  '';
+        }
+        break;
+        // for a view, the ENGINE is sometimes reported as null,
+        // or on some servers it's reported as "SYSTEM VIEW"
+    case null :
+    case 'SYSTEM VIEW' :
+    case 'FunctionEngine' :
+        // if table is broken, Engine is reported as null, so one more test
+        if ($current_table['TABLE_TYPE'] == 'VIEW') {
+            // countRecords() takes care of $cfg['MaxExactCountViews']
+            $current_table['TABLE_ROWS'] = PMA_Table::countRecords(
+                $GLOBALS['db'], $current_table['TABLE_NAME'],
+                $force_exact = true, $is_view = true
+            );
+            $table_is_view = true;
+        }
+        break;
+    default :
+        // Unknown table type.
+        if ($is_show_stats) {
+            $formatted_size =  __('unknown');
+            $unit          =  '';
+        }
+    } // end switch
+
+    return array($current_table, $formatted_size, $unit, $formatted_overhead,
+        $overhead_unit, $overhead_size, $table_is_view, $sum_size
+    );
+}
+
+/**
+ * Get values for ARIA/MARIA tables
+ * $current_table, $formatted_size, $unit, $formatted_overhead,
+ * $overhead_unit, $overhead_size
+ *
+ * @param boolean $db_is_information_schema whether db is information schema or not
+ * @param array   $current_table            current table
+ * @param boolean $is_show_stats            whether stats show or not
+ * @param double  $sum_size                 sum size
+ * @param double  $overhead_size            overhead size
+ *
+ * @return array
+ */
+function PMA_getValuesForAriaTable($db_is_information_schema, $current_table,
+    $is_show_stats, $sum_size, $overhead_size, $formatted_size, $unit,
+    $formatted_overhead, $overhead_unit
+) {
+    if ($db_is_information_schema) {
+        $current_table['Rows'] = PMA_Table::countRecords(
+            $GLOBALS['db'], $current_table['Name']
+        );
+    }
+
+    if ($is_show_stats) {
+        $tblsize = doubleval($current_table['Data_length'])
+            + doubleval($current_table['Index_length']);
+        $sum_size += $tblsize;
+        list($formatted_size, $unit) = PMA_Util::formatByteDown(
+            $tblsize, 3, ($tblsize > 0) ? 1 : 0
+        );
+        if (isset($current_table['Data_free']) && $current_table['Data_free'] > 0) {
+            list($formatted_overhead, $overhead_unit)
+                = PMA_Util::formatByteDown(
+                    $current_table['Data_free'], 3,
+                    (($current_table['Data_free'] > 0) ? 1 : 0)
+                );
+            $overhead_size += $current_table['Data_free'];
+        }
+    }
+    return array($current_table, $formatted_size, $unit, $formatted_overhead,
+        $overhead_unit, $overhead_size, $sum_size
+    );
+}
+
+/**
+ * Get valuse for PBMS table
+ * $current_table, $formatted_size, $unit, $sum_size
+ *
+ * @param array   $current_table current table
+ * @param boolean $is_show_stats whether stats show or not
+ * @param double  $sum_size      sum size
+ *
+ * @return array
+ */
+function PMA_getValuesForPbmsTable($current_table, $is_show_stats, $sum_size)
+{
+    if (($current_table['ENGINE'] == 'InnoDB'
+        && $current_table['TABLE_ROWS'] < $GLOBALS['cfg']['MaxExactCount'])
+        || !isset($current_table['TABLE_ROWS'])
+    ) {
+        $current_table['COUNTED'] = true;
+        $current_table['TABLE_ROWS'] = PMA_Table::countRecords(
+            $GLOBALS['db'], $current_table['TABLE_NAME'],
+            $force_exact = true, $is_view = false
+        );
+    } else {
+        $current_table['COUNTED'] = false;
+    }
+
+    // Drizzle doesn't provide data and index length, check for null
+    if ($is_show_stats && $current_table['Data_length'] !== null) {
+        $tblsize =  $current_table['Data_length'] + $current_table['Index_length'];
+        $sum_size += $tblsize;
+        list($formatted_size, $unit) = PMA_Util::formatByteDown(
+            $tblsize, 3, (($tblsize > 0) ? 1 : 0)
+        );
+    }
+
+    return array($current_table, $formatted_size, $unit, $sum_size);
+}
+
+/**
+ * table structure
+ */
+
+/**
+ * Get the HTML snippet for structure table table header
+ *
+ * @param type $db_is_information_schema whether db is information schema or not
+ * @param type $tbl_is_view              whether table is view or nt
+ *
+ * @return string $html_output
+ */
+function PMA_getHtmlForTableStructureHeader(
+    $db_is_information_schema,
+    $tbl_is_view
+) {
+    $html_output = '<thead>';
+    $html_output .= '<tr>';
+    $html_output .= '<th></th>'
+        . '<th>#</th>'
+        . '<th>' . __('Name') . '</th>'
+        . '<th>' . __('Type'). '</th>'
+        . '<th>' . __('Collation') . '</th>'
+        . '<th>' . __('Attributes') . '</th>'
+        . '<th>' . __('Null') . '</th>'
+        . '<th>' . __('Default') . '</th>'
+        . '<th>' . __('Extra') . '</th>';
+
+    if ($db_is_information_schema || $tbl_is_view) {
+        $html_output .= '<th>' . __('View') . '</th>';
+    } else { /* see tbl_structure.js, function moreOptsMenuResize() */
+        $colspan = 9;
+        if (PMA_DRIZZLE) {
+            $colspan -= 2;
+        }
+        if ($GLOBALS['cfg']['PropertiesIconic']) {
+            $colspan--;
+        }
+        $html_output .= '<th colspan="' . $colspan . '" '
+            . 'class="action">' . __('Action') . '</th>';
+    }
+    $html_output .= '</tr>'
+        . '</thead>';
+
+    return $html_output;
+}
+
+/**
+ * Get HTML for structure table's rows and return $odd_row parameter also
+ * For "Action" Column, this function contains only HTML code for "Change"
+ * and "Drop"
+ *
+ * @param array   $row                      current row
+ * @param string  $rownum                   row number
+ * @param string  $displayed_field_name     displayed field name
+ * @param string  $type_nowrap              type nowrap
+ * @param array   $extracted_columnspec     associative array containing type,
+ *                                          spec_in_brackets and possibly
+ *                                          enum_set_values (another array)
+ * @param string  $type_mime                mime type
+ * @param string  $field_charset            field charset
+ * @param string  $attribute                attribute (BINARY, UNSIGNED,
+ *                                          UNSIGNED ZEROFILL,
+ *                                          on update CURRENT_TIMESTAMP)
+ * @param boolean $tbl_is_view              whether tables is view or not
+ * @param boolean $db_is_information_schema whether db is information schema or not
+ * @param string  $url_query                url query
+ * @param string  $field_encoded            field encoded
+ * @param array   $titles                   tittles array
+ * @param string  $table                    table
+ *
+ * @return array ($html_output, $odd_row)
+ */
+function PMA_getHtmlTableStructureRow($row, $rownum,
+    $displayed_field_name, $type_nowrap, $extracted_columnspec, $type_mime,
+    $field_charset, $attribute, $tbl_is_view, $db_is_information_schema,
+    $url_query, $field_encoded, $titles, $table
+) {
+    $html_output = '<td class="center">'
+        . '<input type="checkbox" class="checkall" name="selected_fld[]" '
+        . 'value="' . htmlspecialchars($row['Field']) . '" '
+        . 'id="checkbox_row_' . $rownum . '"/>'
+        . '</td>';
+
+    $html_output .= '<td class="right">'
+        . $rownum
+        . '</td>';
+
+    $html_output .= '<th class="nowrap">'
+        . '<label for="checkbox_row_' . $rownum . '">'
+        . $displayed_field_name . '</label>'
+        . '</th>';
+
+    $html_output .= '<td' . $type_nowrap . '>'
+        .'<bdo dir="ltr" lang="en">'
+        . $extracted_columnspec['displayed_type'] . $type_mime
+        . '</bdo></td>';
+
+    $html_output .= '<td>' .
+        (empty($field_charset)
+            ? ''
+            : '<dfn title="' . PMA_getCollationDescr($field_charset) . '">'
+                . $field_charset . '</dfn>'
+        )
+        . '</td>';
+
+    $html_output .= '<td class="column_attribute nowrap">'
+        . $attribute . '</td>';
+    $html_output .= '<td>'
+        . (($row['Null'] == 'YES') ? __('Yes') : __('No')) . '  </td>';
+
+    $html_output .= '<td class="nowrap">';
+    if (isset($row['Default'])) {
+        if ($extracted_columnspec['type'] == 'bit') {
+            // here, $row['Default'] contains something like b'010'
+            $html_output .= PMA_Util::convertBitDefaultValue($row['Default']);
+        } else {
+            $html_output .= $row['Default'];
+        }
+    } else {
+        $html_output .= '<i>' . _pgettext('None for default', 'None') . '</i>';
+    }
+    $html_output .= '</td>';
+
+    $html_output .= '<td class="nowrap">' . strtoupper($row['Extra']) . '</td>';
+
+    $html_output .= PMA_getHtmlForDropColumn(
+        $tbl_is_view, $db_is_information_schema,
+        $url_query, $field_encoded,
+        $titles, $table, $row
+    );
+
+    return $html_output;
+}
+
+/**
+ * Get HTML code for "Drop" Action link
+ *
+ * @param boolean $tbl_is_view              whether tables is view or not
+ * @param boolean $db_is_information_schema whether db is information schema or not
+ * @param string  $url_query                url query
+ * @param string  $field_encoded            field encoded
+ * @param array   $titles                   tittles array
+ * @param string  $table                    table
+ * @param array   $row                      current row
+ *
+ * @return string $html_output
+ */
+function PMA_getHtmlForDropColumn($tbl_is_view, $db_is_information_schema,
+    $url_query, $field_encoded, $titles, $table, $row
+) {
+    $html_output = '';
+
+    if (! $tbl_is_view && ! $db_is_information_schema) {
+        $html_output .= '<td class="edit center">'
+            . '<a class="change_column_anchor ajax"'
+            . ' href="tbl_structure.php?' 
+            . $url_query . '&field=' . $field_encoded 
+            . '&change_column=1">'
+            . $titles['Change'] . '</a>' . '</td>';
+        $html_output .= '<td class="drop center">'
+            . '<a class="drop_column_anchor ajax"'
+            . ' href="sql.php?' . $url_query . '&sql_query='
+            . urlencode(
+                'ALTER TABLE ' . PMA_Util::backquote($table)
+                . ' DROP ' . PMA_Util::backquote($row['Field']) . ';'
+            )
+            . '&dropped_column=' . urlencode($row['Field'])
+            . '&message_to_show=' . urlencode(
+                sprintf(
+                    __('Column %s has been dropped'),
+                    htmlspecialchars($row['Field'])
+                )
+            ) . '" >'
+            . $titles['Drop'] . '</a>'
+            . '</td>';
+    }
+
+    return $html_output;
+}
+
+/**
+ * Get HTML for "check all" check box with "with selected" actions in table
+ * structure
+ *
+ * @param string  $pmaThemeImage            pma theme image url
+ * @param string  $text_dir                 test directory
+ * @param boolean $tbl_is_view              whether table is view or not
+ * @param boolean $db_is_information_schema whether db is information schema or not
+ * @param string  $tbl_storage_engine       table storage engine
+ *
+ * @return string $html_output
+ */
+function PMA_getHtmlForCheckAllTableColumn($pmaThemeImage, $text_dir,
+    $tbl_is_view, $db_is_information_schema, $tbl_storage_engine
+) {
+    $html_output = '<img class="selectallarrow" '
+        . 'src="' . $pmaThemeImage . 'arrow_' . $text_dir . '.png' . '"'
+        . 'width="38" height="22" alt="' . __('With selected:') . '" />';
+
+    $html_output .= '<input type="checkbox" id="checkall" '
+        . 'title="' . __('Check All') . '" />'
+        . '<label for="checkall">' . __('Check All') . '</label>';
+
+    $html_output .= '<i style="margin-left: 2em">'
+        . __('With selected:') . '</i>';
+
+    $html_output .= PMA_Util::getButtonOrImage(
+        'submit_mult', 'mult_submit', 'submit_mult_browse',
+        __('Browse'), 'b_browse.png', 'browse'
+    );
+
+    if (! $tbl_is_view && ! $db_is_information_schema) {
+        $html_output .= PMA_Util::getButtonOrImage(
+            'submit_mult', 'mult_submit change_columns_anchor ajax',
+            'submit_mult_change', __('Change'), 'b_edit.png', 'change'
+        );
+        $html_output .= PMA_Util::getButtonOrImage(
+            'submit_mult', 'mult_submit', 'submit_mult_drop',
+            __('Drop'), 'b_drop.png', 'drop'
+        );
+        if ('ARCHIVE' != $tbl_storage_engine) {
+            $html_output .= PMA_Util::getButtonOrImage(
+                'submit_mult', 'mult_submit', 'submit_mult_primary',
+                __('Primary'), 'b_primary.png', 'primary'
+            );
+            $html_output .= PMA_Util::getButtonOrImage(
+                'submit_mult', 'mult_submit', 'submit_mult_unique',
+                __('Unique'), 'b_unique.png', 'unique'
+            );
+            $html_output .= PMA_Util::getButtonOrImage(
+                'submit_mult', 'mult_submit', 'submit_mult_index',
+                __('Index'), 'b_index.png', 'index'
+            );
+        }
+
+        if (! empty($tbl_storage_engine) && $tbl_storage_engine == 'MYISAM') {
+            $html_output .= PMA_Util::getButtonOrImage(
+                'submit_mult', 'mult_submit', 'submit_mult_spatial',
+                __('Spatial'), 'b_spatial.png', 'spatial'
+            );
+        }
+        if (! empty($tbl_storage_engine)
+            && ($tbl_storage_engine == 'MYISAM'
+            || $tbl_storage_engine == 'ARIA'
+            || $tbl_storage_engine == 'MARIA')
+        ) {
+            $html_output .= PMA_Util::getButtonOrImage(
+                'submit_mult', 'mult_submit', 'submit_mult_fulltext',
+                __('Fulltext'), 'b_ftext.png', 'ftext'
+            );
+        }
+    }
+    return $html_output;
+}
+
+/**
+ * Get HTML for move columns dialog
+ *
+ * @return string $html_output
+ */
+function PMA_getHtmlDivForMoveColumnsDialog()
+{
+    $html_output = '<div id="move_columns_dialog" '
+        . 'title="' . __('Move columns') . '" style="display: none">';
+
+    $html_output .= '<p>'
+        . __('Move the columns by dragging them up and down.') . '</p>';
+
+    $html_output .= '<form action="tbl_structure.php">'
+        . '<div>'
+        . PMA_generate_common_hidden_inputs($GLOBALS['db'], $GLOBALS['table'])
+        . '<ul></ul>'
+        . '</div>'
+        . '</form>'
+        . '</div>';
+
+    return $html_output;
+}
+
+/**
+ * Get HTML for edit views'
+ *
+ * @param string $url_params URL parameters
+ *
+ * @return string $html_output
+ */
+function PMA_getHtmlForEditView($url_params)
+{
+    $create_view = PMA_DBI_get_definition(
+        $GLOBALS['db'], 'VIEW', $GLOBALS['table']
+    );
+    $create_view = preg_replace('@^CREATE@', 'ALTER', $create_view);
+    $html_output = PMA_Util::linkOrButton(
+        'tbl_sql.php' . PMA_generate_common_url(
+            $url_params +
+            array(
+                'sql_query' => $create_view,
+                'show_query' => '1',
+            )
+        ),
+        PMA_Util::getIcon('b_edit.png', __('Edit view'), true)
+    );
+    return $html_output;
+}
+
+/**
+ * Get HTML links for 'Print view', 'Relation view', 'Propose table structure',
+ * 'Track table' and 'Move columns'
+ *
+ * @param string  $url_query                url query
+ * @param boolean $tbl_is_view              whether table is view or not
+ * @param boolean $db_is_information_schema whether db is information schema or not
+ * @param string  $tbl_storage_engine       table storage engine
+ * @param array   $cfgRelation              current relation parameters
+ *
+ * @return string $html_output
+ */
+function PMA_getHtmlForOptionalActionLinks($url_query, $tbl_is_view,
+    $db_is_information_schema, $tbl_storage_engine, $cfgRelation
+) {
+    $html_output = '<a href="tbl_printview.php?' . $url_query . '" target="print_view">'
+        . PMA_Util::getIcon('b_print.png', __('Print view'), true)
+        . '</a>';
+
+    if (! $tbl_is_view && ! $db_is_information_schema) {
+        // if internal relations are available, or foreign keys are supported
+        // ($tbl_storage_engine comes from libraries/tbl_info.inc.php
+
+        if ($cfgRelation['relwork']
+            || PMA_Util::isForeignKeySupported($tbl_storage_engine)
+        ) {
+            $html_output .= '<a href="tbl_relation.php?' . $url_query . '">'
+                . PMA_Util::getIcon(
+                    'b_relations.png', __('Relation view'), true
+                )
+                . '</a>';
+        }
+        if (!PMA_DRIZZLE) {
+            $html_output .= '<a href="sql.php?' . $url_query
+                . '&session_max_rows=all&sql_query=' . urlencode(
+                    'SELECT * FROM ' . PMA_Util::backquote($GLOBALS['table'])
+                    . ' PROCEDURE ANALYSE()'
+                ) . '">'
+                . PMA_Util::getIcon(
+                    'b_tblanalyse.png',
+                    __('Propose table structure'),
+                    true
+                )
+                . '</a>';
+            $html_output .= PMA_Util::showMySQLDocu(
+                'Extending_MySQL', 'procedure_analyse'
+            ) . "\n";
+        }
+        if (PMA_Tracker::isActive()) {
+            $html_output .= '<a href="tbl_tracking.php?' . $url_query . '">'
+                . PMA_Util::getIcon('eye.png', __('Track table'), true)
+                . '</a>';
+        }
+        $html_output .= '<a href="#" id="move_columns_anchor">'
+            . PMA_Util::getIcon('b_move.png', __('Move columns'), true)
+            . '</a>';
+    }
+
+    return $html_output;
+}
+
+/**
+ * Get HTML snippet for "Add column" feature in structure table
+ *
+ * @param array $columns_list column list array
+ *
+ * @return string $html_output
+ */
+function PMA_getHtmlForAddColumn($columns_list)
+{
+    $html_output = '<form method="post" action="tbl_addfield.php" '
+        . 'id="addColumns" name="addColumns" '
+        . 'onsubmit="return checkFormElementInRange('
+            . 'this, \'num_fields\', \'' . str_replace(
+                '\'',
+                '\\\'',
+                __('You have to add at least one column.')
+            ) . '\', 1)'
+        . '">';
+
+    $html_output .= PMA_generate_common_hidden_inputs(
+        $GLOBALS['db'],
+        $GLOBALS['table']
+    );
+    if ($GLOBALS['cfg']['PropertiesIconic']) {
+        $html_output .=PMA_Util::getImage(
+            'b_insrow.png',
+            __('Add column')
+        );
+    }
+    $num_fields = '<input type="text" name="num_fields" size="2" '
+        . 'maxlength="2" value="1" onfocus="this.select()" />';
+    $html_output .= sprintf(__('Add %s column(s)'), $num_fields);
+
+    // I tried displaying the drop-down inside the label but with Firefox
+    // the drop-down was blinking
+    $column_selector = '<select name="after_field" '
+        . 'onclick="this.form.field_where[2].checked=true" '
+        . 'onchange="this.form.field_where[2].checked=true">';
+
+    foreach ($columns_list as $one_column_name) {
+        $column_selector .= '<option '
+            . 'value="' . htmlspecialchars($one_column_name) . '">'
+            . htmlspecialchars($one_column_name)
+            . '</option>';
+    }
+    $column_selector .= '</select>';
+
+    $choices = array(
+        'last'  => __('At End of Table'),
+        'first' => __('At Beginning of Table'),
+        'after' => sprintf(__('After %s'), '')
+    );
+    $html_output .= PMA_Util::getRadioFields(
+        'field_where', $choices, 'last', false
+    );
+    $html_output .= $column_selector;
+    $html_output .= '<input type="submit" value="' . __('Go') . '" />'
+        . '</form>';
+
+    return $html_output;
+}
+
+/**
+ * Get HTML snippet for table rows in the Information ->Space usage table
+ *
+ * @param boolean $odd_row whether current row is odd or even
+ * @param string  $name    type of usage
+ * @param string  $value   value of usage
+ * @param string  $unit    unit
+ *
+ * @return string $html_output
+ */
+function PMA_getHtmlForSpaceUsageTableRow($odd_row, $name, $value, $unit)
+{
+    $html_output = '<tr class="' . (($odd_row = !$odd_row) ? 'odd' : 'even') . '">';
+    $html_output .= '<th class="name">' . $name . '</th>';
+    $html_output .= '<td class="value">' . $value . '</td>';
+    $html_output .= '<td class="unit">' . $unit . '</td>';
+    $html_output .= '</tr>';
+
+    return $html_output;
+}
+
+/**
+ * Get HTML for Optimize link if overhead in Information fieldset
+ *
+ * @param type $url_query URL query
+ *
+ * @return string $html_output
+ */
+function PMA_getHtmlForOptimizeLink($url_query)
+{
+    $html_output = '<tr class="tblFooters">';
+    $html_output .= '<td colspan="3" class="center">';
+    $html_output .= '<a href="sql.php?' . $url_query
+        . '&pos=0&sql_query=' . urlencode(
+            'OPTIMIZE TABLE ' . PMA_Util::backquote($GLOBALS['table'])
+        )
+        . '">'
+        . PMA_Util::getIcon('b_tbloptimize.png', __('Optimize table'))
+        . '</a>';
+    $html_output .= '</td>';
+    $html_output .= '</tr>';
+
+    return $html_output;
+}
+
+/**
+ * Get HTML for 'Row statistics' table row
+ *
+ * @param type $odd_row whether current row is odd or even
+ * @param type $name    statement name
+ * @param type $value   value
+ *
+ * @return string $html_output
+ */
+function PMA_getHtmlForRowStatsTableRow($odd_row, $name, $value)
+{
+    $html_output = '<tr class="' . (($odd_row = !$odd_row) ? 'odd' : 'even') . '">';
+    $html_output .= '<th class="name">' . $name . '</th>';
+    $html_output .= '<td class="value">' . $value . '</td>';
+    $html_output .= '</tr>';
+
+    return $html_output;
+}
+
+/**
+ * Get HTML snippet for display Row statistics table
+ *
+ * @param array   $showtable     show table array
+ * @param string  $tbl_collation table collation
+ * @param boolean $is_innodb     whether table is innob or not
+ * @param boolean $mergetable    Checks if current table is a merge table
+ * @param integer $avg_size      average size
+ * @param string  $avg_unit      average unit
+ *
+ * @return string $html_output
+ */
+function getHtmlForRowStatsTable($showtable, $tbl_collation,
+    $is_innodb, $mergetable, $avg_size, $avg_unit
+) {
+    $odd_row = false;
+    $html_output = '<table id="tablerowstats" class="data">';
+    $html_output .= '<caption class="tblHeaders">'
+        . __('Row statistics') . '</caption>';
+    $html_output .= '<tbody>';
+
+    if (isset($showtable['Row_format'])) {
+        if ($showtable['Row_format'] == 'Fixed') {
+            $value = __('static');
+        } elseif ($showtable['Row_format'] == 'Dynamic') {
+            $value = __('dynamic');
+        } else {
+            $value = $showtable['Row_format'];
+        }
+        $html_output .= PMA_getHtmlForRowStatsTableRow(
+            $odd_row, __('Format'), $value
+        );
+        $odd_row = !$odd_row;
+    }
+    if (! empty($showtable['Create_options'])) {
+        if ($showtable['Create_options'] == 'partitioned') {
+            $value = __('partitioned');
+        } else {
+            $value = $showtable['Create_options'];
+        }
+        $html_output .= PMA_getHtmlForRowStatsTableRow(
+            $odd_row, __('Options'), $value
+        );
+        $odd_row = !$odd_row;
+    }
+    if (!empty($tbl_collation)) {
+        $value = '<dfn title="' . PMA_getCollationDescr($tbl_collation) . '">'
+            . $tbl_collation . '</dfn>';
+        $html_output .= PMA_getHtmlForRowStatsTableRow(
+            $odd_row, __('Collation'), $value
+        );
+        $odd_row = !$odd_row;
+    }
+    if (!$is_innodb && isset($showtable['Rows'])) {
+        $html_output .= PMA_getHtmlForRowStatsTableRow(
+            $odd_row,
+            __('Rows'),
+            PMA_Util::formatNumber($showtable['Rows'], 0)
+        );
+        $odd_row = !$odd_row;
+    }
+    if (!$is_innodb
+        && isset($showtable['Avg_row_length'])
+        && $showtable['Avg_row_length'] > 0
+    ) {
+        list($avg_row_length_value, $avg_row_length_unit) 
+            = PMA_Util::formatByteDown(
+                $showtable['Avg_row_length'],
+                6, 
+                1
+            );
+        $html_output .= PMA_getHtmlForRowStatsTableRow(
+            $odd_row,
+            __('Row length'),
+            ($avg_row_length_value . ' ' . $avg_row_length_unit)
+        );
+        unset($avg_row_length_value, $avg_row_length_unit);
+        $odd_row = !$odd_row;
+    }
+    if (!$is_innodb
+        && isset($showtable['Data_length'])
+        && $showtable['Rows'] > 0
+        && $mergetable == false
+    ) {
+        $html_output .= PMA_getHtmlForRowStatsTableRow(
+            $odd_row,
+            __('Row size'),
+            ($avg_size . ' ' . $avg_unit)
+        );
+        $odd_row = !$odd_row;
+    }
+    if (isset($showtable['Auto_increment'])) {
+        $html_output .= PMA_getHtmlForRowStatsTableRow(
+            $odd_row,
+            __('Next autoindex'),
+            PMA_Util::formatNumber($showtable['Auto_increment'], 0)
+        );
+        $odd_row = !$odd_row;
+    }
+    if (isset($showtable['Create_time'])) {
+        $html_output .= PMA_getHtmlForRowStatsTableRow(
+            $odd_row,
+            __('Creation'),
+            PMA_Util::localisedDate(strtotime($showtable['Create_time']))
+        );
+        $odd_row = !$odd_row;
+    }
+    if (isset($showtable['Update_time'])) {
+        $html_output .= PMA_getHtmlForRowStatsTableRow(
+            $odd_row,
+            __('Last update'),
+            PMA_Util::localisedDate(strtotime($showtable['Update_time']))
+        );
+        $odd_row = !$odd_row;
+    }
+    if (isset($showtable['Check_time'])) {
+        $html_output .= PMA_getHtmlForRowStatsTableRow(
+            $odd_row,
+            __('Last check'),
+            PMA_Util::localisedDate(strtotime($showtable['Check_time']))
+        );
+    }
+    $html_output .= '</tbody>'
+    . '</table>'
+    . '</fieldset>'
+    . '</div>';
+
+    return $html_output;
+}
+
+/**
+ * Get HTML snippet for action row in structure table,
+ * This function returns common HTML <td> for Primary, Unique, Index,
+ * Spatial actions
+ *
+ * @param array   $type               column type
+ * @param array   $tbl_storage_engine table storage engine
+ * @param string  $class              class attribute for <td>
+ * @param boolean $hasField           has field
+ * @param boolean $hasLinkClass       has <a> the class attribute
+ * @param string  $url_query          url query
+ * @param boolean $primary            primary if set, false otherwise
+ * @param string  $syntax             Sql syntax
+ * @param string  $message            message to show
+ * @param string  $action             action
+ * @param array   $titles             titles array
+ * @param array   $row                current row
+ * @param boolean $isPrimary          is primary action
+ *
+ * @return array $html_output, $action_enabled
+ */
+function PMA_getHtmlForActionRowInStructureTable($type, $tbl_storage_engine,
+    $class, $hasField, $hasLinkClass, $url_query, $primary, $syntax,
+    $message, $action, $titles, $row, $isPrimary
+) {
+    $html_output = '<li class="'. $class .'">';
+
+    if ($type == 'text'
+        || $type == 'blob'
+        || 'ARCHIVE' == $tbl_storage_engine
+        || $hasField
+    ) {
+        $html_output .= $titles['No' . $action];
+        $action_enabled = false;
+    } else {
+        $html_output .= '<a rel="samepage" '
+            . ($hasLinkClass ? 'class="ajax add_primary_key_anchor" ' : '')
+            . 'href="sql.php?' . $url_query . '&sql_query='
+            . urlencode(
+                'ALTER TABLE ' . PMA_Util::backquote($GLOBALS['table'])
+                . ($isPrimary ? ($primary ? ' DROP PRIMARY KEY,' : '') : '')
+                . ' ' . $syntax . '('
+                . PMA_Util::backquote($row['Field']) . ');'
+            )
+            . '&message_to_show=' . urlencode(
+                sprintf(
+                    $message,
+                    htmlspecialchars($row['Field'])
+                )
+            ) . '" >'
+            . $titles[$action] . '</a>';
+        $action_enabled = true;
+    }
+    $html_output .= '</li>';
+
+    return array($html_output, $action_enabled);
+}
+
+/**
+ * Get HTML for fulltext action,
+ * and this function returns $fulltext_enabled boolean value also
+ *
+ * @param string $tbl_storage_engine table storage engine
+ * @param string $type               column type
+ * @param string $url_query          url query
+ * @param array  $row                current row
+ * @param array  $titles             titles array
+ *
+ * @return type array $html_output, $fulltext_enabled
+ */
+function PMA_getHtmlForFullTextAction($tbl_storage_engine, $type, $url_query,
+    $row, $titles
+) {
+    $html_output = '<li class="fulltext nowrap">';
+    if (! empty($tbl_storage_engine)
+        && ($tbl_storage_engine == 'MYISAM'
+        || $tbl_storage_engine == 'ARIA'
+        || $tbl_storage_engine == 'MARIA'
+        || ($tbl_storage_engine == 'INNODB' && PMA_MYSQL_INT_VERSION >= 50604))
+        && (strpos(' ' . $type, 'text') || strpos(' ' . $type, 'char'))
+    ) {
+        $html_output .= '<a rel="samepage" href="sql.php?' . $url_query . '&sql_query='
+            . urlencode(
+                'ALTER TABLE ' . PMA_Util::backquote($GLOBALS['table'])
+                . ' ADD FULLTEXT(' . PMA_Util::backquote($row['Field'])
+                . ');'
+            )
+            . '&message_to_show='
+            . urlencode(
+                sprintf(
+                    __('An index has been added on %s'),
+                    htmlspecialchars($row['Field'])
+                )
+            )
+            . '">';
+        $html_output .= $titles['IdxFulltext'] . '</a>';
+        $fulltext_enabled = true;
+    } else {
+        $html_output .= $titles['NoIdxFulltext'];
+        $fulltext_enabled = false;
+    }
+    $html_output .= '</li>';
+    return array($html_output, $fulltext_enabled);
+}
+
+/**
+ * Get HTML snippet for "Distinc Value" action
+ *
+ * @param string $url_query url query
+ * @param array  $row       current row
+ * @param array  $titles    titles array
+ *
+ * @return string $html_output
+ */
+function PMA_getHtmlForDistinctValueAction($url_query, $row, $titles)
+{
+    $html_output = '<li class="browse nowrap">';
+    $html_output .= '<a href="sql.php?' . $url_query . '&sql_query='
+        . urlencode(
+            'SELECT COUNT(*) AS ' . PMA_Util::backquote(__('Rows'))
+            . ', ' . PMA_Util::backquote($row['Field'])
+            . ' FROM ' . PMA_Util::backquote($GLOBALS['table'])
+            . ' GROUP BY ' . PMA_Util::backquote($row['Field'])
+            . ' ORDER BY ' . PMA_Util::backquote($row['Field'])
+        )
+        . '">'
+        . $titles['DistinctValues']
+        . '</a>';
+    $html_output .= '</li>';
+
+    return $html_output;
+}
+
+/**
+ * Get HTML snippet for Actions in table structure
+ *
+ * @param string  $type                      column type
+ * @param string  $tbl_storage_engine        table storage engine
+ * @param boolean $primary                   primary if set, false otherwise
+ * @param string  $field_name                column name
+ * @param string  $url_query                 url query
+ * @param array   $titles                    titles array
+ * @param array   $row                       current row
+ * @param string  $rownum                    row number
+ * @param array   $hidden_titles             hidden titles
+ * @param array   $columns_with_unique_index columns with unique index
+ *
+ * @return string $html_output;
+ */
+function PMA_getHtmlForActionsInTableStructure($type, $tbl_storage_engine,
+    $primary, $field_name, $url_query, $titles, $row, $rownum, $hidden_titles,
+    $columns_with_unique_index
+) {
+    $html_output = '<td><ul class="table-structure-actions resizable-menu">';
+    list($primary, $primary_enabled)
+        = PMA_getHtmlForActionRowInStructureTable(
+            $type, $tbl_storage_engine,
+            'primary nowrap',
+            ($primary && $primary->hasColumn($field_name)),
+            true, $url_query, $primary,
+            'ADD PRIMARY KEY',
+            __('A primary key has been added on %s'),
+            'Primary', $titles, $row, true
+        );
+    $html_output .= $primary;
+    list($unique, $unique_enabled)
+        = PMA_getHtmlForActionRowInStructureTable(
+            $type, $tbl_storage_engine,
+            'unique nowrap',
+            isset($columns_with_unique_index[$field_name]),
+            false, $url_query, $primary, 'ADD UNIQUE',
+            __('An index has been added on %s'),
+            'Unique', $titles, $row, false
+        );
+    $html_output .= $unique;
+    list($index, $index_enabled)
+        = PMA_getHtmlForActionRowInStructureTable(
+            $type, $tbl_storage_engine,
+            'index nowrap', false, false, $url_query,
+            $primary, 'ADD INDEX', __('An index has been added on %s'),
+            'Index', $titles, $row, false
+        );
+    $html_output .= $index;
+    if (!PMA_DRIZZLE) {
+        $spatial_types = array(
+            'geometry', 'point', 'linestring', 'polygon', 'multipoint',
+            'multilinestring', 'multipolygon', 'geomtrycollection'
+        );
+        list($spatial, $spatial_enabled)
+            = PMA_getHtmlForActionRowInStructureTable(
+                $type, $tbl_storage_engine,
+                'spatial nowrap',
+                (! in_array($type, $spatial_types)
+                    || 'MYISAM' != $tbl_storage_engine
+                ),
+                false, $url_query, $primary, 'ADD SPATIAL',
+                __('An index has been added on %s'), 'Spatial',
+                $titles, $row, false
+            );
+        $html_output .= $spatial;
+
+        // FULLTEXT is possible on TEXT, CHAR and VARCHAR
+        list ($fulltext, $fulltext_enabled) = PMA_getHtmlForFullTextAction(
+            $tbl_storage_engine, $type, $url_query, $row, $titles
+        );
+        $html_output .= $fulltext;
+    }
+    $html_output .= PMA_getHtmlForDistinctValueAction($url_query, $row, $titles);
+    $html_output .= '</ul></td>';
+    return $html_output;
+}
+
+/**
+ * Get hidden action titles (image and string)
+ *
+ * @return array $hidden_titles
+ */
+function PMA_getHiddenTitlesArray()
+{
+    $hidden_titles = array();
+    $hidden_titles['DistinctValues'] = PMA_Util::getIcon(
+        'b_browse.png', __('Distinct values'), true
+    );
+    $hidden_titles['Primary'] = PMA_Util::getIcon(
+        'b_primary.png', __('Add primary key'), true
+    );
+    $hidden_titles['NoPrimary'] = PMA_Util::getIcon(
+        'bd_primary.png', __('Add primary key'), true
+    );
+    $hidden_titles['Index'] = PMA_Util::getIcon(
+        'b_index.png', __('Add index'), true
+    );
+    $hidden_titles['NoIndex'] = PMA_Util::getIcon(
+        'bd_index.png', __('Add index'), true
+    );
+    $hidden_titles['Unique'] = PMA_Util::getIcon(
+        'b_unique.png', __('Add unique index'), true
+    );
+    $hidden_titles['NoUnique'] = PMA_Util::getIcon(
+        'bd_unique.png', __('Add unique index'), true
+    );
+    $hidden_titles['Spatial'] = PMA_Util::getIcon(
+        'b_spatial.png', __('Add SPATIAL index'), true
+    );
+    $hidden_titles['NoSpatial'] = PMA_Util::getIcon(
+        'bd_spatial.png', __('Add SPATIAL index'), true
+    );
+    $hidden_titles['IdxFulltext'] = PMA_Util::getIcon(
+        'b_ftext.png', __('Add FULLTEXT index'), true
+    );
+    $hidden_titles['NoIdxFulltext'] = PMA_Util::getIcon(
+        'bd_ftext.png', __('Add FULLTEXT index'), true
+    );
+
+    return $hidden_titles;
+}
+
+/**
+ * Get action titles (image or string array
+ *
+ * @return array  $titles
+ */
+function PMA_getActionTitlesArray()
+{
+    $titles = array();
+    $titles['Change']
+        = PMA_Util::getIcon('b_edit.png', __('Change'));
+    $titles['Drop']
+        = PMA_Util::getIcon('b_drop.png', __('Drop'));
+    $titles['NoDrop']
+        = PMA_Util::getIcon('b_drop.png', __('Drop'));
+    $titles['Primary']
+        = PMA_Util::getIcon('b_primary.png', __('Primary'));
+    $titles['Index']
+        = PMA_Util::getIcon('b_index.png', __('Index'));
+    $titles['Unique']
+        = PMA_Util::getIcon('b_unique.png', __('Unique'));
+    $titles['Spatial']
+        = PMA_Util::getIcon('b_spatial.png', __('Spatial'));
+    $titles['IdxFulltext']
+        = PMA_Util::getIcon('b_ftext.png', __('Fulltext'));
+    $titles['NoPrimary']
+        = PMA_Util::getIcon('bd_primary.png', __('Primary'));
+    $titles['NoIndex']
+        = PMA_Util::getIcon('bd_index.png', __('Index'));
+    $titles['NoUnique']
+        = PMA_Util::getIcon('bd_unique.png', __('Unique'));
+    $titles['NoSpatial']
+        = PMA_Util::getIcon('bd_spatial.png', __('Spatial'));
+    $titles['NoIdxFulltext']
+        = PMA_Util::getIcon('bd_ftext.png', __('Fulltext'));
+    $titles['DistinctValues']
+        = PMA_Util::getIcon('b_browse.png', __('Distinct values'));
+
+    return $titles;
+}
+
+/**
+ * Get HTML snippet for display table statistics
+ *
+ * @param array   $showtable                full table status info
+ * @param integer $table_info_num_rows      table info number of rows
+ * @param boolean $tbl_is_view              whether table is view or not
+ * @param boolean $db_is_information_schema whether db is information schema or not
+ * @param string  $tbl_storage_engine       table storage engine
+ * @param string  $url_query                url query
+ * @param string  $tbl_collation            table collation
+ *
+ * @return string $html_output
+ */
+function PMA_getHtmlForDisplayTableStats($showtable, $table_info_num_rows,
+    $tbl_is_view, $db_is_information_schema, $tbl_storage_engine, $url_query,
+    $tbl_collation
+) {
+    $html_output = '<div id="tablestatistics">';
+    if (empty($showtable)) {
+        $showtable = PMA_Table::sGetStatusInfo(
+            $GLOBALS['db'], $GLOBALS['table'], null, true
+        );
+    }
+
+    $nonisam     = false;
+    $is_innodb = (isset($showtable['Type']) && $showtable['Type'] == 'InnoDB');
+    if (isset($showtable['Type'])
+        && ! preg_match('@ISAM|HEAP at i', $showtable['Type'])
+    ) {
+        $nonisam = true;
+    }
+
+    // Gets some sizes
+
+    $mergetable = PMA_Table::isMerge($GLOBALS['db'], $GLOBALS['table']);
+
+    // this is to display for example 261.2 MiB instead of 268k KiB
+    $max_digits = 3;
+    $decimals = 1;
+    list($data_size, $data_unit) = PMA_Util::formatByteDown(
+        $showtable['Data_length'], $max_digits, $decimals
+    );
+    if ($mergetable == false) {
+        list($index_size, $index_unit) = PMA_Util::formatByteDown(
+            $showtable['Index_length'], $max_digits, $decimals
+        );
+    }
+    // InnoDB returns a huge value in Data_free, do not use it
+    if (! $is_innodb
+        && isset($showtable['Data_free'])
+        && $showtable['Data_free'] > 0
+    ) {
+        list($free_size, $free_unit) = PMA_Util::formatByteDown(
+            $showtable['Data_free'], $max_digits, $decimals
+        );
+        list($effect_size, $effect_unit) = PMA_Util::formatByteDown(
+            $showtable['Data_length'] + $showtable['Index_length'] - $showtable['Data_free'],
+            $max_digits, $decimals
+        );
+    } else {
+        list($effect_size, $effect_unit) = PMA_Util::formatByteDown(
+            $showtable['Data_length'] + $showtable['Index_length'],
+            $max_digits, $decimals
+        );
+    }
+    list($tot_size, $tot_unit) = PMA_Util::formatByteDown(
+        $showtable['Data_length'] + $showtable['Index_length'],
+        $max_digits, $decimals
+    );
+    if ($table_info_num_rows > 0) {
+        list($avg_size, $avg_unit) = PMA_Util::formatByteDown(
+            ($showtable['Data_length'] + $showtable['Index_length']) / $showtable['Rows'],
+            6, 1
+        );
+    }
+
+    // Displays them
+    $odd_row = false;
+
+    $html_output .=  '<fieldset>'
+        . '<legend>' . __('Information') . '</legend>'
+        . '<a id="showusage"></a>';
+
+    if (! $tbl_is_view && ! $db_is_information_schema) {
+        $html_output .= '<table id="tablespaceusage" class="data">'
+            . '<caption class="tblHeaders">' . __('Space usage') . '</caption>'
+            . '<tbody>';
+
+        $html_output .= PMA_getHtmlForSpaceUsageTableRow(
+            $odd_row, __('Data'), $data_size, $data_unit
+        );
+        $odd_row = !$odd_row;
+
+        if (isset($index_size)) {
+            $html_output .= PMA_getHtmlForSpaceUsageTableRow(
+                $odd_row, __('Index'), $index_size, $index_unit
+            );
+            $odd_row = !$odd_row;
+        }
+
+        if (isset($free_size)) {
+            $html_output .= PMA_getHtmlForSpaceUsageTableRow(
+                $odd_row, __('Overhead'), $free_size, $free_unit
+            );
+            $html_output .= PMA_getHtmlForSpaceUsageTableRow(
+                $odd_row, __('Effective'), $effect_size, $effect_unit
+            );
+            $odd_row = !$odd_row;
+        }
+        if (isset($tot_size) && $mergetable == false) {
+            $html_output .= PMA_getHtmlForSpaceUsageTableRow(
+                $odd_row, __('Total'), $tot_size, $tot_unit
+            );
+            $odd_row = !$odd_row;
+        }
+        // Optimize link if overhead
+        if (isset($free_size) && !PMA_DRIZZLE
+            && ($tbl_storage_engine == 'MYISAM'
+            || $tbl_storage_engine == 'ARIA'
+            || $tbl_storage_engine == 'MARIA'
+            || $tbl_storage_engine == 'BDB')
+        ) {
+            $html_output .= PMA_getHtmlForOptimizeLink($url_query);
+        }
+        $html_output .= '</tbody>'
+            . '</table>';
+    }
+
+    $html_output .= getHtmlForRowStatsTable(
+        $showtable, $tbl_collation,
+        $is_innodb, $mergetable,
+        (isset ($avg_size) ? $avg_size : ''),
+        (isset ($avg_unit) ? $avg_unit : '')
+    );
+
+    return $html_output;
+}
+
+/**
+ * Displays HTML for changing one or more columns
+ *
+ * @param string  $db                       database name
+ * @param string  $table                    table name
+ * @param array   $selected                 the selected columns
+ * @param string  $action                   target script to call 
+ *
+ * @return boolean $regenerate              true if error occurred
+ * 
+ */
+function PMA_displayHtmlForColumnChange($db, $table, $selected, $action) 
+{
+    // $selected comes from multi_submits.inc.php
+    if (empty($selected)) {
+        $selected[]   = $_REQUEST['field'];
+        $selected_cnt = 1;
+    } else { // from a multiple submit
+        $selected_cnt = count($selected);
+    }
+
+    /**
+     * @todo optimize in case of multiple fields to modify
+     */
+    for ($i = 0; $i < $selected_cnt; $i++) {
+        $fields_meta[] = PMA_DBI_get_columns($db, $table, $selected[$i], true);
+    }
+    $num_fields  = count($fields_meta);
+    // set these globals because tbl_columns_definition_form.inc.php 
+    // verifies them
+    // @todo: refactor tbl_columns_definition_form.inc.php so that it uses 
+    // function params
+    $GLOBALS['action'] = 'tbl_structure.php';
+    $GLOBALS['num_fields'] = $num_fields; 
+
+    // Get more complete field information.
+    // For now, this is done to obtain MySQL 4.1.2+ new TIMESTAMP options
+    // and to know when there is an empty DEFAULT value.
+    // Later, if the analyser returns more information, it
+    // could be executed to replace the info given by SHOW FULL COLUMNS FROM.
+    /**
+     * @todo put this code into a require()
+     * or maybe make it part of PMA_DBI_get_columns();
+     */
+
+    // We also need this to correctly learn if a TIMESTAMP is NOT NULL, since
+    // SHOW FULL COLUMNS says NULL and SHOW CREATE TABLE says NOT NULL (tested
+    // in MySQL 4.0.25).
+
+    $show_create_table = PMA_DBI_fetch_value(
+        'SHOW CREATE TABLE ' . PMA_Util::backquote($db) . '.' . PMA_Util::backquote($table),
+        0, 1
+    );
+    $analyzed_sql = PMA_SQP_analyze(PMA_SQP_parse($show_create_table));
+    unset($show_create_table);
+    /**
+     * Form for changing properties.
+     */
+    include 'libraries/tbl_columns_definition_form.inc.php';
+}
+
+
+/**
+ * Update the table's structure based on $_REQUEST
+ *
+ * @param string  $db                       database name
+ * @param string  $table                    table name
+ *
+ * @return boolean $regenerate              true if error occurred
+ *
+ */
+function PMA_updateColumns($db, $table)
+{
+    $err_url = 'tbl_structure.php?' . PMA_generate_common_url($db, $table);
+    $regenerate = false;
+    $field_cnt = count($_REQUEST['field_name']);
+    $key_fields = array();
+    $changes = array();
+
+    for ($i = 0; $i < $field_cnt; $i++) {
+        $changes[] = 'CHANGE ' . PMA_Table::generateAlter(
+            isset($_REQUEST['field_orig'][$i])
+                ? $_REQUEST['field_orig'][$i]
+                : '',
+            $_REQUEST['field_name'][$i],
+            $_REQUEST['field_type'][$i],
+            $_REQUEST['field_length'][$i],
+            $_REQUEST['field_attribute'][$i],
+            isset($_REQUEST['field_collation'][$i])
+                ? $_REQUEST['field_collation'][$i]
+                : '',
+            isset($_REQUEST['field_null'][$i])
+                ? $_REQUEST['field_null'][$i]
+                : 'NOT NULL',
+            $_REQUEST['field_default_type'][$i],
+            $_REQUEST['field_default_value'][$i],
+            isset($_REQUEST['field_extra'][$i])
+                ? $_REQUEST['field_extra'][$i]
+                : false,
+            isset($_REQUEST['field_comments'][$i])
+                ? $_REQUEST['field_comments'][$i]
+                : '',
+            $key_fields,
+            $i,
+            isset($_REQUEST['field_move_to'][$i])
+                ? $_REQUEST['field_move_to'][$i]
+                : ''
+        );
+    } // end for
+
+    // Builds the primary keys statements and updates the table
+    $key_query = '';
+    /**
+     * this is a little bit more complex
+     *
+     * @todo if someone selects A_I when altering a column we need to check:
+     *  - no other column with A_I
+     *  - the column has an index, if not create one
+     *
+    if (count($key_fields)) {
+        $fields = array();
+        foreach ($key_fields as $each_field) {
+            if (isset($_REQUEST['field_name'][$each_field]) && strlen($_REQUEST['field_name'][$each_field])) {
+                $fields[] = PMA_Util::backquote($_REQUEST['field_name'][$each_field]);
+            }
+        } // end for
+        $key_query = ', ADD KEY (' . implode(', ', $fields) . ') ';
+    }
+     */
+
+    // To allow replication, we first select the db to use and then run queries
+    // on this db.
+    if (! PMA_DBI_select_db($db)) {
+        PMA_Util::mysqlDie(
+            PMA_DBI_getError(),
+            'USE ' . PMA_Util::backquote($db) . ';',
+            '',
+            $err_url
+        );
+    }
+    $sql_query = 'ALTER TABLE ' . PMA_Util::backquote($table) . ' ';
+    $sql_query .= implode(', ', $changes) . $key_query;
+    $sql_query .= ';';
+    $result    = PMA_DBI_try_query($sql_query);
+
+    $response = PMA_Response::getInstance();
+    if ($result !== false) {
+        $message = PMA_Message::success(
+            __('Table %1$s has been altered successfully')
+        );
+        $message->addParam($table);
+
+        /**
+         * If comments were sent, enable relation stuff
+         */
+        include_once 'libraries/transformations.lib.php';
+
+        // update field names in relation
+        if (isset($_REQUEST['field_orig']) && is_array($_REQUEST['field_orig'])) {
+            foreach ($_REQUEST['field_orig'] as $fieldindex => $fieldcontent) {
+                if ($_REQUEST['field_name'][$fieldindex] != $fieldcontent) {
+                    PMA_REL_renameField(
+                        $db, $table, $fieldcontent,
+                        $_REQUEST['field_name'][$fieldindex]
+                    );
+                }
+            }
+        }
+
+        // update mime types
+        if (isset($_REQUEST['field_mimetype'])
+            && is_array($_REQUEST['field_mimetype'])
+            && $GLOBALS['cfg']['BrowseMIME']
+        ) {
+            foreach ($_REQUEST['field_mimetype'] as $fieldindex => $mimetype) {
+                if (isset($_REQUEST['field_name'][$fieldindex])
+                    && strlen($_REQUEST['field_name'][$fieldindex])
+                ) {
+                    PMA_setMIME(
+                        $db, $table, $_REQUEST['field_name'][$fieldindex],
+                        $mimetype,
+                        $_REQUEST['field_transformation'][$fieldindex],
+                        $_REQUEST['field_transformation_options'][$fieldindex]
+                    );
+                }
+            }
+        }
+
+        $response->addHTML(
+            PMA_Util::getMessage($message, $sql_query, 'success')
+        );
+    } else {
+        // An error happened while inserting/updating a table definition
+        $response->isSuccess(false);
+        $response->addJSON('message',
+            PMA_Message::rawError(__('Query error') . ':<br />'.PMA_DBI_getError())
+        );
+        $regenerate = true;
+    }
+    return $regenerate;
+}
+
+/**
+ * Moves columns in the table's structure based on $_REQUEST
+ *
+ * @param string  $db                       database name
+ * @param string  $table                    table name
+ */
+function PMA_moveColumns($db, $table)
+{
+    PMA_DBI_select_db($db);
+
+    /*
+     * load the definitions for all columns
+     */
+    $columns = PMA_DBI_get_columns_full($db, $table);
+    $column_names = array_keys($columns);
+    $changes = array();
+    $we_dont_change_keys = array();
+
+    // move columns from first to last
+    for ($i = 0, $l = count($_REQUEST['move_columns']); $i < $l; $i++) {
+        $column = $_REQUEST['move_columns'][$i];
+        // is this column already correctly placed?
+        if ($column_names[$i] == $column) {
+            continue;
+        }
+
+        // it is not, let's move it to index $i
+        $data = $columns[$column];
+        $extracted_columnspec = PMA_Util::extractColumnSpec($data['Type']);
+        if (isset($data['Extra']) && $data['Extra'] == 'on update CURRENT_TIMESTAMP') {
+            $extracted_columnspec['attribute'] = $data['Extra'];
+            unset($data['Extra']);
+        }
+        $current_timestamp = false;
+        if ($data['Type'] == 'timestamp' && $data['Default'] == 'CURRENT_TIMESTAMP') {
+            $current_timestamp = true;
+        }
+        $default_type
+            = $data['Null'] === 'YES' && $data['Default'] === null
+                ? 'NULL'
+                : ($current_timestamp
+                    ? 'CURRENT_TIMESTAMP'
+                    : ($data['Default'] == ''
+                        ? 'NONE'
+                        : 'USER_DEFINED'));
+
+        $changes[] = 'CHANGE ' . PMA_Table::generateAlter(
+            $column,
+            $column,
+            strtoupper($extracted_columnspec['type']),
+            $extracted_columnspec['spec_in_brackets'],
+            $extracted_columnspec['attribute'],
+            isset($data['Collation']) ? $data['Collation'] : '',
+            $data['Null'] === 'YES' ? 'NULL' : 'NOT NULL',
+            $default_type,
+            $current_timestamp ? '' : $data['Default'],
+            isset($data['Extra']) && $data['Extra'] !== '' ? $data['Extra'] : false,
+            isset($data['Comments']) && $data['Comments'] !== ''
+            ? $data['Comments'] : false,
+            $we_dont_change_keys,
+            $i,
+            $i === 0 ? '-first' : $column_names[$i - 1]
+        );
+        // update current column_names array, first delete old position
+        for ($j = 0, $ll = count($column_names); $j < $ll; $j++) {
+            if ($column_names[$j] == $column) {
+                unset($column_names[$j]);
+            }
+        }
+        // insert moved column
+        array_splice($column_names, $i, 0, $column);
+    }
+    $response = PMA_Response::getInstance();
+    if (empty($changes)) { // should never happen
+        $response->isSuccess(false);
+        exit;
+    }
+    $move_query = 'ALTER TABLE ' . PMA_Util::backquote($table) . ' ';
+    $move_query .= implode(', ', $changes);
+    // move columns
+    $result = PMA_DBI_try_query($move_query);
+    $tmp_error = PMA_DBI_getError();
+    if ($tmp_error) {
+        $response->isSuccess(false);
+        $response->addJSON('message', PMA_Message::error($tmp_error));
+    } else {
+        $message = PMA_Message::success(
+            __('The columns have been moved successfully.')
+        );
+        $response->addJSON('message', $message);
+        $response->addJSON('columns', $column_names);
+    }
+    exit;
+}
+?>
diff --git a/phpmyadmin/libraries/sysinfo.lib.php b/phpmyadmin/libraries/sysinfo.lib.php
new file mode 100644
index 0000000..14fcdfd
--- /dev/null
+++ b/phpmyadmin/libraries/sysinfo.lib.php
@@ -0,0 +1,363 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * Library for extracting information about system memory and cpu.
+ * Currently supports all Windows and Linux plattforms
+ *
+ * This code is based on the OS Classes from the phpsysinfo project
+ * (http://phpsysinfo.sourceforge.net/)
+ *
+ * @package PhpMyAdmin-sysinfo
+ */
+if (! defined('PHPMYADMIN')) {
+    exit;
+}
+
+define(
+    'MEMORY_REGEXP',
+    '/^(MemTotal|MemFree|Cached|Buffers|SwapCached|SwapTotal|SwapFree):'
+    . '\s+(.*)\s*kB/im'
+);
+
+/**
+ * Returns OS type used for sysinfo class
+ *
+ * @param string $php_os PHP_OS constant
+ *
+ * @return string
+ */
+function PMA_getSysInfoOs($php_os = PHP_OS)
+{
+
+    // look for common UNIX-like systems
+    $unix_like = array('FreeBSD', 'DragonFly');
+    if (in_array($php_os, $unix_like)) {
+        $php_os = 'Linux';
+    }
+
+    return ucfirst($php_os);
+}
+
+/**
+ * Gets sysinfo class mathing current OS
+ *
+ * @return sysinfo class
+ */
+function PMA_getSysInfo()
+{
+    $php_os = PMA_getSysInfoOs();
+    $supported = array('Linux', 'WINNT', 'SunOS');
+
+    $sysinfo = array();
+
+    if (in_array($php_os, $supported)) {
+        $ret = eval("return new PMA_SysInfo" . $php_os . "();");
+        if ($ret->supported()) {
+            return $ret;
+        }
+    }
+
+    return new PMA_SysInfo;
+}
+
+/**
+ * Basic sysinfo class not providing any real data.
+ *
+ * @package PhpMyAdmin-sysinfo
+ */
+class PMA_SysInfo
+{
+    public $os = PHP_OS;
+
+    /**
+     * Gets load information
+     *
+     * @return array with load data
+     */
+    public function loadavg()
+    {
+        return array('loadavg' => 0);
+    }
+
+    /**
+     * Gets information about memory usage
+     *
+     * @return array with memory usage data
+     */
+    public function memory()
+    {
+        return array();
+    }
+
+    /**
+     * Checks whether class is supported in this environment
+     *
+     * @return true on success
+     */
+    public function supported()
+    {
+        return true;
+    }
+}
+
+/**
+ * Windows NT based SysInfo class
+ *
+ * @package PhpMyAdmin-sysinfo
+ */
+class PMA_SysInfoWinnt extends PMA_SysInfo
+{
+    private $_wmi;
+
+    public $os = 'WINNT';
+
+    /**
+     * Constructor to access to wmi database.
+     */
+    public function __construct()
+    {
+        if (!class_exists('COM')) {
+            $this->_wmi = null;
+        } else {
+            // initialize the wmi object
+            $objLocator = new COM('WbemScripting.SWbemLocator');
+            $this->_wmi = $objLocator->ConnectServer();
+        }
+    }
+
+    /**
+     * Gets load information
+     *
+     * @return array with load data
+     */
+    function loadavg()
+    {
+        $loadavg = "";
+        $sum = 0;
+        $buffer = $this->_getWMI('Win32_Processor', array('LoadPercentage'));
+
+        foreach ($buffer as $load) {
+            $value = $load['LoadPercentage'];
+            $loadavg .= $value . ' ';
+            $sum += $value;
+        }
+
+        return array('loadavg' => $sum / count($buffer));
+    }
+
+    /**
+     * Checks whether class is supported in this environment
+     *
+     * @return true on success
+     */
+    public function supported()
+    {
+        return !is_null($this->_wmi);
+    }
+
+    /**
+     * Reads data from WMI
+     *
+     * @param string $strClass Class to read
+     * @param array  $strValue Values to read
+     *
+     * @return arrray with results
+     */
+    private function _getWMI($strClass, $strValue = array())
+    {
+        $arrData = array();
+        $value = "";
+
+        $objWEBM = $this->_wmi->Get($strClass);
+        $arrProp = $objWEBM->Properties_;
+        $arrWEBMCol = $objWEBM->Instances_();
+        foreach ($arrWEBMCol as $objItem) {
+            if (is_array($arrProp)) {
+                reset($arrProp);
+            }
+            $arrInstance = array();
+            foreach ($arrProp as $propItem) {
+                if ( empty($strValue)) {
+                    eval("\$value = \$objItem->" . $propItem->Name . ";");
+                    $arrInstance[$propItem->Name] = trim($value);
+                } else {
+                    if (in_array($propItem->Name, $strValue)) {
+                        eval("\$value = \$objItem->" . $propItem->Name . ";");
+                        $arrInstance[$propItem->Name] = trim($value);
+                    }
+                }
+            }
+            $arrData[] = $arrInstance;
+        }
+        return $arrData;
+    }
+
+    /**
+     * Gets information about memory usage
+     *
+     * @return array with memory usage data
+     */
+    function memory()
+    {
+        $buffer = $this->_getWMI(
+            "Win32_OperatingSystem",
+            array('TotalVisibleMemorySize', 'FreePhysicalMemory')
+        );
+        $mem = Array();
+        $mem['MemTotal'] = $buffer[0]['TotalVisibleMemorySize'];
+        $mem['MemFree'] = $buffer[0]['FreePhysicalMemory'];
+        $mem['MemUsed'] = $mem['MemTotal'] - $mem['MemFree'];
+
+        $buffer = $this->_getWMI('Win32_PageFileUsage');
+
+        $mem['SwapTotal'] = 0;
+        $mem['SwapUsed'] = 0;
+        $mem['SwapPeak'] = 0;
+
+        foreach ($buffer as $swapdevice) {
+            $mem['SwapTotal'] += $swapdevice['AllocatedBaseSize'] * 1024;
+            $mem['SwapUsed'] += $swapdevice['CurrentUsage'] * 1024;
+            $mem['SwapPeak'] += $swapdevice['PeakUsage'] * 1024;
+        }
+
+        return $mem;
+    }
+}
+
+/**
+ * Linux based SysInfo class
+ *
+ * @package PhpMyAdmin-sysinfo
+ */
+class PMA_SysInfoLinux extends PMA_SysInfo
+{
+    public $os = 'Linux';
+
+    /**
+     * Gets load information
+     *
+     * @return array with load data
+     */
+    function loadavg()
+    {
+        $buf = file_get_contents('/proc/stat');
+        $nums = preg_split("/\s+/", substr($buf, 0, strpos($buf, "\n")));
+        return Array(
+            'busy' => $nums[1] + $nums[2] + $nums[3],
+            'idle' => intval($nums[4])
+        );
+    }
+
+    /**
+     * Checks whether class is supported in this environment
+     *
+     * @return true on success
+     */
+    public function supported()
+    {
+        return is_readable('/proc/meminfo') && is_readable('/proc/stat');
+    }
+
+
+    /**
+     * Gets information about memory usage
+     *
+     * @return array with memory usage data
+     */
+    function memory()
+    {
+        preg_match_all(
+            MEMORY_REGEXP,
+            file_get_contents('/proc/meminfo'),
+            $matches
+        );
+
+        $mem = array_combine($matches[1], $matches[2]);
+        $mem['MemUsed']
+            = $mem['MemTotal'] - $mem['MemFree'] - $mem['Cached'] - $mem['Buffers'];
+        $mem['SwapUsed']
+            = $mem['SwapTotal'] - $mem['SwapFree'] - $mem['SwapCached'];
+
+        foreach ($mem as $idx => $value) {
+            $mem[$idx] = intval($value);
+        }
+        return $mem;
+    }
+}
+
+/**
+ * SunOS based SysInfo class
+ *
+ * @package PhpMyAdmin-sysinfo
+ */
+class PMA_SysInfoSunos extends PMA_SysInfo
+{
+    public $os = 'SunOS';
+
+    /**
+     * Read value from kstat
+     *
+     * @param string $key Key to read
+     *
+     * @return string with value
+     */
+    private function _kstat($key)
+    {
+        if ($m = shell_exec('kstat -p d '.$key)) {
+            list($key, $value) = preg_split("/\t/", trim($m), 2);
+            return $value;
+        } else {
+            return '';
+        }
+    }
+
+    /**
+     * Gets load information
+     *
+     * @return array with load data
+     */
+    public function loadavg()
+    {
+        $load1 = $this->_kstat('unix:0:system_misc:avenrun_1min');
+
+        return array('loadavg' => $load1);
+    }
+
+    /**
+     * Checks whether class is supported in this environment
+     *
+     * @return true on success
+     */
+    public function supported()
+    {
+        return is_readable('/proc/meminfo');
+    }
+
+
+    /**
+     * Gets information about memory usage
+     *
+     * @return array with memory usage data
+     */
+    public function memory()
+    {
+        preg_match_all(
+            MEMORY_REGEXP,
+            file_get_contents('/proc/meminfo'),
+            $matches
+        );
+
+        $pagesize = $this->_kstat('unix:0:seg_cache:slab_size');
+        $mem['MemTotal']
+            = $this->_kstat('unix:0:system_pages:pagestotal') * $pagesize;
+        $mem['MemUsed']
+            = $this->_kstat('unix:0:system_pages:pageslocked') * $pagesize;
+        $mem['MemFree']
+            = $this->_kstat('unix:0:system_pages:pagesfree') * $pagesize;
+        $mem['SwapTotal'] = $this->_kstat('unix:0:vminfo:swap_avail') / 1024;
+        $mem['SwapUsed'] = $this->_kstat('unix:0:vminfo:swap_alloc') / 1024;
+        $mem['SwapFree'] = $this->_kstat('unix:0:vminfo:swap_free') / 1024;
+
+        return $mem;
+    }
+}
diff --git a/phpmyadmin/libraries/tbl_columns_definition_form.inc.php b/phpmyadmin/libraries/tbl_columns_definition_form.inc.php
new file mode 100644
index 0000000..4acf33a
--- /dev/null
+++ b/phpmyadmin/libraries/tbl_columns_definition_form.inc.php
@@ -0,0 +1,906 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * Display form for changing/adding table fields/columns.
+ * Included by tbl_addfield.php and tbl_create.php
+ *
+ * @package PhpMyAdmin
+ */
+if (! defined('PHPMYADMIN')) {
+    exit;
+}
+
+/**
+ * Check parameters
+ */
+require_once './libraries/Util.class.php';
+
+PMA_Util::checkParameters(array('db', 'table', 'action', 'num_fields'));
+
+
+// Get available character sets and storage engines
+require_once './libraries/mysql_charsets.lib.php';
+require_once './libraries/StorageEngine.class.php';
+
+/**
+ * Class for partition management
+ */
+require_once './libraries/Partition.class.php';
+
+/**
+ * We are in transition between old-style echo and new-style PMA_Response
+ * so this script generates $html and at the bottom, either echos it
+ * or uses addHTML on it. 
+ *
+ * Initialize $html in case this variable was used by a caller 
+ * (yes, this script should be refactored into functions)
+ */
+$html = '';
+
+$length_values_input_size = 8;
+
+$_form_params = array(
+    'db' => $db
+);
+
+if ($action == 'tbl_create.php') {
+    $_form_params['reload'] = 1;
+} elseif ($action == 'tbl_addfield.php') {
+    $_form_params['field_where'] = $_REQUEST['field_where'];
+    $_form_params['after_field'] = $_REQUEST['after_field'];
+    $_form_params['table'] = $table;
+} else {
+    $_form_params['table'] = $table;
+}
+
+if (isset($num_fields)) {
+    $_form_params['orig_num_fields'] = $num_fields;
+}
+
+if (isset($_REQUEST['field_where'])) {
+    $_form_params['orig_field_where'] = $_REQUEST['field_where'];
+}
+
+if (isset($_REQUEST['after_field'])) {
+    $_form_params['orig_after_field'] = $_REQUEST['after_field'];
+}
+
+if (isset($selected) && is_array($selected)) {
+    foreach ($selected as $o_fld_nr => $o_fld_val) {
+        $_form_params['selected[' . $o_fld_nr . ']'] = $o_fld_val;
+        if (! isset($true_selected)) {
+            $_form_params['true_selected[' . $o_fld_nr . ']'] = $o_fld_val;
+        }
+    }
+
+    if (isset($true_selected) && is_array($true_selected)) {
+        foreach ($true_selected as $o_fld_nr => $o_fld_val) {
+            $_form_params['true_selected[' . $o_fld_nr . ']'] = $o_fld_val;
+        }
+    }
+} elseif (isset($_REQUEST['field'])) {
+    $_form_params['orig_field'] = $_REQUEST['field'];
+    if (isset($orig_field)) {
+        $_form_params['true_selected[]'] = $orig_field;
+    } else {
+        $_form_params['true_selected[]'] = $_REQUEST['field'];
+    }
+}
+
+$is_backup = ($action != 'tbl_create.php' && $action != 'tbl_addfield.php');
+
+$header_cells = array();
+$content_cells = array();
+
+$header_cells[] = __('Name');
+$header_cells[] = __('Type')
+    . PMA_Util::showMySQLDocu('SQL-Syntax', 'data-types');
+$header_cells[] = __('Length/Values')
+    . PMA_Util::showHint(
+        __(
+            'If column type is "enum" or "set", please enter the values using'
+            . ' this format: \'a\',\'b\',\'c\'…<br />If you ever need to put'
+            . ' a backslash ("\") or a single quote ("\'") amongst those values,'
+            . ' precede it with a backslash (for example \'\\\\xyz\' or \'a\\\'b\').'
+        )
+    );
+$header_cells[] = __('Default')
+    . PMA_Util::showHint(
+        __(
+            'For default values, please enter just a single value,'
+            . ' without backslash escaping or quotes, using this format: a'
+        )
+    );
+$header_cells[] = __('Collation');
+$header_cells[] = __('Attributes');
+$header_cells[] = __('Null');
+
+// We could remove this 'if' and let the key information be shown and
+// editable. However, for this to work, structure.lib.php must be modified 
+// to use the key fields, as tbl_addfield does.
+
+if (! $is_backup) {
+    $header_cells[] = __('Index');
+}
+
+$header_cells[] = '<abbr title="AUTO_INCREMENT">A_I</abbr>';
+
+require_once './libraries/transformations.lib.php';
+$cfgRelation = PMA_getRelationsParam();
+
+$comments_map = array();
+$mime_map = array();
+$available_mime = array();
+
+$comments_map = PMA_getComments($db, $table);
+$header_cells[] = __('Comments');
+
+if (isset($fields_meta)) {
+    // for moving, load all available column names
+    $move_columns_sql_query    = 'SELECT * FROM ' 
+        . PMA_Util::backquote($db)
+        . '.'
+        . PMA_Util::backquote($table)
+        . ' LIMIT 1';
+    $move_columns_sql_result = PMA_DBI_try_query($move_columns_sql_query);
+    $move_columns = PMA_DBI_get_fields_meta($move_columns_sql_result);
+    unset($move_columns_sql_query, $move_columns_sql_result);
+
+    $header_cells[] = __('Move column');
+}
+
+if ($cfgRelation['mimework'] && $GLOBALS['cfg']['BrowseMIME']) {
+    $mime_map = PMA_getMIME($db, $table);
+    $available_mime = PMA_getAvailableMIMEtypes();
+
+    $hint = '<br />'
+        . sprintf(
+            __(
+                'For a list of available transformation options and their MIME'
+                . ' type transformations, click on %stransformation descriptions%s'
+            ),
+            '<a href="transformation_overview.php?'
+            . PMA_generate_common_url($db, $table)
+            . '" target="_blank">',
+            '</a>'
+        );
+
+
+    $header_cells[] = __('MIME type');
+    $header_cells[] = __('Browser transformation');
+    $header_cells[] = __('Transformation options')
+        . PMA_Util::showHint(
+            __(
+                'Please enter the values for transformation options using this'
+                . ' format: \'a\', 100, b,\'c\'…<br />If you ever need to put'
+                . ' a backslash ("\") or a single quote ("\'") amongst those'
+                . ' values, precede it with a backslash (for example \'\\\\xyz\''
+                . ' or \'a\\\'b\').'
+            )
+            . $hint
+        );
+}
+
+//  workaround for field_fulltext, because its submitted indices contain
+//  the index as a value, not a key. Inserted here for easier maintaineance
+//  and less code to change in existing files.
+if (isset($field_fulltext) && is_array($field_fulltext)) {
+    foreach ($field_fulltext as $fulltext_nr => $fulltext_indexkey) {
+        $submit_fulltext[$fulltext_indexkey] = $fulltext_indexkey;
+    }
+}
+
+for ($i = 0; $i < $num_fields; $i++) {
+    if (! empty($regenerate)) {
+        // An error happened with previous inputs, so we will restore the data
+        // to embed it once again in this form.
+
+        $row['Field'] = isset($_REQUEST['field_name'][$i])
+            ? $_REQUEST['field_name'][$i]
+            : false;
+        $row['Type'] = isset($_REQUEST['field_type'][$i])
+            ? $_REQUEST['field_type'][$i]
+            : false;
+        $row['Collation'] = isset($_REQUEST['field_collation'][$i])
+            ? $_REQUEST['field_collation'][$i]
+            : '';
+        $row['Null'] = isset($_REQUEST['field_null'][$i])
+            ? $_REQUEST['field_null'][$i]
+            : '';
+
+        if (isset($_REQUEST['field_key'][$i])
+            && $_REQUEST['field_key'][$i] == 'primary_' . $i
+        ) {
+            $row['Key'] = 'PRI';
+        } elseif (isset($_REQUEST['field_key'][$i])
+            && $_REQUEST['field_key'][$i] == 'index_' . $i
+        ) {
+            $row['Key'] = 'MUL';
+        } elseif (isset($_REQUEST['field_key'][$i])
+            && $_REQUEST['field_key'][$i] == 'unique_' . $i
+        ) {
+            $row['Key'] = 'UNI';
+        } elseif (isset($_REQUEST['field_key'][$i])
+            && $_REQUEST['field_key'][$i] == 'fulltext_' . $i
+        ) {
+            $row['Key'] = 'FULLTEXT';
+        } else {
+            $row['Key'] = '';
+        }
+
+        // put None in the drop-down for Default, when someone adds a field
+        $row['DefaultType'] = isset($_REQUEST['field_default_type'][$i])
+            ? $_REQUEST['field_default_type'][$i]
+            : 'NONE';
+        $row['DefaultValue'] = isset($_REQUEST['field_default_value'][$i])
+            ? $_REQUEST['field_default_value'][$i]
+            : '';
+
+        switch ($row['DefaultType']) {
+        case 'NONE' :
+            $row['Default'] = null;
+            break;
+        case 'USER_DEFINED' :
+            $row['Default'] = $row['DefaultValue'];
+            break;
+        case 'NULL' :
+        case 'CURRENT_TIMESTAMP' :
+            $row['Default'] = $row['DefaultType'];
+            break;
+        }
+
+        $row['Extra']
+            = (isset($_REQUEST['field_extra'][$i])
+            ? $_REQUEST['field_extra'][$i]
+            : false);
+        $row['Comment']
+            = (isset($submit_fulltext[$i])
+                && ($submit_fulltext[$i] == $i)
+            ? 'FULLTEXT'
+            : false);
+
+        $submit_length
+            = (isset($_REQUEST['field_length'][$i])
+            ? $_REQUEST['field_length'][$i]
+            : false);
+        $submit_attribute
+            = (isset($_REQUEST['field_attribute'][$i])
+            ? $_REQUEST['field_attribute'][$i]
+            : false);
+
+        $submit_default_current_timestamp
+            = (isset($_REQUEST['field_default_current_timestamp'][$i])
+            ? true
+            : false);
+
+        if (isset($_REQUEST['field_comments'][$i])) {
+            $comments_map[$row['Field']] = $_REQUEST['field_comments'][$i];
+        }
+
+        if (isset($_REQUEST['field_mimetype'][$i])) {
+            $mime_map[$row['Field']]['mimetype'] = $_REQUEST['field_mimetype'][$i];
+        }
+
+        if (isset($_REQUEST['field_transformation'][$i])) {
+            $mime_map[$row['Field']]['transformation']
+                = $_REQUEST['field_transformation'][$i];
+        }
+
+        if (isset($_REQUEST['field_transformation_options'][$i])) {
+            $mime_map[$row['Field']]['transformation_options']
+                = $_REQUEST['field_transformation_options'][$i];
+        }
+
+    } elseif (isset($fields_meta[$i])) {
+        $row = $fields_meta[$i];
+        switch ($row['Default']) {
+        case null:
+            if ($row['Null'] == 'YES') {
+                $row['DefaultType']  = 'NULL';
+                $row['DefaultValue'] = '';
+                // SHOW FULL COLUMNS does not report the case
+                // when there is a DEFAULT value which is empty so we need to use the
+                // results of SHOW CREATE TABLE
+            } elseif (isset($row)
+                && isset($analyzed_sql[0]['create_table_fields'][$row['Field']]
+                    ['default_value'])
+            ) {
+                $row['DefaultType']  = 'USER_DEFINED';
+                $row['DefaultValue'] = $row['Default'];
+            } else {
+                $row['DefaultType']  = 'NONE';
+                $row['DefaultValue'] = '';
+            }
+            break;
+        case 'CURRENT_TIMESTAMP':
+            $row['DefaultType']  = 'CURRENT_TIMESTAMP';
+            $row['DefaultValue'] = '';
+            break;
+        default:
+            $row['DefaultType']  = 'USER_DEFINED';
+            $row['DefaultValue'] = $row['Default'];
+            break;
+        }
+    }
+
+    if (isset($row['Type'])) {
+        $extracted_columnspec = PMA_Util::extractColumnSpec($row['Type']);
+        if ($extracted_columnspec['type'] == 'bit') {
+            $row['Default']
+                = PMA_Util::convertBitDefaultValue($row['Default']);
+        }
+    }
+    // Cell index: If certain fields get left out, the counter shouldn't change.
+    $ci = 0;
+    // Everytime a cell shall be left out the STRG-jumping feature, $ci_offset
+    // has to be incremented ($ci_offset++)
+    $ci_offset = -1;
+
+    // old column name
+    if ($is_backup) {
+        if (! empty($true_selected[$i])) {
+            $_form_params['field_orig[' . $i . ']'] = $true_selected[$i];
+        } elseif (isset($row['Field'])) {
+            $_form_params['field_orig[' . $i . ']'] = $row['Field'];
+        } else {
+            $_form_params['field_orig[' . $i . ']'] = '';
+        }
+    }
+
+    // column name
+    $content_cells[$i][$ci] = '<input id="field_' . $i . '_' . ($ci - $ci_offset)
+        . '"' . ' type="text" name="field_name[' . $i . ']"'
+        . ' maxlength="64" class="textfield" title="' . __('Column') . '"'
+        . ' size="10"'
+        . ' value="' . (isset($row['Field']) ? htmlspecialchars($row['Field']) : '')
+        . '"' . ' />';
+    $ci++;
+
+    // column type
+    $select_id = 'field_' . $i . '_' . ($ci - $ci_offset);
+    $content_cells[$i][$ci] = '<select class="column_type" name="field_type[' .
+        $i . ']"' .' id="' . $select_id . '">';
+
+    if (empty($row['Type'])) {
+        // creating a column
+        $row['Type'] = '';
+        $type        = '';
+        $length = '';
+    } else {
+        $type = $extracted_columnspec['type'];
+        $length = $extracted_columnspec['spec_in_brackets'];
+    }
+
+    // some types, for example longtext, are reported as
+    // "longtext character set latin7" when their charset and / or collation
+    // differs from the ones of the corresponding database.
+    $tmp = strpos($type, 'character set');
+    if ($tmp) {
+        $type = substr($type, 0, $tmp - 1);
+    }
+
+    if (isset($submit_length) && $submit_length != false) {
+        $length = $submit_length;
+    }
+
+    // rtrim the type, for cases like "float unsigned"
+    $type = rtrim($type);
+    $type_upper = strtoupper($type);
+
+    $content_cells[$i][$ci]
+        .= PMA_Util::getSupportedDatatypes(true, $type_upper);
+    $content_cells[$i][$ci] .= '    </select>';
+    $ci++;
+
+    // old column length
+    if ($is_backup) {
+        $_form_params['field_length_orig[' . $i . ']'] = $length;
+    }
+
+    // column length
+    $length_to_display = $length;
+
+    $content_cells[$i][$ci] = '<input id="field_' . $i . '_' . ($ci - $ci_offset)
+        . '"' . ' type="text" name="field_length[' . $i . ']" size="'
+        . $length_values_input_size . '"' . ' value="' . htmlspecialchars(
+            $length_to_display
+        )
+        . '"'
+        . ' class="textfield" />'
+        . '<p class="enum_notice" id="enum_notice_' . $i . '_' . ($ci - $ci_offset)
+        . '">';
+    $content_cells[$i][$ci] .= __('ENUM or SET data too long?')
+        . '<a href="#" class="open_enum_editor"> '
+        . __('Get more editing space') . '</a>'
+        . '</p>';
+    $ci++;
+
+    // column default
+
+    // old column default
+    if ($is_backup) {
+        $_form_params['field_default_orig[' . $i . ']']
+            = (isset($row['Default']) ? $row['Default'] : '');
+    }
+
+    // here we put 'NONE' as the default value of drop-down; otherwise
+    // users would have problems if they forget to enter the default
+    // value (example, for an INT)
+    $default_options = array(
+        'NONE'              =>  _pgettext('for default', 'None'),
+        'USER_DEFINED'      =>  __('As defined:'),
+        'NULL'              => 'NULL',
+        'CURRENT_TIMESTAMP' => 'CURRENT_TIMESTAMP',
+    );
+
+    // for a TIMESTAMP, do not show the string "CURRENT_TIMESTAMP" as a default value
+    if ($type_upper == 'TIMESTAMP'
+        && ! empty($default_current_timestamp)
+        && isset($row['Default'])
+    ) {
+        $row['Default'] = '';
+    }
+
+    if ($type_upper == 'BIT') {
+        $row['DefaultValue']
+            = PMA_Util::convertBitDefaultValue($row['DefaultValue']);
+    }
+
+    $content_cells[$i][$ci] = '<select name="field_default_type[' . $i
+        . ']" id="field_' . $i . '_' . ($ci - $ci_offset) 
+        . '" class="default_type">';
+    foreach ($default_options as $key => $value) {
+        $content_cells[$i][$ci] .= '<option value="' . $key . '"';
+        // is only set when we go back to edit a field's structure
+        if (isset($row['DefaultType']) && $row['DefaultType'] == $key) {
+            $content_cells[$i][$ci] .= ' selected="selected"';
+        }
+        $content_cells[$i][$ci] .= ' >' . $value . '</option>';
+    }
+    $content_cells[$i][$ci] .= '</select>';
+    $content_cells[$i][$ci] .= '<br />';
+    $content_cells[$i][$ci] .= '<input type="text"'
+        . ' name="field_default_value[' . $i . ']" size="12"'
+        . ' value="' . (isset($row['DefaultValue'])
+            ? htmlspecialchars($row['DefaultValue'])
+            : '') . '"'
+        . ' class="textfield default_value" />';
+    $ci++;
+
+    // column collation
+    $tmp_collation          = empty($row['Collation']) ? null : $row['Collation'];
+    $content_cells[$i][$ci] = PMA_generateCharsetDropdownBox(
+        PMA_CSDROPDOWN_COLLATION, 'field_collation[' . $i . ']',
+        'field_' . $i . '_' . ($ci - $ci_offset), $tmp_collation, false
+    );
+    unset($tmp_collation);
+    $ci++;
+
+    // column attribute
+    $content_cells[$i][$ci] = '<select style="font-size: 70%;"'
+        . ' name="field_attribute[' . $i . ']"'
+        . ' id="field_' . $i . '_' . ($ci - $ci_offset) . '">';
+
+    $attribute     = '';
+    if (isset($extracted_columnspec)) {
+        $attribute = $extracted_columnspec['attribute'];
+    }
+
+    if (isset($row['Extra']) && $row['Extra'] == 'on update CURRENT_TIMESTAMP') {
+        $attribute = 'on update CURRENT_TIMESTAMP';
+    }
+
+    if (isset($submit_attribute) && $submit_attribute != false) {
+        $attribute = $submit_attribute;
+    }
+
+    // here, we have a TIMESTAMP that SHOW FULL COLUMNS reports as having the
+    // NULL attribute, but SHOW CREATE TABLE says the contrary. Believe
+    // the latter.
+    if (PMA_MYSQL_INT_VERSION < 50025
+        && isset($row['Field'])
+        && isset($analyzed_sql[0]['create_table_fields'][$row['Field']]['type'])
+        && $analyzed_sql[0]['create_table_fields'][$row['Field']]['type'] == 'TIMESTAMP'
+        && $analyzed_sql[0]['create_table_fields'][$row['Field']]['timestamp_not_null'] == true
+    ) {
+        $row['Null'] = '';
+    }
+
+    // MySQL 4.1.2+ TIMESTAMP options
+    // (if on_update_current_timestamp is set, then it's TRUE)
+    if (isset($row['Field'])
+        && isset($analyzed_sql[0]['create_table_fields'][$row['Field']]['on_update_current_timestamp'])
+    ) {
+        $attribute = 'on update CURRENT_TIMESTAMP';
+    }
+    if ((isset($row['Field'])
+        && isset($analyzed_sql[0]['create_table_fields'][$row['Field']]['default_current_timestamp']))
+        || (isset($submit_default_current_timestamp)
+        && $submit_default_current_timestamp)
+    ) {
+        $default_current_timestamp = true;
+    } else {
+        $default_current_timestamp = false;
+    }
+
+    $attribute_types = $GLOBALS['PMA_Types']->getAttributes();
+    $cnt_attribute_types = count($attribute_types);
+    for ($j = 0; $j < $cnt_attribute_types; $j++) {
+        $content_cells[$i][$ci]
+            .= '                <option value="' . $attribute_types[$j] . '"';
+        if (strtoupper($attribute) == strtoupper($attribute_types[$j])) {
+            $content_cells[$i][$ci] .= ' selected="selected"';
+        }
+        $content_cells[$i][$ci] .= '>' . $attribute_types[$j] . '</option>';
+    }
+
+    $content_cells[$i][$ci] .= '</select>';
+    $ci++;
+
+    // column NULL
+    $content_cells[$i][$ci] = '<input name="field_null[' . $i . ']"'
+        . ' id="field_' . $i . '_' . ($ci - $ci_offset) . '"';
+
+    if (! empty($row['Null'])
+        && $row['Null'] != 'NO'
+        && $row['Null'] != 'NOT NULL'
+    ) {
+        $content_cells[$i][$ci] .= ' checked="checked"';
+    }
+
+    $content_cells[$i][$ci] .= ' type="checkbox" value="NULL" class="allow_null"/>';
+    $ci++;
+
+    // column indexes
+    // See my other comment about removing this 'if'.
+    if (!$is_backup) {
+        $content_cells[$i][$ci] = '<select name="field_key[' . $i . ']"'
+            . ' id="field_' . $i . '_' . ($ci - $ci_offset) . '">';
+        $content_cells[$i][$ci] .= '<option value="none_' . $i . '">---</option>';
+
+        $content_cells[$i][$ci] .= '<option value="primary_' . $i . '" title="'
+            . __('Primary') . '"';
+        if (isset($row['Key']) && $row['Key'] == 'PRI') {
+            $content_cells[$i][$ci] .= ' selected="selected"';
+        }
+        $content_cells[$i][$ci] .= '>PRIMARY</option>';
+
+        $content_cells[$i][$ci] .= '<option value="unique_' . $i . '" title="'
+            . __('Unique') . '"';
+        if (isset($row['Key']) && $row['Key'] == 'UNI') {
+            $content_cells[$i][$ci] .= ' selected="selected"';
+        }
+        $content_cells[$i][$ci] .= '>UNIQUE</option>';
+
+        $content_cells[$i][$ci] .= '<option value="index_' . $i . '" title="'
+            . __('Index') . '"';
+        if (isset($row['Key']) && $row['Key'] == 'MUL') {
+            $content_cells[$i][$ci] .= ' selected="selected"';
+        }
+        $content_cells[$i][$ci] .= '>INDEX</option>';
+
+        if (!PMA_DRIZZLE) {
+            $content_cells[$i][$ci] .= '<option value="fulltext_' . $i . '" title="'
+                . __('Fulltext') . '"';
+            if (isset($row['Key']) && $row['Key'] == 'FULLTEXT') {
+                $content_cells[$i][$ci] .= ' selected="selected"';
+            }
+            $content_cells[$i][$ci] .= '>FULLTEXT</option>';
+        }
+
+        $content_cells[$i][$ci] .= '</select>';
+        $ci++;
+    } // end if ($action ==...)
+
+    // column auto_increment
+    $content_cells[$i][$ci] = '<input name="field_extra[' . $i . ']"'
+        . ' id="field_' . $i . '_' . ($ci - $ci_offset) . '"';
+
+    if (isset($row['Extra']) && strtolower($row['Extra']) == 'auto_increment') {
+        $content_cells[$i][$ci] .= ' checked="checked"';
+    }
+
+    $content_cells[$i][$ci] .= ' type="checkbox" value="AUTO_INCREMENT" />';
+    $ci++;
+
+    // column comments
+    $content_cells[$i][$ci] = '<input id="field_' . $i . '_' . ($ci - $ci_offset)
+        . '"' . ' type="text" name="field_comments[' . $i . ']" size="12"'
+        . ' value="' . (isset($row['Field'])
+                && is_array($comments_map)
+                && isset($comments_map[$row['Field']])
+            ?  htmlspecialchars($comments_map[$row['Field']])
+            : '') . '"'
+        . ' class="textfield" />';
+    $ci++;
+
+    // move column
+    if (isset($fields_meta)) {
+        $content_cells[$i][$ci] = '<select id="field_' . $i . '_'
+            . ($ci - $ci_offset) . '"' . ' name="field_move_to[' . $i
+            . ']" size="1" width="5em">'
+            . '<option value="" selected="selected"> </option>';
+
+        // find index of current column
+        $current_index = 0;
+        for ($mi = 0, $cols = count($move_columns); $mi < $cols; $mi++) {
+            if ($move_columns[$mi]->name == $row['Field']) {
+                $current_index = $mi;
+                break;
+            }
+        }
+        $content_cells[$i][$ci] .= '<option value="-first"'
+            . ($current_index == 0 ? ' disabled="disabled"' : '')
+            . '>' . __('first') . '</option>';
+
+        for ($mi = 0, $cols = count($move_columns); $mi < $cols; $mi++) {
+            $content_cells[$i][$ci] .=
+                '<option value="' . htmlspecialchars($move_columns[$mi]->name) . '"'
+                . (($current_index == $mi || $current_index == $mi + 1)
+                    ? ' disabled="disabled"'
+                    : '')
+                .'>'
+                . sprintf(
+                    __('after %s'),
+                    PMA_Util::backquote(
+                        htmlspecialchars(
+                            $move_columns[$mi]->name
+                        )
+                    )
+                )
+                . '</option>';
+        }
+
+        $content_cells[$i][$ci] .= '</select>';
+        $ci++;
+    }
+
+    // column MIME-types
+    if ($cfgRelation['mimework']
+        && $GLOBALS['cfg']['BrowseMIME']
+        && $cfgRelation['commwork']
+    ) {
+        $content_cells[$i][$ci] = '<select id="field_' . $i . '_'
+            . ($ci - $ci_offset) . '" size="1" name="field_mimetype[' . $i . ']">';
+        $content_cells[$i][$ci] .= '    <option value=""> </option>';
+
+        if (is_array($available_mime['mimetype'])) {
+            foreach ($available_mime['mimetype'] as $mimekey => $mimetype) {
+                $checked = (isset($row['Field'])
+                    && isset($mime_map[$row['Field']]['mimetype'])
+                    && ($mime_map[$row['Field']]['mimetype']
+                        == str_replace('/', '_', $mimetype))
+                    ? 'selected '
+                    : '');
+                $content_cells[$i][$ci] .= '    <option value="'
+                    . str_replace('/', '_', $mimetype) . '" ' . $checked . '>'
+                    . htmlspecialchars($mimetype) . '</option>';
+            }
+        }
+
+        $content_cells[$i][$ci] .= '</select>';
+        $ci++;
+
+        $content_cells[$i][$ci] = '<select id="field_' . $i . '_'
+            . ($ci - $ci_offset) . '" size="1" name="field_transformation['
+            . $i . ']">';
+        $content_cells[$i][$ci] .= '    <option value="" title="' . __('None')
+            . '"></option>';
+        if (is_array($available_mime['transformation'])) {
+            foreach ($available_mime['transformation'] as $mimekey => $transform) {
+                $checked = isset($row['Field'])
+                    && isset($mime_map[$row['Field']]['transformation'])
+                    && preg_match(
+                        '@' . preg_quote(
+                            $available_mime['transformation_file'][$mimekey]
+                        ) . '3?@i',
+                        $mime_map[$row['Field']]['transformation']
+                    )
+                    ? 'selected '
+                    : '';
+                $tooltip = PMA_getTransformationDescription(
+                    $available_mime['transformation_file'][$mimekey], false
+                );
+                $content_cells[$i][$ci] .= '<option value="'
+                    . $available_mime['transformation_file'][$mimekey] . '" '
+                    . $checked . ' title="' . htmlspecialchars($tooltip) . '">'
+                    . htmlspecialchars($transform) . '</option>';
+            }
+        }
+
+        $content_cells[$i][$ci] .= '</select>';
+        $ci++;
+
+        $val = isset($row['Field'])
+            && isset($mime_map[$row['Field']]['transformation_options'])
+            ? htmlspecialchars($mime_map[$row['Field']]['transformation_options'])
+            : '';
+        $content_cells[$i][$ci] = '<input id="field_' . $i . '_'
+            . ($ci - $ci_offset) . '"' . ' type="text" '
+            . 'name="field_transformation_options[' . $i . ']"'
+            . ' size="16" class="textfield"'
+            . ' value="' . $val . '"'
+            . ' />';
+        //$ci++;
+    }
+} // end for
+
+$html .= '<form method="post" action="' . $action  . '" class="'
+    . ($action == 'tbl_create.php' ? 'create_table' : 'append_fields')
+    . '_form ajax">';
+
+$html .= PMA_generate_common_hidden_inputs($_form_params);
+unset($_form_params);
+if ($action == 'tbl_create.php') {
+    $html .= '<table>'
+        . '<tr class="vmiddle">'
+        . '<td>' . __('Table name')
+        . ': <input type="text" name="table" size="40" maxlength="80"'
+        . ' value="'
+        . (isset($_REQUEST['table']) ? htmlspecialchars($_REQUEST['table']) : '')
+        . '" class="textfield" autofocus />'
+        . '</td>'
+        . '<td>';
+    if ($action == 'tbl_create.php'
+        || $action == 'tbl_addfield.php'
+    ) {
+        $html .= sprintf(
+            __('Add %s column(s)'), '<input type="text" id="added_fields" '
+            . 'name="added_fields" size="2" value="1" onfocus="this.select'
+            . '()" />'
+        );
+
+        $html .= '<input type="submit" name="submit_num_fields"'
+            . 'value="' . __('Go') . '"'
+            . 'onclick="return'
+            . ' checkFormElementInRange(this.form, \'added_fields\', \''
+            . str_replace(
+                '\'', '\\\'', __('You have to add at least one column.')
+            ) . '\', 1)" />';
+    }
+    $html .= '</td>'
+        . '</tr>'
+        . '</table>';
+}
+
+if (is_array($content_cells) && is_array($header_cells)) {
+    // last row is for javascript insert
+    //$empty_row = array_pop($content_cells);
+
+    $html .= '<table id="table_columns" class="noclick">';
+    $html .= '<caption class="tblHeaders">' . __('Structure')
+        . PMA_Util::showMySQLDocu('SQL-Syntax', 'CREATE_TABLE') . '</caption>';
+
+    $html .= '<tr>';
+    foreach ($header_cells as $header_val) {
+        $html .= '<th>' . $header_val . '</th>';
+    }
+    $html .= '</tr>';
+
+    $odd_row = true;
+    foreach ($content_cells as $content_row) {
+        $html .= '<tr class="' . ($odd_row ? 'odd' : 'even') . '">';
+        $odd_row = ! $odd_row;
+
+        if (is_array($content_row)) {
+            foreach ($content_row as $content_row_val) {
+                $html .= '<td class="center">' . $content_row_val . '</td>';
+            }
+        }
+        $html .= '</tr>';
+    }
+    $html .= '</table>'
+        . '<br />';
+}
+
+/**
+ * needs to be finished
+ *
+ *
+if ($display_type == 'horizontal') {
+    $new_field = '';
+    foreach ($empty_row as $content_row_val) {
+        $new_field .= '<td class="center">' . $content_row_val . '</td>';
+    }
+    ?>
+<script type="text/javascript">
+// <![CDATA[
+var odd_row = <?php echo $odd_row; ?>;
+
+function addField()
+{
+    var new_fields = document.getElementById('added_fields').value;
+    var new_field_container = document.getElementById('table_columns');
+    var new_field = '<?php echo preg_replace('|\s+|', ' ', preg_replace('|\'|', '\\\'', $new_field)); ?>';
+    var i = 0;
+    for (i = 0; i < new_fields; i++) {
+        if (odd_row) {
+            new_field_container.innerHTML += '<tr class="odd">' + new_field + '</tr>';
+        } else {
+            new_field_container.innerHTML += '<tr class="even">' + new_field + '</tr>';
+        }
+        odd_row = ! odd_row;
+    }
+
+    return true;
+}
+// ]]>
+</script>
+    <?php
+}
+ */
+
+if ($action == 'tbl_create.php') {
+    $html .= '<table>'
+        . '<tr class="vtop">'
+        . '<th>' . __('Table comments') . ': </th>'
+        . '<td width="25"> </td>'
+        . '<th>' . __('Storage Engine') . ':'
+        . PMA_Util::showMySQLDocu('Storage_engines', 'Storage_engines')
+        . '</th>'
+        . '<td width="25"> </td>'
+        . '<th>' . __('Collation') . ': </th>'
+        . '</tr>'
+        . '<tr><td><input type="text" name="comment" size="40" maxlength="80"'
+        . 'value="'
+        . (isset($_REQUEST['comment'])
+        ? htmlspecialchars($_REQUEST['comment'])
+        : '')
+        . '" class="textfield" />'
+        . '</td>'
+        . '<td width="25"> </td>'
+        . '<td>'
+        . PMA_StorageEngine::getHtmlSelect(
+            'tbl_storage_engine', null,
+            (isset($_REQUEST['tbl_storage_engine'])
+                ? $_REQUEST['tbl_storage_engine']
+                : null
+            )
+        )
+        . '</td>'
+        . '<td width="25"> </td>'
+        . '<td>'
+        . PMA_generateCharsetDropdownBox(
+            PMA_CSDROPDOWN_COLLATION, 'tbl_collation', null,
+            (isset($_REQUEST['tbl_collation'])
+                ? $_REQUEST['tbl_collation']
+                : null
+            ),
+            false, 3
+        )
+        . '</td>'
+        . '</tr>';
+
+    if (PMA_Partition::havePartitioning()) {
+        $html .= '<tr class="vtop">'
+            . '<th>' . __('PARTITION definition') . ': '
+            . PMA_Util::showMySQLDocu('Partitioning', 'Partitioning')
+            . '</th>'
+            . '</tr>'
+            . '<tr>'
+            . '<td>'
+            . '<textarea name="partition_definition" id="partitiondefinition"'
+            . ' cols="' . $GLOBALS['cfg']['TextareaCols'] . '"'
+            . ' rows="' . $GLOBALS['cfg']['TextareaRows'] . '"'
+            . ' dir="' . $GLOBALS['text_dir'] . '">'
+            . (isset($_REQUEST['partition_definition'])
+                ? htmlspecialchars($_REQUEST['partition_definition'])
+                : '')
+            . '</textarea>'
+            . '</td>'
+            . '</tr>';
+    }
+    $html .= '</table>'
+        . '<br />';
+} // end if ($action == 'tbl_create.php')
+
+$html .= '<fieldset class="tblFooters">'
+    . '<input type="submit" name="do_save_data" value="' . __('Save') . '" />'
+    . '</fieldset>'
+    . '<div id="properties_message"></div>'
+    . '</form>';
+
+$html .= '<div id="popup_background"></div>';
+
+PMA_Response::getInstance()->addHTML($html);
+?>
diff --git a/phpmyadmin/libraries/tbl_common.inc.php b/phpmyadmin/libraries/tbl_common.inc.php
new file mode 100644
index 0000000..9974d34
--- /dev/null
+++ b/phpmyadmin/libraries/tbl_common.inc.php
@@ -0,0 +1,63 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * Common includes for the table level views
+ *
+ * @package PhpMyAdmin
+ */
+if (! defined('PHPMYADMIN')) {
+    exit;
+}
+
+/**
+ * Gets some core libraries
+ */
+require_once './libraries/bookmark.lib.php';
+
+// Check parameters
+PMA_Util::checkParameters(array('db', 'table'));
+
+$db_is_information_schema = PMA_is_system_schema($db);
+
+/**
+ * Set parameters for links
+ * @deprecated
+ */
+$url_query = PMA_generate_common_url($db, $table);
+
+/**
+ * Set parameters for links
+ */
+$url_params = array();
+$url_params['db']    = $db;
+$url_params['table'] = $table;
+
+/**
+ * Defines the urls to return to in case of error in a sql statement
+ */
+$err_url_0 = $cfg['DefaultTabDatabase']
+    . PMA_generate_common_url(array('db' => $db,));
+$err_url   = $cfg['DefaultTabTable'] . PMA_generate_common_url($url_params);
+
+
+/**
+ * Ensures the database and the table exist (else move to the "parent" script)
+ */
+require_once './libraries/db_table_exists.lib.php';
+
+if (PMA_Tracker::isActive()
+    && PMA_Tracker::isTracked($GLOBALS["db"], $GLOBALS["table"])
+    && ! isset($_REQUEST['submit_deactivate_now'])
+) {
+    $temp_msg = '<a href="tbl_tracking.php?' . $url_query . '">';
+    $temp_msg .= sprintf(
+        __('Tracking of %s is activated.'),
+        htmlspecialchars($GLOBALS["db"] . '.' . $GLOBALS["table"])
+    );
+    $temp_msg .= '</a>';
+
+    $msg = PMA_Message::notice($temp_msg);
+    $msg->display();
+}
+
+?>
diff --git a/phpmyadmin/libraries/tbl_info.inc.php b/phpmyadmin/libraries/tbl_info.inc.php
new file mode 100644
index 0000000..7347a84
--- /dev/null
+++ b/phpmyadmin/libraries/tbl_info.inc.php
@@ -0,0 +1,105 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * extracts table properties from create statement
+ *
+ * @todo should be handled by class Table
+ * @todo this should be recoded as functions, to avoid messing with global variables
+ *
+ * @package PhpMyAdmin
+ */
+if (! defined('PHPMYADMIN')) {
+    exit;
+}
+
+// Check parameters
+PMA_Util::checkParameters(array('db', 'table'));
+
+/**
+ * Defining global variables, in case this script is included by a function.
+ */
+global $showtable, $tbl_is_view, $tbl_storage_engine, $show_comment, $tbl_collation,
+       $table_info_num_rows, $auto_increment;
+
+/**
+ * Gets table informations
+ */
+// Seems we need to do this in MySQL 5.0.2,
+// otherwise error #1046, no database selected
+PMA_DBI_select_db($GLOBALS['db']);
+
+
+/**
+ * Holds information about the current table
+ *
+ * @todo replace this by PMA_Table
+ * @global array $GLOBALS['showtable']
+ * @name $showtable
+ */
+$GLOBALS['showtable'] = array();
+
+// PMA_Table::sGetStatusInfo() does caching by default, but here
+// we force reading of the current table status
+// if $reread_info is true (for example, coming from tbl_operations.php
+// and we just changed the table's storage engine)
+$GLOBALS['showtable'] = PMA_Table::sGetStatusInfo(
+    $GLOBALS['db'],
+    $GLOBALS['table'],
+    null,
+    (isset($reread_info) && $reread_info ? true : false)
+);
+
+// need this test because when we are creating a table, we get 0 rows
+// from the SHOW TABLE query
+// and we don't want to mess up the $tbl_storage_engine coming from the form
+
+if ($showtable) {
+    if (PMA_Table::isView($GLOBALS['db'], $GLOBALS['table'])) {
+        $tbl_is_view     = true;
+        $tbl_storage_engine = __('View');
+        $show_comment    = null;
+    } else {
+        $tbl_is_view     = false;
+        $tbl_storage_engine = isset($showtable['Engine'])
+            ? strtoupper($showtable['Engine'])
+            : '';
+        $show_comment = '';
+        if (isset($showtable['Comment'])) {
+            $show_comment = $showtable['Comment'];
+        }
+    }
+    $tbl_collation       = empty($showtable['Collation'])
+        ? ''
+        : $showtable['Collation'];
+
+    if (null === $showtable['Rows']) {
+        $showtable['Rows']   = PMA_Table::countRecords(
+            $GLOBALS['db'], $showtable['Name'], true
+        );
+    }
+    $table_info_num_rows = isset($showtable['Rows']) ? $showtable['Rows'] : 0;
+    $row_format = isset($showtable['Row_format']) ? $showtable['Row_format'] : '';
+    $auto_increment      = isset($showtable['Auto_increment'])
+        ? $showtable['Auto_increment']
+        : '';
+
+    $create_options      = isset($showtable['Create_options'])
+        ? explode(' ', $showtable['Create_options'])
+        : array();
+
+    // export create options by its name as variables into global namespace
+    // f.e. pack_keys=1 becomes available as $pack_keys with value of '1'
+    unset($pack_keys);
+    foreach ($create_options as $each_create_option) {
+        $each_create_option = explode('=', $each_create_option);
+        if (isset($each_create_option[1])) {
+            $$each_create_option[0]    = $each_create_option[1];
+        }
+    }
+    // we need explicit DEFAULT value here (different from '0')
+    $pack_keys = (! isset($pack_keys) || strlen($pack_keys) == 0)
+        ? 'DEFAULT'
+        : $pack_keys;
+    unset($create_options, $each_create_option);
+} // end if
+?>
diff --git a/phpmyadmin/libraries/tbl_views.lib.php b/phpmyadmin/libraries/tbl_views.lib.php
new file mode 100644
index 0000000..224f41a
--- /dev/null
+++ b/phpmyadmin/libraries/tbl_views.lib.php
@@ -0,0 +1,157 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * Set of functions related to applying transformations for VIEWs
+ *
+ * @package PhpMyAdmin
+ */
+if (! defined('PHPMYADMIN')) {
+    exit;
+}
+
+
+/**
+ * Get the column details of VIEW with its original references
+ *
+ * @param string $sql_query    SQL for original resource
+ * @param array  $view_columns Columns of VIEW if defined new column names
+ *
+ * @return array $column_map Details of VIEW columns
+ */
+function PMA_getColumnMap($sql_query, $view_columns)
+{
+
+    $column_map = array();
+    // Select query which give results for VIEW
+    $real_source_result = PMA_DBI_try_query($sql_query);
+
+    if ($real_source_result !== false) {
+
+        $real_source_fields_meta = PMA_DBI_get_fields_meta($real_source_result);
+
+        if (count($real_source_fields_meta) > 0) {
+
+            for ($i=0; $i<count($real_source_fields_meta); $i++) {
+
+                $map = array();
+                $map['table_name'] = $real_source_fields_meta[$i]->table;
+                $map['refering_column'] = $real_source_fields_meta[$i]->name;
+
+                if (count($view_columns) > 1) {
+                    $map['real_column'] = $view_columns[$i];
+                }
+
+                $column_map[] = $map;
+
+            }
+
+        }
+
+    }
+    unset($real_source_result);
+
+    return $column_map;
+
+}
+
+
+/**
+ * Get existing data on tranformations applyed for
+ * columns in a particular table
+ *
+ * @param string $db Database name looking for
+ *
+ * @return mysqli_result Result of executed SQL query
+ */
+function PMA_getExistingTranformationData($db)
+{
+    $cfgRelation = PMA_getRelationsParam();
+
+    // Get the existing transformation details of the same database
+    // from pma__column_info table
+    $pma_transformation_sql = 'SELECT * FROM '
+        . PMA_Util::backquote($cfgRelation['db']) . '.'
+        . PMA_Util::backquote($cfgRelation['column_info'])
+        . ' WHERE `db_name` = \''
+        . PMA_Util::sqlAddSlashes($db) . '\'';
+
+    return PMA_DBI_try_query($pma_transformation_sql);
+
+}
+
+
+/**
+ * Get SQL query for store new transformation details of a VIEW
+ *
+ * @param mysqli_result $pma_tranformation_data Result set of SQL execution
+ * @param array         $column_map             Details of VIEW columns
+ * @param string        $view_name              Name of the VIEW
+ * @param string        $db                     Database name of the VIEW
+ *
+ * @return string $new_transformations_sql SQL query for new tranformations
+ */
+function PMA_getNewTransformationDataSql(
+    $pma_tranformation_data, $column_map, $view_name, $db
+) {
+    $cfgRelation = PMA_getRelationsParam();
+
+    // Need to store new transformation details for VIEW
+    $new_transformations_sql = 'INSERT INTO '
+        . PMA_Util::backquote($cfgRelation['db']) . '.'
+        . PMA_Util::backquote($cfgRelation['column_info'])
+        . ' (`db_name`, `table_name`, `column_name`, `comment`, '
+        . '`mimetype`, `transformation`, `transformation_options`)'
+        . ' VALUES ';
+
+    $column_count = 0;
+    $add_comma = false;
+
+    while ($data_row = PMA_DBI_fetch_assoc($pma_tranformation_data)) {
+
+        foreach ($column_map as $column) {
+
+            if ($data_row['table_name'] == $column['table_name']
+                && $data_row['column_name'] == $column['refering_column']
+            ) {
+
+                $new_transformations_sql .= $add_comma ? ', ' : '';
+
+                $new_transformations_sql .= '('
+                    . '\'' . $db . '\', '
+                    . '\'' . $view_name . '\', '
+                    . '\'';
+
+                $new_transformations_sql .= (isset($column['real_column']))
+                        ? $column['real_column']
+                        : $column['refering_column'];
+
+                $new_transformations_sql .= '\', '
+                    . '\'' . $data_row['comment'] . '\', '
+                    . '\'' . $data_row['mimetype'] . '\', '
+                    . '\'' . $data_row['transformation'] . '\', '
+                    . '\''
+                    . PMA_Util::sqlAddSlashes(
+                        $data_row['transformation_options']
+                    )
+                    . '\')';
+
+                $add_comma = true;
+                $column_count++;
+                break;
+
+            }
+
+        }
+
+        if ($column_count == count($column_map)) {
+            break;
+        }
+
+    }
+
+    return ($column_count > 0) ? $new_transformations_sql : '';
+
+}
+
+
+?>
diff --git a/phpmyadmin/libraries/tcpdf/LICENSE.TXT b/phpmyadmin/libraries/tcpdf/LICENSE.TXT
new file mode 100644
index 0000000..daf21f7
--- /dev/null
+++ b/phpmyadmin/libraries/tcpdf/LICENSE.TXT
@@ -0,0 +1,858 @@
+**********************************************************************
+* TCPDF LICENSE
+**********************************************************************
+
+  TCPDF is free software: you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as
+  published by the Free Software Foundation, either version 3 of the
+  License, or (at your option) any later version.
+
+**********************************************************************
+**********************************************************************
+
+                   GNU LESSER GENERAL PUBLIC LICENSE
+                       Version 3, 29 June 2007
+
+ Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+
+  This version of the GNU Lesser General Public License incorporates
+the terms and conditions of version 3 of the GNU General Public
+License, supplemented by the additional permissions listed below.
+
+  0. Additional Definitions.
+
+  As used herein, "this License" refers to version 3 of the GNU Lesser
+General Public License, and the "GNU GPL" refers to version 3 of the GNU
+General Public License.
+
+  "The Library" refers to a covered work governed by this License,
+other than an Application or a Combined Work as defined below.
+
+  An "Application" is any work that makes use of an interface provided
+by the Library, but which is not otherwise based on the Library.
+Defining a subclass of a class defined by the Library is deemed a mode
+of using an interface provided by the Library.
+
+  A "Combined Work" is a work produced by combining or linking an
+Application with the Library.  The particular version of the Library
+with which the Combined Work was made is also called the "Linked
+Version".
+
+  The "Minimal Corresponding Source" for a Combined Work means the
+Corresponding Source for the Combined Work, excluding any source code
+for portions of the Combined Work that, considered in isolation, are
+based on the Application, and not on the Linked Version.
+
+  The "Corresponding Application Code" for a Combined Work means the
+object code and/or source code for the Application, including any data
+and utility programs needed for reproducing the Combined Work from the
+Application, but excluding the System Libraries of the Combined Work.
+
+  1. Exception to Section 3 of the GNU GPL.
+
+  You may convey a covered work under sections 3 and 4 of this License
+without being bound by section 3 of the GNU GPL.
+
+  2. Conveying Modified Versions.
+
+  If you modify a copy of the Library, and, in your modifications, a
+facility refers to a function or data to be supplied by an Application
+that uses the facility (other than as an argument passed when the
+facility is invoked), then you may convey a copy of the modified
+version:
+
+   a) under this License, provided that you make a good faith effort to
+   ensure that, in the event an Application does not supply the
+   function or data, the facility still operates, and performs
+   whatever part of its purpose remains meaningful, or
+
+   b) under the GNU GPL, with none of the additional permissions of
+   this License applicable to that copy.
+
+  3. Object Code Incorporating Material from Library Header Files.
+
+  The object code form of an Application may incorporate material from
+a header file that is part of the Library.  You may convey such object
+code under terms of your choice, provided that, if the incorporated
+material is not limited to numerical parameters, data structure
+layouts and accessors, or small macros, inline functions and templates
+(ten or fewer lines in length), you do both of the following:
+
+   a) Give prominent notice with each copy of the object code that the
+   Library is used in it and that the Library and its use are
+   covered by this License.
+
+   b) Accompany the object code with a copy of the GNU GPL and this license
+   document.
+
+  4. Combined Works.
+
+  You may convey a Combined Work under terms of your choice that,
+taken together, effectively do not restrict modification of the
+portions of the Library contained in the Combined Work and reverse
+engineering for debugging such modifications, if you also do each of
+the following:
+
+   a) Give prominent notice with each copy of the Combined Work that
+   the Library is used in it and that the Library and its use are
+   covered by this License.
+
+   b) Accompany the Combined Work with a copy of the GNU GPL and this license
+   document.
+
+   c) For a Combined Work that displays copyright notices during
+   execution, include the copyright notice for the Library among
+   these notices, as well as a reference directing the user to the
+   copies of the GNU GPL and this license document.
+
+   d) Do one of the following:
+
+       0) Convey the Minimal Corresponding Source under the terms of this
+       License, and the Corresponding Application Code in a form
+       suitable for, and under terms that permit, the user to
+       recombine or relink the Application with a modified version of
+       the Linked Version to produce a modified Combined Work, in the
+       manner specified by section 6 of the GNU GPL for conveying
+       Corresponding Source.
+
+       1) Use a suitable shared library mechanism for linking with the
+       Library.  A suitable mechanism is one that (a) uses at run time
+       a copy of the Library already present on the user's computer
+       system, and (b) will operate properly with a modified version
+       of the Library that is interface-compatible with the Linked
+       Version.
+
+   e) Provide Installation Information, but only if you would otherwise
+   be required to provide such information under section 6 of the
+   GNU GPL, and only to the extent that such information is
+   necessary to install and execute a modified version of the
+   Combined Work produced by recombining or relinking the
+   Application with a modified version of the Linked Version. (If
+   you use option 4d0, the Installation Information must accompany
+   the Minimal Corresponding Source and Corresponding Application
+   Code. If you use option 4d1, you must provide the Installation
+   Information in the manner specified by section 6 of the GNU GPL
+   for conveying Corresponding Source.)
+
+  5. Combined Libraries.
+
+  You may place library facilities that are a work based on the
+Library side by side in a single library together with other library
+facilities that are not Applications and are not covered by this
+License, and convey such a combined library under terms of your
+choice, if you do both of the following:
+
+   a) Accompany the combined library with a copy of the same work based
+   on the Library, uncombined with any other library facilities,
+   conveyed under the terms of this License.
+
+   b) Give prominent notice with the combined library that part of it
+   is a work based on the Library, and explaining where to find the
+   accompanying uncombined form of the same work.
+
+  6. Revised Versions of the GNU Lesser General Public License.
+
+  The Free Software Foundation may publish revised and/or new versions
+of the GNU Lesser General Public License from time to time. Such new
+versions will be similar in spirit to the present version, but may
+differ in detail to address new problems or concerns.
+
+  Each version is given a distinguishing version number. If the
+Library as you received it specifies that a certain numbered version
+of the GNU Lesser General Public License "or any later version"
+applies to it, you have the option of following the terms and
+conditions either of that published version or of any later version
+published by the Free Software Foundation. If the Library as you
+received it does not specify a version number of the GNU Lesser
+General Public License, you may choose any version of the GNU Lesser
+General Public License ever published by the Free Software Foundation.
+
+  If the Library as you received it specifies that a proxy can decide
+whether future versions of the GNU Lesser General Public License shall
+apply, that proxy's public statement of acceptance of any version is
+permanent authorization for you to choose that version for the
+Library.
+
+**********************************************************************
+**********************************************************************
+
+                    GNU GENERAL PUBLIC LICENSE
+                       Version 3, 29 June 2007
+
+ Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+                            Preamble
+
+  The GNU General Public License is a free, copyleft license for
+software and other kinds of works.
+
+  The licenses for most software and other practical works are designed
+to take away your freedom to share and change the works.  By contrast,
+the GNU General Public License is intended to guarantee your freedom to
+share and change all versions of a program--to make sure it remains free
+software for all its users.  We, the Free Software Foundation, use the
+GNU General Public License for most of our software; it applies also to
+any other work released this way by its authors.  You can apply it to
+your programs, too.
+
+  When we speak of free software, we are referring to freedom, not
+price.  Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+them if you wish), that you receive source code or can get it if you
+want it, that you can change the software or use pieces of it in new
+free programs, and that you know you can do these things.
+
+  To protect your rights, we need to prevent others from denying you
+these rights or asking you to surrender the rights.  Therefore, you have
+certain responsibilities if you distribute copies of the software, or if
+you modify it: responsibilities to respect the freedom of others.
+
+  For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must pass on to the recipients the same
+freedoms that you received.  You must make sure that they, too, receive
+or can get the source code.  And you must show them these terms so they
+know their rights.
+
+  Developers that use the GNU GPL protect your rights with two steps:
+(1) assert copyright on the software, and (2) offer you this License
+giving you legal permission to copy, distribute and/or modify it.
+
+  For the developers' and authors' protection, the GPL clearly explains
+that there is no warranty for this free software.  For both users' and
+authors' sake, the GPL requires that modified versions be marked as
+changed, so that their problems will not be attributed erroneously to
+authors of previous versions.
+
+  Some devices are designed to deny users access to install or run
+modified versions of the software inside them, although the manufacturer
+can do so.  This is fundamentally incompatible with the aim of
+protecting users' freedom to change the software.  The systematic
+pattern of such abuse occurs in the area of products for individuals to
+use, which is precisely where it is most unacceptable.  Therefore, we
+have designed this version of the GPL to prohibit the practice for those
+products.  If such problems arise substantially in other domains, we
+stand ready to extend this provision to those domains in future versions
+of the GPL, as needed to protect the freedom of users.
+
+  Finally, every program is threatened constantly by software patents.
+States should not allow patents to restrict development and use of
+software on general-purpose computers, but in those that do, we wish to
+avoid the special danger that patents applied to a free program could
+make it effectively proprietary.  To prevent this, the GPL assures that
+patents cannot be used to render the program non-free.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.
+
+                       TERMS AND CONDITIONS
+
+  0. Definitions.
+
+  "This License" refers to version 3 of the GNU General Public License.
+
+  "Copyright" also means copyright-like laws that apply to other kinds of
+works, such as semiconductor masks.
+
+  "The Program" refers to any copyrightable work licensed under this
+License.  Each licensee is addressed as "you".  "Licensees" and
+"recipients" may be individuals or organizations.
+
+  To "modify" a work means to copy from or adapt all or part of the work
+in a fashion requiring copyright permission, other than the making of an
+exact copy.  The resulting work is called a "modified version" of the
+earlier work or a work "based on" the earlier work.
+
+  A "covered work" means either the unmodified Program or a work based
+on the Program.
+
+  To "propagate" a work means to do anything with it that, without
+permission, would make you directly or secondarily liable for
+infringement under applicable copyright law, except executing it on a
+computer or modifying a private copy.  Propagation includes copying,
+distribution (with or without modification), making available to the
+public, and in some countries other activities as well.
+
+  To "convey" a work means any kind of propagation that enables other
+parties to make or receive copies.  Mere interaction with a user through
+a computer network, with no transfer of a copy, is not conveying.
+
+  An interactive user interface displays "Appropriate Legal Notices"
+to the extent that it includes a convenient and prominently visible
+feature that (1) displays an appropriate copyright notice, and (2)
+tells the user that there is no warranty for the work (except to the
+extent that warranties are provided), that licensees may convey the
+work under this License, and how to view a copy of this License.  If
+the interface presents a list of user commands or options, such as a
+menu, a prominent item in the list meets this criterion.
+
+  1. Source Code.
+
+  The "source code" for a work means the preferred form of the work
+for making modifications to it.  "Object code" means any non-source
+form of a work.
+
+  A "Standard Interface" means an interface that either is an official
+standard defined by a recognized standards body, or, in the case of
+interfaces specified for a particular programming language, one that
+is widely used among developers working in that language.
+
+  The "System Libraries" of an executable work include anything, other
+than the work as a whole, that (a) is included in the normal form of
+packaging a Major Component, but which is not part of that Major
+Component, and (b) serves only to enable use of the work with that
+Major Component, or to implement a Standard Interface for which an
+implementation is available to the public in source code form.  A
+"Major Component", in this context, means a major essential component
+(kernel, window system, and so on) of the specific operating system
+(if any) on which the executable work runs, or a compiler used to
+produce the work, or an object code interpreter used to run it.
+
+  The "Corresponding Source" for a work in object code form means all
+the source code needed to generate, install, and (for an executable
+work) run the object code and to modify the work, including scripts to
+control those activities.  However, it does not include the work's
+System Libraries, or general-purpose tools or generally available free
+programs which are used unmodified in performing those activities but
+which are not part of the work.  For example, Corresponding Source
+includes interface definition files associated with source files for
+the work, and the source code for shared libraries and dynamically
+linked subprograms that the work is specifically designed to require,
+such as by intimate data communication or control flow between those
+subprograms and other parts of the work.
+
+  The Corresponding Source need not include anything that users
+can regenerate automatically from other parts of the Corresponding
+Source.
+
+  The Corresponding Source for a work in source code form is that
+same work.
+
+  2. Basic Permissions.
+
+  All rights granted under this License are granted for the term of
+copyright on the Program, and are irrevocable provided the stated
+conditions are met.  This License explicitly affirms your unlimited
+permission to run the unmodified Program.  The output from running a
+covered work is covered by this License only if the output, given its
+content, constitutes a covered work.  This License acknowledges your
+rights of fair use or other equivalent, as provided by copyright law.
+
+  You may make, run and propagate covered works that you do not
+convey, without conditions so long as your license otherwise remains
+in force.  You may convey covered works to others for the sole purpose
+of having them make modifications exclusively for you, or provide you
+with facilities for running those works, provided that you comply with
+the terms of this License in conveying all material for which you do
+not control copyright.  Those thus making or running the covered works
+for you must do so exclusively on your behalf, under your direction
+and control, on terms that prohibit them from making any copies of
+your copyrighted material outside their relationship with you.
+
+  Conveying under any other circumstances is permitted solely under
+the conditions stated below.  Sublicensing is not allowed; section 10
+makes it unnecessary.
+
+  3. Protecting Users' Legal Rights From Anti-Circumvention Law.
+
+  No covered work shall be deemed part of an effective technological
+measure under any applicable law fulfilling obligations under article
+11 of the WIPO copyright treaty adopted on 20 December 1996, or
+similar laws prohibiting or restricting circumvention of such
+measures.
+
+  When you convey a covered work, you waive any legal power to forbid
+circumvention of technological measures to the extent such circumvention
+is effected by exercising rights under this License with respect to
+the covered work, and you disclaim any intention to limit operation or
+modification of the work as a means of enforcing, against the work's
+users, your or third parties' legal rights to forbid circumvention of
+technological measures.
+
+  4. Conveying Verbatim Copies.
+
+  You may convey verbatim copies of the Program's source code as you
+receive it, in any medium, provided that you conspicuously and
+appropriately publish on each copy an appropriate copyright notice;
+keep intact all notices stating that this License and any
+non-permissive terms added in accord with section 7 apply to the code;
+keep intact all notices of the absence of any warranty; and give all
+recipients a copy of this License along with the Program.
+
+  You may charge any price or no price for each copy that you convey,
+and you may offer support or warranty protection for a fee.
+
+  5. Conveying Modified Source Versions.
+
+  You may convey a work based on the Program, or the modifications to
+produce it from the Program, in the form of source code under the
+terms of section 4, provided that you also meet all of these conditions:
+
+    a) The work must carry prominent notices stating that you modified
+    it, and giving a relevant date.
+
+    b) The work must carry prominent notices stating that it is
+    released under this License and any conditions added under section
+    7.  This requirement modifies the requirement in section 4 to
+    "keep intact all notices".
+
+    c) You must license the entire work, as a whole, under this
+    License to anyone who comes into possession of a copy.  This
+    License will therefore apply, along with any applicable section 7
+    additional terms, to the whole of the work, and all its parts,
+    regardless of how they are packaged.  This License gives no
+    permission to license the work in any other way, but it does not
+    invalidate such permission if you have separately received it.
+
+    d) If the work has interactive user interfaces, each must display
+    Appropriate Legal Notices; however, if the Program has interactive
+    interfaces that do not display Appropriate Legal Notices, your
+    work need not make them do so.
+
+  A compilation of a covered work with other separate and independent
+works, which are not by their nature extensions of the covered work,
+and which are not combined with it such as to form a larger program,
+in or on a volume of a storage or distribution medium, is called an
+"aggregate" if the compilation and its resulting copyright are not
+used to limit the access or legal rights of the compilation's users
+beyond what the individual works permit.  Inclusion of a covered work
+in an aggregate does not cause this License to apply to the other
+parts of the aggregate.
+
+  6. Conveying Non-Source Forms.
+
+  You may convey a covered work in object code form under the terms
+of sections 4 and 5, provided that you also convey the
+machine-readable Corresponding Source under the terms of this License,
+in one of these ways:
+
+    a) Convey the object code in, or embodied in, a physical product
+    (including a physical distribution medium), accompanied by the
+    Corresponding Source fixed on a durable physical medium
+    customarily used for software interchange.
+
+    b) Convey the object code in, or embodied in, a physical product
+    (including a physical distribution medium), accompanied by a
+    written offer, valid for at least three years and valid for as
+    long as you offer spare parts or customer support for that product
+    model, to give anyone who possesses the object code either (1) a
+    copy of the Corresponding Source for all the software in the
+    product that is covered by this License, on a durable physical
+    medium customarily used for software interchange, for a price no
+    more than your reasonable cost of physically performing this
+    conveying of source, or (2) access to copy the
+    Corresponding Source from a network server at no charge.
+
+    c) Convey individual copies of the object code with a copy of the
+    written offer to provide the Corresponding Source.  This
+    alternative is allowed only occasionally and noncommercially, and
+    only if you received the object code with such an offer, in accord
+    with subsection 6b.
+
+    d) Convey the object code by offering access from a designated
+    place (gratis or for a charge), and offer equivalent access to the
+    Corresponding Source in the same way through the same place at no
+    further charge.  You need not require recipients to copy the
+    Corresponding Source along with the object code.  If the place to
+    copy the object code is a network server, the Corresponding Source
+    may be on a different server (operated by you or a third party)
+    that supports equivalent copying facilities, provided you maintain
+    clear directions next to the object code saying where to find the
+    Corresponding Source.  Regardless of what server hosts the
+    Corresponding Source, you remain obligated to ensure that it is
+    available for as long as needed to satisfy these requirements.
+
+    e) Convey the object code using peer-to-peer transmission, provided
+    you inform other peers where the object code and Corresponding
+    Source of the work are being offered to the general public at no
+    charge under subsection 6d.
+
+  A separable portion of the object code, whose source code is excluded
+from the Corresponding Source as a System Library, need not be
+included in conveying the object code work.
+
+  A "User Product" is either (1) a "consumer product", which means any
+tangible personal property which is normally used for personal, family,
+or household purposes, or (2) anything designed or sold for incorporation
+into a dwelling.  In determining whether a product is a consumer product,
+doubtful cases shall be resolved in favor of coverage.  For a particular
+product received by a particular user, "normally used" refers to a
+typical or common use of that class of product, regardless of the status
+of the particular user or of the way in which the particular user
+actually uses, or expects or is expected to use, the product.  A product
+is a consumer product regardless of whether the product has substantial
+commercial, industrial or non-consumer uses, unless such uses represent
+the only significant mode of use of the product.
+
+  "Installation Information" for a User Product means any methods,
+procedures, authorization keys, or other information required to install
+and execute modified versions of a covered work in that User Product from
+a modified version of its Corresponding Source.  The information must
+suffice to ensure that the continued functioning of the modified object
+code is in no case prevented or interfered with solely because
+modification has been made.
+
+  If you convey an object code work under this section in, or with, or
+specifically for use in, a User Product, and the conveying occurs as
+part of a transaction in which the right of possession and use of the
+User Product is transferred to the recipient in perpetuity or for a
+fixed term (regardless of how the transaction is characterized), the
+Corresponding Source conveyed under this section must be accompanied
+by the Installation Information.  But this requirement does not apply
+if neither you nor any third party retains the ability to install
+modified object code on the User Product (for example, the work has
+been installed in ROM).
+
+  The requirement to provide Installation Information does not include a
+requirement to continue to provide support service, warranty, or updates
+for a work that has been modified or installed by the recipient, or for
+the User Product in which it has been modified or installed.  Access to a
+network may be denied when the modification itself materially and
+adversely affects the operation of the network or violates the rules and
+protocols for communication across the network.
+
+  Corresponding Source conveyed, and Installation Information provided,
+in accord with this section must be in a format that is publicly
+documented (and with an implementation available to the public in
+source code form), and must require no special password or key for
+unpacking, reading or copying.
+
+  7. Additional Terms.
+
+  "Additional permissions" are terms that supplement the terms of this
+License by making exceptions from one or more of its conditions.
+Additional permissions that are applicable to the entire Program shall
+be treated as though they were included in this License, to the extent
+that they are valid under applicable law.  If additional permissions
+apply only to part of the Program, that part may be used separately
+under those permissions, but the entire Program remains governed by
+this License without regard to the additional permissions.
+
+  When you convey a copy of a covered work, you may at your option
+remove any additional permissions from that copy, or from any part of
+it.  (Additional permissions may be written to require their own
+removal in certain cases when you modify the work.)  You may place
+additional permissions on material, added by you to a covered work,
+for which you have or can give appropriate copyright permission.
+
+  Notwithstanding any other provision of this License, for material you
+add to a covered work, you may (if authorized by the copyright holders of
+that material) supplement the terms of this License with terms:
+
+    a) Disclaiming warranty or limiting liability differently from the
+    terms of sections 15 and 16 of this License; or
+
+    b) Requiring preservation of specified reasonable legal notices or
+    author attributions in that material or in the Appropriate Legal
+    Notices displayed by works containing it; or
+
+    c) Prohibiting misrepresentation of the origin of that material, or
+    requiring that modified versions of such material be marked in
+    reasonable ways as different from the original version; or
+
+    d) Limiting the use for publicity purposes of names of licensors or
+    authors of the material; or
+
+    e) Declining to grant rights under trademark law for use of some
+    trade names, trademarks, or service marks; or
+
+    f) Requiring indemnification of licensors and authors of that
+    material by anyone who conveys the material (or modified versions of
+    it) with contractual assumptions of liability to the recipient, for
+    any liability that these contractual assumptions directly impose on
+    those licensors and authors.
+
+  All other non-permissive additional terms are considered "further
+restrictions" within the meaning of section 10.  If the Program as you
+received it, or any part of it, contains a notice stating that it is
+governed by this License along with a term that is a further
+restriction, you may remove that term.  If a license document contains
+a further restriction but permits relicensing or conveying under this
+License, you may add to a covered work material governed by the terms
+of that license document, provided that the further restriction does
+not survive such relicensing or conveying.
+
+  If you add terms to a covered work in accord with this section, you
+must place, in the relevant source files, a statement of the
+additional terms that apply to those files, or a notice indicating
+where to find the applicable terms.
+
+  Additional terms, permissive or non-permissive, may be stated in the
+form of a separately written license, or stated as exceptions;
+the above requirements apply either way.
+
+  8. Termination.
+
+  You may not propagate or modify a covered work except as expressly
+provided under this License.  Any attempt otherwise to propagate or
+modify it is void, and will automatically terminate your rights under
+this License (including any patent licenses granted under the third
+paragraph of section 11).
+
+  However, if you cease all violation of this License, then your
+license from a particular copyright holder is reinstated (a)
+provisionally, unless and until the copyright holder explicitly and
+finally terminates your license, and (b) permanently, if the copyright
+holder fails to notify you of the violation by some reasonable means
+prior to 60 days after the cessation.
+
+  Moreover, your license from a particular copyright holder is
+reinstated permanently if the copyright holder notifies you of the
+violation by some reasonable means, this is the first time you have
+received notice of violation of this License (for any work) from that
+copyright holder, and you cure the violation prior to 30 days after
+your receipt of the notice.
+
+  Termination of your rights under this section does not terminate the
+licenses of parties who have received copies or rights from you under
+this License.  If your rights have been terminated and not permanently
+reinstated, you do not qualify to receive new licenses for the same
+material under section 10.
+
+  9. Acceptance Not Required for Having Copies.
+
+  You are not required to accept this License in order to receive or
+run a copy of the Program.  Ancillary propagation of a covered work
+occurring solely as a consequence of using peer-to-peer transmission
+to receive a copy likewise does not require acceptance.  However,
+nothing other than this License grants you permission to propagate or
+modify any covered work.  These actions infringe copyright if you do
+not accept this License.  Therefore, by modifying or propagating a
+covered work, you indicate your acceptance of this License to do so.
+
+  10. Automatic Licensing of Downstream Recipients.
+
+  Each time you convey a covered work, the recipient automatically
+receives a license from the original licensors, to run, modify and
+propagate that work, subject to this License.  You are not responsible
+for enforcing compliance by third parties with this License.
+
+  An "entity transaction" is a transaction transferring control of an
+organization, or substantially all assets of one, or subdividing an
+organization, or merging organizations.  If propagation of a covered
+work results from an entity transaction, each party to that
+transaction who receives a copy of the work also receives whatever
+licenses to the work the party's predecessor in interest had or could
+give under the previous paragraph, plus a right to possession of the
+Corresponding Source of the work from the predecessor in interest, if
+the predecessor has it or can get it with reasonable efforts.
+
+  You may not impose any further restrictions on the exercise of the
+rights granted or affirmed under this License.  For example, you may
+not impose a license fee, royalty, or other charge for exercise of
+rights granted under this License, and you may not initiate litigation
+(including a cross-claim or counterclaim in a lawsuit) alleging that
+any patent claim is infringed by making, using, selling, offering for
+sale, or importing the Program or any portion of it.
+
+  11. Patents.
+
+  A "contributor" is a copyright holder who authorizes use under this
+License of the Program or a work on which the Program is based.  The
+work thus licensed is called the contributor's "contributor version".
+
+  A contributor's "essential patent claims" are all patent claims
+owned or controlled by the contributor, whether already acquired or
+hereafter acquired, that would be infringed by some manner, permitted
+by this License, of making, using, or selling its contributor version,
+but do not include claims that would be infringed only as a
+consequence of further modification of the contributor version.  For
+purposes of this definition, "control" includes the right to grant
+patent sublicenses in a manner consistent with the requirements of
+this License.
+
+  Each contributor grants you a non-exclusive, worldwide, royalty-free
+patent license under the contributor's essential patent claims, to
+make, use, sell, offer for sale, import and otherwise run, modify and
+propagate the contents of its contributor version.
+
+  In the following three paragraphs, a "patent license" is any express
+agreement or commitment, however denominated, not to enforce a patent
+(such as an express permission to practice a patent or covenant not to
+sue for patent infringement).  To "grant" such a patent license to a
+party means to make such an agreement or commitment not to enforce a
+patent against the party.
+
+  If you convey a covered work, knowingly relying on a patent license,
+and the Corresponding Source of the work is not available for anyone
+to copy, free of charge and under the terms of this License, through a
+publicly available network server or other readily accessible means,
+then you must either (1) cause the Corresponding Source to be so
+available, or (2) arrange to deprive yourself of the benefit of the
+patent license for this particular work, or (3) arrange, in a manner
+consistent with the requirements of this License, to extend the patent
+license to downstream recipients.  "Knowingly relying" means you have
+actual knowledge that, but for the patent license, your conveying the
+covered work in a country, or your recipient's use of the covered work
+in a country, would infringe one or more identifiable patents in that
+country that you have reason to believe are valid.
+
+  If, pursuant to or in connection with a single transaction or
+arrangement, you convey, or propagate by procuring conveyance of, a
+covered work, and grant a patent license to some of the parties
+receiving the covered work authorizing them to use, propagate, modify
+or convey a specific copy of the covered work, then the patent license
+you grant is automatically extended to all recipients of the covered
+work and works based on it.
+
+  A patent license is "discriminatory" if it does not include within
+the scope of its coverage, prohibits the exercise of, or is
+conditioned on the non-exercise of one or more of the rights that are
+specifically granted under this License.  You may not convey a covered
+work if you are a party to an arrangement with a third party that is
+in the business of distributing software, under which you make payment
+to the third party based on the extent of your activity of conveying
+the work, and under which the third party grants, to any of the
+parties who would receive the covered work from you, a discriminatory
+patent license (a) in connection with copies of the covered work
+conveyed by you (or copies made from those copies), or (b) primarily
+for and in connection with specific products or compilations that
+contain the covered work, unless you entered into that arrangement,
+or that patent license was granted, prior to 28 March 2007.
+
+  Nothing in this License shall be construed as excluding or limiting
+any implied license or other defenses to infringement that may
+otherwise be available to you under applicable patent law.
+
+  12. No Surrender of Others' Freedom.
+
+  If conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License.  If you cannot convey a
+covered work so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you may
+not convey it at all.  For example, if you agree to terms that obligate you
+to collect a royalty for further conveying from those to whom you convey
+the Program, the only way you could satisfy both those terms and this
+License would be to refrain entirely from conveying the Program.
+
+  13. Use with the GNU Affero General Public License.
+
+  Notwithstanding any other provision of this License, you have
+permission to link or combine any covered work with a work licensed
+under version 3 of the GNU Affero General Public License into a single
+combined work, and to convey the resulting work.  The terms of this
+License will continue to apply to the part which is the covered work,
+but the special requirements of the GNU Affero General Public License,
+section 13, concerning interaction through a network will apply to the
+combination as such.
+
+  14. Revised Versions of this License.
+
+  The Free Software Foundation may publish revised and/or new versions of
+the GNU General Public License from time to time.  Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+  Each version is given a distinguishing version number.  If the
+Program specifies that a certain numbered version of the GNU General
+Public License "or any later version" applies to it, you have the
+option of following the terms and conditions either of that numbered
+version or of any later version published by the Free Software
+Foundation.  If the Program does not specify a version number of the
+GNU General Public License, you may choose any version ever published
+by the Free Software Foundation.
+
+  If the Program specifies that a proxy can decide which future
+versions of the GNU General Public License can be used, that proxy's
+public statement of acceptance of a version permanently authorizes you
+to choose that version for the Program.
+
+  Later license versions may give you additional or different
+permissions.  However, no additional obligations are imposed on any
+author or copyright holder as a result of your choosing to follow a
+later version.
+
+  15. Disclaimer of Warranty.
+
+  THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
+APPLICABLE LAW.  EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
+HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
+OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
+THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
+IS WITH YOU.  SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
+ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+  16. Limitation of Liability.
+
+  IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
+THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
+GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
+USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
+DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
+PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
+EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGES.
+
+  17. Interpretation of Sections 15 and 16.
+
+  If the disclaimer of warranty and limitation of liability provided
+above cannot be given local legal effect according to their terms,
+reviewing courts shall apply local law that most closely approximates
+an absolute waiver of all civil liability in connection with the
+Program, unless a warranty or assumption of liability accompanies a
+copy of the Program in return for a fee.
+
+                     END OF TERMS AND CONDITIONS
+
+            How to Apply These Terms to Your New Programs
+
+  If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+  To do so, attach the following notices to the program.  It is safest
+to attach them to the start of each source file to most effectively
+state the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+    <one line to give the program's name and a brief idea of what it does.>
+    Copyright (C) <year>  <name of author>
+
+    This program is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+Also add information on how to contact you by electronic and paper mail.
+
+  If the program does terminal interaction, make it output a short
+notice like this when it starts in an interactive mode:
+
+    <program>  Copyright (C) <year>  <name of author>
+    This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+    This is free software, and you are welcome to redistribute it
+    under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License.  Of course, your program's commands
+might be different; for a GUI interface, you would use an "about box".
+
+  You should also get your employer (if you work as a programmer) or school,
+if any, to sign a "copyright disclaimer" for the program, if necessary.
+For more information on this, and how to apply and follow the GNU GPL, see
+<http://www.gnu.org/licenses/>.
+
+  The GNU General Public License does not permit incorporating your program
+into proprietary programs.  If your program is a subroutine library, you
+may consider it more useful to permit linking proprietary applications with
+the library.  If this is what you want to do, use the GNU Lesser General
+Public License instead of this License.  But first, please read
+<http://www.gnu.org/philosophy/why-not-lgpl.html>.
+
+**********************************************************************
+**********************************************************************
diff --git a/phpmyadmin/libraries/tcpdf/README.TXT b/phpmyadmin/libraries/tcpdf/README.TXT
new file mode 100644
index 0000000..54db72f
--- /dev/null
+++ b/phpmyadmin/libraries/tcpdf/README.TXT
@@ -0,0 +1,97 @@
+TCPDF - README
+============================================================
+
+I WISH TO IMPROVE AND EXPAND TCPDF BUT I NEED YOUR SUPPORT.
+PLEASE MAKE A DONATION:
+http://sourceforge.net/donate/index.php?group_id=128076
+
+------------------------------------------------------------
+
+Name: TCPDF
+Version: 5.9.207
+Release date: 2013-03-04
+Author:	Nicola Asuni
+
+Copyright (c) 2002-2013:
+	Nicola Asuni
+	Tecnick.com LTD
+	Manor Coach House, Church Hill
+	Aldershot, Hants, GU12 4RQ
+	UK
+	www.tecnick.com
+
+URLs:
+	http:  www.tcpdf.org
+	http:  www.sourceforge.net/projects/tcpdf
+
+Description:
+	TCPDF is a PHP class for generating PDF files on-the-fly without requiring external extensions.
+
+Main Features:
+    * no external libraries are required for the basic functions;
+    * all standard page formats, custom page formats, custom margins and units of measure;
+    * UTF-8 Unicode and Right-To-Left languages;
+    * TrueTypeUnicode, OpenTypeUnicode v1, TrueType, OpenType v1, Type1 and CID-0 fonts;
+    * font subsetting;
+    * methods to publish some XHTML + CSS code, Javascript and Forms;
+    * images, graphic (geometric figures) and transformation methods;
+    * supports JPEG, PNG and SVG images natively, all images supported by GD (GD, GD2, GD2PART, GIF, JPEG, PNG, BMP, XBM, XPM) and all images supported via ImagMagick (http:  www.imagemagick.org/www/formats.html)
+    * 1D and 2D barcodes: CODE 39, ANSI MH10.8M-1983, USD-3, 3 of 9, CODE 93, USS-93, Standard 2 of 5, Interleaved 2 of 5, CODE 128 A/B/C, 2 and 5 Digits UPC-Based Extention, EAN 8, EAN 13, UPC-A, UPC-E, MSI, POSTNET, PLANET, RMS4CC (Royal Mail 4-state Customer Code), CBC (Customer Bar Code), KIX (Klant index - Customer index), Intelligent Mail Barcode, Onecode, USPS-B-3200, CODABAR, CODE 11, PHARMACODE, PHARMACODE TWO-TRACKS, Datamatrix, QR-Code, PDF417;
+    * JPEG and PNG ICC profiles, Grayscale, RGB, CMYK, Spot Colors and Transparencies;
+    * automatic page header and footer management;
+    * document encryption up to 256 bit and digital signature certifications;
+    * transactions to UNDO commands;
+    * PDF annotations, including links, text and file attachments;
+    * text rendering modes (fill, stroke and clipping);
+    * multiple columns mode;
+    * no-write page regions;
+    * bookmarks, named destinations and table of content;
+    * text hyphenation;
+    * text stretching and spacing (tracking);
+    * automatic page break, line break and text alignments including justification;
+    * automatic page numbering and page groups;
+    * move and delete pages;
+    * page compression (requires php-zlib extension);
+    * XOBject Templates;
+	* Layers and object visibility.
+	* PDF/A-1b support.
+
+Installation (full instructions on http:  www.tcpdf.org):
+	1. copy the folder on your Web server
+	2. set your installation path and other parameters on the config/tcpdf_config.php
+	3. call the examples/example_001.php page with your browser to see an example
+
+Source Code Documentation:
+	http://www.tcpdf.org
+
+Additional Documentation:
+	http://www.tcpdf.org
+
+License
+	Copyright (C) 2002-2013  Nicola Asuni - Tecnick.com LTD
+
+	TCPDF is free software: you can redistribute it and/or modify it
+	under the terms of the GNU Lesser General Public License as
+	published by the Free Software Foundation, either version 3 of the
+	License, or (at your option) any later version.
+
+	TCPDF is distributed in the hope that it will be useful, but
+	WITHOUT ANY WARRANTY; without even the implied warranty of
+	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+	See the GNU Lesser General Public License for more details.
+
+	You should have received a copy of the License
+	along with TCPDF. If not, see
+	<http://www.tecnick.com/pagefiles/tcpdf/LICENSE.TXT>.
+
+	See LICENSE.TXT file for more information.
+
+Third party fonts
+	This library includes third party font files released with different licenses.
+	These fonts are not required by TCPDF but have been included as you convenience.
+	The original TTF font files have been renamed for compatibility with TCPDF and compressed using the gzcompress PHP function that uses the ZLIB data format (.z files).
+	To get the original distribution archives please check the information on fonts subfolders:
+	 - DejaVu fonts 2.33 (Bitstream) - Copyright, License and other info: fonts/dejavu-fonts-ttf-2.33
+	 - GNU FreeFont (GNU-GPLv3) - Copyright, License and other info: fonts/freefont-20100919
+
+============================================================
diff --git a/phpmyadmin/libraries/tcpdf/config/tcpdf_config.php b/phpmyadmin/libraries/tcpdf/config/tcpdf_config.php
new file mode 100644
index 0000000..f5c0a18
--- /dev/null
+++ b/phpmyadmin/libraries/tcpdf/config/tcpdf_config.php
@@ -0,0 +1,258 @@
+<?php
+//============================================================+
+// File name   : tcpdf_config.php
+// Begin       : 2004-06-11
+// Last Update : 2013-02-06
+//
+// Description : Configuration file for TCPDF.
+// Author      : Nicola Asuni - Tecnick.com LTD - Manor Coach House, Church Hill, Aldershot, Hants, GU12 4RQ, UK - www.tecnick.com - info at tecnick.com
+// License     : GNU-LGPL v3 (http://www.gnu.org/copyleft/lesser.html)
+// -------------------------------------------------------------------
+// Copyright (C) 2004-2013  Nicola Asuni - Tecnick.com LTD
+//
+// This file is part of TCPDF software library.
+//
+// TCPDF is free software: you can redistribute it and/or modify it
+// under the terms of the GNU Lesser General Public License as
+// published by the Free Software Foundation, either version 3 of the
+// License, or (at your option) any later version.
+//
+// TCPDF is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+// See the GNU Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with TCPDF.  If not, see <http://www.gnu.org/licenses/>.
+//
+// See LICENSE.TXT file for more information.
+//============================================================+
+
+/**
+ * Configuration file for TCPDF.
+ * @author Nicola Asuni
+ * @package com.tecnick.tcpdf
+ * @version 4.9.005
+ * @since 2004-10-27
+ */
+
+// If you define the constant K_TCPDF_EXTERNAL_CONFIG, the following settings will be ignored.
+
+if (!defined('K_TCPDF_EXTERNAL_CONFIG')) {
+
+	// DOCUMENT_ROOT fix for IIS Webserver
+	if ((!isset($_SERVER['DOCUMENT_ROOT'])) OR (empty($_SERVER['DOCUMENT_ROOT']))) {
+		if(isset($_SERVER['SCRIPT_FILENAME'])) {
+			$_SERVER['DOCUMENT_ROOT'] = str_replace( '\\', '/', substr($_SERVER['SCRIPT_FILENAME'], 0, 0-strlen($_SERVER['PHP_SELF'])));
+		} elseif(isset($_SERVER['PATH_TRANSLATED'])) {
+			$_SERVER['DOCUMENT_ROOT'] = str_replace( '\\', '/', substr(str_replace('\\\\', '\\', $_SERVER['PATH_TRANSLATED']), 0, 0-strlen($_SERVER['PHP_SELF'])));
+		} else {
+			// define here your DOCUMENT_ROOT path if the previous fails (e.g. '/var/www')
+			$_SERVER['DOCUMENT_ROOT'] = '/';
+		}
+	}
+
+	// be sure that the end slash is present
+	$_SERVER['DOCUMENT_ROOT'] = str_replace('//', '/', $_SERVER['DOCUMENT_ROOT'].'/');
+
+	// Automatic calculation for the following K_PATH_MAIN constant
+	$k_path_main = str_replace( '\\', '/', realpath(substr(dirname(__FILE__), 0, 0-strlen('config'))));
+	if (substr($k_path_main, -1) != '/') {
+		$k_path_main .= '/';
+	}
+
+	/**
+	 * Installation path (/var/www/tcpdf/).
+	 * By default it is automatically calculated but you can also set it as a fixed string to improve performances.
+	 */
+	define ('K_PATH_MAIN', $k_path_main);
+
+	// Automatic calculation for the following K_PATH_URL constant
+	$k_path_url = $k_path_main; // default value for console mode
+	if (isset($_SERVER['HTTP_HOST']) AND (!empty($_SERVER['HTTP_HOST']))) {
+		if(isset($_SERVER['HTTPS']) AND (!empty($_SERVER['HTTPS'])) AND strtolower($_SERVER['HTTPS'])!='off') {
+			$k_path_url = 'https://';
+		} else {
+			$k_path_url = 'http://';
+		}
+		$k_path_url .= $_SERVER['HTTP_HOST'];
+		$k_path_url .= str_replace( '\\', '/', substr(K_PATH_MAIN, (strlen($_SERVER['DOCUMENT_ROOT']) - 1)));
+	}
+
+	/**
+	 * URL path to tcpdf installation folder (http://localhost/tcpdf/).
+	 * By default it is automatically calculated but you can also set it as a fixed string to improve performances.
+	 */
+	define ('K_PATH_URL', $k_path_url);
+
+	/**
+	 * path for PDF fonts
+	 * use K_PATH_MAIN.'fonts/old/' for old non-UTF8 fonts
+	 */
+	define ('K_PATH_FONTS', K_PATH_MAIN.'fonts/');
+
+	/**
+	 * cache directory for temporary files (full path)
+	 */
+	define ('K_PATH_CACHE', K_PATH_MAIN.'cache/');
+
+	/**
+	 * cache directory for temporary files (url path)
+	 */
+	define ('K_PATH_URL_CACHE', K_PATH_URL.'cache/');
+
+	/**
+	 *images directory
+	 */
+	define ('K_PATH_IMAGES', K_PATH_MAIN.'images/');
+
+	/**
+	 * blank image
+	 */
+	define ('K_BLANK_IMAGE', K_PATH_IMAGES.'_blank.png');
+
+	/**
+	 * page format
+	 */
+	define ('PDF_PAGE_FORMAT', 'A4');
+
+	/**
+	 * page orientation (P=portrait, L=landscape)
+	 */
+	define ('PDF_PAGE_ORIENTATION', 'P');
+
+	/**
+	 * document creator
+	 */
+	define ('PDF_CREATOR', 'TCPDF');
+
+	/**
+	 * document author
+	 */
+	define ('PDF_AUTHOR', 'TCPDF');
+
+	/**
+	 * header title
+	 */
+	define ('PDF_HEADER_TITLE', 'TCPDF Example');
+
+	/**
+	 * header description string
+	 */
+	define ('PDF_HEADER_STRING', "by Nicola Asuni - Tecnick.com\nwww.tcpdf.org");
+
+	/**
+	 * image logo
+	 */
+	define ('PDF_HEADER_LOGO', 'tcpdf_logo.jpg');
+
+	/**
+	 * header logo image width [mm]
+	 */
+	define ('PDF_HEADER_LOGO_WIDTH', 30);
+
+	/**
+	 *  document unit of measure [pt=point, mm=millimeter, cm=centimeter, in=inch]
+	 */
+	define ('PDF_UNIT', 'mm');
+
+	/**
+	 * header margin
+	 */
+	define ('PDF_MARGIN_HEADER', 5);
+
+	/**
+	 * footer margin
+	 */
+	define ('PDF_MARGIN_FOOTER', 10);
+
+	/**
+	 * top margin
+	 */
+	define ('PDF_MARGIN_TOP', 27);
+
+	/**
+	 * bottom margin
+	 */
+	define ('PDF_MARGIN_BOTTOM', 25);
+
+	/**
+	 * left margin
+	 */
+	define ('PDF_MARGIN_LEFT', 15);
+
+	/**
+	 * right margin
+	 */
+	define ('PDF_MARGIN_RIGHT', 15);
+
+	/**
+	 * default main font name
+	 */
+	define ('PDF_FONT_NAME_MAIN', 'helvetica');
+
+	/**
+	 * default main font size
+	 */
+	define ('PDF_FONT_SIZE_MAIN', 10);
+
+	/**
+	 * default data font name
+	 */
+	define ('PDF_FONT_NAME_DATA', 'helvetica');
+
+	/**
+	 * default data font size
+	 */
+	define ('PDF_FONT_SIZE_DATA', 8);
+
+	/**
+	 * default monospaced font name
+	 */
+	define ('PDF_FONT_MONOSPACED', 'courier');
+
+	/**
+	 * ratio used to adjust the conversion of pixels to user units
+	 */
+	define ('PDF_IMAGE_SCALE_RATIO', 1.25);
+
+	/**
+	 * magnification factor for titles
+	 */
+	define('HEAD_MAGNIFICATION', 1.1);
+
+	/**
+	 * height of cell respect font height
+	 */
+	define('K_CELL_HEIGHT_RATIO', 1.25);
+
+	/**
+	 * title magnification respect main font size
+	 */
+	define('K_TITLE_MAGNIFICATION', 1.3);
+
+	/**
+	 * reduction factor for small font
+	 */
+	define('K_SMALL_RATIO', 2/3);
+
+	/**
+	 * set to true to enable the special procedure used to avoid the overlappind of symbols on Thai language
+	 */
+	define('K_THAI_TOPCHARS', true);
+
+	/**
+	 * if true allows to call TCPDF methods using HTML syntax
+	 * IMPORTANT: For security reason, disable this feature if you are printing user HTML content.
+	 */
+	define('K_TCPDF_CALLS_IN_HTML', true);
+
+	/**
+	 * if true adn PHP version is greater than 5, then the Error() method throw new exception instead of terminating the execution.
+	 */
+	define('K_TCPDF_THROW_EXCEPTION_ERROR', false);
+}
+
+//============================================================+
+// END OF FILE
+//============================================================+
diff --git a/phpmyadmin/libraries/tcpdf/encodings_maps.php b/phpmyadmin/libraries/tcpdf/encodings_maps.php
new file mode 100644
index 0000000..414f8b6
--- /dev/null
+++ b/phpmyadmin/libraries/tcpdf/encodings_maps.php
@@ -0,0 +1,846 @@
+<?php
+//============================================================+
+// File name   : encodings_maps.php
+// Version     : 1.0.001
+// Begin       : 2011-10-01
+// Last Update : 2011-11-15
+// Author      : Nicola Asuni - Tecnick.com LTD - Manor Coach House, Church Hill, Aldershot, Hants, GU12 4RQ, UK - www.tecnick.com - info at tecnick.com
+// License     : GNU-LGPL v3 (http://www.gnu.org/copyleft/lesser.html)
+// -------------------------------------------------------------------
+// Copyright (C) 2008-2012  Nicola Asuni - Tecnick.com LTD
+//
+// This file is part of TCPDF software library.
+//
+// TCPDF is free software: you can redistribute it and/or modify it
+// under the terms of the GNU Lesser General Public License as
+// published by the Free Software Foundation, either version 3 of the
+// License, or (at your option) any later version.
+//
+// TCPDF is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+// See the GNU Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with TCPDF.  If not, see <http://www.gnu.org/licenses/>.
+//
+// See LICENSE.TXT file for more information.
+// -------------------------------------------------------------------
+//
+// Description : Unicode data for TCPDF library.
+//
+//============================================================+
+
+/**
+ * @file
+ * Font encodings maps class for TCPDF library.
+ * @author Nicola Asuni
+ * @package com.tecnick.tcpdf
+ * @since 5.9.123 (2011-10-01)
+ */
+
+/**
+ * @class TCPDF_ENCODING_MAPS
+ * This is a PHP class containing Font encodings maps class for TCPDF library.
+ * @package com.tecnick.tcpdf
+ * @version 1.0.000
+ * @author Nicola Asuni - info at tecnick.com
+ */
+class TCPDF_ENCODING_MAPS {
+
+/**
+ * Array of Encoding Maps.
+ * @public
+ */
+public $encmap = array(
+
+// encoding map for: cp1251
+'cp1251' => array(0=>'.notdef',1=>'.notdef',2=>'.notdef',3=>'.notdef',4=>'.notdef',5=>'.notdef',6=>'.notdef',7=>'.notdef',
+8=>'.notdef',9=>'.notdef',10=>'.notdef',11=>'.notdef',12=>'.notdef',13=>'.notdef',14=>'.notdef',15=>'.notdef',
+16=>'.notdef',17=>'.notdef',18=>'.notdef',19=>'.notdef',20=>'.notdef',21=>'.notdef',22=>'.notdef',23=>'.notdef',
+24=>'.notdef',25=>'.notdef',26=>'.notdef',27=>'.notdef',28=>'.notdef',29=>'.notdef',30=>'.notdef',31=>'.notdef',
+32=>'space',33=>'exclam',34=>'quotedbl',35=>'numbersign',36=>'dollar',37=>'percent',38=>'ampersand',39=>'quotesingle',
+40=>'parenleft',41=>'parenright',42=>'asterisk',43=>'plus',44=>'comma',45=>'hyphen',46=>'period',47=>'slash',
+48=>'zero',49=>'one',50=>'two',51=>'three',52=>'four',53=>'five',54=>'six',55=>'seven',
+56=>'eight',57=>'nine',58=>'colon',59=>'semicolon',60=>'less',61=>'equal',62=>'greater',63=>'question',
+64=>'at',65=>'A',66=>'B',67=>'C',68=>'D',69=>'E',70=>'F',71=>'G',
+72=>'H',73=>'I',74=>'J',75=>'K',76=>'L',77=>'M',78=>'N',79=>'O',
+80=>'P',81=>'Q',82=>'R',83=>'S',84=>'T',85=>'U',86=>'V',87=>'W',
+88=>'X',89=>'Y',90=>'Z',91=>'bracketleft',92=>'backslash',93=>'bracketright',94=>'asciicircum',95=>'underscore',
+96=>'grave',97=>'a',98=>'b',99=>'c',100=>'d',101=>'e',102=>'f',103=>'g',
+104=>'h',105=>'i',106=>'j',107=>'k',108=>'l',109=>'m',110=>'n',111=>'o',
+112=>'p',113=>'q',114=>'r',115=>'s',116=>'t',117=>'u',118=>'v',119=>'w',
+120=>'x',121=>'y',122=>'z',123=>'braceleft',124=>'bar',125=>'braceright',126=>'asciitilde',127=>'.notdef',
+128=>'afii10051',129=>'afii10052',130=>'quotesinglbase',131=>'afii10100',132=>'quotedblbase',133=>'ellipsis',134=>'dagger',135=>'daggerdbl',
+136=>'Euro',137=>'perthousand',138=>'afii10058',139=>'guilsinglleft',140=>'afii10059',141=>'afii10061',142=>'afii10060',143=>'afii10145',
+144=>'afii10099',145=>'quoteleft',146=>'quoteright',147=>'quotedblleft',148=>'quotedblright',149=>'bullet',150=>'endash',151=>'emdash',
+152=>'.notdef',153=>'trademark',154=>'afii10106',155=>'guilsinglright',156=>'afii10107',157=>'afii10109',158=>'afii10108',159=>'afii10193',
+160=>'space',161=>'afii10062',162=>'afii10110',163=>'afii10057',164=>'currency',165=>'afii10050',166=>'brokenbar',167=>'section',
+168=>'afii10023',169=>'copyright',170=>'afii10053',171=>'guillemotleft',172=>'logicalnot',173=>'hyphen',174=>'registered',175=>'afii10056',
+176=>'degree',177=>'plusminus',178=>'afii10055',179=>'afii10103',180=>'afii10098',181=>'mu',182=>'paragraph',183=>'periodcentered',
+184=>'afii10071',185=>'afii61352',186=>'afii10101',187=>'guillemotright',188=>'afii10105',189=>'afii10054',190=>'afii10102',191=>'afii10104',
+192=>'afii10017',193=>'afii10018',194=>'afii10019',195=>'afii10020',196=>'afii10021',197=>'afii10022',198=>'afii10024',199=>'afii10025',
+200=>'afii10026',201=>'afii10027',202=>'afii10028',203=>'afii10029',204=>'afii10030',205=>'afii10031',206=>'afii10032',207=>'afii10033',
+208=>'afii10034',209=>'afii10035',210=>'afii10036',211=>'afii10037',212=>'afii10038',213=>'afii10039',214=>'afii10040',215=>'afii10041',
+216=>'afii10042',217=>'afii10043',218=>'afii10044',219=>'afii10045',220=>'afii10046',221=>'afii10047',222=>'afii10048',223=>'afii10049',
+224=>'afii10065',225=>'afii10066',226=>'afii10067',227=>'afii10068',228=>'afii10069',229=>'afii10070',230=>'afii10072',231=>'afii10073',
+232=>'afii10074',233=>'afii10075',234=>'afii10076',235=>'afii10077',236=>'afii10078',237=>'afii10079',238=>'afii10080',239=>'afii10081',
+240=>'afii10082',241=>'afii10083',242=>'afii10084',243=>'afii10085',244=>'afii10086',245=>'afii10087',246=>'afii10088',247=>'afii10089',
+248=>'afii10090',249=>'afii10091',250=>'afii10092',251=>'afii10093',252=>'afii10094',253=>'afii10095',254=>'afii10096',255=>'afii10097'),
+
+// encoding map for: iso-8859-4
+'iso-8859-4' => array(0=>'.notdef',1=>'.notdef',2=>'.notdef',3=>'.notdef',4=>'.notdef',5=>'.notdef',6=>'.notdef',7=>'.notdef',
+8=>'.notdef',9=>'.notdef',10=>'.notdef',11=>'.notdef',12=>'.notdef',13=>'.notdef',14=>'.notdef',15=>'.notdef',
+16=>'.notdef',17=>'.notdef',18=>'.notdef',19=>'.notdef',20=>'.notdef',21=>'.notdef',22=>'.notdef',23=>'.notdef',
+24=>'.notdef',25=>'.notdef',26=>'.notdef',27=>'.notdef',28=>'.notdef',29=>'.notdef',30=>'.notdef',31=>'.notdef',
+32=>'space',33=>'exclam',34=>'quotedbl',35=>'numbersign',36=>'dollar',37=>'percent',38=>'ampersand',39=>'quotesingle',
+40=>'parenleft',41=>'parenright',42=>'asterisk',43=>'plus',44=>'comma',45=>'hyphen',46=>'period',47=>'slash',
+48=>'zero',49=>'one',50=>'two',51=>'three',52=>'four',53=>'five',54=>'six',55=>'seven',
+56=>'eight',57=>'nine',58=>'colon',59=>'semicolon',60=>'less',61=>'equal',62=>'greater',63=>'question',
+64=>'at',65=>'A',66=>'B',67=>'C',68=>'D',69=>'E',70=>'F',71=>'G',
+72=>'H',73=>'I',74=>'J',75=>'K',76=>'L',77=>'M',78=>'N',79=>'O',
+80=>'P',81=>'Q',82=>'R',83=>'S',84=>'T',85=>'U',86=>'V',87=>'W',
+88=>'X',89=>'Y',90=>'Z',91=>'bracketleft',92=>'backslash',93=>'bracketright',94=>'asciicircum',95=>'underscore',
+96=>'grave',97=>'a',98=>'b',99=>'c',100=>'d',101=>'e',102=>'f',103=>'g',
+104=>'h',105=>'i',106=>'j',107=>'k',108=>'l',109=>'m',110=>'n',111=>'o',
+112=>'p',113=>'q',114=>'r',115=>'s',116=>'t',117=>'u',118=>'v',119=>'w',
+120=>'x',121=>'y',122=>'z',123=>'braceleft',124=>'bar',125=>'braceright',126=>'asciitilde',127=>'.notdef',
+128=>'.notdef',129=>'.notdef',130=>'.notdef',131=>'.notdef',132=>'.notdef',133=>'.notdef',134=>'.notdef',135=>'.notdef',
+136=>'.notdef',137=>'.notdef',138=>'.notdef',139=>'.notdef',140=>'.notdef',141=>'.notdef',142=>'.notdef',143=>'.notdef',
+144=>'.notdef',145=>'.notdef',146=>'.notdef',147=>'.notdef',148=>'.notdef',149=>'.notdef',150=>'.notdef',151=>'.notdef',
+152=>'.notdef',153=>'.notdef',154=>'.notdef',155=>'.notdef',156=>'.notdef',157=>'.notdef',158=>'.notdef',159=>'.notdef',
+160=>'space',161=>'Aogonek',162=>'kgreenlandic',163=>'Rcommaaccent',164=>'currency',165=>'Itilde',166=>'Lcommaaccent',167=>'section',
+168=>'dieresis',169=>'Scaron',170=>'Emacron',171=>'Gcommaaccent',172=>'Tbar',173=>'hyphen',174=>'Zcaron',175=>'macron',
+176=>'degree',177=>'aogonek',178=>'ogonek',179=>'rcommaaccent',180=>'acute',181=>'itilde',182=>'lcommaaccent',183=>'caron',
+184=>'cedilla',185=>'scaron',186=>'emacron',187=>'gcommaaccent',188=>'tbar',189=>'Eng',190=>'zcaron',191=>'eng',
+192=>'Amacron',193=>'Aacute',194=>'Acircumflex',195=>'Atilde',196=>'Adieresis',197=>'Aring',198=>'AE',199=>'Iogonek',
+200=>'Ccaron',201=>'Eacute',202=>'Eogonek',203=>'Edieresis',204=>'Edotaccent',205=>'Iacute',206=>'Icircumflex',207=>'Imacron',
+208=>'Dcroat',209=>'Ncommaaccent',210=>'Omacron',211=>'Kcommaaccent',212=>'Ocircumflex',213=>'Otilde',214=>'Odieresis',215=>'multiply',
+216=>'Oslash',217=>'Uogonek',218=>'Uacute',219=>'Ucircumflex',220=>'Udieresis',221=>'Utilde',222=>'Umacron',223=>'germandbls',
+224=>'amacron',225=>'aacute',226=>'acircumflex',227=>'atilde',228=>'adieresis',229=>'aring',230=>'ae',231=>'iogonek',
+232=>'ccaron',233=>'eacute',234=>'eogonek',235=>'edieresis',236=>'edotaccent',237=>'iacute',238=>'icircumflex',239=>'imacron',
+240=>'dcroat',241=>'ncommaaccent',242=>'omacron',243=>'kcommaaccent',244=>'ocircumflex',245=>'otilde',246=>'odieresis',247=>'divide',
+248=>'oslash',249=>'uogonek',250=>'uacute',251=>'ucircumflex',252=>'udieresis',253=>'utilde',254=>'umacron',255=>'dotaccent'),
+
+// encoding map for: cp1255
+'cp1255' => array(0=>'.notdef',1=>'.notdef',2=>'.notdef',3=>'.notdef',4=>'.notdef',5=>'.notdef',6=>'.notdef',7=>'.notdef',
+8=>'.notdef',9=>'.notdef',10=>'.notdef',11=>'.notdef',12=>'.notdef',13=>'.notdef',14=>'.notdef',15=>'.notdef',
+16=>'.notdef',17=>'.notdef',18=>'.notdef',19=>'.notdef',20=>'.notdef',21=>'.notdef',22=>'.notdef',23=>'.notdef',
+24=>'.notdef',25=>'.notdef',26=>'.notdef',27=>'.notdef',28=>'.notdef',29=>'.notdef',30=>'.notdef',31=>'.notdef',
+32=>'space',33=>'exclam',34=>'quotedbl',35=>'numbersign',36=>'dollar',37=>'percent',38=>'ampersand',39=>'quotesingle',
+40=>'parenleft',41=>'parenright',42=>'asterisk',43=>'plus',44=>'comma',45=>'hyphen',46=>'period',47=>'slash',
+48=>'zero',49=>'one',50=>'two',51=>'three',52=>'four',53=>'five',54=>'six',55=>'seven',
+56=>'eight',57=>'nine',58=>'colon',59=>'semicolon',60=>'less',61=>'equal',62=>'greater',63=>'question',
+64=>'at',65=>'A',66=>'B',67=>'C',68=>'D',69=>'E',70=>'F',71=>'G',
+72=>'H',73=>'I',74=>'J',75=>'K',76=>'L',77=>'M',78=>'N',79=>'O',
+80=>'P',81=>'Q',82=>'R',83=>'S',84=>'T',85=>'U',86=>'V',87=>'W',
+88=>'X',89=>'Y',90=>'Z',91=>'bracketleft',92=>'backslash',93=>'bracketright',94=>'asciicircum',95=>'underscore',
+96=>'grave',97=>'a',98=>'b',99=>'c',100=>'d',101=>'e',102=>'f',103=>'g',
+104=>'h',105=>'i',106=>'j',107=>'k',108=>'l',109=>'m',110=>'n',111=>'o',
+112=>'p',113=>'q',114=>'r',115=>'s',116=>'t',117=>'u',118=>'v',119=>'w',
+120=>'x',121=>'y',122=>'z',123=>'braceleft',124=>'bar',125=>'braceright',126=>'asciitilde',127=>'.notdef',
+128=>'Euro',129=>'.notdef',130=>'quotesinglbase',131=>'florin',132=>'quotedblbase',133=>'ellipsis',134=>'dagger',135=>'daggerdbl',
+136=>'circumflex',137=>'perthousand',138=>'.notdef',139=>'guilsinglleft',140=>'.notdef',141=>'.notdef',142=>'.notdef',143=>'.notdef',
+144=>'.notdef',145=>'quoteleft',146=>'quoteright',147=>'quotedblleft',148=>'quotedblright',149=>'bullet',150=>'endash',151=>'emdash',
+152=>'tilde',153=>'trademark',154=>'.notdef',155=>'guilsinglright',156=>'.notdef',157=>'.notdef',158=>'.notdef',159=>'.notdef',
+160=>'space',161=>'exclamdown',162=>'cent',163=>'sterling',164=>'afii57636',165=>'yen',166=>'brokenbar',167=>'section',
+168=>'dieresis',169=>'copyright',170=>'multiply',171=>'guillemotleft',172=>'logicalnot',173=>'sfthyphen',174=>'registered',175=>'macron',
+176=>'degree',177=>'plusminus',178=>'twosuperior',179=>'threesuperior',180=>'acute',181=>'mu',182=>'paragraph',183=>'middot',
+184=>'cedilla',185=>'onesuperior',186=>'divide',187=>'guillemotright',188=>'onequarter',189=>'onehalf',190=>'threequarters',191=>'questiondown',
+192=>'afii57799',193=>'afii57801',194=>'afii57800',195=>'afii57802',196=>'afii57793',197=>'afii57794',198=>'afii57795',199=>'afii57798',
+200=>'afii57797',201=>'afii57806',202=>'.notdef',203=>'afii57796',204=>'afii57807',205=>'afii57839',206=>'afii57645',207=>'afii57841',
+208=>'afii57842',209=>'afii57804',210=>'afii57803',211=>'afii57658',212=>'afii57716',213=>'afii57717',214=>'afii57718',215=>'gereshhebrew',
+216=>'gershayimhebrew',217=>'.notdef',218=>'.notdef',219=>'.notdef',220=>'.notdef',221=>'.notdef',222=>'.notdef',223=>'.notdef',
+224=>'afii57664',225=>'afii57665',226=>'afii57666',227=>'afii57667',228=>'afii57668',229=>'afii57669',230=>'afii57670',231=>'afii57671',
+232=>'afii57672',233=>'afii57673',234=>'afii57674',235=>'afii57675',236=>'afii57676',237=>'afii57677',238=>'afii57678',239=>'afii57679',
+240=>'afii57680',241=>'afii57681',242=>'afii57682',243=>'afii57683',244=>'afii57684',245=>'afii57685',246=>'afii57686',247=>'afii57687',
+248=>'afii57688',249=>'afii57689',250=>'afii57690',251=>'.notdef',252=>'.notdef',253=>'afii299',254=>'afii300',255=>'.notdef'),
+
+// encoding map for: iso-8859-11
+'iso-8859-11' => array(0=>'.notdef',1=>'.notdef',2=>'.notdef',3=>'.notdef',4=>'.notdef',5=>'.notdef',6=>'.notdef',7=>'.notdef',
+8=>'.notdef',9=>'.notdef',10=>'.notdef',11=>'.notdef',12=>'.notdef',13=>'.notdef',14=>'.notdef',15=>'.notdef',
+16=>'.notdef',17=>'.notdef',18=>'.notdef',19=>'.notdef',20=>'.notdef',21=>'.notdef',22=>'.notdef',23=>'.notdef',
+24=>'.notdef',25=>'.notdef',26=>'.notdef',27=>'.notdef',28=>'.notdef',29=>'.notdef',30=>'.notdef',31=>'.notdef',
+32=>'space',33=>'exclam',34=>'quotedbl',35=>'numbersign',36=>'dollar',37=>'percent',38=>'ampersand',39=>'quotesingle',
+40=>'parenleft',41=>'parenright',42=>'asterisk',43=>'plus',44=>'comma',45=>'hyphen',46=>'period',47=>'slash',
+48=>'zero',49=>'one',50=>'two',51=>'three',52=>'four',53=>'five',54=>'six',55=>'seven',
+56=>'eight',57=>'nine',58=>'colon',59=>'semicolon',60=>'less',61=>'equal',62=>'greater',63=>'question',
+64=>'at',65=>'A',66=>'B',67=>'C',68=>'D',69=>'E',70=>'F',71=>'G',
+72=>'H',73=>'I',74=>'J',75=>'K',76=>'L',77=>'M',78=>'N',79=>'O',
+80=>'P',81=>'Q',82=>'R',83=>'S',84=>'T',85=>'U',86=>'V',87=>'W',
+88=>'X',89=>'Y',90=>'Z',91=>'bracketleft',92=>'backslash',93=>'bracketright',94=>'asciicircum',95=>'underscore',
+96=>'grave',97=>'a',98=>'b',99=>'c',100=>'d',101=>'e',102=>'f',103=>'g',
+104=>'h',105=>'i',106=>'j',107=>'k',108=>'l',109=>'m',110=>'n',111=>'o',
+112=>'p',113=>'q',114=>'r',115=>'s',116=>'t',117=>'u',118=>'v',119=>'w',
+120=>'x',121=>'y',122=>'z',123=>'braceleft',124=>'bar',125=>'braceright',126=>'asciitilde',127=>'.notdef',
+128=>'.notdef',129=>'.notdef',130=>'.notdef',131=>'.notdef',132=>'.notdef',133=>'.notdef',134=>'.notdef',135=>'.notdef',
+136=>'.notdef',137=>'.notdef',138=>'.notdef',139=>'.notdef',140=>'.notdef',141=>'.notdef',142=>'.notdef',143=>'.notdef',
+144=>'.notdef',145=>'.notdef',146=>'.notdef',147=>'.notdef',148=>'.notdef',149=>'.notdef',150=>'.notdef',151=>'.notdef',
+152=>'.notdef',153=>'.notdef',154=>'.notdef',155=>'.notdef',156=>'.notdef',157=>'.notdef',158=>'.notdef',159=>'.notdef',
+160=>'space',161=>'kokaithai',162=>'khokhaithai',163=>'khokhuatthai',164=>'khokhwaithai',165=>'khokhonthai',166=>'khorakhangthai',167=>'ngonguthai',
+168=>'chochanthai',169=>'chochingthai',170=>'chochangthai',171=>'sosothai',172=>'chochoethai',173=>'yoyingthai',174=>'dochadathai',175=>'topatakthai',
+176=>'thothanthai',177=>'thonangmonthothai',178=>'thophuthaothai',179=>'nonenthai',180=>'dodekthai',181=>'totaothai',182=>'thothungthai',183=>'thothahanthai',
+184=>'thothongthai',185=>'nonuthai',186=>'bobaimaithai',187=>'poplathai',188=>'phophungthai',189=>'fofathai',190=>'phophanthai',191=>'fofanthai',
+192=>'phosamphaothai',193=>'momathai',194=>'yoyakthai',195=>'roruathai',196=>'ruthai',197=>'lolingthai',198=>'luthai',199=>'wowaenthai',
+200=>'sosalathai',201=>'sorusithai',202=>'sosuathai',203=>'hohipthai',204=>'lochulathai',205=>'oangthai',206=>'honokhukthai',207=>'paiyannoithai',
+208=>'saraathai',209=>'maihanakatthai',210=>'saraaathai',211=>'saraamthai',212=>'saraithai',213=>'saraiithai',214=>'sarauethai',215=>'saraueethai',
+216=>'sarauthai',217=>'sarauuthai',218=>'phinthuthai',219=>'.notdef',220=>'.notdef',221=>'.notdef',222=>'.notdef',223=>'bahtthai',
+224=>'saraethai',225=>'saraaethai',226=>'saraothai',227=>'saraaimaimuanthai',228=>'saraaimaimalaithai',229=>'lakkhangyaothai',230=>'maiyamokthai',231=>'maitaikhuthai',
+232=>'maiekthai',233=>'maithothai',234=>'maitrithai',235=>'maichattawathai',236=>'thanthakhatthai',237=>'nikhahitthai',238=>'yamakkanthai',239=>'fongmanthai',
+240=>'zerothai',241=>'onethai',242=>'twothai',243=>'threethai',244=>'fourthai',245=>'fivethai',246=>'sixthai',247=>'seventhai',
+248=>'eightthai',249=>'ninethai',250=>'angkhankhuthai',251=>'khomutthai',252=>'.notdef',253=>'.notdef',254=>'.notdef',255=>'.notdef'),
+
+// encoding map for: cp1257
+'cp1257' => array(0=>'.notdef',1=>'.notdef',2=>'.notdef',3=>'.notdef',4=>'.notdef',5=>'.notdef',6=>'.notdef',7=>'.notdef',
+8=>'.notdef',9=>'.notdef',10=>'.notdef',11=>'.notdef',12=>'.notdef',13=>'.notdef',14=>'.notdef',15=>'.notdef',
+16=>'.notdef',17=>'.notdef',18=>'.notdef',19=>'.notdef',20=>'.notdef',21=>'.notdef',22=>'.notdef',23=>'.notdef',
+24=>'.notdef',25=>'.notdef',26=>'.notdef',27=>'.notdef',28=>'.notdef',29=>'.notdef',30=>'.notdef',31=>'.notdef',
+32=>'space',33=>'exclam',34=>'quotedbl',35=>'numbersign',36=>'dollar',37=>'percent',38=>'ampersand',39=>'quotesingle',
+40=>'parenleft',41=>'parenright',42=>'asterisk',43=>'plus',44=>'comma',45=>'hyphen',46=>'period',47=>'slash',
+48=>'zero',49=>'one',50=>'two',51=>'three',52=>'four',53=>'five',54=>'six',55=>'seven',
+56=>'eight',57=>'nine',58=>'colon',59=>'semicolon',60=>'less',61=>'equal',62=>'greater',63=>'question',
+64=>'at',65=>'A',66=>'B',67=>'C',68=>'D',69=>'E',70=>'F',71=>'G',
+72=>'H',73=>'I',74=>'J',75=>'K',76=>'L',77=>'M',78=>'N',79=>'O',
+80=>'P',81=>'Q',82=>'R',83=>'S',84=>'T',85=>'U',86=>'V',87=>'W',
+88=>'X',89=>'Y',90=>'Z',91=>'bracketleft',92=>'backslash',93=>'bracketright',94=>'asciicircum',95=>'underscore',
+96=>'grave',97=>'a',98=>'b',99=>'c',100=>'d',101=>'e',102=>'f',103=>'g',
+104=>'h',105=>'i',106=>'j',107=>'k',108=>'l',109=>'m',110=>'n',111=>'o',
+112=>'p',113=>'q',114=>'r',115=>'s',116=>'t',117=>'u',118=>'v',119=>'w',
+120=>'x',121=>'y',122=>'z',123=>'braceleft',124=>'bar',125=>'braceright',126=>'asciitilde',127=>'.notdef',
+128=>'Euro',129=>'.notdef',130=>'quotesinglbase',131=>'.notdef',132=>'quotedblbase',133=>'ellipsis',134=>'dagger',135=>'daggerdbl',
+136=>'.notdef',137=>'perthousand',138=>'.notdef',139=>'guilsinglleft',140=>'.notdef',141=>'dieresis',142=>'caron',143=>'cedilla',
+144=>'.notdef',145=>'quoteleft',146=>'quoteright',147=>'quotedblleft',148=>'quotedblright',149=>'bullet',150=>'endash',151=>'emdash',
+152=>'.notdef',153=>'trademark',154=>'.notdef',155=>'guilsinglright',156=>'.notdef',157=>'macron',158=>'ogonek',159=>'.notdef',
+160=>'space',161=>'.notdef',162=>'cent',163=>'sterling',164=>'currency',165=>'.notdef',166=>'brokenbar',167=>'section',
+168=>'Oslash',169=>'copyright',170=>'Rcommaaccent',171=>'guillemotleft',172=>'logicalnot',173=>'hyphen',174=>'registered',175=>'AE',
+176=>'degree',177=>'plusminus',178=>'twosuperior',179=>'threesuperior',180=>'acute',181=>'mu',182=>'paragraph',183=>'periodcentered',
+184=>'oslash',185=>'onesuperior',186=>'rcommaaccent',187=>'guillemotright',188=>'onequarter',189=>'onehalf',190=>'threequarters',191=>'ae',
+192=>'Aogonek',193=>'Iogonek',194=>'Amacron',195=>'Cacute',196=>'Adieresis',197=>'Aring',198=>'Eogonek',199=>'Emacron',
+200=>'Ccaron',201=>'Eacute',202=>'Zacute',203=>'Edotaccent',204=>'Gcommaaccent',205=>'Kcommaaccent',206=>'Imacron',207=>'Lcommaaccent',
+208=>'Scaron',209=>'Nacute',210=>'Ncommaaccent',211=>'Oacute',212=>'Omacron',213=>'Otilde',214=>'Odieresis',215=>'multiply',
+216=>'Uogonek',217=>'Lslash',218=>'Sacute',219=>'Umacron',220=>'Udieresis',221=>'Zdotaccent',222=>'Zcaron',223=>'germandbls',
+224=>'aogonek',225=>'iogonek',226=>'amacron',227=>'cacute',228=>'adieresis',229=>'aring',230=>'eogonek',231=>'emacron',
+232=>'ccaron',233=>'eacute',234=>'zacute',235=>'edotaccent',236=>'gcommaaccent',237=>'kcommaaccent',238=>'imacron',239=>'lcommaaccent',
+240=>'scaron',241=>'nacute',242=>'ncommaaccent',243=>'oacute',244=>'omacron',245=>'otilde',246=>'odieresis',247=>'divide',
+248=>'uogonek',249=>'lslash',250=>'sacute',251=>'umacron',252=>'udieresis',253=>'zdotaccent',254=>'zcaron',255=>'dotaccent'),
+
+// encoding map for: cp1258
+'cp1258' => array(0=>'.notdef',1=>'.notdef',2=>'.notdef',3=>'.notdef',4=>'.notdef',5=>'.notdef',6=>'.notdef',7=>'.notdef',
+8=>'.notdef',9=>'.notdef',10=>'.notdef',11=>'.notdef',12=>'.notdef',13=>'.notdef',14=>'.notdef',15=>'.notdef',
+16=>'.notdef',17=>'.notdef',18=>'.notdef',19=>'.notdef',20=>'.notdef',21=>'.notdef',22=>'.notdef',23=>'.notdef',
+24=>'.notdef',25=>'.notdef',26=>'.notdef',27=>'.notdef',28=>'.notdef',29=>'.notdef',30=>'.notdef',31=>'.notdef',
+32=>'space',33=>'exclam',34=>'quotedbl',35=>'numbersign',36=>'dollar',37=>'percent',38=>'ampersand',39=>'quotesingle',
+40=>'parenleft',41=>'parenright',42=>'asterisk',43=>'plus',44=>'comma',45=>'hyphen',46=>'period',47=>'slash',
+48=>'zero',49=>'one',50=>'two',51=>'three',52=>'four',53=>'five',54=>'six',55=>'seven',
+56=>'eight',57=>'nine',58=>'colon',59=>'semicolon',60=>'less',61=>'equal',62=>'greater',63=>'question',
+64=>'at',65=>'A',66=>'B',67=>'C',68=>'D',69=>'E',70=>'F',71=>'G',
+72=>'H',73=>'I',74=>'J',75=>'K',76=>'L',77=>'M',78=>'N',79=>'O',
+80=>'P',81=>'Q',82=>'R',83=>'S',84=>'T',85=>'U',86=>'V',87=>'W',
+88=>'X',89=>'Y',90=>'Z',91=>'bracketleft',92=>'backslash',93=>'bracketright',94=>'asciicircum',95=>'underscore',
+96=>'grave',97=>'a',98=>'b',99=>'c',100=>'d',101=>'e',102=>'f',103=>'g',
+104=>'h',105=>'i',106=>'j',107=>'k',108=>'l',109=>'m',110=>'n',111=>'o',
+112=>'p',113=>'q',114=>'r',115=>'s',116=>'t',117=>'u',118=>'v',119=>'w',
+120=>'x',121=>'y',122=>'z',123=>'braceleft',124=>'bar',125=>'braceright',126=>'asciitilde',127=>'.notdef',
+128=>'Euro',129=>'.notdef',130=>'quotesinglbase',131=>'florin',132=>'quotedblbase',133=>'ellipsis',134=>'dagger',135=>'daggerdbl',
+136=>'circumflex',137=>'perthousand',138=>'.notdef',139=>'guilsinglleft',140=>'OE',141=>'.notdef',142=>'.notdef',143=>'.notdef',
+144=>'.notdef',145=>'quoteleft',146=>'quoteright',147=>'quotedblleft',148=>'quotedblright',149=>'bullet',150=>'endash',151=>'emdash',
+152=>'tilde',153=>'trademark',154=>'.notdef',155=>'guilsinglright',156=>'oe',157=>'.notdef',158=>'.notdef',159=>'Ydieresis',
+160=>'space',161=>'exclamdown',162=>'cent',163=>'sterling',164=>'currency',165=>'yen',166=>'brokenbar',167=>'section',
+168=>'dieresis',169=>'copyright',170=>'ordfeminine',171=>'guillemotleft',172=>'logicalnot',173=>'hyphen',174=>'registered',175=>'macron',
+176=>'degree',177=>'plusminus',178=>'twosuperior',179=>'threesuperior',180=>'acute',181=>'mu',182=>'paragraph',183=>'periodcentered',
+184=>'cedilla',185=>'onesuperior',186=>'ordmasculine',187=>'guillemotright',188=>'onequarter',189=>'onehalf',190=>'threequarters',191=>'questiondown',
+192=>'Agrave',193=>'Aacute',194=>'Acircumflex',195=>'Abreve',196=>'Adieresis',197=>'Aring',198=>'AE',199=>'Ccedilla',
+200=>'Egrave',201=>'Eacute',202=>'Ecircumflex',203=>'Edieresis',204=>'gravecomb',205=>'Iacute',206=>'Icircumflex',207=>'Idieresis',
+208=>'Dcroat',209=>'Ntilde',210=>'hookabovecomb',211=>'Oacute',212=>'Ocircumflex',213=>'Ohorn',214=>'Odieresis',215=>'multiply',
+216=>'Oslash',217=>'Ugrave',218=>'Uacute',219=>'Ucircumflex',220=>'Udieresis',221=>'Uhorn',222=>'tildecomb',223=>'germandbls',
+224=>'agrave',225=>'aacute',226=>'acircumflex',227=>'abreve',228=>'adieresis',229=>'aring',230=>'ae',231=>'ccedilla',
+232=>'egrave',233=>'eacute',234=>'ecircumflex',235=>'edieresis',236=>'acutecomb',237=>'iacute',238=>'icircumflex',239=>'idieresis',
+240=>'dcroat',241=>'ntilde',242=>'dotbelowcomb',243=>'oacute',244=>'ocircumflex',245=>'ohorn',246=>'odieresis',247=>'divide',
+248=>'oslash',249=>'ugrave',250=>'uacute',251=>'ucircumflex',252=>'udieresis',253=>'uhorn',254=>'dong',255=>'ydieresis'),
+
+// encoding map for: cp1253
+'cp1253' => array(0=>'.notdef',1=>'.notdef',2=>'.notdef',3=>'.notdef',4=>'.notdef',5=>'.notdef',6=>'.notdef',7=>'.notdef',
+8=>'.notdef',9=>'.notdef',10=>'.notdef',11=>'.notdef',12=>'.notdef',13=>'.notdef',14=>'.notdef',15=>'.notdef',
+16=>'.notdef',17=>'.notdef',18=>'.notdef',19=>'.notdef',20=>'.notdef',21=>'.notdef',22=>'.notdef',23=>'.notdef',
+24=>'.notdef',25=>'.notdef',26=>'.notdef',27=>'.notdef',28=>'.notdef',29=>'.notdef',30=>'.notdef',31=>'.notdef',
+32=>'space',33=>'exclam',34=>'quotedbl',35=>'numbersign',36=>'dollar',37=>'percent',38=>'ampersand',39=>'quotesingle',
+40=>'parenleft',41=>'parenright',42=>'asterisk',43=>'plus',44=>'comma',45=>'hyphen',46=>'period',47=>'slash',
+48=>'zero',49=>'one',50=>'two',51=>'three',52=>'four',53=>'five',54=>'six',55=>'seven',
+56=>'eight',57=>'nine',58=>'colon',59=>'semicolon',60=>'less',61=>'equal',62=>'greater',63=>'question',
+64=>'at',65=>'A',66=>'B',67=>'C',68=>'D',69=>'E',70=>'F',71=>'G',
+72=>'H',73=>'I',74=>'J',75=>'K',76=>'L',77=>'M',78=>'N',79=>'O',
+80=>'P',81=>'Q',82=>'R',83=>'S',84=>'T',85=>'U',86=>'V',87=>'W',
+88=>'X',89=>'Y',90=>'Z',91=>'bracketleft',92=>'backslash',93=>'bracketright',94=>'asciicircum',95=>'underscore',
+96=>'grave',97=>'a',98=>'b',99=>'c',100=>'d',101=>'e',102=>'f',103=>'g',
+104=>'h',105=>'i',106=>'j',107=>'k',108=>'l',109=>'m',110=>'n',111=>'o',
+112=>'p',113=>'q',114=>'r',115=>'s',116=>'t',117=>'u',118=>'v',119=>'w',
+120=>'x',121=>'y',122=>'z',123=>'braceleft',124=>'bar',125=>'braceright',126=>'asciitilde',127=>'.notdef',
+128=>'Euro',129=>'.notdef',130=>'quotesinglbase',131=>'florin',132=>'quotedblbase',133=>'ellipsis',134=>'dagger',135=>'daggerdbl',
+136=>'.notdef',137=>'perthousand',138=>'.notdef',139=>'guilsinglleft',140=>'.notdef',141=>'.notdef',142=>'.notdef',143=>'.notdef',
+144=>'.notdef',145=>'quoteleft',146=>'quoteright',147=>'quotedblleft',148=>'quotedblright',149=>'bullet',150=>'endash',151=>'emdash',
+152=>'.notdef',153=>'trademark',154=>'.notdef',155=>'guilsinglright',156=>'.notdef',157=>'.notdef',158=>'.notdef',159=>'.notdef',
+160=>'space',161=>'dieresistonos',162=>'Alphatonos',163=>'sterling',164=>'currency',165=>'yen',166=>'brokenbar',167=>'section',
+168=>'dieresis',169=>'copyright',170=>'.notdef',171=>'guillemotleft',172=>'logicalnot',173=>'hyphen',174=>'registered',175=>'afii00208',
+176=>'degree',177=>'plusminus',178=>'twosuperior',179=>'threesuperior',180=>'tonos',181=>'mu',182=>'paragraph',183=>'periodcentered',
+184=>'Epsilontonos',185=>'Etatonos',186=>'Iotatonos',187=>'guillemotright',188=>'Omicrontonos',189=>'onehalf',190=>'Upsilontonos',191=>'Omegatonos',
+192=>'iotadieresistonos',193=>'Alpha',194=>'Beta',195=>'Gamma',196=>'Delta',197=>'Epsilon',198=>'Zeta',199=>'Eta',
+200=>'Theta',201=>'Iota',202=>'Kappa',203=>'Lambda',204=>'Mu',205=>'Nu',206=>'Xi',207=>'Omicron',
+208=>'Pi',209=>'Rho',210=>'.notdef',211=>'Sigma',212=>'Tau',213=>'Upsilon',214=>'Phi',215=>'Chi',
+216=>'Psi',217=>'Omega',218=>'Iotadieresis',219=>'Upsilondieresis',220=>'alphatonos',221=>'epsilontonos',222=>'etatonos',223=>'iotatonos',
+224=>'upsilondieresistonos',225=>'alpha',226=>'beta',227=>'gamma',228=>'delta',229=>'epsilon',230=>'zeta',231=>'eta',
+232=>'theta',233=>'iota',234=>'kappa',235=>'lambda',236=>'mu',237=>'nu',238=>'xi',239=>'omicron',
+240=>'pi',241=>'rho',242=>'sigma1',243=>'sigma',244=>'tau',245=>'upsilon',246=>'phi',247=>'chi',
+248=>'psi',249=>'omega',250=>'iotadieresis',251=>'upsilondieresis',252=>'omicrontonos',253=>'upsilontonos',254=>'omegatonos',255=>'.notdef'),
+
+// encoding map for: cp874
+'cp874' => array(0=>'.notdef',1=>'.notdef',2=>'.notdef',3=>'.notdef',4=>'.notdef',5=>'.notdef',6=>'.notdef',7=>'.notdef',
+8=>'.notdef',9=>'.notdef',10=>'.notdef',11=>'.notdef',12=>'.notdef',13=>'.notdef',14=>'.notdef',15=>'.notdef',
+16=>'.notdef',17=>'.notdef',18=>'.notdef',19=>'.notdef',20=>'.notdef',21=>'.notdef',22=>'.notdef',23=>'.notdef',
+24=>'.notdef',25=>'.notdef',26=>'.notdef',27=>'.notdef',28=>'.notdef',29=>'.notdef',30=>'.notdef',31=>'.notdef',
+32=>'space',33=>'exclam',34=>'quotedbl',35=>'numbersign',36=>'dollar',37=>'percent',38=>'ampersand',39=>'quotesingle',
+40=>'parenleft',41=>'parenright',42=>'asterisk',43=>'plus',44=>'comma',45=>'hyphen',46=>'period',47=>'slash',
+48=>'zero',49=>'one',50=>'two',51=>'three',52=>'four',53=>'five',54=>'six',55=>'seven',
+56=>'eight',57=>'nine',58=>'colon',59=>'semicolon',60=>'less',61=>'equal',62=>'greater',63=>'question',
+64=>'at',65=>'A',66=>'B',67=>'C',68=>'D',69=>'E',70=>'F',71=>'G',
+72=>'H',73=>'I',74=>'J',75=>'K',76=>'L',77=>'M',78=>'N',79=>'O',
+80=>'P',81=>'Q',82=>'R',83=>'S',84=>'T',85=>'U',86=>'V',87=>'W',
+88=>'X',89=>'Y',90=>'Z',91=>'bracketleft',92=>'backslash',93=>'bracketright',94=>'asciicircum',95=>'underscore',
+96=>'grave',97=>'a',98=>'b',99=>'c',100=>'d',101=>'e',102=>'f',103=>'g',
+104=>'h',105=>'i',106=>'j',107=>'k',108=>'l',109=>'m',110=>'n',111=>'o',
+112=>'p',113=>'q',114=>'r',115=>'s',116=>'t',117=>'u',118=>'v',119=>'w',
+120=>'x',121=>'y',122=>'z',123=>'braceleft',124=>'bar',125=>'braceright',126=>'asciitilde',127=>'.notdef',
+128=>'Euro',129=>'.notdef',130=>'.notdef',131=>'.notdef',132=>'.notdef',133=>'ellipsis',134=>'.notdef',135=>'.notdef',
+136=>'.notdef',137=>'.notdef',138=>'.notdef',139=>'.notdef',140=>'.notdef',141=>'.notdef',142=>'.notdef',143=>'.notdef',
+144=>'.notdef',145=>'quoteleft',146=>'quoteright',147=>'quotedblleft',148=>'quotedblright',149=>'bullet',150=>'endash',151=>'emdash',
+152=>'.notdef',153=>'.notdef',154=>'.notdef',155=>'.notdef',156=>'.notdef',157=>'.notdef',158=>'.notdef',159=>'.notdef',
+160=>'space',161=>'kokaithai',162=>'khokhaithai',163=>'khokhuatthai',164=>'khokhwaithai',165=>'khokhonthai',166=>'khorakhangthai',167=>'ngonguthai',
+168=>'chochanthai',169=>'chochingthai',170=>'chochangthai',171=>'sosothai',172=>'chochoethai',173=>'yoyingthai',174=>'dochadathai',175=>'topatakthai',
+176=>'thothanthai',177=>'thonangmonthothai',178=>'thophuthaothai',179=>'nonenthai',180=>'dodekthai',181=>'totaothai',182=>'thothungthai',183=>'thothahanthai',
+184=>'thothongthai',185=>'nonuthai',186=>'bobaimaithai',187=>'poplathai',188=>'phophungthai',189=>'fofathai',190=>'phophanthai',191=>'fofanthai',
+192=>'phosamphaothai',193=>'momathai',194=>'yoyakthai',195=>'roruathai',196=>'ruthai',197=>'lolingthai',198=>'luthai',199=>'wowaenthai',
+200=>'sosalathai',201=>'sorusithai',202=>'sosuathai',203=>'hohipthai',204=>'lochulathai',205=>'oangthai',206=>'honokhukthai',207=>'paiyannoithai',
+208=>'saraathai',209=>'maihanakatthai',210=>'saraaathai',211=>'saraamthai',212=>'saraithai',213=>'saraiithai',214=>'sarauethai',215=>'saraueethai',
+216=>'sarauthai',217=>'sarauuthai',218=>'phinthuthai',219=>'.notdef',220=>'.notdef',221=>'.notdef',222=>'.notdef',223=>'bahtthai',
+224=>'saraethai',225=>'saraaethai',226=>'saraothai',227=>'saraaimaimuanthai',228=>'saraaimaimalaithai',229=>'lakkhangyaothai',230=>'maiyamokthai',231=>'maitaikhuthai',
+232=>'maiekthai',233=>'maithothai',234=>'maitrithai',235=>'maichattawathai',236=>'thanthakhatthai',237=>'nikhahitthai',238=>'yamakkanthai',239=>'fongmanthai',
+240=>'zerothai',241=>'onethai',242=>'twothai',243=>'threethai',244=>'fourthai',245=>'fivethai',246=>'sixthai',247=>'seventhai',
+248=>'eightthai',249=>'ninethai',250=>'angkhankhuthai',251=>'khomutthai',252=>'.notdef',253=>'.notdef',254=>'.notdef',255=>'.notdef'),
+
+// encoding map for: iso-8859-2
+'iso-8859-2' => array(0=>'.notdef',1=>'.notdef',2=>'.notdef',3=>'.notdef',4=>'.notdef',5=>'.notdef',6=>'.notdef',7=>'.notdef',
+8=>'.notdef',9=>'.notdef',10=>'.notdef',11=>'.notdef',12=>'.notdef',13=>'.notdef',14=>'.notdef',15=>'.notdef',
+16=>'.notdef',17=>'.notdef',18=>'.notdef',19=>'.notdef',20=>'.notdef',21=>'.notdef',22=>'.notdef',23=>'.notdef',
+24=>'.notdef',25=>'.notdef',26=>'.notdef',27=>'.notdef',28=>'.notdef',29=>'.notdef',30=>'.notdef',31=>'.notdef',
+32=>'space',33=>'exclam',34=>'quotedbl',35=>'numbersign',36=>'dollar',37=>'percent',38=>'ampersand',39=>'quotesingle',
+40=>'parenleft',41=>'parenright',42=>'asterisk',43=>'plus',44=>'comma',45=>'hyphen',46=>'period',47=>'slash',
+48=>'zero',49=>'one',50=>'two',51=>'three',52=>'four',53=>'five',54=>'six',55=>'seven',
+56=>'eight',57=>'nine',58=>'colon',59=>'semicolon',60=>'less',61=>'equal',62=>'greater',63=>'question',
+64=>'at',65=>'A',66=>'B',67=>'C',68=>'D',69=>'E',70=>'F',71=>'G',
+72=>'H',73=>'I',74=>'J',75=>'K',76=>'L',77=>'M',78=>'N',79=>'O',
+80=>'P',81=>'Q',82=>'R',83=>'S',84=>'T',85=>'U',86=>'V',87=>'W',
+88=>'X',89=>'Y',90=>'Z',91=>'bracketleft',92=>'backslash',93=>'bracketright',94=>'asciicircum',95=>'underscore',
+96=>'grave',97=>'a',98=>'b',99=>'c',100=>'d',101=>'e',102=>'f',103=>'g',
+104=>'h',105=>'i',106=>'j',107=>'k',108=>'l',109=>'m',110=>'n',111=>'o',
+112=>'p',113=>'q',114=>'r',115=>'s',116=>'t',117=>'u',118=>'v',119=>'w',
+120=>'x',121=>'y',122=>'z',123=>'braceleft',124=>'bar',125=>'braceright',126=>'asciitilde',127=>'.notdef',
+128=>'.notdef',129=>'.notdef',130=>'.notdef',131=>'.notdef',132=>'.notdef',133=>'.notdef',134=>'.notdef',135=>'.notdef',
+136=>'.notdef',137=>'.notdef',138=>'.notdef',139=>'.notdef',140=>'.notdef',141=>'.notdef',142=>'.notdef',143=>'.notdef',
+144=>'.notdef',145=>'.notdef',146=>'.notdef',147=>'.notdef',148=>'.notdef',149=>'.notdef',150=>'.notdef',151=>'.notdef',
+152=>'.notdef',153=>'.notdef',154=>'.notdef',155=>'.notdef',156=>'.notdef',157=>'.notdef',158=>'.notdef',159=>'.notdef',
+160=>'space',161=>'Aogonek',162=>'breve',163=>'Lslash',164=>'currency',165=>'Lcaron',166=>'Sacute',167=>'section',
+168=>'dieresis',169=>'Scaron',170=>'Scedilla',171=>'Tcaron',172=>'Zacute',173=>'hyphen',174=>'Zcaron',175=>'Zdotaccent',
+176=>'degree',177=>'aogonek',178=>'ogonek',179=>'lslash',180=>'acute',181=>'lcaron',182=>'sacute',183=>'caron',
+184=>'cedilla',185=>'scaron',186=>'scedilla',187=>'tcaron',188=>'zacute',189=>'hungarumlaut',190=>'zcaron',191=>'zdotaccent',
+192=>'Racute',193=>'Aacute',194=>'Acircumflex',195=>'Abreve',196=>'Adieresis',197=>'Lacute',198=>'Cacute',199=>'Ccedilla',
+200=>'Ccaron',201=>'Eacute',202=>'Eogonek',203=>'Edieresis',204=>'Ecaron',205=>'Iacute',206=>'Icircumflex',207=>'Dcaron',
+208=>'Dcroat',209=>'Nacute',210=>'Ncaron',211=>'Oacute',212=>'Ocircumflex',213=>'Ohungarumlaut',214=>'Odieresis',215=>'multiply',
+216=>'Rcaron',217=>'Uring',218=>'Uacute',219=>'Uhungarumlaut',220=>'Udieresis',221=>'Yacute',222=>'Tcommaaccent',223=>'germandbls',
+224=>'racute',225=>'aacute',226=>'acircumflex',227=>'abreve',228=>'adieresis',229=>'lacute',230=>'cacute',231=>'ccedilla',
+232=>'ccaron',233=>'eacute',234=>'eogonek',235=>'edieresis',236=>'ecaron',237=>'iacute',238=>'icircumflex',239=>'dcaron',
+240=>'dcroat',241=>'nacute',242=>'ncaron',243=>'oacute',244=>'ocircumflex',245=>'ohungarumlaut',246=>'odieresis',247=>'divide',
+248=>'rcaron',249=>'uring',250=>'uacute',251=>'uhungarumlaut',252=>'udieresis',253=>'yacute',254=>'tcommaaccent',255=>'dotaccent'),
+
+// encoding map for: cp1250
+'cp1250' => array(0=>'.notdef',1=>'.notdef',2=>'.notdef',3=>'.notdef',4=>'.notdef',5=>'.notdef',6=>'.notdef',7=>'.notdef',
+8=>'.notdef',9=>'.notdef',10=>'.notdef',11=>'.notdef',12=>'.notdef',13=>'.notdef',14=>'.notdef',15=>'.notdef',
+16=>'.notdef',17=>'.notdef',18=>'.notdef',19=>'.notdef',20=>'.notdef',21=>'.notdef',22=>'.notdef',23=>'.notdef',
+24=>'.notdef',25=>'.notdef',26=>'.notdef',27=>'.notdef',28=>'.notdef',29=>'.notdef',30=>'.notdef',31=>'.notdef',
+32=>'space',33=>'exclam',34=>'quotedbl',35=>'numbersign',36=>'dollar',37=>'percent',38=>'ampersand',39=>'quotesingle',
+40=>'parenleft',41=>'parenright',42=>'asterisk',43=>'plus',44=>'comma',45=>'hyphen',46=>'period',47=>'slash',
+48=>'zero',49=>'one',50=>'two',51=>'three',52=>'four',53=>'five',54=>'six',55=>'seven',
+56=>'eight',57=>'nine',58=>'colon',59=>'semicolon',60=>'less',61=>'equal',62=>'greater',63=>'question',
+64=>'at',65=>'A',66=>'B',67=>'C',68=>'D',69=>'E',70=>'F',71=>'G',
+72=>'H',73=>'I',74=>'J',75=>'K',76=>'L',77=>'M',78=>'N',79=>'O',
+80=>'P',81=>'Q',82=>'R',83=>'S',84=>'T',85=>'U',86=>'V',87=>'W',
+88=>'X',89=>'Y',90=>'Z',91=>'bracketleft',92=>'backslash',93=>'bracketright',94=>'asciicircum',95=>'underscore',
+96=>'grave',97=>'a',98=>'b',99=>'c',100=>'d',101=>'e',102=>'f',103=>'g',
+104=>'h',105=>'i',106=>'j',107=>'k',108=>'l',109=>'m',110=>'n',111=>'o',
+112=>'p',113=>'q',114=>'r',115=>'s',116=>'t',117=>'u',118=>'v',119=>'w',
+120=>'x',121=>'y',122=>'z',123=>'braceleft',124=>'bar',125=>'braceright',126=>'asciitilde',127=>'.notdef',
+128=>'Euro',129=>'.notdef',130=>'quotesinglbase',131=>'.notdef',132=>'quotedblbase',133=>'ellipsis',134=>'dagger',135=>'daggerdbl',
+136=>'.notdef',137=>'perthousand',138=>'Scaron',139=>'guilsinglleft',140=>'Sacute',141=>'Tcaron',142=>'Zcaron',143=>'Zacute',
+144=>'.notdef',145=>'quoteleft',146=>'quoteright',147=>'quotedblleft',148=>'quotedblright',149=>'bullet',150=>'endash',151=>'emdash',
+152=>'.notdef',153=>'trademark',154=>'scaron',155=>'guilsinglright',156=>'sacute',157=>'tcaron',158=>'zcaron',159=>'zacute',
+160=>'space',161=>'caron',162=>'breve',163=>'Lslash',164=>'currency',165=>'Aogonek',166=>'brokenbar',167=>'section',
+168=>'dieresis',169=>'copyright',170=>'Scedilla',171=>'guillemotleft',172=>'logicalnot',173=>'hyphen',174=>'registered',175=>'Zdotaccent',
+176=>'degree',177=>'plusminus',178=>'ogonek',179=>'lslash',180=>'acute',181=>'mu',182=>'paragraph',183=>'periodcentered',
+184=>'cedilla',185=>'aogonek',186=>'scedilla',187=>'guillemotright',188=>'Lcaron',189=>'hungarumlaut',190=>'lcaron',191=>'zdotaccent',
+192=>'Racute',193=>'Aacute',194=>'Acircumflex',195=>'Abreve',196=>'Adieresis',197=>'Lacute',198=>'Cacute',199=>'Ccedilla',
+200=>'Ccaron',201=>'Eacute',202=>'Eogonek',203=>'Edieresis',204=>'Ecaron',205=>'Iacute',206=>'Icircumflex',207=>'Dcaron',
+208=>'Dcroat',209=>'Nacute',210=>'Ncaron',211=>'Oacute',212=>'Ocircumflex',213=>'Ohungarumlaut',214=>'Odieresis',215=>'multiply',
+216=>'Rcaron',217=>'Uring',218=>'Uacute',219=>'Uhungarumlaut',220=>'Udieresis',221=>'Yacute',222=>'Tcommaaccent',223=>'germandbls',
+224=>'racute',225=>'aacute',226=>'acircumflex',227=>'abreve',228=>'adieresis',229=>'lacute',230=>'cacute',231=>'ccedilla',
+232=>'ccaron',233=>'eacute',234=>'eogonek',235=>'edieresis',236=>'ecaron',237=>'iacute',238=>'icircumflex',239=>'dcaron',
+240=>'dcroat',241=>'nacute',242=>'ncaron',243=>'oacute',244=>'ocircumflex',245=>'ohungarumlaut',246=>'odieresis',247=>'divide',
+248=>'rcaron',249=>'uring',250=>'uacute',251=>'uhungarumlaut',252=>'udieresis',253=>'yacute',254=>'tcommaaccent',255=>'dotaccent'),
+
+// encoding map for: iso-8859-7
+'iso-8859-7' => array(0=>'.notdef',1=>'.notdef',2=>'.notdef',3=>'.notdef',4=>'.notdef',5=>'.notdef',6=>'.notdef',7=>'.notdef',
+8=>'.notdef',9=>'.notdef',10=>'.notdef',11=>'.notdef',12=>'.notdef',13=>'.notdef',14=>'.notdef',15=>'.notdef',
+16=>'.notdef',17=>'.notdef',18=>'.notdef',19=>'.notdef',20=>'.notdef',21=>'.notdef',22=>'.notdef',23=>'.notdef',
+24=>'.notdef',25=>'.notdef',26=>'.notdef',27=>'.notdef',28=>'.notdef',29=>'.notdef',30=>'.notdef',31=>'.notdef',
+32=>'space',33=>'exclam',34=>'quotedbl',35=>'numbersign',36=>'dollar',37=>'percent',38=>'ampersand',39=>'quotesingle',
+40=>'parenleft',41=>'parenright',42=>'asterisk',43=>'plus',44=>'comma',45=>'hyphen',46=>'period',47=>'slash',
+48=>'zero',49=>'one',50=>'two',51=>'three',52=>'four',53=>'five',54=>'six',55=>'seven',
+56=>'eight',57=>'nine',58=>'colon',59=>'semicolon',60=>'less',61=>'equal',62=>'greater',63=>'question',
+64=>'at',65=>'A',66=>'B',67=>'C',68=>'D',69=>'E',70=>'F',71=>'G',
+72=>'H',73=>'I',74=>'J',75=>'K',76=>'L',77=>'M',78=>'N',79=>'O',
+80=>'P',81=>'Q',82=>'R',83=>'S',84=>'T',85=>'U',86=>'V',87=>'W',
+88=>'X',89=>'Y',90=>'Z',91=>'bracketleft',92=>'backslash',93=>'bracketright',94=>'asciicircum',95=>'underscore',
+96=>'grave',97=>'a',98=>'b',99=>'c',100=>'d',101=>'e',102=>'f',103=>'g',
+104=>'h',105=>'i',106=>'j',107=>'k',108=>'l',109=>'m',110=>'n',111=>'o',
+112=>'p',113=>'q',114=>'r',115=>'s',116=>'t',117=>'u',118=>'v',119=>'w',
+120=>'x',121=>'y',122=>'z',123=>'braceleft',124=>'bar',125=>'braceright',126=>'asciitilde',127=>'.notdef',
+128=>'.notdef',129=>'.notdef',130=>'.notdef',131=>'.notdef',132=>'.notdef',133=>'.notdef',134=>'.notdef',135=>'.notdef',
+136=>'.notdef',137=>'.notdef',138=>'.notdef',139=>'.notdef',140=>'.notdef',141=>'.notdef',142=>'.notdef',143=>'.notdef',
+144=>'.notdef',145=>'.notdef',146=>'.notdef',147=>'.notdef',148=>'.notdef',149=>'.notdef',150=>'.notdef',151=>'.notdef',
+152=>'.notdef',153=>'.notdef',154=>'.notdef',155=>'.notdef',156=>'.notdef',157=>'.notdef',158=>'.notdef',159=>'.notdef',
+160=>'space',161=>'quoteleft',162=>'quoteright',163=>'sterling',164=>'.notdef',165=>'.notdef',166=>'brokenbar',167=>'section',
+168=>'dieresis',169=>'copyright',170=>'.notdef',171=>'guillemotleft',172=>'logicalnot',173=>'hyphen',174=>'.notdef',175=>'afii00208',
+176=>'degree',177=>'plusminus',178=>'twosuperior',179=>'threesuperior',180=>'tonos',181=>'dieresistonos',182=>'Alphatonos',183=>'periodcentered',
+184=>'Epsilontonos',185=>'Etatonos',186=>'Iotatonos',187=>'guillemotright',188=>'Omicrontonos',189=>'onehalf',190=>'Upsilontonos',191=>'Omegatonos',
+192=>'iotadieresistonos',193=>'Alpha',194=>'Beta',195=>'Gamma',196=>'Delta',197=>'Epsilon',198=>'Zeta',199=>'Eta',
+200=>'Theta',201=>'Iota',202=>'Kappa',203=>'Lambda',204=>'Mu',205=>'Nu',206=>'Xi',207=>'Omicron',
+208=>'Pi',209=>'Rho',210=>'.notdef',211=>'Sigma',212=>'Tau',213=>'Upsilon',214=>'Phi',215=>'Chi',
+216=>'Psi',217=>'Omega',218=>'Iotadieresis',219=>'Upsilondieresis',220=>'alphatonos',221=>'epsilontonos',222=>'etatonos',223=>'iotatonos',
+224=>'upsilondieresistonos',225=>'alpha',226=>'beta',227=>'gamma',228=>'delta',229=>'epsilon',230=>'zeta',231=>'eta',
+232=>'theta',233=>'iota',234=>'kappa',235=>'lambda',236=>'mu',237=>'nu',238=>'xi',239=>'omicron',
+240=>'pi',241=>'rho',242=>'sigma1',243=>'sigma',244=>'tau',245=>'upsilon',246=>'phi',247=>'chi',
+248=>'psi',249=>'omega',250=>'iotadieresis',251=>'upsilondieresis',252=>'omicrontonos',253=>'upsilontonos',254=>'omegatonos',255=>'.notdef'),
+
+// encoding map for: iso-8859-9
+'iso-8859-9' => array(0=>'.notdef',1=>'.notdef',2=>'.notdef',3=>'.notdef',4=>'.notdef',5=>'.notdef',6=>'.notdef',7=>'.notdef',
+8=>'.notdef',9=>'.notdef',10=>'.notdef',11=>'.notdef',12=>'.notdef',13=>'.notdef',14=>'.notdef',15=>'.notdef',
+16=>'.notdef',17=>'.notdef',18=>'.notdef',19=>'.notdef',20=>'.notdef',21=>'.notdef',22=>'.notdef',23=>'.notdef',
+24=>'.notdef',25=>'.notdef',26=>'.notdef',27=>'.notdef',28=>'.notdef',29=>'.notdef',30=>'.notdef',31=>'.notdef',
+32=>'space',33=>'exclam',34=>'quotedbl',35=>'numbersign',36=>'dollar',37=>'percent',38=>'ampersand',39=>'quotesingle',
+40=>'parenleft',41=>'parenright',42=>'asterisk',43=>'plus',44=>'comma',45=>'hyphen',46=>'period',47=>'slash',
+48=>'zero',49=>'one',50=>'two',51=>'three',52=>'four',53=>'five',54=>'six',55=>'seven',
+56=>'eight',57=>'nine',58=>'colon',59=>'semicolon',60=>'less',61=>'equal',62=>'greater',63=>'question',
+64=>'at',65=>'A',66=>'B',67=>'C',68=>'D',69=>'E',70=>'F',71=>'G',
+72=>'H',73=>'I',74=>'J',75=>'K',76=>'L',77=>'M',78=>'N',79=>'O',
+80=>'P',81=>'Q',82=>'R',83=>'S',84=>'T',85=>'U',86=>'V',87=>'W',
+88=>'X',89=>'Y',90=>'Z',91=>'bracketleft',92=>'backslash',93=>'bracketright',94=>'asciicircum',95=>'underscore',
+96=>'grave',97=>'a',98=>'b',99=>'c',100=>'d',101=>'e',102=>'f',103=>'g',
+104=>'h',105=>'i',106=>'j',107=>'k',108=>'l',109=>'m',110=>'n',111=>'o',
+112=>'p',113=>'q',114=>'r',115=>'s',116=>'t',117=>'u',118=>'v',119=>'w',
+120=>'x',121=>'y',122=>'z',123=>'braceleft',124=>'bar',125=>'braceright',126=>'asciitilde',127=>'.notdef',
+128=>'.notdef',129=>'.notdef',130=>'.notdef',131=>'.notdef',132=>'.notdef',133=>'.notdef',134=>'.notdef',135=>'.notdef',
+136=>'.notdef',137=>'.notdef',138=>'.notdef',139=>'.notdef',140=>'.notdef',141=>'.notdef',142=>'.notdef',143=>'.notdef',
+144=>'.notdef',145=>'.notdef',146=>'.notdef',147=>'.notdef',148=>'.notdef',149=>'.notdef',150=>'.notdef',151=>'.notdef',
+152=>'.notdef',153=>'.notdef',154=>'.notdef',155=>'.notdef',156=>'.notdef',157=>'.notdef',158=>'.notdef',159=>'.notdef',
+160=>'space',161=>'exclamdown',162=>'cent',163=>'sterling',164=>'currency',165=>'yen',166=>'brokenbar',167=>'section',
+168=>'dieresis',169=>'copyright',170=>'ordfeminine',171=>'guillemotleft',172=>'logicalnot',173=>'hyphen',174=>'registered',175=>'macron',
+176=>'degree',177=>'plusminus',178=>'twosuperior',179=>'threesuperior',180=>'acute',181=>'mu',182=>'paragraph',183=>'periodcentered',
+184=>'cedilla',185=>'onesuperior',186=>'ordmasculine',187=>'guillemotright',188=>'onequarter',189=>'onehalf',190=>'threequarters',191=>'questiondown',
+192=>'Agrave',193=>'Aacute',194=>'Acircumflex',195=>'Atilde',196=>'Adieresis',197=>'Aring',198=>'AE',199=>'Ccedilla',
+200=>'Egrave',201=>'Eacute',202=>'Ecircumflex',203=>'Edieresis',204=>'Igrave',205=>'Iacute',206=>'Icircumflex',207=>'Idieresis',
+208=>'Gbreve',209=>'Ntilde',210=>'Ograve',211=>'Oacute',212=>'Ocircumflex',213=>'Otilde',214=>'Odieresis',215=>'multiply',
+216=>'Oslash',217=>'Ugrave',218=>'Uacute',219=>'Ucircumflex',220=>'Udieresis',221=>'Idotaccent',222=>'Scedilla',223=>'germandbls',
+224=>'agrave',225=>'aacute',226=>'acircumflex',227=>'atilde',228=>'adieresis',229=>'aring',230=>'ae',231=>'ccedilla',
+232=>'egrave',233=>'eacute',234=>'ecircumflex',235=>'edieresis',236=>'igrave',237=>'iacute',238=>'icircumflex',239=>'idieresis',
+240=>'gbreve',241=>'ntilde',242=>'ograve',243=>'oacute',244=>'ocircumflex',245=>'otilde',246=>'odieresis',247=>'divide',
+248=>'oslash',249=>'ugrave',250=>'uacute',251=>'ucircumflex',252=>'udieresis',253=>'dotlessi',254=>'scedilla',255=>'ydieresis'),
+
+// encoding map for: cp1252
+'cp1252' => array(0=>'.notdef',1=>'.notdef',2=>'.notdef',3=>'.notdef',4=>'.notdef',5=>'.notdef',6=>'.notdef',7=>'.notdef',
+8=>'.notdef',9=>'.notdef',10=>'.notdef',11=>'.notdef',12=>'.notdef',13=>'.notdef',14=>'.notdef',15=>'.notdef',
+16=>'.notdef',17=>'.notdef',18=>'.notdef',19=>'.notdef',20=>'.notdef',21=>'.notdef',22=>'.notdef',23=>'.notdef',
+24=>'.notdef',25=>'.notdef',26=>'.notdef',27=>'.notdef',28=>'.notdef',29=>'.notdef',30=>'.notdef',31=>'.notdef',
+32=>'space',33=>'exclam',34=>'quotedbl',35=>'numbersign',36=>'dollar',37=>'percent',38=>'ampersand',39=>'quotesingle',
+40=>'parenleft',41=>'parenright',42=>'asterisk',43=>'plus',44=>'comma',45=>'hyphen',46=>'period',47=>'slash',
+48=>'zero',49=>'one',50=>'two',51=>'three',52=>'four',53=>'five',54=>'six',55=>'seven',
+56=>'eight',57=>'nine',58=>'colon',59=>'semicolon',60=>'less',61=>'equal',62=>'greater',63=>'question',
+64=>'at',65=>'A',66=>'B',67=>'C',68=>'D',69=>'E',70=>'F',71=>'G',
+72=>'H',73=>'I',74=>'J',75=>'K',76=>'L',77=>'M',78=>'N',79=>'O',
+80=>'P',81=>'Q',82=>'R',83=>'S',84=>'T',85=>'U',86=>'V',87=>'W',
+88=>'X',89=>'Y',90=>'Z',91=>'bracketleft',92=>'backslash',93=>'bracketright',94=>'asciicircum',95=>'underscore',
+96=>'grave',97=>'a',98=>'b',99=>'c',100=>'d',101=>'e',102=>'f',103=>'g',
+104=>'h',105=>'i',106=>'j',107=>'k',108=>'l',109=>'m',110=>'n',111=>'o',
+112=>'p',113=>'q',114=>'r',115=>'s',116=>'t',117=>'u',118=>'v',119=>'w',
+120=>'x',121=>'y',122=>'z',123=>'braceleft',124=>'bar',125=>'braceright',126=>'asciitilde',127=>'.notdef',
+128=>'Euro',129=>'.notdef',130=>'quotesinglbase',131=>'florin',132=>'quotedblbase',133=>'ellipsis',134=>'dagger',135=>'daggerdbl',
+136=>'circumflex',137=>'perthousand',138=>'Scaron',139=>'guilsinglleft',140=>'OE',141=>'.notdef',142=>'Zcaron',143=>'.notdef',
+144=>'.notdef',145=>'quoteleft',146=>'quoteright',147=>'quotedblleft',148=>'quotedblright',149=>'bullet',150=>'endash',151=>'emdash',
+152=>'tilde',153=>'trademark',154=>'scaron',155=>'guilsinglright',156=>'oe',157=>'.notdef',158=>'zcaron',159=>'Ydieresis',
+160=>'space',161=>'exclamdown',162=>'cent',163=>'sterling',164=>'currency',165=>'yen',166=>'brokenbar',167=>'section',
+168=>'dieresis',169=>'copyright',170=>'ordfeminine',171=>'guillemotleft',172=>'logicalnot',173=>'hyphen',174=>'registered',175=>'macron',
+176=>'degree',177=>'plusminus',178=>'twosuperior',179=>'threesuperior',180=>'acute',181=>'mu',182=>'paragraph',183=>'periodcentered',
+184=>'cedilla',185=>'onesuperior',186=>'ordmasculine',187=>'guillemotright',188=>'onequarter',189=>'onehalf',190=>'threequarters',191=>'questiondown',
+192=>'Agrave',193=>'Aacute',194=>'Acircumflex',195=>'Atilde',196=>'Adieresis',197=>'Aring',198=>'AE',199=>'Ccedilla',
+200=>'Egrave',201=>'Eacute',202=>'Ecircumflex',203=>'Edieresis',204=>'Igrave',205=>'Iacute',206=>'Icircumflex',207=>'Idieresis',
+208=>'Eth',209=>'Ntilde',210=>'Ograve',211=>'Oacute',212=>'Ocircumflex',213=>'Otilde',214=>'Odieresis',215=>'multiply',
+216=>'Oslash',217=>'Ugrave',218=>'Uacute',219=>'Ucircumflex',220=>'Udieresis',221=>'Yacute',222=>'Thorn',223=>'germandbls',
+224=>'agrave',225=>'aacute',226=>'acircumflex',227=>'atilde',228=>'adieresis',229=>'aring',230=>'ae',231=>'ccedilla',
+232=>'egrave',233=>'eacute',234=>'ecircumflex',235=>'edieresis',236=>'igrave',237=>'iacute',238=>'icircumflex',239=>'idieresis',
+240=>'eth',241=>'ntilde',242=>'ograve',243=>'oacute',244=>'ocircumflex',245=>'otilde',246=>'odieresis',247=>'divide',
+248=>'oslash',249=>'ugrave',250=>'uacute',251=>'ucircumflex',252=>'udieresis',253=>'yacute',254=>'thorn',255=>'ydieresis'),
+
+// encoding map for: cp1254
+'cp1254' => array(0=>'.notdef',1=>'.notdef',2=>'.notdef',3=>'.notdef',4=>'.notdef',5=>'.notdef',6=>'.notdef',7=>'.notdef',
+8=>'.notdef',9=>'.notdef',10=>'.notdef',11=>'.notdef',12=>'.notdef',13=>'.notdef',14=>'.notdef',15=>'.notdef',
+16=>'.notdef',17=>'.notdef',18=>'.notdef',19=>'.notdef',20=>'.notdef',21=>'.notdef',22=>'.notdef',23=>'.notdef',
+24=>'.notdef',25=>'.notdef',26=>'.notdef',27=>'.notdef',28=>'.notdef',29=>'.notdef',30=>'.notdef',31=>'.notdef',
+32=>'space',33=>'exclam',34=>'quotedbl',35=>'numbersign',36=>'dollar',37=>'percent',38=>'ampersand',39=>'quotesingle',
+40=>'parenleft',41=>'parenright',42=>'asterisk',43=>'plus',44=>'comma',45=>'hyphen',46=>'period',47=>'slash',
+48=>'zero',49=>'one',50=>'two',51=>'three',52=>'four',53=>'five',54=>'six',55=>'seven',
+56=>'eight',57=>'nine',58=>'colon',59=>'semicolon',60=>'less',61=>'equal',62=>'greater',63=>'question',
+64=>'at',65=>'A',66=>'B',67=>'C',68=>'D',69=>'E',70=>'F',71=>'G',
+72=>'H',73=>'I',74=>'J',75=>'K',76=>'L',77=>'M',78=>'N',79=>'O',
+80=>'P',81=>'Q',82=>'R',83=>'S',84=>'T',85=>'U',86=>'V',87=>'W',
+88=>'X',89=>'Y',90=>'Z',91=>'bracketleft',92=>'backslash',93=>'bracketright',94=>'asciicircum',95=>'underscore',
+96=>'grave',97=>'a',98=>'b',99=>'c',100=>'d',101=>'e',102=>'f',103=>'g',
+104=>'h',105=>'i',106=>'j',107=>'k',108=>'l',109=>'m',110=>'n',111=>'o',
+112=>'p',113=>'q',114=>'r',115=>'s',116=>'t',117=>'u',118=>'v',119=>'w',
+120=>'x',121=>'y',122=>'z',123=>'braceleft',124=>'bar',125=>'braceright',126=>'asciitilde',127=>'.notdef',
+128=>'Euro',129=>'.notdef',130=>'quotesinglbase',131=>'florin',132=>'quotedblbase',133=>'ellipsis',134=>'dagger',135=>'daggerdbl',
+136=>'circumflex',137=>'perthousand',138=>'Scaron',139=>'guilsinglleft',140=>'OE',141=>'.notdef',142=>'.notdef',143=>'.notdef',
+144=>'.notdef',145=>'quoteleft',146=>'quoteright',147=>'quotedblleft',148=>'quotedblright',149=>'bullet',150=>'endash',151=>'emdash',
+152=>'tilde',153=>'trademark',154=>'scaron',155=>'guilsinglright',156=>'oe',157=>'.notdef',158=>'.notdef',159=>'Ydieresis',
+160=>'space',161=>'exclamdown',162=>'cent',163=>'sterling',164=>'currency',165=>'yen',166=>'brokenbar',167=>'section',
+168=>'dieresis',169=>'copyright',170=>'ordfeminine',171=>'guillemotleft',172=>'logicalnot',173=>'hyphen',174=>'registered',175=>'macron',
+176=>'degree',177=>'plusminus',178=>'twosuperior',179=>'threesuperior',180=>'acute',181=>'mu',182=>'paragraph',183=>'periodcentered',
+184=>'cedilla',185=>'onesuperior',186=>'ordmasculine',187=>'guillemotright',188=>'onequarter',189=>'onehalf',190=>'threequarters',191=>'questiondown',
+192=>'Agrave',193=>'Aacute',194=>'Acircumflex',195=>'Atilde',196=>'Adieresis',197=>'Aring',198=>'AE',199=>'Ccedilla',
+200=>'Egrave',201=>'Eacute',202=>'Ecircumflex',203=>'Edieresis',204=>'Igrave',205=>'Iacute',206=>'Icircumflex',207=>'Idieresis',
+208=>'Gbreve',209=>'Ntilde',210=>'Ograve',211=>'Oacute',212=>'Ocircumflex',213=>'Otilde',214=>'Odieresis',215=>'multiply',
+216=>'Oslash',217=>'Ugrave',218=>'Uacute',219=>'Ucircumflex',220=>'Udieresis',221=>'Idotaccent',222=>'Scedilla',223=>'germandbls',
+224=>'agrave',225=>'aacute',226=>'acircumflex',227=>'atilde',228=>'adieresis',229=>'aring',230=>'ae',231=>'ccedilla',
+232=>'egrave',233=>'eacute',234=>'ecircumflex',235=>'edieresis',236=>'igrave',237=>'iacute',238=>'icircumflex',239=>'idieresis',
+240=>'gbreve',241=>'ntilde',242=>'ograve',243=>'oacute',244=>'ocircumflex',245=>'otilde',246=>'odieresis',247=>'divide',
+248=>'oslash',249=>'ugrave',250=>'uacute',251=>'ucircumflex',252=>'udieresis',253=>'dotlessi',254=>'scedilla',255=>'ydieresis'),
+
+// encoding map for: iso-8859-1
+'iso-8859-1' => array(0=>'.notdef',1=>'.notdef',2=>'.notdef',3=>'.notdef',4=>'.notdef',5=>'.notdef',6=>'.notdef',7=>'.notdef',
+8=>'.notdef',9=>'.notdef',10=>'.notdef',11=>'.notdef',12=>'.notdef',13=>'.notdef',14=>'.notdef',15=>'.notdef',
+16=>'.notdef',17=>'.notdef',18=>'.notdef',19=>'.notdef',20=>'.notdef',21=>'.notdef',22=>'.notdef',23=>'.notdef',
+24=>'.notdef',25=>'.notdef',26=>'.notdef',27=>'.notdef',28=>'.notdef',29=>'.notdef',30=>'.notdef',31=>'.notdef',
+32=>'space',33=>'exclam',34=>'quotedbl',35=>'numbersign',36=>'dollar',37=>'percent',38=>'ampersand',39=>'quotesingle',
+40=>'parenleft',41=>'parenright',42=>'asterisk',43=>'plus',44=>'comma',45=>'hyphen',46=>'period',47=>'slash',
+48=>'zero',49=>'one',50=>'two',51=>'three',52=>'four',53=>'five',54=>'six',55=>'seven',
+56=>'eight',57=>'nine',58=>'colon',59=>'semicolon',60=>'less',61=>'equal',62=>'greater',63=>'question',
+64=>'at',65=>'A',66=>'B',67=>'C',68=>'D',69=>'E',70=>'F',71=>'G',
+72=>'H',73=>'I',74=>'J',75=>'K',76=>'L',77=>'M',78=>'N',79=>'O',
+80=>'P',81=>'Q',82=>'R',83=>'S',84=>'T',85=>'U',86=>'V',87=>'W',
+88=>'X',89=>'Y',90=>'Z',91=>'bracketleft',92=>'backslash',93=>'bracketright',94=>'asciicircum',95=>'underscore',
+96=>'grave',97=>'a',98=>'b',99=>'c',100=>'d',101=>'e',102=>'f',103=>'g',
+104=>'h',105=>'i',106=>'j',107=>'k',108=>'l',109=>'m',110=>'n',111=>'o',
+112=>'p',113=>'q',114=>'r',115=>'s',116=>'t',117=>'u',118=>'v',119=>'w',
+120=>'x',121=>'y',122=>'z',123=>'braceleft',124=>'bar',125=>'braceright',126=>'asciitilde',127=>'.notdef',
+128=>'.notdef',129=>'.notdef',130=>'.notdef',131=>'.notdef',132=>'.notdef',133=>'.notdef',134=>'.notdef',135=>'.notdef',
+136=>'.notdef',137=>'.notdef',138=>'.notdef',139=>'.notdef',140=>'.notdef',141=>'.notdef',142=>'.notdef',143=>'.notdef',
+144=>'.notdef',145=>'.notdef',146=>'.notdef',147=>'.notdef',148=>'.notdef',149=>'.notdef',150=>'.notdef',151=>'.notdef',
+152=>'.notdef',153=>'.notdef',154=>'.notdef',155=>'.notdef',156=>'.notdef',157=>'.notdef',158=>'.notdef',159=>'.notdef',
+160=>'space',161=>'exclamdown',162=>'cent',163=>'sterling',164=>'currency',165=>'yen',166=>'brokenbar',167=>'section',
+168=>'dieresis',169=>'copyright',170=>'ordfeminine',171=>'guillemotleft',172=>'logicalnot',173=>'hyphen',174=>'registered',175=>'macron',
+176=>'degree',177=>'plusminus',178=>'twosuperior',179=>'threesuperior',180=>'acute',181=>'mu',182=>'paragraph',183=>'periodcentered',
+184=>'cedilla',185=>'onesuperior',186=>'ordmasculine',187=>'guillemotright',188=>'onequarter',189=>'onehalf',190=>'threequarters',191=>'questiondown',
+192=>'Agrave',193=>'Aacute',194=>'Acircumflex',195=>'Atilde',196=>'Adieresis',197=>'Aring',198=>'AE',199=>'Ccedilla',
+200=>'Egrave',201=>'Eacute',202=>'Ecircumflex',203=>'Edieresis',204=>'Igrave',205=>'Iacute',206=>'Icircumflex',207=>'Idieresis',
+208=>'Eth',209=>'Ntilde',210=>'Ograve',211=>'Oacute',212=>'Ocircumflex',213=>'Otilde',214=>'Odieresis',215=>'multiply',
+216=>'Oslash',217=>'Ugrave',218=>'Uacute',219=>'Ucircumflex',220=>'Udieresis',221=>'Yacute',222=>'Thorn',223=>'germandbls',
+224=>'agrave',225=>'aacute',226=>'acircumflex',227=>'atilde',228=>'adieresis',229=>'aring',230=>'ae',231=>'ccedilla',
+232=>'egrave',233=>'eacute',234=>'ecircumflex',235=>'edieresis',236=>'igrave',237=>'iacute',238=>'icircumflex',239=>'idieresis',
+240=>'eth',241=>'ntilde',242=>'ograve',243=>'oacute',244=>'ocircumflex',245=>'otilde',246=>'odieresis',247=>'divide',
+248=>'oslash',249=>'ugrave',250=>'uacute',251=>'ucircumflex',252=>'udieresis',253=>'yacute',254=>'thorn',255=>'ydieresis'),
+
+// encoding map for: iso-8859-15
+'iso-8859-15' => array(0=>'.notdef',1=>'.notdef',2=>'.notdef',3=>'.notdef',4=>'.notdef',5=>'.notdef',6=>'.notdef',7=>'.notdef',
+8=>'.notdef',9=>'.notdef',10=>'.notdef',11=>'.notdef',12=>'.notdef',13=>'.notdef',14=>'.notdef',15=>'.notdef',
+16=>'.notdef',17=>'.notdef',18=>'.notdef',19=>'.notdef',20=>'.notdef',21=>'.notdef',22=>'.notdef',23=>'.notdef',
+24=>'.notdef',25=>'.notdef',26=>'.notdef',27=>'.notdef',28=>'.notdef',29=>'.notdef',30=>'.notdef',31=>'.notdef',
+32=>'space',33=>'exclam',34=>'quotedbl',35=>'numbersign',36=>'dollar',37=>'percent',38=>'ampersand',39=>'quotesingle',
+40=>'parenleft',41=>'parenright',42=>'asterisk',43=>'plus',44=>'comma',45=>'hyphen',46=>'period',47=>'slash',
+48=>'zero',49=>'one',50=>'two',51=>'three',52=>'four',53=>'five',54=>'six',55=>'seven',
+56=>'eight',57=>'nine',58=>'colon',59=>'semicolon',60=>'less',61=>'equal',62=>'greater',63=>'question',
+64=>'at',65=>'A',66=>'B',67=>'C',68=>'D',69=>'E',70=>'F',71=>'G',
+72=>'H',73=>'I',74=>'J',75=>'K',76=>'L',77=>'M',78=>'N',79=>'O',
+80=>'P',81=>'Q',82=>'R',83=>'S',84=>'T',85=>'U',86=>'V',87=>'W',
+88=>'X',89=>'Y',90=>'Z',91=>'bracketleft',92=>'backslash',93=>'bracketright',94=>'asciicircum',95=>'underscore',
+96=>'grave',97=>'a',98=>'b',99=>'c',100=>'d',101=>'e',102=>'f',103=>'g',
+104=>'h',105=>'i',106=>'j',107=>'k',108=>'l',109=>'m',110=>'n',111=>'o',
+112=>'p',113=>'q',114=>'r',115=>'s',116=>'t',117=>'u',118=>'v',119=>'w',
+120=>'x',121=>'y',122=>'z',123=>'braceleft',124=>'bar',125=>'braceright',126=>'asciitilde',127=>'.notdef',
+128=>'.notdef',129=>'.notdef',130=>'.notdef',131=>'.notdef',132=>'.notdef',133=>'.notdef',134=>'.notdef',135=>'.notdef',
+136=>'.notdef',137=>'.notdef',138=>'.notdef',139=>'.notdef',140=>'.notdef',141=>'.notdef',142=>'.notdef',143=>'.notdef',
+144=>'.notdef',145=>'.notdef',146=>'.notdef',147=>'.notdef',148=>'.notdef',149=>'.notdef',150=>'.notdef',151=>'.notdef',
+152=>'.notdef',153=>'.notdef',154=>'.notdef',155=>'.notdef',156=>'.notdef',157=>'.notdef',158=>'.notdef',159=>'.notdef',
+160=>'space',161=>'exclamdown',162=>'cent',163=>'sterling',164=>'Euro',165=>'yen',166=>'Scaron',167=>'section',
+168=>'scaron',169=>'copyright',170=>'ordfeminine',171=>'guillemotleft',172=>'logicalnot',173=>'hyphen',174=>'registered',175=>'macron',
+176=>'degree',177=>'plusminus',178=>'twosuperior',179=>'threesuperior',180=>'Zcaron',181=>'mu',182=>'paragraph',183=>'periodcentered',
+184=>'zcaron',185=>'onesuperior',186=>'ordmasculine',187=>'guillemotright',188=>'OE',189=>'oe',190=>'Ydieresis',191=>'questiondown',
+192=>'Agrave',193=>'Aacute',194=>'Acircumflex',195=>'Atilde',196=>'Adieresis',197=>'Aring',198=>'AE',199=>'Ccedilla',
+200=>'Egrave',201=>'Eacute',202=>'Ecircumflex',203=>'Edieresis',204=>'Igrave',205=>'Iacute',206=>'Icircumflex',207=>'Idieresis',
+208=>'Eth',209=>'Ntilde',210=>'Ograve',211=>'Oacute',212=>'Ocircumflex',213=>'Otilde',214=>'Odieresis',215=>'multiply',
+216=>'Oslash',217=>'Ugrave',218=>'Uacute',219=>'Ucircumflex',220=>'Udieresis',221=>'Yacute',222=>'Thorn',223=>'germandbls',
+224=>'agrave',225=>'aacute',226=>'acircumflex',227=>'atilde',228=>'adieresis',229=>'aring',230=>'ae',231=>'ccedilla',
+232=>'egrave',233=>'eacute',234=>'ecircumflex',235=>'edieresis',236=>'igrave',237=>'iacute',238=>'icircumflex',239=>'idieresis',
+240=>'eth',241=>'ntilde',242=>'ograve',243=>'oacute',244=>'ocircumflex',245=>'otilde',246=>'odieresis',247=>'divide',
+248=>'oslash',249=>'ugrave',250=>'uacute',251=>'ucircumflex',252=>'udieresis',253=>'yacute',254=>'thorn',255=>'ydieresis'),
+
+// encoding map for: iso-8859-5
+'iso-8859-5' => array(0=>'.notdef',1=>'.notdef',2=>'.notdef',3=>'.notdef',4=>'.notdef',5=>'.notdef',6=>'.notdef',7=>'.notdef',
+8=>'.notdef',9=>'.notdef',10=>'.notdef',11=>'.notdef',12=>'.notdef',13=>'.notdef',14=>'.notdef',15=>'.notdef',
+16=>'.notdef',17=>'.notdef',18=>'.notdef',19=>'.notdef',20=>'.notdef',21=>'.notdef',22=>'.notdef',23=>'.notdef',
+24=>'.notdef',25=>'.notdef',26=>'.notdef',27=>'.notdef',28=>'.notdef',29=>'.notdef',30=>'.notdef',31=>'.notdef',
+32=>'space',33=>'exclam',34=>'quotedbl',35=>'numbersign',36=>'dollar',37=>'percent',38=>'ampersand',39=>'quotesingle',
+40=>'parenleft',41=>'parenright',42=>'asterisk',43=>'plus',44=>'comma',45=>'hyphen',46=>'period',47=>'slash',
+48=>'zero',49=>'one',50=>'two',51=>'three',52=>'four',53=>'five',54=>'six',55=>'seven',
+56=>'eight',57=>'nine',58=>'colon',59=>'semicolon',60=>'less',61=>'equal',62=>'greater',63=>'question',
+64=>'at',65=>'A',66=>'B',67=>'C',68=>'D',69=>'E',70=>'F',71=>'G',
+72=>'H',73=>'I',74=>'J',75=>'K',76=>'L',77=>'M',78=>'N',79=>'O',
+80=>'P',81=>'Q',82=>'R',83=>'S',84=>'T',85=>'U',86=>'V',87=>'W',
+88=>'X',89=>'Y',90=>'Z',91=>'bracketleft',92=>'backslash',93=>'bracketright',94=>'asciicircum',95=>'underscore',
+96=>'grave',97=>'a',98=>'b',99=>'c',100=>'d',101=>'e',102=>'f',103=>'g',
+104=>'h',105=>'i',106=>'j',107=>'k',108=>'l',109=>'m',110=>'n',111=>'o',
+112=>'p',113=>'q',114=>'r',115=>'s',116=>'t',117=>'u',118=>'v',119=>'w',
+120=>'x',121=>'y',122=>'z',123=>'braceleft',124=>'bar',125=>'braceright',126=>'asciitilde',127=>'.notdef',
+128=>'.notdef',129=>'.notdef',130=>'.notdef',131=>'.notdef',132=>'.notdef',133=>'.notdef',134=>'.notdef',135=>'.notdef',
+136=>'.notdef',137=>'.notdef',138=>'.notdef',139=>'.notdef',140=>'.notdef',141=>'.notdef',142=>'.notdef',143=>'.notdef',
+144=>'.notdef',145=>'.notdef',146=>'.notdef',147=>'.notdef',148=>'.notdef',149=>'.notdef',150=>'.notdef',151=>'.notdef',
+152=>'.notdef',153=>'.notdef',154=>'.notdef',155=>'.notdef',156=>'.notdef',157=>'.notdef',158=>'.notdef',159=>'.notdef',
+160=>'space',161=>'afii10023',162=>'afii10051',163=>'afii10052',164=>'afii10053',165=>'afii10054',166=>'afii10055',167=>'afii10056',
+168=>'afii10057',169=>'afii10058',170=>'afii10059',171=>'afii10060',172=>'afii10061',173=>'hyphen',174=>'afii10062',175=>'afii10145',
+176=>'afii10017',177=>'afii10018',178=>'afii10019',179=>'afii10020',180=>'afii10021',181=>'afii10022',182=>'afii10024',183=>'afii10025',
+184=>'afii10026',185=>'afii10027',186=>'afii10028',187=>'afii10029',188=>'afii10030',189=>'afii10031',190=>'afii10032',191=>'afii10033',
+192=>'afii10034',193=>'afii10035',194=>'afii10036',195=>'afii10037',196=>'afii10038',197=>'afii10039',198=>'afii10040',199=>'afii10041',
+200=>'afii10042',201=>'afii10043',202=>'afii10044',203=>'afii10045',204=>'afii10046',205=>'afii10047',206=>'afii10048',207=>'afii10049',
+208=>'afii10065',209=>'afii10066',210=>'afii10067',211=>'afii10068',212=>'afii10069',213=>'afii10070',214=>'afii10072',215=>'afii10073',
+216=>'afii10074',217=>'afii10075',218=>'afii10076',219=>'afii10077',220=>'afii10078',221=>'afii10079',222=>'afii10080',223=>'afii10081',
+224=>'afii10082',225=>'afii10083',226=>'afii10084',227=>'afii10085',228=>'afii10086',229=>'afii10087',230=>'afii10088',231=>'afii10089',
+232=>'afii10090',233=>'afii10091',234=>'afii10092',235=>'afii10093',236=>'afii10094',237=>'afii10095',238=>'afii10096',239=>'afii10097',
+240=>'afii61352',241=>'afii10071',242=>'afii10099',243=>'afii10100',244=>'afii10101',245=>'afii10102',246=>'afii10103',247=>'afii10104',
+248=>'afii10105',249=>'afii10106',250=>'afii10107',251=>'afii10108',252=>'afii10109',253=>'section',254=>'afii10110',255=>'afii10193'),
+
+// encoding map for: iso-8859-5
+'iso-8859-5' => array(0=>'.notdef',1=>'.notdef',2=>'.notdef',3=>'.notdef',4=>'.notdef',5=>'.notdef',6=>'.notdef',7=>'.notdef',
+8=>'.notdef',9=>'.notdef',10=>'.notdef',11=>'.notdef',12=>'.notdef',13=>'.notdef',14=>'.notdef',15=>'.notdef',
+16=>'.notdef',17=>'.notdef',18=>'.notdef',19=>'.notdef',20=>'.notdef',21=>'.notdef',22=>'.notdef',23=>'.notdef',
+24=>'.notdef',25=>'.notdef',26=>'.notdef',27=>'.notdef',28=>'.notdef',29=>'.notdef',30=>'.notdef',31=>'.notdef',
+32=>'space',33=>'exclam',34=>'quotedbl',35=>'numbersign',36=>'dollar',37=>'percent',38=>'ampersand',39=>'quotesingle',
+40=>'parenleft',41=>'parenright',42=>'asterisk',43=>'plus',44=>'comma',45=>'hyphen',46=>'period',47=>'slash',
+48=>'zero',49=>'one',50=>'two',51=>'three',52=>'four',53=>'five',54=>'six',55=>'seven',
+56=>'eight',57=>'nine',58=>'colon',59=>'semicolon',60=>'less',61=>'equal',62=>'greater',63=>'question',
+64=>'at',65=>'A',66=>'B',67=>'C',68=>'D',69=>'E',70=>'F',71=>'G',
+72=>'H',73=>'I',74=>'J',75=>'K',76=>'L',77=>'M',78=>'N',79=>'O',
+80=>'P',81=>'Q',82=>'R',83=>'S',84=>'T',85=>'U',86=>'V',87=>'W',
+88=>'X',89=>'Y',90=>'Z',91=>'bracketleft',92=>'backslash',93=>'bracketright',94=>'asciicircum',95=>'underscore',
+96=>'grave',97=>'a',98=>'b',99=>'c',100=>'d',101=>'e',102=>'f',103=>'g',
+104=>'h',105=>'i',106=>'j',107=>'k',108=>'l',109=>'m',110=>'n',111=>'o',
+112=>'p',113=>'q',114=>'r',115=>'s',116=>'t',117=>'u',118=>'v',119=>'w',
+120=>'x',121=>'y',122=>'z',123=>'braceleft',124=>'bar',125=>'braceright',126=>'asciitilde',127=>'.notdef',
+128=>'.notdef',129=>'.notdef',130=>'.notdef',131=>'.notdef',132=>'.notdef',133=>'.notdef',134=>'.notdef',135=>'.notdef',
+136=>'.notdef',137=>'.notdef',138=>'.notdef',139=>'.notdef',140=>'.notdef',141=>'.notdef',142=>'.notdef',143=>'.notdef',
+144=>'.notdef',145=>'.notdef',146=>'.notdef',147=>'.notdef',148=>'.notdef',149=>'.notdef',150=>'.notdef',151=>'.notdef',
+152=>'.notdef',153=>'.notdef',154=>'.notdef',155=>'.notdef',156=>'.notdef',157=>'.notdef',158=>'.notdef',159=>'.notdef',
+160=>'space',161=>'afii10023',162=>'afii10051',163=>'afii10052',164=>'afii10053',165=>'afii10054',166=>'afii10055',167=>'afii10056',
+168=>'afii10057',169=>'afii10058',170=>'afii10059',171=>'afii10060',172=>'afii10061',173=>'hyphen',174=>'afii10062',175=>'afii10145',
+176=>'afii10017',177=>'afii10018',178=>'afii10019',179=>'afii10020',180=>'afii10021',181=>'afii10022',182=>'afii10024',183=>'afii10025',
+184=>'afii10026',185=>'afii10027',186=>'afii10028',187=>'afii10029',188=>'afii10030',189=>'afii10031',190=>'afii10032',191=>'afii10033',
+192=>'afii10034',193=>'afii10035',194=>'afii10036',195=>'afii10037',196=>'afii10038',197=>'afii10039',198=>'afii10040',199=>'afii10041',
+200=>'afii10042',201=>'afii10043',202=>'afii10044',203=>'afii10045',204=>'afii10046',205=>'afii10047',206=>'afii10048',207=>'afii10049',
+208=>'afii10065',209=>'afii10066',210=>'afii10067',211=>'afii10068',212=>'afii10069',213=>'afii10070',214=>'afii10072',215=>'afii10073',
+216=>'afii10074',217=>'afii10075',218=>'afii10076',219=>'afii10077',220=>'afii10078',221=>'afii10079',222=>'afii10080',223=>'afii10081',
+224=>'afii10082',225=>'afii10083',226=>'afii10084',227=>'afii10085',228=>'afii10086',229=>'afii10087',230=>'afii10088',231=>'afii10089',
+232=>'afii10090',233=>'afii10091',234=>'afii10092',235=>'afii10093',236=>'afii10094',237=>'afii10095',238=>'afii10096',239=>'afii10097',
+240=>'afii61352',241=>'afii10071',242=>'afii10099',243=>'afii10100',244=>'afii10101',245=>'afii10102',246=>'afii10103',247=>'afii10104',
+248=>'afii10105',249=>'afii10106',250=>'afii10107',251=>'afii10108',252=>'afii10109',253=>'section',254=>'afii10110',255=>'afii10193'),
+
+// encoding map for: koi8-r
+'koi8-r' => array(0=>'.notdef',1=>'.notdef',2=>'.notdef',3=>'.notdef',4=>'.notdef',5=>'.notdef',6=>'.notdef',7=>'.notdef',
+8=>'.notdef',9=>'.notdef',10=>'.notdef',11=>'.notdef',12=>'.notdef',13=>'.notdef',14=>'.notdef',15=>'.notdef',
+16=>'.notdef',17=>'.notdef',18=>'.notdef',19=>'.notdef',20=>'.notdef',21=>'.notdef',22=>'.notdef',23=>'.notdef',
+24=>'.notdef',25=>'.notdef',26=>'.notdef',27=>'.notdef',28=>'.notdef',29=>'.notdef',30=>'.notdef',31=>'.notdef',
+32=>'space',33=>'exclam',34=>'quotedbl',35=>'numbersign',36=>'dollar',37=>'percent',38=>'ampersand',39=>'quotesingle',
+40=>'parenleft',41=>'parenright',42=>'asterisk',43=>'plus',44=>'comma',45=>'hyphen',46=>'period',47=>'slash',
+48=>'zero',49=>'one',50=>'two',51=>'three',52=>'four',53=>'five',54=>'six',55=>'seven',
+56=>'eight',57=>'nine',58=>'colon',59=>'semicolon',60=>'less',61=>'equal',62=>'greater',63=>'question',
+64=>'at',65=>'A',66=>'B',67=>'C',68=>'D',69=>'E',70=>'F',71=>'G',
+72=>'H',73=>'I',74=>'J',75=>'K',76=>'L',77=>'M',78=>'N',79=>'O',
+80=>'P',81=>'Q',82=>'R',83=>'S',84=>'T',85=>'U',86=>'V',87=>'W',
+88=>'X',89=>'Y',90=>'Z',91=>'bracketleft',92=>'backslash',93=>'bracketright',94=>'asciicircum',95=>'underscore',
+96=>'grave',97=>'a',98=>'b',99=>'c',100=>'d',101=>'e',102=>'f',103=>'g',
+104=>'h',105=>'i',106=>'j',107=>'k',108=>'l',109=>'m',110=>'n',111=>'o',
+112=>'p',113=>'q',114=>'r',115=>'s',116=>'t',117=>'u',118=>'v',119=>'w',
+120=>'x',121=>'y',122=>'z',123=>'braceleft',124=>'bar',125=>'braceright',126=>'asciitilde',127=>'.notdef',
+128=>'SF100000',129=>'SF110000',130=>'SF010000',131=>'SF030000',132=>'SF020000',133=>'SF040000',134=>'SF080000',135=>'SF090000',
+136=>'SF060000',137=>'SF070000',138=>'SF050000',139=>'upblock',140=>'dnblock',141=>'block',142=>'lfblock',143=>'rtblock',
+144=>'ltshade',145=>'shade',146=>'dkshade',147=>'integraltp',148=>'filledbox',149=>'periodcentered',150=>'radical',151=>'approxequal',
+152=>'lessequal',153=>'greaterequal',154=>'space',155=>'integralbt',156=>'degree',157=>'twosuperior',158=>'periodcentered',159=>'divide',
+160=>'SF430000',161=>'SF240000',162=>'SF510000',163=>'afii10071',164=>'SF520000',165=>'SF390000',166=>'SF220000',167=>'SF210000',
+168=>'SF250000',169=>'SF500000',170=>'SF490000',171=>'SF380000',172=>'SF280000',173=>'SF270000',174=>'SF260000',175=>'SF360000',
+176=>'SF370000',177=>'SF420000',178=>'SF190000',179=>'afii10023',180=>'SF200000',181=>'SF230000',182=>'SF470000',183=>'SF480000',
+184=>'SF410000',185=>'SF450000',186=>'SF460000',187=>'SF400000',188=>'SF540000',189=>'SF530000',190=>'SF440000',191=>'copyright',
+192=>'afii10096',193=>'afii10065',194=>'afii10066',195=>'afii10088',196=>'afii10069',197=>'afii10070',198=>'afii10086',199=>'afii10068',
+200=>'afii10087',201=>'afii10074',202=>'afii10075',203=>'afii10076',204=>'afii10077',205=>'afii10078',206=>'afii10079',207=>'afii10080',
+208=>'afii10081',209=>'afii10097',210=>'afii10082',211=>'afii10083',212=>'afii10084',213=>'afii10085',214=>'afii10072',215=>'afii10067',
+216=>'afii10094',217=>'afii10093',218=>'afii10073',219=>'afii10090',220=>'afii10095',221=>'afii10091',222=>'afii10089',223=>'afii10092',
+224=>'afii10048',225=>'afii10017',226=>'afii10018',227=>'afii10040',228=>'afii10021',229=>'afii10022',230=>'afii10038',231=>'afii10020',
+232=>'afii10039',233=>'afii10026',234=>'afii10027',235=>'afii10028',236=>'afii10029',237=>'afii10030',238=>'afii10031',239=>'afii10032',
+240=>'afii10033',241=>'afii10049',242=>'afii10034',243=>'afii10035',244=>'afii10036',245=>'afii10037',246=>'afii10024',247=>'afii10019',
+248=>'afii10046',249=>'afii10045',250=>'afii10025',251=>'afii10042',252=>'afii10047',253=>'afii10043',254=>'afii10041',255=>'afii10044'),
+
+// encoding map for: koi8-r
+'koi8-r' => array(0=>'.notdef',1=>'.notdef',2=>'.notdef',3=>'.notdef',4=>'.notdef',5=>'.notdef',6=>'.notdef',7=>'.notdef',
+8=>'.notdef',9=>'.notdef',10=>'.notdef',11=>'.notdef',12=>'.notdef',13=>'.notdef',14=>'.notdef',15=>'.notdef',
+16=>'.notdef',17=>'.notdef',18=>'.notdef',19=>'.notdef',20=>'.notdef',21=>'.notdef',22=>'.notdef',23=>'.notdef',
+24=>'.notdef',25=>'.notdef',26=>'.notdef',27=>'.notdef',28=>'.notdef',29=>'.notdef',30=>'.notdef',31=>'.notdef',
+32=>'space',33=>'exclam',34=>'quotedbl',35=>'numbersign',36=>'dollar',37=>'percent',38=>'ampersand',39=>'quotesingle',
+40=>'parenleft',41=>'parenright',42=>'asterisk',43=>'plus',44=>'comma',45=>'hyphen',46=>'period',47=>'slash',
+48=>'zero',49=>'one',50=>'two',51=>'three',52=>'four',53=>'five',54=>'six',55=>'seven',
+56=>'eight',57=>'nine',58=>'colon',59=>'semicolon',60=>'less',61=>'equal',62=>'greater',63=>'question',
+64=>'at',65=>'A',66=>'B',67=>'C',68=>'D',69=>'E',70=>'F',71=>'G',
+72=>'H',73=>'I',74=>'J',75=>'K',76=>'L',77=>'M',78=>'N',79=>'O',
+80=>'P',81=>'Q',82=>'R',83=>'S',84=>'T',85=>'U',86=>'V',87=>'W',
+88=>'X',89=>'Y',90=>'Z',91=>'bracketleft',92=>'backslash',93=>'bracketright',94=>'asciicircum',95=>'underscore',
+96=>'grave',97=>'a',98=>'b',99=>'c',100=>'d',101=>'e',102=>'f',103=>'g',
+104=>'h',105=>'i',106=>'j',107=>'k',108=>'l',109=>'m',110=>'n',111=>'o',
+112=>'p',113=>'q',114=>'r',115=>'s',116=>'t',117=>'u',118=>'v',119=>'w',
+120=>'x',121=>'y',122=>'z',123=>'braceleft',124=>'bar',125=>'braceright',126=>'asciitilde',127=>'.notdef',
+128=>'SF100000',129=>'SF110000',130=>'SF010000',131=>'SF030000',132=>'SF020000',133=>'SF040000',134=>'SF080000',135=>'SF090000',
+136=>'SF060000',137=>'SF070000',138=>'SF050000',139=>'upblock',140=>'dnblock',141=>'block',142=>'lfblock',143=>'rtblock',
+144=>'ltshade',145=>'shade',146=>'dkshade',147=>'integraltp',148=>'filledbox',149=>'periodcentered',150=>'radical',151=>'approxequal',
+152=>'lessequal',153=>'greaterequal',154=>'space',155=>'integralbt',156=>'degree',157=>'twosuperior',158=>'periodcentered',159=>'divide',
+160=>'SF430000',161=>'SF240000',162=>'SF510000',163=>'afii10071',164=>'SF520000',165=>'SF390000',166=>'SF220000',167=>'SF210000',
+168=>'SF250000',169=>'SF500000',170=>'SF490000',171=>'SF380000',172=>'SF280000',173=>'SF270000',174=>'SF260000',175=>'SF360000',
+176=>'SF370000',177=>'SF420000',178=>'SF190000',179=>'afii10023',180=>'SF200000',181=>'SF230000',182=>'SF470000',183=>'SF480000',
+184=>'SF410000',185=>'SF450000',186=>'SF460000',187=>'SF400000',188=>'SF540000',189=>'SF530000',190=>'SF440000',191=>'copyright',
+192=>'afii10096',193=>'afii10065',194=>'afii10066',195=>'afii10088',196=>'afii10069',197=>'afii10070',198=>'afii10086',199=>'afii10068',
+200=>'afii10087',201=>'afii10074',202=>'afii10075',203=>'afii10076',204=>'afii10077',205=>'afii10078',206=>'afii10079',207=>'afii10080',
+208=>'afii10081',209=>'afii10097',210=>'afii10082',211=>'afii10083',212=>'afii10084',213=>'afii10085',214=>'afii10072',215=>'afii10067',
+216=>'afii10094',217=>'afii10093',218=>'afii10073',219=>'afii10090',220=>'afii10095',221=>'afii10091',222=>'afii10089',223=>'afii10092',
+224=>'afii10048',225=>'afii10017',226=>'afii10018',227=>'afii10040',228=>'afii10021',229=>'afii10022',230=>'afii10038',231=>'afii10020',
+232=>'afii10039',233=>'afii10026',234=>'afii10027',235=>'afii10028',236=>'afii10029',237=>'afii10030',238=>'afii10031',239=>'afii10032',
+240=>'afii10033',241=>'afii10049',242=>'afii10034',243=>'afii10035',244=>'afii10036',245=>'afii10037',246=>'afii10024',247=>'afii10019',
+248=>'afii10046',249=>'afii10045',250=>'afii10025',251=>'afii10042',252=>'afii10047',253=>'afii10043',254=>'afii10041',255=>'afii10044'),
+
+// encoding map for: iso-8859-16
+'iso-8859-16' => array(0=>'.notdef',1=>'.notdef',2=>'.notdef',3=>'.notdef',4=>'.notdef',5=>'.notdef',6=>'.notdef',7=>'.notdef',
+8=>'.notdef',9=>'.notdef',10=>'.notdef',11=>'.notdef',12=>'.notdef',13=>'.notdef',14=>'.notdef',15=>'.notdef',
+16=>'.notdef',17=>'.notdef',18=>'.notdef',19=>'.notdef',20=>'.notdef',21=>'.notdef',22=>'.notdef',23=>'.notdef',
+24=>'.notdef',25=>'.notdef',26=>'.notdef',27=>'.notdef',28=>'.notdef',29=>'.notdef',30=>'.notdef',31=>'.notdef',
+32=>'space',33=>'exclam',34=>'quotedbl',35=>'numbersign',36=>'dollar',37=>'percent',38=>'ampersand',39=>'quotesingle',
+40=>'parenleft',41=>'parenright',42=>'asterisk',43=>'plus',44=>'comma',45=>'hyphen',46=>'period',47=>'slash',
+48=>'zero',49=>'one',50=>'two',51=>'three',52=>'four',53=>'five',54=>'six',55=>'seven',
+56=>'eight',57=>'nine',58=>'colon',59=>'semicolon',60=>'less',61=>'equal',62=>'greater',63=>'question',
+64=>'at',65=>'A',66=>'B',67=>'C',68=>'D',69=>'E',70=>'F',71=>'G',
+72=>'H',73=>'I',74=>'J',75=>'K',76=>'L',77=>'M',78=>'N',79=>'O',
+80=>'P',81=>'Q',82=>'R',83=>'S',84=>'T',85=>'U',86=>'V',87=>'W',
+88=>'X',89=>'Y',90=>'Z',91=>'bracketleft',92=>'backslash',93=>'bracketright',94=>'asciicircum',95=>'underscore',
+96=>'grave',97=>'a',98=>'b',99=>'c',100=>'d',101=>'e',102=>'f',103=>'g',
+104=>'h',105=>'i',106=>'j',107=>'k',108=>'l',109=>'m',110=>'n',111=>'o',
+112=>'p',113=>'q',114=>'r',115=>'s',116=>'t',117=>'u',118=>'v',119=>'w',
+120=>'x',121=>'y',122=>'z',123=>'braceleft',124=>'bar',125=>'braceright',126=>'asciitilde',127=>'.notdef',
+128=>'.notdef',129=>'.notdef',130=>'.notdef',131=>'.notdef',132=>'.notdef',133=>'.notdef',134=>'.notdef',135=>'.notdef',
+136=>'.notdef',137=>'.notdef',138=>'.notdef',139=>'.notdef',140=>'.notdef',141=>'.notdef',142=>'.notdef',143=>'.notdef',
+144=>'.notdef',145=>'.notdef',146=>'.notdef',147=>'.notdef',148=>'.notdef',149=>'.notdef',150=>'.notdef',151=>'.notdef',
+152=>'.notdef',153=>'.notdef',154=>'.notdef',155=>'.notdef',156=>'.notdef',157=>'.notdef',158=>'.notdef',159=>'.notdef',
+160=>'space',161=>'Aogonek',162=>'aogonek',163=>'Lslash',164=>'Euro',165=>'quotedblbase',166=>'Scaron',167=>'section',
+168=>'scaron',169=>'copyright',170=>'Scommaaccent',171=>'guillemotleft',172=>'Zacute',173=>'hyphen',174=>'zacute',175=>'Zdotaccent',
+176=>'degree',177=>'plusminus',178=>'Ccaron',179=>'lslash',180=>'Zcaron',181=>'quotedblright',182=>'paragraph',183=>'periodcentered',
+184=>'zcaron',185=>'ccaron',186=>'scommaaccent',187=>'guillemotright',188=>'OE',189=>'oe',190=>'Ydieresis',191=>'zdotaccent',
+192=>'Agrave',193=>'Aacute',194=>'Acircumflex',195=>'Abreve',196=>'Adieresis',197=>'Cacute',198=>'AE',199=>'Ccedilla',
+200=>'Egrave',201=>'Eacute',202=>'Ecircumflex',203=>'Edieresis',204=>'Igrave',205=>'Iacute',206=>'Icircumflex',207=>'Idieresis',
+208=>'Dcroat',209=>'Nacute',210=>'Ograve',211=>'Oacute',212=>'Ocircumflex',213=>'Ohungarumlaut',214=>'Odieresis',215=>'Sacute',
+216=>'Uhungarumlaut',217=>'Ugrave',218=>'Uacute',219=>'Ucircumflex',220=>'Udieresis',221=>'Eogonek',222=>'Tcommaaccent',223=>'germandbls',
+224=>'agrave',225=>'aacute',226=>'acircumflex',227=>'abreve',228=>'adieresis',229=>'cacute',230=>'ae',231=>'ccedilla',
+232=>'egrave',233=>'eacute',234=>'ecircumflex',235=>'edieresis',236=>'igrave',237=>'iacute',238=>'icircumflex',239=>'idieresis',
+240=>'dcroat',241=>'nacute',242=>'ograve',243=>'oacute',244=>'ocircumflex',245=>'ohungarumlaut',246=>'odieresis',247=>'sacute',
+248=>'uhungarumlaut',249=>'ugrave',250=>'uacute',251=>'ucircumflex',252=>'udieresis',253=>'eogonek',254=>'tcommaaccent',255=>'ydieresis'),
+
+// encoding map for: koi8-u
+'koi8-u' => array(0=>'.notdef',1=>'.notdef',2=>'.notdef',3=>'.notdef',4=>'.notdef',5=>'.notdef',6=>'.notdef',7=>'.notdef',
+8=>'.notdef',9=>'.notdef',10=>'.notdef',11=>'.notdef',12=>'.notdef',13=>'.notdef',14=>'.notdef',15=>'.notdef',
+16=>'.notdef',17=>'.notdef',18=>'.notdef',19=>'.notdef',20=>'.notdef',21=>'.notdef',22=>'.notdef',23=>'.notdef',
+24=>'.notdef',25=>'.notdef',26=>'.notdef',27=>'.notdef',28=>'.notdef',29=>'.notdef',30=>'.notdef',31=>'.notdef',
+32=>'space',33=>'exclam',34=>'quotedbl',35=>'numbersign',36=>'dollar',37=>'percent',38=>'ampersand',39=>'quotesingle',
+40=>'parenleft',41=>'parenright',42=>'asterisk',43=>'plus',44=>'comma',45=>'hyphen',46=>'period',47=>'slash',
+48=>'zero',49=>'one',50=>'two',51=>'three',52=>'four',53=>'five',54=>'six',55=>'seven',
+56=>'eight',57=>'nine',58=>'colon',59=>'semicolon',60=>'less',61=>'equal',62=>'greater',63=>'question',
+64=>'at',65=>'A',66=>'B',67=>'C',68=>'D',69=>'E',70=>'F',71=>'G',
+72=>'H',73=>'I',74=>'J',75=>'K',76=>'L',77=>'M',78=>'N',79=>'O',
+80=>'P',81=>'Q',82=>'R',83=>'S',84=>'T',85=>'U',86=>'V',87=>'W',
+88=>'X',89=>'Y',90=>'Z',91=>'bracketleft',92=>'backslash',93=>'bracketright',94=>'asciicircum',95=>'underscore',
+96=>'grave',97=>'a',98=>'b',99=>'c',100=>'d',101=>'e',102=>'f',103=>'g',
+104=>'h',105=>'i',106=>'j',107=>'k',108=>'l',109=>'m',110=>'n',111=>'o',
+112=>'p',113=>'q',114=>'r',115=>'s',116=>'t',117=>'u',118=>'v',119=>'w',
+120=>'x',121=>'y',122=>'z',123=>'braceleft',124=>'bar',125=>'braceright',126=>'asciitilde',127=>'.notdef',
+128=>'SF100000',129=>'SF110000',130=>'SF010000',131=>'SF030000',132=>'SF020000',133=>'SF040000',134=>'SF080000',135=>'SF090000',
+136=>'SF060000',137=>'SF070000',138=>'SF050000',139=>'upblock',140=>'dnblock',141=>'block',142=>'lfblock',143=>'rtblock',
+144=>'ltshade',145=>'shade',146=>'dkshade',147=>'integraltp',148=>'filledbox',149=>'bullet',150=>'radical',151=>'approxequal',
+152=>'lessequal',153=>'greaterequal',154=>'space',155=>'integralbt',156=>'degree',157=>'twosuperior',158=>'periodcentered',159=>'divide',
+160=>'SF430000',161=>'SF240000',162=>'SF510000',163=>'afii10071',164=>'afii10101',165=>'SF390000',166=>'afii10103',167=>'afii10104',
+168=>'SF250000',169=>'SF500000',170=>'SF490000',171=>'SF380000',172=>'SF280000',173=>'afii10098',174=>'SF260000',175=>'SF360000',
+176=>'SF370000',177=>'SF420000',178=>'SF190000',179=>'afii10023',180=>'afii10053',181=>'SF230000',182=>'afii10055',183=>'afii10056',
+184=>'SF410000',185=>'SF450000',186=>'SF460000',187=>'SF400000',188=>'SF540000',189=>'afii10050',190=>'SF440000',191=>'copyright',
+192=>'afii10096',193=>'afii10065',194=>'afii10066',195=>'afii10088',196=>'afii10069',197=>'afii10070',198=>'afii10086',199=>'afii10068',
+200=>'afii10087',201=>'afii10074',202=>'afii10075',203=>'afii10076',204=>'afii10077',205=>'afii10078',206=>'afii10079',207=>'afii10080',
+208=>'afii10081',209=>'afii10097',210=>'afii10082',211=>'afii10083',212=>'afii10084',213=>'afii10085',214=>'afii10072',215=>'afii10067',
+216=>'afii10094',217=>'afii10093',218=>'afii10073',219=>'afii10090',220=>'afii10095',221=>'afii10091',222=>'afii10089',223=>'afii10092',
+224=>'afii10048',225=>'afii10017',226=>'afii10018',227=>'afii10040',228=>'afii10021',229=>'afii10022',230=>'afii10038',231=>'afii10020',
+232=>'afii10039',233=>'afii10026',234=>'afii10027',235=>'afii10028',236=>'afii10029',237=>'afii10030',238=>'afii10031',239=>'afii10032',
+240=>'afii10033',241=>'afii10049',242=>'afii10034',243=>'afii10035',244=>'afii10036',245=>'afii10037',246=>'afii10024',247=>'afii10019',
+248=>'afii10046',249=>'afii10045',250=>'afii10025',251=>'afii10042',252=>'afii10047',253=>'afii10043',254=>'afii10041',255=>'afii10044'),
+
+// encoding map for: symbol
+'symbol' => array(0=>'.notdef',1=>'.notdef',2=>'.notdef',3=>'.notdef',4=>'.notdef',5=>'.notdef',6=>'.notdef',7=>'.notdef',
+8=>'.notdef',9=>'.notdef',10=>'.notdef',11=>'.notdef',12=>'.notdef',13=>'.notdef',14=>'.notdef',15=>'.notdef',
+16=>'.notdef',17=>'.notdef',18=>'.notdef',19=>'.notdef',20=>'.notdef',21=>'.notdef',22=>'.notdef',23=>'.notdef',
+24=>'.notdef',25=>'.notdef',26=>'.notdef',27=>'.notdef',28=>'.notdef',29=>'.notdef',30=>'.notdef',31=>'.notdef',
+32=>'space',33=>'exclam',34=>'universal',35=>'numbersign',36=>'existential',37=>'percent',38=>'ampersand',39=>'suchthat',
+40=>'parenleft',41=>'parenright',42=>'asteriskmath',43=>'plus',44=>'comma',45=>'minus',46=>'period',47=>'slash',
+48=>'zero',49=>'one',50=>'two',51=>'three',52=>'four',53=>'five',54=>'six',55=>'seven',
+56=>'eight',57=>'nine',58=>'colon',59=>'semicolon',60=>'less',61=>'equal',62=>'greater',63=>'question',
+64=>'congruent',65=>'Alpha',66=>'Beta',67=>'Chi',68=>'Delta',69=>'Epsilon',70=>'Phi',71=>'Gamma',
+72=>'Eta',73=>'Iota',74=>'theta1',75=>'Kappa',76=>'Lambda',77=>'Mu',78=>'Nu',79=>'Omicron',
+80=>'Pi',81=>'Theta',82=>'Rho',83=>'Sigma',84=>'Tau',85=>'Upsilon',86=>'sigma1',87=>'Omega',
+88=>'Xi',89=>'Psi',90=>'Zeta',91=>'bracketleft',92=>'therefore',93=>'bracketright',94=>'perpendicular',95=>'underscore',
+96=>'radicalex',97=>'alpha',98=>'beta',99=>'chi',100=>'delta',101=>'epsilon',102=>'phi',103=>'gamma',
+104=>'eta',105=>'iota',106=>'phi1',107=>'kappa',108=>'lambda',109=>'mu',110=>'nu',111=>'omicron',
+112=>'pi',113=>'theta',114=>'rho',115=>'sigma',116=>'tau',117=>'upsilon',118=>'omega1',119=>'omega',
+120=>'xi',121=>'psi',122=>'zeta',123=>'braceleft',124=>'bar',125=>'braceright',126=>'similar',127=>'.notdef',
+128=>'.notdef',129=>'.notdef',130=>'.notdef',131=>'.notdef',132=>'.notdef',133=>'.notdef',134=>'.notdef',135=>'.notdef',
+136=>'.notdef',137=>'.notdef',138=>'.notdef',139=>'.notdef',140=>'.notdef',141=>'.notdef',142=>'.notdef',143=>'.notdef',
+144=>'.notdef',145=>'.notdef',146=>'.notdef',147=>'.notdef',148=>'.notdef',149=>'.notdef',150=>'.notdef',151=>'.notdef',
+152=>'.notdef',153=>'.notdef',154=>'.notdef',155=>'.notdef',156=>'.notdef',157=>'.notdef',158=>'.notdef',159=>'.notdef',
+160=>'Euro',161=>'Upsilon1',162=>'minute',163=>'lessequal',164=>'fraction',165=>'infinity',166=>'florin',167=>'club',
+168=>'diamond',169=>'heart',170=>'spade',171=>'arrowboth',172=>'arrowleft',173=>'arrowup',174=>'arrowright',175=>'arrowdown',
+176=>'degree',177=>'plusminus',178=>'second',179=>'greaterequal',180=>'multiply',181=>'proportional',182=>'partialdiff',183=>'bullet',
+184=>'divide',185=>'notequal',186=>'equivalence',187=>'approxequal',188=>'ellipsis',189=>'arrowvertex',190=>'arrowhorizex',191=>'carriagereturn',
+192=>'aleph',193=>'Ifraktur',194=>'Rfraktur',195=>'weierstrass',196=>'circlemultiply',197=>'circleplus',198=>'emptyset',199=>'intersection',
+200=>'union',201=>'propersuperset',202=>'reflexsuperset',203=>'notsubset',204=>'propersubset',205=>'reflexsubset',206=>'element',207=>'notelement',
+208=>'angle',209=>'gradient',210=>'registerserif',211=>'copyrightserif',212=>'trademarkserif',213=>'product',214=>'radical',215=>'dotmath',
+216=>'logicalnot',217=>'logicaland',218=>'logicalor',219=>'arrowdblboth',220=>'arrowdblleft',221=>'arrowdblup',222=>'arrowdblright',223=>'arrowdbldown',
+224=>'lozenge',225=>'angleleft',226=>'registersans',227=>'copyrightsans',228=>'trademarksans',229=>'summation',230=>'parenlefttp',231=>'parenleftex',
+232=>'parenleftbt',233=>'bracketlefttp',234=>'bracketleftex',235=>'bracketleftbt',236=>'bracelefttp',237=>'braceleftmid',238=>'braceleftbt',239=>'braceex',
+240=>'.notdef',241=>'angleright',242=>'integral',243=>'integraltp',244=>'integralex',245=>'integralbt',246=>'parenrighttp',247=>'parenrightex',
+248=>'parenrightbt',249=>'bracketrighttp',250=>'bracketrightex',251=>'bracketrightbt',252=>'bracerighttp',253=>'bracerightmid',254=>'bracerightbt',255=>'.notdef',
+1226=>'registered',1227=>'copyright',1228=>'trademark')
+
+); // end of encoding maps
+
+} // --- END OF CLASS ---
+
+//============================================================+
+// END OF FILE
+//============================================================+
diff --git a/phpmyadmin/libraries/tcpdf/fonts/dejavu-fonts-ttf-2.33/LICENSE b/phpmyadmin/libraries/tcpdf/fonts/dejavu-fonts-ttf-2.33/LICENSE
new file mode 100644
index 0000000..254e2cc
--- /dev/null
+++ b/phpmyadmin/libraries/tcpdf/fonts/dejavu-fonts-ttf-2.33/LICENSE
@@ -0,0 +1,99 @@
+Fonts are (c) Bitstream (see below). DejaVu changes are in public domain.
+Glyphs imported from Arev fonts are (c) Tavmjong Bah (see below)
+
+Bitstream Vera Fonts Copyright
+------------------------------
+
+Copyright (c) 2003 by Bitstream, Inc. All Rights Reserved. Bitstream Vera is
+a trademark of Bitstream, Inc.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of the fonts accompanying this license ("Fonts") and associated
+documentation files (the "Font Software"), to reproduce and distribute the
+Font Software, including without limitation the rights to use, copy, merge,
+publish, distribute, and/or sell copies of the Font Software, and to permit
+persons to whom the Font Software is furnished to do so, subject to the
+following conditions:
+
+The above copyright and trademark notices and this permission notice shall
+be included in all copies of one or more of the Font Software typefaces.
+
+The Font Software may be modified, altered, or added to, and in particular
+the designs of glyphs or characters in the Fonts may be modified and
+additional glyphs or characters may be added to the Fonts, only if the fonts
+are renamed to names not containing either the words "Bitstream" or the word
+"Vera".
+
+This License becomes null and void to the extent applicable to Fonts or Font
+Software that has been modified and is distributed under the "Bitstream
+Vera" names.
+
+The Font Software may be sold as part of a larger software package but no
+copy of one or more of the Font Software typefaces may be sold by itself.
+
+THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF COPYRIGHT, PATENT,
+TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL BITSTREAM OR THE GNOME
+FOUNDATION BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, INCLUDING
+ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL DAMAGES,
+WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
+THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM OTHER DEALINGS IN THE
+FONT SOFTWARE.
+
+Except as contained in this notice, the names of Gnome, the Gnome
+Foundation, and Bitstream Inc., shall not be used in advertising or
+otherwise to promote the sale, use or other dealings in this Font Software
+without prior written authorization from the Gnome Foundation or Bitstream
+Inc., respectively. For further information, contact: fonts at gnome dot
+org. 
+
+Arev Fonts Copyright
+------------------------------
+
+Copyright (c) 2006 by Tavmjong Bah. All Rights Reserved.
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of the fonts accompanying this license ("Fonts") and
+associated documentation files (the "Font Software"), to reproduce
+and distribute the modifications to the Bitstream Vera Font Software,
+including without limitation the rights to use, copy, merge, publish,
+distribute, and/or sell copies of the Font Software, and to permit
+persons to whom the Font Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright and trademark notices and this permission notice
+shall be included in all copies of one or more of the Font Software
+typefaces.
+
+The Font Software may be modified, altered, or added to, and in
+particular the designs of glyphs or characters in the Fonts may be
+modified and additional glyphs or characters may be added to the
+Fonts, only if the fonts are renamed to names not containing either
+the words "Tavmjong Bah" or the word "Arev".
+
+This License becomes null and void to the extent applicable to Fonts
+or Font Software that has been modified and is distributed under the 
+"Tavmjong Bah Arev" names.
+
+The Font Software may be sold as part of a larger software package but
+no copy of one or more of the Font Software typefaces may be sold by
+itself.
+
+THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
+OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL
+TAVMJONG BAH BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
+DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
+OTHER DEALINGS IN THE FONT SOFTWARE.
+
+Except as contained in this notice, the name of Tavmjong Bah shall not
+be used in advertising or otherwise to promote the sale, use or other
+dealings in this Font Software without prior written authorization
+from Tavmjong Bah. For further information, contact: tavmjong @ free
+. fr.
+
+$Id: LICENSE 2133 2007-11-28 02:46:28Z lechimp $
diff --git a/phpmyadmin/libraries/tcpdf/fonts/dejavusans.ctg.z b/phpmyadmin/libraries/tcpdf/fonts/dejavusans.ctg.z
new file mode 100644
index 0000000..cceabb6
Binary files /dev/null and b/phpmyadmin/libraries/tcpdf/fonts/dejavusans.ctg.z differ
diff --git a/phpmyadmin/libraries/tcpdf/fonts/dejavusans.php b/phpmyadmin/libraries/tcpdf/fonts/dejavusans.php
new file mode 100644
index 0000000..3cd0813
--- /dev/null
+++ b/phpmyadmin/libraries/tcpdf/fonts/dejavusans.php
@@ -0,0 +1,15 @@
+<?php
+// TCPDF FONT FILE DESCRIPTION
+$type='TrueTypeUnicode';
+$name='DejaVuSans';
+$up=-63;
+$ut=44;
+$dw=600;
+$diff='';
+$originalsize=720012;
+$enc='';
+$file='dejavusans.z';
+$ctg='dejavusans.ctg.z';
+$desc=array('Flags'=>32,'FontBBox'=>'[-1021 -415 1681 1167]','ItalicAngle'=>0,'Ascent'=>928,'Descent'=>-236,'Leading'=>0,'CapHeight'=>729,'XHeight'=>547,'StemV'=>34,'StemH'=>15,'AvgWidth'=>507,'MaxWidth'=>1735,'MissingWidth'=>600);
+$cw=array(0=>600,32=>318,33=>401,34=>460,35=>838,36=>636,37=>950,38=>780,39=>275,40=>390,41=>390,42=>500,43=>838,44=>318,45=>361,46=>318,47=>337,48=>636,49=>636,50=>636,51=>636,52=>636,53=>636,54=>636,55=>636,56=>636,57=>636,58=>337,59=>337,60=>838,61=>838,62=>838,63=>531,64=>1000,65=>684,66=>686,67=>698,68=>770,69=>632,70=>575,71=>775,72=>752,73=>295,74=>295,75=>656,76=>557,77=>863,78=>748,79=>787,80=>603,81=>787,82=>695,83=>635,84=>611,85=>732,86=>684,87=>989,88=>685,89=>611,90=>685,91 [...]
+// --- EOF ---
diff --git a/phpmyadmin/libraries/tcpdf/fonts/dejavusans.z b/phpmyadmin/libraries/tcpdf/fonts/dejavusans.z
new file mode 100644
index 0000000..114ed7d
Binary files /dev/null and b/phpmyadmin/libraries/tcpdf/fonts/dejavusans.z differ
diff --git a/phpmyadmin/libraries/tcpdf/fonts/dejavusansb.ctg.z b/phpmyadmin/libraries/tcpdf/fonts/dejavusansb.ctg.z
new file mode 100644
index 0000000..0d17132
Binary files /dev/null and b/phpmyadmin/libraries/tcpdf/fonts/dejavusansb.ctg.z differ
diff --git a/phpmyadmin/libraries/tcpdf/fonts/dejavusansb.php b/phpmyadmin/libraries/tcpdf/fonts/dejavusansb.php
new file mode 100644
index 0000000..ee8a5b6
--- /dev/null
+++ b/phpmyadmin/libraries/tcpdf/fonts/dejavusansb.php
@@ -0,0 +1,15 @@
+<?php
+// TCPDF FONT FILE DESCRIPTION
+$type='TrueTypeUnicode';
+$name='DejaVuSans-Bold';
+$up=-63;
+$ut=44;
+$dw=600;
+$diff='';
+$originalsize=672300;
+$enc='';
+$file='dejavusansb.z';
+$ctg='dejavusansb.ctg.z';
+$desc=array('Flags'=>32,'FontBBox'=>'[-1069 -415 1975 1174]','ItalicAngle'=>0,'Ascent'=>928,'Descent'=>-236,'Leading'=>0,'CapHeight'=>729,'XHeight'=>547,'StemV'=>60,'StemH'=>26,'AvgWidth'=>573,'MaxWidth'=>2016,'MissingWidth'=>600);
+$cw=array(0=>600,32=>348,33=>456,34=>521,35=>838,36=>696,37=>1002,38=>872,39=>306,40=>457,41=>457,42=>523,43=>838,44=>380,45=>415,46=>380,47=>365,48=>696,49=>696,50=>696,51=>696,52=>696,53=>696,54=>696,55=>696,56=>696,57=>696,58=>400,59=>400,60=>838,61=>838,62=>838,63=>580,64=>1000,65=>774,66=>762,67=>734,68=>830,69=>683,70=>683,71=>821,72=>837,73=>372,74=>372,75=>775,76=>637,77=>995,78=>837,79=>850,80=>733,81=>850,82=>770,83=>720,84=>682,85=>812,86=>774,87=>1103,88=>771,89=>724,90=>725, [...]
+// --- EOF ---
diff --git a/phpmyadmin/libraries/tcpdf/fonts/dejavusansb.z b/phpmyadmin/libraries/tcpdf/fonts/dejavusansb.z
new file mode 100644
index 0000000..ec19021
Binary files /dev/null and b/phpmyadmin/libraries/tcpdf/fonts/dejavusansb.z differ
diff --git a/phpmyadmin/libraries/tcpdf/fonts/helvetica.php b/phpmyadmin/libraries/tcpdf/fonts/helvetica.php
new file mode 100644
index 0000000..d1aa6d8
--- /dev/null
+++ b/phpmyadmin/libraries/tcpdf/fonts/helvetica.php
@@ -0,0 +1,13 @@
+<?php
+// TCPDF FONT FILE DESCRIPTION
+$type='core';
+$name='Helvetica';
+$up=-100;
+$ut=50;
+$dw=513;
+$diff='';
+$enc='';
+$desc=array('Flags'=>32,'FontBBox'=>'[-166 -225 1000 931]','ItalicAngle'=>0,'Ascent'=>931,'Descent'=>-225,'Leading'=>0,'CapHeight'=>718,'XHeight'=>523,'StemV'=>88,'StemH'=>76,'AvgWidth'=>513,'MaxWidth'=>1015,'MissingWidth'=>513);
+$cw=array(0=>500,1=>500,2=>500,3=>500,4=>500,5=>500,6=>500,7=>500,8=>500,9=>500,10=>500,11=>500,12=>500,13=>500,14=>500,15=>500,16=>500,17=>500,18=>500,19=>500,20=>500,21=>500,22=>500,23=>500,24=>500,25=>500,26=>500,27=>500,28=>500,29=>500,30=>500,31=>500,32=>278,33=>278,34=>355,35=>556,36=>556,37=>889,38=>667,39=>191,40=>333,41=>333,42=>389,43=>584,44=>278,45=>333,46=>278,47=>278,48=>556,49=>556,50=>556,51=>556,52=>556,53=>556,54=>556,55=>556,56=>556,57=>556,58=>278,59=>278,60=>584,61=> [...]
+
+// --- EOF ---
diff --git a/phpmyadmin/libraries/tcpdf/htmlcolors.php b/phpmyadmin/libraries/tcpdf/htmlcolors.php
new file mode 100644
index 0000000..e1a58b5
--- /dev/null
+++ b/phpmyadmin/libraries/tcpdf/htmlcolors.php
@@ -0,0 +1,199 @@
+<?php
+//============================================================+
+// File name   : htmlcolors.php
+// Version     : 1.0.008
+// Begin       : 2002-04-09
+// Last Update : 2010-12-16
+// Author      : Nicola Asuni - Tecnick.com LTD - Manor Coach House, Church Hill, Aldershot, Hants, GU12 4RQ, UK - www.tecnick.com - info at tecnick.com
+// License     : GNU-LGPL v3 (http://www.gnu.org/copyleft/lesser.html)
+// -------------------------------------------------------------------
+// Copyright (C) 2002-2012  Nicola Asuni - Tecnick.com LTD
+//
+// This file is part of TCPDF software library.
+//
+// TCPDF is free software: you can redistribute it and/or modify it
+// under the terms of the GNU Lesser General Public License as
+// published by the Free Software Foundation, either version 3 of the
+// License, or (at your option) any later version.
+//
+// TCPDF is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+// See the GNU Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with TCPDF.  If not, see <http://www.gnu.org/licenses/>.
+//
+// See LICENSE.TXT file for more information.
+// -------------------------------------------------------------------
+//
+// Description : Array of WEB safe colors
+//
+//============================================================+
+
+/**
+ * @file
+ * Array of WEB safe colors
+ * @author Nicola Asuni
+ * @package com.tecnick.tcpdf
+ * @since 2.9.000 (2008-03-26)
+ */
+
+/**
+ * Array of WEB safe colors
+ */
+$webcolor = array (
+'aliceblue' => 'f0f8ff',
+'antiquewhite' => 'faebd7',
+'aqua' => '00ffff',
+'aquamarine' => '7fffd4',
+'azure' => 'f0ffff',
+'beige' => 'f5f5dc',
+'bisque' => 'ffe4c4',
+'black' => '000000',
+'blanchedalmond' => 'ffebcd',
+'blue' => '0000ff',
+'blueviolet' => '8a2be2',
+'brown' => 'a52a2a',
+'burlywood' => 'deb887',
+'cadetblue' => '5f9ea0',
+'chartreuse' => '7fff00',
+'chocolate' => 'd2691e',
+'coral' => 'ff7f50',
+'cornflowerblue' => '6495ed',
+'cornsilk' => 'fff8dc',
+'crimson' => 'dc143c',
+'cyan' => '00ffff',
+'darkblue' => '00008b',
+'darkcyan' => '008b8b',
+'darkgoldenrod' => 'b8860b',
+'dkgray' => 'a9a9a9',
+'darkgray' => 'a9a9a9',
+'darkgrey' => 'a9a9a9',
+'darkgreen' => '006400',
+'darkkhaki' => 'bdb76b',
+'darkmagenta' => '8b008b',
+'darkolivegreen' => '556b2f',
+'darkorange' => 'ff8c00',
+'darkorchid' => '9932cc',
+'darkred' => '8b0000',
+'darksalmon' => 'e9967a',
+'darkseagreen' => '8fbc8f',
+'darkslateblue' => '483d8b',
+'darkslategray' => '2f4f4f',
+'darkslategrey' => '2f4f4f',
+'darkturquoise' => '00ced1',
+'darkviolet' => '9400d3',
+'deeppink' => 'ff1493',
+'deepskyblue' => '00bfff',
+'dimgray' => '696969',
+'dimgrey' => '696969',
+'dodgerblue' => '1e90ff',
+'firebrick' => 'b22222',
+'floralwhite' => 'fffaf0',
+'forestgreen' => '228b22',
+'fuchsia' => 'ff00ff',
+'gainsboro' => 'dcdcdc',
+'ghostwhite' => 'f8f8ff',
+'gold' => 'ffd700',
+'goldenrod' => 'daa520',
+'gray' => '808080',
+'grey' => '808080',
+'green' => '008000',
+'greenyellow' => 'adff2f',
+'honeydew' => 'f0fff0',
+'hotpink' => 'ff69b4',
+'indianred' => 'cd5c5c',
+'indigo' => '4b0082',
+'ivory' => 'fffff0',
+'khaki' => 'f0e68c',
+'lavender' => 'e6e6fa',
+'lavenderblush' => 'fff0f5',
+'lawngreen' => '7cfc00',
+'lemonchiffon' => 'fffacd',
+'lightblue' => 'add8e6',
+'lightcoral' => 'f08080',
+'lightcyan' => 'e0ffff',
+'lightgoldenrodyellow' => 'fafad2',
+'ltgray' => 'd3d3d3',
+'lightgray' => 'd3d3d3',
+'lightgrey' => 'd3d3d3',
+'lightgreen' => '90ee90',
+'lightpink' => 'ffb6c1',
+'lightsalmon' => 'ffa07a',
+'lightseagreen' => '20b2aa',
+'lightskyblue' => '87cefa',
+'lightslategray' => '778899',
+'lightslategrey' => '778899',
+'lightsteelblue' => 'b0c4de',
+'lightyellow' => 'ffffe0',
+'lime' => '00ff00',
+'limegreen' => '32cd32',
+'linen' => 'faf0e6',
+'magenta' => 'ff00ff',
+'maroon' => '800000',
+'mediumaquamarine' => '66cdaa',
+'mediumblue' => '0000cd',
+'mediumorchid' => 'ba55d3',
+'mediumpurple' => '9370d8',
+'mediumseagreen' => '3cb371',
+'mediumslateblue' => '7b68ee',
+'mediumspringgreen' => '00fa9a',
+'mediumturquoise' => '48d1cc',
+'mediumvioletred' => 'c71585',
+'midnightblue' => '191970',
+'mintcream' => 'f5fffa',
+'mistyrose' => 'ffe4e1',
+'moccasin' => 'ffe4b5',
+'navajowhite' => 'ffdead',
+'navy' => '000080',
+'oldlace' => 'fdf5e6',
+'olive' => '808000',
+'olivedrab' => '6b8e23',
+'orange' => 'ffa500',
+'orangered' => 'ff4500',
+'orchid' => 'da70d6',
+'palegoldenrod' => 'eee8aa',
+'palegreen' => '98fb98',
+'paleturquoise' => 'afeeee',
+'palevioletred' => 'd87093',
+'papayawhip' => 'ffefd5',
+'peachpuff' => 'ffdab9',
+'peru' => 'cd853f',
+'pink' => 'ffc0cb',
+'plum' => 'dda0dd',
+'powderblue' => 'b0e0e6',
+'purple' => '800080',
+'red' => 'ff0000',
+'rosybrown' => 'bc8f8f',
+'royalblue' => '4169e1',
+'saddlebrown' => '8b4513',
+'salmon' => 'fa8072',
+'sandybrown' => 'f4a460',
+'seagreen' => '2e8b57',
+'seashell' => 'fff5ee',
+'sienna' => 'a0522d',
+'silver' => 'c0c0c0',
+'skyblue' => '87ceeb',
+'slateblue' => '6a5acd',
+'slategray' => '708090',
+'slategrey' => '708090',
+'snow' => 'fffafa',
+'springgreen' => '00ff7f',
+'steelblue' => '4682b4',
+'tan' => 'd2b48c',
+'teal' => '008080',
+'thistle' => 'd8bfd8',
+'tomato' => 'ff6347',
+'turquoise' => '40e0d0',
+'violet' => 'ee82ee',
+'wheat' => 'f5deb3',
+'white' => 'ffffff',
+'whitesmoke' => 'f5f5f5',
+'yellow' => 'ffff00',
+'yellowgreen' => '9acd32'
+);
+
+//============================================================+
+// END OF FILE
+//============================================================+
diff --git a/phpmyadmin/libraries/tcpdf/tcpdf.php b/phpmyadmin/libraries/tcpdf/tcpdf.php
new file mode 100644
index 0000000..e2f511b
--- /dev/null
+++ b/phpmyadmin/libraries/tcpdf/tcpdf.php
@@ -0,0 +1,29927 @@
+<?php
+//============================================================+
+// File name   : tcpdf.php
+// Version     : 5.9.207
+// Begin       : 2002-08-03
+// Last Update : 2013-03-04
+// Author      : Nicola Asuni - Tecnick.com LTD - Manor Coach House, Church Hill, Aldershot, Hants, GU12 4RQ, UK - www.tecnick.com - info at tecnick.com
+// License     : http://www.tecnick.com/pagefiles/tcpdf/LICENSE.TXT GNU-LGPLv3
+// -------------------------------------------------------------------
+// Copyright (C) 2002-2013 Nicola Asuni - Tecnick.com LTD
+//
+// This file is part of TCPDF software library.
+//
+// TCPDF is free software: you can redistribute it and/or modify it
+// under the terms of the GNU Lesser General Public License as
+// published by the Free Software Foundation, either version 3 of the
+// License, or (at your option) any later version.
+//
+// TCPDF is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+// See the GNU Lesser General Public License for more details.
+//
+// You should have received a copy of the License
+// along with TCPDF. If not, see
+// <http://www.tecnick.com/pagefiles/tcpdf/LICENSE.TXT>.
+//
+// See LICENSE.TXT file for more information.
+// -------------------------------------------------------------------
+//
+// Description :
+//   This is a PHP class for generating PDF documents without requiring external extensions.
+//
+// NOTE:
+//   This class was originally derived in 2002 from the Public
+//   Domain FPDF class by Olivier Plathey (http://www.fpdf.org),
+//   but now is almost entirely rewritten and contains thousands of
+//   new lines of code and hundreds new features.
+//
+// Main features:
+//  * no external libraries are required for the basic functions;
+//  * all standard page formats, custom page formats, custom margins and units of measure;
+//  * UTF-8 Unicode and Right-To-Left languages;
+//  * TrueTypeUnicode, TrueType, Type1 and CID-0 fonts;
+//  * font subsetting;
+//  * methods to publish some XHTML + CSS code, Javascript and Forms;
+//  * images, graphic (geometric figures) and transformation methods;
+//  * supports JPEG, PNG and SVG images natively, all images supported by GD (GD, GD2, GD2PART, GIF, JPEG, PNG, BMP, XBM, XPM) and all images supported via ImagMagick (http://www.imagemagick.org/www/formats.html)
+//  * 1D and 2D barcodes: CODE 39, ANSI MH10.8M-1983, USD-3, 3 of 9, CODE 93, USS-93, Standard 2 of 5, Interleaved 2 of 5, CODE 128 A/B/C, 2 and 5 Digits UPC-Based Extention, EAN 8, EAN 13, UPC-A, UPC-E, MSI, POSTNET, PLANET, RMS4CC (Royal Mail 4-state Customer Code), CBC (Customer Bar Code), KIX (Klant index - Customer index), Intelligent Mail Barcode, Onecode, USPS-B-3200, CODABAR, CODE 11, PHARMACODE, PHARMACODE TWO-TRACKS, Datamatrix, QR-Code, PDF417;
+//  * JPEG and PNG ICC profiles, Grayscale, RGB, CMYK, Spot Colors and Transparencies;
+//  * automatic page header and footer management;
+//  * document encryption up to 256 bit and digital signature certifications;
+//  * transactions to UNDO commands;
+//  * PDF annotations, including links, text and file attachments;
+//  * text rendering modes (fill, stroke and clipping);
+//  * multiple columns mode;
+//  * no-write page regions;
+//  * bookmarks, named destinations and table of content;
+//  * text hyphenation;
+//  * text stretching and spacing (tracking);
+//  * automatic page break, line break and text alignments including justification;
+//  * automatic page numbering and page groups;
+//  * move and delete pages;
+//  * page compression (requires php-zlib extension);
+//  * XOBject Templates;
+//  * Layers and object visibility.
+//	* PDF/A-1b support.
+//
+// -----------------------------------------------------------
+// THANKS TO:
+//
+// Olivier Plathey (http://www.fpdf.org) for original FPDF.
+// Efthimios Mavrogeorgiadis (emavro at yahoo.com) for suggestions on RTL language support.
+// Klemen Vodopivec (http://www.fpdf.de/downloads/addons/37/) for Encryption algorithm.
+// Warren Sherliker (wsherliker at gmail.com) for better image handling.
+// dullus for text Justification.
+// Bob Vincent (pillarsdotnet at users.sourceforge.net) for <li> value attribute.
+// Patrick Benny for text stretch suggestion on Cell().
+// Johannes G�ntert for JavaScript support.
+// Denis Van Nuffelen for Dynamic Form.
+// Jacek Czekaj for multibyte justification
+// Anthony Ferrara for the reintroduction of legacy image methods.
+// Sourceforge user 1707880 (hucste) for line-trough mode.
+// Larry Stanbery for page groups.
+// Martin Hall-May for transparency.
+// Aaron C. Spike for Polycurve method.
+// Mohamad Ali Golkar, Saleh AlMatrafe, Charles Abbott for Arabic and Persian support.
+// Moritz Wagner and Andreas Wurmser for graphic functions.
+// Andrew Whitehead for core fonts support.
+// Esteban Jo�l Mar�n for OpenType font conversion.
+// Teus Hagen for several suggestions and fixes.
+// Yukihiro Nakadaira for CID-0 CJK fonts fixes.
+// Kosmas Papachristos for some CSS improvements.
+// Marcel Partap for some fixes.
+// Won Kyu Park for several suggestions, fixes and patches.
+// Dominik Dzienia for QR-code support.
+// Laurent Minguet for some suggestions.
+// Christian Deligant for some suggestions and fixes.
+// Travis Harris for crop mark suggestion.
+// Aleksey Kuznetsov for some suggestions and text shadows.
+// Jim Hanlon for several suggestions and patches.
+// Anyone else that has reported a bug or sent a suggestion.
+//============================================================+
+
+/**
+ * @file
+ * This is a PHP class for generating PDF documents without requiring external extensions.<br>
+ * TCPDF project (http://www.tcpdf.org) was originally derived in 2002 from the Public Domain FPDF class by Olivier Plathey (http://www.fpdf.org), but now is almost entirely rewritten.<br>
+ * <h3>TCPDF main features are:</h3>
+ * <ul>
+ * <li>no external libraries are required for the basic functions;</li>
+ * <li>all standard page formats, custom page formats, custom margins and units of measure;</li>
+ * <li>UTF-8 Unicode and Right-To-Left languages;</li>
+ * <li>TrueTypeUnicode, TrueType, Type1 and CID-0 fonts;</li>
+ * <li>font subsetting;</li>
+ * <li>methods to publish some XHTML + CSS code, Javascript and Forms;</li>
+ * <li>images, graphic (geometric figures) and transformation methods;
+ * <li>supports JPEG, PNG and SVG images natively, all images supported by GD (GD, GD2, GD2PART, GIF, JPEG, PNG, BMP, XBM, XPM) and all images supported via ImagMagick (http://www.imagemagick.org/www/formats.html)</li>
+ * <li>1D and 2D barcodes: CODE 39, ANSI MH10.8M-1983, USD-3, 3 of 9, CODE 93, USS-93, Standard 2 of 5, Interleaved 2 of 5, CODE 128 A/B/C, 2 and 5 Digits UPC-Based Extention, EAN 8, EAN 13, UPC-A, UPC-E, MSI, POSTNET, PLANET, RMS4CC (Royal Mail 4-state Customer Code), CBC (Customer Bar Code), KIX (Klant index - Customer index), Intelligent Mail Barcode, Onecode, USPS-B-3200, CODABAR, CODE 11, PHARMACODE, PHARMACODE TWO-TRACKS, Datamatrix, QR-Code, PDF417;</li>
+ * <li>JPEG and PNG ICC profiles, Grayscale, RGB, CMYK, Spot Colors and Transparencies;</li>
+ * <li>automatic page header and footer management;</li>
+ * <li>document encryption up to 256 bit and digital signature certifications;</li>
+ * <li>transactions to UNDO commands;</li>
+ * <li>PDF annotations, including links, text and file attachments;</li>
+ * <li>text rendering modes (fill, stroke and clipping);</li>
+ * <li>multiple columns mode;</li>
+ * <li>no-write page regions;</li>
+ * <li>bookmarks, named destinations and table of content;</li>
+ * <li>text hyphenation;</li>
+ * <li>text stretching and spacing (tracking);</li>
+ * <li>automatic page break, line break and text alignments including justification;</li>
+ * <li>automatic page numbering and page groups;</li>
+ * <li>move and delete pages;</li>
+ * <li>page compression (requires php-zlib extension);</li>
+ * <li>XOBject Templates;</li>
+ * <li>Layers and object visibility;</li>
+ * <li>PDF/A-1b support.</li>
+ * </ul>
+ * Tools to encode your unicode fonts are on fonts/utils directory.</p>
+ * @package com.tecnick.tcpdf
+ * @author Nicola Asuni
+ * @version 5.9.207
+ */
+
+// Main configuration file. Define the K_TCPDF_EXTERNAL_CONFIG constant to skip this file.
+require_once(dirname(__FILE__).'/config/tcpdf_config.php');
+
+/**
+ * @class TCPDF
+ * PHP class for generating PDF documents without requiring external extensions.
+ * TCPDF project (http://www.tcpdf.org) has been originally derived in 2002 from the Public Domain FPDF class by Olivier Plathey (http://www.fpdf.org), but now is almost entirely rewritten.<br>
+ * @package com.tecnick.tcpdf
+ * @brief PHP class for generating PDF documents without requiring external extensions.
+ * @version 5.9.207
+ * @author Nicola Asuni - info at tecnick.com
+ */
+class TCPDF {
+
+	// private properties
+
+	/**
+	 * Current TCPDF version.
+	 * @private
+	 */
+	private $tcpdf_version = '5.9.207';
+
+	// Protected properties
+
+	/**
+	 * Current page number.
+	 * @protected
+	 */
+	protected $page;
+
+	/**
+	 * Current object number.
+	 * @protected
+	 */
+	protected $n;
+
+	/**
+	 * Array of object offsets.
+	 * @protected
+	 */
+	protected $offsets = array();
+
+	/**
+	 * Array of object IDs for each page.
+	 * @protected
+	 */
+	protected $pageobjects = array();
+
+	/**
+	 * Buffer holding in-memory PDF.
+	 * @protected
+	 */
+	protected $buffer;
+
+	/**
+	 * Array containing pages.
+	 * @protected
+	 */
+	protected $pages = array();
+
+	/**
+	 * Current document state.
+	 * @protected
+	 */
+	protected $state;
+
+	/**
+	 * Compression flag.
+	 * @protected
+	 */
+	protected $compress;
+
+	/**
+	 * Current page orientation (P = Portrait, L = Landscape).
+	 * @protected
+	 */
+	protected $CurOrientation;
+
+	/**
+	 * Page dimensions.
+	 * @protected
+	 */
+	protected $pagedim = array();
+
+	/**
+	 * Scale factor (number of points in user unit).
+	 * @protected
+	 */
+	protected $k;
+
+	/**
+	 * Width of page format in points.
+	 * @protected
+	 */
+	protected $fwPt;
+
+	/**
+	 * Height of page format in points.
+	 * @protected
+	 */
+	protected $fhPt;
+
+	/**
+	 * Current width of page in points.
+	 * @protected
+	 */
+	protected $wPt;
+
+	/**
+	 * Current height of page in points.
+	 * @protected
+	 */
+	protected $hPt;
+
+	/**
+	 * Current width of page in user unit.
+	 * @protected
+	 */
+	protected $w;
+
+	/**
+	 * Current height of page in user unit.
+	 * @protected
+	 */
+	protected $h;
+
+	/**
+	 * Left margin.
+	 * @protected
+	 */
+	protected $lMargin;
+
+	/**
+	 * Right margin.
+	 * @protected
+	 */
+	protected $rMargin;
+
+	/**
+	 * Cell left margin (used by regions).
+	 * @protected
+	 */
+	protected $clMargin;
+
+	/**
+	 * Cell right margin (used by regions).
+	 * @protected
+	 */
+	protected $crMargin;
+
+	/**
+	 * Top margin.
+	 * @protected
+	 */
+	protected $tMargin;
+
+	/**
+	 * Page break margin.
+	 * @protected
+	 */
+	protected $bMargin;
+
+	/**
+	 * Array of cell internal paddings ('T' => top, 'R' => right, 'B' => bottom, 'L' => left).
+	 * @since 5.9.000 (2010-10-03)
+	 * @protected
+	 */
+	protected $cell_padding = array('T' => 0, 'R' => 0, 'B' => 0, 'L' => 0);
+
+	/**
+	 * Array of cell margins ('T' => top, 'R' => right, 'B' => bottom, 'L' => left).
+	 * @since 5.9.000 (2010-10-04)
+	 * @protected
+	 */
+	protected $cell_margin = array('T' => 0, 'R' => 0, 'B' => 0, 'L' => 0);
+
+	/**
+	 * Current horizontal position in user unit for cell positioning.
+	 * @protected
+	 */
+	protected $x;
+
+	/**
+	 * Current vertical position in user unit for cell positioning.
+	 * @protected
+	 */
+	protected $y;
+
+	/**
+	 * Height of last cell printed.
+	 * @protected
+	 */
+	protected $lasth;
+
+	/**
+	 * Line width in user unit.
+	 * @protected
+	 */
+	protected $LineWidth;
+
+	/**
+	 * Array of standard font names.
+	 * @protected
+	 */
+	protected $CoreFonts;
+
+	/**
+	 * Array of used fonts.
+	 * @protected
+	 */
+	protected $fonts = array();
+
+	/**
+	 * Array of font files.
+	 * @protected
+	 */
+	protected $FontFiles = array();
+
+	/**
+	 * Array of encoding differences.
+	 * @protected
+	 */
+	protected $diffs = array();
+
+	/**
+	 * Array of used images.
+	 * @protected
+	 */
+	protected $images = array();
+
+	/**
+	 * Array of cached files.
+	 * @protected
+	 */
+	protected $cached_files = array();
+
+	/**
+	 * Array of Annotations in pages.
+	 * @protected
+	 */
+	protected $PageAnnots = array();
+
+	/**
+	 * Array of internal links.
+	 * @protected
+	 */
+	protected $links = array();
+
+	/**
+	 * Current font family.
+	 * @protected
+	 */
+	protected $FontFamily;
+
+	/**
+	 * Current font style.
+	 * @protected
+	 */
+	protected $FontStyle;
+
+	/**
+	 * Current font ascent (distance between font top and baseline).
+	 * @protected
+	 * @since 2.8.000 (2007-03-29)
+	 */
+	protected $FontAscent;
+
+	/**
+	 * Current font descent (distance between font bottom and baseline).
+	 * @protected
+	 * @since 2.8.000 (2007-03-29)
+	 */
+	protected $FontDescent;
+
+	/**
+	 * Underlining flag.
+	 * @protected
+	 */
+	protected $underline;
+
+	/**
+	 * Overlining flag.
+	 * @protected
+	 */
+	protected $overline;
+
+	/**
+	 * Current font info.
+	 * @protected
+	 */
+	protected $CurrentFont;
+
+	/**
+	 * Current font size in points.
+	 * @protected
+	 */
+	protected $FontSizePt;
+
+	/**
+	 * Current font size in user unit.
+	 * @protected
+	 */
+	protected $FontSize;
+
+	/**
+	 * Commands for drawing color.
+	 * @protected
+	 */
+	protected $DrawColor;
+
+	/**
+	 * Commands for filling color.
+	 * @protected
+	 */
+	protected $FillColor;
+
+	/**
+	 * Commands for text color.
+	 * @protected
+	 */
+	protected $TextColor;
+
+	/**
+	 * Indicates whether fill and text colors are different.
+	 * @protected
+	 */
+	protected $ColorFlag;
+
+	/**
+	 * Automatic page breaking.
+	 * @protected
+	 */
+	protected $AutoPageBreak;
+
+	/**
+	 * Threshold used to trigger page breaks.
+	 * @protected
+	 */
+	protected $PageBreakTrigger;
+
+	/**
+	 * Flag set when processing page header.
+	 * @protected
+	 */
+	protected $InHeader = false;
+
+	/**
+	 * Flag set when processing page footer.
+	 * @protected
+	 */
+	protected $InFooter = false;
+
+	/**
+	 * Zoom display mode.
+	 * @protected
+	 */
+	protected $ZoomMode;
+
+	/**
+	 * Layout display mode.
+	 * @protected
+	 */
+	protected $LayoutMode;
+
+	/**
+	 * If true set the document information dictionary in Unicode.
+	 * @protected
+	 */
+	protected $docinfounicode = true;
+
+	/**
+	 * Document title.
+	 * @protected
+	 */
+	protected $title = '';
+
+	/**
+	 * Document subject.
+	 * @protected
+	 */
+	protected $subject = '';
+
+	/**
+	 * Document author.
+	 * @protected
+	 */
+	protected $author = '';
+
+	/**
+	 * Document keywords.
+	 * @protected
+	 */
+	protected $keywords = '';
+
+	/**
+	 * Document creator.
+	 * @protected
+	 */
+	protected $creator = '';
+
+	/**
+	 * Starting page number.
+	 * @protected
+	 */
+	protected $starting_page_number = 1;
+
+	/**
+	 * String alias for total number of pages.
+	 * @protected
+	 */
+	protected $alias_tot_pages = '{:ptp:}';
+
+	/**
+	 * String alias for page number.
+	 * @protected
+	 */
+	protected $alias_num_page = '{:pnp:}';
+
+	/**
+	 * String alias for total number of pages in a single group.
+	 * @protected
+	 */
+	protected $alias_group_tot_pages = '{:ptg:}';
+
+	/**
+	 * String alias for group page number.
+	 * @protected
+	 */
+	protected $alias_group_num_page = '{:png:}';
+
+	/**
+	 * String alias for right shift compensation used to correctly align page numbers on the right.
+	 * @protected
+	 */
+	protected $alias_right_shift = '{rsc:';
+
+	/**
+	 * The right-bottom (or left-bottom for RTL) corner X coordinate of last inserted image.
+	 * @since 2002-07-31
+	 * @author Nicola Asuni
+	 * @protected
+	 */
+	protected $img_rb_x;
+
+	/**
+	 * The right-bottom corner Y coordinate of last inserted image.
+	 * @since 2002-07-31
+	 * @author Nicola Asuni
+	 * @protected
+	 */
+	protected $img_rb_y;
+
+	/**
+	 * Adjusting factor to convert pixels to user units.
+	 * @since 2004-06-14
+	 * @author Nicola Asuni
+	 * @protected
+	 */
+	protected $imgscale = 1;
+
+	/**
+	 * Boolean flag set to true when the input text is unicode (require unicode fonts).
+	 * @since 2005-01-02
+	 * @author Nicola Asuni
+	 * @protected
+	 */
+	protected $isunicode = false;
+
+	/**
+	 * Object containing unicode data.
+	 * @since 5.9.004 (2010-10-18)
+	 * @author Nicola Asuni
+	 * @protected
+	 */
+	protected $unicode;
+
+	/**
+	 * Object containing font encoding maps.
+	 * @since 5.9.123 (2011-10-01)
+	 * @author Nicola Asuni
+	 * @protected
+	 */
+	protected $encmaps;
+
+	/**
+	 * PDF version.
+	 * @since 1.5.3
+	 * @protected
+	 */
+	protected $PDFVersion = '1.7';
+
+	/**
+	 * ID of the stored default header template (-1 = not set).
+	 * @protected
+	 */
+	protected $header_xobjid = -1;
+
+	/**
+	 * If true reset the Header Xobject template at each page
+	 * @protected
+	 */
+	protected $header_xobj_autoreset = false;
+
+	/**
+	 * Minimum distance between header and top page margin.
+	 * @protected
+	 */
+	protected $header_margin;
+
+	/**
+	 * Minimum distance between footer and bottom page margin.
+	 * @protected
+	 */
+	protected $footer_margin;
+
+	/**
+	 * Original left margin value.
+	 * @protected
+	 * @since 1.53.0.TC013
+	 */
+	protected $original_lMargin;
+
+	/**
+	 * Original right margin value.
+	 * @protected
+	 * @since 1.53.0.TC013
+	 */
+	protected $original_rMargin;
+
+	/**
+	 * Default font used on page header.
+	 * @protected
+	 */
+	protected $header_font;
+
+	/**
+	 * Default font used on page footer.
+	 * @protected
+	 */
+	protected $footer_font;
+
+	/**
+	 * Language templates.
+	 * @protected
+	 */
+	protected $l;
+
+	/**
+	 * Barcode to print on page footer (only if set).
+	 * @protected
+	 */
+	protected $barcode = false;
+
+	/**
+	 * Boolean flag to print/hide page header.
+	 * @protected
+	 */
+	protected $print_header = true;
+
+	/**
+	 * Boolean flag to print/hide page footer.
+	 * @protected
+	 */
+	protected $print_footer = true;
+
+	/**
+	 * Header image logo.
+	 * @protected
+	 */
+	protected $header_logo = '';
+
+	/**
+	 * Width of header image logo in user units.
+	 * @protected
+	 */
+	protected $header_logo_width = 30;
+
+	/**
+	 * Title to be printed on default page header.
+	 * @protected
+	 */
+	protected $header_title = '';
+
+	/**
+	 * String to pring on page header after title.
+	 * @protected
+	 */
+	protected $header_string = '';
+
+	/**
+	 * Color for header text (RGB array).
+	 * @since 5.9.174 (2012-07-25)
+	 * @protected
+	 */
+	protected $header_text_color = array(0,0,0);
+
+	/**
+	 * Color for header line (RGB array).
+	 * @since 5.9.174 (2012-07-25)
+	 * @protected
+	 */
+	protected $header_line_color = array(0,0,0);
+
+	/**
+	 * Color for footer text (RGB array).
+	 * @since 5.9.174 (2012-07-25)
+	 * @protected
+	 */
+	protected $footer_text_color = array(0,0,0);
+
+	/**
+	 * Color for footer line (RGB array).
+	 * @since 5.9.174 (2012-07-25)
+	 * @protected
+	 */
+	protected $footer_line_color = array(0,0,0);
+
+	/**
+	 * Text shadow data array.
+	 * @since 5.9.174 (2012-07-25)
+	 * @protected
+	 */
+	protected $txtshadow = array('enabled'=>false, 'depth_w'=>0, 'depth_h'=>0, 'color'=>false, 'opacity'=>1, 'blend_mode'=>'Normal');
+
+	/**
+	 * Default number of columns for html table.
+	 * @protected
+	 */
+	protected $default_table_columns = 4;
+
+	// variables for html parser
+
+	/**
+	 * HTML PARSER: array to store current link and rendering styles.
+	 * @protected
+	 */
+	protected $HREF = array();
+
+	/**
+	 * List of available fonts on filesystem.
+	 * @protected
+	 */
+	protected $fontlist = array();
+
+	/**
+	 * Current foreground color.
+	 * @protected
+	 */
+	protected $fgcolor;
+
+	/**
+	 * HTML PARSER: array of boolean values, true in case of ordered list (OL), false otherwise.
+	 * @protected
+	 */
+	protected $listordered = array();
+
+	/**
+	 * HTML PARSER: array count list items on nested lists.
+	 * @protected
+	 */
+	protected $listcount = array();
+
+	/**
+	 * HTML PARSER: current list nesting level.
+	 * @protected
+	 */
+	protected $listnum = 0;
+
+	/**
+	 * HTML PARSER: indent amount for lists.
+	 * @protected
+	 */
+	protected $listindent = 0;
+
+	/**
+	 * HTML PARSER: current list indententation level.
+	 * @protected
+	 */
+	protected $listindentlevel = 0;
+
+	/**
+	 * Current background color.
+	 * @protected
+	 */
+	protected $bgcolor;
+
+	/**
+	 * Temporary font size in points.
+	 * @protected
+	 */
+	protected $tempfontsize = 10;
+
+	/**
+	 * Spacer string for LI tags.
+	 * @protected
+	 */
+	protected $lispacer = '';
+
+	/**
+	 * Default encoding.
+	 * @protected
+	 * @since 1.53.0.TC010
+	 */
+	protected $encoding = 'UTF-8';
+
+	/**
+	 * PHP internal encoding.
+	 * @protected
+	 * @since 1.53.0.TC016
+	 */
+	protected $internal_encoding;
+
+	/**
+	 * Boolean flag to indicate if the document language is Right-To-Left.
+	 * @protected
+	 * @since 2.0.000
+	 */
+	protected $rtl = false;
+
+	/**
+	 * Boolean flag used to force RTL or LTR string direction.
+	 * @protected
+	 * @since 2.0.000
+	 */
+	protected $tmprtl = false;
+
+	// --- Variables used for document encryption:
+
+	/**
+	 * IBoolean flag indicating whether document is protected.
+	 * @protected
+	 * @since 2.0.000 (2008-01-02)
+	 */
+	protected $encrypted;
+
+	/**
+	 * Array containing encryption settings.
+	 * @protected
+	 * @since 5.0.005 (2010-05-11)
+	 */
+	protected $encryptdata = array();
+
+	/**
+	 * Last RC4 key encrypted (cached for optimisation).
+	 * @protected
+	 * @since 2.0.000 (2008-01-02)
+	 */
+	protected $last_enc_key;
+
+	/**
+	 * Last RC4 computed key.
+	 * @protected
+	 * @since 2.0.000 (2008-01-02)
+	 */
+	protected $last_enc_key_c;
+
+	/**
+	 * Encryption padding string.
+	 * @protected
+	 */
+	protected $enc_padding = "\x28\xBF\x4E\x5E\x4E\x75\x8A\x41\x64\x00\x4E\x56\xFF\xFA\x01\x08\x2E\x2E\x00\xB6\xD0\x68\x3E\x80\x2F\x0C\xA9\xFE\x64\x53\x69\x7A";
+
+	/**
+	 * File ID (used on document trailer).
+	 * @protected
+	 * @since 5.0.005 (2010-05-12)
+	 */
+	protected $file_id;
+
+	// --- bookmark ---
+
+	/**
+	 * Outlines for bookmark.
+	 * @protected
+	 * @since 2.1.002 (2008-02-12)
+	 */
+	protected $outlines = array();
+
+	/**
+	 * Outline root for bookmark.
+	 * @protected
+	 * @since 2.1.002 (2008-02-12)
+	 */
+	protected $OutlineRoot;
+
+	// --- javascript and form ---
+
+	/**
+	 * Javascript code.
+	 * @protected
+	 * @since 2.1.002 (2008-02-12)
+	 */
+	protected $javascript = '';
+
+	/**
+	 * Javascript counter.
+	 * @protected
+	 * @since 2.1.002 (2008-02-12)
+	 */
+	protected $n_js;
+
+	/**
+	 * line trough state
+	 * @protected
+	 * @since 2.8.000 (2008-03-19)
+	 */
+	protected $linethrough;
+
+	/**
+	 * Array with additional document-wide usage rights for the document.
+	 * @protected
+	 * @since 5.8.014 (2010-08-23)
+	 */
+	protected $ur = array();
+
+	/**
+	 * DPI (Dot Per Inch) Document Resolution (do not change).
+	 * @protected
+	 * @since 3.0.000 (2008-03-27)
+	 */
+	protected $dpi = 72;
+
+	/**
+	 * Array of page numbers were a new page group was started (the page numbers are the keys of the array).
+	 * @protected
+	 * @since 3.0.000 (2008-03-27)
+	 */
+	protected $newpagegroup = array();
+
+	/**
+	 * Array that contains the number of pages in each page group.
+	 * @protected
+	 * @since 3.0.000 (2008-03-27)
+	 */
+	protected $pagegroups = array();
+
+	/**
+	 * Current page group number.
+	 * @protected
+	 * @since 3.0.000 (2008-03-27)
+	 */
+	protected $currpagegroup = 0;
+
+	/**
+	 * Array of transparency objects and parameters.
+	 * @protected
+	 * @since 3.0.000 (2008-03-27)
+	 */
+	protected $extgstates;
+
+	/**
+	 * Set the default JPEG compression quality (1-100).
+	 * @protected
+	 * @since 3.0.000 (2008-03-27)
+	 */
+	protected $jpeg_quality;
+
+	/**
+	 * Default cell height ratio.
+	 * @protected
+	 * @since 3.0.014 (2008-05-23)
+	 */
+	protected $cell_height_ratio = K_CELL_HEIGHT_RATIO;
+
+	/**
+	 * PDF viewer preferences.
+	 * @protected
+	 * @since 3.1.000 (2008-06-09)
+	 */
+	protected $viewer_preferences;
+
+	/**
+	 * A name object specifying how the document should be displayed when opened.
+	 * @protected
+	 * @since 3.1.000 (2008-06-09)
+	 */
+	protected $PageMode;
+
+	/**
+	 * Array for storing gradient information.
+	 * @protected
+	 * @since 3.1.000 (2008-06-09)
+	 */
+	protected $gradients = array();
+
+	/**
+	 * Array used to store positions inside the pages buffer (keys are the page numbers).
+	 * @protected
+	 * @since 3.2.000 (2008-06-26)
+	 */
+	protected $intmrk = array();
+
+	/**
+	 * Array used to store positions inside the pages buffer (keys are the page numbers).
+	 * @protected
+	 * @since 5.7.000 (2010-08-03)
+	 */
+	protected $bordermrk = array();
+
+	/**
+	 * Array used to store page positions to track empty pages (keys are the page numbers).
+	 * @protected
+	 * @since 5.8.007 (2010-08-18)
+	 */
+	protected $emptypagemrk = array();
+
+	/**
+	 * Array used to store content positions inside the pages buffer (keys are the page numbers).
+	 * @protected
+	 * @since 4.6.021 (2009-07-20)
+	 */
+	protected $cntmrk = array();
+
+	/**
+	 * Array used to store footer positions of each page.
+	 * @protected
+	 * @since 3.2.000 (2008-07-01)
+	 */
+	protected $footerpos = array();
+
+	/**
+	 * Array used to store footer length of each page.
+	 * @protected
+	 * @since 4.0.014 (2008-07-29)
+	 */
+	protected $footerlen = array();
+
+	/**
+	 * Boolean flag to indicate if a new line is created.
+	 * @protected
+	 * @since 3.2.000 (2008-07-01)
+	 */
+	protected $newline = true;
+
+	/**
+	 * End position of the latest inserted line.
+	 * @protected
+	 * @since 3.2.000 (2008-07-01)
+	 */
+	protected $endlinex = 0;
+
+	/**
+	 * PDF string for width value of the last line.
+	 * @protected
+	 * @since 4.0.006 (2008-07-16)
+	 */
+	protected $linestyleWidth = '';
+
+	/**
+	 * PDF string for CAP value of the last line.
+	 * @protected
+	 * @since 4.0.006 (2008-07-16)
+	 */
+	protected $linestyleCap = '0 J';
+
+	/**
+	 * PDF string for join value of the last line.
+	 * @protected
+	 * @since 4.0.006 (2008-07-16)
+	 */
+	protected $linestyleJoin = '0 j';
+
+	/**
+	 * PDF string for dash value of the last line.
+	 * @protected
+	 * @since 4.0.006 (2008-07-16)
+	 */
+	protected $linestyleDash = '[] 0 d';
+
+	/**
+	 * Boolean flag to indicate if marked-content sequence is open.
+	 * @protected
+	 * @since 4.0.013 (2008-07-28)
+	 */
+	protected $openMarkedContent = false;
+
+	/**
+	 * Count the latest inserted vertical spaces on HTML.
+	 * @protected
+	 * @since 4.0.021 (2008-08-24)
+	 */
+	protected $htmlvspace = 0;
+
+	/**
+	 * Array of Spot colors.
+	 * @protected
+	 * @since 4.0.024 (2008-09-12)
+	 */
+	protected $spot_colors = array();
+
+	/**
+	 * Symbol used for HTML unordered list items.
+	 * @protected
+	 * @since 4.0.028 (2008-09-26)
+	 */
+	protected $lisymbol = '';
+
+	/**
+	 * String used to mark the beginning and end of EPS image blocks.
+	 * @protected
+	 * @since 4.1.000 (2008-10-18)
+	 */
+	protected $epsmarker = 'x#!#EPS#!#x';
+
+	/**
+	 * Array of transformation matrix.
+	 * @protected
+	 * @since 4.2.000 (2008-10-29)
+	 */
+	protected $transfmatrix = array();
+
+	/**
+	 * Current key for transformation matrix.
+	 * @protected
+	 * @since 4.8.005 (2009-09-17)
+	 */
+	protected $transfmatrix_key = 0;
+
+	/**
+	 * Booklet mode for double-sided pages.
+	 * @protected
+	 * @since 4.2.000 (2008-10-29)
+	 */
+	protected $booklet = false;
+
+	/**
+	 * Epsilon value used for float calculations.
+	 * @protected
+	 * @since 4.2.000 (2008-10-29)
+	 */
+	protected $feps = 0.005;
+
+	/**
+	 * Array used for custom vertical spaces for HTML tags.
+	 * @protected
+	 * @since 4.2.001 (2008-10-30)
+	 */
+	protected $tagvspaces = array();
+
+	/**
+	 * HTML PARSER: custom indent amount for lists. Negative value means disabled.
+	 * @protected
+	 * @since 4.2.007 (2008-11-12)
+	 */
+	protected $customlistindent = -1;
+
+	/**
+	 * Boolean flag to indicate if the border of the cell sides that cross the page should be removed.
+	 * @protected
+	 * @since 4.2.010 (2008-11-14)
+	 */
+	protected $opencell = true;
+
+	/**
+	 * Array of files to embedd.
+	 * @protected
+	 * @since 4.4.000 (2008-12-07)
+	 */
+	protected $embeddedfiles = array();
+
+	/**
+	 * Boolean flag to indicate if we are inside a PRE tag.
+	 * @protected
+	 * @since 4.4.001 (2008-12-08)
+	 */
+	protected $premode = false;
+
+	/**
+	 * Array used to store positions of graphics transformation blocks inside the page buffer.
+	 * keys are the page numbers
+	 * @protected
+	 * @since 4.4.002 (2008-12-09)
+	 */
+	protected $transfmrk = array();
+
+	/**
+	 * Default color for html links.
+	 * @protected
+	 * @since 4.4.003 (2008-12-09)
+	 */
+	protected $htmlLinkColorArray = array(0, 0, 255);
+
+	/**
+	 * Default font style to add to html links.
+	 * @protected
+	 * @since 4.4.003 (2008-12-09)
+	 */
+	protected $htmlLinkFontStyle = 'U';
+
+	/**
+	 * Counts the number of pages.
+	 * @protected
+	 * @since 4.5.000 (2008-12-31)
+	 */
+	protected $numpages = 0;
+
+	/**
+	 * Array containing page lengths in bytes.
+	 * @protected
+	 * @since 4.5.000 (2008-12-31)
+	 */
+	protected $pagelen = array();
+
+	/**
+	 * Counts the number of pages.
+	 * @protected
+	 * @since 4.5.000 (2008-12-31)
+	 */
+	protected $numimages = 0;
+
+	/**
+	 * Store the image keys.
+	 * @protected
+	 * @since 4.5.000 (2008-12-31)
+	 */
+	protected $imagekeys = array();
+
+	/**
+	 * Length of the buffer in bytes.
+	 * @protected
+	 * @since 4.5.000 (2008-12-31)
+	 */
+	protected $bufferlen = 0;
+
+	/**
+	 * If true enables disk caching.
+	 * @protected
+	 * @since 4.5.000 (2008-12-31)
+	 */
+	protected $diskcache = false;
+
+	/**
+	 * Counts the number of fonts.
+	 * @protected
+	 * @since 4.5.000 (2009-01-02)
+	 */
+	protected $numfonts = 0;
+
+	/**
+	 * Store the font keys.
+	 * @protected
+	 * @since 4.5.000 (2009-01-02)
+	 */
+	protected $fontkeys = array();
+
+	/**
+	 * Store the font object IDs.
+	 * @protected
+	 * @since 4.8.001 (2009-09-09)
+	 */
+	protected $font_obj_ids = array();
+
+	/**
+	 * Store the fage status (true when opened, false when closed).
+	 * @protected
+	 * @since 4.5.000 (2009-01-02)
+	 */
+	protected $pageopen = array();
+
+	/**
+	 * Default monospace font.
+	 * @protected
+	 * @since 4.5.025 (2009-03-10)
+	 */
+	protected $default_monospaced_font = 'courier';
+
+	/**
+	 * Cloned copy of the current class object.
+	 * @protected
+	 * @since 4.5.029 (2009-03-19)
+	 */
+	protected $objcopy;
+
+	/**
+	 * Array used to store the lengths of cache files.
+	 * @protected
+	 * @since 4.5.029 (2009-03-19)
+	 */
+	protected $cache_file_length = array();
+
+	/**
+	 * Table header content to be repeated on each new page.
+	 * @protected
+	 * @since 4.5.030 (2009-03-20)
+	 */
+	protected $thead = '';
+
+	/**
+	 * Margins used for table header.
+	 * @protected
+	 * @since 4.5.030 (2009-03-20)
+	 */
+	protected $theadMargins = array();
+
+	/**
+	 * Cache array for UTF8StringToArray() method.
+	 * @protected
+	 * @since 4.5.037 (2009-04-07)
+	 */
+	protected $cache_UTF8StringToArray = array();
+
+	/**
+	 * Maximum size of cache array used for UTF8StringToArray() method.
+	 * @protected
+	 * @since 4.5.037 (2009-04-07)
+	 */
+	protected $cache_maxsize_UTF8StringToArray = 8;
+
+	/**
+	 * Current size of cache array used for UTF8StringToArray() method.
+	 * @protected
+	 * @since 4.5.037 (2009-04-07)
+	 */
+	protected $cache_size_UTF8StringToArray = 0;
+
+	/**
+	 * Boolean flag to enable document digital signature.
+	 * @protected
+	 * @since 4.6.005 (2009-04-24)
+	 */
+	protected $sign = false;
+
+	/**
+	 * Digital signature data.
+	 * @protected
+	 * @since 4.6.005 (2009-04-24)
+	 */
+	protected $signature_data = array();
+
+	/**
+	 * Digital signature max length.
+	 * @protected
+	 * @since 4.6.005 (2009-04-24)
+	 */
+	protected $signature_max_length = 11742;
+
+	/**
+	 * Data for digital signature appearance.
+	 * @protected
+	 * @since 5.3.011 (2010-06-16)
+	 */
+	protected $signature_appearance = array('page' => 1, 'rect' => '0 0 0 0');
+
+	/**
+	 * Array of empty digital signature appearances.
+	 * @protected
+	 * @since 5.9.101 (2011-07-06)
+	 */
+	protected $empty_signature_appearance = array();
+
+	/**
+	 * Regular expression used to find blank characters (required for word-wrapping).
+	 * @protected
+	 * @since 4.6.006 (2009-04-28)
+	 */
+	protected $re_spaces = '/[^\S\xa0]/';
+
+	/**
+	 * Array of $re_spaces parts.
+	 * @protected
+	 * @since 5.5.011 (2010-07-09)
+	 */
+	protected $re_space = array('p' => '[^\S\xa0]', 'm' => '');
+
+	/**
+	 * Digital signature object ID.
+	 * @protected
+	 * @since 4.6.022 (2009-06-23)
+	 */
+	protected $sig_obj_id = 0;
+
+	/**
+	 * ByteRange placemark used during digital signature process.
+	 * @protected
+	 * @since 4.6.028 (2009-08-25)
+	 */
+	protected $byterange_string = '/ByteRange[0 ********** ********** **********]';
+
+	/**
+	 * Placemark used during digital signature process.
+	 * @protected
+	 * @since 4.6.028 (2009-08-25)
+	 */
+	protected $sig_annot_ref = '***SIGANNREF*** 0 R';
+
+	/**
+	 * ID of page objects.
+	 * @protected
+	 * @since 4.7.000 (2009-08-29)
+	 */
+	protected $page_obj_id = array();
+
+	/**
+	 * List of form annotations IDs.
+	 * @protected
+	 * @since 4.8.000 (2009-09-07)
+	 */
+	protected $form_obj_id = array();
+
+	/**
+	 * Deafult Javascript field properties. Possible values are described on official Javascript for Acrobat API reference. Annotation options can be directly specified using the 'aopt' entry.
+	 * @protected
+	 * @since 4.8.000 (2009-09-07)
+	 */
+	protected $default_form_prop = array('lineWidth'=>1, 'borderStyle'=>'solid', 'fillColor'=>array(255, 255, 255), 'strokeColor'=>array(128, 128, 128));
+
+	/**
+	 * Javascript objects array.
+	 * @protected
+	 * @since 4.8.000 (2009-09-07)
+	 */
+	protected $js_objects = array();
+
+	/**
+	 * Current form action (used during XHTML rendering).
+	 * @protected
+	 * @since 4.8.000 (2009-09-07)
+	 */
+	protected $form_action = '';
+
+	/**
+	 * Current form encryption type (used during XHTML rendering).
+	 * @protected
+	 * @since 4.8.000 (2009-09-07)
+	 */
+	protected $form_enctype = 'application/x-www-form-urlencoded';
+
+	/**
+	 * Current method to submit forms.
+	 * @protected
+	 * @since 4.8.000 (2009-09-07)
+	 */
+	protected $form_mode = 'post';
+
+	/**
+	 * List of fonts used on form fields (fontname => fontkey).
+	 * @protected
+	 * @since 4.8.001 (2009-09-09)
+	 */
+	protected $annotation_fonts = array();
+
+	/**
+	 * List of radio buttons parent objects.
+	 * @protected
+	 * @since 4.8.001 (2009-09-09)
+	 */
+	protected $radiobutton_groups = array();
+
+	/**
+	 * List of radio group objects IDs.
+	 * @protected
+	 * @since 4.8.001 (2009-09-09)
+	 */
+	protected $radio_groups = array();
+
+	/**
+	 * Text indentation value (used for text-indent CSS attribute).
+	 * @protected
+	 * @since 4.8.006 (2009-09-23)
+	 */
+	protected $textindent = 0;
+
+	/**
+	 * Store page number when startTransaction() is called.
+	 * @protected
+	 * @since 4.8.006 (2009-09-23)
+	 */
+	protected $start_transaction_page = 0;
+
+	/**
+	 * Store Y position when startTransaction() is called.
+	 * @protected
+	 * @since 4.9.001 (2010-03-28)
+	 */
+	protected $start_transaction_y = 0;
+
+	/**
+	 * True when we are printing the thead section on a new page.
+	 * @protected
+	 * @since 4.8.027 (2010-01-25)
+	 */
+	protected $inthead = false;
+
+	/**
+	 * Array of column measures (width, space, starting Y position).
+	 * @protected
+	 * @since 4.9.001 (2010-03-28)
+	 */
+	protected $columns = array();
+
+	/**
+	 * Number of colums.
+	 * @protected
+	 * @since 4.9.001 (2010-03-28)
+	 */
+	protected $num_columns = 1;
+
+	/**
+	 * Current column number.
+	 * @protected
+	 * @since 4.9.001 (2010-03-28)
+	 */
+	protected $current_column = 0;
+
+	/**
+	 * Starting page for columns.
+	 * @protected
+	 * @since 4.9.001 (2010-03-28)
+	 */
+	protected $column_start_page = 0;
+
+	/**
+	 * Maximum page and column selected.
+	 * @protected
+	 * @since 5.8.000 (2010-08-11)
+	 */
+	protected $maxselcol = array('page' => 0, 'column' => 0);
+
+	/**
+	 * Array of: X difference between table cell x start and starting page margin, cellspacing, cellpadding.
+	 * @protected
+	 * @since 5.8.000 (2010-08-11)
+	 */
+	protected $colxshift = array('x' => 0, 's' => array('H' => 0, 'V' => 0), 'p' => array('L' => 0, 'T' => 0, 'R' => 0, 'B' => 0));
+
+	/**
+	 * Text rendering mode: 0 = Fill text; 1 = Stroke text; 2 = Fill, then stroke text; 3 = Neither fill nor stroke text (invisible); 4 = Fill text and add to path for clipping; 5 = Stroke text and add to path for clipping; 6 = Fill, then stroke text and add to path for clipping; 7 = Add text to path for clipping.
+	 * @protected
+	 * @since 4.9.008 (2010-04-03)
+	 */
+	protected $textrendermode = 0;
+
+	/**
+	 * Text stroke width in doc units.
+	 * @protected
+	 * @since 4.9.008 (2010-04-03)
+	 */
+	protected $textstrokewidth = 0;
+
+	/**
+	 * Current stroke color.
+	 * @protected
+	 * @since 4.9.008 (2010-04-03)
+	 */
+	protected $strokecolor;
+
+	/**
+	 * Default unit of measure for document.
+	 * @protected
+	 * @since 5.0.000 (2010-04-22)
+	 */
+	protected $pdfunit = 'mm';
+
+	/**
+	 * Boolean flag true when we are on TOC (Table Of Content) page.
+	 * @protected
+	 */
+	protected $tocpage = false;
+
+	/**
+	 * Boolean flag: if true convert vector images (SVG, EPS) to raster image using GD or ImageMagick library.
+	 * @protected
+	 * @since 5.0.000 (2010-04-26)
+	 */
+	protected $rasterize_vector_images = false;
+
+	/**
+	 * Boolean flag: if true enables font subsetting by default.
+	 * @protected
+	 * @since 5.3.002 (2010-06-07)
+	 */
+	protected $font_subsetting = true;
+
+	/**
+	 * Array of default graphic settings.
+	 * @protected
+	 * @since 5.5.008 (2010-07-02)
+	 */
+	protected $default_graphic_vars = array();
+
+	/**
+	 * Array of XObjects.
+	 * @protected
+	 * @since 5.8.014 (2010-08-23)
+	 */
+	protected $xobjects = array();
+
+	/**
+	 * Boolean value true when we are inside an XObject.
+	 * @protected
+	 * @since 5.8.017 (2010-08-24)
+	 */
+	protected $inxobj = false;
+
+	/**
+	 * Current XObject ID.
+	 * @protected
+	 * @since 5.8.017 (2010-08-24)
+	 */
+	protected $xobjid = '';
+
+	/**
+	 * Percentage of character stretching.
+	 * @protected
+	 * @since 5.9.000 (2010-09-29)
+	 */
+	protected $font_stretching = 100;
+
+	/**
+	 * Increases or decreases the space between characters in a text by the specified amount (tracking).
+	 * @protected
+	 * @since 5.9.000 (2010-09-29)
+	 */
+	protected $font_spacing = 0;
+
+	/**
+	 * Array of no-write regions.
+	 * ('page' => page number or empy for current page, 'xt' => X top, 'yt' => Y top, 'xb' => X bottom, 'yb' => Y bottom, 'side' => page side 'L' = left or 'R' = right)
+	 * @protected
+	 * @since 5.9.003 (2010-10-14)
+	 */
+	protected $page_regions = array();
+
+	/**
+	 * Boolean value true when page region check is active.
+	 * @protected
+	 */
+	protected $check_page_regions = true;
+
+	/**
+	 * Array containing HTML color names and values.
+	 * @protected
+	 * @since 5.9.004 (2010-10-18)
+	 */
+	protected $webcolor = array();
+
+	/**
+	 * Array containing spot color names and values.
+	 * @protected
+	 * @since 5.9.012 (2010-11-11)
+	 */
+	protected $spotcolor = array();
+
+	/**
+	 * Array of PDF layers data.
+	 * @protected
+	 * @since 5.9.102 (2011-07-13)
+	 */
+	protected $pdflayers = array();
+
+	/**
+	 * A dictionary of names and corresponding destinations (Dests key on document Catalog).
+	 * @protected
+	 * @since 5.9.097 (2011-06-23)
+	 */
+	protected $dests = array();
+
+	/**
+	 * Object ID for Named Destinations
+	 * @protected
+	 * @since 5.9.097 (2011-06-23)
+	 */
+	protected $n_dests;
+
+	/**
+	 * Embedded Files Names
+	 * @protected
+	 * @since 5.9.204 (2013-01-23)
+	 */
+	protected $efnames = array();
+
+	/**
+	 * Directory used for the last SVG image.
+	 * @protected
+	 * @since 5.0.000 (2010-05-05)
+	 */
+	protected $svgdir = '';
+
+	/**
+	 *  Deafult unit of measure for SVG.
+	 * @protected
+	 * @since 5.0.000 (2010-05-02)
+	 */
+	protected $svgunit = 'px';
+
+	/**
+	 * Array of SVG gradients.
+	 * @protected
+	 * @since 5.0.000 (2010-05-02)
+	 */
+	protected $svggradients = array();
+
+	/**
+	 * ID of last SVG gradient.
+	 * @protected
+	 * @since 5.0.000 (2010-05-02)
+	 */
+	protected $svggradientid = 0;
+
+	/**
+	 * Boolean value true when in SVG defs group.
+	 * @protected
+	 * @since 5.0.000 (2010-05-02)
+	 */
+	protected $svgdefsmode = false;
+
+	/**
+	 * Array of SVG defs.
+	 * @protected
+	 * @since 5.0.000 (2010-05-02)
+	 */
+	protected $svgdefs = array();
+
+	/**
+	 * Boolean value true when in SVG clipPath tag.
+	 * @protected
+	 * @since 5.0.000 (2010-04-26)
+	 */
+	protected $svgclipmode = false;
+
+	/**
+	 * Array of SVG clipPath commands.
+	 * @protected
+	 * @since 5.0.000 (2010-05-02)
+	 */
+	protected $svgclippaths = array();
+
+	/**
+	 * Array of SVG clipPath tranformation matrix.
+	 * @protected
+	 * @since 5.8.022 (2010-08-31)
+	 */
+	protected $svgcliptm = array();
+
+	/**
+	 * ID of last SVG clipPath.
+	 * @protected
+	 * @since 5.0.000 (2010-05-02)
+	 */
+	protected $svgclipid = 0;
+
+	/**
+	 * SVG text.
+	 * @protected
+	 * @since 5.0.000 (2010-05-02)
+	 */
+	protected $svgtext = '';
+
+	/**
+	 * SVG text properties.
+	 * @protected
+	 * @since 5.8.013 (2010-08-23)
+	 */
+	protected $svgtextmode = array();
+
+	/**
+	 * Array of hinheritable SVG properties.
+	 * @protected
+	 * @since 5.0.000 (2010-05-02)
+	 */
+	protected $svginheritprop = array('clip-rule', 'color', 'color-interpolation', 'color-interpolation-filters', 'color-profile', 'color-rendering', 'cursor', 'direction', 'fill', 'fill-opacity', 'fill-rule', 'font', 'font-family', 'font-size', 'font-size-adjust', 'font-stretch', 'font-style', 'font-variant', 'font-weight', 'glyph-orientation-horizontal', 'glyph-orientation-vertical', 'image-rendering', 'kerning', 'letter-spacing', 'marker', 'marker-end', 'marker-mid', 'marker-start', 'poi [...]
+
+	/**
+	 * Array of SVG properties.
+	 * @protected
+	 * @since 5.0.000 (2010-05-02)
+	 */
+	protected $svgstyles = array(array(
+		'alignment-baseline' => 'auto',
+		'baseline-shift' => 'baseline',
+		'clip' => 'auto',
+		'clip-path' => 'none',
+		'clip-rule' => 'nonzero',
+		'color' => 'black',
+		'color-interpolation' => 'sRGB',
+		'color-interpolation-filters' => 'linearRGB',
+		'color-profile' => 'auto',
+		'color-rendering' => 'auto',
+		'cursor' => 'auto',
+		'direction' => 'ltr',
+		'display' => 'inline',
+		'dominant-baseline' => 'auto',
+		'enable-background' => 'accumulate',
+		'fill' => 'black',
+		'fill-opacity' => 1,
+		'fill-rule' => 'nonzero',
+		'filter' => 'none',
+		'flood-color' => 'black',
+		'flood-opacity' => 1,
+		'font' => '',
+		'font-family' => 'helvetica',
+		'font-size' => 'medium',
+		'font-size-adjust' => 'none',
+		'font-stretch' => 'normal',
+		'font-style' => 'normal',
+		'font-variant' => 'normal',
+		'font-weight' => 'normal',
+		'glyph-orientation-horizontal' => '0deg',
+		'glyph-orientation-vertical' => 'auto',
+		'image-rendering' => 'auto',
+		'kerning' => 'auto',
+		'letter-spacing' => 'normal',
+		'lighting-color' => 'white',
+		'marker' => '',
+		'marker-end' => 'none',
+		'marker-mid' => 'none',
+		'marker-start' => 'none',
+		'mask' => 'none',
+		'opacity' => 1,
+		'overflow' => 'auto',
+		'pointer-events' => 'visiblePainted',
+		'shape-rendering' => 'auto',
+		'stop-color' => 'black',
+		'stop-opacity' => 1,
+		'stroke' => 'none',
+		'stroke-dasharray' => 'none',
+		'stroke-dashoffset' => 0,
+		'stroke-linecap' => 'butt',
+		'stroke-linejoin' => 'miter',
+		'stroke-miterlimit' => 4,
+		'stroke-opacity' => 1,
+		'stroke-width' => 1,
+		'text-anchor' => 'start',
+		'text-decoration' => 'none',
+		'text-rendering' => 'auto',
+		'unicode-bidi' => 'normal',
+		'visibility' => 'visible',
+		'word-spacing' => 'normal',
+		'writing-mode' => 'lr-tb',
+		'text-color' => 'black',
+		'transfmatrix' => array(1, 0, 0, 1, 0, 0)
+		));
+
+	/**
+	 * If true force sRGB color profile for all document.
+	 * @protected
+	 * @since 5.9.121 (2011-09-28)
+	 */
+	protected $force_srgb = false;
+
+	/**
+	 * If true set the document to PDF/A mode.
+	 * @protected
+	 * @since 5.9.121 (2011-09-27)
+	 */
+	protected $pdfa_mode = false;
+
+	/**
+	 * Document creation date-time
+	 * @protected
+	 * @since 5.9.152 (2012-03-22)
+	 */
+	protected $doc_creation_timestamp;
+
+	/**
+	 * Document modification date-time
+	 * @protected
+	 * @since 5.9.152 (2012-03-22)
+	 */
+	protected $doc_modification_timestamp;
+
+	/**
+	 * Custom XMP data.
+	 * @protected
+	 * @since 5.9.128 (2011-10-06)
+	 */
+	protected $custom_xmp = '';
+
+	/**
+	 * Overprint mode array.
+	 * (Check the "Entries in a Graphics State Parameter Dictionary" on PDF 32000-1:2008).
+	 * @protected
+	 * @since 5.9.152 (2012-03-23)
+	 */
+	protected $overprint = array('OP' => false, 'op' => false, 'OPM' => 0);
+
+	/**
+	 * Alpha mode array.
+	 * (Check the "Entries in a Graphics State Parameter Dictionary" on PDF 32000-1:2008).
+	 * @protected
+	 * @since 5.9.152 (2012-03-23)
+	 */
+	protected $alpha = array('CA' => 1, 'ca' => 1, 'BM' => '/Normal', 'AIS' => false);
+
+	/**
+	 * Define the page boundaries boxes to be set on document.
+	 * @protected
+	 * @since 5.9.152 (2012-03-23)
+	 */
+	protected $page_boxes = array('MediaBox', 'CropBox', 'BleedBox', 'TrimBox', 'ArtBox');
+
+	/**
+	 * Set the document producer metadata.
+	 * @protected
+	 * @since 5.9.152 (2012-03-23)
+	 */
+	protected $pdfproducer;
+
+	/**
+	 * If true print TCPDF meta link.
+	 * @protected
+	 * @since 5.9.152 (2012-03-23)
+	 */
+	protected $tcpdflink = true;
+
+	/**
+	 * Cache array for computed GD gamma values.
+	 * @protected
+	 * @since 5.9.1632 (2012-06-05)
+	 */
+	protected $gdgammacache = array();
+
+	//------------------------------------------------------------
+	// METHODS
+	//------------------------------------------------------------
+
+	/**
+	 * This is the class constructor.
+	 * It allows to set up the page format, the orientation and the measure unit used in all the methods (except for the font sizes).
+	 * @param $orientation (string) page orientation. Possible values are (case insensitive):<ul><li>P or Portrait (default)</li><li>L or Landscape</li><li>'' (empty string) for automatic orientation</li></ul>
+	 * @param $unit (string) User measure unit. Possible values are:<ul><li>pt: point</li><li>mm: millimeter (default)</li><li>cm: centimeter</li><li>in: inch</li></ul><br />A point equals 1/72 of inch, that is to say about 0.35 mm (an inch being 2.54 cm). This is a very common unit in typography; font sizes are expressed in that unit.
+	 * @param $format (mixed) The format used for pages. It can be either: one of the string values specified at getPageSizeFromFormat() or an array of parameters specified at setPageFormat().
+	 * @param $unicode (boolean) TRUE means that the input text is unicode (default = true)
+	 * @param $encoding (string) Charset encoding; default is UTF-8.
+	 * @param $diskcache (boolean) If TRUE reduce the RAM memory usage by caching temporary data on filesystem (slower).
+	 * @param $pdfa (boolean) If TRUE set the document to PDF/A mode.
+	 * @public
+	 * @see getPageSizeFromFormat(), setPageFormat()
+	 */
+	public function __construct($orientation='P', $unit='mm', $format='A4', $unicode=true, $encoding='UTF-8', $diskcache=false, $pdfa=false) {
+		/* Set internal character encoding to ASCII */
+		if (function_exists('mb_internal_encoding') AND mb_internal_encoding()) {
+			$this->internal_encoding = mb_internal_encoding();
+			mb_internal_encoding('ASCII');
+		}
+		// get array of HTML colors
+		require(dirname(__FILE__).'/htmlcolors.php');
+		$this->webcolor = $webcolor;
+		// get array of custom spot colors
+		if (file_exists(dirname(__FILE__).'/spotcolors.php')) {
+			require(dirname(__FILE__).'/spotcolors.php');
+			$this->spotcolor = $spotcolor;
+		} else {
+			$this->spotcolor = array();
+		}
+		require_once(dirname(__FILE__).'/unicode_data.php');
+		$this->unicode = new TCPDF_UNICODE_DATA();
+		require_once(dirname(__FILE__).'/encodings_maps.php');
+		$this->encmaps = new TCPDF_ENCODING_MAPS();
+		$this->font_obj_ids = array();
+		$this->page_obj_id = array();
+		$this->form_obj_id = array();
+		// set pdf/a mode
+		$this->pdfa_mode = $pdfa;
+		$this->force_srgb = false;
+		// set disk caching
+		$this->diskcache = $diskcache ? true : false;
+		// set language direction
+		$this->rtl = false;
+		$this->tmprtl = false;
+		// some checks
+		$this->_dochecks();
+		// initialization of properties
+		$this->isunicode = $unicode;
+		$this->page = 0;
+		$this->transfmrk[0] = array();
+		$this->pagedim = array();
+		$this->n = 2;
+		$this->buffer = '';
+		$this->pages = array();
+		$this->state = 0;
+		$this->fonts = array();
+		$this->FontFiles = array();
+		$this->diffs = array();
+		$this->images = array();
+		$this->links = array();
+		$this->gradients = array();
+		$this->InFooter = false;
+		$this->lasth = 0;
+		$this->FontFamily = defined('PDF_FONT_NAME_MAIN')?PDF_FONT_NAME_MAIN:'helvetica';
+		$this->FontStyle = '';
+		$this->FontSizePt = 12;
+		$this->underline = false;
+		$this->overline = false;
+		$this->linethrough = false;
+		$this->DrawColor = '0 G';
+		$this->FillColor = '0 g';
+		$this->TextColor = '0 g';
+		$this->ColorFlag = false;
+		$this->pdflayers = array();
+		// encryption values
+		$this->encrypted = false;
+		$this->last_enc_key = '';
+		// standard Unicode fonts
+		$this->CoreFonts = array(
+			'courier'=>'Courier',
+			'courierB'=>'Courier-Bold',
+			'courierI'=>'Courier-Oblique',
+			'courierBI'=>'Courier-BoldOblique',
+			'helvetica'=>'Helvetica',
+			'helveticaB'=>'Helvetica-Bold',
+			'helveticaI'=>'Helvetica-Oblique',
+			'helveticaBI'=>'Helvetica-BoldOblique',
+			'times'=>'Times-Roman',
+			'timesB'=>'Times-Bold',
+			'timesI'=>'Times-Italic',
+			'timesBI'=>'Times-BoldItalic',
+			'symbol'=>'Symbol',
+			'zapfdingbats'=>'ZapfDingbats'
+		);
+		// set scale factor
+		$this->setPageUnit($unit);
+		// set page format and orientation
+		$this->setPageFormat($format, $orientation);
+		// page margins (1 cm)
+		$margin = 28.35 / $this->k;
+		$this->SetMargins($margin, $margin);
+		$this->clMargin = $this->lMargin;
+		$this->crMargin = $this->rMargin;
+		// internal cell padding
+		$cpadding = $margin / 10;
+		$this->setCellPaddings($cpadding, 0, $cpadding, 0);
+		// cell margins
+		$this->setCellMargins(0, 0, 0, 0);
+		// line width (0.2 mm)
+		$this->LineWidth = 0.57 / $this->k;
+		$this->linestyleWidth = sprintf('%F w', ($this->LineWidth * $this->k));
+		$this->linestyleCap = '0 J';
+		$this->linestyleJoin = '0 j';
+		$this->linestyleDash = '[] 0 d';
+		// automatic page break
+		$this->SetAutoPageBreak(true, (2 * $margin));
+		// full width display mode
+		$this->SetDisplayMode('fullwidth');
+		// compression
+		$this->SetCompression();
+		// set default PDF version number
+		$this->setPDFVersion();
+		$this->pdfproducer = "\x54\x43\x50\x44\x46\x20".$this->tcpdf_version."\x20\x28\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x74\x63\x70\x64\x66\x2e\x6f\x72\x67\x29";
+		$this->tcpdflink = true;
+		$this->encoding = $encoding;
+		$this->HREF = array();
+		$this->getFontsList();
+		$this->fgcolor = array('R' => 0, 'G' => 0, 'B' => 0);
+		$this->strokecolor = array('R' => 0, 'G' => 0, 'B' => 0);
+		$this->bgcolor = array('R' => 255, 'G' => 255, 'B' => 255);
+		$this->extgstates = array();
+		$this->setTextShadow();
+		// user's rights
+		$this->sign = false;
+		$this->ur['enabled'] = false;
+		$this->ur['document'] = '/FullSave';
+		$this->ur['annots'] = '/Create/Delete/Modify/Copy/Import/Export';
+		$this->ur['form'] = '/Add/Delete/FillIn/Import/Export/SubmitStandalone/SpawnTemplate';
+		$this->ur['signature'] = '/Modify';
+		$this->ur['ef'] = '/Create/Delete/Modify/Import';
+		$this->ur['formex'] = '';
+		$this->signature_appearance = array('page' => 1, 'rect' => '0 0 0 0');
+		$this->empty_signature_appearance = array();
+		// set default JPEG quality
+		$this->jpeg_quality = 75;
+		// initialize some settings
+		$this->utf8Bidi(array(''), '');
+		// set default font
+		$this->SetFont($this->FontFamily, $this->FontStyle, $this->FontSizePt);
+		// check if PCRE Unicode support is enabled
+		if ($this->isunicode AND (@preg_match('/\pL/u', 'a') == 1)) {
+			// PCRE unicode support is turned ON
+			// \p{Z} or \p{Separator}: any kind of Unicode whitespace or invisible separator.
+			// \p{Lo} or \p{Other_Letter}: a Unicode letter or ideograph that does not have lowercase and uppercase variants.
+			// \p{Lo} is needed because Chinese characters are packed next to each other without spaces in between.
+			//$this->setSpacesRE('/[^\S\P{Z}\P{Lo}\xa0]/u');
+			$this->setSpacesRE('/[^\S\P{Z}\xa0]/u');
+		} else {
+			// PCRE unicode support is turned OFF
+			$this->setSpacesRE('/[^\S\xa0]/');
+		}
+		$this->default_form_prop = array('lineWidth'=>1, 'borderStyle'=>'solid', 'fillColor'=>array(255, 255, 255), 'strokeColor'=>array(128, 128, 128));
+		// set file ID for trailer
+		$serformat = (is_array($format) ? serialize($format) : $format);
+		$this->file_id = md5($this->getRandomSeed('TCPDF'.$orientation.$unit.$serformat.$encoding));
+		// set document creation and modification timestamp
+		$this->doc_creation_timestamp = time();
+		$this->doc_modification_timestamp = $this->doc_creation_timestamp;
+		// get default graphic vars
+		$this->default_graphic_vars = $this->getGraphicVars();
+		$this->header_xobj_autoreset = false;
+		$this->custom_xmp = '';
+	}
+
+	/**
+	 * Default destructor.
+	 * @public
+	 * @since 1.53.0.TC016
+	 */
+	public function __destruct() {
+		// restore internal encoding
+		if (isset($this->internal_encoding) AND !empty($this->internal_encoding)) {
+			mb_internal_encoding($this->internal_encoding);
+		}
+		// unset all class variables
+		$this->_destroy(true);
+	}
+
+	/**
+	 * Return the current TCPDF version.
+	 * @return TCPDF version string
+	 * @public
+	 * @since 5.9.012 (2010-11-10)
+	 */
+	public function getTCPDFVersion() {
+		return $this->tcpdf_version;
+	}
+
+	/**
+	 * Set the units of measure for the document.
+	 * @param $unit (string) User measure unit. Possible values are:<ul><li>pt: point</li><li>mm: millimeter (default)</li><li>cm: centimeter</li><li>in: inch</li></ul><br />A point equals 1/72 of inch, that is to say about 0.35 mm (an inch being 2.54 cm). This is a very common unit in typography; font sizes are expressed in that unit.
+	 * @public
+	 * @since 3.0.015 (2008-06-06)
+	 */
+	public function setPageUnit($unit) {
+		$unit = strtolower($unit);
+		//Set scale factor
+		switch ($unit) {
+			// points
+			case 'px':
+			case 'pt': {
+				$this->k = 1;
+				break;
+			}
+			// millimeters
+			case 'mm': {
+				$this->k = $this->dpi / 25.4;
+				break;
+			}
+			// centimeters
+			case 'cm': {
+				$this->k = $this->dpi / 2.54;
+				break;
+			}
+			// inches
+			case 'in': {
+				$this->k = $this->dpi;
+				break;
+			}
+			// unsupported unit
+			default : {
+				$this->Error('Incorrect unit: '.$unit);
+				break;
+			}
+		}
+		$this->pdfunit = $unit;
+		if (isset($this->CurOrientation)) {
+			$this->setPageOrientation($this->CurOrientation);
+		}
+	}
+
+	/**
+	 * Get page dimensions from format name.
+	 * @param $format (mixed) The format name. It can be: <ul>
+	 * <li><b>ISO 216 A Series + 2 SIS 014711 extensions</b></li>
+	 * <li>A0 (841x1189 mm ; 33.11x46.81 in)</li>
+	 * <li>A1 (594x841 mm ; 23.39x33.11 in)</li>
+	 * <li>A2 (420x594 mm ; 16.54x23.39 in)</li>
+	 * <li>A3 (297x420 mm ; 11.69x16.54 in)</li>
+	 * <li>A4 (210x297 mm ; 8.27x11.69 in)</li>
+	 * <li>A5 (148x210 mm ; 5.83x8.27 in)</li>
+	 * <li>A6 (105x148 mm ; 4.13x5.83 in)</li>
+	 * <li>A7 (74x105 mm ; 2.91x4.13 in)</li>
+	 * <li>A8 (52x74 mm ; 2.05x2.91 in)</li>
+	 * <li>A9 (37x52 mm ; 1.46x2.05 in)</li>
+	 * <li>A10 (26x37 mm ; 1.02x1.46 in)</li>
+	 * <li>A11 (18x26 mm ; 0.71x1.02 in)</li>
+	 * <li>A12 (13x18 mm ; 0.51x0.71 in)</li>
+	 * <li><b>ISO 216 B Series + 2 SIS 014711 extensions</b></li>
+	 * <li>B0 (1000x1414 mm ; 39.37x55.67 in)</li>
+	 * <li>B1 (707x1000 mm ; 27.83x39.37 in)</li>
+	 * <li>B2 (500x707 mm ; 19.69x27.83 in)</li>
+	 * <li>B3 (353x500 mm ; 13.90x19.69 in)</li>
+	 * <li>B4 (250x353 mm ; 9.84x13.90 in)</li>
+	 * <li>B5 (176x250 mm ; 6.93x9.84 in)</li>
+	 * <li>B6 (125x176 mm ; 4.92x6.93 in)</li>
+	 * <li>B7 (88x125 mm ; 3.46x4.92 in)</li>
+	 * <li>B8 (62x88 mm ; 2.44x3.46 in)</li>
+	 * <li>B9 (44x62 mm ; 1.73x2.44 in)</li>
+	 * <li>B10 (31x44 mm ; 1.22x1.73 in)</li>
+	 * <li>B11 (22x31 mm ; 0.87x1.22 in)</li>
+	 * <li>B12 (15x22 mm ; 0.59x0.87 in)</li>
+	 * <li><b>ISO 216 C Series + 2 SIS 014711 extensions + 2 EXTENSION</b></li>
+	 * <li>C0 (917x1297 mm ; 36.10x51.06 in)</li>
+	 * <li>C1 (648x917 mm ; 25.51x36.10 in)</li>
+	 * <li>C2 (458x648 mm ; 18.03x25.51 in)</li>
+	 * <li>C3 (324x458 mm ; 12.76x18.03 in)</li>
+	 * <li>C4 (229x324 mm ; 9.02x12.76 in)</li>
+	 * <li>C5 (162x229 mm ; 6.38x9.02 in)</li>
+	 * <li>C6 (114x162 mm ; 4.49x6.38 in)</li>
+	 * <li>C7 (81x114 mm ; 3.19x4.49 in)</li>
+	 * <li>C8 (57x81 mm ; 2.24x3.19 in)</li>
+	 * <li>C9 (40x57 mm ; 1.57x2.24 in)</li>
+	 * <li>C10 (28x40 mm ; 1.10x1.57 in)</li>
+	 * <li>C11 (20x28 mm ; 0.79x1.10 in)</li>
+	 * <li>C12 (14x20 mm ; 0.55x0.79 in)</li>
+	 * <li>C76 (81x162 mm ; 3.19x6.38 in)</li>
+	 * <li>DL (110x220 mm ; 4.33x8.66 in)</li>
+	 * <li><b>SIS 014711 E Series</b></li>
+	 * <li>E0 (879x1241 mm ; 34.61x48.86 in)</li>
+	 * <li>E1 (620x879 mm ; 24.41x34.61 in)</li>
+	 * <li>E2 (440x620 mm ; 17.32x24.41 in)</li>
+	 * <li>E3 (310x440 mm ; 12.20x17.32 in)</li>
+	 * <li>E4 (220x310 mm ; 8.66x12.20 in)</li>
+	 * <li>E5 (155x220 mm ; 6.10x8.66 in)</li>
+	 * <li>E6 (110x155 mm ; 4.33x6.10 in)</li>
+	 * <li>E7 (78x110 mm ; 3.07x4.33 in)</li>
+	 * <li>E8 (55x78 mm ; 2.17x3.07 in)</li>
+	 * <li>E9 (39x55 mm ; 1.54x2.17 in)</li>
+	 * <li>E10 (27x39 mm ; 1.06x1.54 in)</li>
+	 * <li>E11 (19x27 mm ; 0.75x1.06 in)</li>
+	 * <li>E12 (13x19 mm ; 0.51x0.75 in)</li>
+	 * <li><b>SIS 014711 G Series</b></li>
+	 * <li>G0 (958x1354 mm ; 37.72x53.31 in)</li>
+	 * <li>G1 (677x958 mm ; 26.65x37.72 in)</li>
+	 * <li>G2 (479x677 mm ; 18.86x26.65 in)</li>
+	 * <li>G3 (338x479 mm ; 13.31x18.86 in)</li>
+	 * <li>G4 (239x338 mm ; 9.41x13.31 in)</li>
+	 * <li>G5 (169x239 mm ; 6.65x9.41 in)</li>
+	 * <li>G6 (119x169 mm ; 4.69x6.65 in)</li>
+	 * <li>G7 (84x119 mm ; 3.31x4.69 in)</li>
+	 * <li>G8 (59x84 mm ; 2.32x3.31 in)</li>
+	 * <li>G9 (42x59 mm ; 1.65x2.32 in)</li>
+	 * <li>G10 (29x42 mm ; 1.14x1.65 in)</li>
+	 * <li>G11 (21x29 mm ; 0.83x1.14 in)</li>
+	 * <li>G12 (14x21 mm ; 0.55x0.83 in)</li>
+	 * <li><b>ISO Press</b></li>
+	 * <li>RA0 (860x1220 mm ; 33.86x48.03 in)</li>
+	 * <li>RA1 (610x860 mm ; 24.02x33.86 in)</li>
+	 * <li>RA2 (430x610 mm ; 16.93x24.02 in)</li>
+	 * <li>RA3 (305x430 mm ; 12.01x16.93 in)</li>
+	 * <li>RA4 (215x305 mm ; 8.46x12.01 in)</li>
+	 * <li>SRA0 (900x1280 mm ; 35.43x50.39 in)</li>
+	 * <li>SRA1 (640x900 mm ; 25.20x35.43 in)</li>
+	 * <li>SRA2 (450x640 mm ; 17.72x25.20 in)</li>
+	 * <li>SRA3 (320x450 mm ; 12.60x17.72 in)</li>
+	 * <li>SRA4 (225x320 mm ; 8.86x12.60 in)</li>
+	 * <li><b>German DIN 476</b></li>
+	 * <li>4A0 (1682x2378 mm ; 66.22x93.62 in)</li>
+	 * <li>2A0 (1189x1682 mm ; 46.81x66.22 in)</li>
+	 * <li><b>Variations on the ISO Standard</b></li>
+	 * <li>A2_EXTRA (445x619 mm ; 17.52x24.37 in)</li>
+	 * <li>A3+ (329x483 mm ; 12.95x19.02 in)</li>
+	 * <li>A3_EXTRA (322x445 mm ; 12.68x17.52 in)</li>
+	 * <li>A3_SUPER (305x508 mm ; 12.01x20.00 in)</li>
+	 * <li>SUPER_A3 (305x487 mm ; 12.01x19.17 in)</li>
+	 * <li>A4_EXTRA (235x322 mm ; 9.25x12.68 in)</li>
+	 * <li>A4_SUPER (229x322 mm ; 9.02x12.68 in)</li>
+	 * <li>SUPER_A4 (227x356 mm ; 8.94x14.02 in)</li>
+	 * <li>A4_LONG (210x348 mm ; 8.27x13.70 in)</li>
+	 * <li>F4 (210x330 mm ; 8.27x12.99 in)</li>
+	 * <li>SO_B5_EXTRA (202x276 mm ; 7.95x10.87 in)</li>
+	 * <li>A5_EXTRA (173x235 mm ; 6.81x9.25 in)</li>
+	 * <li><b>ANSI Series</b></li>
+	 * <li>ANSI_E (864x1118 mm ; 34.00x44.00 in)</li>
+	 * <li>ANSI_D (559x864 mm ; 22.00x34.00 in)</li>
+	 * <li>ANSI_C (432x559 mm ; 17.00x22.00 in)</li>
+	 * <li>ANSI_B (279x432 mm ; 11.00x17.00 in)</li>
+	 * <li>ANSI_A (216x279 mm ; 8.50x11.00 in)</li>
+	 * <li><b>Traditional 'Loose' North American Paper Sizes</b></li>
+	 * <li>LEDGER, USLEDGER (432x279 mm ; 17.00x11.00 in)</li>
+	 * <li>TABLOID, USTABLOID, BIBLE, ORGANIZERK (279x432 mm ; 11.00x17.00 in)</li>
+	 * <li>LETTER, USLETTER, ORGANIZERM (216x279 mm ; 8.50x11.00 in)</li>
+	 * <li>LEGAL, USLEGAL (216x356 mm ; 8.50x14.00 in)</li>
+	 * <li>GLETTER, GOVERNMENTLETTER (203x267 mm ; 8.00x10.50 in)</li>
+	 * <li>JLEGAL, JUNIORLEGAL (203x127 mm ; 8.00x5.00 in)</li>
+	 * <li><b>Other North American Paper Sizes</b></li>
+	 * <li>QUADDEMY (889x1143 mm ; 35.00x45.00 in)</li>
+	 * <li>SUPER_B (330x483 mm ; 13.00x19.00 in)</li>
+	 * <li>QUARTO (229x279 mm ; 9.00x11.00 in)</li>
+	 * <li>FOLIO, GOVERNMENTLEGAL (216x330 mm ; 8.50x13.00 in)</li>
+	 * <li>EXECUTIVE, MONARCH (184x267 mm ; 7.25x10.50 in)</li>
+	 * <li>MEMO, STATEMENT, ORGANIZERL (140x216 mm ; 5.50x8.50 in)</li>
+	 * <li>FOOLSCAP (210x330 mm ; 8.27x13.00 in)</li>
+	 * <li>COMPACT (108x171 mm ; 4.25x6.75 in)</li>
+	 * <li>ORGANIZERJ (70x127 mm ; 2.75x5.00 in)</li>
+	 * <li><b>Canadian standard CAN 2-9.60M</b></li>
+	 * <li>P1 (560x860 mm ; 22.05x33.86 in)</li>
+	 * <li>P2 (430x560 mm ; 16.93x22.05 in)</li>
+	 * <li>P3 (280x430 mm ; 11.02x16.93 in)</li>
+	 * <li>P4 (215x280 mm ; 8.46x11.02 in)</li>
+	 * <li>P5 (140x215 mm ; 5.51x8.46 in)</li>
+	 * <li>P6 (107x140 mm ; 4.21x5.51 in)</li>
+	 * <li><b>North American Architectural Sizes</b></li>
+	 * <li>ARCH_E (914x1219 mm ; 36.00x48.00 in)</li>
+	 * <li>ARCH_E1 (762x1067 mm ; 30.00x42.00 in)</li>
+	 * <li>ARCH_D (610x914 mm ; 24.00x36.00 in)</li>
+	 * <li>ARCH_C, BROADSHEET (457x610 mm ; 18.00x24.00 in)</li>
+	 * <li>ARCH_B (305x457 mm ; 12.00x18.00 in)</li>
+	 * <li>ARCH_A (229x305 mm ; 9.00x12.00 in)</li>
+	 * <li><b>Announcement Envelopes</b></li>
+	 * <li>ANNENV_A2 (111x146 mm ; 4.37x5.75 in)</li>
+	 * <li>ANNENV_A6 (121x165 mm ; 4.75x6.50 in)</li>
+	 * <li>ANNENV_A7 (133x184 mm ; 5.25x7.25 in)</li>
+	 * <li>ANNENV_A8 (140x206 mm ; 5.50x8.12 in)</li>
+	 * <li>ANNENV_A10 (159x244 mm ; 6.25x9.62 in)</li>
+	 * <li>ANNENV_SLIM (98x225 mm ; 3.87x8.87 in)</li>
+	 * <li><b>Commercial Envelopes</b></li>
+	 * <li>COMMENV_N6_1/4 (89x152 mm ; 3.50x6.00 in)</li>
+	 * <li>COMMENV_N6_3/4 (92x165 mm ; 3.62x6.50 in)</li>
+	 * <li>COMMENV_N8 (98x191 mm ; 3.87x7.50 in)</li>
+	 * <li>COMMENV_N9 (98x225 mm ; 3.87x8.87 in)</li>
+	 * <li>COMMENV_N10 (105x241 mm ; 4.12x9.50 in)</li>
+	 * <li>COMMENV_N11 (114x263 mm ; 4.50x10.37 in)</li>
+	 * <li>COMMENV_N12 (121x279 mm ; 4.75x11.00 in)</li>
+	 * <li>COMMENV_N14 (127x292 mm ; 5.00x11.50 in)</li>
+	 * <li><b>Catalogue Envelopes</b></li>
+	 * <li>CATENV_N1 (152x229 mm ; 6.00x9.00 in)</li>
+	 * <li>CATENV_N1_3/4 (165x241 mm ; 6.50x9.50 in)</li>
+	 * <li>CATENV_N2 (165x254 mm ; 6.50x10.00 in)</li>
+	 * <li>CATENV_N3 (178x254 mm ; 7.00x10.00 in)</li>
+	 * <li>CATENV_N6 (191x267 mm ; 7.50x10.50 in)</li>
+	 * <li>CATENV_N7 (203x279 mm ; 8.00x11.00 in)</li>
+	 * <li>CATENV_N8 (210x286 mm ; 8.25x11.25 in)</li>
+	 * <li>CATENV_N9_1/2 (216x267 mm ; 8.50x10.50 in)</li>
+	 * <li>CATENV_N9_3/4 (222x286 mm ; 8.75x11.25 in)</li>
+	 * <li>CATENV_N10_1/2 (229x305 mm ; 9.00x12.00 in)</li>
+	 * <li>CATENV_N12_1/2 (241x318 mm ; 9.50x12.50 in)</li>
+	 * <li>CATENV_N13_1/2 (254x330 mm ; 10.00x13.00 in)</li>
+	 * <li>CATENV_N14_1/4 (286x311 mm ; 11.25x12.25 in)</li>
+	 * <li>CATENV_N14_1/2 (292x368 mm ; 11.50x14.50 in)</li>
+	 * <li><b>Japanese (JIS P 0138-61) Standard B-Series</b></li>
+	 * <li>JIS_B0 (1030x1456 mm ; 40.55x57.32 in)</li>
+	 * <li>JIS_B1 (728x1030 mm ; 28.66x40.55 in)</li>
+	 * <li>JIS_B2 (515x728 mm ; 20.28x28.66 in)</li>
+	 * <li>JIS_B3 (364x515 mm ; 14.33x20.28 in)</li>
+	 * <li>JIS_B4 (257x364 mm ; 10.12x14.33 in)</li>
+	 * <li>JIS_B5 (182x257 mm ; 7.17x10.12 in)</li>
+	 * <li>JIS_B6 (128x182 mm ; 5.04x7.17 in)</li>
+	 * <li>JIS_B7 (91x128 mm ; 3.58x5.04 in)</li>
+	 * <li>JIS_B8 (64x91 mm ; 2.52x3.58 in)</li>
+	 * <li>JIS_B9 (45x64 mm ; 1.77x2.52 in)</li>
+	 * <li>JIS_B10 (32x45 mm ; 1.26x1.77 in)</li>
+	 * <li>JIS_B11 (22x32 mm ; 0.87x1.26 in)</li>
+	 * <li>JIS_B12 (16x22 mm ; 0.63x0.87 in)</li>
+	 * <li><b>PA Series</b></li>
+	 * <li>PA0 (840x1120 mm ; 33.07x44.09 in)</li>
+	 * <li>PA1 (560x840 mm ; 22.05x33.07 in)</li>
+	 * <li>PA2 (420x560 mm ; 16.54x22.05 in)</li>
+	 * <li>PA3 (280x420 mm ; 11.02x16.54 in)</li>
+	 * <li>PA4 (210x280 mm ; 8.27x11.02 in)</li>
+	 * <li>PA5 (140x210 mm ; 5.51x8.27 in)</li>
+	 * <li>PA6 (105x140 mm ; 4.13x5.51 in)</li>
+	 * <li>PA7 (70x105 mm ; 2.76x4.13 in)</li>
+	 * <li>PA8 (52x70 mm ; 2.05x2.76 in)</li>
+	 * <li>PA9 (35x52 mm ; 1.38x2.05 in)</li>
+	 * <li>PA10 (26x35 mm ; 1.02x1.38 in)</li>
+	 * <li><b>Standard Photographic Print Sizes</b></li>
+	 * <li>PASSPORT_PHOTO (35x45 mm ; 1.38x1.77 in)</li>
+	 * <li>E (82x120 mm ; 3.25x4.72 in)</li>
+	 * <li>3R, L (89x127 mm ; 3.50x5.00 in)</li>
+	 * <li>4R, KG (102x152 mm ; 4.02x5.98 in)</li>
+	 * <li>4D (120x152 mm ; 4.72x5.98 in)</li>
+	 * <li>5R, 2L (127x178 mm ; 5.00x7.01 in)</li>
+	 * <li>6R, 8P (152x203 mm ; 5.98x7.99 in)</li>
+	 * <li>8R, 6P (203x254 mm ; 7.99x10.00 in)</li>
+	 * <li>S8R, 6PW (203x305 mm ; 7.99x12.01 in)</li>
+	 * <li>10R, 4P (254x305 mm ; 10.00x12.01 in)</li>
+	 * <li>S10R, 4PW (254x381 mm ; 10.00x15.00 in)</li>
+	 * <li>11R (279x356 mm ; 10.98x14.02 in)</li>
+	 * <li>S11R (279x432 mm ; 10.98x17.01 in)</li>
+	 * <li>12R (305x381 mm ; 12.01x15.00 in)</li>
+	 * <li>S12R (305x456 mm ; 12.01x17.95 in)</li>
+	 * <li><b>Common Newspaper Sizes</b></li>
+	 * <li>NEWSPAPER_BROADSHEET (750x600 mm ; 29.53x23.62 in)</li>
+	 * <li>NEWSPAPER_BERLINER (470x315 mm ; 18.50x12.40 in)</li>
+	 * <li>NEWSPAPER_COMPACT, NEWSPAPER_TABLOID (430x280 mm ; 16.93x11.02 in)</li>
+	 * <li><b>Business Cards</b></li>
+	 * <li>CREDIT_CARD, BUSINESS_CARD, BUSINESS_CARD_ISO7810 (54x86 mm ; 2.13x3.37 in)</li>
+	 * <li>BUSINESS_CARD_ISO216 (52x74 mm ; 2.05x2.91 in)</li>
+	 * <li>BUSINESS_CARD_IT, BUSINESS_CARD_UK, BUSINESS_CARD_FR, BUSINESS_CARD_DE, BUSINESS_CARD_ES (55x85 mm ; 2.17x3.35 in)</li>
+	 * <li>BUSINESS_CARD_US, BUSINESS_CARD_CA (51x89 mm ; 2.01x3.50 in)</li>
+	 * <li>BUSINESS_CARD_JP (55x91 mm ; 2.17x3.58 in)</li>
+	 * <li>BUSINESS_CARD_HK (54x90 mm ; 2.13x3.54 in)</li>
+	 * <li>BUSINESS_CARD_AU, BUSINESS_CARD_DK, BUSINESS_CARD_SE (55x90 mm ; 2.17x3.54 in)</li>
+	 * <li>BUSINESS_CARD_RU, BUSINESS_CARD_CZ, BUSINESS_CARD_FI, BUSINESS_CARD_HU, BUSINESS_CARD_IL (50x90 mm ; 1.97x3.54 in)</li>
+	 * <li><b>Billboards</b></li>
+	 * <li>4SHEET (1016x1524 mm ; 40.00x60.00 in)</li>
+	 * <li>6SHEET (1200x1800 mm ; 47.24x70.87 in)</li>
+	 * <li>12SHEET (3048x1524 mm ; 120.00x60.00 in)</li>
+	 * <li>16SHEET (2032x3048 mm ; 80.00x120.00 in)</li>
+	 * <li>32SHEET (4064x3048 mm ; 160.00x120.00 in)</li>
+	 * <li>48SHEET (6096x3048 mm ; 240.00x120.00 in)</li>
+	 * <li>64SHEET (8128x3048 mm ; 320.00x120.00 in)</li>
+	 * <li>96SHEET (12192x3048 mm ; 480.00x120.00 in)</li>
+	 * <li><b>Old Imperial English (some are still used in USA)</b></li>
+	 * <li>EN_EMPEROR (1219x1829 mm ; 48.00x72.00 in)</li>
+	 * <li>EN_ANTIQUARIAN (787x1346 mm ; 31.00x53.00 in)</li>
+	 * <li>EN_GRAND_EAGLE (730x1067 mm ; 28.75x42.00 in)</li>
+	 * <li>EN_DOUBLE_ELEPHANT (679x1016 mm ; 26.75x40.00 in)</li>
+	 * <li>EN_ATLAS (660x864 mm ; 26.00x34.00 in)</li>
+	 * <li>EN_COLOMBIER (597x876 mm ; 23.50x34.50 in)</li>
+	 * <li>EN_ELEPHANT (584x711 mm ; 23.00x28.00 in)</li>
+	 * <li>EN_DOUBLE_DEMY (572x902 mm ; 22.50x35.50 in)</li>
+	 * <li>EN_IMPERIAL (559x762 mm ; 22.00x30.00 in)</li>
+	 * <li>EN_PRINCESS (546x711 mm ; 21.50x28.00 in)</li>
+	 * <li>EN_CARTRIDGE (533x660 mm ; 21.00x26.00 in)</li>
+	 * <li>EN_DOUBLE_LARGE_POST (533x838 mm ; 21.00x33.00 in)</li>
+	 * <li>EN_ROYAL (508x635 mm ; 20.00x25.00 in)</li>
+	 * <li>EN_SHEET, EN_HALF_POST (495x597 mm ; 19.50x23.50 in)</li>
+	 * <li>EN_SUPER_ROYAL (483x686 mm ; 19.00x27.00 in)</li>
+	 * <li>EN_DOUBLE_POST (483x775 mm ; 19.00x30.50 in)</li>
+	 * <li>EN_MEDIUM (445x584 mm ; 17.50x23.00 in)</li>
+	 * <li>EN_DEMY (445x572 mm ; 17.50x22.50 in)</li>
+	 * <li>EN_LARGE_POST (419x533 mm ; 16.50x21.00 in)</li>
+	 * <li>EN_COPY_DRAUGHT (406x508 mm ; 16.00x20.00 in)</li>
+	 * <li>EN_POST (394x489 mm ; 15.50x19.25 in)</li>
+	 * <li>EN_CROWN (381x508 mm ; 15.00x20.00 in)</li>
+	 * <li>EN_PINCHED_POST (375x470 mm ; 14.75x18.50 in)</li>
+	 * <li>EN_BRIEF (343x406 mm ; 13.50x16.00 in)</li>
+	 * <li>EN_FOOLSCAP (343x432 mm ; 13.50x17.00 in)</li>
+	 * <li>EN_SMALL_FOOLSCAP (337x419 mm ; 13.25x16.50 in)</li>
+	 * <li>EN_POTT (318x381 mm ; 12.50x15.00 in)</li>
+	 * <li><b>Old Imperial Belgian</b></li>
+	 * <li>BE_GRAND_AIGLE (700x1040 mm ; 27.56x40.94 in)</li>
+	 * <li>BE_COLOMBIER (620x850 mm ; 24.41x33.46 in)</li>
+	 * <li>BE_DOUBLE_CARRE (620x920 mm ; 24.41x36.22 in)</li>
+	 * <li>BE_ELEPHANT (616x770 mm ; 24.25x30.31 in)</li>
+	 * <li>BE_PETIT_AIGLE (600x840 mm ; 23.62x33.07 in)</li>
+	 * <li>BE_GRAND_JESUS (550x730 mm ; 21.65x28.74 in)</li>
+	 * <li>BE_JESUS (540x730 mm ; 21.26x28.74 in)</li>
+	 * <li>BE_RAISIN (500x650 mm ; 19.69x25.59 in)</li>
+	 * <li>BE_GRAND_MEDIAN (460x605 mm ; 18.11x23.82 in)</li>
+	 * <li>BE_DOUBLE_POSTE (435x565 mm ; 17.13x22.24 in)</li>
+	 * <li>BE_COQUILLE (430x560 mm ; 16.93x22.05 in)</li>
+	 * <li>BE_PETIT_MEDIAN (415x530 mm ; 16.34x20.87 in)</li>
+	 * <li>BE_RUCHE (360x460 mm ; 14.17x18.11 in)</li>
+	 * <li>BE_PROPATRIA (345x430 mm ; 13.58x16.93 in)</li>
+	 * <li>BE_LYS (317x397 mm ; 12.48x15.63 in)</li>
+	 * <li>BE_POT (307x384 mm ; 12.09x15.12 in)</li>
+	 * <li>BE_ROSETTE (270x347 mm ; 10.63x13.66 in)</li>
+	 * <li><b>Old Imperial French</b></li>
+	 * <li>FR_UNIVERS (1000x1300 mm ; 39.37x51.18 in)</li>
+	 * <li>FR_DOUBLE_COLOMBIER (900x1260 mm ; 35.43x49.61 in)</li>
+	 * <li>FR_GRANDE_MONDE (900x1260 mm ; 35.43x49.61 in)</li>
+	 * <li>FR_DOUBLE_SOLEIL (800x1200 mm ; 31.50x47.24 in)</li>
+	 * <li>FR_DOUBLE_JESUS (760x1120 mm ; 29.92x44.09 in)</li>
+	 * <li>FR_GRAND_AIGLE (750x1060 mm ; 29.53x41.73 in)</li>
+	 * <li>FR_PETIT_AIGLE (700x940 mm ; 27.56x37.01 in)</li>
+	 * <li>FR_DOUBLE_RAISIN (650x1000 mm ; 25.59x39.37 in)</li>
+	 * <li>FR_JOURNAL (650x940 mm ; 25.59x37.01 in)</li>
+	 * <li>FR_COLOMBIER_AFFICHE (630x900 mm ; 24.80x35.43 in)</li>
+	 * <li>FR_DOUBLE_CAVALIER (620x920 mm ; 24.41x36.22 in)</li>
+	 * <li>FR_CLOCHE (600x800 mm ; 23.62x31.50 in)</li>
+	 * <li>FR_SOLEIL (600x800 mm ; 23.62x31.50 in)</li>
+	 * <li>FR_DOUBLE_CARRE (560x900 mm ; 22.05x35.43 in)</li>
+	 * <li>FR_DOUBLE_COQUILLE (560x880 mm ; 22.05x34.65 in)</li>
+	 * <li>FR_JESUS (560x760 mm ; 22.05x29.92 in)</li>
+	 * <li>FR_RAISIN (500x650 mm ; 19.69x25.59 in)</li>
+	 * <li>FR_CAVALIER (460x620 mm ; 18.11x24.41 in)</li>
+	 * <li>FR_DOUBLE_COURONNE (460x720 mm ; 18.11x28.35 in)</li>
+	 * <li>FR_CARRE (450x560 mm ; 17.72x22.05 in)</li>
+	 * <li>FR_COQUILLE (440x560 mm ; 17.32x22.05 in)</li>
+	 * <li>FR_DOUBLE_TELLIERE (440x680 mm ; 17.32x26.77 in)</li>
+	 * <li>FR_DOUBLE_CLOCHE (400x600 mm ; 15.75x23.62 in)</li>
+	 * <li>FR_DOUBLE_POT (400x620 mm ; 15.75x24.41 in)</li>
+	 * <li>FR_ECU (400x520 mm ; 15.75x20.47 in)</li>
+	 * <li>FR_COURONNE (360x460 mm ; 14.17x18.11 in)</li>
+	 * <li>FR_TELLIERE (340x440 mm ; 13.39x17.32 in)</li>
+	 * <li>FR_POT (310x400 mm ; 12.20x15.75 in)</li>
+	 * </ul>
+	 * @return array containing page width and height in points
+	 * @public
+	 * @since 5.0.010 (2010-05-17)
+	 */
+	public function getPageSizeFromFormat($format) {
+		// Paper cordinates are calculated in this way: (inches * 72) where (1 inch = 25.4 mm)
+		switch (strtoupper($format)) {
+			// ISO 216 A Series + 2 SIS 014711 extensions
+			case 'A0' : {$pf = array( 2383.937, 3370.394); break;}
+			case 'A1' : {$pf = array( 1683.780, 2383.937); break;}
+			case 'A2' : {$pf = array( 1190.551, 1683.780); break;}
+			case 'A3' : {$pf = array(  841.890, 1190.551); break;}
+			case 'A4' : {$pf = array(  595.276,  841.890); break;}
+			case 'A5' : {$pf = array(  419.528,  595.276); break;}
+			case 'A6' : {$pf = array(  297.638,  419.528); break;}
+			case 'A7' : {$pf = array(  209.764,  297.638); break;}
+			case 'A8' : {$pf = array(  147.402,  209.764); break;}
+			case 'A9' : {$pf = array(  104.882,  147.402); break;}
+			case 'A10': {$pf = array(   73.701,  104.882); break;}
+			case 'A11': {$pf = array(   51.024,   73.701); break;}
+			case 'A12': {$pf = array(   36.850,   51.024); break;}
+			// ISO 216 B Series + 2 SIS 014711 extensions
+			case 'B0' : {$pf = array( 2834.646, 4008.189); break;}
+			case 'B1' : {$pf = array( 2004.094, 2834.646); break;}
+			case 'B2' : {$pf = array( 1417.323, 2004.094); break;}
+			case 'B3' : {$pf = array( 1000.630, 1417.323); break;}
+			case 'B4' : {$pf = array(  708.661, 1000.630); break;}
+			case 'B5' : {$pf = array(  498.898,  708.661); break;}
+			case 'B6' : {$pf = array(  354.331,  498.898); break;}
+			case 'B7' : {$pf = array(  249.449,  354.331); break;}
+			case 'B8' : {$pf = array(  175.748,  249.449); break;}
+			case 'B9' : {$pf = array(  124.724,  175.748); break;}
+			case 'B10': {$pf = array(   87.874,  124.724); break;}
+			case 'B11': {$pf = array(   62.362,   87.874); break;}
+			case 'B12': {$pf = array(   42.520,   62.362); break;}
+			// ISO 216 C Series + 2 SIS 014711 extensions + 2 EXTENSION
+			case 'C0' : {$pf = array( 2599.370, 3676.535); break;}
+			case 'C1' : {$pf = array( 1836.850, 2599.370); break;}
+			case 'C2' : {$pf = array( 1298.268, 1836.850); break;}
+			case 'C3' : {$pf = array(  918.425, 1298.268); break;}
+			case 'C4' : {$pf = array(  649.134,  918.425); break;}
+			case 'C5' : {$pf = array(  459.213,  649.134); break;}
+			case 'C6' : {$pf = array(  323.150,  459.213); break;}
+			case 'C7' : {$pf = array(  229.606,  323.150); break;}
+			case 'C8' : {$pf = array(  161.575,  229.606); break;}
+			case 'C9' : {$pf = array(  113.386,  161.575); break;}
+			case 'C10': {$pf = array(   79.370,  113.386); break;}
+			case 'C11': {$pf = array(   56.693,   79.370); break;}
+			case 'C12': {$pf = array(   39.685,   56.693); break;}
+			case 'C76': {$pf = array(  229.606,  459.213); break;}
+			case 'DL' : {$pf = array(  311.811,  623.622); break;}
+			// SIS 014711 E Series
+			case 'E0' : {$pf = array( 2491.654, 3517.795); break;}
+			case 'E1' : {$pf = array( 1757.480, 2491.654); break;}
+			case 'E2' : {$pf = array( 1247.244, 1757.480); break;}
+			case 'E3' : {$pf = array(  878.740, 1247.244); break;}
+			case 'E4' : {$pf = array(  623.622,  878.740); break;}
+			case 'E5' : {$pf = array(  439.370,  623.622); break;}
+			case 'E6' : {$pf = array(  311.811,  439.370); break;}
+			case 'E7' : {$pf = array(  221.102,  311.811); break;}
+			case 'E8' : {$pf = array(  155.906,  221.102); break;}
+			case 'E9' : {$pf = array(  110.551,  155.906); break;}
+			case 'E10': {$pf = array(   76.535,  110.551); break;}
+			case 'E11': {$pf = array(   53.858,   76.535); break;}
+			case 'E12': {$pf = array(   36.850,   53.858); break;}
+			// SIS 014711 G Series
+			case 'G0' : {$pf = array( 2715.591, 3838.110); break;}
+			case 'G1' : {$pf = array( 1919.055, 2715.591); break;}
+			case 'G2' : {$pf = array( 1357.795, 1919.055); break;}
+			case 'G3' : {$pf = array(  958.110, 1357.795); break;}
+			case 'G4' : {$pf = array(  677.480,  958.110); break;}
+			case 'G5' : {$pf = array(  479.055,  677.480); break;}
+			case 'G6' : {$pf = array(  337.323,  479.055); break;}
+			case 'G7' : {$pf = array(  238.110,  337.323); break;}
+			case 'G8' : {$pf = array(  167.244,  238.110); break;}
+			case 'G9' : {$pf = array(  119.055,  167.244); break;}
+			case 'G10': {$pf = array(   82.205,  119.055); break;}
+			case 'G11': {$pf = array(   59.528,   82.205); break;}
+			case 'G12': {$pf = array(   39.685,   59.528); break;}
+			// ISO Press
+			case 'RA0': {$pf = array( 2437.795, 3458.268); break;}
+			case 'RA1': {$pf = array( 1729.134, 2437.795); break;}
+			case 'RA2': {$pf = array( 1218.898, 1729.134); break;}
+			case 'RA3': {$pf = array(  864.567, 1218.898); break;}
+			case 'RA4': {$pf = array(  609.449,  864.567); break;}
+			case 'SRA0': {$pf = array( 2551.181, 3628.346); break;}
+			case 'SRA1': {$pf = array( 1814.173, 2551.181); break;}
+			case 'SRA2': {$pf = array( 1275.591, 1814.173); break;}
+			case 'SRA3': {$pf = array(  907.087, 1275.591); break;}
+			case 'SRA4': {$pf = array(  637.795,  907.087); break;}
+			// German  DIN 476
+			case '4A0': {$pf = array( 4767.874, 6740.787); break;}
+			case '2A0': {$pf = array( 3370.394, 4767.874); break;}
+			// Variations on the ISO Standard
+			case 'A2_EXTRA'   : {$pf = array( 1261.417, 1754.646); break;}
+			case 'A3+'        : {$pf = array(  932.598, 1369.134); break;}
+			case 'A3_EXTRA'   : {$pf = array(  912.756, 1261.417); break;}
+			case 'A3_SUPER'   : {$pf = array(  864.567, 1440.000); break;}
+			case 'SUPER_A3'   : {$pf = array(  864.567, 1380.472); break;}
+			case 'A4_EXTRA'   : {$pf = array(  666.142,  912.756); break;}
+			case 'A4_SUPER'   : {$pf = array(  649.134,  912.756); break;}
+			case 'SUPER_A4'   : {$pf = array(  643.465, 1009.134); break;}
+			case 'A4_LONG'    : {$pf = array(  595.276,  986.457); break;}
+			case 'F4'         : {$pf = array(  595.276,  935.433); break;}
+			case 'SO_B5_EXTRA': {$pf = array(  572.598,  782.362); break;}
+			case 'A5_EXTRA'   : {$pf = array(  490.394,  666.142); break;}
+			// ANSI Series
+			case 'ANSI_E': {$pf = array( 2448.000, 3168.000); break;}
+			case 'ANSI_D': {$pf = array( 1584.000, 2448.000); break;}
+			case 'ANSI_C': {$pf = array( 1224.000, 1584.000); break;}
+			case 'ANSI_B': {$pf = array(  792.000, 1224.000); break;}
+			case 'ANSI_A': {$pf = array(  612.000,  792.000); break;}
+			// Traditional 'Loose' North American Paper Sizes
+			case 'USLEDGER':
+			case 'LEDGER' : {$pf = array( 1224.000,  792.000); break;}
+			case 'ORGANIZERK':
+			case 'BIBLE':
+			case 'USTABLOID':
+			case 'TABLOID': {$pf = array(  792.000, 1224.000); break;}
+			case 'ORGANIZERM':
+			case 'USLETTER':
+			case 'LETTER' : {$pf = array(  612.000,  792.000); break;}
+			case 'USLEGAL':
+			case 'LEGAL'  : {$pf = array(  612.000, 1008.000); break;}
+			case 'GOVERNMENTLETTER':
+			case 'GLETTER': {$pf = array(  576.000,  756.000); break;}
+			case 'JUNIORLEGAL':
+			case 'JLEGAL' : {$pf = array(  576.000,  360.000); break;}
+			// Other North American Paper Sizes
+			case 'QUADDEMY': {$pf = array( 2520.000, 3240.000); break;}
+			case 'SUPER_B': {$pf = array(  936.000, 1368.000); break;}
+			case 'QUARTO': {$pf = array(  648.000,  792.000); break;}
+			case 'GOVERNMENTLEGAL':
+			case 'FOLIO': {$pf = array(  612.000,  936.000); break;}
+			case 'MONARCH':
+			case 'EXECUTIVE': {$pf = array(  522.000,  756.000); break;}
+			case 'ORGANIZERL':
+			case 'STATEMENT':
+			case 'MEMO': {$pf = array(  396.000,  612.000); break;}
+			case 'FOOLSCAP': {$pf = array(  595.440,  936.000); break;}
+			case 'COMPACT': {$pf = array(  306.000,  486.000); break;}
+			case 'ORGANIZERJ': {$pf = array(  198.000,  360.000); break;}
+			// Canadian standard CAN 2-9.60M
+			case 'P1': {$pf = array( 1587.402, 2437.795); break;}
+			case 'P2': {$pf = array( 1218.898, 1587.402); break;}
+			case 'P3': {$pf = array(  793.701, 1218.898); break;}
+			case 'P4': {$pf = array(  609.449,  793.701); break;}
+			case 'P5': {$pf = array(  396.850,  609.449); break;}
+			case 'P6': {$pf = array(  303.307,  396.850); break;}
+			// North American Architectural Sizes
+			case 'ARCH_E' : {$pf = array( 2592.000, 3456.000); break;}
+			case 'ARCH_E1': {$pf = array( 2160.000, 3024.000); break;}
+			case 'ARCH_D' : {$pf = array( 1728.000, 2592.000); break;}
+			case 'BROADSHEET':
+			case 'ARCH_C' : {$pf = array( 1296.000, 1728.000); break;}
+			case 'ARCH_B' : {$pf = array(  864.000, 1296.000); break;}
+			case 'ARCH_A' : {$pf = array(  648.000,  864.000); break;}
+			// --- North American Envelope Sizes ---
+			//   - Announcement Envelopes
+			case 'ANNENV_A2'  : {$pf = array(  314.640,  414.000); break;}
+			case 'ANNENV_A6'  : {$pf = array(  342.000,  468.000); break;}
+			case 'ANNENV_A7'  : {$pf = array(  378.000,  522.000); break;}
+			case 'ANNENV_A8'  : {$pf = array(  396.000,  584.640); break;}
+			case 'ANNENV_A10' : {$pf = array(  450.000,  692.640); break;}
+			case 'ANNENV_SLIM': {$pf = array(  278.640,  638.640); break;}
+			//   - Commercial Envelopes
+			case 'COMMENV_N6_1/4': {$pf = array(  252.000,  432.000); break;}
+			case 'COMMENV_N6_3/4': {$pf = array(  260.640,  468.000); break;}
+			case 'COMMENV_N8'    : {$pf = array(  278.640,  540.000); break;}
+			case 'COMMENV_N9'    : {$pf = array(  278.640,  638.640); break;}
+			case 'COMMENV_N10'   : {$pf = array(  296.640,  684.000); break;}
+			case 'COMMENV_N11'   : {$pf = array(  324.000,  746.640); break;}
+			case 'COMMENV_N12'   : {$pf = array(  342.000,  792.000); break;}
+			case 'COMMENV_N14'   : {$pf = array(  360.000,  828.000); break;}
+			//   - Catalogue Envelopes
+			case 'CATENV_N1'     : {$pf = array(  432.000,  648.000); break;}
+			case 'CATENV_N1_3/4' : {$pf = array(  468.000,  684.000); break;}
+			case 'CATENV_N2'     : {$pf = array(  468.000,  720.000); break;}
+			case 'CATENV_N3'     : {$pf = array(  504.000,  720.000); break;}
+			case 'CATENV_N6'     : {$pf = array(  540.000,  756.000); break;}
+			case 'CATENV_N7'     : {$pf = array(  576.000,  792.000); break;}
+			case 'CATENV_N8'     : {$pf = array(  594.000,  810.000); break;}
+			case 'CATENV_N9_1/2' : {$pf = array(  612.000,  756.000); break;}
+			case 'CATENV_N9_3/4' : {$pf = array(  630.000,  810.000); break;}
+			case 'CATENV_N10_1/2': {$pf = array(  648.000,  864.000); break;}
+			case 'CATENV_N12_1/2': {$pf = array(  684.000,  900.000); break;}
+			case 'CATENV_N13_1/2': {$pf = array(  720.000,  936.000); break;}
+			case 'CATENV_N14_1/4': {$pf = array(  810.000,  882.000); break;}
+			case 'CATENV_N14_1/2': {$pf = array(  828.000, 1044.000); break;}
+			// Japanese (JIS P 0138-61) Standard B-Series
+			case 'JIS_B0' : {$pf = array( 2919.685, 4127.244); break;}
+			case 'JIS_B1' : {$pf = array( 2063.622, 2919.685); break;}
+			case 'JIS_B2' : {$pf = array( 1459.843, 2063.622); break;}
+			case 'JIS_B3' : {$pf = array( 1031.811, 1459.843); break;}
+			case 'JIS_B4' : {$pf = array(  728.504, 1031.811); break;}
+			case 'JIS_B5' : {$pf = array(  515.906,  728.504); break;}
+			case 'JIS_B6' : {$pf = array(  362.835,  515.906); break;}
+			case 'JIS_B7' : {$pf = array(  257.953,  362.835); break;}
+			case 'JIS_B8' : {$pf = array(  181.417,  257.953); break;}
+			case 'JIS_B9' : {$pf = array(  127.559,  181.417); break;}
+			case 'JIS_B10': {$pf = array(   90.709,  127.559); break;}
+			case 'JIS_B11': {$pf = array(   62.362,   90.709); break;}
+			case 'JIS_B12': {$pf = array(   45.354,   62.362); break;}
+			// PA Series
+			case 'PA0' : {$pf = array( 2381.102, 3174.803,); break;}
+			case 'PA1' : {$pf = array( 1587.402, 2381.102); break;}
+			case 'PA2' : {$pf = array( 1190.551, 1587.402); break;}
+			case 'PA3' : {$pf = array(  793.701, 1190.551); break;}
+			case 'PA4' : {$pf = array(  595.276,  793.701); break;}
+			case 'PA5' : {$pf = array(  396.850,  595.276); break;}
+			case 'PA6' : {$pf = array(  297.638,  396.850); break;}
+			case 'PA7' : {$pf = array(  198.425,  297.638); break;}
+			case 'PA8' : {$pf = array(  147.402,  198.425); break;}
+			case 'PA9' : {$pf = array(   99.213,  147.402); break;}
+			case 'PA10': {$pf = array(   73.701,   99.213); break;}
+			// Standard Photographic Print Sizes
+			case 'PASSPORT_PHOTO': {$pf = array(   99.213,  127.559); break;}
+			case 'E'   : {$pf = array(  233.858,  340.157); break;}
+			case 'L':
+			case '3R'  : {$pf = array(  252.283,  360.000); break;}
+			case 'KG':
+			case '4R'  : {$pf = array(  289.134,  430.866); break;}
+			case '4D'  : {$pf = array(  340.157,  430.866); break;}
+			case '2L':
+			case '5R'  : {$pf = array(  360.000,  504.567); break;}
+			case '8P':
+			case '6R'  : {$pf = array(  430.866,  575.433); break;}
+			case '6P':
+			case '8R'  : {$pf = array(  575.433,  720.000); break;}
+			case '6PW':
+			case 'S8R' : {$pf = array(  575.433,  864.567); break;}
+			case '4P':
+			case '10R' : {$pf = array(  720.000,  864.567); break;}
+			case '4PW':
+			case 'S10R': {$pf = array(  720.000, 1080.000); break;}
+			case '11R' : {$pf = array(  790.866, 1009.134); break;}
+			case 'S11R': {$pf = array(  790.866, 1224.567); break;}
+			case '12R' : {$pf = array(  864.567, 1080.000); break;}
+			case 'S12R': {$pf = array(  864.567, 1292.598); break;}
+			// Common Newspaper Sizes
+			case 'NEWSPAPER_BROADSHEET': {$pf = array( 2125.984, 1700.787); break;}
+			case 'NEWSPAPER_BERLINER'  : {$pf = array( 1332.283,  892.913); break;}
+			case 'NEWSPAPER_TABLOID':
+			case 'NEWSPAPER_COMPACT'   : {$pf = array( 1218.898,  793.701); break;}
+			// Business Cards
+			case 'CREDIT_CARD':
+			case 'BUSINESS_CARD':
+			case 'BUSINESS_CARD_ISO7810': {$pf = array(  153.014,  242.646); break;}
+			case 'BUSINESS_CARD_ISO216' : {$pf = array(  147.402,  209.764); break;}
+			case 'BUSINESS_CARD_IT':
+			case 'BUSINESS_CARD_UK':
+			case 'BUSINESS_CARD_FR':
+			case 'BUSINESS_CARD_DE':
+			case 'BUSINESS_CARD_ES'     : {$pf = array(  155.906,  240.945); break;}
+			case 'BUSINESS_CARD_CA':
+			case 'BUSINESS_CARD_US'     : {$pf = array(  144.567,  252.283); break;}
+			case 'BUSINESS_CARD_JP'     : {$pf = array(  155.906,  257.953); break;}
+			case 'BUSINESS_CARD_HK'     : {$pf = array(  153.071,  255.118); break;}
+			case 'BUSINESS_CARD_AU':
+			case 'BUSINESS_CARD_DK':
+			case 'BUSINESS_CARD_SE'     : {$pf = array(  155.906,  255.118); break;}
+			case 'BUSINESS_CARD_RU':
+			case 'BUSINESS_CARD_CZ':
+			case 'BUSINESS_CARD_FI':
+			case 'BUSINESS_CARD_HU':
+			case 'BUSINESS_CARD_IL'     : {$pf = array(  141.732,  255.118); break;}
+			// Billboards
+			case '4SHEET' : {$pf = array( 2880.000, 4320.000); break;}
+			case '6SHEET' : {$pf = array( 3401.575, 5102.362); break;}
+			case '12SHEET': {$pf = array( 8640.000, 4320.000); break;}
+			case '16SHEET': {$pf = array( 5760.000, 8640.000); break;}
+			case '32SHEET': {$pf = array(11520.000, 8640.000); break;}
+			case '48SHEET': {$pf = array(17280.000, 8640.000); break;}
+			case '64SHEET': {$pf = array(23040.000, 8640.000); break;}
+			case '96SHEET': {$pf = array(34560.000, 8640.000); break;}
+			// Old European Sizes
+			//   - Old Imperial English Sizes
+			case 'EN_EMPEROR'          : {$pf = array( 3456.000, 5184.000); break;}
+			case 'EN_ANTIQUARIAN'      : {$pf = array( 2232.000, 3816.000); break;}
+			case 'EN_GRAND_EAGLE'      : {$pf = array( 2070.000, 3024.000); break;}
+			case 'EN_DOUBLE_ELEPHANT'  : {$pf = array( 1926.000, 2880.000); break;}
+			case 'EN_ATLAS'            : {$pf = array( 1872.000, 2448.000); break;}
+			case 'EN_COLOMBIER'        : {$pf = array( 1692.000, 2484.000); break;}
+			case 'EN_ELEPHANT'         : {$pf = array( 1656.000, 2016.000); break;}
+			case 'EN_DOUBLE_DEMY'      : {$pf = array( 1620.000, 2556.000); break;}
+			case 'EN_IMPERIAL'         : {$pf = array( 1584.000, 2160.000); break;}
+			case 'EN_PRINCESS'         : {$pf = array( 1548.000, 2016.000); break;}
+			case 'EN_CARTRIDGE'        : {$pf = array( 1512.000, 1872.000); break;}
+			case 'EN_DOUBLE_LARGE_POST': {$pf = array( 1512.000, 2376.000); break;}
+			case 'EN_ROYAL'            : {$pf = array( 1440.000, 1800.000); break;}
+			case 'EN_SHEET':
+			case 'EN_HALF_POST'        : {$pf = array( 1404.000, 1692.000); break;}
+			case 'EN_SUPER_ROYAL'      : {$pf = array( 1368.000, 1944.000); break;}
+			case 'EN_DOUBLE_POST'      : {$pf = array( 1368.000, 2196.000); break;}
+			case 'EN_MEDIUM'           : {$pf = array( 1260.000, 1656.000); break;}
+			case 'EN_DEMY'             : {$pf = array( 1260.000, 1620.000); break;}
+			case 'EN_LARGE_POST'       : {$pf = array( 1188.000, 1512.000); break;}
+			case 'EN_COPY_DRAUGHT'     : {$pf = array( 1152.000, 1440.000); break;}
+			case 'EN_POST'             : {$pf = array( 1116.000, 1386.000); break;}
+			case 'EN_CROWN'            : {$pf = array( 1080.000, 1440.000); break;}
+			case 'EN_PINCHED_POST'     : {$pf = array( 1062.000, 1332.000); break;}
+			case 'EN_BRIEF'            : {$pf = array(  972.000, 1152.000); break;}
+			case 'EN_FOOLSCAP'         : {$pf = array(  972.000, 1224.000); break;}
+			case 'EN_SMALL_FOOLSCAP'   : {$pf = array(  954.000, 1188.000); break;}
+			case 'EN_POTT'             : {$pf = array(  900.000, 1080.000); break;}
+			//   - Old Imperial Belgian Sizes
+			case 'BE_GRAND_AIGLE' : {$pf = array( 1984.252, 2948.031); break;}
+			case 'BE_COLOMBIER'   : {$pf = array( 1757.480, 2409.449); break;}
+			case 'BE_DOUBLE_CARRE': {$pf = array( 1757.480, 2607.874); break;}
+			case 'BE_ELEPHANT'    : {$pf = array( 1746.142, 2182.677); break;}
+			case 'BE_PETIT_AIGLE' : {$pf = array( 1700.787, 2381.102); break;}
+			case 'BE_GRAND_JESUS' : {$pf = array( 1559.055, 2069.291); break;}
+			case 'BE_JESUS'       : {$pf = array( 1530.709, 2069.291); break;}
+			case 'BE_RAISIN'      : {$pf = array( 1417.323, 1842.520); break;}
+			case 'BE_GRAND_MEDIAN': {$pf = array( 1303.937, 1714.961); break;}
+			case 'BE_DOUBLE_POSTE': {$pf = array( 1233.071, 1601.575); break;}
+			case 'BE_COQUILLE'    : {$pf = array( 1218.898, 1587.402); break;}
+			case 'BE_PETIT_MEDIAN': {$pf = array( 1176.378, 1502.362); break;}
+			case 'BE_RUCHE'       : {$pf = array( 1020.472, 1303.937); break;}
+			case 'BE_PROPATRIA'   : {$pf = array(  977.953, 1218.898); break;}
+			case 'BE_LYS'         : {$pf = array(  898.583, 1125.354); break;}
+			case 'BE_POT'         : {$pf = array(  870.236, 1088.504); break;}
+			case 'BE_ROSETTE'     : {$pf = array(  765.354,  983.622); break;}
+			//   - Old Imperial French Sizes
+			case 'FR_UNIVERS'          : {$pf = array( 2834.646, 3685.039); break;}
+			case 'FR_DOUBLE_COLOMBIER' : {$pf = array( 2551.181, 3571.654); break;}
+			case 'FR_GRANDE_MONDE'     : {$pf = array( 2551.181, 3571.654); break;}
+			case 'FR_DOUBLE_SOLEIL'    : {$pf = array( 2267.717, 3401.575); break;}
+			case 'FR_DOUBLE_JESUS'     : {$pf = array( 2154.331, 3174.803); break;}
+			case 'FR_GRAND_AIGLE'      : {$pf = array( 2125.984, 3004.724); break;}
+			case 'FR_PETIT_AIGLE'      : {$pf = array( 1984.252, 2664.567); break;}
+			case 'FR_DOUBLE_RAISIN'    : {$pf = array( 1842.520, 2834.646); break;}
+			case 'FR_JOURNAL'          : {$pf = array( 1842.520, 2664.567); break;}
+			case 'FR_COLOMBIER_AFFICHE': {$pf = array( 1785.827, 2551.181); break;}
+			case 'FR_DOUBLE_CAVALIER'  : {$pf = array( 1757.480, 2607.874); break;}
+			case 'FR_CLOCHE'           : {$pf = array( 1700.787, 2267.717); break;}
+			case 'FR_SOLEIL'           : {$pf = array( 1700.787, 2267.717); break;}
+			case 'FR_DOUBLE_CARRE'     : {$pf = array( 1587.402, 2551.181); break;}
+			case 'FR_DOUBLE_COQUILLE'  : {$pf = array( 1587.402, 2494.488); break;}
+			case 'FR_JESUS'            : {$pf = array( 1587.402, 2154.331); break;}
+			case 'FR_RAISIN'           : {$pf = array( 1417.323, 1842.520); break;}
+			case 'FR_CAVALIER'         : {$pf = array( 1303.937, 1757.480); break;}
+			case 'FR_DOUBLE_COURONNE'  : {$pf = array( 1303.937, 2040.945); break;}
+			case 'FR_CARRE'            : {$pf = array( 1275.591, 1587.402); break;}
+			case 'FR_COQUILLE'         : {$pf = array( 1247.244, 1587.402); break;}
+			case 'FR_DOUBLE_TELLIERE'  : {$pf = array( 1247.244, 1927.559); break;}
+			case 'FR_DOUBLE_CLOCHE'    : {$pf = array( 1133.858, 1700.787); break;}
+			case 'FR_DOUBLE_POT'       : {$pf = array( 1133.858, 1757.480); break;}
+			case 'FR_ECU'              : {$pf = array( 1133.858, 1474.016); break;}
+			case 'FR_COURONNE'         : {$pf = array( 1020.472, 1303.937); break;}
+			case 'FR_TELLIERE'         : {$pf = array(  963.780, 1247.244); break;}
+			case 'FR_POT'              : {$pf = array(  878.740, 1133.858); break;}
+			// DEFAULT ISO A4
+			default: {$pf = array(  595.276,  841.890); break;}
+		}
+		return $pf;
+	}
+
+	/**
+	 * Change the format of the current page
+	 * @param $format (mixed) The format used for pages. It can be either: one of the string values specified at getPageSizeFromFormat() documentation or an array of two numners (width, height) or an array containing the following measures and options:<ul>
+	 * <li>['format'] = page format name (one of the above);</li>
+	 * <li>['Rotate'] : The number of degrees by which the page shall be rotated clockwise when displayed or printed. The value shall be a multiple of 90.</li>
+	 * <li>['PZ'] : The page's preferred zoom (magnification) factor.</li>
+	 * <li>['MediaBox'] : the boundaries of the physical medium on which the page shall be displayed or printed:</li>
+	 * <li>['MediaBox']['llx'] : lower-left x coordinate in points</li>
+	 * <li>['MediaBox']['lly'] : lower-left y coordinate in points</li>
+	 * <li>['MediaBox']['urx'] : upper-right x coordinate in points</li>
+	 * <li>['MediaBox']['ury'] : upper-right y coordinate in points</li>
+	 * <li>['CropBox'] : the visible region of default user space:</li>
+	 * <li>['CropBox']['llx'] : lower-left x coordinate in points</li>
+	 * <li>['CropBox']['lly'] : lower-left y coordinate in points</li>
+	 * <li>['CropBox']['urx'] : upper-right x coordinate in points</li>
+	 * <li>['CropBox']['ury'] : upper-right y coordinate in points</li>
+	 * <li>['BleedBox'] : the region to which the contents of the page shall be clipped when output in a production environment:</li>
+	 * <li>['BleedBox']['llx'] : lower-left x coordinate in points</li>
+	 * <li>['BleedBox']['lly'] : lower-left y coordinate in points</li>
+	 * <li>['BleedBox']['urx'] : upper-right x coordinate in points</li>
+	 * <li>['BleedBox']['ury'] : upper-right y coordinate in points</li>
+	 * <li>['TrimBox'] : the intended dimensions of the finished page after trimming:</li>
+	 * <li>['TrimBox']['llx'] : lower-left x coordinate in points</li>
+	 * <li>['TrimBox']['lly'] : lower-left y coordinate in points</li>
+	 * <li>['TrimBox']['urx'] : upper-right x coordinate in points</li>
+	 * <li>['TrimBox']['ury'] : upper-right y coordinate in points</li>
+	 * <li>['ArtBox'] : the extent of the page's meaningful content:</li>
+	 * <li>['ArtBox']['llx'] : lower-left x coordinate in points</li>
+	 * <li>['ArtBox']['lly'] : lower-left y coordinate in points</li>
+	 * <li>['ArtBox']['urx'] : upper-right x coordinate in points</li>
+	 * <li>['ArtBox']['ury'] : upper-right y coordinate in points</li>
+	 * <li>['BoxColorInfo'] :specify the colours and other visual characteristics that should be used in displaying guidelines on the screen for each of the possible page boundaries other than the MediaBox:</li>
+	 * <li>['BoxColorInfo'][BOXTYPE]['C'] : an array of three numbers in the range 0-255, representing the components in the DeviceRGB colour space.</li>
+	 * <li>['BoxColorInfo'][BOXTYPE]['W'] : the guideline width in default user units</li>
+	 * <li>['BoxColorInfo'][BOXTYPE]['S'] : the guideline style: S = Solid; D = Dashed</li>
+	 * <li>['BoxColorInfo'][BOXTYPE]['D'] : dash array defining a pattern of dashes and gaps to be used in drawing dashed guidelines</li>
+	 * <li>['trans'] : the style and duration of the visual transition to use when moving from another page to the given page during a presentation</li>
+	 * <li>['trans']['Dur'] : The page's display duration (also called its advance timing): the maximum length of time, in seconds, that the page shall be displayed during presentations before the viewer application shall automatically advance to the next page.</li>
+	 * <li>['trans']['S'] : transition style : Split, Blinds, Box, Wipe, Dissolve, Glitter, R, Fly, Push, Cover, Uncover, Fade</li>
+	 * <li>['trans']['D'] : The duration of the transition effect, in seconds.</li>
+	 * <li>['trans']['Dm'] : (Split and Blinds transition styles only) The dimension in which the specified transition effect shall occur: H = Horizontal, V = Vertical. Default value: H.</li>
+	 * <li>['trans']['M'] : (Split, Box and Fly transition styles only) The direction of motion for the specified transition effect: I = Inward from the edges of the page, O = Outward from the center of the pageDefault value: I.</li>
+	 * <li>['trans']['Di'] : (Wipe, Glitter, Fly, Cover, Uncover and Push transition styles only) The direction in which the specified transition effect shall moves, expressed in degrees counterclockwise starting from a left-to-right direction. If the value is a number, it shall be one of: 0 = Left to right, 90 = Bottom to top (Wipe only), 180 = Right to left (Wipe only), 270 = Top to bottom, 315 = Top-left to bottom-right (Glitter only). If the value is a name, it shall be None, which is r [...]
+	 * <li>['trans']['SS'] : (Fly transition style only) The starting or ending scale at which the changes shall be drawn. If M specifies an inward transition, the scale of the changes drawn shall progress from SS to 1.0 over the course of the transition. If M specifies an outward transition, the scale of the changes drawn shall progress from 1.0 to SS over the course of the transition. Default: 1.0.</li>
+	 * <li>['trans']['B'] : (Fly transition style only) If true, the area that shall be flown in is rectangular and opaque. Default: false.</li>
+	 * </ul>
+	 * @param $orientation (string) page orientation. Possible values are (case insensitive):<ul>
+	 * <li>P or Portrait (default)</li>
+	 * <li>L or Landscape</li>
+	 * <li>'' (empty string) for automatic orientation</li>
+	 * </ul>
+	 * @protected
+	 * @since 3.0.015 (2008-06-06)
+	 * @see getPageSizeFromFormat()
+	 */
+	protected function setPageFormat($format, $orientation='P') {
+		if (!empty($format) AND isset($this->pagedim[$this->page])) {
+			// remove inherited values
+			unset($this->pagedim[$this->page]);
+		}
+		if (is_string($format)) {
+			// get page measures from format name
+			$pf = $this->getPageSizeFromFormat($format);
+			$this->fwPt = $pf[0];
+			$this->fhPt = $pf[1];
+		} else {
+			// the boundaries of the physical medium on which the page shall be displayed or printed
+			if (isset($format['MediaBox'])) {
+				$this->setPageBoxes($this->page, 'MediaBox', $format['MediaBox']['llx'], $format['MediaBox']['lly'], $format['MediaBox']['urx'], $format['MediaBox']['ury'], false);
+				$this->fwPt = (($format['MediaBox']['urx'] - $format['MediaBox']['llx']) * $this->k);
+				$this->fhPt = (($format['MediaBox']['ury'] - $format['MediaBox']['lly']) * $this->k);
+			} else {
+				if (isset($format[0]) AND is_numeric($format[0]) AND isset($format[1]) AND is_numeric($format[1])) {
+					$pf = array(($format[0] * $this->k), ($format[1] * $this->k));
+				} else {
+					if (!isset($format['format'])) {
+						// default value
+						$format['format'] = 'A4';
+					}
+					$pf = $this->getPageSizeFromFormat($format['format']);
+				}
+				$this->fwPt = $pf[0];
+				$this->fhPt = $pf[1];
+				$this->setPageBoxes($this->page, 'MediaBox', 0, 0, $this->fwPt, $this->fhPt, true);
+			}
+			// the visible region of default user space
+			if (isset($format['CropBox'])) {
+				$this->setPageBoxes($this->page, 'CropBox', $format['CropBox']['llx'], $format['CropBox']['lly'], $format['CropBox']['urx'], $format['CropBox']['ury'], false);
+			}
+			// the region to which the contents of the page shall be clipped when output in a production environment
+			if (isset($format['BleedBox'])) {
+				$this->setPageBoxes($this->page, 'BleedBox', $format['BleedBox']['llx'], $format['BleedBox']['lly'], $format['BleedBox']['urx'], $format['BleedBox']['ury'], false);
+			}
+			// the intended dimensions of the finished page after trimming
+			if (isset($format['TrimBox'])) {
+				$this->setPageBoxes($this->page, 'TrimBox', $format['TrimBox']['llx'], $format['TrimBox']['lly'], $format['TrimBox']['urx'], $format['TrimBox']['ury'], false);
+			}
+			// the page's meaningful content (including potential white space)
+			if (isset($format['ArtBox'])) {
+				$this->setPageBoxes($this->page, 'ArtBox', $format['ArtBox']['llx'], $format['ArtBox']['lly'], $format['ArtBox']['urx'], $format['ArtBox']['ury'], false);
+			}
+			// specify the colours and other visual characteristics that should be used in displaying guidelines on the screen for the various page boundaries
+			if (isset($format['BoxColorInfo'])) {
+				$this->pagedim[$this->page]['BoxColorInfo'] = $format['BoxColorInfo'];
+			}
+			if (isset($format['Rotate']) AND (($format['Rotate'] % 90) == 0)) {
+				// The number of degrees by which the page shall be rotated clockwise when displayed or printed. The value shall be a multiple of 90.
+				$this->pagedim[$this->page]['Rotate'] = intval($format['Rotate']);
+			}
+			if (isset($format['PZ'])) {
+				// The page's preferred zoom (magnification) factor
+				$this->pagedim[$this->page]['PZ'] = floatval($format['PZ']);
+			}
+			if (isset($format['trans'])) {
+				// The style and duration of the visual transition to use when moving from another page to the given page during a presentation
+				if (isset($format['trans']['Dur'])) {
+					// The page's display duration
+					$this->pagedim[$this->page]['trans']['Dur'] = floatval($format['trans']['Dur']);
+				}
+				$stansition_styles = array('Split', 'Blinds', 'Box', 'Wipe', 'Dissolve', 'Glitter', 'R', 'Fly', 'Push', 'Cover', 'Uncover', 'Fade');
+				if (isset($format['trans']['S']) AND in_array($format['trans']['S'], $stansition_styles)) {
+					// The transition style that shall be used when moving to this page from another during a presentation
+					$this->pagedim[$this->page]['trans']['S'] = $format['trans']['S'];
+					$valid_effect = array('Split', 'Blinds');
+					$valid_vals = array('H', 'V');
+					if (isset($format['trans']['Dm']) AND in_array($format['trans']['S'], $valid_effect) AND in_array($format['trans']['Dm'], $valid_vals)) {
+						$this->pagedim[$this->page]['trans']['Dm'] = $format['trans']['Dm'];
+					}
+					$valid_effect = array('Split', 'Box', 'Fly');
+					$valid_vals = array('I', 'O');
+					if (isset($format['trans']['M']) AND in_array($format['trans']['S'], $valid_effect) AND in_array($format['trans']['M'], $valid_vals)) {
+						$this->pagedim[$this->page]['trans']['M'] = $format['trans']['M'];
+					}
+					$valid_effect = array('Wipe', 'Glitter', 'Fly', 'Cover', 'Uncover', 'Push');
+					if (isset($format['trans']['Di']) AND in_array($format['trans']['S'], $valid_effect)) {
+						if (((($format['trans']['Di'] == 90) OR ($format['trans']['Di'] == 180)) AND ($format['trans']['S'] == 'Wipe'))
+							OR (($format['trans']['Di'] == 315) AND ($format['trans']['S'] == 'Glitter'))
+							OR (($format['trans']['Di'] == 0) OR ($format['trans']['Di'] == 270))) {
+							$this->pagedim[$this->page]['trans']['Di'] = intval($format['trans']['Di']);
+						}
+					}
+					if (isset($format['trans']['SS']) AND ($format['trans']['S'] == 'Fly')) {
+						$this->pagedim[$this->page]['trans']['SS'] = floatval($format['trans']['SS']);
+					}
+					if (isset($format['trans']['B']) AND ($format['trans']['B'] === true) AND ($format['trans']['S'] == 'Fly')) {
+						$this->pagedim[$this->page]['trans']['B'] = 'true';
+					}
+				} else {
+					$this->pagedim[$this->page]['trans']['S'] = 'R';
+				}
+				if (isset($format['trans']['D'])) {
+					// The duration of the transition effect, in seconds
+					$this->pagedim[$this->page]['trans']['D'] = floatval($format['trans']['D']);
+				} else {
+					$this->pagedim[$this->page]['trans']['D'] = 1;
+				}
+			}
+		}
+		$this->setPageOrientation($orientation);
+	}
+
+	/**
+	 * Set page boundaries.
+	 * @param $page (int) page number
+	 * @param $type (string) valid values are: <ul><li>'MediaBox' : the boundaries of the physical medium on which the page shall be displayed or printed;</li><li>'CropBox' : the visible region of default user space;</li><li>'BleedBox' : the region to which the contents of the page shall be clipped when output in a production environment;</li><li>'TrimBox' : the intended dimensions of the finished page after trimming;</li><li>'ArtBox' : the page's meaningful content (including potential whi [...]
+	 * @param $llx (float) lower-left x coordinate in user units
+	 * @param $lly (float) lower-left y coordinate in user units
+	 * @param $urx (float) upper-right x coordinate in user units
+	 * @param $ury (float) upper-right y coordinate in user units
+	 * @param $points (boolean) if true uses user units as unit of measure, otherwise uses PDF points
+	 * @public
+	 * @since 5.0.010 (2010-05-17)
+	 */
+	public function setPageBoxes($page, $type, $llx, $lly, $urx, $ury, $points=false) {
+		if (!isset($this->pagedim[$page])) {
+			// initialize array
+			$this->pagedim[$page] = array();
+		}
+		$pageboxes = array('MediaBox', 'CropBox', 'BleedBox', 'TrimBox', 'ArtBox');
+		if (!in_array($type, $pageboxes)) {
+			return;
+		}
+		if ($points) {
+			$k = 1;
+		} else {
+			$k = $this->k;
+		}
+		$this->pagedim[$page][$type]['llx'] = ($llx * $k);
+		$this->pagedim[$page][$type]['lly'] = ($lly * $k);
+		$this->pagedim[$page][$type]['urx'] = ($urx * $k);
+		$this->pagedim[$page][$type]['ury'] = ($ury * $k);
+	}
+
+	/**
+	 * Swap X and Y coordinates of page boxes (change page boxes orientation).
+	 * @param $page (int) page number
+	 * @protected
+	 * @since 5.0.010 (2010-05-17)
+	 */
+	protected function swapPageBoxCoordinates($page) {
+		$pageboxes = array('MediaBox', 'CropBox', 'BleedBox', 'TrimBox', 'ArtBox');
+		foreach ($pageboxes as $type) {
+			// swap X and Y coordinates
+			if (isset($this->pagedim[$page][$type])) {
+				$tmp = $this->pagedim[$page][$type]['llx'];
+				$this->pagedim[$page][$type]['llx'] = $this->pagedim[$page][$type]['lly'];
+				$this->pagedim[$page][$type]['lly'] = $tmp;
+				$tmp = $this->pagedim[$page][$type]['urx'];
+				$this->pagedim[$page][$type]['urx'] = $this->pagedim[$page][$type]['ury'];
+				$this->pagedim[$page][$type]['ury'] = $tmp;
+			}
+		}
+	}
+
+	/**
+	 * Set page orientation.
+	 * @param $orientation (string) page orientation. Possible values are (case insensitive):<ul><li>P or Portrait (default)</li><li>L or Landscape</li><li>'' (empty string) for automatic orientation</li></ul>
+	 * @param $autopagebreak (boolean) Boolean indicating if auto-page-break mode should be on or off.
+	 * @param $bottommargin (float) bottom margin of the page.
+	 * @public
+	 * @since 3.0.015 (2008-06-06)
+	 */
+	public function setPageOrientation($orientation, $autopagebreak='', $bottommargin='') {
+		if (!isset($this->pagedim[$this->page]['MediaBox'])) {
+			// the boundaries of the physical medium on which the page shall be displayed or printed
+			$this->setPageBoxes($this->page, 'MediaBox', 0, 0, $this->fwPt, $this->fhPt, true);
+		}
+		if (!isset($this->pagedim[$this->page]['CropBox'])) {
+			// the visible region of default user space
+			$this->setPageBoxes($this->page, 'CropBox', $this->pagedim[$this->page]['MediaBox']['llx'], $this->pagedim[$this->page]['MediaBox']['lly'], $this->pagedim[$this->page]['MediaBox']['urx'], $this->pagedim[$this->page]['MediaBox']['ury'], true);
+		}
+		if (!isset($this->pagedim[$this->page]['BleedBox'])) {
+			// the region to which the contents of the page shall be clipped when output in a production environment
+			$this->setPageBoxes($this->page, 'BleedBox', $this->pagedim[$this->page]['CropBox']['llx'], $this->pagedim[$this->page]['CropBox']['lly'], $this->pagedim[$this->page]['CropBox']['urx'], $this->pagedim[$this->page]['CropBox']['ury'], true);
+		}
+		if (!isset($this->pagedim[$this->page]['TrimBox'])) {
+			// the intended dimensions of the finished page after trimming
+			$this->setPageBoxes($this->page, 'TrimBox', $this->pagedim[$this->page]['CropBox']['llx'], $this->pagedim[$this->page]['CropBox']['lly'], $this->pagedim[$this->page]['CropBox']['urx'], $this->pagedim[$this->page]['CropBox']['ury'], true);
+		}
+		if (!isset($this->pagedim[$this->page]['ArtBox'])) {
+			// the page's meaningful content (including potential white space)
+			$this->setPageBoxes($this->page, 'ArtBox', $this->pagedim[$this->page]['CropBox']['llx'], $this->pagedim[$this->page]['CropBox']['lly'], $this->pagedim[$this->page]['CropBox']['urx'], $this->pagedim[$this->page]['CropBox']['ury'], true);
+		}
+		if (!isset($this->pagedim[$this->page]['Rotate'])) {
+			// The number of degrees by which the page shall be rotated clockwise when displayed or printed. The value shall be a multiple of 90.
+			$this->pagedim[$this->page]['Rotate'] = 0;
+		}
+		if (!isset($this->pagedim[$this->page]['PZ'])) {
+			// The page's preferred zoom (magnification) factor
+			$this->pagedim[$this->page]['PZ'] = 1;
+		}
+		if ($this->fwPt > $this->fhPt) {
+			// landscape
+			$default_orientation = 'L';
+		} else {
+			// portrait
+			$default_orientation = 'P';
+		}
+		$valid_orientations = array('P', 'L');
+		if (empty($orientation)) {
+			$orientation = $default_orientation;
+		} else {
+			$orientation = strtoupper($orientation{0});
+		}
+		if (in_array($orientation, $valid_orientations) AND ($orientation != $default_orientation)) {
+			$this->CurOrientation = $orientation;
+			$this->wPt = $this->fhPt;
+			$this->hPt = $this->fwPt;
+		} else {
+			$this->CurOrientation = $default_orientation;
+			$this->wPt = $this->fwPt;
+			$this->hPt = $this->fhPt;
+		}
+		if ((abs($this->pagedim[$this->page]['MediaBox']['urx'] - $this->hPt) < $this->feps) AND (abs($this->pagedim[$this->page]['MediaBox']['ury'] - $this->wPt) < $this->feps)){
+			// swap X and Y coordinates (change page orientation)
+			$this->swapPageBoxCoordinates($this->page);
+		}
+		$this->w = ($this->wPt / $this->k);
+		$this->h = ($this->hPt / $this->k);
+		if ($this->empty_string($autopagebreak)) {
+			if (isset($this->AutoPageBreak)) {
+				$autopagebreak = $this->AutoPageBreak;
+			} else {
+				$autopagebreak = true;
+			}
+		}
+		if ($this->empty_string($bottommargin)) {
+			if (isset($this->bMargin)) {
+				$bottommargin = $this->bMargin;
+			} else {
+				// default value = 2 cm
+				$bottommargin = 2 * 28.35 / $this->k;
+			}
+		}
+		$this->SetAutoPageBreak($autopagebreak, $bottommargin);
+		// store page dimensions
+		$this->pagedim[$this->page]['w'] = $this->wPt;
+		$this->pagedim[$this->page]['h'] = $this->hPt;
+		$this->pagedim[$this->page]['wk'] = $this->w;
+		$this->pagedim[$this->page]['hk'] = $this->h;
+		$this->pagedim[$this->page]['tm'] = $this->tMargin;
+		$this->pagedim[$this->page]['bm'] = $bottommargin;
+		$this->pagedim[$this->page]['lm'] = $this->lMargin;
+		$this->pagedim[$this->page]['rm'] = $this->rMargin;
+		$this->pagedim[$this->page]['pb'] = $autopagebreak;
+		$this->pagedim[$this->page]['or'] = $this->CurOrientation;
+		$this->pagedim[$this->page]['olm'] = $this->original_lMargin;
+		$this->pagedim[$this->page]['orm'] = $this->original_rMargin;
+	}
+
+	/**
+	 * Set regular expression to detect withespaces or word separators.
+	 * The pattern delimiter must be the forward-slash character "/".
+	 * Some example patterns are:
+	 * <pre>
+	 * Non-Unicode or missing PCRE unicode support: "/[^\S\xa0]/"
+	 * Unicode and PCRE unicode support: "/[^\S\P{Z}\xa0]/u"
+	 * Unicode and PCRE unicode support in Chinese mode: "/[^\S\P{Z}\P{Lo}\xa0]/u"
+	 * if PCRE unicode support is turned ON ("\P" is the negate class of "\p"):
+	 * "\p{Z}" or "\p{Separator}": any kind of Unicode whitespace or invisible separator.
+	 * "\p{Lo}" or "\p{Other_Letter}": a Unicode letter or ideograph that does not have lowercase and uppercase variants.
+	 * "\p{Lo}" is needed for Chinese characters because are packed next to each other without spaces in between.
+	 * </pre>
+	 * @param $re (string) regular expression (leave empty for default).
+	 * @public
+	 * @since 4.6.016 (2009-06-15)
+	 */
+	public function setSpacesRE($re='/[^\S\xa0]/') {
+		$this->re_spaces = $re;
+		$re_parts = explode('/', $re);
+		// get pattern parts
+		$this->re_space = array();
+		if (isset($re_parts[1]) AND !empty($re_parts[1])) {
+			$this->re_space['p'] = $re_parts[1];
+		} else {
+			$this->re_space['p'] = '[\s]';
+		}
+		// set pattern modifiers
+		if (isset($re_parts[2]) AND !empty($re_parts[2])) {
+			$this->re_space['m'] = $re_parts[2];
+		} else {
+			$this->re_space['m'] = '';
+		}
+	}
+
+	/**
+	 * Enable or disable Right-To-Left language mode
+	 * @param $enable (Boolean) if true enable Right-To-Left language mode.
+	 * @param $resetx (Boolean) if true reset the X position on direction change.
+	 * @public
+	 * @since 2.0.000 (2008-01-03)
+	 */
+	public function setRTL($enable, $resetx=true) {
+		$enable = $enable ? true : false;
+		$resetx = ($resetx AND ($enable != $this->rtl));
+		$this->rtl = $enable;
+		$this->tmprtl = false;
+		if ($resetx) {
+			$this->Ln(0);
+		}
+	}
+
+	/**
+	 * Return the RTL status
+	 * @return boolean
+	 * @public
+	 * @since 4.0.012 (2008-07-24)
+	 */
+	public function getRTL() {
+		return $this->rtl;
+	}
+
+	/**
+	 * Force temporary RTL language direction
+	 * @param $mode (mixed) can be false, 'L' for LTR or 'R' for RTL
+	 * @public
+	 * @since 2.1.000 (2008-01-09)
+	 */
+	public function setTempRTL($mode) {
+		$newmode = false;
+		switch (strtoupper($mode)) {
+			case 'LTR':
+			case 'L': {
+				if ($this->rtl) {
+					$newmode = 'L';
+				}
+				break;
+			}
+			case 'RTL':
+			case 'R': {
+				if (!$this->rtl) {
+					$newmode = 'R';
+				}
+				break;
+			}
+			case false:
+			default: {
+				$newmode = false;
+				break;
+			}
+		}
+		$this->tmprtl = $newmode;
+	}
+
+	/**
+	 * Return the current temporary RTL status
+	 * @return boolean
+	 * @public
+	 * @since 4.8.014 (2009-11-04)
+	 */
+	public function isRTLTextDir() {
+		return ($this->rtl OR ($this->tmprtl == 'R'));
+	}
+
+	/**
+	 * Set the last cell height.
+	 * @param $h (float) cell height.
+	 * @author Nicola Asuni
+	 * @public
+	 * @since 1.53.0.TC034
+	 */
+	public function setLastH($h) {
+		$this->lasth = $h;
+	}
+
+	/**
+	 * Reset the last cell height.
+	 * @public
+	 * @since 5.9.000 (2010-10-03)
+	 */
+	public function resetLastH() {
+		$this->lasth = ($this->FontSize * $this->cell_height_ratio) + $this->cell_padding['T'] + $this->cell_padding['B'];
+	}
+
+	/**
+	 * Get the last cell height.
+	 * @return last cell height
+	 * @public
+	 * @since 4.0.017 (2008-08-05)
+	 */
+	public function getLastH() {
+		return $this->lasth;
+	}
+
+	/**
+	 * Set the adjusting factor to convert pixels to user units.
+	 * @param $scale (float) adjusting factor to convert pixels to user units.
+	 * @author Nicola Asuni
+	 * @public
+	 * @since 1.5.2
+	 */
+	public function setImageScale($scale) {
+		$this->imgscale = $scale;
+	}
+
+	/**
+	 * Returns the adjusting factor to convert pixels to user units.
+	 * @return float adjusting factor to convert pixels to user units.
+	 * @author Nicola Asuni
+	 * @public
+	 * @since 1.5.2
+	 */
+	public function getImageScale() {
+		return $this->imgscale;
+	}
+
+	/**
+	 * Returns an array of page dimensions:
+	 * <ul><li>$this->pagedim[$this->page]['w'] = page width in points</li><li>$this->pagedim[$this->page]['h'] = height in points</li><li>$this->pagedim[$this->page]['wk'] = page width in user units</li><li>$this->pagedim[$this->page]['hk'] = page height in user units</li><li>$this->pagedim[$this->page]['tm'] = top margin</li><li>$this->pagedim[$this->page]['bm'] = bottom margin</li><li>$this->pagedim[$this->page]['lm'] = left margin</li><li>$this->pagedim[$this->page]['rm'] = right margin [...]
+	 * @param $pagenum (int) page number (empty = current page)
+	 * @return array of page dimensions.
+	 * @author Nicola Asuni
+	 * @public
+	 * @since 4.5.027 (2009-03-16)
+	 */
+	public function getPageDimensions($pagenum='') {
+		if (empty($pagenum)) {
+			$pagenum = $this->page;
+		}
+		return $this->pagedim[$pagenum];
+	}
+
+	/**
+	 * Returns the page width in units.
+	 * @param $pagenum (int) page number (empty = current page)
+	 * @return int page width.
+	 * @author Nicola Asuni
+	 * @public
+	 * @since 1.5.2
+	 * @see getPageDimensions()
+	 */
+	public function getPageWidth($pagenum='') {
+		if (empty($pagenum)) {
+			return $this->w;
+		}
+		return $this->pagedim[$pagenum]['w'];
+	}
+
+	/**
+	 * Returns the page height in units.
+	 * @param $pagenum (int) page number (empty = current page)
+	 * @return int page height.
+	 * @author Nicola Asuni
+	 * @public
+	 * @since 1.5.2
+	 * @see getPageDimensions()
+	 */
+	public function getPageHeight($pagenum='') {
+		if (empty($pagenum)) {
+			return $this->h;
+		}
+		return $this->pagedim[$pagenum]['h'];
+	}
+
+	/**
+	 * Returns the page break margin.
+	 * @param $pagenum (int) page number (empty = current page)
+	 * @return int page break margin.
+	 * @author Nicola Asuni
+	 * @public
+	 * @since 1.5.2
+	 * @see getPageDimensions()
+	 */
+	public function getBreakMargin($pagenum='') {
+		if (empty($pagenum)) {
+			return $this->bMargin;
+		}
+		return $this->pagedim[$pagenum]['bm'];
+	}
+
+	/**
+	 * Returns the scale factor (number of points in user unit).
+	 * @return int scale factor.
+	 * @author Nicola Asuni
+	 * @public
+	 * @since 1.5.2
+	 */
+	public function getScaleFactor() {
+		return $this->k;
+	}
+
+	/**
+	 * Defines the left, top and right margins.
+	 * @param $left (float) Left margin.
+	 * @param $top (float) Top margin.
+	 * @param $right (float) Right margin. Default value is the left one.
+	 * @param $keepmargins (boolean) if true overwrites the default page margins
+	 * @public
+	 * @since 1.0
+	 * @see SetLeftMargin(), SetTopMargin(), SetRightMargin(), SetAutoPageBreak()
+	 */
+	public function SetMargins($left, $top, $right=-1, $keepmargins=false) {
+		//Set left, top and right margins
+		$this->lMargin = $left;
+		$this->tMargin = $top;
+		if ($right == -1) {
+			$right = $left;
+		}
+		$this->rMargin = $right;
+		if ($keepmargins) {
+			// overwrite original values
+			$this->original_lMargin = $this->lMargin;
+			$this->original_rMargin = $this->rMargin;
+		}
+	}
+
+	/**
+	 * Defines the left margin. The method can be called before creating the first page. If the current abscissa gets out of page, it is brought back to the margin.
+	 * @param $margin (float) The margin.
+	 * @public
+	 * @since 1.4
+	 * @see SetTopMargin(), SetRightMargin(), SetAutoPageBreak(), SetMargins()
+	 */
+	public function SetLeftMargin($margin) {
+		//Set left margin
+		$this->lMargin = $margin;
+		if (($this->page > 0) AND ($this->x < $margin)) {
+			$this->x = $margin;
+		}
+	}
+
+	/**
+	 * Defines the top margin. The method can be called before creating the first page.
+	 * @param $margin (float) The margin.
+	 * @public
+	 * @since 1.5
+	 * @see SetLeftMargin(), SetRightMargin(), SetAutoPageBreak(), SetMargins()
+	 */
+	public function SetTopMargin($margin) {
+		//Set top margin
+		$this->tMargin = $margin;
+		if (($this->page > 0) AND ($this->y < $margin)) {
+			$this->y = $margin;
+		}
+	}
+
+	/**
+	 * Defines the right margin. The method can be called before creating the first page.
+	 * @param $margin (float) The margin.
+	 * @public
+	 * @since 1.5
+	 * @see SetLeftMargin(), SetTopMargin(), SetAutoPageBreak(), SetMargins()
+	 */
+	public function SetRightMargin($margin) {
+		$this->rMargin = $margin;
+		if (($this->page > 0) AND ($this->x > ($this->w - $margin))) {
+			$this->x = $this->w - $margin;
+		}
+	}
+
+	/**
+	 * Set the same internal Cell padding for top, right, bottom, left-
+	 * @param $pad (float) internal padding.
+	 * @public
+	 * @since 2.1.000 (2008-01-09)
+	 * @see getCellPaddings(), setCellPaddings()
+	 */
+	public function SetCellPadding($pad) {
+		if ($pad >= 0) {
+			$this->cell_padding['L'] = $pad;
+			$this->cell_padding['T'] = $pad;
+			$this->cell_padding['R'] = $pad;
+			$this->cell_padding['B'] = $pad;
+		}
+	}
+
+	/**
+	 * Set the internal Cell paddings.
+	 * @param $left (float) left padding
+	 * @param $top (float) top padding
+	 * @param $right (float) right padding
+	 * @param $bottom (float) bottom padding
+	 * @public
+	 * @since 5.9.000 (2010-10-03)
+	 * @see getCellPaddings(), SetCellPadding()
+	 */
+	public function setCellPaddings($left='', $top='', $right='', $bottom='') {
+		if (($left !== '') AND ($left >= 0)) {
+			$this->cell_padding['L'] = $left;
+		}
+		if (($top !== '') AND ($top >= 0)) {
+			$this->cell_padding['T'] = $top;
+		}
+		if (($right !== '') AND ($right >= 0)) {
+			$this->cell_padding['R'] = $right;
+		}
+		if (($bottom !== '') AND ($bottom >= 0)) {
+			$this->cell_padding['B'] = $bottom;
+		}
+	}
+
+	/**
+	 * Get the internal Cell padding array.
+	 * @return array of padding values
+	 * @public
+	 * @since 5.9.000 (2010-10-03)
+	 * @see setCellPaddings(), SetCellPadding()
+	 */
+	public function getCellPaddings() {
+		return $this->cell_padding;
+	}
+
+	/**
+	 * Set the internal Cell margins.
+	 * @param $left (float) left margin
+	 * @param $top (float) top margin
+	 * @param $right (float) right margin
+	 * @param $bottom (float) bottom margin
+	 * @public
+	 * @since 5.9.000 (2010-10-03)
+	 * @see getCellMargins()
+	 */
+	public function setCellMargins($left='', $top='', $right='', $bottom='') {
+		if (($left !== '') AND ($left >= 0)) {
+			$this->cell_margin['L'] = $left;
+		}
+		if (($top !== '') AND ($top >= 0)) {
+			$this->cell_margin['T'] = $top;
+		}
+		if (($right !== '') AND ($right >= 0)) {
+			$this->cell_margin['R'] = $right;
+		}
+		if (($bottom !== '') AND ($bottom >= 0)) {
+			$this->cell_margin['B'] = $bottom;
+		}
+	}
+
+	/**
+	 * Get the internal Cell margin array.
+	 * @return array of margin values
+	 * @public
+	 * @since 5.9.000 (2010-10-03)
+	 * @see setCellMargins()
+	 */
+	public function getCellMargins() {
+		return $this->cell_margin;
+	}
+
+	/**
+	 * Adjust the internal Cell padding array to take account of the line width.
+	 * @param $brd (mixed) Indicates if borders must be drawn around the cell. The value can be a number:<ul><li>0: no border (default)</li><li>1: frame</li></ul> or a string containing some or all of the following characters (in any order):<ul><li>L: left</li><li>T: top</li><li>R: right</li><li>B: bottom</li></ul> or an array of line styles for each border group - for example: array('LTRB' => array('width' => 2, 'cap' => 'butt', 'join' => 'miter', 'dash' => 0, 'color' => array(0, 0, 0)))
+	 * @return array of adjustments
+	 * @public
+	 * @since 5.9.000 (2010-10-03)
+	 */
+	protected function adjustCellPadding($brd=0) {
+		if (empty($brd)) {
+			return;
+		}
+		if (is_string($brd)) {
+			// convert string to array
+			$slen = strlen($brd);
+			$newbrd = array();
+			for ($i = 0; $i < $slen; ++$i) {
+				$newbrd[$brd[$i]] = true;
+			}
+			$brd = $newbrd;
+		} elseif (($brd === 1) OR ($brd === true) OR (is_numeric($brd) AND (intval($brd) > 0))) {
+			$brd = array('LRTB' => true);
+		}
+		if (!is_array($brd)) {
+			return;
+		}
+		// store current cell padding
+		$cp = $this->cell_padding;
+		// select border mode
+		if (isset($brd['mode'])) {
+			$mode = $brd['mode'];
+			unset($brd['mode']);
+		} else {
+			$mode = 'normal';
+		}
+		// process borders
+		foreach ($brd as $border => $style) {
+			$line_width = $this->LineWidth;
+			if (is_array($style) AND isset($style['width'])) {
+				// get border width
+				$line_width = $style['width'];
+			}
+			$adj = 0; // line width inside the cell
+			switch ($mode) {
+				case 'ext': {
+					$adj = 0;
+					break;
+				}
+				case 'int': {
+					$adj = $line_width;
+					break;
+				}
+				case 'normal':
+				default: {
+					$adj = ($line_width / 2);
+					break;
+				}
+			}
+			// correct internal cell padding if required to avoid overlap between text and lines
+			if ((strpos($border,'T') !== false) AND ($this->cell_padding['T'] < $adj)) {
+				$this->cell_padding['T'] = $adj;
+			}
+			if ((strpos($border,'R') !== false) AND ($this->cell_padding['R'] < $adj)) {
+				$this->cell_padding['R'] = $adj;
+			}
+			if ((strpos($border,'B') !== false) AND ($this->cell_padding['B'] < $adj)) {
+				$this->cell_padding['B'] = $adj;
+			}
+			if ((strpos($border,'L') !== false) AND ($this->cell_padding['L'] < $adj)) {
+				$this->cell_padding['L'] = $adj;
+			}
+		}
+		return array('T' => ($this->cell_padding['T'] - $cp['T']), 'R' => ($this->cell_padding['R'] - $cp['R']), 'B' => ($this->cell_padding['B'] - $cp['B']), 'L' => ($this->cell_padding['L'] - $cp['L']));
+	}
+
+	/**
+	 * Enables or disables the automatic page breaking mode. When enabling, the second parameter is the distance from the bottom of the page that defines the triggering limit. By default, the mode is on and the margin is 2 cm.
+	 * @param $auto (boolean) Boolean indicating if mode should be on or off.
+	 * @param $margin (float) Distance from the bottom of the page.
+	 * @public
+	 * @since 1.0
+	 * @see Cell(), MultiCell(), AcceptPageBreak()
+	 */
+	public function SetAutoPageBreak($auto, $margin=0) {
+		$this->AutoPageBreak = $auto ? true : false;
+		$this->bMargin = $margin;
+		$this->PageBreakTrigger = $this->h - $margin;
+	}
+
+	/**
+	 * Return the auto-page-break mode (true or false).
+	 * @return boolean auto-page-break mode
+	 * @public
+	 * @since 5.9.088
+	 */
+	public function getAutoPageBreak() {
+		return $this->AutoPageBreak;
+	}
+
+	/**
+	 * Defines the way the document is to be displayed by the viewer.
+	 * @param $zoom (mixed) The zoom to use. It can be one of the following string values or a number indicating the zooming factor to use. <ul><li>fullpage: displays the entire page on screen </li><li>fullwidth: uses maximum width of window</li><li>real: uses real size (equivalent to 100% zoom)</li><li>default: uses viewer default mode</li></ul>
+	 * @param $layout (string) The page layout. Possible values are:<ul><li>SinglePage Display one page at a time</li><li>OneColumn Display the pages in one column</li><li>TwoColumnLeft Display the pages in two columns, with odd-numbered pages on the left</li><li>TwoColumnRight Display the pages in two columns, with odd-numbered pages on the right</li><li>TwoPageLeft (PDF 1.5) Display the pages two at a time, with odd-numbered pages on the left</li><li>TwoPageRight (PDF 1.5) Display the pag [...]
+	 * @param $mode (string) A name object specifying how the document should be displayed when opened:<ul><li>UseNone Neither document outline nor thumbnail images visible</li><li>UseOutlines Document outline visible</li><li>UseThumbs Thumbnail images visible</li><li>FullScreen Full-screen mode, with no menu bar, window controls, or any other window visible</li><li>UseOC (PDF 1.5) Optional content group panel visible</li><li>UseAttachments (PDF 1.6) Attachments panel visible</li></ul>
+	 * @public
+	 * @since 1.2
+	 */
+	public function SetDisplayMode($zoom, $layout='SinglePage', $mode='UseNone') {
+		if (($zoom == 'fullpage') OR ($zoom == 'fullwidth') OR ($zoom == 'real') OR ($zoom == 'default') OR (!is_string($zoom))) {
+			$this->ZoomMode = $zoom;
+		} else {
+			$this->Error('Incorrect zoom display mode: '.$zoom);
+		}
+		switch ($layout) {
+			case 'default':
+			case 'single':
+			case 'SinglePage': {
+				$this->LayoutMode = 'SinglePage';
+				break;
+			}
+			case 'continuous':
+			case 'OneColumn': {
+				$this->LayoutMode = 'OneColumn';
+				break;
+			}
+			case 'two':
+			case 'TwoColumnLeft': {
+				$this->LayoutMode = 'TwoColumnLeft';
+				break;
+			}
+			case 'TwoColumnRight': {
+				$this->LayoutMode = 'TwoColumnRight';
+				break;
+			}
+			case 'TwoPageLeft': {
+				$this->LayoutMode = 'TwoPageLeft';
+				break;
+			}
+			case 'TwoPageRight': {
+				$this->LayoutMode = 'TwoPageRight';
+				break;
+			}
+			default: {
+				$this->LayoutMode = 'SinglePage';
+			}
+		}
+		switch ($mode) {
+			case 'UseNone': {
+				$this->PageMode = 'UseNone';
+				break;
+			}
+			case 'UseOutlines': {
+				$this->PageMode = 'UseOutlines';
+				break;
+			}
+			case 'UseThumbs': {
+				$this->PageMode = 'UseThumbs';
+				break;
+			}
+			case 'FullScreen': {
+				$this->PageMode = 'FullScreen';
+				break;
+			}
+			case 'UseOC': {
+				$this->PageMode = 'UseOC';
+				break;
+			}
+			case '': {
+				$this->PageMode = 'UseAttachments';
+				break;
+			}
+			default: {
+				$this->PageMode = 'UseNone';
+			}
+		}
+	}
+
+	/**
+	 * Activates or deactivates page compression. When activated, the internal representation of each page is compressed, which leads to a compression ratio of about 2 for the resulting document. Compression is on by default.
+	 * Note: the Zlib extension is required for this feature. If not present, compression will be turned off.
+	 * @param $compress (boolean) Boolean indicating if compression must be enabled.
+	 * @public
+	 * @since 1.4
+	 */
+	public function SetCompression($compress=true) {
+		if (function_exists('gzcompress')) {
+			$this->compress = $compress ? true : false;
+		} else {
+			$this->compress = false;
+		}
+	}
+
+	/**
+	 * Set flag to force sRGB_IEC61966-2.1 black scaled ICC color profile for the whole document.
+	 * @param $mode (boolean) If true force sRGB output intent.
+	 * @public
+	 * @since 5.9.121 (2011-09-28)
+	 */
+	public function setSRGBmode($mode=false) {
+		$this->force_srgb = $mode ? true : false;
+	}
+
+	/**
+	 * Turn on/off Unicode mode for document information dictionary (meta tags).
+	 * This has effect only when unicode mode is set to false.
+	 * @param $unicode (boolean) if true set the meta information in Unicode
+	 * @since 5.9.027 (2010-12-01)
+	 * @public
+	 */
+	public function SetDocInfoUnicode($unicode=true) {
+		$this->docinfounicode = $unicode ? true : false;
+	}
+
+	/**
+	 * Defines the title of the document.
+	 * @param $title (string) The title.
+	 * @public
+	 * @since 1.2
+	 * @see SetAuthor(), SetCreator(), SetKeywords(), SetSubject()
+	 */
+	public function SetTitle($title) {
+		$this->title = $title;
+	}
+
+	/**
+	 * Defines the subject of the document.
+	 * @param $subject (string) The subject.
+	 * @public
+	 * @since 1.2
+	 * @see SetAuthor(), SetCreator(), SetKeywords(), SetTitle()
+	 */
+	public function SetSubject($subject) {
+		$this->subject = $subject;
+	}
+
+	/**
+	 * Defines the author of the document.
+	 * @param $author (string) The name of the author.
+	 * @public
+	 * @since 1.2
+	 * @see SetCreator(), SetKeywords(), SetSubject(), SetTitle()
+	 */
+	public function SetAuthor($author) {
+		$this->author = $author;
+	}
+
+	/**
+	 * Associates keywords with the document, generally in the form 'keyword1 keyword2 ...'.
+	 * @param $keywords (string) The list of keywords.
+	 * @public
+	 * @since 1.2
+	 * @see SetAuthor(), SetCreator(), SetSubject(), SetTitle()
+	 */
+	public function SetKeywords($keywords) {
+		$this->keywords = $keywords;
+	}
+
+	/**
+	 * Defines the creator of the document. This is typically the name of the application that generates the PDF.
+	 * @param $creator (string) The name of the creator.
+	 * @public
+	 * @since 1.2
+	 * @see SetAuthor(), SetKeywords(), SetSubject(), SetTitle()
+	 */
+	public function SetCreator($creator) {
+		$this->creator = $creator;
+	}
+
+	/**
+	 * This method is automatically called in case of fatal error; it simply outputs the message and halts the execution. An inherited class may override it to customize the error handling but should always halt the script, or the resulting document would probably be invalid.
+	 * 2004-06-11 :: Nicola Asuni : changed bold tag with strong
+	 * @param $msg (string) The error message
+	 * @public
+	 * @since 1.0
+	 */
+	public function Error($msg) {
+		// unset all class variables
+		$this->_destroy(true);
+		$phpmainver = PHP_VERSION;
+		// exit program and print error
+		if ((intval($phpmainver[0]) < 5) OR !defined('K_TCPDF_THROW_EXCEPTION_ERROR') OR !K_TCPDF_THROW_EXCEPTION_ERROR) {
+			die('<strong>TCPDF ERROR: </strong>'.$msg);
+		} else {
+			throw new Exception('TCPDF ERROR: '.$msg);
+		}
+	}
+
+	/**
+	 * This method begins the generation of the PDF document.
+	 * It is not necessary to call it explicitly because AddPage() does it automatically.
+	 * Note: no page is created by this method
+	 * @public
+	 * @since 1.0
+	 * @see AddPage(), Close()
+	 */
+	public function Open() {
+		$this->state = 1;
+	}
+
+	/**
+	 * Terminates the PDF document.
+	 * It is not necessary to call this method explicitly because Output() does it automatically.
+	 * If the document contains no page, AddPage() is called to prevent from getting an invalid document.
+	 * @public
+	 * @since 1.0
+	 * @see Open(), Output()
+	 */
+	public function Close() {
+		if ($this->state == 3) {
+			return;
+		}
+		if ($this->page == 0) {
+			$this->AddPage();
+		}
+		$this->endLayer();
+		if ($this->tcpdflink) {
+			// save current graphic settings
+			$gvars = $this->getGraphicVars();
+			$this->setEqualColumns();
+			$this->lastpage(true);
+			$this->SetAutoPageBreak(false);
+			$this->x = 0;
+			$this->y = $this->h - (1 / $this->k);
+			$this->lMargin = 0;
+			$this->_out('q');
+			$font = defined('PDF_FONT_NAME_MAIN')?PDF_FONT_NAME_MAIN:'helvetica';
+			$this->SetFont($font, '', 1);
+			$this->setTextRenderingMode(0, false, false);
+			$msg = "\x50\x6f\x77\x65\x72\x65\x64\x20\x62\x79\x20\x54\x43\x50\x44\x46\x20\x28\x77\x77\x77\x2e\x74\x63\x70\x64\x66\x2e\x6f\x72\x67\x29";
+			$lnk = "\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x74\x63\x70\x64\x66\x2e\x6f\x72\x67";
+			$this->Cell(0, 0, $msg, 0, 0, 'L', 0, $lnk, 0, false, 'D', 'B');
+			$this->_out('Q');
+			// restore graphic settings
+			$this->setGraphicVars($gvars);
+		}
+		// close page
+		$this->endPage();
+		// close document
+		$this->_enddoc();
+		// unset all class variables (except critical ones)
+		$this->_destroy(false);
+	}
+
+	/**
+	 * Move pointer at the specified document page and update page dimensions.
+	 * @param $pnum (int) page number (1 ... numpages)
+	 * @param $resetmargins (boolean) if true reset left, right, top margins and Y position.
+	 * @public
+	 * @since 2.1.000 (2008-01-07)
+	 * @see getPage(), lastpage(), getNumPages()
+	 */
+	public function setPage($pnum, $resetmargins=false) {
+		if (($pnum == $this->page) AND ($this->state == 2)) {
+			return;
+		}
+		if (($pnum > 0) AND ($pnum <= $this->numpages)) {
+			$this->state = 2;
+			// save current graphic settings
+			//$gvars = $this->getGraphicVars();
+			$oldpage = $this->page;
+			$this->page = $pnum;
+			$this->wPt = $this->pagedim[$this->page]['w'];
+			$this->hPt = $this->pagedim[$this->page]['h'];
+			$this->w = $this->pagedim[$this->page]['wk'];
+			$this->h = $this->pagedim[$this->page]['hk'];
+			$this->tMargin = $this->pagedim[$this->page]['tm'];
+			$this->bMargin = $this->pagedim[$this->page]['bm'];
+			$this->original_lMargin = $this->pagedim[$this->page]['olm'];
+			$this->original_rMargin = $this->pagedim[$this->page]['orm'];
+			$this->AutoPageBreak = $this->pagedim[$this->page]['pb'];
+			$this->CurOrientation = $this->pagedim[$this->page]['or'];
+			$this->SetAutoPageBreak($this->AutoPageBreak, $this->bMargin);
+			// restore graphic settings
+			//$this->setGraphicVars($gvars);
+			if ($resetmargins) {
+				$this->lMargin = $this->pagedim[$this->page]['olm'];
+				$this->rMargin = $this->pagedim[$this->page]['orm'];
+				$this->SetY($this->tMargin);
+			} else {
+				// account for booklet mode
+				if ($this->pagedim[$this->page]['olm'] != $this->pagedim[$oldpage]['olm']) {
+					$deltam = $this->pagedim[$this->page]['olm'] - $this->pagedim[$this->page]['orm'];
+					$this->lMargin += $deltam;
+					$this->rMargin -= $deltam;
+				}
+			}
+		} else {
+			$this->Error('Wrong page number on setPage() function: '.$pnum);
+		}
+	}
+
+	/**
+	 * Reset pointer to the last document page.
+	 * @param $resetmargins (boolean) if true reset left, right, top margins and Y position.
+	 * @public
+	 * @since 2.0.000 (2008-01-04)
+	 * @see setPage(), getPage(), getNumPages()
+	 */
+	public function lastPage($resetmargins=false) {
+		$this->setPage($this->getNumPages(), $resetmargins);
+	}
+
+	/**
+	 * Get current document page number.
+	 * @return int page number
+	 * @public
+	 * @since 2.1.000 (2008-01-07)
+	 * @see setPage(), lastpage(), getNumPages()
+	 */
+	public function getPage() {
+		return $this->page;
+	}
+
+	/**
+	 * Get the total number of insered pages.
+	 * @return int number of pages
+	 * @public
+	 * @since 2.1.000 (2008-01-07)
+	 * @see setPage(), getPage(), lastpage()
+	 */
+	public function getNumPages() {
+		return $this->numpages;
+	}
+
+	/**
+	 * Adds a new TOC (Table Of Content) page to the document.
+	 * @param $orientation (string) page orientation.
+	 * @param $format (mixed) The format used for pages. It can be either: one of the string values specified at getPageSizeFromFormat() or an array of parameters specified at setPageFormat().
+	 * @param $keepmargins (boolean) if true overwrites the default page margins with the current margins
+	 * @public
+	 * @since 5.0.001 (2010-05-06)
+	 * @see AddPage(), startPage(), endPage(), endTOCPage()
+	 */
+	public function addTOCPage($orientation='', $format='', $keepmargins=false) {
+		$this->AddPage($orientation, $format, $keepmargins, true);
+	}
+
+	/**
+	 * Terminate the current TOC (Table Of Content) page
+	 * @public
+	 * @since 5.0.001 (2010-05-06)
+	 * @see AddPage(), startPage(), endPage(), addTOCPage()
+	 */
+	public function endTOCPage() {
+		$this->endPage(true);
+	}
+
+	/**
+	 * Adds a new page to the document. If a page is already present, the Footer() method is called first to output the footer (if enabled). Then the page is added, the current position set to the top-left corner according to the left and top margins (or top-right if in RTL mode), and Header() is called to display the header (if enabled).
+	 * The origin of the coordinate system is at the top-left corner (or top-right for RTL) and increasing ordinates go downwards.
+	 * @param $orientation (string) page orientation. Possible values are (case insensitive):<ul><li>P or PORTRAIT (default)</li><li>L or LANDSCAPE</li></ul>
+	 * @param $format (mixed) The format used for pages. It can be either: one of the string values specified at getPageSizeFromFormat() or an array of parameters specified at setPageFormat().
+	 * @param $keepmargins (boolean) if true overwrites the default page margins with the current margins
+	 * @param $tocpage (boolean) if true set the tocpage state to true (the added page will be used to display Table Of Content).
+	 * @public
+	 * @since 1.0
+	 * @see startPage(), endPage(), addTOCPage(), endTOCPage(), getPageSizeFromFormat(), setPageFormat()
+	 */
+	public function AddPage($orientation='', $format='', $keepmargins=false, $tocpage=false) {
+		if ($this->inxobj) {
+			// we are inside an XObject template
+			return;
+		}
+		if (!isset($this->original_lMargin) OR $keepmargins) {
+			$this->original_lMargin = $this->lMargin;
+		}
+		if (!isset($this->original_rMargin) OR $keepmargins) {
+			$this->original_rMargin = $this->rMargin;
+		}
+		// terminate previous page
+		$this->endPage();
+		// start new page
+		$this->startPage($orientation, $format, $tocpage);
+	}
+
+	/**
+	 * Terminate the current page
+	 * @param $tocpage (boolean) if true set the tocpage state to false (end the page used to display Table Of Content).
+	 * @public
+	 * @since 4.2.010 (2008-11-14)
+	 * @see AddPage(), startPage(), addTOCPage(), endTOCPage()
+	 */
+	public function endPage($tocpage=false) {
+		// check if page is already closed
+		if (($this->page == 0) OR ($this->numpages > $this->page) OR (!$this->pageopen[$this->page])) {
+			return;
+		}
+		// print page footer
+		$this->setFooter();
+		// close page
+		$this->_endpage();
+		// mark page as closed
+		$this->pageopen[$this->page] = false;
+		if ($tocpage) {
+			$this->tocpage = false;
+		}
+	}
+
+	/**
+	 * Starts a new page to the document. The page must be closed using the endPage() function.
+	 * The origin of the coordinate system is at the top-left corner and increasing ordinates go downwards.
+	 * @param $orientation (string) page orientation. Possible values are (case insensitive):<ul><li>P or PORTRAIT (default)</li><li>L or LANDSCAPE</li></ul>
+	 * @param $format (mixed) The format used for pages. It can be either: one of the string values specified at getPageSizeFromFormat() or an array of parameters specified at setPageFormat().
+	 * @param $tocpage (boolean) if true the page is designated to contain the Table-Of-Content.
+	 * @since 4.2.010 (2008-11-14)
+	 * @see AddPage(), endPage(), addTOCPage(), endTOCPage(), getPageSizeFromFormat(), setPageFormat()
+	 * @public
+	 */
+	public function startPage($orientation='', $format='', $tocpage=false) {
+		if ($tocpage) {
+			$this->tocpage = true;
+		}
+		// move page numbers of documents to be attached
+		if ($this->tocpage) {
+			// move reference to unexistent pages (used for page attachments)
+			// adjust outlines
+			$tmpoutlines = $this->outlines;
+			foreach ($tmpoutlines as $key => $outline) {
+				if ($outline['p'] > $this->numpages) {
+					$this->outlines[$key]['p'] = ($outline['p'] + 1);
+				}
+			}
+			// adjust dests
+			$tmpdests = $this->dests;
+			foreach ($tmpdests as $key => $dest) {
+				if ($dest['p'] > $this->numpages) {
+					$this->dests[$key]['p'] = ($dest['p'] + 1);
+				}
+			}
+			// adjust links
+			$tmplinks = $this->links;
+			foreach ($tmplinks as $key => $link) {
+				if ($link[0] > $this->numpages) {
+					$this->links[$key][0] = ($link[0] + 1);
+				}
+			}
+		}
+		if ($this->numpages > $this->page) {
+			// this page has been already added
+			$this->setPage($this->page + 1);
+			$this->SetY($this->tMargin);
+			return;
+		}
+		// start a new page
+		if ($this->state == 0) {
+			$this->Open();
+		}
+		++$this->numpages;
+		$this->swapMargins($this->booklet);
+		// save current graphic settings
+		$gvars = $this->getGraphicVars();
+		// start new page
+		$this->_beginpage($orientation, $format);
+		// mark page as open
+		$this->pageopen[$this->page] = true;
+		// restore graphic settings
+		$this->setGraphicVars($gvars);
+		// mark this point
+		$this->setPageMark();
+		// print page header
+		$this->setHeader();
+		// restore graphic settings
+		$this->setGraphicVars($gvars);
+		// mark this point
+		$this->setPageMark();
+		// print table header (if any)
+		$this->setTableHeader();
+		// set mark for empty page check
+		$this->emptypagemrk[$this->page]= $this->pagelen[$this->page];
+	}
+
+	/**
+	 * Set start-writing mark on current page stream used to put borders and fills.
+	 * Borders and fills are always created after content and inserted on the position marked by this method.
+	 * This function must be called after calling Image() function for a background image.
+	 * Background images must be always inserted before calling Multicell() or WriteHTMLCell() or WriteHTML() functions.
+	 * @public
+	 * @since 4.0.016 (2008-07-30)
+	 */
+	public function setPageMark() {
+		$this->intmrk[$this->page] = $this->pagelen[$this->page];
+		$this->bordermrk[$this->page] = $this->intmrk[$this->page];
+		$this->setContentMark();
+	}
+
+	/**
+	 * Set start-writing mark on selected page.
+	 * Borders and fills are always created after content and inserted on the position marked by this method.
+	 * @param $page (int) page number (default is the current page)
+	 * @protected
+	 * @since 4.6.021 (2009-07-20)
+	 */
+	protected function setContentMark($page=0) {
+		if ($page <= 0) {
+			$page = $this->page;
+		}
+		if (isset($this->footerlen[$page])) {
+			$this->cntmrk[$page] = $this->pagelen[$page] - $this->footerlen[$page];
+		} else {
+			$this->cntmrk[$page] = $this->pagelen[$page];
+		}
+	}
+
+	/**
+	 * Set header data.
+	 * @param $ln (string) header image logo
+	 * @param $lw (string) header image logo width in mm
+	 * @param $ht (string) string to print as title on document header
+	 * @param $hs (string) string to print on document header
+	 * @param $tc (array) RGB array color for text.
+	 * @param $lc (array) RGB array color for line.
+	 * @public
+	 */
+	public function setHeaderData($ln='', $lw=0, $ht='', $hs='', $tc=array(0,0,0), $lc=array(0,0,0)) {
+		$this->header_logo = $ln;
+		$this->header_logo_width = $lw;
+		$this->header_title = $ht;
+		$this->header_string = $hs;
+		$this->header_text_color = $tc;
+		$this->header_line_color = $lc;
+	}
+
+	/**
+	 * Set footer data.
+	 * @param $tc (array) RGB array color for text.
+	 * @param $lc (array) RGB array color for line.
+	 * @public
+	 */
+	public function setFooterData($tc=array(0,0,0), $lc=array(0,0,0)) {
+		$this->footer_text_color = $tc;
+		$this->footer_line_color = $lc;
+	}
+
+	/**
+	 * Returns header data:
+	 * <ul><li>$ret['logo'] = logo image</li><li>$ret['logo_width'] = width of the image logo in user units</li><li>$ret['title'] = header title</li><li>$ret['string'] = header description string</li></ul>
+	 * @return array()
+	 * @public
+	 * @since 4.0.012 (2008-07-24)
+	 */
+	public function getHeaderData() {
+		$ret = array();
+		$ret['logo'] = $this->header_logo;
+		$ret['logo_width'] = $this->header_logo_width;
+		$ret['title'] = $this->header_title;
+		$ret['string'] = $this->header_string;
+		$ret['text_color'] = $this->header_text_color;
+		$ret['line_color'] = $this->header_line_color;
+		return $ret;
+	}
+
+	/**
+	 * Set header margin.
+	 * (minimum distance between header and top page margin)
+	 * @param $hm (int) distance in user units
+	 * @public
+	 */
+	public function setHeaderMargin($hm=10) {
+		$this->header_margin = $hm;
+	}
+
+	/**
+	 * Returns header margin in user units.
+	 * @return float
+	 * @since 4.0.012 (2008-07-24)
+	 * @public
+	 */
+	public function getHeaderMargin() {
+		return $this->header_margin;
+	}
+
+	/**
+	 * Set footer margin.
+	 * (minimum distance between footer and bottom page margin)
+	 * @param $fm (int) distance in user units
+	 * @public
+	 */
+	public function setFooterMargin($fm=10) {
+		$this->footer_margin = $fm;
+	}
+
+	/**
+	 * Returns footer margin in user units.
+	 * @return float
+	 * @since 4.0.012 (2008-07-24)
+	 * @public
+	 */
+	public function getFooterMargin() {
+		return $this->footer_margin;
+	}
+	/**
+	 * Set a flag to print page header.
+	 * @param $val (boolean) set to true to print the page header (default), false otherwise.
+	 * @public
+	 */
+	public function setPrintHeader($val=true) {
+		$this->print_header = $val ? true : false;
+	}
+
+	/**
+	 * Set a flag to print page footer.
+	 * @param $val (boolean) set to true to print the page footer (default), false otherwise.
+	 * @public
+	 */
+	public function setPrintFooter($val=true) {
+		$this->print_footer = $val ? true : false;
+	}
+
+	/**
+	 * Return the right-bottom (or left-bottom for RTL) corner X coordinate of last inserted image
+	 * @return float
+	 * @public
+	 */
+	public function getImageRBX() {
+		return $this->img_rb_x;
+	}
+
+	/**
+	 * Return the right-bottom (or left-bottom for RTL) corner Y coordinate of last inserted image
+	 * @return float
+	 * @public
+	 */
+	public function getImageRBY() {
+		return $this->img_rb_y;
+	}
+
+	/**
+	 * Reset the xobject template used by Header() method.
+	 * @public
+	 */
+	public function resetHeaderTemplate() {
+		$this->header_xobjid = -1;
+	}
+
+	/**
+	 * Set a flag to automatically reset the xobject template used by Header() method at each page.
+	 * @param $val (boolean) set to true to reset Header xobject template at each page, false otherwise.
+	 * @public
+	 */
+	public function setHeaderTemplateAutoreset($val=true) {
+		$this->header_xobj_autoreset = $val ? true : false;
+	}
+
+	/**
+	 * This method is used to render the page header.
+	 * It is automatically called by AddPage() and could be overwritten in your own inherited class.
+	 * @public
+	 */
+	public function Header() {
+		if ($this->header_xobjid < 0) {
+			// start a new XObject Template
+			$this->header_xobjid = $this->startTemplate($this->w, $this->tMargin);
+			$headerfont = $this->getHeaderFont();
+			$headerdata = $this->getHeaderData();
+			$this->y = $this->header_margin;
+			if ($this->rtl) {
+				$this->x = $this->w - $this->original_rMargin;
+			} else {
+				$this->x = $this->original_lMargin;
+			}
+			if (($headerdata['logo']) AND ($headerdata['logo'] != K_BLANK_IMAGE)) {
+				$imgtype = $this->getImageFileType(K_PATH_IMAGES.$headerdata['logo']);
+				if (($imgtype == 'eps') OR ($imgtype == 'ai')) {
+					$this->ImageEps(K_PATH_IMAGES.$headerdata['logo'], '', '', $headerdata['logo_width']);
+				} elseif ($imgtype == 'svg') {
+					$this->ImageSVG(K_PATH_IMAGES.$headerdata['logo'], '', '', $headerdata['logo_width']);
+				} else {
+					$this->Image(K_PATH_IMAGES.$headerdata['logo'], '', '', $headerdata['logo_width']);
+				}
+				$imgy = $this->getImageRBY();
+			} else {
+				$imgy = $this->y;
+			}
+			$cell_height = round(($this->cell_height_ratio * $headerfont[2]) / $this->k, 2);
+			// set starting margin for text data cell
+			if ($this->getRTL()) {
+				$header_x = $this->original_rMargin + ($headerdata['logo_width'] * 1.1);
+			} else {
+				$header_x = $this->original_lMargin + ($headerdata['logo_width'] * 1.1);
+			}
+			$cw = $this->w - $this->original_lMargin - $this->original_rMargin - ($headerdata['logo_width'] * 1.1);
+			$this->SetTextColorArray($this->header_text_color);
+			// header title
+			$this->SetFont($headerfont[0], 'B', $headerfont[2] + 1);
+			$this->SetX($header_x);
+			$this->Cell($cw, $cell_height, $headerdata['title'], 0, 1, '', 0, '', 0);
+			// header string
+			$this->SetFont($headerfont[0], $headerfont[1], $headerfont[2]);
+			$this->SetX($header_x);
+			$this->MultiCell($cw, $cell_height, $headerdata['string'], 0, '', 0, 1, '', '', true, 0, false, true, 0, 'T', false);
+			// print an ending header line
+			$this->SetLineStyle(array('width' => 0.85 / $this->k, 'cap' => 'butt', 'join' => 'miter', 'dash' => 0, 'color' => $headerdata['line_color']));
+			$this->SetY((2.835 / $this->k) + max($imgy, $this->y));
+			if ($this->rtl) {
+				$this->SetX($this->original_rMargin);
+			} else {
+				$this->SetX($this->original_lMargin);
+			}
+			$this->Cell(($this->w - $this->original_lMargin - $this->original_rMargin), 0, '', 'T', 0, 'C');
+			$this->endTemplate();
+		}
+		// print header template
+		$x = 0;
+		$dx = 0;
+		if (!$this->header_xobj_autoreset AND $this->booklet AND (($this->page % 2) == 0)) {
+			// adjust margins for booklet mode
+			$dx = ($this->original_lMargin - $this->original_rMargin);
+		}
+		if ($this->rtl) {
+			$x = $this->w + $dx;
+		} else {
+			$x = 0 + $dx;
+		}
+		$this->printTemplate($this->header_xobjid, $x, 0, 0, 0, '', '', false);
+		if ($this->header_xobj_autoreset) {
+			// reset header xobject template at each page
+			$this->header_xobjid = -1;
+		}
+	}
+
+	/**
+	 * This method is used to render the page footer.
+	 * It is automatically called by AddPage() and could be overwritten in your own inherited class.
+	 * @public
+	 */
+	public function Footer() {
+		$cur_y = $this->y;
+		$this->SetTextColorArray($this->footer_text_color);
+		//set style for cell border
+		$line_width = (0.85 / $this->k);
+		$this->SetLineStyle(array('width' => $line_width, 'cap' => 'butt', 'join' => 'miter', 'dash' => 0, 'color' => $this->footer_line_color));
+		//print document barcode
+		$barcode = $this->getBarcode();
+		if (!empty($barcode)) {
+			$this->Ln($line_width);
+			$barcode_width = round(($this->w - $this->original_lMargin - $this->original_rMargin) / 3);
+			$style = array(
+				'position' => $this->rtl?'R':'L',
+				'align' => $this->rtl?'R':'L',
+				'stretch' => false,
+				'fitwidth' => true,
+				'cellfitalign' => '',
+				'border' => false,
+				'padding' => 0,
+				'fgcolor' => array(0,0,0),
+				'bgcolor' => false,
+				'text' => false
+			);
+			$this->write1DBarcode($barcode, 'C128', '', $cur_y + $line_width, '', (($this->footer_margin / 3) - $line_width), 0.3, $style, '');
+		}
+		$w_page = isset($this->l['w_page']) ? $this->l['w_page'].' ' : '';
+		if (empty($this->pagegroups)) {
+			$pagenumtxt = $w_page.$this->getAliasNumPage().' / '.$this->getAliasNbPages();
+		} else {
+			$pagenumtxt = $w_page.$this->getPageNumGroupAlias().' / '.$this->getPageGroupAlias();
+		}
+		$this->SetY($cur_y);
+		//Print page number
+		if ($this->getRTL()) {
+			$this->SetX($this->original_rMargin);
+			$this->Cell(0, 0, $pagenumtxt, 'T', 0, 'L');
+		} else {
+			$this->SetX($this->original_lMargin);
+			$this->Cell(0, 0, $this->getAliasRightShift().$pagenumtxt, 'T', 0, 'R');
+		}
+	}
+
+	/**
+	 * This method is used to render the page header.
+	 * @protected
+	 * @since 4.0.012 (2008-07-24)
+	 */
+	protected function setHeader() {
+		if (!$this->print_header OR ($this->state != 2)) {
+			return;
+		}
+		$this->InHeader = true;
+		$this->setGraphicVars($this->default_graphic_vars);
+		$temp_thead = $this->thead;
+		$temp_theadMargins = $this->theadMargins;
+		$lasth = $this->lasth;
+		$this->_out('q');
+		$this->rMargin = $this->original_rMargin;
+		$this->lMargin = $this->original_lMargin;
+		$this->SetCellPadding(0);
+		//set current position
+		if ($this->rtl) {
+			$this->SetXY($this->original_rMargin, $this->header_margin);
+		} else {
+			$this->SetXY($this->original_lMargin, $this->header_margin);
+		}
+		$this->SetFont($this->header_font[0], $this->header_font[1], $this->header_font[2]);
+		$this->Header();
+		//restore position
+		if ($this->rtl) {
+			$this->SetXY($this->original_rMargin, $this->tMargin);
+		} else {
+			$this->SetXY($this->original_lMargin, $this->tMargin);
+		}
+		$this->_out('Q');
+		$this->lasth = $lasth;
+		$this->thead = $temp_thead;
+		$this->theadMargins = $temp_theadMargins;
+		$this->newline = false;
+		$this->InHeader = false;
+	}
+
+	/**
+	 * This method is used to render the page footer.
+	 * @protected
+	 * @since 4.0.012 (2008-07-24)
+	 */
+	protected function setFooter() {
+		if ($this->state != 2) {
+			return;
+		}
+		$this->InFooter = true;
+		// save current graphic settings
+		$gvars = $this->getGraphicVars();
+		// mark this point
+		$this->footerpos[$this->page] = $this->pagelen[$this->page];
+		$this->_out("\n");
+		if ($this->print_footer) {
+			$this->setGraphicVars($this->default_graphic_vars);
+			$this->current_column = 0;
+			$this->num_columns = 1;
+			$temp_thead = $this->thead;
+			$temp_theadMargins = $this->theadMargins;
+			$lasth = $this->lasth;
+			$this->_out('q');
+			$this->rMargin = $this->original_rMargin;
+			$this->lMargin = $this->original_lMargin;
+			$this->SetCellPadding(0);
+			//set current position
+			$footer_y = $this->h - $this->footer_margin;
+			if ($this->rtl) {
+				$this->SetXY($this->original_rMargin, $footer_y);
+			} else {
+				$this->SetXY($this->original_lMargin, $footer_y);
+			}
+			$this->SetFont($this->footer_font[0], $this->footer_font[1], $this->footer_font[2]);
+			$this->Footer();
+			//restore position
+			if ($this->rtl) {
+				$this->SetXY($this->original_rMargin, $this->tMargin);
+			} else {
+				$this->SetXY($this->original_lMargin, $this->tMargin);
+			}
+			$this->_out('Q');
+			$this->lasth = $lasth;
+			$this->thead = $temp_thead;
+			$this->theadMargins = $temp_theadMargins;
+		}
+		// restore graphic settings
+		$this->setGraphicVars($gvars);
+		$this->current_column = $gvars['current_column'];
+		$this->num_columns = $gvars['num_columns'];
+		// calculate footer length
+		$this->footerlen[$this->page] = $this->pagelen[$this->page] - $this->footerpos[$this->page] + 1;
+		$this->InFooter = false;
+	}
+
+	/**
+	 * Check if we are on the page body (excluding page header and footer).
+	 * @return true if we are not in page header nor in page footer, false otherwise.
+	 * @protected
+	 * @since 5.9.091 (2011-06-15)
+	 */
+	protected function inPageBody() {
+		return (($this->InHeader === false) AND ($this->InFooter === false));
+	}
+
+	/**
+	 * This method is used to render the table header on new page (if any).
+	 * @protected
+	 * @since 4.5.030 (2009-03-25)
+	 */
+	protected function setTableHeader() {
+		if ($this->num_columns > 1) {
+			// multi column mode
+			return;
+		}
+		if (isset($this->theadMargins['top'])) {
+			// restore the original top-margin
+			$this->tMargin = $this->theadMargins['top'];
+			$this->pagedim[$this->page]['tm'] = $this->tMargin;
+			$this->y = $this->tMargin;
+		}
+		if (!$this->empty_string($this->thead) AND (!$this->inthead)) {
+			// set margins
+			$prev_lMargin = $this->lMargin;
+			$prev_rMargin = $this->rMargin;
+			$prev_cell_padding = $this->cell_padding;
+			$this->lMargin = $this->theadMargins['lmargin'] + ($this->pagedim[$this->page]['olm'] - $this->pagedim[$this->theadMargins['page']]['olm']);
+			$this->rMargin = $this->theadMargins['rmargin'] + ($this->pagedim[$this->page]['orm'] - $this->pagedim[$this->theadMargins['page']]['orm']);
+			$this->cell_padding = $this->theadMargins['cell_padding'];
+			if ($this->rtl) {
+				$this->x = $this->w - $this->rMargin;
+			} else {
+				$this->x = $this->lMargin;
+			}
+			// account for special "cell" mode
+			if ($this->theadMargins['cell']) {
+				if ($this->rtl) {
+					$this->x -= $this->cell_padding['R'];
+				} else {
+					$this->x += $this->cell_padding['L'];
+				}
+			}
+			// print table header
+			$this->writeHTML($this->thead, false, false, false, false, '');
+			// set new top margin to skip the table headers
+			if (!isset($this->theadMargins['top'])) {
+				$this->theadMargins['top'] = $this->tMargin;
+			}
+			// store end of header position
+			if (!isset($this->columns[0]['th'])) {
+				$this->columns[0]['th'] = array();
+			}
+			$this->columns[0]['th']['\''.$this->page.'\''] = $this->y;
+			$this->tMargin = $this->y;
+			$this->pagedim[$this->page]['tm'] = $this->tMargin;
+			$this->lasth = 0;
+			$this->lMargin = $prev_lMargin;
+			$this->rMargin = $prev_rMargin;
+			$this->cell_padding = $prev_cell_padding;
+		}
+	}
+
+	/**
+	 * Returns the current page number.
+	 * @return int page number
+	 * @public
+	 * @since 1.0
+	 * @see getAliasNbPages()
+	 */
+	public function PageNo() {
+		return $this->page;
+	}
+
+	/**
+	 * Defines a new spot color.
+	 * It can be expressed in RGB components or gray scale.
+	 * The method can be called before the first page is created and the value is retained from page to page.
+	 * @param $name (string) Full name of the spot color.
+	 * @param $c (float) Cyan color for CMYK. Value between 0 and 100.
+	 * @param $m (float) Magenta color for CMYK. Value between 0 and 100.
+	 * @param $y (float) Yellow color for CMYK. Value between 0 and 100.
+	 * @param $k (float) Key (Black) color for CMYK. Value between 0 and 100.
+	 * @public
+	 * @since 4.0.024 (2008-09-12)
+	 * @see SetDrawSpotColor(), SetFillSpotColor(), SetTextSpotColor()
+	 */
+	public function AddSpotColor($name, $c, $m, $y, $k) {
+		if (!isset($this->spot_colors[$name])) {
+			$i = (1 + count($this->spot_colors));
+			$this->spot_colors[$name] = array('C' => $c, 'M' => $m, 'Y' => $y, 'K' => $k, 'name' => $name, 'i' => $i);
+		}
+	}
+
+	/**
+	 * Return the Spot color array.
+	 * @param $name (string) Name of the spot color.
+	 * @return (array) Spot color array or false if not defined.
+	 * @public
+	 * @since 5.9.125 (2011-10-03)
+	 */
+	public function getSpotColor($name) {
+		if (isset($this->spot_colors[$name])) {
+			return $this->spot_colors[$name];
+		}
+		$color = preg_replace('/[\s]*/', '', $name); // remove extra spaces
+		$color = strtolower($color);
+		if (isset($this->spotcolor[$color])) {
+			$this->AddSpotColor($this->spotcolor[$color][4], $this->spotcolor[$color][0], $this->spotcolor[$color][1], $this->spotcolor[$color][2], $this->spotcolor[$color][3]);
+			return $this->spot_colors[$this->spotcolor[$color][4]];
+		}
+		return false;
+	}
+
+	/**
+	 * Set the spot color for the specified type ('draw', 'fill', 'text').
+	 * @param $type (string) Type of object affected by this color: ('draw', 'fill', 'text').
+	 * @param $name (string) Name of the spot color.
+	 * @param $tint (float) Intensity of the color (from 0 to 100 ; 100 = full intensity by default).
+	 * @return (string) PDF color command.
+	 * @public
+	 * @since 5.9.125 (2011-10-03)
+	 */
+	public function setSpotColor($type, $name, $tint=100) {
+		$spotcolor = $this->getSpotColor($name);
+		if ($spotcolor === false) {
+			$this->Error('Undefined spot color: '.$name.', you must add it on the spotcolors.php file.');
+		}
+		$tint = (max(0, min(100, $tint)) / 100);
+		$pdfcolor = sprintf('/CS%d ', $this->spot_colors[$name]['i']);
+		switch ($type) {
+			case 'draw': {
+				$pdfcolor .= sprintf('CS %F SCN', $tint);
+				$this->DrawColor = $pdfcolor;
+				$this->strokecolor = $spotcolor;
+				break;
+			}
+			case 'fill': {
+				$pdfcolor .= sprintf('cs %F scn', $tint);
+				$this->FillColor = $pdfcolor;
+				$this->bgcolor = $spotcolor;
+				break;
+			}
+			case 'text': {
+				$pdfcolor .= sprintf('cs %F scn', $tint);
+				$this->TextColor = $pdfcolor;
+				$this->fgcolor = $spotcolor;
+				break;
+			}
+		}
+		$this->ColorFlag = ($this->FillColor != $this->TextColor);
+		if ($this->state == 2) {
+			$this->_out($pdfcolor);
+		}
+		if ($this->inxobj) {
+			// we are inside an XObject template
+			$this->xobjects[$this->xobjid]['spot_colors'][$name] = $this->spot_colors[$name];
+		}
+		return $pdfcolor;
+	}
+
+	/**
+	 * Defines the spot color used for all drawing operations (lines, rectangles and cell borders).
+	 * @param $name (string) Name of the spot color.
+	 * @param $tint (float) Intensity of the color (from 0 to 100 ; 100 = full intensity by default).
+	 * @public
+	 * @since 4.0.024 (2008-09-12)
+	 * @see AddSpotColor(), SetFillSpotColor(), SetTextSpotColor()
+	 */
+	public function SetDrawSpotColor($name, $tint=100) {
+		$this->setSpotColor('draw', $name, $tint);
+	}
+
+	/**
+	 * Defines the spot color used for all filling operations (filled rectangles and cell backgrounds).
+	 * @param $name (string) Name of the spot color.
+	 * @param $tint (float) Intensity of the color (from 0 to 100 ; 100 = full intensity by default).
+	 * @public
+	 * @since 4.0.024 (2008-09-12)
+	 * @see AddSpotColor(), SetDrawSpotColor(), SetTextSpotColor()
+	 */
+	public function SetFillSpotColor($name, $tint=100) {
+		$this->setSpotColor('fill', $name, $tint);
+	}
+
+	/**
+	 * Defines the spot color used for text.
+	 * @param $name (string) Name of the spot color.
+	 * @param $tint (int) Intensity of the color (from 0 to 100 ; 100 = full intensity by default).
+	 * @public
+	 * @since 4.0.024 (2008-09-12)
+	 * @see AddSpotColor(), SetDrawSpotColor(), SetFillSpotColor()
+	 */
+	public function SetTextSpotColor($name, $tint=100) {
+		$this->setSpotColor('text', $name, $tint);
+	}
+
+	/**
+	 * Set the color array for the specified type ('draw', 'fill', 'text').
+	 * It can be expressed in RGB, CMYK or GRAY SCALE components.
+	 * The method can be called before the first page is created and the value is retained from page to page.
+	 * @param $type (string) Type of object affected by this color: ('draw', 'fill', 'text').
+	 * @param $color (array) Array of colors (1=gray, 3=RGB, 4=CMYK or 5=spotcolor=CMYK+name values).
+	 * @param $ret (boolean) If true do not send the PDF command.
+	 * @return (string) The PDF command or empty string.
+	 * @public
+	 * @since 3.1.000 (2008-06-11)
+	 */
+	public function setColorArray($type, $color, $ret=false) {
+		if (is_array($color)) {
+			$color = array_values($color);
+			// component: grey, RGB red or CMYK cyan
+			$c = isset($color[0]) ? $color[0] : -1;
+			// component: RGB green or CMYK magenta
+			$m = isset($color[1]) ? $color[1] : -1;
+			// component: RGB blue or CMYK yellow
+			$y = isset($color[2]) ? $color[2] : -1;
+			// component: CMYK black
+			$k = isset($color[3]) ? $color[3] : -1;
+			// color name
+			$name = isset($color[4]) ? $color[4] : '';
+			if ($c >= 0) {
+				return $this->setColor($type, $c, $m, $y, $k, $ret, $name);
+			}
+		}
+		return '';
+	}
+
+	/**
+	 * Defines the color used for all drawing operations (lines, rectangles and cell borders).
+	 * It can be expressed in RGB, CMYK or GRAY SCALE components.
+	 * The method can be called before the first page is created and the value is retained from page to page.
+	 * @param $color (array) Array of colors (1, 3 or 4 values).
+	 * @param $ret (boolean) If true do not send the PDF command.
+	 * @return string the PDF command
+	 * @public
+	 * @since 3.1.000 (2008-06-11)
+	 * @see SetDrawColor()
+	 */
+	public function SetDrawColorArray($color, $ret=false) {
+		return $this->setColorArray('draw', $color, $ret);
+	}
+
+	/**
+	 * Defines the color used for all filling operations (filled rectangles and cell backgrounds).
+	 * It can be expressed in RGB, CMYK or GRAY SCALE components.
+	 * The method can be called before the first page is created and the value is retained from page to page.
+	 * @param $color (array) Array of colors (1, 3 or 4 values).
+	 * @param $ret (boolean) If true do not send the PDF command.
+	 * @public
+	 * @since 3.1.000 (2008-6-11)
+	 * @see SetFillColor()
+	 */
+	public function SetFillColorArray($color, $ret=false) {
+		return $this->setColorArray('fill', $color, $ret);
+	}
+
+	/**
+	 * Defines the color used for text. It can be expressed in RGB components or gray scale.
+	 * The method can be called before the first page is created and the value is retained from page to page.
+	 * @param $color (array) Array of colors (1, 3 or 4 values).
+	 * @param $ret (boolean) If true do not send the PDF command.
+	 * @public
+	 * @since 3.1.000 (2008-6-11)
+	 * @see SetFillColor()
+	 */
+	public function SetTextColorArray($color, $ret=false) {
+		return $this->setColorArray('text', $color, $ret);
+	}
+
+	/**
+	 * Defines the color used by the specified type ('draw', 'fill', 'text').
+	 * @param $type (string) Type of object affected by this color: ('draw', 'fill', 'text').
+	 * @param $col1 (float) GRAY level for single color, or Red color for RGB (0-255), or CYAN color for CMYK (0-100).
+	 * @param $col2 (float) GREEN color for RGB (0-255), or MAGENTA color for CMYK (0-100).
+	 * @param $col3 (float) BLUE color for RGB (0-255), or YELLOW color for CMYK (0-100).
+	 * @param $col4 (float) KEY (BLACK) color for CMYK (0-100).
+	 * @param $ret (boolean) If true do not send the command.
+	 * @param $name (string) spot color name (if any)
+	 * @return (string) The PDF command or empty string.
+	 * @public
+	 * @since 5.9.125 (2011-10-03)
+	 */
+	public function setColor($type, $col1=0, $col2=-1, $col3=-1, $col4=-1, $ret=false, $name='') {
+		// set default values
+		if (!is_numeric($col1)) {
+			$col1 = 0;
+		}
+		if (!is_numeric($col2)) {
+			$col2 = -1;
+		}
+		if (!is_numeric($col3)) {
+			$col3 = -1;
+		}
+		if (!is_numeric($col4)) {
+			$col4 = -1;
+		}
+		// set color by case
+		$suffix = '';
+		if (($col2 == -1) AND ($col3 == -1) AND ($col4 == -1)) {
+			// Grey scale
+			$col1 = max(0, min(255, $col1));
+			$intcolor = array('G' => $col1);
+			$pdfcolor = sprintf('%F ', ($col1 / 255));
+			$suffix = 'g';
+		} elseif ($col4 == -1) {
+			// RGB
+			$col1 = max(0, min(255, $col1));
+			$col2 = max(0, min(255, $col2));
+			$col3 = max(0, min(255, $col3));
+			$intcolor = array('R' => $col1, 'G' => $col2, 'B' => $col3);
+			$pdfcolor = sprintf('%F %F %F ', ($col1 / 255), ($col2 / 255), ($col3 / 255));
+			$suffix = 'rg';
+		} else {
+			$col1 = max(0, min(100, $col1));
+			$col2 = max(0, min(100, $col2));
+			$col3 = max(0, min(100, $col3));
+			$col4 = max(0, min(100, $col4));
+			if (empty($name)) {
+				// CMYK
+				$intcolor = array('C' => $col1, 'M' => $col2, 'Y' => $col3, 'K' => $col4);
+				$pdfcolor = sprintf('%F %F %F %F ', ($col1 / 100), ($col2 / 100), ($col3 / 100), ($col4 / 100));
+				$suffix = 'k';
+			} else {
+				// SPOT COLOR
+				$intcolor = array('C' => $col1, 'M' => $col2, 'Y' => $col3, 'K' => $col4, 'name' => $name);
+				$this->AddSpotColor($name, $col1, $col2, $col3, $col4);
+				$pdfcolor = $this->setSpotColor($type, $name, 100);
+			}
+		}
+		switch ($type) {
+			case 'draw': {
+				$pdfcolor .= strtoupper($suffix);
+				$this->DrawColor = $pdfcolor;
+				$this->strokecolor = $intcolor;
+				break;
+			}
+			case 'fill': {
+				$pdfcolor .= $suffix;
+				$this->FillColor = $pdfcolor;
+				$this->bgcolor = $intcolor;
+				break;
+			}
+			case 'text': {
+				$pdfcolor .= $suffix;
+				$this->TextColor = $pdfcolor;
+				$this->fgcolor = $intcolor;
+				break;
+			}
+		}
+		$this->ColorFlag = ($this->FillColor != $this->TextColor);
+		if (($type != 'text') AND ($this->state == 2)) {
+			if (!$ret) {
+				$this->_out($pdfcolor);
+			}
+			return $pdfcolor;
+		}
+		return '';
+	}
+
+	/**
+	 * Convert a color array into a string representation.
+	 * @param $c (array) Array of colors.
+	 * @return (string) The color array representation.
+	 * @protected
+	 * @since 5.9.137 (2011-12-01)
+	 */
+	protected function getColorStringFromArray($c) {
+		$c = array_values($c);
+		$color = '[';
+		switch (count($c)) {
+			case 4: {
+				// CMYK
+				$color .= sprintf('%F %F %F %F', (max(0, min(100, floatval($c[0]))) / 100), (max(0, min(100, floatval($c[1]))) / 100), (max(0, min(100, floatval($c[2]))) / 100), (max(0, min(100, floatval($c[3]))) / 100));
+				break;
+			}
+			case 3: {
+				// RGB
+				$color .= sprintf('%F %F %F', (max(0, min(255, floatval($c[0]))) / 255), (max(0, min(255, floatval($c[1]))) / 255), (max(0, min(255, floatval($c[2]))) / 255));
+				break;
+			}
+			case 1: {
+				// grayscale
+				$color .= sprintf('%F', (max(0, min(255, floatval($c[0]))) / 255));
+				break;
+			}
+		}
+		$color .= ']';
+		return $color;
+	}
+
+	/**
+	 * Defines the color used for all drawing operations (lines, rectangles and cell borders). It can be expressed in RGB components or gray scale. The method can be called before the first page is created and the value is retained from page to page.
+	 * @param $col1 (float) GRAY level for single color, or Red color for RGB (0-255), or CYAN color for CMYK (0-100).
+	 * @param $col2 (float) GREEN color for RGB (0-255), or MAGENTA color for CMYK (0-100).
+	 * @param $col3 (float) BLUE color for RGB (0-255), or YELLOW color for CMYK (0-100).
+	 * @param $col4 (float) KEY (BLACK) color for CMYK (0-100).
+	 * @param $ret (boolean) If true do not send the command.
+	 * @param $name (string) spot color name (if any)
+	 * @return string the PDF command
+	 * @public
+	 * @since 1.3
+	 * @see SetDrawColorArray(), SetFillColor(), SetTextColor(), Line(), Rect(), Cell(), MultiCell()
+	 */
+	public function SetDrawColor($col1=0, $col2=-1, $col3=-1, $col4=-1, $ret=false, $name='') {
+		return $this->setColor('draw', $col1, $col2, $col3, $col4, $ret, $name);
+	}
+
+	/**
+	 * Defines the color used for all filling operations (filled rectangles and cell backgrounds). It can be expressed in RGB components or gray scale. The method can be called before the first page is created and the value is retained from page to page.
+	 * @param $col1 (float) GRAY level for single color, or Red color for RGB (0-255), or CYAN color for CMYK (0-100).
+	 * @param $col2 (float) GREEN color for RGB (0-255), or MAGENTA color for CMYK (0-100).
+	 * @param $col3 (float) BLUE color for RGB (0-255), or YELLOW color for CMYK (0-100).
+	 * @param $col4 (float) KEY (BLACK) color for CMYK (0-100).
+	 * @param $ret (boolean) If true do not send the command.
+	 * @param $name (string) Spot color name (if any).
+	 * @return (string) The PDF command.
+	 * @public
+	 * @since 1.3
+	 * @see SetFillColorArray(), SetDrawColor(), SetTextColor(), Rect(), Cell(), MultiCell()
+	 */
+	public function SetFillColor($col1=0, $col2=-1, $col3=-1, $col4=-1, $ret=false, $name='') {
+		return $this->setColor('fill', $col1, $col2, $col3, $col4, $ret, $name);
+	}
+
+	/**
+	 * Defines the color used for text. It can be expressed in RGB components or gray scale. The method can be called before the first page is created and the value is retained from page to page.
+	 * @param $col1 (float) GRAY level for single color, or Red color for RGB (0-255), or CYAN color for CMYK (0-100).
+	 * @param $col2 (float) GREEN color for RGB (0-255), or MAGENTA color for CMYK (0-100).
+	 * @param $col3 (float) BLUE color for RGB (0-255), or YELLOW color for CMYK (0-100).
+	 * @param $col4 (float) KEY (BLACK) color for CMYK (0-100).
+	 * @param $ret (boolean) If true do not send the command.
+	 * @param $name (string) Spot color name (if any).
+	 * @return (string) Empty string.
+	 * @public
+	 * @since 1.3
+	 * @see SetTextColorArray(), SetDrawColor(), SetFillColor(), Text(), Cell(), MultiCell()
+	 */
+	public function SetTextColor($col1=0, $col2=-1, $col3=-1, $col4=-1, $ret=false, $name='') {
+		return $this->setColor('text', $col1, $col2, $col3, $col4, $ret, $name);
+	}
+
+	/**
+	 * Returns the length of a string in user unit. A font must be selected.<br>
+	 * @param $s (string) The string whose length is to be computed
+	 * @param $fontname (string) Family font. It can be either a name defined by AddFont() or one of the standard families. It is also possible to pass an empty string, in that case, the current family is retained.
+	 * @param $fontstyle (string) Font style. Possible values are (case insensitive):<ul><li>empty string: regular</li><li>B: bold</li><li>I: italic</li><li>U: underline</li><li>D: line-trough</li><li>O: overline</li></ul> or any combination. The default value is regular.
+	 * @param $fontsize (float) Font size in points. The default value is the current size.
+	 * @param $getarray (boolean) if true returns an array of characters widths, if false returns the total length.
+	 * @return mixed int total string length or array of characted widths
+	 * @author Nicola Asuni
+	 * @public
+	 * @since 1.2
+	 */
+	public function GetStringWidth($s, $fontname='', $fontstyle='', $fontsize=0, $getarray=false) {
+		return $this->GetArrStringWidth($this->utf8Bidi($this->UTF8StringToArray($s), $s, $this->tmprtl), $fontname, $fontstyle, $fontsize, $getarray);
+	}
+
+	/**
+	 * Returns the string length of an array of chars in user unit or an array of characters widths. A font must be selected.<br>
+	 * @param $sa (string) The array of chars whose total length is to be computed
+	 * @param $fontname (string) Family font. It can be either a name defined by AddFont() or one of the standard families. It is also possible to pass an empty string, in that case, the current family is retained.
+	 * @param $fontstyle (string) Font style. Possible values are (case insensitive):<ul><li>empty string: regular</li><li>B: bold</li><li>I: italic</li><li>U: underline</li><li>D: line trough</li><li>O: overline</li></ul> or any combination. The default value is regular.
+	 * @param $fontsize (float) Font size in points. The default value is the current size.
+	 * @param $getarray (boolean) if true returns an array of characters widths, if false returns the total length.
+	 * @return mixed int total string length or array of characted widths
+	 * @author Nicola Asuni
+	 * @public
+	 * @since 2.4.000 (2008-03-06)
+	 */
+	public function GetArrStringWidth($sa, $fontname='', $fontstyle='', $fontsize=0, $getarray=false) {
+		// store current values
+		if (!$this->empty_string($fontname)) {
+			$prev_FontFamily = $this->FontFamily;
+			$prev_FontStyle = $this->FontStyle;
+			$prev_FontSizePt = $this->FontSizePt;
+			$this->SetFont($fontname, $fontstyle, $fontsize, '', 'default', false);
+		}
+		// convert UTF-8 array to Latin1 if required
+		$sa = $this->UTF8ArrToLatin1($sa);
+		$w = 0; // total width
+		$wa = array(); // array of characters widths
+		foreach ($sa as $ck => $char) {
+			// character width
+			$cw = $this->GetCharWidth($char, isset($sa[($ck + 1)]));
+			$wa[] = $cw;
+			$w += $cw;
+		}
+		// restore previous values
+		if (!$this->empty_string($fontname)) {
+			$this->SetFont($prev_FontFamily, $prev_FontStyle, $prev_FontSizePt, '', 'default', false);
+		}
+		if ($getarray) {
+			return $wa;
+		}
+		return $w;
+	}
+
+	/**
+	 * Returns the length of the char in user unit for the current font considering current stretching and spacing (tracking).
+	 * @param $char (int) The char code whose length is to be returned
+	 * @param $notlast (boolean) If false ignore the font-spacing.
+	 * @return float char width
+	 * @author Nicola Asuni
+	 * @public
+	 * @since 2.4.000 (2008-03-06)
+	 */
+	public function GetCharWidth($char, $notlast=true) {
+		// get raw width
+		$chw = $this->getRawCharWidth($char);
+		if (($this->font_spacing < 0) OR (($this->font_spacing > 0) AND $notlast)) {
+			// increase/decrease font spacing
+			$chw += $this->font_spacing;
+		}
+		if ($this->font_stretching != 100) {
+			// fixed stretching mode
+			$chw *= ($this->font_stretching / 100);
+		}
+		return $chw;
+	}
+
+	/**
+	 * Returns the length of the char in user unit for the current font.
+	 * @param $char (int) The char code whose length is to be returned
+	 * @return float char width
+	 * @author Nicola Asuni
+	 * @public
+	 * @since 5.9.000 (2010-09-28)
+	 */
+	public function getRawCharWidth($char) {
+		if ($char == 173) {
+			// SHY character will not be printed
+			return (0);
+		}
+		if (isset($this->CurrentFont['cw'][$char])) {
+			$w = $this->CurrentFont['cw'][$char];
+		} elseif (isset($this->CurrentFont['dw'])) {
+			// default width
+			$w = $this->CurrentFont['dw'];
+		} elseif (isset($this->CurrentFont['cw'][32])) {
+			// default width
+			$w = $this->CurrentFont['cw'][32];
+		} else {
+			$w = 600;
+		}
+		return $this->getAbsFontMeasure($w);
+	}
+
+	/**
+	 * Returns the numbero of characters in a string.
+	 * @param $s (string) The input string.
+	 * @return int number of characters
+	 * @public
+	 * @since 2.0.0001 (2008-01-07)
+	 */
+	public function GetNumChars($s) {
+		if ($this->isUnicodeFont()) {
+			return count($this->UTF8StringToArray($s));
+		}
+		return strlen($s);
+	}
+
+	/**
+	 * Fill the list of available fonts ($this->fontlist).
+	 * @protected
+	 * @since 4.0.013 (2008-07-28)
+	 */
+	protected function getFontsList() {
+		if (($fontsdir = opendir($this->_getfontpath())) !== false) {
+			while (($file = readdir($fontsdir)) !== false) {
+				if (substr($file, -4) == '.php') {
+					array_push($this->fontlist, strtolower(basename($file, '.php')));
+				}
+			}
+			closedir($fontsdir);
+		}
+	}
+
+	/**
+	 * Imports a TrueType, Type1, core, or CID0 font and makes it available.
+	 * It is necessary to generate a font definition file first (read /fonts/utils/README.TXT).
+	 * The definition file (and the font file itself when embedding) must be present either in the current directory or in the one indicated by K_PATH_FONTS if the constant is defined. If it could not be found, the error "Could not include font definition file" is generated.
+	 * @param $family (string) Font family. The name can be chosen arbitrarily. If it is a standard family name, it will override the corresponding font.
+	 * @param $style (string) Font style. Possible values are (case insensitive):<ul><li>empty string: regular (default)</li><li>B: bold</li><li>I: italic</li><li>BI or IB: bold italic</li></ul>
+	 * @param $fontfile (string) The font definition file. By default, the name is built from the family and style, in lower case with no spaces.
+	 * @return array containing the font data, or false in case of error.
+	 * @param $subset (mixed) if true embedd only a subset of the font (stores only the information related to the used characters); if false embedd full font; if 'default' uses the default value set using setFontSubsetting(). This option is valid only for TrueTypeUnicode fonts. If you want to enable users to change the document, set this parameter to false. If you subset the font, the person who receives your PDF would need to have your same font in order to make changes to your PDF. The f [...]
+	 * @public
+	 * @since 1.5
+	 * @see SetFont(), setFontSubsetting()
+	 */
+	public function AddFont($family, $style='', $fontfile='', $subset='default') {
+		if ($subset === 'default') {
+			$subset = $this->font_subsetting;
+		}
+		if ($this->pdfa_mode) {
+			$subset = false;
+		}
+		if ($this->empty_string($family)) {
+			if (!$this->empty_string($this->FontFamily)) {
+				$family = $this->FontFamily;
+			} else {
+				$this->Error('Empty font family');
+			}
+		}
+		// move embedded styles on $style
+		if (substr($family, -1) == 'I') {
+			$style .= 'I';
+			$family = substr($family, 0, -1);
+		}
+		if (substr($family, -1) == 'B') {
+			$style .= 'B';
+			$family = substr($family, 0, -1);
+		}
+		// normalize family name
+		$family = strtolower($family);
+		if ((!$this->isunicode) AND ($family == 'arial')) {
+			$family = 'helvetica';
+		}
+		if (($family == 'symbol') OR ($family == 'zapfdingbats')) {
+			$style = '';
+		}
+		if ($this->pdfa_mode AND (isset($this->CoreFonts[$family]))) {
+			// all fonts must be embedded
+			$family = 'pdfa'.$family;
+		}
+		$tempstyle = strtoupper($style);
+		$style = '';
+		// underline
+		if (strpos($tempstyle, 'U') !== false) {
+			$this->underline = true;
+		} else {
+			$this->underline = false;
+		}
+		// line-through (deleted)
+		if (strpos($tempstyle, 'D') !== false) {
+			$this->linethrough = true;
+		} else {
+			$this->linethrough = false;
+		}
+		// overline
+		if (strpos($tempstyle, 'O') !== false) {
+			$this->overline = true;
+		} else {
+			$this->overline = false;
+		}
+		// bold
+		if (strpos($tempstyle, 'B') !== false) {
+			$style .= 'B';
+		}
+		// oblique
+		if (strpos($tempstyle, 'I') !== false) {
+			$style .= 'I';
+		}
+		$bistyle = $style;
+		$fontkey = $family.$style;
+		$font_style = $style.($this->underline ? 'U' : '').($this->linethrough ? 'D' : '').($this->overline ? 'O' : '');
+		$fontdata = array('fontkey' => $fontkey, 'family' => $family, 'style' => $font_style);
+		// check if the font has been already added
+		$fb = $this->getFontBuffer($fontkey);
+		if ($fb !== false) {
+			if ($this->inxobj) {
+				// we are inside an XObject template
+				$this->xobjects[$this->xobjid]['fonts'][$fontkey] = $fb['i'];
+			}
+			return $fontdata;
+		}
+		if (isset($type)) {
+			unset($type);
+		}
+		if (isset($cw)) {
+			unset($cw);
+		}
+		// get specified font directory (if any)
+		$fontdir = false;
+		if (!$this->empty_string($fontfile)) {
+			$fontdir = dirname($fontfile);
+			if ($this->empty_string($fontdir) OR ($fontdir == '.')) {
+				$fontdir = '';
+			} else {
+				$fontdir .= '/';
+			}
+		}
+		$missing_style = false; // true when the font style variation is missing
+		// search and include font file
+		if ($this->empty_string($fontfile) OR (!file_exists($fontfile))) {
+			// build a standard filenames for specified font
+			$tmp_fontfile = str_replace(' ', '', $family).strtolower($style).'.php';
+			// search files on various directories
+			if (($fontdir !== false) AND file_exists($fontdir.$tmp_fontfile)) {
+				$fontfile = $fontdir.$tmp_fontfile;
+			} elseif (file_exists($this->_getfontpath().$tmp_fontfile)) {
+				$fontfile = $this->_getfontpath().$tmp_fontfile;
+			} elseif (file_exists($tmp_fontfile)) {
+				$fontfile = $tmp_fontfile;
+			} elseif (!$this->empty_string($style)) {
+				$missing_style = true;
+				// try to remove the style part
+				$tmp_fontfile = str_replace(' ', '', $family).'.php';
+				if (($fontdir !== false) AND file_exists($fontdir.$tmp_fontfile)) {
+					$fontfile = $fontdir.$tmp_fontfile;
+				} elseif (file_exists($this->_getfontpath().$tmp_fontfile)) {
+					$fontfile = $this->_getfontpath().$tmp_fontfile;
+				} else {
+					$fontfile = $tmp_fontfile;
+				}
+			}
+		}
+		// include font file
+		if (file_exists($fontfile)) {
+			include($fontfile);
+		} else {
+			$this->Error('Could not include font definition file: '.$family.'');
+		}
+		// check font parameters
+		if ((!isset($type)) OR (!isset($cw))) {
+			$this->Error('The font definition file has a bad format: '.$fontfile.'');
+		}
+		// SET default parameters
+		if (!isset($file) OR $this->empty_string($file)) {
+			$file = '';
+		}
+		if (!isset($enc) OR $this->empty_string($enc)) {
+			$enc = '';
+		}
+		if (!isset($cidinfo) OR $this->empty_string($cidinfo)) {
+			$cidinfo = array('Registry'=>'Adobe', 'Ordering'=>'Identity', 'Supplement'=>0);
+			$cidinfo['uni2cid'] = array();
+		}
+		if (!isset($ctg) OR $this->empty_string($ctg)) {
+			$ctg = '';
+		}
+		if (!isset($desc) OR $this->empty_string($desc)) {
+			$desc = array();
+		}
+		if (!isset($up) OR $this->empty_string($up)) {
+			$up = -100;
+		}
+		if (!isset($ut) OR $this->empty_string($ut)) {
+			$ut = 50;
+		}
+		if (!isset($cw) OR $this->empty_string($cw)) {
+			$cw = array();
+		}
+		if (!isset($dw) OR $this->empty_string($dw)) {
+			// set default width
+			if (isset($desc['MissingWidth']) AND ($desc['MissingWidth'] > 0)) {
+				$dw = $desc['MissingWidth'];
+			} elseif (isset($cw[32])) {
+				$dw = $cw[32];
+			} else {
+				$dw = 600;
+			}
+		}
+		++$this->numfonts;
+		if ($type == 'core') {
+			$name = $this->CoreFonts[$fontkey];
+			$subset = false;
+		} elseif (($type == 'TrueType') OR ($type == 'Type1')) {
+			$subset = false;
+		} elseif ($type == 'TrueTypeUnicode') {
+			$enc = 'Identity-H';
+		} elseif ($type == 'cidfont0') {
+			if ($this->pdfa_mode) {
+				$this->Error('All fonts must be embedded in PDF/A mode!');
+			}
+		} else {
+			$this->Error('Unknow font type: '.$type.'');
+		}
+		// set name if unset
+		if (!isset($name) OR empty($name)) {
+			$name = $fontkey;
+		}
+		// create artificial font style variations if missing (only works with non-embedded fonts)
+		if (($type != 'core') AND $missing_style) {
+			// style variations
+			$styles = array('' => '', 'B' => ',Bold', 'I' => ',Italic', 'BI' => ',BoldItalic');
+			$name .= $styles[$bistyle];
+			// artificial bold
+			if (strpos($bistyle, 'B') !== false) {
+				if (isset($desc['StemV'])) {
+					// from normal to bold
+					$desc['StemV'] = round($desc['StemV'] * 1.75);
+				} else {
+					// bold
+					$desc['StemV'] = 123;
+				}
+			}
+			// artificial italic
+			if (strpos($bistyle, 'I') !== false) {
+				if (isset($desc['ItalicAngle'])) {
+					$desc['ItalicAngle'] -= 11;
+				} else {
+					$desc['ItalicAngle'] = -11;
+				}
+				if (isset($desc['Flags'])) {
+					$desc['Flags'] |= 64; //bit 7
+				} else {
+					$desc['Flags'] = 64;
+				}
+			}
+		}
+		// check if the array of characters bounding boxes is defined
+		if (!isset($cbbox)) {
+			$cbbox = array();
+		}
+		// initialize subsetchars
+		$subsetchars = array_fill(0, 255, true);
+		$this->setFontBuffer($fontkey, array('fontkey' => $fontkey, 'i' => $this->numfonts, 'type' => $type, 'name' => $name, 'desc' => $desc, 'up' => $up, 'ut' => $ut, 'cw' => $cw, 'cbbox' => $cbbox, 'dw' => $dw, 'enc' => $enc, 'cidinfo' => $cidinfo, 'file' => $file, 'ctg' => $ctg, 'subset' => $subset, 'subsetchars' => $subsetchars));
+		if ($this->inxobj) {
+			// we are inside an XObject template
+			$this->xobjects[$this->xobjid]['fonts'][$fontkey] = $this->numfonts;
+		}
+		if (isset($diff) AND (!empty($diff))) {
+			//Search existing encodings
+			$d = 0;
+			$nb = count($this->diffs);
+			for ($i=1; $i <= $nb; ++$i) {
+				if ($this->diffs[$i] == $diff) {
+					$d = $i;
+					break;
+				}
+			}
+			if ($d == 0) {
+				$d = $nb + 1;
+				$this->diffs[$d] = $diff;
+			}
+			$this->setFontSubBuffer($fontkey, 'diff', $d);
+		}
+		if (!$this->empty_string($file)) {
+			if (!isset($this->FontFiles[$file])) {
+				if ((strcasecmp($type,'TrueType') == 0) OR (strcasecmp($type, 'TrueTypeUnicode') == 0)) {
+					$this->FontFiles[$file] = array('length1' => $originalsize, 'fontdir' => $fontdir, 'subset' => $subset, 'fontkeys' => array($fontkey));
+				} elseif ($type != 'core') {
+					$this->FontFiles[$file] = array('length1' => $size1, 'length2' => $size2, 'fontdir' => $fontdir, 'subset' => $subset, 'fontkeys' => array($fontkey));
+				}
+			} else {
+				// update fontkeys that are sharing this font file
+				$this->FontFiles[$file]['subset'] = ($this->FontFiles[$file]['subset'] AND $subset);
+				if (!in_array($fontkey, $this->FontFiles[$file]['fontkeys'])) {
+					$this->FontFiles[$file]['fontkeys'][] = $fontkey;
+				}
+			}
+		}
+		return $fontdata;
+	}
+
+	/**
+	 * Sets the font used to print character strings.
+	 * The font can be either a standard one or a font added via the AddFont() method. Standard fonts use Windows encoding cp1252 (Western Europe).
+	 * The method can be called before the first page is created and the font is retained from page to page.
+	 * If you just wish to change the current font size, it is simpler to call SetFontSize().
+	 * Note: for the standard fonts, the font metric files must be accessible. There are three possibilities for this:<ul><li>They are in the current directory (the one where the running script lies)</li><li>They are in one of the directories defined by the include_path parameter</li><li>They are in the directory defined by the K_PATH_FONTS constant</li></ul><br />
+	 * @param $family (string) Family font. It can be either a name defined by AddFont() or one of the standard Type1 families (case insensitive):<ul><li>times (Times-Roman)</li><li>timesb (Times-Bold)</li><li>timesi (Times-Italic)</li><li>timesbi (Times-BoldItalic)</li><li>helvetica (Helvetica)</li><li>helveticab (Helvetica-Bold)</li><li>helveticai (Helvetica-Oblique)</li><li>helveticabi (Helvetica-BoldOblique)</li><li>courier (Courier)</li><li>courierb (Courier-Bold)</li><li>courieri (Cou [...]
+	 * @param $style (string) Font style. Possible values are (case insensitive):<ul><li>empty string: regular</li><li>B: bold</li><li>I: italic</li><li>U: underline</li><li>D: line trough</li><li>O: overline</li></ul> or any combination. The default value is regular. Bold and italic styles do not apply to Symbol and ZapfDingbats basic fonts or other fonts when not defined.
+	 * @param $size (float) Font size in points. The default value is the current size. If no size has been specified since the beginning of the document, the value taken is 12
+	 * @param $fontfile (string) The font definition file. By default, the name is built from the family and style, in lower case with no spaces.
+	 * @param $subset (mixed) if true embedd only a subset of the font (stores only the information related to the used characters); if false embedd full font; if 'default' uses the default value set using setFontSubsetting(). This option is valid only for TrueTypeUnicode fonts. If you want to enable users to change the document, set this parameter to false. If you subset the font, the person who receives your PDF would need to have your same font in order to make changes to your PDF. The f [...]
+	 * @param $out (boolean) if true output the font size command, otherwise only set the font properties.
+	 * @author Nicola Asuni
+	 * @public
+	 * @since 1.0
+	 * @see AddFont(), SetFontSize()
+	 */
+	public function SetFont($family, $style='', $size=null, $fontfile='', $subset='default', $out=true) {
+		//Select a font; size given in points
+		if ($size === null) {
+			$size = $this->FontSizePt;
+		}
+		if ($size < 0) {
+			$size = 0;
+		}
+		// try to add font (if not already added)
+		$fontdata = $this->AddFont($family, $style, $fontfile, $subset);
+		$this->FontFamily = $fontdata['family'];
+		$this->FontStyle = $fontdata['style'];
+		$this->CurrentFont = $this->getFontBuffer($fontdata['fontkey']);
+		$this->SetFontSize($size, $out);
+	}
+
+	/**
+	 * Defines the size of the current font.
+	 * @param $size (float) The font size in points.
+	 * @param $out (boolean) if true output the font size command, otherwise only set the font properties.
+	 * @public
+	 * @since 1.0
+	 * @see SetFont()
+	 */
+	public function SetFontSize($size, $out=true) {
+		// font size in points
+		$this->FontSizePt = $size;
+		// font size in user units
+		$this->FontSize = $size / $this->k;
+		// calculate some font metrics
+		if (isset($this->CurrentFont['desc']['FontBBox'])) {
+			$bbox = explode(' ', substr($this->CurrentFont['desc']['FontBBox'], 1, -1));
+			$font_height = ((intval($bbox[3]) - intval($bbox[1])) * $size / 1000);
+		} else {
+			$font_height = $size * 1.219;
+		}
+		if (isset($this->CurrentFont['desc']['Ascent']) AND ($this->CurrentFont['desc']['Ascent'] > 0)) {
+			$font_ascent = ($this->CurrentFont['desc']['Ascent'] * $size / 1000);
+		}
+		if (isset($this->CurrentFont['desc']['Descent']) AND ($this->CurrentFont['desc']['Descent'] <= 0)) {
+			$font_descent = (- $this->CurrentFont['desc']['Descent'] * $size / 1000);
+		}
+		if (!isset($font_ascent) AND !isset($font_descent)) {
+			// core font
+			$font_ascent = 0.76 * $font_height;
+			$font_descent = $font_height - $font_ascent;
+		} elseif (!isset($font_descent)) {
+			$font_descent = $font_height - $font_ascent;
+		} elseif (!isset($font_ascent)) {
+			$font_ascent = $font_height - $font_descent;
+		}
+		$this->FontAscent = ($font_ascent / $this->k);
+		$this->FontDescent = ($font_descent / $this->k);
+		if ($out AND ($this->page > 0) AND (isset($this->CurrentFont['i'])) AND ($this->state == 2)) {
+			$this->_out(sprintf('BT /F%d %F Tf ET', $this->CurrentFont['i'], $this->FontSizePt));
+		}
+	}
+
+	/**
+	 * Returns the bounding box of the current font in user units.
+	 * @return array
+	 * @public
+	 * @since 5.9.152 (2012-03-23)
+	 */
+	public function getFontBBox() {
+		$fbbox = array();
+		if (isset($this->CurrentFont['desc']['FontBBox'])) {
+			$tmpbbox = explode(' ', substr($this->CurrentFont['desc']['FontBBox'], 1, -1));
+			$fbbox = array_map(array($this,'getAbsFontMeasure'), $tmpbbox);
+		} else {
+			// Find max width
+			if (isset($this->CurrentFont['desc']['MaxWidth'])) {
+				$maxw = $this->getAbsFontMeasure(intval($this->CurrentFont['desc']['MaxWidth']));
+			} else {
+				$maxw = 0;
+				if (isset($this->CurrentFont['desc']['MissingWidth'])) {
+					$maxw = max($maxw, $this->CurrentFont['desc']['MissingWidth']);
+				}
+				if (isset($this->CurrentFont['desc']['AvgWidth'])) {
+					$maxw = max($maxw, $this->CurrentFont['desc']['AvgWidth']);
+				}
+				if (isset($this->CurrentFont['dw'])) {
+					$maxw = max($maxw, $this->CurrentFont['dw']);
+				}
+				foreach ($this->CurrentFont['cw'] as $char => $w) {
+					$maxw = max($maxw, $w);
+				}
+				if ($maxw == 0) {
+					$maxw = 600;
+				}
+				$maxw = $this->getAbsFontMeasure($maxw);
+			}
+			$fbbox = array(0, -$this->FontDescent, $maxw, $this->FontAscent);
+		}
+		return $fbbox;
+	}
+
+	/**
+	 * Convert a relative font measure into absolute value.
+	 * @param $s (int) Font measure.
+	 * @return float Absolute measure.
+	 * @since 5.9.186 (2012-09-13)
+	 */
+	public function getAbsFontMeasure($s) {
+		return ($s * $this->FontSize / 1000);
+	}
+
+	/**
+	 * Returns the glyph bounding box of the specified character in the current font in user units.
+	 * @param $char (int) Input character code.
+	 * @return mixed array(xMin, yMin, xMax, yMax) or FALSE if not defined.
+	 * @since 5.9.186 (2012-09-13)
+	 */
+	public function getCharBBox($char) {
+		if (isset($this->CurrentFont['cbbox'][$char])) {
+			return array_map(array($this,'getAbsFontMeasure'), $this->CurrentFont['cbbox'][intval($char)]);
+		}
+		return false;
+	}
+
+	/**
+	 * Return the font descent value
+	 * @param $font (string) font name
+	 * @param $style (string) font style
+	 * @param $size (float) The size (in points)
+	 * @return int font descent
+	 * @public
+	 * @author Nicola Asuni
+	 * @since 4.9.003 (2010-03-30)
+	 */
+	public function getFontDescent($font, $style='', $size=0) {
+		$fontdata = $this->AddFont($font, $style);
+		$fontinfo = $this->getFontBuffer($fontdata['fontkey']);
+		if (isset($fontinfo['desc']['Descent']) AND ($fontinfo['desc']['Descent'] <= 0)) {
+			$descent = (- $fontinfo['desc']['Descent'] * $size / 1000);
+		} else {
+			$descent = (1.219 * 0.24 * $size);
+		}
+		return ($descent / $this->k);
+	}
+
+	/**
+	 * Return the font ascent value.
+	 * @param $font (string) font name
+	 * @param $style (string) font style
+	 * @param $size (float) The size (in points)
+	 * @return int font ascent
+	 * @public
+	 * @author Nicola Asuni
+	 * @since 4.9.003 (2010-03-30)
+	 */
+	public function getFontAscent($font, $style='', $size=0) {
+		$fontdata = $this->AddFont($font, $style);
+		$fontinfo = $this->getFontBuffer($fontdata['fontkey']);
+		if (isset($fontinfo['desc']['Ascent']) AND ($fontinfo['desc']['Ascent'] > 0)) {
+			$ascent = ($fontinfo['desc']['Ascent'] * $size / 1000);
+		} else {
+			$ascent = 1.219 * 0.76 * $size;
+		}
+		return ($ascent / $this->k);
+	}
+
+	/**
+	 * Return true in the character is present in the specified font.
+	 * @param $char (mixed) Character to check (integer value or string)
+	 * @param $font (string) Font name (family name).
+	 * @param $style (string) Font style.
+	 * @return (boolean) true if the char is defined, false otherwise.
+	 * @public
+	 * @since 5.9.153 (2012-03-28)
+	 */
+	public function isCharDefined($char, $font='', $style='') {
+		if (is_string($char)) {
+			// get character code
+			$char = $this->UTF8StringToArray($char);
+			$char = $char[0];
+		}
+		if ($this->empty_string($font)) {
+			if ($this->empty_string($style)) {
+				return (isset($this->CurrentFont['cw'][intval($char)]));
+			}
+			$font = $this->FontFamily;
+		}
+		$fontdata = $this->AddFont($font, $style);
+		$fontinfo = $this->getFontBuffer($fontdata['fontkey']);
+		return (isset($fontinfo['cw'][intval($char)]));
+	}
+
+	/**
+	 * Replace missing font characters on selected font with specified substitutions.
+	 * @param $text (string) Text to process.
+	 * @param $font (string) Font name (family name).
+	 * @param $style (string) Font style.
+	 * @param $subs (array) Array of possible character substitutions. The key is the character to check (integer value) and the value is a single intege value or an array of possible substitutes.
+	 * @return (string) Processed text.
+	 * @public
+	 * @since 5.9.153 (2012-03-28)
+	 */
+	public function replaceMissingChars($text, $font='', $style='', $subs=array()) {
+		if (empty($subs)) {
+			return $text;
+		}
+		if ($this->empty_string($font)) {
+			$font = $this->FontFamily;
+		}
+		$fontdata = $this->AddFont($font, $style);
+		$fontinfo = $this->getFontBuffer($fontdata['fontkey']);
+		$uniarr = $this->UTF8StringToArray($text);
+		foreach ($uniarr as $k => $chr) {
+			if (!isset($fontinfo['cw'][$chr])) {
+				// this character is missing on the selected font
+				if (isset($subs[$chr])) {
+					// we have available substitutions
+					if (is_array($subs[$chr])) {
+						foreach($subs[$chr] as $s) {
+							if (isset($fontinfo['cw'][$s])) {
+								$uniarr[$k] = $s;
+								break;
+							}
+						}
+					} elseif (isset($fontinfo['cw'][$subs[$chr]])) {
+						$uniarr[$k] = $subs[$chr];
+					}
+				}
+			}
+		}
+		return $this->UniArrSubString($this->UTF8ArrayToUniArray($uniarr));
+	}
+
+	/**
+	 * Defines the default monospaced font.
+	 * @param $font (string) Font name.
+	 * @public
+	 * @since 4.5.025
+	 */
+	public function SetDefaultMonospacedFont($font) {
+		$this->default_monospaced_font = $font;
+	}
+
+	/**
+	 * Creates a new internal link and returns its identifier. An internal link is a clickable area which directs to another place within the document.<br />
+	 * The identifier can then be passed to Cell(), Write(), Image() or Link(). The destination is defined with SetLink().
+	 * @public
+	 * @since 1.5
+	 * @see Cell(), Write(), Image(), Link(), SetLink()
+	 */
+	public function AddLink() {
+		//Create a new internal link
+		$n = count($this->links) + 1;
+		$this->links[$n] = array(0, 0);
+		return $n;
+	}
+
+	/**
+	 * Defines the page and position a link points to.
+	 * @param $link (int) The link identifier returned by AddLink()
+	 * @param $y (float) Ordinate of target position; -1 indicates the current position. The default value is 0 (top of page)
+	 * @param $page (int) Number of target page; -1 indicates the current page. This is the default value
+	 * @public
+	 * @since 1.5
+	 * @see AddLink()
+	 */
+	public function SetLink($link, $y=0, $page=-1) {
+		if ($y == -1) {
+			$y = $this->y;
+		}
+		if ($page == -1) {
+			$page = $this->page;
+		}
+		$this->links[$link] = array($page, $y);
+	}
+
+	/**
+	 * Puts a link on a rectangular area of the page.
+	 * Text or image links are generally put via Cell(), Write() or Image(), but this method can be useful for instance to define a clickable area inside an image.
+	 * @param $x (float) Abscissa of the upper-left corner of the rectangle
+	 * @param $y (float) Ordinate of the upper-left corner of the rectangle
+	 * @param $w (float) Width of the rectangle
+	 * @param $h (float) Height of the rectangle
+	 * @param $link (mixed) URL or identifier returned by AddLink()
+	 * @param $spaces (int) number of spaces on the text to link
+	 * @public
+	 * @since 1.5
+	 * @see AddLink(), Annotation(), Cell(), Write(), Image()
+	 */
+	public function Link($x, $y, $w, $h, $link, $spaces=0) {
+		$this->Annotation($x, $y, $w, $h, $link, array('Subtype'=>'Link'), $spaces);
+	}
+
+	/**
+	 * Check if the URL exist.
+	 * @param $ur (string) URL to check.
+	 * @return Boolean true if the URl exist, false otherwise.
+	 * @public
+	 * @since 5.9.204 (2013-01-28)
+	 */
+	public function isValidURL($url) {
+		$headers = @get_headers($url);
+    	return (strpos($headers[0], '200') !== false);
+	}
+
+	/**
+	 * Puts a markup annotation on a rectangular area of the page.
+	 * !!!!THE ANNOTATION SUPPORT IS NOT YET FULLY IMPLEMENTED !!!!
+	 * @param $x (float) Abscissa of the upper-left corner of the rectangle
+	 * @param $y (float) Ordinate of the upper-left corner of the rectangle
+	 * @param $w (float) Width of the rectangle
+	 * @param $h (float) Height of the rectangle
+	 * @param $text (string) annotation text or alternate content
+	 * @param $opt (array) array of options (see section 8.4 of PDF reference 1.7).
+	 * @param $spaces (int) number of spaces on the text to link
+	 * @public
+	 * @since 4.0.018 (2008-08-06)
+	 */
+	public function Annotation($x, $y, $w, $h, $text, $opt=array('Subtype'=>'Text'), $spaces=0) {
+		if ($this->inxobj) {
+			// store parameters for later use on template
+			$this->xobjects[$this->xobjid]['annotations'][] = array('x' => $x, 'y' => $y, 'w' => $w, 'h' => $h, 'text' => $text, 'opt' => $opt, 'spaces' => $spaces);
+			return;
+		}
+		if ($x === '') {
+			$x = $this->x;
+		}
+		if ($y === '') {
+			$y = $this->y;
+		}
+		// check page for no-write regions and adapt page margins if necessary
+		list($x, $y) = $this->checkPageRegions($h, $x, $y);
+		// recalculate coordinates to account for graphic transformations
+		if (isset($this->transfmatrix) AND !empty($this->transfmatrix)) {
+			for ($i=$this->transfmatrix_key; $i > 0; --$i) {
+				$maxid = count($this->transfmatrix[$i]) - 1;
+				for ($j=$maxid; $j >= 0; --$j) {
+					$ctm = $this->transfmatrix[$i][$j];
+					if (isset($ctm['a'])) {
+						$x = $x * $this->k;
+						$y = ($this->h - $y) * $this->k;
+						$w = $w * $this->k;
+						$h = $h * $this->k;
+						// top left
+						$xt = $x;
+						$yt = $y;
+						$x1 = ($ctm['a'] * $xt) + ($ctm['c'] * $yt) + $ctm['e'];
+						$y1 = ($ctm['b'] * $xt) + ($ctm['d'] * $yt) + $ctm['f'];
+						// top right
+						$xt = $x + $w;
+						$yt = $y;
+						$x2 = ($ctm['a'] * $xt) + ($ctm['c'] * $yt) + $ctm['e'];
+						$y2 = ($ctm['b'] * $xt) + ($ctm['d'] * $yt) + $ctm['f'];
+						// bottom left
+						$xt = $x;
+						$yt = $y - $h;
+						$x3 = ($ctm['a'] * $xt) + ($ctm['c'] * $yt) + $ctm['e'];
+						$y3 = ($ctm['b'] * $xt) + ($ctm['d'] * $yt) + $ctm['f'];
+						// bottom right
+						$xt = $x + $w;
+						$yt = $y - $h;
+						$x4 = ($ctm['a'] * $xt) + ($ctm['c'] * $yt) + $ctm['e'];
+						$y4 = ($ctm['b'] * $xt) + ($ctm['d'] * $yt) + $ctm['f'];
+						// new coordinates (rectangle area)
+						$x = min($x1, $x2, $x3, $x4);
+						$y = max($y1, $y2, $y3, $y4);
+						$w = (max($x1, $x2, $x3, $x4) - $x) / $this->k;
+						$h = ($y - min($y1, $y2, $y3, $y4)) / $this->k;
+						$x = $x / $this->k;
+						$y = $this->h - ($y / $this->k);
+					}
+				}
+			}
+		}
+		if ($this->page <= 0) {
+			$page = 1;
+		} else {
+			$page = $this->page;
+		}
+		if (!isset($this->PageAnnots[$page])) {
+			$this->PageAnnots[$page] = array();
+		}
+		$this->PageAnnots[$page][] = array('n' => ++$this->n, 'x' => $x, 'y' => $y, 'w' => $w, 'h' => $h, 'txt' => $text, 'opt' => $opt, 'numspaces' => $spaces);
+		if (!$this->pdfa_mode) {
+			if ((($opt['Subtype'] == 'FileAttachment') OR ($opt['Subtype'] == 'Sound')) AND (!$this->empty_string($opt['FS']))
+				AND (file_exists($opt['FS']) OR $this->isValidURL($opt['FS']))
+				AND (!isset($this->embeddedfiles[basename($opt['FS'])]))) {
+				$this->embeddedfiles[basename($opt['FS'])] = array('f' => ++$this->n, 'n' => ++$this->n, 'file' => $opt['FS']);
+			}
+		}
+		// Add widgets annotation's icons
+		if (isset($opt['mk']['i']) AND file_exists($opt['mk']['i'])) {
+			$this->Image($opt['mk']['i'], '', '', 10, 10, '', '', '', false, 300, '', false, false, 0, false, true);
+		}
+		if (isset($opt['mk']['ri']) AND file_exists($opt['mk']['ri'])) {
+			$this->Image($opt['mk']['ri'], '', '', 0, 0, '', '', '', false, 300, '', false, false, 0, false, true);
+		}
+		if (isset($opt['mk']['ix']) AND file_exists($opt['mk']['ix'])) {
+			$this->Image($opt['mk']['ix'], '', '', 0, 0, '', '', '', false, 300, '', false, false, 0, false, true);
+		}
+	}
+
+	/**
+	 * Embedd the attached files.
+	 * @since 4.4.000 (2008-12-07)
+	 * @protected
+	 * @see Annotation()
+	 */
+	protected function _putEmbeddedFiles() {
+		if ($this->pdfa_mode) {
+			// embedded files are not allowed in PDF/A mode
+			return;
+		}
+		reset($this->embeddedfiles);
+		foreach ($this->embeddedfiles as $filename => $filedata) {
+			// update name tree
+			$this->efnames[$filename] = $filedata['f'].' 0 R';
+			// embedded file specification  object
+			$out = $this->_getobj($filedata['f'])."\n";
+			$out .= '<</Type /Filespec /F '.$this->_datastring($filename, $filedata['f']).' /EF <</F '.$filedata['n'].' 0 R>> >>';
+			$out .= "\n".'endobj';
+			$this->_out($out);
+			// embedded file object
+			$data = file_get_contents($filedata['file']);
+			$filter = '';
+			$rawsize = strlen($data);
+			if ($this->compress) {
+				$data = gzcompress($data);
+				$filter = ' /Filter /FlateDecode';
+			}
+			$stream = $this->_getrawstream($data, $filedata['n']);
+			$out = $this->_getobj($filedata['n'])."\n";
+			$out .= '<< /Type /EmbeddedFile'.$filter.' /Length '.strlen($stream).' /Params <</Size '.$rawsize.'>> >>';
+			$out .= ' stream'."\n".$stream."\n".'endstream';
+			$out .= "\n".'endobj';
+			$this->_out($out);
+		}
+	}
+
+	/**
+	 * Prints a text cell at the specified position.
+	 * This method allows to place a string precisely on the page.
+	 * @param $x (float) Abscissa of the cell origin
+	 * @param $y (float) Ordinate of the cell origin
+	 * @param $txt (string) String to print
+	 * @param $fstroke (int) outline size in user units (false = disable)
+	 * @param $fclip (boolean) if true activate clipping mode (you must call StartTransform() before this function and StopTransform() to stop the clipping tranformation).
+	 * @param $ffill (boolean) if true fills the text
+	 * @param $border (mixed) Indicates if borders must be drawn around the cell. The value can be a number:<ul><li>0: no border (default)</li><li>1: frame</li></ul> or a string containing some or all of the following characters (in any order):<ul><li>L: left</li><li>T: top</li><li>R: right</li><li>B: bottom</li></ul> or an array of line styles for each border group - for example: array('LTRB' => array('width' => 2, 'cap' => 'butt', 'join' => 'miter', 'dash' => 0, 'color' => array(0, 0, 0)))
+	 * @param $ln (int) Indicates where the current position should go after the call. Possible values are:<ul><li>0: to the right (or left for RTL languages)</li><li>1: to the beginning of the next line</li><li>2: below</li></ul>Putting 1 is equivalent to putting 0 and calling Ln() just after. Default value: 0.
+	 * @param $align (string) Allows to center or align the text. Possible values are:<ul><li>L or empty string: left align (default value)</li><li>C: center</li><li>R: right align</li><li>J: justify</li></ul>
+	 * @param $fill (boolean) Indicates if the cell background must be painted (true) or transparent (false).
+	 * @param $link (mixed) URL or identifier returned by AddLink().
+	 * @param $stretch (int) font stretch mode: <ul><li>0 = disabled</li><li>1 = horizontal scaling only if text is larger than cell width</li><li>2 = forced horizontal scaling to fit cell width</li><li>3 = character spacing only if text is larger than cell width</li><li>4 = forced character spacing to fit cell width</li></ul> General font stretching and scaling values will be preserved when possible.
+	 * @param $ignore_min_height (boolean) if true ignore automatic minimum height value.
+	 * @param $calign (string) cell vertical alignment relative to the specified Y value. Possible values are:<ul><li>T : cell top</li><li>A : font top</li><li>L : font baseline</li><li>D : font bottom</li><li>B : cell bottom</li></ul>
+	 * @param $valign (string) text vertical alignment inside the cell. Possible values are:<ul><li>T : top</li><li>C : center</li><li>B : bottom</li></ul>
+	 * @param $rtloff (boolean) if true uses the page top-left corner as origin of axis for $x and $y initial position.
+	 * @public
+	 * @since 1.0
+	 * @see Cell(), Write(), MultiCell(), WriteHTML(), WriteHTMLCell()
+	 */
+	public function Text($x, $y, $txt, $fstroke=false, $fclip=false, $ffill=true, $border=0, $ln=0, $align='', $fill=false, $link='', $stretch=0, $ignore_min_height=false, $calign='T', $valign='M', $rtloff=false) {
+		$textrendermode = $this->textrendermode;
+		$textstrokewidth = $this->textstrokewidth;
+		$this->setTextRenderingMode($fstroke, $ffill, $fclip);
+		$this->SetXY($x, $y, $rtloff);
+		$this->Cell(0, 0, $txt, $border, $ln, $align, $fill, $link, $stretch, $ignore_min_height, $calign, $valign);
+		// restore previous rendering mode
+		$this->textrendermode = $textrendermode;
+		$this->textstrokewidth = $textstrokewidth;
+	}
+
+	/**
+	 * Whenever a page break condition is met, the method is called, and the break is issued or not depending on the returned value.
+	 * The default implementation returns a value according to the mode selected by SetAutoPageBreak().<br />
+	 * This method is called automatically and should not be called directly by the application.
+	 * @return boolean
+	 * @public
+	 * @since 1.4
+	 * @see SetAutoPageBreak()
+	 */
+	public function AcceptPageBreak() {
+		if ($this->num_columns > 1) {
+			// multi column mode
+			if ($this->current_column < ($this->num_columns - 1)) {
+				// go to next column
+				$this->selectColumn($this->current_column + 1);
+			} elseif ($this->AutoPageBreak) {
+				// add a new page
+				$this->AddPage();
+				// set first column
+				$this->selectColumn(0);
+			}
+			// avoid page breaking from checkPageBreak()
+			return false;
+		}
+		return $this->AutoPageBreak;
+	}
+
+	/**
+	 * Add page if needed.
+	 * @param $h (float) Cell height. Default value: 0.
+	 * @param $y (mixed) starting y position, leave empty for current position.
+	 * @param $addpage (boolean) if true add a page, otherwise only return the true/false state
+	 * @return boolean true in case of page break, false otherwise.
+	 * @since 3.2.000 (2008-07-01)
+	 * @protected
+	 */
+	protected function checkPageBreak($h=0, $y='', $addpage=true) {
+		if ($this->empty_string($y)) {
+			$y = $this->y;
+		}
+		$current_page = $this->page;
+		if ((($y + $h) > $this->PageBreakTrigger) AND ($this->inPageBody()) AND ($this->AcceptPageBreak())) {
+			if ($addpage) {
+				//Automatic page break
+				$x = $this->x;
+				$this->AddPage($this->CurOrientation);
+				$this->y = $this->tMargin;
+				$oldpage = $this->page - 1;
+				if ($this->rtl) {
+					if ($this->pagedim[$this->page]['orm'] != $this->pagedim[$oldpage]['orm']) {
+						$this->x = $x - ($this->pagedim[$this->page]['orm'] - $this->pagedim[$oldpage]['orm']);
+					} else {
+						$this->x = $x;
+					}
+				} else {
+					if ($this->pagedim[$this->page]['olm'] != $this->pagedim[$oldpage]['olm']) {
+						$this->x = $x + ($this->pagedim[$this->page]['olm'] - $this->pagedim[$oldpage]['olm']);
+					} else {
+						$this->x = $x;
+					}
+				}
+			}
+			return true;
+		}
+		if ($current_page != $this->page) {
+			// account for columns mode
+			return true;
+		}
+		return false;
+	}
+
+	/**
+	 * Removes SHY characters from text.
+	 * Unicode Data:<ul>
+	 * <li>Name : SOFT HYPHEN, commonly abbreviated as SHY</li>
+	 * <li>HTML Entity (decimal): "&#173;"</li>
+	 * <li>HTML Entity (hex): "&#xad;"</li>
+	 * <li>HTML Entity (named): "&shy;"</li>
+	 * <li>How to type in Microsoft Windows: [Alt +00AD] or [Alt 0173]</li>
+	 * <li>UTF-8 (hex): 0xC2 0xAD (c2ad)</li>
+	 * <li>UTF-8 character: chr(194).chr(173)</li>
+	 * </ul>
+	 * @param $txt (string) input string
+	 * @return string without SHY characters.
+	 * @public
+	 * @since (4.5.019) 2009-02-28
+	 */
+	public function removeSHY($txt='') {
+		$txt = preg_replace('/([\\xc2]{1}[\\xad]{1})/', '', $txt);
+		if (!$this->isunicode) {
+			$txt = preg_replace('/([\\xad]{1})/', '', $txt);
+		}
+		return $txt;
+	}
+
+	/**
+	 * Prints a cell (rectangular area) with optional borders, background color and character string. The upper-left corner of the cell corresponds to the current position. The text can be aligned or centered. After the call, the current position moves to the right or to the next line. It is possible to put a link on the text.<br />
+	 * If automatic page breaking is enabled and the cell goes beyond the limit, a page break is done before outputting.
+	 * @param $w (float) Cell width. If 0, the cell extends up to the right margin.
+	 * @param $h (float) Cell height. Default value: 0.
+	 * @param $txt (string) String to print. Default value: empty string.
+	 * @param $border (mixed) Indicates if borders must be drawn around the cell. The value can be a number:<ul><li>0: no border (default)</li><li>1: frame</li></ul> or a string containing some or all of the following characters (in any order):<ul><li>L: left</li><li>T: top</li><li>R: right</li><li>B: bottom</li></ul> or an array of line styles for each border group - for example: array('LTRB' => array('width' => 2, 'cap' => 'butt', 'join' => 'miter', 'dash' => 0, 'color' => array(0, 0, 0)))
+	 * @param $ln (int) Indicates where the current position should go after the call. Possible values are:<ul><li>0: to the right (or left for RTL languages)</li><li>1: to the beginning of the next line</li><li>2: below</li></ul> Putting 1 is equivalent to putting 0 and calling Ln() just after. Default value: 0.
+	 * @param $align (string) Allows to center or align the text. Possible values are:<ul><li>L or empty string: left align (default value)</li><li>C: center</li><li>R: right align</li><li>J: justify</li></ul>
+	 * @param $fill (boolean) Indicates if the cell background must be painted (true) or transparent (false).
+	 * @param $link (mixed) URL or identifier returned by AddLink().
+	 * @param $stretch (int) font stretch mode: <ul><li>0 = disabled</li><li>1 = horizontal scaling only if text is larger than cell width</li><li>2 = forced horizontal scaling to fit cell width</li><li>3 = character spacing only if text is larger than cell width</li><li>4 = forced character spacing to fit cell width</li></ul> General font stretching and scaling values will be preserved when possible.
+	 * @param $ignore_min_height (boolean) if true ignore automatic minimum height value.
+	 * @param $calign (string) cell vertical alignment relative to the specified Y value. Possible values are:<ul><li>T : cell top</li><li>C : center</li><li>B : cell bottom</li><li>A : font top</li><li>L : font baseline</li><li>D : font bottom</li></ul>
+	 * @param $valign (string) text vertical alignment inside the cell. Possible values are:<ul><li>T : top</li><li>C : center</li><li>B : bottom</li></ul>
+	 * @public
+	 * @since 1.0
+	 * @see SetFont(), SetDrawColor(), SetFillColor(), SetTextColor(), SetLineWidth(), AddLink(), Ln(), MultiCell(), Write(), SetAutoPageBreak()
+	 */
+	public function Cell($w, $h=0, $txt='', $border=0, $ln=0, $align='', $fill=false, $link='', $stretch=0, $ignore_min_height=false, $calign='T', $valign='M') {
+		$prev_cell_margin = $this->cell_margin;
+		$prev_cell_padding = $this->cell_padding;
+		$this->adjustCellPadding($border);
+		if (!$ignore_min_height) {
+			$min_cell_height = ($this->FontSize * $this->cell_height_ratio) + $this->cell_padding['T'] + $this->cell_padding['B'];
+			if ($h < $min_cell_height) {
+				$h = $min_cell_height;
+			}
+		}
+		$this->checkPageBreak($h + $this->cell_margin['T'] + $this->cell_margin['B']);
+		// apply text shadow if enabled
+		if ($this->txtshadow['enabled']) {
+			// save data
+			$x = $this->x;
+			$y = $this->y;
+			$bc = $this->bgcolor;
+			$fc = $this->fgcolor;
+			$sc = $this->strokecolor;
+			$alpha = $this->alpha;
+			// print shadow
+			$this->x += $this->txtshadow['depth_w'];
+			$this->y += $this->txtshadow['depth_h'];
+			$this->SetFillColorArray($this->txtshadow['color']);
+			$this->SetTextColorArray($this->txtshadow['color']);
+			$this->SetDrawColorArray($this->txtshadow['color']);
+			if ($this->txtshadow['opacity'] != $alpha['CA']) {
+				$this->setAlpha($this->txtshadow['opacity'], $this->txtshadow['blend_mode']);
+			}
+			if ($this->state == 2) {
+				$this->_out($this->getCellCode($w, $h, $txt, $border, $ln, $align, $fill, $link, $stretch, true, $calign, $valign));
+			}
+			//restore data
+			$this->x = $x;
+			$this->y = $y;
+			$this->SetFillColorArray($bc);
+			$this->SetTextColorArray($fc);
+			$this->SetDrawColorArray($sc);
+			if ($this->txtshadow['opacity'] != $alpha['CA']) {
+				$this->setAlpha($alpha['CA'], $alpha['BM'], $alpha['ca'], $alpha['AIS']);
+			}
+		}
+		if ($this->state == 2) {
+			$this->_out($this->getCellCode($w, $h, $txt, $border, $ln, $align, $fill, $link, $stretch, true, $calign, $valign));
+		}
+		$this->cell_padding = $prev_cell_padding;
+		$this->cell_margin = $prev_cell_margin;
+	}
+
+	/**
+	 * Returns the PDF string code to print a cell (rectangular area) with optional borders, background color and character string. The upper-left corner of the cell corresponds to the current position. The text can be aligned or centered. After the call, the current position moves to the right or to the next line. It is possible to put a link on the text.<br />
+	 * If automatic page breaking is enabled and the cell goes beyond the limit, a page break is done before outputting.
+	 * @param $w (float) Cell width. If 0, the cell extends up to the right margin.
+	 * @param $h (float) Cell height. Default value: 0.
+	 * @param $txt (string) String to print. Default value: empty string.
+	 * @param $border (mixed) Indicates if borders must be drawn around the cell. The value can be a number:<ul><li>0: no border (default)</li><li>1: frame</li></ul> or a string containing some or all of the following characters (in any order):<ul><li>L: left</li><li>T: top</li><li>R: right</li><li>B: bottom</li></ul> or an array of line styles for each border group - for example: array('LTRB' => array('width' => 2, 'cap' => 'butt', 'join' => 'miter', 'dash' => 0, 'color' => array(0, 0, 0)))
+	 * @param $ln (int) Indicates where the current position should go after the call. Possible values are:<ul><li>0: to the right (or left for RTL languages)</li><li>1: to the beginning of the next line</li><li>2: below</li></ul>Putting 1 is equivalent to putting 0 and calling Ln() just after. Default value: 0.
+	 * @param $align (string) Allows to center or align the text. Possible values are:<ul><li>L or empty string: left align (default value)</li><li>C: center</li><li>R: right align</li><li>J: justify</li></ul>
+	 * @param $fill (boolean) Indicates if the cell background must be painted (true) or transparent (false).
+	 * @param $link (mixed) URL or identifier returned by AddLink().
+	 * @param $stretch (int) font stretch mode: <ul><li>0 = disabled</li><li>1 = horizontal scaling only if text is larger than cell width</li><li>2 = forced horizontal scaling to fit cell width</li><li>3 = character spacing only if text is larger than cell width</li><li>4 = forced character spacing to fit cell width</li></ul> General font stretching and scaling values will be preserved when possible.
+	 * @param $ignore_min_height (boolean) if true ignore automatic minimum height value.
+	 * @param $calign (string) cell vertical alignment relative to the specified Y value. Possible values are:<ul><li>T : cell top</li><li>C : center</li><li>B : cell bottom</li><li>A : font top</li><li>L : font baseline</li><li>D : font bottom</li></ul>
+	 * @param $valign (string) text vertical alignment inside the cell. Possible values are:<ul><li>T : top</li><li>M : middle</li><li>B : bottom</li></ul>
+	 * @return string containing cell code
+	 * @protected
+	 * @since 1.0
+	 * @see Cell()
+	 */
+	protected function getCellCode($w, $h=0, $txt='', $border=0, $ln=0, $align='', $fill=false, $link='', $stretch=0, $ignore_min_height=false, $calign='T', $valign='M') {
+		// replace 'NO-BREAK SPACE' (U+00A0) character with a simple space
+		$txt = str_replace($this->unichr(160), ' ', $txt);
+		$prev_cell_margin = $this->cell_margin;
+		$prev_cell_padding = $this->cell_padding;
+		$txt = $this->removeSHY($txt);
+		$rs = ''; //string to be returned
+		$this->adjustCellPadding($border);
+		if (!$ignore_min_height) {
+			$min_cell_height = ($this->FontSize * $this->cell_height_ratio) + $this->cell_padding['T'] + $this->cell_padding['B'];
+			if ($h < $min_cell_height) {
+				$h = $min_cell_height;
+			}
+		}
+		$k = $this->k;
+		// check page for no-write regions and adapt page margins if necessary
+		list($this->x, $this->y) = $this->checkPageRegions($h, $this->x, $this->y);
+		if ($this->rtl) {
+			$x = $this->x - $this->cell_margin['R'];
+		} else {
+			$x = $this->x + $this->cell_margin['L'];
+		}
+		$y = $this->y + $this->cell_margin['T'];
+		$prev_font_stretching = $this->font_stretching;
+		$prev_font_spacing = $this->font_spacing;
+		// cell vertical alignment
+		switch ($calign) {
+			case 'A': {
+				// font top
+				switch ($valign) {
+					case 'T': {
+						// top
+						$y -= $this->cell_padding['T'];
+						break;
+					}
+					case 'B': {
+						// bottom
+						$y -= ($h - $this->cell_padding['B'] - $this->FontAscent - $this->FontDescent);
+						break;
+					}
+					default:
+					case 'C':
+					case 'M': {
+						// center
+						$y -= (($h - $this->FontAscent - $this->FontDescent) / 2);
+						break;
+					}
+				}
+				break;
+			}
+			case 'L': {
+				// font baseline
+				switch ($valign) {
+					case 'T': {
+						// top
+						$y -= ($this->cell_padding['T'] + $this->FontAscent);
+						break;
+					}
+					case 'B': {
+						// bottom
+						$y -= ($h - $this->cell_padding['B'] - $this->FontDescent);
+						break;
+					}
+					default:
+					case 'C':
+					case 'M': {
+						// center
+						$y -= (($h + $this->FontAscent - $this->FontDescent) / 2);
+						break;
+					}
+				}
+				break;
+			}
+			case 'D': {
+				// font bottom
+				switch ($valign) {
+					case 'T': {
+						// top
+						$y -= ($this->cell_padding['T'] + $this->FontAscent + $this->FontDescent);
+						break;
+					}
+					case 'B': {
+						// bottom
+						$y -= ($h - $this->cell_padding['B']);
+						break;
+					}
+					default:
+					case 'C':
+					case 'M': {
+						// center
+						$y -= (($h + $this->FontAscent + $this->FontDescent) / 2);
+						break;
+					}
+				}
+				break;
+			}
+			case 'B': {
+				// cell bottom
+				$y -= $h;
+				break;
+			}
+			case 'C':
+			case 'M': {
+				// cell center
+				$y -= ($h / 2);
+				break;
+			}
+			default:
+			case 'T': {
+				// cell top
+				break;
+			}
+		}
+		// text vertical alignment
+		switch ($valign) {
+			case 'T': {
+				// top
+				$yt = $y + $this->cell_padding['T'];
+				break;
+			}
+			case 'B': {
+				// bottom
+				$yt = $y + $h - $this->cell_padding['B'] - $this->FontAscent - $this->FontDescent;
+				break;
+			}
+			default:
+			case 'C':
+			case 'M': {
+				// center
+				$yt = $y + (($h - $this->FontAscent - $this->FontDescent) / 2);
+				break;
+			}
+		}
+		$basefonty = $yt + $this->FontAscent;
+		if ($this->empty_string($w) OR ($w <= 0)) {
+			if ($this->rtl) {
+				$w = $x - $this->lMargin;
+			} else {
+				$w = $this->w - $this->rMargin - $x;
+			}
+		}
+		$s = '';
+		// fill and borders
+		if (is_string($border) AND (strlen($border) == 4)) {
+			// full border
+			$border = 1;
+		}
+		if ($fill OR ($border == 1)) {
+			if ($fill) {
+				$op = ($border == 1) ? 'B' : 'f';
+			} else {
+				$op = 'S';
+			}
+			if ($this->rtl) {
+				$xk = (($x - $w) * $k);
+			} else {
+				$xk = ($x * $k);
+			}
+			$s .= sprintf('%F %F %F %F re %s ', $xk, (($this->h - $y) * $k), ($w * $k), (-$h * $k), $op);
+		}
+		// draw borders
+		$s .= $this->getCellBorder($x, $y, $w, $h, $border);
+		if ($txt != '') {
+			$txt2 = $txt;
+			if ($this->isunicode) {
+				if (($this->CurrentFont['type'] == 'core') OR ($this->CurrentFont['type'] == 'TrueType') OR ($this->CurrentFont['type'] == 'Type1')) {
+					$txt2 = $this->UTF8ToLatin1($txt2);
+				} else {
+					$unicode = $this->UTF8StringToArray($txt); // array of UTF-8 unicode values
+					$unicode = $this->utf8Bidi($unicode, '', $this->tmprtl);
+					// replace thai chars (if any)
+					if (defined('K_THAI_TOPCHARS') AND (K_THAI_TOPCHARS == true)) {
+						// number of chars
+						$numchars = count($unicode);
+						// po pla, for far, for fan
+						$longtail = array(0x0e1b, 0x0e1d, 0x0e1f);
+						// do chada, to patak
+						$lowtail = array(0x0e0e, 0x0e0f);
+						// mai hun arkad, sara i, sara ii, sara ue, sara uee
+						$upvowel = array(0x0e31, 0x0e34, 0x0e35, 0x0e36, 0x0e37);
+						// mai ek, mai tho, mai tri, mai chattawa, karan
+						$tonemark = array(0x0e48, 0x0e49, 0x0e4a, 0x0e4b, 0x0e4c);
+						// sara u, sara uu, pinthu
+						$lowvowel = array(0x0e38, 0x0e39, 0x0e3a);
+						$output = array();
+						for ($i = 0; $i < $numchars; $i++) {
+							if (($unicode[$i] >= 0x0e00) && ($unicode[$i] <= 0x0e5b)) {
+								$ch0 = $unicode[$i];
+								$ch1 = ($i > 0) ? $unicode[($i - 1)] : 0;
+								$ch2 = ($i > 1) ? $unicode[($i - 2)] : 0;
+								$chn = ($i < ($numchars - 1)) ? $unicode[($i + 1)] : 0;
+								if (in_array($ch0, $tonemark)) {
+									if ($chn == 0x0e33) {
+										// sara um
+										if (in_array($ch1, $longtail)) {
+											// tonemark at upper left
+											$output[] = $this->replaceChar($ch0, (0xf713 + $ch0 - 0x0e48));
+										} else {
+											// tonemark at upper right (normal position)
+											$output[] = $ch0;
+										}
+									} elseif (in_array($ch1, $longtail) OR (in_array($ch2, $longtail) AND in_array($ch1, $lowvowel))) {
+										// tonemark at lower left
+										$output[] = $this->replaceChar($ch0, (0xf705 + $ch0 - 0x0e48));
+									} elseif (in_array($ch1, $upvowel)) {
+										if (in_array($ch2, $longtail)) {
+											// tonemark at upper left
+											$output[] = $this->replaceChar($ch0, (0xf713 + $ch0 - 0x0e48));
+										} else {
+											// tonemark at upper right (normal position)
+											$output[] = $ch0;
+										}
+									} else {
+										// tonemark at lower right
+										$output[] = $this->replaceChar($ch0, (0xf70a + $ch0 - 0x0e48));
+									}
+								} elseif (($ch0 == 0x0e33) AND (in_array($ch1, $longtail) OR (in_array($ch2, $longtail) AND in_array($ch1, $tonemark)))) {
+									// add lower left nikhahit and sara aa
+									if ($this->isCharDefined(0xf711) AND $this->isCharDefined(0x0e32)) {
+										$output[] = 0xf711;
+										$this->CurrentFont['subsetchars'][0xf711] = true;
+										$output[] = 0x0e32;
+										$this->CurrentFont['subsetchars'][0x0e32] = true;
+									} else {
+										$output[] = $ch0;
+									}
+								} elseif (in_array($ch1, $longtail)) {
+									if ($ch0 == 0x0e31) {
+										// lower left mai hun arkad
+										$output[] = $this->replaceChar($ch0, 0xf710);
+									} elseif (in_array($ch0, $upvowel)) {
+										// lower left
+										$output[] = $this->replaceChar($ch0, (0xf701 + $ch0 - 0x0e34));
+									} elseif ($ch0 == 0x0e47) {
+										// lower left mai tai koo
+										$output[] = $this->replaceChar($ch0, 0xf712);
+									} else {
+										// normal character
+										$output[] = $ch0;
+									}
+								} elseif (in_array($ch1, $lowtail) AND in_array($ch0, $lowvowel)) {
+									// lower vowel
+									$output[] = $this->replaceChar($ch0, (0xf718 + $ch0 - 0x0e38));
+								} elseif (($ch0 == 0x0e0d) AND in_array($chn, $lowvowel)) {
+									// yo ying without lower part
+									$output[] = $this->replaceChar($ch0, 0xf70f);
+								} elseif (($ch0 == 0x0e10) AND in_array($chn, $lowvowel)) {
+									// tho santan without lower part
+									$output[] = $this->replaceChar($ch0, 0xf700);
+								} else {
+									$output[] = $ch0;
+								}
+							} else {
+								// non-thai character
+								$output[] = $unicode[$i];
+							}
+						}
+						$unicode = $output;
+						// update font subsetchars
+						$this->setFontSubBuffer($this->CurrentFont['fontkey'], 'subsetchars', $this->CurrentFont['subsetchars']);
+					} // end of K_THAI_TOPCHARS
+					$txt2 = $this->arrUTF8ToUTF16BE($unicode, false);
+				}
+			}
+			$txt2 = $this->_escape($txt2);
+			// get current text width (considering general font stretching and spacing)
+			$txwidth = $this->GetStringWidth($txt);
+			$width = $txwidth;
+			// check for stretch mode
+			if ($stretch > 0) {
+				// calculate ratio between cell width and text width
+				if ($width <= 0) {
+					$ratio = 1;
+				} else {
+					$ratio = (($w - $this->cell_padding['L'] - $this->cell_padding['R']) / $width);
+				}
+				// check if stretching is required
+				if (($ratio < 1) OR (($ratio > 1) AND (($stretch % 2) == 0))) {
+					// the text will be stretched to fit cell width
+					if ($stretch > 2) {
+						// set new character spacing
+						$this->font_spacing += ($w - $this->cell_padding['L'] - $this->cell_padding['R'] - $width) / (max(($this->GetNumChars($txt) - 1), 1) * ($this->font_stretching / 100));
+					} else {
+						// set new horizontal stretching
+						$this->font_stretching *= $ratio;
+					}
+					// recalculate text width (the text fills the entire cell)
+					$width = $w - $this->cell_padding['L'] - $this->cell_padding['R'];
+					// reset alignment
+					$align = '';
+				}
+			}
+			if ($this->font_stretching != 100) {
+				// apply font stretching
+				$rs .= sprintf('BT %F Tz ET ', $this->font_stretching);
+			}
+			if ($this->font_spacing != 0) {
+				// increase/decrease font spacing
+				$rs .= sprintf('BT %F Tc ET ', ($this->font_spacing * $this->k));
+			}
+			if ($this->ColorFlag AND ($this->textrendermode < 4)) {
+				$s .= 'q '.$this->TextColor.' ';
+			}
+			// rendering mode
+			$s .= sprintf('BT %d Tr %F w ET ', $this->textrendermode, ($this->textstrokewidth * $this->k));
+			// count number of spaces
+			$ns = substr_count($txt, chr(32));
+			// Justification
+			$spacewidth = 0;
+			if (($align == 'J') AND ($ns > 0)) {
+				if ($this->isUnicodeFont()) {
+					// get string width without spaces
+					$width = $this->GetStringWidth(str_replace(' ', '', $txt));
+					// calculate average space width
+					$spacewidth = -1000 * ($w - $width - $this->cell_padding['L'] - $this->cell_padding['R']) / ($ns?$ns:1) / $this->FontSize;
+					if ($this->font_stretching != 100) {
+						// word spacing is affected by stretching
+						$spacewidth /= ($this->font_stretching / 100);
+					}
+					// set word position to be used with TJ operator
+					$txt2 = str_replace(chr(0).chr(32), ') '.sprintf('%F', $spacewidth).' (', $txt2);
+					$unicode_justification = true;
+				} else {
+					// get string width
+					$width = $txwidth;
+					// new space width
+					$spacewidth = (($w - $width - $this->cell_padding['L'] - $this->cell_padding['R']) / ($ns?$ns:1)) * $this->k;
+					if ($this->font_stretching != 100) {
+						// word spacing (Tw) is affected by stretching
+						$spacewidth /= ($this->font_stretching / 100);
+					}
+					// set word spacing
+					$rs .= sprintf('BT %F Tw ET ', $spacewidth);
+				}
+				$width = $w - $this->cell_padding['L'] - $this->cell_padding['R'];
+			}
+			// replace carriage return characters
+			$txt2 = str_replace("\r", ' ', $txt2);
+			switch ($align) {
+				case 'C': {
+					$dx = ($w - $width) / 2;
+					break;
+				}
+				case 'R': {
+					if ($this->rtl) {
+						$dx = $this->cell_padding['R'];
+					} else {
+						$dx = $w - $width - $this->cell_padding['R'];
+					}
+					break;
+				}
+				case 'L': {
+					if ($this->rtl) {
+						$dx = $w - $width - $this->cell_padding['L'];
+					} else {
+						$dx = $this->cell_padding['L'];
+					}
+					break;
+				}
+				case 'J':
+				default: {
+					if ($this->rtl) {
+						$dx = $this->cell_padding['R'];
+					} else {
+						$dx = $this->cell_padding['L'];
+					}
+					break;
+				}
+			}
+			if ($this->rtl) {
+				$xdx = $x - $dx - $width;
+			} else {
+				$xdx = $x + $dx;
+			}
+			$xdk = $xdx * $k;
+			// print text
+			$s .= sprintf('BT %F %F Td [(%s)] TJ ET', $xdk, (($this->h - $basefonty) * $k), $txt2);
+			if (isset($uniblock)) {
+				// print overlapping characters as separate string
+				$xshift = 0; // horizontal shift
+				$ty = (($this->h - $basefonty + (0.2 * $this->FontSize)) * $k);
+				$spw = (($w - $txwidth - $this->cell_padding['L'] - $this->cell_padding['R']) / ($ns?$ns:1));
+				foreach ($uniblock as $uk => $uniarr) {
+					if (($uk % 2) == 0) {
+						// x space to skip
+						if ($spacewidth != 0) {
+							// justification shift
+							$xshift += (count(array_keys($uniarr, 32)) * $spw);
+						}
+						$xshift += $this->GetArrStringWidth($uniarr); // + shift justification
+					} else {
+						// character to print
+						$topchr = $this->arrUTF8ToUTF16BE($uniarr, false);
+						$topchr = $this->_escape($topchr);
+						$s .= sprintf(' BT %F %F Td [(%s)] TJ ET', ($xdk + ($xshift * $k)), $ty, $topchr);
+					}
+				}
+			}
+			if ($this->underline) {
+				$s .= ' '.$this->_dounderlinew($xdx, $basefonty, $width);
+			}
+			if ($this->linethrough) {
+				$s .= ' '.$this->_dolinethroughw($xdx, $basefonty, $width);
+			}
+			if ($this->overline) {
+				$s .= ' '.$this->_dooverlinew($xdx, $basefonty, $width);
+			}
+			if ($this->ColorFlag AND ($this->textrendermode < 4)) {
+				$s .= ' Q';
+			}
+			if ($link) {
+				$this->Link($xdx, $yt, $width, ($this->FontAscent + $this->FontDescent), $link, $ns);
+			}
+		}
+		// output cell
+		if ($s) {
+			// output cell
+			$rs .= $s;
+			if ($this->font_spacing != 0) {
+				// reset font spacing mode
+				$rs .= ' BT 0 Tc ET';
+			}
+			if ($this->font_stretching != 100) {
+				// reset font stretching mode
+				$rs .= ' BT 100 Tz ET';
+			}
+		}
+		// reset word spacing
+		if (!$this->isUnicodeFont() AND ($align == 'J')) {
+			$rs .= ' BT 0 Tw ET';
+		}
+		// reset stretching and spacing
+		$this->font_stretching = $prev_font_stretching;
+		$this->font_spacing = $prev_font_spacing;
+		$this->lasth = $h;
+		if ($ln > 0) {
+			//Go to the beginning of the next line
+			$this->y = $y + $h + $this->cell_margin['B'];
+			if ($ln == 1) {
+				if ($this->rtl) {
+					$this->x = $this->w - $this->rMargin;
+				} else {
+					$this->x = $this->lMargin;
+				}
+			}
+		} else {
+			// go left or right by case
+			if ($this->rtl) {
+				$this->x = $x - $w - $this->cell_margin['L'];
+			} else {
+				$this->x = $x + $w + $this->cell_margin['R'];
+			}
+		}
+		$gstyles = ''.$this->linestyleWidth.' '.$this->linestyleCap.' '.$this->linestyleJoin.' '.$this->linestyleDash.' '.$this->DrawColor.' '.$this->FillColor."\n";
+		$rs = $gstyles.$rs;
+		$this->cell_padding = $prev_cell_padding;
+		$this->cell_margin = $prev_cell_margin;
+		return $rs;
+	}
+
+	/**
+	 * Replace a char if is defined on the current font.
+	 * @param $oldchar (int) Integer code (unicode) of the character to replace.
+	 * @param $newchar (int) Integer code (unicode) of the new character.
+	 * @return int the replaced char or the old char in case the new char i not defined
+	 * @protected
+	 * @since 5.9.167 (2012-06-22)
+	 */
+	protected function replaceChar($oldchar, $newchar) {
+		if ($this->isCharDefined($newchar)) {
+			// add the new char on the subset list
+			$this->CurrentFont['subsetchars'][$newchar] = true;
+			// return the new character
+			return $newchar;
+		}
+		// return the old char
+		return $oldchar;
+	}
+
+	/**
+	 * Returns the code to draw the cell border
+	 * @param $x (float) X coordinate.
+	 * @param $y (float) Y coordinate.
+	 * @param $w (float) Cell width.
+	 * @param $h (float) Cell height.
+	 * @param $brd (mixed) Indicates if borders must be drawn around the cell. The value can be a number:<ul><li>0: no border (default)</li><li>1: frame</li></ul> or a string containing some or all of the following characters (in any order):<ul><li>L: left</li><li>T: top</li><li>R: right</li><li>B: bottom</li></ul> or an array of line styles for each border group - for example: array('LTRB' => array('width' => 2, 'cap' => 'butt', 'join' => 'miter', 'dash' => 0, 'color' => array(0, 0, 0)))
+	 * @return string containing cell border code
+	 * @protected
+	 * @see SetLineStyle()
+	 * @since 5.7.000 (2010-08-02)
+	 */
+	protected function getCellBorder($x, $y, $w, $h, $brd) {
+		$s = ''; // string to be returned
+		if (empty($brd)) {
+			return $s;
+		}
+		if ($brd == 1) {
+			$brd = array('LRTB' => true);
+		}
+		// calculate coordinates for border
+		$k = $this->k;
+		if ($this->rtl) {
+			$xeL = ($x - $w) * $k;
+			$xeR = $x * $k;
+		} else {
+			$xeL = $x * $k;
+			$xeR = ($x + $w) * $k;
+		}
+		$yeL = (($this->h - ($y + $h)) * $k);
+		$yeT = (($this->h - $y) * $k);
+		$xeT = $xeL;
+		$xeB = $xeR;
+		$yeR = $yeT;
+		$yeB = $yeL;
+		if (is_string($brd)) {
+			// convert string to array
+			$slen = strlen($brd);
+			$newbrd = array();
+			for ($i = 0; $i < $slen; ++$i) {
+				$newbrd[$brd[$i]] = array('cap' => 'square', 'join' => 'miter');
+			}
+			$brd = $newbrd;
+		}
+		if (isset($brd['mode'])) {
+			$mode = $brd['mode'];
+			unset($brd['mode']);
+		} else {
+			$mode = 'normal';
+		}
+		foreach ($brd as $border => $style) {
+			if (is_array($style) AND !empty($style)) {
+				// apply border style
+				$prev_style = $this->linestyleWidth.' '.$this->linestyleCap.' '.$this->linestyleJoin.' '.$this->linestyleDash.' '.$this->DrawColor.' ';
+				$s .= $this->SetLineStyle($style, true)."\n";
+			}
+			switch ($mode) {
+				case 'ext': {
+					$off = (($this->LineWidth / 2) * $k);
+					$xL = $xeL - $off;
+					$xR = $xeR + $off;
+					$yT = $yeT + $off;
+					$yL = $yeL - $off;
+					$xT = $xL;
+					$xB = $xR;
+					$yR = $yT;
+					$yB = $yL;
+					$w += $this->LineWidth;
+					$h += $this->LineWidth;
+					break;
+				}
+				case 'int': {
+					$off = ($this->LineWidth / 2) * $k;
+					$xL = $xeL + $off;
+					$xR = $xeR - $off;
+					$yT = $yeT - $off;
+					$yL = $yeL + $off;
+					$xT = $xL;
+					$xB = $xR;
+					$yR = $yT;
+					$yB = $yL;
+					$w -= $this->LineWidth;
+					$h -= $this->LineWidth;
+					break;
+				}
+				case 'normal':
+				default: {
+					$xL = $xeL;
+					$xT = $xeT;
+					$xB = $xeB;
+					$xR = $xeR;
+					$yL = $yeL;
+					$yT = $yeT;
+					$yB = $yeB;
+					$yR = $yeR;
+					break;
+				}
+			}
+			// draw borders by case
+			if (strlen($border) == 4) {
+				$s .= sprintf('%F %F %F %F re S ', $xT, $yT, ($w * $k), (-$h * $k));
+			} elseif (strlen($border) == 3) {
+				if (strpos($border,'B') === false) { // LTR
+					$s .= sprintf('%F %F m ', $xL, $yL);
+					$s .= sprintf('%F %F l ', $xT, $yT);
+					$s .= sprintf('%F %F l ', $xR, $yR);
+					$s .= sprintf('%F %F l ', $xB, $yB);
+					$s .= 'S ';
+				} elseif (strpos($border,'L') === false) { // TRB
+					$s .= sprintf('%F %F m ', $xT, $yT);
+					$s .= sprintf('%F %F l ', $xR, $yR);
+					$s .= sprintf('%F %F l ', $xB, $yB);
+					$s .= sprintf('%F %F l ', $xL, $yL);
+					$s .= 'S ';
+				} elseif (strpos($border,'T') === false) { // RBL
+					$s .= sprintf('%F %F m ', $xR, $yR);
+					$s .= sprintf('%F %F l ', $xB, $yB);
+					$s .= sprintf('%F %F l ', $xL, $yL);
+					$s .= sprintf('%F %F l ', $xT, $yT);
+					$s .= 'S ';
+				} elseif (strpos($border,'R') === false) { // BLT
+					$s .= sprintf('%F %F m ', $xB, $yB);
+					$s .= sprintf('%F %F l ', $xL, $yL);
+					$s .= sprintf('%F %F l ', $xT, $yT);
+					$s .= sprintf('%F %F l ', $xR, $yR);
+					$s .= 'S ';
+				}
+			} elseif (strlen($border) == 2) {
+				if ((strpos($border,'L') !== false) AND (strpos($border,'T') !== false)) { // LT
+					$s .= sprintf('%F %F m ', $xL, $yL);
+					$s .= sprintf('%F %F l ', $xT, $yT);
+					$s .= sprintf('%F %F l ', $xR, $yR);
+					$s .= 'S ';
+				} elseif ((strpos($border,'T') !== false) AND (strpos($border,'R') !== false)) { // TR
+					$s .= sprintf('%F %F m ', $xT, $yT);
+					$s .= sprintf('%F %F l ', $xR, $yR);
+					$s .= sprintf('%F %F l ', $xB, $yB);
+					$s .= 'S ';
+				} elseif ((strpos($border,'R') !== false) AND (strpos($border,'B') !== false)) { // RB
+					$s .= sprintf('%F %F m ', $xR, $yR);
+					$s .= sprintf('%F %F l ', $xB, $yB);
+					$s .= sprintf('%F %F l ', $xL, $yL);
+					$s .= 'S ';
+				} elseif ((strpos($border,'B') !== false) AND (strpos($border,'L') !== false)) { // BL
+					$s .= sprintf('%F %F m ', $xB, $yB);
+					$s .= sprintf('%F %F l ', $xL, $yL);
+					$s .= sprintf('%F %F l ', $xT, $yT);
+					$s .= 'S ';
+				} elseif ((strpos($border,'L') !== false) AND (strpos($border,'R') !== false)) { // LR
+					$s .= sprintf('%F %F m ', $xL, $yL);
+					$s .= sprintf('%F %F l ', $xT, $yT);
+					$s .= 'S ';
+					$s .= sprintf('%F %F m ', $xR, $yR);
+					$s .= sprintf('%F %F l ', $xB, $yB);
+					$s .= 'S ';
+				} elseif ((strpos($border,'T') !== false) AND (strpos($border,'B') !== false)) { // TB
+					$s .= sprintf('%F %F m ', $xT, $yT);
+					$s .= sprintf('%F %F l ', $xR, $yR);
+					$s .= 'S ';
+					$s .= sprintf('%F %F m ', $xB, $yB);
+					$s .= sprintf('%F %F l ', $xL, $yL);
+					$s .= 'S ';
+				}
+			} else { // strlen($border) == 1
+				if (strpos($border,'L') !== false) { // L
+					$s .= sprintf('%F %F m ', $xL, $yL);
+					$s .= sprintf('%F %F l ', $xT, $yT);
+					$s .= 'S ';
+				} elseif (strpos($border,'T') !== false) { // T
+					$s .= sprintf('%F %F m ', $xT, $yT);
+					$s .= sprintf('%F %F l ', $xR, $yR);
+					$s .= 'S ';
+				} elseif (strpos($border,'R') !== false) { // R
+					$s .= sprintf('%F %F m ', $xR, $yR);
+					$s .= sprintf('%F %F l ', $xB, $yB);
+					$s .= 'S ';
+				} elseif (strpos($border,'B') !== false) { // B
+					$s .= sprintf('%F %F m ', $xB, $yB);
+					$s .= sprintf('%F %F l ', $xL, $yL);
+					$s .= 'S ';
+				}
+			}
+			if (is_array($style) AND !empty($style)) {
+				// reset border style to previous value
+				$s .= "\n".$this->linestyleWidth.' '.$this->linestyleCap.' '.$this->linestyleJoin.' '.$this->linestyleDash.' '.$this->DrawColor."\n";
+			}
+		}
+		return $s;
+	}
+
+	/**
+	 * This method allows printing text with line breaks.
+	 * They can be automatic (as soon as the text reaches the right border of the cell) or explicit (via the \n character). As many cells as necessary are output, one below the other.<br />
+	 * Text can be aligned, centered or justified. The cell block can be framed and the background painted.
+	 * @param $w (float) Width of cells. If 0, they extend up to the right margin of the page.
+	 * @param $h (float) Cell minimum height. The cell extends automatically if needed.
+	 * @param $txt (string) String to print
+	 * @param $border (mixed) Indicates if borders must be drawn around the cell. The value can be a number:<ul><li>0: no border (default)</li><li>1: frame</li></ul> or a string containing some or all of the following characters (in any order):<ul><li>L: left</li><li>T: top</li><li>R: right</li><li>B: bottom</li></ul> or an array of line styles for each border group - for example: array('LTRB' => array('width' => 2, 'cap' => 'butt', 'join' => 'miter', 'dash' => 0, 'color' => array(0, 0, 0)))
+	 * @param $align (string) Allows to center or align the text. Possible values are:<ul><li>L or empty string: left align</li><li>C: center</li><li>R: right align</li><li>J: justification (default value when $ishtml=false)</li></ul>
+	 * @param $fill (boolean) Indicates if the cell background must be painted (true) or transparent (false).
+	 * @param $ln (int) Indicates where the current position should go after the call. Possible values are:<ul><li>0: to the right</li><li>1: to the beginning of the next line [DEFAULT]</li><li>2: below</li></ul>
+	 * @param $x (float) x position in user units
+	 * @param $y (float) y position in user units
+	 * @param $reseth (boolean) if true reset the last cell height (default true).
+	 * @param $stretch (int) font stretch mode: <ul><li>0 = disabled</li><li>1 = horizontal scaling only if text is larger than cell width</li><li>2 = forced horizontal scaling to fit cell width</li><li>3 = character spacing only if text is larger than cell width</li><li>4 = forced character spacing to fit cell width</li></ul> General font stretching and scaling values will be preserved when possible.
+	 * @param $ishtml (boolean) INTERNAL USE ONLY -- set to true if $txt is HTML content (default = false). Never set this parameter to true, use instead writeHTMLCell() or writeHTML() methods.
+	 * @param $autopadding (boolean) if true, uses internal padding and automatically adjust it to account for line width.
+	 * @param $maxh (float) maximum height. It should be >= $h and less then remaining space to the bottom of the page, or 0 for disable this feature. This feature works only when $ishtml=false.
+	 * @param $valign (string) Vertical alignment of text (requires $maxh = $h > 0). Possible values are:<ul><li>T: TOP</li><li>M: middle</li><li>B: bottom</li></ul>. This feature works only when $ishtml=false and the cell must fit in a single page.
+	 * @param $fitcell (boolean) if true attempt to fit all the text within the cell by reducing the font size (do not work in HTML mode).
+	 * @return int Return the number of cells or 1 for html mode.
+	 * @public
+	 * @since 1.3
+	 * @see SetFont(), SetDrawColor(), SetFillColor(), SetTextColor(), SetLineWidth(), Cell(), Write(), SetAutoPageBreak()
+	 */
+	public function MultiCell($w, $h, $txt, $border=0, $align='J', $fill=false, $ln=1, $x='', $y='', $reseth=true, $stretch=0, $ishtml=false, $autopadding=true, $maxh=0, $valign='T', $fitcell=false) {
+		$prev_cell_margin = $this->cell_margin;
+		$prev_cell_padding = $this->cell_padding;
+		// adjust internal padding
+		$this->adjustCellPadding($border);
+		$mc_padding = $this->cell_padding;
+		$mc_margin = $this->cell_margin;
+		$this->cell_padding['T'] = 0;
+		$this->cell_padding['B'] = 0;
+		$this->setCellMargins(0, 0, 0, 0);
+		if ($this->empty_string($this->lasth) OR $reseth) {
+			// reset row height
+			$this->resetLastH();
+		}
+		if (!$this->empty_string($y)) {
+			$this->SetY($y);
+		} else {
+			$y = $this->GetY();
+		}
+		$resth = 0;
+		if (($h > 0) AND $this->inPageBody() AND (($y + $h + $mc_margin['T'] + $mc_margin['B']) > $this->PageBreakTrigger)) {
+			// spit cell in more pages/columns
+			$newh = ($this->PageBreakTrigger - $y);
+			$resth = ($h - $newh); // cell to be printed on the next page/column
+			$h = $newh;
+		}
+		// get current page number
+		$startpage = $this->page;
+		// get current column
+		$startcolumn = $this->current_column;
+		if (!$this->empty_string($x)) {
+			$this->SetX($x);
+		} else {
+			$x = $this->GetX();
+		}
+		// check page for no-write regions and adapt page margins if necessary
+		list($x, $y) = $this->checkPageRegions(0, $x, $y);
+		// apply margins
+		$oy = $y + $mc_margin['T'];
+		if ($this->rtl) {
+			$ox = ($this->w - $x - $mc_margin['R']);
+		} else {
+			$ox = ($x + $mc_margin['L']);
+		}
+		$this->x = $ox;
+		$this->y = $oy;
+		// set width
+		if ($this->empty_string($w) OR ($w <= 0)) {
+			if ($this->rtl) {
+				$w = ($this->x - $this->lMargin - $mc_margin['L']);
+			} else {
+				$w = ($this->w - $this->x - $this->rMargin - $mc_margin['R']);
+			}
+		}
+		// store original margin values
+		$lMargin = $this->lMargin;
+		$rMargin = $this->rMargin;
+		if ($this->rtl) {
+			$this->rMargin = ($this->w - $this->x);
+			$this->lMargin = ($this->x - $w);
+		} else {
+			$this->lMargin = ($this->x);
+			$this->rMargin = ($this->w - $this->x - $w);
+		}
+		$this->clMargin = $this->lMargin;
+		$this->crMargin = $this->rMargin;
+		if ($autopadding) {
+			// add top padding
+			$this->y += $mc_padding['T'];
+		}
+		if ($ishtml) { // ******* Write HTML text
+			$this->writeHTML($txt, true, false, $reseth, true, $align);
+			$nl = 1;
+		} else { // ******* Write simple text
+			$prev_FontSizePt = $this->FontSizePt;
+			// vertical alignment
+			if ($maxh > 0) {
+				// get text height
+				$text_height = $this->getStringHeight($w, $txt, $reseth, $autopadding, $mc_padding, $border);
+				if ($fitcell) {
+					// try to reduce font size to fit text on cell (use a quick search algorithm)
+					$fmin = 1;
+					$fmax = $this->FontSizePt;
+					$prev_text_height = $text_height;
+					$maxit = 100; // max number of iterations
+					while ($maxit > 0) {
+						$fmid = (($fmax + $fmin) / 2);
+						$this->SetFontSize($fmid, false);
+						$this->resetLastH();
+						$text_height = $this->getStringHeight($w, $txt, $reseth, $autopadding, $mc_padding, $border);
+						if (($text_height == $maxh) OR (($text_height < $maxh) AND ($fmin >= ($fmax - 0.01)))) {
+							break;
+						} elseif ($text_height < $maxh) {
+							$fmin = $fmid;
+						} else {
+							$fmax = $fmid;
+						}
+						--$maxit;
+					}
+					$this->SetFontSize($this->FontSizePt);
+				}
+				if ($text_height < $maxh) {
+					if ($valign == 'M') {
+						// text vertically centered
+						$this->y += (($maxh - $text_height) / 2);
+					} elseif ($valign == 'B') {
+						// text vertically aligned on bottom
+						$this->y += ($maxh - $text_height);
+					}
+				}
+			}
+			$nl = $this->Write($this->lasth, $txt, '', 0, $align, true, $stretch, false, true, $maxh, 0, $mc_margin);
+			if ($fitcell) {
+				// restore font size
+				$this->SetFontSize($prev_FontSizePt);
+			}
+		}
+		if ($autopadding) {
+			// add bottom padding
+			$this->y += $mc_padding['B'];
+		}
+		// Get end-of-text Y position
+		$currentY = $this->y;
+		// get latest page number
+		$endpage = $this->page;
+		if ($resth > 0) {
+			$skip = ($endpage - $startpage);
+			$tmpresth = $resth;
+			while ($tmpresth > 0) {
+				if ($skip <= 0) {
+					// add a page (or trig AcceptPageBreak() for multicolumn mode)
+					$this->checkPageBreak($this->PageBreakTrigger + 1);
+				}
+				if ($this->num_columns > 1) {
+					$tmpresth -= ($this->h - $this->y - $this->bMargin);
+				} else {
+					$tmpresth -= ($this->h - $this->tMargin - $this->bMargin);
+				}
+				--$skip;
+			}
+			$currentY = $this->y;
+			$endpage = $this->page;
+		}
+		// get latest column
+		$endcolumn = $this->current_column;
+		if ($this->num_columns == 0) {
+			$this->num_columns = 1;
+		}
+		// disable page regions check
+		$check_page_regions = $this->check_page_regions;
+		$this->check_page_regions = false;
+		// get border modes
+		$border_start = $this->getBorderMode($border, $position='start');
+		$border_end = $this->getBorderMode($border, $position='end');
+		$border_middle = $this->getBorderMode($border, $position='middle');
+		// design borders around HTML cells.
+		for ($page = $startpage; $page <= $endpage; ++$page) { // for each page
+			$ccode = '';
+			$this->setPage($page);
+			if ($this->num_columns < 2) {
+				// single-column mode
+				$this->SetX($x);
+				$this->y = $this->tMargin;
+			}
+			// account for margin changes
+			if ($page > $startpage) {
+				if (($this->rtl) AND ($this->pagedim[$page]['orm'] != $this->pagedim[$startpage]['orm'])) {
+					$this->x -= ($this->pagedim[$page]['orm'] - $this->pagedim[$startpage]['orm']);
+				} elseif ((!$this->rtl) AND ($this->pagedim[$page]['olm'] != $this->pagedim[$startpage]['olm'])) {
+					$this->x += ($this->pagedim[$page]['olm'] - $this->pagedim[$startpage]['olm']);
+				}
+			}
+			if ($startpage == $endpage) {
+				// single page
+				for ($column = $startcolumn; $column <= $endcolumn; ++$column) { // for each column
+					$this->selectColumn($column);
+					if ($this->rtl) {
+						$this->x -= $mc_margin['R'];
+					} else {
+						$this->x += $mc_margin['L'];
+					}
+					if ($startcolumn == $endcolumn) { // single column
+						$cborder = $border;
+						$h = max($h, ($currentY - $oy));
+						$this->y = $oy;
+					} elseif ($column == $startcolumn) { // first column
+						$cborder = $border_start;
+						$this->y = $oy;
+						$h = $this->h - $this->y - $this->bMargin;
+					} elseif ($column == $endcolumn) { // end column
+						$cborder = $border_end;
+						$h = $currentY - $this->y;
+						if ($resth > $h) {
+							$h = $resth;
+						}
+					} else { // middle column
+						$cborder = $border_middle;
+						$h = $this->h - $this->y - $this->bMargin;
+						$resth -= $h;
+					}
+					$ccode .= $this->getCellCode($w, $h, '', $cborder, 1, '', $fill, '', 0, true)."\n";
+				} // end for each column
+			} elseif ($page == $startpage) { // first page
+				for ($column = $startcolumn; $column < $this->num_columns; ++$column) { // for each column
+					$this->selectColumn($column);
+					if ($this->rtl) {
+						$this->x -= $mc_margin['R'];
+					} else {
+						$this->x += $mc_margin['L'];
+					}
+					if ($column == $startcolumn) { // first column
+						$cborder = $border_start;
+						$this->y = $oy;
+						$h = $this->h - $this->y - $this->bMargin;
+					} else { // middle column
+						$cborder = $border_middle;
+						$h = $this->h - $this->y - $this->bMargin;
+						$resth -= $h;
+					}
+					$ccode .= $this->getCellCode($w, $h, '', $cborder, 1, '', $fill, '', 0, true)."\n";
+				} // end for each column
+			} elseif ($page == $endpage) { // last page
+				for ($column = 0; $column <= $endcolumn; ++$column) { // for each column
+					$this->selectColumn($column);
+					if ($this->rtl) {
+						$this->x -= $mc_margin['R'];
+					} else {
+						$this->x += $mc_margin['L'];
+					}
+					if ($column == $endcolumn) {
+						// end column
+						$cborder = $border_end;
+						$h = $currentY - $this->y;
+						if ($resth > $h) {
+							$h = $resth;
+						}
+					} else {
+						// middle column
+						$cborder = $border_middle;
+						$h = $this->h - $this->y - $this->bMargin;
+						$resth -= $h;
+					}
+					$ccode .= $this->getCellCode($w, $h, '', $cborder, 1, '', $fill, '', 0, true)."\n";
+				} // end for each column
+			} else { // middle page
+				for ($column = 0; $column < $this->num_columns; ++$column) { // for each column
+					$this->selectColumn($column);
+					if ($this->rtl) {
+						$this->x -= $mc_margin['R'];
+					} else {
+						$this->x += $mc_margin['L'];
+					}
+					$cborder = $border_middle;
+					$h = $this->h - $this->y - $this->bMargin;
+					$resth -= $h;
+					$ccode .= $this->getCellCode($w, $h, '', $cborder, 1, '', $fill, '', 0, true)."\n";
+				} // end for each column
+			}
+			if ($cborder OR $fill) {
+				$offsetlen = strlen($ccode);
+				// draw border and fill
+				if ($this->inxobj) {
+					// we are inside an XObject template
+					if (end($this->xobjects[$this->xobjid]['transfmrk']) !== false) {
+						$pagemarkkey = key($this->xobjects[$this->xobjid]['transfmrk']);
+						$pagemark = $this->xobjects[$this->xobjid]['transfmrk'][$pagemarkkey];
+						$this->xobjects[$this->xobjid]['transfmrk'][$pagemarkkey] += $offsetlen;
+					} else {
+						$pagemark = $this->xobjects[$this->xobjid]['intmrk'];
+						$this->xobjects[$this->xobjid]['intmrk'] += $offsetlen;
+					}
+					$pagebuff = $this->xobjects[$this->xobjid]['outdata'];
+					$pstart = substr($pagebuff, 0, $pagemark);
+					$pend = substr($pagebuff, $pagemark);
+					$this->xobjects[$this->xobjid]['outdata'] = $pstart.$ccode.$pend;
+				} else {
+					if (end($this->transfmrk[$this->page]) !== false) {
+						$pagemarkkey = key($this->transfmrk[$this->page]);
+						$pagemark = $this->transfmrk[$this->page][$pagemarkkey];
+						$this->transfmrk[$this->page][$pagemarkkey] += $offsetlen;
+					} elseif ($this->InFooter) {
+						$pagemark = $this->footerpos[$this->page];
+						$this->footerpos[$this->page] += $offsetlen;
+					} else {
+						$pagemark = $this->intmrk[$this->page];
+						$this->intmrk[$this->page] += $offsetlen;
+					}
+					$pagebuff = $this->getPageBuffer($this->page);
+					$pstart = substr($pagebuff, 0, $pagemark);
+					$pend = substr($pagebuff, $pagemark);
+					$this->setPageBuffer($this->page, $pstart.$ccode.$pend);
+				}
+			}
+		} // end for each page
+		// restore page regions check
+		$this->check_page_regions = $check_page_regions;
+		// Get end-of-cell Y position
+		$currentY = $this->GetY();
+		// restore previous values
+		if ($this->num_columns > 1) {
+			$this->selectColumn();
+		} else {
+			// restore original margins
+			$this->lMargin = $lMargin;
+			$this->rMargin = $rMargin;
+			if ($this->page > $startpage) {
+				// check for margin variations between pages (i.e. booklet mode)
+				$dl = ($this->pagedim[$this->page]['olm'] - $this->pagedim[$startpage]['olm']);
+				$dr = ($this->pagedim[$this->page]['orm'] - $this->pagedim[$startpage]['orm']);
+				if (($dl != 0) OR ($dr != 0)) {
+					$this->lMargin += $dl;
+					$this->rMargin += $dr;
+				}
+			}
+		}
+		if ($ln > 0) {
+			//Go to the beginning of the next line
+			$this->SetY($currentY + $mc_margin['B']);
+			if ($ln == 2) {
+				$this->SetX($x + $w + $mc_margin['L'] + $mc_margin['R']);
+			}
+		} else {
+			// go left or right by case
+			$this->setPage($startpage);
+			$this->y = $y;
+			$this->SetX($x + $w + $mc_margin['L'] + $mc_margin['R']);
+		}
+		$this->setContentMark();
+		$this->cell_padding = $prev_cell_padding;
+		$this->cell_margin = $prev_cell_margin;
+		$this->clMargin = $this->lMargin;
+		$this->crMargin = $this->rMargin;
+		return $nl;
+	}
+
+	/**
+	 * Get the border mode accounting for multicell position (opens bottom side of multicell crossing pages)
+	 * @param $brd (mixed) Indicates if borders must be drawn around the cell block. The value can be a number:<ul><li>0: no border (default)</li><li>1: frame</li></ul>or a string containing some or all of the following characters (in any order):<ul><li>L: left</li><li>T: top</li><li>R: right</li><li>B: bottom</li></ul> or an array of line styles for each border group: array('LTRB' => array('width' => 2, 'cap' => 'butt', 'join' => 'miter', 'dash' => 0, 'color' => array(0, 0, 0)))
+	 * @param $position (string) multicell position: 'start', 'middle', 'end'
+	 * @return border mode array
+	 * @protected
+	 * @since 4.4.002 (2008-12-09)
+	 */
+	protected function getBorderMode($brd, $position='start') {
+		if ((!$this->opencell) OR empty($brd)) {
+			return $brd;
+		}
+		if ($brd == 1) {
+			$brd = 'LTRB';
+		}
+		if (is_string($brd)) {
+			// convert string to array
+			$slen = strlen($brd);
+			$newbrd = array();
+			for ($i = 0; $i < $slen; ++$i) {
+				$newbrd[$brd[$i]] = array('cap' => 'square', 'join' => 'miter');
+			}
+			$brd = $newbrd;
+		}
+		foreach ($brd as $border => $style) {
+			switch ($position) {
+				case 'start': {
+					if (strpos($border, 'B') !== false) {
+						// remove bottom line
+						$newkey = str_replace('B', '', $border);
+						if (strlen($newkey) > 0) {
+							$brd[$newkey] = $style;
+						}
+						unset($brd[$border]);
+					}
+					break;
+				}
+				case 'middle': {
+					if (strpos($border, 'B') !== false) {
+						// remove bottom line
+						$newkey = str_replace('B', '', $border);
+						if (strlen($newkey) > 0) {
+							$brd[$newkey] = $style;
+						}
+						unset($brd[$border]);
+						$border = $newkey;
+					}
+					if (strpos($border, 'T') !== false) {
+						// remove bottom line
+						$newkey = str_replace('T', '', $border);
+						if (strlen($newkey) > 0) {
+							$brd[$newkey] = $style;
+						}
+						unset($brd[$border]);
+					}
+					break;
+				}
+				case 'end': {
+					if (strpos($border, 'T') !== false) {
+						// remove bottom line
+						$newkey = str_replace('T', '', $border);
+						if (strlen($newkey) > 0) {
+							$brd[$newkey] = $style;
+						}
+						unset($brd[$border]);
+					}
+					break;
+				}
+			}
+		}
+		return $brd;
+	}
+
+	/**
+	 * This method return the estimated number of lines for print a simple text string using Multicell() method.
+	 * @param $txt (string) String for calculating his height
+	 * @param $w (float) Width of cells. If 0, they extend up to the right margin of the page.
+	 * @param $reseth (boolean) if true reset the last cell height (default false).
+	 * @param $autopadding (boolean) if true, uses internal padding and automatically adjust it to account for line width (default true).
+	 * @param $cellpadding (float) Internal cell padding, if empty uses default cell padding.
+	 * @param $border (mixed) Indicates if borders must be drawn around the cell. The value can be a number:<ul><li>0: no border (default)</li><li>1: frame</li></ul> or a string containing some or all of the following characters (in any order):<ul><li>L: left</li><li>T: top</li><li>R: right</li><li>B: bottom</li></ul> or an array of line styles for each border group - for example: array('LTRB' => array('width' => 2, 'cap' => 'butt', 'join' => 'miter', 'dash' => 0, 'color' => array(0, 0, 0)))
+	 * @return float Return the minimal height needed for multicell method for printing the $txt param.
+	 * @author Alexander Escalona Fern�ndez, Nicola Asuni
+	 * @public
+	 * @since 4.5.011
+	 */
+	public function getNumLines($txt, $w=0, $reseth=false, $autopadding=true, $cellpadding='', $border=0) {
+		if ($txt === '') {
+			// empty string
+			return 1;
+		}
+		// adjust internal padding
+		$prev_cell_padding = $this->cell_padding;
+		$prev_lasth = $this->lasth;
+		if (is_array($cellpadding)) {
+			$this->cell_padding = $cellpadding;
+		}
+		$this->adjustCellPadding($border);
+		if ($this->empty_string($w) OR ($w <= 0)) {
+			if ($this->rtl) {
+				$w = $this->x - $this->lMargin;
+			} else {
+				$w = $this->w - $this->rMargin - $this->x;
+			}
+		}
+		$wmax = $w - $this->cell_padding['L'] - $this->cell_padding['R'];
+		if ($reseth) {
+			// reset row height
+			$this->resetLastH();
+		}
+		$lines = 1;
+		$sum = 0;
+		$chars = $this->utf8Bidi($this->UTF8StringToArray($txt), $txt, $this->tmprtl);
+		$charsWidth = $this->GetArrStringWidth($chars, '', '', 0, true);
+		$length = count($chars);
+		$lastSeparator = -1;
+		for ($i = 0; $i < $length; ++$i) {
+			$charWidth = $charsWidth[$i];
+			if (preg_match($this->re_spaces, $this->unichr($chars[$i]))) {
+				$lastSeparator = $i;
+			}
+			if ((($sum + $charWidth) > $wmax) OR ($chars[$i] == 10)) {
+				++$lines;
+				if ($chars[$i] == 10) {
+					$lastSeparator = -1;
+					$sum = 0;
+				} elseif ($lastSeparator != -1) {
+					$i = $lastSeparator;
+					$lastSeparator = -1;
+					$sum = 0;
+				} else {
+					$sum = $charWidth;
+				}
+			} else {
+				$sum += $charWidth;
+			}
+		}
+		if ($chars[($length - 1)] == 10) {
+			--$lines;
+		}
+		$this->cell_padding = $prev_cell_padding;
+		$this->lasth = $prev_lasth;
+		return $lines;
+	}
+
+	/**
+	 * This method return the estimated height needed for printing a simple text string using the Multicell() method.
+	 * Generally, if you want to know the exact height for a block of content you can use the following alternative technique:
+	 * @pre
+	 *  // store current object
+	 *  $pdf->startTransaction();
+	 *  // store starting values
+	 *  $start_y = $pdf->GetY();
+	 *  $start_page = $pdf->getPage();
+	 *  // call your printing functions with your parameters
+	 *  // - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+	 *  $pdf->MultiCell($w=0, $h=0, $txt, $border=1, $align='L', $fill=false, $ln=1, $x='', $y='', $reseth=true, $stretch=0, $ishtml=false, $autopadding=true, $maxh=0);
+	 *  // - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+	 *  // get the new Y
+	 *  $end_y = $pdf->GetY();
+	 *  $end_page = $pdf->getPage();
+	 *  // calculate height
+	 *  $height = 0;
+	 *  if ($end_page == $start_page) {
+	 *  	$height = $end_y - $start_y;
+	 *  } else {
+	 *  	for ($page=$start_page; $page <= $end_page; ++$page) {
+	 *  		$this->setPage($page);
+	 *  		if ($page == $start_page) {
+	 *  			// first page
+	 *  			$height = $this->h - $start_y - $this->bMargin;
+	 *  		} elseif ($page == $end_page) {
+	 *  			// last page
+	 *  			$height = $end_y - $this->tMargin;
+	 *  		} else {
+	 *  			$height = $this->h - $this->tMargin - $this->bMargin;
+	 *  		}
+	 *  	}
+	 *  }
+	 *  // restore previous object
+	 *  $pdf = $pdf->rollbackTransaction();
+	 *
+	 * @param $w (float) Width of cells. If 0, they extend up to the right margin of the page.
+	 * @param $txt (string) String for calculating his height
+	 * @param $reseth (boolean) if true reset the last cell height (default false).
+	 * @param $autopadding (boolean) if true, uses internal padding and automatically adjust it to account for line width (default true).
+	 * @param $cellpadding (float) Internal cell padding, if empty uses default cell padding.
+	 * @param $border (mixed) Indicates if borders must be drawn around the cell. The value can be a number:<ul><li>0: no border (default)</li><li>1: frame</li></ul> or a string containing some or all of the following characters (in any order):<ul><li>L: left</li><li>T: top</li><li>R: right</li><li>B: bottom</li></ul> or an array of line styles for each border group - for example: array('LTRB' => array('width' => 2, 'cap' => 'butt', 'join' => 'miter', 'dash' => 0, 'color' => array(0, 0, 0)))
+	 * @return float Return the minimal height needed for multicell method for printing the $txt param.
+	 * @author Nicola Asuni, Alexander Escalona Fern�ndez
+	 * @public
+	 */
+	public function getStringHeight($w, $txt, $reseth=false, $autopadding=true, $cellpadding='', $border=0) {
+		// adjust internal padding
+		$prev_cell_padding = $this->cell_padding;
+		$prev_lasth = $this->lasth;
+		if (is_array($cellpadding)) {
+			$this->cell_padding = $cellpadding;
+		}
+		$this->adjustCellPadding($border);
+		$lines = $this->getNumLines($txt, $w, $reseth, $autopadding, $cellpadding, $border);
+		$height = $lines * ($this->FontSize * $this->cell_height_ratio);
+		if ($autopadding) {
+			// add top and bottom padding
+			$height += ($this->cell_padding['T'] + $this->cell_padding['B']);
+		}
+		$this->cell_padding = $prev_cell_padding;
+		$this->lasth = $prev_lasth;
+		return $height;
+	}
+
+	/**
+	 * This method prints text from the current position.<br />
+	 * @param $h (float) Line height
+	 * @param $txt (string) String to print
+	 * @param $link (mixed) URL or identifier returned by AddLink()
+	 * @param $fill (boolean) Indicates if the cell background must be painted (true) or transparent (false).
+	 * @param $align (string) Allows to center or align the text. Possible values are:<ul><li>L or empty string: left align (default value)</li><li>C: center</li><li>R: right align</li><li>J: justify</li></ul>
+	 * @param $ln (boolean) if true set cursor at the bottom of the line, otherwise set cursor at the top of the line.
+	 * @param $stretch (int) font stretch mode: <ul><li>0 = disabled</li><li>1 = horizontal scaling only if text is larger than cell width</li><li>2 = forced horizontal scaling to fit cell width</li><li>3 = character spacing only if text is larger than cell width</li><li>4 = forced character spacing to fit cell width</li></ul> General font stretching and scaling values will be preserved when possible.
+	 * @param $firstline (boolean) if true prints only the first line and return the remaining string.
+	 * @param $firstblock (boolean) if true the string is the starting of a line.
+	 * @param $maxh (float) maximum height. The remaining unprinted text will be returned. It should be >= $h and less then remaining space to the bottom of the page, or 0 for disable this feature.
+	 * @param $wadj (float) first line width will be reduced by this amount (used in HTML mode).
+	 * @param $margin (array) margin array of the parent container
+	 * @return mixed Return the number of cells or the remaining string if $firstline = true.
+	 * @public
+	 * @since 1.5
+	 */
+	public function Write($h, $txt, $link='', $fill=false, $align='', $ln=false, $stretch=0, $firstline=false, $firstblock=false, $maxh=0, $wadj=0, $margin='') {
+		// check page for no-write regions and adapt page margins if necessary
+		list($this->x, $this->y) = $this->checkPageRegions($h, $this->x, $this->y);
+		if (strlen($txt) == 0) {
+			// fix empty text
+			$txt = ' ';
+		}
+		if ($margin === '') {
+			// set default margins
+			$margin = $this->cell_margin;
+		}
+		// remove carriage returns
+		$s = str_replace("\r", '', $txt);
+		// check if string contains arabic text
+		if (preg_match($this->unicode->uni_RE_PATTERN_ARABIC, $s)) {
+			$arabic = true;
+		} else {
+			$arabic = false;
+		}
+		// check if string contains RTL text
+		if ($arabic OR ($this->tmprtl == 'R') OR preg_match($this->unicode->uni_RE_PATTERN_RTL, $s)) {
+			$rtlmode = true;
+		} else {
+			$rtlmode = false;
+		}
+		// get a char width
+		$chrwidth = $this->GetCharWidth(46); // dot character
+		// get array of unicode values
+		$chars = $this->UTF8StringToArray($s);
+		// calculate maximum width for a single character on string
+		$chrw = $this->GetArrStringWidth($chars, '', '', 0, true);
+		array_walk($chrw, array($this, 'getRawCharWidth'));
+		$maxchwidth = max($chrw);
+		// get array of chars
+		$uchars = $this->UTF8ArrayToUniArray($chars);
+		// get the number of characters
+		$nb = count($chars);
+		// replacement for SHY character (minus symbol)
+		$shy_replacement = 45;
+		$shy_replacement_char = $this->unichr($shy_replacement);
+		// widht for SHY replacement
+		$shy_replacement_width = $this->GetCharWidth($shy_replacement);
+		// max Y
+		$maxy = $this->y + $maxh - $h - $this->cell_padding['T'] - $this->cell_padding['B'];
+		// page width
+		$pw = $w = $this->w - $this->lMargin - $this->rMargin;
+		// calculate remaining line width ($w)
+		if ($this->rtl) {
+			$w = $this->x - $this->lMargin;
+		} else {
+			$w = $this->w - $this->rMargin - $this->x;
+		}
+		// max column width
+		$wmax = ($w - $wadj);
+		if (!$firstline) {
+			$wmax -= ($this->cell_padding['L'] + $this->cell_padding['R']);
+		}
+		if ((!$firstline) AND (($chrwidth > $wmax) OR ($maxchwidth > $wmax))) {
+			// the maximum width character do not fit on column
+			return '';
+		}
+		// minimum row height
+		$row_height = max($h, $this->FontSize * $this->cell_height_ratio);
+		$start_page = $this->page;
+		$i = 0; // character position
+		$j = 0; // current starting position
+		$sep = -1; // position of the last blank space
+		$shy = false; // true if the last blank is a soft hypen (SHY)
+		$l = 0; // current string length
+		$nl = 0; //number of lines
+		$linebreak = false;
+		$pc = 0; // previous character
+		// for each character
+		while ($i < $nb) {
+			if (($maxh > 0) AND ($this->y >= $maxy) ) {
+				break;
+			}
+			//Get the current character
+			$c = $chars[$i];
+			if ($c == 10) { // 10 = "\n" = new line
+				//Explicit line break
+				if ($align == 'J') {
+					if ($this->rtl) {
+						$talign = 'R';
+					} else {
+						$talign = 'L';
+					}
+				} else {
+					$talign = $align;
+				}
+				$tmpstr = $this->UniArrSubString($uchars, $j, $i);
+				if ($firstline) {
+					$startx = $this->x;
+					$tmparr = array_slice($chars, $j, ($i - $j));
+					if ($rtlmode) {
+						$tmparr = $this->utf8Bidi($tmparr, $tmpstr, $this->tmprtl);
+					}
+					$linew = $this->GetArrStringWidth($tmparr);
+					unset($tmparr);
+					if ($this->rtl) {
+						$this->endlinex = $startx - $linew;
+					} else {
+						$this->endlinex = $startx + $linew;
+					}
+					$w = $linew;
+					$tmpcellpadding = $this->cell_padding;
+					if ($maxh == 0) {
+						$this->SetCellPadding(0);
+					}
+				}
+				if ($firstblock AND $this->isRTLTextDir()) {
+					$tmpstr = $this->stringRightTrim($tmpstr);
+				}
+				// Skip newlines at the begining of a page or column
+				if (!empty($tmpstr) OR ($this->y < ($this->PageBreakTrigger - $row_height))) {
+					$this->Cell($w, $h, $tmpstr, 0, 1, $talign, $fill, $link, $stretch);
+				}
+				unset($tmpstr);
+				if ($firstline) {
+					$this->cell_padding = $tmpcellpadding;
+					return ($this->UniArrSubString($uchars, $i));
+				}
+				++$nl;
+				$j = $i + 1;
+				$l = 0;
+				$sep = -1;
+				$shy = false;
+				// account for margin changes
+				if ((($this->y + $this->lasth) > $this->PageBreakTrigger) AND ($this->inPageBody())) {
+					$this->AcceptPageBreak();
+					if ($this->rtl) {
+						$this->x -= $margin['R'];
+					} else {
+						$this->x += $margin['L'];
+					}
+					$this->lMargin += $margin['L'];
+					$this->rMargin += $margin['R'];
+				}
+				$w = $this->getRemainingWidth();
+				$wmax = ($w - $this->cell_padding['L'] - $this->cell_padding['R']);
+			} else {
+				// 160 is the non-breaking space.
+				// 173 is SHY (Soft Hypen).
+				// \p{Z} or \p{Separator}: any kind of Unicode whitespace or invisible separator.
+				// \p{Lo} or \p{Other_Letter}: a Unicode letter or ideograph that does not have lowercase and uppercase variants.
+				// \p{Lo} is needed because Chinese characters are packed next to each other without spaces in between.
+				if (($c != 160)
+					AND (($c == 173)
+						OR preg_match($this->re_spaces, $this->unichr($c))
+						OR (($c == 45)
+							AND ($i < ($nb - 1))
+							AND @preg_match('/[\p{L}]/'.$this->re_space['m'], $this->unichr($pc))
+							AND @preg_match('/[\p{L}]/'.$this->re_space['m'], $this->unichr($chars[($i + 1)]))
+						)
+					)
+				) {
+					// update last blank space position
+					$sep = $i;
+					// check if is a SHY
+					if (($c == 173) OR ($c == 45)) {
+						$shy = true;
+						if ($pc == 45) {
+							$tmp_shy_replacement_width = 0;
+							$tmp_shy_replacement_char = '';
+						} else {
+							$tmp_shy_replacement_width = $shy_replacement_width;
+							$tmp_shy_replacement_char = $shy_replacement_char;
+						}
+					} else {
+						$shy = false;
+					}
+				}
+				// update string length
+				if ($this->isUnicodeFont() AND ($arabic)) {
+					// with bidirectional algorithm some chars may be changed affecting the line length
+					// *** very slow ***
+					$l = $this->GetArrStringWidth($this->utf8Bidi(array_slice($chars, $j, ($i - $j)), '', $this->tmprtl));
+				} else {
+					$l += $this->GetCharWidth($c);
+				}
+				if (($l > $wmax) OR (($c == 173) AND (($l + $tmp_shy_replacement_width) > $wmax)) ) {
+					// we have reached the end of column
+					if ($sep == -1) {
+						// check if the line was already started
+						if (($this->rtl AND ($this->x <= ($this->w - $this->rMargin - $this->cell_padding['R'] - $margin['R'] - $chrwidth)))
+							OR ((!$this->rtl) AND ($this->x >= ($this->lMargin + $this->cell_padding['L'] + $margin['L'] + $chrwidth)))) {
+							// print a void cell and go to next line
+							$this->Cell($w, $h, '', 0, 1);
+							$linebreak = true;
+							if ($firstline) {
+								return ($this->UniArrSubString($uchars, $j));
+							}
+						} else {
+							// truncate the word because do not fit on column
+							$tmpstr = $this->UniArrSubString($uchars, $j, $i);
+							if ($firstline) {
+								$startx = $this->x;
+								$tmparr = array_slice($chars, $j, ($i - $j));
+								if ($rtlmode) {
+									$tmparr = $this->utf8Bidi($tmparr, $tmpstr, $this->tmprtl);
+								}
+								$linew = $this->GetArrStringWidth($tmparr);
+								unset($tmparr);
+								if ($this->rtl) {
+									$this->endlinex = $startx - $linew;
+								} else {
+									$this->endlinex = $startx + $linew;
+								}
+								$w = $linew;
+								$tmpcellpadding = $this->cell_padding;
+								if ($maxh == 0) {
+									$this->SetCellPadding(0);
+								}
+							}
+							if ($firstblock AND $this->isRTLTextDir()) {
+								$tmpstr = $this->stringRightTrim($tmpstr);
+							}
+							$this->Cell($w, $h, $tmpstr, 0, 1, $align, $fill, $link, $stretch);
+							unset($tmpstr);
+							if ($firstline) {
+								$this->cell_padding = $tmpcellpadding;
+								return ($this->UniArrSubString($uchars, $i));
+							}
+							$j = $i;
+							--$i;
+						}
+					} else {
+						// word wrapping
+						if ($this->rtl AND (!$firstblock) AND ($sep < $i)) {
+							$endspace = 1;
+						} else {
+							$endspace = 0;
+						}
+						// check the length of the next string
+						$strrest = $this->UniArrSubString($uchars, ($sep + $endspace));
+						$nextstr = preg_split('/'.$this->re_space['p'].'/'.$this->re_space['m'], $this->stringTrim($strrest));
+						if (isset($nextstr[0]) AND ($this->GetStringWidth($nextstr[0]) > $pw)) {
+							// truncate the word because do not fit on a full page width
+							$tmpstr = $this->UniArrSubString($uchars, $j, $i);
+							if ($firstline) {
+								$startx = $this->x;
+								$tmparr = array_slice($chars, $j, ($i - $j));
+								if ($rtlmode) {
+									$tmparr = $this->utf8Bidi($tmparr, $tmpstr, $this->tmprtl);
+								}
+								$linew = $this->GetArrStringWidth($tmparr);
+								unset($tmparr);
+								if ($this->rtl) {
+									$this->endlinex = ($startx - $linew);
+								} else {
+									$this->endlinex = ($startx + $linew);
+								}
+								$w = $linew;
+								$tmpcellpadding = $this->cell_padding;
+								if ($maxh == 0) {
+									$this->SetCellPadding(0);
+								}
+							}
+							if ($firstblock AND $this->isRTLTextDir()) {
+								$tmpstr = $this->stringRightTrim($tmpstr);
+							}
+							$this->Cell($w, $h, $tmpstr, 0, 1, $align, $fill, $link, $stretch);
+							unset($tmpstr);
+							if ($firstline) {
+								$this->cell_padding = $tmpcellpadding;
+								return ($this->UniArrSubString($uchars, $i));
+							}
+							$j = $i;
+							--$i;
+						} else {
+							// word wrapping
+							if ($shy) {
+								// add hypen (minus symbol) at the end of the line
+								$shy_width = $tmp_shy_replacement_width;
+								if ($this->rtl) {
+									$shy_char_left = $tmp_shy_replacement_char;
+									$shy_char_right = '';
+								} else {
+									$shy_char_left = '';
+									$shy_char_right = $tmp_shy_replacement_char;
+								}
+							} else {
+								$shy_width = 0;
+								$shy_char_left = '';
+								$shy_char_right = '';
+							}
+							$tmpstr = $this->UniArrSubString($uchars, $j, ($sep + $endspace));
+							if ($firstline) {
+								$startx = $this->x;
+								$tmparr = array_slice($chars, $j, (($sep + $endspace) - $j));
+								if ($rtlmode) {
+									$tmparr = $this->utf8Bidi($tmparr, $tmpstr, $this->tmprtl);
+								}
+								$linew = $this->GetArrStringWidth($tmparr);
+								unset($tmparr);
+								if ($this->rtl) {
+									$this->endlinex = $startx - $linew - $shy_width;
+								} else {
+									$this->endlinex = $startx + $linew + $shy_width;
+								}
+								$w = $linew;
+								$tmpcellpadding = $this->cell_padding;
+								if ($maxh == 0) {
+									$this->SetCellPadding(0);
+								}
+							}
+							// print the line
+							if ($firstblock AND $this->isRTLTextDir()) {
+								$tmpstr = $this->stringRightTrim($tmpstr);
+							}
+							$this->Cell($w, $h, $shy_char_left.$tmpstr.$shy_char_right, 0, 1, $align, $fill, $link, $stretch);
+							unset($tmpstr);
+							if ($firstline) {
+								if ($chars[$sep] == 45) {
+									$endspace += 1;
+								}
+								// return the remaining text
+								$this->cell_padding = $tmpcellpadding;
+								return ($this->UniArrSubString($uchars, ($sep + $endspace)));
+							}
+							$i = $sep;
+							$sep = -1;
+							$shy = false;
+							$j = ($i + 1);
+						}
+					}
+					// account for margin changes
+					if ((($this->y + $this->lasth) > $this->PageBreakTrigger) AND ($this->inPageBody())) {
+						$this->AcceptPageBreak();
+						if ($this->rtl) {
+							$this->x -= $margin['R'];
+						} else {
+							$this->x += $margin['L'];
+						}
+						$this->lMargin += $margin['L'];
+						$this->rMargin += $margin['R'];
+					}
+					$w = $this->getRemainingWidth();
+					$wmax = $w - $this->cell_padding['L'] - $this->cell_padding['R'];
+					if ($linebreak) {
+						$linebreak = false;
+					} else {
+						++$nl;
+						$l = 0;
+					}
+				}
+			}
+			// save last character
+			$pc = $c;
+			++$i;
+		} // end while i < nb
+		// print last substring (if any)
+		if ($l > 0) {
+			switch ($align) {
+				case 'J':
+				case 'C': {
+					$w = $w;
+					break;
+				}
+				case 'L': {
+					if ($this->rtl) {
+						$w = $w;
+					} else {
+						$w = $l;
+					}
+					break;
+				}
+				case 'R': {
+					if ($this->rtl) {
+						$w = $l;
+					} else {
+						$w = $w;
+					}
+					break;
+				}
+				default: {
+					$w = $l;
+					break;
+				}
+			}
+			$tmpstr = $this->UniArrSubString($uchars, $j, $nb);
+			if ($firstline) {
+				$startx = $this->x;
+				$tmparr = array_slice($chars, $j, ($nb - $j));
+				if ($rtlmode) {
+					$tmparr = $this->utf8Bidi($tmparr, $tmpstr, $this->tmprtl);
+				}
+				$linew = $this->GetArrStringWidth($tmparr);
+				unset($tmparr);
+				if ($this->rtl) {
+					$this->endlinex = $startx - $linew;
+				} else {
+					$this->endlinex = $startx + $linew;
+				}
+				$w = $linew;
+				$tmpcellpadding = $this->cell_padding;
+				if ($maxh == 0) {
+					$this->SetCellPadding(0);
+				}
+			}
+			if ($firstblock AND $this->isRTLTextDir()) {
+				$tmpstr = $this->stringRightTrim($tmpstr);
+			}
+			$this->Cell($w, $h, $tmpstr, 0, $ln, $align, $fill, $link, $stretch);
+			unset($tmpstr);
+			if ($firstline) {
+				$this->cell_padding = $tmpcellpadding;
+				return ($this->UniArrSubString($uchars, $nb));
+			}
+			++$nl;
+		}
+		if ($firstline) {
+			return '';
+		}
+		return $nl;
+	}
+
+	/**
+	 * Returns the remaining width between the current position and margins.
+	 * @return int Return the remaining width
+	 * @protected
+	 */
+	protected function getRemainingWidth() {
+		list($this->x, $this->y) = $this->checkPageRegions(0, $this->x, $this->y);
+		if ($this->rtl) {
+			return ($this->x - $this->lMargin);
+		} else {
+			return ($this->w - $this->rMargin - $this->x);
+		}
+	}
+
+	/**
+	 * Extract a slice of the $strarr array and return it as string.
+	 * @param $strarr (string) The input array of characters.
+	 * @param $start (int) the starting element of $strarr.
+	 * @param $end (int) first element that will not be returned.
+	 * @return Return part of a string
+	 * @public
+	 */
+	public function UTF8ArrSubString($strarr, $start='', $end='') {
+		if (strlen($start) == 0) {
+			$start = 0;
+		}
+		if (strlen($end) == 0) {
+			$end = count($strarr);
+		}
+		$string = '';
+		for ($i=$start; $i < $end; ++$i) {
+			$string .= $this->unichr($strarr[$i]);
+		}
+		return $string;
+	}
+
+	/**
+	 * Extract a slice of the $uniarr array and return it as string.
+	 * @param $uniarr (string) The input array of characters.
+	 * @param $start (int) the starting element of $strarr.
+	 * @param $end (int) first element that will not be returned.
+	 * @return Return part of a string
+	 * @public
+	 * @since 4.5.037 (2009-04-07)
+	 */
+	public function UniArrSubString($uniarr, $start='', $end='') {
+		if (strlen($start) == 0) {
+			$start = 0;
+		}
+		if (strlen($end) == 0) {
+			$end = count($uniarr);
+		}
+		$string = '';
+		for ($i=$start; $i < $end; ++$i) {
+			$string .= $uniarr[$i];
+		}
+		return $string;
+	}
+
+	/**
+	 * Convert an array of UTF8 values to array of unicode characters
+	 * @param $ta (string) The input array of UTF8 values.
+	 * @return Return array of unicode characters
+	 * @public
+	 * @since 4.5.037 (2009-04-07)
+	 */
+	public function UTF8ArrayToUniArray($ta) {
+		return array_map(array($this, 'unichr'), $ta);
+	}
+
+	/**
+	 * Returns the unicode caracter specified by UTF-8 value
+	 * @param $c (int) UTF-8 value
+	 * @return Returns the specified character.
+	 * @author Miguel Perez, Nicola Asuni
+	 * @public
+	 * @since 2.3.000 (2008-03-05)
+	 */
+	public function unichr($c) {
+		if (!$this->isunicode) {
+			return chr($c);
+		} elseif ($c <= 0x7F) {
+			// one byte
+			return chr($c);
+		} elseif ($c <= 0x7FF) {
+			// two bytes
+			return chr(0xC0 | $c >> 6).chr(0x80 | $c & 0x3F);
+		} elseif ($c <= 0xFFFF) {
+			// three bytes
+			return chr(0xE0 | $c >> 12).chr(0x80 | $c >> 6 & 0x3F).chr(0x80 | $c & 0x3F);
+		} elseif ($c <= 0x10FFFF) {
+			// four bytes
+			return chr(0xF0 | $c >> 18).chr(0x80 | $c >> 12 & 0x3F).chr(0x80 | $c >> 6 & 0x3F).chr(0x80 | $c & 0x3F);
+		} else {
+			return '';
+		}
+	}
+
+	/**
+	 * Return the image type given the file name or array returned by getimagesize() function.
+	 * @param $imgfile (string) image file name
+	 * @param $iminfo (array) array of image information returned by getimagesize() function.
+	 * @return string image type
+	 * @since 4.8.017 (2009-11-27)
+	 */
+	public function getImageFileType($imgfile, $iminfo=array()) {
+		$type = '';
+		if (isset($iminfo['mime']) AND !empty($iminfo['mime'])) {
+			$mime = explode('/', $iminfo['mime']);
+			if ((count($mime) > 1) AND ($mime[0] == 'image') AND (!empty($mime[1]))) {
+				$type = strtolower(trim($mime[1]));
+			}
+		}
+		if (empty($type)) {
+			$fileinfo = pathinfo($imgfile);
+			if (isset($fileinfo['extension']) AND (!$this->empty_string($fileinfo['extension']))) {
+				$type = strtolower(trim($fileinfo['extension']));
+			}
+		}
+		if ($type == 'jpg') {
+			$type = 'jpeg';
+		}
+		return $type;
+	}
+
+	/**
+	 * Set the block dimensions accounting for page breaks and page/column fitting
+	 * @param $w (float) width
+	 * @param $h (float) height
+	 * @param $x (float) X coordinate
+	 * @param $y (float) Y coodiante
+	 * @param $fitonpage (boolean) if true the block is resized to not exceed page dimensions.
+	 * @return array($w, $h, $x, $y)
+	 * @protected
+	 * @since 5.5.009 (2010-07-05)
+	 */
+	protected function fitBlock($w, $h, $x, $y, $fitonpage=false) {
+		if ($w <= 0) {
+			// set maximum width
+			$w = ($this->w - $this->lMargin - $this->rMargin);
+		}
+		if ($h <= 0) {
+			// set maximum height
+			$h = ($this->PageBreakTrigger - $this->tMargin);
+		}
+		// resize the block to be vertically contained on a single page or single column
+		if ($fitonpage OR $this->AutoPageBreak) {
+			$ratio_wh = ($w / $h);
+			if ($h > ($this->PageBreakTrigger - $this->tMargin)) {
+				$h = $this->PageBreakTrigger - $this->tMargin;
+				$w = ($h * $ratio_wh);
+			}
+			// resize the block to be horizontally contained on a single page or single column
+			if ($fitonpage) {
+				$maxw = ($this->w - $this->lMargin - $this->rMargin);
+				if ($w > $maxw) {
+					$w = $maxw;
+					$h = ($w / $ratio_wh);
+				}
+			}
+		}
+		// Check whether we need a new page or new column first as this does not fit
+		$prev_x = $this->x;
+		$prev_y = $this->y;
+		if ($this->checkPageBreak($h, $y) OR ($this->y < $prev_y)) {
+			$y = $this->y;
+			if ($this->rtl) {
+				$x += ($prev_x - $this->x);
+			} else {
+				$x += ($this->x - $prev_x);
+			}
+			$this->newline = true;
+		}
+		// resize the block to be contained on the remaining available page or column space
+		if ($fitonpage) {
+			$ratio_wh = ($w / $h);
+			if (($y + $h) > $this->PageBreakTrigger) {
+				$h = $this->PageBreakTrigger - $y;
+				$w = ($h * $ratio_wh);
+			}
+			if ((!$this->rtl) AND (($x + $w) > ($this->w - $this->rMargin))) {
+				$w = $this->w - $this->rMargin - $x;
+				$h = ($w / $ratio_wh);
+			} elseif (($this->rtl) AND (($x - $w) < ($this->lMargin))) {
+				$w = $x - $this->lMargin;
+				$h = ($w / $ratio_wh);
+			}
+		}
+		return array($w, $h, $x, $y);
+	}
+
+	/**
+	 * Puts an image in the page.
+	 * The upper-left corner must be given.
+	 * The dimensions can be specified in different ways:<ul>
+	 * <li>explicit width and height (expressed in user unit)</li>
+	 * <li>one explicit dimension, the other being calculated automatically in order to keep the original proportions</li>
+	 * <li>no explicit dimension, in which case the image is put at 72 dpi</li></ul>
+	 * Supported formats are JPEG and PNG images whitout GD library and all images supported by GD: GD, GD2, GD2PART, GIF, JPEG, PNG, BMP, XBM, XPM;
+	 * The format can be specified explicitly or inferred from the file extension.<br />
+	 * It is possible to put a link on the image.<br />
+	 * Remark: if an image is used several times, only one copy will be embedded in the file.<br />
+	 * @param $file (string) Name of the file containing the image or a '@' character followed by the image data string. To link an image without embedding it on the document, set an asterisk character before the URL (i.e.: '*http://www.example.com/image.jpg').
+	 * @param $x (float) Abscissa of the upper-left corner (LTR) or upper-right corner (RTL).
+	 * @param $y (float) Ordinate of the upper-left corner (LTR) or upper-right corner (RTL).
+	 * @param $w (float) Width of the image in the page. If not specified or equal to zero, it is automatically calculated.
+	 * @param $h (float) Height of the image in the page. If not specified or equal to zero, it is automatically calculated.
+	 * @param $type (string) Image format. Possible values are (case insensitive): JPEG and PNG (whitout GD library) and all images supported by GD: GD, GD2, GD2PART, GIF, JPEG, PNG, BMP, XBM, XPM;. If not specified, the type is inferred from the file extension.
+	 * @param $link (mixed) URL or identifier returned by AddLink().
+	 * @param $align (string) Indicates the alignment of the pointer next to image insertion relative to image height. The value can be:<ul><li>T: top-right for LTR or top-left for RTL</li><li>M: middle-right for LTR or middle-left for RTL</li><li>B: bottom-right for LTR or bottom-left for RTL</li><li>N: next line</li></ul>
+	 * @param $resize (mixed) If true resize (reduce) the image to fit $w and $h (requires GD or ImageMagick library); if false do not resize; if 2 force resize in all cases (upscaling and downscaling).
+	 * @param $dpi (int) dot-per-inch resolution used on resize
+	 * @param $palign (string) Allows to center or align the image on the current line. Possible values are:<ul><li>L : left align</li><li>C : center</li><li>R : right align</li><li>'' : empty string : left for LTR or right for RTL</li></ul>
+	 * @param $ismask (boolean) true if this image is a mask, false otherwise
+	 * @param $imgmask (mixed) image object returned by this function or false
+	 * @param $border (mixed) Indicates if borders must be drawn around the cell. The value can be a number:<ul><li>0: no border (default)</li><li>1: frame</li></ul> or a string containing some or all of the following characters (in any order):<ul><li>L: left</li><li>T: top</li><li>R: right</li><li>B: bottom</li></ul> or an array of line styles for each border group - for example: array('LTRB' => array('width' => 2, 'cap' => 'butt', 'join' => 'miter', 'dash' => 0, 'color' => array(0, 0, 0)))
+	 * @param $fitbox (mixed) If not false scale image dimensions proportionally to fit within the ($w, $h) box. $fitbox can be true or a 2 characters string indicating the image alignment inside the box. The first character indicate the horizontal alignment (L = left, C = center, R = right) the second character indicate the vertical algnment (T = top, M = middle, B = bottom).
+	 * @param $hidden (boolean) If true do not display the image.
+	 * @param $fitonpage (boolean) If true the image is resized to not exceed page dimensions.
+	 * @param $alt (boolean) If true the image will be added as alternative and not directly printed (the ID of the image will be returned).
+	 * @param $altimgs (array) Array of alternate images IDs. Each alternative image must be an array with two values: an integer representing the image ID (the value returned by the Image method) and a boolean value to indicate if the image is the default for printing.
+	 * @return image information
+	 * @public
+	 * @since 1.1
+	 */
+	public function Image($file, $x='', $y='', $w=0, $h=0, $type='', $link='', $align='', $resize=false, $dpi=300, $palign='', $ismask=false, $imgmask=false, $border=0, $fitbox=false, $hidden=false, $fitonpage=false, $alt=false, $altimgs=array()) {
+		if ($this->state != 2) {
+			return;
+		}
+		if ($x === '') {
+			$x = $this->x;
+		}
+		if ($y === '') {
+			$y = $this->y;
+		}
+		// check page for no-write regions and adapt page margins if necessary
+		list($x, $y) = $this->checkPageRegions($h, $x, $y);
+		$exurl = ''; // external streams
+		// check if we are passing an image as file or string
+		if ($file[0] === '@') {
+			// image from string
+			$imgdata = substr($file, 1);
+			$file = $this->getObjFilename('img');
+			$fp = fopen($file, 'w');
+			fwrite($fp, $imgdata);
+			fclose($fp);
+			unset($imgdata);
+			$imsize = @getimagesize($file);
+			if ($imsize === FALSE) {
+				unlink($file);
+			} else {
+				$this->cached_files[] = $file;
+			}
+		} else { // image file
+			if ($file{0} === '*') {
+				// image as external stream
+				$file = substr($file, 1);
+				$exurl = $file;
+			}
+			// check if is local file
+			if (!@file_exists($file)) {
+				// encode spaces on filename (file is probably an URL)
+				$file = str_replace(' ', '%20', $file);
+			}
+			if (@file_exists($file)) {
+				// get image dimensions
+				$imsize = @getimagesize($file);
+			} else {
+				$imsize = false;
+			}
+			if ($imsize === FALSE) {
+				if (function_exists('curl_init')) {
+					// try to get remote file data using cURL
+					$cs = curl_init(); // curl session
+					curl_setopt($cs, CURLOPT_URL, $file);
+					curl_setopt($cs, CURLOPT_BINARYTRANSFER, true);
+					curl_setopt($cs, CURLOPT_FAILONERROR, true);
+					curl_setopt($cs, CURLOPT_RETURNTRANSFER, true);
+					if ((ini_get('open_basedir') == '') AND (!ini_get('safe_mode'))) {
+						curl_setopt($cs, CURLOPT_FOLLOWLOCATION, true);
+					}
+					curl_setopt($cs, CURLOPT_CONNECTTIMEOUT, 5);
+					curl_setopt($cs, CURLOPT_TIMEOUT, 30);
+					curl_setopt($cs, CURLOPT_SSL_VERIFYPEER, false);
+					curl_setopt($cs, CURLOPT_SSL_VERIFYHOST, false);
+					curl_setopt($cs, CURLOPT_USERAGENT, 'TCPDF');
+					$imgdata = curl_exec($cs);
+					curl_close($cs);
+					if ($imgdata !== FALSE) {
+						// copy image to cache
+						$file = $this->getObjFilename('img');
+						$fp = fopen($file, 'w');
+						fwrite($fp, $imgdata);
+						fclose($fp);
+						unset($imgdata);
+						$imsize = @getimagesize($file);
+						if ($imsize === FALSE) {
+							unlink($file);
+						} else {
+							$this->cached_files[] = $file;
+						}
+					}
+				} elseif (($w > 0) AND ($h > 0)) {
+					// get measures from specified data
+					$pw = $this->getHTMLUnitToUnits($w, 0, $this->pdfunit, true) * $this->imgscale * $this->k;
+					$ph = $this->getHTMLUnitToUnits($h, 0, $this->pdfunit, true) * $this->imgscale * $this->k;
+					$imsize = array($pw, $ph);
+				}
+			}
+		}
+		if ($imsize === FALSE) {
+			if (substr($file, 0, -34) == K_PATH_CACHE.'msk') { // mask file
+				// get measures from specified data
+				$pw = $this->getHTMLUnitToUnits($w, 0, $this->pdfunit, true) * $this->imgscale * $this->k;
+				$ph = $this->getHTMLUnitToUnits($h, 0, $this->pdfunit, true) * $this->imgscale * $this->k;
+				$imsize = array($pw, $ph);
+			} else {
+				$this->Error('[Image] Unable to get image: '.$file);
+			}
+		}
+		// file hash
+		$filehash = md5($this->file_id.$file);
+		// get original image width and height in pixels
+		list($pixw, $pixh) = $imsize;
+		// calculate image width and height on document
+		if (($w <= 0) AND ($h <= 0)) {
+			// convert image size to document unit
+			$w = $this->pixelsToUnits($pixw);
+			$h = $this->pixelsToUnits($pixh);
+		} elseif ($w <= 0) {
+			$w = $h * $pixw / $pixh;
+		} elseif ($h <= 0) {
+			$h = $w * $pixh / $pixw;
+		} elseif (($fitbox !== false) AND ($w > 0) AND ($h > 0)) {
+			if (strlen($fitbox) !== 2) {
+				// set default alignment
+				$fitbox = '--';
+			}
+			// scale image dimensions proportionally to fit within the ($w, $h) box
+			if ((($w * $pixh) / ($h * $pixw)) < 1) {
+				// store current height
+				$oldh = $h;
+				// calculate new height
+				$h = $w * $pixh / $pixw;
+				// height difference
+				$hdiff = ($oldh - $h);
+				// vertical alignment
+				switch (strtoupper($fitbox{1})) {
+					case 'T': {
+						break;
+					}
+					case 'M': {
+						$y += ($hdiff / 2);
+						break;
+					}
+					case 'B': {
+						$y += $hdiff;
+						break;
+					}
+				}
+			} else {
+				// store current width
+				$oldw = $w;
+				// calculate new width
+				$w = $h * $pixw / $pixh;
+				// width difference
+				$wdiff = ($oldw - $w);
+				// horizontal alignment
+				switch (strtoupper($fitbox{0})) {
+					case 'L': {
+						if ($this->rtl) {
+							$x -= $wdiff;
+						}
+						break;
+					}
+					case 'C': {
+						if ($this->rtl) {
+							$x -= ($wdiff / 2);
+						} else {
+							$x += ($wdiff / 2);
+						}
+						break;
+					}
+					case 'R': {
+						if (!$this->rtl) {
+							$x += $wdiff;
+						}
+						break;
+					}
+				}
+			}
+		}
+		// fit the image on available space
+		list($w, $h, $x, $y) = $this->fitBlock($w, $h, $x, $y, $fitonpage);
+		// calculate new minimum dimensions in pixels
+		$neww = round($w * $this->k * $dpi / $this->dpi);
+		$newh = round($h * $this->k * $dpi / $this->dpi);
+		// check if resize is necessary (resize is used only to reduce the image)
+		$newsize = ($neww * $newh);
+		$pixsize = ($pixw * $pixh);
+		if (intval($resize) == 2) {
+			$resize = true;
+		} elseif ($newsize >= $pixsize) {
+			$resize = false;
+		}
+		// check if image has been already added on document
+		$newimage = true;
+		if (in_array($file, $this->imagekeys)) {
+			$newimage = false;
+			// get existing image data
+			$info = $this->getImageBuffer($file);
+			if (substr($file, 0, -34) != K_PATH_CACHE.'msk') {
+				// check if the newer image is larger
+				$oldsize = ($info['w'] * $info['h']);
+				if ((($oldsize < $newsize) AND ($resize)) OR (($oldsize < $pixsize) AND (!$resize))) {
+					$newimage = true;
+				}
+			}
+		} elseif (substr($file, 0, -34) != K_PATH_CACHE.'msk') {
+			// check for cached images with alpha channel
+			$tempfile_plain = K_PATH_CACHE.'mskp_'.$filehash;
+			$tempfile_alpha = K_PATH_CACHE.'mska_'.$filehash;
+			if (in_array($tempfile_plain, $this->imagekeys)) {
+				// get existing image data
+				$info = $this->getImageBuffer($tempfile_plain);
+				// check if the newer image is larger
+				$oldsize = ($info['w'] * $info['h']);
+				if ((($oldsize < $newsize) AND ($resize)) OR (($oldsize < $pixsize) AND (!$resize))) {
+					$newimage = true;
+				} else {
+					$newimage = false;
+					// embed mask image
+					$imgmask = $this->Image($tempfile_alpha, $x, $y, $w, $h, 'PNG', '', '', $resize, $dpi, '', true, false);
+					// embed image, masked with previously embedded mask
+					return $this->Image($tempfile_plain, $x, $y, $w, $h, $type, $link, $align, $resize, $dpi, $palign, false, $imgmask);
+				}
+			}
+		}
+		if ($newimage) {
+			//First use of image, get info
+			$type = strtolower($type);
+			if ($type == '') {
+				$type = $this->getImageFileType($file, $imsize);
+			} elseif ($type == 'jpg') {
+				$type = 'jpeg';
+			}
+			$mqr = $this->get_mqr();
+			$this->set_mqr(false);
+			// Specific image handlers
+			$mtd = '_parse'.$type;
+			// GD image handler function
+			$gdfunction = 'imagecreatefrom'.$type;
+			$info = false;
+			if ((method_exists($this, $mtd)) AND (!($resize AND (function_exists($gdfunction) OR extension_loaded('imagick'))))) {
+				// TCPDF image functions
+				$info = $this->$mtd($file);
+				if ($info == 'pngalpha') {
+					return $this->ImagePngAlpha($file, $x, $y, $pixw, $pixh, $w, $h, 'PNG', $link, $align, $resize, $dpi, $palign, $filehash);
+				}
+			}
+			if (!$info) {
+				if (function_exists($gdfunction)) {
+					// GD library
+					$img = $gdfunction($file);
+					if ($resize) {
+						$imgr = imagecreatetruecolor($neww, $newh);
+						if (($type == 'gif') OR ($type == 'png')) {
+							$imgr = $this->_setGDImageTransparency($imgr, $img);
+						}
+						imagecopyresampled($imgr, $img, 0, 0, 0, 0, $neww, $newh, $pixw, $pixh);
+						if (($type == 'gif') OR ($type == 'png')) {
+							$info = $this->_toPNG($imgr);
+						} else {
+							$info = $this->_toJPEG($imgr);
+						}
+					} else {
+						if (($type == 'gif') OR ($type == 'png')) {
+							$info = $this->_toPNG($img);
+						} else {
+							$info = $this->_toJPEG($img);
+						}
+					}
+				} elseif (extension_loaded('imagick')) {
+					// ImageMagick library
+					$img = new Imagick();
+					if ($type == 'SVG') {
+						// get SVG file content
+						$svgimg = file_get_contents($file);
+						// get width and height
+						$regs = array();
+						if (preg_match('/<svg([^\>]*)>/si', $svgimg, $regs)) {
+							$svgtag = $regs[1];
+							$tmp = array();
+							if (preg_match('/[\s]+width[\s]*=[\s]*"([^"]*)"/si', $svgtag, $tmp)) {
+								$ow = $this->getHTMLUnitToUnits($tmp[1], 1, $this->svgunit, false);
+								$owu = sprintf('%F', ($ow * $dpi / 72)).$this->pdfunit;
+								$svgtag = preg_replace('/[\s]+width[\s]*=[\s]*"[^"]*"/si', ' width="'.$owu.'"', $svgtag, 1);
+							} else {
+								$ow = $w;
+							}
+							$tmp = array();
+							if (preg_match('/[\s]+height[\s]*=[\s]*"([^"]*)"/si', $svgtag, $tmp)) {
+								$oh = $this->getHTMLUnitToUnits($tmp[1], 1, $this->svgunit, false);
+								$ohu = sprintf('%F', ($oh * $dpi / 72)).$this->pdfunit;
+								$svgtag = preg_replace('/[\s]+height[\s]*=[\s]*"[^"]*"/si', ' height="'.$ohu.'"', $svgtag, 1);
+							} else {
+								$oh = $h;
+							}
+							$tmp = array();
+							if (!preg_match('/[\s]+viewBox[\s]*=[\s]*"[\s]*([0-9\.]+)[\s]+([0-9\.]+)[\s]+([0-9\.]+)[\s]+([0-9\.]+)[\s]*"/si', $svgtag, $tmp)) {
+								$vbw = ($ow * $this->imgscale * $this->k);
+								$vbh = ($oh * $this->imgscale * $this->k);
+								$vbox = sprintf(' viewBox="0 0 %F %F" ', $vbw, $vbh);
+								$svgtag = $vbox.$svgtag;
+							}
+							$svgimg = preg_replace('/<svg([^\>]*)>/si', '<svg'.$svgtag.'>', $svgimg, 1);
+						}
+						$img->readImageBlob($svgimg);
+					} else {
+						$img->readImage($file);
+					}
+					if ($resize) {
+						$img->resizeImage($neww, $newh, 10, 1, false);
+					}
+					$img->setCompressionQuality($this->jpeg_quality);
+					$img->setImageFormat('jpeg');
+					$tempname = tempnam(K_PATH_CACHE, 'jpg_');
+					$img->writeImage($tempname);
+					$info = $this->_parsejpeg($tempname);
+					unlink($tempname);
+					$img->destroy();
+				} else {
+					return;
+				}
+			}
+			if ($info === false) {
+				//If false, we cannot process image
+				return;
+			}
+			$this->set_mqr($mqr);
+			if ($ismask) {
+				// force grayscale
+				$info['cs'] = 'DeviceGray';
+			}
+			if ($imgmask !== false) {
+				$info['masked'] = $imgmask;
+			}
+			if (!empty($exurl)) {
+				$info['exurl'] = $exurl;
+			}
+			// array of alternative images
+			$info['altimgs'] = $altimgs;
+			// add image to document
+			$info['i'] = $this->setImageBuffer($file, $info);
+		}
+		// set alignment
+		$this->img_rb_y = $y + $h;
+		// set alignment
+		if ($this->rtl) {
+			if ($palign == 'L') {
+				$ximg = $this->lMargin;
+			} elseif ($palign == 'C') {
+				$ximg = ($this->w + $this->lMargin - $this->rMargin - $w) / 2;
+			} elseif ($palign == 'R') {
+				$ximg = $this->w - $this->rMargin - $w;
+			} else {
+				$ximg = $x - $w;
+			}
+			$this->img_rb_x = $ximg;
+		} else {
+			if ($palign == 'L') {
+				$ximg = $this->lMargin;
+			} elseif ($palign == 'C') {
+				$ximg = ($this->w + $this->lMargin - $this->rMargin - $w) / 2;
+			} elseif ($palign == 'R') {
+				$ximg = $this->w - $this->rMargin - $w;
+			} else {
+				$ximg = $x;
+			}
+			$this->img_rb_x = $ximg + $w;
+		}
+		if ($ismask OR $hidden) {
+			// image is not displayed
+			return $info['i'];
+		}
+		$xkimg = $ximg * $this->k;
+		if (!$alt) {
+			// only non-alternative immages will be set
+			$this->_out(sprintf('q %F 0 0 %F %F %F cm /I%u Do Q', ($w * $this->k), ($h * $this->k), $xkimg, (($this->h - ($y + $h)) * $this->k), $info['i']));
+		}
+		if (!empty($border)) {
+			$bx = $this->x;
+			$by = $this->y;
+			$this->x = $ximg;
+			if ($this->rtl) {
+				$this->x += $w;
+			}
+			$this->y = $y;
+			$this->Cell($w, $h, '', $border, 0, '', 0, '', 0, true);
+			$this->x = $bx;
+			$this->y = $by;
+		}
+		if ($link) {
+			$this->Link($ximg, $y, $w, $h, $link, 0);
+		}
+		// set pointer to align the next text/objects
+		switch($align) {
+			case 'T': {
+				$this->y = $y;
+				$this->x = $this->img_rb_x;
+				break;
+			}
+			case 'M': {
+				$this->y = $y + round($h/2);
+				$this->x = $this->img_rb_x;
+				break;
+			}
+			case 'B': {
+				$this->y = $this->img_rb_y;
+				$this->x = $this->img_rb_x;
+				break;
+			}
+			case 'N': {
+				$this->SetY($this->img_rb_y);
+				break;
+			}
+			default:{
+				break;
+			}
+		}
+		$this->endlinex = $this->img_rb_x;
+		if ($this->inxobj) {
+			// we are inside an XObject template
+			$this->xobjects[$this->xobjid]['images'][] = $info['i'];
+		}
+		return $info['i'];
+	}
+
+	/**
+	 * Sets the current active configuration setting of magic_quotes_runtime (if the set_magic_quotes_runtime function exist)
+	 * @param $mqr (boolean) FALSE for off, TRUE for on.
+	 * @since 4.6.025 (2009-08-17)
+	 */
+	public function set_mqr($mqr) {
+		if (!defined('PHP_VERSION_ID')) {
+			$version = PHP_VERSION;
+			define('PHP_VERSION_ID', (($version{0} * 10000) + ($version{2} * 100) + $version{4}));
+		}
+		if (PHP_VERSION_ID < 50300) {
+			@set_magic_quotes_runtime($mqr);
+		}
+	}
+
+	/**
+	 * Gets the current active configuration setting of magic_quotes_runtime (if the get_magic_quotes_runtime function exist)
+	 * @return Returns 0 if magic quotes runtime is off or get_magic_quotes_runtime doesn't exist, 1 otherwise.
+	 * @since 4.6.025 (2009-08-17)
+	 */
+	public function get_mqr() {
+		if (!defined('PHP_VERSION_ID')) {
+			$version = PHP_VERSION;
+			define('PHP_VERSION_ID', (($version{0} * 10000) + ($version{2} * 100) + $version{4}));
+		}
+		if (PHP_VERSION_ID < 50300) {
+			return @get_magic_quotes_runtime();
+		}
+		return 0;
+	}
+
+	/**
+	 * Convert the loaded image to a JPEG and then return a structure for the PDF creator.
+	 * This function requires GD library and write access to the directory defined on K_PATH_CACHE constant.
+	 * @param $image (image) Image object.
+	 * return image JPEG image object.
+	 * @protected
+	 */
+	protected function _toJPEG($image) {
+		$tempname = tempnam(K_PATH_CACHE, 'jpg_');
+		imagejpeg($image, $tempname, $this->jpeg_quality);
+		imagedestroy($image);
+		$retvars = $this->_parsejpeg($tempname);
+		// tidy up by removing temporary image
+		unlink($tempname);
+		return $retvars;
+	}
+
+	/**
+	 * Convert the loaded image to a PNG and then return a structure for the PDF creator.
+	 * This function requires GD library and write access to the directory defined on K_PATH_CACHE constant.
+	 * @param $image (image) Image object.
+	 * return image PNG image object.
+	 * @protected
+	 * @since 4.9.016 (2010-04-20)
+	 */
+	protected function _toPNG($image) {
+		// set temporary image file name
+		$tempname = tempnam(K_PATH_CACHE, 'jpg_');
+		// turn off interlaced mode
+		imageinterlace($image, 0);
+		// create temporary PNG image
+		imagepng($image, $tempname);
+		// remove image from memory
+		imagedestroy($image);
+		// get PNG image data
+		$retvars = $this->_parsepng($tempname);
+		// tidy up by removing temporary image
+		unlink($tempname);
+		return $retvars;
+	}
+
+	/**
+	 * Set the transparency for the given GD image.
+	 * @param $new_image (image) GD image object
+	 * @param $image (image) GD image object.
+	 * return GD image object.
+	 * @protected
+	 * @since 4.9.016 (2010-04-20)
+	 */
+	protected function _setGDImageTransparency($new_image, $image) {
+		// transparency index
+		$tid = imagecolortransparent($image);
+		// default transparency color
+		$tcol = array('red' => 255, 'green' => 255, 'blue' => 255);
+		if ($tid >= 0) {
+			// get the colors for the transparency index
+			$tcol = imagecolorsforindex($image, $tid);
+		}
+		$tid = imagecolorallocate($new_image, $tcol['red'], $tcol['green'], $tcol['blue']);
+		imagefill($new_image, 0, 0, $tid);
+		imagecolortransparent($new_image, $tid);
+		return $new_image;
+	}
+
+	/**
+	 * Extract info from a JPEG file without using the GD library.
+	 * @param $file (string) image file to parse
+	 * @return array structure containing the image data
+	 * @protected
+	 */
+	protected function _parsejpeg($file) {
+		$a = getimagesize($file);
+		if (empty($a)) {
+			$this->Error('Missing or incorrect image file: '.$file);
+		}
+		if ($a[2] != 2) {
+			$this->Error('Not a JPEG file: '.$file);
+		}
+		// bits per pixel
+		$bpc = isset($a['bits']) ? intval($a['bits']) : 8;
+		// number of image channels
+		if (!isset($a['channels'])) {
+			$channels = 3;
+		} else {
+			$channels = intval($a['channels']);
+		}
+		// default colour space
+		switch ($channels) {
+			case 1: {
+				$colspace = 'DeviceGray';
+				break;
+			}
+			case 3: {
+				$colspace = 'DeviceRGB';
+				break;
+			}
+			case 4: {
+				$colspace = 'DeviceCMYK';
+				break;
+			}
+			default: {
+				$channels = 3;
+				$colspace = 'DeviceRGB';
+				break;
+			}
+		}
+		// get file content
+		$data = file_get_contents($file);
+		// check for embedded ICC profile
+		$icc = array();
+		$offset = 0;
+		while (($pos = strpos($data, "ICC_PROFILE\0", $offset)) !== false) {
+			// get ICC sequence length
+			$length = ($this->_getUSHORT($data, ($pos - 2)) - 16);
+			// marker sequence number
+			$msn = max(1, ord($data[($pos + 12)]));
+			// number of markers (total of APP2 used)
+			$nom = max(1, ord($data[($pos + 13)]));
+			// get sequence segment
+			$icc[($msn - 1)] = substr($data, ($pos + 14), $length);
+			// move forward to next sequence
+			$offset = ($pos + 14 + $length);
+		}
+		// order and compact ICC segments
+		if (count($icc) > 0) {
+			ksort($icc);
+			$icc = implode('', $icc);
+			if ((ord($icc{36}) != 0x61) OR (ord($icc{37}) != 0x63) OR (ord($icc{38}) != 0x73) OR (ord($icc{39}) != 0x70)) {
+				// invalid ICC profile
+				$icc = false;
+			}
+		} else {
+			$icc = false;
+		}
+		return array('w' => $a[0], 'h' => $a[1], 'ch' => $channels, 'icc' => $icc, 'cs' => $colspace, 'bpc' => $bpc, 'f' => 'DCTDecode', 'data' => $data);
+	}
+
+	/**
+	 * Extract info from a PNG file without using the GD library.
+	 * @param $file (string) image file to parse
+	 * @return array structure containing the image data
+	 * @protected
+	 */
+	protected function _parsepng($file) {
+		$f = fopen($file, 'rb');
+		if ($f === false) {
+			$this->Error('Can\'t open image file: '.$file);
+		}
+		//Check signature
+		if (fread($f, 8) != chr(137).'PNG'.chr(13).chr(10).chr(26).chr(10)) {
+			$this->Error('Not a PNG file: '.$file);
+		}
+		//Read header chunk
+		fread($f, 4);
+		if (fread($f, 4) != 'IHDR') {
+			$this->Error('Incorrect PNG file: '.$file);
+		}
+		$w = $this->_freadint($f);
+		$h = $this->_freadint($f);
+		$bpc = ord(fread($f, 1));
+		if ($bpc > 8) {
+			//$this->Error('16-bit depth not supported: '.$file);
+			fclose($f);
+			return false;
+		}
+		$ct = ord(fread($f, 1));
+		if ($ct == 0) {
+			$colspace = 'DeviceGray';
+		} elseif ($ct == 2) {
+			$colspace = 'DeviceRGB';
+		} elseif ($ct == 3) {
+			$colspace = 'Indexed';
+		} else {
+			// alpha channel
+			fclose($f);
+			return 'pngalpha';
+		}
+		if (ord(fread($f, 1)) != 0) {
+			//$this->Error('Unknown compression method: '.$file);
+			fclose($f);
+			return false;
+		}
+		if (ord(fread($f, 1)) != 0) {
+			//$this->Error('Unknown filter method: '.$file);
+			fclose($f);
+			return false;
+		}
+		if (ord(fread($f, 1)) != 0) {
+			//$this->Error('Interlacing not supported: '.$file);
+			fclose($f);
+			return false;
+		}
+		fread($f, 4);
+		$channels = ($ct == 2 ? 3 : 1);
+		$parms = '/DecodeParms << /Predictor 15 /Colors '.$channels.' /BitsPerComponent '.$bpc.' /Columns '.$w.' >>';
+		//Scan chunks looking for palette, transparency and image data
+		$pal = '';
+		$trns = '';
+		$data = '';
+		$icc = false;
+		do {
+			$n = $this->_freadint($f);
+			$type = fread($f, 4);
+			if ($type == 'PLTE') {
+				// read palette
+				$pal = $this->rfread($f, $n);
+				fread($f, 4);
+			} elseif ($type == 'tRNS') {
+				// read transparency info
+				$t = $this->rfread($f, $n);
+				if ($ct == 0) {
+					$trns = array(ord($t{1}));
+				} elseif ($ct == 2) {
+					$trns = array(ord($t{1}), ord($t{3}), ord($t{5}));
+				} else {
+					$pos = strpos($t, chr(0));
+					if ($pos !== false) {
+						$trns = array($pos);
+					}
+				}
+				fread($f, 4);
+			} elseif ($type == 'IDAT') {
+				// read image data block
+				$data .= $this->rfread($f, $n);
+				fread($f, 4);
+			} elseif ($type == 'iCCP') {
+				// skip profile name
+				$len = 0;
+				while ((ord(fread($f, 1)) > 0) AND ($len < 80)) {
+					++$len;
+				}
+				// skip null separator
+				fread($f, 1);
+				// get compression method
+				if (ord(fread($f, 1)) != 0) {
+					//$this->Error('Unknown filter method: '.$file);
+					fclose($f);
+					return false;
+				}
+				// read ICC Color Profile
+				$icc = $this->rfread($f, ($n - $len - 2));
+				// decompress profile
+				$icc = gzuncompress($icc);
+				fread($f, 4);
+			} elseif ($type == 'IEND') {
+				break;
+			} else {
+				$this->rfread($f, $n + 4);
+			}
+		} while ($n);
+		if (($colspace == 'Indexed') AND (empty($pal))) {
+			//$this->Error('Missing palette in '.$file);
+			fclose($f);
+			return false;
+		}
+		fclose($f);
+		return array('w' => $w, 'h' => $h, 'ch' => $channels, 'icc' => $icc, 'cs' => $colspace, 'bpc' => $bpc, 'f' => 'FlateDecode', 'parms' => $parms, 'pal' => $pal, 'trns' => $trns, 'data' => $data);
+	}
+
+	/**
+	 * Binary-safe and URL-safe file read.
+	 * Reads up to length bytes from the file pointer referenced by handle. Reading stops as soon as one of the following conditions is met: length bytes have been read; EOF (end of file) is reached.
+	 * @param $handle (resource)
+	 * @param $length (int)
+	 * @return Returns the read string or FALSE in case of error.
+	 * @author Nicola Asuni
+	 * @protected
+	 * @since 4.5.027 (2009-03-16)
+	 */
+	protected function rfread($handle, $length) {
+		$data = fread($handle, $length);
+		if ($data === false) {
+			return false;
+		}
+		$rest = $length - strlen($data);
+		if ($rest > 0) {
+			$data .= $this->rfread($handle, $rest);
+		}
+		return $data;
+	}
+
+	/**
+	 * Extract info from a PNG image with alpha channel using the GD library.
+	 * @param $file (string) Name of the file containing the image.
+	 * @param $x (float) Abscissa of the upper-left corner.
+	 * @param $y (float) Ordinate of the upper-left corner.
+	 * @param $wpx (float) Original width of the image in pixels.
+	 * @param $hpx (float) original height of the image in pixels.
+	 * @param $w (float) Width of the image in the page. If not specified or equal to zero, it is automatically calculated.
+	 * @param $h (float) Height of the image in the page. If not specified or equal to zero, it is automatically calculated.
+	 * @param $type (string) Image format. Possible values are (case insensitive): JPEG and PNG (whitout GD library) and all images supported by GD: GD, GD2, GD2PART, GIF, JPEG, PNG, BMP, XBM, XPM;. If not specified, the type is inferred from the file extension.
+	 * @param $link (mixed) URL or identifier returned by AddLink().
+	 * @param $align (string) Indicates the alignment of the pointer next to image insertion relative to image height. The value can be:<ul><li>T: top-right for LTR or top-left for RTL</li><li>M: middle-right for LTR or middle-left for RTL</li><li>B: bottom-right for LTR or bottom-left for RTL</li><li>N: next line</li></ul>
+	 * @param $resize (boolean) If true resize (reduce) the image to fit $w and $h (requires GD library).
+	 * @param $dpi (int) dot-per-inch resolution used on resize
+	 * @param $palign (string) Allows to center or align the image on the current line. Possible values are:<ul><li>L : left align</li><li>C : center</li><li>R : right align</li><li>'' : empty string : left for LTR or right for RTL</li></ul>
+	 * @param $filehash (string) File hash used to build unique file names.
+	 * @author Nicola Asuni
+	 * @protected
+	 * @since 4.3.007 (2008-12-04)
+	 * @see Image()
+	 */
+	protected function ImagePngAlpha($file, $x, $y, $wpx, $hpx, $w, $h, $type, $link, $align, $resize, $dpi, $palign, $filehash='') {
+		if (empty($filehash)) {
+			$filehash = md5($this->file_id.$file);
+		}
+		// create temp image file (without alpha channel)
+		$tempfile_plain = K_PATH_CACHE.'mskp_'.$filehash;
+		// create temp alpha file
+		$tempfile_alpha = K_PATH_CACHE.'mska_'.$filehash;
+		if (extension_loaded('imagick')) { // ImageMagick extension
+			// ImageMagick library
+			$img = new Imagick();
+			$img->readImage($file);
+			// clone image object
+			$imga = $this->objclone($img);
+			// extract alpha channel
+			if (method_exists($img, 'setImageAlphaChannel') AND defined('Imagick::ALPHACHANNEL_EXTRACT')) {
+				$img->setImageAlphaChannel(Imagick::ALPHACHANNEL_EXTRACT);
+			} else {
+				$img->separateImageChannel(8); // 8 = (imagick::CHANNEL_ALPHA | imagick::CHANNEL_OPACITY | imagick::CHANNEL_MATTE);
+				$img->negateImage(true);
+			}
+			$img->setImageFormat('png');
+			$img->writeImage($tempfile_alpha);
+			// remove alpha channel
+			if (method_exists($imga, 'setImageMatte')) {
+				$imga->setImageMatte(false);
+			} else {
+				$imga->separateImageChannel(39); // 39 = (imagick::CHANNEL_ALL & ~(imagick::CHANNEL_ALPHA | imagick::CHANNEL_OPACITY | imagick::CHANNEL_MATTE));
+			}
+			$imga->setImageFormat('png');
+			$imga->writeImage($tempfile_plain);
+		} elseif (function_exists('imagecreatefrompng')) { // GD extension
+			// generate images
+			$img = imagecreatefrompng($file);
+			$imgalpha = imagecreate($wpx, $hpx);
+			// generate gray scale palette (0 -> 255)
+			for ($c = 0; $c < 256; ++$c) {
+				ImageColorAllocate($imgalpha, $c, $c, $c);
+			}
+			// extract alpha channel
+			for ($xpx = 0; $xpx < $wpx; ++$xpx) {
+				for ($ypx = 0; $ypx < $hpx; ++$ypx) {
+					$color = imagecolorat($img, $xpx, $ypx);
+					$alpha = $this->getGDgamma($color); // correct gamma
+					imagesetpixel($imgalpha, $xpx, $ypx, $alpha);
+				}
+			}
+			imagepng($imgalpha, $tempfile_alpha);
+			imagedestroy($imgalpha);
+			// extract image without alpha channel
+			$imgplain = imagecreatetruecolor($wpx, $hpx);
+			imagecopy($imgplain, $img, 0, 0, 0, 0, $wpx, $hpx);
+			imagepng($imgplain, $tempfile_plain);
+			imagedestroy($imgplain);
+		} else {
+			$this->Error('TCPDF requires the Imagick or GD extension to handle PNG images with alpha channel.');
+		}
+		// embed mask image
+		$imgmask = $this->Image($tempfile_alpha, $x, $y, $w, $h, 'PNG', '', '', $resize, $dpi, '', true, false);
+		// embed image, masked with previously embedded mask
+		$this->Image($tempfile_plain, $x, $y, $w, $h, $type, $link, $align, $resize, $dpi, $palign, false, $imgmask);
+		// remove temp files
+		unlink($tempfile_alpha);
+		unlink($tempfile_plain);
+	}
+
+	/**
+	 * Get the GD-corrected PNG gamma value from alpha color
+	 * @param $c (int) alpha color
+	 * @protected
+	 * @since 4.3.007 (2008-12-04)
+	 */
+	protected function getGDgamma($c) {
+		if (!isset($this->gdgammacache["'".$c."'"])) {
+			// shifts off the first 24 bits (where 8x3 are used for each color),
+			// and returns the remaining 7 allocated bits (commonly used for alpha)
+			$alpha = ($c >> 24);
+			// GD alpha is only 7 bit (0 -> 127)
+			$alpha = (((127 - $alpha) / 127) * 255);
+			// correct gamma
+			$this->gdgammacache["'".$c."'"] = (pow(($alpha / 255), 2.2) * 255);
+			// store the latest values on cache to improve performances
+			if (count($this->gdgammacache) > 8) {
+				// remove one element from the cache array
+				array_shift($this->gdgammacache);
+			}
+		}
+		return $this->gdgammacache["'".$c."'"];
+	}
+
+	/**
+	 * Performs a line break.
+	 * The current abscissa goes back to the left margin and the ordinate increases by the amount passed in parameter.
+	 * @param $h (float) The height of the break. By default, the value equals the height of the last printed cell.
+	 * @param $cell (boolean) if true add the current left (or right o for RTL) padding to the X coordinate
+	 * @public
+	 * @since 1.0
+	 * @see Cell()
+	 */
+	public function Ln($h='', $cell=false) {
+		if (($this->num_columns > 1) AND ($this->y == $this->columns[$this->current_column]['y']) AND isset($this->columns[$this->current_column]['x']) AND ($this->x == $this->columns[$this->current_column]['x'])) {
+			// revove vertical space from the top of the column
+			return;
+		}
+		if ($cell) {
+			if ($this->rtl) {
+				$cellpadding = $this->cell_padding['R'];
+			} else {
+				$cellpadding = $this->cell_padding['L'];
+			}
+		} else {
+			$cellpadding = 0;
+		}
+		if ($this->rtl) {
+			$this->x = $this->w - $this->rMargin - $cellpadding;
+		} else {
+			$this->x = $this->lMargin + $cellpadding;
+		}
+		if (is_string($h)) {
+			$this->y += $this->lasth;
+		} else {
+			$this->y += $h;
+		}
+		$this->newline = true;
+	}
+
+	/**
+	 * Returns the relative X value of current position.
+	 * The value is relative to the left border for LTR languages and to the right border for RTL languages.
+	 * @return float
+	 * @public
+	 * @since 1.2
+	 * @see SetX(), GetY(), SetY()
+	 */
+	public function GetX() {
+		//Get x position
+		if ($this->rtl) {
+			return ($this->w - $this->x);
+		} else {
+			return $this->x;
+		}
+	}
+
+	/**
+	 * Returns the absolute X value of current position.
+	 * @return float
+	 * @public
+	 * @since 1.2
+	 * @see SetX(), GetY(), SetY()
+	 */
+	public function GetAbsX() {
+		return $this->x;
+	}
+
+	/**
+	 * Returns the ordinate of the current position.
+	 * @return float
+	 * @public
+	 * @since 1.0
+	 * @see SetY(), GetX(), SetX()
+	 */
+	public function GetY() {
+		return $this->y;
+	}
+
+	/**
+	 * Defines the abscissa of the current position.
+	 * If the passed value is negative, it is relative to the right of the page (or left if language is RTL).
+	 * @param $x (float) The value of the abscissa in user units.
+	 * @param $rtloff (boolean) if true always uses the page top-left corner as origin of axis.
+	 * @public
+	 * @since 1.2
+	 * @see GetX(), GetY(), SetY(), SetXY()
+	 */
+	public function SetX($x, $rtloff=false) {
+		$x = floatval($x);
+		if (!$rtloff AND $this->rtl) {
+			if ($x >= 0) {
+				$this->x = $this->w - $x;
+			} else {
+				$this->x = abs($x);
+			}
+		} else {
+			if ($x >= 0) {
+				$this->x = $x;
+			} else {
+				$this->x = $this->w + $x;
+			}
+		}
+		if ($this->x < 0) {
+			$this->x = 0;
+		}
+		if ($this->x > $this->w) {
+			$this->x = $this->w;
+		}
+	}
+
+	/**
+	 * Moves the current abscissa back to the left margin and sets the ordinate.
+	 * If the passed value is negative, it is relative to the bottom of the page.
+	 * @param $y (float) The value of the ordinate in user units.
+	 * @param $resetx (bool) if true (default) reset the X position.
+	 * @param $rtloff (boolean) if true always uses the page top-left corner as origin of axis.
+	 * @public
+	 * @since 1.0
+	 * @see GetX(), GetY(), SetY(), SetXY()
+	 */
+	public function SetY($y, $resetx=true, $rtloff=false) {
+		$y = floatval($y);
+		if ($resetx) {
+			//reset x
+			if (!$rtloff AND $this->rtl) {
+				$this->x = $this->w - $this->rMargin;
+			} else {
+				$this->x = $this->lMargin;
+			}
+		}
+		if ($y >= 0) {
+			$this->y = $y;
+		} else {
+			$this->y = $this->h + $y;
+		}
+		if ($this->y < 0) {
+			$this->y = 0;
+		}
+		if ($this->y > $this->h) {
+			$this->y = $this->h;
+		}
+	}
+
+	/**
+	 * Defines the abscissa and ordinate of the current position.
+	 * If the passed values are negative, they are relative respectively to the right and bottom of the page.
+	 * @param $x (float) The value of the abscissa.
+	 * @param $y (float) The value of the ordinate.
+	 * @param $rtloff (boolean) if true always uses the page top-left corner as origin of axis.
+	 * @public
+	 * @since 1.2
+	 * @see SetX(), SetY()
+	 */
+	public function SetXY($x, $y, $rtloff=false) {
+		$this->SetY($y, false, $rtloff);
+		$this->SetX($x, $rtloff);
+	}
+
+	/**
+	 * Set the absolute X coordinate of the current pointer.
+	 * @param $x (float) The value of the abscissa in user units.
+	 * @public
+	 * @since 5.9.186 (2012-09-13)
+	 * @see setAbsX(), setAbsY(), SetAbsXY()
+	 */
+	public function SetAbsX($x) {
+		$this->x = floatval($x);
+	}
+
+	/**
+	 * Set the absolute Y coordinate of the current pointer.
+	 * @param $y (float) (float) The value of the ordinate in user units.
+	 * @public
+	 * @since 5.9.186 (2012-09-13)
+	 * @see setAbsX(), setAbsY(), SetAbsXY()
+	 */
+	public function SetAbsY($y) {
+		$this->y = floatval($y);
+	}
+
+	/**
+	 * Set the absolute X and Y coordinates of the current pointer.
+	 * @param $x (float) The value of the abscissa in user units.
+	 * @param $y (float) (float) The value of the ordinate in user units.
+	 * @public
+	 * @since 5.9.186 (2012-09-13)
+	 * @see setAbsX(), setAbsY(), SetAbsXY()
+	 */
+	public function SetAbsXY($x, $y) {
+		$this->SetAbsX($x);
+		$this->SetAbsY($y);
+	}
+
+	/**
+	 * Ouput input data and compress it if possible.
+	 * @param $data (string) Data to output.
+	 * @param $length (int) Data length in bytes.
+	 * @protected
+	 * @since 5.9.086
+	 */
+	protected function sendOutputData($data, $length) {
+		if (!isset($_SERVER['HTTP_ACCEPT_ENCODING']) OR empty($_SERVER['HTTP_ACCEPT_ENCODING'])) {
+			// the content length may vary if the server is using compression
+			header('Content-Length: '.$length);
+		}
+		echo $data;
+	}
+
+	/**
+	 * Send the document to a given destination: string, local file or browser.
+	 * In the last case, the plug-in may be used (if present) or a download ("Save as" dialog box) may be forced.<br />
+	 * The method first calls Close() if necessary to terminate the document.
+	 * @param $name (string) The name of the file when saved. Note that special characters are removed and blanks characters are replaced with the underscore character.
+	 * @param $dest (string) Destination where to send the document. It can take one of the following values:<ul><li>I: send the file inline to the browser (default). The plug-in is used if available. The name given by name is used when one selects the "Save as" option on the link generating the PDF.</li><li>D: send to the browser and force a file download with the name given by name.</li><li>F: save to a local server file with the name given by name.</li><li>S: return the document as a str [...]
+	 * @public
+	 * @since 1.0
+	 * @see Close()
+	 */
+	public function Output($name='doc.pdf', $dest='I') {
+		//Output PDF to some destination
+		//Finish document if necessary
+		if ($this->state < 3) {
+			$this->Close();
+		}
+		//Normalize parameters
+		if (is_bool($dest)) {
+			$dest = $dest ? 'D' : 'F';
+		}
+		$dest = strtoupper($dest);
+		if ($dest{0} != 'F') {
+			$name = preg_replace('/[\s]+/', '_', $name);
+			$name = preg_replace('/[^a-zA-Z0-9_\.-]/', '', $name);
+		}
+		if ($this->sign) {
+			// *** apply digital signature to the document ***
+			// get the document content
+			$pdfdoc = $this->getBuffer();
+			// remove last newline
+			$pdfdoc = substr($pdfdoc, 0, -1);
+			// Remove the original buffer
+			if (isset($this->diskcache) AND $this->diskcache) {
+				// remove buffer file from cache
+				unlink($this->buffer);
+			}
+			unset($this->buffer);
+			// remove filler space
+			$byterange_string_len = strlen($this->byterange_string);
+			// define the ByteRange
+			$byte_range = array();
+			$byte_range[0] = 0;
+			$byte_range[1] = strpos($pdfdoc, $this->byterange_string) + $byterange_string_len + 10;
+			$byte_range[2] = $byte_range[1] + $this->signature_max_length + 2;
+			$byte_range[3] = strlen($pdfdoc) - $byte_range[2];
+			$pdfdoc = substr($pdfdoc, 0, $byte_range[1]).substr($pdfdoc, $byte_range[2]);
+			// replace the ByteRange
+			$byterange = sprintf('/ByteRange[0 %u %u %u]', $byte_range[1], $byte_range[2], $byte_range[3]);
+			$byterange .= str_repeat(' ', ($byterange_string_len - strlen($byterange)));
+			$pdfdoc = str_replace($this->byterange_string, $byterange, $pdfdoc);
+			// write the document to a temporary folder
+			$tempdoc = tempnam(K_PATH_CACHE, 'tmppdf_');
+			$f = fopen($tempdoc, 'wb');
+			if (!$f) {
+				$this->Error('Unable to create temporary file: '.$tempdoc);
+			}
+			$pdfdoc_length = strlen($pdfdoc);
+			fwrite($f, $pdfdoc, $pdfdoc_length);
+			fclose($f);
+			// get digital signature via openssl library
+			$tempsign = tempnam(K_PATH_CACHE, 'tmpsig_');
+			if (empty($this->signature_data['extracerts'])) {
+				openssl_pkcs7_sign($tempdoc, $tempsign, $this->signature_data['signcert'], array($this->signature_data['privkey'], $this->signature_data['password']), array(), PKCS7_BINARY | PKCS7_DETACHED);
+			} else {
+				openssl_pkcs7_sign($tempdoc, $tempsign, $this->signature_data['signcert'], array($this->signature_data['privkey'], $this->signature_data['password']), array(), PKCS7_BINARY | PKCS7_DETACHED, $this->signature_data['extracerts']);
+			}
+			unlink($tempdoc);
+			// read signature
+			$signature = file_get_contents($tempsign);
+			unlink($tempsign);
+			// extract signature
+			$signature = substr($signature, $pdfdoc_length);
+			$signature = substr($signature, (strpos($signature, "%%EOF\n\n------") + 13));
+			$tmparr = explode("\n\n", $signature);
+			$signature = $tmparr[1];
+			unset($tmparr);
+			// decode signature
+			$signature = base64_decode(trim($signature));
+			// convert signature to hex
+			$signature = current(unpack('H*', $signature));
+			$signature = str_pad($signature, $this->signature_max_length, '0');
+			// disable disk caching
+			$this->diskcache = false;
+			// Add signature to the document
+			$this->buffer = substr($pdfdoc, 0, $byte_range[1]).'<'.$signature.'>'.substr($pdfdoc, $byte_range[1]);
+			$this->bufferlen = strlen($this->buffer);
+		}
+		switch($dest) {
+			case 'I': {
+				// Send PDF to the standard output
+				if (ob_get_contents()) {
+					$this->Error('Some data has already been output, can\'t send PDF file');
+				}
+				if (php_sapi_name() != 'cli') {
+					// send output to a browser
+					header('Content-Type: application/pdf');
+					if (headers_sent()) {
+						$this->Error('Some data has already been output to browser, can\'t send PDF file');
+					}
+					header('Cache-Control: private, must-revalidate, post-check=0, pre-check=0, max-age=1');
+					//header('Cache-Control: public, must-revalidate, max-age=0'); // HTTP/1.1
+					header('Pragma: public');
+					header('Expires: Sat, 26 Jul 1997 05:00:00 GMT'); // Date in the past
+					header('Last-Modified: '.gmdate('D, d M Y H:i:s').' GMT');
+					header('Content-Disposition: inline; filename="'.basename($name).'"');
+					$this->sendOutputData($this->getBuffer(), $this->bufferlen);
+				} else {
+					echo $this->getBuffer();
+				}
+				break;
+			}
+			case 'D': {
+				// download PDF as file
+				if (ob_get_contents()) {
+					$this->Error('Some data has already been output, can\'t send PDF file');
+				}
+				header('Content-Description: File Transfer');
+				if (headers_sent()) {
+					$this->Error('Some data has already been output to browser, can\'t send PDF file');
+				}
+				header('Cache-Control: private, must-revalidate, post-check=0, pre-check=0, max-age=1');
+				//header('Cache-Control: public, must-revalidate, max-age=0'); // HTTP/1.1
+				header('Pragma: public');
+				header('Expires: Sat, 26 Jul 1997 05:00:00 GMT'); // Date in the past
+				header('Last-Modified: '.gmdate('D, d M Y H:i:s').' GMT');
+				// force download dialog
+				if (strpos(php_sapi_name(), 'cgi') === false) {
+					header('Content-Type: application/force-download');
+					header('Content-Type: application/octet-stream', false);
+					header('Content-Type: application/download', false);
+					header('Content-Type: application/pdf', false);
+				} else {
+					header('Content-Type: application/pdf');
+				}
+				// use the Content-Disposition header to supply a recommended filename
+				header('Content-Disposition: attachment; filename="'.basename($name).'"');
+				header('Content-Transfer-Encoding: binary');
+				$this->sendOutputData($this->getBuffer(), $this->bufferlen);
+				break;
+			}
+			case 'F':
+			case 'FI':
+			case 'FD': {
+				// save PDF to a local file
+				if ($this->diskcache) {
+					copy($this->buffer, $name);
+				} else {
+					$f = fopen($name, 'wb');
+					if (!$f) {
+						$this->Error('Unable to create output file: '.$name);
+					}
+					fwrite($f, $this->getBuffer(), $this->bufferlen);
+					fclose($f);
+				}
+				if ($dest == 'FI') {
+					// send headers to browser
+					header('Content-Type: application/pdf');
+					header('Cache-Control: private, must-revalidate, post-check=0, pre-check=0, max-age=1');
+					//header('Cache-Control: public, must-revalidate, max-age=0'); // HTTP/1.1
+					header('Pragma: public');
+					header('Expires: Sat, 26 Jul 1997 05:00:00 GMT'); // Date in the past
+					header('Last-Modified: '.gmdate('D, d M Y H:i:s').' GMT');
+					header('Content-Disposition: inline; filename="'.basename($name).'"');
+					$this->sendOutputData(file_get_contents($name), filesize($name));
+				} elseif ($dest == 'FD') {
+					// send headers to browser
+					if (ob_get_contents()) {
+						$this->Error('Some data has already been output, can\'t send PDF file');
+					}
+					header('Content-Description: File Transfer');
+					if (headers_sent()) {
+						$this->Error('Some data has already been output to browser, can\'t send PDF file');
+					}
+					header('Cache-Control: private, must-revalidate, post-check=0, pre-check=0, max-age=1');
+					header('Pragma: public');
+					header('Expires: Sat, 26 Jul 1997 05:00:00 GMT'); // Date in the past
+					header('Last-Modified: '.gmdate('D, d M Y H:i:s').' GMT');
+					// force download dialog
+					if (strpos(php_sapi_name(), 'cgi') === false) {
+						header('Content-Type: application/force-download');
+						header('Content-Type: application/octet-stream', false);
+						header('Content-Type: application/download', false);
+						header('Content-Type: application/pdf', false);
+					} else {
+						header('Content-Type: application/pdf');
+					}
+					// use the Content-Disposition header to supply a recommended filename
+					header('Content-Disposition: attachment; filename="'.basename($name).'"');
+					header('Content-Transfer-Encoding: binary');
+					$this->sendOutputData(file_get_contents($name), filesize($name));
+				}
+				break;
+			}
+			case 'E': {
+				// return PDF as base64 mime multi-part email attachment (RFC 2045)
+				$retval = 'Content-Type: application/pdf;'."\r\n";
+				$retval .= ' name="'.$name.'"'."\r\n";
+				$retval .= 'Content-Transfer-Encoding: base64'."\r\n";
+				$retval .= 'Content-Disposition: attachment;'."\r\n";
+				$retval .= ' filename="'.$name.'"'."\r\n\r\n";
+				$retval .= chunk_split(base64_encode($this->getBuffer()), 76, "\r\n");
+				return $retval;
+			}
+			case 'S': {
+				// returns PDF as a string
+				return $this->getBuffer();
+			}
+			default: {
+				$this->Error('Incorrect output destination: '.$dest);
+			}
+		}
+		return '';
+	}
+
+	/**
+	 * Unset all class variables except the following critical variables.
+	 * @param $destroyall (boolean) if true destroys all class variables, otherwise preserves critical variables.
+	 * @param $preserve_objcopy (boolean) if true preserves the objcopy variable
+	 * @public
+	 * @since 4.5.016 (2009-02-24)
+	 */
+	public function _destroy($destroyall=false, $preserve_objcopy=false) {
+		if ($destroyall AND isset($this->diskcache) AND $this->diskcache AND (!$preserve_objcopy) AND (!$this->empty_string($this->buffer))) {
+			// remove buffer file from cache
+			unlink($this->buffer);
+		}
+		if ($destroyall AND isset($this->cached_files) AND !empty($this->cached_files)) {
+			// remove cached files
+			foreach ($this->cached_files as $cachefile) {
+				if (is_file($cachefile)) {
+					unlink($cachefile);
+				}
+			}
+			unset($this->cached_files);
+		}
+		foreach (array_keys(get_object_vars($this)) as $val) {
+			if ($destroyall OR (
+				($val != 'internal_encoding')
+				AND ($val != 'state')
+				AND ($val != 'bufferlen')
+				AND ($val != 'buffer')
+				AND ($val != 'diskcache')
+				AND ($val != 'cached_files')
+				AND ($val != 'sign')
+				AND ($val != 'signature_data')
+				AND ($val != 'signature_max_length')
+				AND ($val != 'byterange_string')
+				)) {
+				if ((!$preserve_objcopy OR ($val != 'objcopy')) AND isset($this->$val)) {
+					unset($this->$val);
+				}
+			}
+		}
+	}
+
+	/**
+	 * Check for locale-related bug
+	 * @protected
+	 */
+	protected function _dochecks() {
+		//Check for locale-related bug
+		if (1.1 == 1) {
+			$this->Error('Don\'t alter the locale before including class file');
+		}
+		//Check for decimal separator
+		if (sprintf('%.1F', 1.0) != '1.0') {
+			setlocale(LC_NUMERIC, 'C');
+		}
+	}
+
+	/**
+	 * Return fonts path
+	 * @return string
+	 * @protected
+	 */
+	protected function _getfontpath() {
+		if (!defined('K_PATH_FONTS') AND is_dir(dirname(__FILE__).'/fonts')) {
+			define('K_PATH_FONTS', dirname(__FILE__).'/fonts/');
+		}
+		return defined('K_PATH_FONTS') ? K_PATH_FONTS : '';
+	}
+
+	/**
+	 * Return an array containing variations for the basic page number alias.
+	 * @param $a (string) Base alias.
+	 * @return array of page number aliases
+	 * @protected
+	 */
+	protected function getInternalPageNumberAliases($a= '') {
+		$alias = array();
+		// build array of Unicode + ASCII variants (the order is important)
+		$alias = array('u' => array(), 'a' => array());
+		$u = '{'.$a.'}';
+		$alias['u'][] = $this->_escape($u);
+		if ($this->isunicode) {
+			$alias['u'][] = $this->_escape($this->UTF8ToLatin1($u));
+			$alias['u'][] = $this->_escape($this->utf8StrRev($u, false, $this->tmprtl));
+			$alias['a'][] = $this->_escape($this->UTF8ToLatin1($a));
+			$alias['a'][] = $this->_escape($this->utf8StrRev($a, false, $this->tmprtl));
+		}
+		$alias['a'][] = $this->_escape($a);
+		return $alias;
+	}
+
+	/**
+	 * Return an array containing all internal page aliases.
+	 * @return array of page number aliases
+	 * @protected
+	 */
+	protected function getAllInternalPageNumberAliases() {
+		$basic_alias = array($this->alias_tot_pages, $this->alias_num_page, $this->alias_group_tot_pages, $this->alias_group_num_page, $this->alias_right_shift);
+		$pnalias = array();
+		foreach($basic_alias as $k => $a) {
+			$pnalias[$k] = $this->getInternalPageNumberAliases($a);
+		}
+		return $pnalias;
+	}
+
+	/**
+	 * Replace page number aliases with number.
+	 * @param $page (string) Page content.
+	 * @param $replace (array) Array of replacements (array keys are replacement strings, values are alias arrays).
+	 * @param $diff (int) If passed, this will be set to the total char number difference between alias and replacements.
+	 * @return replaced page content and updated $diff parameter as array.
+	 * @protected
+	 */
+	protected function replacePageNumAliases($page, $replace, $diff=0) {
+		foreach ($replace as $rep) {
+			foreach ($rep[3] as $a) {
+				if (strpos($page, $a) !== false) {
+					$page = str_replace($a, $rep[0], $page);
+					$diff += ($rep[2] - $rep[1]);
+				}
+			}
+		}
+		return array($page, $diff);
+	}
+
+	/**
+	 * Replace right shift page number aliases with spaces to correct right alignment.
+	 * This works perfectly only when using monospaced fonts.
+	 * @param $page (string) Page content.
+	 * @param $aliases (array) Array of page aliases.
+	 * @param $diff (int) initial difference to add.
+	 * @return replaced page content.
+	 * @protected
+	 */
+	protected function replaceRightShiftPageNumAliases($page, $aliases, $diff) {
+		foreach ($aliases as $type => $alias) {
+			foreach ($alias as $a) {
+				// find position of compensation factor
+				$startnum = (strpos($a, ':') + 1);
+				$a = substr($a, 0, $startnum);
+				if (($pos = strpos($page, $a)) !== false) {
+					// end of alias
+					$endnum = strpos($page, '}', $pos);
+					// string to be replaced
+					$aa = substr($page, $pos, ($endnum - $pos + 1));
+					// get compensation factor
+					$ratio = substr($page, ($pos + $startnum), ($endnum - $pos - $startnum));
+					$ratio = preg_replace('/[^0-9\.]/', '', $ratio);
+					$ratio = floatval($ratio);
+					if ($type == 'u') {
+						$chrdiff = floor(($diff + 12) * $ratio);
+						$shift = str_repeat(' ', $chrdiff);
+						$shift = $this->UTF8ToUTF16BE($shift, false);
+					} else {
+						$chrdiff = floor(($diff + 11) * $ratio);
+						$shift = str_repeat(' ', $chrdiff);
+					}
+					$page = str_replace($aa, $shift, $page);
+				}
+			}
+		}
+		return $page;
+	}
+
+	/**
+	 * Set page boxes to be included on page descriptions.
+	 * @param $boxes (array) Array of page boxes to set on document: ('MediaBox', 'CropBox', 'BleedBox', 'TrimBox', 'ArtBox').
+	 * @protected
+	 */
+	protected function setPageBoxTypes($boxes) {
+		$validboxes = array('MediaBox', 'CropBox', 'BleedBox', 'TrimBox', 'ArtBox');
+		$this->page_boxes = array();
+		foreach ($boxes as $box) {
+			if (in_array($box, $validboxes)) {
+				$this->page_boxes[] = $box;
+			}
+		}
+	}
+
+	/**
+	 * Output pages (and replace page number aliases).
+	 * @protected
+	 */
+	protected function _putpages() {
+		$filter = ($this->compress) ? '/Filter /FlateDecode ' : '';
+		// get internal aliases for page numbers
+		$pnalias = $this->getAllInternalPageNumberAliases();
+		$num_pages = $this->numpages;
+		$ptpa = $this->formatPageNumber(($this->starting_page_number + $num_pages - 1));
+		$ptpu = $this->UTF8ToUTF16BE($ptpa, false);
+		$ptp_num_chars = $this->GetNumChars($ptpa);
+		$pagegroupnum = 0;
+		$groupnum = 0;
+		$ptgu = 1;
+		$ptga = 1;
+		for ($n = 1; $n <= $num_pages; ++$n) {
+			// get current page
+			$temppage = $this->getPageBuffer($n);
+			$pagelen = strlen($temppage);
+			// set replacements for total pages number
+			$pnpa = $this->formatPageNumber(($this->starting_page_number + $n - 1));
+			$pnpu = $this->UTF8ToUTF16BE($pnpa, false);
+			$pnp_num_chars = $this->GetNumChars($pnpa);
+			$pdiff = 0; // difference used for right shift alignment of page numbers
+			$gdiff = 0; // difference used for right shift alignment of page group numbers
+			if (!empty($this->pagegroups)) {
+				if (isset($this->newpagegroup[$n])) {
+					$pagegroupnum = 0;
+					++$groupnum;
+					$ptga = $this->formatPageNumber($this->pagegroups[$groupnum]);
+					$ptgu = $this->UTF8ToUTF16BE($ptga, false);
+					$ptg_num_chars = $this->GetNumChars($ptga);
+				}
+				++$pagegroupnum;
+				$pnga = $this->formatPageNumber($pagegroupnum);
+				$pngu = $this->UTF8ToUTF16BE($pnga, false);
+				$png_num_chars = $this->GetNumChars($pnga);
+				// replace page numbers
+				$replace = array();
+				$replace[] = array($ptgu, $ptg_num_chars, 9, $pnalias[2]['u']);
+				$replace[] = array($ptga, $ptg_num_chars, 7, $pnalias[2]['a']);
+				$replace[] = array($pngu, $png_num_chars, 9, $pnalias[3]['u']);
+				$replace[] = array($pnga, $png_num_chars, 7, $pnalias[3]['a']);
+				list($temppage, $gdiff) = $this->replacePageNumAliases($temppage, $replace, $gdiff);
+			}
+			// replace page numbers
+			$replace = array();
+			$replace[] = array($ptpu, $ptp_num_chars, 9, $pnalias[0]['u']);
+			$replace[] = array($ptpa, $ptp_num_chars, 7, $pnalias[0]['a']);
+			$replace[] = array($pnpu, $pnp_num_chars, 9, $pnalias[1]['u']);
+			$replace[] = array($pnpa, $pnp_num_chars, 7, $pnalias[1]['a']);
+			list($temppage, $pdiff) = $this->replacePageNumAliases($temppage, $replace, $pdiff);
+			// replace right shift alias
+			$temppage = $this->replaceRightShiftPageNumAliases($temppage, $pnalias[4], max($pdiff, $gdiff));
+			// replace EPS marker
+			$temppage = str_replace($this->epsmarker, '', $temppage);
+			//Page
+			$this->page_obj_id[$n] = $this->_newobj();
+			$out = '<<';
+			$out .= ' /Type /Page';
+			$out .= ' /Parent 1 0 R';
+			$out .= ' /LastModified '.$this->_datestring(0, $this->doc_modification_timestamp);
+			$out .= ' /Resources 2 0 R';
+			foreach ($this->page_boxes as $box) {
+				$out .= ' /'.$box;
+				$out .= sprintf(' [%F %F %F %F]', $this->pagedim[$n][$box]['llx'], $this->pagedim[$n][$box]['lly'], $this->pagedim[$n][$box]['urx'], $this->pagedim[$n][$box]['ury']);
+			}
+			if (isset($this->pagedim[$n]['BoxColorInfo']) AND !empty($this->pagedim[$n]['BoxColorInfo'])) {
+				$out .= ' /BoxColorInfo <<';
+				foreach ($this->page_boxes as $box) {
+					if (isset($this->pagedim[$n]['BoxColorInfo'][$box])) {
+						$out .= ' /'.$box.' <<';
+						if (isset($this->pagedim[$n]['BoxColorInfo'][$box]['C'])) {
+							$color = $this->pagedim[$n]['BoxColorInfo'][$box]['C'];
+							$out .= ' /C [';
+							$out .= sprintf(' %F %F %F', ($color[0] / 255), ($color[1] / 255), ($color[2] / 255));
+							$out .= ' ]';
+						}
+						if (isset($this->pagedim[$n]['BoxColorInfo'][$box]['W'])) {
+							$out .= ' /W '.($this->pagedim[$n]['BoxColorInfo'][$box]['W'] * $this->k);
+						}
+						if (isset($this->pagedim[$n]['BoxColorInfo'][$box]['S'])) {
+							$out .= ' /S /'.$this->pagedim[$n]['BoxColorInfo'][$box]['S'];
+						}
+						if (isset($this->pagedim[$n]['BoxColorInfo'][$box]['D'])) {
+							$dashes = $this->pagedim[$n]['BoxColorInfo'][$box]['D'];
+							$out .= ' /D [';
+							foreach ($dashes as $dash) {
+								$out .= sprintf(' %F', ($dash * $this->k));
+							}
+							$out .= ' ]';
+						}
+						$out .= ' >>';
+					}
+				}
+				$out .= ' >>';
+			}
+			$out .= ' /Contents '.($this->n + 1).' 0 R';
+			$out .= ' /Rotate '.$this->pagedim[$n]['Rotate'];
+			if (!$this->pdfa_mode) {
+				$out .= ' /Group << /Type /Group /S /Transparency /CS /DeviceRGB >>';
+			}
+			if (isset($this->pagedim[$n]['trans']) AND !empty($this->pagedim[$n]['trans'])) {
+				// page transitions
+				if (isset($this->pagedim[$n]['trans']['Dur'])) {
+					$out .= ' /Dur '.$this->pagedim[$n]['trans']['Dur'];
+				}
+				$out .= ' /Trans <<';
+				$out .= ' /Type /Trans';
+				if (isset($this->pagedim[$n]['trans']['S'])) {
+					$out .= ' /S /'.$this->pagedim[$n]['trans']['S'];
+				}
+				if (isset($this->pagedim[$n]['trans']['D'])) {
+					$out .= ' /D '.$this->pagedim[$n]['trans']['D'];
+				}
+				if (isset($this->pagedim[$n]['trans']['Dm'])) {
+					$out .= ' /Dm /'.$this->pagedim[$n]['trans']['Dm'];
+				}
+				if (isset($this->pagedim[$n]['trans']['M'])) {
+					$out .= ' /M /'.$this->pagedim[$n]['trans']['M'];
+				}
+				if (isset($this->pagedim[$n]['trans']['Di'])) {
+					$out .= ' /Di '.$this->pagedim[$n]['trans']['Di'];
+				}
+				if (isset($this->pagedim[$n]['trans']['SS'])) {
+					$out .= ' /SS '.$this->pagedim[$n]['trans']['SS'];
+				}
+				if (isset($this->pagedim[$n]['trans']['B'])) {
+					$out .= ' /B '.$this->pagedim[$n]['trans']['B'];
+				}
+				$out .= ' >>';
+			}
+			$out .= $this->_getannotsrefs($n);
+			$out .= ' /PZ '.$this->pagedim[$n]['PZ'];
+			$out .= ' >>';
+			$out .= "\n".'endobj';
+			$this->_out($out);
+			//Page content
+			$p = ($this->compress) ? gzcompress($temppage) : $temppage;
+			$this->_newobj();
+			$p = $this->_getrawstream($p);
+			$this->_out('<<'.$filter.'/Length '.strlen($p).'>> stream'."\n".$p."\n".'endstream'."\n".'endobj');
+			if ($this->diskcache) {
+				// remove temporary files
+				unlink($this->pages[$n]);
+			}
+		}
+		//Pages root
+		$out = $this->_getobj(1)."\n";
+		$out .= '<< /Type /Pages /Kids [';
+		foreach($this->page_obj_id as $page_obj) {
+			$out .= ' '.$page_obj.' 0 R';
+		}
+		$out .= ' ] /Count '.$num_pages.' >>';
+		$out .= "\n".'endobj';
+		$this->_out($out);
+	}
+
+	/**
+	 * Output references to page annotations
+	 * @param $n (int) page number
+	 * @protected
+	 * @author Nicola Asuni
+	 * @since 4.7.000 (2008-08-29)
+	 * @deprecated
+	 */
+	protected function _putannotsrefs($n) {
+		$this->_out($this->_getannotsrefs($n));
+	}
+
+	/**
+	 * Get references to page annotations.
+	 * @param $n (int) page number
+	 * @return string
+	 * @protected
+	 * @author Nicola Asuni
+	 * @since 5.0.010 (2010-05-17)
+	 */
+	protected function _getannotsrefs($n) {
+		if (!(isset($this->PageAnnots[$n]) OR ($this->sign AND isset($this->signature_data['cert_type'])))) {
+			return '';
+		}
+		$out = ' /Annots [';
+		if (isset($this->PageAnnots[$n])) {
+			foreach ($this->PageAnnots[$n] as $key => $val) {
+				if (!in_array($val['n'], $this->radio_groups)) {
+					$out .= ' '.$val['n'].' 0 R';
+				}
+			}
+			// add radiobutton groups
+			if (isset($this->radiobutton_groups[$n])) {
+				foreach ($this->radiobutton_groups[$n] as $key => $data) {
+					if (isset($data['n'])) {
+						$out .= ' '.$data['n'].' 0 R';
+					}
+				}
+			}
+		}
+		if ($this->sign AND ($n == $this->signature_appearance['page']) AND isset($this->signature_data['cert_type'])) {
+			// set reference for signature object
+			$out .= ' '.$this->sig_obj_id.' 0 R';
+		}
+		if (!empty($this->empty_signature_appearance)) {
+			foreach ($this->empty_signature_appearance as $esa) {
+				if ($esa['page'] == $n) {
+					// set reference for empty signature objects
+					$out .= ' '.$esa['objid'].' 0 R';
+				}
+			}
+		}
+		$out .= ' ]';
+		return $out;
+	}
+
+	/**
+	 * Output annotations objects for all pages.
+	 * !!! THIS METHOD IS NOT YET COMPLETED !!!
+	 * See section 12.5 of PDF 32000_2008 reference.
+	 * @protected
+	 * @author Nicola Asuni
+	 * @since 4.0.018 (2008-08-06)
+	 */
+	protected function _putannotsobjs() {
+		// reset object counter
+		for ($n=1; $n <= $this->numpages; ++$n) {
+			if (isset($this->PageAnnots[$n])) {
+				// set page annotations
+				foreach ($this->PageAnnots[$n] as $key => $pl) {
+					$annot_obj_id = $this->PageAnnots[$n][$key]['n'];
+					// create annotation object for grouping radiobuttons
+					if (isset($this->radiobutton_groups[$n][$pl['txt']]) AND is_array($this->radiobutton_groups[$n][$pl['txt']])) {
+						$radio_button_obj_id = $this->radiobutton_groups[$n][$pl['txt']]['n'];
+						$annots = '<<';
+						$annots .= ' /Type /Annot';
+						$annots .= ' /Subtype /Widget';
+						$annots .= ' /Rect [0 0 0 0]';
+						if ($this->radiobutton_groups[$n][$pl['txt']]['#readonly#']) {
+							// read only
+							$annots .= ' /F 68';
+							$annots .= ' /Ff 49153';
+						} else {
+							$annots .= ' /F 4'; // default print for PDF/A
+							$annots .= ' /Ff 49152';
+						}
+						$annots .= ' /T '.$this->_datastring($pl['txt'], $radio_button_obj_id);
+						if (isset($pl['opt']['tu']) AND is_string($pl['opt']['tu'])) {
+							$annots .= ' /TU '.$this->_datastring($pl['opt']['tu'], $radio_button_obj_id);
+						}
+						$annots .= ' /FT /Btn';
+						$annots .= ' /Kids [';
+						$defval = '';
+						foreach ($this->radiobutton_groups[$n][$pl['txt']] as $key => $data) {
+							if (isset($data['kid'])) {
+								$annots .= ' '.$data['kid'].' 0 R';
+								if ($data['def'] !== 'Off') {
+									$defval = $data['def'];
+								}
+							}
+						}
+						$annots .= ' ]';
+						if (!empty($defval)) {
+							$annots .= ' /V /'.$defval;
+						}
+						$annots .= ' >>';
+						$this->_out($this->_getobj($radio_button_obj_id)."\n".$annots."\n".'endobj');
+						$this->form_obj_id[] = $radio_button_obj_id;
+						// store object id to be used on Parent entry of Kids
+						$this->radiobutton_groups[$n][$pl['txt']] = $radio_button_obj_id;
+					}
+					$formfield = false;
+					$pl['opt'] = array_change_key_case($pl['opt'], CASE_LOWER);
+					$a = $pl['x'] * $this->k;
+					$b = $this->pagedim[$n]['h'] - (($pl['y'] + $pl['h']) * $this->k);
+					$c = $pl['w'] * $this->k;
+					$d = $pl['h'] * $this->k;
+					$rect = sprintf('%F %F %F %F', $a, $b, $a+$c, $b+$d);
+					// create new annotation object
+					$annots = '<</Type /Annot';
+					$annots .= ' /Subtype /'.$pl['opt']['subtype'];
+					$annots .= ' /Rect ['.$rect.']';
+					$ft = array('Btn', 'Tx', 'Ch', 'Sig');
+					if (isset($pl['opt']['ft']) AND in_array($pl['opt']['ft'], $ft)) {
+						$annots .= ' /FT /'.$pl['opt']['ft'];
+						$formfield = true;
+					}
+					$annots .= ' /Contents '.$this->_textstring($pl['txt'], $annot_obj_id);
+					$annots .= ' /P '.$this->page_obj_id[$n].' 0 R';
+					$annots .= ' /NM '.$this->_datastring(sprintf('%04u-%04u', $n, $key), $annot_obj_id);
+					$annots .= ' /M '.$this->_datestring($annot_obj_id, $this->doc_modification_timestamp);
+					if (isset($pl['opt']['f'])) {
+						$fval = 0;
+						if (is_array($pl['opt']['f'])) {
+							foreach ($pl['opt']['f'] as $f) {
+								switch (strtolower($f)) {
+									case 'invisible': {
+										$fval += 1 << 0;
+										break;
+									}
+									case 'hidden': {
+										$fval += 1 << 1;
+										break;
+									}
+									case 'print': {
+										$fval += 1 << 2;
+										break;
+									}
+									case 'nozoom': {
+										$fval += 1 << 3;
+										break;
+									}
+									case 'norotate': {
+										$fval += 1 << 4;
+										break;
+									}
+									case 'noview': {
+										$fval += 1 << 5;
+										break;
+									}
+									case 'readonly': {
+										$fval += 1 << 6;
+										break;
+									}
+									case 'locked': {
+										$fval += 1 << 8;
+										break;
+									}
+									case 'togglenoview': {
+										$fval += 1 << 9;
+										break;
+									}
+									case 'lockedcontents': {
+										$fval += 1 << 10;
+										break;
+									}
+									default: {
+										break;
+									}
+								}
+							}
+						} else {
+							$fval = intval($pl['opt']['f']);
+						}
+					} else {
+						$fval = 4;
+					}
+					if ($this->pdfa_mode) {
+						// force print flag for PDF/A mode
+						$fval |= 4;
+					}
+					$annots .= ' /F '.intval($fval);
+					if (isset($pl['opt']['as']) AND is_string($pl['opt']['as'])) {
+						$annots .= ' /AS /'.$pl['opt']['as'];
+					}
+					if (isset($pl['opt']['ap'])) {
+						// appearance stream
+						$annots .= ' /AP <<';
+						if (is_array($pl['opt']['ap'])) {
+							foreach ($pl['opt']['ap'] as $apmode => $apdef) {
+								// $apmode can be: n = normal; r = rollover; d = down;
+								$annots .= ' /'.strtoupper($apmode);
+								if (is_array($apdef)) {
+									$annots .= ' <<';
+									foreach ($apdef as $apstate => $stream) {
+										// reference to XObject that define the appearance for this mode-state
+										$apsobjid = $this->_putAPXObject($c, $d, $stream);
+										$annots .= ' /'.$apstate.' '.$apsobjid.' 0 R';
+									}
+									$annots .= ' >>';
+								} else {
+									// reference to XObject that define the appearance for this mode
+									$apsobjid = $this->_putAPXObject($c, $d, $apdef);
+									$annots .= ' '.$apsobjid.' 0 R';
+								}
+							}
+						} else {
+							$annots .= $pl['opt']['ap'];
+						}
+						$annots .= ' >>';
+					}
+					if (isset($pl['opt']['bs']) AND (is_array($pl['opt']['bs']))) {
+						$annots .= ' /BS <<';
+						$annots .= ' /Type /Border';
+						if (isset($pl['opt']['bs']['w'])) {
+							$annots .= ' /W '.intval($pl['opt']['bs']['w']);
+						}
+						$bstyles = array('S', 'D', 'B', 'I', 'U');
+						if (isset($pl['opt']['bs']['s']) AND in_array($pl['opt']['bs']['s'], $bstyles)) {
+							$annots .= ' /S /'.$pl['opt']['bs']['s'];
+						}
+						if (isset($pl['opt']['bs']['d']) AND (is_array($pl['opt']['bs']['d']))) {
+							$annots .= ' /D [';
+							foreach ($pl['opt']['bs']['d'] as $cord) {
+								$annots .= ' '.intval($cord);
+							}
+							$annots .= ']';
+						}
+						$annots .= ' >>';
+					} else {
+						$annots .= ' /Border [';
+						if (isset($pl['opt']['border']) AND (count($pl['opt']['border']) >= 3)) {
+							$annots .= intval($pl['opt']['border'][0]).' ';
+							$annots .= intval($pl['opt']['border'][1]).' ';
+							$annots .= intval($pl['opt']['border'][2]);
+							if (isset($pl['opt']['border'][3]) AND is_array($pl['opt']['border'][3])) {
+								$annots .= ' [';
+								foreach ($pl['opt']['border'][3] as $dash) {
+									$annots .= intval($dash).' ';
+								}
+								$annots .= ']';
+							}
+						} else {
+							$annots .= '0 0 0';
+						}
+						$annots .= ']';
+					}
+					if (isset($pl['opt']['be']) AND (is_array($pl['opt']['be']))) {
+						$annots .= ' /BE <<';
+						$bstyles = array('S', 'C');
+						if (isset($pl['opt']['be']['s']) AND in_array($pl['opt']['be']['s'], $bstyles)) {
+							$annots .= ' /S /'.$pl['opt']['bs']['s'];
+						} else {
+							$annots .= ' /S /S';
+						}
+						if (isset($pl['opt']['be']['i']) AND ($pl['opt']['be']['i'] >= 0) AND ($pl['opt']['be']['i'] <= 2)) {
+							$annots .= ' /I '.sprintf(' %F', $pl['opt']['be']['i']);
+						}
+						$annots .= '>>';
+					}
+					if (isset($pl['opt']['c']) AND (is_array($pl['opt']['c'])) AND !empty($pl['opt']['c'])) {
+						$annots .= ' /C '.$this->getColorStringFromArray($pl['opt']['c']);
+					}
+					//$annots .= ' /StructParent ';
+					//$annots .= ' /OC ';
+					$markups = array('text', 'freetext', 'line', 'square', 'circle', 'polygon', 'polyline', 'highlight', 'underline', 'squiggly', 'strikeout', 'stamp', 'caret', 'ink', 'fileattachment', 'sound');
+					if (in_array(strtolower($pl['opt']['subtype']), $markups)) {
+						// this is a markup type
+						if (isset($pl['opt']['t']) AND is_string($pl['opt']['t'])) {
+							$annots .= ' /T '.$this->_textstring($pl['opt']['t'], $annot_obj_id);
+						}
+						//$annots .= ' /Popup ';
+						if (isset($pl['opt']['ca'])) {
+							$annots .= ' /CA '.sprintf('%F', floatval($pl['opt']['ca']));
+						}
+						if (isset($pl['opt']['rc'])) {
+							$annots .= ' /RC '.$this->_textstring($pl['opt']['rc'], $annot_obj_id);
+						}
+						$annots .= ' /CreationDate '.$this->_datestring($annot_obj_id, $this->doc_creation_timestamp);
+						//$annots .= ' /IRT ';
+						if (isset($pl['opt']['subj'])) {
+							$annots .= ' /Subj '.$this->_textstring($pl['opt']['subj'], $annot_obj_id);
+						}
+						//$annots .= ' /RT ';
+						//$annots .= ' /IT ';
+						//$annots .= ' /ExData ';
+					}
+					$lineendings = array('Square', 'Circle', 'Diamond', 'OpenArrow', 'ClosedArrow', 'None', 'Butt', 'ROpenArrow', 'RClosedArrow', 'Slash');
+					// Annotation types
+					switch (strtolower($pl['opt']['subtype'])) {
+						case 'text': {
+							if (isset($pl['opt']['open'])) {
+								$annots .= ' /Open '. (strtolower($pl['opt']['open']) == 'true' ? 'true' : 'false');
+							}
+							$iconsapp = array('Comment', 'Help', 'Insert', 'Key', 'NewParagraph', 'Note', 'Paragraph');
+							if (isset($pl['opt']['name']) AND in_array($pl['opt']['name'], $iconsapp)) {
+								$annots .= ' /Name /'.$pl['opt']['name'];
+							} else {
+								$annots .= ' /Name /Note';
+							}
+							$statemodels = array('Marked', 'Review');
+							if (isset($pl['opt']['statemodel']) AND in_array($pl['opt']['statemodel'], $statemodels)) {
+								$annots .= ' /StateModel /'.$pl['opt']['statemodel'];
+							} else {
+								$pl['opt']['statemodel'] = 'Marked';
+								$annots .= ' /StateModel /'.$pl['opt']['statemodel'];
+							}
+							if ($pl['opt']['statemodel'] == 'Marked') {
+								$states = array('Accepted', 'Unmarked');
+							} else {
+								$states = array('Accepted', 'Rejected', 'Cancelled', 'Completed', 'None');
+							}
+							if (isset($pl['opt']['state']) AND in_array($pl['opt']['state'], $states)) {
+								$annots .= ' /State /'.$pl['opt']['state'];
+							} else {
+								if ($pl['opt']['statemodel'] == 'Marked') {
+									$annots .= ' /State /Unmarked';
+								} else {
+									$annots .= ' /State /None';
+								}
+							}
+							break;
+						}
+						case 'link': {
+							if (is_string($pl['txt'])) {
+								if ($pl['txt'][0] == '#') {
+									// internal destination
+									$annots .= ' /Dest /'.$this->encodeNameObject(substr($pl['txt'], 1));
+								} elseif ($pl['txt'][0] == '%') {
+									// embedded PDF file
+									$filename = basename(substr($pl['txt'], 1));
+									$annots .= ' /A << /S /GoToE /D [0 /Fit] /NewWindow true /T << /R /C /P '.($n - 1).' /A '.$this->embeddedfiles[$filename]['a'].' >> >>';
+								} elseif ($pl['txt'][0] == '*') {
+									// embedded generic file
+									$filename = basename(substr($pl['txt'], 1));
+									$jsa = 'var D=event.target.doc;var MyData=D.dataObjects;for (var i in MyData) if (MyData[i].path=="'.$filename.'") D.exportDataObject( { cName : MyData[i].name, nLaunch : 2});';
+									$annots .= ' /A << /S /JavaScript /JS '.$this->_textstring($jsa, $annot_obj_id).'>>';
+								} else {
+									// external URI link
+									$annots .= ' /A <</S /URI /URI '.$this->_datastring($this->unhtmlentities($pl['txt']), $annot_obj_id).'>>';
+								}
+							} elseif (isset($this->links[$pl['txt']])) {
+								// internal link ID
+								$l = $this->links[$pl['txt']];
+								if (isset($this->page_obj_id[($l[0])])) {
+									$annots .= sprintf(' /Dest [%u 0 R /XYZ 0 %F null]', $this->page_obj_id[($l[0])], ($this->pagedim[$l[0]]['h'] - ($l[1] * $this->k)));
+								}
+							}
+							$hmodes = array('N', 'I', 'O', 'P');
+							if (isset($pl['opt']['h']) AND in_array($pl['opt']['h'], $hmodes)) {
+								$annots .= ' /H /'.$pl['opt']['h'];
+							} else {
+								$annots .= ' /H /I';
+							}
+							//$annots .= ' /PA ';
+							//$annots .= ' /Quadpoints ';
+							break;
+						}
+						case 'freetext': {
+							if (isset($pl['opt']['da']) AND !empty($pl['opt']['da'])) {
+								$annots .= ' /DA ('.$pl['opt']['da'].')';
+							}
+							if (isset($pl['opt']['q']) AND ($pl['opt']['q'] >= 0) AND ($pl['opt']['q'] <= 2)) {
+								$annots .= ' /Q '.intval($pl['opt']['q']);
+							}
+							if (isset($pl['opt']['rc'])) {
+								$annots .= ' /RC '.$this->_textstring($pl['opt']['rc'], $annot_obj_id);
+							}
+							if (isset($pl['opt']['ds'])) {
+								$annots .= ' /DS '.$this->_textstring($pl['opt']['ds'], $annot_obj_id);
+							}
+							if (isset($pl['opt']['cl']) AND is_array($pl['opt']['cl'])) {
+								$annots .= ' /CL [';
+								foreach ($pl['opt']['cl'] as $cl) {
+									$annots .= sprintf('%F ', $cl * $this->k);
+								}
+								$annots .= ']';
+							}
+							$tfit = array('FreeText', 'FreeTextCallout', 'FreeTextTypeWriter');
+							if (isset($pl['opt']['it']) AND in_array($pl['opt']['it'], $tfit)) {
+								$annots .= ' /IT /'.$pl['opt']['it'];
+							}
+							if (isset($pl['opt']['rd']) AND is_array($pl['opt']['rd'])) {
+								$l = $pl['opt']['rd'][0] * $this->k;
+								$r = $pl['opt']['rd'][1] * $this->k;
+								$t = $pl['opt']['rd'][2] * $this->k;
+								$b = $pl['opt']['rd'][3] * $this->k;
+								$annots .= ' /RD ['.sprintf('%F %F %F %F', $l, $r, $t, $b).']';
+							}
+							if (isset($pl['opt']['le']) AND in_array($pl['opt']['le'], $lineendings)) {
+								$annots .= ' /LE /'.$pl['opt']['le'];
+							}
+							break;
+						}
+						case 'line': {
+							break;
+						}
+						case 'square': {
+							break;
+						}
+						case 'circle': {
+							break;
+						}
+						case 'polygon': {
+							break;
+						}
+						case 'polyline': {
+							break;
+						}
+						case 'highlight': {
+							break;
+						}
+						case 'underline': {
+							break;
+						}
+						case 'squiggly': {
+							break;
+						}
+						case 'strikeout': {
+							break;
+						}
+						case 'stamp': {
+							break;
+						}
+						case 'caret': {
+							break;
+						}
+						case 'ink': {
+							break;
+						}
+						case 'popup': {
+							break;
+						}
+						case 'fileattachment': {
+							if ($this->pdfa_mode) {
+								// embedded files are not allowed in PDF/A mode
+								break;
+							}
+							if (!isset($pl['opt']['fs'])) {
+								break;
+							}
+							$filename = basename($pl['opt']['fs']);
+							if (isset($this->embeddedfiles[$filename]['f'])) {
+								$annots .= ' /FS '.$this->embeddedfiles[$filename]['f'].' 0 R';
+								$iconsapp = array('Graph', 'Paperclip', 'PushPin', 'Tag');
+								if (isset($pl['opt']['name']) AND in_array($pl['opt']['name'], $iconsapp)) {
+									$annots .= ' /Name /'.$pl['opt']['name'];
+								} else {
+									$annots .= ' /Name /PushPin';
+								}
+								// index (zero-based) of the annotation in the Annots array of this page
+								$this->embeddedfiles[$filename]['a'] = $key;
+							}
+							break;
+						}
+						case 'sound': {
+							if (!isset($pl['opt']['fs'])) {
+								break;
+							}
+							$filename = basename($pl['opt']['fs']);
+							if (isset($this->embeddedfiles[$filename]['f'])) {
+								// ... TO BE COMPLETED ...
+								// /R /C /B /E /CO /CP
+								$annots .= ' /Sound '.$this->embeddedfiles[$filename]['f'].' 0 R';
+								$iconsapp = array('Speaker', 'Mic');
+								if (isset($pl['opt']['name']) AND in_array($pl['opt']['name'], $iconsapp)) {
+									$annots .= ' /Name /'.$pl['opt']['name'];
+								} else {
+									$annots .= ' /Name /Speaker';
+								}
+							}
+							break;
+						}
+						case 'movie': {
+							break;
+						}
+						case 'widget': {
+							$hmode = array('N', 'I', 'O', 'P', 'T');
+							if (isset($pl['opt']['h']) AND in_array($pl['opt']['h'], $hmode)) {
+								$annots .= ' /H /'.$pl['opt']['h'];
+							}
+							if (isset($pl['opt']['mk']) AND (is_array($pl['opt']['mk'])) AND !empty($pl['opt']['mk'])) {
+								$annots .= ' /MK <<';
+								if (isset($pl['opt']['mk']['r'])) {
+									$annots .= ' /R '.$pl['opt']['mk']['r'];
+								}
+								if (isset($pl['opt']['mk']['bc']) AND (is_array($pl['opt']['mk']['bc']))) {
+									$annots .= ' /BC '.$this->getColorStringFromArray($pl['opt']['mk']['bc']);
+								}
+								if (isset($pl['opt']['mk']['bg']) AND (is_array($pl['opt']['mk']['bg']))) {
+									$annots .= ' /BG '.$this->getColorStringFromArray($pl['opt']['mk']['bg']);
+								}
+								if (isset($pl['opt']['mk']['ca'])) {
+									$annots .= ' /CA '.$pl['opt']['mk']['ca'];
+								}
+								if (isset($pl['opt']['mk']['rc'])) {
+									$annots .= ' /RC '.$pl['opt']['mk']['rc'];
+								}
+								if (isset($pl['opt']['mk']['ac'])) {
+									$annots .= ' /AC '.$pl['opt']['mk']['ac'];
+								}
+								if (isset($pl['opt']['mk']['i'])) {
+									$info = $this->getImageBuffer($pl['opt']['mk']['i']);
+									if ($info !== false) {
+										$annots .= ' /I '.$info['n'].' 0 R';
+									}
+								}
+								if (isset($pl['opt']['mk']['ri'])) {
+									$info = $this->getImageBuffer($pl['opt']['mk']['ri']);
+									if ($info !== false) {
+										$annots .= ' /RI '.$info['n'].' 0 R';
+									}
+								}
+								if (isset($pl['opt']['mk']['ix'])) {
+									$info = $this->getImageBuffer($pl['opt']['mk']['ix']);
+									if ($info !== false) {
+										$annots .= ' /IX '.$info['n'].' 0 R';
+									}
+								}
+								if (isset($pl['opt']['mk']['if']) AND (is_array($pl['opt']['mk']['if'])) AND !empty($pl['opt']['mk']['if'])) {
+									$annots .= ' /IF <<';
+									$if_sw = array('A', 'B', 'S', 'N');
+									if (isset($pl['opt']['mk']['if']['sw']) AND in_array($pl['opt']['mk']['if']['sw'], $if_sw)) {
+										$annots .= ' /SW /'.$pl['opt']['mk']['if']['sw'];
+									}
+									$if_s = array('A', 'P');
+									if (isset($pl['opt']['mk']['if']['s']) AND in_array($pl['opt']['mk']['if']['s'], $if_s)) {
+										$annots .= ' /S /'.$pl['opt']['mk']['if']['s'];
+									}
+									if (isset($pl['opt']['mk']['if']['a']) AND (is_array($pl['opt']['mk']['if']['a'])) AND !empty($pl['opt']['mk']['if']['a'])) {
+										$annots .= sprintf(' /A [%F %F]', $pl['opt']['mk']['if']['a'][0], $pl['opt']['mk']['if']['a'][1]);
+									}
+									if (isset($pl['opt']['mk']['if']['fb']) AND ($pl['opt']['mk']['if']['fb'])) {
+										$annots .= ' /FB true';
+									}
+									$annots .= '>>';
+								}
+								if (isset($pl['opt']['mk']['tp']) AND ($pl['opt']['mk']['tp'] >= 0) AND ($pl['opt']['mk']['tp'] <= 6)) {
+									$annots .= ' /TP '.intval($pl['opt']['mk']['tp']);
+								}
+								$annots .= '>>';
+							} // end MK
+							// --- Entries for field dictionaries ---
+							if (isset($this->radiobutton_groups[$n][$pl['txt']])) {
+								// set parent
+								$annots .= ' /Parent '.$this->radiobutton_groups[$n][$pl['txt']].' 0 R';
+							}
+							if (isset($pl['opt']['t']) AND is_string($pl['opt']['t'])) {
+								$annots .= ' /T '.$this->_datastring($pl['opt']['t'], $annot_obj_id);
+							}
+							if (isset($pl['opt']['tu']) AND is_string($pl['opt']['tu'])) {
+								$annots .= ' /TU '.$this->_datastring($pl['opt']['tu'], $annot_obj_id);
+							}
+							if (isset($pl['opt']['tm']) AND is_string($pl['opt']['tm'])) {
+								$annots .= ' /TM '.$this->_datastring($pl['opt']['tm'], $annot_obj_id);
+							}
+							if (isset($pl['opt']['ff'])) {
+								if (is_array($pl['opt']['ff'])) {
+									// array of bit settings
+									$flag = 0;
+									foreach($pl['opt']['ff'] as $val) {
+										$flag += 1 << ($val - 1);
+									}
+								} else {
+									$flag = intval($pl['opt']['ff']);
+								}
+								$annots .= ' /Ff '.$flag;
+							}
+							if (isset($pl['opt']['maxlen'])) {
+								$annots .= ' /MaxLen '.intval($pl['opt']['maxlen']);
+							}
+							if (isset($pl['opt']['v'])) {
+								$annots .= ' /V';
+								if (is_array($pl['opt']['v'])) {
+									foreach ($pl['opt']['v'] AS $optval) {
+										if (is_float($optval)) {
+											$optval = sprintf('%F', $optval);
+										}
+										$annots .= ' '.$optval;
+									}
+								} else {
+									$annots .= ' '.$this->_textstring($pl['opt']['v'], $annot_obj_id);
+								}
+							}
+							if (isset($pl['opt']['dv'])) {
+								$annots .= ' /DV';
+								if (is_array($pl['opt']['dv'])) {
+									foreach ($pl['opt']['dv'] AS $optval) {
+										if (is_float($optval)) {
+											$optval = sprintf('%F', $optval);
+										}
+										$annots .= ' '.$optval;
+									}
+								} else {
+									$annots .= ' '.$this->_textstring($pl['opt']['dv'], $annot_obj_id);
+								}
+							}
+							if (isset($pl['opt']['rv'])) {
+								$annots .= ' /RV';
+								if (is_array($pl['opt']['rv'])) {
+									foreach ($pl['opt']['rv'] AS $optval) {
+										if (is_float($optval)) {
+											$optval = sprintf('%F', $optval);
+										}
+										$annots .= ' '.$optval;
+									}
+								} else {
+									$annots .= ' '.$this->_textstring($pl['opt']['rv'], $annot_obj_id);
+								}
+							}
+							if (isset($pl['opt']['a']) AND !empty($pl['opt']['a'])) {
+								$annots .= ' /A << '.$pl['opt']['a'].' >>';
+							}
+							if (isset($pl['opt']['aa']) AND !empty($pl['opt']['aa'])) {
+								$annots .= ' /AA << '.$pl['opt']['aa'].' >>';
+							}
+							if (isset($pl['opt']['da']) AND !empty($pl['opt']['da'])) {
+								$annots .= ' /DA ('.$pl['opt']['da'].')';
+							}
+							if (isset($pl['opt']['q']) AND ($pl['opt']['q'] >= 0) AND ($pl['opt']['q'] <= 2)) {
+								$annots .= ' /Q '.intval($pl['opt']['q']);
+							}
+							if (isset($pl['opt']['opt']) AND (is_array($pl['opt']['opt'])) AND !empty($pl['opt']['opt'])) {
+								$annots .= ' /Opt [';
+								foreach($pl['opt']['opt'] AS $copt) {
+									if (is_array($copt)) {
+										$annots .= ' ['.$this->_textstring($copt[0], $annot_obj_id).' '.$this->_textstring($copt[1], $annot_obj_id).']';
+									} else {
+										$annots .= ' '.$this->_textstring($copt, $annot_obj_id);
+									}
+								}
+								$annots .= ']';
+							}
+							if (isset($pl['opt']['ti'])) {
+								$annots .= ' /TI '.intval($pl['opt']['ti']);
+							}
+							if (isset($pl['opt']['i']) AND (is_array($pl['opt']['i'])) AND !empty($pl['opt']['i'])) {
+								$annots .= ' /I [';
+								foreach($pl['opt']['i'] AS $copt) {
+									$annots .= intval($copt).' ';
+								}
+								$annots .= ']';
+							}
+							break;
+						}
+						case 'screen': {
+							break;
+						}
+						case 'printermark': {
+							break;
+						}
+						case 'trapnet': {
+							break;
+						}
+						case 'watermark': {
+							break;
+						}
+						case '3d': {
+							break;
+						}
+						default: {
+							break;
+						}
+					}
+					$annots .= '>>';
+					// create new annotation object
+					$this->_out($this->_getobj($annot_obj_id)."\n".$annots."\n".'endobj');
+					if ($formfield AND !isset($this->radiobutton_groups[$n][$pl['txt']])) {
+						// store reference of form object
+						$this->form_obj_id[] = $annot_obj_id;
+					}
+				}
+			}
+		} // end for each page
+	}
+
+	/**
+	 * Put appearance streams XObject used to define annotation's appearance states.
+	 * @param $w (int) annotation width
+	 * @param $h (int) annotation height
+	 * @param $stream (string) appearance stream
+	 * @return int object ID
+	 * @protected
+	 * @since 4.8.001 (2009-09-09)
+	 */
+	protected function _putAPXObject($w=0, $h=0, $stream='') {
+		$stream = trim($stream);
+		$out = $this->_getobj()."\n";
+		$this->xobjects['AX'.$this->n] = array('n' => $this->n);
+		$out .= '<<';
+		$out .= ' /Type /XObject';
+		$out .= ' /Subtype /Form';
+		$out .= ' /FormType 1';
+		if ($this->compress) {
+			$stream = gzcompress($stream);
+			$out .= ' /Filter /FlateDecode';
+		}
+		$rect = sprintf('%F %F', $w, $h);
+		$out .= ' /BBox [0 0 '.$rect.']';
+		$out .= ' /Matrix [1 0 0 1 0 0]';
+		$out .= ' /Resources 2 0 R';
+		$stream = $this->_getrawstream($stream);
+		$out .= ' /Length '.strlen($stream);
+		$out .= ' >>';
+		$out .= ' stream'."\n".$stream."\n".'endstream';
+		$out .= "\n".'endobj';
+		$this->_out($out);
+		return $this->n;
+	}
+
+	/**
+	 * Get ULONG from string (Big Endian 32-bit unsigned integer).
+	 * @param $str (string) string from where to extract value
+	 * @param $offset (int) point from where to read the data
+	 * @return int 32 bit value
+	 * @author Nicola Asuni
+	 * @protected
+	 * @since 5.2.000 (2010-06-02)
+	 */
+	protected function _getULONG($str, $offset) {
+		$v = unpack('Ni', substr($str, $offset, 4));
+		return $v['i'];
+	}
+
+	/**
+	 * Get USHORT from string (Big Endian 16-bit unsigned integer).
+	 * @param $str (string) string from where to extract value
+	 * @param $offset (int) point from where to read the data
+	 * @return int 16 bit value
+	 * @author Nicola Asuni
+	 * @protected
+	 * @since 5.2.000 (2010-06-02)
+	 */
+	protected function _getUSHORT($str, $offset) {
+		$v = unpack('ni', substr($str, $offset, 2));
+		return $v['i'];
+	}
+
+	/**
+	 * Get SHORT from string (Big Endian 16-bit signed integer).
+	 * @param $str (string) String from where to extract value.
+	 * @param $offset (int) Point from where to read the data.
+	 * @return int 16 bit value
+	 * @author Nicola Asuni
+	 * @protected
+	 * @since 5.2.000 (2010-06-02)
+	 */
+	protected function _getSHORT($str, $offset) {
+		$v = unpack('si', substr($str, $offset, 2));
+		return $v['i'];
+	}
+
+	/**
+	 * Get FWORD from string (Big Endian 16-bit signed integer).
+	 * @param $str (string) String from where to extract value.
+	 * @param $offset (int) Point from where to read the data.
+	 * @return int 16 bit value
+	 * @author Nicola Asuni
+	 * @protected
+	 * @since 5.9.123 (2011-09-30)
+	 */
+	protected function _getFWORD($str, $offset) {
+		$v = $this->_getUSHORT($str, $offset);
+		if ($v > 0x7fff) {
+			$v -= 0x10000;
+		}
+		return $v;
+	}
+
+	/**
+	 * Get UFWORD from string (Big Endian 16-bit unsigned integer).
+	 * @param $str (string) string from where to extract value
+	 * @param $offset (int) point from where to read the data
+	 * @return int 16 bit value
+	 * @author Nicola Asuni
+	 * @protected
+	 * @since 5.9.123 (2011-09-30)
+	 */
+	protected function _getUFWORD($str, $offset) {
+		$v = $this->_getUSHORT($str, $offset);
+		return $v;
+	}
+
+	/**
+	 * Get FIXED from string (32-bit signed fixed-point number (16.16).
+	 * @param $str (string) string from where to extract value
+	 * @param $offset (int) point from where to read the data
+	 * @return int 16 bit value
+	 * @author Nicola Asuni
+	 * @protected
+	 * @since 5.9.123 (2011-09-30)
+	 */
+	protected function _getFIXED($str, $offset) {
+		// mantissa
+		$m = $this->_getFWORD($str, $offset);
+		// fraction
+		$f = $this->_getUSHORT($str, ($offset + 2));
+		$v = floatval(''.$m.'.'.$f.'');
+		return $v;
+	}
+
+	/**
+	 * Get BYTE from string (8-bit unsigned integer).
+	 * @param $str (string) String from where to extract value.
+	 * @param $offset (int) Point from where to read the data.
+	 * @return int 8 bit value
+	 * @author Nicola Asuni
+	 * @protected
+	 * @since 5.2.000 (2010-06-02)
+	 */
+	protected function _getBYTE($str, $offset) {
+		$v = unpack('Ci', substr($str, $offset, 1));
+		return $v['i'];
+	}
+	/**
+	 * Update the CIDToGIDMap string with a new value.
+	 * @param $map (string) CIDToGIDMap.
+	 * @param $cid (int) CID value.
+	 * @param $gid (int) GID value.
+	 * @return (string) CIDToGIDMap.
+	 * @author Nicola Asuni
+	 * @protected
+	 * @since 5.9.123 (2011-09-29)
+	 */
+	protected function updateCIDtoGIDmap($map, $cid, $gid) {
+		if (($cid >= 0) AND ($cid <= 0xFFFF) AND ($gid >= 0)) {
+			if ($gid > 0xFFFF) {
+				$gid -= 0x10000;
+			}
+			$map[($cid * 2)] = chr($gid >> 8);
+			$map[(($cid * 2) + 1)] = chr($gid & 0xFF);
+		}
+		return $map;
+	}
+
+	/**
+	 * Convert and add the selected TrueType or Type1 font to the fonts folder (that must be writeable).
+	 * @param $fontfile (string) Font file (full path).
+	 * @param $fonttype (string) Font type. Leave empty for autodetect mode. Valid values are: TrueTypeUnicode, TrueType, Type1, CID0JP = CID-0 Japanese, CID0KR = CID-0 Korean, CID0CS = CID-0 Chinese Simplified, CID0CT = CID-0 Chinese Traditional.
+	 * @param $enc (string) Name of the encoding table to use. Leave empty for default mode. Omit this parameter for TrueType Unicode and symbolic fonts like Symbol or ZapfDingBats.
+	 * @param $flags (int) Unsigned 32-bit integer containing flags specifying various characteristics of the font (PDF32000:2008 - 9.8.2 Font Descriptor Flags): +1 for fixed font; +4 for symbol or +32 for non-symbol; +64 for italic. Fixed and Italic mode are generally autodetected so you have to set it to 32 = non-symbolic font (default) or 4 = symbolic font.
+	 * @param $outpath (string) Output path for generated font files (must be writeable by the web server). Leave empty for default font folder.
+	 * @param $platid (int) Platform ID for CMAP table to extract (when building a Unicode font for Windows this value should be 3, for Macintosh should be 1).
+	 * @param $encid (int) Encoding ID for CMAP table to extract (when building a Unicode font for Windows this value should be 1, for Macintosh should be 0). When Platform ID is 3, legal values for Encoding ID are: 0=Symbol, 1=Unicode, 2=ShiftJIS, 3=PRC, 4=Big5, 5=Wansung, 6=Johab, 7=Reserved, 8=Reserved, 9=Reserved, 10=UCS-4.
+	 * @param $addcbbox (boolean) If true includes the character bounding box information on the php font file.
+	 * @return (string) TCPDF font name.
+	 * @author Nicola Asuni
+	 * @public
+	 * @since 5.9.123 (2010-09-30)
+	 */
+	public function addTTFfont($fontfile, $fonttype='', $enc='', $flags=32, $outpath='', $platid=3, $encid=1, $addcbbox=false) {
+		if (!file_exists($fontfile)) {
+			$this->Error('Could not find file: '.$fontfile.'');
+		}
+		// font metrics
+		$fmetric = array();
+		// build new font name for TCPDF compatibility
+		$font_path_parts = pathinfo($fontfile);
+		if (!isset($font_path_parts['filename'])) {
+			$font_path_parts['filename'] = substr($font_path_parts['basename'], 0, -(strlen($font_path_parts['extension']) + 1));
+		}
+		$font_name = strtolower($font_path_parts['filename']);
+		$font_name = preg_replace('/[^a-z0-9_]/', '', $font_name);
+		$search  = array('bold', 'oblique', 'italic', 'regular');
+		$replace = array('b', 'i', 'i', '');
+		$font_name = str_replace($search, $replace, $font_name);
+		if (empty($font_name)) {
+			// set generic name
+			$font_name = 'tcpdffont';
+		}
+		// set output path
+		if (empty($outpath)) {
+			$outpath = $this->_getfontpath();
+		}
+		// check if this font already exist
+		if (file_exists($outpath.$font_name.'.php')) {
+			// this font already exist (delete it from fonts folder to rebuild it)
+			return $font_name;
+		}
+		$fmetric['file'] = $font_name.'.z';
+		$fmetric['ctg'] = $font_name.'.ctg.z';
+		// get font data
+		$font = file_get_contents($fontfile);
+		$fmetric['originalsize'] = strlen($font);
+		// autodetect font type
+		if (empty($fonttype)) {
+			if ($this->_getULONG($font, 0) == 0x10000) {
+				// True Type (Unicode or not)
+				$fonttype = 'TrueTypeUnicode';
+			} elseif (substr($font, 0, 4) == 'OTTO') {
+				// Open Type (Unicode or not)
+				$this->Error('Unsupported font format: OpenType with CFF data.');
+			} else {
+				// Type 1
+				$fonttype = 'Type1';
+			}
+		}
+		// set font type
+		switch ($fonttype) {
+			case 'CID0CT':
+			case 'CID0CS':
+			case 'CID0KR':
+			case 'CID0JP': {
+				$fmetric['type'] = 'cidfont0';
+				break;
+			}
+			case 'Type1': {
+				$fmetric['type'] = 'Type1';
+				if (empty($enc) AND (($flags & 4) == 0)) {
+					$enc = 'cp1252';
+				}
+				break;
+			}
+			case 'TrueType': {
+				$fmetric['type'] = 'TrueType';
+				break;
+			}
+			case 'TrueTypeUnicode':
+			default: {
+				$fmetric['type'] = 'TrueTypeUnicode';
+				break;
+			}
+		}
+		// set encoding maps (if any)
+		$fmetric['enc'] = preg_replace('/[^A-Za-z0-9_\-]/', '', $enc);
+		$fmetric['diff'] = '';
+		if (($fmetric['type'] == 'TrueType') OR ($fmetric['type'] == 'Type1')) {
+			if (!empty($enc) AND ($enc != 'cp1252') AND isset($this->encmaps->encmap[$enc])) {
+				// build differences from reference encoding
+				$enc_ref = $this->encmaps->encmap['cp1252'];
+				$enc_target = $this->encmaps->encmap[$enc];
+				$last = 0;
+				for ($i = 32; $i <= 255; ++$i) {
+					if ($enc_target != $enc_ref[$i]) {
+						if ($i != ($last + 1)) {
+							$fmetric['diff'] .= $i.' ';
+						}
+						$last = $i;
+						$fmetric['diff'] .= '/'.$enc_target[$i].' ';
+					}
+				}
+			}
+		}
+		// parse the font by type
+		if ($fmetric['type'] == 'Type1') {
+			// ---------- TYPE 1 ----------
+			// read first segment
+			$a = unpack('Cmarker/Ctype/Vsize', substr($font, 0, 6));
+			if ($a['marker'] != 128) {
+				$this->Error('Font file is not a valid binary Type1');
+			}
+			$fmetric['size1'] = $a['size'];
+			$data = substr($font, 6, $fmetric['size1']);
+			// read second segment
+			$a = unpack('Cmarker/Ctype/Vsize', substr($font, (6 + $fmetric['size1']), 6));
+			if ($a['marker'] != 128) {
+				$this->Error('Font file is not a valid binary Type1');
+			}
+			$fmetric['size2'] = $a['size'];
+			$encrypted = substr($font, (12 + $fmetric['size1']), $fmetric['size2']);
+			$data .= $encrypted;
+			// store compressed font
+			$fp = fopen($outpath.$fmetric['file'], 'wb');
+			fwrite($fp, gzcompress($data));
+			fclose($fp);
+			// get font info
+			$fmetric['Flags'] = $flags;
+			preg_match ('#/FullName[\s]*\(([^\)]*)#', $font, $matches);
+			$fmetric['name'] = preg_replace('/[^a-zA-Z0-9_\-]/', '', $matches[1]);
+			preg_match('#/FontBBox[\s]*{([^}]*)#', $font, $matches);
+			$fmetric['bbox'] = trim($matches[1]);
+			$bv = explode(' ', $fmetric['bbox']);
+			$fmetric['Ascent'] = intval($bv[3]);
+			$fmetric['Descent'] = intval($bv[1]);
+			preg_match('#/ItalicAngle[\s]*([0-9\+\-]*)#', $font, $matches);
+			$fmetric['italicAngle'] = intval($matches[1]);
+			if ($fmetric['italicAngle'] != 0) {
+				$fmetric['Flags'] |= 64;
+			}
+			preg_match('#/UnderlinePosition[\s]*([0-9\+\-]*)#', $font, $matches);
+			$fmetric['underlinePosition'] = intval($matches[1]);
+			preg_match('#/UnderlineThickness[\s]*([0-9\+\-]*)#', $font, $matches);
+			$fmetric['underlineThickness'] = intval($matches[1]);
+			preg_match('#/isFixedPitch[\s]*([^\s]*)#', $font, $matches);
+			if ($matches[1] == 'true') {
+				$fmetric['Flags'] |= 1;
+			}
+			// get internal map
+			$imap = array();
+			if (preg_match_all('#dup[\s]([0-9]+)[\s]*/([^\s]*)[\s]put#sU', $font, $fmap, PREG_SET_ORDER) > 0) {
+				foreach ($fmap as $v) {
+					$imap[$v[2]] = $v[1];
+				}
+			}
+			// decrypt eexec encrypted part
+			$r = 55665; // eexec encryption constant
+			$c1 = 52845;
+			$c2 = 22719;
+			$elen = strlen($encrypted);
+			$eplain = '';
+			for ($i = 0; $i < $elen; ++$i) {
+				$chr = ord($encrypted[$i]);
+				$eplain .= chr($chr ^ ($r >> 8));
+				$r = ((($chr + $r) * $c1 + $c2) % 65536);
+			}
+			if (preg_match('#/ForceBold[\s]*([^\s]*)#', $eplain, $matches) > 0) {
+				if ($matches[1] == 'true') {
+					$fmetric['Flags'] |= 0x40000;
+				}
+			}
+			if (preg_match('#/StdVW[\s]*\[([^\]]*)#', $eplain, $matches) > 0) {
+				$fmetric['StemV'] = intval($matches[1]);
+			} else {
+				$fmetric['StemV'] = 70;
+			}
+			if (preg_match('#/StdHW[\s]*\[([^\]]*)#', $eplain, $matches) > 0) {
+				$fmetric['StemH'] = intval($matches[1]);
+			} else {
+				$fmetric['StemH'] = 30;
+			}
+			if (preg_match('#/BlueValues[\s]*\[([^\]]*)#', $eplain, $matches) > 0) {
+				$bv = explode(' ', $matches[1]);
+				if (count($bv) >= 6) {
+					$v1 = intval($bv[2]);
+					$v2 = intval($bv[4]);
+					if ($v1 <= $v2) {
+						$fmetric['XHeight'] = $v1;
+						$fmetric['CapHeight'] = $v2;
+					} else {
+						$fmetric['XHeight'] = $v2;
+						$fmetric['CapHeight'] = $v1;
+					}
+				} else {
+					$fmetric['XHeight'] = 450;
+					$fmetric['CapHeight'] = 700;
+				}
+			} else {
+				$fmetric['XHeight'] = 450;
+				$fmetric['CapHeight'] = 700;
+			}
+			// get the number of random bytes at the beginning of charstrings
+			if (preg_match('#/lenIV[\s]*([0-9]*)#', $eplain, $matches) > 0) {
+				$lenIV = intval($matches[1]);
+			} else {
+				$lenIV = 4;
+			}
+			$fmetric['Leading'] = 0;
+			// get charstring data
+			$eplain = substr($eplain, (strpos($eplain, '/CharStrings') + 1));
+			preg_match_all('#/([A-Za-z0-9\.]*)[\s][0-9]+[\s]RD[\s](.*)[\s]ND#sU', $eplain, $matches, PREG_SET_ORDER);
+			if (!empty($enc) AND isset($this->encmaps->encmap[$enc])) {
+				$enc_map = $this->encmaps->encmap[$enc];
+			} else {
+				$enc_map = false;
+			}
+			$fmetric['cw'] = '';
+			$fmetric['MaxWidth'] = 0;
+			$cwidths = array();
+			foreach ($matches as $k => $v) {
+				$cid = 0;
+				if (isset($imap[$v[1]])) {
+					$cid = $imap[$v[1]];
+				} elseif ($enc_map !== false) {
+					$cid = array_search($v[1], $enc_map);
+					if ($cid === false) {
+						$cid = 0;
+					} elseif ($cid > 1000) {
+						$cid -= 1000;
+					}
+				}
+				// decrypt charstring encrypted part
+				$r = 4330; // charstring encryption constant
+				$c1 = 52845;
+				$c2 = 22719;
+				$cd = $v[2];
+				$clen = strlen($cd);
+				$ccom = array();
+				for ($i = 0; $i < $clen; ++$i) {
+					$chr = ord($cd[$i]);
+					$ccom[] = ($chr ^ ($r >> 8));
+					$r = ((($chr + $r) * $c1 + $c2) % 65536);
+				}
+				// decode numbers
+				$cdec = array();
+				$ck = 0;
+				$i = $lenIV;
+				while ($i < $clen) {
+					if ($ccom[$i] < 32) {
+						$cdec[$ck] = $ccom[$i];
+						if (($ck > 0) AND ($cdec[$ck] == 13)) {
+							// hsbw command: update width
+							$cwidths[$cid] = $cdec[($ck - 1)];
+						}
+						++$i;
+					} elseif (($ccom[$i] >= 32) AND ($ccom[$i] <= 246)) {
+						$cdec[$ck] = ($ccom[$i] - 139);
+						++$i;
+					} elseif (($ccom[$i] >= 247) AND ($ccom[$i] <= 250)) {
+						$cdec[$ck] = ((($ccom[$i] - 247) * 256) + $ccom[($i + 1)] + 108);
+						$i += 2;
+					} elseif (($ccom[$i] >= 251) AND ($ccom[$i] <= 254)) {
+						$cdec[$ck] = ((-($ccom[$i] - 251) * 256) - $ccom[($i + 1)] - 108);
+						$i += 2;
+					} elseif ($ccom[$i] == 255) {
+						$sval = chr($ccom[($i + 1)]).chr($ccom[($i + 2)]).chr($ccom[($i + 3)]).chr($ccom[($i + 4)]);
+						$vsval = unpack('li', $sval);
+						$cdec[$ck] = $vsval['i'];
+						$i += 5;
+					}
+					++$ck;
+				}
+			} // end for each matches
+			$fmetric['MissingWidth'] = $cwidths[0];
+			$fmetric['MaxWidth'] = $fmetric['MissingWidth'];
+			$fmetric['AvgWidth'] = 0;
+			// set chars widths
+			for ($cid = 0; $cid <= 255; ++$cid) {
+				if (isset($cwidths[$cid])) {
+					if ($cwidths[$cid] > $fmetric['MaxWidth']) {
+						$fmetric['MaxWidth'] = $cwidths[$cid];
+					}
+					$fmetric['AvgWidth'] += $cwidths[$cid];
+					$fmetric['cw'] .= ','.$cid.'=>'.$cwidths[$cid];
+				} else {
+					$fmetric['cw'] .= ','.$cid.'=>'.$fmetric['MissingWidth'];
+				}
+			}
+			$fmetric['AvgWidth'] = round($fmetric['AvgWidth'] / count($cwidths));
+		} else {
+			// ---------- TRUE TYPE ----------
+			if ($fmetric['type'] != 'cidfont0') {
+				// store compressed font
+				$fp = fopen($outpath.$fmetric['file'], 'wb');
+				fwrite($fp, gzcompress($font));
+				fclose($fp);
+			}
+			$offset = 0; // offset position of the font data
+			if ($this->_getULONG($font, $offset) != 0x10000) {
+				// sfnt version must be 0x00010000 for TrueType version 1.0.
+				return $font;
+			}
+			$offset += 4;
+			// get number of tables
+			$numTables = $this->_getUSHORT($font, $offset);
+			$offset += 2;
+			// skip searchRange, entrySelector and rangeShift
+			$offset += 6;
+			// tables array
+			$table = array();
+			// ---------- get tables ----------
+			for ($i = 0; $i < $numTables; ++$i) {
+				// get table info
+				$tag = substr($font, $offset, 4);
+				$offset += 4;
+				$table[$tag] = array();
+				$table[$tag]['checkSum'] = $this->_getULONG($font, $offset);
+				$offset += 4;
+				$table[$tag]['offset'] = $this->_getULONG($font, $offset);
+				$offset += 4;
+				$table[$tag]['length'] = $this->_getULONG($font, $offset);
+				$offset += 4;
+			}
+			// check magicNumber
+			$offset = $table['head']['offset'] + 12;
+			if ($this->_getULONG($font, $offset) != 0x5F0F3CF5) {
+				// magicNumber must be 0x5F0F3CF5
+				return $font;
+			}
+			$offset += 4;
+			$offset += 2; // skip flags
+			// get FUnits
+			$fmetric['unitsPerEm'] = $this->_getUSHORT($font, $offset);
+			$offset += 2;
+			// units ratio constant
+			$urk = (1000 / $fmetric['unitsPerEm']);
+			$offset += 16; // skip created, modified
+			$xMin = round($this->_getFWORD($font, $offset) * $urk);
+			$offset += 2;
+			$yMin = round($this->_getFWORD($font, $offset) * $urk);
+			$offset += 2;
+			$xMax = round($this->_getFWORD($font, $offset) * $urk);
+			$offset += 2;
+			$yMax = round($this->_getFWORD($font, $offset) * $urk);
+			$offset += 2;
+			$fmetric['bbox'] = ''.$xMin.' '.$yMin.' '.$xMax.' '.$yMax.'';
+			$macStyle = $this->_getUSHORT($font, $offset);
+			$offset += 2;
+			// PDF font flags
+			$fmetric['Flags'] = $flags;
+			if (($macStyle & 2) == 2) {
+				// italic flag
+				$fmetric['Flags'] |= 64;
+			}
+			// get offset mode (indexToLocFormat : 0 = short, 1 = long)
+			$offset = $table['head']['offset'] + 50;
+			$short_offset = ($this->_getSHORT($font, $offset) == 0);
+			$offset += 2;
+			// get the offsets to the locations of the glyphs in the font, relative to the beginning of the glyphData table
+			$indexToLoc = array();
+			$offset = $table['loca']['offset'];
+			if ($short_offset) {
+				// short version
+				$tot_num_glyphs = ($table['loca']['length'] / 2); // numGlyphs + 1
+				for ($i = 0; $i < $tot_num_glyphs; ++$i) {
+					$indexToLoc[$i] = $this->_getUSHORT($font, $offset) * 2;
+					$offset += 2;
+				}
+			} else {
+				// long version
+				$tot_num_glyphs = ($table['loca']['length'] / 4); // numGlyphs + 1
+				for ($i = 0; $i < $tot_num_glyphs; ++$i) {
+					$indexToLoc[$i] = $this->_getULONG($font, $offset);
+					$offset += 4;
+				}
+			}
+			// get glyphs indexes of chars from cmap table
+			$offset = $table['cmap']['offset'] + 2;
+			$numEncodingTables = $this->_getUSHORT($font, $offset);
+			$offset += 2;
+			$encodingTables = array();
+			for ($i = 0; $i < $numEncodingTables; ++$i) {
+				$encodingTables[$i]['platformID'] = $this->_getUSHORT($font, $offset);
+				$offset += 2;
+				$encodingTables[$i]['encodingID'] = $this->_getUSHORT($font, $offset);
+				$offset += 2;
+				$encodingTables[$i]['offset'] = $this->_getULONG($font, $offset);
+				$offset += 4;
+			}
+			// ---------- get os/2 metrics ----------
+			$offset = $table['OS/2']['offset'];
+			$offset += 2; // skip version
+			// xAvgCharWidth
+			$fmetric['AvgWidth'] = round($this->_getFWORD($font, $offset) * $urk);
+			$offset += 2;
+			// usWeightClass
+			$usWeightClass = round($this->_getUFWORD($font, $offset) * $urk);
+			// estimate StemV and StemH (400 = usWeightClass for Normal - Regular font)
+			$fmetric['StemV'] = round((70 * $usWeightClass) / 400);
+			$fmetric['StemH'] = round((30 * $usWeightClass) / 400);
+			$offset += 2;
+			$offset += 2; // usWidthClass
+			$fsType = $this->_getSHORT($font, $offset);
+			$offset += 2;
+			if ($fsType == 2) {
+				$this->Error('This Font cannot be modified, embedded or exchanged in any manner without first obtaining permission of the legal owner.');
+			}
+			// ---------- get font name ----------
+			$fmetric['name'] = '';
+			$offset = $table['name']['offset'];
+			$offset += 2; // skip Format selector (=0).
+			// Number of NameRecords that follow n.
+			$numNameRecords = $this->_getUSHORT($font, $offset);
+			$offset += 2;
+			// Offset to start of string storage (from start of table).
+			$stringStorageOffset = $this->_getUSHORT($font, $offset);
+			$offset += 2;
+			for ($i = 0; $i < $numNameRecords; ++$i) {
+				$offset += 6; // skip Platform ID, Platform-specific encoding ID, Language ID.
+				// Name ID.
+				$nameID = $this->_getUSHORT($font, $offset);
+				$offset += 2;
+				if ($nameID == 6) {
+					// String length (in bytes).
+					$stringLength = $this->_getUSHORT($font, $offset);
+					$offset += 2;
+					// String offset from start of storage area (in bytes).
+					$stringOffset = $this->_getUSHORT($font, $offset);
+					$offset += 2;
+					$offset = ($table['name']['offset'] + $stringStorageOffset + $stringOffset);
+					$fmetric['name'] = substr($font, $offset, $stringLength);
+					$fmetric['name'] = preg_replace('/[^a-zA-Z0-9_\-]/', '', $fmetric['name']);
+					break;
+				} else {
+					$offset += 4; // skip String length, String offset
+				}
+			}
+			if (empty($fmetric['name'])) {
+				$fmetric['name'] = $font_name;
+			}
+			// ---------- get post data ----------
+			$offset = $table['post']['offset'];
+			$offset += 4; // skip Format Type
+			$fmetric['italicAngle'] = $this->_getFIXED($font, $offset);
+			$offset += 4;
+			$fmetric['underlinePosition'] = round($this->_getFWORD($font, $offset) * $urk);
+			$offset += 2;
+			$fmetric['underlineThickness'] = round($this->_getFWORD($font, $offset) * $urk);
+			$offset += 2;
+			$isFixedPitch = ($this->_getULONG($font, $offset) == 0) ? false : true;
+			$offset += 2;
+			if ($isFixedPitch) {
+				$fmetric['Flags'] |= 1;
+			}
+			// ---------- get hhea data ----------
+			$offset = $table['hhea']['offset'];
+			$offset += 4; // skip Table version number
+			// Ascender
+			$fmetric['Ascent'] = round($this->_getFWORD($font, $offset) * $urk);
+			$offset += 2;
+			// Descender
+			$fmetric['Descent'] = round($this->_getFWORD($font, $offset) * $urk);
+			$offset += 2;
+			// LineGap
+			$fmetric['Leading'] = round($this->_getFWORD($font, $offset) * $urk);
+			$offset += 2;
+			// advanceWidthMax
+			$fmetric['MaxWidth'] = round($this->_getUFWORD($font, $offset) * $urk);
+			$offset += 2;
+			$offset += 22; // skip some values
+			// get the number of hMetric entries in hmtx table
+			$numberOfHMetrics = $this->_getUSHORT($font, $offset);
+			// ---------- get maxp data ----------
+			$offset = $table['maxp']['offset'];
+			$offset += 4; // skip Table version number
+			// get the the number of glyphs in the font.
+			$numGlyphs = $this->_getUSHORT($font, $offset);
+			// ---------- get CIDToGIDMap ----------
+			$ctg = array();
+			foreach ($encodingTables as $enctable) {
+				// get only specified Platform ID and Encoding ID
+				if (($enctable['platformID'] == $platid) AND ($enctable['encodingID'] == $encid)) {
+					$offset = $table['cmap']['offset'] + $enctable['offset'];
+					$format = $this->_getUSHORT($font, $offset);
+					$offset += 2;
+					switch ($format) {
+						case 0: { // Format 0: Byte encoding table
+							$offset += 4; // skip length and version/language
+							for ($c = 0; $c < 256; ++$c) {
+								$g = $this->_getBYTE($font, $offset);
+								$ctg[$c] = $g;
+								++$offset;
+							}
+							break;
+						}
+						case 2: { // Format 2: High-byte mapping through table
+							$offset += 4; // skip length and version/language
+							$numSubHeaders = 0;
+							for ($i = 0; $i < 256; ++$i) {
+								// Array that maps high bytes to subHeaders: value is subHeader index * 8.
+								$subHeaderKeys[$i] = ($this->_getUSHORT($font, $offset) / 8);
+								$offset += 2;
+								if ($numSubHeaders < $subHeaderKeys[$i]) {
+									$numSubHeaders = $subHeaderKeys[$i];
+								}
+							}
+							// the number of subHeaders is equal to the max of subHeaderKeys + 1
+							++$numSubHeaders;
+							// read subHeader structures
+							$subHeaders = array();
+							$numGlyphIndexArray = 0;
+							for ($k = 0; $k < $numSubHeaders; ++$k) {
+								$subHeaders[$k]['firstCode'] = $this->_getUSHORT($font, $offset);
+								$offset += 2;
+								$subHeaders[$k]['entryCount'] = $this->_getUSHORT($font, $offset);
+								$offset += 2;
+								$subHeaders[$k]['idDelta'] = $this->_getUSHORT($font, $offset);
+								$offset += 2;
+								$subHeaders[$k]['idRangeOffset'] = $this->_getUSHORT($font, $offset);
+								$offset += 2;
+								$subHeaders[$k]['idRangeOffset'] -= (2 + (($numSubHeaders - $k - 1) * 8));
+								$subHeaders[$k]['idRangeOffset'] /= 2;
+								$numGlyphIndexArray += $subHeaders[$k]['entryCount'];
+							}
+							for ($k = 0; $k < $numGlyphIndexArray; ++$k) {
+								$glyphIndexArray[$k] = $this->_getUSHORT($font, $offset);
+								$offset += 2;
+							}
+							for ($i = 0; $i < 256; ++$i) {
+								$k = $subHeaderKeys[$i];
+								if ($k == 0) {
+									// one byte code
+									$c = $i;
+									$g = $glyphIndexArray[0];
+									$ctg[$c] = $g;
+								} else {
+									// two bytes code
+									$start_byte = $subHeaders[$k]['firstCode'];
+									$end_byte = $start_byte + $subHeaders[$k]['entryCount'];
+									for ($j = $start_byte; $j < $end_byte; ++$j) {
+										// combine high and low bytes
+										$c = (($i << 8) + $j);
+										$idRangeOffset = ($subHeaders[$k]['idRangeOffset'] + $j - $subHeaders[$k]['firstCode']);
+										$g = ($glyphIndexArray[$idRangeOffset] + $idDelta[$k]) % 65536;
+										if ($g < 0) {
+											$g = 0;
+										}
+										$ctg[$c] = $g;
+									}
+								}
+							}
+							break;
+						}
+						case 4: { // Format 4: Segment mapping to delta values
+							$length = $this->_getUSHORT($font, $offset);
+							$offset += 2;
+							$offset += 2; // skip version/language
+							$segCount = ($this->_getUSHORT($font, $offset) / 2);
+							$offset += 2;
+							$offset += 6; // skip searchRange, entrySelector, rangeShift
+							$endCount = array(); // array of end character codes for each segment
+							for ($k = 0; $k < $segCount; ++$k) {
+								$endCount[$k] = $this->_getUSHORT($font, $offset);
+								$offset += 2;
+							}
+							$offset += 2; // skip reservedPad
+							$startCount = array(); // array of start character codes for each segment
+							for ($k = 0; $k < $segCount; ++$k) {
+								$startCount[$k] = $this->_getUSHORT($font, $offset);
+								$offset += 2;
+							}
+							$idDelta = array(); // delta for all character codes in segment
+							for ($k = 0; $k < $segCount; ++$k) {
+								$idDelta[$k] = $this->_getUSHORT($font, $offset);
+								$offset += 2;
+							}
+							$idRangeOffset = array(); // Offsets into glyphIdArray or 0
+							for ($k = 0; $k < $segCount; ++$k) {
+								$idRangeOffset[$k] = $this->_getUSHORT($font, $offset);
+								$offset += 2;
+							}
+							$gidlen = ($length / 2) - 8 - (4 * $segCount);
+							$glyphIdArray = array(); // glyph index array
+							for ($k = 0; $k < $gidlen; ++$k) {
+								$glyphIdArray[$k] = $this->_getUSHORT($font, $offset);
+								$offset += 2;
+							}
+							for ($k = 0; $k < $segCount; ++$k) {
+								for ($c = $startCount[$k]; $c <= $endCount[$k]; ++$c) {
+									if ($idRangeOffset[$k] == 0) {
+										$g = ($idDelta[$k] + $c) % 65536;
+									} else {
+										$gid = (($idRangeOffset[$k] / 2) + ($c - $startCount[$k]) - ($segCount - $k));
+										$g = ($glyphIdArray[$gid] + $idDelta[$k]) % 65536;
+									}
+									if ($g < 0) {
+										$g = 0;
+									}
+									$ctg[$c] = $g;
+								}
+							}
+							break;
+						}
+						case 6: { // Format 6: Trimmed table mapping
+							$offset += 4; // skip length and version/language
+							$firstCode = $this->_getUSHORT($font, $offset);
+							$offset += 2;
+							$entryCount = $this->_getUSHORT($font, $offset);
+							$offset += 2;
+							for ($k = 0; $k < $entryCount; ++$k) {
+								$c = ($k + $firstCode);
+								$g = $this->_getUSHORT($font, $offset);
+								$offset += 2;
+								$ctg[$c] = $g;
+							}
+							break;
+						}
+						case 8: { // Format 8: Mixed 16-bit and 32-bit coverage
+							$offset += 10; // skip reserved, length and version/language
+							for ($k = 0; $k < 8192; ++$k) {
+								$is32[$k] = $this->_getBYTE($font, $offset);
+								++$offset;
+							}
+							$nGroups = $this->_getULONG($font, $offset);
+							$offset += 4;
+							for ($i = 0; $i < $nGroups; ++$i) {
+								$startCharCode = $this->_getULONG($font, $offset);
+								$offset += 4;
+								$endCharCode = $this->_getULONG($font, $offset);
+								$offset += 4;
+								$startGlyphID = $this->_getULONG($font, $offset);
+								$offset += 4;
+								for ($k = $startCharCode; $k <= $endCharCode; ++$k) {
+									$is32idx = floor($c / 8);
+									if ((isset($is32[$is32idx])) AND (($is32[$is32idx] & (1 << (7 - ($c % 8)))) == 0)) {
+										$c = $k;
+									} else {
+										// 32 bit format
+										// convert to decimal (http://www.unicode.org/faq//utf_bom.html#utf16-4)
+										//LEAD_OFFSET = (0xD800 - (0x10000 >> 10)) = 55232
+										//SURROGATE_OFFSET = (0x10000 - (0xD800 << 10) - 0xDC00) = -56613888
+										$c = ((55232 + ($k >> 10)) << 10) + (0xDC00 + ($k & 0x3FF)) -56613888;
+									}
+									$ctg[$c] = 0;
+									++$startGlyphID;
+								}
+							}
+							break;
+						}
+						case 10: { // Format 10: Trimmed array
+							$offset += 10; // skip reserved, length and version/language
+							$startCharCode = $this->_getULONG($font, $offset);
+							$offset += 4;
+							$numChars = $this->_getULONG($font, $offset);
+							$offset += 4;
+							for ($k = 0; $k < $numChars; ++$k) {
+								$c = ($k + $startCharCode);
+								$g = $this->_getUSHORT($font, $offset);
+								$ctg[$c] = $g;
+								$offset += 2;
+							}
+							break;
+						}
+						case 12: { // Format 12: Segmented coverage
+							$offset += 10; // skip length and version/language
+							$nGroups = $this->_getULONG($font, $offset);
+							$offset += 4;
+							for ($k = 0; $k < $nGroups; ++$k) {
+								$startCharCode = $this->_getULONG($font, $offset);
+								$offset += 4;
+								$endCharCode = $this->_getULONG($font, $offset);
+								$offset += 4;
+								$startGlyphCode = $this->_getULONG($font, $offset);
+								$offset += 4;
+								for ($c = $startCharCode; $c <= $endCharCode; ++$c) {
+									$ctg[$c] = $startGlyphCode;
+									++$startGlyphCode;
+								}
+							}
+							break;
+						}
+						case 13: { // Format 13: Many-to-one range mappings
+							// to be implemented ...
+							break;
+						}
+						case 14: { // Format 14: Unicode Variation Sequences
+							// to be implemented ...
+							break;
+						}
+					}
+				}
+			}
+			if (!isset($ctg[0])) {
+				$ctg[0] = 0;
+			}
+			// get xHeight (height of x)
+			$offset = ($table['glyf']['offset'] + $indexToLoc[$ctg[120]] + 4);
+			$yMin = $this->_getFWORD($font, $offset);
+			$offset += 4;
+			$yMax = $this->_getFWORD($font, $offset);
+			$offset += 2;
+			$fmetric['XHeight'] = round(($yMax - $yMin) * $urk);
+			// get CapHeight (height of H)
+			$offset = ($table['glyf']['offset'] + $indexToLoc[$ctg[72]] + 4);
+			$yMin = $this->_getFWORD($font, $offset);
+			$offset += 4;
+			$yMax = $this->_getFWORD($font, $offset);
+			$offset += 2;
+			$fmetric['CapHeight'] = round(($yMax - $yMin) * $urk);
+			// ceate widths array
+			$cw = array();
+			$offset = $table['hmtx']['offset'];
+			for ($i = 0 ; $i < $numberOfHMetrics; ++$i) {
+				$cw[$i] = round($this->_getUFWORD($font, $offset) * $urk);
+				$offset += 4; // skip lsb
+			}
+			if ($numberOfHMetrics < $numGlyphs) {
+				// fill missing widths with the last value
+				$cw = array_pad($cw, $numGlyphs, $cw[($numberOfHMetrics - 1)]);
+			}
+			$fmetric['MissingWidth'] = $cw[0];
+			$fmetric['cw'] = '';
+			for ($cid = 0; $cid <= 65535; ++$cid) {
+				if (isset($ctg[$cid])) {
+					if (isset($cw[$ctg[$cid]])) {
+						$fmetric['cw'] .= ','.$cid.'=>'.$cw[$ctg[$cid]];
+					}
+					if ($addcbbox AND isset($indexToLoc[$ctg[$cid]])) {
+						$offset = ($table['glyf']['offset'] + $indexToLoc[$ctg[$cid]]);
+						$xMin = round($this->_getFWORD($font, $offset + 2)) * $urk;
+						$yMin = round($this->_getFWORD($font, $offset + 4)) * $urk;
+						$xMax = round($this->_getFWORD($font, $offset + 6)) * $urk;
+						$yMax = round($this->_getFWORD($font, $offset + 8)) * $urk;
+						$fmetric['cbbox'] .= ','.$cid.'=>array('.$xMin.','.$yMin.','.$xMax.','.$yMax.')';
+					}
+				}
+			}
+		} // end of true type
+		if (($fmetric['type'] == 'TrueTypeUnicode') AND (count($ctg) == 256)) {
+			$fmetric['type'] == 'TrueType';
+		}
+		// ---------- create php font file ----------
+		$pfile = '<'.'?'.'php'."\n";
+		$pfile .= '// TCPDF FONT FILE DESCRIPTION'."\n";
+		$pfile .= '$type=\''.$fmetric['type'].'\';'."\n";
+		$pfile .= '$name=\''.$fmetric['name'].'\';'."\n";
+		$pfile .= '$up='.$fmetric['underlinePosition'].';'."\n";
+		$pfile .= '$ut='.$fmetric['underlineThickness'].';'."\n";
+		if ($fmetric['MissingWidth'] > 0) {
+			$pfile .= '$dw='.$fmetric['MissingWidth'].';'."\n";
+		} else {
+			$pfile .= '$dw='.$fmetric['AvgWidth'].';'."\n";
+		}
+		$pfile .= '$diff=\''.$fmetric['diff'].'\';'."\n";
+		if ($fmetric['type'] == 'Type1') {
+			// Type 1
+			$pfile .= '$enc=\''.$fmetric['enc'].'\';'."\n";
+			$pfile .= '$file=\''.$fmetric['file'].'\';'."\n";
+			$pfile .= '$size1='.$fmetric['size1'].';'."\n";
+			$pfile .= '$size2='.$fmetric['size2'].';'."\n";
+		} else {
+			$pfile .= '$originalsize='.$fmetric['originalsize'].';'."\n";
+			if ($fmetric['type'] == 'cidfont0') {
+				// CID-0
+				switch ($fonttype) {
+					case 'CID0JP': {
+						$pfile .= '// Japanese'."\n";
+						$pfile .= '$enc=\'UniJIS-UTF16-H\';'."\n";
+						$pfile .= '$cidinfo=array(\'Registry\'=>\'Adobe\', \'Ordering\'=>\'Japan1\',\'Supplement\'=>5);'."\n";
+						$pfile .= 'include(dirname(__FILE__).\'/uni2cid_aj16.php\');'."\n";
+						break;
+					}
+					case 'CID0KR': {
+						$pfile .= '// Korean'."\n";
+						$pfile .= '$enc=\'UniKS-UTF16-H\';'."\n";
+						$pfile .= '$cidinfo=array(\'Registry\'=>\'Adobe\', \'Ordering\'=>\'Korea1\',\'Supplement\'=>0);'."\n";
+						$pfile .= 'include(dirname(__FILE__).\'/uni2cid_ak12.php\');'."\n";
+						break;
+					}
+					case 'CID0CS': {
+						$pfile .= '// Chinese Simplified'."\n";
+						$pfile .= '$enc=\'UniGB-UTF16-H\';'."\n";
+						$pfile .= '$cidinfo=array(\'Registry\'=>\'Adobe\', \'Ordering\'=>\'GB1\',\'Supplement\'=>2);'."\n";
+						$pfile .= 'include(dirname(__FILE__).\'/uni2cid_ag15.php\');'."\n";
+						break;
+					}
+					case 'CID0CT':
+					default: {
+						$pfile .= '// Chinese Traditional'."\n";
+						$pfile .= '$enc=\'UniCNS-UTF16-H\';'."\n";
+						$pfile .= '$cidinfo=array(\'Registry\'=>\'Adobe\', \'Ordering\'=>\'CNS1\',\'Supplement\'=>0);'."\n";
+						$pfile .= 'include(dirname(__FILE__).\'/uni2cid_aj16.php\');'."\n";
+						break;
+					}
+				}
+			} else {
+				// TrueType
+				$pfile .= '$enc=\''.$fmetric['enc'].'\';'."\n";
+				$pfile .= '$file=\''.$fmetric['file'].'\';'."\n";
+				$pfile .= '$ctg=\''.$fmetric['ctg'].'\';'."\n";
+				// create CIDToGIDMap
+				$cidtogidmap = str_pad('', 131072, "\x00"); // (256 * 256 * 2) = 131072
+				foreach ($ctg as $cid => $gid) {
+					$cidtogidmap = $this->updateCIDtoGIDmap($cidtogidmap, $cid, $ctg[$cid]);
+				}
+				// store compressed CIDToGIDMap
+				$fp = fopen($outpath.$fmetric['ctg'], 'wb');
+				fwrite($fp, gzcompress($cidtogidmap));
+				fclose($fp);
+			}
+		}
+		$pfile .= '$desc=array(';
+		$pfile .= '\'Flags\'=>'.$fmetric['Flags'].',';
+		$pfile .= '\'FontBBox\'=>\'['.$fmetric['bbox'].']\',';
+		$pfile .= '\'ItalicAngle\'=>'.$fmetric['italicAngle'].',';
+		$pfile .= '\'Ascent\'=>'.$fmetric['Ascent'].',';
+		$pfile .= '\'Descent\'=>'.$fmetric['Descent'].',';
+		$pfile .= '\'Leading\'=>'.$fmetric['Leading'].',';
+		$pfile .= '\'CapHeight\'=>'.$fmetric['CapHeight'].',';
+		$pfile .= '\'XHeight\'=>'.$fmetric['XHeight'].',';
+		$pfile .= '\'StemV\'=>'.$fmetric['StemV'].',';
+		$pfile .= '\'StemH\'=>'.$fmetric['StemH'].',';
+		$pfile .= '\'AvgWidth\'=>'.$fmetric['AvgWidth'].',';
+		$pfile .= '\'MaxWidth\'=>'.$fmetric['MaxWidth'].',';
+		$pfile .= '\'MissingWidth\'=>'.$fmetric['MissingWidth'].'';
+		$pfile .= ');'."\n";
+		if (isset($fmetric['cbbox'])) {
+			$pfile .= '$cbbox=array('.substr($fmetric['cbbox'], 1).');'."\n";
+		}
+		$pfile .= '$cw=array('.substr($fmetric['cw'], 1).');'."\n";
+		$pfile .= '// --- EOF ---'."\n";
+		// store file
+		$fp = fopen($outpath.$font_name.'.php', 'w');
+		fwrite($fp, $pfile);
+		fclose($fp);
+		// return TCPDF font name
+		return $font_name;
+	}
+
+	/**
+	 * Returns a subset of the TrueType font data without the unused glyphs.
+	 * @param $font (string) TrueType font data.
+	 * @param $subsetchars (array) Array of used characters (the glyphs to keep).
+	 * @return (string) A subset of TrueType font data without the unused glyphs.
+	 * @author Nicola Asuni
+	 * @protected
+	 * @since 5.2.000 (2010-06-02)
+	 */
+	protected function _getTrueTypeFontSubset($font, $subsetchars) {
+		ksort($subsetchars);
+		$offset = 0; // offset position of the font data
+		if ($this->_getULONG($font, $offset) != 0x10000) {
+			// sfnt version must be 0x00010000 for TrueType version 1.0.
+			return $font;
+		}
+		$offset += 4;
+		// get number of tables
+		$numTables = $this->_getUSHORT($font, $offset);
+		$offset += 2;
+		// skip searchRange, entrySelector and rangeShift
+		$offset += 6;
+		// tables array
+		$table = array();
+		// for each table
+		for ($i = 0; $i < $numTables; ++$i) {
+			// get table info
+			$tag = substr($font, $offset, 4);
+			$offset += 4;
+			$table[$tag] = array();
+			$table[$tag]['checkSum'] = $this->_getULONG($font, $offset);
+			$offset += 4;
+			$table[$tag]['offset'] = $this->_getULONG($font, $offset);
+			$offset += 4;
+			$table[$tag]['length'] = $this->_getULONG($font, $offset);
+			$offset += 4;
+		}
+		// check magicNumber
+		$offset = $table['head']['offset'] + 12;
+		if ($this->_getULONG($font, $offset) != 0x5F0F3CF5) {
+			// magicNumber must be 0x5F0F3CF5
+			return $font;
+		}
+		$offset += 4;
+		// get offset mode (indexToLocFormat : 0 = short, 1 = long)
+		$offset = $table['head']['offset'] + 50;
+		$short_offset = ($this->_getSHORT($font, $offset) == 0);
+		$offset += 2;
+		// get the offsets to the locations of the glyphs in the font, relative to the beginning of the glyphData table
+		$indexToLoc = array();
+		$offset = $table['loca']['offset'];
+		if ($short_offset) {
+			// short version
+			$tot_num_glyphs = ($table['loca']['length'] / 2); // numGlyphs + 1
+			for ($i = 0; $i < $tot_num_glyphs; ++$i) {
+				$indexToLoc[$i] = $this->_getUSHORT($font, $offset) * 2;
+				$offset += 2;
+			}
+		} else {
+			// long version
+			$tot_num_glyphs = ($table['loca']['length'] / 4); // numGlyphs + 1
+			for ($i = 0; $i < $tot_num_glyphs; ++$i) {
+				$indexToLoc[$i] = $this->_getULONG($font, $offset);
+				$offset += 4;
+			}
+		}
+		// get glyphs indexes of chars from cmap table
+		$subsetglyphs = array(); // glyph IDs on key
+		$subsetglyphs[0] = true; // character codes that do not correspond to any glyph in the font should be mapped to glyph index 0
+		$offset = $table['cmap']['offset'] + 2;
+		$numEncodingTables = $this->_getUSHORT($font, $offset);
+		$offset += 2;
+		$encodingTables = array();
+		for ($i = 0; $i < $numEncodingTables; ++$i) {
+			$encodingTables[$i]['platformID'] = $this->_getUSHORT($font, $offset);
+			$offset += 2;
+			$encodingTables[$i]['encodingID'] = $this->_getUSHORT($font, $offset);
+			$offset += 2;
+			$encodingTables[$i]['offset'] = $this->_getULONG($font, $offset);
+			$offset += 4;
+		}
+		foreach ($encodingTables as $enctable) {
+			// get all platforms and encodings
+			$offset = $table['cmap']['offset'] + $enctable['offset'];
+			$format = $this->_getUSHORT($font, $offset);
+			$offset += 2;
+			switch ($format) {
+				case 0: { // Format 0: Byte encoding table
+					$offset += 4; // skip length and version/language
+					for ($c = 0; $c < 256; ++$c) {
+						if (isset($subsetchars[$c])) {
+							$g = $this->_getBYTE($font, $offset);
+							$subsetglyphs[$g] = true;
+						}
+						++$offset;
+					}
+					break;
+				}
+				case 2: { // Format 2: High-byte mapping through table
+					$offset += 4; // skip length and version/language
+					$numSubHeaders = 0;
+					for ($i = 0; $i < 256; ++$i) {
+						// Array that maps high bytes to subHeaders: value is subHeader index * 8.
+						$subHeaderKeys[$i] = ($this->_getUSHORT($font, $offset) / 8);
+						$offset += 2;
+						if ($numSubHeaders < $subHeaderKeys[$i]) {
+							$numSubHeaders = $subHeaderKeys[$i];
+						}
+					}
+					// the number of subHeaders is equal to the max of subHeaderKeys + 1
+					++$numSubHeaders;
+					// read subHeader structures
+					$subHeaders = array();
+					$numGlyphIndexArray = 0;
+					for ($k = 0; $k < $numSubHeaders; ++$k) {
+						$subHeaders[$k]['firstCode'] = $this->_getUSHORT($font, $offset);
+						$offset += 2;
+						$subHeaders[$k]['entryCount'] = $this->_getUSHORT($font, $offset);
+						$offset += 2;
+						$subHeaders[$k]['idDelta'] = $this->_getUSHORT($font, $offset);
+						$offset += 2;
+						$subHeaders[$k]['idRangeOffset'] = $this->_getUSHORT($font, $offset);
+						$offset += 2;
+						$subHeaders[$k]['idRangeOffset'] -= (2 + (($numSubHeaders - $k - 1) * 8));
+						$subHeaders[$k]['idRangeOffset'] /= 2;
+						$numGlyphIndexArray += $subHeaders[$k]['entryCount'];
+					}
+					for ($k = 0; $k < $numGlyphIndexArray; ++$k) {
+						$glyphIndexArray[$k] = $this->_getUSHORT($font, $offset);
+						$offset += 2;
+					}
+					for ($i = 0; $i < 256; ++$i) {
+						$k = $subHeaderKeys[$i];
+						if ($k == 0) {
+							// one byte code
+							$c = $i;
+							if (isset($subsetchars[$c])) {
+								$g = $glyphIndexArray[0];
+								$subsetglyphs[$g] = true;
+							}
+						} else {
+							// two bytes code
+							$start_byte = $subHeaders[$k]['firstCode'];
+							$end_byte = $start_byte + $subHeaders[$k]['entryCount'];
+							for ($j = $start_byte; $j < $end_byte; ++$j) {
+								// combine high and low bytes
+								$c = (($i << 8) + $j);
+								if (isset($subsetchars[$c])) {
+									$idRangeOffset = ($subHeaders[$k]['idRangeOffset'] + $j - $subHeaders[$k]['firstCode']);
+									$g = ($glyphIndexArray[$idRangeOffset] + $idDelta[$k]) % 65536;
+									if ($g < 0) {
+										$g = 0;
+									}
+									$subsetglyphs[$g] = true;
+								}
+							}
+						}
+					}
+					break;
+				}
+				case 4: { // Format 4: Segment mapping to delta values
+					$length = $this->_getUSHORT($font, $offset);
+					$offset += 2;
+					$offset += 2; // skip version/language
+					$segCount = ($this->_getUSHORT($font, $offset) / 2);
+					$offset += 2;
+					$offset += 6; // skip searchRange, entrySelector, rangeShift
+					$endCount = array(); // array of end character codes for each segment
+					for ($k = 0; $k < $segCount; ++$k) {
+						$endCount[$k] = $this->_getUSHORT($font, $offset);
+						$offset += 2;
+					}
+					$offset += 2; // skip reservedPad
+					$startCount = array(); // array of start character codes for each segment
+					for ($k = 0; $k < $segCount; ++$k) {
+						$startCount[$k] = $this->_getUSHORT($font, $offset);
+						$offset += 2;
+					}
+					$idDelta = array(); // delta for all character codes in segment
+					for ($k = 0; $k < $segCount; ++$k) {
+						$idDelta[$k] = $this->_getUSHORT($font, $offset);
+						$offset += 2;
+					}
+					$idRangeOffset = array(); // Offsets into glyphIdArray or 0
+					for ($k = 0; $k < $segCount; ++$k) {
+						$idRangeOffset[$k] = $this->_getUSHORT($font, $offset);
+						$offset += 2;
+					}
+					$gidlen = ($length / 2) - 8 - (4 * $segCount);
+					$glyphIdArray = array(); // glyph index array
+					for ($k = 0; $k < $gidlen; ++$k) {
+						$glyphIdArray[$k] = $this->_getUSHORT($font, $offset);
+						$offset += 2;
+					}
+					for ($k = 0; $k < $segCount; ++$k) {
+						for ($c = $startCount[$k]; $c <= $endCount[$k]; ++$c) {
+							if (isset($subsetchars[$c])) {
+								if ($idRangeOffset[$k] == 0) {
+									$g = ($idDelta[$k] + $c) % 65536;
+								} else {
+									$gid = (($idRangeOffset[$k] / 2) + ($c - $startCount[$k]) - ($segCount - $k));
+									$g = ($glyphIdArray[$gid] + $idDelta[$k]) % 65536;
+								}
+								if ($g < 0) {
+									$g = 0;
+								}
+								$subsetglyphs[$g] = true;
+							}
+						}
+					}
+					break;
+				}
+				case 6: { // Format 6: Trimmed table mapping
+					$offset += 4; // skip length and version/language
+					$firstCode = $this->_getUSHORT($font, $offset);
+					$offset += 2;
+					$entryCount = $this->_getUSHORT($font, $offset);
+					$offset += 2;
+					for ($k = 0; $k < $entryCount; ++$k) {
+						$c = ($k + $firstCode);
+						if (isset($subsetchars[$c])) {
+							$g = $this->_getUSHORT($font, $offset);
+							$subsetglyphs[$g] = true;
+						}
+						$offset += 2;
+					}
+					break;
+				}
+				case 8: { // Format 8: Mixed 16-bit and 32-bit coverage
+					$offset += 10; // skip reserved, length and version/language
+					for ($k = 0; $k < 8192; ++$k) {
+						$is32[$k] = $this->_getBYTE($font, $offset);
+						++$offset;
+					}
+					$nGroups = $this->_getULONG($font, $offset);
+					$offset += 4;
+					for ($i = 0; $i < $nGroups; ++$i) {
+						$startCharCode = $this->_getULONG($font, $offset);
+						$offset += 4;
+						$endCharCode = $this->_getULONG($font, $offset);
+						$offset += 4;
+						$startGlyphID = $this->_getULONG($font, $offset);
+						$offset += 4;
+						for ($k = $startCharCode; $k <= $endCharCode; ++$k) {
+							$is32idx = floor($c / 8);
+							if ((isset($is32[$is32idx])) AND (($is32[$is32idx] & (1 << (7 - ($c % 8)))) == 0)) {
+								$c = $k;
+							} else {
+								// 32 bit format
+								// convert to decimal (http://www.unicode.org/faq//utf_bom.html#utf16-4)
+								//LEAD_OFFSET = (0xD800 - (0x10000 >> 10)) = 55232
+								//SURROGATE_OFFSET = (0x10000 - (0xD800 << 10) - 0xDC00) = -56613888
+								$c = ((55232 + ($k >> 10)) << 10) + (0xDC00 + ($k & 0x3FF)) -56613888;
+							}
+							if (isset($subsetchars[$c])) {
+								$subsetglyphs[$startGlyphID] = true;
+							}
+							++$startGlyphID;
+						}
+					}
+					break;
+				}
+				case 10: { // Format 10: Trimmed array
+					$offset += 10; // skip reserved, length and version/language
+					$startCharCode = $this->_getULONG($font, $offset);
+					$offset += 4;
+					$numChars = $this->_getULONG($font, $offset);
+					$offset += 4;
+					for ($k = 0; $k < $numChars; ++$k) {
+						$c = ($k + $startCharCode);
+						if (isset($subsetchars[$c])) {
+							$g = $this->_getUSHORT($font, $offset);
+							$subsetglyphs[$g] = true;
+						}
+						$offset += 2;
+					}
+					break;
+				}
+				case 12: { // Format 12: Segmented coverage
+					$offset += 10; // skip length and version/language
+					$nGroups = $this->_getULONG($font, $offset);
+					$offset += 4;
+					for ($k = 0; $k < $nGroups; ++$k) {
+						$startCharCode = $this->_getULONG($font, $offset);
+						$offset += 4;
+						$endCharCode = $this->_getULONG($font, $offset);
+						$offset += 4;
+						$startGlyphCode = $this->_getULONG($font, $offset);
+						$offset += 4;
+						for ($c = $startCharCode; $c <= $endCharCode; ++$c) {
+							if (isset($subsetchars[$c])) {
+								$subsetglyphs[$startGlyphCode] = true;
+							}
+							++$startGlyphCode;
+						}
+					}
+					break;
+				}
+				case 13: { // Format 13: Many-to-one range mappings
+					// to be implemented ...
+					break;
+				}
+				case 14: { // Format 14: Unicode Variation Sequences
+					// to be implemented ...
+					break;
+				}
+			}
+		}
+		// include all parts of composite glyphs
+		$new_sga = $subsetglyphs;
+		while (!empty($new_sga)) {
+			$sga = $new_sga;
+			$new_sga = array();
+			foreach ($sga as $key => $val) {
+				if (isset($indexToLoc[$key])) {
+					$offset = ($table['glyf']['offset'] + $indexToLoc[$key]);
+					$numberOfContours = $this->_getSHORT($font, $offset);
+					$offset += 2;
+					if ($numberOfContours < 0) { // composite glyph
+						$offset += 8; // skip xMin, yMin, xMax, yMax
+						do {
+							$flags = $this->_getUSHORT($font, $offset);
+							$offset += 2;
+							$glyphIndex = $this->_getUSHORT($font, $offset);
+							$offset += 2;
+							if (!isset($subsetglyphs[$glyphIndex])) {
+								// add missing glyphs
+								$new_sga[$glyphIndex] = true;
+							}
+							// skip some bytes by case
+							if ($flags & 1) {
+								$offset += 4;
+							} else {
+								$offset += 2;
+							}
+							if ($flags & 8) {
+								$offset += 2;
+							} elseif ($flags & 64) {
+								$offset += 4;
+							} elseif ($flags & 128) {
+								$offset += 8;
+							}
+						} while ($flags & 32);
+					}
+				}
+			}
+			$subsetglyphs += $new_sga;
+		}
+		// sort glyphs by key (and remove duplicates)
+		ksort($subsetglyphs);
+		// build new glyf and loca tables
+		$glyf = '';
+		$loca = '';
+		$offset = 0;
+		$glyf_offset = $table['glyf']['offset'];
+		for ($i = 0; $i < $tot_num_glyphs; ++$i) {
+			if (isset($subsetglyphs[$i])) {
+				$length = ($indexToLoc[($i + 1)] - $indexToLoc[$i]);
+				$glyf .= substr($font, ($glyf_offset + $indexToLoc[$i]), $length);
+			} else {
+				$length = 0;
+			}
+			if ($short_offset) {
+				$loca .= pack('n', ($offset / 2));
+			} else {
+				$loca .= pack('N', $offset);
+			}
+			$offset += $length;
+		}
+		// array of table names to preserve (loca and glyf tables will be added later)
+		// the cmap table is not needed and shall not be present, since the mapping from character codes to glyph descriptions is provided separately
+		$table_names = array ('head', 'hhea', 'hmtx', 'maxp', 'cvt ', 'fpgm', 'prep'); // minimum required table names
+		// get the tables to preserve
+		$offset = 12;
+		foreach ($table as $tag => $val) {
+			if (in_array($tag, $table_names)) {
+				$table[$tag]['data'] = substr($font, $table[$tag]['offset'], $table[$tag]['length']);
+				if ($tag == 'head') {
+					// set the checkSumAdjustment to 0
+					$table[$tag]['data'] = substr($table[$tag]['data'], 0, 8)."\x0\x0\x0\x0".substr($table[$tag]['data'], 12);
+				}
+				$pad = 4 - ($table[$tag]['length'] % 4);
+				if ($pad != 4) {
+					// the length of a table must be a multiple of four bytes
+					$table[$tag]['length'] += $pad;
+					$table[$tag]['data'] .= str_repeat("\x0", $pad);
+				}
+				$table[$tag]['offset'] = $offset;
+				$offset += $table[$tag]['length'];
+				// check sum is not changed (so keep the following line commented)
+				//$table[$tag]['checkSum'] = $this->_getTTFtableChecksum($table[$tag]['data'], $table[$tag]['length']);
+			} else {
+				unset($table[$tag]);
+			}
+		}
+		// add loca
+		$table['loca']['data'] = $loca;
+		$table['loca']['length'] = strlen($loca);
+		$pad = 4 - ($table['loca']['length'] % 4);
+		if ($pad != 4) {
+			// the length of a table must be a multiple of four bytes
+			$table['loca']['length'] += $pad;
+			$table['loca']['data'] .= str_repeat("\x0", $pad);
+		}
+		$table['loca']['offset'] = $offset;
+		$table['loca']['checkSum'] = $this->_getTTFtableChecksum($table['loca']['data'], $table['loca']['length']);
+		$offset += $table['loca']['length'];
+		// add glyf
+		$table['glyf']['data'] = $glyf;
+		$table['glyf']['length'] = strlen($glyf);
+		$pad = 4 - ($table['glyf']['length'] % 4);
+		if ($pad != 4) {
+			// the length of a table must be a multiple of four bytes
+			$table['glyf']['length'] += $pad;
+			$table['glyf']['data'] .= str_repeat("\x0", $pad);
+		}
+		$table['glyf']['offset'] = $offset;
+		$table['glyf']['checkSum'] = $this->_getTTFtableChecksum($table['glyf']['data'], $table['glyf']['length']);
+		// rebuild font
+		$font = '';
+		$font .= pack('N', 0x10000); // sfnt version
+		$numTables = count($table);
+		$font .= pack('n', $numTables); // numTables
+		$entrySelector = floor(log($numTables, 2));
+		$searchRange = pow(2, $entrySelector) * 16;
+		$rangeShift = ($numTables * 16) - $searchRange;
+		$font .= pack('n', $searchRange); // searchRange
+		$font .= pack('n', $entrySelector); // entrySelector
+		$font .= pack('n', $rangeShift); // rangeShift
+		$offset = ($numTables * 16);
+		foreach ($table as $tag => $data) {
+			$font .= $tag; // tag
+			$font .= pack('N', $data['checkSum']); // checkSum
+			$font .= pack('N', ($data['offset'] + $offset)); // offset
+			$font .= pack('N', $data['length']); // length
+		}
+		foreach ($table as $data) {
+			$font .= $data['data'];
+		}
+		// set checkSumAdjustment on head table
+		$checkSumAdjustment = 0xB1B0AFBA - $this->_getTTFtableChecksum($font, strlen($font));
+		$font = substr($font, 0, $table['head']['offset'] + 8).pack('N', $checkSumAdjustment).substr($font, $table['head']['offset'] + 12);
+		return $font;
+	}
+
+	/**
+	 * Returs the checksum of a TTF table.
+	 * @param $table (string) table to check
+	 * @param $length (int) length of table in bytes
+	 * @return int checksum
+	 * @author Nicola Asuni
+	 * @protected
+	 * @since 5.2.000 (2010-06-02)
+	 */
+	protected function _getTTFtableChecksum($table, $length) {
+		$sum = 0;
+		$tlen = ($length / 4);
+		$offset = 0;
+		for ($i = 0; $i < $tlen; ++$i) {
+			$v = unpack('Ni', substr($table, $offset, 4));
+			$sum += $v['i'];
+			$offset += 4;
+		}
+		$sum = unpack('Ni', pack('N', $sum));
+		return $sum['i'];
+	}
+
+	/**
+	 * Outputs font widths
+	 * @param $font (array) font data
+	 * @param $cidoffset (int) offset for CID values
+	 * @return PDF command string for font widths
+	 * @author Nicola Asuni
+	 * @protected
+	 * @since 4.4.000 (2008-12-07)
+	 */
+	protected function _putfontwidths($font, $cidoffset=0) {
+		ksort($font['cw']);
+		$rangeid = 0;
+		$range = array();
+		$prevcid = -2;
+		$prevwidth = -1;
+		$interval = false;
+		// for each character
+		foreach ($font['cw'] as $cid => $width) {
+			$cid -= $cidoffset;
+			if ($font['subset'] AND (!isset($font['subsetchars'][$cid]))) {
+				// ignore the unused characters (font subsetting)
+				continue;
+			}
+			if ($width != $font['dw']) {
+				if ($cid == ($prevcid + 1)) {
+					// consecutive CID
+					if ($width == $prevwidth) {
+						if ($width == $range[$rangeid][0]) {
+							$range[$rangeid][] = $width;
+						} else {
+							array_pop($range[$rangeid]);
+							// new range
+							$rangeid = $prevcid;
+							$range[$rangeid] = array();
+							$range[$rangeid][] = $prevwidth;
+							$range[$rangeid][] = $width;
+						}
+						$interval = true;
+						$range[$rangeid]['interval'] = true;
+					} else {
+						if ($interval) {
+							// new range
+							$rangeid = $cid;
+							$range[$rangeid] = array();
+							$range[$rangeid][] = $width;
+						} else {
+							$range[$rangeid][] = $width;
+						}
+						$interval = false;
+					}
+				} else {
+					// new range
+					$rangeid = $cid;
+					$range[$rangeid] = array();
+					$range[$rangeid][] = $width;
+					$interval = false;
+				}
+				$prevcid = $cid;
+				$prevwidth = $width;
+			}
+		}
+		// optimize ranges
+		$prevk = -1;
+		$nextk = -1;
+		$prevint = false;
+		foreach ($range as $k => $ws) {
+			$cws = count($ws);
+			if (($k == $nextk) AND (!$prevint) AND ((!isset($ws['interval'])) OR ($cws < 4))) {
+				if (isset($range[$k]['interval'])) {
+					unset($range[$k]['interval']);
+				}
+				$range[$prevk] = array_merge($range[$prevk], $range[$k]);
+				unset($range[$k]);
+			} else {
+				$prevk = $k;
+			}
+			$nextk = $k + $cws;
+			if (isset($ws['interval'])) {
+				if ($cws > 3) {
+					$prevint = true;
+				} else {
+					$prevint = false;
+				}
+				if (isset($range[$k]['interval'])) {
+					unset($range[$k]['interval']);
+				}
+				--$nextk;
+			} else {
+				$prevint = false;
+			}
+		}
+		// output data
+		$w = '';
+		foreach ($range as $k => $ws) {
+			if (count(array_count_values($ws)) == 1) {
+				// interval mode is more compact
+				$w .= ' '.$k.' '.($k + count($ws) - 1).' '.$ws[0];
+			} else {
+				// range mode
+				$w .= ' '.$k.' [ '.implode(' ', $ws).' ]';
+			}
+		}
+		return '/W ['.$w.' ]';
+	}
+
+	/**
+	 * Output fonts.
+	 * @author Nicola Asuni
+	 * @protected
+	 */
+	protected function _putfonts() {
+		$nf = $this->n;
+		foreach ($this->diffs as $diff) {
+			//Encodings
+			$this->_newobj();
+			$this->_out('<< /Type /Encoding /BaseEncoding /WinAnsiEncoding /Differences ['.$diff.'] >>'."\n".'endobj');
+		}
+		$mqr = $this->get_mqr();
+		$this->set_mqr(false);
+		foreach ($this->FontFiles as $file => $info) {
+			// search and get font file to embedd
+			$fontdir = $info['fontdir'];
+			$file = strtolower($file);
+			$fontfile = '';
+			// search files on various directories
+			if (($fontdir !== false) AND file_exists($fontdir.$file)) {
+				$fontfile = $fontdir.$file;
+			} elseif (file_exists($this->_getfontpath().$file)) {
+				$fontfile = $this->_getfontpath().$file;
+			} elseif (file_exists($file)) {
+				$fontfile = $file;
+			}
+			if (!$this->empty_string($fontfile)) {
+				$font = file_get_contents($fontfile);
+				$compressed = (substr($file, -2) == '.z');
+				if ((!$compressed) AND (isset($info['length2']))) {
+					$header = (ord($font{0}) == 128);
+					if ($header) {
+						// strip first binary header
+						$font = substr($font, 6);
+					}
+					if ($header AND (ord($font[$info['length1']]) == 128)) {
+						// strip second binary header
+						$font = substr($font, 0, $info['length1']).substr($font, ($info['length1'] + 6));
+					}
+				} elseif ($info['subset'] AND ((!$compressed) OR ($compressed AND function_exists('gzcompress')))) {
+					if ($compressed) {
+						// uncompress font
+						$font = gzuncompress($font);
+					}
+					// merge subset characters
+					$subsetchars = array(); // used chars
+					foreach ($info['fontkeys'] as $fontkey) {
+						$fontinfo = $this->getFontBuffer($fontkey);
+						$subsetchars += $fontinfo['subsetchars'];
+					}
+					// rebuild a font subset
+					$font = $this->_getTrueTypeFontSubset($font, $subsetchars);
+					// calculate new font length
+					$info['length1'] = strlen($font);
+					if ($compressed) {
+						// recompress font
+						$font = gzcompress($font);
+					}
+				}
+				$this->_newobj();
+				$this->FontFiles[$file]['n'] = $this->n;
+				$stream = $this->_getrawstream($font);
+				$out = '<< /Length '.strlen($stream);
+				if ($compressed) {
+					$out .= ' /Filter /FlateDecode';
+				}
+				$out .= ' /Length1 '.$info['length1'];
+				if (isset($info['length2'])) {
+					$out .= ' /Length2 '.$info['length2'].' /Length3 0';
+				}
+				$out .= ' >>';
+				$out .= ' stream'."\n".$stream."\n".'endstream';
+				$out .= "\n".'endobj';
+				$this->_out($out);
+			}
+		}
+		$this->set_mqr($mqr);
+		foreach ($this->fontkeys as $k) {
+			//Font objects
+			$font = $this->getFontBuffer($k);
+			$type = $font['type'];
+			$name = $font['name'];
+			if ($type == 'core') {
+				// standard core font
+				$out = $this->_getobj($this->font_obj_ids[$k])."\n";
+				$out .= '<</Type /Font';
+				$out .= ' /Subtype /Type1';
+				$out .= ' /BaseFont /'.$name;
+				$out .= ' /Name /F'.$font['i'];
+				if ((strtolower($name) != 'symbol') AND (strtolower($name) != 'zapfdingbats')) {
+					$out .= ' /Encoding /WinAnsiEncoding';
+				}
+				if ($k == 'helvetica') {
+					// add default font for annotations
+					$this->annotation_fonts[$k] = $font['i'];
+				}
+				$out .= ' >>';
+				$out .= "\n".'endobj';
+				$this->_out($out);
+			} elseif (($type == 'Type1') OR ($type == 'TrueType')) {
+				// additional Type1 or TrueType font
+				$out = $this->_getobj($this->font_obj_ids[$k])."\n";
+				$out .= '<</Type /Font';
+				$out .= ' /Subtype /'.$type;
+				$out .= ' /BaseFont /'.$name;
+				$out .= ' /Name /F'.$font['i'];
+				$out .= ' /FirstChar 32 /LastChar 255';
+				$out .= ' /Widths '.($this->n + 1).' 0 R';
+				$out .= ' /FontDescriptor '.($this->n + 2).' 0 R';
+				if ($font['enc']) {
+					if (isset($font['diff'])) {
+						$out .= ' /Encoding '.($nf + $font['diff']).' 0 R';
+					} else {
+						$out .= ' /Encoding /WinAnsiEncoding';
+					}
+				}
+				$out .= ' >>';
+				$out .= "\n".'endobj';
+				$this->_out($out);
+				// Widths
+				$this->_newobj();
+				$s = '[';
+				for ($i = 32; $i < 256; ++$i) {
+					if (isset($font['cw'][$i])) {
+						$s .= $font['cw'][$i].' ';
+					} else {
+						$s .= $font['dw'].' ';
+					}
+				}
+				$s .= ']';
+				$s .= "\n".'endobj';
+				$this->_out($s);
+				//Descriptor
+				$this->_newobj();
+				$s = '<</Type /FontDescriptor /FontName /'.$name;
+				foreach ($font['desc'] as $fdk => $fdv) {
+					if (is_float($fdv)) {
+						$fdv = sprintf('%F', $fdv);
+					}
+					$s .= ' /'.$fdk.' '.$fdv.'';
+				}
+				if (!$this->empty_string($font['file'])) {
+					$s .= ' /FontFile'.($type == 'Type1' ? '' : '2').' '.$this->FontFiles[$font['file']]['n'].' 0 R';
+				}
+				$s .= '>>';
+				$s .= "\n".'endobj';
+				$this->_out($s);
+			} else {
+				// additional types
+				$mtd = '_put'.strtolower($type);
+				if (!method_exists($this, $mtd)) {
+					$this->Error('Unsupported font type: '.$type);
+				}
+				$this->$mtd($font);
+			}
+		}
+	}
+
+	/**
+	 * Adds unicode fonts.<br>
+	 * Based on PDF Reference 1.3 (section 5)
+	 * @param $font (array) font data
+	 * @protected
+	 * @author Nicola Asuni
+	 * @since 1.52.0.TC005 (2005-01-05)
+	 */
+	protected function _puttruetypeunicode($font) {
+		$fontname = '';
+		if ($font['subset']) {
+			// change name for font subsetting
+			$subtag = sprintf('%06u', $font['i']);
+			$subtag = strtr($subtag, '0123456789', 'ABCDEFGHIJ');
+			$fontname .= $subtag.'+';
+		}
+		$fontname .= $font['name'];
+		// Type0 Font
+		// A composite font composed of other fonts, organized hierarchically
+		$out = $this->_getobj($this->font_obj_ids[$font['fontkey']])."\n";
+		$out .= '<< /Type /Font';
+		$out .= ' /Subtype /Type0';
+		$out .= ' /BaseFont /'.$fontname;
+		$out .= ' /Name /F'.$font['i'];
+		$out .= ' /Encoding /'.$font['enc'];
+		$out .= ' /ToUnicode '.($this->n + 1).' 0 R';
+		$out .= ' /DescendantFonts ['.($this->n + 2).' 0 R]';
+		$out .= ' >>';
+		$out .= "\n".'endobj';
+		$this->_out($out);
+		// ToUnicode map for Identity-H
+		$stream = "/CIDInit /ProcSet findresource begin\n";
+		$stream .= "12 dict begin\n";
+		$stream .= "begincmap\n";
+		$stream .= "/CIDSystemInfo << /Registry (Adobe) /Ordering (UCS) /Supplement 0 >> def\n";
+		$stream .= "/CMapName /Adobe-Identity-UCS def\n";
+		$stream .= "/CMapType 2 def\n";
+		$stream .= "/WMode 0 def\n";
+		$stream .= "1 begincodespacerange\n";
+		$stream .= "<0000> <FFFF>\n";
+		$stream .= "endcodespacerange\n";
+		$stream .= "100 beginbfrange\n";
+		$stream .= "<0000> <00ff> <0000>\n";
+		$stream .= "<0100> <01ff> <0100>\n";
+		$stream .= "<0200> <02ff> <0200>\n";
+		$stream .= "<0300> <03ff> <0300>\n";
+		$stream .= "<0400> <04ff> <0400>\n";
+		$stream .= "<0500> <05ff> <0500>\n";
+		$stream .= "<0600> <06ff> <0600>\n";
+		$stream .= "<0700> <07ff> <0700>\n";
+		$stream .= "<0800> <08ff> <0800>\n";
+		$stream .= "<0900> <09ff> <0900>\n";
+		$stream .= "<0a00> <0aff> <0a00>\n";
+		$stream .= "<0b00> <0bff> <0b00>\n";
+		$stream .= "<0c00> <0cff> <0c00>\n";
+		$stream .= "<0d00> <0dff> <0d00>\n";
+		$stream .= "<0e00> <0eff> <0e00>\n";
+		$stream .= "<0f00> <0fff> <0f00>\n";
+		$stream .= "<1000> <10ff> <1000>\n";
+		$stream .= "<1100> <11ff> <1100>\n";
+		$stream .= "<1200> <12ff> <1200>\n";
+		$stream .= "<1300> <13ff> <1300>\n";
+		$stream .= "<1400> <14ff> <1400>\n";
+		$stream .= "<1500> <15ff> <1500>\n";
+		$stream .= "<1600> <16ff> <1600>\n";
+		$stream .= "<1700> <17ff> <1700>\n";
+		$stream .= "<1800> <18ff> <1800>\n";
+		$stream .= "<1900> <19ff> <1900>\n";
+		$stream .= "<1a00> <1aff> <1a00>\n";
+		$stream .= "<1b00> <1bff> <1b00>\n";
+		$stream .= "<1c00> <1cff> <1c00>\n";
+		$stream .= "<1d00> <1dff> <1d00>\n";
+		$stream .= "<1e00> <1eff> <1e00>\n";
+		$stream .= "<1f00> <1fff> <1f00>\n";
+		$stream .= "<2000> <20ff> <2000>\n";
+		$stream .= "<2100> <21ff> <2100>\n";
+		$stream .= "<2200> <22ff> <2200>\n";
+		$stream .= "<2300> <23ff> <2300>\n";
+		$stream .= "<2400> <24ff> <2400>\n";
+		$stream .= "<2500> <25ff> <2500>\n";
+		$stream .= "<2600> <26ff> <2600>\n";
+		$stream .= "<2700> <27ff> <2700>\n";
+		$stream .= "<2800> <28ff> <2800>\n";
+		$stream .= "<2900> <29ff> <2900>\n";
+		$stream .= "<2a00> <2aff> <2a00>\n";
+		$stream .= "<2b00> <2bff> <2b00>\n";
+		$stream .= "<2c00> <2cff> <2c00>\n";
+		$stream .= "<2d00> <2dff> <2d00>\n";
+		$stream .= "<2e00> <2eff> <2e00>\n";
+		$stream .= "<2f00> <2fff> <2f00>\n";
+		$stream .= "<3000> <30ff> <3000>\n";
+		$stream .= "<3100> <31ff> <3100>\n";
+		$stream .= "<3200> <32ff> <3200>\n";
+		$stream .= "<3300> <33ff> <3300>\n";
+		$stream .= "<3400> <34ff> <3400>\n";
+		$stream .= "<3500> <35ff> <3500>\n";
+		$stream .= "<3600> <36ff> <3600>\n";
+		$stream .= "<3700> <37ff> <3700>\n";
+		$stream .= "<3800> <38ff> <3800>\n";
+		$stream .= "<3900> <39ff> <3900>\n";
+		$stream .= "<3a00> <3aff> <3a00>\n";
+		$stream .= "<3b00> <3bff> <3b00>\n";
+		$stream .= "<3c00> <3cff> <3c00>\n";
+		$stream .= "<3d00> <3dff> <3d00>\n";
+		$stream .= "<3e00> <3eff> <3e00>\n";
+		$stream .= "<3f00> <3fff> <3f00>\n";
+		$stream .= "<4000> <40ff> <4000>\n";
+		$stream .= "<4100> <41ff> <4100>\n";
+		$stream .= "<4200> <42ff> <4200>\n";
+		$stream .= "<4300> <43ff> <4300>\n";
+		$stream .= "<4400> <44ff> <4400>\n";
+		$stream .= "<4500> <45ff> <4500>\n";
+		$stream .= "<4600> <46ff> <4600>\n";
+		$stream .= "<4700> <47ff> <4700>\n";
+		$stream .= "<4800> <48ff> <4800>\n";
+		$stream .= "<4900> <49ff> <4900>\n";
+		$stream .= "<4a00> <4aff> <4a00>\n";
+		$stream .= "<4b00> <4bff> <4b00>\n";
+		$stream .= "<4c00> <4cff> <4c00>\n";
+		$stream .= "<4d00> <4dff> <4d00>\n";
+		$stream .= "<4e00> <4eff> <4e00>\n";
+		$stream .= "<4f00> <4fff> <4f00>\n";
+		$stream .= "<5000> <50ff> <5000>\n";
+		$stream .= "<5100> <51ff> <5100>\n";
+		$stream .= "<5200> <52ff> <5200>\n";
+		$stream .= "<5300> <53ff> <5300>\n";
+		$stream .= "<5400> <54ff> <5400>\n";
+		$stream .= "<5500> <55ff> <5500>\n";
+		$stream .= "<5600> <56ff> <5600>\n";
+		$stream .= "<5700> <57ff> <5700>\n";
+		$stream .= "<5800> <58ff> <5800>\n";
+		$stream .= "<5900> <59ff> <5900>\n";
+		$stream .= "<5a00> <5aff> <5a00>\n";
+		$stream .= "<5b00> <5bff> <5b00>\n";
+		$stream .= "<5c00> <5cff> <5c00>\n";
+		$stream .= "<5d00> <5dff> <5d00>\n";
+		$stream .= "<5e00> <5eff> <5e00>\n";
+		$stream .= "<5f00> <5fff> <5f00>\n";
+		$stream .= "<6000> <60ff> <6000>\n";
+		$stream .= "<6100> <61ff> <6100>\n";
+		$stream .= "<6200> <62ff> <6200>\n";
+		$stream .= "<6300> <63ff> <6300>\n";
+		$stream .= "endbfrange\n";
+		$stream .= "100 beginbfrange\n";
+		$stream .= "<6400> <64ff> <6400>\n";
+		$stream .= "<6500> <65ff> <6500>\n";
+		$stream .= "<6600> <66ff> <6600>\n";
+		$stream .= "<6700> <67ff> <6700>\n";
+		$stream .= "<6800> <68ff> <6800>\n";
+		$stream .= "<6900> <69ff> <6900>\n";
+		$stream .= "<6a00> <6aff> <6a00>\n";
+		$stream .= "<6b00> <6bff> <6b00>\n";
+		$stream .= "<6c00> <6cff> <6c00>\n";
+		$stream .= "<6d00> <6dff> <6d00>\n";
+		$stream .= "<6e00> <6eff> <6e00>\n";
+		$stream .= "<6f00> <6fff> <6f00>\n";
+		$stream .= "<7000> <70ff> <7000>\n";
+		$stream .= "<7100> <71ff> <7100>\n";
+		$stream .= "<7200> <72ff> <7200>\n";
+		$stream .= "<7300> <73ff> <7300>\n";
+		$stream .= "<7400> <74ff> <7400>\n";
+		$stream .= "<7500> <75ff> <7500>\n";
+		$stream .= "<7600> <76ff> <7600>\n";
+		$stream .= "<7700> <77ff> <7700>\n";
+		$stream .= "<7800> <78ff> <7800>\n";
+		$stream .= "<7900> <79ff> <7900>\n";
+		$stream .= "<7a00> <7aff> <7a00>\n";
+		$stream .= "<7b00> <7bff> <7b00>\n";
+		$stream .= "<7c00> <7cff> <7c00>\n";
+		$stream .= "<7d00> <7dff> <7d00>\n";
+		$stream .= "<7e00> <7eff> <7e00>\n";
+		$stream .= "<7f00> <7fff> <7f00>\n";
+		$stream .= "<8000> <80ff> <8000>\n";
+		$stream .= "<8100> <81ff> <8100>\n";
+		$stream .= "<8200> <82ff> <8200>\n";
+		$stream .= "<8300> <83ff> <8300>\n";
+		$stream .= "<8400> <84ff> <8400>\n";
+		$stream .= "<8500> <85ff> <8500>\n";
+		$stream .= "<8600> <86ff> <8600>\n";
+		$stream .= "<8700> <87ff> <8700>\n";
+		$stream .= "<8800> <88ff> <8800>\n";
+		$stream .= "<8900> <89ff> <8900>\n";
+		$stream .= "<8a00> <8aff> <8a00>\n";
+		$stream .= "<8b00> <8bff> <8b00>\n";
+		$stream .= "<8c00> <8cff> <8c00>\n";
+		$stream .= "<8d00> <8dff> <8d00>\n";
+		$stream .= "<8e00> <8eff> <8e00>\n";
+		$stream .= "<8f00> <8fff> <8f00>\n";
+		$stream .= "<9000> <90ff> <9000>\n";
+		$stream .= "<9100> <91ff> <9100>\n";
+		$stream .= "<9200> <92ff> <9200>\n";
+		$stream .= "<9300> <93ff> <9300>\n";
+		$stream .= "<9400> <94ff> <9400>\n";
+		$stream .= "<9500> <95ff> <9500>\n";
+		$stream .= "<9600> <96ff> <9600>\n";
+		$stream .= "<9700> <97ff> <9700>\n";
+		$stream .= "<9800> <98ff> <9800>\n";
+		$stream .= "<9900> <99ff> <9900>\n";
+		$stream .= "<9a00> <9aff> <9a00>\n";
+		$stream .= "<9b00> <9bff> <9b00>\n";
+		$stream .= "<9c00> <9cff> <9c00>\n";
+		$stream .= "<9d00> <9dff> <9d00>\n";
+		$stream .= "<9e00> <9eff> <9e00>\n";
+		$stream .= "<9f00> <9fff> <9f00>\n";
+		$stream .= "<a000> <a0ff> <a000>\n";
+		$stream .= "<a100> <a1ff> <a100>\n";
+		$stream .= "<a200> <a2ff> <a200>\n";
+		$stream .= "<a300> <a3ff> <a300>\n";
+		$stream .= "<a400> <a4ff> <a400>\n";
+		$stream .= "<a500> <a5ff> <a500>\n";
+		$stream .= "<a600> <a6ff> <a600>\n";
+		$stream .= "<a700> <a7ff> <a700>\n";
+		$stream .= "<a800> <a8ff> <a800>\n";
+		$stream .= "<a900> <a9ff> <a900>\n";
+		$stream .= "<aa00> <aaff> <aa00>\n";
+		$stream .= "<ab00> <abff> <ab00>\n";
+		$stream .= "<ac00> <acff> <ac00>\n";
+		$stream .= "<ad00> <adff> <ad00>\n";
+		$stream .= "<ae00> <aeff> <ae00>\n";
+		$stream .= "<af00> <afff> <af00>\n";
+		$stream .= "<b000> <b0ff> <b000>\n";
+		$stream .= "<b100> <b1ff> <b100>\n";
+		$stream .= "<b200> <b2ff> <b200>\n";
+		$stream .= "<b300> <b3ff> <b300>\n";
+		$stream .= "<b400> <b4ff> <b400>\n";
+		$stream .= "<b500> <b5ff> <b500>\n";
+		$stream .= "<b600> <b6ff> <b600>\n";
+		$stream .= "<b700> <b7ff> <b700>\n";
+		$stream .= "<b800> <b8ff> <b800>\n";
+		$stream .= "<b900> <b9ff> <b900>\n";
+		$stream .= "<ba00> <baff> <ba00>\n";
+		$stream .= "<bb00> <bbff> <bb00>\n";
+		$stream .= "<bc00> <bcff> <bc00>\n";
+		$stream .= "<bd00> <bdff> <bd00>\n";
+		$stream .= "<be00> <beff> <be00>\n";
+		$stream .= "<bf00> <bfff> <bf00>\n";
+		$stream .= "<c000> <c0ff> <c000>\n";
+		$stream .= "<c100> <c1ff> <c100>\n";
+		$stream .= "<c200> <c2ff> <c200>\n";
+		$stream .= "<c300> <c3ff> <c300>\n";
+		$stream .= "<c400> <c4ff> <c400>\n";
+		$stream .= "<c500> <c5ff> <c500>\n";
+		$stream .= "<c600> <c6ff> <c600>\n";
+		$stream .= "<c700> <c7ff> <c700>\n";
+		$stream .= "endbfrange\n";
+		$stream .= "56 beginbfrange\n";
+		$stream .= "<c800> <c8ff> <c800>\n";
+		$stream .= "<c900> <c9ff> <c900>\n";
+		$stream .= "<ca00> <caff> <ca00>\n";
+		$stream .= "<cb00> <cbff> <cb00>\n";
+		$stream .= "<cc00> <ccff> <cc00>\n";
+		$stream .= "<cd00> <cdff> <cd00>\n";
+		$stream .= "<ce00> <ceff> <ce00>\n";
+		$stream .= "<cf00> <cfff> <cf00>\n";
+		$stream .= "<d000> <d0ff> <d000>\n";
+		$stream .= "<d100> <d1ff> <d100>\n";
+		$stream .= "<d200> <d2ff> <d200>\n";
+		$stream .= "<d300> <d3ff> <d300>\n";
+		$stream .= "<d400> <d4ff> <d400>\n";
+		$stream .= "<d500> <d5ff> <d500>\n";
+		$stream .= "<d600> <d6ff> <d600>\n";
+		$stream .= "<d700> <d7ff> <d700>\n";
+		$stream .= "<d800> <d8ff> <d800>\n";
+		$stream .= "<d900> <d9ff> <d900>\n";
+		$stream .= "<da00> <daff> <da00>\n";
+		$stream .= "<db00> <dbff> <db00>\n";
+		$stream .= "<dc00> <dcff> <dc00>\n";
+		$stream .= "<dd00> <ddff> <dd00>\n";
+		$stream .= "<de00> <deff> <de00>\n";
+		$stream .= "<df00> <dfff> <df00>\n";
+		$stream .= "<e000> <e0ff> <e000>\n";
+		$stream .= "<e100> <e1ff> <e100>\n";
+		$stream .= "<e200> <e2ff> <e200>\n";
+		$stream .= "<e300> <e3ff> <e300>\n";
+		$stream .= "<e400> <e4ff> <e400>\n";
+		$stream .= "<e500> <e5ff> <e500>\n";
+		$stream .= "<e600> <e6ff> <e600>\n";
+		$stream .= "<e700> <e7ff> <e700>\n";
+		$stream .= "<e800> <e8ff> <e800>\n";
+		$stream .= "<e900> <e9ff> <e900>\n";
+		$stream .= "<ea00> <eaff> <ea00>\n";
+		$stream .= "<eb00> <ebff> <eb00>\n";
+		$stream .= "<ec00> <ecff> <ec00>\n";
+		$stream .= "<ed00> <edff> <ed00>\n";
+		$stream .= "<ee00> <eeff> <ee00>\n";
+		$stream .= "<ef00> <efff> <ef00>\n";
+		$stream .= "<f000> <f0ff> <f000>\n";
+		$stream .= "<f100> <f1ff> <f100>\n";
+		$stream .= "<f200> <f2ff> <f200>\n";
+		$stream .= "<f300> <f3ff> <f300>\n";
+		$stream .= "<f400> <f4ff> <f400>\n";
+		$stream .= "<f500> <f5ff> <f500>\n";
+		$stream .= "<f600> <f6ff> <f600>\n";
+		$stream .= "<f700> <f7ff> <f700>\n";
+		$stream .= "<f800> <f8ff> <f800>\n";
+		$stream .= "<f900> <f9ff> <f900>\n";
+		$stream .= "<fa00> <faff> <fa00>\n";
+		$stream .= "<fb00> <fbff> <fb00>\n";
+		$stream .= "<fc00> <fcff> <fc00>\n";
+		$stream .= "<fd00> <fdff> <fd00>\n";
+		$stream .= "<fe00> <feff> <fe00>\n";
+		$stream .= "<ff00> <ffff> <ff00>\n";
+		$stream .= "endbfrange\n";
+		$stream .= "endcmap\n";
+		$stream .= "CMapName currentdict /CMap defineresource pop\n";
+		$stream .= "end\n";
+		$stream .= "end";
+		// ToUnicode Object
+		$this->_newobj();
+		$stream = ($this->compress) ? gzcompress($stream) : $stream;
+		$filter = ($this->compress) ? '/Filter /FlateDecode ' : '';
+		$stream = $this->_getrawstream($stream);
+		$this->_out('<<'.$filter.'/Length '.strlen($stream).'>> stream'."\n".$stream."\n".'endstream'."\n".'endobj');
+		// CIDFontType2
+		// A CIDFont whose glyph descriptions are based on TrueType font technology
+		$oid = $this->_newobj();
+		$out = '<< /Type /Font';
+		$out .= ' /Subtype /CIDFontType2';
+		$out .= ' /BaseFont /'.$fontname;
+		// A dictionary containing entries that define the character collection of the CIDFont.
+		$cidinfo = '/Registry '.$this->_datastring($font['cidinfo']['Registry'], $oid);
+		$cidinfo .= ' /Ordering '.$this->_datastring($font['cidinfo']['Ordering'], $oid);
+		$cidinfo .= ' /Supplement '.$font['cidinfo']['Supplement'];
+		$out .= ' /CIDSystemInfo << '.$cidinfo.' >>';
+		$out .= ' /FontDescriptor '.($this->n + 1).' 0 R';
+		$out .= ' /DW '.$font['dw']; // default width
+		$out .= "\n".$this->_putfontwidths($font, 0);
+		if (isset($font['ctg']) AND (!$this->empty_string($font['ctg']))) {
+			$out .= "\n".'/CIDToGIDMap '.($this->n + 2).' 0 R';
+		}
+		$out .= ' >>';
+		$out .= "\n".'endobj';
+		$this->_out($out);
+		// Font descriptor
+		// A font descriptor describing the CIDFont default metrics other than its glyph widths
+		$this->_newobj();
+		$out = '<< /Type /FontDescriptor';
+		$out .= ' /FontName /'.$fontname;
+		foreach ($font['desc'] as $key => $value) {
+			if (is_float($value)) {
+				$value = sprintf('%F', $value);
+			}
+			$out .= ' /'.$key.' '.$value;
+		}
+		$fontdir = false;
+		if (!$this->empty_string($font['file'])) {
+			// A stream containing a TrueType font
+			$out .= ' /FontFile2 '.$this->FontFiles[$font['file']]['n'].' 0 R';
+			$fontdir = $this->FontFiles[$font['file']]['fontdir'];
+		}
+		$out .= ' >>';
+		$out .= "\n".'endobj';
+		$this->_out($out);
+		if (isset($font['ctg']) AND (!$this->empty_string($font['ctg']))) {
+			$this->_newobj();
+			// Embed CIDToGIDMap
+			// A specification of the mapping from CIDs to glyph indices
+			// search and get CTG font file to embedd
+			$ctgfile = strtolower($font['ctg']);
+			// search and get ctg font file to embedd
+			$fontfile = '';
+			// search files on various directories
+			if (($fontdir !== false) AND file_exists($fontdir.$ctgfile)) {
+				$fontfile = $fontdir.$ctgfile;
+			} elseif (file_exists($this->_getfontpath().$ctgfile)) {
+				$fontfile = $this->_getfontpath().$ctgfile;
+			} elseif (file_exists($ctgfile)) {
+				$fontfile = $ctgfile;
+			}
+			if ($this->empty_string($fontfile)) {
+				$this->Error('Font file not found: '.$ctgfile);
+			}
+			$stream = $this->_getrawstream(file_get_contents($fontfile));
+			$out = '<< /Length '.strlen($stream).'';
+			if (substr($fontfile, -2) == '.z') { // check file extension
+				// Decompresses data encoded using the public-domain
+				// zlib/deflate compression method, reproducing the
+				// original text or binary data
+				$out .= ' /Filter /FlateDecode';
+			}
+			$out .= ' >>';
+			$out .= ' stream'."\n".$stream."\n".'endstream';
+			$out .= "\n".'endobj';
+			$this->_out($out);
+		}
+	}
+
+	/**
+	 * Output CID-0 fonts.
+	 * A Type 0 CIDFont contains glyph descriptions based on the Adobe Type 1 font format
+	 * @param $font (array) font data
+	 * @protected
+	 * @author Andrew Whitehead, Nicola Asuni, Yukihiro Nakadaira
+	 * @since 3.2.000 (2008-06-23)
+	 */
+	protected function _putcidfont0($font) {
+		$cidoffset = 0;
+		if (!isset($font['cw'][1])) {
+			$cidoffset = 31;
+		}
+		if (isset($font['cidinfo']['uni2cid'])) {
+			// convert unicode to cid.
+			$uni2cid = $font['cidinfo']['uni2cid'];
+			$cw = array();
+			foreach ($font['cw'] as $uni => $width) {
+				if (isset($uni2cid[$uni])) {
+					$cw[($uni2cid[$uni] + $cidoffset)] = $width;
+				} elseif ($uni < 256) {
+					$cw[$uni] = $width;
+				} // else unknown character
+			}
+			$font = array_merge($font, array('cw' => $cw));
+		}
+		$name = $font['name'];
+		$enc = $font['enc'];
+		if ($enc) {
+			$longname = $name.'-'.$enc;
+		} else {
+			$longname = $name;
+		}
+		$out = $this->_getobj($this->font_obj_ids[$font['fontkey']])."\n";
+		$out .= '<</Type /Font';
+		$out .= ' /Subtype /Type0';
+		$out .= ' /BaseFont /'.$longname;
+		$out .= ' /Name /F'.$font['i'];
+		if ($enc) {
+			$out .= ' /Encoding /'.$enc;
+		}
+		$out .= ' /DescendantFonts ['.($this->n + 1).' 0 R]';
+		$out .= ' >>';
+		$out .= "\n".'endobj';
+		$this->_out($out);
+		$oid = $this->_newobj();
+		$out = '<</Type /Font';
+		$out .= ' /Subtype /CIDFontType0';
+		$out .= ' /BaseFont /'.$name;
+		$cidinfo = '/Registry '.$this->_datastring($font['cidinfo']['Registry'], $oid);
+		$cidinfo .= ' /Ordering '.$this->_datastring($font['cidinfo']['Ordering'], $oid);
+		$cidinfo .= ' /Supplement '.$font['cidinfo']['Supplement'];
+		$out .= ' /CIDSystemInfo <<'.$cidinfo.'>>';
+		$out .= ' /FontDescriptor '.($this->n + 1).' 0 R';
+		$out .= ' /DW '.$font['dw'];
+		$out .= "\n".$this->_putfontwidths($font, $cidoffset);
+		$out .= ' >>';
+		$out .= "\n".'endobj';
+		$this->_out($out);
+		$this->_newobj();
+		$s = '<</Type /FontDescriptor /FontName /'.$name;
+		foreach ($font['desc'] as $k => $v) {
+			if ($k != 'Style') {
+				if (is_float($v)) {
+					$v = sprintf('%F', $v);
+				}
+				$s .= ' /'.$k.' '.$v.'';
+			}
+		}
+		$s .= '>>';
+		$s .= "\n".'endobj';
+		$this->_out($s);
+	}
+
+	/**
+	 * Output images.
+	 * @protected
+	 */
+	protected function _putimages() {
+		$filter = ($this->compress) ? '/Filter /FlateDecode ' : '';
+		foreach ($this->imagekeys as $file) {
+			$info = $this->getImageBuffer($file);
+			// set object for alternate images array
+			if ((!$this->pdfa_mode) AND isset($info['altimgs']) AND !empty($info['altimgs'])) {
+				$altoid = $this->_newobj();
+				$out = '[';
+				foreach ($info['altimgs'] as $altimage) {
+					if (isset($this->xobjects['I'.$altimage[0]]['n'])) {
+						$out .= ' << /Image '.$this->xobjects['I'.$altimage[0]]['n'].' 0 R';
+						$out .= ' /DefaultForPrinting';
+						if ($altimage[1] === true) {
+							$out .= ' true';
+						} else {
+							$out .= ' false';
+						}
+						$out .= ' >>';
+					}
+				}
+				$out .= ' ]';
+				$out .= "\n".'endobj';
+				$this->_out($out);
+			}
+			// set image object
+			$oid = $this->_newobj();
+			$this->xobjects['I'.$info['i']] = array('n' => $oid);
+			$this->setImageSubBuffer($file, 'n', $this->n);
+			$out = '<</Type /XObject';
+			$out .= ' /Subtype /Image';
+			$out .= ' /Width '.$info['w'];
+			$out .= ' /Height '.$info['h'];
+			if (array_key_exists('masked', $info)) {
+				$out .= ' /SMask '.($this->n - 1).' 0 R';
+			}
+			// set color space
+			$icc = false;
+			if (isset($info['icc']) AND ($info['icc'] !== false)) {
+				// ICC Colour Space
+				$icc = true;
+				$out .= ' /ColorSpace [/ICCBased '.($this->n + 1).' 0 R]';
+			} elseif ($info['cs'] == 'Indexed') {
+				// Indexed Colour Space
+				$out .= ' /ColorSpace [/Indexed /DeviceRGB '.((strlen($info['pal']) / 3) - 1).' '.($this->n + 1).' 0 R]';
+			} else {
+				// Device Colour Space
+				$out .= ' /ColorSpace /'.$info['cs'];
+			}
+			if ($info['cs'] == 'DeviceCMYK') {
+				$out .= ' /Decode [1 0 1 0 1 0 1 0]';
+			}
+			$out .= ' /BitsPerComponent '.$info['bpc'];
+			if (isset($altoid) AND ($altoid > 0)) {
+				// reference to alternate images dictionary
+				$out .= ' /Alternates '.$altoid.' 0 R';
+			}
+			if (isset($info['exurl']) AND !empty($info['exurl'])) {
+				// external stream
+				$out .= ' /Length 0';
+				$out .= ' /F << /FS /URL /F '.$this->_datastring($info['exurl'], $oid).' >>';
+				if (isset($info['f'])) {
+					$out .= ' /FFilter /'.$info['f'];
+				}
+				$out .= ' >>';
+				$out .= ' stream'."\n".'endstream';
+			} else {
+				if (isset($info['f'])) {
+					$out .= ' /Filter /'.$info['f'];
+				}
+				if (isset($info['parms'])) {
+					$out .= ' '.$info['parms'];
+				}
+				if (isset($info['trns']) AND is_array($info['trns'])) {
+					$trns = '';
+					$count_info = count($info['trns']);
+					for ($i=0; $i < $count_info; ++$i) {
+						$trns .= $info['trns'][$i].' '.$info['trns'][$i].' ';
+					}
+					$out .= ' /Mask ['.$trns.']';
+				}
+				$stream = $this->_getrawstream($info['data']);
+				$out .= ' /Length '.strlen($stream).' >>';
+				$out .= ' stream'."\n".$stream."\n".'endstream';
+			}
+			$out .= "\n".'endobj';
+			$this->_out($out);
+			if ($icc) {
+				// ICC colour profile
+				$this->_newobj();
+				$icc = ($this->compress) ? gzcompress($info['icc']) : $info['icc'];
+				$icc = $this->_getrawstream($icc);
+				$this->_out('<</N '.$info['ch'].' /Alternate /'.$info['cs'].' '.$filter.'/Length '.strlen($icc).'>> stream'."\n".$icc."\n".'endstream'."\n".'endobj');
+			} elseif ($info['cs'] == 'Indexed') {
+				// colour palette
+				$this->_newobj();
+				$pal = ($this->compress) ? gzcompress($info['pal']) : $info['pal'];
+				$pal = $this->_getrawstream($pal);
+				$this->_out('<<'.$filter.'/Length '.strlen($pal).'>> stream'."\n".$pal."\n".'endstream'."\n".'endobj');
+			}
+		}
+	}
+
+	/**
+	 * Output Form XObjects Templates.
+	 * @author Nicola Asuni
+	 * @since 5.8.017 (2010-08-24)
+	 * @protected
+	 * @see startTemplate(), endTemplate(), printTemplate()
+	 */
+	protected function _putxobjects() {
+		foreach ($this->xobjects as $key => $data) {
+			if (isset($data['outdata'])) {
+				$stream = trim($data['outdata']);
+				$out = $this->_getobj($data['n'])."\n";
+				$out .= '<<';
+				$out .= ' /Type /XObject';
+				$out .= ' /Subtype /Form';
+				$out .= ' /FormType 1';
+				if ($this->compress) {
+					$stream = gzcompress($stream);
+					$out .= ' /Filter /FlateDecode';
+				}
+				$out .= sprintf(' /BBox [%F %F %F %F]', ($data['x'] * $this->k), (-$data['y'] * $this->k), (($data['w'] + $data['x']) * $this->k), (($data['h'] - $data['y']) * $this->k));
+				$out .= ' /Matrix [1 0 0 1 0 0]';
+				$out .= ' /Resources <<';
+				$out .= ' /ProcSet [/PDF /Text /ImageB /ImageC /ImageI]';
+				if (!$this->pdfa_mode) {
+					// transparency
+					if (isset($data['extgstates']) AND !empty($data['extgstates'])) {
+						$out .= ' /ExtGState <<';
+						foreach ($data['extgstates'] as $k => $extgstate) {
+							if (isset($this->extgstates[$k]['name'])) {
+								$out .= ' /'.$this->extgstates[$k]['name'];
+							} else {
+								$out .= ' /GS'.$k;
+							}
+							$out .= ' '.$this->extgstates[$k]['n'].' 0 R';
+						}
+						$out .= ' >>';
+					}
+					if (isset($data['gradients']) AND !empty($data['gradients'])) {
+						$gp = '';
+						$gs = '';
+						foreach ($data['gradients'] as $id => $grad) {
+							// gradient patterns
+							$gp .= ' /p'.$id.' '.$this->gradients[$id]['pattern'].' 0 R';
+							// gradient shadings
+							$gs .= ' /Sh'.$id.' '.$this->gradients[$id]['id'].' 0 R';
+						}
+						$out .= ' /Pattern <<'.$gp.' >>';
+						$out .= ' /Shading <<'.$gs.' >>';
+					}
+				}
+				// spot colors
+				if (isset($data['spot_colors']) AND !empty($data['spot_colors'])) {
+					$out .= ' /ColorSpace <<';
+					foreach ($data['spot_colors'] as $name => $color) {
+						$out .= ' /CS'.$color['i'].' '.$this->spot_colors[$name]['n'].' 0 R';
+					}
+					$out .= ' >>';
+				}
+				// fonts
+				if (!empty($data['fonts'])) {
+					$out .= ' /Font <<';
+					foreach ($data['fonts'] as $fontkey => $fontid) {
+						$out .= ' /F'.$fontid.' '.$this->font_obj_ids[$fontkey].' 0 R';
+					}
+					$out .= ' >>';
+				}
+				// images or nested xobjects
+				if (!empty($data['images']) OR !empty($data['xobjects'])) {
+					$out .= ' /XObject <<';
+					foreach ($data['images'] as $imgid) {
+						$out .= ' /I'.$imgid.' '.$this->xobjects['I'.$imgid]['n'].' 0 R';
+					}
+					foreach ($data['xobjects'] as $sub_id => $sub_objid) {
+						$out .= ' /'.$sub_id.' '.$sub_objid['n'].' 0 R';
+					}
+					$out .= ' >>';
+				}
+				$out .= ' >>'; //end resources
+				if (isset($data['group']) AND ($data['group'] !== false)) {
+					// set transparency group
+					$out .= ' /Group << /Type /Group /S /Transparency';
+					if (is_array($data['group'])) {
+						if (isset($data['group']['CS']) AND !empty($data['group']['CS'])) {
+							$out .= ' /CS /'.$data['group']['CS'];
+						}
+						if (isset($data['group']['I'])) {
+							$out .= ' /I /'.($data['group']['I']===true?'true':'false');
+						}
+						if (isset($data['group']['K'])) {
+							$out .= ' /K /'.($data['group']['K']===true?'true':'false');
+						}
+					}
+					$out .= ' >>';
+				}
+				$stream = $this->_getrawstream($stream, $data['n']);
+				$out .= ' /Length '.strlen($stream);
+				$out .= ' >>';
+				$out .= ' stream'."\n".$stream."\n".'endstream';
+				$out .= "\n".'endobj';
+				$this->_out($out);
+			}
+		}
+	}
+
+	/**
+	 * Output Spot Colors Resources.
+	 * @protected
+	 * @since 4.0.024 (2008-09-12)
+	 */
+	protected function _putspotcolors() {
+		foreach ($this->spot_colors as $name => $color) {
+			$this->_newobj();
+			$this->spot_colors[$name]['n'] = $this->n;
+			$out = '[/Separation /'.str_replace(' ', '#20', $name);
+			$out .= ' /DeviceCMYK <<';
+			$out .= ' /Range [0 1 0 1 0 1 0 1] /C0 [0 0 0 0]';
+			$out .= ' '.sprintf('/C1 [%F %F %F %F] ', ($color['C'] / 100), ($color['M'] / 100), ($color['Y'] / 100), ($color['K'] / 100));
+			$out .= ' /FunctionType 2 /Domain [0 1] /N 1>>]';
+			$out .= "\n".'endobj';
+			$this->_out($out);
+		}
+	}
+
+	/**
+	 * Return XObjects Dictionary.
+	 * @return string XObjects dictionary
+	 * @protected
+	 * @since 5.8.014 (2010-08-23)
+	 */
+	protected function _getxobjectdict() {
+		$out = '';
+		foreach ($this->xobjects as $id => $objid) {
+			$out .= ' /'.$id.' '.$objid['n'].' 0 R';
+		}
+		return $out;
+	}
+
+	/**
+	 * Output Resources Dictionary.
+	 * @protected
+	 */
+	protected function _putresourcedict() {
+		$out = $this->_getobj(2)."\n";
+		$out .= '<< /ProcSet [/PDF /Text /ImageB /ImageC /ImageI]';
+		$out .= ' /Font <<';
+		foreach ($this->fontkeys as $fontkey) {
+			$font = $this->getFontBuffer($fontkey);
+			$out .= ' /F'.$font['i'].' '.$font['n'].' 0 R';
+		}
+		$out .= ' >>';
+		$out .= ' /XObject <<';
+		$out .= $this->_getxobjectdict();
+		$out .= ' >>';
+		// layers
+		if (!empty($this->pdflayers)) {
+			$out .= ' /Properties <<';
+			foreach ($this->pdflayers as $layer) {
+				$out .= ' /'.$layer['layer'].' '.$layer['objid'].' 0 R';
+			}
+			$out .= ' >>';
+		}
+		if (!$this->pdfa_mode) {
+			// transparency
+			if (isset($this->extgstates) AND !empty($this->extgstates)) {
+				$out .= ' /ExtGState <<';
+				foreach ($this->extgstates as $k => $extgstate) {
+					if (isset($extgstate['name'])) {
+						$out .= ' /'.$extgstate['name'];
+					} else {
+						$out .= ' /GS'.$k;
+					}
+					$out .= ' '.$extgstate['n'].' 0 R';
+				}
+				$out .= ' >>';
+			}
+			if (isset($this->gradients) AND !empty($this->gradients)) {
+				$gp = '';
+				$gs = '';
+				foreach ($this->gradients as $id => $grad) {
+					// gradient patterns
+					$gp .= ' /p'.$id.' '.$grad['pattern'].' 0 R';
+					// gradient shadings
+					$gs .= ' /Sh'.$id.' '.$grad['id'].' 0 R';
+				}
+				$out .= ' /Pattern <<'.$gp.' >>';
+				$out .= ' /Shading <<'.$gs.' >>';
+			}
+		}
+		// spot colors
+		if (isset($this->spot_colors) AND !empty($this->spot_colors)) {
+			$out .= ' /ColorSpace <<';
+			foreach ($this->spot_colors as $color) {
+				$out .= ' /CS'.$color['i'].' '.$color['n'].' 0 R';
+			}
+			$out .= ' >>';
+		}
+		$out .= ' >>';
+		$out .= "\n".'endobj';
+		$this->_out($out);
+	}
+
+	/**
+	 * Output Resources.
+	 * @protected
+	 */
+	protected function _putresources() {
+		$this->_putextgstates();
+		$this->_putocg();
+		$this->_putfonts();
+		$this->_putimages();
+		$this->_putspotcolors();
+		$this->_putshaders();
+		$this->_putxobjects();
+		$this->_putresourcedict();
+		$this->_putdests();
+		$this->_putEmbeddedFiles();
+		$this->_putannotsobjs();
+		$this->_putjavascript();
+		$this->_putbookmarks();
+		$this->_putencryption();
+	}
+
+	/**
+	 * Adds some Metadata information (Document Information Dictionary)
+	 * (see Chapter 14.3.3 Document Information Dictionary of PDF32000_2008.pdf Reference)
+	 * @return int object id
+	 * @protected
+	 */
+	protected function _putinfo() {
+		$oid = $this->_newobj();
+		$out = '<<';
+		// store current isunicode value
+		$prev_isunicode = $this->isunicode;
+		if ($this->docinfounicode) {
+			$this->isunicode = true;
+		}
+		if (!$this->empty_string($this->title)) {
+			// The document's title.
+			$out .= ' /Title '.$this->_textstring($this->title, $oid);
+		}
+		if (!$this->empty_string($this->author)) {
+			// The name of the person who created the document.
+			$out .= ' /Author '.$this->_textstring($this->author, $oid);
+		}
+		if (!$this->empty_string($this->subject)) {
+			// The subject of the document.
+			$out .= ' /Subject '.$this->_textstring($this->subject, $oid);
+		}
+		if (!$this->empty_string($this->keywords)) {
+			// Keywords associated with the document.
+			$out .= ' /Keywords '.$this->_textstring($this->keywords.' TCPDF', $oid);
+		}
+		if (!$this->empty_string($this->creator)) {
+			// If the document was converted to PDF from another format, the name of the conforming product that created the original document from which it was converted.
+			$out .= ' /Creator '.$this->_textstring($this->creator, $oid);
+		}
+		// restore previous isunicode value
+		$this->isunicode = $prev_isunicode;
+		// default producer
+		$out .= ' /Producer '.$this->_textstring($this->pdfproducer, $oid);
+		// The date and time the document was created, in human-readable form
+		$out .= ' /CreationDate '.$this->_datestring(0, $this->doc_creation_timestamp);
+		// The date and time the document was most recently modified, in human-readable form
+		$out .= ' /ModDate '.$this->_datestring(0, $this->doc_modification_timestamp);
+		// A name object indicating whether the document has been modified to include trapping information
+		$out .= ' /Trapped /False';
+		$out .= ' >>';
+		$out .= "\n".'endobj';
+		$this->_out($out);
+		return $oid;
+	}
+
+	/**
+	 * Set additional XMP data to be added on the default XMP data just before the end of "x:xmpmeta" tag.
+	 * IMPORTANT: This data is added as-is without controls, so you have to validate your data before using this method!
+	 * @param $xmp (string) Custom XMP data.
+	 * @since 5.9.128 (2011-10-06)
+	 * @public
+	 */
+	public function setExtraXMP($xmp) {
+		$this->custom_xmp = $xmp;
+	}
+
+	/**
+	 * Put XMP data object and return ID.
+	 * @return (int) The object ID.
+	 * @since 5.9.121 (2011-09-28)
+	 * @protected
+	 */
+	protected function _putXMP() {
+		$oid = $this->_newobj();
+		// store current isunicode value
+		$prev_isunicode = $this->isunicode;
+		$this->isunicode = true;
+		$prev_encrypted = $this->encrypted;
+		$this->encrypted = false;
+		// set XMP data
+		$xmp = '<?xpacket begin="'.$this->unichr(0xfeff).'" id="W5M0MpCehiHzreSzNTczkc9d"?>'."\n";
+		$xmp .= '<x:xmpmeta xmlns:x="adobe:ns:meta/" x:xmptk="Adobe XMP Core 4.2.1-c043 52.372728, 2009/01/18-15:08:04">'."\n";
+		$xmp .= "\t".'<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">'."\n";
+		$xmp .= "\t\t".'<rdf:Description rdf:about="" xmlns:dc="http://purl.org/dc/elements/1.1/">'."\n";
+		$xmp .= "\t\t\t".'<dc:format>application/pdf</dc:format>'."\n";
+		$xmp .= "\t\t\t".'<dc:title>'."\n";
+		$xmp .= "\t\t\t\t".'<rdf:Alt>'."\n";
+		$xmp .= "\t\t\t\t\t".'<rdf:li xml:lang="x-default">'.$this->_escapeXML($this->title).'</rdf:li>'."\n";
+		$xmp .= "\t\t\t\t".'</rdf:Alt>'."\n";
+		$xmp .= "\t\t\t".'</dc:title>'."\n";
+		$xmp .= "\t\t\t".'<dc:creator>'."\n";
+		$xmp .= "\t\t\t\t".'<rdf:Seq>'."\n";
+		$xmp .= "\t\t\t\t\t".'<rdf:li>'.$this->_escapeXML($this->author).'</rdf:li>'."\n";
+		$xmp .= "\t\t\t\t".'</rdf:Seq>'."\n";
+		$xmp .= "\t\t\t".'</dc:creator>'."\n";
+		$xmp .= "\t\t\t".'<dc:description>'."\n";
+		$xmp .= "\t\t\t\t".'<rdf:Alt>'."\n";
+		$xmp .= "\t\t\t\t\t".'<rdf:li xml:lang="x-default">'.$this->_escapeXML($this->subject).'</rdf:li>'."\n";
+		$xmp .= "\t\t\t\t".'</rdf:Alt>'."\n";
+		$xmp .= "\t\t\t".'</dc:description>'."\n";
+		$xmp .= "\t\t\t".'<dc:subject>'."\n";
+		$xmp .= "\t\t\t\t".'<rdf:Bag>'."\n";
+		$xmp .= "\t\t\t\t\t".'<rdf:li>'.$this->_escapeXML($this->keywords).' TCPDF</rdf:li>'."\n";
+		$xmp .= "\t\t\t\t".'</rdf:Bag>'."\n";
+		$xmp .= "\t\t\t".'</dc:subject>'."\n";
+		$xmp .= "\t\t".'</rdf:Description>'."\n";
+		// convert doc creation date format
+		$dcdate = $this->getFormattedDate($this->doc_creation_timestamp);
+		$doccreationdate = substr($dcdate, 0, 4).'-'.substr($dcdate, 4, 2).'-'.substr($dcdate, 6, 2);
+		$doccreationdate .= 'T'.substr($dcdate, 8, 2).':'.substr($dcdate, 10, 2).':'.substr($dcdate, 12, 2);
+		$doccreationdate .= '+'.substr($dcdate, 15, 2).':'.substr($dcdate, 18, 2);
+		$doccreationdate = $this->_escapeXML($doccreationdate);
+		// convert doc modification date format
+		$dmdate = $this->getFormattedDate($this->doc_modification_timestamp);
+		$docmoddate = substr($dmdate, 0, 4).'-'.substr($dmdate, 4, 2).'-'.substr($dmdate, 6, 2);
+		$docmoddate .= 'T'.substr($dmdate, 8, 2).':'.substr($dmdate, 10, 2).':'.substr($dmdate, 12, 2);
+		$docmoddate .= '+'.substr($dmdate, 15, 2).':'.substr($dmdate, 18, 2);
+		$docmoddate = $this->_escapeXML($docmoddate);
+		$xmp .= "\t\t".'<rdf:Description rdf:about="" xmlns:xmp="http://ns.adobe.com/xap/1.0/">'."\n";
+		$xmp .= "\t\t\t".'<xmp:CreateDate>'.$doccreationdate.'</xmp:CreateDate>'."\n";
+		$xmp .= "\t\t\t".'<xmp:CreatorTool>'.$this->creator.'</xmp:CreatorTool>'."\n";
+		$xmp .= "\t\t\t".'<xmp:ModifyDate>'.$docmoddate.'</xmp:ModifyDate>'."\n";
+		$xmp .= "\t\t\t".'<xmp:MetadataDate>'.$doccreationdate.'</xmp:MetadataDate>'."\n";
+		$xmp .= "\t\t".'</rdf:Description>'."\n";
+		$xmp .= "\t\t".'<rdf:Description rdf:about="" xmlns:pdf="http://ns.adobe.com/pdf/1.3/">'."\n";
+		$xmp .= "\t\t\t".'<pdf:Keywords>'.$this->_escapeXML($this->keywords).' TCPDF</pdf:Keywords>'."\n";
+		$xmp .= "\t\t\t".'<pdf:Producer>'.$this->_escapeXML($this->pdfproducer).'</pdf:Producer>'."\n";
+		$xmp .= "\t\t".'</rdf:Description>'."\n";
+		$xmp .= "\t\t".'<rdf:Description rdf:about="" xmlns:xmpMM="http://ns.adobe.com/xap/1.0/mm/">'."\n";
+		$uuid = 'uuid:'.substr($this->file_id, 0, 8).'-'.substr($this->file_id, 8, 4).'-'.substr($this->file_id, 12, 4).'-'.substr($this->file_id, 16, 4).'-'.substr($this->file_id, 20, 12);
+		$xmp .= "\t\t\t".'<xmpMM:DocumentID>'.$uuid.'</xmpMM:DocumentID>'."\n";
+		$xmp .= "\t\t\t".'<xmpMM:InstanceID>'.$uuid.'</xmpMM:InstanceID>'."\n";
+		$xmp .= "\t\t".'</rdf:Description>'."\n";
+		if ($this->pdfa_mode) {
+			$xmp .= "\t\t".'<rdf:Description rdf:about="" xmlns:pdfaid="http://www.aiim.org/pdfa/ns/id/">'."\n";
+			$xmp .= "\t\t\t".'<pdfaid:part>1</pdfaid:part>'."\n";
+			$xmp .= "\t\t\t".'<pdfaid:conformance>B</pdfaid:conformance>'."\n";
+			$xmp .= "\t\t".'</rdf:Description>'."\n";
+		}
+		// XMP extension schemas
+		$xmp .= "\t\t".'<rdf:Description rdf:about="" xmlns:pdfaExtension="http://www.aiim.org/pdfa/ns/extension/" xmlns:pdfaSchema="http://www.aiim.org/pdfa/ns/schema#" xmlns:pdfaProperty="http://www.aiim.org/pdfa/ns/property#">'."\n";
+		$xmp .= "\t\t\t".'<pdfaExtension:schemas>'."\n";
+		$xmp .= "\t\t\t\t".'<rdf:Bag>'."\n";
+		$xmp .= "\t\t\t\t\t".'<rdf:li rdf:parseType="Resource">'."\n";
+		$xmp .= "\t\t\t\t\t\t".'<pdfaSchema:namespaceURI>http://ns.adobe.com/pdf/1.3/</pdfaSchema:namespaceURI>'."\n";
+		$xmp .= "\t\t\t\t\t\t".'<pdfaSchema:prefix>pdf</pdfaSchema:prefix>'."\n";
+		$xmp .= "\t\t\t\t\t\t".'<pdfaSchema:schema>Adobe PDF Schema</pdfaSchema:schema>'."\n";
+		$xmp .= "\t\t\t\t\t".'</rdf:li>'."\n";
+		$xmp .= "\t\t\t\t\t".'<rdf:li rdf:parseType="Resource">'."\n";
+		$xmp .= "\t\t\t\t\t\t".'<pdfaSchema:namespaceURI>http://ns.adobe.com/xap/1.0/mm/</pdfaSchema:namespaceURI>'."\n";
+		$xmp .= "\t\t\t\t\t\t".'<pdfaSchema:prefix>xmpMM</pdfaSchema:prefix>'."\n";
+		$xmp .= "\t\t\t\t\t\t".'<pdfaSchema:schema>XMP Media Management Schema</pdfaSchema:schema>'."\n";
+		$xmp .= "\t\t\t\t\t\t".'<pdfaSchema:property>'."\n";
+		$xmp .= "\t\t\t\t\t\t\t".'<rdf:Seq>'."\n";
+		$xmp .= "\t\t\t\t\t\t\t\t".'<rdf:li rdf:parseType="Resource">'."\n";
+		$xmp .= "\t\t\t\t\t\t\t\t\t".'<pdfaProperty:category>internal</pdfaProperty:category>'."\n";
+		$xmp .= "\t\t\t\t\t\t\t\t\t".'<pdfaProperty:description>UUID based identifier for specific incarnation of a document</pdfaProperty:description>'."\n";
+		$xmp .= "\t\t\t\t\t\t\t\t\t".'<pdfaProperty:name>InstanceID</pdfaProperty:name>'."\n";
+		$xmp .= "\t\t\t\t\t\t\t\t\t".'<pdfaProperty:valueType>URI</pdfaProperty:valueType>'."\n";
+		$xmp .= "\t\t\t\t\t\t\t\t".'</rdf:li>'."\n";
+		$xmp .= "\t\t\t\t\t\t\t".'</rdf:Seq>'."\n";
+		$xmp .= "\t\t\t\t\t\t".'</pdfaSchema:property>'."\n";
+		$xmp .= "\t\t\t\t\t".'</rdf:li>'."\n";
+		$xmp .= "\t\t\t\t\t".'<rdf:li rdf:parseType="Resource">'."\n";
+		$xmp .= "\t\t\t\t\t\t".'<pdfaSchema:namespaceURI>http://www.aiim.org/pdfa/ns/id/</pdfaSchema:namespaceURI>'."\n";
+		$xmp .= "\t\t\t\t\t\t".'<pdfaSchema:prefix>pdfaid</pdfaSchema:prefix>'."\n";
+		$xmp .= "\t\t\t\t\t\t".'<pdfaSchema:schema>PDF/A ID Schema</pdfaSchema:schema>'."\n";
+		$xmp .= "\t\t\t\t\t\t".'<pdfaSchema:property>'."\n";
+		$xmp .= "\t\t\t\t\t\t\t".'<rdf:Seq>'."\n";
+		$xmp .= "\t\t\t\t\t\t\t\t".'<rdf:li rdf:parseType="Resource">'."\n";
+		$xmp .= "\t\t\t\t\t\t\t\t\t".'<pdfaProperty:category>internal</pdfaProperty:category>'."\n";
+		$xmp .= "\t\t\t\t\t\t\t\t\t".'<pdfaProperty:description>Part of PDF/A standard</pdfaProperty:description>'."\n";
+		$xmp .= "\t\t\t\t\t\t\t\t\t".'<pdfaProperty:name>part</pdfaProperty:name>'."\n";
+		$xmp .= "\t\t\t\t\t\t\t\t\t".'<pdfaProperty:valueType>Integer</pdfaProperty:valueType>'."\n";
+		$xmp .= "\t\t\t\t\t\t\t\t".'</rdf:li>'."\n";
+		$xmp .= "\t\t\t\t\t\t\t\t".'<rdf:li rdf:parseType="Resource">'."\n";
+		$xmp .= "\t\t\t\t\t\t\t\t\t".'<pdfaProperty:category>internal</pdfaProperty:category>'."\n";
+		$xmp .= "\t\t\t\t\t\t\t\t\t".'<pdfaProperty:description>Amendment of PDF/A standard</pdfaProperty:description>'."\n";
+		$xmp .= "\t\t\t\t\t\t\t\t\t".'<pdfaProperty:name>amd</pdfaProperty:name>'."\n";
+		$xmp .= "\t\t\t\t\t\t\t\t\t".'<pdfaProperty:valueType>Text</pdfaProperty:valueType>'."\n";
+		$xmp .= "\t\t\t\t\t\t\t\t".'</rdf:li>'."\n";
+		$xmp .= "\t\t\t\t\t\t\t\t".'<rdf:li rdf:parseType="Resource">'."\n";
+		$xmp .= "\t\t\t\t\t\t\t\t\t".'<pdfaProperty:category>internal</pdfaProperty:category>'."\n";
+		$xmp .= "\t\t\t\t\t\t\t\t\t".'<pdfaProperty:description>Conformance level of PDF/A standard</pdfaProperty:description>'."\n";
+		$xmp .= "\t\t\t\t\t\t\t\t\t".'<pdfaProperty:name>conformance</pdfaProperty:name>'."\n";
+		$xmp .= "\t\t\t\t\t\t\t\t\t".'<pdfaProperty:valueType>Text</pdfaProperty:valueType>'."\n";
+		$xmp .= "\t\t\t\t\t\t\t\t".'</rdf:li>'."\n";
+		$xmp .= "\t\t\t\t\t\t\t".'</rdf:Seq>'."\n";
+		$xmp .= "\t\t\t\t\t\t".'</pdfaSchema:property>'."\n";
+		$xmp .= "\t\t\t\t\t".'</rdf:li>'."\n";
+		$xmp .= "\t\t\t\t".'</rdf:Bag>'."\n";
+		$xmp .= "\t\t\t".'</pdfaExtension:schemas>'."\n";
+		$xmp .= "\t\t".'</rdf:Description>'."\n";
+		$xmp .= "\t".'</rdf:RDF>'."\n";
+		$xmp .= $this->custom_xmp;
+		$xmp .= '</x:xmpmeta>'."\n";
+		$xmp .= '<?xpacket end="w"?>';
+		$out = '<< /Type /Metadata /Subtype /XML /Length '.strlen($xmp).' >> stream'."\n".$xmp."\n".'endstream'."\n".'endobj';
+		// restore previous isunicode value
+		$this->isunicode = $prev_isunicode;
+		$this->encrypted = $prev_encrypted;
+		$this->_out($out);
+		return $oid;
+	}
+
+	/**
+	 * Output Catalog.
+	 * @return int object id
+	 * @protected
+	 */
+	protected function _putcatalog() {
+		// put XMP
+		$xmpobj = $this->_putXMP();
+		// if required, add standard sRGB_IEC61966-2.1 blackscaled ICC colour profile
+		if ($this->pdfa_mode OR $this->force_srgb) {
+			$iccobj = $this->_newobj();
+			$icc = file_get_contents(dirname(__FILE__).'/sRGB.icc');
+			$filter = '';
+			if ($this->compress) {
+				$filter = ' /Filter /FlateDecode';
+				$icc = gzcompress($icc);
+			}
+			$icc = $this->_getrawstream($icc);
+			$this->_out('<</N 3 '.$filter.'/Length '.strlen($icc).'>> stream'."\n".$icc."\n".'endstream'."\n".'endobj');
+		}
+		// start catalog
+		$oid = $this->_newobj();
+		$out = '<< /Type /Catalog';
+		$out .= ' /Version /'.$this->PDFVersion;
+		//$out .= ' /Extensions <<>>';
+		$out .= ' /Pages 1 0 R';
+		//$out .= ' /PageLabels ' //...;
+		$out .= ' /Names <<';
+		if ((!$this->pdfa_mode) AND !empty($this->n_js)) {
+			$out .= ' /JavaScript '.$this->n_js;
+		}
+		if (!empty($this->efnames)) {
+			$out .= ' /EmbeddedFiles <</Names [';
+			foreach ($this->efnames AS $fn => $fref) {
+				$out .= ' '.$this->_datastring($fn).' '.$fref;
+			}
+			$out .= ' ]>>';
+		}
+		$out .= ' >>';
+		if (!empty($this->dests)) {
+			$out .= ' /Dests '.($this->n_dests).' 0 R';
+		}
+		$out .= $this->_putviewerpreferences();
+		if (isset($this->LayoutMode) AND (!$this->empty_string($this->LayoutMode))) {
+			$out .= ' /PageLayout /'.$this->LayoutMode;
+		}
+		if (isset($this->PageMode) AND (!$this->empty_string($this->PageMode))) {
+			$out .= ' /PageMode /'.$this->PageMode;
+		}
+		if (count($this->outlines) > 0) {
+			$out .= ' /Outlines '.$this->OutlineRoot.' 0 R';
+			$out .= ' /PageMode /UseOutlines';
+		}
+		//$out .= ' /Threads []';
+		if ($this->ZoomMode == 'fullpage') {
+			$out .= ' /OpenAction ['.$this->page_obj_id[1].' 0 R /Fit]';
+		} elseif ($this->ZoomMode == 'fullwidth') {
+			$out .= ' /OpenAction ['.$this->page_obj_id[1].' 0 R /FitH null]';
+		} elseif ($this->ZoomMode == 'real') {
+			$out .= ' /OpenAction ['.$this->page_obj_id[1].' 0 R /XYZ null null 1]';
+		} elseif (!is_string($this->ZoomMode)) {
+			$out .= sprintf(' /OpenAction ['.$this->page_obj_id[1].' 0 R /XYZ null null %F]', ($this->ZoomMode / 100));
+		}
+		//$out .= ' /AA <<>>';
+		//$out .= ' /URI <<>>';
+		$out .= ' /Metadata '.$xmpobj.' 0 R';
+		//$out .= ' /StructTreeRoot <<>>';
+		//$out .= ' /MarkInfo <<>>';
+		if (isset($this->l['a_meta_language'])) {
+			$out .= ' /Lang '.$this->_textstring($this->l['a_meta_language'], $oid);
+		}
+		//$out .= ' /SpiderInfo <<>>';
+		// set OutputIntent to sRGB IEC61966-2.1 if required
+		if ($this->pdfa_mode OR $this->force_srgb) {
+			$out .= ' /OutputIntents [<<';
+			$out .= ' /Type /OutputIntent';
+			$out .= ' /S /GTS_PDFA1';
+			$out .= ' /OutputCondition '.$this->_textstring('sRGB IEC61966-2.1', $oid);
+			$out .= ' /OutputConditionIdentifier '.$this->_textstring('sRGB IEC61966-2.1', $oid);
+			$out .= ' /RegistryName '.$this->_textstring('http://www.color.org', $oid);
+			$out .= ' /Info '.$this->_textstring('sRGB IEC61966-2.1', $oid);
+			$out .= ' /DestOutputProfile '.$iccobj.' 0 R';
+			$out .= ' >>]';
+		}
+		//$out .= ' /PieceInfo <<>>';
+		if (!empty($this->pdflayers)) {
+			$lyrobjs = '';
+			$lyrobjs_print = '';
+			$lyrobjs_view = '';
+			foreach ($this->pdflayers as $layer) {
+				$lyrobjs .= ' '.$layer['objid'].' 0 R';
+				if ($layer['print']) {
+					$lyrobjs_print .= ' '.$layer['objid'].' 0 R';
+				}
+				if ($layer['view']) {
+					$lyrobjs_view .= ' '.$layer['objid'].' 0 R';
+				}
+			}
+			$out .= ' /OCProperties << /OCGs ['.$lyrobjs.']';
+			$out .= ' /D <<';
+			$out .= ' /Name '.$this->_textstring('Layers', $oid);
+			$out .= ' /Creator '.$this->_textstring('TCPDF', $oid);
+			$out .= ' /BaseState /ON';
+			$out .= ' /ON ['.$lyrobjs_print.']';
+			$out .= ' /OFF ['.$lyrobjs_view.']';
+			$out .= ' /Intent /View';
+			$out .= ' /AS [';
+			$out .= ' << /Event /Print /OCGs ['.$lyrobjs.'] /Category [/Print] >>';
+			$out .= ' << /Event /View /OCGs ['.$lyrobjs.'] /Category [/View] >>';
+			$out .= ' ]';
+			$out .= ' /Order ['.$lyrobjs.']';
+			$out .= ' /ListMode /AllPages';
+			//$out .= ' /RBGroups ['..']';
+			//$out .= ' /Locked ['..']';
+			$out .= ' >>';
+			$out .= ' >>';
+		}
+		// AcroForm
+		if (!empty($this->form_obj_id) OR ($this->sign AND isset($this->signature_data['cert_type']))) {
+			$out .= ' /AcroForm <<';
+			$objrefs = '';
+			if ($this->sign AND isset($this->signature_data['cert_type'])) {
+				// set reference for signature object
+				$objrefs .= $this->sig_obj_id.' 0 R';
+			}
+			if (!empty($this->empty_signature_appearance)) {
+				foreach ($this->empty_signature_appearance as $esa) {
+					// set reference for empty signature objects
+					$objrefs .= ' '.$esa['objid'].' 0 R';
+				}
+			}
+			if (!empty($this->form_obj_id)) {
+				foreach($this->form_obj_id as $objid) {
+					$objrefs .= ' '.$objid.' 0 R';
+				}
+			}
+			$out .= ' /Fields ['.$objrefs.']';
+			// It's better to turn off this value and set the appearance stream for each annotation (/AP) to avoid conflicts with signature fields.
+			$out .= ' /NeedAppearances false';
+			if ($this->sign AND isset($this->signature_data['cert_type'])) {
+				if ($this->signature_data['cert_type'] > 0) {
+					$out .= ' /SigFlags 3';
+				} else {
+					$out .= ' /SigFlags 1';
+				}
+			}
+			//$out .= ' /CO ';
+			if (isset($this->annotation_fonts) AND !empty($this->annotation_fonts)) {
+				$out .= ' /DR <<';
+				$out .= ' /Font <<';
+				foreach ($this->annotation_fonts as $fontkey => $fontid) {
+					$out .= ' /F'.$fontid.' '.$this->font_obj_ids[$fontkey].' 0 R';
+				}
+				$out .= ' >> >>';
+			}
+			$font = $this->getFontBuffer('helvetica');
+			$out .= ' /DA (/F'.$font['i'].' 0 Tf 0 g)';
+			$out .= ' /Q '.(($this->rtl)?'2':'0');
+			//$out .= ' /XFA ';
+			$out .= ' >>';
+			// signatures
+			if ($this->sign AND isset($this->signature_data['cert_type'])) {
+				if ($this->signature_data['cert_type'] > 0) {
+					$out .= ' /Perms << /DocMDP '.($this->sig_obj_id + 1).' 0 R >>';
+				} else {
+					$out .= ' /Perms << /UR3 '.($this->sig_obj_id + 1).' 0 R >>';
+				}
+			}
+		}
+		//$out .= ' /Legal <<>>';
+		//$out .= ' /Requirements []';
+		//$out .= ' /Collection <<>>';
+		//$out .= ' /NeedsRendering true';
+		$out .= ' >>';
+		$out .= "\n".'endobj';
+		$this->_out($out);
+		return $oid;
+	}
+
+	/**
+	 * Output viewer preferences.
+	 * @return string for viewer preferences
+	 * @author Nicola asuni
+	 * @since 3.1.000 (2008-06-09)
+	 * @protected
+	 */
+	protected function _putviewerpreferences() {
+		$out = ' /ViewerPreferences <<';
+		if ($this->rtl) {
+			$out .= ' /Direction /R2L';
+		} else {
+			$out .= ' /Direction /L2R';
+		}
+		if (isset($this->viewer_preferences['HideToolbar']) AND ($this->viewer_preferences['HideToolbar'])) {
+			$out .= ' /HideToolbar true';
+		}
+		if (isset($this->viewer_preferences['HideMenubar']) AND ($this->viewer_preferences['HideMenubar'])) {
+			$out .= ' /HideMenubar true';
+		}
+		if (isset($this->viewer_preferences['HideWindowUI']) AND ($this->viewer_preferences['HideWindowUI'])) {
+			$out .= ' /HideWindowUI true';
+		}
+		if (isset($this->viewer_preferences['FitWindow']) AND ($this->viewer_preferences['FitWindow'])) {
+			$out .= ' /FitWindow true';
+		}
+		if (isset($this->viewer_preferences['CenterWindow']) AND ($this->viewer_preferences['CenterWindow'])) {
+			$out .= ' /CenterWindow true';
+		}
+		if (isset($this->viewer_preferences['DisplayDocTitle']) AND ($this->viewer_preferences['DisplayDocTitle'])) {
+			$out .= ' /DisplayDocTitle true';
+		}
+		if (isset($this->viewer_preferences['NonFullScreenPageMode'])) {
+			$out .= ' /NonFullScreenPageMode /'.$this->viewer_preferences['NonFullScreenPageMode'];
+		}
+		if (isset($this->viewer_preferences['ViewArea'])) {
+			$out .= ' /ViewArea /'.$this->viewer_preferences['ViewArea'];
+		}
+		if (isset($this->viewer_preferences['ViewClip'])) {
+			$out .= ' /ViewClip /'.$this->viewer_preferences['ViewClip'];
+		}
+		if (isset($this->viewer_preferences['PrintArea'])) {
+			$out .= ' /PrintArea /'.$this->viewer_preferences['PrintArea'];
+		}
+		if (isset($this->viewer_preferences['PrintClip'])) {
+			$out .= ' /PrintClip /'.$this->viewer_preferences['PrintClip'];
+		}
+		if (isset($this->viewer_preferences['PrintScaling'])) {
+			$out .= ' /PrintScaling /'.$this->viewer_preferences['PrintScaling'];
+		}
+		if (isset($this->viewer_preferences['Duplex']) AND (!$this->empty_string($this->viewer_preferences['Duplex']))) {
+			$out .= ' /Duplex /'.$this->viewer_preferences['Duplex'];
+		}
+		if (isset($this->viewer_preferences['PickTrayByPDFSize'])) {
+			if ($this->viewer_preferences['PickTrayByPDFSize']) {
+				$out .= ' /PickTrayByPDFSize true';
+			} else {
+				$out .= ' /PickTrayByPDFSize false';
+			}
+		}
+		if (isset($this->viewer_preferences['PrintPageRange'])) {
+			$PrintPageRangeNum = '';
+			foreach ($this->viewer_preferences['PrintPageRange'] as $k => $v) {
+				$PrintPageRangeNum .= ' '.($v - 1).'';
+			}
+			$out .= ' /PrintPageRange ['.substr($PrintPageRangeNum,1).']';
+		}
+		if (isset($this->viewer_preferences['NumCopies'])) {
+			$out .= ' /NumCopies '.intval($this->viewer_preferences['NumCopies']);
+		}
+		$out .= ' >>';
+		return $out;
+	}
+
+	/**
+	 * Output PDF File Header (7.5.2).
+	 * @protected
+	 */
+	protected function _putheader() {
+		$this->_out('%PDF-'.$this->PDFVersion);
+		$this->_out('%'.chr(0xe2).chr(0xe3).chr(0xcf).chr(0xd3));
+	}
+
+	/**
+	 * Output end of document (EOF).
+	 * @protected
+	 */
+	protected function _enddoc() {
+		$this->state = 1;
+		$this->_putheader();
+		$this->_putpages();
+		$this->_putresources();
+		// empty signature fields
+		if (!empty($this->empty_signature_appearance)) {
+			foreach ($this->empty_signature_appearance as $key => $esa) {
+				// widget annotation for empty signature
+				$out = $this->_getobj($esa['objid'])."\n";
+				$out .= '<< /Type /Annot';
+				$out .= ' /Subtype /Widget';
+				$out .= ' /Rect ['.$esa['rect'].']';
+				$out .= ' /P '.$this->page_obj_id[($esa['page'])].' 0 R'; // link to signature appearance page
+				$out .= ' /F 4';
+				$out .= ' /FT /Sig';
+				$signame = sprintf('Signature_%03d', ($key + 1));
+				$out .= ' /T '.$this->_textstring($signame, $esa['objid']);
+				$out .= ' /Ff 0';
+				$out .= ' >>';
+				$out .= "\n".'endobj';
+				$this->_out($out);
+			}
+		}
+		// Signature
+		if ($this->sign AND isset($this->signature_data['cert_type'])) {
+			// widget annotation for signature
+			$out = $this->_getobj($this->sig_obj_id)."\n";
+			$out .= '<< /Type /Annot';
+			$out .= ' /Subtype /Widget';
+			$out .= ' /Rect ['.$this->signature_appearance['rect'].']';
+			$out .= ' /P '.$this->page_obj_id[($this->signature_appearance['page'])].' 0 R'; // link to signature appearance page
+			$out .= ' /F 4';
+			$out .= ' /FT /Sig';
+			$out .= ' /T '.$this->_textstring('Signature_000', $this->sig_obj_id);
+			$out .= ' /Ff 0';
+			$out .= ' /V '.($this->sig_obj_id + 1).' 0 R';
+			$out .= ' >>';
+			$out .= "\n".'endobj';
+			$this->_out($out);
+			// signature
+			$this->_putsignature();
+		}
+		// Info
+		$objid_info = $this->_putinfo();
+		// Catalog
+		$objid_catalog = $this->_putcatalog();
+		// Cross-ref
+		$o = $this->bufferlen;
+		// XREF section
+		$this->_out('xref');
+		$this->_out('0 '.($this->n + 1));
+		$this->_out('0000000000 65535 f ');
+		$freegen = ($this->n + 2);
+		for ($i=1; $i <= $this->n; ++$i) {
+			if (!isset($this->offsets[$i]) AND ($i > 1)) {
+				$this->_out(sprintf('0000000000 %05d f ', $freegen));
+				++$freegen;
+			} else {
+				$this->_out(sprintf('%010d 00000 n ', $this->offsets[$i]));
+			}
+		}
+		// TRAILER
+		$out = 'trailer'."\n";
+		$out .= '<<';
+		$out .= ' /Size '.($this->n + 1);
+		$out .= ' /Root '.$objid_catalog.' 0 R';
+		$out .= ' /Info '.$objid_info.' 0 R';
+		if ($this->encrypted) {
+			$out .= ' /Encrypt '.$this->encryptdata['objid'].' 0 R';
+		}
+		$out .= ' /ID [ <'.$this->file_id.'> <'.$this->file_id.'> ]';
+		$out .= ' >>';
+		$this->_out($out);
+		$this->_out('startxref');
+		$this->_out($o);
+		$this->_out('%%EOF');
+		$this->state = 3; // end-of-doc
+		if ($this->diskcache) {
+			// remove temporary files used for images
+			foreach ($this->imagekeys as $key) {
+				// remove temporary files
+				unlink($this->images[$key]);
+			}
+			foreach ($this->fontkeys as $key) {
+				// remove temporary files
+				unlink($this->fonts[$key]);
+			}
+		}
+	}
+
+	/**
+	 * Initialize a new page.
+	 * @param $orientation (string) page orientation. Possible values are (case insensitive):<ul><li>P or PORTRAIT (default)</li><li>L or LANDSCAPE</li></ul>
+	 * @param $format (mixed) The format used for pages. It can be either: one of the string values specified at getPageSizeFromFormat() or an array of parameters specified at setPageFormat().
+	 * @protected
+	 * @see getPageSizeFromFormat(), setPageFormat()
+	 */
+	protected function _beginpage($orientation='', $format='') {
+		++$this->page;
+		$this->pageobjects[$this->page] = array();
+		$this->setPageBuffer($this->page, '');
+		// initialize array for graphics tranformation positions inside a page buffer
+		$this->transfmrk[$this->page] = array();
+		$this->state = 2;
+		if ($this->empty_string($orientation)) {
+			if (isset($this->CurOrientation)) {
+				$orientation = $this->CurOrientation;
+			} elseif ($this->fwPt > $this->fhPt) {
+				// landscape
+				$orientation = 'L';
+			} else {
+				// portrait
+				$orientation = 'P';
+			}
+		}
+		if ($this->empty_string($format)) {
+			$this->pagedim[$this->page] = $this->pagedim[($this->page - 1)];
+			$this->setPageOrientation($orientation);
+		} else {
+			$this->setPageFormat($format, $orientation);
+		}
+		if ($this->rtl) {
+			$this->x = $this->w - $this->rMargin;
+		} else {
+			$this->x = $this->lMargin;
+		}
+		$this->y = $this->tMargin;
+		if (isset($this->newpagegroup[$this->page])) {
+			// start a new group
+			$this->currpagegroup = $this->newpagegroup[$this->page];
+			$this->pagegroups[$this->currpagegroup] = 1;
+		} elseif (isset($this->currpagegroup) AND ($this->currpagegroup > 0)) {
+			++$this->pagegroups[$this->currpagegroup];
+		}
+	}
+
+	/**
+	 * Mark end of page.
+	 * @protected
+	 */
+	protected function _endpage() {
+		$this->setVisibility('all');
+		$this->state = 1;
+	}
+
+	/**
+	 * Begin a new object and return the object number.
+	 * @return int object number
+	 * @protected
+	 */
+	protected function _newobj() {
+		$this->_out($this->_getobj());
+		return $this->n;
+	}
+
+	/**
+	 * Return the starting object string for the selected object ID.
+	 * @param $objid (int) Object ID (leave empty to get a new ID).
+	 * @return string the starting object string
+	 * @protected
+	 * @since 5.8.009 (2010-08-20)
+	 */
+	protected function _getobj($objid='') {
+		if ($objid === '') {
+			++$this->n;
+			$objid = $this->n;
+		}
+		$this->offsets[$objid] = $this->bufferlen;
+		$this->pageobjects[$this->page][] = $objid;
+		return $objid.' 0 obj';
+	}
+
+	/**
+	 * Underline text.
+	 * @param $x (int) X coordinate
+	 * @param $y (int) Y coordinate
+	 * @param $txt (string) text to underline
+	 * @protected
+	 */
+	protected function _dounderline($x, $y, $txt) {
+		$w = $this->GetStringWidth($txt);
+		return $this->_dounderlinew($x, $y, $w);
+	}
+
+	/**
+	 * Underline for rectangular text area.
+	 * @param $x (int) X coordinate
+	 * @param $y (int) Y coordinate
+	 * @param $w (int) width to underline
+	 * @protected
+	 * @since 4.8.008 (2009-09-29)
+	 */
+	protected function _dounderlinew($x, $y, $w) {
+		$linew = - $this->CurrentFont['ut'] / 1000 * $this->FontSizePt;
+		return sprintf('%F %F %F %F re f', $x * $this->k, ((($this->h - $y) * $this->k) + $linew), $w * $this->k, $linew);
+	}
+
+	/**
+	 * Line through text.
+	 * @param $x (int) X coordinate
+	 * @param $y (int) Y coordinate
+	 * @param $txt (string) text to linethrough
+	 * @protected
+	 */
+	protected function _dolinethrough($x, $y, $txt) {
+		$w = $this->GetStringWidth($txt);
+		return $this->_dolinethroughw($x, $y, $w);
+	}
+
+	/**
+	 * Line through for rectangular text area.
+	 * @param $x (int) X coordinate
+	 * @param $y (int) Y coordinate
+	 * @param $w (int) line length (width)
+	 * @protected
+	 * @since 4.9.008 (2009-09-29)
+	 */
+	protected function _dolinethroughw($x, $y, $w) {
+		$linew = - $this->CurrentFont['ut'] / 1000 * $this->FontSizePt;
+		return sprintf('%F %F %F %F re f', $x * $this->k, ((($this->h - $y) * $this->k) + $linew + ($this->FontSizePt / 3)), $w * $this->k, $linew);
+	}
+
+	/**
+	 * Overline text.
+	 * @param $x (int) X coordinate
+	 * @param $y (int) Y coordinate
+	 * @param $txt (string) text to overline
+	 * @protected
+	 * @since 4.9.015 (2010-04-19)
+	 */
+	protected function _dooverline($x, $y, $txt) {
+		$w = $this->GetStringWidth($txt);
+		return $this->_dooverlinew($x, $y, $w);
+	}
+
+	/**
+	 * Overline for rectangular text area.
+	 * @param $x (int) X coordinate
+	 * @param $y (int) Y coordinate
+	 * @param $w (int) width to overline
+	 * @protected
+	 * @since 4.9.015 (2010-04-19)
+	 */
+	protected function _dooverlinew($x, $y, $w) {
+		$linew = - $this->CurrentFont['ut'] / 1000 * $this->FontSizePt;
+		return sprintf('%F %F %F %F re f', $x * $this->k, (($this->h - $y + $this->FontAscent) * $this->k) - $linew, $w * $this->k, $linew);
+
+	}
+
+	/**
+	 * Read a 4-byte (32 bit) integer from file.
+	 * @param $f (string) file name.
+	 * @return 4-byte integer
+	 * @protected
+	 */
+	protected function _freadint($f) {
+		$a = unpack('Ni', fread($f, 4));
+		return $a['i'];
+	}
+
+	/**
+	 * Add "\" before "\", "(" and ")"
+	 * @param $s (string) string to escape.
+	 * @return string escaped string.
+	 * @protected
+	 */
+	protected function _escape($s) {
+		// the chr(13) substitution fixes the Bugs item #1421290.
+		return strtr($s, array(')' => '\\)', '(' => '\\(', '\\' => '\\\\', chr(13) => '\r'));
+	}
+
+	/**
+	 * Format a data string for meta information
+	 * @param $s (string) data string to escape.
+	 * @param $n (int) object ID
+	 * @return string escaped string.
+	 * @protected
+	 */
+	protected function _datastring($s, $n=0) {
+		if ($n == 0) {
+			$n = $this->n;
+		}
+		$s = $this->_encrypt_data($n, $s);
+		return '('. $this->_escape($s).')';
+	}
+
+	/**
+	 * Set the document creation timestamp
+	 * @param $time (mixed) Document creation timestamp in seconds or date-time string.
+	 * @public
+	 * @since 5.9.152 (2012-03-23)
+	 */
+	public function setDocCreationTimestamp($time) {
+		if (is_string($time)) {
+			$time = getTimestamp($time);
+		}
+		$this->doc_creation_timestamp = intval($time);
+	}
+
+	/**
+	 * Set the document modification timestamp
+	 * @param $time (mixed) Document modification timestamp in seconds or date-time string.
+	 * @public
+	 * @since 5.9.152 (2012-03-23)
+	 */
+	public function setDocModificationTimestamp($time) {
+		if (is_string($time)) {
+			$time = getTimestamp($time);
+		}
+		$this->doc_modification_timestamp = intval($time);
+	}
+
+	/**
+	 * Returns document creation timestamp in seconds.
+	 * @return (int) Creation timestamp in seconds.
+	 * @public
+	 * @since 5.9.152 (2012-03-23)
+	 */
+	public function getDocCreationTimestamp() {
+		return $this->doc_creation_timestamp;
+	}
+
+	/**
+	 * Returns document modification timestamp in seconds.
+	 * @return (int) Modfication timestamp in seconds.
+	 * @public
+	 * @since 5.9.152 (2012-03-23)
+	 */
+	public function getDocModificationTimestamp() {
+		return $this->doc_modification_timestamp;
+	}
+
+	/**
+	 * Returns timestamp in seconds from formatted date-time.
+	 * @param $date (string) Formatted date-time.
+	 * @return int seconds.
+	 * @public
+	 * @since 5.9.152 (2012-03-23)
+	 */
+	public function getTimestamp($date) {
+		if (($date[0] == 'D') AND ($date[1] == ':')) {
+			// remove date prefix if present
+			$date = substr($date, 2);
+		}
+		return strtotime($date);
+	}
+
+	/**
+	 * Returns a formatted date-time.
+	 * @param $time (int) Time in seconds.
+	 * @return string escaped date string.
+	 * @public
+	 * @since 5.9.152 (2012-03-23)
+	 */
+	public function getFormattedDate($time) {
+		return substr_replace(date('YmdHisO', intval($time)), '\'', (0 - 2), 0).'\'';
+	}
+
+	/**
+	 * Returns a formatted date for meta information
+	 * @param $n (int) Object ID.
+	 * @param $timestamp (int) Timestamp to convert.
+	 * @return string escaped date string.
+	 * @protected
+	 * @since 4.6.028 (2009-08-25)
+	 */
+	protected function _datestring($n=0, $timestamp=0) {
+		if ((empty($timestamp)) OR ($timestamp < 0)) {
+			$timestamp = $this->doc_creation_timestamp;
+		}
+		return $this->_datastring('D:'.$this->getFormattedDate($timestamp), $n);
+	}
+
+	/**
+	 * Format a text string for meta information
+	 * @param $s (string) string to escape.
+	 * @param $n (int) object ID
+	 * @return string escaped string.
+	 * @protected
+	 */
+	protected function _textstring($s, $n=0) {
+		if ($this->isunicode) {
+			//Convert string to UTF-16BE
+			$s = $this->UTF8ToUTF16BE($s, true);
+		}
+		return $this->_datastring($s, $n);
+	}
+
+	/**
+	 * THIS METHOD IS DEPRECATED
+	 * Format a text string
+	 * @param $s (string) string to escape.
+	 * @return string escaped string.
+	 * @protected
+	 * @deprecated
+	 */
+	protected function _escapetext($s) {
+		if ($this->isunicode) {
+			if (($this->CurrentFont['type'] == 'core') OR ($this->CurrentFont['type'] == 'TrueType') OR ($this->CurrentFont['type'] == 'Type1')) {
+				$s = $this->UTF8ToLatin1($s);
+			} else {
+				//Convert string to UTF-16BE and reverse RTL language
+				$s = $this->utf8StrRev($s, false, $this->tmprtl);
+			}
+		}
+		return $this->_escape($s);
+	}
+
+	/**
+	* Escape some special characters (< > &) for XML output.
+	* @param $str (string) Input string to convert.
+	* @return converted string
+	* @since 5.9.121 (2011-09-28)
+	* @protected
+	*/
+	protected function _escapeXML($str) {
+		$replaceTable = array("\0" => '', '&' => '&', '<' => '<', '>' => '>');
+		$str = strtr($str, $replaceTable);
+		return $str;
+	}
+
+	/**
+	 * get raw output stream.
+	 * @param $s (string) string to output.
+	 * @param $n (int) object reference for encryption mode
+	 * @protected
+	 * @author Nicola Asuni
+	 * @since 5.5.000 (2010-06-22)
+	 */
+	protected function _getrawstream($s, $n=0) {
+		if ($n <= 0) {
+			// default to current object
+			$n = $this->n;
+		}
+		return $this->_encrypt_data($n, $s);
+	}
+
+	/**
+	 * Format output stream (DEPRECATED).
+	 * @param $s (string) string to output.
+	 * @param $n (int) object reference for encryption mode
+	 * @protected
+	 * @deprecated
+	 */
+	protected function _getstream($s, $n=0) {
+		return 'stream'."\n".$this->_getrawstream($s, $n)."\n".'endstream';
+	}
+
+	/**
+	 * Output a stream (DEPRECATED).
+	 * @param $s (string) string to output.
+	 * @param $n (int) object reference for encryption mode
+	 * @protected
+	 * @deprecated
+	 */
+	protected function _putstream($s, $n=0) {
+		$this->_out($this->_getstream($s, $n));
+	}
+
+	/**
+	 * Output a string to the document.
+	 * @param $s (string) string to output.
+	 * @protected
+	 */
+	protected function _out($s) {
+		if ($this->state == 2) {
+			if ($this->inxobj) {
+				// we are inside an XObject template
+				$this->xobjects[$this->xobjid]['outdata'] .= $s."\n";
+			} elseif ((!$this->InFooter) AND isset($this->footerlen[$this->page]) AND ($this->footerlen[$this->page] > 0)) {
+				// puts data before page footer
+				$pagebuff = $this->getPageBuffer($this->page);
+				$page = substr($pagebuff, 0, -$this->footerlen[$this->page]);
+				$footer = substr($pagebuff, -$this->footerlen[$this->page]);
+				$this->setPageBuffer($this->page, $page.$s."\n".$footer);
+				// update footer position
+				$this->footerpos[$this->page] += strlen($s."\n");
+			} else {
+				// set page data
+				$this->setPageBuffer($this->page, $s."\n", true);
+			}
+		} elseif ($this->state > 0) {
+			// set general data
+			$this->setBuffer($s."\n");
+		}
+	}
+
+	/**
+	 * Converts UTF-8 strings to codepoints array.<br>
+	 * Invalid byte sequences will be replaced with 0xFFFD (replacement character)<br>
+	 * Based on: http://www.faqs.org/rfcs/rfc3629.html
+	 * <pre>
+	 *    Char. number range  |        UTF-8 octet sequence
+	 *       (hexadecimal)    |              (binary)
+	 *    --------------------+-----------------------------------------------
+	 *    0000 0000-0000 007F | 0xxxxxxx
+	 *    0000 0080-0000 07FF | 110xxxxx 10xxxxxx
+	 *    0000 0800-0000 FFFF | 1110xxxx 10xxxxxx 10xxxxxx
+	 *    0001 0000-0010 FFFF | 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
+	 *    ---------------------------------------------------------------------
+	 *
+	 *   ABFN notation:
+	 *   ---------------------------------------------------------------------
+	 *   UTF8-octets = *( UTF8-char )
+	 *   UTF8-char   = UTF8-1 / UTF8-2 / UTF8-3 / UTF8-4
+	 *   UTF8-1      = %x00-7F
+	 *   UTF8-2      = %xC2-DF UTF8-tail
+	 *
+	 *   UTF8-3      = %xE0 %xA0-BF UTF8-tail / %xE1-EC 2( UTF8-tail ) /
+	 *                 %xED %x80-9F UTF8-tail / %xEE-EF 2( UTF8-tail )
+	 *   UTF8-4      = %xF0 %x90-BF 2( UTF8-tail ) / %xF1-F3 3( UTF8-tail ) /
+	 *                 %xF4 %x80-8F 2( UTF8-tail )
+	 *   UTF8-tail   = %x80-BF
+	 *   ---------------------------------------------------------------------
+	 * </pre>
+	 * @param $str (string) string to process.
+	 * @return array containing codepoints (UTF-8 characters values)
+	 * @protected
+	 * @author Nicola Asuni
+	 * @since 1.53.0.TC005 (2005-01-05)
+	 */
+	protected function UTF8StringToArray($str) {
+		// build a unique string key
+		$strkey = md5($str);
+		if (isset($this->cache_UTF8StringToArray[$strkey])) {
+			// return cached value
+			$chrarray = $this->cache_UTF8StringToArray[$strkey]['s'];
+			if (!isset($this->cache_UTF8StringToArray[$strkey]['f'][$this->CurrentFont['fontkey']])) {
+				if ($this->isunicode) {
+					foreach ($chrarray as $chr) {
+						// store this char for font subsetting
+						$this->CurrentFont['subsetchars'][$chr] = true;
+					}
+					// update font subsetchars
+					$this->setFontSubBuffer($this->CurrentFont['fontkey'], 'subsetchars', $this->CurrentFont['subsetchars']);
+				}
+				$this->cache_UTF8StringToArray[$strkey]['f'][$this->CurrentFont['fontkey']] = true;
+			}
+			return $chrarray;
+		}
+		// check cache size
+		if ($this->cache_size_UTF8StringToArray >= $this->cache_maxsize_UTF8StringToArray) {
+			// remove first element
+			array_shift($this->cache_UTF8StringToArray);
+		}
+		// new cache array for selected string
+		$this->cache_UTF8StringToArray[$strkey] = array('s' => array(), 'f' => array());
+		++$this->cache_size_UTF8StringToArray;
+		if (!$this->isunicode) {
+			// split string into array of equivalent codes
+			$strarr = array();
+			$strlen = strlen($str);
+			for ($i=0; $i < $strlen; ++$i) {
+				$strarr[] = ord($str[$i]);
+			}
+			// insert new value on cache
+			$this->cache_UTF8StringToArray[$strkey]['s'] = $strarr;
+			$this->cache_UTF8StringToArray[$strkey]['f'][$this->CurrentFont['fontkey']] = true;
+			return $strarr;
+		}
+		$unichar = -1; // last unicode char
+		$unicode = array(); // array containing unicode values
+		$bytes  = array(); // array containing single character byte sequences
+		$numbytes = 1; // number of octetc needed to represent the UTF-8 character
+		$str .= ''; // force $str to be a string
+		$length = strlen($str);
+		for ($i = 0; $i < $length; ++$i) {
+			$char = ord($str[$i]); // get one string character at time
+			if (count($bytes) == 0) { // get starting octect
+				if ($char <= 0x7F) {
+					$unichar = $char; // use the character "as is" because is ASCII
+					$numbytes = 1;
+				} elseif (($char >> 0x05) == 0x06) { // 2 bytes character (0x06 = 110 BIN)
+					$bytes[] = ($char - 0xC0) << 0x06;
+					$numbytes = 2;
+				} elseif (($char >> 0x04) == 0x0E) { // 3 bytes character (0x0E = 1110 BIN)
+					$bytes[] = ($char - 0xE0) << 0x0C;
+					$numbytes = 3;
+				} elseif (($char >> 0x03) == 0x1E) { // 4 bytes character (0x1E = 11110 BIN)
+					$bytes[] = ($char - 0xF0) << 0x12;
+					$numbytes = 4;
+				} else {
+					// use replacement character for other invalid sequences
+					$unichar = 0xFFFD;
+					$bytes = array();
+					$numbytes = 1;
+				}
+			} elseif (($char >> 0x06) == 0x02) { // bytes 2, 3 and 4 must start with 0x02 = 10 BIN
+				$bytes[] = $char - 0x80;
+				if (count($bytes) == $numbytes) {
+					// compose UTF-8 bytes to a single unicode value
+					$char = $bytes[0];
+					for ($j = 1; $j < $numbytes; ++$j) {
+						$char += ($bytes[$j] << (($numbytes - $j - 1) * 0x06));
+					}
+					if ((($char >= 0xD800) AND ($char <= 0xDFFF)) OR ($char >= 0x10FFFF)) {
+						/* The definition of UTF-8 prohibits encoding character numbers between
+						U+D800 and U+DFFF, which are reserved for use with the UTF-16
+						encoding form (as surrogate pairs) and do not directly represent
+						characters. */
+						$unichar = 0xFFFD; // use replacement character
+					} else {
+						$unichar = $char; // add char to array
+					}
+					// reset data for next char
+					$bytes = array();
+					$numbytes = 1;
+				}
+			} else {
+				// use replacement character for other invalid sequences
+				$unichar = 0xFFFD;
+				$bytes = array();
+				$numbytes = 1;
+			}
+			if ($unichar >= 0) {
+				// insert unicode value into array
+				$unicode[] = $unichar;
+				// store this char for font subsetting
+				$this->CurrentFont['subsetchars'][$unichar] = true;
+				$unichar = -1;
+			}
+		}
+		// update font subsetchars
+		$this->setFontSubBuffer($this->CurrentFont['fontkey'], 'subsetchars', $this->CurrentFont['subsetchars']);
+		// insert new value on cache
+		$this->cache_UTF8StringToArray[$strkey]['s'] = $unicode;
+		$this->cache_UTF8StringToArray[$strkey]['f'][$this->CurrentFont['fontkey']] = true;
+		return $unicode;
+	}
+
+	/**
+	 * Converts UTF-8 strings to UTF16-BE.<br>
+	 * @param $str (string) string to process.
+	 * @param $setbom (boolean) if true set the Byte Order Mark (BOM = 0xFEFF)
+	 * @return string
+	 * @author Nicola Asuni
+	 * @since 1.53.0.TC005 (2005-01-05)
+	 * @see UTF8StringToArray(), arrUTF8ToUTF16BE()
+	 * @protected
+	 */
+	protected function UTF8ToUTF16BE($str, $setbom=false) {
+		if (!$this->isunicode) {
+			return $str; // string is not in unicode
+		}
+		$unicode = $this->UTF8StringToArray($str); // array containing UTF-8 unicode values
+		return $this->arrUTF8ToUTF16BE($unicode, $setbom);
+	}
+
+	/**
+	 * Converts UTF-8 strings to Latin1 when using the standard 14 core fonts.<br>
+	 * @param $str (string) string to process.
+	 * @return string
+	 * @author Andrew Whitehead, Nicola Asuni
+	 * @protected
+	 * @since 3.2.000 (2008-06-23)
+	 */
+	protected function UTF8ToLatin1($str) {
+		if (!$this->isunicode) {
+			return $str; // string is not in unicode
+		}
+		$outstr = ''; // string to be returned
+		$unicode = $this->UTF8StringToArray($str); // array containing UTF-8 unicode values
+		foreach ($unicode as $char) {
+			if ($char < 256) {
+				$outstr .= chr($char);
+			} elseif (array_key_exists($char, $this->unicode->uni_utf8tolatin)) {
+				// map from UTF-8
+				$outstr .= chr($this->unicode->uni_utf8tolatin[$char]);
+			} elseif ($char == 0xFFFD) {
+				// skip
+			} else {
+				$outstr .= '?';
+			}
+		}
+		return $outstr;
+	}
+
+	/**
+	 * Converts UTF-8 characters array to array of Latin1 characters<br>
+	 * @param $unicode (array) array containing UTF-8 unicode values
+	 * @return array
+	 * @author Nicola Asuni
+	 * @protected
+	 * @since 4.8.023 (2010-01-15)
+	 */
+	protected function UTF8ArrToLatin1($unicode) {
+		if ((!$this->isunicode) OR $this->isUnicodeFont()) {
+			return $unicode;
+		}
+		$outarr = array(); // array to be returned
+		foreach ($unicode as $char) {
+			if ($char < 256) {
+				$outarr[] = $char;
+			} elseif (array_key_exists($char, $this->unicode->uni_utf8tolatin)) {
+				// map from UTF-8
+				$outarr[] = $this->unicode->uni_utf8tolatin[$char];
+			} elseif ($char == 0xFFFD) {
+				// skip
+			} else {
+				$outarr[] = 63; // '?' character
+			}
+		}
+		return $outarr;
+	}
+
+	/**
+	 * Converts array of UTF-8 characters to UTF16-BE string.<br>
+	 * Based on: http://www.faqs.org/rfcs/rfc2781.html
+	 * <pre>
+	 *   Encoding UTF-16:
+	 *
+	 *   Encoding of a single character from an ISO 10646 character value to
+	 *    UTF-16 proceeds as follows. Let U be the character number, no greater
+	 *    than 0x10FFFF.
+	 *
+	 *    1) If U < 0x10000, encode U as a 16-bit unsigned integer and
+	 *       terminate.
+	 *
+	 *    2) Let U' = U - 0x10000. Because U is less than or equal to 0x10FFFF,
+	 *       U' must be less than or equal to 0xFFFFF. That is, U' can be
+	 *       represented in 20 bits.
+	 *
+	 *    3) Initialize two 16-bit unsigned integers, W1 and W2, to 0xD800 and
+	 *       0xDC00, respectively. These integers each have 10 bits free to
+	 *       encode the character value, for a total of 20 bits.
+	 *
+	 *    4) Assign the 10 high-order bits of the 20-bit U' to the 10 low-order
+	 *       bits of W1 and the 10 low-order bits of U' to the 10 low-order
+	 *       bits of W2. Terminate.
+	 *
+	 *    Graphically, steps 2 through 4 look like:
+	 *    U' = yyyyyyyyyyxxxxxxxxxx
+	 *    W1 = 110110yyyyyyyyyy
+	 *    W2 = 110111xxxxxxxxxx
+	 * </pre>
+	 * @param $unicode (array) array containing UTF-8 unicode values
+	 * @param $setbom (boolean) if true set the Byte Order Mark (BOM = 0xFEFF)
+	 * @return string
+	 * @protected
+	 * @author Nicola Asuni
+	 * @since 2.1.000 (2008-01-08)
+	 * @see UTF8ToUTF16BE()
+	 */
+	protected function arrUTF8ToUTF16BE($unicode, $setbom=false) {
+		$outstr = ''; // string to be returned
+		if ($setbom) {
+			$outstr .= "\xFE\xFF"; // Byte Order Mark (BOM)
+		}
+		foreach ($unicode as $char) {
+			if ($char == 0x200b) {
+				// skip Unicode Character 'ZERO WIDTH SPACE' (DEC:8203, U+200B)
+			} elseif ($char == 0xFFFD) {
+				$outstr .= "\xFF\xFD"; // replacement character
+			} elseif ($char < 0x10000) {
+				$outstr .= chr($char >> 0x08);
+				$outstr .= chr($char & 0xFF);
+			} else {
+				$char -= 0x10000;
+				$w1 = 0xD800 | ($char >> 0x0a);
+				$w2 = 0xDC00 | ($char & 0x3FF);
+				$outstr .= chr($w1 >> 0x08);
+				$outstr .= chr($w1 & 0xFF);
+				$outstr .= chr($w2 >> 0x08);
+				$outstr .= chr($w2 & 0xFF);
+			}
+		}
+		return $outstr;
+	}
+	// ====================================================
+
+	/**
+	 * Set header font.
+	 * @param $font (array) font
+	 * @public
+	 * @since 1.1
+	 */
+	public function setHeaderFont($font) {
+		$this->header_font = $font;
+	}
+
+	/**
+	 * Get header font.
+	 * @return array()
+	 * @public
+	 * @since 4.0.012 (2008-07-24)
+	 */
+	public function getHeaderFont() {
+		return $this->header_font;
+	}
+
+	/**
+	 * Set footer font.
+	 * @param $font (array) font
+	 * @public
+	 * @since 1.1
+	 */
+	public function setFooterFont($font) {
+		$this->footer_font = $font;
+	}
+
+	/**
+	 * Get Footer font.
+	 * @return array()
+	 * @public
+	 * @since 4.0.012 (2008-07-24)
+	 */
+	public function getFooterFont() {
+		return $this->footer_font;
+	}
+
+	/**
+	 * Set language array.
+	 * @param $language (array)
+	 * @public
+	 * @since 1.1
+	 */
+	public function setLanguageArray($language) {
+		$this->l = $language;
+		if (isset($this->l['a_meta_dir'])) {
+			$this->rtl = $this->l['a_meta_dir']=='rtl' ? true : false;
+		} else {
+			$this->rtl = false;
+		}
+	}
+
+	/**
+	 * Returns the PDF data.
+	 * @public
+	 */
+	public function getPDFData() {
+		if ($this->state < 3) {
+			$this->Close();
+		}
+		return $this->buffer;
+	}
+
+	/**
+	 * Output anchor link.
+	 * @param $url (string) link URL or internal link (i.e.: <a href="#23,4.5">link to page 23 at 4.5 Y position</a>)
+	 * @param $name (string) link name
+	 * @param $fill (boolean) Indicates if the cell background must be painted (true) or transparent (false).
+	 * @param $firstline (boolean) if true prints only the first line and return the remaining string.
+	 * @param $color (array) array of RGB text color
+	 * @param $style (string) font style (U, D, B, I)
+	 * @param $firstblock (boolean) if true the string is the starting of a line.
+	 * @return the number of cells used or the remaining text if $firstline = true;
+	 * @public
+	 */
+	public function addHtmlLink($url, $name, $fill=false, $firstline=false, $color='', $style=-1, $firstblock=false) {
+		if (!$this->empty_string($url) AND ($url[0] == '#') AND is_numeric($url[1])) {
+			// convert url to internal link
+			$lnkdata = explode(',', $url);
+			if (isset($lnkdata[0])) {
+				$page = intval(substr($lnkdata[0], 1));
+				if (empty($page) OR ($page <= 0)) {
+					$page = $this->page;
+				}
+				if (isset($lnkdata[1]) AND (strlen($lnkdata[1]) > 0)) {
+					$lnky = floatval($lnkdata[1]);
+				} else {
+					$lnky = 0;
+				}
+				$url = $this->AddLink();
+				$this->SetLink($url, $lnky, $page);
+			}
+		}
+		// store current settings
+		$prevcolor = $this->fgcolor;
+		$prevstyle = $this->FontStyle;
+		if (empty($color)) {
+			$this->SetTextColorArray($this->htmlLinkColorArray);
+		} else {
+			$this->SetTextColorArray($color);
+		}
+		if ($style == -1) {
+			$this->SetFont('', $this->FontStyle.$this->htmlLinkFontStyle);
+		} else {
+			$this->SetFont('', $this->FontStyle.$style);
+		}
+		$ret = $this->Write($this->lasth, $name, $url, $fill, '', false, 0, $firstline, $firstblock, 0);
+		// restore settings
+		$this->SetFont('', $prevstyle);
+		$this->SetTextColorArray($prevcolor);
+		return $ret;
+	}
+
+	/**
+	 * Returns an array (RGB or CMYK) from an html color name, or a six-digit (i.e. #3FE5AA), or three-digit (i.e. #7FF) hexadecimal color, or a javascript color array, or javascript color name.
+	 * @param $hcolor (string) HTML color.
+	 * @param $defcol (array) Color to return in case of error.
+	 * @return array RGB or CMYK color, or false in case of error.
+	 * @public
+	 */
+	public function convertHTMLColorToDec($hcolor='#FFFFFF', $defcol=array('R'=>128,'G'=>128,'B'=>128)) {
+		$color = preg_replace('/[\s]*/', '', $hcolor); // remove extra spaces
+		$color = strtolower($color);
+		// check for javascript color array syntax
+		if (strpos($color, '[') !== false) {
+			if (preg_match('/[\[][\"\'](t|g|rgb|cmyk)[\"\'][\,]?([0-9\.]*)[\,]?([0-9\.]*)[\,]?([0-9\.]*)[\,]?([0-9\.]*)[\]]/', $color, $m) > 0) {
+				$returncolor = array();
+				switch ($m[1]) {
+					case 'cmyk': {
+						// RGB
+						$returncolor['C'] = max(0, min(100, (floatval($m[2]) * 100)));
+						$returncolor['M'] = max(0, min(100, (floatval($m[3]) * 100)));
+						$returncolor['Y'] = max(0, min(100, (floatval($m[4]) * 100)));
+						$returncolor['K'] = max(0, min(100, (floatval($m[5]) * 100)));
+						break;
+					}
+					case 'rgb': {
+						// RGB
+						$returncolor['R'] = max(0, min(255, (floatval($m[2]) * 255)));
+						$returncolor['G'] = max(0, min(255, (floatval($m[3]) * 255)));
+						$returncolor['B'] = max(0, min(255, (floatval($m[4]) * 255)));
+						break;
+					}
+					case 'g': {
+						// grayscale
+						$returncolor['G'] = max(0, min(255, (floatval($m[2]) * 255)));
+						break;
+					}
+					case 't':
+					default: {
+						// transparent (empty array)
+						break;
+					}
+				}
+				return $returncolor;
+			}
+		} elseif (($dotpos = strpos($color, '.')) !== false) {
+			// remove class parent (i.e.: color.red)
+			$color = substr($color, ($dotpos + 1));
+			if ($color == 'transparent') {
+				// transparent (empty array)
+				return array();
+			}
+		}
+		if (strlen($color) == 0) {
+			return $defcol;
+		}
+		// RGB ARRAY
+		if (substr($color, 0, 3) == 'rgb') {
+			$codes = substr($color, 4);
+			$codes = str_replace(')', '', $codes);
+			$returncolor = explode(',', $codes);
+			foreach ($returncolor as $key => $val) {
+				if (strpos($val, '%') > 0) {
+					// percentage
+					$returncolor[$key] = (255 * intval($val) / 100);
+				} else {
+					$returncolor[$key] = intval($val);
+				}
+				// normalize value
+				$returncolor[$key] = max(0, min(255, $returncolor[$key]));
+			}
+			return $returncolor;
+		}
+		// CMYK ARRAY
+		if (substr($color, 0, 4) == 'cmyk') {
+			$codes = substr($color, 5);
+			$codes = str_replace(')', '', $codes);
+			$returncolor = explode(',', $codes);
+			foreach ($returncolor as $key => $val) {
+				if (strpos($val, '%') !== false) {
+					// percentage
+					$returncolor[$key] = (100 * intval($val) / 100);
+				} else {
+					$returncolor[$key] = intval($val);
+				}
+				// normalize value
+				$returncolor[$key] = max(0, min(100, $returncolor[$key]));
+			}
+			return $returncolor;
+		}
+		if ($color{0} != '#') {
+			// COLOR NAME
+			if (isset($this->webcolor[$color])) {
+				// web color
+				$color_code = $this->webcolor[$color];
+			} else {
+				// spot color
+				$returncolor = $this->getSpotColor($color);
+				if ($returncolor === false) {
+					$returncolor = $defcol;
+				}
+				return $returncolor;
+			}
+		} else {
+			$color_code = substr($color, 1);
+		}
+		// HEXADECIMAL REPRESENTATION
+		switch (strlen($color_code)) {
+			case 3: {
+				// 3-digit RGB hexadecimal representation
+				$r = substr($color_code, 0, 1);
+				$g = substr($color_code, 1, 1);
+				$b = substr($color_code, 2, 1);
+				$returncolor = array();
+				$returncolor['R'] = max(0, min(255, hexdec($r.$r)));
+				$returncolor['G'] = max(0, min(255, hexdec($g.$g)));
+				$returncolor['B'] = max(0, min(255, hexdec($b.$b)));
+				break;
+			}
+			case 6: {
+				// 6-digit RGB hexadecimal representation
+				$returncolor = array();
+				$returncolor['R'] = max(0, min(255, hexdec(substr($color_code, 0, 2))));
+				$returncolor['G'] = max(0, min(255, hexdec(substr($color_code, 2, 2))));
+				$returncolor['B'] = max(0, min(255, hexdec(substr($color_code, 4, 2))));
+				break;
+			}
+			case 8: {
+				// 8-digit CMYK hexadecimal representation
+				$returncolor = array();
+				$returncolor['C'] = max(0, min(100, round(hexdec(substr($color_code, 0, 2)) / 2.55)));
+				$returncolor['M'] = max(0, min(100, round(hexdec(substr($color_code, 2, 2)) / 2.55)));
+				$returncolor['Y'] = max(0, min(100, round(hexdec(substr($color_code, 4, 2)) / 2.55)));
+				$returncolor['K'] = max(0, min(100, round(hexdec(substr($color_code, 6, 2)) / 2.55)));
+				break;
+			}
+			default: {
+				$returncolor = $defcol;
+				break;
+			}
+		}
+		return $returncolor;
+	}
+
+	/**
+	 * Converts pixels to User's Units.
+	 * @param $px (int) pixels
+	 * @return float value in user's unit
+	 * @public
+	 * @see setImageScale(), getImageScale()
+	 */
+	public function pixelsToUnits($px) {
+		return ($px / ($this->imgscale * $this->k));
+	}
+
+	/**
+	 * Reverse function for htmlentities.
+	 * Convert entities in UTF-8.
+	 * @param $text_to_convert (string) Text to convert.
+	 * @return string converted text string
+	 * @public
+	 */
+	public function unhtmlentities($text_to_convert) {
+		return @html_entity_decode($text_to_convert, ENT_QUOTES, $this->encoding);
+	}
+
+	// ENCRYPTION METHODS ----------------------------------
+
+	/**
+	 * Returns a string containing random data to be used as a seed for encryption methods.
+	 * @param $seed (string) starting seed value
+	 * @return string containing random data
+	 * @author Nicola Asuni
+	 * @since 5.9.006 (2010-10-19)
+	 * @protected
+	 */
+	protected function getRandomSeed($seed='') {
+		$seed .= microtime();
+		if (function_exists('openssl_random_pseudo_bytes') AND (strtoupper(substr(PHP_OS, 0, 3)) !== 'WIN')) {
+			// this is not used on windows systems because it is very slow for a know bug
+			$seed .= openssl_random_pseudo_bytes(512);
+		} else {
+			for ($i = 0; $i < 23; ++$i) {
+				$seed .= uniqid('', true);
+			}
+		}
+		$seed .= uniqid('', true);
+		$seed .= rand();
+		$seed .= getmypid();
+		$seed .= __FILE__;
+		$seed .= $this->bufferlen;
+		if (isset($_SERVER['REMOTE_ADDR'])) {
+			$seed .= $_SERVER['REMOTE_ADDR'];
+		}
+		if (isset($_SERVER['HTTP_USER_AGENT'])) {
+			$seed .= $_SERVER['HTTP_USER_AGENT'];
+		}
+		if (isset($_SERVER['HTTP_ACCEPT'])) {
+			$seed .= $_SERVER['HTTP_ACCEPT'];
+		}
+		if (isset($_SERVER['HTTP_ACCEPT_ENCODING'])) {
+			$seed .= $_SERVER['HTTP_ACCEPT_ENCODING'];
+		}
+		if (isset($_SERVER['HTTP_ACCEPT_LANGUAGE'])) {
+			$seed .= $_SERVER['HTTP_ACCEPT_LANGUAGE'];
+		}
+		if (isset($_SERVER['HTTP_ACCEPT_CHARSET'])) {
+			$seed .= $_SERVER['HTTP_ACCEPT_CHARSET'];
+		}
+		$seed .= rand();
+		$seed .= uniqid('', true);
+		$seed .= microtime();
+		return $seed;
+	}
+
+	/**
+	 * Compute encryption key depending on object number where the encrypted data is stored.
+	 * This is used for all strings and streams without crypt filter specifier.
+	 * @param $n (int) object number
+	 * @return int object key
+	 * @protected
+	 * @author Nicola Asuni
+	 * @since 2.0.000 (2008-01-02)
+	 */
+	protected function _objectkey($n) {
+		$objkey = $this->encryptdata['key'].pack('VXxx', $n);
+		if ($this->encryptdata['mode'] == 2) { // AES-128
+			// AES padding
+			$objkey .= "\x73\x41\x6C\x54"; // sAlT
+		}
+		$objkey = substr($this->_md5_16($objkey), 0, (($this->encryptdata['Length'] / 8) + 5));
+		$objkey = substr($objkey, 0, 16);
+		return $objkey;
+	}
+
+	/**
+	 * Encrypt the input string.
+	 * @param $n (int) object number
+	 * @param $s (string) data string to encrypt
+	 * @return encrypted string
+	 * @protected
+	 * @author Nicola Asuni
+	 * @since 5.0.005 (2010-05-11)
+	 */
+	protected function _encrypt_data($n, $s) {
+		if (!$this->encrypted) {
+			return $s;
+		}
+		switch ($this->encryptdata['mode']) {
+			case 0:   // RC4-40
+			case 1: { // RC4-128
+				$s = $this->_RC4($this->_objectkey($n), $s);
+				break;
+			}
+			case 2: { // AES-128
+				$s = $this->_AES($this->_objectkey($n), $s);
+				break;
+			}
+			case 3: { // AES-256
+				$s = $this->_AES($this->encryptdata['key'], $s);
+				break;
+			}
+		}
+		return $s;
+	}
+
+	/**
+	 * Put encryption on PDF document.
+	 * @protected
+	 * @author Nicola Asuni
+	 * @since 2.0.000 (2008-01-02)
+	 */
+	protected function _putencryption() {
+		if (!$this->encrypted) {
+			return;
+		}
+		$this->encryptdata['objid'] = $this->_newobj();
+		$out = '<<';
+		if (!isset($this->encryptdata['Filter']) OR empty($this->encryptdata['Filter'])) {
+			$this->encryptdata['Filter'] = 'Standard';
+		}
+		$out .= ' /Filter /'.$this->encryptdata['Filter'];
+		if (isset($this->encryptdata['SubFilter']) AND !empty($this->encryptdata['SubFilter'])) {
+			$out .= ' /SubFilter /'.$this->encryptdata['SubFilter'];
+		}
+		if (!isset($this->encryptdata['V']) OR empty($this->encryptdata['V'])) {
+			$this->encryptdata['V'] = 1;
+		}
+		// V is a code specifying the algorithm to be used in encrypting and decrypting the document
+		$out .= ' /V '.$this->encryptdata['V'];
+		if (isset($this->encryptdata['Length']) AND !empty($this->encryptdata['Length'])) {
+			// The length of the encryption key, in bits. The value shall be a multiple of 8, in the range 40 to 256
+			$out .= ' /Length '.$this->encryptdata['Length'];
+		} else {
+			$out .= ' /Length 40';
+		}
+		if ($this->encryptdata['V'] >= 4) {
+			if (!isset($this->encryptdata['StmF']) OR empty($this->encryptdata['StmF'])) {
+				$this->encryptdata['StmF'] = 'Identity';
+			}
+			if (!isset($this->encryptdata['StrF']) OR empty($this->encryptdata['StrF'])) {
+				// The name of the crypt filter that shall be used when decrypting all strings in the document.
+				$this->encryptdata['StrF'] = 'Identity';
+			}
+			// A dictionary whose keys shall be crypt filter names and whose values shall be the corresponding crypt filter dictionaries.
+			if (isset($this->encryptdata['CF']) AND !empty($this->encryptdata['CF'])) {
+				$out .= ' /CF <<';
+				$out .= ' /'.$this->encryptdata['StmF'].' <<';
+				$out .= ' /Type /CryptFilter';
+				if (isset($this->encryptdata['CF']['CFM']) AND !empty($this->encryptdata['CF']['CFM'])) {
+					// The method used
+					$out .= ' /CFM /'.$this->encryptdata['CF']['CFM'];
+					if ($this->encryptdata['pubkey']) {
+						$out .= ' /Recipients [';
+						foreach ($this->encryptdata['Recipients'] as $rec) {
+							$out .= ' <'.$rec.'>';
+						}
+						$out .= ' ]';
+						if (isset($this->encryptdata['CF']['EncryptMetadata']) AND (!$this->encryptdata['CF']['EncryptMetadata'])) {
+							$out .= ' /EncryptMetadata false';
+						} else {
+							$out .= ' /EncryptMetadata true';
+						}
+					}
+				} else {
+					$out .= ' /CFM /None';
+				}
+				if (isset($this->encryptdata['CF']['AuthEvent']) AND !empty($this->encryptdata['CF']['AuthEvent'])) {
+					// The event to be used to trigger the authorization that is required to access encryption keys used by this filter.
+					$out .= ' /AuthEvent /'.$this->encryptdata['CF']['AuthEvent'];
+				} else {
+					$out .= ' /AuthEvent /DocOpen';
+				}
+				if (isset($this->encryptdata['CF']['Length']) AND !empty($this->encryptdata['CF']['Length'])) {
+					// The bit length of the encryption key.
+					$out .= ' /Length '.$this->encryptdata['CF']['Length'];
+				}
+				$out .= ' >> >>';
+			}
+			// The name of the crypt filter that shall be used by default when decrypting streams.
+			$out .= ' /StmF /'.$this->encryptdata['StmF'];
+			// The name of the crypt filter that shall be used when decrypting all strings in the document.
+			$out .= ' /StrF /'.$this->encryptdata['StrF'];
+			if (isset($this->encryptdata['EFF']) AND !empty($this->encryptdata['EFF'])) {
+				// The name of the crypt filter that shall be used when encrypting embedded file streams that do not have their own crypt filter specifier.
+				$out .= ' /EFF /'.$this->encryptdata[''];
+			}
+		}
+		// Additional encryption dictionary entries for the standard security handler
+		if ($this->encryptdata['pubkey']) {
+			if (($this->encryptdata['V'] < 4) AND isset($this->encryptdata['Recipients']) AND !empty($this->encryptdata['Recipients'])) {
+				$out .= ' /Recipients [';
+				foreach ($this->encryptdata['Recipients'] as $rec) {
+					$out .= ' <'.$rec.'>';
+				}
+				$out .= ' ]';
+			}
+		} else {
+			$out .= ' /R';
+			if ($this->encryptdata['V'] == 5) { // AES-256
+				$out .= ' 5';
+				$out .= ' /OE ('.$this->_escape($this->encryptdata['OE']).')';
+				$out .= ' /UE ('.$this->_escape($this->encryptdata['UE']).')';
+				$out .= ' /Perms ('.$this->_escape($this->encryptdata['perms']).')';
+			} elseif ($this->encryptdata['V'] == 4) { // AES-128
+				$out .= ' 4';
+			} elseif ($this->encryptdata['V'] < 2) { // RC-40
+				$out .= ' 2';
+			} else { // RC-128
+				$out .= ' 3';
+			}
+			$out .= ' /O ('.$this->_escape($this->encryptdata['O']).')';
+			$out .= ' /U ('.$this->_escape($this->encryptdata['U']).')';
+			$out .= ' /P '.$this->encryptdata['P'];
+			if (isset($this->encryptdata['EncryptMetadata']) AND (!$this->encryptdata['EncryptMetadata'])) {
+				$out .= ' /EncryptMetadata false';
+			} else {
+				$out .= ' /EncryptMetadata true';
+			}
+		}
+		$out .= ' >>';
+		$out .= "\n".'endobj';
+		$this->_out($out);
+	}
+
+	/**
+	 * Returns the input text encrypted using RC4 algorithm and the specified key.
+	 * RC4 is the standard encryption algorithm used in PDF format
+	 * @param $key (string) encryption key
+	 * @param $text (String) input text to be encrypted
+	 * @return String encrypted text
+	 * @protected
+	 * @since 2.0.000 (2008-01-02)
+	 * @author Klemen Vodopivec, Nicola Asuni
+	 */
+	protected function _RC4($key, $text) {
+		if (function_exists('mcrypt_decrypt') AND ($out = @mcrypt_decrypt(MCRYPT_ARCFOUR, $key, $text, MCRYPT_MODE_STREAM, ''))) {
+			// try to use mcrypt function if exist
+			return $out;
+		}
+		if ($this->last_enc_key != $key) {
+			$k = str_repeat($key, ((256 / strlen($key)) + 1));
+			$rc4 = range(0, 255);
+			$j = 0;
+			for ($i = 0; $i < 256; ++$i) {
+				$t = $rc4[$i];
+				$j = ($j + $t + ord($k[$i])) % 256;
+				$rc4[$i] = $rc4[$j];
+				$rc4[$j] = $t;
+			}
+			$this->last_enc_key = $key;
+			$this->last_enc_key_c = $rc4;
+		} else {
+			$rc4 = $this->last_enc_key_c;
+		}
+		$len = strlen($text);
+		$a = 0;
+		$b = 0;
+		$out = '';
+		for ($i = 0; $i < $len; ++$i) {
+			$a = ($a + 1) % 256;
+			$t = $rc4[$a];
+			$b = ($b + $t) % 256;
+			$rc4[$a] = $rc4[$b];
+			$rc4[$b] = $t;
+			$k = $rc4[($rc4[$a] + $rc4[$b]) % 256];
+			$out .= chr(ord($text[$i]) ^ $k);
+		}
+		return $out;
+	}
+
+	/**
+	 * Returns the input text exrypted using AES algorithm and the specified key.
+	 * This method requires mcrypt.
+	 * @param $key (string) encryption key
+	 * @param $text (String) input text to be encrypted
+	 * @return String encrypted text
+	 * @protected
+	 * @author Nicola Asuni
+	 * @since 5.0.005 (2010-05-11)
+	 */
+	protected function _AES($key, $text) {
+		// padding (RFC 2898, PKCS #5: Password-Based Cryptography Specification Version 2.0)
+		$padding = 16 - (strlen($text) % 16);
+		$text .= str_repeat(chr($padding), $padding);
+		$iv = mcrypt_create_iv(mcrypt_get_iv_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_CBC), MCRYPT_RAND);
+		$text = mcrypt_encrypt(MCRYPT_RIJNDAEL_128, $key, $text, MCRYPT_MODE_CBC, $iv);
+		$text = $iv.$text;
+		return $text;
+	}
+
+	/**
+	 * Encrypts a string using MD5 and returns it's value as a binary string.
+	 * @param $str (string) input string
+	 * @return String MD5 encrypted binary string
+	 * @protected
+	 * @since 2.0.000 (2008-01-02)
+	 * @author Klemen Vodopivec
+	 */
+	protected function _md5_16($str) {
+		return pack('H*', md5($str));
+	}
+
+	/**
+	 * Compute U value (used for encryption)
+	 * @return string U value
+	 * @protected
+	 * @since 2.0.000 (2008-01-02)
+	 * @author Nicola Asuni
+	 */
+	protected function _Uvalue() {
+		if ($this->encryptdata['mode'] == 0) { // RC4-40
+			return $this->_RC4($this->encryptdata['key'], $this->enc_padding);
+		} elseif ($this->encryptdata['mode'] < 3) { // RC4-128, AES-128
+			$tmp = $this->_md5_16($this->enc_padding.$this->encryptdata['fileid']);
+			$enc = $this->_RC4($this->encryptdata['key'], $tmp);
+			$len = strlen($tmp);
+			for ($i = 1; $i <= 19; ++$i) {
+				$ek = '';
+				for ($j = 0; $j < $len; ++$j) {
+					$ek .= chr(ord($this->encryptdata['key'][$j]) ^ $i);
+				}
+				$enc = $this->_RC4($ek, $enc);
+			}
+			$enc .= str_repeat("\x00", 16);
+			return substr($enc, 0, 32);
+		} elseif ($this->encryptdata['mode'] == 3) { // AES-256
+			$seed = $this->_md5_16($this->getRandomSeed());
+			// User Validation Salt
+			$this->encryptdata['UVS'] = substr($seed, 0, 8);
+			// User Key Salt
+			$this->encryptdata['UKS'] = substr($seed, 8, 16);
+			return hash('sha256', $this->encryptdata['user_password'].$this->encryptdata['UVS'], true).$this->encryptdata['UVS'].$this->encryptdata['UKS'];
+		}
+	}
+
+	/**
+	 * Compute UE value (used for encryption)
+	 * @return string UE value
+	 * @protected
+	 * @since 5.9.006 (2010-10-19)
+	 * @author Nicola Asuni
+	 */
+	protected function _UEvalue() {
+		$hashkey = hash('sha256', $this->encryptdata['user_password'].$this->encryptdata['UKS'], true);
+		$iv = str_repeat("\x00", mcrypt_get_iv_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_CBC));
+		return mcrypt_encrypt(MCRYPT_RIJNDAEL_128, $hashkey, $this->encryptdata['key'], MCRYPT_MODE_CBC, $iv);
+	}
+
+	/**
+	 * Compute O value (used for encryption)
+	 * @return string O value
+	 * @protected
+	 * @since 2.0.000 (2008-01-02)
+	 * @author Nicola Asuni
+	 */
+	protected function _Ovalue() {
+		if ($this->encryptdata['mode'] < 3) { // RC4-40, RC4-128, AES-128
+			$tmp = $this->_md5_16($this->encryptdata['owner_password']);
+			if ($this->encryptdata['mode'] > 0) {
+				for ($i = 0; $i < 50; ++$i) {
+					$tmp = $this->_md5_16($tmp);
+				}
+			}
+			$owner_key = substr($tmp, 0, ($this->encryptdata['Length'] / 8));
+			$enc = $this->_RC4($owner_key, $this->encryptdata['user_password']);
+			if ($this->encryptdata['mode'] > 0) {
+				$len = strlen($owner_key);
+				for ($i = 1; $i <= 19; ++$i) {
+					$ek = '';
+					for ($j = 0; $j < $len; ++$j) {
+						$ek .= chr(ord($owner_key[$j]) ^ $i);
+					}
+					$enc = $this->_RC4($ek, $enc);
+				}
+			}
+			return $enc;
+		} elseif ($this->encryptdata['mode'] == 3) { // AES-256
+			$seed = $this->_md5_16($this->getRandomSeed());
+			// Owner Validation Salt
+			$this->encryptdata['OVS'] = substr($seed, 0, 8);
+			// Owner Key Salt
+			$this->encryptdata['OKS'] = substr($seed, 8, 16);
+			return hash('sha256', $this->encryptdata['owner_password'].$this->encryptdata['OVS'].$this->encryptdata['U'], true).$this->encryptdata['OVS'].$this->encryptdata['OKS'];
+		}
+	}
+
+	/**
+	 * Compute OE value (used for encryption)
+	 * @return string OE value
+	 * @protected
+	 * @since 5.9.006 (2010-10-19)
+	 * @author Nicola Asuni
+	 */
+	protected function _OEvalue() {
+		$hashkey = hash('sha256', $this->encryptdata['owner_password'].$this->encryptdata['OKS'].$this->encryptdata['U'], true);
+		$iv = str_repeat("\x00", mcrypt_get_iv_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_CBC));
+		return mcrypt_encrypt(MCRYPT_RIJNDAEL_128, $hashkey, $this->encryptdata['key'], MCRYPT_MODE_CBC, $iv);
+	}
+
+	/**
+	 * Convert password for AES-256 encryption mode
+	 * @param $password (string) password
+	 * @return string password
+	 * @protected
+	 * @since 5.9.006 (2010-10-19)
+	 * @author Nicola Asuni
+	 */
+	protected function _fixAES256Password($password) {
+		$psw = ''; // password to be returned
+		$psw_array = $this->utf8Bidi($this->UTF8StringToArray($password), $password, $this->rtl);
+		foreach ($psw_array as $c) {
+			$psw .= $this->unichr($c);
+		}
+		return substr($psw, 0, 127);
+	}
+
+	/**
+	 * Compute encryption key
+	 * @protected
+	 * @since 2.0.000 (2008-01-02)
+	 * @author Nicola Asuni
+	 */
+	protected function _generateencryptionkey() {
+		$keybytelen = ($this->encryptdata['Length'] / 8);
+		if (!$this->encryptdata['pubkey']) { // standard mode
+			if ($this->encryptdata['mode'] == 3) { // AES-256
+				// generate 256 bit random key
+				$this->encryptdata['key'] = substr(hash('sha256', $this->getRandomSeed(), true), 0, $keybytelen);
+				// truncate passwords
+				$this->encryptdata['user_password'] = $this->_fixAES256Password($this->encryptdata['user_password']);
+				$this->encryptdata['owner_password'] = $this->_fixAES256Password($this->encryptdata['owner_password']);
+				// Compute U value
+				$this->encryptdata['U'] = $this->_Uvalue();
+				// Compute UE value
+				$this->encryptdata['UE'] = $this->_UEvalue();
+				// Compute O value
+				$this->encryptdata['O'] = $this->_Ovalue();
+				// Compute OE value
+				$this->encryptdata['OE'] = $this->_OEvalue();
+				// Compute P value
+				$this->encryptdata['P'] = $this->encryptdata['protection'];
+				// Computing the encryption dictionary's Perms (permissions) value
+				$perms = $this->getEncPermissionsString($this->encryptdata['protection']); // bytes 0-3
+				$perms .= chr(255).chr(255).chr(255).chr(255); // bytes 4-7
+				if (isset($this->encryptdata['CF']['EncryptMetadata']) AND (!$this->encryptdata['CF']['EncryptMetadata'])) { // byte 8
+					$perms .= 'F';
+				} else {
+					$perms .= 'T';
+				}
+				$perms .= 'adb'; // bytes 9-11
+				$perms .= 'nick'; // bytes 12-15
+				$iv = str_repeat("\x00", mcrypt_get_iv_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_ECB));
+				$this->encryptdata['perms'] = mcrypt_encrypt(MCRYPT_RIJNDAEL_128, $this->encryptdata['key'], $perms, MCRYPT_MODE_ECB, $iv);
+			} else { // RC4-40, RC4-128, AES-128
+				// Pad passwords
+				$this->encryptdata['user_password'] = substr($this->encryptdata['user_password'].$this->enc_padding, 0, 32);
+				$this->encryptdata['owner_password'] = substr($this->encryptdata['owner_password'].$this->enc_padding, 0, 32);
+				// Compute O value
+				$this->encryptdata['O'] = $this->_Ovalue();
+				// get default permissions (reverse byte order)
+				$permissions = $this->getEncPermissionsString($this->encryptdata['protection']);
+				// Compute encryption key
+				$tmp = $this->_md5_16($this->encryptdata['user_password'].$this->encryptdata['O'].$permissions.$this->encryptdata['fileid']);
+				if ($this->encryptdata['mode'] > 0) {
+					for ($i = 0; $i < 50; ++$i) {
+						$tmp = $this->_md5_16(substr($tmp, 0, $keybytelen));
+					}
+				}
+				$this->encryptdata['key'] = substr($tmp, 0, $keybytelen);
+				// Compute U value
+				$this->encryptdata['U'] = $this->_Uvalue();
+				// Compute P value
+				$this->encryptdata['P'] = $this->encryptdata['protection'];
+			}
+		} else { // Public-Key mode
+			// random 20-byte seed
+			$seed = sha1($this->getRandomSeed(), true);
+			$recipient_bytes = '';
+			foreach ($this->encryptdata['pubkeys'] as $pubkey) {
+				// for each public certificate
+				if (isset($pubkey['p'])) {
+					$pkprotection = $this->getUserPermissionCode($pubkey['p'], $this->encryptdata['mode']);
+				} else {
+					$pkprotection = $this->encryptdata['protection'];
+				}
+				// get default permissions (reverse byte order)
+				$pkpermissions = $this->getEncPermissionsString($pkprotection);
+				// envelope data
+				$envelope = $seed.$pkpermissions;
+				// write the envelope data to a temporary file
+				$tempkeyfile = tempnam(K_PATH_CACHE, 'tmpkey_');
+				$f = fopen($tempkeyfile, 'wb');
+				if (!$f) {
+					$this->Error('Unable to create temporary key file: '.$tempkeyfile);
+				}
+				$envelope_length = strlen($envelope);
+				fwrite($f, $envelope, $envelope_length);
+				fclose($f);
+				$tempencfile = tempnam(K_PATH_CACHE, 'tmpenc_');
+				if (!openssl_pkcs7_encrypt($tempkeyfile, $tempencfile, $pubkey['c'], array(), PKCS7_BINARY | PKCS7_DETACHED)) {
+					$this->Error('Unable to encrypt the file: '.$tempkeyfile);
+				}
+				unlink($tempkeyfile);
+				// read encryption signature
+				$signature = file_get_contents($tempencfile, false, null, $envelope_length);
+				unlink($tempencfile);
+				// extract signature
+				$signature = substr($signature, strpos($signature, 'Content-Disposition'));
+				$tmparr = explode("\n\n", $signature);
+				$signature = trim($tmparr[1]);
+				unset($tmparr);
+				// decode signature
+				$signature = base64_decode($signature);
+				// convert signature to hex
+				$hexsignature = current(unpack('H*', $signature));
+				// store signature on recipients array
+				$this->encryptdata['Recipients'][] = $hexsignature;
+				// The bytes of each item in the Recipients array of PKCS#7 objects in the order in which they appear in the array
+				$recipient_bytes .= $signature;
+			}
+			// calculate encryption key
+			if ($this->encryptdata['mode'] == 3) { // AES-256
+				$this->encryptdata['key'] = substr(hash('sha256', $seed.$recipient_bytes, true), 0, $keybytelen);
+			} else { // RC4-40, RC4-128, AES-128
+				$this->encryptdata['key'] = substr(sha1($seed.$recipient_bytes, true), 0, $keybytelen);
+			}
+		}
+	}
+
+	/**
+	 * Return the premission code used on encryption (P value).
+	 * @param $permissions (Array) the set of permissions (specify the ones you want to block).
+	 * @param $mode (int) encryption strength: 0 = RC4 40 bit; 1 = RC4 128 bit; 2 = AES 128 bit; 3 = AES 256 bit.
+	 * @protected
+	 * @since 5.0.005 (2010-05-12)
+	 * @author Nicola Asuni
+	 */
+	protected function getUserPermissionCode($permissions, $mode=0) {
+		$options = array(
+			'owner' => 2, // bit 2 -- inverted logic: cleared by default
+			'print' => 4, // bit 3
+			'modify' => 8, // bit 4
+			'copy' => 16, // bit 5
+			'annot-forms' => 32, // bit 6
+			'fill-forms' => 256, // bit 9
+			'extract' => 512, // bit 10
+			'assemble' => 1024,// bit 11
+			'print-high' => 2048 // bit 12
+			);
+		$protection = 2147422012; // 32 bit: (01111111 11111111 00001111 00111100)
+		foreach ($permissions as $permission) {
+			if (!isset($options[$permission])) {
+				$this->Error('Incorrect permission: '.$permission);
+			}
+			if (($mode > 0) OR ($options[$permission] <= 32)) {
+				// set only valid permissions
+				if ($options[$permission] == 2) {
+					// the logic for bit 2 is inverted (cleared by default)
+					$protection += $options[$permission];
+				} else {
+					$protection -= $options[$permission];
+				}
+			}
+		}
+		return $protection;
+	}
+
+	/**
+	 * Set document protection
+	 * Remark: the protection against modification is for people who have the full Acrobat product.
+	 * If you don't set any password, the document will open as usual. If you set a user password, the PDF viewer will ask for it before displaying the document. The master password, if different from the user one, can be used to get full access.
+	 * Note: protecting a document requires to encrypt it, which increases the processing time a lot. This can cause a PHP time-out in some cases, especially if the document contains images or fonts.
+	 * @param $permissions (Array) the set of permissions (specify the ones you want to block):<ul><li>print : Print the document;</li><li>modify : Modify the contents of the document by operations other than those controlled by 'fill-forms', 'extract' and 'assemble';</li><li>copy : Copy or otherwise extract text and graphics from the document;</li><li>annot-forms : Add or modify text annotations, fill in interactive form fields, and, if 'modify' is also set, create or modify interactive fo [...]
+	 * @param $user_pass (String) user password. Empty by default.
+	 * @param $owner_pass (String) owner password. If not specified, a random value is used.
+	 * @param $mode (int) encryption strength: 0 = RC4 40 bit; 1 = RC4 128 bit; 2 = AES 128 bit; 3 = AES 256 bit.
+	 * @param $pubkeys (String) array of recipients containing public-key certificates ('c') and permissions ('p'). For example: array(array('c' => 'file://../tcpdf.crt', 'p' => array('print')))
+	 * @public
+	 * @since 2.0.000 (2008-01-02)
+	 * @author Nicola Asuni
+	 */
+	public function SetProtection($permissions=array('print', 'modify', 'copy', 'annot-forms', 'fill-forms', 'extract', 'assemble', 'print-high'), $user_pass='', $owner_pass=null, $mode=0, $pubkeys=null) {
+		if ($this->pdfa_mode) {
+			// encryption is not allowed in PDF/A mode
+			return;
+		}
+		$this->encryptdata['protection'] = $this->getUserPermissionCode($permissions, $mode);
+		if (($pubkeys !== null) AND (is_array($pubkeys))) {
+			// public-key mode
+			$this->encryptdata['pubkeys'] = $pubkeys;
+			if ($mode == 0) {
+				// public-Key Security requires at least 128 bit
+				$mode = 1;
+			}
+			if (!function_exists('openssl_pkcs7_encrypt')) {
+				$this->Error('Public-Key Security requires openssl library.');
+			}
+			// Set Public-Key filter (availabe are: Entrust.PPKEF, Adobe.PPKLite, Adobe.PubSec)
+			$this->encryptdata['pubkey'] = true;
+			$this->encryptdata['Filter'] = 'Adobe.PubSec';
+			$this->encryptdata['StmF'] = 'DefaultCryptFilter';
+			$this->encryptdata['StrF'] = 'DefaultCryptFilter';
+		} else {
+			// standard mode (password mode)
+			$this->encryptdata['pubkey'] = false;
+			$this->encryptdata['Filter'] = 'Standard';
+			$this->encryptdata['StmF'] = 'StdCF';
+			$this->encryptdata['StrF'] = 'StdCF';
+		}
+		if ($mode > 1) { // AES
+			if (!extension_loaded('mcrypt')) {
+				$this->Error('AES encryption requires mcrypt library (http://www.php.net/manual/en/mcrypt.requirements.php).');
+			}
+			if (mcrypt_get_cipher_name(MCRYPT_RIJNDAEL_128) === false) {
+				$this->Error('AES encryption requires MCRYPT_RIJNDAEL_128 cypher.');
+			}
+			if (($mode == 3) AND !function_exists('hash')) {
+				// the Hash extension requires no external libraries and is enabled by default as of PHP 5.1.2.
+				$this->Error('AES 256 encryption requires HASH Message Digest Framework (http://www.php.net/manual/en/book.hash.php).');
+			}
+		}
+		if ($owner_pass === null) {
+			$owner_pass = md5($this->getRandomSeed());
+		}
+		$this->encryptdata['user_password'] = $user_pass;
+		$this->encryptdata['owner_password'] = $owner_pass;
+		$this->encryptdata['mode'] = $mode;
+		switch ($mode) {
+			case 0: { // RC4 40 bit
+				$this->encryptdata['V'] = 1;
+				$this->encryptdata['Length'] = 40;
+				$this->encryptdata['CF']['CFM'] = 'V2';
+				break;
+			}
+			case 1: { // RC4 128 bit
+				$this->encryptdata['V'] = 2;
+				$this->encryptdata['Length'] = 128;
+				$this->encryptdata['CF']['CFM'] = 'V2';
+				if ($this->encryptdata['pubkey']) {
+					$this->encryptdata['SubFilter'] = 'adbe.pkcs7.s4';
+					$this->encryptdata['Recipients'] = array();
+				}
+				break;
+			}
+			case 2: { // AES 128 bit
+				$this->encryptdata['V'] = 4;
+				$this->encryptdata['Length'] = 128;
+				$this->encryptdata['CF']['CFM'] = 'AESV2';
+				$this->encryptdata['CF']['Length'] = 128;
+				if ($this->encryptdata['pubkey']) {
+					$this->encryptdata['SubFilter'] = 'adbe.pkcs7.s5';
+					$this->encryptdata['Recipients'] = array();
+				}
+				break;
+			}
+			case 3: { // AES 256 bit
+				$this->encryptdata['V'] = 5;
+				$this->encryptdata['Length'] = 256;
+				$this->encryptdata['CF']['CFM'] = 'AESV3';
+				$this->encryptdata['CF']['Length'] = 256;
+				if ($this->encryptdata['pubkey']) {
+					$this->encryptdata['SubFilter'] = 'adbe.pkcs7.s5';
+					$this->encryptdata['Recipients'] = array();
+				}
+				break;
+			}
+		}
+		$this->encrypted = true;
+		$this->encryptdata['fileid'] = $this->convertHexStringToString($this->file_id);
+		$this->_generateencryptionkey();
+	}
+
+	/**
+	 * Convert hexadecimal string to string
+	 * @param $bs (string) byte-string to convert
+	 * @return String
+	 * @protected
+	 * @since 5.0.005 (2010-05-12)
+	 * @author Nicola Asuni
+	 */
+	protected function convertHexStringToString($bs) {
+		$string = ''; // string to be returned
+		$bslength = strlen($bs);
+		if (($bslength % 2) != 0) {
+			// padding
+			$bs .= '0';
+			++$bslength;
+		}
+		for ($i = 0; $i < $bslength; $i += 2) {
+			$string .= chr(hexdec($bs[$i].$bs[($i + 1)]));
+		}
+		return $string;
+	}
+
+	/**
+	 * Convert string to hexadecimal string (byte string)
+	 * @param $s (string) string to convert
+	 * @return byte string
+	 * @protected
+	 * @since 5.0.010 (2010-05-17)
+	 * @author Nicola Asuni
+	 */
+	protected function convertStringToHexString($s) {
+		$bs = '';
+		$chars = preg_split('//', $s, -1, PREG_SPLIT_NO_EMPTY);
+		foreach ($chars as $c) {
+			$bs .= sprintf('%02s', dechex(ord($c)));
+		}
+		return $bs;
+	}
+
+	/**
+	 * Convert encryption P value to a string of bytes, low-order byte first.
+	 * @param $protection (string) 32bit encryption permission value (P value)
+	 * @return String
+	 * @protected
+	 * @since 5.0.005 (2010-05-12)
+	 * @author Nicola Asuni
+	 */
+	protected function getEncPermissionsString($protection) {
+		$binprot = sprintf('%032b', $protection);
+		$str = chr(bindec(substr($binprot, 24, 8)));
+		$str .= chr(bindec(substr($binprot, 16, 8)));
+		$str .= chr(bindec(substr($binprot, 8, 8)));
+		$str .= chr(bindec(substr($binprot, 0, 8)));
+		return $str;
+	}
+
+	// END OF ENCRYPTION FUNCTIONS -------------------------
+
+	// START TRANSFORMATIONS SECTION -----------------------
+
+	/**
+	 * Starts a 2D tranformation saving current graphic state.
+	 * This function must be called before scaling, mirroring, translation, rotation and skewing.
+	 * Use StartTransform() before, and StopTransform() after the transformations to restore the normal behavior.
+	 * @public
+	 * @since 2.1.000 (2008-01-07)
+	 * @see StartTransform(), StopTransform()
+	 */
+	public function StartTransform() {
+		if ($this->state != 2) {
+			return;
+		}
+		$this->_out('q');
+		if ($this->inxobj) {
+			// we are inside an XObject template
+			$this->xobjects[$this->xobjid]['transfmrk'][] = strlen($this->xobjects[$this->xobjid]['outdata']);
+		} else {
+			$this->transfmrk[$this->page][] = $this->pagelen[$this->page];
+		}
+		++$this->transfmatrix_key;
+		$this->transfmatrix[$this->transfmatrix_key] = array();
+	}
+
+	/**
+	 * Stops a 2D tranformation restoring previous graphic state.
+	 * This function must be called after scaling, mirroring, translation, rotation and skewing.
+	 * Use StartTransform() before, and StopTransform() after the transformations to restore the normal behavior.
+	 * @public
+	 * @since 2.1.000 (2008-01-07)
+	 * @see StartTransform(), StopTransform()
+	 */
+	public function StopTransform() {
+		if ($this->state != 2) {
+			return;
+		}
+		$this->_out('Q');
+		if (isset($this->transfmatrix[$this->transfmatrix_key])) {
+			array_pop($this->transfmatrix[$this->transfmatrix_key]);
+			--$this->transfmatrix_key;
+		}
+		if ($this->inxobj) {
+			// we are inside an XObject template
+			array_pop($this->xobjects[$this->xobjid]['transfmrk']);
+		} else {
+			array_pop($this->transfmrk[$this->page]);
+		}
+	}
+	/**
+	 * Horizontal Scaling.
+	 * @param $s_x (float) scaling factor for width as percent. 0 is not allowed.
+	 * @param $x (int) abscissa of the scaling center. Default is current x position
+	 * @param $y (int) ordinate of the scaling center. Default is current y position
+	 * @public
+	 * @since 2.1.000 (2008-01-07)
+	 * @see StartTransform(), StopTransform()
+	 */
+	public function ScaleX($s_x, $x='', $y='') {
+		$this->Scale($s_x, 100, $x, $y);
+	}
+
+	/**
+	 * Vertical Scaling.
+	 * @param $s_y (float) scaling factor for height as percent. 0 is not allowed.
+	 * @param $x (int) abscissa of the scaling center. Default is current x position
+	 * @param $y (int) ordinate of the scaling center. Default is current y position
+	 * @public
+	 * @since 2.1.000 (2008-01-07)
+	 * @see StartTransform(), StopTransform()
+	 */
+	public function ScaleY($s_y, $x='', $y='') {
+		$this->Scale(100, $s_y, $x, $y);
+	}
+
+	/**
+	 * Vertical and horizontal proportional Scaling.
+	 * @param $s (float) scaling factor for width and height as percent. 0 is not allowed.
+	 * @param $x (int) abscissa of the scaling center. Default is current x position
+	 * @param $y (int) ordinate of the scaling center. Default is current y position
+	 * @public
+	 * @since 2.1.000 (2008-01-07)
+	 * @see StartTransform(), StopTransform()
+	 */
+	public function ScaleXY($s, $x='', $y='') {
+		$this->Scale($s, $s, $x, $y);
+	}
+
+	/**
+	 * Vertical and horizontal non-proportional Scaling.
+	 * @param $s_x (float) scaling factor for width as percent. 0 is not allowed.
+	 * @param $s_y (float) scaling factor for height as percent. 0 is not allowed.
+	 * @param $x (int) abscissa of the scaling center. Default is current x position
+	 * @param $y (int) ordinate of the scaling center. Default is current y position
+	 * @public
+	 * @since 2.1.000 (2008-01-07)
+	 * @see StartTransform(), StopTransform()
+	 */
+	public function Scale($s_x, $s_y, $x='', $y='') {
+		if ($x === '') {
+			$x = $this->x;
+		}
+		if ($y === '') {
+			$y = $this->y;
+		}
+		if (($s_x == 0) OR ($s_y == 0)) {
+			$this->Error('Please do not use values equal to zero for scaling');
+		}
+		$y = ($this->h - $y) * $this->k;
+		$x *= $this->k;
+		//calculate elements of transformation matrix
+		$s_x /= 100;
+		$s_y /= 100;
+		$tm = array();
+		$tm[0] = $s_x;
+		$tm[1] = 0;
+		$tm[2] = 0;
+		$tm[3] = $s_y;
+		$tm[4] = $x * (1 - $s_x);
+		$tm[5] = $y * (1 - $s_y);
+		//scale the coordinate system
+		$this->Transform($tm);
+	}
+
+	/**
+	 * Horizontal Mirroring.
+	 * @param $x (int) abscissa of the point. Default is current x position
+	 * @public
+	 * @since 2.1.000 (2008-01-07)
+	 * @see StartTransform(), StopTransform()
+	 */
+	public function MirrorH($x='') {
+		$this->Scale(-100, 100, $x);
+	}
+
+	/**
+	 * Verical Mirroring.
+	 * @param $y (int) ordinate of the point. Default is current y position
+	 * @public
+	 * @since 2.1.000 (2008-01-07)
+	 * @see StartTransform(), StopTransform()
+	 */
+	public function MirrorV($y='') {
+		$this->Scale(100, -100, '', $y);
+	}
+
+	/**
+	 * Point reflection mirroring.
+	 * @param $x (int) abscissa of the point. Default is current x position
+	 * @param $y (int) ordinate of the point. Default is current y position
+	 * @public
+	 * @since 2.1.000 (2008-01-07)
+	 * @see StartTransform(), StopTransform()
+	 */
+	public function MirrorP($x='',$y='') {
+		$this->Scale(-100, -100, $x, $y);
+	}
+
+	/**
+	 * Reflection against a straight line through point (x, y) with the gradient angle (angle).
+	 * @param $angle (float) gradient angle of the straight line. Default is 0 (horizontal line).
+	 * @param $x (int) abscissa of the point. Default is current x position
+	 * @param $y (int) ordinate of the point. Default is current y position
+	 * @public
+	 * @since 2.1.000 (2008-01-07)
+	 * @see StartTransform(), StopTransform()
+	 */
+	public function MirrorL($angle=0, $x='',$y='') {
+		$this->Scale(-100, 100, $x, $y);
+		$this->Rotate(-2*($angle-90), $x, $y);
+	}
+
+	/**
+	 * Translate graphic object horizontally.
+	 * @param $t_x (int) movement to the right (or left for RTL)
+	 * @public
+	 * @since 2.1.000 (2008-01-07)
+	 * @see StartTransform(), StopTransform()
+	 */
+	public function TranslateX($t_x) {
+		$this->Translate($t_x, 0);
+	}
+
+	/**
+	 * Translate graphic object vertically.
+	 * @param $t_y (int) movement to the bottom
+	 * @public
+	 * @since 2.1.000 (2008-01-07)
+	 * @see StartTransform(), StopTransform()
+	 */
+	public function TranslateY($t_y) {
+		$this->Translate(0, $t_y);
+	}
+
+	/**
+	 * Translate graphic object horizontally and vertically.
+	 * @param $t_x (int) movement to the right
+	 * @param $t_y (int) movement to the bottom
+	 * @public
+	 * @since 2.1.000 (2008-01-07)
+	 * @see StartTransform(), StopTransform()
+	 */
+	public function Translate($t_x, $t_y) {
+		//calculate elements of transformation matrix
+		$tm = array();
+		$tm[0] = 1;
+		$tm[1] = 0;
+		$tm[2] = 0;
+		$tm[3] = 1;
+		$tm[4] = $t_x * $this->k;
+		$tm[5] = -$t_y * $this->k;
+		//translate the coordinate system
+		$this->Transform($tm);
+	}
+
+	/**
+	 * Rotate object.
+	 * @param $angle (float) angle in degrees for counter-clockwise rotation
+	 * @param $x (int) abscissa of the rotation center. Default is current x position
+	 * @param $y (int) ordinate of the rotation center. Default is current y position
+	 * @public
+	 * @since 2.1.000 (2008-01-07)
+	 * @see StartTransform(), StopTransform()
+	 */
+	public function Rotate($angle, $x='', $y='') {
+		if ($x === '') {
+			$x = $this->x;
+		}
+		if ($y === '') {
+			$y = $this->y;
+		}
+		$y = ($this->h - $y) * $this->k;
+		$x *= $this->k;
+		//calculate elements of transformation matrix
+		$tm = array();
+		$tm[0] = cos(deg2rad($angle));
+		$tm[1] = sin(deg2rad($angle));
+		$tm[2] = -$tm[1];
+		$tm[3] = $tm[0];
+		$tm[4] = $x + ($tm[1] * $y) - ($tm[0] * $x);
+		$tm[5] = $y - ($tm[0] * $y) - ($tm[1] * $x);
+		//rotate the coordinate system around ($x,$y)
+		$this->Transform($tm);
+	}
+
+	/**
+	 * Skew horizontally.
+	 * @param $angle_x (float) angle in degrees between -90 (skew to the left) and 90 (skew to the right)
+	 * @param $x (int) abscissa of the skewing center. default is current x position
+	 * @param $y (int) ordinate of the skewing center. default is current y position
+	 * @public
+	 * @since 2.1.000 (2008-01-07)
+	 * @see StartTransform(), StopTransform()
+	 */
+	public function SkewX($angle_x, $x='', $y='') {
+		$this->Skew($angle_x, 0, $x, $y);
+	}
+
+	/**
+	 * Skew vertically.
+	 * @param $angle_y (float) angle in degrees between -90 (skew to the bottom) and 90 (skew to the top)
+	 * @param $x (int) abscissa of the skewing center. default is current x position
+	 * @param $y (int) ordinate of the skewing center. default is current y position
+	 * @public
+	 * @since 2.1.000 (2008-01-07)
+	 * @see StartTransform(), StopTransform()
+	 */
+	public function SkewY($angle_y, $x='', $y='') {
+		$this->Skew(0, $angle_y, $x, $y);
+	}
+
+	/**
+	 * Skew.
+	 * @param $angle_x (float) angle in degrees between -90 (skew to the left) and 90 (skew to the right)
+	 * @param $angle_y (float) angle in degrees between -90 (skew to the bottom) and 90 (skew to the top)
+	 * @param $x (int) abscissa of the skewing center. default is current x position
+	 * @param $y (int) ordinate of the skewing center. default is current y position
+	 * @public
+	 * @since 2.1.000 (2008-01-07)
+	 * @see StartTransform(), StopTransform()
+	 */
+	public function Skew($angle_x, $angle_y, $x='', $y='') {
+		if ($x === '') {
+			$x = $this->x;
+		}
+		if ($y === '') {
+			$y = $this->y;
+		}
+		if (($angle_x <= -90) OR ($angle_x >= 90) OR ($angle_y <= -90) OR ($angle_y >= 90)) {
+			$this->Error('Please use values between -90 and +90 degrees for Skewing.');
+		}
+		$x *= $this->k;
+		$y = ($this->h - $y) * $this->k;
+		//calculate elements of transformation matrix
+		$tm = array();
+		$tm[0] = 1;
+		$tm[1] = tan(deg2rad($angle_y));
+		$tm[2] = tan(deg2rad($angle_x));
+		$tm[3] = 1;
+		$tm[4] = -$tm[2] * $y;
+		$tm[5] = -$tm[1] * $x;
+		//skew the coordinate system
+		$this->Transform($tm);
+	}
+
+	/**
+	 * Apply graphic transformations.
+	 * @param $tm (array) transformation matrix
+	 * @protected
+	 * @since 2.1.000 (2008-01-07)
+	 * @see StartTransform(), StopTransform()
+	 */
+	protected function Transform($tm) {
+		if ($this->state != 2) {
+			return;
+		}
+		$this->_out(sprintf('%F %F %F %F %F %F cm', $tm[0], $tm[1], $tm[2], $tm[3], $tm[4], $tm[5]));
+		// add tranformation matrix
+		$this->transfmatrix[$this->transfmatrix_key][] = array('a' => $tm[0], 'b' => $tm[1], 'c' => $tm[2], 'd' => $tm[3], 'e' => $tm[4], 'f' => $tm[5]);
+		// update transformation mark
+		if ($this->inxobj) {
+			// we are inside an XObject template
+			if (end($this->xobjects[$this->xobjid]['transfmrk']) !== false) {
+				$key = key($this->xobjects[$this->xobjid]['transfmrk']);
+				$this->xobjects[$this->xobjid]['transfmrk'][$key] = strlen($this->xobjects[$this->xobjid]['outdata']);
+			}
+		} elseif (end($this->transfmrk[$this->page]) !== false) {
+			$key = key($this->transfmrk[$this->page]);
+			$this->transfmrk[$this->page][$key] = $this->pagelen[$this->page];
+		}
+	}
+
+	// END TRANSFORMATIONS SECTION -------------------------
+
+	// START GRAPHIC FUNCTIONS SECTION ---------------------
+	// The following section is based on the code provided by David Hernandez Sanz
+
+	/**
+	 * Defines the line width. By default, the value equals 0.2 mm. The method can be called before the first page is created and the value is retained from page to page.
+	 * @param $width (float) The width.
+	 * @public
+	 * @since 1.0
+	 * @see Line(), Rect(), Cell(), MultiCell()
+	 */
+	public function SetLineWidth($width) {
+		//Set line width
+		$this->LineWidth = $width;
+		$this->linestyleWidth = sprintf('%F w', ($width * $this->k));
+		if ($this->state == 2) {
+			$this->_out($this->linestyleWidth);
+		}
+	}
+
+	/**
+	 * Returns the current the line width.
+	 * @return int Line width
+	 * @public
+	 * @since 2.1.000 (2008-01-07)
+	 * @see Line(), SetLineWidth()
+	 */
+	public function GetLineWidth() {
+		return $this->LineWidth;
+	}
+
+	/**
+	 * Set line style.
+	 * @param $style (array) Line style. Array with keys among the following:
+	 * <ul>
+	 *	 <li>width (float): Width of the line in user units.</li>
+	 *	 <li>cap (string): Type of cap to put on the line. Possible values are:
+	 * butt, round, square. The difference between "square" and "butt" is that
+	 * "square" projects a flat end past the end of the line.</li>
+	 *	 <li>join (string): Type of join. Possible values are: miter, round,
+	 * bevel.</li>
+	 *	 <li>dash (mixed): Dash pattern. Is 0 (without dash) or string with
+	 * series of length values, which are the lengths of the on and off dashes.
+	 * For example: "2" represents 2 on, 2 off, 2 on, 2 off, ...; "2,1" is 2 on,
+	 * 1 off, 2 on, 1 off, ...</li>
+	 *	 <li>phase (integer): Modifier on the dash pattern which is used to shift
+	 * the point at which the pattern starts.</li>
+	 *	 <li>color (array): Draw color. Format: array(GREY) or array(R,G,B) or array(C,M,Y,K) or array(C,M,Y,K,SpotColorName).</li>
+	 * </ul>
+	 * @param $ret (boolean) if true do not send the command.
+	 * @return string the PDF command
+	 * @public
+	 * @since 2.1.000 (2008-01-08)
+	 */
+	public function SetLineStyle($style, $ret=false) {
+		$s = ''; // string to be returned
+		if (!is_array($style)) {
+			return;
+		}
+		if (isset($style['width'])) {
+			$this->LineWidth = $style['width'];
+			$this->linestyleWidth = sprintf('%F w', ($style['width'] * $this->k));
+			$s .= $this->linestyleWidth.' ';
+		}
+		if (isset($style['cap'])) {
+			$ca = array('butt' => 0, 'round'=> 1, 'square' => 2);
+			if (isset($ca[$style['cap']])) {
+				$this->linestyleCap = $ca[$style['cap']].' J';
+				$s .= $this->linestyleCap.' ';
+			}
+		}
+		if (isset($style['join'])) {
+			$ja = array('miter' => 0, 'round' => 1, 'bevel' => 2);
+			if (isset($ja[$style['join']])) {
+				$this->linestyleJoin = $ja[$style['join']].' j';
+				$s .= $this->linestyleJoin.' ';
+			}
+		}
+		if (isset($style['dash'])) {
+			$dash_string = '';
+			if ($style['dash']) {
+				if (preg_match('/^.+,/', $style['dash']) > 0) {
+					$tab = explode(',', $style['dash']);
+				} else {
+					$tab = array($style['dash']);
+				}
+				$dash_string = '';
+				foreach ($tab as $i => $v) {
+					if ($i) {
+						$dash_string .= ' ';
+					}
+					$dash_string .= sprintf('%F', $v);
+				}
+			}
+			if (!isset($style['phase']) OR !$style['dash']) {
+				$style['phase'] = 0;
+			}
+			$this->linestyleDash = sprintf('[%s] %F d', $dash_string, $style['phase']);
+			$s .= $this->linestyleDash.' ';
+		}
+		if (isset($style['color'])) {
+			$s .= $this->SetDrawColorArray($style['color'], true).' ';
+		}
+		if (!$ret AND ($this->state == 2)) {
+			$this->_out($s);
+		}
+		return $s;
+	}
+
+	/**
+	 * Begin a new subpath by moving the current point to coordinates (x, y), omitting any connecting line segment.
+	 * @param $x (float) Abscissa of point.
+	 * @param $y (float) Ordinate of point.
+	 * @protected
+	 * @since 2.1.000 (2008-01-08)
+	 */
+	protected function _outPoint($x, $y) {
+		if ($this->state == 2) {
+			$this->_out(sprintf('%F %F m', ($x * $this->k), (($this->h - $y) * $this->k)));
+		}
+	}
+
+	/**
+	 * Append a straight line segment from the current point to the point (x, y).
+	 * The new current point shall be (x, y).
+	 * @param $x (float) Abscissa of end point.
+	 * @param $y (float) Ordinate of end point.
+	 * @protected
+	 * @since 2.1.000 (2008-01-08)
+	 */
+	protected function _outLine($x, $y) {
+		if ($this->state == 2) {
+			$this->_out(sprintf('%F %F l', ($x * $this->k), (($this->h - $y) * $this->k)));
+		}
+	}
+
+	/**
+	 * Append a rectangle to the current path as a complete subpath, with lower-left corner (x, y) and dimensions widthand height in user space.
+	 * @param $x (float) Abscissa of upper-left corner.
+	 * @param $y (float) Ordinate of upper-left corner.
+	 * @param $w (float) Width.
+	 * @param $h (float) Height.
+	 * @param $op (string) options
+	 * @protected
+	 * @since 2.1.000 (2008-01-08)
+	 */
+	protected function _outRect($x, $y, $w, $h, $op) {
+		if ($this->state == 2) {
+			$this->_out(sprintf('%F %F %F %F re %s', $x * $this->k, ($this->h - $y) * $this->k, $w * $this->k, -$h * $this->k, $op));
+		}
+	}
+
+	/**
+	 * Append a cubic B�zier curve to the current path. The curve shall extend from the current point to the point (x3, y3), using (x1, y1) and (x2, y2) as the B�zier control points.
+	 * The new current point shall be (x3, y3).
+	 * @param $x1 (float) Abscissa of control point 1.
+	 * @param $y1 (float) Ordinate of control point 1.
+	 * @param $x2 (float) Abscissa of control point 2.
+	 * @param $y2 (float) Ordinate of control point 2.
+	 * @param $x3 (float) Abscissa of end point.
+	 * @param $y3 (float) Ordinate of end point.
+	 * @protected
+	 * @since 2.1.000 (2008-01-08)
+	 */
+	protected function _outCurve($x1, $y1, $x2, $y2, $x3, $y3) {
+		if ($this->state == 2) {
+			$this->_out(sprintf('%F %F %F %F %F %F c', $x1 * $this->k, ($this->h - $y1) * $this->k, $x2 * $this->k, ($this->h - $y2) * $this->k, $x3 * $this->k, ($this->h - $y3) * $this->k));
+		}
+	}
+
+	/**
+	 * Append a cubic B�zier curve to the current path. The curve shall extend from the current point to the point (x3, y3), using the current point and (x2, y2) as the B�zier control points.
+	 * The new current point shall be (x3, y3).
+	 * @param $x2 (float) Abscissa of control point 2.
+	 * @param $y2 (float) Ordinate of control point 2.
+	 * @param $x3 (float) Abscissa of end point.
+	 * @param $y3 (float) Ordinate of end point.
+	 * @protected
+	 * @since 4.9.019 (2010-04-26)
+	 */
+	protected function _outCurveV($x2, $y2, $x3, $y3) {
+		if ($this->state == 2) {
+			$this->_out(sprintf('%F %F %F %F v', $x2 * $this->k, ($this->h - $y2) * $this->k, $x3 * $this->k, ($this->h - $y3) * $this->k));
+		}
+	}
+
+	/**
+	 * Append a cubic B�zier curve to the current path. The curve shall extend from the current point to the point (x3, y3), using (x1, y1) and (x3, y3) as the B�zier control points.
+	 * The new current point shall be (x3, y3).
+	 * @param $x1 (float) Abscissa of control point 1.
+	 * @param $y1 (float) Ordinate of control point 1.
+	 * @param $x3 (float) Abscissa of end point.
+	 * @param $y3 (float) Ordinate of end point.
+	 * @protected
+	 * @since 2.1.000 (2008-01-08)
+	 */
+	protected function _outCurveY($x1, $y1, $x3, $y3) {
+		if ($this->state == 2) {
+			$this->_out(sprintf('%F %F %F %F y', $x1 * $this->k, ($this->h - $y1) * $this->k, $x3 * $this->k, ($this->h - $y3) * $this->k));
+		}
+	}
+
+	/**
+	 * Draws a line between two points.
+	 * @param $x1 (float) Abscissa of first point.
+	 * @param $y1 (float) Ordinate of first point.
+	 * @param $x2 (float) Abscissa of second point.
+	 * @param $y2 (float) Ordinate of second point.
+	 * @param $style (array) Line style. Array like for SetLineStyle(). Default value: default line style (empty array).
+	 * @public
+	 * @since 1.0
+	 * @see SetLineWidth(), SetDrawColor(), SetLineStyle()
+	 */
+	public function Line($x1, $y1, $x2, $y2, $style=array()) {
+		if ($this->state != 2) {
+			return;
+		}
+		if (is_array($style)) {
+			$this->SetLineStyle($style);
+		}
+		$this->_outPoint($x1, $y1);
+		$this->_outLine($x2, $y2);
+		$this->_out('S');
+	}
+
+	/**
+	 * Draws a rectangle.
+	 * @param $x (float) Abscissa of upper-left corner.
+	 * @param $y (float) Ordinate of upper-left corner.
+	 * @param $w (float) Width.
+	 * @param $h (float) Height.
+	 * @param $style (string) Style of rendering. See the getPathPaintOperator() function for more information.
+	 * @param $border_style (array) Border style of rectangle. Array with keys among the following:
+	 * <ul>
+	 *	 <li>all: Line style of all borders. Array like for SetLineStyle().</li>
+	 *	 <li>L, T, R, B or combinations: Line style of left, top, right or bottom border. Array like for SetLineStyle().</li>
+	 * </ul>
+	 * If a key is not present or is null, not draws the border. Default value: default line style (empty array).
+	 * @param $fill_color (array) Fill color. Format: array(GREY) or array(R,G,B) or array(C,M,Y,K) or array(C,M,Y,K,SpotColorName). Default value: default color (empty array).
+	 * @public
+	 * @since 1.0
+	 * @see SetLineStyle()
+	 */
+	public function Rect($x, $y, $w, $h, $style='', $border_style=array(), $fill_color=array()) {
+		if ($this->state != 2) {
+			return;
+		}
+		if (!(false === strpos($style, 'F')) AND !empty($fill_color)) {
+			$this->SetFillColorArray($fill_color);
+		}
+		$op = $this->getPathPaintOperator($style);
+		if ((!$border_style) OR (isset($border_style['all']))) {
+			if (isset($border_style['all']) AND $border_style['all']) {
+				$this->SetLineStyle($border_style['all']);
+				$border_style = array();
+			}
+		}
+		$this->_outRect($x, $y, $w, $h, $op);
+		if ($border_style) {
+			$border_style2 = array();
+			foreach ($border_style as $line => $value) {
+				$length = strlen($line);
+				for ($i = 0; $i < $length; ++$i) {
+					$border_style2[$line[$i]] = $value;
+				}
+			}
+			$border_style = $border_style2;
+			if (isset($border_style['L']) AND $border_style['L']) {
+				$this->Line($x, $y, $x, $y + $h, $border_style['L']);
+			}
+			if (isset($border_style['T']) AND $border_style['T']) {
+				$this->Line($x, $y, $x + $w, $y, $border_style['T']);
+			}
+			if (isset($border_style['R']) AND $border_style['R']) {
+				$this->Line($x + $w, $y, $x + $w, $y + $h, $border_style['R']);
+			}
+			if (isset($border_style['B']) AND $border_style['B']) {
+				$this->Line($x, $y + $h, $x + $w, $y + $h, $border_style['B']);
+			}
+		}
+	}
+
+	/**
+	 * Draws a Bezier curve.
+	 * The Bezier curve is a tangent to the line between the control points at
+	 * either end of the curve.
+	 * @param $x0 (float) Abscissa of start point.
+	 * @param $y0 (float) Ordinate of start point.
+	 * @param $x1 (float) Abscissa of control point 1.
+	 * @param $y1 (float) Ordinate of control point 1.
+	 * @param $x2 (float) Abscissa of control point 2.
+	 * @param $y2 (float) Ordinate of control point 2.
+	 * @param $x3 (float) Abscissa of end point.
+	 * @param $y3 (float) Ordinate of end point.
+	 * @param $style (string) Style of rendering. See the getPathPaintOperator() function for more information.
+	 * @param $line_style (array) Line style of curve. Array like for SetLineStyle(). Default value: default line style (empty array).
+	 * @param $fill_color (array) Fill color. Format: array(GREY) or array(R,G,B) or array(C,M,Y,K) or array(C,M,Y,K,SpotColorName). Default value: default color (empty array).
+	 * @public
+	 * @see SetLineStyle()
+	 * @since 2.1.000 (2008-01-08)
+	 */
+	public function Curve($x0, $y0, $x1, $y1, $x2, $y2, $x3, $y3, $style='', $line_style=array(), $fill_color=array()) {
+		if ($this->state != 2) {
+			return;
+		}
+		if (!(false === strpos($style, 'F')) AND isset($fill_color)) {
+			$this->SetFillColorArray($fill_color);
+		}
+		$op = $this->getPathPaintOperator($style);
+		if ($line_style) {
+			$this->SetLineStyle($line_style);
+		}
+		$this->_outPoint($x0, $y0);
+		$this->_outCurve($x1, $y1, $x2, $y2, $x3, $y3);
+		$this->_out($op);
+	}
+
+	/**
+	 * Draws a poly-Bezier curve.
+	 * Each Bezier curve segment is a tangent to the line between the control points at
+	 * either end of the curve.
+	 * @param $x0 (float) Abscissa of start point.
+	 * @param $y0 (float) Ordinate of start point.
+	 * @param $segments (float) An array of bezier descriptions. Format: array(x1, y1, x2, y2, x3, y3).
+	 * @param $style (string) Style of rendering. See the getPathPaintOperator() function for more information.
+	 * @param $line_style (array) Line style of curve. Array like for SetLineStyle(). Default value: default line style (empty array).
+	 * @param $fill_color (array) Fill color. Format: array(GREY) or array(R,G,B) or array(C,M,Y,K) or array(C,M,Y,K,SpotColorName). Default value: default color (empty array).
+	 * @public
+	 * @see SetLineStyle()
+	 * @since 3.0008 (2008-05-12)
+	 */
+	public function Polycurve($x0, $y0, $segments, $style='', $line_style=array(), $fill_color=array()) {
+		if ($this->state != 2) {
+			return;
+		}
+		if (!(false === strpos($style, 'F')) AND isset($fill_color)) {
+			$this->SetFillColorArray($fill_color);
+		}
+		$op = $this->getPathPaintOperator($style);
+		if ($op == 'f') {
+			$line_style = array();
+		}
+		if ($line_style) {
+			$this->SetLineStyle($line_style);
+		}
+		$this->_outPoint($x0, $y0);
+		foreach ($segments as $segment) {
+			list($x1, $y1, $x2, $y2, $x3, $y3) = $segment;
+			$this->_outCurve($x1, $y1, $x2, $y2, $x3, $y3);
+		}
+		$this->_out($op);
+	}
+
+	/**
+	 * Draws an ellipse.
+	 * An ellipse is formed from n Bezier curves.
+	 * @param $x0 (float) Abscissa of center point.
+	 * @param $y0 (float) Ordinate of center point.
+	 * @param $rx (float) Horizontal radius.
+	 * @param $ry (float) Vertical radius (if ry = 0 then is a circle, see Circle()). Default value: 0.
+	 * @param $angle: (float) Angle oriented (anti-clockwise). Default value: 0.
+	 * @param $astart: (float) Angle start of draw line. Default value: 0.
+	 * @param $afinish: (float) Angle finish of draw line. Default value: 360.
+	 * @param $style (string) Style of rendering. See the getPathPaintOperator() function for more information.
+	 * @param $line_style (array) Line style of ellipse. Array like for SetLineStyle(). Default value: default line style (empty array).
+	 * @param $fill_color (array) Fill color. Format: array(GREY) or array(R,G,B) or array(C,M,Y,K) or array(C,M,Y,K,SpotColorName). Default value: default color (empty array).
+	 * @param $nc (integer) Number of curves used to draw a 90 degrees portion of ellipse.
+	 * @author Nicola Asuni
+	 * @public
+	 * @since 2.1.000 (2008-01-08)
+	 */
+	public function Ellipse($x0, $y0, $rx, $ry='', $angle=0, $astart=0, $afinish=360, $style='', $line_style=array(), $fill_color=array(), $nc=2) {
+		if ($this->state != 2) {
+			return;
+		}
+		if ($this->empty_string($ry) OR ($ry == 0)) {
+			$ry = $rx;
+		}
+		if (!(false === strpos($style, 'F')) AND isset($fill_color)) {
+			$this->SetFillColorArray($fill_color);
+		}
+		$op = $this->getPathPaintOperator($style);
+		if ($op == 'f') {
+			$line_style = array();
+		}
+		if ($line_style) {
+			$this->SetLineStyle($line_style);
+		}
+		$this->_outellipticalarc($x0, $y0, $rx, $ry, $angle, $astart, $afinish, false, $nc, true, true, false);
+		$this->_out($op);
+	}
+
+	/**
+	 * Append an elliptical arc to the current path.
+	 * An ellipse is formed from n Bezier curves.
+	 * @param $xc (float) Abscissa of center point.
+	 * @param $yc (float) Ordinate of center point.
+	 * @param $rx (float) Horizontal radius.
+	 * @param $ry (float) Vertical radius (if ry = 0 then is a circle, see Circle()). Default value: 0.
+	 * @param $xang: (float) Angle between the X-axis and the major axis of the ellipse. Default value: 0.
+	 * @param $angs: (float) Angle start of draw line. Default value: 0.
+	 * @param $angf: (float) Angle finish of draw line. Default value: 360.
+	 * @param $pie (boolean) if true do not mark the border point (used to draw pie sectors).
+	 * @param $nc (integer) Number of curves used to draw a 90 degrees portion of ellipse.
+	 * @param $startpoint (boolean) if true output a starting point.
+	 * @param $ccw (boolean) if true draws in counter-clockwise.
+	 * @param $svg (boolean) if true the angles are in svg mode (already calculated).
+	 * @return array bounding box coordinates (x min, y min, x max, y max)
+	 * @author Nicola Asuni
+	 * @protected
+	 * @since 4.9.019 (2010-04-26)
+	 */
+	protected function _outellipticalarc($xc, $yc, $rx, $ry, $xang=0, $angs=0, $angf=360, $pie=false, $nc=2, $startpoint=true, $ccw=true, $svg=false) {
+		$k = $this->k;
+		if ($nc < 2) {
+			$nc = 2;
+		}
+		$xmin = 2147483647;
+		$ymin = 2147483647;
+		$xmax = 0;
+		$ymax = 0;
+		if ($pie) {
+			// center of the arc
+			$this->_outPoint($xc, $yc);
+		}
+		$xang = deg2rad((float) $xang);
+		$angs = deg2rad((float) $angs);
+		$angf = deg2rad((float) $angf);
+		if ($svg) {
+			$as = $angs;
+			$af = $angf;
+		} else {
+			$as = atan2((sin($angs) / $ry), (cos($angs) / $rx));
+			$af = atan2((sin($angf) / $ry), (cos($angf) / $rx));
+		}
+		if ($as < 0) {
+			$as += (2 * M_PI);
+		}
+		if ($af < 0) {
+			$af += (2 * M_PI);
+		}
+		if ($ccw AND ($as > $af)) {
+			// reverse rotation
+			$as -= (2 * M_PI);
+		} elseif (!$ccw AND ($as < $af)) {
+			// reverse rotation
+			$af -= (2 * M_PI);
+		}
+		$total_angle = ($af - $as);
+		if ($nc < 2) {
+			$nc = 2;
+		}
+		// total arcs to draw
+		$nc *= (2 * abs($total_angle) / M_PI);
+		$nc = round($nc) + 1;
+		// angle of each arc
+		$arcang = ($total_angle / $nc);
+		// center point in PDF coordinates
+		$x0 = $xc;
+		$y0 = ($this->h - $yc);
+		// starting angle
+		$ang = $as;
+		$alpha = sin($arcang) * ((sqrt(4 + (3 * pow(tan(($arcang) / 2), 2))) - 1) / 3);
+		$cos_xang = cos($xang);
+		$sin_xang = sin($xang);
+		$cos_ang = cos($ang);
+		$sin_ang = sin($ang);
+		// first arc point
+		$px1 = $x0 + ($rx * $cos_xang * $cos_ang) - ($ry * $sin_xang * $sin_ang);
+		$py1 = $y0 + ($rx * $sin_xang * $cos_ang) + ($ry * $cos_xang * $sin_ang);
+		// first Bezier control point
+		$qx1 = ($alpha * ((-$rx * $cos_xang * $sin_ang) - ($ry * $sin_xang * $cos_ang)));
+		$qy1 = ($alpha * ((-$rx * $sin_xang * $sin_ang) + ($ry * $cos_xang * $cos_ang)));
+		if ($pie) {
+			// line from center to arc starting point
+			$this->_outLine($px1, $this->h - $py1);
+		} elseif ($startpoint) {
+			// arc starting point
+			$this->_outPoint($px1, $this->h - $py1);
+		}
+		// draw arcs
+		for ($i = 1; $i <= $nc; ++$i) {
+			// starting angle
+			$ang = $as + ($i * $arcang);
+			if ($i == $nc) {
+				$ang = $af;
+			}
+			$cos_ang = cos($ang);
+			$sin_ang = sin($ang);
+			// second arc point
+			$px2 = $x0 + ($rx * $cos_xang * $cos_ang) - ($ry * $sin_xang * $sin_ang);
+			$py2 = $y0 + ($rx * $sin_xang * $cos_ang) + ($ry * $cos_xang * $sin_ang);
+			// second Bezier control point
+			$qx2 = ($alpha * ((-$rx * $cos_xang * $sin_ang) - ($ry * $sin_xang * $cos_ang)));
+			$qy2 = ($alpha * ((-$rx * $sin_xang * $sin_ang) + ($ry * $cos_xang * $cos_ang)));
+			// draw arc
+			$cx1 = ($px1 + $qx1);
+			$cy1 = ($this->h - ($py1 + $qy1));
+			$cx2 = ($px2 - $qx2);
+			$cy2 = ($this->h - ($py2 - $qy2));
+			$cx3 = $px2;
+			$cy3 = ($this->h - $py2);
+			$this->_outCurve($cx1, $cy1, $cx2, $cy2, $cx3, $cy3);
+			// get bounding box coordinates
+			$xmin = min($xmin, $cx1, $cx2, $cx3);
+			$ymin = min($ymin, $cy1, $cy2, $cy3);
+			$xmax = max($xmax, $cx1, $cx2, $cx3);
+			$ymax = max($ymax, $cy1, $cy2, $cy3);
+			// move to next point
+			$px1 = $px2;
+			$py1 = $py2;
+			$qx1 = $qx2;
+			$qy1 = $qy2;
+		}
+		if ($pie) {
+			$this->_outLine($xc, $yc);
+			// get bounding box coordinates
+			$xmin = min($xmin, $xc);
+			$ymin = min($ymin, $yc);
+			$xmax = max($xmax, $xc);
+			$ymax = max($ymax, $yc);
+		}
+		return array($xmin, $ymin, $xmax, $ymax);
+	}
+
+	/**
+	 * Draws a circle.
+	 * A circle is formed from n Bezier curves.
+	 * @param $x0 (float) Abscissa of center point.
+	 * @param $y0 (float) Ordinate of center point.
+	 * @param $r (float) Radius.
+	 * @param $angstr: (float) Angle start of draw line. Default value: 0.
+	 * @param $angend: (float) Angle finish of draw line. Default value: 360.
+	 * @param $style (string) Style of rendering. See the getPathPaintOperator() function for more information.
+	 * @param $line_style (array) Line style of circle. Array like for SetLineStyle(). Default value: default line style (empty array).
+	 * @param $fill_color (array) Fill color. Format: array(red, green, blue). Default value: default color (empty array).
+	 * @param $nc (integer) Number of curves used to draw a 90 degrees portion of circle.
+	 * @public
+	 * @since 2.1.000 (2008-01-08)
+	 */
+	public function Circle($x0, $y0, $r, $angstr=0, $angend=360, $style='', $line_style=array(), $fill_color=array(), $nc=2) {
+		$this->Ellipse($x0, $y0, $r, $r, 0, $angstr, $angend, $style, $line_style, $fill_color, $nc);
+	}
+
+	/**
+	 * Draws a polygonal line
+	 * @param $p (array) Points 0 to ($np - 1). Array with values (x0, y0, x1, y1,..., x(np-1), y(np - 1))
+	 * @param $style (string) Style of rendering. See the getPathPaintOperator() function for more information.
+	 * @param $line_style (array) Line style of polygon. Array with keys among the following:
+	 * <ul>
+	 *	 <li>all: Line style of all lines. Array like for SetLineStyle().</li>
+	 *	 <li>0 to ($np - 1): Line style of each line. Array like for SetLineStyle().</li>
+	 * </ul>
+	 * If a key is not present or is null, not draws the line. Default value is default line style (empty array).
+	 * @param $fill_color (array) Fill color. Format: array(GREY) or array(R,G,B) or array(C,M,Y,K) or array(C,M,Y,K,SpotColorName). Default value: default color (empty array).
+	 * @since 4.8.003 (2009-09-15)
+	 * @public
+	 */
+	public function PolyLine($p, $style='', $line_style=array(), $fill_color=array()) {
+		$this->Polygon($p, $style, $line_style, $fill_color, false);
+	}
+
+	/**
+	 * Draws a polygon.
+	 * @param $p (array) Points 0 to ($np - 1). Array with values (x0, y0, x1, y1,..., x(np-1), y(np - 1))
+	 * @param $style (string) Style of rendering. See the getPathPaintOperator() function for more information.
+	 * @param $line_style (array) Line style of polygon. Array with keys among the following:
+	 * <ul>
+	 *	 <li>all: Line style of all lines. Array like for SetLineStyle().</li>
+	 *	 <li>0 to ($np - 1): Line style of each line. Array like for SetLineStyle().</li>
+	 * </ul>
+	 * If a key is not present or is null, not draws the line. Default value is default line style (empty array).
+	 * @param $fill_color (array) Fill color. Format: array(GREY) or array(R,G,B) or array(C,M,Y,K) or array(C,M,Y,K,SpotColorName). Default value: default color (empty array).
+	 * @param $closed (boolean) if true the polygon is closes, otherwise will remain open
+	 * @public
+	 * @since 2.1.000 (2008-01-08)
+	 */
+	public function Polygon($p, $style='', $line_style=array(), $fill_color=array(), $closed=true) {
+		if ($this->state != 2) {
+			return;
+		}
+		$nc = count($p); // number of coordinates
+		$np = $nc / 2; // number of points
+		if ($closed) {
+			// close polygon by adding the first 2 points at the end (one line)
+			for ($i = 0; $i < 4; ++$i) {
+				$p[$nc + $i] = $p[$i];
+			}
+			// copy style for the last added line
+			if (isset($line_style[0])) {
+				$line_style[$np] = $line_style[0];
+			}
+			$nc += 4;
+		}
+		if (!(false === strpos($style, 'F')) AND isset($fill_color)) {
+			$this->SetFillColorArray($fill_color);
+		}
+		$op = $this->getPathPaintOperator($style);
+		if ($op == 'f') {
+			$line_style = array();
+		}
+		$draw = true;
+		if ($line_style) {
+			if (isset($line_style['all'])) {
+				$this->SetLineStyle($line_style['all']);
+			} else {
+				$draw = false;
+				if ($op == 'B') {
+					// draw fill
+					$op = 'f';
+					$this->_outPoint($p[0], $p[1]);
+					for ($i = 2; $i < $nc; $i = $i + 2) {
+						$this->_outLine($p[$i], $p[$i + 1]);
+					}
+					$this->_out($op);
+				}
+				// draw outline
+				$this->_outPoint($p[0], $p[1]);
+				for ($i = 2; $i < $nc; $i = $i + 2) {
+					$line_num = ($i / 2) - 1;
+					if (isset($line_style[$line_num])) {
+						if ($line_style[$line_num] != 0) {
+							if (is_array($line_style[$line_num])) {
+								$this->_out('S');
+								$this->SetLineStyle($line_style[$line_num]);
+								$this->_outPoint($p[$i - 2], $p[$i - 1]);
+								$this->_outLine($p[$i], $p[$i + 1]);
+								$this->_out('S');
+								$this->_outPoint($p[$i], $p[$i + 1]);
+							} else {
+								$this->_outLine($p[$i], $p[$i + 1]);
+							}
+						}
+					} else {
+						$this->_outLine($p[$i], $p[$i + 1]);
+					}
+				}
+				$this->_out($op);
+			}
+		}
+		if ($draw) {
+			$this->_outPoint($p[0], $p[1]);
+			for ($i = 2; $i < $nc; $i = $i + 2) {
+				$this->_outLine($p[$i], $p[$i + 1]);
+			}
+			$this->_out($op);
+		}
+	}
+
+	/**
+	 * Draws a regular polygon.
+	 * @param $x0 (float) Abscissa of center point.
+	 * @param $y0 (float) Ordinate of center point.
+	 * @param $r: (float) Radius of inscribed circle.
+	 * @param $ns (integer) Number of sides.
+	 * @param $angle (float) Angle oriented (anti-clockwise). Default value: 0.
+	 * @param $draw_circle (boolean) Draw inscribed circle or not. Default value: false.
+	 * @param $style (string) Style of rendering. See the getPathPaintOperator() function for more information.
+	 * @param $line_style (array) Line style of polygon sides. Array with keys among the following:
+	 * <ul>
+	 *	 <li>all: Line style of all sides. Array like for SetLineStyle().</li>
+	 *	 <li>0 to ($ns - 1): Line style of each side. Array like for SetLineStyle().</li>
+	 * </ul>
+	 * If a key is not present or is null, not draws the side. Default value is default line style (empty array).
+	 * @param $fill_color (array) Fill color. Format: array(red, green, blue). Default value: default color (empty array).
+	 * @param $circle_style (string) Style of rendering of inscribed circle (if draws). Possible values are:
+	 * <ul>
+	 *	 <li>D or empty string: Draw (default).</li>
+	 *	 <li>F: Fill.</li>
+	 *	 <li>DF or FD: Draw and fill.</li>
+	 *	 <li>CNZ: Clipping mode (using the even-odd rule to determine which regions lie inside the clipping path).</li>
+	 *	 <li>CEO: Clipping mode (using the nonzero winding number rule to determine which regions lie inside the clipping path).</li>
+	 * </ul>
+	 * @param $circle_outLine_style (array) Line style of inscribed circle (if draws). Array like for SetLineStyle(). Default value: default line style (empty array).
+	 * @param $circle_fill_color (array) Fill color of inscribed circle (if draws). Format: array(red, green, blue). Default value: default color (empty array).
+	 * @public
+	 * @since 2.1.000 (2008-01-08)
+	 */
+	public function RegularPolygon($x0, $y0, $r, $ns, $angle=0, $draw_circle=false, $style='', $line_style=array(), $fill_color=array(), $circle_style='', $circle_outLine_style=array(), $circle_fill_color=array()) {
+		if (3 > $ns) {
+			$ns = 3;
+		}
+		if ($draw_circle) {
+			$this->Circle($x0, $y0, $r, 0, 360, $circle_style, $circle_outLine_style, $circle_fill_color);
+		}
+		$p = array();
+		for ($i = 0; $i < $ns; ++$i) {
+			$a = $angle + ($i * 360 / $ns);
+			$a_rad = deg2rad((float) $a);
+			$p[] = $x0 + ($r * sin($a_rad));
+			$p[] = $y0 + ($r * cos($a_rad));
+		}
+		$this->Polygon($p, $style, $line_style, $fill_color);
+	}
+
+	/**
+	 * Draws a star polygon
+	 * @param $x0 (float) Abscissa of center point.
+	 * @param $y0 (float) Ordinate of center point.
+	 * @param $r (float) Radius of inscribed circle.
+	 * @param $nv (integer) Number of vertices.
+	 * @param $ng (integer) Number of gap (if ($ng % $nv = 1) then is a regular polygon).
+	 * @param $angle: (float) Angle oriented (anti-clockwise). Default value: 0.
+	 * @param $draw_circle: (boolean) Draw inscribed circle or not. Default value is false.
+	 * @param $style (string) Style of rendering. See the getPathPaintOperator() function for more information.
+	 * @param $line_style (array) Line style of polygon sides. Array with keys among the following:
+	 * <ul>
+	 *	 <li>all: Line style of all sides. Array like for
+	 * SetLineStyle().</li>
+	 *	 <li>0 to (n - 1): Line style of each side. Array like for SetLineStyle().</li>
+	 * </ul>
+	 * If a key is not present or is null, not draws the side. Default value is default line style (empty array).
+	 * @param $fill_color (array) Fill color. Format: array(red, green, blue). Default value: default color (empty array).
+	 * @param $circle_style (string) Style of rendering of inscribed circle (if draws). Possible values are:
+	 * <ul>
+	 *	 <li>D or empty string: Draw (default).</li>
+	 *	 <li>F: Fill.</li>
+	 *	 <li>DF or FD: Draw and fill.</li>
+	 *	 <li>CNZ: Clipping mode (using the even-odd rule to determine which regions lie inside the clipping path).</li>
+	 *	 <li>CEO: Clipping mode (using the nonzero winding number rule to determine which regions lie inside the clipping path).</li>
+	 * </ul>
+	 * @param $circle_outLine_style (array) Line style of inscribed circle (if draws). Array like for SetLineStyle(). Default value: default line style (empty array).
+	 * @param $circle_fill_color (array) Fill color of inscribed circle (if draws). Format: array(red, green, blue). Default value: default color (empty array).
+	 * @public
+	 * @since 2.1.000 (2008-01-08)
+	 */
+	public function StarPolygon($x0, $y0, $r, $nv, $ng, $angle=0, $draw_circle=false, $style='', $line_style=array(), $fill_color=array(), $circle_style='', $circle_outLine_style=array(), $circle_fill_color=array()) {
+		if ($nv < 2) {
+			$nv = 2;
+		}
+		if ($draw_circle) {
+			$this->Circle($x0, $y0, $r, 0, 360, $circle_style, $circle_outLine_style, $circle_fill_color);
+		}
+		$p2 = array();
+		$visited = array();
+		for ($i = 0; $i < $nv; ++$i) {
+			$a = $angle + ($i * 360 / $nv);
+			$a_rad = deg2rad((float) $a);
+			$p2[] = $x0 + ($r * sin($a_rad));
+			$p2[] = $y0 + ($r * cos($a_rad));
+			$visited[] = false;
+		}
+		$p = array();
+		$i = 0;
+		do {
+			$p[] = $p2[$i * 2];
+			$p[] = $p2[($i * 2) + 1];
+			$visited[$i] = true;
+			$i += $ng;
+			$i %= $nv;
+		} while (!$visited[$i]);
+		$this->Polygon($p, $style, $line_style, $fill_color);
+	}
+
+	/**
+	 * Draws a rounded rectangle.
+	 * @param $x (float) Abscissa of upper-left corner.
+	 * @param $y (float) Ordinate of upper-left corner.
+	 * @param $w (float) Width.
+	 * @param $h (float) Height.
+	 * @param $r (float) the radius of the circle used to round off the corners of the rectangle.
+	 * @param $round_corner (string) Draws rounded corner or not. String with a 0 (not rounded i-corner) or 1 (rounded i-corner) in i-position. Positions are, in order and begin to 0: top right, bottom right, bottom left and top left. Default value: all rounded corner ("1111").
+	 * @param $style (string) Style of rendering. See the getPathPaintOperator() function for more information.
+	 * @param $border_style (array) Border style of rectangle. Array like for SetLineStyle(). Default value: default line style (empty array).
+	 * @param $fill_color (array) Fill color. Format: array(GREY) or array(R,G,B) or array(C,M,Y,K) or array(C,M,Y,K,SpotColorName). Default value: default color (empty array).
+	 * @public
+	 * @since 2.1.000 (2008-01-08)
+	 */
+	public function RoundedRect($x, $y, $w, $h, $r, $round_corner='1111', $style='', $border_style=array(), $fill_color=array()) {
+		$this->RoundedRectXY($x, $y, $w, $h, $r, $r, $round_corner, $style, $border_style, $fill_color);
+	}
+
+	/**
+	 * Draws a rounded rectangle.
+	 * @param $x (float) Abscissa of upper-left corner.
+	 * @param $y (float) Ordinate of upper-left corner.
+	 * @param $w (float) Width.
+	 * @param $h (float) Height.
+	 * @param $rx (float) the x-axis radius of the ellipse used to round off the corners of the rectangle.
+	 * @param $ry (float) the y-axis radius of the ellipse used to round off the corners of the rectangle.
+	 * @param $round_corner (string) Draws rounded corner or not. String with a 0 (not rounded i-corner) or 1 (rounded i-corner) in i-position. Positions are, in order and begin to 0: top right, bottom right, bottom left and top left. Default value: all rounded corner ("1111").
+	 * @param $style (string) Style of rendering. See the getPathPaintOperator() function for more information.
+	 * @param $border_style (array) Border style of rectangle. Array like for SetLineStyle(). Default value: default line style (empty array).
+	 * @param $fill_color (array) Fill color. Format: array(GREY) or array(R,G,B) or array(C,M,Y,K) or array(C,M,Y,K,SpotColorName). Default value: default color (empty array).
+	 * @public
+	 * @since 4.9.019 (2010-04-22)
+	 */
+	public function RoundedRectXY($x, $y, $w, $h, $rx, $ry, $round_corner='1111', $style='', $border_style=array(), $fill_color=array()) {
+		if ($this->state != 2) {
+			return;
+		}
+		if (($round_corner == '0000') OR (($rx == $ry) AND ($rx == 0))) {
+			// Not rounded
+			$this->Rect($x, $y, $w, $h, $style, $border_style, $fill_color);
+			return;
+		}
+		// Rounded
+		if (!(false === strpos($style, 'F')) AND isset($fill_color)) {
+			$this->SetFillColorArray($fill_color);
+		}
+		$op = $this->getPathPaintOperator($style);
+		if ($op == 'f') {
+			$border_style = array();
+		}
+		if ($border_style) {
+			$this->SetLineStyle($border_style);
+		}
+		$MyArc = 4 / 3 * (sqrt(2) - 1);
+		$this->_outPoint($x + $rx, $y);
+		$xc = $x + $w - $rx;
+		$yc = $y + $ry;
+		$this->_outLine($xc, $y);
+		if ($round_corner[0]) {
+			$this->_outCurve($xc + ($rx * $MyArc), $yc - $ry, $xc + $rx, $yc - ($ry * $MyArc), $xc + $rx, $yc);
+		} else {
+			$this->_outLine($x + $w, $y);
+		}
+		$xc = $x + $w - $rx;
+		$yc = $y + $h - $ry;
+		$this->_outLine($x + $w, $yc);
+		if ($round_corner[1]) {
+			$this->_outCurve($xc + $rx, $yc + ($ry * $MyArc), $xc + ($rx * $MyArc), $yc + $ry, $xc, $yc + $ry);
+		} else {
+			$this->_outLine($x + $w, $y + $h);
+		}
+		$xc = $x + $rx;
+		$yc = $y + $h - $ry;
+		$this->_outLine($xc, $y + $h);
+		if ($round_corner[2]) {
+			$this->_outCurve($xc - ($rx * $MyArc), $yc + $ry, $xc - $rx, $yc + ($ry * $MyArc), $xc - $rx, $yc);
+		} else {
+			$this->_outLine($x, $y + $h);
+		}
+		$xc = $x + $rx;
+		$yc = $y + $ry;
+		$this->_outLine($x, $yc);
+		if ($round_corner[3]) {
+			$this->_outCurve($xc - $rx, $yc - ($ry * $MyArc), $xc - ($rx * $MyArc), $yc - $ry, $xc, $yc - $ry);
+		} else {
+			$this->_outLine($x, $y);
+			$this->_outLine($x + $rx, $y);
+		}
+		$this->_out($op);
+	}
+
+	/**
+	 * Draws a grahic arrow.
+	 * @param $x0 (float) Abscissa of first point.
+	 * @param $y0 (float) Ordinate of first point.
+	 * @param $x1 (float) Abscissa of second point.
+	 * @param $y1 (float) Ordinate of second point.
+	 * @param $head_style (int) (0 = draw only arrowhead arms, 1 = draw closed arrowhead, but no fill, 2 = closed and filled arrowhead, 3 = filled arrowhead)
+	 * @param $arm_size (float) length of arrowhead arms
+	 * @param $arm_angle (int) angle between an arm and the shaft
+	 * @author Piotr Galecki, Nicola Asuni, Andy Meier
+	 * @since 4.6.018 (2009-07-10)
+	 */
+	public function Arrow($x0, $y0, $x1, $y1, $head_style=0, $arm_size=5, $arm_angle=15) {
+		// getting arrow direction angle
+		// 0 deg angle is when both arms go along X axis. angle grows clockwise.
+		$dir_angle = atan2(($y0 - $y1), ($x0 - $x1));
+		if ($dir_angle < 0) {
+			$dir_angle += (2 * M_PI);
+		}
+		$arm_angle = deg2rad($arm_angle);
+		$sx1 = $x1;
+		$sy1 = $y1;
+		if ($head_style > 0) {
+			// calculate the stopping point for the arrow shaft
+			$sx1 = $x1 + (($arm_size - $this->LineWidth) * cos($dir_angle));
+			$sy1 = $y1 + (($arm_size - $this->LineWidth) * sin($dir_angle));
+		}
+		// main arrow line / shaft
+		$this->Line($x0, $y0, $sx1, $sy1);
+		// left arrowhead arm tip
+		$x2L = $x1 + ($arm_size * cos($dir_angle + $arm_angle));
+		$y2L = $y1 + ($arm_size * sin($dir_angle + $arm_angle));
+		// right arrowhead arm tip
+		$x2R = $x1 + ($arm_size * cos($dir_angle - $arm_angle));
+		$y2R = $y1 + ($arm_size * sin($dir_angle - $arm_angle));
+		$mode = 'D';
+		$style = array();
+		switch ($head_style) {
+			case 0: {
+				// draw only arrowhead arms
+				$mode = 'D';
+				$style = array(1, 1, 0);
+				break;
+			}
+			case 1: {
+				// draw closed arrowhead, but no fill
+				$mode = 'D';
+				break;
+			}
+			case 2: {
+				// closed and filled arrowhead
+				$mode = 'DF';
+				break;
+			}
+			case 3: {
+				// filled arrowhead
+				$mode = 'F';
+				break;
+			}
+		}
+		$this->Polygon(array($x2L, $y2L, $x1, $y1, $x2R, $y2R), $mode, $style, array());
+	}
+
+	// END GRAPHIC FUNCTIONS SECTION -----------------------
+
+	// BIDIRECTIONAL TEXT SECTION --------------------------
+
+	/**
+	 * Reverse the RLT substrings using the Bidirectional Algorithm (http://unicode.org/reports/tr9/).
+	 * @param $str (string) string to manipulate.
+	 * @param $setbom (bool) if true set the Byte Order Mark (BOM = 0xFEFF)
+	 * @param $forcertl (bool) if true forces RTL text direction
+	 * @return string
+	 * @protected
+	 * @author Nicola Asuni
+	 * @since 2.1.000 (2008-01-08)
+	 */
+	protected function utf8StrRev($str, $setbom=false, $forcertl=false) {
+		return $this->utf8StrArrRev($this->UTF8StringToArray($str), $str, $setbom, $forcertl);
+	}
+
+	/**
+	 * Reverse the RLT substrings array using the Bidirectional Algorithm (http://unicode.org/reports/tr9/).
+	 * @param $arr (array) array of unicode values.
+	 * @param $str (string) string to manipulate (or empty value).
+	 * @param $setbom (bool) if true set the Byte Order Mark (BOM = 0xFEFF)
+	 * @param $forcertl (bool) if true forces RTL text direction
+	 * @return string
+	 * @protected
+	 * @author Nicola Asuni
+	 * @since 4.9.000 (2010-03-27)
+	 */
+	protected function utf8StrArrRev($arr, $str='', $setbom=false, $forcertl=false) {
+		return $this->arrUTF8ToUTF16BE($this->utf8Bidi($arr, $str, $forcertl), $setbom);
+	}
+
+	/**
+	 * Reverse the RLT substrings using the Bidirectional Algorithm (http://unicode.org/reports/tr9/).
+	 * @param $ta (array) array of characters composing the string.
+	 * @param $str (string) string to process
+	 * @param $forcertl (bool) if 'R' forces RTL, if 'L' forces LTR
+	 * @return array of unicode chars
+	 * @author Nicola Asuni
+	 * @protected
+	 * @since 2.4.000 (2008-03-06)
+	 */
+	protected function utf8Bidi($ta, $str='', $forcertl=false) {
+		// paragraph embedding level
+		$pel = 0;
+		// max level
+		$maxlevel = 0;
+		if ($this->empty_string($str)) {
+			// create string from array
+			$str = $this->UTF8ArrSubString($ta);
+		}
+		// check if string contains arabic text
+		if (preg_match($this->unicode->uni_RE_PATTERN_ARABIC, $str)) {
+			$arabic = true;
+		} else {
+			$arabic = false;
+		}
+		// check if string contains RTL text
+		if (!($forcertl OR $arabic OR preg_match($this->unicode->uni_RE_PATTERN_RTL, $str))) {
+			return $ta;
+		}
+
+		// get number of chars
+		$numchars = count($ta);
+
+		if ($forcertl == 'R') {
+			$pel = 1;
+		} elseif ($forcertl == 'L') {
+			$pel = 0;
+		} else {
+			// P2. In each paragraph, find the first character of type L, AL, or R.
+			// P3. If a character is found in P2 and it is of type AL or R, then set the paragraph embedding level to one; otherwise, set it to zero.
+			for ($i=0; $i < $numchars; ++$i) {
+				$type = $this->unicode->uni_type[$ta[$i]];
+				if ($type == 'L') {
+					$pel = 0;
+					break;
+				} elseif (($type == 'AL') OR ($type == 'R')) {
+					$pel = 1;
+					break;
+				}
+			}
+		}
+
+		// Current Embedding Level
+		$cel = $pel;
+		// directional override status
+		$dos = 'N';
+		$remember = array();
+		// start-of-level-run
+		$sor = $pel % 2 ? 'R' : 'L';
+		$eor = $sor;
+
+		// Array of characters data
+		$chardata = Array();
+
+		// X1. Begin by setting the current embedding level to the paragraph embedding level. Set the directional override status to neutral. Process each character iteratively, applying rules X2 through X9. Only embedding levels from 0 to 61 are valid in this phase.
+		// In the resolution of levels in rules I1 and I2, the maximum embedding level of 62 can be reached.
+		for ($i=0; $i < $numchars; ++$i) {
+			if ($ta[$i] == $this->unicode->uni_RLE) {
+				// X2. With each RLE, compute the least greater odd embedding level.
+				//	a. If this new level would be valid, then this embedding code is valid. Remember (push) the current embedding level and override status. Reset the current level to this new level, and reset the override status to neutral.
+				//	b. If the new level would not be valid, then this code is invalid. Do not change the current level or override status.
+				$next_level = $cel + ($cel % 2) + 1;
+				if ($next_level < 62) {
+					$remember[] = array('num' => $this->unicode->uni_RLE, 'cel' => $cel, 'dos' => $dos);
+					$cel = $next_level;
+					$dos = 'N';
+					$sor = $eor;
+					$eor = $cel % 2 ? 'R' : 'L';
+				}
+			} elseif ($ta[$i] == $this->unicode->uni_LRE) {
+				// X3. With each LRE, compute the least greater even embedding level.
+				//	a. If this new level would be valid, then this embedding code is valid. Remember (push) the current embedding level and override status. Reset the current level to this new level, and reset the override status to neutral.
+				//	b. If the new level would not be valid, then this code is invalid. Do not change the current level or override status.
+				$next_level = $cel + 2 - ($cel % 2);
+				if ( $next_level < 62 ) {
+					$remember[] = array('num' => $this->unicode->uni_LRE, 'cel' => $cel, 'dos' => $dos);
+					$cel = $next_level;
+					$dos = 'N';
+					$sor = $eor;
+					$eor = $cel % 2 ? 'R' : 'L';
+				}
+			} elseif ($ta[$i] == $this->unicode->uni_RLO) {
+				// X4. With each RLO, compute the least greater odd embedding level.
+				//	a. If this new level would be valid, then this embedding code is valid. Remember (push) the current embedding level and override status. Reset the current level to this new level, and reset the override status to right-to-left.
+				//	b. If the new level would not be valid, then this code is invalid. Do not change the current level or override status.
+				$next_level = $cel + ($cel % 2) + 1;
+				if ($next_level < 62) {
+					$remember[] = array('num' => $this->unicode->uni_RLO, 'cel' => $cel, 'dos' => $dos);
+					$cel = $next_level;
+					$dos = 'R';
+					$sor = $eor;
+					$eor = $cel % 2 ? 'R' : 'L';
+				}
+			} elseif ($ta[$i] == $this->unicode->uni_LRO) {
+				// X5. With each LRO, compute the least greater even embedding level.
+				//	a. If this new level would be valid, then this embedding code is valid. Remember (push) the current embedding level and override status. Reset the current level to this new level, and reset the override status to left-to-right.
+				//	b. If the new level would not be valid, then this code is invalid. Do not change the current level or override status.
+				$next_level = $cel + 2 - ($cel % 2);
+				if ( $next_level < 62 ) {
+					$remember[] = array('num' => $this->unicode->uni_LRO, 'cel' => $cel, 'dos' => $dos);
+					$cel = $next_level;
+					$dos = 'L';
+					$sor = $eor;
+					$eor = $cel % 2 ? 'R' : 'L';
+				}
+			} elseif ($ta[$i] == $this->unicode->uni_PDF) {
+				// X7. With each PDF, determine the matching embedding or override code. If there was a valid matching code, restore (pop) the last remembered (pushed) embedding level and directional override.
+				if (count($remember)) {
+					$last = count($remember ) - 1;
+					if (($remember[$last]['num'] == $this->unicode->uni_RLE) OR
+						($remember[$last]['num'] == $this->unicode->uni_LRE) OR
+						($remember[$last]['num'] == $this->unicode->uni_RLO) OR
+						($remember[$last]['num'] == $this->unicode->uni_LRO)) {
+						$match = array_pop($remember);
+						$cel = $match['cel'];
+						$dos = $match['dos'];
+						$sor = $eor;
+						$eor = ($cel > $match['cel'] ? $cel : $match['cel']) % 2 ? 'R' : 'L';
+					}
+				}
+			} elseif (($ta[$i] != $this->unicode->uni_RLE) AND
+							 ($ta[$i] != $this->unicode->uni_LRE) AND
+							 ($ta[$i] != $this->unicode->uni_RLO) AND
+							 ($ta[$i] != $this->unicode->uni_LRO) AND
+							 ($ta[$i] != $this->unicode->uni_PDF)) {
+				// X6. For all types besides RLE, LRE, RLO, LRO, and PDF:
+				//	a. Set the level of the current character to the current embedding level.
+				//	b. Whenever the directional override status is not neutral, reset the current character type to the directional override status.
+				if ($dos != 'N') {
+					$chardir = $dos;
+				} else {
+					if (isset($this->unicode->uni_type[$ta[$i]])) {
+						$chardir = $this->unicode->uni_type[$ta[$i]];
+					} else {
+						$chardir = 'L';
+					}
+				}
+				// stores string characters and other information
+				$chardata[] = array('char' => $ta[$i], 'level' => $cel, 'type' => $chardir, 'sor' => $sor, 'eor' => $eor);
+			}
+		} // end for each char
+
+		// X8. All explicit directional embeddings and overrides are completely terminated at the end of each paragraph. Paragraph separators are not included in the embedding.
+		// X9. Remove all RLE, LRE, RLO, LRO, PDF, and BN codes.
+		// X10. The remaining rules are applied to each run of characters at the same level. For each run, determine the start-of-level-run (sor) and end-of-level-run (eor) type, either L or R. This depends on the higher of the two levels on either side of the boundary (at the start or end of the paragraph, the level of the 'other' run is the base embedding level). If the higher level is odd, the type is R; otherwise, it is L.
+
+		// 3.3.3 Resolving Weak Types
+		// Weak types are now resolved one level run at a time. At level run boundaries where the type of the character on the other side of the boundary is required, the type assigned to sor or eor is used.
+		// Nonspacing marks are now resolved based on the previous characters.
+		$numchars = count($chardata);
+
+		// W1. Examine each nonspacing mark (NSM) in the level run, and change the type of the NSM to the type of the previous character. If the NSM is at the start of the level run, it will get the type of sor.
+		$prevlevel = -1; // track level changes
+		$levcount = 0; // counts consecutive chars at the same level
+		for ($i=0; $i < $numchars; ++$i) {
+			if ($chardata[$i]['type'] == 'NSM') {
+				if ($levcount) {
+					$chardata[$i]['type'] = $chardata[$i]['sor'];
+				} elseif ($i > 0) {
+					$chardata[$i]['type'] = $chardata[($i-1)]['type'];
+				}
+			}
+			if ($chardata[$i]['level'] != $prevlevel) {
+				$levcount = 0;
+			} else {
+				++$levcount;
+			}
+			$prevlevel = $chardata[$i]['level'];
+		}
+
+		// W2. Search backward from each instance of a European number until the first strong type (R, L, AL, or sor) is found. If an AL is found, change the type of the European number to Arabic number.
+		$prevlevel = -1;
+		$levcount = 0;
+		for ($i=0; $i < $numchars; ++$i) {
+			if ($chardata[$i]['char'] == 'EN') {
+				for ($j=$levcount; $j >= 0; $j--) {
+					if ($chardata[$j]['type'] == 'AL') {
+						$chardata[$i]['type'] = 'AN';
+					} elseif (($chardata[$j]['type'] == 'L') OR ($chardata[$j]['type'] == 'R')) {
+						break;
+					}
+				}
+			}
+			if ($chardata[$i]['level'] != $prevlevel) {
+				$levcount = 0;
+			} else {
+				++$levcount;
+			}
+			$prevlevel = $chardata[$i]['level'];
+		}
+
+		// W3. Change all ALs to R.
+		for ($i=0; $i < $numchars; ++$i) {
+			if ($chardata[$i]['type'] == 'AL') {
+				$chardata[$i]['type'] = 'R';
+			}
+		}
+
+		// W4. A single European separator between two European numbers changes to a European number. A single common separator between two numbers of the same type changes to that type.
+		$prevlevel = -1;
+		$levcount = 0;
+		for ($i=0; $i < $numchars; ++$i) {
+			if (($levcount > 0) AND (($i+1) < $numchars) AND ($chardata[($i+1)]['level'] == $prevlevel)) {
+				if (($chardata[$i]['type'] == 'ES') AND ($chardata[($i-1)]['type'] == 'EN') AND ($chardata[($i+1)]['type'] == 'EN')) {
+					$chardata[$i]['type'] = 'EN';
+				} elseif (($chardata[$i]['type'] == 'CS') AND ($chardata[($i-1)]['type'] == 'EN') AND ($chardata[($i+1)]['type'] == 'EN')) {
+					$chardata[$i]['type'] = 'EN';
+				} elseif (($chardata[$i]['type'] == 'CS') AND ($chardata[($i-1)]['type'] == 'AN') AND ($chardata[($i+1)]['type'] == 'AN')) {
+					$chardata[$i]['type'] = 'AN';
+				}
+			}
+			if ($chardata[$i]['level'] != $prevlevel) {
+				$levcount = 0;
+			} else {
+				++$levcount;
+			}
+			$prevlevel = $chardata[$i]['level'];
+		}
+
+		// W5. A sequence of European terminators adjacent to European numbers changes to all European numbers.
+		$prevlevel = -1;
+		$levcount = 0;
+		for ($i=0; $i < $numchars; ++$i) {
+			if ($chardata[$i]['type'] == 'ET') {
+				if (($levcount > 0) AND ($chardata[($i-1)]['type'] == 'EN')) {
+					$chardata[$i]['type'] = 'EN';
+				} else {
+					$j = $i+1;
+					while (($j < $numchars) AND ($chardata[$j]['level'] == $prevlevel)) {
+						if ($chardata[$j]['type'] == 'EN') {
+							$chardata[$i]['type'] = 'EN';
+							break;
+						} elseif ($chardata[$j]['type'] != 'ET') {
+							break;
+						}
+						++$j;
+					}
+				}
+			}
+			if ($chardata[$i]['level'] != $prevlevel) {
+				$levcount = 0;
+			} else {
+				++$levcount;
+			}
+			$prevlevel = $chardata[$i]['level'];
+		}
+
+		// W6. Otherwise, separators and terminators change to Other Neutral.
+		$prevlevel = -1;
+		$levcount = 0;
+		for ($i=0; $i < $numchars; ++$i) {
+			if (($chardata[$i]['type'] == 'ET') OR ($chardata[$i]['type'] == 'ES') OR ($chardata[$i]['type'] == 'CS')) {
+				$chardata[$i]['type'] = 'ON';
+			}
+			if ($chardata[$i]['level'] != $prevlevel) {
+				$levcount = 0;
+			} else {
+				++$levcount;
+			}
+			$prevlevel = $chardata[$i]['level'];
+		}
+
+		//W7. Search backward from each instance of a European number until the first strong type (R, L, or sor) is found. If an L is found, then change the type of the European number to L.
+		$prevlevel = -1;
+		$levcount = 0;
+		for ($i=0; $i < $numchars; ++$i) {
+			if ($chardata[$i]['char'] == 'EN') {
+				for ($j=$levcount; $j >= 0; $j--) {
+					if ($chardata[$j]['type'] == 'L') {
+						$chardata[$i]['type'] = 'L';
+					} elseif ($chardata[$j]['type'] == 'R') {
+						break;
+					}
+				}
+			}
+			if ($chardata[$i]['level'] != $prevlevel) {
+				$levcount = 0;
+			} else {
+				++$levcount;
+			}
+			$prevlevel = $chardata[$i]['level'];
+		}
+
+		// N1. A sequence of neutrals takes the direction of the surrounding strong text if the text on both sides has the same direction. European and Arabic numbers act as if they were R in terms of their influence on neutrals. Start-of-level-run (sor) and end-of-level-run (eor) are used at level run boundaries.
+		$prevlevel = -1;
+		$levcount = 0;
+		for ($i=0; $i < $numchars; ++$i) {
+			if (($levcount > 0) AND (($i+1) < $numchars) AND ($chardata[($i+1)]['level'] == $prevlevel)) {
+				if (($chardata[$i]['type'] == 'N') AND ($chardata[($i-1)]['type'] == 'L') AND ($chardata[($i+1)]['type'] == 'L')) {
+					$chardata[$i]['type'] = 'L';
+				} elseif (($chardata[$i]['type'] == 'N') AND
+				 (($chardata[($i-1)]['type'] == 'R') OR ($chardata[($i-1)]['type'] == 'EN') OR ($chardata[($i-1)]['type'] == 'AN')) AND
+				 (($chardata[($i+1)]['type'] == 'R') OR ($chardata[($i+1)]['type'] == 'EN') OR ($chardata[($i+1)]['type'] == 'AN'))) {
+					$chardata[$i]['type'] = 'R';
+				} elseif ($chardata[$i]['type'] == 'N') {
+					// N2. Any remaining neutrals take the embedding direction
+					$chardata[$i]['type'] = $chardata[$i]['sor'];
+				}
+			} elseif (($levcount == 0) AND (($i+1) < $numchars) AND ($chardata[($i+1)]['level'] == $prevlevel)) {
+				// first char
+				if (($chardata[$i]['type'] == 'N') AND ($chardata[$i]['sor'] == 'L') AND ($chardata[($i+1)]['type'] == 'L')) {
+					$chardata[$i]['type'] = 'L';
+				} elseif (($chardata[$i]['type'] == 'N') AND
+				 (($chardata[$i]['sor'] == 'R') OR ($chardata[$i]['sor'] == 'EN') OR ($chardata[$i]['sor'] == 'AN')) AND
+				 (($chardata[($i+1)]['type'] == 'R') OR ($chardata[($i+1)]['type'] == 'EN') OR ($chardata[($i+1)]['type'] == 'AN'))) {
+					$chardata[$i]['type'] = 'R';
+				} elseif ($chardata[$i]['type'] == 'N') {
+					// N2. Any remaining neutrals take the embedding direction
+					$chardata[$i]['type'] = $chardata[$i]['sor'];
+				}
+			} elseif (($levcount > 0) AND ((($i+1) == $numchars) OR (($i+1) < $numchars) AND ($chardata[($i+1)]['level'] != $prevlevel))) {
+				//last char
+				if (($chardata[$i]['type'] == 'N') AND ($chardata[($i-1)]['type'] == 'L') AND ($chardata[$i]['eor'] == 'L')) {
+					$chardata[$i]['type'] = 'L';
+				} elseif (($chardata[$i]['type'] == 'N') AND
+				 (($chardata[($i-1)]['type'] == 'R') OR ($chardata[($i-1)]['type'] == 'EN') OR ($chardata[($i-1)]['type'] == 'AN')) AND
+				 (($chardata[$i]['eor'] == 'R') OR ($chardata[$i]['eor'] == 'EN') OR ($chardata[$i]['eor'] == 'AN'))) {
+					$chardata[$i]['type'] = 'R';
+				} elseif ($chardata[$i]['type'] == 'N') {
+					// N2. Any remaining neutrals take the embedding direction
+					$chardata[$i]['type'] = $chardata[$i]['sor'];
+				}
+			} elseif ($chardata[$i]['type'] == 'N') {
+				// N2. Any remaining neutrals take the embedding direction
+				$chardata[$i]['type'] = $chardata[$i]['sor'];
+			}
+			if ($chardata[$i]['level'] != $prevlevel) {
+				$levcount = 0;
+			} else {
+				++$levcount;
+			}
+			$prevlevel = $chardata[$i]['level'];
+		}
+
+		// I1. For all characters with an even (left-to-right) embedding direction, those of type R go up one level and those of type AN or EN go up two levels.
+		// I2. For all characters with an odd (right-to-left) embedding direction, those of type L, EN or AN go up one level.
+		for ($i=0; $i < $numchars; ++$i) {
+			$odd = $chardata[$i]['level'] % 2;
+			if ($odd) {
+				if (($chardata[$i]['type'] == 'L') OR ($chardata[$i]['type'] == 'AN') OR ($chardata[$i]['type'] == 'EN')) {
+					$chardata[$i]['level'] += 1;
+				}
+			} else {
+				if ($chardata[$i]['type'] == 'R') {
+					$chardata[$i]['level'] += 1;
+				} elseif (($chardata[$i]['type'] == 'AN') OR ($chardata[$i]['type'] == 'EN')) {
+					$chardata[$i]['level'] += 2;
+				}
+			}
+			$maxlevel = max($chardata[$i]['level'],$maxlevel);
+		}
+
+		// L1. On each line, reset the embedding level of the following characters to the paragraph embedding level:
+		//	1. Segment separators,
+		//	2. Paragraph separators,
+		//	3. Any sequence of whitespace characters preceding a segment separator or paragraph separator, and
+		//	4. Any sequence of white space characters at the end of the line.
+		for ($i=0; $i < $numchars; ++$i) {
+			if (($chardata[$i]['type'] == 'B') OR ($chardata[$i]['type'] == 'S')) {
+				$chardata[$i]['level'] = $pel;
+			} elseif ($chardata[$i]['type'] == 'WS') {
+				$j = $i+1;
+				while ($j < $numchars) {
+					if ((($chardata[$j]['type'] == 'B') OR ($chardata[$j]['type'] == 'S')) OR
+						(($j == ($numchars-1)) AND ($chardata[$j]['type'] == 'WS'))) {
+						$chardata[$i]['level'] = $pel;
+						break;
+					} elseif ($chardata[$j]['type'] != 'WS') {
+						break;
+					}
+					++$j;
+				}
+			}
+		}
+
+		// Arabic Shaping
+		// Cursively connected scripts, such as Arabic or Syriac, require the selection of positional character shapes that depend on adjacent characters. Shaping is logically applied after the Bidirectional Algorithm is used and is limited to characters within the same directional run.
+		if ($arabic) {
+			$endedletter = array(1569,1570,1571,1572,1573,1575,1577,1583,1584,1585,1586,1608,1688);
+			$alfletter = array(1570,1571,1573,1575);
+			$chardata2 = $chardata;
+			$laaletter = false;
+			$charAL = array();
+			$x = 0;
+			for ($i=0; $i < $numchars; ++$i) {
+				if (($this->unicode->uni_type[$chardata[$i]['char']] == 'AL') OR ($chardata[$i]['char'] == 32) OR ($chardata[$i]['char'] == 8204)) {
+					$charAL[$x] = $chardata[$i];
+					$charAL[$x]['i'] = $i;
+					$chardata[$i]['x'] = $x;
+					++$x;
+				}
+			}
+			$numAL = $x;
+			for ($i=0; $i < $numchars; ++$i) {
+				$thischar = $chardata[$i];
+				if ($i > 0) {
+					$prevchar = $chardata[($i-1)];
+				} else {
+					$prevchar = false;
+				}
+				if (($i+1) < $numchars) {
+					$nextchar = $chardata[($i+1)];
+				} else {
+					$nextchar = false;
+				}
+				if ($this->unicode->uni_type[$thischar['char']] == 'AL') {
+					$x = $thischar['x'];
+					if ($x > 0) {
+						$prevchar = $charAL[($x-1)];
+					} else {
+						$prevchar = false;
+					}
+					if (($x+1) < $numAL) {
+						$nextchar = $charAL[($x+1)];
+					} else {
+						$nextchar = false;
+					}
+					// if laa letter
+					if (($prevchar !== false) AND ($prevchar['char'] == 1604) AND (in_array($thischar['char'], $alfletter))) {
+						$arabicarr = $this->unicode->uni_laa_array;
+						$laaletter = true;
+						if ($x > 1) {
+							$prevchar = $charAL[($x-2)];
+						} else {
+							$prevchar = false;
+						}
+					} else {
+						$arabicarr = $this->unicode->uni_arabicsubst;
+						$laaletter = false;
+					}
+					if (($prevchar !== false) AND ($nextchar !== false) AND
+						(($this->unicode->uni_type[$prevchar['char']] == 'AL') OR ($this->unicode->uni_type[$prevchar['char']] == 'NSM')) AND
+						(($this->unicode->uni_type[$nextchar['char']] == 'AL') OR ($this->unicode->uni_type[$nextchar['char']] == 'NSM')) AND
+						($prevchar['type'] == $thischar['type']) AND
+						($nextchar['type'] == $thischar['type']) AND
+						($nextchar['char'] != 1567)) {
+						if (in_array($prevchar['char'], $endedletter)) {
+							if (isset($arabicarr[$thischar['char']][2])) {
+								// initial
+								$chardata2[$i]['char'] = $arabicarr[$thischar['char']][2];
+							}
+						} else {
+							if (isset($arabicarr[$thischar['char']][3])) {
+								// medial
+								$chardata2[$i]['char'] = $arabicarr[$thischar['char']][3];
+							}
+						}
+					} elseif (($nextchar !== false) AND
+						(($this->unicode->uni_type[$nextchar['char']] == 'AL') OR ($this->unicode->uni_type[$nextchar['char']] == 'NSM')) AND
+						($nextchar['type'] == $thischar['type']) AND
+						($nextchar['char'] != 1567)) {
+						if (isset($arabicarr[$chardata[$i]['char']][2])) {
+							// initial
+							$chardata2[$i]['char'] = $arabicarr[$thischar['char']][2];
+						}
+					} elseif ((($prevchar !== false) AND
+						(($this->unicode->uni_type[$prevchar['char']] == 'AL') OR ($this->unicode->uni_type[$prevchar['char']] == 'NSM')) AND
+						($prevchar['type'] == $thischar['type'])) OR
+						(($nextchar !== false) AND ($nextchar['char'] == 1567))) {
+						// final
+						if (($i > 1) AND ($thischar['char'] == 1607) AND
+							($chardata[$i-1]['char'] == 1604) AND
+							($chardata[$i-2]['char'] == 1604)) {
+							//Allah Word
+							// mark characters to delete with false
+							$chardata2[$i-2]['char'] = false;
+							$chardata2[$i-1]['char'] = false;
+							$chardata2[$i]['char'] = 65010;
+						} else {
+							if (($prevchar !== false) AND in_array($prevchar['char'], $endedletter)) {
+								if (isset($arabicarr[$thischar['char']][0])) {
+									// isolated
+									$chardata2[$i]['char'] = $arabicarr[$thischar['char']][0];
+								}
+							} else {
+								if (isset($arabicarr[$thischar['char']][1])) {
+									// final
+									$chardata2[$i]['char'] = $arabicarr[$thischar['char']][1];
+								}
+							}
+						}
+					} elseif (isset($arabicarr[$thischar['char']][0])) {
+						// isolated
+						$chardata2[$i]['char'] = $arabicarr[$thischar['char']][0];
+					}
+					// if laa letter
+					if ($laaletter) {
+						// mark characters to delete with false
+						$chardata2[($charAL[($x-1)]['i'])]['char'] = false;
+					}
+				} // end if AL (Arabic Letter)
+			} // end for each char
+			/*
+			 * Combining characters that can occur with Arabic Shadda (0651 HEX, 1617 DEC) are replaced.
+			 * Putting the combining mark and shadda in the same glyph allows us to avoid the two marks overlapping each other in an illegible manner.
+			 */
+			for ($i = 0; $i < ($numchars-1); ++$i) {
+				if (($chardata2[$i]['char'] == 1617) AND (isset($this->unicode->uni_diacritics[($chardata2[$i+1]['char'])]))) {
+					// check if the subtitution font is defined on current font
+					if (isset($this->CurrentFont['cw'][($this->unicode->uni_diacritics[($chardata2[$i+1]['char'])])])) {
+						$chardata2[$i]['char'] = false;
+						$chardata2[$i+1]['char'] = $this->unicode->uni_diacritics[($chardata2[$i+1]['char'])];
+					}
+				}
+			}
+			// remove marked characters
+			foreach ($chardata2 as $key => $value) {
+				if ($value['char'] === false) {
+					unset($chardata2[$key]);
+				}
+			}
+			$chardata = array_values($chardata2);
+			$numchars = count($chardata);
+			unset($chardata2);
+			unset($arabicarr);
+			unset($laaletter);
+			unset($charAL);
+		}
+
+		// L2. From the highest level found in the text to the lowest odd level on each line, including intermediate levels not actually present in the text, reverse any contiguous sequence of characters that are at that level or higher.
+		for ($j=$maxlevel; $j > 0; $j--) {
+			$ordarray = Array();
+			$revarr = Array();
+			$onlevel = false;
+			for ($i=0; $i < $numchars; ++$i) {
+				if ($chardata[$i]['level'] >= $j) {
+					$onlevel = true;
+					if (isset($this->unicode->uni_mirror[$chardata[$i]['char']])) {
+						// L4. A character is depicted by a mirrored glyph if and only if (a) the resolved directionality of that character is R, and (b) the Bidi_Mirrored property value of that character is true.
+						$chardata[$i]['char'] = $this->unicode->uni_mirror[$chardata[$i]['char']];
+					}
+					$revarr[] = $chardata[$i];
+				} else {
+					if ($onlevel) {
+						$revarr = array_reverse($revarr);
+						$ordarray = array_merge($ordarray, $revarr);
+						$revarr = Array();
+						$onlevel = false;
+					}
+					$ordarray[] = $chardata[$i];
+				}
+			}
+			if ($onlevel) {
+				$revarr = array_reverse($revarr);
+				$ordarray = array_merge($ordarray, $revarr);
+			}
+			$chardata = $ordarray;
+		}
+
+		$ordarray = array();
+		for ($i=0; $i < $numchars; ++$i) {
+			$ordarray[] = $chardata[$i]['char'];
+			// store char values for subsetting
+			$this->CurrentFont['subsetchars'][$chardata[$i]['char']] = true;
+		}
+		// update font subsetchars
+		$this->setFontSubBuffer($this->CurrentFont['fontkey'], 'subsetchars', $this->CurrentFont['subsetchars']);
+		return $ordarray;
+	}
+
+	// END OF BIDIRECTIONAL TEXT SECTION -------------------
+
+	/**
+	 * Encode a name object.
+	 * @param $name (string) Name object to encode.
+	 * @return (string) Encoded name object.
+	 * @protected
+	 * @author Nicola Asuni
+	 * @since 5.9.097 (2011-06-23)
+	 */
+	protected function encodeNameObject($name) {
+		$escname = '';
+		$length = strlen($name);
+		for ($i = 0; $i < $length; ++$i) {
+			$chr = $name[$i];
+			if (preg_match('/[0-9a-zA-Z]/', $chr) == 1) {
+				$escname .= $chr;
+			} else {
+				$escname .= sprintf('#%02X', ord($chr));
+			}
+		}
+		return $escname;
+	}
+
+	/**
+	 * Add a Named Destination.
+	 * NOTE: destination names are unique, so only last entry will be saved.
+	 * @param $name (string) Destination name.
+	 * @param $y (float) Y position in user units of the destiantion on the selected page (default = -1 = current position; 0 = page start;).
+	 * @param $page (int) Target page number (leave empty for current page).
+	 * @param $x (float) X position in user units of the destiantion on the selected page (default = -1 = current position;).
+	 * @return (string) Stripped named destination identifier or false in case of error.
+	 * @public
+	 * @author Christian Deligant, Nicola Asuni
+	 * @since 5.9.097 (2011-06-23)
+	 */
+	public function setDestination($name, $y=-1, $page='', $x=-1) {
+		// remove unsupported characters
+		$name = $this->encodeNameObject($name);
+		if ($this->empty_string($name)) {
+			return false;
+		}
+		if ($y == -1) {
+			$y = $this->GetY();
+		} elseif ($y < 0) {
+			$y = 0;
+		} elseif ($y > $this->h) {
+			$y = $this->h;
+		}
+		if ($x == -1) {
+			$x = $this->GetX();
+		} elseif ($x < 0) {
+			$x = 0;
+		} elseif ($x > $this->w) {
+			$x = $this->w;
+		}
+		if (empty($page)) {
+			$page = $this->PageNo();
+			if (empty($page)) {
+				return;
+			}
+		}
+		$this->dests[$name] = array('x' => $x, 'y' => $y, 'p' => $page);
+		return $name;
+	}
+
+	/**
+	 * Return the Named Destination array.
+	 * @return (array) Named Destination array.
+	 * @public
+	 * @author Nicola Asuni
+	 * @since 5.9.097 (2011-06-23)
+	 */
+	public function getDestination() {
+		return $this->dests;
+	}
+
+	/**
+	 * Insert Named Destinations.
+	 * @protected
+	 * @author Johannes G�ntert, Nicola Asuni
+	 * @since 5.9.098 (2011-06-23)
+	 */
+	protected function _putdests() {
+		if (empty($this->dests)) {
+			return;
+		}
+		$this->n_dests = $this->_newobj();
+		$out = ' <<';
+		foreach($this->dests as $name => $o) {
+			$out .= ' /'.$name.' '.sprintf('[%u 0 R /XYZ %F %F null]', $this->page_obj_id[($o['p'])], ($o['x'] * $this->k), ($this->pagedim[$o['p']]['h'] - ($o['y'] * $this->k)));
+		}
+		$out .= ' >>';
+		$out .= "\n".'endobj';
+		$this->_out($out);
+	}
+
+	/**
+	 * Adds a bookmark - alias for Bookmark().
+	 * @param $txt (string) Bookmark description.
+	 * @param $level (int) Bookmark level (minimum value is 0).
+	 * @param $y (float) Y position in user units of the bookmark on the selected page (default = -1 = current position; 0 = page start;).
+	 * @param $page (int) Target page number (leave empty for current page).
+	 * @param $style (string) Font style: B = Bold, I = Italic, BI = Bold + Italic.
+	 * @param $color (array) RGB color array (values from 0 to 255).
+	 * @param $x (float) X position in user units of the bookmark on the selected page (default = -1 = current position;).
+	 * @param $link (mixed) URL, or numerical link ID, or named destination (# character followed by the destination name), or embedded file (* character followed by the file name).
+	 * @public
+	 */
+	public function setBookmark($txt, $level=0, $y=-1, $page='', $style='', $color=array(0,0,0), $x=-1, $link='') {
+		$this->Bookmark($txt, $level, $y, $page, $style, $color, $x, $link);
+	}
+
+	/**
+	 * Adds a bookmark.
+	 * @param $txt (string) Bookmark description.
+	 * @param $level (int) Bookmark level (minimum value is 0).
+	 * @param $y (float) Y position in user units of the bookmark on the selected page (default = -1 = current position; 0 = page start;).
+	 * @param $page (int) Target page number (leave empty for current page).
+	 * @param $style (string) Font style: B = Bold, I = Italic, BI = Bold + Italic.
+	 * @param $color (array) RGB color array (values from 0 to 255).
+	 * @param $x (float) X position in user units of the bookmark on the selected page (default = -1 = current position;).
+	 * @param $link (mixed) URL, or numerical link ID, or named destination (# character followed by the destination name), or embedded file (* character followed by the file name).
+	 * @public
+	 * @since 2.1.002 (2008-02-12)
+	 */
+	public function Bookmark($txt, $level=0, $y=-1, $page='', $style='', $color=array(0,0,0), $x=-1, $link='') {
+		if ($level < 0) {
+			$level = 0;
+		}
+		if (isset($this->outlines[0])) {
+			$lastoutline = end($this->outlines);
+			$maxlevel = $lastoutline['l'] + 1;
+		} else {
+			$maxlevel = 0;
+		}
+		if ($level > $maxlevel) {
+			$level = $maxlevel;
+		}
+		if ($y == -1) {
+			$y = $this->GetY();
+		} elseif ($y < 0) {
+			$y = 0;
+		} elseif ($y > $this->h) {
+			$y = $this->h;
+		}
+		if ($x == -1) {
+			$x = $this->GetX();
+		} elseif ($x < 0) {
+			$x = 0;
+		} elseif ($x > $this->w) {
+			$x = $this->w;
+		}
+		if (empty($page)) {
+			$page = $this->PageNo();
+			if (empty($page)) {
+				return;
+			}
+		}
+		$this->outlines[] = array('t' => $txt, 'l' => $level, 'x' => $x, 'y' => $y, 'p' => $page, 's' => strtoupper($style), 'c' => $color, 'u' => $link);
+	}
+
+	/**
+	 * Sort bookmarks for page and key.
+	 * @protected
+	 * @since 5.9.119 (2011-09-19)
+	 */
+	protected function sortBookmarks() {
+		// get sorting columns
+		$outline_p = array();
+		$outline_y = array();
+		foreach ($this->outlines as $key => $row) {
+			$outline_p[$key] = $row['p'];
+			$outline_k[$key] = $key;
+		}
+		// sort outlines by page and original position
+		array_multisort($outline_p, SORT_NUMERIC, SORT_ASC, $outline_k, SORT_NUMERIC, SORT_ASC, $this->outlines);
+	}
+
+	/**
+	 * Create a bookmark PDF string.
+	 * @protected
+	 * @author Olivier Plathey, Nicola Asuni
+	 * @since 2.1.002 (2008-02-12)
+	 */
+	protected function _putbookmarks() {
+		$nb = count($this->outlines);
+		if ($nb == 0) {
+			return;
+		}
+		// sort bookmarks
+		$this->sortBookmarks();
+		$lru = array();
+		$level = 0;
+		foreach ($this->outlines as $i => $o) {
+			if ($o['l'] > 0) {
+				$parent = $lru[($o['l'] - 1)];
+				//Set parent and last pointers
+				$this->outlines[$i]['parent'] = $parent;
+				$this->outlines[$parent]['last'] = $i;
+				if ($o['l'] > $level) {
+					//Level increasing: set first pointer
+					$this->outlines[$parent]['first'] = $i;
+				}
+			} else {
+				$this->outlines[$i]['parent'] = $nb;
+			}
+			if (($o['l'] <= $level) AND ($i > 0)) {
+				//Set prev and next pointers
+				$prev = $lru[$o['l']];
+				$this->outlines[$prev]['next'] = $i;
+				$this->outlines[$i]['prev'] = $prev;
+			}
+			$lru[$o['l']] = $i;
+			$level = $o['l'];
+		}
+		//Outline items
+		$n = $this->n + 1;
+		$nltags = '/<br[\s]?\/>|<\/(blockquote|dd|dl|div|dt|h1|h2|h3|h4|h5|h6|hr|li|ol|p|pre|ul|tcpdf|table|tr|td)>/si';
+		foreach ($this->outlines as $i => $o) {
+			$oid = $this->_newobj();
+			// covert HTML title to string
+			$title = preg_replace($nltags, "\n", $o['t']);
+			$title = preg_replace("/[\r]+/si", '', $title);
+			$title = preg_replace("/[\n]+/si", "\n", $title);
+			$title = strip_tags($title);
+			$title = $this->stringTrim($title);
+			$out = '<</Title '.$this->_textstring($title, $oid);
+			$out .= ' /Parent '.($n + $o['parent']).' 0 R';
+			if (isset($o['prev'])) {
+				$out .= ' /Prev '.($n + $o['prev']).' 0 R';
+			}
+			if (isset($o['next'])) {
+				$out .= ' /Next '.($n + $o['next']).' 0 R';
+			}
+			if (isset($o['first'])) {
+				$out .= ' /First '.($n + $o['first']).' 0 R';
+			}
+			if (isset($o['last'])) {
+				$out .= ' /Last '.($n + $o['last']).' 0 R';
+			}
+			if (isset($o['u']) AND !empty($o['u'])) {
+				// link
+				if (is_string($o['u'])) {
+					if ($o['u'][0] == '#') {
+						// internal destination
+						$out .= ' /Dest /'.$this->encodeNameObject(substr($o['u'], 1));
+					} elseif ($o['u'][0] == '%') {
+						// embedded PDF file
+						$filename = basename(substr($o['u'], 1));
+						$out .= ' /A <</S /GoToE /D [0 /Fit] /NewWindow true /T << /R /C /P '.($o['p'] - 1).' /A '.$this->embeddedfiles[$filename]['a'].' >> >>';
+					} elseif ($o['u'][0] == '*') {
+						// embedded generic file
+						$filename = basename(substr($o['u'], 1));
+						$jsa = 'var D=event.target.doc;var MyData=D.dataObjects;for (var i in MyData) if (MyData[i].path=="'.$filename.'") D.exportDataObject( { cName : MyData[i].name, nLaunch : 2});';
+						$out .= ' /A <</S /JavaScript /JS '.$this->_textstring($jsa, $oid).'>>';
+					} else {
+						// external URI link
+						$out .= ' /A <</S /URI /URI '.$this->_datastring($this->unhtmlentities($o['u']), $oid).'>>';
+					}
+				} elseif (isset($this->links[$o['u']])) {
+					// internal link ID
+					$l = $this->links[$o['u']];
+					if (isset($this->page_obj_id[($l[0])])) {
+						$out .= sprintf(' /Dest [%u 0 R /XYZ 0 %F null]', $this->page_obj_id[($l[0])], ($this->pagedim[$l[0]]['h'] - ($l[1] * $this->k)));
+					}
+				}
+			} elseif (isset($this->page_obj_id[($o['p'])])) {
+				// link to a page
+				$out .= ' '.sprintf('/Dest [%u 0 R /XYZ %F %F null]', $this->page_obj_id[($o['p'])], ($o['x'] * $this->k), ($this->pagedim[$o['p']]['h'] - ($o['y'] * $this->k)));
+			}
+			// set font style
+			$style = 0;
+			if (!empty($o['s'])) {
+				// bold
+				if (strpos($o['s'], 'B') !== false) {
+					$style |= 2;
+				}
+				// oblique
+				if (strpos($o['s'], 'I') !== false) {
+					$style |= 1;
+				}
+			}
+			$out .= sprintf(' /F %d', $style);
+			// set bookmark color
+			if (isset($o['c']) AND is_array($o['c']) AND (count($o['c']) == 3)) {
+				$color = array_values($o['c']);
+				$out .= sprintf(' /C [%F %F %F]', ($color[0] / 255), ($color[1] / 255), ($color[2] / 255));
+			} else {
+				// black
+				$out .= ' /C [0.0 0.0 0.0]';
+			}
+			$out .= ' /Count 0'; // normally closed item
+			$out .= ' >>';
+			$out .= "\n".'endobj';
+			$this->_out($out);
+		}
+		//Outline root
+		$this->OutlineRoot = $this->_newobj();
+		$this->_out('<< /Type /Outlines /First '.$n.' 0 R /Last '.($n + $lru[0]).' 0 R >>'."\n".'endobj');
+	}
+
+	// --- JAVASCRIPT ------------------------------------------------------
+
+	/**
+	 * Adds a javascript
+	 * @param $script (string) Javascript code
+	 * @public
+	 * @author Johannes G�ntert, Nicola Asuni
+	 * @since 2.1.002 (2008-02-12)
+	 */
+	public function IncludeJS($script) {
+		$this->javascript .= $script;
+	}
+
+	/**
+	 * Adds a javascript object and return object ID
+	 * @param $script (string) Javascript code
+	 * @param $onload (boolean) if true executes this object when opening the document
+	 * @return int internal object ID
+	 * @public
+	 * @author Nicola Asuni
+	 * @since 4.8.000 (2009-09-07)
+	 */
+	public function addJavascriptObject($script, $onload=false) {
+		if ($this->pdfa_mode) {
+			// javascript is not allowed in PDF/A mode
+			return false;
+		}
+		++$this->n;
+		$this->js_objects[$this->n] = array('n' => $this->n, 'js' => $script, 'onload' => $onload);
+		return $this->n;
+	}
+
+	/**
+	 * Create a javascript PDF string.
+	 * @protected
+	 * @author Johannes G�ntert, Nicola Asuni
+	 * @since 2.1.002 (2008-02-12)
+	 */
+	protected function _putjavascript() {
+		if ($this->pdfa_mode OR (empty($this->javascript) AND empty($this->js_objects))) {
+			return;
+		}
+		if (strpos($this->javascript, 'this.addField') > 0) {
+			if (!$this->ur['enabled']) {
+				//$this->setUserRights();
+			}
+			// the following two lines are used to avoid form fields duplication after saving
+			// The addField method only works when releasing user rights (UR3)
+			$jsa = sprintf("ftcpdfdocsaved=this.addField('%s','%s',%d,[%F,%F,%F,%F]);", 'tcpdfdocsaved', 'text', 0, 0, 1, 0, 1);
+			$jsb = "getField('tcpdfdocsaved').value='saved';";
+			$this->javascript = $jsa."\n".$this->javascript."\n".$jsb;
+		}
+		// name tree for javascript
+		$this->n_js = '<< /Names [';
+		if (!empty($this->javascript)) {
+			$this->n_js .= ' (EmbeddedJS) '.($this->n + 1).' 0 R';
+		}
+		if (!empty($this->js_objects)) {
+			foreach ($this->js_objects as $key => $val) {
+				if ($val['onload']) {
+					$this->n_js .= ' (JS'.$key.') '.$key.' 0 R';
+				}
+			}
+		}
+		$this->n_js .= ' ] >>';
+		// default Javascript object
+		if (!empty($this->javascript)) {
+			$obj_id = $this->_newobj();
+			$out = '<< /S /JavaScript';
+			$out .= ' /JS '.$this->_textstring($this->javascript, $obj_id);
+			$out .= ' >>';
+			$out .= "\n".'endobj';
+			$this->_out($out);
+		}
+		// additional Javascript objects
+		if (!empty($this->js_objects)) {
+			foreach ($this->js_objects as $key => $val) {
+				$out = $this->_getobj($key)."\n".' << /S /JavaScript /JS '.$this->_textstring($val['js'], $key).' >>'."\n".'endobj';
+				$this->_out($out);
+			}
+		}
+	}
+
+	/**
+	 * Convert color to javascript color.
+	 * @param $color (string) color name or "#RRGGBB"
+	 * @protected
+	 * @author Denis Van Nuffelen, Nicola Asuni
+	 * @since 2.1.002 (2008-02-12)
+	 */
+	protected function _JScolor($color) {
+		static $aColors = array('transparent', 'black', 'white', 'red', 'green', 'blue', 'cyan', 'magenta', 'yellow', 'dkGray', 'gray', 'ltGray');
+		if (substr($color,0,1) == '#') {
+			return sprintf("['RGB',%F,%F,%F]", hexdec(substr($color,1,2))/255, hexdec(substr($color,3,2))/255, hexdec(substr($color,5,2))/255);
+		}
+		if (!in_array($color,$aColors)) {
+			$this->Error('Invalid color: '.$color);
+		}
+		return 'color.'.$color;
+	}
+
+	/**
+	 * Adds a javascript form field.
+	 * @param $type (string) field type
+	 * @param $name (string) field name
+	 * @param $x (int) horizontal position
+	 * @param $y (int) vertical position
+	 * @param $w (int) width
+	 * @param $h (int) height
+	 * @param $prop (array) javascript field properties. Possible values are described on official Javascript for Acrobat API reference.
+	 * @protected
+	 * @author Denis Van Nuffelen, Nicola Asuni
+	 * @since 2.1.002 (2008-02-12)
+	 */
+	protected function _addfield($type, $name, $x, $y, $w, $h, $prop) {
+		if ($this->rtl) {
+			$x = $x - $w;
+		}
+		// the followind avoid fields duplication after saving the document
+		$this->javascript .= "if (getField('tcpdfdocsaved').value != 'saved') {";
+		$k = $this->k;
+		$this->javascript .= sprintf("f".$name."=this.addField('%s','%s',%u,[%F,%F,%F,%F]);", $name, $type, $this->PageNo()-1, $x*$k, ($this->h-$y)*$k+1, ($x+$w)*$k, ($this->h-$y-$h)*$k+1)."\n";
+		$this->javascript .= 'f'.$name.'.textSize='.$this->FontSizePt.";\n";
+		while (list($key, $val) = each($prop)) {
+			if (strcmp(substr($key, -5), 'Color') == 0) {
+				$val = $this->_JScolor($val);
+			} else {
+				$val = "'".$val."'";
+			}
+			$this->javascript .= 'f'.$name.'.'.$key.'='.$val.";\n";
+		}
+		if ($this->rtl) {
+			$this->x -= $w;
+		} else {
+			$this->x += $w;
+		}
+		$this->javascript .= '}';
+	}
+
+	// --- FORM FIELDS -----------------------------------------------------
+
+	/**
+	 * Convert JavaScript form fields properties array to Annotation Properties array.
+	 * @param $prop (array) javascript field properties. Possible values are described on official Javascript for Acrobat API reference.
+	 * @return array of annotation properties
+	 * @protected
+	 * @author Nicola Asuni
+	 * @since 4.8.000 (2009-09-06)
+	 */
+	protected function getAnnotOptFromJSProp($prop) {
+		if (isset($prop['aopt']) AND is_array($prop['aopt'])) {
+			// the annotation options area lready defined
+			return $prop['aopt'];
+		}
+		$opt = array(); // value to be returned
+		// alignment: Controls how the text is laid out within the text field.
+		if (isset($prop['alignment'])) {
+			switch ($prop['alignment']) {
+				case 'left': {
+					$opt['q'] = 0;
+					break;
+				}
+				case 'center': {
+					$opt['q'] = 1;
+					break;
+				}
+				case 'right': {
+					$opt['q'] = 2;
+					break;
+				}
+				default: {
+					$opt['q'] = ($this->rtl)?2:0;
+					break;
+				}
+			}
+		}
+		// lineWidth: Specifies the thickness of the border when stroking the perimeter of a field's rectangle.
+		if (isset($prop['lineWidth'])) {
+			$linewidth = intval($prop['lineWidth']);
+		} else {
+			$linewidth = 1;
+		}
+		// borderStyle: The border style for a field.
+		if (isset($prop['borderStyle'])) {
+			switch ($prop['borderStyle']) {
+				case 'border.d':
+				case 'dashed': {
+					$opt['border'] = array(0, 0, $linewidth, array(3, 2));
+					$opt['bs'] = array('w'=>$linewidth, 's'=>'D', 'd'=>array(3, 2));
+					break;
+				}
+				case 'border.b':
+				case 'beveled': {
+					$opt['border'] = array(0, 0, $linewidth);
+					$opt['bs'] = array('w'=>$linewidth, 's'=>'B');
+					break;
+				}
+				case 'border.i':
+				case 'inset': {
+					$opt['border'] = array(0, 0, $linewidth);
+					$opt['bs'] = array('w'=>$linewidth, 's'=>'I');
+					break;
+				}
+				case 'border.u':
+				case 'underline': {
+					$opt['border'] = array(0, 0, $linewidth);
+					$opt['bs'] = array('w'=>$linewidth, 's'=>'U');
+					break;
+				}
+				case 'border.s':
+				case 'solid': {
+					$opt['border'] = array(0, 0, $linewidth);
+					$opt['bs'] = array('w'=>$linewidth, 's'=>'S');
+					break;
+				}
+				default: {
+					break;
+				}
+			}
+		}
+		if (isset($prop['border']) AND is_array($prop['border'])) {
+			$opt['border'] = $prop['border'];
+		}
+		if (!isset($opt['mk'])) {
+			$opt['mk'] = array();
+		}
+		if (!isset($opt['mk']['if'])) {
+			$opt['mk']['if'] = array();
+		}
+		$opt['mk']['if']['a'] = array(0.5, 0.5);
+		// buttonAlignX: Controls how space is distributed from the left of the button face with respect to the icon.
+		if (isset($prop['buttonAlignX'])) {
+			$opt['mk']['if']['a'][0] = $prop['buttonAlignX'];
+		}
+		// buttonAlignY: Controls how unused space is distributed from the bottom of the button face with respect to the icon.
+		if (isset($prop['buttonAlignY'])) {
+			$opt['mk']['if']['a'][1] = $prop['buttonAlignY'];
+		}
+		// buttonFitBounds: If true, the extent to which the icon may be scaled is set to the bounds of the button field.
+		if (isset($prop['buttonFitBounds']) AND ($prop['buttonFitBounds'] == 'true')) {
+			$opt['mk']['if']['fb'] = true;
+		}
+		// buttonScaleHow: Controls how the icon is scaled (if necessary) to fit inside the button face.
+		if (isset($prop['buttonScaleHow'])) {
+			switch ($prop['buttonScaleHow']) {
+				case 'scaleHow.proportional': {
+					$opt['mk']['if']['s'] = 'P';
+					break;
+				}
+				case 'scaleHow.anamorphic': {
+					$opt['mk']['if']['s'] = 'A';
+					break;
+				}
+			}
+		}
+		// buttonScaleWhen: Controls when an icon is scaled to fit inside the button face.
+		if (isset($prop['buttonScaleWhen'])) {
+			switch ($prop['buttonScaleWhen']) {
+				case 'scaleWhen.always': {
+					$opt['mk']['if']['sw'] = 'A';
+					break;
+				}
+				case 'scaleWhen.never': {
+					$opt['mk']['if']['sw'] = 'N';
+					break;
+				}
+				case 'scaleWhen.tooBig': {
+					$opt['mk']['if']['sw'] = 'B';
+					break;
+				}
+				case 'scaleWhen.tooSmall': {
+					$opt['mk']['if']['sw'] = 'S';
+					break;
+				}
+			}
+		}
+		// buttonPosition: Controls how the text and the icon of the button are positioned with respect to each other within the button face.
+		if (isset($prop['buttonPosition'])) {
+			switch ($prop['buttonPosition']) {
+				case 0:
+				case 'position.textOnly': {
+					$opt['mk']['tp'] = 0;
+					break;
+				}
+				case 1:
+				case 'position.iconOnly': {
+					$opt['mk']['tp'] = 1;
+					break;
+				}
+				case 2:
+				case 'position.iconTextV': {
+					$opt['mk']['tp'] = 2;
+					break;
+				}
+				case 3:
+				case 'position.textIconV': {
+					$opt['mk']['tp'] = 3;
+					break;
+				}
+				case 4:
+				case 'position.iconTextH': {
+					$opt['mk']['tp'] = 4;
+					break;
+				}
+				case 5:
+				case 'position.textIconH': {
+					$opt['mk']['tp'] = 5;
+					break;
+				}
+				case 6:
+				case 'position.overlay': {
+					$opt['mk']['tp'] = 6;
+					break;
+				}
+			}
+		}
+		// fillColor: Specifies the background color for a field.
+		if (isset($prop['fillColor'])) {
+			if (is_array($prop['fillColor'])) {
+				$opt['mk']['bg'] = $prop['fillColor'];
+			} else {
+				$opt['mk']['bg'] = $this->convertHTMLColorToDec($prop['fillColor']);
+			}
+		}
+		// strokeColor: Specifies the stroke color for a field that is used to stroke the rectangle of the field with a line as large as the line width.
+		if (isset($prop['strokeColor'])) {
+			if (is_array($prop['strokeColor'])) {
+				$opt['mk']['bc'] = $prop['strokeColor'];
+			} else {
+				$opt['mk']['bc'] = $this->convertHTMLColorToDec($prop['strokeColor']);
+			}
+		}
+		// rotation: The rotation of a widget in counterclockwise increments.
+		if (isset($prop['rotation'])) {
+			$opt['mk']['r'] = $prop['rotation'];
+		}
+		// charLimit: Limits the number of characters that a user can type into a text field.
+		if (isset($prop['charLimit'])) {
+			$opt['maxlen'] = intval($prop['charLimit']);
+		}
+		if (!isset($ff)) {
+			$ff = 0; // default value
+		}
+		// readonly: The read-only characteristic of a field. If a field is read-only, the user can see the field but cannot change it.
+		if (isset($prop['readonly']) AND ($prop['readonly'] == 'true')) {
+			$ff += 1 << 0;
+		}
+		// required: Specifies whether a field requires a value.
+		if (isset($prop['required']) AND ($prop['required'] == 'true')) {
+			$ff += 1 << 1;
+		}
+		// multiline: Controls how text is wrapped within the field.
+		if (isset($prop['multiline']) AND ($prop['multiline'] == 'true')) {
+			$ff += 1 << 12;
+		}
+		// password: Specifies whether the field should display asterisks when data is entered in the field.
+		if (isset($prop['password']) AND ($prop['password'] == 'true')) {
+			$ff += 1 << 13;
+		}
+		// NoToggleToOff: If set, exactly one radio button shall be selected at all times; selecting the currently selected button has no effect.
+		if (isset($prop['NoToggleToOff']) AND ($prop['NoToggleToOff'] == 'true')) {
+			$ff += 1 << 14;
+		}
+		// Radio: If set, the field is a set of radio buttons.
+		if (isset($prop['Radio']) AND ($prop['Radio'] == 'true')) {
+			$ff += 1 << 15;
+		}
+		// Pushbutton: If set, the field is a pushbutton that does not retain a permanent value.
+		if (isset($prop['Pushbutton']) AND ($prop['Pushbutton'] == 'true')) {
+			$ff += 1 << 16;
+		}
+		// Combo: If set, the field is a combo box; if clear, the field is a list box.
+		if (isset($prop['Combo']) AND ($prop['Combo'] == 'true')) {
+			$ff += 1 << 17;
+		}
+		// editable: Controls whether a combo box is editable.
+		if (isset($prop['editable']) AND ($prop['editable'] == 'true')) {
+			$ff += 1 << 18;
+		}
+		// Sort: If set, the field's option items shall be sorted alphabetically.
+		if (isset($prop['Sort']) AND ($prop['Sort'] == 'true')) {
+			$ff += 1 << 19;
+		}
+		// fileSelect: If true, sets the file-select flag in the Options tab of the text field (Field is Used for File Selection).
+		if (isset($prop['fileSelect']) AND ($prop['fileSelect'] == 'true')) {
+			$ff += 1 << 20;
+		}
+		// multipleSelection: If true, indicates that a list box allows a multiple selection of items.
+		if (isset($prop['multipleSelection']) AND ($prop['multipleSelection'] == 'true')) {
+			$ff += 1 << 21;
+		}
+		// doNotSpellCheck: If true, spell checking is not performed on this editable text field.
+		if (isset($prop['doNotSpellCheck']) AND ($prop['doNotSpellCheck'] == 'true')) {
+			$ff += 1 << 22;
+		}
+		// doNotScroll: If true, the text field does not scroll and the user, therefore, is limited by the rectangular region designed for the field.
+		if (isset($prop['doNotScroll']) AND ($prop['doNotScroll'] == 'true')) {
+			$ff += 1 << 23;
+		}
+		// comb: If set to true, the field background is drawn as series of boxes (one for each character in the value of the field) and each character of the content is drawn within those boxes. The number of boxes drawn is determined from the charLimit property. It applies only to text fields. The setter will also raise if any of the following field properties are also set multiline, password, and fileSelect. A side-effect of setting this property is that the doNotScroll property is also set.
+		if (isset($prop['comb']) AND ($prop['comb'] == 'true')) {
+			$ff += 1 << 24;
+		}
+		// radiosInUnison: If false, even if a group of radio buttons have the same name and export value, they behave in a mutually exclusive fashion, like HTML radio buttons.
+		if (isset($prop['radiosInUnison']) AND ($prop['radiosInUnison'] == 'true')) {
+			$ff += 1 << 25;
+		}
+		// richText: If true, the field allows rich text formatting.
+		if (isset($prop['richText']) AND ($prop['richText'] == 'true')) {
+			$ff += 1 << 25;
+		}
+		// commitOnSelChange: Controls whether a field value is committed after a selection change.
+		if (isset($prop['commitOnSelChange']) AND ($prop['commitOnSelChange'] == 'true')) {
+			$ff += 1 << 26;
+		}
+		$opt['ff'] = $ff;
+		// defaultValue: The default value of a field - that is, the value that the field is set to when the form is reset.
+		if (isset($prop['defaultValue'])) {
+			$opt['dv'] = $prop['defaultValue'];
+		}
+		$f = 4; // default value for annotation flags
+		// readonly: The read-only characteristic of a field. If a field is read-only, the user can see the field but cannot change it.
+		if (isset($prop['readonly']) AND ($prop['readonly'] == 'true')) {
+			$f += 1 << 6;
+		}
+		// display: Controls whether the field is hidden or visible on screen and in print.
+		if (isset($prop['display'])) {
+			if ($prop['display'] == 'display.visible') {
+				//
+			} elseif ($prop['display'] == 'display.hidden') {
+				$f += 1 << 1;
+			} elseif ($prop['display'] == 'display.noPrint') {
+				$f -= 1 << 2;
+			} elseif ($prop['display'] == 'display.noView') {
+				$f += 1 << 5;
+			}
+		}
+		$opt['f'] = $f;
+		// currentValueIndices: Reads and writes single or multiple values of a list box or combo box.
+		if (isset($prop['currentValueIndices']) AND is_array($prop['currentValueIndices'])) {
+			$opt['i'] = $prop['currentValueIndices'];
+		}
+		// value: The value of the field data that the user has entered.
+		if (isset($prop['value'])) {
+			if (is_array($prop['value'])) {
+				$opt['opt'] = array();
+				foreach ($prop['value'] AS $key => $optval) {
+					// exportValues: An array of strings representing the export values for the field.
+					if (isset($prop['exportValues'][$key])) {
+						$opt['opt'][$key] = array($prop['exportValues'][$key], $prop['value'][$key]);
+					} else {
+						$opt['opt'][$key] = $prop['value'][$key];
+					}
+				}
+			} else {
+				$opt['v'] = $prop['value'];
+			}
+		}
+		// richValue: This property specifies the text contents and formatting of a rich text field.
+		if (isset($prop['richValue'])) {
+			$opt['rv'] = $prop['richValue'];
+		}
+		// submitName: If nonempty, used during form submission instead of name. Only applicable if submitting in HTML format (that is, URL-encoded).
+		if (isset($prop['submitName'])) {
+			$opt['tm'] = $prop['submitName'];
+		}
+		// name: Fully qualified field name.
+		if (isset($prop['name'])) {
+			$opt['t'] = $prop['name'];
+		}
+		// userName: The user name (short description string) of the field.
+		if (isset($prop['userName'])) {
+			$opt['tu'] = $prop['userName'];
+		}
+		// highlight: Defines how a button reacts when a user clicks it.
+		if (isset($prop['highlight'])) {
+			switch ($prop['highlight']) {
+				case 'none':
+				case 'highlight.n': {
+					$opt['h'] = 'N';
+					break;
+				}
+				case 'invert':
+				case 'highlight.i': {
+					$opt['h'] = 'i';
+					break;
+				}
+				case 'push':
+				case 'highlight.p': {
+					$opt['h'] = 'P';
+					break;
+				}
+				case 'outline':
+				case 'highlight.o': {
+					$opt['h'] = 'O';
+					break;
+				}
+			}
+		}
+		// Unsupported options:
+		// - calcOrderIndex: Changes the calculation order of fields in the document.
+		// - delay: Delays the redrawing of a field's appearance.
+		// - defaultStyle: This property defines the default style attributes for the form field.
+		// - style: Allows the user to set the glyph style of a check box or radio button.
+		// - textColor, textFont, textSize
+		return $opt;
+	}
+
+	/**
+	 * Set default properties for form fields.
+	 * @param $prop (array) javascript field properties. Possible values are described on official Javascript for Acrobat API reference.
+	 * @public
+	 * @author Nicola Asuni
+	 * @since 4.8.000 (2009-09-06)
+	 */
+	public function setFormDefaultProp($prop=array()) {
+		$this->default_form_prop = $prop;
+	}
+
+	/**
+	 * Return the default properties for form fields.
+	 * @return array $prop javascript field properties. Possible values are described on official Javascript for Acrobat API reference.
+	 * @public
+	 * @author Nicola Asuni
+	 * @since 4.8.000 (2009-09-06)
+	 */
+	public function getFormDefaultProp() {
+		return $this->default_form_prop;
+	}
+
+	/**
+	 * Creates a text field
+	 * @param $name (string) field name
+	 * @param $w (float) Width of the rectangle
+	 * @param $h (float) Height of the rectangle
+	 * @param $prop (array) javascript field properties. Possible values are described on official Javascript for Acrobat API reference.
+	 * @param $opt (array) annotation parameters. Possible values are described on official PDF32000_2008 reference.
+	 * @param $x (float) Abscissa of the upper-left corner of the rectangle
+	 * @param $y (float) Ordinate of the upper-left corner of the rectangle
+	 * @param $js (boolean) if true put the field using JavaScript (requires Acrobat Writer to be rendered).
+	 * @public
+	 * @author Nicola Asuni
+	 * @since 4.8.000 (2009-09-07)
+	 */
+	public function TextField($name, $w, $h, $prop=array(), $opt=array(), $x='', $y='', $js=false) {
+		if ($x === '') {
+			$x = $this->x;
+		}
+		if ($y === '') {
+			$y = $this->y;
+		}
+		// check page for no-write regions and adapt page margins if necessary
+		list($x, $y) = $this->checkPageRegions($h, $x, $y);
+		if ($js) {
+			$this->_addfield('text', $name, $x, $y, $w, $h, $prop);
+			return;
+		}
+		// get default style
+		$prop = array_merge($this->getFormDefaultProp(), $prop);
+		// get annotation data
+		$popt = $this->getAnnotOptFromJSProp($prop);
+		// set default appearance stream
+		$this->annotation_fonts[$this->CurrentFont['fontkey']] = $this->CurrentFont['i'];
+		$fontstyle = sprintf('/F%d %F Tf %s', $this->CurrentFont['i'], $this->FontSizePt, $this->TextColor);
+		$popt['da'] = $fontstyle;
+		// build appearance stream
+		$popt['ap'] = array();
+		$popt['ap']['n'] = '/Tx BMC q '.$fontstyle.' ';
+		$text = '';
+		if (isset($prop['value']) AND !empty($prop['value'])) {
+			$text = $prop['value'];
+		} elseif (isset($opt['v']) AND !empty($opt['v'])) {
+			$text = $opt['v'];
+		}
+		$tmpid = $this->startTemplate($w, $h, false);
+		$align = '';
+		if (isset($popt['q'])) {
+			switch ($popt['q']) {
+				case 0: {
+					$align = 'L';
+					break;
+				}
+				case 1: {
+					$align = 'C';
+					break;
+				}
+				case 2: {
+					$align = 'R';
+					break;
+				}
+				default: {
+					$align = '';
+					break;
+				}
+			}
+		}
+		$this->MultiCell($w, $h, $text, 0, $align, false, 0, 0, 0, true, 0, false, true, 0, 'T', false);
+		$this->endTemplate();
+		--$this->n;
+		$popt['ap']['n'] .= $this->xobjects[$tmpid]['outdata'];
+		unset($this->xobjects[$tmpid]);
+		$popt['ap']['n'] .= 'Q EMC';
+		// merge options
+		$opt = array_merge($popt, $opt);
+		// remove some conflicting options
+		unset($opt['bs']);
+		// set remaining annotation data
+		$opt['Subtype'] = 'Widget';
+		$opt['ft'] = 'Tx';
+		$opt['t'] = $name;
+		// Additional annotation's parameters (check _putannotsobj() method):
+		//$opt['f']
+		//$opt['as']
+		//$opt['bs']
+		//$opt['be']
+		//$opt['c']
+		//$opt['border']
+		//$opt['h']
+		//$opt['mk'];
+		//$opt['mk']['r']
+		//$opt['mk']['bc'];
+		//$opt['mk']['bg'];
+		unset($opt['mk']['ca']);
+		unset($opt['mk']['rc']);
+		unset($opt['mk']['ac']);
+		unset($opt['mk']['i']);
+		unset($opt['mk']['ri']);
+		unset($opt['mk']['ix']);
+		unset($opt['mk']['if']);
+		//$opt['mk']['if']['sw'];
+		//$opt['mk']['if']['s'];
+		//$opt['mk']['if']['a'];
+		//$opt['mk']['if']['fb'];
+		unset($opt['mk']['tp']);
+		//$opt['tu']
+		//$opt['tm']
+		//$opt['ff']
+		//$opt['v']
+		//$opt['dv']
+		//$opt['a']
+		//$opt['aa']
+		//$opt['q']
+		$this->Annotation($x, $y, $w, $h, $name, $opt, 0);
+		if ($this->rtl) {
+			$this->x -= $w;
+		} else {
+			$this->x += $w;
+		}
+	}
+
+	/**
+	 * Creates a RadioButton field.
+	 * @param $name (string) Field name.
+	 * @param $w (int) Width of the radio button.
+	 * @param $prop (array) Javascript field properties. Possible values are described on official Javascript for Acrobat API reference.
+	 * @param $opt (array) Annotation parameters. Possible values are described on official PDF32000_2008 reference.
+	 * @param $onvalue (string) Value to be returned if selected.
+	 * @param $checked (boolean) Define the initial state.
+	 * @param $x (float) Abscissa of the upper-left corner of the rectangle
+	 * @param $y (float) Ordinate of the upper-left corner of the rectangle
+	 * @param $js (boolean) If true put the field using JavaScript (requires Acrobat Writer to be rendered).
+	 * @public
+	 * @author Nicola Asuni
+	 * @since 4.8.000 (2009-09-07)
+	 */
+	public function RadioButton($name, $w, $prop=array(), $opt=array(), $onvalue='On', $checked=false, $x='', $y='', $js=false) {
+		if ($x === '') {
+			$x = $this->x;
+		}
+		if ($y === '') {
+			$y = $this->y;
+		}
+		// check page for no-write regions and adapt page margins if necessary
+		list($x, $y) = $this->checkPageRegions($w, $x, $y);
+		if ($js) {
+			$this->_addfield('radiobutton', $name, $x, $y, $w, $w, $prop);
+			return;
+		}
+		if ($this->empty_string($onvalue)) {
+			$onvalue = 'On';
+		}
+		if ($checked) {
+			$defval = $onvalue;
+		} else {
+			$defval = 'Off';
+		}
+		// set font
+		$font = 'zapfdingbats';
+		if ($this->pdfa_mode) {
+			// all fonts must be embedded
+			$font = 'pdfa'.$font;
+		}
+		$this->AddFont($font);
+		$tmpfont = $this->getFontBuffer($font);
+		// set data for parent group
+		if (!isset($this->radiobutton_groups[$this->page])) {
+			$this->radiobutton_groups[$this->page] = array();
+		}
+		if (!isset($this->radiobutton_groups[$this->page][$name])) {
+			$this->radiobutton_groups[$this->page][$name] = array();
+			++$this->n;
+			$this->radiobutton_groups[$this->page][$name]['n'] = $this->n;
+			$this->radio_groups[] = $this->n;
+		}
+		$kid = ($this->n + 1);
+		// save object ID to be added on Kids entry on parent object
+		$this->radiobutton_groups[$this->page][$name][] = array('kid' => $kid, 'def' => $defval);
+		// get default style
+		$prop = array_merge($this->getFormDefaultProp(), $prop);
+		$prop['NoToggleToOff'] = 'true';
+		$prop['Radio'] = 'true';
+		$prop['borderStyle'] = 'inset';
+		// get annotation data
+		$popt = $this->getAnnotOptFromJSProp($prop);
+		// set additional default options
+		$this->annotation_fonts[$tmpfont['fontkey']] = $tmpfont['i'];
+		$fontstyle = sprintf('/F%d %F Tf %s', $tmpfont['i'], $this->FontSizePt, $this->TextColor);
+		$popt['da'] = $fontstyle;
+		// build appearance stream
+		$popt['ap'] = array();
+		$popt['ap']['n'] = array();
+		$fx = ((($w - $this->getAbsFontMeasure($tmpfont['cw'][108])) / 2) * $this->k);
+		$fy = (($w - ((($tmpfont['desc']['Ascent'] - $tmpfont['desc']['Descent']) * $this->FontSizePt / 1000) / $this->k)) * $this->k);
+		$popt['ap']['n'][$onvalue] = sprintf('q %s BT /F%d %F Tf %F %F Td ('.chr(108).') Tj ET Q', $this->TextColor, $tmpfont['i'], $this->FontSizePt, $fx, $fy);
+		$popt['ap']['n']['Off'] = sprintf('q %s BT /F%d %F Tf %F %F Td ('.chr(109).') Tj ET Q', $this->TextColor, $tmpfont['i'], $this->FontSizePt, $fx, $fy);
+		if (!isset($popt['mk'])) {
+			$popt['mk'] = array();
+		}
+		$popt['mk']['ca'] = '(l)';
+		// merge options
+		$opt = array_merge($popt, $opt);
+		// set remaining annotation data
+		$opt['Subtype'] = 'Widget';
+		$opt['ft'] = 'Btn';
+		if ($checked) {
+			$opt['v'] = array('/'.$onvalue);
+			$opt['as'] = $onvalue;
+		} else {
+			$opt['as'] = 'Off';
+		}
+		// store readonly flag
+		if (!isset($this->radiobutton_groups[$this->page][$name]['#readonly#'])) {
+			$this->radiobutton_groups[$this->page][$name]['#readonly#'] = false;
+		}
+		$this->radiobutton_groups[$this->page][$name]['#readonly#'] |= ($opt['f'] & 64);
+		$this->Annotation($x, $y, $w, $w, $name, $opt, 0);
+		if ($this->rtl) {
+			$this->x -= $w;
+		} else {
+			$this->x += $w;
+		}
+	}
+
+	/**
+	 * Creates a List-box field
+	 * @param $name (string) field name
+	 * @param $w (int) width
+	 * @param $h (int) height
+	 * @param $values (array) array containing the list of values.
+	 * @param $prop (array) javascript field properties. Possible values are described on official Javascript for Acrobat API reference.
+	 * @param $opt (array) annotation parameters. Possible values are described on official PDF32000_2008 reference.
+	 * @param $x (float) Abscissa of the upper-left corner of the rectangle
+	 * @param $y (float) Ordinate of the upper-left corner of the rectangle
+	 * @param $js (boolean) if true put the field using JavaScript (requires Acrobat Writer to be rendered).
+	 * @public
+	 * @author Nicola Asuni
+	 * @since 4.8.000 (2009-09-07)
+	 */
+	public function ListBox($name, $w, $h, $values, $prop=array(), $opt=array(), $x='', $y='', $js=false) {
+		if ($x === '') {
+			$x = $this->x;
+		}
+		if ($y === '') {
+			$y = $this->y;
+		}
+		// check page for no-write regions and adapt page margins if necessary
+		list($x, $y) = $this->checkPageRegions($h, $x, $y);
+		if ($js) {
+			$this->_addfield('listbox', $name, $x, $y, $w, $h, $prop);
+			$s = '';
+			foreach ($values as $value) {
+				if (is_array($value)) {
+					$s .= ',[\''.addslashes($value[1]).'\',\''.addslashes($value[0]).'\']';
+				} else {
+					$s .= ',[\''.addslashes($value).'\',\''.addslashes($value).'\']';
+				}
+			}
+			$this->javascript .= 'f'.$name.'.setItems('.substr($s, 1).');'."\n";
+			return;
+		}
+		// get default style
+		$prop = array_merge($this->getFormDefaultProp(), $prop);
+		// get annotation data
+		$popt = $this->getAnnotOptFromJSProp($prop);
+		// set additional default values
+		$this->annotation_fonts[$this->CurrentFont['fontkey']] = $this->CurrentFont['i'];
+		$fontstyle = sprintf('/F%d %F Tf %s', $this->CurrentFont['i'], $this->FontSizePt, $this->TextColor);
+		$popt['da'] = $fontstyle;
+		// build appearance stream
+		$popt['ap'] = array();
+		$popt['ap']['n'] = '/Tx BMC q '.$fontstyle.' ';
+		$text = '';
+		foreach($values as $item) {
+			if (is_array($item)) {
+				$text .= $item[1]."\n";
+			} else {
+				$text .= $item."\n";
+			}
+		}
+		$tmpid = $this->startTemplate($w, $h, false);
+		$this->MultiCell($w, $h, $text, 0, '', false, 0, 0, 0, true, 0, false, true, 0, 'T', false);
+		$this->endTemplate();
+		--$this->n;
+		$popt['ap']['n'] .= $this->xobjects[$tmpid]['outdata'];
+		unset($this->xobjects[$tmpid]);
+		$popt['ap']['n'] .= 'Q EMC';
+		// merge options
+		$opt = array_merge($popt, $opt);
+		// set remaining annotation data
+		$opt['Subtype'] = 'Widget';
+		$opt['ft'] = 'Ch';
+		$opt['t'] = $name;
+		$opt['opt'] = $values;
+		unset($opt['mk']['ca']);
+		unset($opt['mk']['rc']);
+		unset($opt['mk']['ac']);
+		unset($opt['mk']['i']);
+		unset($opt['mk']['ri']);
+		unset($opt['mk']['ix']);
+		unset($opt['mk']['if']);
+		unset($opt['mk']['tp']);
+		$this->Annotation($x, $y, $w, $h, $name, $opt, 0);
+		if ($this->rtl) {
+			$this->x -= $w;
+		} else {
+			$this->x += $w;
+		}
+	}
+
+	/**
+	 * Creates a Combo-box field
+	 * @param $name (string) field name
+	 * @param $w (int) width
+	 * @param $h (int) height
+	 * @param $values (array) array containing the list of values.
+	 * @param $prop (array) javascript field properties. Possible values are described on official Javascript for Acrobat API reference.
+	 * @param $opt (array) annotation parameters. Possible values are described on official PDF32000_2008 reference.
+	 * @param $x (float) Abscissa of the upper-left corner of the rectangle
+	 * @param $y (float) Ordinate of the upper-left corner of the rectangle
+	 * @param $js (boolean) if true put the field using JavaScript (requires Acrobat Writer to be rendered).
+	 * @public
+	 * @author Nicola Asuni
+	 * @since 4.8.000 (2009-09-07)
+	 */
+	public function ComboBox($name, $w, $h, $values, $prop=array(), $opt=array(), $x='', $y='', $js=false) {
+		if ($x === '') {
+			$x = $this->x;
+		}
+		if ($y === '') {
+			$y = $this->y;
+		}
+		// check page for no-write regions and adapt page margins if necessary
+		list($x, $y) = $this->checkPageRegions($h, $x, $y);
+		if ($js) {
+			$this->_addfield('combobox', $name, $x, $y, $w, $h, $prop);
+			$s = '';
+			foreach ($values as $value) {
+				if (is_array($value)) {
+					$s .= ',[\''.addslashes($value[1]).'\',\''.addslashes($value[0]).'\']';
+				} else {
+					$s .= ',[\''.addslashes($value).'\',\''.addslashes($value).'\']';
+				}
+			}
+			$this->javascript .= 'f'.$name.'.setItems('.substr($s, 1).');'."\n";
+			return;
+		}
+		// get default style
+		$prop = array_merge($this->getFormDefaultProp(), $prop);
+		$prop['Combo'] = true;
+		// get annotation data
+		$popt = $this->getAnnotOptFromJSProp($prop);
+		// set additional default options
+		$this->annotation_fonts[$this->CurrentFont['fontkey']] = $this->CurrentFont['i'];
+		$fontstyle = sprintf('/F%d %F Tf %s', $this->CurrentFont['i'], $this->FontSizePt, $this->TextColor);
+		$popt['da'] = $fontstyle;
+		// build appearance stream
+		$popt['ap'] = array();
+		$popt['ap']['n'] = '/Tx BMC q '.$fontstyle.' ';
+		$text = '';
+		foreach($values as $item) {
+			if (is_array($item)) {
+				$text .= $item[1]."\n";
+			} else {
+				$text .= $item."\n";
+			}
+		}
+		$tmpid = $this->startTemplate($w, $h, false);
+		$this->MultiCell($w, $h, $text, 0, '', false, 0, 0, 0, true, 0, false, true, 0, 'T', false);
+		$this->endTemplate();
+		--$this->n;
+		$popt['ap']['n'] .= $this->xobjects[$tmpid]['outdata'];
+		unset($this->xobjects[$tmpid]);
+		$popt['ap']['n'] .= 'Q EMC';
+		// merge options
+		$opt = array_merge($popt, $opt);
+		// set remaining annotation data
+		$opt['Subtype'] = 'Widget';
+		$opt['ft'] = 'Ch';
+		$opt['t'] = $name;
+		$opt['opt'] = $values;
+		unset($opt['mk']['ca']);
+		unset($opt['mk']['rc']);
+		unset($opt['mk']['ac']);
+		unset($opt['mk']['i']);
+		unset($opt['mk']['ri']);
+		unset($opt['mk']['ix']);
+		unset($opt['mk']['if']);
+		unset($opt['mk']['tp']);
+		$this->Annotation($x, $y, $w, $h, $name, $opt, 0);
+		if ($this->rtl) {
+			$this->x -= $w;
+		} else {
+			$this->x += $w;
+		}
+	}
+
+	/**
+	 * Creates a CheckBox field
+	 * @param $name (string) field name
+	 * @param $w (int) width
+	 * @param $checked (boolean) define the initial state.
+	 * @param $prop (array) javascript field properties. Possible values are described on official Javascript for Acrobat API reference.
+	 * @param $opt (array) annotation parameters. Possible values are described on official PDF32000_2008 reference.
+	 * @param $onvalue (string) value to be returned if selected.
+	 * @param $x (float) Abscissa of the upper-left corner of the rectangle
+	 * @param $y (float) Ordinate of the upper-left corner of the rectangle
+	 * @param $js (boolean) if true put the field using JavaScript (requires Acrobat Writer to be rendered).
+	 * @public
+	 * @author Nicola Asuni
+	 * @since 4.8.000 (2009-09-07)
+	 */
+	public function CheckBox($name, $w, $checked=false, $prop=array(), $opt=array(), $onvalue='Yes', $x='', $y='', $js=false) {
+		if ($x === '') {
+			$x = $this->x;
+		}
+		if ($y === '') {
+			$y = $this->y;
+		}
+		// check page for no-write regions and adapt page margins if necessary
+		list($x, $y) = $this->checkPageRegions($w, $x, $y);
+		if ($js) {
+			$this->_addfield('checkbox', $name, $x, $y, $w, $w, $prop);
+			return;
+		}
+		if (!isset($prop['value'])) {
+			$prop['value'] = array('Yes');
+		}
+		// get default style
+		$prop = array_merge($this->getFormDefaultProp(), $prop);
+		$prop['borderStyle'] = 'inset';
+		// get annotation data
+		$popt = $this->getAnnotOptFromJSProp($prop);
+		// set additional default options
+		$font = 'zapfdingbats';
+		if ($this->pdfa_mode) {
+			// all fonts must be embedded
+			$font = 'pdfa'.$font;
+		}
+		$this->AddFont($font);
+		$tmpfont = $this->getFontBuffer($font);
+		$this->annotation_fonts[$tmpfont['fontkey']] = $tmpfont['i'];
+		$fontstyle = sprintf('/F%d %F Tf %s', $tmpfont['i'], $this->FontSizePt, $this->TextColor);
+		$popt['da'] = $fontstyle;
+		// build appearance stream
+		$popt['ap'] = array();
+		$popt['ap']['n'] = array();
+		$fx = ((($w - $this->getAbsFontMeasure($tmpfont['cw'][110])) / 2) * $this->k);
+		$fy = (($w - ((($tmpfont['desc']['Ascent'] - $tmpfont['desc']['Descent']) * $this->FontSizePt / 1000) / $this->k)) * $this->k);
+		$popt['ap']['n']['Yes'] = sprintf('q %s BT /F%d %F Tf %F %F Td ('.chr(110).') Tj ET Q', $this->TextColor, $tmpfont['i'], $this->FontSizePt, $fx, $fy);
+		$popt['ap']['n']['Off'] = sprintf('q %s BT /F%d %F Tf %F %F Td ('.chr(111).') Tj ET Q', $this->TextColor, $tmpfont['i'], $this->FontSizePt, $fx, $fy);
+		// merge options
+		$opt = array_merge($popt, $opt);
+		// set remaining annotation data
+		$opt['Subtype'] = 'Widget';
+		$opt['ft'] = 'Btn';
+		$opt['t'] = $name;
+		if ($this->empty_string($onvalue)) {
+			$onvalue = 'Yes';
+		}
+		$opt['opt'] = array($onvalue);
+		if ($checked) {
+			$opt['v'] = array('/Yes');
+			$opt['as'] = 'Yes';
+		} else {
+			$opt['v'] = array('/Off');
+			$opt['as'] = 'Off';
+		}
+		$this->Annotation($x, $y, $w, $w, $name, $opt, 0);
+		if ($this->rtl) {
+			$this->x -= $w;
+		} else {
+			$this->x += $w;
+		}
+	}
+
+	/**
+	 * Creates a button field
+	 * @param $name (string) field name
+	 * @param $w (int) width
+	 * @param $h (int) height
+	 * @param $caption (string) caption.
+	 * @param $action (mixed) action triggered by pressing the button. Use a string to specify a javascript action. Use an array to specify a form action options as on section 12.7.5 of PDF32000_2008.
+	 * @param $prop (array) javascript field properties. Possible values are described on official Javascript for Acrobat API reference.
+	 * @param $opt (array) annotation parameters. Possible values are described on official PDF32000_2008 reference.
+	 * @param $x (float) Abscissa of the upper-left corner of the rectangle
+	 * @param $y (float) Ordinate of the upper-left corner of the rectangle
+	 * @param $js (boolean) if true put the field using JavaScript (requires Acrobat Writer to be rendered).
+	 * @public
+	 * @author Nicola Asuni
+	 * @since 4.8.000 (2009-09-07)
+	 */
+	public function Button($name, $w, $h, $caption, $action, $prop=array(), $opt=array(), $x='', $y='', $js=false) {
+		if ($x === '') {
+			$x = $this->x;
+		}
+		if ($y === '') {
+			$y = $this->y;
+		}
+		// check page for no-write regions and adapt page margins if necessary
+		list($x, $y) = $this->checkPageRegions($h, $x, $y);
+		if ($js) {
+			$this->_addfield('button', $name, $this->x, $this->y, $w, $h, $prop);
+			$this->javascript .= 'f'.$name.".buttonSetCaption('".addslashes($caption)."');\n";
+			$this->javascript .= 'f'.$name.".setAction('MouseUp','".addslashes($action)."');\n";
+			$this->javascript .= 'f'.$name.".highlight='push';\n";
+			$this->javascript .= 'f'.$name.".print=false;\n";
+			return;
+		}
+		// get default style
+		$prop = array_merge($this->getFormDefaultProp(), $prop);
+		$prop['Pushbutton'] = 'true';
+		$prop['highlight'] = 'push';
+		$prop['display'] = 'display.noPrint';
+		// get annotation data
+		$popt = $this->getAnnotOptFromJSProp($prop);
+		$this->annotation_fonts[$this->CurrentFont['fontkey']] = $this->CurrentFont['i'];
+		$fontstyle = sprintf('/F%d %F Tf %s', $this->CurrentFont['i'], $this->FontSizePt, $this->TextColor);
+		$popt['da'] = $fontstyle;
+		// build appearance stream
+		$popt['ap'] = array();
+		$popt['ap']['n'] = '/Tx BMC q '.$fontstyle.' ';
+		$tmpid = $this->startTemplate($w, $h, false);
+		$bw = (2 / $this->k); // border width
+		$border = array(
+			'L' => array('width' => $bw, 'cap' => 'square', 'join' => 'miter', 'dash' => 0, 'color' => array(231)),
+			'R' => array('width' => $bw, 'cap' => 'square', 'join' => 'miter', 'dash' => 0, 'color' => array(51)),
+			'T' => array('width' => $bw, 'cap' => 'square', 'join' => 'miter', 'dash' => 0, 'color' => array(231)),
+			'B' => array('width' => $bw, 'cap' => 'square', 'join' => 'miter', 'dash' => 0, 'color' => array(51)));
+		$this->SetFillColor(204);
+		$this->Cell($w, $h, $caption, $border, 0, 'C', true, '', 1, false, 'T', 'M');
+		$this->endTemplate();
+		--$this->n;
+		$popt['ap']['n'] .= $this->xobjects[$tmpid]['outdata'];
+		unset($this->xobjects[$tmpid]);
+		$popt['ap']['n'] .= 'Q EMC';
+		// set additional default options
+		if (!isset($popt['mk'])) {
+			$popt['mk'] = array();
+		}
+		$ann_obj_id = ($this->n + 1);
+		if (!empty($action) AND !is_array($action)) {
+			$ann_obj_id = ($this->n + 2);
+		}
+		$popt['mk']['ca'] = $this->_textstring($caption, $ann_obj_id);
+		$popt['mk']['rc'] = $this->_textstring($caption, $ann_obj_id);
+		$popt['mk']['ac'] = $this->_textstring($caption, $ann_obj_id);
+		// merge options
+		$opt = array_merge($popt, $opt);
+		// set remaining annotation data
+		$opt['Subtype'] = 'Widget';
+		$opt['ft'] = 'Btn';
+		$opt['t'] = $caption;
+		$opt['v'] = $name;
+		if (!empty($action)) {
+			if (is_array($action)) {
+				// form action options as on section 12.7.5 of PDF32000_2008.
+				$opt['aa'] = '/D <<';
+				$bmode = array('SubmitForm', 'ResetForm', 'ImportData');
+				foreach ($action AS $key => $val) {
+					if (($key == 'S') AND in_array($val, $bmode)) {
+						$opt['aa'] .= ' /S /'.$val;
+					} elseif (($key == 'F') AND (!empty($val))) {
+						$opt['aa'] .= ' /F '.$this->_datastring($val, $ann_obj_id);
+					} elseif (($key == 'Fields') AND is_array($val) AND !empty($val)) {
+						$opt['aa'] .= ' /Fields [';
+						foreach ($val AS $field) {
+							$opt['aa'] .= ' '.$this->_textstring($field, $ann_obj_id);
+						}
+						$opt['aa'] .= ']';
+					} elseif (($key == 'Flags')) {
+						$ff = 0;
+						if (is_array($val)) {
+							foreach ($val AS $flag) {
+								switch ($flag) {
+									case 'Include/Exclude': {
+										$ff += 1 << 0;
+										break;
+									}
+									case 'IncludeNoValueFields': {
+										$ff += 1 << 1;
+										break;
+									}
+									case 'ExportFormat': {
+										$ff += 1 << 2;
+										break;
+									}
+									case 'GetMethod': {
+										$ff += 1 << 3;
+										break;
+									}
+									case 'SubmitCoordinates': {
+										$ff += 1 << 4;
+										break;
+									}
+									case 'XFDF': {
+										$ff += 1 << 5;
+										break;
+									}
+									case 'IncludeAppendSaves': {
+										$ff += 1 << 6;
+										break;
+									}
+									case 'IncludeAnnotations': {
+										$ff += 1 << 7;
+										break;
+									}
+									case 'SubmitPDF': {
+										$ff += 1 << 8;
+										break;
+									}
+									case 'CanonicalFormat': {
+										$ff += 1 << 9;
+										break;
+									}
+									case 'ExclNonUserAnnots': {
+										$ff += 1 << 10;
+										break;
+									}
+									case 'ExclFKey': {
+										$ff += 1 << 11;
+										break;
+									}
+									case 'EmbedForm': {
+										$ff += 1 << 13;
+										break;
+									}
+								}
+							}
+						} else {
+							$ff = intval($val);
+						}
+						$opt['aa'] .= ' /Flags '.$ff;
+					}
+				}
+				$opt['aa'] .= ' >>';
+			} else {
+				// Javascript action or raw action command
+				$js_obj_id = $this->addJavascriptObject($action);
+				$opt['aa'] = '/D '.$js_obj_id.' 0 R';
+			}
+		}
+		$this->Annotation($x, $y, $w, $h, $name, $opt, 0);
+		if ($this->rtl) {
+			$this->x -= $w;
+		} else {
+			$this->x += $w;
+		}
+	}
+
+	// --- END FORMS FIELDS ------------------------------------------------
+
+	/**
+	 * Add certification signature (DocMDP or UR3)
+	 * You can set only one signature type
+	 * @protected
+	 * @author Nicola Asuni
+	 * @since 4.6.008 (2009-05-07)
+	 */
+	protected function _putsignature() {
+		if ((!$this->sign) OR (!isset($this->signature_data['cert_type']))) {
+			return;
+		}
+		$sigobjid = ($this->sig_obj_id + 1);
+		$out = $this->_getobj($sigobjid)."\n";
+		$out .= '<< /Type /Sig';
+		$out .= ' /Filter /Adobe.PPKLite';
+		$out .= ' /SubFilter /adbe.pkcs7.detached';
+		$out .= ' '.$this->byterange_string;
+		$out .= ' /Contents<'.str_repeat('0', $this->signature_max_length).'>';
+		$out .= ' /Reference ['; // array of signature reference dictionaries
+		$out .= ' << /Type /SigRef';
+		if ($this->signature_data['cert_type'] > 0) {
+			$out .= ' /TransformMethod /DocMDP';
+			$out .= ' /TransformParams <<';
+			$out .= ' /Type /TransformParams';
+			$out .= ' /P '.$this->signature_data['cert_type'];
+			$out .= ' /V /1.2';
+		} else {
+			$out .= ' /TransformMethod /UR3';
+			$out .= ' /TransformParams <<';
+			$out .= ' /Type /TransformParams';
+			$out .= ' /V /2.2';
+			if (!$this->empty_string($this->ur['document'])) {
+				$out .= ' /Document['.$this->ur['document'].']';
+			}
+			if (!$this->empty_string($this->ur['form'])) {
+				$out .= ' /Form['.$this->ur['form'].']';
+			}
+			if (!$this->empty_string($this->ur['signature'])) {
+				$out .= ' /Signature['.$this->ur['signature'].']';
+			}
+			if (!$this->empty_string($this->ur['annots'])) {
+				$out .= ' /Annots['.$this->ur['annots'].']';
+			}
+			if (!$this->empty_string($this->ur['ef'])) {
+				$out .= ' /EF['.$this->ur['ef'].']';
+			}
+			if (!$this->empty_string($this->ur['formex'])) {
+				$out .= ' /FormEX['.$this->ur['formex'].']';
+			}
+		}
+		$out .= ' >>'; // close TransformParams
+		// optional digest data (values must be calculated and replaced later)
+		//$out .= ' /Data ********** 0 R';
+		//$out .= ' /DigestMethod/MD5';
+		//$out .= ' /DigestLocation[********** 34]';
+		//$out .= ' /DigestValue<********************************>';
+		$out .= ' >>';
+		$out .= ' ]'; // end of reference
+		if (isset($this->signature_data['info']['Name']) AND !$this->empty_string($this->signature_data['info']['Name'])) {
+			$out .= ' /Name '.$this->_textstring($this->signature_data['info']['Name'], $sigobjid);
+		}
+		if (isset($this->signature_data['info']['Location']) AND !$this->empty_string($this->signature_data['info']['Location'])) {
+			$out .= ' /Location '.$this->_textstring($this->signature_data['info']['Location'], $sigobjid);
+		}
+		if (isset($this->signature_data['info']['Reason']) AND !$this->empty_string($this->signature_data['info']['Reason'])) {
+			$out .= ' /Reason '.$this->_textstring($this->signature_data['info']['Reason'], $sigobjid);
+		}
+		if (isset($this->signature_data['info']['ContactInfo']) AND !$this->empty_string($this->signature_data['info']['ContactInfo'])) {
+			$out .= ' /ContactInfo '.$this->_textstring($this->signature_data['info']['ContactInfo'], $sigobjid);
+		}
+		$out .= ' /M '.$this->_datestring($sigobjid, $this->doc_modification_timestamp);
+		$out .= ' >>';
+		$out .= "\n".'endobj';
+		$this->_out($out);
+	}
+
+	/**
+	 * Set User's Rights for PDF Reader
+	 * WARNING: This is experimental and currently do not work.
+	 * Check the PDF Reference 8.7.1 Transform Methods,
+	 * Table 8.105 Entries in the UR transform parameters dictionary
+	 * @param $enable (boolean) if true enable user's rights on PDF reader
+	 * @param $document (string) Names specifying additional document-wide usage rights for the document. The only defined value is "/FullSave", which permits a user to save the document along with modified form and/or annotation data.
+	 * @param $annots (string) Names specifying additional annotation-related usage rights for the document. Valid names in PDF 1.5 and later are /Create/Delete/Modify/Copy/Import/Export, which permit the user to perform the named operation on annotations.
+	 * @param $form (string) Names specifying additional form-field-related usage rights for the document. Valid names are: /Add/Delete/FillIn/Import/Export/SubmitStandalone/SpawnTemplate
+	 * @param $signature (string) Names specifying additional signature-related usage rights for the document. The only defined value is /Modify, which permits a user to apply a digital signature to an existing signature form field or clear a signed signature form field.
+	 * @param $ef (string) Names specifying additional usage rights for named embedded files in the document. Valid names are /Create/Delete/Modify/Import, which permit the user to perform the named operation on named embedded files
+	 Names specifying additional embedded-files-related usage rights for the document.
+	 * @param $formex (string) Names specifying additional form-field-related usage rights. The only valid name is BarcodePlaintext, which permits text form field data to be encoded as a plaintext two-dimensional barcode.
+	 * @public
+	 * @author Nicola Asuni
+	 * @since 2.9.000 (2008-03-26)
+	 */
+	public function setUserRights(
+			$enable=true,
+			$document='/FullSave',
+			$annots='/Create/Delete/Modify/Copy/Import/Export',
+			$form='/Add/Delete/FillIn/Import/Export/SubmitStandalone/SpawnTemplate',
+			$signature='/Modify',
+			$ef='/Create/Delete/Modify/Import',
+			$formex='') {
+		$this->ur['enabled'] = $enable;
+		$this->ur['document'] = $document;
+		$this->ur['annots'] = $annots;
+		$this->ur['form'] = $form;
+		$this->ur['signature'] = $signature;
+		$this->ur['ef'] = $ef;
+		$this->ur['formex'] = $formex;
+		if (!$this->sign) {
+			$this->setSignature('', '', '', '', 0, array());
+		}
+	}
+
+	/**
+	 * Enable document signature (requires the OpenSSL Library).
+	 * The digital signature improve document authenticity and integrity and allows o enable extra features on Acrobat Reader.
+	 * To create self-signed signature: openssl req -x509 -nodes -days 365000 -newkey rsa:1024 -keyout tcpdf.crt -out tcpdf.crt
+	 * To export crt to p12: openssl pkcs12 -export -in tcpdf.crt -out tcpdf.p12
+	 * To convert pfx certificate to pem: openssl pkcs12 -in tcpdf.pfx -out tcpdf.crt -nodes
+	 * @param $signing_cert (mixed) signing certificate (string or filename prefixed with 'file://')
+	 * @param $private_key (mixed) private key (string or filename prefixed with 'file://')
+	 * @param $private_key_password (string) password
+	 * @param $extracerts (string) specifies the name of a file containing a bunch of extra certificates to include in the signature which can for example be used to help the recipient to verify the certificate that you used.
+	 * @param $cert_type (int) The access permissions granted for this document. Valid values shall be: 1 = No changes to the document shall be permitted; any change to the document shall invalidate the signature; 2 = Permitted changes shall be filling in forms, instantiating page templates, and signing; other changes shall invalidate the signature; 3 = Permitted changes shall be the same as for 2, as well as annotation creation, deletion, and modification; other changes shall invalidate th [...]
+	 * @param $info (array) array of option information: Name, Location, Reason, ContactInfo.
+	 * @public
+	 * @author Nicola Asuni
+	 * @since 4.6.005 (2009-04-24)
+	 */
+	public function setSignature($signing_cert='', $private_key='', $private_key_password='', $extracerts='', $cert_type=2, $info=array()) {
+		// to create self-signed signature: openssl req -x509 -nodes -days 365000 -newkey rsa:1024 -keyout tcpdf.crt -out tcpdf.crt
+		// to export crt to p12: openssl pkcs12 -export -in tcpdf.crt -out tcpdf.p12
+		// to convert pfx certificate to pem: openssl
+		//     OpenSSL> pkcs12 -in <cert.pfx> -out <cert.crt> -nodes
+		$this->sign = true;
+		++$this->n;
+		$this->sig_obj_id = $this->n; // signature widget
+		++$this->n; // signature object ($this->sig_obj_id + 1)
+		$this->signature_data = array();
+		if (strlen($signing_cert) == 0) {
+			$signing_cert = 'file://'.dirname(__FILE__).'/tcpdf.crt';
+			$private_key_password = 'tcpdfdemo';
+		}
+		if (strlen($private_key) == 0) {
+			$private_key = $signing_cert;
+		}
+		$this->signature_data['signcert'] = $signing_cert;
+		$this->signature_data['privkey'] = $private_key;
+		$this->signature_data['password'] = $private_key_password;
+		$this->signature_data['extracerts'] = $extracerts;
+		$this->signature_data['cert_type'] = $cert_type;
+		$this->signature_data['info'] = $info;
+	}
+
+	/**
+	 * Set the digital signature appearance (a cliccable rectangle area to get signature properties)
+	 * @param $x (float) Abscissa of the upper-left corner.
+	 * @param $y (float) Ordinate of the upper-left corner.
+	 * @param $w (float) Width of the signature area.
+	 * @param $h (float) Height of the signature area.
+	 * @param $page (int) option page number (if < 0 the current page is used).
+	 * @public
+	 * @author Nicola Asuni
+	 * @since 5.3.011 (2010-06-17)
+	 */
+	public function setSignatureAppearance($x=0, $y=0, $w=0, $h=0, $page=-1) {
+		$this->signature_appearance = $this->getSignatureAppearanceArray($x, $y, $w, $h, $page);
+	}
+
+	/**
+	 * Add an empty digital signature appearance (a cliccable rectangle area to get signature properties)
+	 * @param $x (float) Abscissa of the upper-left corner.
+	 * @param $y (float) Ordinate of the upper-left corner.
+	 * @param $w (float) Width of the signature area.
+	 * @param $h (float) Height of the signature area.
+	 * @param $page (int) option page number (if < 0 the current page is used).
+	 * @public
+	 * @author Nicola Asuni
+	 * @since 5.9.101 (2011-07-06)
+	 */
+	public function addEmptySignatureAppearance($x=0, $y=0, $w=0, $h=0, $page=-1) {
+		++$this->n;
+		$this->empty_signature_appearance[] = array('objid' => $this->n) + $this->getSignatureAppearanceArray($x, $y, $w, $h, $page);
+	}
+
+	/**
+	 * Get the array that defines the signature appearance (page and rectangle coordinates).
+	 * @param $x (float) Abscissa of the upper-left corner.
+	 * @param $y (float) Ordinate of the upper-left corner.
+	 * @param $w (float) Width of the signature area.
+	 * @param $h (float) Height of the signature area.
+	 * @param $page (int) option page number (if < 0 the current page is used).
+	 * @return (array) Array defining page and rectangle coordinates of signature appearance.
+	 * @protected
+	 * @author Nicola Asuni
+	 * @since 5.9.101 (2011-07-06)
+	 */
+	protected function getSignatureAppearanceArray($x=0, $y=0, $w=0, $h=0, $page=-1) {
+		$sigapp = array();
+		if (($page < 1) OR ($page > $this->numpages)) {
+			$sigapp['page'] = $this->page;
+		} else {
+			$sigapp['page'] = intval($page);
+		}
+		$a = $x * $this->k;
+		$b = $this->pagedim[($sigapp['page'])]['h'] - (($y + $h) * $this->k);
+		$c = $w * $this->k;
+		$d = $h * $this->k;
+		$sigapp['rect'] = sprintf('%F %F %F %F', $a, $b, ($a + $c), ($b + $d));
+		return $sigapp;
+	}
+
+	/**
+	 * Create a new page group.
+	 * NOTE: call this function before calling AddPage()
+	 * @param $page (int) starting group page (leave empty for next page).
+	 * @public
+	 * @since 3.0.000 (2008-03-27)
+	 */
+	public function startPageGroup($page='') {
+		if (empty($page)) {
+			$page = $this->page + 1;
+		}
+		$this->newpagegroup[$page] = sizeof($this->newpagegroup) + 1;
+	}
+
+	/**
+	 * This method is DEPRECATED and doesn't have any effect.
+	 * Please remove any reference to this method.
+	 * @param $s (string) Empty parameter.
+	 * @deprecated deprecated since version 5.9.089 (2011-06-13)
+	 * @public
+	 */
+	public function AliasNbPages($s='') {}
+
+	/**
+	 * This method is DEPRECATED and doesn't have any effect.
+	 * Please remove any reference to this method.
+	 * @param $s (string) Empty parameter.
+	 * @deprecated deprecated since version 5.9.089 (2011-06-13)
+	 * @public
+	 */
+	public function AliasNumPage($s='') {}
+
+	/**
+	 * Set the starting page number.
+	 * @param $num (int) Starting page number.
+	 * @since 5.9.093 (2011-06-16)
+	 * @public
+	 */
+	public function setStartingPageNumber($num=1) {
+		$this->starting_page_number = max(0, intval($num));
+	}
+
+	/**
+	 * Returns the string alias used right align page numbers.
+	 * If the current font is unicode type, the returned string wil contain an additional open curly brace.
+	 * @return string
+	 * @since 5.9.099 (2011-06-27)
+	 * @public
+	 */
+	public function getAliasRightShift() {
+		// calculate aproximatively the ratio between widths of aliases and replacements.
+		$ref = '{'.$this->alias_right_shift.'}{'.$this->alias_tot_pages.'}{'.$this->alias_num_page.'}';
+		$rep = str_repeat(' ', $this->GetNumChars($ref));
+		$wdiff = max(1, ($this->GetStringWidth($ref) / $this->GetStringWidth($rep)));
+		$sdiff = sprintf('%F', $wdiff);
+		$alias = $this->alias_right_shift.$sdiff.'}';
+		if ($this->isUnicodeFont()) {
+			$alias = '{'.$alias;
+		}
+		return $alias;
+	}
+
+	/**
+	 * Returns the string alias used for the total number of pages.
+	 * If the current font is unicode type, the returned string is surrounded by additional curly braces.
+	 * This alias will be replaced by the total number of pages in the document.
+	 * @return string
+	 * @since 4.0.018 (2008-08-08)
+	 * @public
+	 */
+	public function getAliasNbPages() {
+		if ($this->isUnicodeFont()) {
+			return '{'.$this->alias_tot_pages.'}';
+		}
+		return $this->alias_tot_pages;
+	}
+
+	/**
+	 * Returns the string alias used for the page number.
+	 * If the current font is unicode type, the returned string is surrounded by additional curly braces.
+	 * This alias will be replaced by the page number.
+	 * @return string
+	 * @since 4.5.000 (2009-01-02)
+	 * @public
+	 */
+	public function getAliasNumPage() {
+		if ($this->isUnicodeFont()) {
+			return '{'.$this->alias_num_page.'}';
+		}
+		return $this->alias_num_page;
+	}
+
+	/**
+	 * Return the alias for the total number of pages in the current page group.
+	 * If the current font is unicode type, the returned string is surrounded by additional curly braces.
+	 * This alias will be replaced by the total number of pages in this group.
+	 * @return alias of the current page group
+	 * @public
+	 * @since 3.0.000 (2008-03-27)
+	 */
+	public function getPageGroupAlias() {
+		if ($this->isUnicodeFont()) {
+			return '{'.$this->alias_group_tot_pages.'}';
+		}
+		return $this->alias_group_tot_pages;
+	}
+
+	/**
+	 * Return the alias for the page number on the current page group.
+	 * If the current font is unicode type, the returned string is surrounded by additional curly braces.
+	 * This alias will be replaced by the page number (relative to the belonging group).
+	 * @return alias of the current page group
+	 * @public
+	 * @since 4.5.000 (2009-01-02)
+	 */
+	public function getPageNumGroupAlias() {
+		if ($this->isUnicodeFont()) {
+			return '{'.$this->alias_group_num_page.'}';
+		}
+		return $this->alias_group_num_page;
+	}
+
+	/**
+	 * Return the current page in the group.
+	 * @return current page in the group
+	 * @public
+	 * @since 3.0.000 (2008-03-27)
+	 */
+	public function getGroupPageNo() {
+		return $this->pagegroups[$this->currpagegroup];
+	}
+
+	/**
+	 * Returns the current group page number formatted as a string.
+	 * @public
+	 * @since 4.3.003 (2008-11-18)
+	 * @see PaneNo(), formatPageNumber()
+	 */
+	public function getGroupPageNoFormatted() {
+		return $this->formatPageNumber($this->getGroupPageNo());
+	}
+
+	/**
+	 * Format the page numbers.
+	 * This method can be overriden for custom formats.
+	 * @param $num (int) page number
+	 * @protected
+	 * @since 4.2.005 (2008-11-06)
+	 */
+	protected function formatPageNumber($num) {
+		return number_format((float)$num, 0, '', '.');
+	}
+
+	/**
+	 * Format the page numbers on the Table Of Content.
+	 * This method can be overriden for custom formats.
+	 * @param $num (int) page number
+	 * @protected
+	 * @since 4.5.001 (2009-01-04)
+	 * @see addTOC(), addHTMLTOC()
+	 */
+	protected function formatTOCPageNumber($num) {
+		return number_format((float)$num, 0, '', '.');
+	}
+
+	/**
+	 * Returns the current page number formatted as a string.
+	 * @public
+	 * @since 4.2.005 (2008-11-06)
+	 * @see PaneNo(), formatPageNumber()
+	 */
+	public function PageNoFormatted() {
+		return $this->formatPageNumber($this->PageNo());
+	}
+
+	/**
+	 * Put pdf layers.
+	 * @protected
+	 * @since 3.0.000 (2008-03-27)
+	 */
+	protected function _putocg() {
+		if (empty($this->pdflayers)) {
+			return;
+		}
+		foreach ($this->pdflayers as $key => $layer) {
+			 $this->pdflayers[$key]['objid'] = $this->_newobj();
+			 $out = '<< /Type /OCG';
+			 $out .= ' /Name '.$this->_textstring($layer['name'], $this->pdflayers[$key]['objid']);
+			 $out .= ' /Usage <<';
+			 $out .= ' /Print <</PrintState /'.($layer['print']?'ON':'OFF').'>>';
+			 $out .= ' /View <</ViewState /'.($layer['view']?'ON':'OFF').'>>';
+			 $out .= ' >> >>';
+			 $out .= "\n".'endobj';
+			 $this->_out($out);
+		}
+	}
+
+	/**
+	 * Start a new pdf layer.
+	 * @param $name (string) Layer name (only a-z letters and numbers). Leave empty for automatic name.
+	 * @param $print (boolean) Set to true to print this layer.
+	 * @param $view (boolean) Set to true to view this layer.
+	 * @public
+	 * @since 5.9.102 (2011-07-13)
+	 */
+	public function startLayer($name='', $print=true, $view=true) {
+		if ($this->state != 2) {
+			return;
+		}
+		$layer = sprintf('LYR%03d', (count($this->pdflayers) + 1));
+		if (empty($name)) {
+			$name = $layer;
+		} else {
+			$name = preg_replace('/[^a-zA-Z0-9_\-]/', '', $name);
+		}
+		$this->pdflayers[] = array('layer' => $layer, 'name' => $name, 'print' => $print, 'view' => $view);
+		$this->openMarkedContent = true;
+		$this->_out('/OC /'.$layer.' BDC');
+	}
+
+	/**
+	 * End the current PDF layer.
+	 * @public
+	 * @since 5.9.102 (2011-07-13)
+	 */
+	public function endLayer() {
+		if ($this->state != 2) {
+			return;
+		}
+		if ($this->openMarkedContent) {
+			// close existing open marked-content layer
+			$this->_out('EMC');
+			$this->openMarkedContent = false;
+		}
+	}
+
+	/**
+	 * Set the visibility of the successive elements.
+	 * This can be useful, for instance, to put a background
+	 * image or color that will show on screen but won't print.
+	 * @param $v (string) visibility mode. Legal values are: all, print, screen or view.
+	 * @public
+	 * @since 3.0.000 (2008-03-27)
+	 */
+	public function setVisibility($v) {
+		if ($this->state != 2) {
+			return;
+		}
+		$this->endLayer();
+		switch($v) {
+			case 'print': {
+				$this->startLayer('Print', true, false);
+				break;
+			}
+			case 'view':
+			case 'screen': {
+				$this->startLayer('View', false, true);
+				break;
+			}
+			case 'all': {
+				$this->_out('');
+				break;
+			}
+			default: {
+				$this->Error('Incorrect visibility: '.$v);
+				break;
+			}
+		}
+	}
+
+	/**
+	 * Add transparency parameters to the current extgstate
+	 * @param $parms (array) parameters
+	 * @return the number of extgstates
+	 * @protected
+	 * @since 3.0.000 (2008-03-27)
+	 */
+	protected function addExtGState($parms) {
+		if ($this->pdfa_mode) {
+			// transparencies are not allowed in PDF/A mode
+			return;
+		}
+		// check if this ExtGState already exist
+		foreach ($this->extgstates as $i => $ext) {
+			if ($ext['parms'] == $parms) {
+				if ($this->inxobj) {
+					// we are inside an XObject template
+					$this->xobjects[$this->xobjid]['extgstates'][$i] = $ext;
+				}
+				// return reference to existing ExtGState
+				return $i;
+			}
+		}
+		$n = (count($this->extgstates) + 1);
+		$this->extgstates[$n] = array('parms' => $parms);
+		if ($this->inxobj) {
+			// we are inside an XObject template
+			$this->xobjects[$this->xobjid]['extgstates'][$n] = $this->extgstates[$n];
+		}
+		return $n;
+	}
+
+	/**
+	 * Add an extgstate
+	 * @param $gs (array) extgstate
+	 * @protected
+	 * @since 3.0.000 (2008-03-27)
+	 */
+	protected function setExtGState($gs) {
+		if ($this->pdfa_mode OR ($this->state != 2)) {
+			// transparency is not allowed in PDF/A mode
+			return;
+		}
+		$this->_out(sprintf('/GS%d gs', $gs));
+	}
+
+	/**
+	 * Put extgstates for object transparency
+	 * @protected
+	 * @since 3.0.000 (2008-03-27)
+	 */
+	protected function _putextgstates() {
+		foreach ($this->extgstates as $i => $ext) {
+			$this->extgstates[$i]['n'] = $this->_newobj();
+			$out = '<< /Type /ExtGState';
+			foreach ($ext['parms'] as $k => $v) {
+				if (is_float($v)) {
+					$v = sprintf('%F', $v);
+				} elseif ($v === true) {
+					$v = 'true';
+				} elseif ($v === false) {
+					$v = 'false';
+				}
+				$out .= ' /'.$k.' '.$v;
+			}
+			$out .= ' >>';
+			$out .= "\n".'endobj';
+			$this->_out($out);
+		}
+	}
+
+	/**
+	 * Set overprint mode for stroking (OP) and non-stroking (op) painting operations.
+	 * (Check the "Entries in a Graphics State Parameter Dictionary" on PDF 32000-1:2008).
+	 * @param $stroking (boolean) If true apply overprint for stroking operations.
+	 * @param $nonstroking (boolean) If true apply overprint for painting operations other than stroking.
+	 * @param $mode (integer) Overprint mode: (0 = each source colour component value replaces the value previously painted for the corresponding device colorant; 1 = a tint value of 0.0 for a source colour component shall leave the corresponding component of the previously painted colour unchanged).
+	 * @public
+	 * @since 5.9.152 (2012-03-23)
+	 */
+	public function setOverprint($stroking=true, $nonstroking='', $mode=0) {
+		if ($this->state != 2) {
+			return;
+		}
+		$stroking = $stroking ? true : false;
+		if ($this->empty_string($nonstroking)) {
+			// default value if not set
+			$nonstroking = $stroking;
+		} else {
+			$nonstroking = $nonstroking ? true : false;
+		}
+		if (($mode != 0) AND ($mode != 1)) {
+			$mode = 0;
+		}
+		$this->overprint = array('OP' => $stroking, 'op' => $nonstroking, 'OPM' => $mode);
+		$gs = $this->addExtGState($this->overprint);
+		$this->setExtGState($gs);
+	}
+
+	/**
+	 * Get the overprint mode array (OP, op, OPM).
+	 * (Check the "Entries in a Graphics State Parameter Dictionary" on PDF 32000-1:2008).
+	 * @return array.
+	 * @public
+	 * @since 5.9.152 (2012-03-23)
+	 */
+	public function getOverprint() {
+		return $this->overprint;
+	}
+
+	/**
+	 * Set alpha for stroking (CA) and non-stroking (ca) operations.
+	 * @param $stroking (float) Alpha value for stroking operations: real value from 0 (transparent) to 1 (opaque).
+	 * @param $bm (string) blend mode, one of the following: Normal, Multiply, Screen, Overlay, Darken, Lighten, ColorDodge, ColorBurn, HardLight, SoftLight, Difference, Exclusion, Hue, Saturation, Color, Luminosity
+	 * @param $nonstroking (float) Alpha value for non-stroking operations: real value from 0 (transparent) to 1 (opaque).
+	 * @param $ais (boolean)
+	 * @public
+	 * @since 3.0.000 (2008-03-27)
+	 */
+	public function setAlpha($stroking=1, $bm='Normal', $nonstroking='', $ais=false) {
+		if ($this->pdfa_mode) {
+			// transparency is not allowed in PDF/A mode
+			return;
+		}
+		$stroking = floatval($stroking);
+		if ($this->empty_string($nonstroking)) {
+			// default value if not set
+			$nonstroking = $stroking;
+		} else {
+			$nonstroking = floatval($nonstroking);
+		}
+		if ($bm[0] == '/') {
+			// remove trailing slash
+			$bm = substr($bm, 1);
+		}
+		if (!in_array($bm, array('Normal', 'Multiply', 'Screen', 'Overlay', 'Darken', 'Lighten', 'ColorDodge', 'ColorBurn', 'HardLight', 'SoftLight', 'Difference', 'Exclusion', 'Hue', 'Saturation', 'Color', 'Luminosity'))) {
+			$bm = 'Normal';
+		}
+		$ais = $ais ? true : false;
+		$this->alpha = array('CA' => $stroking, 'ca' => $nonstroking, 'BM' => '/'.$bm, 'AIS' => $ais);
+		$gs = $this->addExtGState($this->alpha);
+		$this->setExtGState($gs);
+	}
+
+	/**
+	 * Get the alpha mode array (CA, ca, BM, AIS).
+	 * (Check the "Entries in a Graphics State Parameter Dictionary" on PDF 32000-1:2008).
+	 * @return array.
+	 * @public
+	 * @since 5.9.152 (2012-03-23)
+	 */
+	public function getAlpha() {
+		return $this->alpha;
+	}
+
+	/**
+	 * Set the default JPEG compression quality (1-100)
+	 * @param $quality (int) JPEG quality, integer between 1 and 100
+	 * @public
+	 * @since 3.0.000 (2008-03-27)
+	 */
+	public function setJPEGQuality($quality) {
+		if (($quality < 1) OR ($quality > 100)) {
+			$quality = 75;
+		}
+		$this->jpeg_quality = intval($quality);
+	}
+
+	/**
+	 * Set the default number of columns in a row for HTML tables.
+	 * @param $cols (int) number of columns
+	 * @public
+	 * @since 3.0.014 (2008-06-04)
+	 */
+	public function setDefaultTableColumns($cols=4) {
+		$this->default_table_columns = intval($cols);
+	}
+
+	/**
+	 * Set the height of the cell (line height) respect the font height.
+	 * @param $h (int) cell proportion respect font height (typical value = 1.25).
+	 * @public
+	 * @since 3.0.014 (2008-06-04)
+	 */
+	public function setCellHeightRatio($h) {
+		$this->cell_height_ratio = $h;
+	}
+
+	/**
+	 * return the height of cell repect font height.
+	 * @public
+	 * @since 4.0.012 (2008-07-24)
+	 */
+	public function getCellHeightRatio() {
+		return $this->cell_height_ratio;
+	}
+
+	/**
+	 * Set the PDF version (check PDF reference for valid values).
+	 * @param $version (string) PDF document version.
+	 * @public
+	 * @since 3.1.000 (2008-06-09)
+	 */
+	public function setPDFVersion($version='1.7') {
+		if ($this->pdfa_mode) {
+			// PDF/A mode
+			$this->PDFVersion = '1.4';
+		} else {
+			$this->PDFVersion = $version;
+		}
+	}
+
+	/**
+	 * Set the viewer preferences dictionary controlling the way the document is to be presented on the screen or in print.
+	 * (see Section 8.1 of PDF reference, "Viewer Preferences").
+	 * <ul><li>HideToolbar boolean (Optional) A flag specifying whether to hide the viewer application's tool bars when the document is active. Default value: false.</li><li>HideMenubar boolean (Optional) A flag specifying whether to hide the viewer application's menu bar when the document is active. Default value: false.</li><li>HideWindowUI boolean (Optional) A flag specifying whether to hide user interface elements in the document's window (such as scroll bars and navigation controls), l [...]
+	 * @param $preferences (array) array of options.
+	 * @author Nicola Asuni
+	 * @public
+	 * @since 3.1.000 (2008-06-09)
+	 */
+	public function setViewerPreferences($preferences) {
+		$this->viewer_preferences = $preferences;
+	}
+
+	/**
+	 * Paints color transition registration bars
+	 * @param $x (float) abscissa of the top left corner of the rectangle.
+	 * @param $y (float) ordinate of the top left corner of the rectangle.
+	 * @param $w (float) width of the rectangle.
+	 * @param $h (float) height of the rectangle.
+	 * @param $transition (boolean) if true prints tcolor transitions to white.
+	 * @param $vertical (boolean) if true prints bar vertically.
+	 * @param $colors (string) colors to print, one letter per color separated by comma (for example 'A,W,R,G,B,C,M,Y,K'): A=black, W=white, R=red, G=green, B=blue, C=cyan, M=magenta, Y=yellow, K=black.
+	 * @author Nicola Asuni
+	 * @since 4.9.000 (2010-03-26)
+	 * @public
+	 */
+	public function colorRegistrationBar($x, $y, $w, $h, $transition=true, $vertical=false, $colors='A,R,G,B,C,M,Y,K') {
+		$bars = explode(',', $colors);
+		$numbars = count($bars); // number of bars to print
+		// set bar measures
+		if ($vertical) {
+			$coords = array(0, 0, 0, 1);
+			$wb = $w / $numbars; // bar width
+			$hb = $h; // bar height
+			$xd = $wb; // delta x
+			$yd = 0; // delta y
+		} else {
+			$coords = array(1, 0, 0, 0);
+			$wb = $w; // bar width
+			$hb = $h / $numbars; // bar height
+			$xd = 0; // delta x
+			$yd = $hb; // delta y
+		}
+		$xb = $x;
+		$yb = $y;
+		foreach ($bars as $col) {
+			switch ($col) {
+				// set transition colors
+				case 'A': { // BLACK
+					$col_a = array(255);
+					$col_b = array(0);
+					break;
+				}
+				case 'W': { // WHITE
+					$col_a = array(0);
+					$col_b = array(255);
+					break;
+				}
+				case 'R': { // R
+					$col_a = array(255,255,255);
+					$col_b = array(255,0,0);
+					break;
+				}
+				case 'G': { // G
+					$col_a = array(255,255,255);
+					$col_b = array(0,255,0);
+					break;
+				}
+				case 'B': { // B
+					$col_a = array(255,255,255);
+					$col_b = array(0,0,255);
+					break;
+				}
+				case 'C': { // C
+					$col_a = array(0,0,0,0);
+					$col_b = array(100,0,0,0);
+					break;
+				}
+				case 'M': { // M
+					$col_a = array(0,0,0,0);
+					$col_b = array(0,100,0,0);
+					break;
+				}
+				case 'Y': { // Y
+					$col_a = array(0,0,0,0);
+					$col_b = array(0,0,100,0);
+					break;
+				}
+				case 'K': { // K
+					$col_a = array(0,0,0,0);
+					$col_b = array(0,0,0,100);
+					break;
+				}
+				default: { // GRAY
+					$col_a = array(255);
+					$col_b = array(0);
+					break;
+				}
+			}
+			if ($transition) {
+				// color gradient
+				$this->LinearGradient($xb, $yb, $wb, $hb, $col_a, $col_b, $coords);
+			} else {
+				// color rectangle
+				$this->SetFillColorArray($col_b);
+				$this->Rect($xb, $yb, $wb, $hb, 'F', array());
+			}
+			$xb += $xd;
+			$yb += $yd;
+		}
+	}
+
+	/**
+	 * Paints crop marks.
+	 * @param $x (float) abscissa of the crop mark center.
+	 * @param $y (float) ordinate of the crop mark center.
+	 * @param $w (float) width of the crop mark.
+	 * @param $h (float) height of the crop mark.
+	 * @param $type (string) type of crop mark, one symbol per type separated by comma: T = TOP, F = BOTTOM, L = LEFT, R = RIGHT, TL = A = TOP-LEFT, TR = B = TOP-RIGHT, BL = C = BOTTOM-LEFT, BR = D = BOTTOM-RIGHT.
+	 * @param $color (array) crop mark color (default black).
+	 * @author Nicola Asuni
+	 * @since 4.9.000 (2010-03-26)
+	 * @public
+	 */
+	public function cropMark($x, $y, $w, $h, $type='T,R,B,L', $color=array(0,0,0)) {
+		$this->SetLineStyle(array('width' => (0.5 / $this->k), 'cap' => 'butt', 'join' => 'miter', 'dash' => 0, 'color' => $color));
+		$type = strtoupper($type);
+		$type = preg_replace('/[^A-Z\-\,]*/', '', $type);
+		// split type in single components
+		$type = str_replace('-', ',', $type);
+		$type = str_replace('TL', 'T,L', $type);
+		$type = str_replace('TR', 'T,R', $type);
+		$type = str_replace('BL', 'F,L', $type);
+		$type = str_replace('BR', 'F,R', $type);
+		$type = str_replace('A', 'T,L', $type);
+		$type = str_replace('B', 'T,R', $type);
+		$type = str_replace('T,RO', 'BO', $type);
+		$type = str_replace('C', 'F,L', $type);
+		$type = str_replace('D', 'F,R', $type);
+		$crops = explode(',', strtoupper($type));
+		// remove duplicates
+		$crops = array_unique($crops);
+		$dw = ($w / 4); // horizontal space to leave before the intersection point
+		$dh = ($h / 4); // vertical space to leave before the intersection point
+		foreach ($crops as $crop) {
+			switch ($crop) {
+				case 'T':
+				case 'TOP': {
+					$x1 = $x;
+					$y1 = ($y - $h);
+					$x2 = $x;
+					$y2 = ($y - $dh);
+					break;
+				}
+				case 'F':
+				case 'BOTTOM': {
+					$x1 = $x;
+					$y1 = ($y + $dh);
+					$x2 = $x;
+					$y2 = ($y + $h);
+					break;
+				}
+				case 'L':
+				case 'LEFT': {
+					$x1 = ($x - $w);
+					$y1 = $y;
+					$x2 = ($x - $dw);
+					$y2 = $y;
+					break;
+				}
+				case 'R':
+				case 'RIGHT': {
+					$x1 = ($x + $dw);
+					$y1 = $y;
+					$x2 = ($x + $w);
+					$y2 = $y;
+					break;
+				}
+			}
+			$this->Line($x1, $y1, $x2, $y2);
+		}
+	}
+
+	/**
+	 * Paints a registration mark
+	 * @param $x (float) abscissa of the registration mark center.
+	 * @param $y (float) ordinate of the registration mark center.
+	 * @param $r (float) radius of the crop mark.
+	 * @param $double (boolean) if true print two concentric crop marks.
+	 * @param $cola (array) crop mark color (default black).
+	 * @param $colb (array) second crop mark color.
+	 * @author Nicola Asuni
+	 * @since 4.9.000 (2010-03-26)
+	 * @public
+	 */
+	public function registrationMark($x, $y, $r, $double=false, $cola=array(0,0,0), $colb=array(255,255,255)) {
+		$line_style = array('width' => (0.5 / $this->k), 'cap' => 'butt', 'join' => 'miter', 'dash' => 0, 'color' => $cola);
+		$this->SetFillColorArray($cola);
+		$this->PieSector($x, $y, $r, 90, 180, 'F');
+		$this->PieSector($x, $y, $r, 270, 360, 'F');
+		$this->Circle($x, $y, $r, 0, 360, 'C', $line_style, array(), 8);
+		if ($double) {
+			$r2 = $r * 0.5;
+			$this->SetFillColorArray($colb);
+			$this->PieSector($x, $y, $r2, 90, 180, 'F');
+			$this->PieSector($x, $y, $r2, 270, 360, 'F');
+			$this->SetFillColorArray($cola);
+			$this->PieSector($x, $y, $r2, 0, 90, 'F');
+			$this->PieSector($x, $y, $r2, 180, 270, 'F');
+			$this->Circle($x, $y, $r2, 0, 360, 'C', $line_style, array(), 8);
+		}
+	}
+
+	/**
+	 * Paints a linear colour gradient.
+	 * @param $x (float) abscissa of the top left corner of the rectangle.
+	 * @param $y (float) ordinate of the top left corner of the rectangle.
+	 * @param $w (float) width of the rectangle.
+	 * @param $h (float) height of the rectangle.
+	 * @param $col1 (array) first color (Grayscale, RGB or CMYK components).
+	 * @param $col2 (array) second color (Grayscale, RGB or CMYK components).
+	 * @param $coords (array) array of the form (x1, y1, x2, y2) which defines the gradient vector (see linear_gradient_coords.jpg). The default value is from left to right (x1=0, y1=0, x2=1, y2=0).
+	 * @author Andreas W�rmser, Nicola Asuni
+	 * @since 3.1.000 (2008-06-09)
+	 * @public
+	 */
+	public function LinearGradient($x, $y, $w, $h, $col1=array(), $col2=array(), $coords=array(0,0,1,0)) {
+		$this->Clip($x, $y, $w, $h);
+		$this->Gradient(2, $coords, array(array('color' => $col1, 'offset' => 0, 'exponent' => 1), array('color' => $col2, 'offset' => 1, 'exponent' => 1)), array(), false);
+	}
+
+	/**
+	 * Paints a radial colour gradient.
+	 * @param $x (float) abscissa of the top left corner of the rectangle.
+	 * @param $y (float) ordinate of the top left corner of the rectangle.
+	 * @param $w (float) width of the rectangle.
+	 * @param $h (float) height of the rectangle.
+	 * @param $col1 (array) first color (Grayscale, RGB or CMYK components).
+	 * @param $col2 (array) second color (Grayscale, RGB or CMYK components).
+	 * @param $coords (array) array of the form (fx, fy, cx, cy, r) where (fx, fy) is the starting point of the gradient with color1, (cx, cy) is the center of the circle with color2, and r is the radius of the circle (see radial_gradient_coords.jpg). (fx, fy) should be inside the circle, otherwise some areas will not be defined.
+	 * @author Andreas W�rmser, Nicola Asuni
+	 * @since 3.1.000 (2008-06-09)
+	 * @public
+	 */
+	public function RadialGradient($x, $y, $w, $h, $col1=array(), $col2=array(), $coords=array(0.5,0.5,0.5,0.5,1)) {
+		$this->Clip($x, $y, $w, $h);
+		$this->Gradient(3, $coords, array(array('color' => $col1, 'offset' => 0, 'exponent' => 1), array('color' => $col2, 'offset' => 1, 'exponent' => 1)), array(), false);
+	}
+
+	/**
+	 * Paints a coons patch mesh.
+	 * @param $x (float) abscissa of the top left corner of the rectangle.
+	 * @param $y (float) ordinate of the top left corner of the rectangle.
+	 * @param $w (float) width of the rectangle.
+	 * @param $h (float) height of the rectangle.
+	 * @param $col1 (array) first color (lower left corner) (RGB components).
+	 * @param $col2 (array) second color (lower right corner) (RGB components).
+	 * @param $col3 (array) third color (upper right corner) (RGB components).
+	 * @param $col4 (array) fourth color (upper left corner) (RGB components).
+	 * @param $coords (array) <ul><li>for one patch mesh: array(float x1, float y1, .... float x12, float y12): 12 pairs of coordinates (normally from 0 to 1) which specify the Bezier control points that define the patch. First pair is the lower left edge point, next is its right control point (control point 2). Then the other points are defined in the order: control point 1, edge point, control point 2 going counter-clockwise around the patch. Last (x12, y12) is the first edge point's left [...]
+	 * @param $coords_min (array) minimum value used by the coordinates. If a coordinate's value is smaller than this it will be cut to coords_min. default: 0
+	 * @param $coords_max (array) maximum value used by the coordinates. If a coordinate's value is greater than this it will be cut to coords_max. default: 1
+	 * @param $antialias (boolean) A flag indicating whether to filter the shading function to prevent aliasing artifacts.
+	 * @author Andreas W�rmser, Nicola Asuni
+	 * @since 3.1.000 (2008-06-09)
+	 * @public
+	 */
+	public function CoonsPatchMesh($x, $y, $w, $h, $col1=array(), $col2=array(), $col3=array(), $col4=array(), $coords=array(0.00,0.0,0.33,0.00,0.67,0.00,1.00,0.00,1.00,0.33,1.00,0.67,1.00,1.00,0.67,1.00,0.33,1.00,0.00,1.00,0.00,0.67,0.00,0.33), $coords_min=0, $coords_max=1, $antialias=false) {
+		if ($this->pdfa_mode OR ($this->state != 2)) {
+			return;
+		}
+		$this->Clip($x, $y, $w, $h);
+		$n = count($this->gradients) + 1;
+		$this->gradients[$n] = array();
+		$this->gradients[$n]['type'] = 6; //coons patch mesh
+		$this->gradients[$n]['coords'] = array();
+		$this->gradients[$n]['antialias'] = $antialias;
+		$this->gradients[$n]['colors'] = array();
+		$this->gradients[$n]['transparency'] = false;
+		//check the coords array if it is the simple array or the multi patch array
+		if (!isset($coords[0]['f'])) {
+			//simple array -> convert to multi patch array
+			if (!isset($col1[1])) {
+				$col1[1] = $col1[2] = $col1[0];
+			}
+			if (!isset($col2[1])) {
+				$col2[1] = $col2[2] = $col2[0];
+			}
+			if (!isset($col3[1])) {
+				$col3[1] = $col3[2] = $col3[0];
+			}
+			if (!isset($col4[1])) {
+				$col4[1] = $col4[2] = $col4[0];
+			}
+			$patch_array[0]['f'] = 0;
+			$patch_array[0]['points'] = $coords;
+			$patch_array[0]['colors'][0]['r'] = $col1[0];
+			$patch_array[0]['colors'][0]['g'] = $col1[1];
+			$patch_array[0]['colors'][0]['b'] = $col1[2];
+			$patch_array[0]['colors'][1]['r'] = $col2[0];
+			$patch_array[0]['colors'][1]['g'] = $col2[1];
+			$patch_array[0]['colors'][1]['b'] = $col2[2];
+			$patch_array[0]['colors'][2]['r'] = $col3[0];
+			$patch_array[0]['colors'][2]['g'] = $col3[1];
+			$patch_array[0]['colors'][2]['b'] = $col3[2];
+			$patch_array[0]['colors'][3]['r'] = $col4[0];
+			$patch_array[0]['colors'][3]['g'] = $col4[1];
+			$patch_array[0]['colors'][3]['b'] = $col4[2];
+		} else {
+			//multi patch array
+			$patch_array = $coords;
+		}
+		$bpcd = 65535; //16 bits per coordinate
+		//build the data stream
+		$this->gradients[$n]['stream'] = '';
+		$count_patch = count($patch_array);
+		for ($i=0; $i < $count_patch; ++$i) {
+			$this->gradients[$n]['stream'] .= chr($patch_array[$i]['f']); //start with the edge flag as 8 bit
+			$count_points = count($patch_array[$i]['points']);
+			for ($j=0; $j < $count_points; ++$j) {
+				//each point as 16 bit
+				$patch_array[$i]['points'][$j] = (($patch_array[$i]['points'][$j] - $coords_min) / ($coords_max - $coords_min)) * $bpcd;
+				if ($patch_array[$i]['points'][$j] < 0) {
+					$patch_array[$i]['points'][$j] = 0;
+				}
+				if ($patch_array[$i]['points'][$j] > $bpcd) {
+					$patch_array[$i]['points'][$j] = $bpcd;
+				}
+				$this->gradients[$n]['stream'] .= chr(floor($patch_array[$i]['points'][$j] / 256));
+				$this->gradients[$n]['stream'] .= chr(floor($patch_array[$i]['points'][$j] % 256));
+			}
+			$count_cols = count($patch_array[$i]['colors']);
+			for ($j=0; $j < $count_cols; ++$j) {
+				//each color component as 8 bit
+				$this->gradients[$n]['stream'] .= chr($patch_array[$i]['colors'][$j]['r']);
+				$this->gradients[$n]['stream'] .= chr($patch_array[$i]['colors'][$j]['g']);
+				$this->gradients[$n]['stream'] .= chr($patch_array[$i]['colors'][$j]['b']);
+			}
+		}
+		//paint the gradient
+		$this->_out('/Sh'.$n.' sh');
+		//restore previous Graphic State
+		$this->_out('Q');
+		if ($this->inxobj) {
+			// we are inside an XObject template
+			$this->xobjects[$this->xobjid]['gradients'][$n] = $this->gradients[$n];
+		}
+	}
+
+	/**
+	 * Set a rectangular clipping area.
+	 * @param $x (float) abscissa of the top left corner of the rectangle (or top right corner for RTL mode).
+	 * @param $y (float) ordinate of the top left corner of the rectangle.
+	 * @param $w (float) width of the rectangle.
+	 * @param $h (float) height of the rectangle.
+	 * @author Andreas W�rmser, Nicola Asuni
+	 * @since 3.1.000 (2008-06-09)
+	 * @protected
+	 */
+	protected function Clip($x, $y, $w, $h) {
+		if ($this->state != 2) {
+			 return;
+		}
+		if ($this->rtl) {
+			$x = $this->w - $x - $w;
+		}
+		//save current Graphic State
+		$s = 'q';
+		//set clipping area
+		$s .= sprintf(' %F %F %F %F re W n', $x*$this->k, ($this->h-$y)*$this->k, $w*$this->k, -$h*$this->k);
+		//set up transformation matrix for gradient
+		$s .= sprintf(' %F 0 0 %F %F %F cm', $w*$this->k, $h*$this->k, $x*$this->k, ($this->h-($y+$h))*$this->k);
+		$this->_out($s);
+	}
+
+	/**
+	 * Output gradient.
+	 * @param $type (int) type of gradient (1 Function-based shading; 2 Axial shading; 3 Radial shading; 4 Free-form Gouraud-shaded triangle mesh; 5 Lattice-form Gouraud-shaded triangle mesh; 6 Coons patch mesh; 7 Tensor-product patch mesh). (Not all types are currently supported)
+	 * @param $coords (array) array of coordinates.
+	 * @param $stops (array) array gradient color components: color = array of GRAY, RGB or CMYK color components; offset = (0 to 1) represents a location along the gradient vector; exponent = exponent of the exponential interpolation function (default = 1).
+	 * @param $background (array) An array of colour components appropriate to the colour space, specifying a single background colour value.
+	 * @param $antialias (boolean) A flag indicating whether to filter the shading function to prevent aliasing artifacts.
+	 * @author Nicola Asuni
+	 * @since 3.1.000 (2008-06-09)
+	 * @public
+	 */
+	public function Gradient($type, $coords, $stops, $background=array(), $antialias=false) {
+		if ($this->pdfa_mode OR ($this->state != 2)) {
+			return;
+		}
+		$n = count($this->gradients) + 1;
+		$this->gradients[$n] = array();
+		$this->gradients[$n]['type'] = $type;
+		$this->gradients[$n]['coords'] = $coords;
+		$this->gradients[$n]['antialias'] = $antialias;
+		$this->gradients[$n]['colors'] = array();
+		$this->gradients[$n]['transparency'] = false;
+		// color space
+		$numcolspace = count($stops[0]['color']);
+		$bcolor = array_values($background);
+		switch($numcolspace) {
+			case 4: { // CMYK
+				$this->gradients[$n]['colspace'] = 'DeviceCMYK';
+				if (!empty($background)) {
+					$this->gradients[$n]['background'] = sprintf('%F %F %F %F', $bcolor[0]/100, $bcolor[1]/100, $bcolor[2]/100, $bcolor[3]/100);
+				}
+				break;
+			}
+			case 3: { // RGB
+				$this->gradients[$n]['colspace'] = 'DeviceRGB';
+				if (!empty($background)) {
+					$this->gradients[$n]['background'] = sprintf('%F %F %F', $bcolor[0]/255, $bcolor[1]/255, $bcolor[2]/255);
+				}
+				break;
+			}
+			case 1: { // Gray scale
+				$this->gradients[$n]['colspace'] = 'DeviceGray';
+				if (!empty($background)) {
+					$this->gradients[$n]['background'] = sprintf('%F', $bcolor[0]/255);
+				}
+				break;
+			}
+		}
+		$num_stops = count($stops);
+		$last_stop_id = $num_stops - 1;
+		foreach ($stops as $key => $stop) {
+			$this->gradients[$n]['colors'][$key] = array();
+			// offset represents a location along the gradient vector
+			if (isset($stop['offset'])) {
+				$this->gradients[$n]['colors'][$key]['offset'] = $stop['offset'];
+			} else {
+				if ($key == 0) {
+					$this->gradients[$n]['colors'][$key]['offset'] = 0;
+				} elseif ($key == $last_stop_id) {
+					$this->gradients[$n]['colors'][$key]['offset'] = 1;
+				} else {
+					$offsetstep = (1 - $this->gradients[$n]['colors'][($key - 1)]['offset']) / ($num_stops - $key);
+					$this->gradients[$n]['colors'][$key]['offset'] = $this->gradients[$n]['colors'][($key - 1)]['offset'] + $offsetstep;
+				}
+			}
+			if (isset($stop['opacity'])) {
+				$this->gradients[$n]['colors'][$key]['opacity'] = $stop['opacity'];
+				if ((!$this->pdfa_mode) AND ($stop['opacity'] < 1)) {
+					$this->gradients[$n]['transparency'] = true;
+				}
+			} else {
+				$this->gradients[$n]['colors'][$key]['opacity'] = 1;
+			}
+			// exponent for the exponential interpolation function
+			if (isset($stop['exponent'])) {
+				$this->gradients[$n]['colors'][$key]['exponent'] = $stop['exponent'];
+			} else {
+				$this->gradients[$n]['colors'][$key]['exponent'] = 1;
+			}
+			// set colors
+			$color = array_values($stop['color']);
+			switch($numcolspace) {
+				case 4: { // CMYK
+					$this->gradients[$n]['colors'][$key]['color'] = sprintf('%F %F %F %F', $color[0]/100, $color[1]/100, $color[2]/100, $color[3]/100);
+					break;
+				}
+				case 3: { // RGB
+					$this->gradients[$n]['colors'][$key]['color'] = sprintf('%F %F %F', $color[0]/255, $color[1]/255, $color[2]/255);
+					break;
+				}
+				case 1: { // Gray scale
+					$this->gradients[$n]['colors'][$key]['color'] = sprintf('%F', $color[0]/255);
+					break;
+				}
+			}
+		}
+		if ($this->gradients[$n]['transparency']) {
+			// paint luminosity gradient
+			$this->_out('/TGS'.$n.' gs');
+		}
+		//paint the gradient
+		$this->_out('/Sh'.$n.' sh');
+		//restore previous Graphic State
+		$this->_out('Q');
+		if ($this->inxobj) {
+			// we are inside an XObject template
+			$this->xobjects[$this->xobjid]['gradients'][$n] = $this->gradients[$n];
+		}
+	}
+
+	/**
+	 * Output gradient shaders.
+	 * @author Nicola Asuni
+	 * @since 3.1.000 (2008-06-09)
+	 * @protected
+	 */
+	function _putshaders() {
+		if ($this->pdfa_mode) {
+			return;
+		}
+		$idt = count($this->gradients); //index for transparency gradients
+		foreach ($this->gradients as $id => $grad) {
+			if (($grad['type'] == 2) OR ($grad['type'] == 3)) {
+				$fc = $this->_newobj();
+				$out = '<<';
+				$out .= ' /FunctionType 3';
+				$out .= ' /Domain [0 1]';
+				$functions = '';
+				$bounds = '';
+				$encode = '';
+				$i = 1;
+				$num_cols = count($grad['colors']);
+				$lastcols = $num_cols - 1;
+				for ($i = 1; $i < $num_cols; ++$i) {
+					$functions .= ($fc + $i).' 0 R ';
+					if ($i < $lastcols) {
+						$bounds .= sprintf('%F ', $grad['colors'][$i]['offset']);
+					}
+					$encode .= '0 1 ';
+				}
+				$out .= ' /Functions ['.trim($functions).']';
+				$out .= ' /Bounds ['.trim($bounds).']';
+				$out .= ' /Encode ['.trim($encode).']';
+				$out .= ' >>';
+				$out .= "\n".'endobj';
+				$this->_out($out);
+				for ($i = 1; $i < $num_cols; ++$i) {
+					$this->_newobj();
+					$out = '<<';
+					$out .= ' /FunctionType 2';
+					$out .= ' /Domain [0 1]';
+					$out .= ' /C0 ['.$grad['colors'][($i - 1)]['color'].']';
+					$out .= ' /C1 ['.$grad['colors'][$i]['color'].']';
+					$out .= ' /N '.$grad['colors'][$i]['exponent'];
+					$out .= ' >>';
+					$out .= "\n".'endobj';
+					$this->_out($out);
+				}
+				// set transparency fuctions
+				if ($grad['transparency']) {
+					$ft = $this->_newobj();
+					$out = '<<';
+					$out .= ' /FunctionType 3';
+					$out .= ' /Domain [0 1]';
+					$functions = '';
+					$i = 1;
+					$num_cols = count($grad['colors']);
+					for ($i = 1; $i < $num_cols; ++$i) {
+						$functions .= ($ft + $i).' 0 R ';
+					}
+					$out .= ' /Functions ['.trim($functions).']';
+					$out .= ' /Bounds ['.trim($bounds).']';
+					$out .= ' /Encode ['.trim($encode).']';
+					$out .= ' >>';
+					$out .= "\n".'endobj';
+					$this->_out($out);
+					for ($i = 1; $i < $num_cols; ++$i) {
+						$this->_newobj();
+						$out = '<<';
+						$out .= ' /FunctionType 2';
+						$out .= ' /Domain [0 1]';
+						$out .= ' /C0 ['.$grad['colors'][($i - 1)]['opacity'].']';
+						$out .= ' /C1 ['.$grad['colors'][$i]['opacity'].']';
+						$out .= ' /N '.$grad['colors'][$i]['exponent'];
+						$out .= ' >>';
+						$out .= "\n".'endobj';
+						$this->_out($out);
+					}
+				}
+			}
+			// set shading object
+			$this->_newobj();
+			$out = '<< /ShadingType '.$grad['type'];
+			if (isset($grad['colspace'])) {
+				$out .= ' /ColorSpace /'.$grad['colspace'];
+			} else {
+				$out .= ' /ColorSpace /DeviceRGB';
+			}
+			if (isset($grad['background']) AND !empty($grad['background'])) {
+				$out .= ' /Background ['.$grad['background'].']';
+			}
+			if (isset($grad['antialias']) AND ($grad['antialias'] === true)) {
+				$out .= ' /AntiAlias true';
+			}
+			if ($grad['type'] == 2) {
+				$out .= ' '.sprintf('/Coords [%F %F %F %F]', $grad['coords'][0], $grad['coords'][1], $grad['coords'][2], $grad['coords'][3]);
+				$out .= ' /Domain [0 1]';
+				$out .= ' /Function '.$fc.' 0 R';
+				$out .= ' /Extend [true true]';
+				$out .= ' >>';
+			} elseif ($grad['type'] == 3) {
+				//x0, y0, r0, x1, y1, r1
+				//at this this time radius of inner circle is 0
+				$out .= ' '.sprintf('/Coords [%F %F 0 %F %F %F]', $grad['coords'][0], $grad['coords'][1], $grad['coords'][2], $grad['coords'][3], $grad['coords'][4]);
+				$out .= ' /Domain [0 1]';
+				$out .= ' /Function '.$fc.' 0 R';
+				$out .= ' /Extend [true true]';
+				$out .= ' >>';
+			} elseif ($grad['type'] == 6) {
+				$out .= ' /BitsPerCoordinate 16';
+				$out .= ' /BitsPerComponent 8';
+				$out .= ' /Decode[0 1 0 1 0 1 0 1 0 1]';
+				$out .= ' /BitsPerFlag 8';
+				$stream = $this->_getrawstream($grad['stream']);
+				$out .= ' /Length '.strlen($stream);
+				$out .= ' >>';
+				$out .= ' stream'."\n".$stream."\n".'endstream';
+			}
+			$out .= "\n".'endobj';
+			$this->_out($out);
+			if ($grad['transparency']) {
+				$shading_transparency = preg_replace('/\/ColorSpace \/[^\s]+/si', '/ColorSpace /DeviceGray', $out);
+				$shading_transparency = preg_replace('/\/Function [0-9]+ /si', '/Function '.$ft.' ', $shading_transparency);
+			}
+			$this->gradients[$id]['id'] = $this->n;
+			// set pattern object
+			$this->_newobj();
+			$out = '<< /Type /Pattern /PatternType 2';
+			$out .= ' /Shading '.$this->gradients[$id]['id'].' 0 R';
+			$out .= ' >>';
+			$out .= "\n".'endobj';
+			$this->_out($out);
+			$this->gradients[$id]['pattern'] = $this->n;
+			// set shading and pattern for transparency mask
+			if ($grad['transparency']) {
+				// luminosity pattern
+				$idgs = $id + $idt;
+				$this->_newobj();
+				$this->_out($shading_transparency);
+				$this->gradients[$idgs]['id'] = $this->n;
+				$this->_newobj();
+				$out = '<< /Type /Pattern /PatternType 2';
+				$out .= ' /Shading '.$this->gradients[$idgs]['id'].' 0 R';
+				$out .= ' >>';
+				$out .= "\n".'endobj';
+				$this->_out($out);
+				$this->gradients[$idgs]['pattern'] = $this->n;
+				// luminosity XObject
+				$oid = $this->_newobj();
+				$this->xobjects['LX'.$oid] = array('n' => $oid);
+				$filter = '';
+				$stream = 'q /a0 gs /Pattern cs /p'.$idgs.' scn 0 0 '.$this->wPt.' '.$this->hPt.' re f Q';
+				if ($this->compress) {
+					$filter = ' /Filter /FlateDecode';
+					$stream = gzcompress($stream);
+				}
+				$stream = $this->_getrawstream($stream);
+				$out = '<< /Type /XObject /Subtype /Form /FormType 1'.$filter;
+				$out .= ' /Length '.strlen($stream);
+				$rect = sprintf('%F %F', $this->wPt, $this->hPt);
+				$out .= ' /BBox [0 0 '.$rect.']';
+				$out .= ' /Group << /Type /Group /S /Transparency /CS /DeviceGray >>';
+				$out .= ' /Resources <<';
+				$out .= ' /ExtGState << /a0 << /ca 1 /CA 1 >> >>';
+				$out .= ' /Pattern << /p'.$idgs.' '.$this->gradients[$idgs]['pattern'].' 0 R >>';
+				$out .= ' >>';
+				$out .= ' >> ';
+				$out .= ' stream'."\n".$stream."\n".'endstream';
+				$out .= "\n".'endobj';
+				$this->_out($out);
+				// SMask
+				$this->_newobj();
+				$out = '<< /Type /Mask /S /Luminosity /G '.($this->n - 1).' 0 R >>'."\n".'endobj';
+				$this->_out($out);
+				// ExtGState
+				$this->_newobj();
+				$out = '<< /Type /ExtGState /SMask '.($this->n - 1).' 0 R /AIS false >>'."\n".'endobj';
+				$this->_out($out);
+				$this->extgstates[] = array('n' => $this->n, 'name' => 'TGS'.$id);
+			}
+		}
+	}
+
+	/**
+	 * Draw the sector of a circle.
+	 * It can be used for instance to render pie charts.
+	 * @param $xc (float) abscissa of the center.
+	 * @param $yc (float) ordinate of the center.
+	 * @param $r (float) radius.
+	 * @param $a (float) start angle (in degrees).
+	 * @param $b (float) end angle (in degrees).
+	 * @param $style (string) Style of rendering. See the getPathPaintOperator() function for more information.
+	 * @param $cw: (float) indicates whether to go clockwise (default: true).
+	 * @param $o: (float) origin of angles (0 for 3 o'clock, 90 for noon, 180 for 9 o'clock, 270 for 6 o'clock). Default: 90.
+	 * @author Maxime Delorme, Nicola Asuni
+	 * @since 3.1.000 (2008-06-09)
+	 * @public
+	 */
+	public function PieSector($xc, $yc, $r, $a, $b, $style='FD', $cw=true, $o=90) {
+		$this->PieSectorXY($xc, $yc, $r, $r, $a, $b, $style, $cw, $o);
+	}
+
+	/**
+	 * Draw the sector of an ellipse.
+	 * It can be used for instance to render pie charts.
+	 * @param $xc (float) abscissa of the center.
+	 * @param $yc (float) ordinate of the center.
+	 * @param $rx (float) the x-axis radius.
+	 * @param $ry (float) the y-axis radius.
+	 * @param $a (float) start angle (in degrees).
+	 * @param $b (float) end angle (in degrees).
+	 * @param $style (string) Style of rendering. See the getPathPaintOperator() function for more information.
+	 * @param $cw: (float) indicates whether to go clockwise.
+	 * @param $o: (float) origin of angles (0 for 3 o'clock, 90 for noon, 180 for 9 o'clock, 270 for 6 o'clock).
+	 * @param $nc (integer) Number of curves used to draw a 90 degrees portion of arc.
+	 * @author Maxime Delorme, Nicola Asuni
+	 * @since 3.1.000 (2008-06-09)
+	 * @public
+	 */
+	public function PieSectorXY($xc, $yc, $rx, $ry, $a, $b, $style='FD', $cw=false, $o=0, $nc=2) {
+		if ($this->state != 2) {
+			 return;
+		}
+		if ($this->rtl) {
+			$xc = ($this->w - $xc);
+		}
+		$op = $this->getPathPaintOperator($style);
+		if ($op == 'f') {
+			$line_style = array();
+		}
+		if ($cw) {
+			$d = $b;
+			$b = (360 - $a + $o);
+			$a = (360 - $d + $o);
+		} else {
+			$b += $o;
+			$a += $o;
+		}
+		$this->_outellipticalarc($xc, $yc, $rx, $ry, 0, $a, $b, true, $nc);
+		$this->_out($op);
+	}
+
+	/**
+	 * Embed vector-based Adobe Illustrator (AI) or AI-compatible EPS files.
+	 * NOTE: EPS is not yet fully implemented, use the setRasterizeVectorImages() method to enable/disable rasterization of vector images using ImageMagick library.
+	 * Only vector drawing is supported, not text or bitmap.
+	 * Although the script was successfully tested with various AI format versions, best results are probably achieved with files that were exported in the AI3 format (tested with Illustrator CS2, Freehand MX and Photoshop CS2).
+	 * @param $file (string) Name of the file containing the image or a '@' character followed by the EPS/AI data string.
+	 * @param $x (float) Abscissa of the upper-left corner.
+	 * @param $y (float) Ordinate of the upper-left corner.
+	 * @param $w (float) Width of the image in the page. If not specified or equal to zero, it is automatically calculated.
+	 * @param $h (float) Height of the image in the page. If not specified or equal to zero, it is automatically calculated.
+	 * @param $link (mixed) URL or identifier returned by AddLink().
+	 * @param $useBoundingBox (boolean) specifies whether to position the bounding box (true) or the complete canvas (false) at location (x,y). Default value is true.
+	 * @param $align (string) Indicates the alignment of the pointer next to image insertion relative to image height. The value can be:<ul><li>T: top-right for LTR or top-left for RTL</li><li>M: middle-right for LTR or middle-left for RTL</li><li>B: bottom-right for LTR or bottom-left for RTL</li><li>N: next line</li></ul>
+	 * @param $palign (string) Allows to center or align the image on the current line. Possible values are:<ul><li>L : left align</li><li>C : center</li><li>R : right align</li><li>'' : empty string : left for LTR or right for RTL</li></ul>
+	 * @param $border (mixed) Indicates if borders must be drawn around the cell. The value can be a number:<ul><li>0: no border (default)</li><li>1: frame</li></ul> or a string containing some or all of the following characters (in any order):<ul><li>L: left</li><li>T: top</li><li>R: right</li><li>B: bottom</li></ul> or an array of line styles for each border group - for example: array('LTRB' => array('width' => 2, 'cap' => 'butt', 'join' => 'miter', 'dash' => 0, 'color' => array(0, 0, 0)))
+	 * @param $fitonpage (boolean) if true the image is resized to not exceed page dimensions.
+	 * @param $fixoutvals (boolean) if true remove values outside the bounding box.
+	 * @author Valentin Schmidt, Nicola Asuni
+	 * @since 3.1.000 (2008-06-09)
+	 * @public
+	 */
+	public function ImageEps($file, $x='', $y='', $w=0, $h=0, $link='', $useBoundingBox=true, $align='', $palign='', $border=0, $fitonpage=false, $fixoutvals=false) {
+		if ($this->state != 2) {
+			 return;
+		}
+		if ($this->rasterize_vector_images AND ($w > 0) AND ($h > 0)) {
+			// convert EPS to raster image using GD or ImageMagick libraries
+			return $this->Image($file, $x, $y, $w, $h, 'EPS', $link, $align, true, 300, $palign, false, false, $border, false, false, $fitonpage);
+		}
+		if ($x === '') {
+			$x = $this->x;
+		}
+		if ($y === '') {
+			$y = $this->y;
+		}
+		// check page for no-write regions and adapt page margins if necessary
+		list($x, $y) = $this->checkPageRegions($h, $x, $y);
+		$k = $this->k;
+		if ($file{0} === '@') { // image from string
+			$data = substr($file, 1);
+		} else { // EPS/AI file
+			$data = file_get_contents($file);
+		}
+		if ($data === false) {
+			$this->Error('EPS file not found: '.$file);
+		}
+		$regs = array();
+		// EPS/AI compatibility check (only checks files created by Adobe Illustrator!)
+		preg_match("/%%Creator:([^\r\n]+)/", $data, $regs); # find Creator
+		if (count($regs) > 1) {
+			$version_str = trim($regs[1]); # e.g. "Adobe Illustrator(R) 8.0"
+			if (strpos($version_str, 'Adobe Illustrator') !== false) {
+				$versexp = explode(' ', $version_str);
+				$version = (float)array_pop($versexp);
+				if ($version >= 9) {
+					$this->Error('This version of Adobe Illustrator file is not supported: '.$file);
+				}
+			}
+		}
+		// strip binary bytes in front of PS-header
+		$start = strpos($data, '%!PS-Adobe');
+		if ($start > 0) {
+			$data = substr($data, $start);
+		}
+		// find BoundingBox params
+		preg_match("/%%BoundingBox:([^\r\n]+)/", $data, $regs);
+		if (count($regs) > 1) {
+			list($x1, $y1, $x2, $y2) = explode(' ', trim($regs[1]));
+		} else {
+			$this->Error('No BoundingBox found in EPS/AI file: '.$file);
+		}
+		$start = strpos($data, '%%EndSetup');
+		if ($start === false) {
+			$start = strpos($data, '%%EndProlog');
+		}
+		if ($start === false) {
+			$start = strpos($data, '%%BoundingBox');
+		}
+		$data = substr($data, $start);
+		$end = strpos($data, '%%PageTrailer');
+		if ($end===false) {
+			$end = strpos($data, 'showpage');
+		}
+		if ($end) {
+			$data = substr($data, 0, $end);
+		}
+		// calculate image width and height on document
+		if (($w <= 0) AND ($h <= 0)) {
+			$w = ($x2 - $x1) / $k;
+			$h = ($y2 - $y1) / $k;
+		} elseif ($w <= 0) {
+			$w = ($x2-$x1) / $k * ($h / (($y2 - $y1) / $k));
+		} elseif ($h <= 0) {
+			$h = ($y2 - $y1) / $k * ($w / (($x2 - $x1) / $k));
+		}
+		// fit the image on available space
+		list($w, $h, $x, $y) = $this->fitBlock($w, $h, $x, $y, $fitonpage);
+		if ($this->rasterize_vector_images) {
+			// convert EPS to raster image using GD or ImageMagick libraries
+			return $this->Image($file, $x, $y, $w, $h, 'EPS', $link, $align, true, 300, $palign, false, false, $border, false, false, $fitonpage);
+		}
+		// set scaling factors
+		$scale_x = $w / (($x2 - $x1) / $k);
+		$scale_y = $h / (($y2 - $y1) / $k);
+		// set alignment
+		$this->img_rb_y = $y + $h;
+		// set alignment
+		if ($this->rtl) {
+			if ($palign == 'L') {
+				$ximg = $this->lMargin;
+			} elseif ($palign == 'C') {
+				$ximg = ($this->w + $this->lMargin - $this->rMargin - $w) / 2;
+			} elseif ($palign == 'R') {
+				$ximg = $this->w - $this->rMargin - $w;
+			} else {
+				$ximg = $x - $w;
+			}
+			$this->img_rb_x = $ximg;
+		} else {
+			if ($palign == 'L') {
+				$ximg = $this->lMargin;
+			} elseif ($palign == 'C') {
+				$ximg = ($this->w + $this->lMargin - $this->rMargin - $w) / 2;
+			} elseif ($palign == 'R') {
+				$ximg = $this->w - $this->rMargin - $w;
+			} else {
+				$ximg = $x;
+			}
+			$this->img_rb_x = $ximg + $w;
+		}
+		if ($useBoundingBox) {
+			$dx = $ximg * $k - $x1;
+			$dy = $y * $k - $y1;
+		} else {
+			$dx = $ximg * $k;
+			$dy = $y * $k;
+		}
+		// save the current graphic state
+		$this->_out('q'.$this->epsmarker);
+		// translate
+		$this->_out(sprintf('%F %F %F %F %F %F cm', 1, 0, 0, 1, $dx, $dy + ($this->hPt - (2 * $y * $k) - ($y2 - $y1))));
+		// scale
+		if (isset($scale_x)) {
+			$this->_out(sprintf('%F %F %F %F %F %F cm', $scale_x, 0, 0, $scale_y, $x1 * (1 - $scale_x), $y2 * (1 - $scale_y)));
+		}
+		// handle pc/unix/mac line endings
+		$lines = preg_split('/[\r\n]+/si', $data, -1, PREG_SPLIT_NO_EMPTY);
+		$u=0;
+		$cnt = count($lines);
+		for ($i=0; $i < $cnt; ++$i) {
+			$line = $lines[$i];
+			if (($line == '') OR ($line{0} == '%')) {
+				continue;
+			}
+			$len = strlen($line);
+			// check for spot color names
+			$color_name = '';
+			if (strcasecmp('x', substr(trim($line), -1)) == 0) {
+				if (preg_match('/\([^\)]*\)/', $line, $matches) > 0) {
+					// extract spot color name
+					$color_name = $matches[0];
+					// remove color name from string
+					$line = str_replace(' '.$color_name, '', $line);
+					// remove pharentesis from color name
+					$color_name = substr($color_name, 1, -1);
+				}
+			}
+			$chunks = explode(' ', $line);
+			$cmd = trim(array_pop($chunks));
+			// RGB
+			if (($cmd == 'Xa') OR ($cmd == 'XA')) {
+				$b = array_pop($chunks);
+				$g = array_pop($chunks);
+				$r = array_pop($chunks);
+				$this->_out(''.$r.' '.$g.' '.$b.' '.($cmd=='Xa'?'rg':'RG')); //substr($line, 0, -2).'rg' -> in EPS (AI8): c m y k r g b rg!
+				continue;
+			}
+			$skip = false;
+			if ($fixoutvals) {
+				// check for values outside the bounding box
+				switch ($cmd) {
+					case 'm':
+					case 'l':
+					case 'L': {
+						// skip values outside bounding box
+						foreach ($chunks as $key => $val) {
+							if ((($key % 2) == 0) AND (($val < $x1) OR ($val > $x2))) {
+								$skip = true;
+							} elseif ((($key % 2) != 0) AND (($val < $y1) OR ($val > $y2))) {
+								$skip = true;
+							}
+						}
+					}
+				}
+			}
+			switch ($cmd) {
+				case 'm':
+				case 'l':
+				case 'v':
+				case 'y':
+				case 'c':
+				case 'k':
+				case 'K':
+				case 'g':
+				case 'G':
+				case 's':
+				case 'S':
+				case 'J':
+				case 'j':
+				case 'w':
+				case 'M':
+				case 'd':
+				case 'n': {
+					if ($skip) {
+						break;
+					}
+					$this->_out($line);
+					break;
+				}
+				case 'x': {// custom fill color
+					if (empty($color_name)) {
+						// CMYK color
+						list($col_c, $col_m, $col_y, $col_k) = $chunks;
+						$this->_out(''.$col_c.' '.$col_m.' '.$col_y.' '.$col_k.' k');
+					} else {
+						// Spot Color (CMYK + tint)
+						list($col_c, $col_m, $col_y, $col_k, $col_t) = $chunks;
+						$this->AddSpotColor($color_name, ($col_c * 100), ($col_m * 100), ($col_y * 100), ($col_k * 100));
+						$color_cmd = sprintf('/CS%d cs %F scn', $this->spot_colors[$color_name]['i'], (1 - $col_t));
+						$this->_out($color_cmd);
+					}
+					break;
+				}
+				case 'X': { // custom stroke color
+					if (empty($color_name)) {
+						// CMYK color
+						list($col_c, $col_m, $col_y, $col_k) = $chunks;
+						$this->_out(''.$col_c.' '.$col_m.' '.$col_y.' '.$col_k.' K');
+					} else {
+						// Spot Color (CMYK + tint)
+						list($col_c, $col_m, $col_y, $col_k, $col_t) = $chunks;
+						$this->AddSpotColor($color_name, ($col_c * 100), ($col_m * 100), ($col_y * 100), ($col_k * 100));
+						$color_cmd = sprintf('/CS%d CS %F SCN', $this->spot_colors[$color_name]['i'], (1 - $col_t));
+						$this->_out($color_cmd);
+					}
+					break;
+				}
+				case 'Y':
+				case 'N':
+				case 'V':
+				case 'L':
+				case 'C': {
+					if ($skip) {
+						break;
+					}
+					$line[($len - 1)] = strtolower($cmd);
+					$this->_out($line);
+					break;
+				}
+				case 'b':
+				case 'B': {
+					$this->_out($cmd . '*');
+					break;
+				}
+				case 'f':
+				case 'F': {
+					if ($u > 0) {
+						$isU = false;
+						$max = min(($i + 5), $cnt);
+						for ($j = ($i + 1); $j < $max; ++$j) {
+							$isU = ($isU OR (($lines[$j] == 'U') OR ($lines[$j] == '*U')));
+						}
+						if ($isU) {
+							$this->_out('f*');
+						}
+					} else {
+						$this->_out('f*');
+					}
+					break;
+				}
+				case '*u': {
+					++$u;
+					break;
+				}
+				case '*U': {
+					--$u;
+					break;
+				}
+			}
+		}
+		// restore previous graphic state
+		$this->_out($this->epsmarker.'Q');
+		if (!empty($border)) {
+			$bx = $this->x;
+			$by = $this->y;
+			$this->x = $ximg;
+			if ($this->rtl) {
+				$this->x += $w;
+			}
+			$this->y = $y;
+			$this->Cell($w, $h, '', $border, 0, '', 0, '', 0, true);
+			$this->x = $bx;
+			$this->y = $by;
+		}
+		if ($link) {
+			$this->Link($ximg, $y, $w, $h, $link, 0);
+		}
+		// set pointer to align the next text/objects
+		switch($align) {
+			case 'T':{
+				$this->y = $y;
+				$this->x = $this->img_rb_x;
+				break;
+			}
+			case 'M':{
+				$this->y = $y + round($h/2);
+				$this->x = $this->img_rb_x;
+				break;
+			}
+			case 'B':{
+				$this->y = $this->img_rb_y;
+				$this->x = $this->img_rb_x;
+				break;
+			}
+			case 'N':{
+				$this->SetY($this->img_rb_y);
+				break;
+			}
+			default:{
+				break;
+			}
+		}
+		$this->endlinex = $this->img_rb_x;
+	}
+
+	/**
+	 * Set document barcode.
+	 * @param $bc (string) barcode
+	 * @public
+	 */
+	public function setBarcode($bc='') {
+		$this->barcode = $bc;
+	}
+
+	/**
+	 * Get current barcode.
+	 * @return string
+	 * @public
+	 * @since 4.0.012 (2008-07-24)
+	 */
+	public function getBarcode() {
+		return $this->barcode;
+	}
+
+	/**
+	 * Print a Linear Barcode.
+	 * @param $code (string) code to print
+	 * @param $type (string) type of barcode (see barcodes.php for supported formats).
+	 * @param $x (int) x position in user units (empty string = current x position)
+	 * @param $y (int) y position in user units (empty string = current y position)
+	 * @param $w (int) width in user units (empty string = remaining page width)
+	 * @param $h (int) height in user units (empty string = remaining page height)
+	 * @param $xres (float) width of the smallest bar in user units (empty string = default value = 0.4mm)
+	 * @param $style (array) array of options:<ul>
+	 * <li>boolean $style['border'] if true prints a border</li>
+	 * <li>int $style['padding'] padding to leave around the barcode in user units (set to 'auto' for automatic padding)</li>
+	 * <li>int $style['hpadding'] horizontal padding in user units (set to 'auto' for automatic padding)</li>
+	 * <li>int $style['vpadding'] vertical padding in user units (set to 'auto' for automatic padding)</li>
+	 * <li>array $style['fgcolor'] color array for bars and text</li>
+	 * <li>mixed $style['bgcolor'] color array for background (set to false for transparent)</li>
+	 * <li>boolean $style['text'] if true prints text below the barcode</li>
+	 * <li>string $style['label'] override default label</li>
+	 * <li>string $style['font'] font name for text</li><li>int $style['fontsize'] font size for text</li>
+	 * <li>int $style['stretchtext']: 0 = disabled; 1 = horizontal scaling only if necessary; 2 = forced horizontal scaling; 3 = character spacing only if necessary; 4 = forced character spacing.</li>
+	 * <li>string $style['position'] horizontal position of the containing barcode cell on the page: L = left margin; C = center; R = right margin.</li>
+	 * <li>string $style['align'] horizontal position of the barcode on the containing rectangle: L = left; C = center; R = right.</li>
+	 * <li>string $style['stretch'] if true stretch the barcode to best fit the available width, otherwise uses $xres resolution for a single bar.</li>
+	 * <li>string $style['fitwidth'] if true reduce the width to fit the barcode width + padding. When this option is enabled the 'stretch' option is automatically disabled.</li>
+	 * <li>string $style['cellfitalign'] this option works only when 'fitwidth' is true and 'position' is unset or empty. Set the horizontal position of the containing barcode cell inside the specified rectangle: L = left; C = center; R = right.</li></ul>
+	 * @param $align (string) Indicates the alignment of the pointer next to barcode insertion relative to barcode height. The value can be:<ul><li>T: top-right for LTR or top-left for RTL</li><li>M: middle-right for LTR or middle-left for RTL</li><li>B: bottom-right for LTR or bottom-left for RTL</li><li>N: next line</li></ul>
+	 * @author Nicola Asuni
+	 * @since 3.1.000 (2008-06-09)
+	 * @public
+	 */
+	public function write1DBarcode($code, $type, $x='', $y='', $w='', $h='', $xres='', $style='', $align='') {
+		if ($this->empty_string(trim($code))) {
+			return;
+		}
+		require_once(dirname(__FILE__).'/barcodes.php');
+		// save current graphic settings
+		$gvars = $this->getGraphicVars();
+		// create new barcode object
+		$barcodeobj = new TCPDFBarcode($code, $type);
+		$arrcode = $barcodeobj->getBarcodeArray();
+		if (($arrcode === false) OR empty($arrcode) OR ($arrcode['maxw'] == 0)) {
+			$this->Error('Error in 1D barcode string');
+		}
+		// set default values
+		if (!isset($style['position'])) {
+			$style['position'] = '';
+		} elseif ($style['position'] == 'S') {
+			// keep this for backward compatibility
+			$style['position'] = '';
+			$style['stretch'] = true;
+		}
+		if (!isset($style['fitwidth'])) {
+			if (!isset($style['stretch'])) {
+				$style['fitwidth'] = true;
+			} else {
+				$style['fitwidth'] = false;
+			}
+		}
+		if ($style['fitwidth']) {
+			// disable stretch
+			$style['stretch'] = false;
+		}
+		if (!isset($style['stretch'])) {
+			if (($w === '') OR ($w <= 0)) {
+				$style['stretch'] = false;
+			} else {
+				$style['stretch'] = true;
+			}
+		}
+		if (!isset($style['fgcolor'])) {
+			$style['fgcolor'] = array(0,0,0); // default black
+		}
+		if (!isset($style['bgcolor'])) {
+			$style['bgcolor'] = false; // default transparent
+		}
+		if (!isset($style['border'])) {
+			$style['border'] = false;
+		}
+		$fontsize = 0;
+		if (!isset($style['text'])) {
+			$style['text'] = false;
+		}
+		if ($style['text'] AND isset($style['font'])) {
+			if (isset($style['fontsize'])) {
+				$fontsize = $style['fontsize'];
+			}
+			$this->SetFont($style['font'], '', $fontsize);
+		}
+		if (!isset($style['stretchtext'])) {
+			$style['stretchtext'] = 4;
+		}
+		if ($x === '') {
+			$x = $this->x;
+		}
+		if ($y === '') {
+			$y = $this->y;
+		}
+		// check page for no-write regions and adapt page margins if necessary
+		list($x, $y) = $this->checkPageRegions($h, $x, $y);
+		if (($w === '') OR ($w <= 0)) {
+			if ($this->rtl) {
+				$w = $x - $this->lMargin;
+			} else {
+				$w = $this->w - $this->rMargin - $x;
+			}
+		}
+		// padding
+		if (!isset($style['padding'])) {
+			$padding = 0;
+		} elseif ($style['padding'] === 'auto') {
+			$padding = 10 * ($w / ($arrcode['maxw'] + 20));
+		} else {
+			$padding = floatval($style['padding']);
+		}
+		// horizontal padding
+		if (!isset($style['hpadding'])) {
+			$hpadding = $padding;
+		} elseif ($style['hpadding'] === 'auto') {
+			$hpadding = 10 * ($w / ($arrcode['maxw'] + 20));
+		} else {
+			$hpadding = floatval($style['hpadding']);
+		}
+		// vertical padding
+		if (!isset($style['vpadding'])) {
+			$vpadding = $padding;
+		} elseif ($style['vpadding'] === 'auto') {
+			$vpadding = ($hpadding / 2);
+		} else {
+			$vpadding = floatval($style['vpadding']);
+		}
+		// calculate xres (single bar width)
+		$max_xres = ($w - (2 * $hpadding)) / $arrcode['maxw'];
+		if ($style['stretch']) {
+			$xres = $max_xres;
+		} else {
+			if ($this->empty_string($xres)) {
+				$xres = (0.141 * $this->k); // default bar width = 0.4 mm
+			}
+			if ($xres > $max_xres) {
+				// correct xres to fit on $w
+				$xres = $max_xres;
+			}
+			if ((isset($style['padding']) AND ($style['padding'] === 'auto'))
+				OR (isset($style['hpadding']) AND ($style['hpadding'] === 'auto'))) {
+				$hpadding = 10 * $xres;
+				if (isset($style['vpadding']) AND ($style['vpadding'] === 'auto')) {
+					$vpadding = ($hpadding / 2);
+				}
+			}
+		}
+		if ($style['fitwidth']) {
+			$wold = $w;
+			$w = (($arrcode['maxw'] * $xres) + (2 * $hpadding));
+			if (isset($style['cellfitalign'])) {
+				switch ($style['cellfitalign']) {
+					case 'L': {
+						if ($this->rtl) {
+							$x -= ($wold - $w);
+						}
+						break;
+					}
+					case 'R': {
+						if (!$this->rtl) {
+							$x += ($wold - $w);
+						}
+						break;
+					}
+					case 'C': {
+						if ($this->rtl) {
+							$x -= (($wold - $w) / 2);
+						} else {
+							$x += (($wold - $w) / 2);
+						}
+						break;
+					}
+					default : {
+						break;
+					}
+				}
+			}
+		}
+		$text_height = ($this->cell_height_ratio * $fontsize / $this->k);
+		// height
+		if (($h === '') OR ($h <= 0)) {
+			// set default height
+			$h = (($arrcode['maxw'] * $xres) / 3) + (2 * $vpadding) + $text_height;
+		}
+		$barh = $h - $text_height - (2 * $vpadding);
+		if ($barh <=0) {
+			// try to reduce font or padding to fit barcode on available height
+			if ($text_height > $h) {
+				$fontsize = (($h * $this->k) / (4 * $this->cell_height_ratio));
+				$text_height = ($this->cell_height_ratio * $fontsize / $this->k);
+				$this->SetFont($style['font'], '', $fontsize);
+			}
+			if ($vpadding > 0) {
+				$vpadding = (($h - $text_height) / 4);
+			}
+			$barh = $h - $text_height - (2 * $vpadding);
+		}
+		// fit the barcode on available space
+		list($w, $h, $x, $y) = $this->fitBlock($w, $h, $x, $y, false);
+		// set alignment
+		$this->img_rb_y = $y + $h;
+		// set alignment
+		if ($this->rtl) {
+			if ($style['position'] == 'L') {
+				$xpos = $this->lMargin;
+			} elseif ($style['position'] == 'C') {
+				$xpos = ($this->w + $this->lMargin - $this->rMargin - $w) / 2;
+			} elseif ($style['position'] == 'R') {
+				$xpos = $this->w - $this->rMargin - $w;
+			} else {
+				$xpos = $x - $w;
+			}
+			$this->img_rb_x = $xpos;
+		} else {
+			if ($style['position'] == 'L') {
+				$xpos = $this->lMargin;
+			} elseif ($style['position'] == 'C') {
+				$xpos = ($this->w + $this->lMargin - $this->rMargin - $w) / 2;
+			} elseif ($style['position'] == 'R') {
+				$xpos = $this->w - $this->rMargin - $w;
+			} else {
+				$xpos = $x;
+			}
+			$this->img_rb_x = $xpos + $w;
+		}
+		$xpos_rect = $xpos;
+		if (!isset($style['align'])) {
+			$style['align'] = 'C';
+		}
+		switch ($style['align']) {
+			case 'L': {
+				$xpos = $xpos_rect + $hpadding;
+				break;
+			}
+			case 'R': {
+				$xpos = $xpos_rect + ($w - ($arrcode['maxw'] * $xres)) - $hpadding;
+				break;
+			}
+			case 'C':
+			default : {
+				$xpos = $xpos_rect + (($w - ($arrcode['maxw'] * $xres)) / 2);
+				break;
+			}
+		}
+		$xpos_text = $xpos;
+		// barcode is always printed in LTR direction
+		$tempRTL = $this->rtl;
+		$this->rtl = false;
+		// print background color
+		if ($style['bgcolor']) {
+			$this->Rect($xpos_rect, $y, $w, $h, $style['border'] ? 'DF' : 'F', '', $style['bgcolor']);
+		} elseif ($style['border']) {
+			$this->Rect($xpos_rect, $y, $w, $h, 'D');
+		}
+		// set foreground color
+		$this->SetDrawColorArray($style['fgcolor']);
+		$this->SetTextColorArray($style['fgcolor']);
+		// print bars
+		foreach ($arrcode['bcode'] as $k => $v) {
+			$bw = ($v['w'] * $xres);
+			if ($v['t']) {
+				// draw a vertical bar
+				$ypos = $y + $vpadding + ($v['p'] * $barh / $arrcode['maxh']);
+				$this->Rect($xpos, $ypos, $bw, ($v['h'] * $barh / $arrcode['maxh']), 'F', array(), $style['fgcolor']);
+			}
+			$xpos += $bw;
+		}
+		// print text
+		if ($style['text']) {
+			if (isset($style['label']) AND !$this->empty_string($style['label'])) {
+				$label = $style['label'];
+			} else {
+				$label = $code;
+			}
+			$txtwidth = ($arrcode['maxw'] * $xres);
+			if ($this->GetStringWidth($label) > $txtwidth) {
+				$style['stretchtext'] = 2;
+			}
+			// print text
+			$this->x = $xpos_text;
+			$this->y = $y + $vpadding + $barh;
+			$cellpadding = $this->cell_padding;
+			$this->SetCellPadding(0);
+			$this->Cell($txtwidth, '', $label, 0, 0, 'C', false, '', $style['stretchtext'], false, 'T', 'T');
+			$this->cell_padding = $cellpadding;
+		}
+		// restore original direction
+		$this->rtl = $tempRTL;
+		// restore previous settings
+		$this->setGraphicVars($gvars);
+		// set pointer to align the next text/objects
+		switch($align) {
+			case 'T':{
+				$this->y = $y;
+				$this->x = $this->img_rb_x;
+				break;
+			}
+			case 'M':{
+				$this->y = $y + round($h / 2);
+				$this->x = $this->img_rb_x;
+				break;
+			}
+			case 'B':{
+				$this->y = $this->img_rb_y;
+				$this->x = $this->img_rb_x;
+				break;
+			}
+			case 'N':{
+				$this->SetY($this->img_rb_y);
+				break;
+			}
+			default:{
+				break;
+			}
+		}
+		$this->endlinex = $this->img_rb_x;
+	}
+
+	/**
+	 * This function is DEPRECATED, please use the new write1DBarcode() function.
+	 * @param $x (int) x position in user units
+	 * @param $y (int) y position in user units
+	 * @param $w (int) width in user units
+	 * @param $h (int) height position in user units
+	 * @param $type (string) type of barcode
+	 * @param $style (string) barcode style
+	 * @param $font (string) font for text
+	 * @param $xres (int) x resolution
+	 * @param $code (string) code to print
+	 * @deprecated deprecated since version 3.1.000 (2008-06-10)
+	 * @public
+	 * @see write1DBarcode()
+	 */
+	public function writeBarcode($x, $y, $w, $h, $type, $style, $font, $xres, $code) {
+		// convert old settings for the new write1DBarcode() function.
+		$xres = 1 / $xres;
+		$newstyle = array(
+			'position' => '',
+			'align' => '',
+			'stretch' => false,
+			'fitwidth' => false,
+			'cellfitalign' => '',
+			'border' => false,
+			'padding' => 0,
+			'fgcolor' => array(0,0,0),
+			'bgcolor' => false,
+			'text' => true,
+			'font' => $font,
+			'fontsize' => 8,
+			'stretchtext' => 4
+		);
+		if ($style & 1) {
+			$newstyle['border'] = true;
+		}
+		if ($style & 2) {
+			$newstyle['bgcolor'] = false;
+		}
+		if ($style & 4) {
+			$newstyle['position'] = 'C';
+		} elseif ($style & 8) {
+			$newstyle['position'] = 'L';
+		} elseif ($style & 16) {
+			$newstyle['position'] = 'R';
+		}
+		if ($style & 128) {
+			$newstyle['text'] = true;
+		}
+		if ($style & 256) {
+			$newstyle['stretchtext'] = 4;
+		}
+		$this->write1DBarcode($code, $type, $x, $y, $w, $h, $xres, $newstyle, '');
+	}
+
+	/**
+	 * Print 2D Barcode.
+	 * @param $code (string) code to print
+	 * @param $type (string) type of barcode (see 2dbarcodes.php for supported formats).
+	 * @param $x (int) x position in user units
+	 * @param $y (int) y position in user units
+	 * @param $w (int) width in user units
+	 * @param $h (int) height in user units
+	 * @param $style (array) array of options:<ul>
+	 * <li>boolean $style['border'] if true prints a border around the barcode</li>
+	 * <li>int $style['padding'] padding to leave around the barcode in barcode units (set to 'auto' for automatic padding)</li>
+	 * <li>int $style['hpadding'] horizontal padding in barcode units (set to 'auto' for automatic padding)</li>
+	 * <li>int $style['vpadding'] vertical padding in barcode units (set to 'auto' for automatic padding)</li>
+	 * <li>int $style['module_width'] width of a single module in points</li>
+	 * <li>int $style['module_height'] height of a single module in points</li>
+	 * <li>array $style['fgcolor'] color array for bars and text</li>
+	 * <li>mixed $style['bgcolor'] color array for background or false for transparent</li>
+	 * <li>string $style['position'] barcode position on the page: L = left margin; C = center; R = right margin; S = stretch</li><li>$style['module_width'] width of a single module in points</li>
+	 * <li>$style['module_height'] height of a single module in points</li></ul>
+	 * @param $align (string) Indicates the alignment of the pointer next to barcode insertion relative to barcode height. The value can be:<ul><li>T: top-right for LTR or top-left for RTL</li><li>M: middle-right for LTR or middle-left for RTL</li><li>B: bottom-right for LTR or bottom-left for RTL</li><li>N: next line</li></ul>
+	 * @param $distort (boolean) if true distort the barcode to fit width and height, otherwise preserve aspect ratio
+	 * @author Nicola Asuni
+	 * @since 4.5.037 (2009-04-07)
+	 * @public
+	 */
+	public function write2DBarcode($code, $type, $x='', $y='', $w='', $h='', $style='', $align='', $distort=false) {
+		if ($this->empty_string(trim($code))) {
+			return;
+		}
+		require_once(dirname(__FILE__).'/2dbarcodes.php');
+		// save current graphic settings
+		$gvars = $this->getGraphicVars();
+		// create new barcode object
+		$barcodeobj = new TCPDF2DBarcode($code, $type);
+		$arrcode = $barcodeobj->getBarcodeArray();
+		if (($arrcode === false) OR empty($arrcode) OR !isset($arrcode['num_rows']) OR ($arrcode['num_rows'] == 0) OR !isset($arrcode['num_cols']) OR ($arrcode['num_cols'] == 0)) {
+			$this->Error('Error in 2D barcode string');
+		}
+		// set default values
+		if (!isset($style['position'])) {
+			$style['position'] = '';
+		}
+		if (!isset($style['fgcolor'])) {
+			$style['fgcolor'] = array(0,0,0); // default black
+		}
+		if (!isset($style['bgcolor'])) {
+			$style['bgcolor'] = false; // default transparent
+		}
+		if (!isset($style['border'])) {
+			$style['border'] = false;
+		}
+		// padding
+		if (!isset($style['padding'])) {
+			$style['padding'] = 0;
+		} elseif ($style['padding'] === 'auto') {
+			$style['padding'] = 4;
+		}
+		if (!isset($style['hpadding'])) {
+			$style['hpadding'] = $style['padding'];
+		} elseif ($style['hpadding'] === 'auto') {
+			$style['hpadding'] = 4;
+		}
+		if (!isset($style['vpadding'])) {
+			$style['vpadding'] = $style['padding'];
+		} elseif ($style['vpadding'] === 'auto') {
+			$style['vpadding'] = 4;
+		}
+		$hpad = (2 * $style['hpadding']);
+		$vpad = (2 * $style['vpadding']);
+		// cell (module) dimension
+		if (!isset($style['module_width'])) {
+			$style['module_width'] = 1; // width of a single module in points
+		}
+		if (!isset($style['module_height'])) {
+			$style['module_height'] = 1; // height of a single module in points
+		}
+		if ($x === '') {
+			$x = $this->x;
+		}
+		if ($y === '') {
+			$y = $this->y;
+		}
+		// check page for no-write regions and adapt page margins if necessary
+		list($x, $y) = $this->checkPageRegions($h, $x, $y);
+		// number of barcode columns and rows
+		$rows = $arrcode['num_rows'];
+		$cols = $arrcode['num_cols'];
+		// module width and height
+		$mw = $style['module_width'];
+		$mh = $style['module_height'];
+		if (($mw == 0) OR ($mh == 0)) {
+			$this->Error('Error in 2D barcode string');
+		}
+		// get max dimensions
+		if ($this->rtl) {
+			$maxw = $x - $this->lMargin;
+		} else {
+			$maxw = $this->w - $this->rMargin - $x;
+		}
+		$maxh = ($this->h - $this->tMargin - $this->bMargin);
+		$ratioHW = ((($rows * $mh) + $hpad) / (($cols * $mw) + $vpad));
+		$ratioWH = ((($cols * $mw) + $vpad) / (($rows * $mh) + $hpad));
+		if (!$distort) {
+			if (($maxw * $ratioHW) > $maxh) {
+				$maxw = $maxh * $ratioWH;
+			}
+			if (($maxh * $ratioWH) > $maxw) {
+				$maxh = $maxw * $ratioHW;
+			}
+		}
+		// set maximum dimesions
+		if ($w > $maxw) {
+			$w = $maxw;
+		}
+		if ($h > $maxh) {
+			$h = $maxh;
+		}
+		// set dimensions
+		if ((($w === '') OR ($w <= 0)) AND (($h === '') OR ($h <= 0))) {
+			$w = ($cols + $hpad) * ($mw / $this->k);
+			$h = ($rows + $vpad) * ($mh / $this->k);
+		} elseif (($w === '') OR ($w <= 0)) {
+			$w = $h * $ratioWH;
+		} elseif (($h === '') OR ($h <= 0)) {
+			$h = $w * $ratioHW;
+		}
+		// barcode size (excluding padding)
+		$bw = ($w * $cols) / ($cols + $hpad);
+		$bh = ($h * $rows) / ($rows + $vpad);
+		// dimension of single barcode cell unit
+		$cw = $bw / $cols;
+		$ch = $bh / $rows;
+		if (!$distort) {
+			if (($cw / $ch) > ($mw / $mh)) {
+				// correct horizontal distortion
+				$cw = $ch * $mw / $mh;
+				$bw = $cw * $cols;
+				$style['hpadding'] = ($w - $bw) / (2 * $cw);
+			} else {
+				// correct vertical distortion
+				$ch = $cw * $mh / $mw;
+				$bh = $ch * $rows;
+				$style['vpadding'] = ($h - $bh) / (2 * $ch);
+			}
+		}
+		// fit the barcode on available space
+		list($w, $h, $x, $y) = $this->fitBlock($w, $h, $x, $y, false);
+		// set alignment
+		$this->img_rb_y = $y + $h;
+		// set alignment
+		if ($this->rtl) {
+			if ($style['position'] == 'L') {
+				$xpos = $this->lMargin;
+			} elseif ($style['position'] == 'C') {
+				$xpos = ($this->w + $this->lMargin - $this->rMargin - $w) / 2;
+			} elseif ($style['position'] == 'R') {
+				$xpos = $this->w - $this->rMargin - $w;
+			} else {
+				$xpos = $x - $w;
+			}
+			$this->img_rb_x = $xpos;
+		} else {
+			if ($style['position'] == 'L') {
+				$xpos = $this->lMargin;
+			} elseif ($style['position'] == 'C') {
+				$xpos = ($this->w + $this->lMargin - $this->rMargin - $w) / 2;
+			} elseif ($style['position'] == 'R') {
+				$xpos = $this->w - $this->rMargin - $w;
+			} else {
+				$xpos = $x;
+			}
+			$this->img_rb_x = $xpos + $w;
+		}
+		$xstart = $xpos + ($style['hpadding'] * $cw);
+		$ystart = $y + ($style['vpadding'] * $ch);
+		// barcode is always printed in LTR direction
+		$tempRTL = $this->rtl;
+		$this->rtl = false;
+		// print background color
+		if ($style['bgcolor']) {
+			$this->Rect($xpos, $y, $w, $h, $style['border'] ? 'DF' : 'F', '', $style['bgcolor']);
+		} elseif ($style['border']) {
+			$this->Rect($xpos, $y, $w, $h, 'D');
+		}
+		// set foreground color
+		$this->SetDrawColorArray($style['fgcolor']);
+		// print barcode cells
+		// for each row
+		for ($r = 0; $r < $rows; ++$r) {
+			$xr = $xstart;
+			// for each column
+			for ($c = 0; $c < $cols; ++$c) {
+				if ($arrcode['bcode'][$r][$c] == 1) {
+					// draw a single barcode cell
+					$this->Rect($xr, $ystart, $cw, $ch, 'F', array(), $style['fgcolor']);
+				}
+				$xr += $cw;
+			}
+			$ystart += $ch;
+		}
+		// restore original direction
+		$this->rtl = $tempRTL;
+		// restore previous settings
+		$this->setGraphicVars($gvars);
+		// set pointer to align the next text/objects
+		switch($align) {
+			case 'T':{
+				$this->y = $y;
+				$this->x = $this->img_rb_x;
+				break;
+			}
+			case 'M':{
+				$this->y = $y + round($h/2);
+				$this->x = $this->img_rb_x;
+				break;
+			}
+			case 'B':{
+				$this->y = $this->img_rb_y;
+				$this->x = $this->img_rb_x;
+				break;
+			}
+			case 'N':{
+				$this->SetY($this->img_rb_y);
+				break;
+			}
+			default:{
+				break;
+			}
+		}
+		$this->endlinex = $this->img_rb_x;
+	}
+
+	/**
+	 * Returns an array containing current margins:
+	 * <ul>
+			<li>$ret['left'] = left margin</li>
+			<li>$ret['right'] = right margin</li>
+			<li>$ret['top'] = top margin</li>
+			<li>$ret['bottom'] = bottom margin</li>
+			<li>$ret['header'] = header margin</li>
+			<li>$ret['footer'] = footer margin</li>
+			<li>$ret['cell'] = cell padding array</li>
+			<li>$ret['padding_left'] = cell left padding</li>
+			<li>$ret['padding_top'] = cell top padding</li>
+			<li>$ret['padding_right'] = cell right padding</li>
+			<li>$ret['padding_bottom'] = cell bottom padding</li>
+	 * </ul>
+	 * @return array containing all margins measures
+	 * @public
+	 * @since 3.2.000 (2008-06-23)
+	 */
+	public function getMargins() {
+		$ret = array(
+			'left' => $this->lMargin,
+			'right' => $this->rMargin,
+			'top' => $this->tMargin,
+			'bottom' => $this->bMargin,
+			'header' => $this->header_margin,
+			'footer' => $this->footer_margin,
+			'cell' => $this->cell_padding,
+			'padding_left' => $this->cell_padding['L'],
+			'padding_top' => $this->cell_padding['T'],
+			'padding_right' => $this->cell_padding['R'],
+			'padding_bottom' => $this->cell_padding['B']
+		);
+		return $ret;
+	}
+
+	/**
+	 * Returns an array containing original margins:
+	 * <ul>
+			<li>$ret['left'] = left margin</li>
+			<li>$ret['right'] = right margin</li>
+	 * </ul>
+	 * @return array containing all margins measures
+	 * @public
+	 * @since 4.0.012 (2008-07-24)
+	 */
+	public function getOriginalMargins() {
+		$ret = array(
+			'left' => $this->original_lMargin,
+			'right' => $this->original_rMargin
+		);
+		return $ret;
+	}
+
+	/**
+	 * Returns the current font size.
+	 * @return current font size
+	 * @public
+	 * @since 3.2.000 (2008-06-23)
+	 */
+	public function getFontSize() {
+		return $this->FontSize;
+	}
+
+	/**
+	 * Returns the current font size in points unit.
+	 * @return current font size in points unit
+	 * @public
+	 * @since 3.2.000 (2008-06-23)
+	 */
+	public function getFontSizePt() {
+		return $this->FontSizePt;
+	}
+
+	/**
+	 * Returns the current font family name.
+	 * @return string current font family name
+	 * @public
+	 * @since 4.3.008 (2008-12-05)
+	 */
+	public function getFontFamily() {
+		return $this->FontFamily;
+	}
+
+	/**
+	 * Returns the current font style.
+	 * @return string current font style
+	 * @public
+	 * @since 4.3.008 (2008-12-05)
+	 */
+	public function getFontStyle() {
+		return $this->FontStyle;
+	}
+
+	/**
+	 * Cleanup HTML code (requires HTML Tidy library).
+	 * @param $html (string) htmlcode to fix
+	 * @param $default_css (string) CSS commands to add
+	 * @param $tagvs (array) parameters for setHtmlVSpace method
+	 * @param $tidy_options (array) options for tidy_parse_string function
+	 * @return string XHTML code cleaned up
+	 * @author Nicola Asuni
+	 * @public
+	 * @since 5.9.017 (2010-11-16)
+	 * @see setHtmlVSpace()
+	 */
+	public function fixHTMLCode($html, $default_css='', $tagvs='', $tidy_options='') {
+		// configure parameters for HTML Tidy
+		if ($tidy_options === '') {
+			$tidy_options = array (
+				'clean' => 1,
+				'drop-empty-paras' => 0,
+				'drop-proprietary-attributes' => 1,
+				'fix-backslash' => 1,
+				'hide-comments' => 1,
+				'join-styles' => 1,
+				'lower-literals' => 1,
+				'merge-divs' => 1,
+				'merge-spans' => 1,
+				'output-xhtml' => 1,
+				'word-2000' => 1,
+				'wrap' => 0,
+				'output-bom' => 0,
+				//'char-encoding' => 'utf8',
+				//'input-encoding' => 'utf8',
+				//'output-encoding' => 'utf8'
+			);
+		}
+		// clean up the HTML code
+		$tidy = tidy_parse_string($html, $tidy_options);
+		// fix the HTML
+		$tidy->cleanRepair();
+		// get the CSS part
+		$tidy_head = tidy_get_head($tidy);
+		$css = $tidy_head->value;
+		$css = preg_replace('/<style([^>]+)>/ims', '<style>', $css);
+		$css = preg_replace('/<\/style>(.*)<style>/ims', "\n", $css);
+		$css = str_replace('/*<![CDATA[*/', '', $css);
+		$css = str_replace('/*]]>*/', '', $css);
+		preg_match('/<style>(.*)<\/style>/ims', $css, $matches);
+		if (isset($matches[1])) {
+			$css = strtolower($matches[1]);
+		} else {
+			$css = '';
+		}
+		// include default css
+		$css = '<style>'.$default_css.$css.'</style>';
+		// get the body part
+		$tidy_body = tidy_get_body($tidy);
+		$html = $tidy_body->value;
+		// fix some self-closing tags
+		$html = str_replace('<br>', '<br />', $html);
+		// remove some empty tag blocks
+		$html = preg_replace('/<div([^\>]*)><\/div>/', '', $html);
+		$html = preg_replace('/<p([^\>]*)><\/p>/', '', $html);
+		if ($tagvs !== '') {
+			// set vertical space for some XHTML tags
+			$this->setHtmlVSpace($tagvs);
+		}
+		// return the cleaned XHTML code + CSS
+		return $css.$html;
+	}
+
+	/**
+	 * Extracts the CSS properties from a CSS string.
+	 * @param $cssdata (string) string containing CSS definitions.
+	 * @return An array where the keys are the CSS selectors and the values are the CSS properties.
+	 * @author Nicola Asuni
+	 * @since 5.1.000 (2010-05-25)
+	 * @protected
+	 */
+	protected function extractCSSproperties($cssdata) {
+		if (empty($cssdata)) {
+			return array();
+		}
+		// remove comments
+		$cssdata = preg_replace('/\/\*[^\*]*\*\//', '', $cssdata);
+		// remove newlines and multiple spaces
+		$cssdata = preg_replace('/[\s]+/', ' ', $cssdata);
+		// remove some spaces
+		$cssdata = preg_replace('/[\s]*([;:\{\}]{1})[\s]*/', '\\1', $cssdata);
+		// remove empty blocks
+		$cssdata = preg_replace('/([^\}\{]+)\{\}/', '', $cssdata);
+		// replace media type parenthesis
+		$cssdata = preg_replace('/@media[\s]+([^\{]*)\{/i', '@media \\1�', $cssdata);
+		$cssdata = preg_replace('/\}\}/si', '}�', $cssdata);
+		// trim string
+		$cssdata = trim($cssdata);
+		// find media blocks (all, braille, embossed, handheld, print, projection, screen, speech, tty, tv)
+		$cssblocks = array();
+		$matches = array();
+		if (preg_match_all('/@media[\s]+([^\�]*)�([^�]*)�/i', $cssdata, $matches) > 0) {
+			foreach ($matches[1] as $key => $type) {
+				$cssblocks[$type] = $matches[2][$key];
+			}
+			// remove media blocks
+			$cssdata = preg_replace('/@media[\s]+([^\�]*)�([^�]*)�/i', '', $cssdata);
+		}
+		// keep 'all' and 'print' media, other media types are discarded
+		if (isset($cssblocks['all']) AND !empty($cssblocks['all'])) {
+			$cssdata .= $cssblocks['all'];
+		}
+		if (isset($cssblocks['print']) AND !empty($cssblocks['print'])) {
+			$cssdata .= $cssblocks['print'];
+		}
+		// reset css blocks array
+		$cssblocks = array();
+		$matches = array();
+		// explode css data string into array
+		if (substr($cssdata, -1) == '}') {
+			// remove last parethesis
+			$cssdata = substr($cssdata, 0, -1);
+		}
+		$matches = explode('}', $cssdata);
+		foreach ($matches as $key => $block) {
+			// index 0 contains the CSS selector, index 1 contains CSS properties
+			$cssblocks[$key] = explode('{', $block);
+			if (!isset($cssblocks[$key][1])) {
+				// remove empty definitions
+				unset($cssblocks[$key]);
+			}
+		}
+		// split groups of selectors (comma-separated list of selectors)
+		foreach ($cssblocks as $key => $block) {
+			if (strpos($block[0], ',') > 0) {
+				$selectors = explode(',', $block[0]);
+				foreach ($selectors as $sel) {
+					$cssblocks[] = array(0 => trim($sel), 1 => $block[1]);
+				}
+				unset($cssblocks[$key]);
+			}
+		}
+		// covert array to selector => properties
+		$cssdata = array();
+		foreach ($cssblocks as $block) {
+			$selector = $block[0];
+			// calculate selector's specificity
+			$matches = array();
+			$a = 0; // the declaration is not from is a 'style' attribute
+			$b = intval(preg_match_all('/[\#]/', $selector, $matches)); // number of ID attributes
+			$c = intval(preg_match_all('/[\[\.]/', $selector, $matches)); // number of other attributes
+			$c += intval(preg_match_all('/[\:]link|visited|hover|active|focus|target|lang|enabled|disabled|checked|indeterminate|root|nth|first|last|only|empty|contains|not/i', $selector, $matches)); // number of pseudo-classes
+			$d = intval(preg_match_all('/[\>\+\~\s]{1}[a-zA-Z0-9]+/', ' '.$selector, $matches)); // number of element names
+			$d += intval(preg_match_all('/[\:][\:]/', $selector, $matches)); // number of pseudo-elements
+			$specificity = $a.$b.$c.$d;
+			// add specificity to the beginning of the selector
+			$cssdata[$specificity.' '.$selector] = $block[1];
+		}
+		// sort selectors alphabetically to account for specificity
+		ksort($cssdata, SORT_STRING);
+		// return array
+		return $cssdata;
+	}
+
+	/**
+	 * Returns true if the CSS selector is valid for the selected HTML tag
+	 * @param $dom (array) array of HTML tags and properties
+	 * @param $key (int) key of the current HTML tag
+	 * @param $selector (string) CSS selector string
+	 * @return true if the selector is valid, false otherwise
+	 * @protected
+	 * @since 5.1.000 (2010-05-25)
+	 */
+	protected function isValidCSSSelectorForTag($dom, $key, $selector) {
+		$valid = false; // value to be returned
+		$tag = $dom[$key]['value'];
+		$class = array();
+		if (isset($dom[$key]['attribute']['class']) AND !empty($dom[$key]['attribute']['class'])) {
+			$class = explode(' ', strtolower($dom[$key]['attribute']['class']));
+		}
+		$id = '';
+		if (isset($dom[$key]['attribute']['id']) AND !empty($dom[$key]['attribute']['id'])) {
+			$id = strtolower($dom[$key]['attribute']['id']);
+		}
+		$selector = preg_replace('/([\>\+\~\s]{1})([\.]{1})([^\>\+\~\s]*)/si', '\\1*.\\3', $selector);
+		$matches = array();
+		if (preg_match_all('/([\>\+\~\s]{1})([a-zA-Z0-9\*]+)([^\>\+\~\s]*)/si', $selector, $matches, PREG_PATTERN_ORDER | PREG_OFFSET_CAPTURE) > 0) {
+			$parentop = array_pop($matches[1]);
+			$operator = $parentop[0];
+			$offset = $parentop[1];
+			$lasttag = array_pop($matches[2]);
+			$lasttag = strtolower(trim($lasttag[0]));
+			if (($lasttag == '*') OR ($lasttag == $tag)) {
+				// the last element on selector is our tag or 'any tag'
+				$attrib = array_pop($matches[3]);
+				$attrib = strtolower(trim($attrib[0]));
+				if (!empty($attrib)) {
+					// check if matches class, id, attribute, pseudo-class or pseudo-element
+					switch ($attrib{0}) {
+						case '.': { // class
+							if (in_array(substr($attrib, 1), $class)) {
+								$valid = true;
+							}
+							break;
+						}
+						case '#': { // ID
+							if (substr($attrib, 1) == $id) {
+								$valid = true;
+							}
+							break;
+						}
+						case '[': { // attribute
+							$attrmatch = array();
+							if (preg_match('/\[([a-zA-Z0-9]*)[\s]*([\~\^\$\*\|\=]*)[\s]*["]?([^"\]]*)["]?\]/i', $attrib, $attrmatch) > 0) {
+								$att = strtolower($attrmatch[1]);
+								$val = $attrmatch[3];
+								if (isset($dom[$key]['attribute'][$att])) {
+									switch ($attrmatch[2]) {
+										case '=': {
+											if ($dom[$key]['attribute'][$att] == $val) {
+												$valid = true;
+											}
+											break;
+										}
+										case '~=': {
+											if (in_array($val, explode(' ', $dom[$key]['attribute'][$att]))) {
+												$valid = true;
+											}
+											break;
+										}
+										case '^=': {
+											if ($val == substr($dom[$key]['attribute'][$att], 0, strlen($val))) {
+												$valid = true;
+											}
+											break;
+										}
+										case '$=': {
+											if ($val == substr($dom[$key]['attribute'][$att], -strlen($val))) {
+												$valid = true;
+											}
+											break;
+										}
+										case '*=': {
+											if (strpos($dom[$key]['attribute'][$att], $val) !== false) {
+												$valid = true;
+											}
+											break;
+										}
+										case '|=': {
+											if ($dom[$key]['attribute'][$att] == $val) {
+												$valid = true;
+											} elseif (preg_match('/'.$val.'[\-]{1}/i', $dom[$key]['attribute'][$att]) > 0) {
+												$valid = true;
+											}
+											break;
+										}
+										default: {
+											$valid = true;
+										}
+									}
+								}
+							}
+							break;
+						}
+						case ':': { // pseudo-class or pseudo-element
+							if ($attrib{1} == ':') { // pseudo-element
+								// pseudo-elements are not supported!
+								// (::first-line, ::first-letter, ::before, ::after)
+							} else { // pseudo-class
+								// pseudo-classes are not supported!
+								// (:root, :nth-child(n), :nth-last-child(n), :nth-of-type(n), :nth-last-of-type(n), :first-child, :last-child, :first-of-type, :last-of-type, :only-child, :only-of-type, :empty, :link, :visited, :active, :hover, :focus, :target, :lang(fr), :enabled, :disabled, :checked)
+							}
+							break;
+						}
+					} // end of switch
+				} else {
+					$valid = true;
+				}
+				if ($valid AND ($offset > 0)) {
+					$valid = false;
+					// check remaining selector part
+					$selector = substr($selector, 0, $offset);
+					switch ($operator) {
+						case ' ': { // descendant of an element
+							while ($dom[$key]['parent'] > 0) {
+								if ($this->isValidCSSSelectorForTag($dom, $dom[$key]['parent'], $selector)) {
+									$valid = true;
+									break;
+								} else {
+									$key = $dom[$key]['parent'];
+								}
+							}
+							break;
+						}
+						case '>': { // child of an element
+							$valid = $this->isValidCSSSelectorForTag($dom, $dom[$key]['parent'], $selector);
+							break;
+						}
+						case '+': { // immediately preceded by an element
+							for ($i = ($key - 1); $i > $dom[$key]['parent']; --$i) {
+								if ($dom[$i]['tag'] AND $dom[$i]['opening']) {
+									$valid = $this->isValidCSSSelectorForTag($dom, $i, $selector);
+									break;
+								}
+							}
+							break;
+						}
+						case '~': { // preceded by an element
+							for ($i = ($key - 1); $i > $dom[$key]['parent']; --$i) {
+								if ($dom[$i]['tag'] AND $dom[$i]['opening']) {
+									if ($this->isValidCSSSelectorForTag($dom, $i, $selector)) {
+										break;
+									}
+								}
+							}
+							break;
+						}
+					}
+				}
+			}
+		}
+		return $valid;
+	}
+
+	/**
+	 * Returns the styles array that apply for the selected HTML tag.
+	 * @param $dom (array) array of HTML tags and properties
+	 * @param $key (int) key of the current HTML tag
+	 * @param $css (array) array of CSS properties
+	 * @return array containing CSS properties
+	 * @protected
+	 * @since 5.1.000 (2010-05-25)
+	 */
+	protected function getCSSdataArray($dom, $key, $css) {
+		$cssarray = array(); // style to be returned
+		// get parent CSS selectors
+		$selectors = array();
+		if (isset($dom[($dom[$key]['parent'])]['csssel'])) {
+			$selectors = $dom[($dom[$key]['parent'])]['csssel'];
+		}
+		// get all styles that apply
+		foreach($css as $selector => $style) {
+			$pos = strpos($selector, ' ');
+			// get specificity
+			$specificity = substr($selector, 0, $pos);
+			// remove specificity
+			$selector = substr($selector, $pos);
+			// check if this selector apply to current tag
+			if ($this->isValidCSSSelectorForTag($dom, $key, $selector)) {
+				if (!in_array($selector, $selectors)) {
+					// add style if not already added on parent selector
+					$cssarray[] = array('k' => $selector, 's' => $specificity, 'c' => $style);
+					$selectors[] = $selector;
+				}
+			}
+		}
+		if (isset($dom[$key]['attribute']['style'])) {
+			// attach inline style (latest properties have high priority)
+			$cssarray[] = array('k' => '', 's' => '1000', 'c' => $dom[$key]['attribute']['style']);
+		}
+		// order the css array to account for specificity
+		$cssordered = array();
+		foreach ($cssarray as $key => $val) {
+			$skey = sprintf('%04d', $key);
+			$cssordered[$val['s'].'_'.$skey] = $val;
+		}
+		// sort selectors alphabetically to account for specificity
+		ksort($cssordered, SORT_STRING);
+		return array($selectors, $cssordered);
+	}
+
+	/**
+	 * Compact CSS data array into single string.
+	 * @param $css (array) array of CSS properties
+	 * @return string containing merged CSS properties
+	 * @protected
+	 * @since 5.9.070 (2011-04-19)
+	 */
+	protected function getTagStyleFromCSSarray($css) {
+		$tagstyle = ''; // value to be returned
+		foreach ($css as $style) {
+			// split single css commands
+			$csscmds = explode(';', $style['c']);
+			foreach ($csscmds as $cmd) {
+				if (!empty($cmd)) {
+					$pos = strpos($cmd, ':');
+					if ($pos !== false) {
+						$cmd = substr($cmd, 0, ($pos + 1));
+						if (strpos($tagstyle, $cmd) !== false) {
+							// remove duplicate commands (last commands have high priority)
+							$tagstyle = preg_replace('/'.$cmd.'[^;]+/i', '', $tagstyle);
+						}
+					}
+				}
+			}
+			$tagstyle .= ';'.$style['c'];
+		}
+		// remove multiple semicolons
+		$tagstyle = preg_replace('/[;]+/', ';', $tagstyle);
+		return $tagstyle;
+	}
+
+	/**
+	 * Returns the border width from CSS property
+	 * @param $width (string) border width
+	 * @return int with in user units
+	 * @protected
+	 * @since 5.7.000 (2010-08-02)
+	 */
+	protected function getCSSBorderWidth($width) {
+		if ($width == 'thin') {
+			$width = (2 / $this->k);
+		} elseif ($width == 'medium') {
+			$width = (4 / $this->k);
+		} elseif ($width == 'thick') {
+			$width = (6 / $this->k);
+		} else {
+			$width = $this->getHTMLUnitToUnits($width, 1, 'px', false);
+		}
+		return $width;
+	}
+
+	/**
+	 * Returns the border dash style from CSS property
+	 * @param $style (string) border style to convert
+	 * @return int sash style (return -1 in case of none or hidden border)
+	 * @protected
+	 * @since 5.7.000 (2010-08-02)
+	 */
+	protected function getCSSBorderDashStyle($style) {
+		switch (strtolower($style)) {
+			case 'none':
+			case 'hidden': {
+				$dash = -1;
+				break;
+			}
+			case 'dotted': {
+				$dash = 1;
+				break;
+			}
+			case 'dashed': {
+				$dash = 3;
+				break;
+			}
+			case 'double':
+			case 'groove':
+			case 'ridge':
+			case 'inset':
+			case 'outset':
+			case 'solid':
+			default: {
+				$dash = 0;
+				break;
+			}
+		}
+		return $dash;
+	}
+
+	/**
+	 * Returns the border style array from CSS border properties
+	 * @param $cssborder (string) border properties
+	 * @return array containing border properties
+	 * @protected
+	 * @since 5.7.000 (2010-08-02)
+	 */
+	protected function getCSSBorderStyle($cssborder) {
+		$bprop = preg_split('/[\s]+/', trim($cssborder));
+		$border = array(); // value to be returned
+		switch (count($bprop)) {
+			case 3: {
+				$width = $bprop[0];
+				$style = $bprop[1];
+				$color = $bprop[2];
+				break;
+			}
+			case 2: {
+				$width = 'medium';
+				$style = $bprop[0];
+				$color = $bprop[1];
+				break;
+			}
+			case 1: {
+				$width = 'medium';
+				$style = $bprop[0];
+				$color = 'black';
+				break;
+			}
+			default: {
+				$width = 'medium';
+				$style = 'solid';
+				$color = 'black';
+				break;
+			}
+		}
+		if ($style == 'none') {
+			return array();
+		}
+		$border['cap'] = 'square';
+		$border['join'] = 'miter';
+		$border['dash'] = $this->getCSSBorderDashStyle($style);
+		if ($border['dash'] < 0) {
+			return array();
+		}
+		$border['width'] = $this->getCSSBorderWidth($width);
+		$border['color'] = $this->convertHTMLColorToDec($color);
+		return $border;
+	}
+
+	/**
+	 * Get the internal Cell padding from CSS attribute.
+	 * @param $csspadding (string) padding properties
+	 * @param $width (float) width of the containing element
+	 * @return array of cell paddings
+	 * @public
+	 * @since 5.9.000 (2010-10-04)
+	 */
+	public function getCSSPadding($csspadding, $width=0) {
+		$padding = preg_split('/[\s]+/', trim($csspadding));
+		$cell_padding = array(); // value to be returned
+		switch (count($padding)) {
+			case 4: {
+				$cell_padding['T'] = $padding[0];
+				$cell_padding['R'] = $padding[1];
+				$cell_padding['B'] = $padding[2];
+				$cell_padding['L'] = $padding[3];
+				break;
+			}
+			case 3: {
+				$cell_padding['T'] = $padding[0];
+				$cell_padding['R'] = $padding[1];
+				$cell_padding['B'] = $padding[2];
+				$cell_padding['L'] = $padding[1];
+				break;
+			}
+			case 2: {
+				$cell_padding['T'] = $padding[0];
+				$cell_padding['R'] = $padding[1];
+				$cell_padding['B'] = $padding[0];
+				$cell_padding['L'] = $padding[1];
+				break;
+			}
+			case 1: {
+				$cell_padding['T'] = $padding[0];
+				$cell_padding['R'] = $padding[0];
+				$cell_padding['B'] = $padding[0];
+				$cell_padding['L'] = $padding[0];
+				break;
+			}
+			default: {
+				return $this->cell_padding;
+			}
+		}
+		if ($width == 0) {
+			$width = $this->w - $this->lMargin - $this->rMargin;
+		}
+		$cell_padding['T'] = $this->getHTMLUnitToUnits($cell_padding['T'], $width, 'px', false);
+		$cell_padding['R'] = $this->getHTMLUnitToUnits($cell_padding['R'], $width, 'px', false);
+		$cell_padding['B'] = $this->getHTMLUnitToUnits($cell_padding['B'], $width, 'px', false);
+		$cell_padding['L'] = $this->getHTMLUnitToUnits($cell_padding['L'], $width, 'px', false);
+		return $cell_padding;
+	}
+
+	/**
+	 * Get the internal Cell margin from CSS attribute.
+	 * @param $cssmargin (string) margin properties
+	 * @param $width (float) width of the containing element
+	 * @return array of cell margins
+	 * @public
+	 * @since 5.9.000 (2010-10-04)
+	 */
+	public function getCSSMargin($cssmargin, $width=0) {
+		$margin = preg_split('/[\s]+/', trim($cssmargin));
+		$cell_margin = array(); // value to be returned
+		switch (count($margin)) {
+			case 4: {
+				$cell_margin['T'] = $margin[0];
+				$cell_margin['R'] = $margin[1];
+				$cell_margin['B'] = $margin[2];
+				$cell_margin['L'] = $margin[3];
+				break;
+			}
+			case 3: {
+				$cell_margin['T'] = $margin[0];
+				$cell_margin['R'] = $margin[1];
+				$cell_margin['B'] = $margin[2];
+				$cell_margin['L'] = $margin[1];
+				break;
+			}
+			case 2: {
+				$cell_margin['T'] = $margin[0];
+				$cell_margin['R'] = $margin[1];
+				$cell_margin['B'] = $margin[0];
+				$cell_margin['L'] = $margin[1];
+				break;
+			}
+			case 1: {
+				$cell_margin['T'] = $margin[0];
+				$cell_margin['R'] = $margin[0];
+				$cell_margin['B'] = $margin[0];
+				$cell_margin['L'] = $margin[0];
+				break;
+			}
+			default: {
+				return $this->cell_margin;
+			}
+		}
+		if ($width == 0) {
+			$width = $this->w - $this->lMargin - $this->rMargin;
+		}
+		$cell_margin['T'] = $this->getHTMLUnitToUnits(str_replace('auto', '0', $cell_margin['T']), $width, 'px', false);
+		$cell_margin['R'] = $this->getHTMLUnitToUnits(str_replace('auto', '0', $cell_margin['R']), $width, 'px', false);
+		$cell_margin['B'] = $this->getHTMLUnitToUnits(str_replace('auto', '0', $cell_margin['B']), $width, 'px', false);
+		$cell_margin['L'] = $this->getHTMLUnitToUnits(str_replace('auto', '0', $cell_margin['L']), $width, 'px', false);
+		return $cell_margin;
+	}
+
+	/**
+	 * Get the border-spacing from CSS attribute.
+	 * @param $cssbspace (string) border-spacing CSS properties
+	 * @param $width (float) width of the containing element
+	 * @return array of border spacings
+	 * @public
+	 * @since 5.9.010 (2010-10-27)
+	 */
+	public function getCSSBorderMargin($cssbspace, $width=0) {
+		$space = preg_split('/[\s]+/', trim($cssbspace));
+		$border_spacing = array(); // value to be returned
+		switch (count($space)) {
+			case 2: {
+				$border_spacing['H'] = $space[0];
+				$border_spacing['V'] = $space[1];
+				break;
+			}
+			case 1: {
+				$border_spacing['H'] = $space[0];
+				$border_spacing['V'] = $space[0];
+				break;
+			}
+			default: {
+				return array('H' => 0, 'V' => 0);
+			}
+		}
+		if ($width == 0) {
+			$width = $this->w - $this->lMargin - $this->rMargin;
+		}
+		$border_spacing['H'] = $this->getHTMLUnitToUnits($border_spacing['H'], $width, 'px', false);
+		$border_spacing['V'] = $this->getHTMLUnitToUnits($border_spacing['V'], $width, 'px', false);
+		return $border_spacing;
+	}
+
+	/**
+	 * Returns the letter-spacing value from CSS value
+	 * @param $spacing (string) letter-spacing value
+	 * @param $parent (float) font spacing (tracking) value of the parent element
+	 * @return float quantity to increases or decreases the space between characters in a text.
+	 * @protected
+	 * @since 5.9.000 (2010-10-02)
+	 */
+	protected function getCSSFontSpacing($spacing, $parent=0) {
+		$val = 0; // value to be returned
+		$spacing = trim($spacing);
+		switch ($spacing) {
+			case 'normal': {
+				$val = 0;
+				break;
+			}
+			case 'inherit': {
+				if ($parent == 'normal') {
+					$val = 0;
+				} else {
+					$val = $parent;
+				}
+				break;
+			}
+			default: {
+				$val = $this->getHTMLUnitToUnits($spacing, 0, 'px', false);
+			}
+		}
+		return $val;
+	}
+
+	/**
+	 * Returns the percentage of font stretching from CSS value
+	 * @param $stretch (string) stretch mode
+	 * @param $parent (float) stretch value of the parent element
+	 * @return float font stretching percentage
+	 * @protected
+	 * @since 5.9.000 (2010-10-02)
+	 */
+	protected function getCSSFontStretching($stretch, $parent=100) {
+		$val = 100; // value to be returned
+		$stretch = trim($stretch);
+		switch ($stretch) {
+			case 'ultra-condensed': {
+				$val = 40;
+				break;
+			}
+			case 'extra-condensed': {
+				$val = 55;
+				break;
+			}
+			case 'condensed': {
+				$val = 70;
+				break;
+			}
+			case 'semi-condensed': {
+				$val = 85;
+				break;
+			}
+			case 'normal': {
+				$val = 100;
+				break;
+			}
+			case 'semi-expanded': {
+				$val = 115;
+				break;
+			}
+			case 'expanded': {
+				$val = 130;
+				break;
+			}
+			case 'extra-expanded': {
+				$val = 145;
+				break;
+			}
+			case 'ultra-expanded': {
+				$val = 160;
+				break;
+			}
+			case 'wider': {
+				$val = $parent + 10;
+				break;
+			}
+			case 'narrower': {
+				$val = $parent - 10;
+				break;
+			}
+			case 'inherit': {
+				if ($parent == 'normal') {
+					$val = 100;
+				} else {
+					$val = $parent;
+				}
+				break;
+			}
+			default: {
+				$val = $this->getHTMLUnitToUnits($stretch, 100, '%', false);
+			}
+		}
+		return $val;
+	}
+
+	/**
+	 * Returns the HTML DOM array.
+	 * @param $html (string) html code
+	 * @return array
+	 * @protected
+	 * @since 3.2.000 (2008-06-20)
+	 */
+	protected function getHtmlDomArray($html) {
+		// array of CSS styles ( selector => properties).
+		$css = array();
+		// get CSS array defined at previous call
+		$matches = array();
+		if (preg_match_all('/<cssarray>([^\<]*)<\/cssarray>/isU', $html, $matches) > 0) {
+			if (isset($matches[1][0])) {
+				$css = array_merge($css, unserialize($this->unhtmlentities($matches[1][0])));
+			}
+			$html = preg_replace('/<cssarray>(.*?)<\/cssarray>/isU', '', $html);
+		}
+		// extract external CSS files
+		$matches = array();
+		if (preg_match_all('/<link([^\>]*)>/isU', $html, $matches) > 0) {
+			foreach ($matches[1] as $key => $link) {
+				$type = array();
+				if (preg_match('/type[\s]*=[\s]*"text\/css"/', $link, $type)) {
+					$type = array();
+					preg_match('/media[\s]*=[\s]*"([^"]*)"/', $link, $type);
+					// get 'all' and 'print' media, other media types are discarded
+					// (all, braille, embossed, handheld, print, projection, screen, speech, tty, tv)
+					if (empty($type) OR (isset($type[1]) AND (($type[1] == 'all') OR ($type[1] == 'print')))) {
+						$type = array();
+						if (preg_match('/href[\s]*=[\s]*"([^"]*)"/', $link, $type) > 0) {
+							// read CSS data file
+							$cssdata = file_get_contents(trim($type[1]));
+							$css = array_merge($css, $this->extractCSSproperties($cssdata));
+						}
+					}
+				}
+			}
+		}
+		// extract style tags
+		$matches = array();
+		if (preg_match_all('/<style([^\>]*)>([^\<]*)<\/style>/isU', $html, $matches) > 0) {
+			foreach ($matches[1] as $key => $media) {
+				$type = array();
+				preg_match('/media[\s]*=[\s]*"([^"]*)"/', $media, $type);
+				// get 'all' and 'print' media, other media types are discarded
+				// (all, braille, embossed, handheld, print, projection, screen, speech, tty, tv)
+				if (empty($type) OR (isset($type[1]) AND (($type[1] == 'all') OR ($type[1] == 'print')))) {
+					$cssdata = $matches[2][$key];
+					$css = array_merge($css, $this->extractCSSproperties($cssdata));
+				}
+			}
+		}
+		// create a special tag to contain the CSS array (used for table content)
+		$csstagarray = '<cssarray>'.htmlentities(serialize($css)).'</cssarray>';
+		// remove head and style blocks
+		$html = preg_replace('/<head([^\>]*)>(.*?)<\/head>/siU', '', $html);
+		$html = preg_replace('/<style([^\>]*)>([^\<]*)<\/style>/isU', '', $html);
+		// define block tags
+		$blocktags = array('blockquote','br','dd','dl','div','dt','h1','h2','h3','h4','h5','h6','hr','li','ol','p','pre','ul','tcpdf','table','tr','td');
+		// define self-closing tags
+		$selfclosingtags = array('area','base','basefont','br','hr','input','img','link','meta');
+		// remove all unsupported tags (the line below lists all supported tags)
+		$html = strip_tags($html, '<marker/><a><b><blockquote><body><br><br/><dd><del><div><dl><dt><em><font><form><h1><h2><h3><h4><h5><h6><hr><hr/><i><img><input><label><li><ol><option><p><pre><s><select><small><span><strike><strong><sub><sup><table><tablehead><tcpdf><td><textarea><th><thead><tr><tt><u><ul>');
+		//replace some blank characters
+		$html = preg_replace('/<pre/', '<xre', $html); // preserve pre tag
+		$html = preg_replace('/<(table|tr|td|th|tcpdf|blockquote|dd|div|dl|dt|form|h1|h2|h3|h4|h5|h6|br|hr|li|ol|ul|p)([^\>]*)>[\n\r\t]+/', '<\\1\\2>', $html);
+		$html = preg_replace('@(\r\n|\r)@', "\n", $html);
+		$repTable = array("\t" => ' ', "\0" => ' ', "\x0B" => ' ', "\\" => "\\\\");
+		$html = strtr($html, $repTable);
+		$offset = 0;
+		while (($offset < strlen($html)) AND ($pos = strpos($html, '</pre>', $offset)) !== false) {
+			$html_a = substr($html, 0, $offset);
+			$html_b = substr($html, $offset, ($pos - $offset + 6));
+			while (preg_match("'<xre([^\>]*)>(.*?)\n(.*?)</pre>'si", $html_b)) {
+				// preserve newlines on <pre> tag
+				$html_b = preg_replace("'<xre([^\>]*)>(.*?)\n(.*?)</pre>'si", "<xre\\1>\\2<br />\\3</pre>", $html_b);
+			}
+			while (preg_match("'<xre([^\>]*)>(.*?)".$this->re_space['p']."(.*?)</pre>'".$this->re_space['m'], $html_b)) {
+				// preserve spaces on <pre> tag
+				$html_b = preg_replace("'<xre([^\>]*)>(.*?)".$this->re_space['p']."(.*?)</pre>'".$this->re_space['m'], "<xre\\1>\\2 \\3</pre>", $html_b);
+			}
+			$html = $html_a.$html_b.substr($html, $pos + 6);
+			$offset = strlen($html_a.$html_b);
+		}
+		$offset = 0;
+		while (($offset < strlen($html)) AND ($pos = strpos($html, '</textarea>', $offset)) !== false) {
+			$html_a = substr($html, 0, $offset);
+			$html_b = substr($html, $offset, ($pos - $offset + 11));
+			while (preg_match("'<textarea([^\>]*)>(.*?)\n(.*?)</textarea>'si", $html_b)) {
+				// preserve newlines on <textarea> tag
+				$html_b = preg_replace("'<textarea([^\>]*)>(.*?)\n(.*?)</textarea>'si", "<textarea\\1>\\2<TBR>\\3</textarea>", $html_b);
+				$html_b = preg_replace("'<textarea([^\>]*)>(.*?)[\"](.*?)</textarea>'si", "<textarea\\1>\\2''\\3</textarea>", $html_b);
+			}
+			$html = $html_a.$html_b.substr($html, $pos + 11);
+			$offset = strlen($html_a.$html_b);
+		}
+		$html = preg_replace('/([\s]*)<option/si', '<option', $html);
+		$html = preg_replace('/<\/option>([\s]*)/si', '</option>', $html);
+		$offset = 0;
+		while (($offset < strlen($html)) AND ($pos = strpos($html, '</option>', $offset)) !== false) {
+			$html_a = substr($html, 0, $offset);
+			$html_b = substr($html, $offset, ($pos - $offset + 9));
+			while (preg_match("'<option([^\>]*)>(.*?)</option>'si", $html_b)) {
+				$html_b = preg_replace("'<option([\s]+)value=\"([^\"]*)\"([^\>]*)>(.*?)</option>'si", "\\2#!TaB!#\\4#!NwL!#", $html_b);
+				$html_b = preg_replace("'<option([^\>]*)>(.*?)</option>'si", "\\2#!NwL!#", $html_b);
+			}
+			$html = $html_a.$html_b.substr($html, $pos + 9);
+			$offset = strlen($html_a.$html_b);
+		}
+		if (preg_match("'</select'si", $html)) {
+			$html = preg_replace("'<select([^\>]*)>'si", "<select\\1 opt=\"", $html);
+			$html = preg_replace("'#!NwL!#</select>'si", "\" />", $html);
+		}
+		$html = str_replace("\n", ' ', $html);
+		// restore textarea newlines
+		$html = str_replace('<TBR>', "\n", $html);
+		// remove extra spaces from code
+		$html = preg_replace('/[\s]+<\/(table|tr|ul|ol|dl)>/', '</\\1>', $html);
+		$html = preg_replace('/'.$this->re_space['p'].'+<\/(td|th|li|dt|dd)>/'.$this->re_space['m'], '</\\1>', $html);
+		$html = preg_replace('/[\s]+<(tr|td|th|li|dt|dd)/', '<\\1', $html);
+		$html = preg_replace('/'.$this->re_space['p'].'+<(ul|ol|dl|br)/'.$this->re_space['m'], '<\\1', $html);
+		$html = preg_replace('/<\/(table|tr|td|th|blockquote|dd|dt|dl|div|dt|h1|h2|h3|h4|h5|h6|hr|li|ol|ul|p)>[\s]+</', '</\\1><', $html);
+		$html = preg_replace('/<\/(td|th)>/', '<marker style="font-size:0"/></\\1>', $html);
+		$html = preg_replace('/<\/table>([\s]*)<marker style="font-size:0"\/>/', '</table>', $html);
+		$html = preg_replace('/'.$this->re_space['p'].'+<img/'.$this->re_space['m'], chr(32).'<img', $html);
+		$html = preg_replace('/<img([^\>]*)>[\s]+([^\<])/xi', '<img\\1> \\2', $html);
+		$html = preg_replace('/<img([^\>]*)>/xi', '<img\\1><span><marker style="font-size:0"/></span>', $html);
+		$html = preg_replace('/<xre/', '<pre', $html); // restore pre tag
+		$html = preg_replace('/<textarea([^\>]*)>([^\<]*)<\/textarea>/xi', '<textarea\\1 value="\\2" />', $html);
+		$html = preg_replace('/<li([^\>]*)><\/li>/', '<li\\1> </li>', $html);
+		$html = preg_replace('/<li([^\>]*)>'.$this->re_space['p'].'*<img/'.$this->re_space['m'], '<li\\1><font size="1"> </font><img', $html);
+		$html = preg_replace('/<([^\>\/]*)>[\s]/', '<\\1> ', $html); // preserve some spaces
+		$html = preg_replace('/[\s]<\/([^\>]*)>/', ' </\\1>', $html); // preserve some spaces
+		$html = preg_replace('/<su([bp])/', '<zws/><su\\1', $html); // fix sub/sup alignment
+		$html = preg_replace('/<\/su([bp])>/', '</su\\1><zws/>', $html); // fix sub/sup alignment
+		$html = preg_replace('/'.$this->re_space['p'].'+/'.$this->re_space['m'], chr(32), $html); // replace multiple spaces with a single space
+		// trim string
+		$html = $this->stringTrim($html);
+		// fix first image tag alignment
+		$html = preg_replace('/^<img/', '<span style="font-size:0"><br /></span> <img', $html, 1);
+		// pattern for generic tag
+		$tagpattern = '/(<[^>]+>)/';
+		// explodes the string
+		$a = preg_split($tagpattern, $html, -1, PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY);
+		// count elements
+		$maxel = count($a);
+		$elkey = 0;
+		$key = 0;
+		// create an array of elements
+		$dom = array();
+		$dom[$key] = array();
+		// set inheritable properties fot the first void element
+		// possible inheritable properties are: azimuth, border-collapse, border-spacing, caption-side, color, cursor, direction, empty-cells, font, font-family, font-stretch, font-size, font-size-adjust, font-style, font-variant, font-weight, letter-spacing, line-height, list-style, list-style-image, list-style-position, list-style-type, orphans, page, page-break-inside, quotes, speak, speak-header, text-align, text-indent, text-transform, volume, white-space, widows, word-spacing
+		$dom[$key]['tag'] = false;
+		$dom[$key]['block'] = false;
+		$dom[$key]['value'] = '';
+		$dom[$key]['parent'] = 0;
+		$dom[$key]['hide'] = false;
+		$dom[$key]['fontname'] = $this->FontFamily;
+		$dom[$key]['fontstyle'] = $this->FontStyle;
+		$dom[$key]['fontsize'] = $this->FontSizePt;
+		$dom[$key]['font-stretch'] = $this->font_stretching;
+		$dom[$key]['letter-spacing'] = $this->font_spacing;
+		$dom[$key]['stroke'] = $this->textstrokewidth;
+		$dom[$key]['fill'] = (($this->textrendermode % 2) == 0);
+		$dom[$key]['clip'] = ($this->textrendermode > 3);
+		$dom[$key]['line-height'] = $this->cell_height_ratio;
+		$dom[$key]['bgcolor'] = false;
+		$dom[$key]['fgcolor'] = $this->fgcolor; // color
+		$dom[$key]['strokecolor'] = $this->strokecolor;
+		$dom[$key]['align'] = '';
+		$dom[$key]['listtype'] = '';
+		$dom[$key]['text-indent'] = 0;
+		$dom[$key]['border'] = array();
+		$dom[$key]['dir'] = $this->rtl?'rtl':'ltr';
+		$thead = false; // true when we are inside the THEAD tag
+		++$key;
+		$level = array();
+		array_push($level, 0); // root
+		while ($elkey < $maxel) {
+			$dom[$key] = array();
+			$element = $a[$elkey];
+			$dom[$key]['elkey'] = $elkey;
+			if (preg_match($tagpattern, $element)) {
+				// html tag
+				$element = substr($element, 1, -1);
+				// get tag name
+				preg_match('/[\/]?([a-zA-Z0-9]*)/', $element, $tag);
+				$tagname = strtolower($tag[1]);
+				// check if we are inside a table header
+				if ($tagname == 'thead') {
+					if ($element{0} == '/') {
+						$thead = false;
+					} else {
+						$thead = true;
+					}
+					++$elkey;
+					continue;
+				}
+				$dom[$key]['tag'] = true;
+				$dom[$key]['value'] = $tagname;
+				if (in_array($dom[$key]['value'], $blocktags)) {
+					$dom[$key]['block'] = true;
+				} else {
+					$dom[$key]['block'] = false;
+				}
+				if ($element{0} == '/') {
+					// *** closing html tag
+					$dom[$key]['opening'] = false;
+					$dom[$key]['parent'] = end($level);
+					array_pop($level);
+					$dom[$key]['hide'] = $dom[($dom[($dom[$key]['parent'])]['parent'])]['hide'];
+					$dom[$key]['fontname'] = $dom[($dom[($dom[$key]['parent'])]['parent'])]['fontname'];
+					$dom[$key]['fontstyle'] = $dom[($dom[($dom[$key]['parent'])]['parent'])]['fontstyle'];
+					$dom[$key]['fontsize'] = $dom[($dom[($dom[$key]['parent'])]['parent'])]['fontsize'];
+					$dom[$key]['font-stretch'] = $dom[($dom[($dom[$key]['parent'])]['parent'])]['font-stretch'];
+					$dom[$key]['letter-spacing'] = $dom[($dom[($dom[$key]['parent'])]['parent'])]['letter-spacing'];
+					$dom[$key]['stroke'] = $dom[($dom[($dom[$key]['parent'])]['parent'])]['stroke'];
+					$dom[$key]['fill'] = $dom[($dom[($dom[$key]['parent'])]['parent'])]['fill'];
+					$dom[$key]['clip'] = $dom[($dom[($dom[$key]['parent'])]['parent'])]['clip'];
+					$dom[$key]['line-height'] = $dom[($dom[($dom[$key]['parent'])]['parent'])]['line-height'];
+					$dom[$key]['bgcolor'] = $dom[($dom[($dom[$key]['parent'])]['parent'])]['bgcolor'];
+					$dom[$key]['fgcolor'] = $dom[($dom[($dom[$key]['parent'])]['parent'])]['fgcolor'];
+					$dom[$key]['strokecolor'] = $dom[($dom[($dom[$key]['parent'])]['parent'])]['strokecolor'];
+					$dom[$key]['align'] = $dom[($dom[($dom[$key]['parent'])]['parent'])]['align'];
+					$dom[$key]['dir'] = $dom[($dom[($dom[$key]['parent'])]['parent'])]['dir'];
+					if (isset($dom[($dom[($dom[$key]['parent'])]['parent'])]['listtype'])) {
+						$dom[$key]['listtype'] = $dom[($dom[($dom[$key]['parent'])]['parent'])]['listtype'];
+					}
+					// set the number of columns in table tag
+					if (($dom[$key]['value'] == 'tr') AND (!isset($dom[($dom[($dom[$key]['parent'])]['parent'])]['cols']))) {
+						$dom[($dom[($dom[$key]['parent'])]['parent'])]['cols'] = $dom[($dom[$key]['parent'])]['cols'];
+					}
+					if (($dom[$key]['value'] == 'td') OR ($dom[$key]['value'] == 'th')) {
+						$dom[($dom[$key]['parent'])]['content'] = $csstagarray;
+						for ($i = ($dom[$key]['parent'] + 1); $i < $key; ++$i) {
+							$dom[($dom[$key]['parent'])]['content'] .= $a[$dom[$i]['elkey']];
+						}
+						$key = $i;
+						// mark nested tables
+						$dom[($dom[$key]['parent'])]['content'] = str_replace('<table', '<table nested="true"', $dom[($dom[$key]['parent'])]['content']);
+						// remove thead sections from nested tables
+						$dom[($dom[$key]['parent'])]['content'] = str_replace('<thead>', '', $dom[($dom[$key]['parent'])]['content']);
+						$dom[($dom[$key]['parent'])]['content'] = str_replace('</thead>', '', $dom[($dom[$key]['parent'])]['content']);
+					}
+					// store header rows on a new table
+					if (($dom[$key]['value'] == 'tr') AND ($dom[($dom[$key]['parent'])]['thead'] === true)) {
+						if ($this->empty_string($dom[($dom[($dom[$key]['parent'])]['parent'])]['thead'])) {
+							$dom[($dom[($dom[$key]['parent'])]['parent'])]['thead'] = $csstagarray.$a[$dom[($dom[($dom[$key]['parent'])]['parent'])]['elkey']];
+						}
+						for ($i = $dom[$key]['parent']; $i <= $key; ++$i) {
+							$dom[($dom[($dom[$key]['parent'])]['parent'])]['thead'] .= $a[$dom[$i]['elkey']];
+						}
+						if (!isset($dom[($dom[$key]['parent'])]['attribute'])) {
+							$dom[($dom[$key]['parent'])]['attribute'] = array();
+						}
+						// header elements must be always contained in a single page
+						$dom[($dom[$key]['parent'])]['attribute']['nobr'] = 'true';
+					}
+					if (($dom[$key]['value'] == 'table') AND (!$this->empty_string($dom[($dom[$key]['parent'])]['thead']))) {
+						// remove the nobr attributes from the table header
+						$dom[($dom[$key]['parent'])]['thead'] = str_replace(' nobr="true"', '', $dom[($dom[$key]['parent'])]['thead']);
+						$dom[($dom[$key]['parent'])]['thead'] .= '</tablehead>';
+					}
+				} else {
+					// *** opening or self-closing html tag
+					$dom[$key]['opening'] = true;
+					$dom[$key]['parent'] = end($level);
+					if ((substr($element, -1, 1) == '/') OR (in_array($dom[$key]['value'], $selfclosingtags))) {
+						// self-closing tag
+						$dom[$key]['self'] = true;
+					} else {
+						// opening tag
+						array_push($level, $key);
+						$dom[$key]['self'] = false;
+					}
+					// copy some values from parent
+					$parentkey = 0;
+					if ($key > 0) {
+						$parentkey = $dom[$key]['parent'];
+						$dom[$key]['hide'] = $dom[$parentkey]['hide'];
+						$dom[$key]['fontname'] = $dom[$parentkey]['fontname'];
+						$dom[$key]['fontstyle'] = $dom[$parentkey]['fontstyle'];
+						$dom[$key]['fontsize'] = $dom[$parentkey]['fontsize'];
+						$dom[$key]['font-stretch'] = $dom[$parentkey]['font-stretch'];
+						$dom[$key]['letter-spacing'] = $dom[$parentkey]['letter-spacing'];
+						$dom[$key]['stroke'] = $dom[$parentkey]['stroke'];
+						$dom[$key]['fill'] = $dom[$parentkey]['fill'];
+						$dom[$key]['clip'] = $dom[$parentkey]['clip'];
+						$dom[$key]['line-height'] = $dom[$parentkey]['line-height'];
+						$dom[$key]['bgcolor'] = $dom[$parentkey]['bgcolor'];
+						$dom[$key]['fgcolor'] = $dom[$parentkey]['fgcolor'];
+						$dom[$key]['strokecolor'] = $dom[$parentkey]['strokecolor'];
+						$dom[$key]['align'] = $dom[$parentkey]['align'];
+						$dom[$key]['listtype'] = $dom[$parentkey]['listtype'];
+						$dom[$key]['text-indent'] = $dom[$parentkey]['text-indent'];
+						$dom[$key]['border'] = array();
+						$dom[$key]['dir'] = $dom[$parentkey]['dir'];
+					}
+					// get attributes
+					preg_match_all('/([^=\s]*)[\s]*=[\s]*"([^"]*)"/', $element, $attr_array, PREG_PATTERN_ORDER);
+					$dom[$key]['attribute'] = array(); // reset attribute array
+					while (list($id, $name) = each($attr_array[1])) {
+						$dom[$key]['attribute'][strtolower($name)] = $attr_array[2][$id];
+					}
+					if (!empty($css)) {
+						// merge CSS style to current style
+						list($dom[$key]['csssel'], $dom[$key]['cssdata']) = $this->getCSSdataArray($dom, $key, $css);
+						$dom[$key]['attribute']['style'] = $this->getTagStyleFromCSSarray($dom[$key]['cssdata']);
+					}
+					// split style attributes
+					if (isset($dom[$key]['attribute']['style']) AND !empty($dom[$key]['attribute']['style'])) {
+						// get style attributes
+						preg_match_all('/([^;:\s]*):([^;]*)/', $dom[$key]['attribute']['style'], $style_array, PREG_PATTERN_ORDER);
+						$dom[$key]['style'] = array(); // reset style attribute array
+						while (list($id, $name) = each($style_array[1])) {
+							// in case of duplicate attribute the last replace the previous
+							$dom[$key]['style'][strtolower($name)] = trim($style_array[2][$id]);
+						}
+						// --- get some style attributes ---
+						// text direction
+						if (isset($dom[$key]['style']['direction'])) {
+							$dom[$key]['dir'] = $dom[$key]['style']['direction'];
+						}
+						// display
+						if (isset($dom[$key]['style']['display'])) {
+							$dom[$key]['hide'] = (trim(strtolower($dom[$key]['style']['display'])) == 'none');
+						}
+						// font family
+						if (isset($dom[$key]['style']['font-family'])) {
+							$dom[$key]['fontname'] = $this->getFontFamilyName($dom[$key]['style']['font-family']);
+						}
+						// list-style-type
+						if (isset($dom[$key]['style']['list-style-type'])) {
+							$dom[$key]['listtype'] = trim(strtolower($dom[$key]['style']['list-style-type']));
+							if ($dom[$key]['listtype'] == 'inherit') {
+								$dom[$key]['listtype'] = $dom[$parentkey]['listtype'];
+							}
+						}
+						// text-indent
+						if (isset($dom[$key]['style']['text-indent'])) {
+							$dom[$key]['text-indent'] = $this->getHTMLUnitToUnits($dom[$key]['style']['text-indent']);
+							if ($dom[$key]['text-indent'] == 'inherit') {
+								$dom[$key]['text-indent'] = $dom[$parentkey]['text-indent'];
+							}
+						}
+						// font size
+						if (isset($dom[$key]['style']['font-size'])) {
+							$fsize = trim($dom[$key]['style']['font-size']);
+							switch ($fsize) {
+								// absolute-size
+								case 'xx-small': {
+									$dom[$key]['fontsize'] = $dom[0]['fontsize'] - 4;
+									break;
+								}
+								case 'x-small': {
+									$dom[$key]['fontsize'] = $dom[0]['fontsize'] - 3;
+									break;
+								}
+								case 'small': {
+									$dom[$key]['fontsize'] = $dom[0]['fontsize'] - 2;
+									break;
+								}
+								case 'medium': {
+									$dom[$key]['fontsize'] = $dom[0]['fontsize'];
+									break;
+								}
+								case 'large': {
+									$dom[$key]['fontsize'] = $dom[0]['fontsize'] + 2;
+									break;
+								}
+								case 'x-large': {
+									$dom[$key]['fontsize'] = $dom[0]['fontsize'] + 4;
+									break;
+								}
+								case 'xx-large': {
+									$dom[$key]['fontsize'] = $dom[0]['fontsize'] + 6;
+									break;
+								}
+								// relative-size
+								case 'smaller': {
+									$dom[$key]['fontsize'] = $dom[$parentkey]['fontsize'] - 3;
+									break;
+								}
+								case 'larger': {
+									$dom[$key]['fontsize'] = $dom[$parentkey]['fontsize'] + 3;
+									break;
+								}
+								default: {
+									$dom[$key]['fontsize'] = $this->getHTMLUnitToUnits($fsize, $dom[$parentkey]['fontsize'], 'pt', true);
+								}
+							}
+						}
+						// font-stretch
+						if (isset($dom[$key]['style']['font-stretch'])) {
+							$dom[$key]['font-stretch'] = $this->getCSSFontStretching($dom[$key]['style']['font-stretch'], $dom[$parentkey]['font-stretch']);
+						}
+						// letter-spacing
+						if (isset($dom[$key]['style']['letter-spacing'])) {
+							$dom[$key]['letter-spacing'] = $this->getCSSFontSpacing($dom[$key]['style']['letter-spacing'], $dom[$parentkey]['letter-spacing']);
+						}
+						// line-height
+						if (isset($dom[$key]['style']['line-height'])) {
+							$lineheight = trim($dom[$key]['style']['line-height']);
+							switch ($lineheight) {
+								// A normal line height. This is default
+								case 'normal': {
+									$dom[$key]['line-height'] = $dom[0]['line-height'];
+									break;
+								}
+								default: {
+									if (is_numeric($lineheight)) {
+										$lineheight = $lineheight * 100;
+									}
+									$dom[$key]['line-height'] = $this->getHTMLUnitToUnits($lineheight, 1, '%', true);
+								}
+							}
+						}
+						// font style
+						if (isset($dom[$key]['style']['font-weight'])) {
+							if (strtolower($dom[$key]['style']['font-weight']{0}) == 'n') {
+								if (strpos($dom[$key]['fontstyle'], 'B') !== false) {
+									$dom[$key]['fontstyle'] = str_replace('B', '', $dom[$key]['fontstyle']);
+								}
+							} elseif (strtolower($dom[$key]['style']['font-weight']{0}) == 'b') {
+								$dom[$key]['fontstyle'] .= 'B';
+							}
+						}
+						if (isset($dom[$key]['style']['font-style']) AND (strtolower($dom[$key]['style']['font-style']{0}) == 'i')) {
+							$dom[$key]['fontstyle'] .= 'I';
+						}
+						// font color
+						if (isset($dom[$key]['style']['color']) AND (!$this->empty_string($dom[$key]['style']['color']))) {
+							$dom[$key]['fgcolor'] = $this->convertHTMLColorToDec($dom[$key]['style']['color']);
+						} elseif ($dom[$key]['value'] == 'a') {
+							$dom[$key]['fgcolor'] = $this->htmlLinkColorArray;
+						}
+						// background color
+						if (isset($dom[$key]['style']['background-color']) AND (!$this->empty_string($dom[$key]['style']['background-color']))) {
+							$dom[$key]['bgcolor'] = $this->convertHTMLColorToDec($dom[$key]['style']['background-color']);
+						}
+						// text-decoration
+						if (isset($dom[$key]['style']['text-decoration'])) {
+							$decors = explode(' ', strtolower($dom[$key]['style']['text-decoration']));
+							foreach ($decors as $dec) {
+								$dec = trim($dec);
+								if (!$this->empty_string($dec)) {
+									if ($dec{0} == 'u') {
+										// underline
+										$dom[$key]['fontstyle'] .= 'U';
+									} elseif ($dec{0} == 'l') {
+										// line-trough
+										$dom[$key]['fontstyle'] .= 'D';
+									} elseif ($dec{0} == 'o') {
+										// overline
+										$dom[$key]['fontstyle'] .= 'O';
+									}
+								}
+							}
+						} elseif ($dom[$key]['value'] == 'a') {
+							$dom[$key]['fontstyle'] = $this->htmlLinkFontStyle;
+						}
+						// check for width attribute
+						if (isset($dom[$key]['style']['width'])) {
+							$dom[$key]['width'] = $dom[$key]['style']['width'];
+						}
+						// check for height attribute
+						if (isset($dom[$key]['style']['height'])) {
+							$dom[$key]['height'] = $dom[$key]['style']['height'];
+						}
+						// check for text alignment
+						if (isset($dom[$key]['style']['text-align'])) {
+							$dom[$key]['align'] = strtoupper($dom[$key]['style']['text-align']{0});
+						}
+						// check for CSS border properties
+						if (isset($dom[$key]['style']['border'])) {
+							$borderstyle = $this->getCSSBorderStyle($dom[$key]['style']['border']);
+							if (!empty($borderstyle)) {
+								$dom[$key]['border']['LTRB'] = $borderstyle;
+							}
+						}
+						if (isset($dom[$key]['style']['border-color'])) {
+							$brd_colors = preg_split('/[\s]+/', trim($dom[$key]['style']['border-color']));
+							if (isset($brd_colors[3])) {
+								$dom[$key]['border']['L']['color'] = $this->convertHTMLColorToDec($brd_colors[3]);
+							}
+							if (isset($brd_colors[1])) {
+								$dom[$key]['border']['R']['color'] = $this->convertHTMLColorToDec($brd_colors[1]);
+							}
+							if (isset($brd_colors[0])) {
+								$dom[$key]['border']['T']['color'] = $this->convertHTMLColorToDec($brd_colors[0]);
+							}
+							if (isset($brd_colors[2])) {
+								$dom[$key]['border']['B']['color'] = $this->convertHTMLColorToDec($brd_colors[2]);
+							}
+						}
+						if (isset($dom[$key]['style']['border-width'])) {
+							$brd_widths = preg_split('/[\s]+/', trim($dom[$key]['style']['border-width']));
+							if (isset($brd_widths[3])) {
+								$dom[$key]['border']['L']['width'] = $this->getCSSBorderWidth($brd_widths[3]);
+							}
+							if (isset($brd_widths[1])) {
+								$dom[$key]['border']['R']['width'] = $this->getCSSBorderWidth($brd_widths[1]);
+							}
+							if (isset($brd_widths[0])) {
+								$dom[$key]['border']['T']['width'] = $this->getCSSBorderWidth($brd_widths[0]);
+							}
+							if (isset($brd_widths[2])) {
+								$dom[$key]['border']['B']['width'] = $this->getCSSBorderWidth($brd_widths[2]);
+							}
+						}
+						if (isset($dom[$key]['style']['border-style'])) {
+							$brd_styles = preg_split('/[\s]+/', trim($dom[$key]['style']['border-style']));
+							if (isset($brd_styles[3]) AND ($brd_styles[3]!='none')) {
+								$dom[$key]['border']['L']['cap'] = 'square';
+								$dom[$key]['border']['L']['join'] = 'miter';
+								$dom[$key]['border']['L']['dash'] = $this->getCSSBorderDashStyle($brd_styles[3]);
+								if ($dom[$key]['border']['L']['dash'] < 0) {
+									$dom[$key]['border']['L'] = array();
+								}
+							}
+							if (isset($brd_styles[1])) {
+								$dom[$key]['border']['R']['cap'] = 'square';
+								$dom[$key]['border']['R']['join'] = 'miter';
+								$dom[$key]['border']['R']['dash'] = $this->getCSSBorderDashStyle($brd_styles[1]);
+								if ($dom[$key]['border']['R']['dash'] < 0) {
+									$dom[$key]['border']['R'] = array();
+								}
+							}
+							if (isset($brd_styles[0])) {
+								$dom[$key]['border']['T']['cap'] = 'square';
+								$dom[$key]['border']['T']['join'] = 'miter';
+								$dom[$key]['border']['T']['dash'] = $this->getCSSBorderDashStyle($brd_styles[0]);
+								if ($dom[$key]['border']['T']['dash'] < 0) {
+									$dom[$key]['border']['T'] = array();
+								}
+							}
+							if (isset($brd_styles[2])) {
+								$dom[$key]['border']['B']['cap'] = 'square';
+								$dom[$key]['border']['B']['join'] = 'miter';
+								$dom[$key]['border']['B']['dash'] = $this->getCSSBorderDashStyle($brd_styles[2]);
+								if ($dom[$key]['border']['B']['dash'] < 0) {
+									$dom[$key]['border']['B'] = array();
+								}
+							}
+						}
+						$cellside = array('L' => 'left', 'R' => 'right', 'T' => 'top', 'B' => 'bottom');
+						foreach ($cellside as $bsk => $bsv) {
+							if (isset($dom[$key]['style']['border-'.$bsv])) {
+								$borderstyle = $this->getCSSBorderStyle($dom[$key]['style']['border-'.$bsv]);
+								if (!empty($borderstyle)) {
+									$dom[$key]['border'][$bsk] = $borderstyle;
+								}
+							}
+							if (isset($dom[$key]['style']['border-'.$bsv.'-color'])) {
+								$dom[$key]['border'][$bsk]['color'] = $this->convertHTMLColorToDec($dom[$key]['style']['border-'.$bsv.'-color']);
+							}
+							if (isset($dom[$key]['style']['border-'.$bsv.'-width'])) {
+								$dom[$key]['border'][$bsk]['width'] = $this->getCSSBorderWidth($dom[$key]['style']['border-'.$bsv.'-width']);
+							}
+							if (isset($dom[$key]['style']['border-'.$bsv.'-style'])) {
+								$dom[$key]['border'][$bsk]['dash'] = $this->getCSSBorderDashStyle($dom[$key]['style']['border-'.$bsv.'-style']);
+								if ($dom[$key]['border'][$bsk]['dash'] < 0) {
+									$dom[$key]['border'][$bsk] = array();
+								}
+							}
+						}
+						// check for CSS padding properties
+						if (isset($dom[$key]['style']['padding'])) {
+							$dom[$key]['padding'] = $this->getCSSPadding($dom[$key]['style']['padding']);
+						} else {
+							$dom[$key]['padding'] = $this->cell_padding;
+						}
+						foreach ($cellside as $psk => $psv) {
+							if (isset($dom[$key]['style']['padding-'.$psv])) {
+								$dom[$key]['padding'][$psk] = $this->getHTMLUnitToUnits($dom[$key]['style']['padding-'.$psv], 0, 'px', false);
+							}
+						}
+						// check for CSS margin properties
+						if (isset($dom[$key]['style']['margin'])) {
+							$dom[$key]['margin'] = $this->getCSSMargin($dom[$key]['style']['margin']);
+						} else {
+							$dom[$key]['margin'] = $this->cell_margin;
+						}
+						foreach ($cellside as $psk => $psv) {
+							if (isset($dom[$key]['style']['margin-'.$psv])) {
+								$dom[$key]['margin'][$psk] = $this->getHTMLUnitToUnits(str_replace('auto', '0', $dom[$key]['style']['margin-'.$psv]), 0, 'px', false);
+							}
+						}
+						// check for CSS border-spacing properties
+						if (isset($dom[$key]['style']['border-spacing'])) {
+							$dom[$key]['border-spacing'] = $this->getCSSBorderMargin($dom[$key]['style']['border-spacing']);
+						}
+						// page-break-inside
+						if (isset($dom[$key]['style']['page-break-inside']) AND ($dom[$key]['style']['page-break-inside'] == 'avoid')) {
+							$dom[$key]['attribute']['nobr'] = 'true';
+						}
+						// page-break-before
+						if (isset($dom[$key]['style']['page-break-before'])) {
+							if ($dom[$key]['style']['page-break-before'] == 'always') {
+								$dom[$key]['attribute']['pagebreak'] = 'true';
+							} elseif ($dom[$key]['style']['page-break-before'] == 'left') {
+								$dom[$key]['attribute']['pagebreak'] = 'left';
+							} elseif ($dom[$key]['style']['page-break-before'] == 'right') {
+								$dom[$key]['attribute']['pagebreak'] = 'right';
+							}
+						}
+						// page-break-after
+						if (isset($dom[$key]['style']['page-break-after'])) {
+							if ($dom[$key]['style']['page-break-after'] == 'always') {
+								$dom[$key]['attribute']['pagebreakafter'] = 'true';
+							} elseif ($dom[$key]['style']['page-break-after'] == 'left') {
+								$dom[$key]['attribute']['pagebreakafter'] = 'left';
+							} elseif ($dom[$key]['style']['page-break-after'] == 'right') {
+								$dom[$key]['attribute']['pagebreakafter'] = 'right';
+							}
+						}
+					}
+					if (isset($dom[$key]['attribute']['display'])) {
+						$dom[$key]['hide'] = (trim(strtolower($dom[$key]['attribute']['display'])) == 'none');
+					}
+					if (isset($dom[$key]['attribute']['border']) AND ($dom[$key]['attribute']['border'] != 0)) {
+						$borderstyle = $this->getCSSBorderStyle($dom[$key]['attribute']['border'].' solid black');
+						if (!empty($borderstyle)) {
+							$dom[$key]['border']['LTRB'] = $borderstyle;
+						}
+					}
+					// check for font tag
+					if ($dom[$key]['value'] == 'font') {
+						// font family
+						if (isset($dom[$key]['attribute']['face'])) {
+							$dom[$key]['fontname'] = $this->getFontFamilyName($dom[$key]['attribute']['face']);
+						}
+						// font size
+						if (isset($dom[$key]['attribute']['size'])) {
+							if ($key > 0) {
+								if ($dom[$key]['attribute']['size']{0} == '+') {
+									$dom[$key]['fontsize'] = $dom[($dom[$key]['parent'])]['fontsize'] + intval(substr($dom[$key]['attribute']['size'], 1));
+								} elseif ($dom[$key]['attribute']['size']{0} == '-') {
+									$dom[$key]['fontsize'] = $dom[($dom[$key]['parent'])]['fontsize'] - intval(substr($dom[$key]['attribute']['size'], 1));
+								} else {
+									$dom[$key]['fontsize'] = intval($dom[$key]['attribute']['size']);
+								}
+							} else {
+								$dom[$key]['fontsize'] = intval($dom[$key]['attribute']['size']);
+							}
+						}
+					}
+					// force natural alignment for lists
+					if ((($dom[$key]['value'] == 'ul') OR ($dom[$key]['value'] == 'ol') OR ($dom[$key]['value'] == 'dl'))
+						AND (!isset($dom[$key]['align']) OR $this->empty_string($dom[$key]['align']) OR ($dom[$key]['align'] != 'J'))) {
+						if ($this->rtl) {
+							$dom[$key]['align'] = 'R';
+						} else {
+							$dom[$key]['align'] = 'L';
+						}
+					}
+					if (($dom[$key]['value'] == 'small') OR ($dom[$key]['value'] == 'sup') OR ($dom[$key]['value'] == 'sub')) {
+						if (!isset($dom[$key]['attribute']['size']) AND !isset($dom[$key]['style']['font-size'])) {
+							$dom[$key]['fontsize'] = $dom[$key]['fontsize'] * K_SMALL_RATIO;
+						}
+					}
+					if (($dom[$key]['value'] == 'strong') OR ($dom[$key]['value'] == 'b')) {
+						$dom[$key]['fontstyle'] .= 'B';
+					}
+					if (($dom[$key]['value'] == 'em') OR ($dom[$key]['value'] == 'i')) {
+						$dom[$key]['fontstyle'] .= 'I';
+					}
+					if ($dom[$key]['value'] == 'u') {
+						$dom[$key]['fontstyle'] .= 'U';
+					}
+					if (($dom[$key]['value'] == 'del') OR ($dom[$key]['value'] == 's') OR ($dom[$key]['value'] == 'strike')) {
+						$dom[$key]['fontstyle'] .= 'D';
+					}
+					if (!isset($dom[$key]['style']['text-decoration']) AND ($dom[$key]['value'] == 'a')) {
+						$dom[$key]['fontstyle'] = $this->htmlLinkFontStyle;
+					}
+					if (($dom[$key]['value'] == 'pre') OR ($dom[$key]['value'] == 'tt')) {
+						$dom[$key]['fontname'] = $this->default_monospaced_font;
+					}
+					if (($dom[$key]['value']{0} == 'h') AND (intval($dom[$key]['value']{1}) > 0) AND (intval($dom[$key]['value']{1}) < 7)) {
+						// headings h1, h2, h3, h4, h5, h6
+						if (!isset($dom[$key]['attribute']['size']) AND !isset($dom[$key]['style']['font-size'])) {
+							$headsize = (4 - intval($dom[$key]['value']{1})) * 2;
+							$dom[$key]['fontsize'] = $dom[0]['fontsize'] + $headsize;
+						}
+						if (!isset($dom[$key]['style']['font-weight'])) {
+							$dom[$key]['fontstyle'] .= 'B';
+						}
+					}
+					if (($dom[$key]['value'] == 'table')) {
+						$dom[$key]['rows'] = 0; // number of rows
+						$dom[$key]['trids'] = array(); // IDs of TR elements
+						$dom[$key]['thead'] = ''; // table header rows
+					}
+					if (($dom[$key]['value'] == 'tr')) {
+						$dom[$key]['cols'] = 0;
+						if ($thead) {
+							$dom[$key]['thead'] = true;
+							// rows on thead block are printed as a separate table
+						} else {
+							$dom[$key]['thead'] = false;
+							// store the number of rows on table element
+							++$dom[($dom[$key]['parent'])]['rows'];
+							// store the TR elements IDs on table element
+							array_push($dom[($dom[$key]['parent'])]['trids'], $key);
+						}
+					}
+					if (($dom[$key]['value'] == 'th') OR ($dom[$key]['value'] == 'td')) {
+						if (isset($dom[$key]['attribute']['colspan'])) {
+							$colspan = intval($dom[$key]['attribute']['colspan']);
+						} else {
+							$colspan = 1;
+						}
+						$dom[$key]['attribute']['colspan'] = $colspan;
+						$dom[($dom[$key]['parent'])]['cols'] += $colspan;
+					}
+					// text direction
+					if (isset($dom[$key]['attribute']['dir'])) {
+						$dom[$key]['dir'] = $dom[$key]['attribute']['dir'];
+					}
+					// set foreground color attribute
+					if (isset($dom[$key]['attribute']['color']) AND (!$this->empty_string($dom[$key]['attribute']['color']))) {
+						$dom[$key]['fgcolor'] = $this->convertHTMLColorToDec($dom[$key]['attribute']['color']);
+					} elseif (!isset($dom[$key]['style']['color']) AND ($dom[$key]['value'] == 'a')) {
+						$dom[$key]['fgcolor'] = $this->htmlLinkColorArray;
+					}
+					// set background color attribute
+					if (isset($dom[$key]['attribute']['bgcolor']) AND (!$this->empty_string($dom[$key]['attribute']['bgcolor']))) {
+						$dom[$key]['bgcolor'] = $this->convertHTMLColorToDec($dom[$key]['attribute']['bgcolor']);
+					}
+					// set stroke color attribute
+					if (isset($dom[$key]['attribute']['strokecolor']) AND (!$this->empty_string($dom[$key]['attribute']['strokecolor']))) {
+						$dom[$key]['strokecolor'] = $this->convertHTMLColorToDec($dom[$key]['attribute']['strokecolor']);
+					}
+					// check for width attribute
+					if (isset($dom[$key]['attribute']['width'])) {
+						$dom[$key]['width'] = $dom[$key]['attribute']['width'];
+					}
+					// check for height attribute
+					if (isset($dom[$key]['attribute']['height'])) {
+						$dom[$key]['height'] = $dom[$key]['attribute']['height'];
+					}
+					// check for text alignment
+					if (isset($dom[$key]['attribute']['align']) AND (!$this->empty_string($dom[$key]['attribute']['align'])) AND ($dom[$key]['value'] !== 'img')) {
+						$dom[$key]['align'] = strtoupper($dom[$key]['attribute']['align']{0});
+					}
+					// check for text rendering mode (the following attributes do not exist in HTML)
+					if (isset($dom[$key]['attribute']['stroke'])) {
+						// font stroke width
+						$dom[$key]['stroke'] = $this->getHTMLUnitToUnits($dom[$key]['attribute']['stroke'], $dom[$key]['fontsize'], 'pt', true);
+					}
+					if (isset($dom[$key]['attribute']['fill'])) {
+						// font fill
+						if ($dom[$key]['attribute']['fill'] == 'true') {
+							$dom[$key]['fill'] = true;
+						} else {
+							$dom[$key]['fill'] = false;
+						}
+					}
+					if (isset($dom[$key]['attribute']['clip'])) {
+						// clipping mode
+						if ($dom[$key]['attribute']['clip'] == 'true') {
+							$dom[$key]['clip'] = true;
+						} else {
+							$dom[$key]['clip'] = false;
+						}
+					}
+				} // end opening tag
+			} else {
+				// text
+				$dom[$key]['tag'] = false;
+				$dom[$key]['block'] = false;
+				//$element = str_replace(' ', $this->unichr(160), $element);
+				$dom[$key]['value'] = stripslashes($this->unhtmlentities($element));
+				$dom[$key]['parent'] = end($level);
+				$dom[$key]['dir'] = $dom[$dom[$key]['parent']]['dir'];
+			}
+			++$elkey;
+			++$key;
+		}
+		return $dom;
+	}
+
+	/**
+	 * Returns the string used to find spaces
+	 * @return string
+	 * @protected
+	 * @author Nicola Asuni
+	 * @since 4.8.024 (2010-01-15)
+	 */
+	protected function getSpaceString() {
+		$spacestr = chr(32);
+		if ($this->isUnicodeFont()) {
+			$spacestr = chr(0).chr(32);
+		}
+		return $spacestr;
+	}
+
+	/**
+	 * Prints a cell (rectangular area) with optional borders, background color and html text string.
+	 * The upper-left corner of the cell corresponds to the current position. After the call, the current position moves to the right or to the next line.<br />
+	 * If automatic page breaking is enabled and the cell goes beyond the limit, a page break is done before outputting.
+	 * IMPORTANT: The HTML must be well formatted - try to clean-up it using an application like HTML-Tidy before submitting.
+	 * Supported tags are: a, b, blockquote, br, dd, del, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, img, li, ol, p, pre, small, span, strong, sub, sup, table, tcpdf, td, th, thead, tr, tt, u, ul
+	 * NOTE: all the HTML attributes must be enclosed in double-quote.
+	 * @param $w (float) Cell width. If 0, the cell extends up to the right margin.
+	 * @param $h (float) Cell minimum height. The cell extends automatically if needed.
+	 * @param $x (float) upper-left corner X coordinate
+	 * @param $y (float) upper-left corner Y coordinate
+	 * @param $html (string) html text to print. Default value: empty string.
+	 * @param $border (mixed) Indicates if borders must be drawn around the cell. The value can be a number:<ul><li>0: no border (default)</li><li>1: frame</li></ul> or a string containing some or all of the following characters (in any order):<ul><li>L: left</li><li>T: top</li><li>R: right</li><li>B: bottom</li></ul> or an array of line styles for each border group - for example: array('LTRB' => array('width' => 2, 'cap' => 'butt', 'join' => 'miter', 'dash' => 0, 'color' => array(0, 0, 0)))
+	 * @param $ln (int) Indicates where the current position should go after the call. Possible values are:<ul><li>0: to the right (or left for RTL language)</li><li>1: to the beginning of the next line</li><li>2: below</li></ul>
+Putting 1 is equivalent to putting 0 and calling Ln() just after. Default value: 0.
+	 * @param $fill (boolean) Indicates if the cell background must be painted (true) or transparent (false).
+	 * @param $reseth (boolean) if true reset the last cell height (default true).
+	 * @param $align (string) Allows to center or align the text. Possible values are:<ul><li>L : left align</li><li>C : center</li><li>R : right align</li><li>'' : empty string : left for LTR or right for RTL</li></ul>
+	 * @param $autopadding (boolean) if true, uses internal padding and automatically adjust it to account for line width.
+	 * @see Multicell(), writeHTML()
+	 * @public
+	 */
+	public function writeHTMLCell($w, $h, $x, $y, $html='', $border=0, $ln=0, $fill=false, $reseth=true, $align='', $autopadding=true) {
+		return $this->MultiCell($w, $h, $html, $border, $align, $fill, $ln, $x, $y, $reseth, 0, true, $autopadding, 0, 'T', false);
+	}
+
+	/**
+	 * Allows to preserve some HTML formatting (limited support).<br />
+	 * IMPORTANT: The HTML must be well formatted - try to clean-up it using an application like HTML-Tidy before submitting.
+	 * Supported tags are: a, b, blockquote, br, dd, del, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, img, li, ol, p, pre, small, span, strong, sub, sup, table, tcpdf, td, th, thead, tr, tt, u, ul
+	 * NOTE: all the HTML attributes must be enclosed in double-quote.
+	 * @param $html (string) text to display
+	 * @param $ln (boolean) if true add a new line after text (default = true)
+	 * @param $fill (boolean) Indicates if the background must be painted (true) or transparent (false).
+	 * @param $reseth (boolean) if true reset the last cell height (default false).
+	 * @param $cell (boolean) if true add the current left (or right for RTL) padding to each Write (default false).
+	 * @param $align (string) Allows to center or align the text. Possible values are:<ul><li>L : left align</li><li>C : center</li><li>R : right align</li><li>'' : empty string : left for LTR or right for RTL</li></ul>
+	 * @public
+	 */
+	public function writeHTML($html, $ln=true, $fill=false, $reseth=false, $cell=false, $align='') {
+		$gvars = $this->getGraphicVars();
+		// store current values
+		$prev_cell_margin = $this->cell_margin;
+		$prev_cell_padding = $this->cell_padding;
+		$prevPage = $this->page;
+		$prevlMargin = $this->lMargin;
+		$prevrMargin = $this->rMargin;
+		$curfontname = $this->FontFamily;
+		$curfontstyle = $this->FontStyle;
+		$curfontsize = $this->FontSizePt;
+		$curfontascent = $this->getFontAscent($curfontname, $curfontstyle, $curfontsize);
+		$curfontdescent = $this->getFontDescent($curfontname, $curfontstyle, $curfontsize);
+		$curfontstretcing = $this->font_stretching;
+		$curfonttracking = $this->font_spacing;
+		$this->newline = true;
+		$newline = true;
+		$startlinepage = $this->page;
+		$minstartliney = $this->y;
+		$maxbottomliney = 0;
+		$startlinex = $this->x;
+		$startliney = $this->y;
+		$yshift = 0;
+		$loop = 0;
+		$curpos = 0;
+		$this_method_vars = array();
+		$undo = false;
+		$fontaligned = false;
+		$reverse_dir = false; // true when the text direction is reversed
+		$this->premode = false;
+		if ($this->inxobj) {
+			// we are inside an XObject template
+			$pask = count($this->xobjects[$this->xobjid]['annotations']);
+		} elseif (isset($this->PageAnnots[$this->page])) {
+			$pask = count($this->PageAnnots[$this->page]);
+		} else {
+			$pask = 0;
+		}
+		if ($this->inxobj) {
+			// we are inside an XObject template
+			$startlinepos = strlen($this->xobjects[$this->xobjid]['outdata']);
+		} elseif (!$this->InFooter) {
+			if (isset($this->footerlen[$this->page])) {
+				$this->footerpos[$this->page] = $this->pagelen[$this->page] - $this->footerlen[$this->page];
+			} else {
+				$this->footerpos[$this->page] = $this->pagelen[$this->page];
+			}
+			$startlinepos = $this->footerpos[$this->page];
+		} else {
+			// we are inside the footer
+			$startlinepos = $this->pagelen[$this->page];
+		}
+		$lalign = $align;
+		$plalign = $align;
+		if ($this->rtl) {
+			$w = $this->x - $this->lMargin;
+		} else {
+			$w = $this->w - $this->rMargin - $this->x;
+		}
+		$w -= ($this->cell_padding['L'] + $this->cell_padding['R']);
+		if ($cell) {
+			if ($this->rtl) {
+				$this->x -= $this->cell_padding['R'];
+				$this->lMargin += $this->cell_padding['R'];
+			} else {
+				$this->x += $this->cell_padding['L'];
+				$this->rMargin += $this->cell_padding['L'];
+			}
+		}
+		if ($this->customlistindent >= 0) {
+			$this->listindent = $this->customlistindent;
+		} else {
+			$this->listindent = $this->GetStringWidth('000000');
+		}
+		$this->listindentlevel = 0;
+		// save previous states
+		$prev_cell_height_ratio = $this->cell_height_ratio;
+		$prev_listnum = $this->listnum;
+		$prev_listordered = $this->listordered;
+		$prev_listcount = $this->listcount;
+		$prev_lispacer = $this->lispacer;
+		$this->listnum = 0;
+		$this->listordered = array();
+		$this->listcount = array();
+		$this->lispacer = '';
+		if (($this->empty_string($this->lasth)) OR ($reseth)) {
+			// reset row height
+			$this->resetLastH();
+		}
+		$dom = $this->getHtmlDomArray($html);
+		$maxel = count($dom);
+		$key = 0;
+		$hidden_node_key = -1;
+		while ($key < $maxel) {
+			if ($dom[$key]['tag']) {
+				if ($dom[$key]['opening']) {
+					if (($hidden_node_key <= 0) AND $dom[$key]['hide']) {
+						// store the node key
+						$hidden_node_key = $key;
+					}
+				} elseif (($hidden_node_key > 0) AND ($dom[$key]['parent'] == $hidden_node_key)) {
+					// we have reached the closing tag of the hidden node
+					$hidden_node_key = 0;
+				}
+			}
+			if ($hidden_node_key >= 0) {
+				// skip this node
+				++$key;
+				if ($hidden_node_key == 0) {
+					// reset hidden mode
+					$hidden_node_key = -1;
+				}
+				continue;
+			}
+			if ($dom[$key]['tag'] AND isset($dom[$key]['attribute']['pagebreak'])) {
+				// check for pagebreak
+				if (($dom[$key]['attribute']['pagebreak'] == 'true') OR ($dom[$key]['attribute']['pagebreak'] == 'left') OR ($dom[$key]['attribute']['pagebreak'] == 'right')) {
+					// add a page (or trig AcceptPageBreak() for multicolumn mode)
+					$this->checkPageBreak($this->PageBreakTrigger + 1);
+					$this->htmlvspace = ($this->PageBreakTrigger + 1);
+				}
+				if ((($dom[$key]['attribute']['pagebreak'] == 'left') AND (((!$this->rtl) AND (($this->page % 2) == 0)) OR (($this->rtl) AND (($this->page % 2) != 0))))
+					OR (($dom[$key]['attribute']['pagebreak'] == 'right') AND (((!$this->rtl) AND (($this->page % 2) != 0)) OR (($this->rtl) AND (($this->page % 2) == 0))))) {
+					// add a page (or trig AcceptPageBreak() for multicolumn mode)
+					$this->checkPageBreak($this->PageBreakTrigger + 1);
+					$this->htmlvspace = ($this->PageBreakTrigger + 1);
+				}
+			}
+			if ($dom[$key]['tag'] AND $dom[$key]['opening'] AND isset($dom[$key]['attribute']['nobr']) AND ($dom[$key]['attribute']['nobr'] == 'true')) {
+				if (isset($dom[($dom[$key]['parent'])]['attribute']['nobr']) AND ($dom[($dom[$key]['parent'])]['attribute']['nobr'] == 'true')) {
+					$dom[$key]['attribute']['nobr'] = false;
+				} else {
+					// store current object
+					$this->startTransaction();
+					// save this method vars
+					$this_method_vars['html'] = $html;
+					$this_method_vars['ln'] = $ln;
+					$this_method_vars['fill'] = $fill;
+					$this_method_vars['reseth'] = $reseth;
+					$this_method_vars['cell'] = $cell;
+					$this_method_vars['align'] = $align;
+					$this_method_vars['gvars'] = $gvars;
+					$this_method_vars['prevPage'] = $prevPage;
+					$this_method_vars['prev_cell_margin'] = $prev_cell_margin;
+					$this_method_vars['prev_cell_padding'] = $prev_cell_padding;
+					$this_method_vars['prevlMargin'] = $prevlMargin;
+					$this_method_vars['prevrMargin'] = $prevrMargin;
+					$this_method_vars['curfontname'] = $curfontname;
+					$this_method_vars['curfontstyle'] = $curfontstyle;
+					$this_method_vars['curfontsize'] = $curfontsize;
+					$this_method_vars['curfontascent'] = $curfontascent;
+					$this_method_vars['curfontdescent'] = $curfontdescent;
+					$this_method_vars['curfontstretcing'] = $curfontstretcing;
+					$this_method_vars['curfonttracking'] = $curfonttracking;
+					$this_method_vars['minstartliney'] = $minstartliney;
+					$this_method_vars['maxbottomliney'] = $maxbottomliney;
+					$this_method_vars['yshift'] = $yshift;
+					$this_method_vars['startlinepage'] = $startlinepage;
+					$this_method_vars['startlinepos'] = $startlinepos;
+					$this_method_vars['startlinex'] = $startlinex;
+					$this_method_vars['startliney'] = $startliney;
+					$this_method_vars['newline'] = $newline;
+					$this_method_vars['loop'] = $loop;
+					$this_method_vars['curpos'] = $curpos;
+					$this_method_vars['pask'] = $pask;
+					$this_method_vars['lalign'] = $lalign;
+					$this_method_vars['plalign'] = $plalign;
+					$this_method_vars['w'] = $w;
+					$this_method_vars['prev_cell_height_ratio'] = $prev_cell_height_ratio;
+					$this_method_vars['prev_listnum'] = $prev_listnum;
+					$this_method_vars['prev_listordered'] = $prev_listordered;
+					$this_method_vars['prev_listcount'] = $prev_listcount;
+					$this_method_vars['prev_lispacer'] = $prev_lispacer;
+					$this_method_vars['fontaligned'] = $fontaligned;
+					$this_method_vars['key'] = $key;
+					$this_method_vars['dom'] = $dom;
+				}
+			}
+			// print THEAD block
+			if (($dom[$key]['value'] == 'tr') AND isset($dom[$key]['thead']) AND $dom[$key]['thead']) {
+				if (isset($dom[$key]['parent']) AND isset($dom[$dom[$key]['parent']]['thead']) AND !$this->empty_string($dom[$dom[$key]['parent']]['thead'])) {
+					$this->inthead = true;
+					// print table header (thead)
+					$this->writeHTML($this->thead, false, false, false, false, '');
+					// check if we are on a new page or on a new column
+					if (($this->y < $this->start_transaction_y) OR ($this->checkPageBreak($this->lasth, '', false))) {
+						// we are on a new page or on a new column and the total object height is less than the available vertical space.
+						// restore previous object
+						$this->rollbackTransaction(true);
+						// restore previous values
+						foreach ($this_method_vars as $vkey => $vval) {
+							$$vkey = $vval;
+						}
+						// disable table header
+						$tmp_thead = $this->thead;
+						$this->thead = '';
+						// add a page (or trig AcceptPageBreak() for multicolumn mode)
+						$pre_y = $this->y;
+						if ((!$this->checkPageBreak($this->PageBreakTrigger + 1)) AND ($this->y < $pre_y)) {
+							// fix for multicolumn mode
+							$startliney = $this->y;
+						}
+						$this->start_transaction_page = $this->page;
+						$this->start_transaction_y = $this->y;
+						// restore table header
+						$this->thead = $tmp_thead;
+						// fix table border properties
+						if (isset($dom[$dom[$key]['parent']]['attribute']['cellspacing'])) {
+							$tmp_cellspacing = $this->getHTMLUnitToUnits($dom[$dom[$key]['parent']]['attribute']['cellspacing'], 1, 'px');
+						} elseif (isset($dom[$dom[$key]['parent']]['border-spacing'])) {
+							$tmp_cellspacing = $dom[$dom[$key]['parent']]['border-spacing']['V'];
+						} else {
+							$tmp_cellspacing = 0;
+						}
+						$dom[$dom[$key]['parent']]['borderposition']['page'] = $this->page;
+						$dom[$dom[$key]['parent']]['borderposition']['column'] = $this->current_column;
+						$dom[$dom[$key]['parent']]['borderposition']['y'] = $this->y + $tmp_cellspacing;
+						$xoffset = ($this->x - $dom[$dom[$key]['parent']]['borderposition']['x']);
+						$dom[$dom[$key]['parent']]['borderposition']['x'] += $xoffset;
+						$dom[$dom[$key]['parent']]['borderposition']['xmax'] += $xoffset;
+						// print table header (thead)
+						$this->writeHTML($this->thead, false, false, false, false, '');
+					}
+				}
+				// move $key index forward to skip THEAD block
+				while ( ($key < $maxel) AND (!(
+					($dom[$key]['tag'] AND $dom[$key]['opening'] AND ($dom[$key]['value'] == 'tr') AND (!isset($dom[$key]['thead']) OR !$dom[$key]['thead']))
+					OR ($dom[$key]['tag'] AND (!$dom[$key]['opening']) AND ($dom[$key]['value'] == 'table'))) )) {
+					++$key;
+				}
+			}
+			if ($dom[$key]['tag'] OR ($key == 0)) {
+				if ((($dom[$key]['value'] == 'table') OR ($dom[$key]['value'] == 'tr')) AND (isset($dom[$key]['align']))) {
+					$dom[$key]['align'] = ($this->rtl) ? 'R' : 'L';
+				}
+				// vertically align image in line
+				if ((!$this->newline) AND ($dom[$key]['value'] == 'img') AND (isset($dom[$key]['height'])) AND ($dom[$key]['height'] > 0)) {
+					// get image height
+					$imgh = $this->getHTMLUnitToUnits($dom[$key]['height'], $this->lasth, 'px');
+					$autolinebreak = false;
+					if (isset($dom[$key]['width']) AND ($dom[$key]['width'] > 0)) {
+						$imgw = $this->getHTMLUnitToUnits($dom[$key]['width'], 1, 'px', false);
+						if (($imgw <= ($this->w - $this->lMargin - $this->rMargin - $this->cell_padding['L'] - $this->cell_padding['R']))
+							AND ((($this->rtl) AND (($this->x - $imgw) < ($this->lMargin + $this->cell_padding['L'])))
+							OR ((!$this->rtl) AND (($this->x + $imgw) > ($this->w - $this->rMargin - $this->cell_padding['R']))))) {
+							// add automatic line break
+							$autolinebreak = true;
+							$this->Ln('', $cell);
+							if ((!$dom[($key-1)]['tag']) AND ($dom[($key-1)]['value'] == ' ')) {
+								// go back to evaluate this line break
+								--$key;
+							}
+						}
+					}
+					if (!$autolinebreak) {
+						if ($this->inPageBody()) {
+							$pre_y = $this->y;
+							// check for page break
+							if ((!$this->checkPageBreak($imgh)) AND ($this->y < $pre_y)) {
+								// fix for multicolumn mode
+								$startliney = $this->y;
+							}
+						}
+						if ($this->page > $startlinepage) {
+							// fix line splitted over two pages
+							if (isset($this->footerlen[$startlinepage])) {
+								$curpos = $this->pagelen[$startlinepage] - $this->footerlen[$startlinepage];
+							}
+							// line to be moved one page forward
+							$pagebuff = $this->getPageBuffer($startlinepage);
+							$linebeg = substr($pagebuff, $startlinepos, ($curpos - $startlinepos));
+							$tstart = substr($pagebuff, 0, $startlinepos);
+							$tend = substr($this->getPageBuffer($startlinepage), $curpos);
+							// remove line from previous page
+							$this->setPageBuffer($startlinepage, $tstart.''.$tend);
+							$pagebuff = $this->getPageBuffer($this->page);
+							$tstart = substr($pagebuff, 0, $this->cntmrk[$this->page]);
+							$tend = substr($pagebuff, $this->cntmrk[$this->page]);
+							// add line start to current page
+							$yshift = ($minstartliney - $this->y);
+							if ($fontaligned) {
+								$yshift += ($curfontsize / $this->k);
+							}
+							$try = sprintf('1 0 0 1 0 %F cm', ($yshift * $this->k));
+							$this->setPageBuffer($this->page, $tstart."\nq\n".$try."\n".$linebeg."\nQ\n".$tend);
+							// shift the annotations and links
+							if (isset($this->PageAnnots[$this->page])) {
+								$next_pask = count($this->PageAnnots[$this->page]);
+							} else {
+								$next_pask = 0;
+							}
+							if (isset($this->PageAnnots[$startlinepage])) {
+								foreach ($this->PageAnnots[$startlinepage] as $pak => $pac) {
+									if ($pak >= $pask) {
+										$this->PageAnnots[$this->page][] = $pac;
+										unset($this->PageAnnots[$startlinepage][$pak]);
+										$npak = count($this->PageAnnots[$this->page]) - 1;
+										$this->PageAnnots[$this->page][$npak]['y'] -= $yshift;
+									}
+								}
+							}
+							$pask = $next_pask;
+							$startlinepos = $this->cntmrk[$this->page];
+							$startlinepage = $this->page;
+							$startliney = $this->y;
+							$this->newline = false;
+						}
+						$this->y += ((($curfontsize * $this->cell_height_ratio / $this->k) + $curfontascent - $curfontdescent) / 2) - $imgh;
+						$minstartliney = min($this->y, $minstartliney);
+						$maxbottomliney = ($startliney + ($this->FontSize * $this->cell_height_ratio));
+					}
+				} elseif (isset($dom[$key]['fontname']) OR isset($dom[$key]['fontstyle']) OR isset($dom[$key]['fontsize']) OR isset($dom[$key]['line-height'])) {
+					// account for different font size
+					$pfontname = $curfontname;
+					$pfontstyle = $curfontstyle;
+					$pfontsize = $curfontsize;
+					$fontname = isset($dom[$key]['fontname']) ? $dom[$key]['fontname'] : $curfontname;
+					$fontstyle = isset($dom[$key]['fontstyle']) ? $dom[$key]['fontstyle'] : $curfontstyle;
+					$fontsize = isset($dom[$key]['fontsize']) ? $dom[$key]['fontsize'] : $curfontsize;
+					$fontascent = $this->getFontAscent($fontname, $fontstyle, $fontsize);
+					$fontdescent = $this->getFontDescent($fontname, $fontstyle, $fontsize);
+					if (($fontname != $curfontname) OR ($fontstyle != $curfontstyle) OR ($fontsize != $curfontsize)
+						OR ($this->cell_height_ratio != $dom[$key]['line-height'])
+						OR ($dom[$key]['tag'] AND $dom[$key]['opening'] AND ($dom[$key]['value'] == 'li')) ) {
+						if (($key < ($maxel - 1)) AND (
+								($dom[$key]['tag'] AND $dom[$key]['opening'] AND ($dom[$key]['value'] == 'li'))
+								OR ($this->cell_height_ratio != $dom[$key]['line-height'])
+								OR (!$this->newline AND is_numeric($fontsize) AND is_numeric($curfontsize) AND ($fontsize >= 0) AND ($curfontsize >= 0) AND ($fontsize != $curfontsize))
+							)) {
+							if ($this->page > $startlinepage) {
+								// fix lines splitted over two pages
+								if (isset($this->footerlen[$startlinepage])) {
+									$curpos = $this->pagelen[$startlinepage] - $this->footerlen[$startlinepage];
+								}
+								// line to be moved one page forward
+								$pagebuff = $this->getPageBuffer($startlinepage);
+								$linebeg = substr($pagebuff, $startlinepos, ($curpos - $startlinepos));
+								$tstart = substr($pagebuff, 0, $startlinepos);
+								$tend = substr($this->getPageBuffer($startlinepage), $curpos);
+								// remove line start from previous page
+								$this->setPageBuffer($startlinepage, $tstart.''.$tend);
+								$pagebuff = $this->getPageBuffer($this->page);
+								$tstart = substr($pagebuff, 0, $this->cntmrk[$this->page]);
+								$tend = substr($pagebuff, $this->cntmrk[$this->page]);
+								// add line start to current page
+								$yshift = ($minstartliney - $this->y);
+								$try = sprintf('1 0 0 1 0 %F cm', ($yshift * $this->k));
+								$this->setPageBuffer($this->page, $tstart."\nq\n".$try."\n".$linebeg."\nQ\n".$tend);
+								// shift the annotations and links
+								if (isset($this->PageAnnots[$this->page])) {
+									$next_pask = count($this->PageAnnots[$this->page]);
+								} else {
+									$next_pask = 0;
+								}
+								if (isset($this->PageAnnots[$startlinepage])) {
+									foreach ($this->PageAnnots[$startlinepage] as $pak => $pac) {
+										if ($pak >= $pask) {
+											$this->PageAnnots[$this->page][] = $pac;
+											unset($this->PageAnnots[$startlinepage][$pak]);
+											$npak = count($this->PageAnnots[$this->page]) - 1;
+											$this->PageAnnots[$this->page][$npak]['y'] -= $yshift;
+										}
+									}
+								}
+								$pask = $next_pask;
+								$startlinepos = $this->cntmrk[$this->page];
+								$startlinepage = $this->page;
+								$startliney = $this->y;
+							}
+							if (!isset($dom[$key]['line-height'])) {
+								$dom[$key]['line-height'] = $this->cell_height_ratio;
+							}
+							if (!$dom[$key]['block']) {
+								if (!(isset($dom[($key + 1)]) AND $dom[($key + 1)]['tag'] AND (!$dom[($key + 1)]['opening']) AND ($dom[($key + 1)]['value'] != 'li') AND $dom[$key]['tag'] AND (!$dom[$key]['opening']))) {
+									$this->y += (((($curfontsize * $this->cell_height_ratio) - ($fontsize * $dom[$key]['line-height'])) / $this->k) + $curfontascent - $fontascent - $curfontdescent + $fontdescent) / 2;
+								}
+								if (($dom[$key]['value'] != 'sup') AND ($dom[$key]['value'] != 'sub')) {
+									$current_line_align_data = array($key, $minstartliney, $maxbottomliney);
+									if (isset($line_align_data) AND (($line_align_data[0] == ($key - 1)) OR (($line_align_data[0] == ($key - 2)) AND (isset($dom[($key - 1)])) AND (preg_match('/^([\s]+)$/', $dom[($key - 1)]['value']) > 0)))) {
+										$minstartliney = min($this->y, $line_align_data[1]);
+										$maxbottomliney = max(($this->y + (($fontsize * $this->cell_height_ratio) / $this->k)), $line_align_data[2]);
+									} else {
+										$minstartliney = min($this->y, $minstartliney);
+										$maxbottomliney = max(($this->y + (($fontsize * $this->cell_height_ratio) / $this->k)), $maxbottomliney);
+									}
+									$line_align_data = $current_line_align_data;
+								}
+							}
+							$this->cell_height_ratio = $dom[$key]['line-height'];
+							$fontaligned = true;
+						}
+						$this->SetFont($fontname, $fontstyle, $fontsize);
+						// reset row height
+						$this->resetLastH();
+						$curfontname = $fontname;
+						$curfontstyle = $fontstyle;
+						$curfontsize = $fontsize;
+						$curfontascent = $fontascent;
+						$curfontdescent = $fontdescent;
+					}
+				}
+				// set text rendering mode
+				$textstroke = isset($dom[$key]['stroke']) ? $dom[$key]['stroke'] : $this->textstrokewidth;
+				$textfill = isset($dom[$key]['fill']) ? $dom[$key]['fill'] : (($this->textrendermode % 2) == 0);
+				$textclip = isset($dom[$key]['clip']) ? $dom[$key]['clip'] : ($this->textrendermode > 3);
+				$this->setTextRenderingMode($textstroke, $textfill, $textclip);
+				if (isset($dom[$key]['font-stretch']) AND ($dom[$key]['font-stretch'] !== false)) {
+					$this->setFontStretching($dom[$key]['font-stretch']);
+				}
+				if (isset($dom[$key]['letter-spacing']) AND ($dom[$key]['letter-spacing'] !== false)) {
+					$this->setFontSpacing($dom[$key]['letter-spacing']);
+				}
+				if (($plalign == 'J') AND $dom[$key]['block']) {
+					$plalign = '';
+				}
+				// get current position on page buffer
+				$curpos = $this->pagelen[$startlinepage];
+				if (isset($dom[$key]['bgcolor']) AND ($dom[$key]['bgcolor'] !== false)) {
+					$this->SetFillColorArray($dom[$key]['bgcolor']);
+					$wfill = true;
+				} else {
+					$wfill = $fill | false;
+				}
+				if (isset($dom[$key]['fgcolor']) AND ($dom[$key]['fgcolor'] !== false)) {
+					$this->SetTextColorArray($dom[$key]['fgcolor']);
+				}
+				if (isset($dom[$key]['strokecolor']) AND ($dom[$key]['strokecolor'] !== false)) {
+					$this->SetDrawColorArray($dom[$key]['strokecolor']);
+				}
+				if (isset($dom[$key]['align'])) {
+					$lalign = $dom[$key]['align'];
+				}
+				if ($this->empty_string($lalign)) {
+					$lalign = $align;
+				}
+			}
+			// align lines
+			if ($this->newline AND (strlen($dom[$key]['value']) > 0) AND ($dom[$key]['value'] != 'td') AND ($dom[$key]['value'] != 'th')) {
+				$newline = true;
+				$fontaligned = false;
+				// we are at the beginning of a new line
+				if (isset($startlinex)) {
+					$yshift = ($minstartliney - $startliney);
+					if (($yshift > 0) OR ($this->page > $startlinepage)) {
+						$yshift = 0;
+					}
+					$t_x = 0;
+					// the last line must be shifted to be aligned as requested
+					$linew = abs($this->endlinex - $startlinex);
+					if ($this->inxobj) {
+						// we are inside an XObject template
+						$pstart = substr($this->xobjects[$this->xobjid]['outdata'], 0, $startlinepos);
+						if (isset($opentagpos)) {
+							$midpos = $opentagpos;
+						} else {
+							$midpos = 0;
+						}
+						if ($midpos > 0) {
+							$pmid = substr($this->xobjects[$this->xobjid]['outdata'], $startlinepos, ($midpos - $startlinepos));
+							$pend = substr($this->xobjects[$this->xobjid]['outdata'], $midpos);
+						} else {
+							$pmid = substr($this->xobjects[$this->xobjid]['outdata'], $startlinepos);
+							$pend = '';
+						}
+					} else {
+						$pstart = substr($this->getPageBuffer($startlinepage), 0, $startlinepos);
+						if (isset($opentagpos) AND isset($this->footerlen[$startlinepage]) AND (!$this->InFooter)) {
+							$this->footerpos[$startlinepage] = $this->pagelen[$startlinepage] - $this->footerlen[$startlinepage];
+							$midpos = min($opentagpos, $this->footerpos[$startlinepage]);
+						} elseif (isset($opentagpos)) {
+							$midpos = $opentagpos;
+						} elseif (isset($this->footerlen[$startlinepage]) AND (!$this->InFooter)) {
+							$this->footerpos[$startlinepage] = $this->pagelen[$startlinepage] - $this->footerlen[$startlinepage];
+							$midpos = $this->footerpos[$startlinepage];
+						} else {
+							$midpos = 0;
+						}
+						if ($midpos > 0) {
+							$pmid = substr($this->getPageBuffer($startlinepage), $startlinepos, ($midpos - $startlinepos));
+							$pend = substr($this->getPageBuffer($startlinepage), $midpos);
+						} else {
+							$pmid = substr($this->getPageBuffer($startlinepage), $startlinepos);
+							$pend = '';
+						}
+					}
+					if ((isset($plalign) AND ((($plalign == 'C') OR ($plalign == 'J') OR (($plalign == 'R') AND (!$this->rtl)) OR (($plalign == 'L') AND ($this->rtl)))))) {
+						// calculate shifting amount
+						$tw = $w;
+						if (($plalign == 'J') AND $this->isRTLTextDir() AND ($this->num_columns > 1)) {
+							$tw += $this->cell_padding['R'];
+						}
+						if ($this->lMargin != $prevlMargin) {
+							$tw += ($prevlMargin - $this->lMargin);
+						}
+						if ($this->rMargin != $prevrMargin) {
+							$tw += ($prevrMargin - $this->rMargin);
+						}
+						$one_space_width = $this->GetStringWidth(chr(32));
+						$no = 0; // number of spaces on a line contained on a single block
+						if ($this->isRTLTextDir()) { // RTL
+							// remove left space if exist
+							$pos1 = $this->revstrpos($pmid, '[(');
+							if ($pos1 > 0) {
+								$pos1 = intval($pos1);
+								if ($this->isUnicodeFont()) {
+									$pos2 = intval($this->revstrpos($pmid, '[('.chr(0).chr(32)));
+									$spacelen = 2;
+								} else {
+									$pos2 = intval($this->revstrpos($pmid, '[('.chr(32)));
+									$spacelen = 1;
+								}
+								if ($pos1 == $pos2) {
+									$pmid = substr($pmid, 0, ($pos1 + 2)).substr($pmid, ($pos1 + 2 + $spacelen));
+									if (substr($pmid, $pos1, 4) == '[()]') {
+										$linew -= $one_space_width;
+									} elseif ($pos1 == strpos($pmid, '[(')) {
+										$no = 1;
+									}
+								}
+							}
+						} else { // LTR
+							// remove right space if exist
+							$pos1 = $this->revstrpos($pmid, ')]');
+							if ($pos1 > 0) {
+								$pos1 = intval($pos1);
+								if ($this->isUnicodeFont()) {
+									$pos2 = intval($this->revstrpos($pmid, chr(0).chr(32).')]')) + 2;
+									$spacelen = 2;
+								} else {
+									$pos2 = intval($this->revstrpos($pmid, chr(32).')]')) + 1;
+									$spacelen = 1;
+								}
+								if ($pos1 == $pos2) {
+									$pmid = substr($pmid, 0, ($pos1 - $spacelen)).substr($pmid, $pos1);
+									$linew -= $one_space_width;
+								}
+							}
+						}
+						$mdiff = ($tw - $linew);
+						if ($plalign == 'C') {
+							if ($this->rtl) {
+								$t_x = -($mdiff / 2);
+							} else {
+								$t_x = ($mdiff / 2);
+							}
+						} elseif ($plalign == 'R') {
+							// right alignment on LTR document
+							$t_x = $mdiff;
+						} elseif ($plalign == 'L') {
+							// left alignment on RTL document
+							$t_x = -$mdiff;
+						} elseif (($plalign == 'J') AND ($plalign == $lalign)) {
+							// Justification
+							if ($this->isRTLTextDir()) {
+								// align text on the left
+								$t_x = -$mdiff;
+							}
+							$ns = 0; // number of spaces
+							$pmidtemp = $pmid;
+							// escape special characters
+							$pmidtemp = preg_replace('/[\\\][\(]/x', '\\#!#OP#!#', $pmidtemp);
+							$pmidtemp = preg_replace('/[\\\][\)]/x', '\\#!#CP#!#', $pmidtemp);
+							// search spaces
+							if (preg_match_all('/\[\(([^\)]*)\)\]/x', $pmidtemp, $lnstring, PREG_PATTERN_ORDER)) {
+								$spacestr = $this->getSpaceString();
+								$maxkk = count($lnstring[1]) - 1;
+								for ($kk=0; $kk <= $maxkk; ++$kk) {
+									// restore special characters
+									$lnstring[1][$kk] = str_replace('#!#OP#!#', '(', $lnstring[1][$kk]);
+									$lnstring[1][$kk] = str_replace('#!#CP#!#', ')', $lnstring[1][$kk]);
+									// store number of spaces on the strings
+									$lnstring[2][$kk] = substr_count($lnstring[1][$kk], $spacestr);
+									// count total spaces on line
+									$ns += $lnstring[2][$kk];
+									$lnstring[3][$kk] = $ns;
+								}
+								if ($ns == 0) {
+									$ns = 1;
+								}
+								// calculate additional space to add to each existing space
+								$spacewidth = ($mdiff / ($ns - $no)) * $this->k;
+								$spacewidthu = -1000 * ($mdiff + (($ns + $no) * $one_space_width)) / $ns / $this->FontSize;
+								if ($this->font_spacing != 0) {
+									// fixed spacing mode
+									$osw = -1000 * $this->font_spacing / $this->FontSize;
+									$spacewidthu += $osw;
+								}
+								$nsmax = $ns;
+								$ns = 0;
+								reset($lnstring);
+								$offset = 0;
+								$strcount = 0;
+								$prev_epsposbeg = 0;
+								$textpos = 0;
+								if ($this->isRTLTextDir()) {
+									$textpos = $this->wPt;
+								}
+								global $spacew;
+								while (preg_match('/([0-9\.\+\-]*)[\s](Td|cm|m|l|c|re)[\s]/x', $pmid, $strpiece, PREG_OFFSET_CAPTURE, $offset) == 1) {
+									// check if we are inside a string section '[( ... )]'
+									$stroffset = strpos($pmid, '[(', $offset);
+									if (($stroffset !== false) AND ($stroffset <= $strpiece[2][1])) {
+										// set offset to the end of string section
+										$offset = strpos($pmid, ')]', $stroffset);
+										while (($offset !== false) AND ($pmid[($offset - 1)] == '\\')) {
+											$offset = strpos($pmid, ')]', ($offset + 1));
+										}
+										if ($offset === false) {
+											$this->Error('HTML Justification: malformed PDF code.');
+										}
+										continue;
+									}
+									if ($this->isRTLTextDir()) {
+										$spacew = ($spacewidth * ($nsmax - $ns));
+									} else {
+										$spacew = ($spacewidth * $ns);
+									}
+									$offset = $strpiece[2][1] + strlen($strpiece[2][0]);
+									$epsposbeg = strpos($pmid, 'q'.$this->epsmarker, $offset);
+									$epsposend = strpos($pmid, $this->epsmarker.'Q', $offset) + strlen($this->epsmarker.'Q');
+									if ((($epsposbeg > 0) AND ($epsposend > 0) AND ($offset > $epsposbeg) AND ($offset < $epsposend))
+										OR (($epsposbeg === false) AND ($epsposend > 0) AND ($offset < $epsposend))) {
+										// shift EPS images
+										$trx = sprintf('1 0 0 1 %F 0 cm', $spacew);
+										$epsposbeg = strpos($pmid, 'q'.$this->epsmarker, ($prev_epsposbeg - 6));
+										$pmid_b = substr($pmid, 0, $epsposbeg);
+										$pmid_m = substr($pmid, $epsposbeg, ($epsposend - $epsposbeg));
+										$pmid_e = substr($pmid, $epsposend);
+										$pmid = $pmid_b."\nq\n".$trx."\n".$pmid_m."\nQ\n".$pmid_e;
+										$offset = $epsposend;
+										continue;
+
+									}
+									$prev_epsposbeg = $epsposbeg;
+									$currentxpos = 0;
+									// shift blocks of code
+									switch ($strpiece[2][0]) {
+										case 'Td':
+										case 'cm':
+										case 'm':
+										case 'l': {
+											// get current X position
+											preg_match('/([0-9\.\+\-]*)[\s]('.$strpiece[1][0].')[\s]('.$strpiece[2][0].')([\s]*)/x', $pmid, $xmatches);
+											$currentxpos = $xmatches[1];
+											$textpos = $currentxpos;
+											if (($strcount <= $maxkk) AND ($strpiece[2][0] == 'Td')) {
+												$ns = $lnstring[3][$strcount];
+												if ($this->isRTLTextDir()) {
+													$spacew = ($spacewidth * ($nsmax - $ns));
+												}
+												++$strcount;
+											}
+											// justify block
+											$pmid = preg_replace_callback('/([0-9\.\+\-]*)[\s]('.$strpiece[1][0].')[\s]('.$strpiece[2][0].')([\s]*)/x',
+												create_function('$matches', 'global $spacew;
+												$newx = sprintf("%F",(floatval($matches[1]) + $spacew));
+												return "".$newx." ".$matches[2]." x*#!#*x".$matches[3].$matches[4];'), $pmid, 1);
+											break;
+										}
+										case 're': {
+											// justify block
+											if (!$this->empty_string($this->lispacer)) {
+												$this->lispacer = '';
+												continue;
+											}
+											preg_match('/([0-9\.\+\-]*)[\s]([0-9\.\+\-]*)[\s]([0-9\.\+\-]*)[\s]('.$strpiece[1][0].')[\s](re)([\s]*)/x', $pmid, $xmatches);
+											$currentxpos = $xmatches[1];
+											global $x_diff, $w_diff;
+											$x_diff = 0;
+											$w_diff = 0;
+											if ($this->isRTLTextDir()) { // RTL
+												if ($currentxpos < $textpos) {
+													$x_diff = ($spacewidth * ($nsmax - $lnstring[3][$strcount]));
+													$w_diff = ($spacewidth * $lnstring[2][$strcount]);
+												} else {
+													if ($strcount > 0) {
+														$x_diff = ($spacewidth * ($nsmax - $lnstring[3][($strcount - 1)]));
+														$w_diff = ($spacewidth * $lnstring[2][($strcount - 1)]);
+													}
+												}
+											} else { // LTR
+												if ($currentxpos > $textpos) {
+													if ($strcount > 0) {
+														$x_diff = ($spacewidth * $lnstring[3][($strcount - 1)]);
+													}
+													$w_diff = ($spacewidth * $lnstring[2][$strcount]);
+												} else {
+													if ($strcount > 1) {
+														$x_diff = ($spacewidth * $lnstring[3][($strcount - 2)]);
+													}
+													if ($strcount > 0) {
+														$w_diff = ($spacewidth * $lnstring[2][($strcount - 1)]);
+													}
+												}
+											}
+											$pmid = preg_replace_callback('/('.$xmatches[1].')[\s]('.$xmatches[2].')[\s]('.$xmatches[3].')[\s]('.$strpiece[1][0].')[\s](re)([\s]*)/x',
+												create_function('$matches', 'global $x_diff, $w_diff;
+												$newx = sprintf("%F",(floatval($matches[1]) + $x_diff));
+												$neww = sprintf("%F",(floatval($matches[3]) + $w_diff));
+												return "".$newx." ".$matches[2]." ".$neww." ".$matches[4]." x*#!#*x".$matches[5].$matches[6];'), $pmid, 1);
+											break;
+										}
+										case 'c': {
+											// get current X position
+											preg_match('/([0-9\.\+\-]*)[\s]([0-9\.\+\-]*)[\s]([0-9\.\+\-]*)[\s]([0-9\.\+\-]*)[\s]([0-9\.\+\-]*)[\s]('.$strpiece[1][0].')[\s](c)([\s]*)/x', $pmid, $xmatches);
+											$currentxpos = $xmatches[1];
+											// justify block
+											$pmid = preg_replace_callback('/('.$xmatches[1].')[\s]('.$xmatches[2].')[\s]('.$xmatches[3].')[\s]('.$xmatches[4].')[\s]('.$xmatches[5].')[\s]('.$strpiece[1][0].')[\s](c)([\s]*)/x',
+												create_function('$matches', 'global $spacew;
+												$newx1 = sprintf("%F",(floatval($matches[1]) + $spacew));
+												$newx2 = sprintf("%F",(floatval($matches[3]) + $spacew));
+												$newx3 = sprintf("%F",(floatval($matches[5]) + $spacew));
+												return "".$newx1." ".$matches[2]." ".$newx2." ".$matches[4]." ".$newx3." ".$matches[6]." x*#!#*x".$matches[7].$matches[8];'), $pmid, 1);
+											break;
+										}
+									}
+									// shift the annotations and links
+									$cxpos = ($currentxpos / $this->k);
+									$lmpos = ($this->lMargin + $this->cell_padding['L'] + $this->feps);
+									if ($this->inxobj) {
+										// we are inside an XObject template
+										foreach ($this->xobjects[$this->xobjid]['annotations'] as $pak => $pac) {
+											if (($pac['y'] >= $minstartliney) AND (($pac['x'] * $this->k) >= ($currentxpos - $this->feps)) AND (($pac['x'] * $this->k) <= ($currentxpos + $this->feps))) {
+												if ($cxpos > $lmpos) {
+													$this->xobjects[$this->xobjid]['annotations'][$pak]['x'] += ($spacew / $this->k);
+													$this->xobjects[$this->xobjid]['annotations'][$pak]['w'] += (($spacewidth * $pac['numspaces']) / $this->k);
+												} else {
+													$this->xobjects[$this->xobjid]['annotations'][$pak]['w'] += (($spacewidth * $pac['numspaces']) / $this->k);
+												}
+												break;
+											}
+										}
+									} elseif (isset($this->PageAnnots[$this->page])) {
+										foreach ($this->PageAnnots[$this->page] as $pak => $pac) {
+											if (($pac['y'] >= $minstartliney) AND (($pac['x'] * $this->k) >= ($currentxpos - $this->feps)) AND (($pac['x'] * $this->k) <= ($currentxpos + $this->feps))) {
+												if ($cxpos > $lmpos) {
+													$this->PageAnnots[$this->page][$pak]['x'] += ($spacew / $this->k);
+													$this->PageAnnots[$this->page][$pak]['w'] += (($spacewidth * $pac['numspaces']) / $this->k);
+												} else {
+													$this->PageAnnots[$this->page][$pak]['w'] += (($spacewidth * $pac['numspaces']) / $this->k);
+												}
+												break;
+											}
+										}
+									}
+								} // end of while
+								// remove markers
+								$pmid = str_replace('x*#!#*x', '', $pmid);
+								if ($this->isUnicodeFont()) {
+									// multibyte characters
+									$spacew = $spacewidthu;
+									if ($this->font_stretching != 100) {
+										// word spacing is affected by stretching
+										$spacew /= ($this->font_stretching / 100);
+									}
+									$pmidtemp = $pmid;
+									// escape special characters
+									$pmidtemp = preg_replace('/[\\\][\(]/x', '\\#!#OP#!#', $pmidtemp);
+									$pmidtemp = preg_replace('/[\\\][\)]/x', '\\#!#CP#!#', $pmidtemp);
+									$pmid = preg_replace_callback("/\[\(([^\)]*)\)\]/x",
+												create_function('$matches', 'global $spacew;
+												$matches[1] = str_replace("#!#OP#!#", "(", $matches[1]);
+												$matches[1] = str_replace("#!#CP#!#", ")", $matches[1]);
+												return "[(".str_replace(chr(0).chr(32), ") ".sprintf("%F", $spacew)." (", $matches[1]).")]";'), $pmidtemp);
+									if ($this->inxobj) {
+										// we are inside an XObject template
+										$this->xobjects[$this->xobjid]['outdata'] = $pstart."\n".$pmid."\n".$pend;
+									} else {
+										$this->setPageBuffer($startlinepage, $pstart."\n".$pmid."\n".$pend);
+									}
+									$endlinepos = strlen($pstart."\n".$pmid."\n");
+								} else {
+									// non-unicode (single-byte characters)
+									if ($this->font_stretching != 100) {
+										// word spacing (Tw) is affected by stretching
+										$spacewidth /= ($this->font_stretching / 100);
+									}
+									$rs = sprintf('%F Tw', $spacewidth);
+									$pmid = preg_replace("/\[\(/x", $rs.' [(', $pmid);
+									if ($this->inxobj) {
+										// we are inside an XObject template
+										$this->xobjects[$this->xobjid]['outdata'] = $pstart."\n".$pmid."\nBT 0 Tw ET\n".$pend;
+									} else {
+										$this->setPageBuffer($startlinepage, $pstart."\n".$pmid."\nBT 0 Tw ET\n".$pend);
+									}
+									$endlinepos = strlen($pstart."\n".$pmid."\nBT 0 Tw ET\n");
+								}
+							}
+						} // end of J
+					} // end if $startlinex
+					if (($t_x != 0) OR ($yshift < 0)) {
+						// shift the line
+						$trx = sprintf('1 0 0 1 %F %F cm', ($t_x * $this->k), ($yshift * $this->k));
+						$pstart .= "\nq\n".$trx."\n".$pmid."\nQ\n";
+						$endlinepos = strlen($pstart);
+						if ($this->inxobj) {
+							// we are inside an XObject template
+							$this->xobjects[$this->xobjid]['outdata'] = $pstart.$pend;
+							foreach ($this->xobjects[$this->xobjid]['annotations'] as $pak => $pac) {
+								if ($pak >= $pask) {
+									$this->xobjects[$this->xobjid]['annotations'][$pak]['x'] += $t_x;
+									$this->xobjects[$this->xobjid]['annotations'][$pak]['y'] -= $yshift;
+								}
+							}
+						} else {
+							$this->setPageBuffer($startlinepage, $pstart.$pend);
+							// shift the annotations and links
+							if (isset($this->PageAnnots[$this->page])) {
+								foreach ($this->PageAnnots[$this->page] as $pak => $pac) {
+									if ($pak >= $pask) {
+										$this->PageAnnots[$this->page][$pak]['x'] += $t_x;
+										$this->PageAnnots[$this->page][$pak]['y'] -= $yshift;
+									}
+								}
+							}
+						}
+						$this->y -= $yshift;
+					}
+				}
+				$pbrk = $this->checkPageBreak($this->lasth);
+				$this->newline = false;
+				$startlinex = $this->x;
+				$startliney = $this->y;
+				if ($dom[$dom[$key]['parent']]['value'] == 'sup') {
+					$startliney -= ((0.3 * $this->FontSizePt) / $this->k);
+				} elseif ($dom[$dom[$key]['parent']]['value'] == 'sub') {
+					$startliney -= (($this->FontSizePt / 0.7) / $this->k);
+				} else {
+					$minstartliney = $startliney;
+					$maxbottomliney = ($this->y + (($fontsize * $this->cell_height_ratio) / $this->k));
+				}
+				$startlinepage = $this->page;
+				if (isset($endlinepos) AND (!$pbrk)) {
+					$startlinepos = $endlinepos;
+				} else {
+					if ($this->inxobj) {
+						// we are inside an XObject template
+						$startlinepos = strlen($this->xobjects[$this->xobjid]['outdata']);
+					} elseif (!$this->InFooter) {
+						if (isset($this->footerlen[$this->page])) {
+							$this->footerpos[$this->page] = $this->pagelen[$this->page] - $this->footerlen[$this->page];
+						} else {
+							$this->footerpos[$this->page] = $this->pagelen[$this->page];
+						}
+						$startlinepos = $this->footerpos[$this->page];
+					} else {
+						$startlinepos = $this->pagelen[$this->page];
+					}
+				}
+				unset($endlinepos);
+				$plalign = $lalign;
+				if (isset($this->PageAnnots[$this->page])) {
+					$pask = count($this->PageAnnots[$this->page]);
+				} else {
+					$pask = 0;
+				}
+				if (!($dom[$key]['tag'] AND !$dom[$key]['opening'] AND ($dom[$key]['value'] == 'table')
+					AND (isset($this->emptypagemrk[$this->page]))
+					AND ($this->emptypagemrk[$this->page] == $this->pagelen[$this->page]))) {
+					$this->SetFont($fontname, $fontstyle, $fontsize);
+					if ($wfill) {
+						$this->SetFillColorArray($this->bgcolor);
+					}
+				}
+			} // end newline
+			if (isset($opentagpos)) {
+				unset($opentagpos);
+			}
+			if ($dom[$key]['tag']) {
+				if ($dom[$key]['opening']) {
+					// get text indentation (if any)
+					if (isset($dom[$key]['text-indent']) AND $dom[$key]['block']) {
+						$this->textindent = $dom[$key]['text-indent'];
+						$this->newline = true;
+					}
+					// table
+					if ($dom[$key]['value'] == 'table') {
+						// available page width
+						if ($this->rtl) {
+							$wtmp = $this->x - $this->lMargin;
+						} else {
+							$wtmp = $this->w - $this->rMargin - $this->x;
+						}
+						// get cell spacing
+						if (isset($dom[$key]['attribute']['cellspacing'])) {
+							$clsp = $this->getHTMLUnitToUnits($dom[$key]['attribute']['cellspacing'], 1, 'px');
+							$cellspacing = array('H' => $clsp, 'V' => $clsp);
+						} elseif (isset($dom[$key]['border-spacing'])) {
+							$cellspacing = $dom[$key]['border-spacing'];
+						} else {
+							$cellspacing = array('H' => 0, 'V' => 0);
+						}
+						// table width
+						if (isset($dom[$key]['width'])) {
+							$table_width = $this->getHTMLUnitToUnits($dom[$key]['width'], $wtmp, 'px');
+						} else {
+							$table_width = $wtmp;
+						}
+						$table_width -= (2 * $cellspacing['H']);
+						if (!$this->inthead) {
+							$this->y += $cellspacing['V'];
+						}
+						if ($this->rtl) {
+							$cellspacingx = -$cellspacing['H'];
+						} else {
+							$cellspacingx = $cellspacing['H'];
+						}
+						// total table width without cellspaces
+						$table_columns_width = ($table_width - ($cellspacing['H'] * ($dom[$key]['cols'] - 1)));
+						// minimum column width
+						$table_min_column_width = ($table_columns_width / $dom[$key]['cols']);
+						// array of custom column widths
+						$table_colwidths = array_fill(0, $dom[$key]['cols'], $table_min_column_width);
+					}
+					// table row
+					if ($dom[$key]['value'] == 'tr') {
+						// reset column counter
+						$colid = 0;
+					}
+					// table cell
+					if (($dom[$key]['value'] == 'td') OR ($dom[$key]['value'] == 'th')) {
+						$trid = $dom[$key]['parent'];
+						$table_el = $dom[$trid]['parent'];
+						if (!isset($dom[$table_el]['cols'])) {
+							$dom[$table_el]['cols'] = $dom[$trid]['cols'];
+						}
+						// store border info
+						$tdborder = 0;
+						if (isset($dom[$key]['border']) AND !empty($dom[$key]['border'])) {
+							$tdborder = $dom[$key]['border'];
+						}
+						$colspan = $dom[$key]['attribute']['colspan'];
+						$old_cell_padding = $this->cell_padding;
+						if (isset($dom[($dom[$trid]['parent'])]['attribute']['cellpadding'])) {
+							$crclpd = $this->getHTMLUnitToUnits($dom[($dom[$trid]['parent'])]['attribute']['cellpadding'], 1, 'px');
+							$current_cell_padding = array('L' => $crclpd, 'T' => $crclpd, 'R' => $crclpd, 'B' => $crclpd);
+						} elseif (isset($dom[($dom[$trid]['parent'])]['padding'])) {
+							$current_cell_padding = $dom[($dom[$trid]['parent'])]['padding'];
+						} else {
+							$current_cell_padding = array('L' => 0, 'T' => 0, 'R' => 0, 'B' => 0);
+						}
+						$this->cell_padding = $current_cell_padding;
+						if (isset($dom[$key]['height'])) {
+							// minimum cell height
+							$cellh = $this->getHTMLUnitToUnits($dom[$key]['height'], 0, 'px');
+						} else {
+							$cellh = 0;
+						}
+						if (isset($dom[$key]['content'])) {
+							$cell_content = stripslashes($dom[$key]['content']);
+						} else {
+							$cell_content = ' ';
+						}
+						$tagtype = $dom[$key]['value'];
+						$parentid = $key;
+						while (($key < $maxel) AND (!(($dom[$key]['tag']) AND (!$dom[$key]['opening']) AND ($dom[$key]['value'] == $tagtype) AND ($dom[$key]['parent'] == $parentid)))) {
+							// move $key index forward
+							++$key;
+						}
+						if (!isset($dom[$trid]['startpage'])) {
+							$dom[$trid]['startpage'] = $this->page;
+						} else {
+							$this->setPage($dom[$trid]['startpage']);
+						}
+						if (!isset($dom[$trid]['startcolumn'])) {
+							$dom[$trid]['startcolumn'] = $this->current_column;
+						} elseif ($this->current_column != $dom[$trid]['startcolumn']) {
+							$tmpx = $this->x;
+							$this->selectColumn($dom[$trid]['startcolumn']);
+							$this->x = $tmpx;
+						}
+						if (!isset($dom[$trid]['starty'])) {
+							$dom[$trid]['starty'] = $this->y;
+						} else {
+							$this->y = $dom[$trid]['starty'];
+						}
+						if (!isset($dom[$trid]['startx'])) {
+							$dom[$trid]['startx'] = $this->x;
+							$this->x += $cellspacingx;
+						} else {
+							$this->x += ($cellspacingx / 2);
+						}
+						if (isset($dom[$parentid]['attribute']['rowspan'])) {
+							$rowspan = intval($dom[$parentid]['attribute']['rowspan']);
+						} else {
+							$rowspan = 1;
+						}
+						// skip row-spanned cells started on the previous rows
+						if (isset($dom[$table_el]['rowspans'])) {
+							$rsk = 0;
+							$rskmax = count($dom[$table_el]['rowspans']);
+							while ($rsk < $rskmax) {
+								$trwsp = $dom[$table_el]['rowspans'][$rsk];
+								$rsstartx = $trwsp['startx'];
+								$rsendx = $trwsp['endx'];
+								// account for margin changes
+								if ($trwsp['startpage'] < $this->page) {
+									if (($this->rtl) AND ($this->pagedim[$this->page]['orm'] != $this->pagedim[$trwsp['startpage']]['orm'])) {
+										$dl = ($this->pagedim[$this->page]['orm'] - $this->pagedim[$trwsp['startpage']]['orm']);
+										$rsstartx -= $dl;
+										$rsendx -= $dl;
+									} elseif ((!$this->rtl) AND ($this->pagedim[$this->page]['olm'] != $this->pagedim[$trwsp['startpage']]['olm'])) {
+										$dl = ($this->pagedim[$this->page]['olm'] - $this->pagedim[$trwsp['startpage']]['olm']);
+										$rsstartx += $dl;
+										$rsendx += $dl;
+									}
+								}
+								if (($trwsp['rowspan'] > 0)
+									AND ($rsstartx > ($this->x - $cellspacing['H'] - $current_cell_padding['L'] - $this->feps))
+									AND ($rsstartx < ($this->x + $cellspacing['H'] + $current_cell_padding['R'] + $this->feps))
+									AND (($trwsp['starty'] < ($this->y - $this->feps)) OR ($trwsp['startpage'] < $this->page) OR ($trwsp['startcolumn'] < $this->current_column))) {
+									// set the starting X position of the current cell
+									$this->x = $rsendx + $cellspacingx;
+									// increment column indicator
+									$colid += $trwsp['colspan'];
+									if (($trwsp['rowspan'] == 1)
+										AND (isset($dom[$trid]['endy']))
+										AND (isset($dom[$trid]['endpage']))
+										AND (isset($dom[$trid]['endcolumn']))
+										AND ($trwsp['endpage'] == $dom[$trid]['endpage'])
+										AND ($trwsp['endcolumn'] == $dom[$trid]['endcolumn'])) {
+										// set ending Y position for row
+										$dom[$table_el]['rowspans'][$rsk]['endy'] = max($dom[$trid]['endy'], $trwsp['endy']);
+										$dom[$trid]['endy'] = $dom[$table_el]['rowspans'][$rsk]['endy'];
+									}
+									$rsk = 0;
+								} else {
+									++$rsk;
+								}
+							}
+						}
+						if (isset($dom[$parentid]['width'])) {
+							// user specified width
+							$cellw = $this->getHTMLUnitToUnits($dom[$parentid]['width'], $table_columns_width, 'px');
+							$tmpcw = ($cellw / $colspan);
+							for ($i = 0; $i < $colspan; ++$i) {
+								$table_colwidths[($colid + $i)] = $tmpcw;
+							}
+						} else {
+							// inherit column width
+							$cellw = 0;
+							for ($i = 0; $i < $colspan; ++$i) {
+								$cellw += $table_colwidths[($colid + $i)];
+							}
+						}
+						$cellw += (($colspan - 1) * $cellspacing['H']);
+						// increment column indicator
+						$colid += $colspan;
+						// add rowspan information to table element
+						if ($rowspan > 1) {
+							$trsid = array_push($dom[$table_el]['rowspans'], array('trid' => $trid, 'rowspan' => $rowspan, 'mrowspan' => $rowspan, 'colspan' => $colspan, 'startpage' => $this->page, 'startcolumn' => $this->current_column, 'startx' => $this->x, 'starty' => $this->y));
+						}
+						$cellid = array_push($dom[$trid]['cellpos'], array('startx' => $this->x));
+						if ($rowspan > 1) {
+							$dom[$trid]['cellpos'][($cellid - 1)]['rowspanid'] = ($trsid - 1);
+						}
+						// push background colors
+						if (isset($dom[$parentid]['bgcolor']) AND ($dom[$parentid]['bgcolor'] !== false)) {
+							$dom[$trid]['cellpos'][($cellid - 1)]['bgcolor'] = $dom[$parentid]['bgcolor'];
+						}
+						// store border info
+						if (isset($tdborder) AND !empty($tdborder)) {
+							$dom[$trid]['cellpos'][($cellid - 1)]['border'] = $tdborder;
+						}
+						$prevLastH = $this->lasth;
+						// store some info for multicolumn mode
+						if ($this->rtl) {
+							$this->colxshift['x'] = $this->w - $this->x - $this->rMargin;
+						} else {
+							$this->colxshift['x'] = $this->x - $this->lMargin;
+						}
+						$this->colxshift['s'] = $cellspacing;
+						$this->colxshift['p'] = $current_cell_padding;
+						// ****** write the cell content ******
+						$this->MultiCell($cellw, $cellh, $cell_content, false, $lalign, false, 2, '', '', true, 0, true, true, 0, 'T', false);
+						// restore some values
+						$this->colxshift = array('x' => 0, 's' => array('H' => 0, 'V' => 0), 'p' => array('L' => 0, 'T' => 0, 'R' => 0, 'B' => 0));
+						$this->lasth = $prevLastH;
+						$this->cell_padding = $old_cell_padding;
+						$dom[$trid]['cellpos'][($cellid - 1)]['endx'] = $this->x;
+						// update the end of row position
+						if ($rowspan <= 1) {
+							if (isset($dom[$trid]['endy'])) {
+								if (($this->page == $dom[$trid]['endpage']) AND ($this->current_column == $dom[$trid]['endcolumn'])) {
+									$dom[$trid]['endy'] = max($this->y, $dom[$trid]['endy']);
+								} elseif (($this->page > $dom[$trid]['endpage']) OR ($this->current_column > $dom[$trid]['endcolumn'])) {
+									$dom[$trid]['endy'] = $this->y;
+								}
+							} else {
+								$dom[$trid]['endy'] = $this->y;
+							}
+							if (isset($dom[$trid]['endpage'])) {
+								$dom[$trid]['endpage'] = max($this->page, $dom[$trid]['endpage']);
+							} else {
+								$dom[$trid]['endpage'] = $this->page;
+							}
+							if (isset($dom[$trid]['endcolumn'])) {
+								$dom[$trid]['endcolumn'] = max($this->current_column, $dom[$trid]['endcolumn']);
+							} else {
+								$dom[$trid]['endcolumn'] = $this->current_column;
+							}
+						} else {
+							// account for row-spanned cells
+							$dom[$table_el]['rowspans'][($trsid - 1)]['endx'] = $this->x;
+							$dom[$table_el]['rowspans'][($trsid - 1)]['endy'] = $this->y;
+							$dom[$table_el]['rowspans'][($trsid - 1)]['endpage'] = $this->page;
+							$dom[$table_el]['rowspans'][($trsid - 1)]['endcolumn'] = $this->current_column;
+						}
+						if (isset($dom[$table_el]['rowspans'])) {
+							// update endy and endpage on rowspanned cells
+							foreach ($dom[$table_el]['rowspans'] as $k => $trwsp) {
+								if ($trwsp['rowspan'] > 0) {
+									if (isset($dom[$trid]['endpage'])) {
+										if (($trwsp['endpage'] == $dom[$trid]['endpage']) AND ($trwsp['endcolumn'] == $dom[$trid]['endcolumn'])) {
+											$dom[$table_el]['rowspans'][$k]['endy'] = max($dom[$trid]['endy'], $trwsp['endy']);
+										} elseif (($trwsp['endpage'] < $dom[$trid]['endpage']) OR ($trwsp['endcolumn'] < $dom[$trid]['endcolumn'])) {
+											$dom[$table_el]['rowspans'][$k]['endy'] = $dom[$trid]['endy'];
+											$dom[$table_el]['rowspans'][$k]['endpage'] = $dom[$trid]['endpage'];
+											$dom[$table_el]['rowspans'][$k]['endcolumn'] = $dom[$trid]['endcolumn'];
+										} else {
+											$dom[$trid]['endy'] = $this->pagedim[$dom[$trid]['endpage']]['hk'] - $this->pagedim[$dom[$trid]['endpage']]['bm'];
+										}
+									}
+								}
+							}
+						}
+						$this->x += ($cellspacingx / 2);
+					} else {
+						// opening tag (or self-closing tag)
+						if (!isset($opentagpos)) {
+							if ($this->inxobj) {
+								// we are inside an XObject template
+								$opentagpos = strlen($this->xobjects[$this->xobjid]['outdata']);
+							} elseif (!$this->InFooter) {
+								if (isset($this->footerlen[$this->page])) {
+									$this->footerpos[$this->page] = $this->pagelen[$this->page] - $this->footerlen[$this->page];
+								} else {
+									$this->footerpos[$this->page] = $this->pagelen[$this->page];
+								}
+								$opentagpos = $this->footerpos[$this->page];
+							}
+						}
+						$dom = $this->openHTMLTagHandler($dom, $key, $cell);
+					}
+				} else { // closing tag
+					$prev_numpages = $this->numpages;
+					$old_bordermrk = $this->bordermrk[$this->page];
+					$dom = $this->closeHTMLTagHandler($dom, $key, $cell, $maxbottomliney);
+					if ($this->bordermrk[$this->page] > $old_bordermrk) {
+						$startlinepos += ($this->bordermrk[$this->page] - $old_bordermrk);
+					}
+					if ($prev_numpages > $this->numpages) {
+						$startlinepage = $this->page;
+					}
+				}
+			} elseif (strlen($dom[$key]['value']) > 0) {
+				// print list-item
+				if (!$this->empty_string($this->lispacer) AND ($this->lispacer != '^')) {
+					$this->SetFont($pfontname, $pfontstyle, $pfontsize);
+					$this->resetLastH();
+					$minstartliney = $this->y;
+					$maxbottomliney = ($startliney + ($this->FontSize * $this->cell_height_ratio));
+					$this->putHtmlListBullet($this->listnum, $this->lispacer, $pfontsize);
+					$this->SetFont($curfontname, $curfontstyle, $curfontsize);
+					$this->resetLastH();
+					if (is_numeric($pfontsize) AND ($pfontsize > 0) AND is_numeric($curfontsize) AND ($curfontsize > 0) AND ($pfontsize != $curfontsize)) {
+						$pfontascent = $this->getFontAscent($pfontname, $pfontstyle, $pfontsize);
+						$pfontdescent = $this->getFontDescent($pfontname, $pfontstyle, $pfontsize);
+						$this->y += ((($pfontsize - $curfontsize) * $this->cell_height_ratio / $this->k) + $pfontascent - $curfontascent - $pfontdescent + $curfontdescent) / 2;
+						$minstartliney = min($this->y, $minstartliney);
+						$maxbottomliney = max(($this->y + (($pfontsize * $this->cell_height_ratio) / $this->k)), $maxbottomliney);
+					}
+				}
+				// text
+				$this->htmlvspace = 0;
+				if ((!$this->premode) AND $this->isRTLTextDir()) {
+					// reverse spaces order
+					$lsp = ''; // left spaces
+					$rsp = ''; // right spaces
+					if (preg_match('/^('.$this->re_space['p'].'+)/'.$this->re_space['m'], $dom[$key]['value'], $matches)) {
+						$lsp = $matches[1];
+					}
+					if (preg_match('/('.$this->re_space['p'].'+)$/'.$this->re_space['m'], $dom[$key]['value'], $matches)) {
+						$rsp = $matches[1];
+					}
+					$dom[$key]['value'] = $rsp.$this->stringTrim($dom[$key]['value']).$lsp;
+				}
+				if ($newline) {
+					if (!$this->premode) {
+						$prelen = strlen($dom[$key]['value']);
+						if ($this->isRTLTextDir()) {
+							// right trim except non-breaking space
+							$dom[$key]['value'] = $this->stringRightTrim($dom[$key]['value']);
+						} else {
+							// left trim except non-breaking space
+							$dom[$key]['value'] = $this->stringLeftTrim($dom[$key]['value']);
+						}
+						$postlen = strlen($dom[$key]['value']);
+						if (($postlen == 0) AND ($prelen > 0)) {
+							$dom[$key]['trimmed_space'] = true;
+						}
+					}
+					$newline = false;
+					$firstblock = true;
+				} else {
+					$firstblock = false;
+					// replace empty multiple spaces string with a single space
+					$dom[$key]['value'] = preg_replace('/^'.$this->re_space['p'].'+$/'.$this->re_space['m'], chr(32), $dom[$key]['value']);
+				}
+				$strrest = '';
+				if ($this->rtl) {
+					$this->x -= $this->textindent;
+				} else {
+					$this->x += $this->textindent;
+				}
+				if (!isset($dom[$key]['trimmed_space']) OR !$dom[$key]['trimmed_space']) {
+					$strlinelen = $this->GetStringWidth($dom[$key]['value']);
+					if (!empty($this->HREF) AND (isset($this->HREF['url']))) {
+						// HTML <a> Link
+						$hrefcolor = '';
+						if (isset($dom[($dom[$key]['parent'])]['fgcolor']) AND ($dom[($dom[$key]['parent'])]['fgcolor'] !== false)) {
+							$hrefcolor = $dom[($dom[$key]['parent'])]['fgcolor'];
+						}
+						$hrefstyle = -1;
+						if (isset($dom[($dom[$key]['parent'])]['fontstyle']) AND ($dom[($dom[$key]['parent'])]['fontstyle'] !== false)) {
+							$hrefstyle = $dom[($dom[$key]['parent'])]['fontstyle'];
+						}
+						$strrest = $this->addHtmlLink($this->HREF['url'], $dom[$key]['value'], $wfill, true, $hrefcolor, $hrefstyle, true);
+					} else {
+						$wadj = 0; // space to leave for block continuity
+						if ($this->rtl) {
+							$cwa = ($this->x - $this->lMargin);
+						} else {
+							$cwa = ($this->w - $this->rMargin - $this->x);
+						}
+						if (($strlinelen < $cwa) AND (isset($dom[($key + 1)])) AND ($dom[($key + 1)]['tag']) AND (!$dom[($key + 1)]['block'])) {
+							// check the next text blocks for continuity
+							$nkey = ($key + 1);
+							$write_block = true;
+							$same_textdir = true;
+							$tmp_fontname = $this->FontFamily;
+							$tmp_fontstyle = $this->FontStyle;
+							$tmp_fontsize = $this->FontSizePt;
+							while ($write_block AND isset($dom[$nkey])) {
+								if ($dom[$nkey]['tag']) {
+									if ($dom[$nkey]['block']) {
+										// end of block
+										$write_block = false;
+									}
+									$tmp_fontname = isset($dom[$nkey]['fontname']) ? $dom[$nkey]['fontname'] : $this->FontFamily;
+									$tmp_fontstyle = isset($dom[$nkey]['fontstyle']) ? $dom[$nkey]['fontstyle'] : $this->FontStyle;
+									$tmp_fontsize = isset($dom[$nkey]['fontsize']) ? $dom[$nkey]['fontsize'] : $this->FontSizePt;
+									$same_textdir = ($dom[$nkey]['dir'] == $dom[$key]['dir']);
+								} else {
+									$nextstr = preg_split('/'.$this->re_space['p'].'+/'.$this->re_space['m'], $dom[$nkey]['value']);
+									if (isset($nextstr[0]) AND $same_textdir) {
+										$wadj += $this->GetStringWidth($nextstr[0], $tmp_fontname, $tmp_fontstyle, $tmp_fontsize);
+										if (isset($nextstr[1])) {
+											$write_block = false;
+										}
+									}
+								}
+								++$nkey;
+							}
+						}
+						if (($wadj > 0) AND (($strlinelen + $wadj) >= $cwa)) {
+							$wadj = 0;
+							$nextstr = preg_split('/'.$this->re_space['p'].'/'.$this->re_space['m'], $dom[$key]['value']);
+							$numblks = count($nextstr);
+							if ($numblks > 1) {
+								// try to split on blank spaces
+								$wadj = ($cwa - $strlinelen + $this->GetStringWidth($nextstr[($numblks - 1)]));
+							} else {
+								// set the entire block on new line
+								$wadj = $this->GetStringWidth($nextstr[0]);
+							}
+						}
+						// check for reversed text direction
+						if (($wadj > 0) AND (($this->rtl AND ($this->tmprtl === 'L')) OR (!$this->rtl AND ($this->tmprtl === 'R')))) {
+							// LTR text on RTL direction or RTL text on LTR direction
+							$reverse_dir = true;
+							$this->rtl = !$this->rtl;
+							$revshift = ($strlinelen + $wadj + 0.000001); // add little quantity for rounding problems
+							if ($this->rtl) {
+								$this->x += $revshift;
+							} else {
+								$this->x -= $revshift;
+							}
+							$xws = $this->x;
+						}
+						// ****** write only until the end of the line and get the rest ******
+						$strrest = $this->Write($this->lasth, $dom[$key]['value'], '', $wfill, '', false, 0, true, $firstblock, 0, $wadj);
+						// restore default direction
+						if ($reverse_dir AND ($wadj == 0)) {
+							$this->x = $xws;
+							$this->rtl = !$this->rtl;
+							$reverse_dir = false;
+						}
+					}
+				}
+				$this->textindent = 0;
+				if (strlen($strrest) > 0) {
+					// store the remaining string on the previous $key position
+					$this->newline = true;
+					if ($strrest == $dom[$key]['value']) {
+						// used to avoid infinite loop
+						++$loop;
+					} else {
+						$loop = 0;
+					}
+					$dom[$key]['value'] = $strrest;
+					if ($cell) {
+						if ($this->rtl) {
+							$this->x -= $this->cell_padding['R'];
+						} else {
+							$this->x += $this->cell_padding['L'];
+						}
+					}
+					if ($loop < 3) {
+						--$key;
+					}
+				} else {
+					$loop = 0;
+					// add the positive font spacing of the last character (if any)
+					 if ($this->font_spacing > 0) {
+					 	if ($this->rtl) {
+							$this->x -= $this->font_spacing;
+						} else {
+							$this->x += $this->font_spacing;
+						}
+					}
+				}
+			}
+			++$key;
+			if (isset($dom[$key]['tag']) AND $dom[$key]['tag'] AND (!isset($dom[$key]['opening']) OR !$dom[$key]['opening']) AND isset($dom[($dom[$key]['parent'])]['attribute']['nobr']) AND ($dom[($dom[$key]['parent'])]['attribute']['nobr'] == 'true')) {
+				// check if we are on a new page or on a new column
+				if ((!$undo) AND (($this->y < $this->start_transaction_y) OR (($dom[$key]['value'] == 'tr') AND ($dom[($dom[$key]['parent'])]['endy'] < $this->start_transaction_y)))) {
+					// we are on a new page or on a new column and the total object height is less than the available vertical space.
+					// restore previous object
+					$this->rollbackTransaction(true);
+					// restore previous values
+					foreach ($this_method_vars as $vkey => $vval) {
+						$$vkey = $vval;
+					}
+					// add a page (or trig AcceptPageBreak() for multicolumn mode)
+					$pre_y = $this->y;
+					if ((!$this->checkPageBreak($this->PageBreakTrigger + 1)) AND ($this->y < $pre_y)) {
+						$startliney = $this->y;
+					}
+					$undo = true; // avoid infinite loop
+				} else {
+					$undo = false;
+				}
+			}
+		} // end for each $key
+		// align the last line
+		if (isset($startlinex)) {
+			$yshift = ($minstartliney - $startliney);
+			if (($yshift > 0) OR ($this->page > $startlinepage)) {
+				$yshift = 0;
+			}
+			$t_x = 0;
+			// the last line must be shifted to be aligned as requested
+			$linew = abs($this->endlinex - $startlinex);
+			if ($this->inxobj) {
+				// we are inside an XObject template
+				$pstart = substr($this->xobjects[$this->xobjid]['outdata'], 0, $startlinepos);
+				if (isset($opentagpos)) {
+					$midpos = $opentagpos;
+				} else {
+					$midpos = 0;
+				}
+				if ($midpos > 0) {
+					$pmid = substr($this->xobjects[$this->xobjid]['outdata'], $startlinepos, ($midpos - $startlinepos));
+					$pend = substr($this->xobjects[$this->xobjid]['outdata'], $midpos);
+				} else {
+					$pmid = substr($this->xobjects[$this->xobjid]['outdata'], $startlinepos);
+					$pend = '';
+				}
+			} else {
+				$pstart = substr($this->getPageBuffer($startlinepage), 0, $startlinepos);
+				if (isset($opentagpos) AND isset($this->footerlen[$startlinepage]) AND (!$this->InFooter)) {
+					$this->footerpos[$startlinepage] = $this->pagelen[$startlinepage] - $this->footerlen[$startlinepage];
+					$midpos = min($opentagpos, $this->footerpos[$startlinepage]);
+				} elseif (isset($opentagpos)) {
+					$midpos = $opentagpos;
+				} elseif (isset($this->footerlen[$startlinepage]) AND (!$this->InFooter)) {
+					$this->footerpos[$startlinepage] = $this->pagelen[$startlinepage] - $this->footerlen[$startlinepage];
+					$midpos = $this->footerpos[$startlinepage];
+				} else {
+					$midpos = 0;
+				}
+				if ($midpos > 0) {
+					$pmid = substr($this->getPageBuffer($startlinepage), $startlinepos, ($midpos - $startlinepos));
+					$pend = substr($this->getPageBuffer($startlinepage), $midpos);
+				} else {
+					$pmid = substr($this->getPageBuffer($startlinepage), $startlinepos);
+					$pend = '';
+				}
+			}
+			if ((isset($plalign) AND ((($plalign == 'C') OR (($plalign == 'R') AND (!$this->rtl)) OR (($plalign == 'L') AND ($this->rtl)))))) {
+				// calculate shifting amount
+				$tw = $w;
+				if ($this->lMargin != $prevlMargin) {
+					$tw += ($prevlMargin - $this->lMargin);
+				}
+				if ($this->rMargin != $prevrMargin) {
+					$tw += ($prevrMargin - $this->rMargin);
+				}
+				$one_space_width = $this->GetStringWidth(chr(32));
+				$no = 0; // number of spaces on a line contained on a single block
+				if ($this->isRTLTextDir()) { // RTL
+					// remove left space if exist
+					$pos1 = $this->revstrpos($pmid, '[(');
+					if ($pos1 > 0) {
+						$pos1 = intval($pos1);
+						if ($this->isUnicodeFont()) {
+							$pos2 = intval($this->revstrpos($pmid, '[('.chr(0).chr(32)));
+							$spacelen = 2;
+						} else {
+							$pos2 = intval($this->revstrpos($pmid, '[('.chr(32)));
+							$spacelen = 1;
+						}
+						if ($pos1 == $pos2) {
+							$pmid = substr($pmid, 0, ($pos1 + 2)).substr($pmid, ($pos1 + 2 + $spacelen));
+							if (substr($pmid, $pos1, 4) == '[()]') {
+								$linew -= $one_space_width;
+							} elseif ($pos1 == strpos($pmid, '[(')) {
+								$no = 1;
+							}
+						}
+					}
+				} else { // LTR
+					// remove right space if exist
+					$pos1 = $this->revstrpos($pmid, ')]');
+					if ($pos1 > 0) {
+						$pos1 = intval($pos1);
+						if ($this->isUnicodeFont()) {
+							$pos2 = intval($this->revstrpos($pmid, chr(0).chr(32).')]')) + 2;
+							$spacelen = 2;
+						} else {
+							$pos2 = intval($this->revstrpos($pmid, chr(32).')]')) + 1;
+							$spacelen = 1;
+						}
+						if ($pos1 == $pos2) {
+							$pmid = substr($pmid, 0, ($pos1 - $spacelen)).substr($pmid, $pos1);
+							$linew -= $one_space_width;
+						}
+					}
+				}
+				$mdiff = ($tw - $linew);
+				if ($plalign == 'C') {
+					if ($this->rtl) {
+						$t_x = -($mdiff / 2);
+					} else {
+						$t_x = ($mdiff / 2);
+					}
+				} elseif ($plalign == 'R') {
+					// right alignment on LTR document
+					$t_x = $mdiff;
+				} elseif ($plalign == 'L') {
+					// left alignment on RTL document
+					$t_x = -$mdiff;
+				}
+			} // end if startlinex
+			if (($t_x != 0) OR ($yshift < 0)) {
+				// shift the line
+				$trx = sprintf('1 0 0 1 %F %F cm', ($t_x * $this->k), ($yshift * $this->k));
+				$pstart .= "\nq\n".$trx."\n".$pmid."\nQ\n";
+				$endlinepos = strlen($pstart);
+				if ($this->inxobj) {
+					// we are inside an XObject template
+					$this->xobjects[$this->xobjid]['outdata'] = $pstart.$pend;
+					foreach ($this->xobjects[$this->xobjid]['annotations'] as $pak => $pac) {
+						if ($pak >= $pask) {
+							$this->xobjects[$this->xobjid]['annotations'][$pak]['x'] += $t_x;
+							$this->xobjects[$this->xobjid]['annotations'][$pak]['y'] -= $yshift;
+						}
+					}
+				} else {
+					$this->setPageBuffer($startlinepage, $pstart.$pend);
+					// shift the annotations and links
+					if (isset($this->PageAnnots[$this->page])) {
+						foreach ($this->PageAnnots[$this->page] as $pak => $pac) {
+							if ($pak >= $pask) {
+								$this->PageAnnots[$this->page][$pak]['x'] += $t_x;
+								$this->PageAnnots[$this->page][$pak]['y'] -= $yshift;
+							}
+						}
+					}
+				}
+				$this->y -= $yshift;
+				$yshift = 0;
+			}
+		}
+		// restore previous values
+		$this->setGraphicVars($gvars);
+		if ($this->num_columns > 1) {
+			$this->selectColumn();
+		} elseif ($this->page > $prevPage) {
+			$this->lMargin = $this->pagedim[$this->page]['olm'];
+			$this->rMargin = $this->pagedim[$this->page]['orm'];
+		}
+		// restore previous list state
+		$this->cell_height_ratio = $prev_cell_height_ratio;
+		$this->listnum = $prev_listnum;
+		$this->listordered = $prev_listordered;
+		$this->listcount = $prev_listcount;
+		$this->lispacer = $prev_lispacer;
+		if ($ln AND (!($cell AND ($dom[$key-1]['value'] == 'table')))) {
+			$this->Ln($this->lasth);
+			if ($this->y < $maxbottomliney) {
+				$this->y = $maxbottomliney;
+			}
+		}
+		unset($dom);
+	}
+
+	/**
+	 * Process opening tags.
+	 * @param $dom (array) html dom array
+	 * @param $key (int) current element id
+	 * @param $cell (boolean) if true add the default left (or right if RTL) padding to each new line (default false).
+	 * @return $dom array
+	 * @protected
+	 */
+	protected function openHTMLTagHandler($dom, $key, $cell) {
+		$tag = $dom[$key];
+		$parent = $dom[($dom[$key]['parent'])];
+		$firsttag = ($key == 1);
+		// check for text direction attribute
+		if (isset($tag['dir'])) {
+			$this->setTempRTL($tag['dir']);
+		} else {
+			$this->tmprtl = false;
+		}
+		if ($tag['block']) {
+			$hbz = 0; // distance from y to line bottom
+			$hb = 0; // vertical space between block tags
+			// calculate vertical space for block tags
+			if (isset($this->tagvspaces[$tag['value']][0]['h']) AND ($this->tagvspaces[$tag['value']][0]['h'] >= 0)) {
+				$cur_h = $this->tagvspaces[$tag['value']][0]['h'];
+			} elseif (isset($tag['fontsize'])) {
+				$cur_h = ($tag['fontsize'] / $this->k) * $this->cell_height_ratio;
+			} else {
+				$cur_h = $this->FontSize * $this->cell_height_ratio;
+			}
+			if (isset($this->tagvspaces[$tag['value']][0]['n'])) {
+				$n = $this->tagvspaces[$tag['value']][0]['n'];
+			} elseif (preg_match('/[h][0-9]/', $tag['value']) > 0) {
+				$n = 0.6;
+			} else {
+				$n = 1;
+			}
+			if ((!isset($this->tagvspaces[$tag['value']])) AND (in_array($tag['value'], array('div', 'dt', 'dd', 'li', 'br')))) {
+				$hb = 0;
+			} else {
+				$hb = ($n * $cur_h);
+			}
+			if (($this->htmlvspace <= 0) AND ($n > 0)) {
+				if (isset($parent['fontsize'])) {
+					$hbz = (($parent['fontsize'] / $this->k) * $this->cell_height_ratio);
+				} else {
+					$hbz = $this->FontSize * $this->cell_height_ratio;
+				}
+			}
+			if (isset($dom[($key - 1)]) AND ($dom[($key - 1)]['value'] == 'table')) {
+				// fix vertical space after table
+				$hbz = 0;
+			}
+		}
+		// Opening tag
+		switch($tag['value']) {
+			case 'table': {
+				$cp = 0;
+				$cs = 0;
+				$dom[$key]['rowspans'] = array();
+				if (!isset($dom[$key]['attribute']['nested']) OR ($dom[$key]['attribute']['nested'] != 'true')) {
+					$this->htmlvspace = 0;
+					// set table header
+					if (!$this->empty_string($dom[$key]['thead'])) {
+						// set table header
+						$this->thead = $dom[$key]['thead'];
+						if (!isset($this->theadMargins) OR (empty($this->theadMargins))) {
+							$this->theadMargins = array();
+							$this->theadMargins['cell_padding'] = $this->cell_padding;
+							$this->theadMargins['lmargin'] = $this->lMargin;
+							$this->theadMargins['rmargin'] = $this->rMargin;
+							$this->theadMargins['page'] = $this->page;
+							$this->theadMargins['cell'] = $cell;
+						}
+					}
+				}
+				// store current margins and page
+				$dom[$key]['old_cell_padding'] = $this->cell_padding;
+				if (isset($tag['attribute']['cellpadding'])) {
+					$pad = $this->getHTMLUnitToUnits($tag['attribute']['cellpadding'], 1, 'px');
+					$this->SetCellPadding($pad);
+				} elseif (isset($tag['padding'])) {
+					$this->cell_padding = $tag['padding'];
+				}
+				if (isset($tag['attribute']['cellspacing'])) {
+					$cs = $this->getHTMLUnitToUnits($tag['attribute']['cellspacing'], 1, 'px');
+				} elseif (isset($tag['border-spacing'])) {
+					$cs = $tag['border-spacing']['V'];
+				}
+				$prev_y = $this->y;
+				if ($this->checkPageBreak(((2 * $cp) + (2 * $cs) + $this->lasth), '', false) OR ($this->y < $prev_y)) {
+					$this->inthead = true;
+					// add a page (or trig AcceptPageBreak() for multicolumn mode)
+					$this->checkPageBreak($this->PageBreakTrigger + 1);
+				}
+				break;
+			}
+			case 'tr': {
+				// array of columns positions
+				$dom[$key]['cellpos'] = array();
+				break;
+			}
+			case 'hr': {
+				if ((isset($tag['height'])) AND ($tag['height'] != '')) {
+					$hrHeight = $this->getHTMLUnitToUnits($tag['height'], 1, 'px');
+				} else {
+					$hrHeight = $this->GetLineWidth();
+				}
+				$this->addHTMLVertSpace($hbz, ($hrHeight / 2), $cell, $firsttag);
+				$x = $this->GetX();
+				$y = $this->GetY();
+				$wtmp = $this->w - $this->lMargin - $this->rMargin;
+				if ($cell) {
+					$wtmp -= ($this->cell_padding['L'] + $this->cell_padding['R']);
+				}
+				if ((isset($tag['width'])) AND ($tag['width'] != '')) {
+					$hrWidth = $this->getHTMLUnitToUnits($tag['width'], $wtmp, 'px');
+				} else {
+					$hrWidth = $wtmp;
+				}
+				$prevlinewidth = $this->GetLineWidth();
+				$this->SetLineWidth($hrHeight);
+				$this->Line($x, $y, $x + $hrWidth, $y);
+				$this->SetLineWidth($prevlinewidth);
+				$this->addHTMLVertSpace(($hrHeight / 2), 0, $cell, !isset($dom[($key + 1)]));
+				break;
+			}
+			case 'a': {
+				if (array_key_exists('href', $tag['attribute'])) {
+					$this->HREF['url'] = $tag['attribute']['href'];
+				}
+				break;
+			}
+			case 'img': {
+				if (isset($tag['attribute']['src'])) {
+					if ($tag['attribute']['src']{0} === '@') {
+						// data stream
+						$tag['attribute']['src'] = '@'.base64_decode(substr($tag['attribute']['src'], 1));
+						$type = '';
+					} else {
+						// check for images without protocol
+						if (preg_match('%^/{2}%', $tag['attribute']['src'])) {
+							$tag['attribute']['src'] = 'http:'.$tag['attribute']['src'];
+						}
+						// replace relative path with real server path
+						if (($tag['attribute']['src'][0] == '/') AND !empty($_SERVER['DOCUMENT_ROOT']) AND ($_SERVER['DOCUMENT_ROOT'] != '/')) {
+							$findroot = strpos($tag['attribute']['src'], $_SERVER['DOCUMENT_ROOT']);
+							if (($findroot === false) OR ($findroot > 1)) {
+								if (substr($_SERVER['DOCUMENT_ROOT'], -1) == '/') {
+									$tag['attribute']['src'] = substr($_SERVER['DOCUMENT_ROOT'], 0, -1).$tag['attribute']['src'];
+								} else {
+									$tag['attribute']['src'] = $_SERVER['DOCUMENT_ROOT'].$tag['attribute']['src'];
+								}
+							}
+						}
+						$tag['attribute']['src'] = htmlspecialchars_decode(urldecode($tag['attribute']['src']));
+						$type = $this->getImageFileType($tag['attribute']['src']);
+						$testscrtype = @parse_url($tag['attribute']['src']);
+						if (!isset($testscrtype['query']) OR empty($testscrtype['query'])) {
+							// convert URL to server path
+							$tag['attribute']['src'] = str_replace(K_PATH_URL, K_PATH_MAIN, $tag['attribute']['src']);
+						}
+					}
+					if (!isset($tag['width'])) {
+						$tag['width'] = 0;
+					}
+					if (!isset($tag['height'])) {
+						$tag['height'] = 0;
+					}
+					//if (!isset($tag['attribute']['align'])) {
+						// the only alignment supported is "bottom"
+						// further development is required for other modes.
+						$tag['attribute']['align'] = 'bottom';
+					//}
+					switch($tag['attribute']['align']) {
+						case 'top': {
+							$align = 'T';
+							break;
+						}
+						case 'middle': {
+							$align = 'M';
+							break;
+						}
+						case 'bottom': {
+							$align = 'B';
+							break;
+						}
+						default: {
+							$align = 'B';
+							break;
+						}
+					}
+					$prevy = $this->y;
+					$xpos = $this->x;
+					$imglink = '';
+					if (isset($this->HREF['url']) AND !$this->empty_string($this->HREF['url'])) {
+						$imglink = $this->HREF['url'];
+						if ($imglink{0} == '#') {
+							// convert url to internal link
+							$lnkdata = explode(',', $imglink);
+							if (isset($lnkdata[0])) {
+								$page = intval(substr($lnkdata[0], 1));
+								if (empty($page) OR ($page <= 0)) {
+									$page = $this->page;
+								}
+								if (isset($lnkdata[1]) AND (strlen($lnkdata[1]) > 0)) {
+									$lnky = floatval($lnkdata[1]);
+								} else {
+									$lnky = 0;
+								}
+								$imglink = $this->AddLink();
+								$this->SetLink($imglink, $lnky, $page);
+							}
+						}
+					}
+					$border = 0;
+					if (isset($tag['border']) AND !empty($tag['border'])) {
+						// currently only support 1 (frame) or a combination of 'LTRB'
+						$border = $tag['border'];
+					}
+					$iw = '';
+					if (isset($tag['width'])) {
+						$iw = $this->getHTMLUnitToUnits($tag['width'], 1, 'px', false);
+					}
+					$ih = '';
+					if (isset($tag['height'])) {
+						$ih = $this->getHTMLUnitToUnits($tag['height'], 1, 'px', false);
+					}
+					if (($type == 'eps') OR ($type == 'ai')) {
+						$this->ImageEps($tag['attribute']['src'], $xpos, $this->y, $iw, $ih, $imglink, true, $align, '', $border, true);
+					} elseif ($type == 'svg') {
+						$this->ImageSVG($tag['attribute']['src'], $xpos, $this->y, $iw, $ih, $imglink, $align, '', $border, true);
+					} else {
+						$this->Image($tag['attribute']['src'], $xpos, $this->y, $iw, $ih, '', $imglink, $align, false, 300, '', false, false, $border, false, false, true);
+					}
+					switch($align) {
+						case 'T': {
+							$this->y = $prevy;
+							break;
+						}
+						case 'M': {
+							$this->y = (($this->img_rb_y + $prevy - ($tag['fontsize'] / $this->k)) / 2) ;
+							break;
+						}
+						case 'B': {
+							$this->y = $this->img_rb_y - ($tag['fontsize'] / $this->k);
+							break;
+						}
+					}
+				}
+				break;
+			}
+			case 'dl': {
+				++$this->listnum;
+				if ($this->listnum == 1) {
+					$this->addHTMLVertSpace($hbz, $hb, $cell, $firsttag);
+				} else {
+					$this->addHTMLVertSpace(0, 0, $cell, $firsttag);
+				}
+				break;
+			}
+			case 'dt': {
+				$this->addHTMLVertSpace($hbz, $hb, $cell, $firsttag);
+				break;
+			}
+			case 'dd': {
+				if ($this->rtl) {
+					$this->rMargin += $this->listindent;
+				} else {
+					$this->lMargin += $this->listindent;
+				}
+				++$this->listindentlevel;
+				$this->addHTMLVertSpace($hbz, $hb, $cell, $firsttag);
+				break;
+			}
+			case 'ul':
+			case 'ol': {
+				++$this->listnum;
+				if ($tag['value'] == 'ol') {
+					$this->listordered[$this->listnum] = true;
+				} else {
+					$this->listordered[$this->listnum] = false;
+				}
+				if (isset($tag['attribute']['start'])) {
+					$this->listcount[$this->listnum] = intval($tag['attribute']['start']) - 1;
+				} else {
+					$this->listcount[$this->listnum] = 0;
+				}
+				if ($this->rtl) {
+					$this->rMargin += $this->listindent;
+					$this->x -= $this->listindent;
+				} else {
+					$this->lMargin += $this->listindent;
+					$this->x += $this->listindent;
+				}
+				++$this->listindentlevel;
+				if ($this->listnum == 1) {
+					if ($key > 1) {
+						$this->addHTMLVertSpace($hbz, $hb, $cell, $firsttag);
+					}
+				} else {
+					$this->addHTMLVertSpace(0, 0, $cell, $firsttag);
+				}
+				break;
+			}
+			case 'li': {
+				if ($key > 2) {
+					$this->addHTMLVertSpace($hbz, $hb, $cell, $firsttag);
+				}
+				if ($this->listordered[$this->listnum]) {
+					// ordered item
+					if (isset($parent['attribute']['type']) AND !$this->empty_string($parent['attribute']['type'])) {
+						$this->lispacer = $parent['attribute']['type'];
+					} elseif (isset($parent['listtype']) AND !$this->empty_string($parent['listtype'])) {
+						$this->lispacer = $parent['listtype'];
+					} elseif (isset($this->lisymbol) AND !$this->empty_string($this->lisymbol)) {
+						$this->lispacer = $this->lisymbol;
+					} else {
+						$this->lispacer = '#';
+					}
+					++$this->listcount[$this->listnum];
+					if (isset($tag['attribute']['value'])) {
+						$this->listcount[$this->listnum] = intval($tag['attribute']['value']);
+					}
+				} else {
+					// unordered item
+					if (isset($parent['attribute']['type']) AND !$this->empty_string($parent['attribute']['type'])) {
+						$this->lispacer = $parent['attribute']['type'];
+					} elseif (isset($parent['listtype']) AND !$this->empty_string($parent['listtype'])) {
+						$this->lispacer = $parent['listtype'];
+					} elseif (isset($this->lisymbol) AND !$this->empty_string($this->lisymbol)) {
+						$this->lispacer = $this->lisymbol;
+					} else {
+						$this->lispacer = '!';
+					}
+				}
+				break;
+			}
+			case 'blockquote': {
+				if ($this->rtl) {
+					$this->rMargin += $this->listindent;
+				} else {
+					$this->lMargin += $this->listindent;
+				}
+				++$this->listindentlevel;
+				$this->addHTMLVertSpace($hbz, $hb, $cell, $firsttag);
+				break;
+			}
+			case 'br': {
+				$this->addHTMLVertSpace($hbz, $hb, $cell, $firsttag);
+				break;
+			}
+			case 'div': {
+				$this->addHTMLVertSpace($hbz, $hb, $cell, $firsttag);
+				break;
+			}
+			case 'p': {
+				$this->addHTMLVertSpace($hbz, $hb, $cell, $firsttag);
+				break;
+			}
+			case 'pre': {
+				$this->addHTMLVertSpace($hbz, $hb, $cell, $firsttag);
+				$this->premode = true;
+				break;
+			}
+			case 'sup': {
+				$this->SetXY($this->GetX(), $this->GetY() - ((0.7 * $this->FontSizePt) / $this->k));
+				break;
+			}
+			case 'sub': {
+				$this->SetXY($this->GetX(), $this->GetY() + ((0.3 * $this->FontSizePt) / $this->k));
+				break;
+			}
+			case 'h1':
+			case 'h2':
+			case 'h3':
+			case 'h4':
+			case 'h5':
+			case 'h6': {
+				$this->addHTMLVertSpace($hbz, $hb, $cell, $firsttag);
+				break;
+			}
+			// Form fields (since 4.8.000 - 2009-09-07)
+			case 'form': {
+				if (isset($tag['attribute']['action'])) {
+					$this->form_action = $tag['attribute']['action'];
+				} else {
+					$this->form_action = K_PATH_URL.$_SERVER['SCRIPT_NAME'];
+				}
+				if (isset($tag['attribute']['enctype'])) {
+					$this->form_enctype = $tag['attribute']['enctype'];
+				} else {
+					$this->form_enctype = 'application/x-www-form-urlencoded';
+				}
+				if (isset($tag['attribute']['method'])) {
+					$this->form_mode = $tag['attribute']['method'];
+				} else {
+					$this->form_mode = 'post';
+				}
+				break;
+			}
+			case 'input': {
+				if (isset($tag['attribute']['name']) AND !$this->empty_string($tag['attribute']['name'])) {
+					$name = $tag['attribute']['name'];
+				} else {
+					break;
+				}
+				$prop = array();
+				$opt = array();
+				if (isset($tag['attribute']['readonly']) AND !$this->empty_string($tag['attribute']['readonly'])) {
+					$prop['readonly'] = true;
+				}
+				if (isset($tag['attribute']['value']) AND !$this->empty_string($tag['attribute']['value'])) {
+					$value = $tag['attribute']['value'];
+				}
+				if (isset($tag['attribute']['maxlength']) AND !$this->empty_string($tag['attribute']['maxlength'])) {
+					$opt['maxlen'] = intval($tag['attribute']['maxlength']);
+				}
+				$h = $this->FontSize * $this->cell_height_ratio;
+				if (isset($tag['attribute']['size']) AND !$this->empty_string($tag['attribute']['size'])) {
+					$w = intval($tag['attribute']['size']) * $this->GetStringWidth(chr(32)) * 2;
+				} else {
+					$w = $h;
+				}
+				if (isset($tag['attribute']['checked']) AND (($tag['attribute']['checked'] == 'checked') OR ($tag['attribute']['checked'] == 'true'))) {
+					$checked = true;
+				} else {
+					$checked = false;
+				}
+				if (isset($tag['align'])) {
+					switch ($tag['align']) {
+						case 'C': {
+							$opt['q'] = 1;
+							break;
+						}
+						case 'R': {
+							$opt['q'] = 2;
+							break;
+						}
+						case 'L':
+						default: {
+							break;
+						}
+					}
+				}
+				switch ($tag['attribute']['type']) {
+					case 'text': {
+						if (isset($value)) {
+							$opt['v'] = $value;
+						}
+						$this->TextField($name, $w, $h, $prop, $opt, '', '', false);
+						break;
+					}
+					case 'password': {
+						if (isset($value)) {
+							$opt['v'] = $value;
+						}
+						$prop['password'] = 'true';
+						$this->TextField($name, $w, $h, $prop, $opt, '', '', false);
+						break;
+					}
+					case 'checkbox': {
+						if (!isset($value)) {
+							break;
+						}
+						$this->CheckBox($name, $w, $checked, $prop, $opt, $value, '', '', false);
+						break;
+					}
+					case 'radio': {
+						if (!isset($value)) {
+							break;
+						}
+						$this->RadioButton($name, $w, $prop, $opt, $value, $checked, '', '', false);
+						break;
+					}
+					case 'submit': {
+						if (!isset($value)) {
+							$value = 'submit';
+						}
+						$w = $this->GetStringWidth($value) * 1.5;
+						$h *= 1.6;
+						$prop = array('lineWidth'=>1, 'borderStyle'=>'beveled', 'fillColor'=>array(196, 196, 196), 'strokeColor'=>array(255, 255, 255));
+						$action = array();
+						$action['S'] = 'SubmitForm';
+						$action['F'] = $this->form_action;
+						if ($this->form_enctype != 'FDF') {
+							$action['Flags'] = array('ExportFormat');
+						}
+						if ($this->form_mode == 'get') {
+							$action['Flags'] = array('GetMethod');
+						}
+						$this->Button($name, $w, $h, $value, $action, $prop, $opt, '', '', false);
+						break;
+					}
+					case 'reset': {
+						if (!isset($value)) {
+							$value = 'reset';
+						}
+						$w = $this->GetStringWidth($value) * 1.5;
+						$h *= 1.6;
+						$prop = array('lineWidth'=>1, 'borderStyle'=>'beveled', 'fillColor'=>array(196, 196, 196), 'strokeColor'=>array(255, 255, 255));
+						$this->Button($name, $w, $h, $value, array('S'=>'ResetForm'), $prop, $opt, '', '', false);
+						break;
+					}
+					case 'file': {
+						$prop['fileSelect'] = 'true';
+						$this->TextField($name, $w, $h, $prop, $opt, '', '', false);
+						if (!isset($value)) {
+							$value = '*';
+						}
+						$w = $this->GetStringWidth($value) * 2;
+						$h *= 1.2;
+						$prop = array('lineWidth'=>1, 'borderStyle'=>'beveled', 'fillColor'=>array(196, 196, 196), 'strokeColor'=>array(255, 255, 255));
+						$jsaction = 'var f=this.getField(\''.$name.'\'); f.browseForFileToSubmit();';
+						$this->Button('FB_'.$name, $w, $h, $value, $jsaction, $prop, $opt, '', '', false);
+						break;
+					}
+					case 'hidden': {
+						if (isset($value)) {
+							$opt['v'] = $value;
+						}
+						$opt['f'] = array('invisible', 'hidden');
+						$this->TextField($name, 0, 0, $prop, $opt, '', '', false);
+						break;
+					}
+					case 'image': {
+						// THIS TYPE MUST BE FIXED
+						if (isset($tag['attribute']['src']) AND !$this->empty_string($tag['attribute']['src'])) {
+							$img = $tag['attribute']['src'];
+						} else {
+							break;
+						}
+						$value = 'img';
+						//$opt['mk'] = array('i'=>$img, 'tp'=>1, 'if'=>array('sw'=>'A', 's'=>'A', 'fb'=>false));
+						if (isset($tag['attribute']['onclick']) AND !empty($tag['attribute']['onclick'])) {
+							$jsaction = $tag['attribute']['onclick'];
+						} else {
+							$jsaction = '';
+						}
+						$this->Button($name, $w, $h, $value, $jsaction, $prop, $opt, '', '', false);
+						break;
+					}
+					case 'button': {
+						if (!isset($value)) {
+							$value = ' ';
+						}
+						$w = $this->GetStringWidth($value) * 1.5;
+						$h *= 1.6;
+						$prop = array('lineWidth'=>1, 'borderStyle'=>'beveled', 'fillColor'=>array(196, 196, 196), 'strokeColor'=>array(255, 255, 255));
+						if (isset($tag['attribute']['onclick']) AND !empty($tag['attribute']['onclick'])) {
+							$jsaction = $tag['attribute']['onclick'];
+						} else {
+							$jsaction = '';
+						}
+						$this->Button($name, $w, $h, $value, $jsaction, $prop, $opt, '', '', false);
+						break;
+					}
+				}
+				break;
+			}
+			case 'textarea': {
+				$prop = array();
+				$opt = array();
+				if (isset($tag['attribute']['readonly']) AND !$this->empty_string($tag['attribute']['readonly'])) {
+					$prop['readonly'] = true;
+				}
+				if (isset($tag['attribute']['name']) AND !$this->empty_string($tag['attribute']['name'])) {
+					$name = $tag['attribute']['name'];
+				} else {
+					break;
+				}
+				if (isset($tag['attribute']['value']) AND !$this->empty_string($tag['attribute']['value'])) {
+					$opt['v'] = $tag['attribute']['value'];
+				}
+				if (isset($tag['attribute']['cols']) AND !$this->empty_string($tag['attribute']['cols'])) {
+					$w = intval($tag['attribute']['cols']) * $this->GetStringWidth(chr(32)) * 2;
+				} else {
+					$w = 40;
+				}
+				if (isset($tag['attribute']['rows']) AND !$this->empty_string($tag['attribute']['rows'])) {
+					$h = intval($tag['attribute']['rows']) * $this->FontSize * $this->cell_height_ratio;
+				} else {
+					$h = 10;
+				}
+				$prop['multiline'] = 'true';
+				$this->TextField($name, $w, $h, $prop, $opt, '', '', false);
+				break;
+			}
+			case 'select': {
+				$h = $this->FontSize * $this->cell_height_ratio;
+				if (isset($tag['attribute']['size']) AND !$this->empty_string($tag['attribute']['size'])) {
+					$h *= ($tag['attribute']['size'] + 1);
+				}
+				$prop = array();
+				$opt = array();
+				if (isset($tag['attribute']['name']) AND !$this->empty_string($tag['attribute']['name'])) {
+					$name = $tag['attribute']['name'];
+				} else {
+					break;
+				}
+				$w = 0;
+				if (isset($tag['attribute']['opt']) AND !$this->empty_string($tag['attribute']['opt'])) {
+					$options = explode('#!NwL!#', $tag['attribute']['opt']);
+					$values = array();
+					foreach ($options as $val) {
+						if (strpos($val, '#!TaB!#') !== false) {
+							$opts = explode('#!TaB!#', $val);
+							$values[] = $opts;
+							$w = max($w, $this->GetStringWidth($opts[1]));
+						} else {
+							$values[] = $val;
+							$w = max($w, $this->GetStringWidth($val));
+						}
+					}
+				} else {
+					break;
+				}
+				$w *= 2;
+				if (isset($tag['attribute']['multiple']) AND ($tag['attribute']['multiple']='multiple')) {
+					$prop['multipleSelection'] = 'true';
+					$this->ListBox($name, $w, $h, $values, $prop, $opt, '', '', false);
+				} else {
+					$this->ComboBox($name, $w, $h, $values, $prop, $opt, '', '', false);
+				}
+				break;
+			}
+			case 'tcpdf': {
+				if (defined('K_TCPDF_CALLS_IN_HTML') AND (K_TCPDF_CALLS_IN_HTML === true)) {
+					// Special tag used to call TCPDF methods
+					if (isset($tag['attribute']['method'])) {
+						$tcpdf_method = $tag['attribute']['method'];
+						if (method_exists($this, $tcpdf_method)) {
+							if (isset($tag['attribute']['params']) AND (!empty($tag['attribute']['params']))) {
+								$params = unserialize(urldecode($tag['attribute']['params']));
+								call_user_func_array(array($this, $tcpdf_method), $params);
+							} else {
+								$this->$tcpdf_method();
+							}
+							$this->newline = true;
+						}
+					}
+				}
+				break;
+			}
+			default: {
+				break;
+			}
+		}
+		// define tags that support borders and background colors
+		$bordertags = array('blockquote','br','dd','dl','div','dt','h1','h2','h3','h4','h5','h6','hr','li','ol','p','pre','ul','tcpdf','table');
+		if (in_array($tag['value'], $bordertags)) {
+			// set border
+			$dom[$key]['borderposition'] = $this->getBorderStartPosition();
+		}
+		if ($dom[$key]['self'] AND isset($dom[$key]['attribute']['pagebreakafter'])) {
+			$pba = $dom[$key]['attribute']['pagebreakafter'];
+			// check for pagebreak
+			if (($pba == 'true') OR ($pba == 'left') OR ($pba == 'right')) {
+				// add a page (or trig AcceptPageBreak() for multicolumn mode)
+				$this->checkPageBreak($this->PageBreakTrigger + 1);
+			}
+			if ((($pba == 'left') AND (((!$this->rtl) AND (($this->page % 2) == 0)) OR (($this->rtl) AND (($this->page % 2) != 0))))
+				OR (($pba == 'right') AND (((!$this->rtl) AND (($this->page % 2) != 0)) OR (($this->rtl) AND (($this->page % 2) == 0))))) {
+				// add a page (or trig AcceptPageBreak() for multicolumn mode)
+				$this->checkPageBreak($this->PageBreakTrigger + 1);
+			}
+		}
+		return $dom;
+	}
+
+	/**
+	 * Process closing tags.
+	 * @param $dom (array) html dom array
+	 * @param $key (int) current element id
+	 * @param $cell (boolean) if true add the default left (or right if RTL) padding to each new line (default false).
+	 * @param $maxbottomliney (int) maximum y value of current line
+	 * @return $dom array
+	 * @protected
+	 */
+	protected function closeHTMLTagHandler($dom, $key, $cell, $maxbottomliney=0) {
+		$tag = $dom[$key];
+		$parent = $dom[($dom[$key]['parent'])];
+		$lasttag = ((!isset($dom[($key + 1)])) OR ((!isset($dom[($key + 2)])) AND ($dom[($key + 1)]['value'] == 'marker')));
+		$in_table_head = false;
+		// maximum x position (used to draw borders)
+		if ($this->rtl) {
+			$xmax = $this->w;
+		} else {
+			$xmax = 0;
+		}
+		if ($tag['block']) {
+			$hbz = 0; // distance from y to line bottom
+			$hb = 0; // vertical space between block tags
+			// calculate vertical space for block tags
+			if (isset($this->tagvspaces[$tag['value']][1]['h']) AND ($this->tagvspaces[$tag['value']][1]['h'] >= 0)) {
+				$pre_h = $this->tagvspaces[$tag['value']][1]['h'];
+			} elseif (isset($parent['fontsize'])) {
+				$pre_h = (($parent['fontsize'] / $this->k) * $this->cell_height_ratio);
+			} else {
+				$pre_h = $this->FontSize * $this->cell_height_ratio;
+			}
+			if (isset($this->tagvspaces[$tag['value']][1]['n'])) {
+				$n = $this->tagvspaces[$tag['value']][1]['n'];
+			} elseif (preg_match('/[h][0-9]/', $tag['value']) > 0) {
+				$n = 0.6;
+			} else {
+				$n = 1;
+			}
+			if ((!isset($this->tagvspaces[$tag['value']])) AND ($tag['value'] == 'div')) {
+				$hb = 0;
+			} else {
+				$hb = ($n * $pre_h);
+			}
+			if ($maxbottomliney > $this->PageBreakTrigger) {
+				$hbz = ($this->FontSize * $this->cell_height_ratio);
+			} elseif ($this->y < $maxbottomliney) {
+				$hbz = ($maxbottomliney - $this->y);
+			}
+		}
+		// Closing tag
+		switch($tag['value']) {
+			case 'tr': {
+				$table_el = $dom[($dom[$key]['parent'])]['parent'];
+				if (!isset($parent['endy'])) {
+					$dom[($dom[$key]['parent'])]['endy'] = $this->y;
+					$parent['endy'] = $this->y;
+				}
+				if (!isset($parent['endpage'])) {
+					$dom[($dom[$key]['parent'])]['endpage'] = $this->page;
+					$parent['endpage'] = $this->page;
+				}
+				if (!isset($parent['endcolumn'])) {
+					$dom[($dom[$key]['parent'])]['endcolumn'] = $this->current_column;
+					$parent['endcolumn'] = $this->current_column;
+				}
+				// update row-spanned cells
+				if (isset($dom[$table_el]['rowspans'])) {
+					foreach ($dom[$table_el]['rowspans'] as $k => $trwsp) {
+						$dom[$table_el]['rowspans'][$k]['rowspan'] -= 1;
+						if ($dom[$table_el]['rowspans'][$k]['rowspan'] == 0) {
+							if (($dom[$table_el]['rowspans'][$k]['endpage'] == $parent['endpage']) AND ($dom[$table_el]['rowspans'][$k]['endcolumn'] == $parent['endcolumn'])) {
+								$dom[($dom[$key]['parent'])]['endy'] = max($dom[$table_el]['rowspans'][$k]['endy'], $parent['endy']);
+							} elseif (($dom[$table_el]['rowspans'][$k]['endpage'] > $parent['endpage']) OR ($dom[$table_el]['rowspans'][$k]['endcolumn'] > $parent['endcolumn'])) {
+								$dom[($dom[$key]['parent'])]['endy'] = $dom[$table_el]['rowspans'][$k]['endy'];
+								$dom[($dom[$key]['parent'])]['endpage'] = $dom[$table_el]['rowspans'][$k]['endpage'];
+								$dom[($dom[$key]['parent'])]['endcolumn'] = $dom[$table_el]['rowspans'][$k]['endcolumn'];
+							}
+						}
+					}
+					// report new endy and endpage to the rowspanned cells
+					foreach ($dom[$table_el]['rowspans'] as $k => $trwsp) {
+						if ($dom[$table_el]['rowspans'][$k]['rowspan'] == 0) {
+							$dom[$table_el]['rowspans'][$k]['endpage'] = max($dom[$table_el]['rowspans'][$k]['endpage'], $dom[($dom[$key]['parent'])]['endpage']);
+							$dom[($dom[$key]['parent'])]['endpage'] = $dom[$table_el]['rowspans'][$k]['endpage'];
+							$dom[$table_el]['rowspans'][$k]['endcolumn'] = max($dom[$table_el]['rowspans'][$k]['endcolumn'], $dom[($dom[$key]['parent'])]['endcolumn']);
+							$dom[($dom[$key]['parent'])]['endcolumn'] = $dom[$table_el]['rowspans'][$k]['endcolumn'];
+							$dom[$table_el]['rowspans'][$k]['endy'] = max($dom[$table_el]['rowspans'][$k]['endy'], $dom[($dom[$key]['parent'])]['endy']);
+							$dom[($dom[$key]['parent'])]['endy'] = $dom[$table_el]['rowspans'][$k]['endy'];
+						}
+					}
+					// update remaining rowspanned cells
+					foreach ($dom[$table_el]['rowspans'] as $k => $trwsp) {
+						if ($dom[$table_el]['rowspans'][$k]['rowspan'] == 0) {
+							$dom[$table_el]['rowspans'][$k]['endpage'] = $dom[($dom[$key]['parent'])]['endpage'];
+							$dom[$table_el]['rowspans'][$k]['endcolumn'] = $dom[($dom[$key]['parent'])]['endcolumn'];
+							$dom[$table_el]['rowspans'][$k]['endy'] = $dom[($dom[$key]['parent'])]['endy'];
+						}
+					}
+				}
+				$this->setPage($dom[($dom[$key]['parent'])]['endpage']);
+				if ($this->num_columns > 1) {
+					$this->selectColumn($dom[($dom[$key]['parent'])]['endcolumn']);
+				}
+				$this->y = $dom[($dom[$key]['parent'])]['endy'];
+				if (isset($dom[$table_el]['attribute']['cellspacing'])) {
+					$this->y += $this->getHTMLUnitToUnits($dom[$table_el]['attribute']['cellspacing'], 1, 'px');
+				} elseif (isset($dom[$table_el]['border-spacing'])) {
+					$this->y += $dom[$table_el]['border-spacing']['V'];
+				}
+				$this->Ln(0, $cell);
+				if ($this->current_column == $parent['startcolumn']) {
+					$this->x = $parent['startx'];
+				}
+				// account for booklet mode
+				if ($this->page > $parent['startpage']) {
+					if (($this->rtl) AND ($this->pagedim[$this->page]['orm'] != $this->pagedim[$parent['startpage']]['orm'])) {
+						$this->x -= ($this->pagedim[$this->page]['orm'] - $this->pagedim[$parent['startpage']]['orm']);
+					} elseif ((!$this->rtl) AND ($this->pagedim[$this->page]['olm'] != $this->pagedim[$parent['startpage']]['olm'])) {
+						$this->x += ($this->pagedim[$this->page]['olm'] - $this->pagedim[$parent['startpage']]['olm']);
+					}
+				}
+				break;
+			}
+			case 'tablehead':
+				// closing tag used for the thead part
+				$in_table_head = true;
+				$this->inthead = false;
+			case 'table': {
+				$table_el = $parent;
+				// set default border
+				if (isset($table_el['attribute']['border']) AND ($table_el['attribute']['border'] > 0)) {
+					// set default border
+					$border = array('LTRB' => array('width' => $this->getCSSBorderWidth($table_el['attribute']['border']), 'cap'=>'square', 'join'=>'miter', 'dash'=> 0, 'color'=>array(0,0,0)));
+				} else {
+					$border = 0;
+				}
+				$default_border = $border;
+				// fix bottom line alignment of last line before page break
+				foreach ($dom[($dom[$key]['parent'])]['trids'] as $j => $trkey) {
+					// update row-spanned cells
+					if (isset($dom[($dom[$key]['parent'])]['rowspans'])) {
+						foreach ($dom[($dom[$key]['parent'])]['rowspans'] as $k => $trwsp) {
+							if (isset($prevtrkey) AND ($trwsp['trid'] == $prevtrkey) AND ($trwsp['mrowspan'] > 0)) {
+								$dom[($dom[$key]['parent'])]['rowspans'][$k]['trid'] = $trkey;
+							}
+							if ($dom[($dom[$key]['parent'])]['rowspans'][$k]['trid'] == $trkey) {
+								$dom[($dom[$key]['parent'])]['rowspans'][$k]['mrowspan'] -= 1;
+							}
+						}
+					}
+					if (isset($prevtrkey) AND ($dom[$trkey]['startpage'] > $dom[$prevtrkey]['endpage'])) {
+						$pgendy = $this->pagedim[$dom[$prevtrkey]['endpage']]['hk'] - $this->pagedim[$dom[$prevtrkey]['endpage']]['bm'];
+						$dom[$prevtrkey]['endy'] = $pgendy;
+						// update row-spanned cells
+						if (isset($dom[($dom[$key]['parent'])]['rowspans'])) {
+							foreach ($dom[($dom[$key]['parent'])]['rowspans'] as $k => $trwsp) {
+								if (($trwsp['trid'] == $trkey) AND ($trwsp['mrowspan'] > 1) AND ($trwsp['endpage'] == $dom[$prevtrkey]['endpage'])) {
+									$dom[($dom[$key]['parent'])]['rowspans'][$k]['endy'] = $pgendy;
+									$dom[($dom[$key]['parent'])]['rowspans'][$k]['mrowspan'] = -1;
+								}
+							}
+						}
+					}
+					$prevtrkey = $trkey;
+					$table_el = $dom[($dom[$key]['parent'])];
+				}
+				// for each row
+				if (count($table_el['trids']) > 0) {
+					unset($xmax);
+				}
+				foreach ($table_el['trids'] as $j => $trkey) {
+					$parent = $dom[$trkey];
+					if (!isset($xmax)) {
+						$xmax = $parent['cellpos'][(count($parent['cellpos']) - 1)]['endx'];
+					}
+					// for each cell on the row
+					foreach ($parent['cellpos'] as $k => $cellpos) {
+						if (isset($cellpos['rowspanid']) AND ($cellpos['rowspanid'] >= 0)) {
+							$cellpos['startx'] = $table_el['rowspans'][($cellpos['rowspanid'])]['startx'];
+							$cellpos['endx'] = $table_el['rowspans'][($cellpos['rowspanid'])]['endx'];
+							$endy = $table_el['rowspans'][($cellpos['rowspanid'])]['endy'];
+							$startpage = $table_el['rowspans'][($cellpos['rowspanid'])]['startpage'];
+							$endpage = $table_el['rowspans'][($cellpos['rowspanid'])]['endpage'];
+							$startcolumn = $table_el['rowspans'][($cellpos['rowspanid'])]['startcolumn'];
+							$endcolumn = $table_el['rowspans'][($cellpos['rowspanid'])]['endcolumn'];
+						} else {
+							$endy = $parent['endy'];
+							$startpage = $parent['startpage'];
+							$endpage = $parent['endpage'];
+							$startcolumn = $parent['startcolumn'];
+							$endcolumn = $parent['endcolumn'];
+						}
+						if ($this->num_columns == 0) {
+							$this->num_columns = 1;
+						}
+						if (isset($cellpos['border'])) {
+							$border = $cellpos['border'];
+						}
+						if (isset($cellpos['bgcolor']) AND ($cellpos['bgcolor']) !== false) {
+							$this->SetFillColorArray($cellpos['bgcolor']);
+							$fill = true;
+						} else {
+							$fill = false;
+						}
+						$x = $cellpos['startx'];
+						$y = $parent['starty'];
+						$starty = $y;
+						$w = abs($cellpos['endx'] - $cellpos['startx']);
+						// get border modes
+						$border_start = $this->getBorderMode($border, $position='start');
+						$border_end = $this->getBorderMode($border, $position='end');
+						$border_middle = $this->getBorderMode($border, $position='middle');
+						// design borders around HTML cells.
+						for ($page = $startpage; $page <= $endpage; ++$page) { // for each page
+							$ccode = '';
+							$this->setPage($page);
+							if ($this->num_columns < 2) {
+								// single-column mode
+								$this->x = $x;
+								$this->y = $this->tMargin;
+							}
+							// account for margin changes
+							if ($page > $startpage) {
+								if (($this->rtl) AND ($this->pagedim[$page]['orm'] != $this->pagedim[$startpage]['orm'])) {
+									$this->x -= ($this->pagedim[$page]['orm'] - $this->pagedim[$startpage]['orm']);
+								} elseif ((!$this->rtl) AND ($this->pagedim[$page]['olm'] != $this->pagedim[$startpage]['olm'])) {
+									$this->x += ($this->pagedim[$page]['olm'] - $this->pagedim[$startpage]['olm']);
+								}
+							}
+							if ($startpage == $endpage) { // single page
+								$deltacol = 0;
+								$deltath = 0;
+								for ($column = $startcolumn; $column <= $endcolumn; ++$column) { // for each column
+									$this->selectColumn($column);
+									if ($startcolumn == $endcolumn) { // single column
+										$cborder = $border;
+										$h = $endy - $parent['starty'];
+										$this->y = $y;
+										$this->x = $x;
+									} elseif ($column == $startcolumn) { // first column
+										$cborder = $border_start;
+										$this->y = $starty;
+										$this->x = $x;
+										$h = $this->h - $this->y - $this->bMargin;
+										if ($this->rtl) {
+											$deltacol = $this->x + $this->rMargin - $this->w;
+										} else {
+											$deltacol = $this->x - $this->lMargin;
+										}
+									} elseif ($column == $endcolumn) { // end column
+										$cborder = $border_end;
+										if (isset($this->columns[$column]['th']['\''.$page.'\''])) {
+											$this->y = $this->columns[$column]['th']['\''.$page.'\''];
+										}
+										$this->x += $deltacol;
+										$h = $endy - $this->y;
+									} else { // middle column
+										$cborder = $border_middle;
+										if (isset($this->columns[$column]['th']['\''.$page.'\''])) {
+											$this->y = $this->columns[$column]['th']['\''.$page.'\''];
+										}
+										$this->x += $deltacol;
+										$h = $this->h - $this->y - $this->bMargin;
+									}
+									$ccode .= $this->getCellCode($w, $h, '', $cborder, 1, '', $fill, '', 0, true)."\n";
+								} // end for each column
+							} elseif ($page == $startpage) { // first page
+								$deltacol = 0;
+								$deltath = 0;
+								for ($column = $startcolumn; $column < $this->num_columns; ++$column) { // for each column
+									$this->selectColumn($column);
+									if ($column == $startcolumn) { // first column
+										$cborder = $border_start;
+										$this->y = $starty;
+										$this->x = $x;
+										$h = $this->h - $this->y - $this->bMargin;
+										if ($this->rtl) {
+											$deltacol = $this->x + $this->rMargin - $this->w;
+										} else {
+											$deltacol = $this->x - $this->lMargin;
+										}
+									} else { // middle column
+										$cborder = $border_middle;
+										if (isset($this->columns[$column]['th']['\''.$page.'\''])) {
+											$this->y = $this->columns[$column]['th']['\''.$page.'\''];
+										}
+										$this->x += $deltacol;
+										$h = $this->h - $this->y - $this->bMargin;
+									}
+									$ccode .= $this->getCellCode($w, $h, '', $cborder, 1, '', $fill, '', 0, true)."\n";
+								} // end for each column
+							} elseif ($page == $endpage) { // last page
+								$deltacol = 0;
+								$deltath = 0;
+								for ($column = 0; $column <= $endcolumn; ++$column) { // for each column
+									$this->selectColumn($column);
+									if ($column == $endcolumn) { // end column
+										$cborder = $border_end;
+										if (isset($this->columns[$column]['th']['\''.$page.'\''])) {
+											$this->y = $this->columns[$column]['th']['\''.$page.'\''];
+										}
+										$this->x += $deltacol;
+										$h = $endy - $this->y;
+									} else { // middle column
+										$cborder = $border_middle;
+										if (isset($this->columns[$column]['th']['\''.$page.'\''])) {
+											$this->y = $this->columns[$column]['th']['\''.$page.'\''];
+										}
+										$this->x += $deltacol;
+										$h = $this->h - $this->y - $this->bMargin;
+									}
+									$ccode .= $this->getCellCode($w, $h, '', $cborder, 1, '', $fill, '', 0, true)."\n";
+								} // end for each column
+							} else { // middle page
+								$deltacol = 0;
+								$deltath = 0;
+								for ($column = 0; $column < $this->num_columns; ++$column) { // for each column
+									$this->selectColumn($column);
+									$cborder = $border_middle;
+									if (isset($this->columns[$column]['th']['\''.$page.'\''])) {
+										$this->y = $this->columns[$column]['th']['\''.$page.'\''];
+									}
+									$this->x += $deltacol;
+									$h = $this->h - $this->y - $this->bMargin;
+									$ccode .= $this->getCellCode($w, $h, '', $cborder, 1, '', $fill, '', 0, true)."\n";
+								} // end for each column
+							}
+							if ($cborder OR $fill) {
+								$offsetlen = strlen($ccode);
+								// draw border and fill
+								if ($this->inxobj) {
+									// we are inside an XObject template
+									if (end($this->xobjects[$this->xobjid]['transfmrk']) !== false) {
+										$pagemarkkey = key($this->xobjects[$this->xobjid]['transfmrk']);
+										$pagemark = $this->xobjects[$this->xobjid]['transfmrk'][$pagemarkkey];
+										$this->xobjects[$this->xobjid]['transfmrk'][$pagemarkkey] += $offsetlen;
+									} else {
+										$pagemark = $this->xobjects[$this->xobjid]['intmrk'];
+										$this->xobjects[$this->xobjid]['intmrk'] += $offsetlen;
+									}
+									$pagebuff = $this->xobjects[$this->xobjid]['outdata'];
+									$pstart = substr($pagebuff, 0, $pagemark);
+									$pend = substr($pagebuff, $pagemark);
+									$this->xobjects[$this->xobjid]['outdata'] = $pstart.$ccode.$pend;
+								} else {
+									// draw border and fill
+									if (end($this->transfmrk[$this->page]) !== false) {
+										$pagemarkkey = key($this->transfmrk[$this->page]);
+										$pagemark = $this->transfmrk[$this->page][$pagemarkkey];
+									} elseif ($this->InFooter) {
+										$pagemark = $this->footerpos[$this->page];
+									} else {
+										$pagemark = $this->intmrk[$this->page];
+									}
+									$pagebuff = $this->getPageBuffer($this->page);
+									$pstart = substr($pagebuff, 0, $pagemark);
+									$pend = substr($pagebuff, $pagemark);
+									$this->setPageBuffer($this->page, $pstart.$ccode.$pend);
+								}
+							}
+						} // end for each page
+						// restore default border
+						$border = $default_border;
+					} // end for each cell on the row
+					if (isset($table_el['attribute']['cellspacing'])) {
+						$this->y += $this->getHTMLUnitToUnits($table_el['attribute']['cellspacing'], 1, 'px');
+					} elseif (isset($table_el['border-spacing'])) {
+						$this->y += $table_el['border-spacing']['V'];
+					}
+					$this->Ln(0, $cell);
+					$this->x = $parent['startx'];
+					if ($endpage > $startpage) {
+						if (($this->rtl) AND ($this->pagedim[$endpage]['orm'] != $this->pagedim[$startpage]['orm'])) {
+							$this->x += ($this->pagedim[$endpage]['orm'] - $this->pagedim[$startpage]['orm']);
+						} elseif ((!$this->rtl) AND ($this->pagedim[$endpage]['olm'] != $this->pagedim[$startpage]['olm'])) {
+							$this->x += ($this->pagedim[$endpage]['olm'] - $this->pagedim[$startpage]['olm']);
+						}
+					}
+				}
+				if (!$in_table_head) { // we are not inside a thead section
+					$this->cell_padding = $table_el['old_cell_padding'];
+					// reset row height
+					$this->resetLastH();
+					if (($this->page == ($this->numpages - 1)) AND ($this->pageopen[$this->numpages])) {
+						$plendiff = ($this->pagelen[$this->numpages] - $this->emptypagemrk[$this->numpages]);
+						if (($plendiff > 0) AND ($plendiff < 60)) {
+							$pagediff = substr($this->getPageBuffer($this->numpages), $this->emptypagemrk[$this->numpages], $plendiff);
+							if (substr($pagediff, 0, 5) == 'BT /F') {
+								// the difference is only a font setting
+								$plendiff = 0;
+							}
+						}
+						if ($plendiff == 0) {
+							// remove last blank page
+							$this->deletePage($this->numpages);
+						}
+					}
+					if (isset($this->theadMargins['top'])) {
+						// restore top margin
+						$this->tMargin = $this->theadMargins['top'];
+					}
+					if (!isset($table_el['attribute']['nested']) OR ($table_el['attribute']['nested'] != 'true')) {
+						// reset main table header
+						$this->thead = '';
+						$this->theadMargins = array();
+						$this->pagedim[$this->page]['tm'] = $this->tMargin;
+					}
+				}
+				$parent = $table_el;
+				break;
+			}
+			case 'a': {
+				$this->HREF = '';
+				break;
+			}
+			case 'sup': {
+				$this->SetXY($this->GetX(), $this->GetY() + ((0.7 * $parent['fontsize']) / $this->k));
+				break;
+			}
+			case 'sub': {
+				$this->SetXY($this->GetX(), $this->GetY() - ((0.3 * $parent['fontsize']) / $this->k));
+				break;
+			}
+			case 'div': {
+				$this->addHTMLVertSpace($hbz, $hb, $cell, false, $lasttag);
+				break;
+			}
+			case 'blockquote': {
+				if ($this->rtl) {
+					$this->rMargin -= $this->listindent;
+				} else {
+					$this->lMargin -= $this->listindent;
+				}
+				--$this->listindentlevel;
+				$this->addHTMLVertSpace($hbz, $hb, $cell, false, $lasttag);
+				break;
+			}
+			case 'p': {
+				$this->addHTMLVertSpace($hbz, $hb, $cell, false, $lasttag);
+				break;
+			}
+			case 'pre': {
+				$this->addHTMLVertSpace($hbz, $hb, $cell, false, $lasttag);
+				$this->premode = false;
+				break;
+			}
+			case 'dl': {
+				--$this->listnum;
+				if ($this->listnum <= 0) {
+					$this->listnum = 0;
+					$this->addHTMLVertSpace($hbz, $hb, $cell, false, $lasttag);
+				} else {
+					$this->addHTMLVertSpace(0, 0, $cell, false, $lasttag);
+				}
+				$this->resetLastH();
+				break;
+			}
+			case 'dt': {
+				$this->lispacer = '';
+				$this->addHTMLVertSpace(0, 0, $cell, false, $lasttag);
+				break;
+			}
+			case 'dd': {
+				$this->lispacer = '';
+				if ($this->rtl) {
+					$this->rMargin -= $this->listindent;
+				} else {
+					$this->lMargin -= $this->listindent;
+				}
+				--$this->listindentlevel;
+				$this->addHTMLVertSpace(0, 0, $cell, false, $lasttag);
+				break;
+			}
+			case 'ul':
+			case 'ol': {
+				--$this->listnum;
+				$this->lispacer = '';
+				if ($this->rtl) {
+					$this->rMargin -= $this->listindent;
+				} else {
+					$this->lMargin -= $this->listindent;
+				}
+				--$this->listindentlevel;
+				if ($this->listnum <= 0) {
+					$this->listnum = 0;
+					$this->addHTMLVertSpace($hbz, $hb, $cell, false, $lasttag);
+				} else {
+					$this->addHTMLVertSpace(0, 0, $cell, false, $lasttag);
+				}
+				$this->resetLastH();
+				break;
+			}
+			case 'li': {
+				$this->lispacer = '';
+				$this->addHTMLVertSpace(0, 0, $cell, false, $lasttag);
+				break;
+			}
+			case 'h1':
+			case 'h2':
+			case 'h3':
+			case 'h4':
+			case 'h5':
+			case 'h6': {
+				$this->addHTMLVertSpace($hbz, $hb, $cell, false, $lasttag);
+				break;
+			}
+			// Form fields (since 4.8.000 - 2009-09-07)
+			case 'form': {
+				$this->form_action = '';
+				$this->form_enctype = 'application/x-www-form-urlencoded';
+				break;
+			}
+			default : {
+				break;
+			}
+		}
+		// draw border and background (if any)
+		$this->drawHTMLTagBorder($parent, $xmax);
+		if (isset($dom[($dom[$key]['parent'])]['attribute']['pagebreakafter'])) {
+			$pba = $dom[($dom[$key]['parent'])]['attribute']['pagebreakafter'];
+			// check for pagebreak
+			if (($pba == 'true') OR ($pba == 'left') OR ($pba == 'right')) {
+				// add a page (or trig AcceptPageBreak() for multicolumn mode)
+				$this->checkPageBreak($this->PageBreakTrigger + 1);
+			}
+			if ((($pba == 'left') AND (((!$this->rtl) AND (($this->page % 2) == 0)) OR (($this->rtl) AND (($this->page % 2) != 0))))
+				OR (($pba == 'right') AND (((!$this->rtl) AND (($this->page % 2) != 0)) OR (($this->rtl) AND (($this->page % 2) == 0))))) {
+				// add a page (or trig AcceptPageBreak() for multicolumn mode)
+				$this->checkPageBreak($this->PageBreakTrigger + 1);
+			}
+		}
+		$this->tmprtl = false;
+		return $dom;
+	}
+
+	/**
+	 * Add vertical spaces if needed.
+	 * @param $hbz (string) Distance between current y and line bottom.
+	 * @param $hb (string) The height of the break.
+	 * @param $cell (boolean) if true add the default left (or right if RTL) padding to each new line (default false).
+	 * @param $firsttag (boolean) set to true when the tag is the first.
+	 * @param $lasttag (boolean) set to true when the tag is the last.
+	 * @protected
+	 */
+	protected function addHTMLVertSpace($hbz=0, $hb=0, $cell=false, $firsttag=false, $lasttag=false) {
+		if ($firsttag) {
+			$this->Ln(0, $cell);
+			$this->htmlvspace = 0;
+			return;
+		}
+		if ($lasttag) {
+			$this->Ln($hbz, $cell);
+			$this->htmlvspace = 0;
+			return;
+		}
+		if ($hb < $this->htmlvspace) {
+			$hd = 0;
+		} else {
+			$hd = $hb - $this->htmlvspace;
+			$this->htmlvspace = $hb;
+		}
+		$this->Ln(($hbz + $hd), $cell);
+	}
+
+	/**
+	 * Return the starting coordinates to draw an html border
+	 * @return array containing top-left border coordinates
+	 * @protected
+	 * @since 5.7.000 (2010-08-03)
+	 */
+	protected function getBorderStartPosition() {
+		if ($this->rtl) {
+			$xmax = $this->lMargin;
+		} else {
+			$xmax = $this->w - $this->rMargin;
+		}
+		return array('page' => $this->page, 'column' => $this->current_column, 'x' => $this->x, 'y' => $this->y, 'xmax' => $xmax);
+	}
+
+	/**
+	 * Draw an HTML block border and fill
+	 * @param $tag (array) array of tag properties.
+	 * @param $xmax (int) end X coordinate for border.
+	 * @protected
+	 * @since 5.7.000 (2010-08-03)
+	 */
+	protected function drawHTMLTagBorder($tag, $xmax) {
+		if (!isset($tag['borderposition'])) {
+			// nothing to draw
+			return;
+		}
+		$prev_x = $this->x;
+		$prev_y = $this->y;
+		$prev_lasth = $this->lasth;
+		$border = 0;
+		$fill = false;
+		$this->lasth = 0;
+		if (isset($tag['border']) AND !empty($tag['border'])) {
+			// get border style
+			$border = $tag['border'];
+			if (!$this->empty_string($this->thead) AND (!$this->inthead)) {
+				// border for table header
+				$border = $this->getBorderMode($border, $position='middle');
+			}
+		}
+		if (isset($tag['bgcolor']) AND ($tag['bgcolor'] !== false)) {
+			// get background color
+			$old_bgcolor = $this->bgcolor;
+			$this->SetFillColorArray($tag['bgcolor']);
+			$fill = true;
+		}
+		if (!$border AND !$fill) {
+			// nothing to draw
+			return;
+		}
+		if (isset($tag['attribute']['cellspacing'])) {
+			$clsp = $this->getHTMLUnitToUnits($tag['attribute']['cellspacing'], 1, 'px');
+			$cellspacing = array('H' => $clsp, 'V' => $clsp);
+		} elseif (isset($tag['border-spacing'])) {
+			$cellspacing = $tag['border-spacing'];
+		} else {
+			$cellspacing = array('H' => 0, 'V' => 0);
+		}
+		if (($tag['value'] != 'table') AND (is_array($border)) AND (!empty($border))) {
+			// draw the border externally respect the sqare edge.
+			$border['mode'] = 'ext';
+		}
+		if ($this->rtl) {
+			if ($xmax >= $tag['borderposition']['x']) {
+				$xmax = $tag['borderposition']['xmax'];
+			}
+			$w = ($tag['borderposition']['x'] - $xmax);
+		} else {
+			if ($xmax <= $tag['borderposition']['x']) {
+				$xmax = $tag['borderposition']['xmax'];
+			}
+			$w = ($xmax - $tag['borderposition']['x']);
+		}
+		if ($w <= 0) {
+			return;
+		}
+		$w += $cellspacing['H'];
+		$startpage = $tag['borderposition']['page'];
+		$startcolumn = $tag['borderposition']['column'];
+		$x = $tag['borderposition']['x'];
+		$y = $tag['borderposition']['y'];
+		$endpage = $this->page;
+		$starty = $tag['borderposition']['y'] - $cellspacing['V'];
+		$currentY = $this->y;
+		$this->x = $x;
+		// get latest column
+		$endcolumn = $this->current_column;
+		if ($this->num_columns == 0) {
+			$this->num_columns = 1;
+		}
+		// get border modes
+		$border_start = $this->getBorderMode($border, $position='start');
+		$border_end = $this->getBorderMode($border, $position='end');
+		$border_middle = $this->getBorderMode($border, $position='middle');
+		// temporary disable page regions
+		$temp_page_regions = $this->page_regions;
+		$this->page_regions = array();
+		// design borders around HTML cells.
+		for ($page = $startpage; $page <= $endpage; ++$page) { // for each page
+			$ccode = '';
+			$this->setPage($page);
+			if ($this->num_columns < 2) {
+				// single-column mode
+				$this->x = $x;
+				$this->y = $this->tMargin;
+			}
+			// account for margin changes
+			if ($page > $startpage) {
+				if (($this->rtl) AND ($this->pagedim[$page]['orm'] != $this->pagedim[$startpage]['orm'])) {
+					$this->x -= ($this->pagedim[$page]['orm'] - $this->pagedim[$startpage]['orm']);
+				} elseif ((!$this->rtl) AND ($this->pagedim[$page]['olm'] != $this->pagedim[$startpage]['olm'])) {
+					$this->x += ($this->pagedim[$page]['olm'] - $this->pagedim[$startpage]['olm']);
+				}
+			}
+			if ($startpage == $endpage) {
+				// single page
+				for ($column = $startcolumn; $column <= $endcolumn; ++$column) { // for each column
+					$this->selectColumn($column);
+					if ($startcolumn == $endcolumn) { // single column
+						$cborder = $border;
+						$h = ($currentY - $y) + $cellspacing['V'];
+						$this->y = $starty;
+					} elseif ($column == $startcolumn) { // first column
+						$cborder = $border_start;
+						$this->y = $starty;
+						$h = $this->h - $this->y - $this->bMargin;
+					} elseif ($column == $endcolumn) { // end column
+						$cborder = $border_end;
+						$h = $currentY - $this->y;
+					} else { // middle column
+						$cborder = $border_middle;
+						$h = $this->h - $this->y - $this->bMargin;
+					}
+					$ccode .= $this->getCellCode($w, $h, '', $cborder, 1, '', $fill, '', 0, true)."\n";
+				} // end for each column
+			} elseif ($page == $startpage) { // first page
+				for ($column = $startcolumn; $column < $this->num_columns; ++$column) { // for each column
+					$this->selectColumn($column);
+					if ($column == $startcolumn) { // first column
+						$cborder = $border_start;
+						$this->y = $starty;
+						$h = $this->h - $this->y - $this->bMargin;
+					} else { // middle column
+						$cborder = $border_middle;
+						$h = $this->h - $this->y - $this->bMargin;
+					}
+					$ccode .= $this->getCellCode($w, $h, '', $cborder, 1, '', $fill, '', 0, true)."\n";
+				} // end for each column
+			} elseif ($page == $endpage) { // last page
+				for ($column = 0; $column <= $endcolumn; ++$column) { // for each column
+					$this->selectColumn($column);
+					if ($column == $endcolumn) {
+						// end column
+						$cborder = $border_end;
+						$h = $currentY - $this->y;
+					} else {
+						// middle column
+						$cborder = $border_middle;
+						$h = $this->h - $this->y - $this->bMargin;
+					}
+					$ccode .= $this->getCellCode($w, $h, '', $cborder, 1, '', $fill, '', 0, true)."\n";
+				} // end for each column
+			} else { // middle page
+				for ($column = 0; $column < $this->num_columns; ++$column) { // for each column
+					$this->selectColumn($column);
+					$cborder = $border_middle;
+					$h = $this->h - $this->y - $this->bMargin;
+					$ccode .= $this->getCellCode($w, $h, '', $cborder, 1, '', $fill, '', 0, true)."\n";
+				} // end for each column
+			}
+			if ($cborder OR $fill) {
+				$offsetlen = strlen($ccode);
+				// draw border and fill
+				if ($this->inxobj) {
+					// we are inside an XObject template
+					if (end($this->xobjects[$this->xobjid]['transfmrk']) !== false) {
+						$pagemarkkey = key($this->xobjects[$this->xobjid]['transfmrk']);
+						$pagemark = $this->xobjects[$this->xobjid]['transfmrk'][$pagemarkkey];
+						$this->xobjects[$this->xobjid]['transfmrk'][$pagemarkkey] += $offsetlen;
+					} else {
+						$pagemark = $this->xobjects[$this->xobjid]['intmrk'];
+						$this->xobjects[$this->xobjid]['intmrk'] += $offsetlen;
+					}
+					$pagebuff = $this->xobjects[$this->xobjid]['outdata'];
+					$pstart = substr($pagebuff, 0, $pagemark);
+					$pend = substr($pagebuff, $pagemark);
+					$this->xobjects[$this->xobjid]['outdata'] = $pstart.$ccode.$pend;
+				} else {
+					if (end($this->transfmrk[$this->page]) !== false) {
+						$pagemarkkey = key($this->transfmrk[$this->page]);
+						$pagemark = $this->transfmrk[$this->page][$pagemarkkey];
+					} elseif ($this->InFooter) {
+						$pagemark = $this->footerpos[$this->page];
+					} else {
+						$pagemark = $this->intmrk[$this->page];
+					}
+					$pagebuff = $this->getPageBuffer($this->page);
+					$pstart = substr($pagebuff, 0, $pagemark);
+					$pend = substr($pagebuff, $pagemark);
+					$this->setPageBuffer($this->page, $pstart.$ccode.$pend);
+					$this->bordermrk[$this->page] += $offsetlen;
+					$this->cntmrk[$this->page] += $offsetlen;
+				}
+			}
+		} // end for each page
+		// restore page regions
+		$this->page_regions = $temp_page_regions;
+		if (isset($old_bgcolor)) {
+			// restore background color
+			$this->SetFillColorArray($old_bgcolor);
+		}
+		// restore pointer position
+		$this->x = $prev_x;
+		$this->y = $prev_y;
+		$this->lasth = $prev_lasth;
+	}
+
+	/**
+	 * Set the default bullet to be used as LI bullet symbol
+	 * @param $symbol (string) character or string to be used (legal values are: '' = automatic, '!' = auto bullet, '#' = auto numbering, 'disc', 'disc', 'circle', 'square', '1', 'decimal', 'decimal-leading-zero', 'i', 'lower-roman', 'I', 'upper-roman', 'a', 'lower-alpha', 'lower-latin', 'A', 'upper-alpha', 'upper-latin', 'lower-greek', 'img|type|width|height|image.ext')
+	 * @public
+	 * @since 4.0.028 (2008-09-26)
+	 */
+	public function setLIsymbol($symbol='!') {
+		// check for custom image symbol
+		if (substr($symbol, 0, 4) == 'img|') {
+			$this->lisymbol = $symbol;
+			return;
+		}
+		$symbol = strtolower($symbol);
+		switch ($symbol) {
+			case '!' :
+			case '#' :
+			case 'disc' :
+			case 'circle' :
+			case 'square' :
+			case '1':
+			case 'decimal':
+			case 'decimal-leading-zero':
+			case 'i':
+			case 'lower-roman':
+			case 'I':
+			case 'upper-roman':
+			case 'a':
+			case 'lower-alpha':
+			case 'lower-latin':
+			case 'A':
+			case 'upper-alpha':
+			case 'upper-latin':
+			case 'lower-greek': {
+				$this->lisymbol = $symbol;
+				break;
+			}
+			default : {
+				$this->lisymbol = '';
+			}
+		}
+	}
+
+	/**
+	 * Set the booklet mode for double-sided pages.
+	 * @param $booklet (boolean) true set the booklet mode on, false otherwise.
+	 * @param $inner (float) Inner page margin.
+	 * @param $outer (float) Outer page margin.
+	 * @public
+	 * @since 4.2.000 (2008-10-29)
+	 */
+	public function SetBooklet($booklet=true, $inner=-1, $outer=-1) {
+		$this->booklet = $booklet;
+		if ($inner >= 0) {
+			$this->lMargin = $inner;
+		}
+		if ($outer >= 0) {
+			$this->rMargin = $outer;
+		}
+	}
+
+	/**
+	 * Swap the left and right margins.
+	 * @param $reverse (boolean) if true swap left and right margins.
+	 * @protected
+	 * @since 4.2.000 (2008-10-29)
+	 */
+	protected function swapMargins($reverse=true) {
+		if ($reverse) {
+			// swap left and right margins
+			$mtemp = $this->original_lMargin;
+			$this->original_lMargin = $this->original_rMargin;
+			$this->original_rMargin = $mtemp;
+			$deltam = $this->original_lMargin - $this->original_rMargin;
+			$this->lMargin += $deltam;
+			$this->rMargin -= $deltam;
+		}
+	}
+
+	/**
+	 * Set the vertical spaces for HTML tags.
+	 * The array must have the following structure (example):
+	 * $tagvs = array('h1' => array(0 => array('h' => '', 'n' => 2), 1 => array('h' => 1.3, 'n' => 1)));
+	 * The first array level contains the tag names,
+	 * the second level contains 0 for opening tags or 1 for closing tags,
+	 * the third level contains the vertical space unit (h) and the number spaces to add (n).
+	 * If the h parameter is not specified, default values are used.
+	 * @param $tagvs (array) array of tags and relative vertical spaces.
+	 * @public
+	 * @since 4.2.001 (2008-10-30)
+	 */
+	public function setHtmlVSpace($tagvs) {
+		$this->tagvspaces = $tagvs;
+	}
+
+	/**
+	 * Set custom width for list indentation.
+	 * @param $width (float) width of the indentation. Use negative value to disable it.
+	 * @public
+	 * @since 4.2.007 (2008-11-12)
+	 */
+	public function setListIndentWidth($width) {
+		return $this->customlistindent = floatval($width);
+	}
+
+	/**
+	 * Set the top/bottom cell sides to be open or closed when the cell cross the page.
+	 * @param $isopen (boolean) if true keeps the top/bottom border open for the cell sides that cross the page.
+	 * @public
+	 * @since 4.2.010 (2008-11-14)
+	 */
+	public function setOpenCell($isopen) {
+		$this->opencell = $isopen;
+	}
+
+	/**
+	 * Set the color and font style for HTML links.
+	 * @param $color (array) RGB array of colors
+	 * @param $fontstyle (string) additional font styles to add
+	 * @public
+	 * @since 4.4.003 (2008-12-09)
+	 */
+	public function setHtmlLinksStyle($color=array(0,0,255), $fontstyle='U') {
+		$this->htmlLinkColorArray = $color;
+		$this->htmlLinkFontStyle = $fontstyle;
+	}
+
+	/**
+	 * Convert HTML string containing value and unit of measure to user's units or points.
+	 * @param $htmlval (string) string containing values and unit
+	 * @param $refsize (string) reference value in points
+	 * @param $defaultunit (string) default unit (can be one of the following: %, em, ex, px, in, mm, pc, pt).
+	 * @param $points (boolean) if true returns points, otherwise returns value in user's units
+	 * @return float value in user's unit or point if $points=true
+	 * @public
+	 * @since 4.4.004 (2008-12-10)
+	 */
+	public function getHTMLUnitToUnits($htmlval, $refsize=1, $defaultunit='px', $points=false) {
+		$supportedunits = array('%', 'em', 'ex', 'px', 'in', 'cm', 'mm', 'pc', 'pt');
+		$retval = 0;
+		$value = 0;
+		$unit = 'px';
+		$k = $this->k;
+		if ($points) {
+			$k = 1;
+		}
+		if (in_array($defaultunit, $supportedunits)) {
+			$unit = $defaultunit;
+		}
+		if (is_numeric($htmlval)) {
+			$value = floatval($htmlval);
+		} elseif (preg_match('/([0-9\.\-\+]+)/', $htmlval, $mnum)) {
+			$value = floatval($mnum[1]);
+			if (preg_match('/([a-z%]+)/', $htmlval, $munit)) {
+				if (in_array($munit[1], $supportedunits)) {
+					$unit = $munit[1];
+				}
+			}
+		}
+		switch ($unit) {
+			// percentage
+			case '%': {
+				$retval = (($value * $refsize) / 100);
+				break;
+			}
+			// relative-size
+			case 'em': {
+				$retval = ($value * $refsize);
+				break;
+			}
+			// height of lower case 'x' (about half the font-size)
+			case 'ex': {
+				$retval = $value * ($refsize / 2);
+				break;
+			}
+			// absolute-size
+			case 'in': {
+				$retval = ($value * $this->dpi) / $k;
+				break;
+			}
+			// centimeters
+			case 'cm': {
+				$retval = ($value / 2.54 * $this->dpi) / $k;
+				break;
+			}
+			// millimeters
+			case 'mm': {
+				$retval = ($value / 25.4 * $this->dpi) / $k;
+				break;
+			}
+			// one pica is 12 points
+			case 'pc': {
+				$retval = ($value * 12) / $k;
+				break;
+			}
+			// points
+			case 'pt': {
+				$retval = $value / $k;
+				break;
+			}
+			// pixels
+			case 'px': {
+				$retval = $this->pixelsToUnits($value);
+				break;
+			}
+		}
+		return $retval;
+	}
+
+	/**
+	 * Returns the Roman representation of an integer number
+	 * @param $number (int) number to convert
+	 * @return string roman representation of the specified number
+	 * @since 4.4.004 (2008-12-10)
+	 * @public
+	 */
+	public function intToRoman($number) {
+		$roman = '';
+		while ($number >= 1000) {
+			$roman .= 'M';
+			$number -= 1000;
+		}
+		while ($number >= 900) {
+			$roman .= 'CM';
+			$number -= 900;
+		}
+		while ($number >= 500) {
+			$roman .= 'D';
+			$number -= 500;
+		}
+		while ($number >= 400) {
+			$roman .= 'CD';
+			$number -= 400;
+		}
+		while ($number >= 100) {
+			$roman .= 'C';
+			$number -= 100;
+		}
+		while ($number >= 90) {
+			$roman .= 'XC';
+			$number -= 90;
+		}
+		while ($number >= 50) {
+			$roman .= 'L';
+			$number -= 50;
+		}
+		while ($number >= 40) {
+			$roman .= 'XL';
+			$number -= 40;
+		}
+		while ($number >= 10) {
+			$roman .= 'X';
+			$number -= 10;
+		}
+		while ($number >= 9) {
+			$roman .= 'IX';
+			$number -= 9;
+		}
+		while ($number >= 5) {
+			$roman .= 'V';
+			$number -= 5;
+		}
+		while ($number >= 4) {
+			$roman .= 'IV';
+			$number -= 4;
+		}
+		while ($number >= 1) {
+			$roman .= 'I';
+			--$number;
+		}
+		return $roman;
+	}
+
+	/**
+	 * Output an HTML list bullet or ordered item symbol
+	 * @param $listdepth (int) list nesting level
+	 * @param $listtype (string) type of list
+	 * @param $size (float) current font size
+	 * @protected
+	 * @since 4.4.004 (2008-12-10)
+	 */
+	protected function putHtmlListBullet($listdepth, $listtype='', $size=10) {
+		if ($this->state != 2) {
+			return;
+		}
+		$size /= $this->k;
+		$fill = '';
+		$bgcolor = $this->bgcolor;
+		$color = $this->fgcolor;
+		$strokecolor = $this->strokecolor;
+		$width = 0;
+		$textitem = '';
+		$tmpx = $this->x;
+		$lspace = $this->GetStringWidth('  ');
+		if ($listtype == '^') {
+			// special symbol used for avoid justification of rect bullet
+			$this->lispacer = '';
+			return;
+		} elseif ($listtype == '!') {
+			// set default list type for unordered list
+			$deftypes = array('disc', 'circle', 'square');
+			$listtype = $deftypes[($listdepth - 1) % 3];
+		} elseif ($listtype == '#') {
+			// set default list type for ordered list
+			$listtype = 'decimal';
+		} elseif (substr($listtype, 0, 4) == 'img|') {
+			// custom image type ('img|type|width|height|image.ext')
+			$img = explode('|', $listtype);
+			$listtype = 'img';
+		}
+		switch ($listtype) {
+			// unordered types
+			case 'none': {
+				break;
+			}
+			case 'disc': {
+				$r = $size / 6;
+				$lspace += (2 * $r);
+				if ($this->rtl) {
+					$this->x += $lspace;
+				} else {
+					$this->x -= $lspace;
+				}
+				$this->Circle(($this->x + $r), ($this->y + ($this->lasth / 2)), $r, 0, 360, 'F', array(), $color, 8);
+				break;
+			}
+			case 'circle': {
+				$r = $size / 6;
+				$lspace += (2 * $r);
+				if ($this->rtl) {
+					$this->x += $lspace;
+				} else {
+					$this->x -= $lspace;
+				}
+				$prev_line_style = $this->linestyleWidth.' '.$this->linestyleCap.' '.$this->linestyleJoin.' '.$this->linestyleDash.' '.$this->DrawColor;
+				$new_line_style = array('width' => ($r / 3), 'cap' => 'butt', 'join' => 'miter', 'dash' => 0, 'phase' => 0, 'color'=>$color);
+				$this->Circle(($this->x + $r), ($this->y + ($this->lasth / 2)), ($r * (1 - (1/6))), 0, 360, 'D', $new_line_style, array(), 8);
+				$this->_out($prev_line_style); // restore line settings
+				break;
+			}
+			case 'square': {
+				$l = $size / 3;
+				$lspace += $l;
+				if ($this->rtl) {;
+					$this->x += $lspace;
+				} else {
+					$this->x -= $lspace;
+				}
+				$this->Rect($this->x, ($this->y + (($this->lasth - $l) / 2)), $l, $l, 'F', array(), $color);
+				break;
+			}
+			case 'img': {
+				// 1=>type, 2=>width, 3=>height, 4=>image.ext
+				$lspace += $img[2];
+				if ($this->rtl) {;
+					$this->x += $lspace;
+				} else {
+					$this->x -= $lspace;
+				}
+				$imgtype = strtolower($img[1]);
+				$prev_y = $this->y;
+				switch ($imgtype) {
+					case 'svg': {
+						$this->ImageSVG($img[4], $this->x, ($this->y + (($this->lasth - $img[3]) / 2)), $img[2], $img[3], '', 'T', '', 0, false);
+						break;
+					}
+					case 'ai':
+					case 'eps': {
+						$this->ImageEps($img[4], $this->x, ($this->y + (($this->lasth - $img[3]) / 2)), $img[2], $img[3], '', true, 'T', '', 0, false);
+						break;
+					}
+					default: {
+						$this->Image($img[4], $this->x, ($this->y + (($this->lasth - $img[3]) / 2)), $img[2], $img[3], $img[1], '', 'T', false, 300, '', false, false, 0, false, false, false);
+						break;
+					}
+				}
+				$this->y = $prev_y;
+				break;
+			}
+			// ordered types
+			// $this->listcount[$this->listnum];
+			// $textitem
+			case '1':
+			case 'decimal': {
+				$textitem = $this->listcount[$this->listnum];
+				break;
+			}
+			case 'decimal-leading-zero': {
+				$textitem = sprintf('%02d', $this->listcount[$this->listnum]);
+				break;
+			}
+			case 'i':
+			case 'lower-roman': {
+				$textitem = strtolower($this->intToRoman($this->listcount[$this->listnum]));
+				break;
+			}
+			case 'I':
+			case 'upper-roman': {
+				$textitem = $this->intToRoman($this->listcount[$this->listnum]);
+				break;
+			}
+			case 'a':
+			case 'lower-alpha':
+			case 'lower-latin': {
+				$textitem = chr(97 + $this->listcount[$this->listnum] - 1);
+				break;
+			}
+			case 'A':
+			case 'upper-alpha':
+			case 'upper-latin': {
+				$textitem = chr(65 + $this->listcount[$this->listnum] - 1);
+				break;
+			}
+			case 'lower-greek': {
+				$textitem = $this->unichr(945 + $this->listcount[$this->listnum] - 1);
+				break;
+			}
+			/*
+			// Types to be implemented (special handling)
+			case 'hebrew': {
+				break;
+			}
+			case 'armenian': {
+				break;
+			}
+			case 'georgian': {
+				break;
+			}
+			case 'cjk-ideographic': {
+				break;
+			}
+			case 'hiragana': {
+				break;
+			}
+			case 'katakana': {
+				break;
+			}
+			case 'hiragana-iroha': {
+				break;
+			}
+			case 'katakana-iroha': {
+				break;
+			}
+			*/
+			default: {
+				$textitem = $this->listcount[$this->listnum];
+			}
+		}
+		if (!$this->empty_string($textitem)) {
+			// Check whether we need a new page or new column
+			$prev_y = $this->y;
+			$h = ($this->FontSize * $this->cell_height_ratio) + $this->cell_padding['T'] + $this->cell_padding['B'];
+			if ($this->checkPageBreak($h) OR ($this->y < $prev_y)) {
+				$tmpx = $this->x;
+			}
+			// print ordered item
+			if ($this->rtl) {
+				$textitem = '.'.$textitem;
+			} else {
+				$textitem = $textitem.'.';
+			}
+			$lspace += $this->GetStringWidth($textitem);
+			if ($this->rtl) {
+				$this->x += $lspace;
+			} else {
+				$this->x -= $lspace;
+			}
+			$this->Write($this->lasth, $textitem, '', false, '', false, 0, false);
+		}
+		$this->x = $tmpx;
+		$this->lispacer = '^';
+		// restore colors
+		$this->SetFillColorArray($bgcolor);
+		$this->SetDrawColorArray($strokecolor);
+		$this->SettextColorArray($color);
+	}
+
+	/**
+	 * Returns current graphic variables as array.
+	 * @return array of graphic variables
+	 * @protected
+	 * @since 4.2.010 (2008-11-14)
+	 */
+	protected function getGraphicVars() {
+		$grapvars = array(
+			'FontFamily' => $this->FontFamily,
+			'FontStyle' => $this->FontStyle,
+			'FontSizePt' => $this->FontSizePt,
+			'rMargin' => $this->rMargin,
+			'lMargin' => $this->lMargin,
+			'cell_padding' => $this->cell_padding,
+			'cell_margin' => $this->cell_margin,
+			'LineWidth' => $this->LineWidth,
+			'linestyleWidth' => $this->linestyleWidth,
+			'linestyleCap' => $this->linestyleCap,
+			'linestyleJoin' => $this->linestyleJoin,
+			'linestyleDash' => $this->linestyleDash,
+			'textrendermode' => $this->textrendermode,
+			'textstrokewidth' => $this->textstrokewidth,
+			'DrawColor' => $this->DrawColor,
+			'FillColor' => $this->FillColor,
+			'TextColor' => $this->TextColor,
+			'ColorFlag' => $this->ColorFlag,
+			'bgcolor' => $this->bgcolor,
+			'fgcolor' => $this->fgcolor,
+			'htmlvspace' => $this->htmlvspace,
+			'listindent' => $this->listindent,
+			'listindentlevel' => $this->listindentlevel,
+			'listnum' => $this->listnum,
+			'listordered' => $this->listordered,
+			'listcount' => $this->listcount,
+			'lispacer' => $this->lispacer,
+			'cell_height_ratio' => $this->cell_height_ratio,
+			'font_stretching' => $this->font_stretching,
+			'font_spacing' => $this->font_spacing,
+			'alpha' => $this->alpha,
+			// extended
+			'lasth' => $this->lasth,
+			'tMargin' => $this->tMargin,
+			'bMargin' => $this->bMargin,
+			'AutoPageBreak' => $this->AutoPageBreak,
+			'PageBreakTrigger' => $this->PageBreakTrigger,
+			'x' => $this->x,
+			'y' => $this->y,
+			'w' => $this->w,
+			'h' => $this->h,
+			'wPt' => $this->wPt,
+			'hPt' => $this->hPt,
+			'fwPt' => $this->fwPt,
+			'fhPt' => $this->fhPt,
+			'page' => $this->page,
+			'current_column' => $this->current_column,
+			'num_columns' => $this->num_columns
+			);
+		return $grapvars;
+	}
+
+	/**
+	 * Set graphic variables.
+	 * @param $gvars (array) array of graphic variablesto restore
+	 * @param $extended (boolean) if true restore extended graphic variables
+	 * @protected
+	 * @since 4.2.010 (2008-11-14)
+	 */
+	protected function setGraphicVars($gvars, $extended=false) {
+		if ($this->state != 2) {
+			 return;
+		}
+		$this->FontFamily = $gvars['FontFamily'];
+		$this->FontStyle = $gvars['FontStyle'];
+		$this->FontSizePt = $gvars['FontSizePt'];
+		$this->rMargin = $gvars['rMargin'];
+		$this->lMargin = $gvars['lMargin'];
+		$this->cell_padding = $gvars['cell_padding'];
+		$this->cell_margin = $gvars['cell_margin'];
+		$this->LineWidth = $gvars['LineWidth'];
+		$this->linestyleWidth = $gvars['linestyleWidth'];
+		$this->linestyleCap = $gvars['linestyleCap'];
+		$this->linestyleJoin = $gvars['linestyleJoin'];
+		$this->linestyleDash = $gvars['linestyleDash'];
+		$this->textrendermode = $gvars['textrendermode'];
+		$this->textstrokewidth = $gvars['textstrokewidth'];
+		$this->DrawColor = $gvars['DrawColor'];
+		$this->FillColor = $gvars['FillColor'];
+		$this->TextColor = $gvars['TextColor'];
+		$this->ColorFlag = $gvars['ColorFlag'];
+		$this->bgcolor = $gvars['bgcolor'];
+		$this->fgcolor = $gvars['fgcolor'];
+		$this->htmlvspace = $gvars['htmlvspace'];
+		$this->listindent = $gvars['listindent'];
+		$this->listindentlevel = $gvars['listindentlevel'];
+		$this->listnum = $gvars['listnum'];
+		$this->listordered = $gvars['listordered'];
+		$this->listcount = $gvars['listcount'];
+		$this->lispacer = $gvars['lispacer'];
+		$this->cell_height_ratio = $gvars['cell_height_ratio'];
+		$this->font_stretching = $gvars['font_stretching'];
+		$this->font_spacing = $gvars['font_spacing'];
+		$this->alpha = $gvars['alpha'];
+		if ($extended) {
+			// restore extended values
+			$this->lasth = $gvars['lasth'];
+			$this->tMargin = $gvars['tMargin'];
+			$this->bMargin = $gvars['bMargin'];
+			$this->AutoPageBreak = $gvars['AutoPageBreak'];
+			$this->PageBreakTrigger = $gvars['PageBreakTrigger'];
+			$this->x = $gvars['x'];
+			$this->y = $gvars['y'];
+			$this->w = $gvars['w'];
+			$this->h = $gvars['h'];
+			$this->wPt = $gvars['wPt'];
+			$this->hPt = $gvars['hPt'];
+			$this->fwPt = $gvars['fwPt'];
+			$this->fhPt = $gvars['fhPt'];
+			$this->page = $gvars['page'];
+			$this->current_column = $gvars['current_column'];
+			$this->num_columns = $gvars['num_columns'];
+		}
+		$this->_out(''.$this->linestyleWidth.' '.$this->linestyleCap.' '.$this->linestyleJoin.' '.$this->linestyleDash.' '.$this->DrawColor.' '.$this->FillColor.'');
+		if (!$this->empty_string($this->FontFamily)) {
+			$this->SetFont($this->FontFamily, $this->FontStyle, $this->FontSizePt);
+		}
+	}
+
+	/**
+	 * Returns a temporary filename for caching object on filesystem.
+	 * @param $name (string) prefix to add to filename
+	 * @return string filename.
+	 * @since 4.5.000 (2008-12-31)
+	 * @protected
+	 */
+	protected function getObjFilename($name) {
+		return tempnam(K_PATH_CACHE, $name.'_');
+	}
+
+	/**
+	 * Writes data to a temporary file on filesystem.
+	 * @param $filename (string) file name
+	 * @param $data (mixed) data to write on file
+	 * @param $append (boolean) if true append data, false replace.
+	 * @since 4.5.000 (2008-12-31)
+	 * @protected
+	 */
+	protected function writeDiskCache($filename, $data, $append=false) {
+		if ($append) {
+			$fmode = 'ab+';
+		} else {
+			$fmode = 'wb+';
+		}
+		$f = @fopen($filename, $fmode);
+		if (!$f) {
+			$this->Error('Unable to write cache file: '.$filename);
+		} else {
+			fwrite($f, $data);
+			fclose($f);
+		}
+		// update file length (needed for transactions)
+		if (!isset($this->cache_file_length['_'.$filename])) {
+			$this->cache_file_length['_'.$filename] = strlen($data);
+		} else {
+			$this->cache_file_length['_'.$filename] += strlen($data);
+		}
+	}
+
+	/**
+	 * Read data from a temporary file on filesystem.
+	 * @param $filename (string) file name
+	 * @return mixed retrieved data
+	 * @since 4.5.000 (2008-12-31)
+	 * @protected
+	 */
+	protected function readDiskCache($filename) {
+		return file_get_contents($filename);
+	}
+
+	/**
+	 * Set buffer content (always append data).
+	 * @param $data (string) data
+	 * @protected
+	 * @since 4.5.000 (2009-01-02)
+	 */
+	protected function setBuffer($data) {
+		$this->bufferlen += strlen($data);
+		if ($this->diskcache) {
+			if (!isset($this->buffer) OR $this->empty_string($this->buffer)) {
+				$this->buffer = $this->getObjFilename('buffer');
+			}
+			$this->writeDiskCache($this->buffer, $data, true);
+		} else {
+			$this->buffer .= $data;
+		}
+	}
+
+	/**
+	 * Replace the buffer content
+	 * @param $data (string) data
+	 * @protected
+	 * @since 5.5.000 (2010-06-22)
+	 */
+	protected function replaceBuffer($data) {
+		$this->bufferlen = strlen($data);
+		if ($this->diskcache) {
+			if (!isset($this->buffer) OR $this->empty_string($this->buffer)) {
+				$this->buffer = $this->getObjFilename('buffer');
+			}
+			$this->writeDiskCache($this->buffer, $data, false);
+		} else {
+			$this->buffer = $data;
+		}
+	}
+
+	/**
+	 * Get buffer content.
+	 * @return string buffer content
+	 * @protected
+	 * @since 4.5.000 (2009-01-02)
+	 */
+	protected function getBuffer() {
+		if ($this->diskcache) {
+			return $this->readDiskCache($this->buffer);
+		} else {
+			return $this->buffer;
+		}
+	}
+
+	/**
+	 * Set page buffer content.
+	 * @param $page (int) page number
+	 * @param $data (string) page data
+	 * @param $append (boolean) if true append data, false replace.
+	 * @protected
+	 * @since 4.5.000 (2008-12-31)
+	 */
+	protected function setPageBuffer($page, $data, $append=false) {
+		if ($this->diskcache) {
+			if (!isset($this->pages[$page])) {
+				$this->pages[$page] = $this->getObjFilename('page'.$page);
+			}
+			$this->writeDiskCache($this->pages[$page], $data, $append);
+		} else {
+			if ($append) {
+				$this->pages[$page] .= $data;
+			} else {
+				$this->pages[$page] = $data;
+			}
+		}
+		if ($append AND isset($this->pagelen[$page])) {
+			$this->pagelen[$page] += strlen($data);
+		} else {
+			$this->pagelen[$page] = strlen($data);
+		}
+	}
+
+	/**
+	 * Get page buffer content.
+	 * @param $page (int) page number
+	 * @return string page buffer content or false in case of error
+	 * @protected
+	 * @since 4.5.000 (2008-12-31)
+	 */
+	protected function getPageBuffer($page) {
+		if ($this->diskcache) {
+			return $this->readDiskCache($this->pages[$page]);
+		} elseif (isset($this->pages[$page])) {
+			return $this->pages[$page];
+		}
+		return false;
+	}
+
+	/**
+	 * Set image buffer content.
+	 * @param $image (string) image key
+	 * @param $data (array) image data
+	 * @return int image index number
+	 * @protected
+	 * @since 4.5.000 (2008-12-31)
+	 */
+	protected function setImageBuffer($image, $data) {
+		if (($data['i'] = array_search($image, $this->imagekeys)) === FALSE) {
+			$this->imagekeys[$this->numimages] = $image;
+			$data['i'] = $this->numimages;
+			++$this->numimages;
+		}
+		if ($this->diskcache) {
+			if (!isset($this->images[$image])) {
+				$this->images[$image] = $this->getObjFilename('image'.$image);
+			}
+			$this->writeDiskCache($this->images[$image], serialize($data));
+		} else {
+			$this->images[$image] = $data;
+		}
+		return $data['i'];
+	}
+
+	/**
+	 * Set image buffer content for a specified sub-key.
+	 * @param $image (string) image key
+	 * @param $key (string) image sub-key
+	 * @param $data (array) image data
+	 * @protected
+	 * @since 4.5.000 (2008-12-31)
+	 */
+	protected function setImageSubBuffer($image, $key, $data) {
+		if (!isset($this->images[$image])) {
+			$this->setImageBuffer($image, array());
+		}
+		if ($this->diskcache) {
+			$tmpimg = $this->getImageBuffer($image);
+			$tmpimg[$key] = $data;
+			$this->writeDiskCache($this->images[$image], serialize($tmpimg));
+		} else {
+			$this->images[$image][$key] = $data;
+		}
+	}
+
+	/**
+	 * Get image buffer content.
+	 * @param $image (string) image key
+	 * @return string image buffer content or false in case of error
+	 * @protected
+	 * @since 4.5.000 (2008-12-31)
+	 */
+	protected function getImageBuffer($image) {
+		if ($this->diskcache AND isset($this->images[$image])) {
+			return unserialize($this->readDiskCache($this->images[$image]));
+		} elseif (isset($this->images[$image])) {
+			return $this->images[$image];
+		}
+		return false;
+	}
+
+	/**
+	 * Set font buffer content.
+	 * @param $font (string) font key
+	 * @param $data (array) font data
+	 * @protected
+	 * @since 4.5.000 (2009-01-02)
+	 */
+	protected function setFontBuffer($font, $data) {
+		if ($this->diskcache) {
+			if (!isset($this->fonts[$font])) {
+				$this->fonts[$font] = $this->getObjFilename('font');
+			}
+			$this->writeDiskCache($this->fonts[$font], serialize($data));
+		} else {
+			$this->fonts[$font] = $data;
+		}
+		if (!in_array($font, $this->fontkeys)) {
+			$this->fontkeys[] = $font;
+			// store object ID for current font
+			++$this->n;
+			$this->font_obj_ids[$font] = $this->n;
+			$this->setFontSubBuffer($font, 'n', $this->n);
+		}
+	}
+
+	/**
+	 * Set font buffer content.
+	 * @param $font (string) font key
+	 * @param $key (string) font sub-key
+	 * @param $data (array) font data
+	 * @protected
+	 * @since 4.5.000 (2009-01-02)
+	 */
+	protected function setFontSubBuffer($font, $key, $data) {
+		if (!isset($this->fonts[$font])) {
+			$this->setFontBuffer($font, array());
+		}
+		if ($this->diskcache) {
+			$tmpfont = $this->getFontBuffer($font);
+			$tmpfont[$key] = $data;
+			$this->writeDiskCache($this->fonts[$font], serialize($tmpfont));
+		} else {
+			$this->fonts[$font][$key] = $data;
+		}
+	}
+
+	/**
+	 * Get font buffer content.
+	 * @param $font (string) font key
+	 * @return string font buffer content or false in case of error
+	 * @protected
+	 * @since 4.5.000 (2009-01-02)
+	 */
+	protected function getFontBuffer($font) {
+		if ($this->diskcache AND isset($this->fonts[$font])) {
+			return unserialize($this->readDiskCache($this->fonts[$font]));
+		} elseif (isset($this->fonts[$font])) {
+			return $this->fonts[$font];
+		}
+		return false;
+	}
+
+	/**
+	 * Move a page to a previous position.
+	 * @param $frompage (int) number of the source page
+	 * @param $topage (int) number of the destination page (must be less than $frompage)
+	 * @return true in case of success, false in case of error.
+	 * @public
+	 * @since 4.5.000 (2009-01-02)
+	 */
+	public function movePage($frompage, $topage) {
+		if (($frompage > $this->numpages) OR ($frompage <= $topage)) {
+			return false;
+		}
+		if ($frompage == $this->page) {
+			// close the page before moving it
+			$this->endPage();
+		}
+		// move all page-related states
+		$tmppage = $this->getPageBuffer($frompage);
+		$tmppagedim = $this->pagedim[$frompage];
+		$tmppagelen = $this->pagelen[$frompage];
+		$tmpintmrk = $this->intmrk[$frompage];
+		$tmpbordermrk = $this->bordermrk[$frompage];
+		$tmpcntmrk = $this->cntmrk[$frompage];
+		$tmppageobjects = $this->pageobjects[$frompage];
+		if (isset($this->footerpos[$frompage])) {
+			$tmpfooterpos = $this->footerpos[$frompage];
+		}
+		if (isset($this->footerlen[$frompage])) {
+			$tmpfooterlen = $this->footerlen[$frompage];
+		}
+		if (isset($this->transfmrk[$frompage])) {
+			$tmptransfmrk = $this->transfmrk[$frompage];
+		}
+		if (isset($this->PageAnnots[$frompage])) {
+			$tmpannots = $this->PageAnnots[$frompage];
+		}
+		if (isset($this->newpagegroup) AND !empty($this->newpagegroup)) {
+			for ($i = $frompage; $i > $topage; --$i) {
+				if (isset($this->newpagegroup[$i]) AND (($i + $this->pagegroups[$this->newpagegroup[$i]]) > $frompage)) {
+					--$this->pagegroups[$this->newpagegroup[$i]];
+					break;
+				}
+			}
+			for ($i = $topage; $i > 0; --$i) {
+				if (isset($this->newpagegroup[$i]) AND (($i + $this->pagegroups[$this->newpagegroup[$i]]) > $topage)) {
+					++$this->pagegroups[$this->newpagegroup[$i]];
+					break;
+				}
+			}
+		}
+		for ($i = $frompage; $i > $topage; --$i) {
+			$j = $i - 1;
+			// shift pages down
+			$this->setPageBuffer($i, $this->getPageBuffer($j));
+			$this->pagedim[$i] = $this->pagedim[$j];
+			$this->pagelen[$i] = $this->pagelen[$j];
+			$this->intmrk[$i] = $this->intmrk[$j];
+			$this->bordermrk[$i] = $this->bordermrk[$j];
+			$this->cntmrk[$i] = $this->cntmrk[$j];
+			$this->pageobjects[$i] = $this->pageobjects[$j];
+			if (isset($this->footerpos[$j])) {
+				$this->footerpos[$i] = $this->footerpos[$j];
+			} elseif (isset($this->footerpos[$i])) {
+				unset($this->footerpos[$i]);
+			}
+			if (isset($this->footerlen[$j])) {
+				$this->footerlen[$i] = $this->footerlen[$j];
+			} elseif (isset($this->footerlen[$i])) {
+				unset($this->footerlen[$i]);
+			}
+			if (isset($this->transfmrk[$j])) {
+				$this->transfmrk[$i] = $this->transfmrk[$j];
+			} elseif (isset($this->transfmrk[$i])) {
+				unset($this->transfmrk[$i]);
+			}
+			if (isset($this->PageAnnots[$j])) {
+				$this->PageAnnots[$i] = $this->PageAnnots[$j];
+			} elseif (isset($this->PageAnnots[$i])) {
+				unset($this->PageAnnots[$i]);
+			}
+			if (isset($this->newpagegroup[$j])) {
+				$this->newpagegroup[$i] = $this->newpagegroup[$j];
+				unset($this->newpagegroup[$j]);
+			}
+			if ($this->currpagegroup == $j) {
+				$this->currpagegroup = $i;
+			}
+		}
+		$this->setPageBuffer($topage, $tmppage);
+		$this->pagedim[$topage] = $tmppagedim;
+		$this->pagelen[$topage] = $tmppagelen;
+		$this->intmrk[$topage] = $tmpintmrk;
+		$this->bordermrk[$topage] = $tmpbordermrk;
+		$this->cntmrk[$topage] = $tmpcntmrk;
+		$this->pageobjects[$topage] = $tmppageobjects;
+		if (isset($tmpfooterpos)) {
+			$this->footerpos[$topage] = $tmpfooterpos;
+		} elseif (isset($this->footerpos[$topage])) {
+			unset($this->footerpos[$topage]);
+		}
+		if (isset($tmpfooterlen)) {
+			$this->footerlen[$topage] = $tmpfooterlen;
+		} elseif (isset($this->footerlen[$topage])) {
+			unset($this->footerlen[$topage]);
+		}
+		if (isset($tmptransfmrk)) {
+			$this->transfmrk[$topage] = $tmptransfmrk;
+		} elseif (isset($this->transfmrk[$topage])) {
+			unset($this->transfmrk[$topage]);
+		}
+		if (isset($tmpannots)) {
+			$this->PageAnnots[$topage] = $tmpannots;
+		} elseif (isset($this->PageAnnots[$topage])) {
+			unset($this->PageAnnots[$topage]);
+		}
+		// adjust outlines
+		$tmpoutlines = $this->outlines;
+		foreach ($tmpoutlines as $key => $outline) {
+			if (($outline['p'] >= $topage) AND ($outline['p'] < $frompage)) {
+				$this->outlines[$key]['p'] = ($outline['p'] + 1);
+			} elseif ($outline['p'] == $frompage) {
+				$this->outlines[$key]['p'] = $topage;
+			}
+		}
+		// adjust dests
+		$tmpdests = $this->dests;
+		foreach ($tmpdests as $key => $dest) {
+			if (($dest['p'] >= $topage) AND ($dest['p'] < $frompage)) {
+				$this->dests[$key]['p'] = ($dest['p'] + 1);
+			} elseif ($dest['p'] == $frompage) {
+				$this->dests[$key]['p'] = $topage;
+			}
+		}
+		// adjust links
+		$tmplinks = $this->links;
+		foreach ($tmplinks as $key => $link) {
+			if (($link[0] >= $topage) AND ($link[0] < $frompage)) {
+				$this->links[$key][0] = ($link[0] + 1);
+			} elseif ($link[0] == $frompage) {
+				$this->links[$key][0] = $topage;
+			}
+		}
+		// adjust javascript
+		$tmpjavascript = $this->javascript;
+		global $jfrompage, $jtopage;
+		$jfrompage = $frompage;
+		$jtopage = $topage;
+		$this->javascript = preg_replace_callback('/this\.addField\(\'([^\']*)\',\'([^\']*)\',([0-9]+)/',
+			create_function('$matches', 'global $jfrompage, $jtopage;
+			$pagenum = intval($matches[3]) + 1;
+			if (($pagenum >= $jtopage) AND ($pagenum < $jfrompage)) {
+				$newpage = ($pagenum + 1);
+			} elseif ($pagenum == $jfrompage) {
+				$newpage = $jtopage;
+			} else {
+				$newpage = $pagenum;
+			}
+			--$newpage;
+			return "this.addField(\'".$matches[1]."\',\'".$matches[2]."\',".$newpage."";'), $tmpjavascript);
+		// return to last page
+		$this->lastPage(true);
+		return true;
+	}
+
+	/**
+	 * Remove the specified page.
+	 * @param $page (int) page to remove
+	 * @return true in case of success, false in case of error.
+	 * @public
+	 * @since 4.6.004 (2009-04-23)
+	 */
+	public function deletePage($page) {
+		if (($page < 1) OR ($page > $this->numpages)) {
+			return false;
+		}
+		// delete current page
+		unset($this->pages[$page]);
+		unset($this->pagedim[$page]);
+		unset($this->pagelen[$page]);
+		unset($this->intmrk[$page]);
+		unset($this->bordermrk[$page]);
+		unset($this->cntmrk[$page]);
+		foreach ($this->pageobjects[$page] as $oid) {
+			if (isset($this->offsets[$oid])){
+				unset($this->offsets[$oid]);
+			}
+		}
+		unset($this->pageobjects[$page]);
+		if (isset($this->footerpos[$page])) {
+			unset($this->footerpos[$page]);
+		}
+		if (isset($this->footerlen[$page])) {
+			unset($this->footerlen[$page]);
+		}
+		if (isset($this->transfmrk[$page])) {
+			unset($this->transfmrk[$page]);
+		}
+		if (isset($this->PageAnnots[$page])) {
+			unset($this->PageAnnots[$page]);
+		}
+		if (isset($this->newpagegroup) AND !empty($this->newpagegroup)) {
+			for ($i = $page; $i > 0; --$i) {
+				if (isset($this->newpagegroup[$i]) AND (($i + $this->pagegroups[$this->newpagegroup[$i]]) > $page)) {
+					--$this->pagegroups[$this->newpagegroup[$i]];
+					break;
+				}
+			}
+		}
+		if (isset($this->pageopen[$page])) {
+			unset($this->pageopen[$page]);
+		}
+		if ($page < $this->numpages) {
+			// update remaining pages
+			for ($i = $page; $i < $this->numpages; ++$i) {
+				$j = $i + 1;
+				// shift pages
+				$this->setPageBuffer($i, $this->getPageBuffer($j));
+				$this->pagedim[$i] = $this->pagedim[$j];
+				$this->pagelen[$i] = $this->pagelen[$j];
+				$this->intmrk[$i] = $this->intmrk[$j];
+				$this->bordermrk[$i] = $this->bordermrk[$j];
+				$this->cntmrk[$i] = $this->cntmrk[$j];
+				$this->pageobjects[$i] = $this->pageobjects[$j];
+				if (isset($this->footerpos[$j])) {
+					$this->footerpos[$i] = $this->footerpos[$j];
+				} elseif (isset($this->footerpos[$i])) {
+					unset($this->footerpos[$i]);
+				}
+				if (isset($this->footerlen[$j])) {
+					$this->footerlen[$i] = $this->footerlen[$j];
+				} elseif (isset($this->footerlen[$i])) {
+					unset($this->footerlen[$i]);
+				}
+				if (isset($this->transfmrk[$j])) {
+					$this->transfmrk[$i] = $this->transfmrk[$j];
+				} elseif (isset($this->transfmrk[$i])) {
+					unset($this->transfmrk[$i]);
+				}
+				if (isset($this->PageAnnots[$j])) {
+					$this->PageAnnots[$i] = $this->PageAnnots[$j];
+				} elseif (isset($this->PageAnnots[$i])) {
+					unset($this->PageAnnots[$i]);
+				}
+				if (isset($this->newpagegroup[$j])) {
+					$this->newpagegroup[$i] = $this->newpagegroup[$j];
+					unset($this->newpagegroup[$j]);
+				}
+				if ($this->currpagegroup == $j) {
+					$this->currpagegroup = $i;
+				}
+				if (isset($this->pageopen[$j])) {
+					$this->pageopen[$i] = $this->pageopen[$j];
+				} elseif (isset($this->pageopen[$i])) {
+					unset($this->pageopen[$i]);
+				}
+			}
+			// remove last page
+			unset($this->pages[$this->numpages]);
+			unset($this->pagedim[$this->numpages]);
+			unset($this->pagelen[$this->numpages]);
+			unset($this->intmrk[$this->numpages]);
+			unset($this->bordermrk[$this->numpages]);
+			unset($this->cntmrk[$this->numpages]);
+			foreach ($this->pageobjects[$this->numpages] as $oid) {
+				if (isset($this->offsets[$oid])){
+					unset($this->offsets[$oid]);
+				}
+			}
+			unset($this->pageobjects[$this->numpages]);
+			if (isset($this->footerpos[$this->numpages])) {
+				unset($this->footerpos[$this->numpages]);
+			}
+			if (isset($this->footerlen[$this->numpages])) {
+				unset($this->footerlen[$this->numpages]);
+			}
+			if (isset($this->transfmrk[$this->numpages])) {
+				unset($this->transfmrk[$this->numpages]);
+			}
+			if (isset($this->PageAnnots[$this->numpages])) {
+				unset($this->PageAnnots[$this->numpages]);
+			}
+			if (isset($this->newpagegroup[$this->numpages])) {
+				unset($this->newpagegroup[$this->numpages]);
+			}
+			if ($this->currpagegroup == $this->numpages) {
+				$this->currpagegroup = ($this->numpages - 1);
+			}
+			if (isset($this->pagegroups[$this->numpages])) {
+				unset($this->pagegroups[$this->numpages]);
+			}
+			if (isset($this->pageopen[$this->numpages])) {
+				unset($this->pageopen[$this->numpages]);
+			}
+		}
+		--$this->numpages;
+		$this->page = $this->numpages;
+		// adjust outlines
+		$tmpoutlines = $this->outlines;
+		foreach ($tmpoutlines as $key => $outline) {
+			if ($outline['p'] > $page) {
+				$this->outlines[$key]['p'] = $outline['p'] - 1;
+			} elseif ($outline['p'] == $page) {
+				unset($this->outlines[$key]);
+			}
+		}
+		// adjust dests
+		$tmpdests = $this->dests;
+		foreach ($tmpdests as $key => $dest) {
+			if ($dest['p'] > $page) {
+				$this->dests[$key]['p'] = $dest['p'] - 1;
+			} elseif ($dest['p'] == $page) {
+				unset($this->dests[$key]);
+			}
+		}
+		// adjust links
+		$tmplinks = $this->links;
+		foreach ($tmplinks as $key => $link) {
+			if ($link[0] > $page) {
+				$this->links[$key][0] = $link[0] - 1;
+			} elseif ($link[0] == $page) {
+				unset($this->links[$key]);
+			}
+		}
+		// adjust javascript
+		$tmpjavascript = $this->javascript;
+		global $jpage;
+		$jpage = $page;
+		$this->javascript = preg_replace_callback('/this\.addField\(\'([^\']*)\',\'([^\']*)\',([0-9]+)/',
+			create_function('$matches', 'global $jpage;
+			$pagenum = intval($matches[3]) + 1;
+			if ($pagenum >= $jpage) {
+				$newpage = ($pagenum - 1);
+			} elseif ($pagenum == $jpage) {
+				$newpage = 1;
+			} else {
+				$newpage = $pagenum;
+			}
+			--$newpage;
+			return "this.addField(\'".$matches[1]."\',\'".$matches[2]."\',".$newpage."";'), $tmpjavascript);
+		// return to last page
+		$this->lastPage(true);
+		return true;
+	}
+
+	/**
+	 * Clone the specified page to a new page.
+	 * @param $page (int) number of page to copy (0 = current page)
+	 * @return true in case of success, false in case of error.
+	 * @public
+	 * @since 4.9.015 (2010-04-20)
+	 */
+	public function copyPage($page=0) {
+		if ($page == 0) {
+			// default value
+			$page = $this->page;
+		}
+		if (($page < 1) OR ($page > $this->numpages)) {
+			return false;
+		}
+		// close the last page
+		$this->endPage();
+		// copy all page-related states
+		++$this->numpages;
+		$this->page = $this->numpages;
+		$this->setPageBuffer($this->page, $this->getPageBuffer($page));
+		$this->pagedim[$this->page] = $this->pagedim[$page];
+		$this->pagelen[$this->page] = $this->pagelen[$page];
+		$this->intmrk[$this->page] = $this->intmrk[$page];
+		$this->bordermrk[$this->page] = $this->bordermrk[$page];
+		$this->cntmrk[$this->page] = $this->cntmrk[$page];
+		$this->pageobjects[$this->page] = $this->pageobjects[$page];
+		$this->pageopen[$this->page] = false;
+		if (isset($this->footerpos[$page])) {
+			$this->footerpos[$this->page] = $this->footerpos[$page];
+		}
+		if (isset($this->footerlen[$page])) {
+			$this->footerlen[$this->page] = $this->footerlen[$page];
+		}
+		if (isset($this->transfmrk[$page])) {
+			$this->transfmrk[$this->page] = $this->transfmrk[$page];
+		}
+		if (isset($this->PageAnnots[$page])) {
+			$this->PageAnnots[$this->page] = $this->PageAnnots[$page];
+		}
+		if (isset($this->newpagegroup[$page])) {
+			// start a new group
+			$this->newpagegroup[$this->page] = sizeof($this->newpagegroup) + 1;
+			$this->currpagegroup = $this->newpagegroup[$this->page];
+			$this->pagegroups[$this->currpagegroup] = 1;
+		} elseif (isset($this->currpagegroup) AND ($this->currpagegroup > 0)) {
+			++$this->pagegroups[$this->currpagegroup];
+		}
+		// copy outlines
+		$tmpoutlines = $this->outlines;
+		foreach ($tmpoutlines as $key => $outline) {
+			if ($outline['p'] == $page) {
+				$this->outlines[] = array('t' => $outline['t'], 'l' => $outline['l'], 'x' => $outline['x'], 'y' => $outline['y'], 'p' => $this->page, 's' => $outline['s'], 'c' => $outline['c']);
+			}
+		}
+		// copy links
+		$tmplinks = $this->links;
+		foreach ($tmplinks as $key => $link) {
+			if ($link[0] == $page) {
+				$this->links[] = array($this->page, $link[1]);
+			}
+		}
+		// return to last page
+		$this->lastPage(true);
+		return true;
+	}
+
+	/**
+	 * Output a Table of Content Index (TOC).
+	 * This method must be called after all Bookmarks were set.
+	 * Before calling this method you have to open the page using the addTOCPage() method.
+	 * After calling this method you have to call endTOCPage() to close the TOC page.
+	 * You can override this method to achieve different styles.
+	 * @param $page (int) page number where this TOC should be inserted (leave empty for current page).
+	 * @param $numbersfont (string) set the font for page numbers (please use monospaced font for better alignment).
+	 * @param $filler (string) string used to fill the space between text and page number.
+	 * @param $toc_name (string) name to use for TOC bookmark.
+	 * @param $style (string) Font style for title: B = Bold, I = Italic, BI = Bold + Italic.
+	 * @param $color (array) RGB color array for bookmark title (values from 0 to 255).
+	 * @public
+	 * @author Nicola Asuni
+	 * @since 4.5.000 (2009-01-02)
+	 * @see addTOCPage(), endTOCPage(), addHTMLTOC()
+	 */
+	public function addTOC($page='', $numbersfont='', $filler='.', $toc_name='TOC', $style='', $color=array(0,0,0)) {
+		$fontsize = $this->FontSizePt;
+		$fontfamily = $this->FontFamily;
+		$fontstyle = $this->FontStyle;
+		$w = $this->w - $this->lMargin - $this->rMargin;
+		$spacer = $this->GetStringWidth(chr(32)) * 4;
+		$lmargin = $this->lMargin;
+		$rmargin = $this->rMargin;
+		$x_start = $this->GetX();
+		$page_first = $this->page;
+		$current_page = $this->page;
+		$page_fill_start = false;
+		$page_fill_end = false;
+		$current_column = $this->current_column;
+		if ($this->empty_string($numbersfont)) {
+			$numbersfont = $this->default_monospaced_font;
+		}
+		if ($this->empty_string($filler)) {
+			$filler = ' ';
+		}
+		if ($this->empty_string($page)) {
+			$gap = ' ';
+		} else {
+			$gap = '';
+			if ($page < 1) {
+				$page = 1;
+			}
+		}
+		$this->SetFont($numbersfont, $fontstyle, $fontsize);
+		$numwidth = $this->GetStringWidth('00000');
+		$maxpage = 0; //used for pages on attached documents
+		foreach ($this->outlines as $key => $outline) {
+			// check for extra pages (used for attachments)
+			if (($this->page > $page_first) AND ($outline['p'] >= $this->numpages)) {
+				$outline['p'] += ($this->page - $page_first);
+			}
+			if ($this->rtl) {
+				$aligntext = 'R';
+				$alignnum = 'L';
+			} else {
+				$aligntext = 'L';
+				$alignnum = 'R';
+			}
+			if ($outline['l'] == 0) {
+				$this->SetFont($fontfamily, $outline['s'].'B', $fontsize);
+			} else {
+				$this->SetFont($fontfamily, $outline['s'], $fontsize - $outline['l']);
+			}
+			$this->SetTextColorArray($outline['c']);
+			// check for page break
+			$this->checkPageBreak((2 * $this->FontSize * $this->cell_height_ratio));
+			// set margins and X position
+			if (($this->page == $current_page) AND ($this->current_column == $current_column)) {
+				$this->lMargin = $lmargin;
+				$this->rMargin = $rmargin;
+			} else {
+				if ($this->current_column != $current_column) {
+					if ($this->rtl) {
+						$x_start = $this->w - $this->columns[$this->current_column]['x'];
+					} else {
+						$x_start = $this->columns[$this->current_column]['x'];
+					}
+				}
+				$lmargin = $this->lMargin;
+				$rmargin = $this->rMargin;
+				$current_page = $this->page;
+				$current_column = $this->current_column;
+			}
+			$this->SetX($x_start);
+			$indent = ($spacer * $outline['l']);
+			if ($this->rtl) {
+				$this->x -= $indent;
+				$this->rMargin = $this->w - $this->x;
+			} else {
+				$this->x += $indent;
+				$this->lMargin = $this->x;
+			}
+			$link = $this->AddLink();
+			$this->SetLink($link, $outline['y'], $outline['p']);
+			// write the text
+			if ($this->rtl) {
+				$txt = ' '.$outline['t'];
+			} else {
+				$txt = $outline['t'].' ';
+			}
+			$this->Write(0, $txt, $link, false, $aligntext, false, 0, false, false, 0, $numwidth, '');
+			if ($this->rtl) {
+				$tw = $this->x - $this->lMargin;
+			} else {
+				$tw = $this->w - $this->rMargin - $this->x;
+			}
+			$this->SetFont($numbersfont, $fontstyle, $fontsize);
+			if ($this->empty_string($page)) {
+				$pagenum = $outline['p'];
+			} else {
+				// placemark to be replaced with the correct number
+				$pagenum = '{#'.($outline['p']).'}';
+				if ($this->isUnicodeFont()) {
+					$pagenum = '{'.$pagenum.'}';
+				}
+				$maxpage = max($maxpage, $outline['p']);
+			}
+			$fw = ($tw - $this->GetStringWidth($pagenum.$filler));
+			$numfills = floor($fw / $this->GetStringWidth($filler));
+			if ($numfills > 0) {
+				$rowfill = str_repeat($filler, $numfills);
+			} else {
+				$rowfill = '';
+			}
+			if ($this->rtl) {
+				$pagenum = $pagenum.$gap.$rowfill;
+			} else {
+				$pagenum = $rowfill.$gap.$pagenum;
+			}
+			// write the number
+			$this->Cell($tw, 0, $pagenum, 0, 1, $alignnum, 0, $link, 0);
+		}
+		$page_last = $this->getPage();
+		$numpages = ($page_last - $page_first + 1);
+		// account for booklet mode
+		if ($this->booklet) {
+			// check if a blank page is required before TOC
+			$page_fill_start = ((($page_first % 2) == 0) XOR (($page % 2) == 0));
+			$page_fill_end = (!((($numpages % 2) == 0) XOR ($page_fill_start)));
+			if ($page_fill_start) {
+				// add a page at the end (to be moved before TOC)
+				$this->addPage();
+				++$page_last;
+				++$numpages;
+			}
+			if ($page_fill_end) {
+				// add a page at the end
+				$this->addPage();
+				++$page_last;
+				++$numpages;
+			}
+		}
+		$maxpage = max($maxpage, $page_last);
+		if (!$this->empty_string($page)) {
+			for ($p = $page_first; $p <= $page_last; ++$p) {
+				// get page data
+				$temppage = $this->getPageBuffer($p);
+				for ($n = 1; $n <= $maxpage; ++$n) {
+					// update page numbers
+					$a = '{#'.$n.'}';
+					// get page number aliases
+					$pnalias = $this->getInternalPageNumberAliases($a);
+					// calculate replacement number
+					if (($n >= $page) AND ($n <= $this->numpages)) {
+						$np = $n + $numpages;
+					} else {
+						$np = $n;
+					}
+					$na = $this->formatTOCPageNumber(($this->starting_page_number + $np - 1));
+					$nu = $this->UTF8ToUTF16BE($na, false);
+					// replace aliases with numbers
+					foreach ($pnalias['u'] as $u) {
+						$sfill = str_repeat($filler, max(0, (strlen($u) - strlen($nu.' '))));
+						if ($this->rtl) {
+							$nr = $nu.$this->UTF8ToUTF16BE(' '.$sfill);
+						} else {
+							$nr = $this->UTF8ToUTF16BE($sfill.' ').$nu;
+						}
+						$temppage = str_replace($u, $nr, $temppage);
+					}
+					foreach ($pnalias['a'] as $a) {
+						$sfill = str_repeat($filler, max(0, (strlen($a) - strlen($na.' '))));
+						if ($this->rtl) {
+							$nr = $na.' '.$sfill;
+						} else {
+							$nr = $sfill.' '.$na;
+						}
+						$temppage = str_replace($a, $nr, $temppage);
+					}
+				}
+				// save changes
+				$this->setPageBuffer($p, $temppage);
+			}
+			// move pages
+			$this->Bookmark($toc_name, 0, 0, $page_first, $style, $color);
+			if ($page_fill_start) {
+				$this->movePage($page_last, $page_first);
+			}
+			for ($i = 0; $i < $numpages; ++$i) {
+				$this->movePage($page_last, $page);
+			}
+		}
+	}
+
+	/**
+	 * Output a Table Of Content Index (TOC) using HTML templates.
+	 * This method must be called after all Bookmarks were set.
+	 * Before calling this method you have to open the page using the addTOCPage() method.
+	 * After calling this method you have to call endTOCPage() to close the TOC page.
+	 * @param $page (int) page number where this TOC should be inserted (leave empty for current page).
+	 * @param $toc_name (string) name to use for TOC bookmark.
+	 * @param $templates (array) array of html templates. Use: "#TOC_DESCRIPTION#" for bookmark title, "#TOC_PAGE_NUMBER#" for page number.
+	 * @param $correct_align (boolean) if true correct the number alignment (numbers must be in monospaced font like courier and right aligned on LTR, or left aligned on RTL)
+	 * @param $style (string) Font style for title: B = Bold, I = Italic, BI = Bold + Italic.
+	 * @param $color (array) RGB color array for title (values from 0 to 255).
+	 * @public
+	 * @author Nicola Asuni
+	 * @since 5.0.001 (2010-05-06)
+	 * @see addTOCPage(), endTOCPage(), addTOC()
+	 */
+	public function addHTMLTOC($page='', $toc_name='TOC', $templates=array(), $correct_align=true, $style='', $color=array(0,0,0)) {
+		$filler = ' ';
+		$prev_htmlLinkColorArray = $this->htmlLinkColorArray;
+		$prev_htmlLinkFontStyle = $this->htmlLinkFontStyle;
+		// set new style for link
+		$this->htmlLinkColorArray = array();
+		$this->htmlLinkFontStyle = '';
+		$page_first = $this->getPage();
+		$page_fill_start = false;
+		$page_fill_end = false;
+		// get the font type used for numbers in each template
+		$current_font = $this->FontFamily;
+		foreach ($templates as $level => $html) {
+			$dom = $this->getHtmlDomArray($html);
+			foreach ($dom as $key => $value) {
+				if ($value['value'] == '#TOC_PAGE_NUMBER#') {
+					$this->SetFont($dom[($key - 1)]['fontname']);
+					$templates['F'.$level] = $this->isUnicodeFont();
+				}
+			}
+		}
+		$this->SetFont($current_font);
+		$maxpage = 0; //used for pages on attached documents
+		foreach ($this->outlines as $key => $outline) {
+			// get HTML template
+			$row = $templates[$outline['l']];
+			if ($this->empty_string($page)) {
+				$pagenum = $outline['p'];
+			} else {
+				// placemark to be replaced with the correct number
+				$pagenum = '{#'.($outline['p']).'}';
+				if ($templates['F'.$outline['l']]) {
+					$pagenum = '{'.$pagenum.'}';
+				}
+				$maxpage = max($maxpage, $outline['p']);
+			}
+			// replace templates with current values
+			$row = str_replace('#TOC_DESCRIPTION#', $outline['t'], $row);
+			$row = str_replace('#TOC_PAGE_NUMBER#', $pagenum, $row);
+			// add link to page
+			$row = '<a href="#'.$outline['p'].','.$outline['y'].'">'.$row.'</a>';
+			// write bookmark entry
+			$this->writeHTML($row, false, false, true, false, '');
+		}
+		// restore link styles
+		$this->htmlLinkColorArray = $prev_htmlLinkColorArray;
+		$this->htmlLinkFontStyle = $prev_htmlLinkFontStyle;
+		// move TOC page and replace numbers
+		$page_last = $this->getPage();
+		$numpages = ($page_last - $page_first + 1);
+		// account for booklet mode
+		if ($this->booklet) {
+			// check if a blank page is required before TOC
+			$page_fill_start = ((($page_first % 2) == 0) XOR (($page % 2) == 0));
+			$page_fill_end = (!((($numpages % 2) == 0) XOR ($page_fill_start)));
+			if ($page_fill_start) {
+				// add a page at the end (to be moved before TOC)
+				$this->addPage();
+				++$page_last;
+				++$numpages;
+			}
+			if ($page_fill_end) {
+				// add a page at the end
+				$this->addPage();
+				++$page_last;
+				++$numpages;
+			}
+		}
+		$maxpage = max($maxpage, $page_last);
+		if (!$this->empty_string($page)) {
+			for ($p = $page_first; $p <= $page_last; ++$p) {
+				// get page data
+				$temppage = $this->getPageBuffer($p);
+				for ($n = 1; $n <= $maxpage; ++$n) {
+					// update page numbers
+					$a = '{#'.$n.'}';
+					// get page number aliases
+					$pnalias = $this->getInternalPageNumberAliases($a);
+					// calculate replacement number
+					if ($n >= $page) {
+						$np = $n + $numpages;
+					} else {
+						$np = $n;
+					}
+					$na = $this->formatTOCPageNumber(($this->starting_page_number + $np - 1));
+					$nu = $this->UTF8ToUTF16BE($na, false);
+					// replace aliases with numbers
+					foreach ($pnalias['u'] as $u) {
+						if ($correct_align) {
+							$sfill = str_repeat($filler, (strlen($u) - strlen($nu.' ')));
+							if ($this->rtl) {
+								$nr = $nu.$this->UTF8ToUTF16BE(' '.$sfill);
+							} else {
+								$nr = $this->UTF8ToUTF16BE($sfill.' ').$nu;
+							}
+						} else {
+							$nr = $nu;
+						}
+						$temppage = str_replace($u, $nr, $temppage);
+					}
+					foreach ($pnalias['a'] as $a) {
+						if ($correct_align) {
+							$sfill = str_repeat($filler, (strlen($a) - strlen($na.' ')));
+							if ($this->rtl) {
+								$nr = $na.' '.$sfill;
+							} else {
+								$nr = $sfill.' '.$na;
+							}
+						} else {
+							$nr = $na;
+						}
+						$temppage = str_replace($a, $nr, $temppage);
+					}
+				}
+				// save changes
+				$this->setPageBuffer($p, $temppage);
+			}
+			// move pages
+			$this->Bookmark($toc_name, 0, 0, $page_first, $style, $color);
+			if ($page_fill_start) {
+				$this->movePage($page_last, $page_first);
+			}
+			for ($i = 0; $i < $numpages; ++$i) {
+				$this->movePage($page_last, $page);
+			}
+		}
+	}
+
+	/**
+	 * Stores a copy of the current TCPDF object used for undo operation.
+	 * @public
+	 * @since 4.5.029 (2009-03-19)
+	 */
+	public function startTransaction() {
+		if (isset($this->objcopy)) {
+			// remove previous copy
+			$this->commitTransaction();
+		}
+		// record current page number and Y position
+		$this->start_transaction_page = $this->page;
+		$this->start_transaction_y = $this->y;
+		// clone current object
+		$this->objcopy = $this->objclone($this);
+	}
+
+	/**
+	 * Delete the copy of the current TCPDF object used for undo operation.
+	 * @public
+	 * @since 4.5.029 (2009-03-19)
+	 */
+	public function commitTransaction() {
+		if (isset($this->objcopy)) {
+			$this->objcopy->_destroy(true, true);
+			unset($this->objcopy);
+		}
+	}
+
+	/**
+	 * This method allows to undo the latest transaction by returning the latest saved TCPDF object with startTransaction().
+	 * @param $self (boolean) if true restores current class object to previous state without the need of reassignment via the returned value.
+	 * @return TCPDF object.
+	 * @public
+	 * @since 4.5.029 (2009-03-19)
+	 */
+	public function rollbackTransaction($self=false) {
+		if (isset($this->objcopy)) {
+			if (isset($this->objcopy->diskcache) AND $this->objcopy->diskcache) {
+				// truncate files to previous values
+				foreach ($this->objcopy->cache_file_length as $file => $length) {
+					$file = substr($file, 1);
+					$handle = fopen($file, 'r+');
+					ftruncate($handle, $length);
+				}
+			}
+			$this->_destroy(true, true);
+			if ($self) {
+				$objvars = get_object_vars($this->objcopy);
+				foreach ($objvars as $key => $value) {
+					$this->$key = $value;
+				}
+			}
+			return $this->objcopy;
+		}
+		return $this;
+	}
+
+	/**
+	 * Creates a copy of a class object
+	 * @param $object (object) class object to be cloned
+	 * @return cloned object
+	 * @public
+	 * @since 4.5.029 (2009-03-19)
+	 */
+	public function objclone($object) {
+		return @clone($object);
+	}
+
+	/**
+	 * Determine whether a string is empty.
+	 * @param $str (string) string to be checked
+	 * @return boolean true if string is empty
+	 * @public
+	 * @since 4.5.044 (2009-04-16)
+	 */
+	public function empty_string($str) {
+		return (is_null($str) OR (is_string($str) AND (strlen($str) == 0)));
+	}
+
+	/**
+	 * Find position of last occurrence of a substring in a string
+	 * @param $haystack (string) The string to search in.
+	 * @param $needle (string) substring to search.
+	 * @param $offset (int) May be specified to begin searching an arbitrary number of characters into the string.
+	 * @return Returns the position where the needle exists. Returns FALSE if the needle was not found.
+	 * @public
+	 * @since 4.8.038 (2010-03-13)
+	 */
+	public function revstrpos($haystack, $needle, $offset = 0) {
+		$length = strlen($haystack);
+		$offset = ($offset > 0)?($length - $offset):abs($offset);
+		$pos = strpos(strrev($haystack), strrev($needle), $offset);
+		return ($pos === false)?false:($length - $pos - strlen($needle));
+	}
+
+	// --- MULTI COLUMNS METHODS -----------------------
+
+	/**
+	 * Set multiple columns of the same size
+	 * @param $numcols (int) number of columns (set to zero to disable columns mode)
+	 * @param $width (int) column width
+	 * @param $y (int) column starting Y position (leave empty for current Y position)
+	 * @public
+	 * @since 4.9.001 (2010-03-28)
+	 */
+	public function setEqualColumns($numcols=0, $width=0, $y='') {
+		$this->columns = array();
+		if ($numcols < 2) {
+			$numcols = 0;
+			$this->columns = array();
+		} else {
+			// maximum column width
+			$maxwidth = ($this->w - $this->original_lMargin - $this->original_rMargin) / $numcols;
+			if (($width == 0) OR ($width > $maxwidth)) {
+				$width = $maxwidth;
+			}
+			if ($this->empty_string($y)) {
+				$y = $this->y;
+			}
+			// space between columns
+			$space = (($this->w - $this->original_lMargin - $this->original_rMargin - ($numcols * $width)) / ($numcols - 1));
+			// fill the columns array (with, space, starting Y position)
+			for ($i = 0; $i < $numcols; ++$i) {
+				$this->columns[$i] = array('w' => $width, 's' => $space, 'y' => $y);
+			}
+		}
+		$this->num_columns = $numcols;
+		$this->current_column = 0;
+		$this->column_start_page = $this->page;
+		$this->selectColumn(0);
+	}
+
+	/**
+	 * Remove columns and reset page margins.
+	 * @public
+	 * @since 5.9.072 (2011-04-26)
+	 */
+	public function resetColumns() {
+		$this->lMargin = $this->original_lMargin;
+		$this->rMargin = $this->original_rMargin;
+		$this->setEqualColumns();
+	}
+
+	/**
+	 * Set columns array.
+	 * Each column is represented by an array of arrays with the following keys: (w = width, s = space between columns, y = column top position).
+	 * @param $columns (array)
+	 * @public
+	 * @since 4.9.001 (2010-03-28)
+	 */
+	public function setColumnsArray($columns) {
+		$this->columns = $columns;
+		$this->num_columns = count($columns);
+		$this->current_column = 0;
+		$this->column_start_page = $this->page;
+		$this->selectColumn(0);
+	}
+
+	/**
+	 * Set position at a given column
+	 * @param $col (int) column number (from 0 to getNumberOfColumns()-1); empty string = current column.
+	 * @public
+	 * @since 4.9.001 (2010-03-28)
+	 */
+	public function selectColumn($col='') {
+		if (is_string($col)) {
+			$col = $this->current_column;
+		} elseif ($col >= $this->num_columns) {
+			$col = 0;
+		}
+		$xshift = array('x' => 0, 's' => array('H' => 0, 'V' => 0), 'p' => array('L' => 0, 'T' => 0, 'R' => 0, 'B' => 0));
+		$enable_thead = false;
+		if ($this->num_columns > 1) {
+			if ($col != $this->current_column) {
+				// move Y pointer at the top of the column
+				if ($this->column_start_page == $this->page) {
+					$this->y = $this->columns[$col]['y'];
+				} else {
+					$this->y = $this->tMargin;
+				}
+				// Avoid to write table headers more than once
+				if (($this->page > $this->maxselcol['page']) OR (($this->page == $this->maxselcol['page']) AND ($col > $this->maxselcol['column']))) {
+					$enable_thead = true;
+					$this->maxselcol['page'] = $this->page;
+					$this->maxselcol['column'] = $col;
+				}
+			}
+			$xshift = $this->colxshift;
+			// set X position of the current column by case
+			$listindent = ($this->listindentlevel * $this->listindent);
+			// calculate column X position
+			$colpos = 0;
+			for ($i = 0; $i < $col; ++$i) {
+				$colpos += ($this->columns[$i]['w'] + $this->columns[$i]['s']);
+			}
+			if ($this->rtl) {
+				$x = $this->w - $this->original_rMargin - $colpos;
+				$this->rMargin = ($this->w - $x + $listindent);
+				$this->lMargin = ($x - $this->columns[$col]['w']);
+				$this->x = $x - $listindent;
+			} else {
+				$x = $this->original_lMargin + $colpos;
+				$this->lMargin = ($x + $listindent);
+				$this->rMargin = ($this->w - $x - $this->columns[$col]['w']);
+				$this->x = $x + $listindent;
+			}
+			$this->columns[$col]['x'] = $x;
+		}
+		$this->current_column = $col;
+		// fix for HTML mode
+		$this->newline = true;
+		// print HTML table header (if any)
+		if ((!$this->empty_string($this->thead)) AND (!$this->inthead)) {
+			if ($enable_thead) {
+				// print table header
+				$this->writeHTML($this->thead, false, false, false, false, '');
+				$this->y += $xshift['s']['V'];
+				// store end of header position
+				if (!isset($this->columns[$col]['th'])) {
+					$this->columns[$col]['th'] = array();
+				}
+				$this->columns[$col]['th']['\''.$this->page.'\''] = $this->y;
+				$this->lasth = 0;
+			} elseif (isset($this->columns[$col]['th']['\''.$this->page.'\''])) {
+				$this->y = $this->columns[$col]['th']['\''.$this->page.'\''];
+			}
+		}
+		// account for an html table cell over multiple columns
+		if ($this->rtl) {
+			$this->rMargin += $xshift['x'];
+			$this->x -= ($xshift['x'] + $xshift['p']['R']);
+		} else {
+			$this->lMargin += $xshift['x'];
+			$this->x += $xshift['x'] + $xshift['p']['L'];
+		}
+	}
+
+	/**
+	 * Return the current column number
+	 * @return int current column number
+	 * @public
+	 * @since 5.5.011 (2010-07-08)
+	 */
+	public function getColumn() {
+		return $this->current_column;
+	}
+
+	/**
+	 * Return the current number of columns.
+	 * @return int number of columns
+	 * @public
+	 * @since 5.8.018 (2010-08-25)
+	 */
+	public function getNumberOfColumns() {
+		return $this->num_columns;
+	}
+
+	/**
+	 * Serialize an array of parameters to be used with TCPDF tag in HTML code.
+	 * @param $pararray (array) parameters array
+	 * @return sting containing serialized data
+	 * @public
+	 * @since 4.9.006 (2010-04-02)
+	 */
+	public function serializeTCPDFtagParameters($pararray) {
+		return urlencode(serialize($pararray));
+	}
+
+	/**
+	 * Set Text rendering mode.
+	 * @param $stroke (int) outline size in user units (0 = disable).
+	 * @param $fill (boolean) if true fills the text (default).
+	 * @param $clip (boolean) if true activate clipping mode
+	 * @public
+	 * @since 4.9.008 (2009-04-02)
+	 */
+	public function setTextRenderingMode($stroke=0, $fill=true, $clip=false) {
+		// Ref.: PDF 32000-1:2008 - 9.3.6 Text Rendering Mode
+		// convert text rendering parameters
+		if ($stroke < 0) {
+			$stroke = 0;
+		}
+		if ($fill === true) {
+			if ($stroke > 0) {
+				if ($clip === true) {
+					// Fill, then stroke text and add to path for clipping
+					$textrendermode = 6;
+				} else {
+					// Fill, then stroke text
+					$textrendermode = 2;
+				}
+				$textstrokewidth = $stroke;
+			} else {
+				if ($clip === true) {
+					// Fill text and add to path for clipping
+					$textrendermode = 4;
+				} else {
+					// Fill text
+					$textrendermode = 0;
+				}
+			}
+		} else {
+			if ($stroke > 0) {
+				if ($clip === true) {
+					// Stroke text and add to path for clipping
+					$textrendermode = 5;
+				} else {
+					// Stroke text
+					$textrendermode = 1;
+				}
+				$textstrokewidth = $stroke;
+			} else {
+				if ($clip === true) {
+					// Add text to path for clipping
+					$textrendermode = 7;
+				} else {
+					// Neither fill nor stroke text (invisible)
+					$textrendermode = 3;
+				}
+			}
+		}
+		$this->textrendermode = $textrendermode;
+		$this->textstrokewidth = $stroke;
+	}
+
+	/**
+	 * Set parameters for drop shadow effect for text.
+	 * @param $params (array) Array of parameters: enabled (boolean) set to true to enable shadow; depth_w (float) shadow width in user units; depth_h (float) shadow height in user units; color (array) shadow color or false to use the stroke color; opacity (float) Alpha value: real value from 0 (transparent) to 1 (opaque); blend_mode (string) blend mode, one of the following: Normal, Multiply, Screen, Overlay, Darken, Lighten, ColorDodge, ColorBurn, HardLight, SoftLight, Difference, Exclusi [...]
+	 * @since 5.9.174 (2012-07-25)
+	 * @public
+	*/
+	public function setTextShadow($params=array('enabled'=>false, 'depth_w'=>0, 'depth_h'=>0, 'color'=>false, 'opacity'=>1, 'blend_mode'=>'Normal')) {
+		if (isset($params['enabled'])) {
+			$this->txtshadow['enabled'] = $params['enabled']?true:false;
+		} else {
+			$this->txtshadow['enabled'] = false;
+		}
+		if (isset($params['depth_w'])) {
+			$this->txtshadow['depth_w'] = floatval($params['depth_w']);
+		} else {
+			$this->txtshadow['depth_w'] = 0;
+		}
+		if (isset($params['depth_h'])) {
+			$this->txtshadow['depth_h'] = floatval($params['depth_h']);
+		} else {
+			$this->txtshadow['depth_h'] = 0;
+		}
+		if (isset($params['color']) AND ($params['color'] !== false) AND is_array($params['color'])) {
+			$this->txtshadow['color'] = $params['color'];
+		} else {
+			$this->txtshadow['color'] = $this->strokecolor;
+		}
+		if (isset($params['opacity'])) {
+			$this->txtshadow['opacity'] = min(1, max(0, floatval($params['opacity'])));
+		} else {
+			$this->txtshadow['opacity'] = 1;
+		}
+		if (isset($params['blend_mode']) AND in_array($params['blend_mode'], array('Normal', 'Multiply', 'Screen', 'Overlay', 'Darken', 'Lighten', 'ColorDodge', 'ColorBurn', 'HardLight', 'SoftLight', 'Difference', 'Exclusion', 'Hue', 'Saturation', 'Color', 'Luminosity'))) {
+			$this->txtshadow['blend_mode'] = $params['blend_mode'];
+		} else {
+			$this->txtshadow['blend_mode'] = 'Normal';
+		}
+		if ((($this->txtshadow['depth_w'] == 0) AND ($this->txtshadow['depth_h'] == 0)) OR ($this->txtshadow['opacity'] == 0)) {
+			$this->txtshadow['enabled'] = false;
+		}
+	}
+
+	/**
+	 * Return the text shadow parameters array.
+	 * @return Array of parameters.
+	 * @since 5.9.174 (2012-07-25)
+	 * @public
+	 */
+	public function getTextShadow() {
+		return $this->txtshadow;
+	}
+
+	/**
+	 * Returns an array of chars containing soft hyphens.
+	 * @param $word (array) array of chars
+	 * @param $patterns (array) Array of hypenation patterns.
+	 * @param $dictionary (array) Array of words to be returned without applying the hyphenation algoritm.
+	 * @param $leftmin (int) Minimum number of character to leave on the left of the word without applying the hyphens.
+	 * @param $rightmin (int) Minimum number of character to leave on the right of the word without applying the hyphens.
+	 * @param $charmin (int) Minimum word length to apply the hyphenation algoritm.
+	 * @param $charmax (int) Maximum length of broken piece of word.
+	 * @return array text with soft hyphens
+	 * @author Nicola Asuni
+	 * @since 4.9.012 (2010-04-12)
+	 * @protected
+	 */
+	protected function hyphenateWord($word, $patterns, $dictionary=array(), $leftmin=1, $rightmin=2, $charmin=1, $charmax=8) {
+		$hyphenword = array(); // hyphens positions
+		$numchars = count($word);
+		if ($numchars <= $charmin) {
+			return $word;
+		}
+		$word_string = $this->UTF8ArrSubString($word);
+		// some words will be returned as-is
+		$pattern = '/^([a-zA-Z0-9_\.\-]+)@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.)|(([a-zA-Z0-9\-]+\.)+))([a-zA-Z]{2,4}|[0-9]{1,3})(\]?)$/';
+		if (preg_match($pattern, $word_string) > 0) {
+			// email
+			return $word;
+		}
+		$pattern = '/(([a-zA-Z0-9\-]+\.)?)((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.)|(([a-zA-Z0-9\-]+\.)+))([a-zA-Z]{2,4}|[0-9]{1,3})(\]?)$/';
+		if (preg_match($pattern, $word_string) > 0) {
+			// URL
+			return $word;
+		}
+		if (isset($dictionary[$word_string])) {
+			return $this->UTF8StringToArray($dictionary[$word_string]);
+		}
+		// suround word with '_' characters
+		$tmpword = array_merge(array(95), $word, array(95));
+		$tmpnumchars = $numchars + 2;
+		$maxpos = $tmpnumchars - $charmin;
+		for ($pos = 0; $pos < $maxpos; ++$pos) {
+			$imax = min(($tmpnumchars - $pos), $charmax);
+			for ($i = $charmin; $i <= $imax; ++$i) {
+				$subword = strtolower($this->UTF8ArrSubString($tmpword, $pos, $pos + $i));
+				if (isset($patterns[$subword])) {
+					$pattern = $this->UTF8StringToArray($patterns[$subword]);
+					$pattern_length = count($pattern);
+					$digits = 1;
+					for ($j = 0; $j < $pattern_length; ++$j) {
+						// check if $pattern[$j] is a number
+						if (($pattern[$j] >= 48) AND ($pattern[$j] <= 57)) {
+							if ($j == 0) {
+								$zero = $pos - 1;
+							} else {
+								$zero = $pos + $j - $digits;
+							}
+							if (!isset($hyphenword[$zero]) OR ($hyphenword[$zero] != $pattern[$j])) {
+								$hyphenword[$zero] = $this->unichr($pattern[$j]);
+							}
+							++$digits;
+						}
+					}
+				}
+			}
+		}
+		$inserted = 0;
+		$maxpos = $numchars - $rightmin;
+		for ($i = $leftmin; $i <= $maxpos; ++$i) {
+			if (isset($hyphenword[$i]) AND (($hyphenword[$i] % 2) != 0)) {
+				// 173 = soft hyphen character
+				array_splice($word, $i + $inserted, 0, 173);
+				++$inserted;
+			}
+		}
+		return $word;
+	}
+
+	/**
+	 * Returns an array of hyphenation patterns.
+	 * @param $file (string) TEX file containing hypenation patterns. TEX pattrns can be downloaded from http://www.ctan.org/tex-archive/language/hyph-utf8/tex/generic/hyph-utf8/patterns/
+	 * @return array of hyphenation patterns
+	 * @author Nicola Asuni
+	 * @since 4.9.012 (2010-04-12)
+	 * @public
+	 */
+	public function getHyphenPatternsFromTEX($file) {
+		// TEX patterns are available at:
+		// http://www.ctan.org/tex-archive/language/hyph-utf8/tex/generic/hyph-utf8/patterns/
+		$data = file_get_contents($file);
+		$patterns = array();
+		// remove comments
+		$data = preg_replace('/\%[^\n]*/', '', $data);
+		// extract the patterns part
+		preg_match('/\\\\patterns\{([^\}]*)\}/i', $data, $matches);
+		$data = trim(substr($matches[0], 10, -1));
+		// extract each pattern
+		$patterns_array = preg_split('/[\s]+/', $data);
+		// create new language array of patterns
+		$patterns = array();
+		foreach($patterns_array as $val) {
+			if (!$this->empty_string($val)) {
+				$val = trim($val);
+				$val = str_replace('\'', '\\\'', $val);
+				$key = preg_replace('/[0-9]+/', '', $val);
+				$patterns[$key] = $val;
+			}
+		}
+		return $patterns;
+	}
+
+	/**
+	 * Returns text with soft hyphens.
+	 * @param $text (string) text to process
+	 * @param $patterns (mixed) Array of hypenation patterns or a TEX file containing hypenation patterns. TEX patterns can be downloaded from http://www.ctan.org/tex-archive/language/hyph-utf8/tex/generic/hyph-utf8/patterns/
+	 * @param $dictionary (array) Array of words to be returned without applying the hyphenation algoritm.
+	 * @param $leftmin (int) Minimum number of character to leave on the left of the word without applying the hyphens.
+	 * @param $rightmin (int) Minimum number of character to leave on the right of the word without applying the hyphens.
+	 * @param $charmin (int) Minimum word length to apply the hyphenation algoritm.
+	 * @param $charmax (int) Maximum length of broken piece of word.
+	 * @return array text with soft hyphens
+	 * @author Nicola Asuni
+	 * @since 4.9.012 (2010-04-12)
+	 * @public
+	 */
+	public function hyphenateText($text, $patterns, $dictionary=array(), $leftmin=1, $rightmin=2, $charmin=1, $charmax=8) {
+		$text = $this->unhtmlentities($text);
+		$word = array(); // last word
+		$txtarr = array(); // text to be returned
+		$intag = false; // true if we are inside an HTML tag
+		if (!is_array($patterns)) {
+			$patterns = $this->getHyphenPatternsFromTEX($patterns);
+		}
+		// get array of characters
+		$unichars = $this->UTF8StringToArray($text);
+		// for each char
+		foreach ($unichars as $char) {
+			if ((!$intag) AND $this->unicode->uni_type[$char] == 'L') {
+				// letter character
+				$word[] = $char;
+			} else {
+				// other type of character
+				if (!$this->empty_string($word)) {
+					// hypenate the word
+					$txtarr = array_merge($txtarr, $this->hyphenateWord($word, $patterns, $dictionary, $leftmin, $rightmin, $charmin, $charmax));
+					$word = array();
+				}
+				$txtarr[] = $char;
+				if (chr($char) == '<') {
+					// we are inside an HTML tag
+					$intag = true;
+				} elseif ($intag AND (chr($char) == '>')) {
+					// end of HTML tag
+					$intag = false;
+				}
+			}
+		}
+		if (!$this->empty_string($word)) {
+			// hypenate the word
+			$txtarr = array_merge($txtarr, $this->hyphenateWord($word, $patterns, $dictionary, $leftmin, $rightmin, $charmin, $charmax));
+		}
+		// convert char array to string and return
+		return $this->UTF8ArrSubString($txtarr);
+	}
+
+	/**
+	 * Enable/disable rasterization of vector images using ImageMagick library.
+	 * @param $mode (boolean) if true enable rasterization, false otherwise.
+	 * @public
+	 * @since 5.0.000 (2010-04-27)
+	 */
+	public function setRasterizeVectorImages($mode) {
+		$this->rasterize_vector_images = $mode;
+	}
+
+	/**
+	 * Get the Path-Painting Operators.
+	 * @param $style (string) Style of rendering. Possible values are:
+	 * <ul>
+	 *   <li>S or D: Stroke the path.</li>
+	 *   <li>s or d: Close and stroke the path.</li>
+	 *   <li>f or F: Fill the path, using the nonzero winding number rule to determine the region to fill.</li>
+	 *   <li>f* or F*: Fill the path, using the even-odd rule to determine the region to fill.</li>
+	 *   <li>B or FD or DF: Fill and then stroke the path, using the nonzero winding number rule to determine the region to fill.</li>
+	 *   <li>B* or F*D or DF*: Fill and then stroke the path, using the even-odd rule to determine the region to fill.</li>
+	 *   <li>b or fd or df: Close, fill, and then stroke the path, using the nonzero winding number rule to determine the region to fill.</li>
+	 *   <li>b or f*d or df*: Close, fill, and then stroke the path, using the even-odd rule to determine the region to fill.</li>
+	 *   <li>CNZ: Clipping mode using the even-odd rule to determine which regions lie inside the clipping path.</li>
+	 *   <li>CEO: Clipping mode using the nonzero winding number rule to determine which regions lie inside the clipping path</li>
+	 *   <li>n: End the path object without filling or stroking it.</li>
+	 * </ul>
+	 * @param $default (string) default style
+	 * @author Nicola Asuni
+	 * @since 5.0.000 (2010-04-30)
+	 * @protected
+	 */
+	protected function getPathPaintOperator($style, $default='S') {
+		$op = '';
+		switch($style) {
+			case 'S':
+			case 'D': {
+				$op = 'S';
+				break;
+			}
+			case 's':
+			case 'd': {
+				$op = 's';
+				break;
+			}
+			case 'f':
+			case 'F': {
+				$op = 'f';
+				break;
+			}
+			case 'f*':
+			case 'F*': {
+				$op = 'f*';
+				break;
+			}
+			case 'B':
+			case 'FD':
+			case 'DF': {
+				$op = 'B';
+				break;
+			}
+			case 'B*':
+			case 'F*D':
+			case 'DF*': {
+				$op = 'B*';
+				break;
+			}
+			case 'b':
+			case 'fd':
+			case 'df': {
+				$op = 'b';
+				break;
+			}
+			case 'b*':
+			case 'f*d':
+			case 'df*': {
+				$op = 'b*';
+				break;
+			}
+			case 'CNZ': {
+				$op = 'W n';
+				break;
+			}
+			case 'CEO': {
+				$op = 'W* n';
+				break;
+			}
+			case 'n': {
+				$op = 'n';
+				break;
+			}
+			default: {
+				if (!empty($default)) {
+					$op = $this->getPathPaintOperator($default, '');
+				} else {
+					$op = '';
+				}
+			}
+		}
+		return $op;
+	}
+
+	/**
+	 * Enable or disable default option for font subsetting.
+	 * @param $enable (boolean) if true enable font subsetting by default.
+	 * @author Nicola Asuni
+	 * @public
+	 * @since 5.3.002 (2010-06-07)
+	 */
+	public function setFontSubsetting($enable=true) {
+		if ($this->pdfa_mode) {
+			$this->font_subsetting = false;
+		} else {
+			$this->font_subsetting = $enable ? true : false;
+		}
+	}
+
+	/**
+	 * Return the default option for font subsetting.
+	 * @return boolean default font subsetting state.
+	 * @author Nicola Asuni
+	 * @public
+	 * @since 5.3.002 (2010-06-07)
+	 */
+	public function getFontSubsetting() {
+		return $this->font_subsetting;
+	}
+
+	/**
+	 * Left trim the input string
+	 * @param $str (string) string to trim
+	 * @param $replace (string) string that replace spaces.
+	 * @return left trimmed string
+	 * @author Nicola Asuni
+	 * @public
+	 * @since 5.8.000 (2010-08-11)
+	 */
+	public function stringLeftTrim($str, $replace='') {
+		return preg_replace('/^'.$this->re_space['p'].'+/'.$this->re_space['m'], $replace, $str);
+	}
+
+	/**
+	 * Right trim the input string
+	 * @param $str (string) string to trim
+	 * @param $replace (string) string that replace spaces.
+	 * @return right trimmed string
+	 * @author Nicola Asuni
+	 * @public
+	 * @since 5.8.000 (2010-08-11)
+	 */
+	public function stringRightTrim($str, $replace='') {
+		return preg_replace('/'.$this->re_space['p'].'+$/'.$this->re_space['m'], $replace, $str);
+	}
+
+	/**
+	 * Trim the input string
+	 * @param $str (string) string to trim
+	 * @param $replace (string) string that replace spaces.
+	 * @return trimmed string
+	 * @author Nicola Asuni
+	 * @public
+	 * @since 5.8.000 (2010-08-11)
+	 */
+	public function stringTrim($str, $replace='') {
+		$str = $this->stringLeftTrim($str, $replace);
+		$str = $this->stringRightTrim($str, $replace);
+		return $str;
+	}
+
+	/**
+	 * Return true if the current font is unicode type.
+	 * @return true for unicode font, false otherwise.
+	 * @author Nicola Asuni
+	 * @public
+	 * @since 5.8.002 (2010-08-14)
+	 */
+	public function isUnicodeFont() {
+		return (($this->CurrentFont['type'] == 'TrueTypeUnicode') OR ($this->CurrentFont['type'] == 'cidfont0'));
+	}
+
+	/**
+	 * Return normalized font name
+	 * @param $fontfamily (string) property string containing font family names
+	 * @return string normalized font name
+	 * @author Nicola Asuni
+	 * @public
+	 * @since 5.8.004 (2010-08-17)
+	 */
+	public function getFontFamilyName($fontfamily) {
+		// remove spaces and symbols
+		$fontfamily = preg_replace('/[^a-z0-9_\,]/', '', strtolower($fontfamily));
+		// extract all font names
+		$fontslist = preg_split('/[,]/', $fontfamily);
+		// find first valid font name
+		foreach ($fontslist as $font) {
+			// replace font variations
+			$font = preg_replace('/italic$/', 'I', $font);
+			$font = preg_replace('/oblique$/', 'I', $font);
+			$font = preg_replace('/bold([I]?)$/', 'B\\1', $font);
+			// replace common family names and core fonts
+			$pattern = array();
+			$replacement = array();
+			$pattern[] = '/^serif|^cursive|^fantasy|^timesnewroman/';
+			$replacement[] = 'times';
+			$pattern[] = '/^sansserif/';
+			$replacement[] = 'helvetica';
+			$pattern[] = '/^monospace/';
+			$replacement[] = 'courier';
+			$font = preg_replace($pattern, $replacement, $font);
+			if (in_array(strtolower($font), $this->fontlist) OR in_array($font, $this->fontkeys)) {
+				return $font;
+			}
+		}
+		// return current font as default
+		return $this->CurrentFont['fontkey'];
+	}
+
+	/**
+	 * Start a new XObject Template.
+	 * An XObject Template is a PDF block that is a self-contained description of any sequence of graphics objects (including path objects, text objects, and sampled images).
+	 * An XObject Template may be painted multiple times, either on several pages or at several locations on the same page and produces the same results each time, subject only to the graphics state at the time it is invoked.
+	 * Note: X,Y coordinates will be reset to 0,0.
+	 * @param $w (int) Template width in user units (empty string or zero = page width less margins).
+	 * @param $h (int) Template height in user units (empty string or zero = page height less margins).
+	 * @param $group (mixed) Set transparency group. Can be a boolean value or an array specifying optional parameters: 'CS' (solour space name), 'I' (boolean flag to indicate isolated group) and 'K' (boolean flag to indicate knockout group).
+	 * @return int the XObject Template ID in case of success or false in case of error.
+	 * @author Nicola Asuni
+	 * @public
+	 * @since 5.8.017 (2010-08-24)
+	 * @see endTemplate(), printTemplate()
+	 */
+	public function startTemplate($w=0, $h=0, $group=false) {
+		if ($this->inxobj) {
+			// we are already inside an XObject template
+			return false;
+		}
+		$this->inxobj = true;
+		++$this->n;
+		// XObject ID
+		$this->xobjid = 'XT'.$this->n;
+		// object ID
+		$this->xobjects[$this->xobjid] = array('n' => $this->n);
+		// store current graphic state
+		$this->xobjects[$this->xobjid]['gvars'] = $this->getGraphicVars();
+		// initialize data
+		$this->xobjects[$this->xobjid]['intmrk'] = 0;
+		$this->xobjects[$this->xobjid]['transfmrk'] = array();
+		$this->xobjects[$this->xobjid]['outdata'] = '';
+		$this->xobjects[$this->xobjid]['xobjects'] = array();
+		$this->xobjects[$this->xobjid]['images'] = array();
+		$this->xobjects[$this->xobjid]['fonts'] = array();
+		$this->xobjects[$this->xobjid]['annotations'] = array();
+		$this->xobjects[$this->xobjid]['extgstates'] = array();
+		$this->xobjects[$this->xobjid]['gradients'] = array();
+		$this->xobjects[$this->xobjid]['spot_colors'] = array();
+		// set new environment
+		$this->num_columns = 1;
+		$this->current_column = 0;
+		$this->SetAutoPageBreak(false);
+		if (($w === '') OR ($w <= 0)) {
+			$w = $this->w - $this->lMargin - $this->rMargin;
+		}
+		if (($h === '') OR ($h <= 0)) {
+			$h = $this->h - $this->tMargin - $this->bMargin;
+		}
+		$this->xobjects[$this->xobjid]['x'] = 0;
+		$this->xobjects[$this->xobjid]['y'] = 0;
+		$this->xobjects[$this->xobjid]['w'] = $w;
+		$this->xobjects[$this->xobjid]['h'] = $h;
+		$this->w = $w;
+		$this->h = $h;
+		$this->wPt = $this->w * $this->k;
+		$this->hPt = $this->h * $this->k;
+		$this->fwPt = $this->wPt;
+		$this->fhPt = $this->hPt;
+		$this->x = 0;
+		$this->y = 0;
+		$this->lMargin = 0;
+		$this->rMargin = 0;
+		$this->tMargin = 0;
+		$this->bMargin = 0;
+		// set group mode
+		$this->xobjects[$this->xobjid]['group'] = $group;
+		return $this->xobjid;
+	}
+
+	/**
+	 * End the current XObject Template started with startTemplate() and restore the previous graphic state.
+	 * An XObject Template is a PDF block that is a self-contained description of any sequence of graphics objects (including path objects, text objects, and sampled images).
+	 * An XObject Template may be painted multiple times, either on several pages or at several locations on the same page and produces the same results each time, subject only to the graphics state at the time it is invoked.
+	 * @return int the XObject Template ID in case of success or false in case of error.
+	 * @author Nicola Asuni
+	 * @public
+	 * @since 5.8.017 (2010-08-24)
+	 * @see startTemplate(), printTemplate()
+	 */
+	public function endTemplate() {
+		if (!$this->inxobj) {
+			// we are not inside a template
+			return false;
+		}
+		$this->inxobj = false;
+		// restore previous graphic state
+		$this->setGraphicVars($this->xobjects[$this->xobjid]['gvars'], true);
+		return $this->xobjid;
+	}
+
+	/**
+	 * Print an XObject Template.
+	 * You can print an XObject Template inside the currently opened Template.
+	 * An XObject Template is a PDF block that is a self-contained description of any sequence of graphics objects (including path objects, text objects, and sampled images).
+	 * An XObject Template may be painted multiple times, either on several pages or at several locations on the same page and produces the same results each time, subject only to the graphics state at the time it is invoked.
+	 * @param $id (string) The ID of XObject Template to print.
+	 * @param $x (int) X position in user units (empty string = current x position)
+	 * @param $y (int) Y position in user units (empty string = current y position)
+	 * @param $w (int) Width in user units (zero = remaining page width)
+	 * @param $h (int) Height in user units (zero = remaining page height)
+	 * @param $align (string) Indicates the alignment of the pointer next to template insertion relative to template height. The value can be:<ul><li>T: top-right for LTR or top-left for RTL</li><li>M: middle-right for LTR or middle-left for RTL</li><li>B: bottom-right for LTR or bottom-left for RTL</li><li>N: next line</li></ul>
+	 * @param $palign (string) Allows to center or align the template on the current line. Possible values are:<ul><li>L : left align</li><li>C : center</li><li>R : right align</li><li>'' : empty string : left for LTR or right for RTL</li></ul>
+	 * @param $fitonpage (boolean) If true the template is resized to not exceed page dimensions.
+	 * @author Nicola Asuni
+	 * @public
+	 * @since 5.8.017 (2010-08-24)
+	 * @see startTemplate(), endTemplate()
+	 */
+	public function printTemplate($id, $x='', $y='', $w=0, $h=0, $align='', $palign='', $fitonpage=false) {
+		if ($this->state != 2) {
+			 return;
+		}
+		if (!isset($this->xobjects[$id])) {
+			$this->Error('The XObject Template \''.$id.'\' doesn\'t exist!');
+		}
+		if ($this->inxobj) {
+			if ($id == $this->xobjid) {
+				// close current template
+				$this->endTemplate();
+			} else {
+				// use the template as resource for the template currently opened
+				$this->xobjects[$this->xobjid]['xobjects'][$id] = $this->xobjects[$id];
+			}
+		}
+		// set default values
+		if ($x === '') {
+			$x = $this->x;
+		}
+		if ($y === '') {
+			$y = $this->y;
+		}
+		// check page for no-write regions and adapt page margins if necessary
+		list($x, $y) = $this->checkPageRegions($h, $x, $y);
+		$ow = $this->xobjects[$id]['w'];
+		$oh = $this->xobjects[$id]['h'];
+		// calculate template width and height on document
+		if (($w <= 0) AND ($h <= 0)) {
+			$w = $ow;
+			$h = $oh;
+		} elseif ($w <= 0) {
+			$w = $h * $ow / $oh;
+		} elseif ($h <= 0) {
+			$h = $w * $oh / $ow;
+		}
+		// fit the template on available space
+		list($w, $h, $x, $y) = $this->fitBlock($w, $h, $x, $y, $fitonpage);
+		// set page alignment
+		$rb_y = $y + $h;
+		// set alignment
+		if ($this->rtl) {
+			if ($palign == 'L') {
+				$xt = $this->lMargin;
+			} elseif ($palign == 'C') {
+				$xt = ($this->w + $this->lMargin - $this->rMargin - $w) / 2;
+			} elseif ($palign == 'R') {
+				$xt = $this->w - $this->rMargin - $w;
+			} else {
+				$xt = $x - $w;
+			}
+			$rb_x = $xt;
+		} else {
+			if ($palign == 'L') {
+				$xt = $this->lMargin;
+			} elseif ($palign == 'C') {
+				$xt = ($this->w + $this->lMargin - $this->rMargin - $w) / 2;
+			} elseif ($palign == 'R') {
+				$xt = $this->w - $this->rMargin - $w;
+			} else {
+				$xt = $x;
+			}
+			$rb_x = $xt + $w;
+		}
+		// print XObject Template + Transformation matrix
+		$this->StartTransform();
+		// translate and scale
+		$sx = ($w / $this->xobjects[$id]['w']);
+		$sy = ($h / $this->xobjects[$id]['h']);
+		$tm = array();
+		$tm[0] = $sx;
+		$tm[1] = 0;
+		$tm[2] = 0;
+		$tm[3] = $sy;
+		$tm[4] = $xt * $this->k;
+		$tm[5] = ($this->h - $h - $y) * $this->k;
+		$this->Transform($tm);
+		// set object
+		$this->_out('/'.$id.' Do');
+		$this->StopTransform();
+		// add annotations
+		if (!empty($this->xobjects[$id]['annotations'])) {
+			foreach ($this->xobjects[$id]['annotations'] as $annot) {
+				// transform original coordinates
+				$coordlt = $this->getTransformationMatrixProduct($tm, array(1, 0, 0, 1, ($annot['x'] * $this->k), (-$annot['y'] * $this->k)));
+				$ax = ($coordlt[4] / $this->k);
+				$ay = ($this->h - $h - ($coordlt[5] / $this->k));
+				$coordrb = $this->getTransformationMatrixProduct($tm, array(1, 0, 0, 1, (($annot['x'] + $annot['w']) * $this->k), ((-$annot['y'] - $annot['h']) * $this->k)));
+				$aw = ($coordrb[4] / $this->k) - $ax;
+				$ah = ($this->h - $h - ($coordrb[5] / $this->k)) - $ay;
+				$this->Annotation($ax, $ay, $aw, $ah, $annot['text'], $annot['opt'], $annot['spaces']);
+			}
+		}
+		// set pointer to align the next text/objects
+		switch($align) {
+			case 'T': {
+				$this->y = $y;
+				$this->x = $rb_x;
+				break;
+			}
+			case 'M': {
+				$this->y = $y + round($h/2);
+				$this->x = $rb_x;
+				break;
+			}
+			case 'B': {
+				$this->y = $rb_y;
+				$this->x = $rb_x;
+				break;
+			}
+			case 'N': {
+				$this->SetY($rb_y);
+				break;
+			}
+			default:{
+				break;
+			}
+		}
+	}
+
+	/**
+	 * Set the percentage of character stretching.
+	 * @param $perc (int) percentage of stretching (100 = no stretching)
+	 * @author Nicola Asuni
+	 * @public
+	 * @since 5.9.000 (2010-09-29)
+	 */
+	public function setFontStretching($perc=100) {
+		$this->font_stretching = $perc;
+	}
+
+	/**
+	 * Get the percentage of character stretching.
+	 * @return float stretching value
+	 * @author Nicola Asuni
+	 * @public
+	 * @since 5.9.000 (2010-09-29)
+	 */
+	public function getFontStretching() {
+		return $this->font_stretching;
+	}
+
+	/**
+	 * Set the amount to increase or decrease the space between characters in a text.
+	 * @param $spacing (float) amount to increase or decrease the space between characters in a text (0 = default spacing)
+	 * @author Nicola Asuni
+	 * @public
+	 * @since 5.9.000 (2010-09-29)
+	 */
+	public function setFontSpacing($spacing=0) {
+		$this->font_spacing = $spacing;
+	}
+
+	/**
+	 * Get the amount to increase or decrease the space between characters in a text.
+	 * @return int font spacing (tracking) value
+	 * @author Nicola Asuni
+	 * @public
+	 * @since 5.9.000 (2010-09-29)
+	 */
+	public function getFontSpacing() {
+		return $this->font_spacing;
+	}
+
+	/**
+	 * Return an array of no-write page regions
+	 * @return array of no-write page regions
+	 * @author Nicola Asuni
+	 * @public
+	 * @since 5.9.003 (2010-10-13)
+	 * @see setPageRegions(), addPageRegion()
+	 */
+	public function getPageRegions() {
+		return $this->page_regions;
+	}
+
+	/**
+	 * Set no-write regions on page.
+	 * A no-write region is a portion of the page with a rectangular or trapezium shape that will not be covered when writing text or html code.
+	 * A region is always aligned on the left or right side of the page ad is defined using a vertical segment.
+	 * You can set multiple regions for the same page.
+	 * @param $regions (array) array of no-write regions. For each region you can define an array as follow: ('page' => page number or empy for current page, 'xt' => X top, 'yt' => Y top, 'xb' => X bottom, 'yb' => Y bottom, 'side' => page side 'L' = left or 'R' = right). Omit this parameter to remove all regions.
+	 * @author Nicola Asuni
+	 * @public
+	 * @since 5.9.003 (2010-10-13)
+	 * @see addPageRegion(), getPageRegions()
+	 */
+	public function setPageRegions($regions=array()) {
+		// empty current regions array
+		$this->page_regions = array();
+		// add regions
+		foreach ($regions as $data) {
+			$this->addPageRegion($data);
+		}
+	}
+
+	/**
+	 * Add a single no-write region on selected page.
+	 * A no-write region is a portion of the page with a rectangular or trapezium shape that will not be covered when writing text or html code.
+	 * A region is always aligned on the left or right side of the page ad is defined using a vertical segment.
+	 * You can set multiple regions for the same page.
+	 * @param $region (array) array of a single no-write region array: ('page' => page number or empy for current page, 'xt' => X top, 'yt' => Y top, 'xb' => X bottom, 'yb' => Y bottom, 'side' => page side 'L' = left or 'R' = right).
+	 * @author Nicola Asuni
+	 * @public
+	 * @since 5.9.003 (2010-10-13)
+	 * @see setPageRegions(), getPageRegions()
+	 */
+	public function addPageRegion($region) {
+		if (!isset($region['page']) OR empty($region['page'])) {
+			$region['page'] = $this->page;
+		}
+		if (isset($region['xt']) AND isset($region['xb']) AND ($region['xt'] > 0) AND ($region['xb'] > 0)
+			AND isset($region['yt'])  AND isset($region['yb']) AND ($region['yt'] >= 0) AND ($region['yt'] < $region['yb'])
+			AND isset($region['side']) AND (($region['side'] == 'L') OR ($region['side'] == 'R'))) {
+			$this->page_regions[] = $region;
+		}
+	}
+
+	/**
+	 * Remove a single no-write region.
+	 * @param $key (int) region key
+	 * @author Nicola Asuni
+	 * @public
+	 * @since 5.9.003 (2010-10-13)
+	 * @see setPageRegions(), getPageRegions()
+	 */
+	public function removePageRegion($key) {
+		if (isset($this->page_regions[$key])) {
+			unset($this->page_regions[$key]);
+		}
+	}
+
+	/**
+	 * Check page for no-write regions and adapt current coordinates and page margins if necessary.
+	 * A no-write region is a portion of the page with a rectangular or trapezium shape that will not be covered when writing text or html code.
+	 * A region is always aligned on the left or right side of the page ad is defined using a vertical segment.
+	 * @param $h (float) height of the text/image/object to print in user units
+	 * @param $x (float) current X coordinate in user units
+	 * @param $y (float) current Y coordinate in user units
+	 * @return array($x, $y)
+	 * @author Nicola Asuni
+	 * @protected
+	 * @since 5.9.003 (2010-10-13)
+	 */
+	protected function checkPageRegions($h, $x, $y) {
+		// set default values
+		if ($x === '') {
+			$x = $this->x;
+		}
+		if ($y === '') {
+			$y = $this->y;
+		}
+		if (!$this->check_page_regions OR empty($this->page_regions)) {
+			// no page regions defined
+			return array($x, $y);
+		}
+		if (empty($h)) {
+			$h = ($this->FontSize * $this->cell_height_ratio) + $this->cell_padding['T'] + $this->cell_padding['B'];
+		}
+		// check for page break
+		if ($this->checkPageBreak($h, $y)) {
+			// the content will be printed on a new page
+			$x = $this->x;
+			$y = $this->y;
+		}
+		if ($this->num_columns > 1) {
+			if ($this->rtl) {
+				$this->lMargin = ($this->columns[$this->current_column]['x'] - $this->columns[$this->current_column]['w']);
+			} else {
+				$this->rMargin = ($this->w - $this->columns[$this->current_column]['x'] - $this->columns[$this->current_column]['w']);
+			}
+		} else {
+			if ($this->rtl) {
+				$this->lMargin = max($this->clMargin, $this->original_lMargin);
+			} else {
+				$this->rMargin = max($this->crMargin, $this->original_rMargin);
+			}
+		}
+		// adjust coordinates and page margins
+		foreach ($this->page_regions as $regid => $regdata) {
+			if ($regdata['page'] == $this->page) {
+				// check region boundaries
+				if (($y > ($regdata['yt'] - $h)) AND ($y <= $regdata['yb'])) {
+					// Y is inside the region
+					$minv = ($regdata['xb'] - $regdata['xt']) / ($regdata['yb'] - $regdata['yt']); // inverse of angular coefficient
+					$yt = max($y, $regdata['yt']);
+					$yb = min(($yt + $h), $regdata['yb']);
+					$xt = (($yt - $regdata['yt']) * $minv) + $regdata['xt'];
+					$xb = (($yb - $regdata['yt']) * $minv) + $regdata['xt'];
+					if ($regdata['side'] == 'L') { // left side
+						$new_margin = max($xt, $xb);
+						if ($this->lMargin < $new_margin) {
+							if ($this->rtl) {
+								// adjust left page margin
+								$this->lMargin = max(0, $new_margin);
+							}
+							if ($x < $new_margin) {
+								// adjust x position
+								$x = $new_margin;
+								if ($new_margin > ($this->w - $this->rMargin)) {
+									// adjust y position
+									$y = $regdata['yb'] - $h;
+								}
+							}
+						}
+					} elseif ($regdata['side'] == 'R') { // right side
+						$new_margin = min($xt, $xb);
+						if (($this->w - $this->rMargin) > $new_margin) {
+							if (!$this->rtl) {
+								// adjust right page margin
+								$this->rMargin = max(0, ($this->w - $new_margin));
+							}
+							if ($x > $new_margin) {
+								// adjust x position
+								$x = $new_margin;
+								if ($new_margin > $this->lMargin) {
+									// adjust y position
+									$y = $regdata['yb'] - $h;
+								}
+							}
+						}
+					}
+				}
+			}
+		}
+		return array($x, $y);
+	}
+
+	// --- SVG METHODS ---------------------------------------------------------
+
+	/**
+	 * Embedd a Scalable Vector Graphics (SVG) image.
+	 * NOTE: SVG standard is not yet fully implemented, use the setRasterizeVectorImages() method to enable/disable rasterization of vector images using ImageMagick library.
+	 * @param $file (string) Name of the SVG file or a '@' character followed by the SVG data string.
+	 * @param $x (float) Abscissa of the upper-left corner.
+	 * @param $y (float) Ordinate of the upper-left corner.
+	 * @param $w (float) Width of the image in the page. If not specified or equal to zero, it is automatically calculated.
+	 * @param $h (float) Height of the image in the page. If not specified or equal to zero, it is automatically calculated.
+	 * @param $link (mixed) URL or identifier returned by AddLink().
+	 * @param $align (string) Indicates the alignment of the pointer next to image insertion relative to image height. The value can be:<ul><li>T: top-right for LTR or top-left for RTL</li><li>M: middle-right for LTR or middle-left for RTL</li><li>B: bottom-right for LTR or bottom-left for RTL</li><li>N: next line</li></ul> If the alignment is an empty string, then the pointer will be restored on the starting SVG position.
+	 * @param $palign (string) Allows to center or align the image on the current line. Possible values are:<ul><li>L : left align</li><li>C : center</li><li>R : right align</li><li>'' : empty string : left for LTR or right for RTL</li></ul>
+	 * @param $border (mixed) Indicates if borders must be drawn around the cell. The value can be a number:<ul><li>0: no border (default)</li><li>1: frame</li></ul> or a string containing some or all of the following characters (in any order):<ul><li>L: left</li><li>T: top</li><li>R: right</li><li>B: bottom</li></ul> or an array of line styles for each border group - for example: array('LTRB' => array('width' => 2, 'cap' => 'butt', 'join' => 'miter', 'dash' => 0, 'color' => array(0, 0, 0)))
+	 * @param $fitonpage (boolean) if true the image is resized to not exceed page dimensions.
+	 * @author Nicola Asuni
+	 * @since 5.0.000 (2010-05-02)
+	 * @public
+	 */
+	public function ImageSVG($file, $x='', $y='', $w=0, $h=0, $link='', $align='', $palign='', $border=0, $fitonpage=false) {
+		if ($this->state != 2) {
+			 return;
+		}
+		if ($this->rasterize_vector_images AND ($w > 0) AND ($h > 0)) {
+			// convert SVG to raster image using GD or ImageMagick libraries
+			return $this->Image($file, $x, $y, $w, $h, 'SVG', $link, $align, true, 300, $palign, false, false, $border, false, false, false);
+		}
+		if ($file{0} === '@') { // image from string
+			$this->svgdir = '';
+			$svgdata = substr($file, 1);
+		} else { // SVG file
+			$this->svgdir = dirname($file);
+			$svgdata = file_get_contents($file);
+		}
+		if ($svgdata === false) {
+			$this->Error('SVG file not found: '.$file);
+		}
+		if ($x === '') {
+			$x = $this->x;
+		}
+		if ($y === '') {
+			$y = $this->y;
+		}
+		// check page for no-write regions and adapt page margins if necessary
+		list($x, $y) = $this->checkPageRegions($h, $x, $y);
+		$k = $this->k;
+		$ox = 0;
+		$oy = 0;
+		$ow = $w;
+		$oh = $h;
+		$aspect_ratio_align = 'xMidYMid';
+		$aspect_ratio_ms = 'meet';
+		$regs = array();
+		// get original image width and height
+		preg_match('/<svg([^\>]*)>/si', $svgdata, $regs);
+		if (isset($regs[1]) AND !empty($regs[1])) {
+			$tmp = array();
+			if (preg_match('/[\s]+x[\s]*=[\s]*"([^"]*)"/si', $regs[1], $tmp)) {
+				$ox = $this->getHTMLUnitToUnits($tmp[1], 0, $this->svgunit, false);
+			}
+			$tmp = array();
+			if (preg_match('/[\s]+y[\s]*=[\s]*"([^"]*)"/si', $regs[1], $tmp)) {
+				$oy = $this->getHTMLUnitToUnits($tmp[1], 0, $this->svgunit, false);
+			}
+			$tmp = array();
+			if (preg_match('/[\s]+width[\s]*=[\s]*"([^"]*)"/si', $regs[1], $tmp)) {
+				$ow = $this->getHTMLUnitToUnits($tmp[1], 1, $this->svgunit, false);
+			}
+			$tmp = array();
+			if (preg_match('/[\s]+height[\s]*=[\s]*"([^"]*)"/si', $regs[1], $tmp)) {
+				$oh = $this->getHTMLUnitToUnits($tmp[1], 1, $this->svgunit, false);
+			}
+			$tmp = array();
+			$view_box = array();
+			if (preg_match('/[\s]+viewBox[\s]*=[\s]*"[\s]*([0-9\.\-]+)[\s]+([0-9\.\-]+)[\s]+([0-9\.]+)[\s]+([0-9\.]+)[\s]*"/si', $regs[1], $tmp)) {
+				if (count($tmp) == 5) {
+					array_shift($tmp);
+					foreach ($tmp as $key => $val) {
+						$view_box[$key] = $this->getHTMLUnitToUnits($val, 0, $this->svgunit, false);
+					}
+					$ox = $view_box[0];
+					$oy = $view_box[1];
+				}
+				// get aspect ratio
+				$tmp = array();
+				if (preg_match('/[\s]+preserveAspectRatio[\s]*=[\s]*"([^"]*)"/si', $regs[1], $tmp)) {
+					$aspect_ratio = preg_split('/[\s]+/si', $tmp[1]);
+					switch (count($aspect_ratio)) {
+						case 3: {
+							$aspect_ratio_align = $aspect_ratio[1];
+							$aspect_ratio_ms = $aspect_ratio[2];
+							break;
+						}
+						case 2: {
+							$aspect_ratio_align = $aspect_ratio[0];
+							$aspect_ratio_ms = $aspect_ratio[1];
+							break;
+						}
+						case 1: {
+							$aspect_ratio_align = $aspect_ratio[0];
+							$aspect_ratio_ms = 'meet';
+							break;
+						}
+					}
+				}
+			}
+		}
+		// calculate image width and height on document
+		if (($w <= 0) AND ($h <= 0)) {
+			// convert image size to document unit
+			$w = $ow;
+			$h = $oh;
+		} elseif ($w <= 0) {
+			$w = $h * $ow / $oh;
+		} elseif ($h <= 0) {
+			$h = $w * $oh / $ow;
+		}
+		// fit the image on available space
+		list($w, $h, $x, $y) = $this->fitBlock($w, $h, $x, $y, $fitonpage);
+		if ($this->rasterize_vector_images) {
+			// convert SVG to raster image using GD or ImageMagick libraries
+			return $this->Image($file, $x, $y, $w, $h, 'SVG', $link, $align, true, 300, $palign, false, false, $border, false, false, false);
+		}
+		// set alignment
+		$this->img_rb_y = $y + $h;
+		// set alignment
+		if ($this->rtl) {
+			if ($palign == 'L') {
+				$ximg = $this->lMargin;
+			} elseif ($palign == 'C') {
+				$ximg = ($this->w + $this->lMargin - $this->rMargin - $w) / 2;
+			} elseif ($palign == 'R') {
+				$ximg = $this->w - $this->rMargin - $w;
+			} else {
+				$ximg = $x - $w;
+			}
+			$this->img_rb_x = $ximg;
+		} else {
+			if ($palign == 'L') {
+				$ximg = $this->lMargin;
+			} elseif ($palign == 'C') {
+				$ximg = ($this->w + $this->lMargin - $this->rMargin - $w) / 2;
+			} elseif ($palign == 'R') {
+				$ximg = $this->w - $this->rMargin - $w;
+			} else {
+				$ximg = $x;
+			}
+			$this->img_rb_x = $ximg + $w;
+		}
+		// store current graphic vars
+		$gvars = $this->getGraphicVars();
+		// store SVG position and scale factors
+		$svgoffset_x = ($ximg - $ox) * $this->k;
+		$svgoffset_y = -($y - $oy) * $this->k;
+		if (isset($view_box[2]) AND ($view_box[2] > 0) AND ($view_box[3] > 0)) {
+			$ow = $view_box[2];
+			$oh = $view_box[3];
+		} else {
+			if ($ow <= 0) {
+				$ow = $w;
+			}
+			if ($oh <= 0) {
+				$oh = $h;
+			}
+		}
+		$svgscale_x = $w / $ow;
+		$svgscale_y = $h / $oh;
+		// scaling and alignment
+		if ($aspect_ratio_align != 'none') {
+			// store current scaling values
+			$svgscale_old_x = $svgscale_x;
+			$svgscale_old_y = $svgscale_y;
+			// force uniform scaling
+			if ($aspect_ratio_ms == 'slice') {
+				// the entire viewport is covered by the viewBox
+				if ($svgscale_x > $svgscale_y) {
+					$svgscale_y = $svgscale_x;
+				} elseif ($svgscale_x < $svgscale_y) {
+					$svgscale_x = $svgscale_y;
+				}
+			} else { // meet
+				// the entire viewBox is visible within the viewport
+				if ($svgscale_x < $svgscale_y) {
+					$svgscale_y = $svgscale_x;
+				} elseif ($svgscale_x > $svgscale_y) {
+					$svgscale_x = $svgscale_y;
+				}
+			}
+			// correct X alignment
+			switch (substr($aspect_ratio_align, 1, 3)) {
+				case 'Min': {
+					// do nothing
+					break;
+				}
+				case 'Max': {
+					$svgoffset_x += (($w * $this->k) - ($ow * $this->k * $svgscale_x));
+					break;
+				}
+				default:
+				case 'Mid': {
+					$svgoffset_x += ((($w * $this->k) - ($ow * $this->k * $svgscale_x)) / 2);
+					break;
+				}
+			}
+			// correct Y alignment
+			switch (substr($aspect_ratio_align, 5)) {
+				case 'Min': {
+					// do nothing
+					break;
+				}
+				case 'Max': {
+					$svgoffset_y -= (($h * $this->k) - ($oh * $this->k * $svgscale_y));
+					break;
+				}
+				default:
+				case 'Mid': {
+					$svgoffset_y -= ((($h * $this->k) - ($oh * $this->k * $svgscale_y)) / 2);
+					break;
+				}
+			}
+		}
+		// store current page break mode
+		$page_break_mode = $this->AutoPageBreak;
+		$page_break_margin = $this->getBreakMargin();
+		$cell_padding = $this->cell_padding;
+		$this->SetCellPadding(0);
+		$this->SetAutoPageBreak(false);
+		// save the current graphic state
+		$this->_out('q'.$this->epsmarker);
+		// set initial clipping mask
+		$this->Rect($x, $y, $w, $h, 'CNZ', array(), array());
+		// scale and translate
+		$e = $ox * $this->k * (1 - $svgscale_x);
+		$f = ($this->h - $oy) * $this->k * (1 - $svgscale_y);
+		$this->_out(sprintf('%F %F %F %F %F %F cm', $svgscale_x, 0, 0, $svgscale_y, ($e + $svgoffset_x), ($f + $svgoffset_y)));
+		// creates a new XML parser to be used by the other XML functions
+		$this->parser = xml_parser_create('UTF-8');
+		// the following function allows to use parser inside object
+		xml_set_object($this->parser, $this);
+		// disable case-folding for this XML parser
+		xml_parser_set_option($this->parser, XML_OPTION_CASE_FOLDING, 0);
+		// sets the element handler functions for the XML parser
+		xml_set_element_handler($this->parser, 'startSVGElementHandler', 'endSVGElementHandler');
+		// sets the character data handler function for the XML parser
+		xml_set_character_data_handler($this->parser, 'segSVGContentHandler');
+		// start parsing an XML document
+		if (!xml_parse($this->parser, $svgdata)) {
+			$error_message = sprintf('SVG Error: %s at line %d', xml_error_string(xml_get_error_code($this->parser)), xml_get_current_line_number($this->parser));
+			$this->Error($error_message);
+		}
+		// free this XML parser
+		xml_parser_free($this->parser);
+		// restore previous graphic state
+		$this->_out($this->epsmarker.'Q');
+		// restore graphic vars
+		$this->setGraphicVars($gvars);
+		$this->lasth = $gvars['lasth'];
+		if (!empty($border)) {
+			$bx = $this->x;
+			$by = $this->y;
+			$this->x = $ximg;
+			if ($this->rtl) {
+				$this->x += $w;
+			}
+			$this->y = $y;
+			$this->Cell($w, $h, '', $border, 0, '', 0, '', 0, true);
+			$this->x = $bx;
+			$this->y = $by;
+		}
+		if ($link) {
+			$this->Link($ximg, $y, $w, $h, $link, 0);
+		}
+		// set pointer to align the next text/objects
+		switch($align) {
+			case 'T':{
+				$this->y = $y;
+				$this->x = $this->img_rb_x;
+				break;
+			}
+			case 'M':{
+				$this->y = $y + round($h/2);
+				$this->x = $this->img_rb_x;
+				break;
+			}
+			case 'B':{
+				$this->y = $this->img_rb_y;
+				$this->x = $this->img_rb_x;
+				break;
+			}
+			case 'N':{
+				$this->SetY($this->img_rb_y);
+				break;
+			}
+			default:{
+				// restore pointer to starting position
+				$this->x = $gvars['x'];
+				$this->y = $gvars['y'];
+				$this->page = $gvars['page'];
+				$this->current_column = $gvars['current_column'];
+				$this->tMargin = $gvars['tMargin'];
+				$this->bMargin = $gvars['bMargin'];
+				$this->w = $gvars['w'];
+				$this->h = $gvars['h'];
+				$this->wPt = $gvars['wPt'];
+				$this->hPt = $gvars['hPt'];
+				$this->fwPt = $gvars['fwPt'];
+				$this->fhPt = $gvars['fhPt'];
+				break;
+			}
+		}
+		$this->endlinex = $this->img_rb_x;
+		// restore page break
+		$this->SetAutoPageBreak($page_break_mode, $page_break_margin);
+		$this->cell_padding = $cell_padding;
+	}
+
+	/**
+	 * Get the tranformation matrix from SVG transform attribute
+	 * @param $attribute (string) transformation
+	 * @return array of transformations
+	 * @author Nicola Asuni
+	 * @since 5.0.000 (2010-05-02)
+	 * @protected
+	 */
+	protected function getSVGTransformMatrix($attribute) {
+		// identity matrix
+		$tm = array(1, 0, 0, 1, 0, 0);
+		$transform = array();
+		if (preg_match_all('/(matrix|translate|scale|rotate|skewX|skewY)[\s]*\(([^\)]+)\)/si', $attribute, $transform, PREG_SET_ORDER) > 0) {
+			foreach ($transform as $key => $data) {
+				if (!empty($data[2])) {
+					$a = 1;
+					$b = 0;
+					$c = 0;
+					$d = 1;
+					$e = 0;
+					$f = 0;
+					$regs = array();
+					switch ($data[1]) {
+						case 'matrix': {
+							if (preg_match('/([a-z0-9\-\.]+)[\,\s]+([a-z0-9\-\.]+)[\,\s]+([a-z0-9\-\.]+)[\,\s]+([a-z0-9\-\.]+)[\,\s]+([a-z0-9\-\.]+)[\,\s]+([a-z0-9\-\.]+)/si', $data[2], $regs)) {
+								$a = $regs[1];
+								$b = $regs[2];
+								$c = $regs[3];
+								$d = $regs[4];
+								$e = $regs[5];
+								$f = $regs[6];
+							}
+							break;
+						}
+						case 'translate': {
+							if (preg_match('/([a-z0-9\-\.]+)[\,\s]+([a-z0-9\-\.]+)/si', $data[2], $regs)) {
+								$e = $regs[1];
+								$f = $regs[2];
+							} elseif (preg_match('/([a-z0-9\-\.]+)/si', $data[2], $regs)) {
+								$e = $regs[1];
+							}
+							break;
+						}
+						case 'scale': {
+							if (preg_match('/([a-z0-9\-\.]+)[\,\s]+([a-z0-9\-\.]+)/si', $data[2], $regs)) {
+								$a = $regs[1];
+								$d = $regs[2];
+							} elseif (preg_match('/([a-z0-9\-\.]+)/si', $data[2], $regs)) {
+								$a = $regs[1];
+								$d = $a;
+							}
+							break;
+						}
+						case 'rotate': {
+							if (preg_match('/([0-9\-\.]+)[\,\s]+([a-z0-9\-\.]+)[\,\s]+([a-z0-9\-\.]+)/si', $data[2], $regs)) {
+								$ang = deg2rad($regs[1]);
+								$x = $regs[2];
+								$y = $regs[3];
+								$a = cos($ang);
+								$b = sin($ang);
+								$c = -$b;
+								$d = $a;
+								$e = ($x * (1 - $a)) - ($y * $c);
+								$f = ($y * (1 - $d)) - ($x * $b);
+							} elseif (preg_match('/([0-9\-\.]+)/si', $data[2], $regs)) {
+								$ang = deg2rad($regs[1]);
+								$a = cos($ang);
+								$b = sin($ang);
+								$c = -$b;
+								$d = $a;
+								$e = 0;
+								$f = 0;
+							}
+							break;
+						}
+						case 'skewX': {
+							if (preg_match('/([0-9\-\.]+)/si', $data[2], $regs)) {
+								$c = tan(deg2rad($regs[1]));
+							}
+							break;
+						}
+						case 'skewY': {
+							if (preg_match('/([0-9\-\.]+)/si', $data[2], $regs)) {
+								$b = tan(deg2rad($regs[1]));
+							}
+							break;
+						}
+					}
+					$tm = $this->getTransformationMatrixProduct($tm, array($a, $b, $c, $d, $e, $f));
+				}
+			}
+		}
+		return $tm;
+	}
+
+	/**
+	 * Get the product of two SVG tranformation matrices
+	 * @param $ta (array) first SVG tranformation matrix
+	 * @param $tb (array) second SVG tranformation matrix
+	 * @return transformation array
+	 * @author Nicola Asuni
+	 * @since 5.0.000 (2010-05-02)
+	 * @protected
+	 */
+	protected function getTransformationMatrixProduct($ta, $tb) {
+		$tm = array();
+		$tm[0] = ($ta[0] * $tb[0]) + ($ta[2] * $tb[1]);
+		$tm[1] = ($ta[1] * $tb[0]) + ($ta[3] * $tb[1]);
+		$tm[2] = ($ta[0] * $tb[2]) + ($ta[2] * $tb[3]);
+		$tm[3] = ($ta[1] * $tb[2]) + ($ta[3] * $tb[3]);
+		$tm[4] = ($ta[0] * $tb[4]) + ($ta[2] * $tb[5]) + $ta[4];
+		$tm[5] = ($ta[1] * $tb[4]) + ($ta[3] * $tb[5]) + $ta[5];
+		return $tm;
+	}
+
+	/**
+	 * Convert SVG transformation matrix to PDF.
+	 * @param $tm (array) original SVG transformation matrix
+	 * @return array transformation matrix
+	 * @protected
+	 * @since 5.0.000 (2010-05-02)
+	 */
+	protected function convertSVGtMatrix($tm) {
+		$a = $tm[0];
+		$b = -$tm[1];
+		$c = -$tm[2];
+		$d = $tm[3];
+		$e = $this->getHTMLUnitToUnits($tm[4], 1, $this->svgunit, false) * $this->k;
+		$f = -$this->getHTMLUnitToUnits($tm[5], 1, $this->svgunit, false) * $this->k;
+		$x = 0;
+		$y = $this->h * $this->k;
+		$e = ($x * (1 - $a)) - ($y * $c) + $e;
+		$f = ($y * (1 - $d)) - ($x * $b) + $f;
+		return array($a, $b, $c, $d, $e, $f);
+	}
+
+	/**
+	 * Apply SVG graphic transformation matrix.
+	 * @param $tm (array) original SVG transformation matrix
+	 * @protected
+	 * @since 5.0.000 (2010-05-02)
+	 */
+	protected function SVGTransform($tm) {
+		$this->Transform($this->convertSVGtMatrix($tm));
+	}
+
+	/**
+	 * Apply the requested SVG styles (*** TO BE COMPLETED ***)
+	 * @param $svgstyle (array) array of SVG styles to apply
+	 * @param $prevsvgstyle (array) array of previous SVG style
+	 * @param $x (int) X origin of the bounding box
+	 * @param $y (int) Y origin of the bounding box
+	 * @param $w (int) width of the bounding box
+	 * @param $h (int) height of the bounding box
+	 * @param $clip_function (string) clip function
+	 * @param $clip_params (array) array of parameters for clipping function
+	 * @return object style
+	 * @author Nicola Asuni
+	 * @since 5.0.000 (2010-05-02)
+	 * @protected
+	 */
+	protected function setSVGStyles($svgstyle, $prevsvgstyle, $x=0, $y=0, $w=1, $h=1, $clip_function='', $clip_params=array()) {
+		if ($this->state != 2) {
+			 return;
+		}
+		$objstyle = '';
+		$minlen = (0.01 / $this->k); // minimum acceptable length (3 point)
+		if (!isset($svgstyle['opacity'])) {
+			return $objstyle;
+		}
+		// clip-path
+		$regs = array();
+		if (preg_match('/url\([\s]*\#([^\)]*)\)/si', $svgstyle['clip-path'], $regs)) {
+			$clip_path = $this->svgclippaths[$regs[1]];
+			foreach ($clip_path as $cp) {
+				$this->startSVGElementHandler('clip-path', $cp['name'], $cp['attribs'], $cp['tm']);
+			}
+		}
+		// opacity
+		if ($svgstyle['opacity'] != 1) {
+			$this->setAlpha($svgstyle['opacity'], 'Normal', $svgstyle['opacity'], false);
+		}
+		// color
+		$fill_color = $this->convertHTMLColorToDec($svgstyle['color']);
+		$this->SetFillColorArray($fill_color);
+		// text color
+		$text_color = $this->convertHTMLColorToDec($svgstyle['text-color']);
+		$this->SetTextColorArray($text_color);
+		// clip
+		if (preg_match('/rect\(([a-z0-9\-\.]*)[\s]*([a-z0-9\-\.]*)[\s]*([a-z0-9\-\.]*)[\s]*([a-z0-9\-\.]*)\)/si', $svgstyle['clip'], $regs)) {
+			$top = (isset($regs[1])?$this->getHTMLUnitToUnits($regs[1], 0, $this->svgunit, false):0);
+			$right = (isset($regs[2])?$this->getHTMLUnitToUnits($regs[2], 0, $this->svgunit, false):0);
+			$bottom = (isset($regs[3])?$this->getHTMLUnitToUnits($regs[3], 0, $this->svgunit, false):0);
+			$left = (isset($regs[4])?$this->getHTMLUnitToUnits($regs[4], 0, $this->svgunit, false):0);
+			$cx = $x + $left;
+			$cy = $y + $top;
+			$cw = $w - $left - $right;
+			$ch = $h - $top - $bottom;
+			if ($svgstyle['clip-rule'] == 'evenodd') {
+				$clip_rule = 'CNZ';
+			} else {
+				$clip_rule = 'CEO';
+			}
+			$this->Rect($cx, $cy, $cw, $ch, $clip_rule, array(), array());
+		}
+		// fill
+		$regs = array();
+		if (preg_match('/url\([\s]*\#([^\)]*)\)/si', $svgstyle['fill'], $regs)) {
+			// gradient
+			$gradient = $this->svggradients[$regs[1]];
+			if (isset($gradient['xref'])) {
+				// reference to another gradient definition
+				$newgradient = $this->svggradients[$gradient['xref']];
+				$newgradient['coords'] = $gradient['coords'];
+				$newgradient['mode'] = $gradient['mode'];
+				$newgradient['gradientUnits'] = $gradient['gradientUnits'];
+				if (isset($gradient['gradientTransform'])) {
+					$newgradient['gradientTransform'] = $gradient['gradientTransform'];
+				}
+				$gradient = $newgradient;
+			}
+			//save current Graphic State
+			$this->_out('q');
+			//set clipping area
+			if (!empty($clip_function) AND method_exists($this, $clip_function)) {
+				$bbox = call_user_func_array(array($this, $clip_function), $clip_params);
+				if (is_array($bbox) AND (count($bbox) == 4)) {
+					list($x, $y, $w, $h) = $bbox;
+				}
+			}
+			if ($gradient['mode'] == 'measure') {
+				if (isset($gradient['gradientTransform']) AND !empty($gradient['gradientTransform'])) {
+					$gtm = $gradient['gradientTransform'];
+					// apply transformation matrix
+					$xa = ($gtm[0] * $gradient['coords'][0]) + ($gtm[2] * $gradient['coords'][1]) + $gtm[4];
+					$ya = ($gtm[1] * $gradient['coords'][0]) + ($gtm[3] * $gradient['coords'][1]) + $gtm[5];
+					$xb = ($gtm[0] * $gradient['coords'][2]) + ($gtm[2] * $gradient['coords'][3]) + $gtm[4];
+					$yb = ($gtm[1] * $gradient['coords'][2]) + ($gtm[3] * $gradient['coords'][3]) + $gtm[5];
+					if (isset($gradient['coords'][4])) {
+						$gradient['coords'][4] = sqrt(pow(($gtm[0] * $gradient['coords'][4]), 2) + pow(($gtm[1] * $gradient['coords'][4]), 2));
+					}
+					$gradient['coords'][0] = $xa;
+					$gradient['coords'][1] = $ya;
+					$gradient['coords'][2] = $xb;
+					$gradient['coords'][3] = $yb;
+				}
+				// convert SVG coordinates to user units
+				$gradient['coords'][0] = $this->getHTMLUnitToUnits($gradient['coords'][0], 0, $this->svgunit, false);
+				$gradient['coords'][1] = $this->getHTMLUnitToUnits($gradient['coords'][1], 0, $this->svgunit, false);
+				$gradient['coords'][2] = $this->getHTMLUnitToUnits($gradient['coords'][2], 0, $this->svgunit, false);
+				$gradient['coords'][3] = $this->getHTMLUnitToUnits($gradient['coords'][3], 0, $this->svgunit, false);
+				if (isset($gradient['coords'][4])) {
+					$gradient['coords'][4] = $this->getHTMLUnitToUnits($gradient['coords'][4], 0, $this->svgunit, false);
+				}
+				if ($w <= $minlen) {
+					$w = $minlen;
+				}
+				if ($h <= $minlen) {
+					$h = $minlen;
+				}
+				// shift units
+				if ($gradient['gradientUnits'] == 'objectBoundingBox') {
+					// convert to SVG coordinate system
+					$gradient['coords'][0] += $x;
+					$gradient['coords'][1] += $y;
+					$gradient['coords'][2] += $x;
+					$gradient['coords'][3] += $y;
+				}
+				// calculate percentages
+				$gradient['coords'][0] = (($gradient['coords'][0] - $x) / $w);
+				$gradient['coords'][1] = (($gradient['coords'][1] - $y) / $h);
+				$gradient['coords'][2] = (($gradient['coords'][2] - $x) / $w);
+				$gradient['coords'][3] = (($gradient['coords'][3] - $y) / $h);
+				if (isset($gradient['coords'][4])) {
+					$gradient['coords'][4] /= $w;
+				}
+			} elseif ($gradient['mode'] == 'percentage') {
+				foreach($gradient['coords'] as $key => $val) {
+					$gradient['coords'][$key] = (intval($val) / 100);
+					if ($val < 0) {
+						$gradient['coords'][$key] = 0;
+					} elseif ($val > 1) {
+						$gradient['coords'][$key] = 1;
+					}
+				}
+			}
+			if (($gradient['type'] == 2) AND ($gradient['coords'][0] == $gradient['coords'][2]) AND ($gradient['coords'][1] == $gradient['coords'][3])) {
+				// single color (no shading)
+				$gradient['coords'][0] = 1;
+				$gradient['coords'][1] = 0;
+				$gradient['coords'][2] = 0.999;
+				$gradient['coords'][3] = 0;
+			}
+			// swap Y coordinates
+			$tmp = $gradient['coords'][1];
+			$gradient['coords'][1] = $gradient['coords'][3];
+			$gradient['coords'][3] = $tmp;
+			// set transformation map for gradient
+			if ($gradient['type'] == 3) {
+				// circular gradient
+				$cy = $this->h - $y - ($gradient['coords'][1] * ($w + $h));
+				$this->_out(sprintf('%F 0 0 %F %F %F cm', ($w * $this->k), ($w * $this->k), ($x * $this->k), ($cy * $this->k)));
+			} else {
+				$this->_out(sprintf('%F 0 0 %F %F %F cm', ($w * $this->k), ($h * $this->k), ($x * $this->k), (($this->h - ($y + $h)) * $this->k)));
+			}
+			if (count($gradient['stops']) > 1) {
+				$this->Gradient($gradient['type'], $gradient['coords'], $gradient['stops'], array(), false);
+			}
+		} elseif ($svgstyle['fill'] != 'none') {
+			$fill_color = $this->convertHTMLColorToDec($svgstyle['fill']);
+			if ($svgstyle['fill-opacity'] != 1) {
+				$this->setAlpha($this->alpha['CA'], 'Normal', $svgstyle['fill-opacity'], false);
+			}
+			$this->SetFillColorArray($fill_color);
+			if ($svgstyle['fill-rule'] == 'evenodd') {
+				$objstyle .= 'F*';
+			} else {
+				$objstyle .= 'F';
+			}
+		}
+		// stroke
+		if ($svgstyle['stroke'] != 'none') {
+			if ($svgstyle['stroke-opacity'] != 1) {
+				$this->setAlpha($svgstyle['stroke-opacity'], 'Normal', $this->alpha['ca'], false);
+			}
+			$stroke_style = array(
+				'color' => $this->convertHTMLColorToDec($svgstyle['stroke']),
+				'width' => $this->getHTMLUnitToUnits($svgstyle['stroke-width'], 0, $this->svgunit, false),
+				'cap' => $svgstyle['stroke-linecap'],
+				'join' => $svgstyle['stroke-linejoin']
+				);
+			if (isset($svgstyle['stroke-dasharray']) AND !empty($svgstyle['stroke-dasharray']) AND ($svgstyle['stroke-dasharray'] != 'none')) {
+				$stroke_style['dash'] = $svgstyle['stroke-dasharray'];
+			}
+			$this->SetLineStyle($stroke_style);
+			$objstyle .= 'D';
+		}
+		// font
+		$regs = array();
+		if (!empty($svgstyle['font'])) {
+			if (preg_match('/font-family[\s]*:[\s]*([^\;\"]*)/si', $svgstyle['font'], $regs)) {
+				$font_family = $this->getFontFamilyName($regs[1]);
+			} else {
+				$font_family = $svgstyle['font-family'];
+			}
+			if (preg_match('/font-size[\s]*:[\s]*([^\s\;\"]*)/si', $svgstyle['font'], $regs)) {
+				$font_size = trim($regs[1]);
+			} else {
+				$font_size = $svgstyle['font-size'];
+			}
+			if (preg_match('/font-style[\s]*:[\s]*([^\s\;\"]*)/si', $svgstyle['font'], $regs)) {
+				$font_style = trim($regs[1]);
+			} else {
+				$font_style = $svgstyle['font-style'];
+			}
+			if (preg_match('/font-weight[\s]*:[\s]*([^\s\;\"]*)/si', $svgstyle['font'], $regs)) {
+				$font_weight = trim($regs[1]);
+			} else {
+				$font_weight = $svgstyle['font-weight'];
+			}
+			if (preg_match('/font-stretch[\s]*:[\s]*([^\s\;\"]*)/si', $svgstyle['font'], $regs)) {
+				$font_stretch = trim($regs[1]);
+			} else {
+				$font_stretch = $svgstyle['font-stretch'];
+			}
+			if (preg_match('/letter-spacing[\s]*:[\s]*([^\s\;\"]*)/si', $svgstyle['font'], $regs)) {
+				$font_spacing = trim($regs[1]);
+			} else {
+				$font_spacing = $svgstyle['letter-spacing'];
+			}
+		} else {
+			$font_family = $this->getFontFamilyName($svgstyle['font-family']);
+			$font_size = $svgstyle['font-size'];
+			$font_style = $svgstyle['font-style'];
+			$font_weight = $svgstyle['font-weight'];
+			$font_stretch = $svgstyle['font-stretch'];
+			$font_spacing = $svgstyle['letter-spacing'];
+		}
+		$font_size = $this->getHTMLUnitToUnits($font_size, $prevsvgstyle['font-size'], $this->svgunit, false) * $this->k;
+		$font_stretch = $this->getCSSFontStretching($font_stretch, $svgstyle['font-stretch']);
+		$font_spacing = $this->getCSSFontSpacing($font_spacing, $svgstyle['letter-spacing']);
+		switch ($font_style) {
+			case 'italic': {
+				$font_style = 'I';
+				break;
+			}
+			case 'oblique': {
+				$font_style = 'I';
+				break;
+			}
+			default:
+			case 'normal': {
+				$font_style = '';
+				break;
+			}
+		}
+		switch ($font_weight) {
+			case 'bold':
+			case 'bolder': {
+				$font_style .= 'B';
+				break;
+			}
+		}
+		switch ($svgstyle['text-decoration']) {
+			case 'underline': {
+				$font_style .= 'U';
+				break;
+			}
+			case 'overline': {
+				$font_style .= 'O';
+				break;
+			}
+			case 'line-through': {
+				$font_style .= 'D';
+				break;
+			}
+			default:
+			case 'none': {
+				break;
+			}
+		}
+		$this->SetFont($font_family, $font_style, $font_size);
+		$this->setFontStretching($font_stretch);
+		$this->setFontSpacing($font_spacing);
+		return $objstyle;
+	}
+
+	/**
+	 * Draws an SVG path
+	 * @param $d (string) attribute d of the path SVG element
+	 * @param $style (string) Style of rendering. Possible values are:
+	 * <ul>
+	 *	 <li>D or empty string: Draw (default).</li>
+	 *	 <li>F: Fill.</li>
+	 *	 <li>F*: Fill using the even-odd rule to determine which regions lie inside the clipping path.</li>
+	 *	 <li>DF or FD: Draw and fill.</li>
+	 *	 <li>DF* or FD*: Draw and fill using the even-odd rule to determine which regions lie inside the clipping path.</li>
+	 *	 <li>CNZ: Clipping mode (using the even-odd rule to determine which regions lie inside the clipping path).</li>
+	 *	 <li>CEO: Clipping mode (using the nonzero winding number rule to determine which regions lie inside the clipping path).</li>
+	 * </ul>
+	 * @return array of container box measures (x, y, w, h)
+	 * @author Nicola Asuni
+	 * @since 5.0.000 (2010-05-02)
+	 * @protected
+	 */
+	protected function SVGPath($d, $style='') {
+		if ($this->state != 2) {
+			 return;
+		}
+		// set fill/stroke style
+		$op = $this->getPathPaintOperator($style, '');
+		if (empty($op)) {
+			return;
+		}
+		$paths = array();
+		$d = preg_replace('/([0-9ACHLMQSTVZ])([\-\+])/si', '\\1 \\2', $d);
+		preg_match_all('/([ACHLMQSTVZ])[\s]*([^ACHLMQSTVZ\"]*)/si', $d, $paths, PREG_SET_ORDER);
+		$x = 0;
+		$y = 0;
+		$x1 = 0;
+		$y1 = 0;
+		$x2 = 0;
+		$y2 = 0;
+		$xmin = 2147483647;
+		$xmax = 0;
+		$ymin = 2147483647;
+		$ymax = 0;
+		$relcoord = false;
+		$minlen = (0.01 / $this->k); // minimum acceptable length (3 point)
+		$firstcmd = true; // used to print first point
+		// draw curve pieces
+		foreach ($paths as $key => $val) {
+			// get curve type
+			$cmd = trim($val[1]);
+			if (strtolower($cmd) == $cmd) {
+				// use relative coordinated instead of absolute
+				$relcoord = true;
+				$xoffset = $x;
+				$yoffset = $y;
+			} else {
+				$relcoord = false;
+				$xoffset = 0;
+				$yoffset = 0;
+			}
+			$params = array();
+			if (isset($val[2])) {
+				// get curve parameters
+				$rawparams = preg_split('/([\,\s]+)/si', trim($val[2]));
+				$params = array();
+				foreach ($rawparams as $ck => $cp) {
+					$params[$ck] = $this->getHTMLUnitToUnits($cp, 0, $this->svgunit, false);
+					if (abs($params[$ck]) < $minlen) {
+						// aproximate little values to zero
+						$params[$ck] = 0;
+					}
+				}
+			}
+			// store current origin point
+			$x0 = $x;
+			$y0 = $y;
+			switch (strtoupper($cmd)) {
+				case 'M': { // moveto
+					foreach ($params as $ck => $cp) {
+						if (($ck % 2) == 0) {
+							$x = $cp + $xoffset;
+						} else {
+							$y = $cp + $yoffset;
+							if ($firstcmd OR (abs($x0 - $x) >= $minlen) OR (abs($y0 - $y) >= $minlen)) {
+								if ($ck == 1) {
+									$this->_outPoint($x, $y);
+									$firstcmd = false;
+								} else {
+									$this->_outLine($x, $y);
+								}
+								$x0 = $x;
+								$y0 = $y;
+							}
+							$xmin = min($xmin, $x);
+							$ymin = min($ymin, $y);
+							$xmax = max($xmax, $x);
+							$ymax = max($ymax, $y);
+							if ($relcoord) {
+								$xoffset = $x;
+								$yoffset = $y;
+							}
+						}
+					}
+					break;
+				}
+				case 'L': { // lineto
+					foreach ($params as $ck => $cp) {
+						if (($ck % 2) == 0) {
+							$x = $cp + $xoffset;
+						} else {
+							$y = $cp + $yoffset;
+							if ((abs($x0 - $x) >= $minlen) OR (abs($y0 - $y) >= $minlen)) {
+								$this->_outLine($x, $y);
+								$x0 = $x;
+								$y0 = $y;
+							}
+							$xmin = min($xmin, $x);
+							$ymin = min($ymin, $y);
+							$xmax = max($xmax, $x);
+							$ymax = max($ymax, $y);
+							if ($relcoord) {
+								$xoffset = $x;
+								$yoffset = $y;
+							}
+						}
+					}
+					break;
+				}
+				case 'H': { // horizontal lineto
+					foreach ($params as $ck => $cp) {
+						$x = $cp + $xoffset;
+						if ((abs($x0 - $x) >= $minlen) OR (abs($y0 - $y) >= $minlen)) {
+							$this->_outLine($x, $y);
+							$x0 = $x;
+							$y0 = $y;
+						}
+						$xmin = min($xmin, $x);
+						$xmax = max($xmax, $x);
+						if ($relcoord) {
+							$xoffset = $x;
+						}
+					}
+					break;
+				}
+				case 'V': { // vertical lineto
+					foreach ($params as $ck => $cp) {
+						$y = $cp + $yoffset;
+						if ((abs($x0 - $x) >= $minlen) OR (abs($y0 - $y) >= $minlen)) {
+							$this->_outLine($x, $y);
+							$x0 = $x;
+							$y0 = $y;
+						}
+						$ymin = min($ymin, $y);
+						$ymax = max($ymax, $y);
+						if ($relcoord) {
+							$yoffset = $y;
+						}
+					}
+					break;
+				}
+				case 'C': { // curveto
+					foreach ($params as $ck => $cp) {
+						$params[$ck] = $cp;
+						if ((($ck + 1) % 6) == 0) {
+							$x1 = $params[($ck - 5)] + $xoffset;
+							$y1 = $params[($ck - 4)] + $yoffset;
+							$x2 = $params[($ck - 3)] + $xoffset;
+							$y2 = $params[($ck - 2)] + $yoffset;
+							$x = $params[($ck - 1)] + $xoffset;
+							$y = $params[($ck)] + $yoffset;
+							$this->_outCurve($x1, $y1, $x2, $y2, $x, $y);
+							$xmin = min($xmin, $x, $x1, $x2);
+							$ymin = min($ymin, $y, $y1, $y2);
+							$xmax = max($xmax, $x, $x1, $x2);
+							$ymax = max($ymax, $y, $y1, $y2);
+							if ($relcoord) {
+								$xoffset = $x;
+								$yoffset = $y;
+							}
+						}
+					}
+					break;
+				}
+				case 'S': { // shorthand/smooth curveto
+					foreach ($params as $ck => $cp) {
+						$params[$ck] = $cp;
+						if ((($ck + 1) % 4) == 0) {
+							if (($key > 0) AND ((strtoupper($paths[($key - 1)][1]) == 'C') OR (strtoupper($paths[($key - 1)][1]) == 'S'))) {
+								$x1 = (2 * $x) - $x2;
+								$y1 = (2 * $y) - $y2;
+							} else {
+								$x1 = $x;
+								$y1 = $y;
+							}
+							$x2 = $params[($ck - 3)] + $xoffset;
+							$y2 = $params[($ck - 2)] + $yoffset;
+							$x = $params[($ck - 1)] + $xoffset;
+							$y = $params[($ck)] + $yoffset;
+							$this->_outCurve($x1, $y1, $x2, $y2, $x, $y);
+							$xmin = min($xmin, $x, $x1, $x2);
+							$ymin = min($ymin, $y, $y1, $y2);
+							$xmax = max($xmax, $x, $x1, $x2);
+							$ymax = max($ymax, $y, $y1, $y2);
+							if ($relcoord) {
+								$xoffset = $x;
+								$yoffset = $y;
+							}
+						}
+					}
+					break;
+				}
+				case 'Q': { // quadratic B�zier curveto
+					foreach ($params as $ck => $cp) {
+						$params[$ck] = $cp;
+						if ((($ck + 1) % 4) == 0) {
+							// convert quadratic points to cubic points
+							$x1 = $params[($ck - 3)] + $xoffset;
+							$y1 = $params[($ck - 2)] + $yoffset;
+							$xa = ($x + (2 * $x1)) / 3;
+							$ya = ($y + (2 * $y1)) / 3;
+							$x = $params[($ck - 1)] + $xoffset;
+							$y = $params[($ck)] + $yoffset;
+							$xb = ($x + (2 * $x1)) / 3;
+							$yb = ($y + (2 * $y1)) / 3;
+							$this->_outCurve($xa, $ya, $xb, $yb, $x, $y);
+							$xmin = min($xmin, $x, $xa, $xb);
+							$ymin = min($ymin, $y, $ya, $yb);
+							$xmax = max($xmax, $x, $xa, $xb);
+							$ymax = max($ymax, $y, $ya, $yb);
+							if ($relcoord) {
+								$xoffset = $x;
+								$yoffset = $y;
+							}
+						}
+					}
+					break;
+				}
+				case 'T': { // shorthand/smooth quadratic B�zier curveto
+					foreach ($params as $ck => $cp) {
+						$params[$ck] = $cp;
+						if (($ck % 2) != 0) {
+							if (($key > 0) AND ((strtoupper($paths[($key - 1)][1]) == 'Q') OR (strtoupper($paths[($key - 1)][1]) == 'T'))) {
+								$x1 = (2 * $x) - $x1;
+								$y1 = (2 * $y) - $y1;
+							} else {
+								$x1 = $x;
+								$y1 = $y;
+							}
+							// convert quadratic points to cubic points
+							$xa = ($x + (2 * $x1)) / 3;
+							$ya = ($y + (2 * $y1)) / 3;
+							$x = $params[($ck - 1)] + $xoffset;
+							$y = $params[($ck)] + $yoffset;
+							$xb = ($x + (2 * $x1)) / 3;
+							$yb = ($y + (2 * $y1)) / 3;
+							$this->_outCurve($xa, $ya, $xb, $yb, $x, $y);
+							$xmin = min($xmin, $x, $xa, $xb);
+							$ymin = min($ymin, $y, $ya, $yb);
+							$xmax = max($xmax, $x, $xa, $xb);
+							$ymax = max($ymax, $y, $ya, $yb);
+							if ($relcoord) {
+								$xoffset = $x;
+								$yoffset = $y;
+							}
+						}
+					}
+					break;
+				}
+				case 'A': { // elliptical arc
+					foreach ($params as $ck => $cp) {
+						$params[$ck] = $cp;
+						if ((($ck + 1) % 7) == 0) {
+							$x0 = $x;
+							$y0 = $y;
+							$rx = abs($params[($ck - 6)]);
+							$ry = abs($params[($ck - 5)]);
+							$ang = -$rawparams[($ck - 4)];
+							$angle = deg2rad($ang);
+							$fa = $rawparams[($ck - 3)]; // large-arc-flag
+							$fs = $rawparams[($ck - 2)]; // sweep-flag
+							$x = $params[($ck - 1)] + $xoffset;
+							$y = $params[$ck] + $yoffset;
+							if ((abs($x0 - $x) < $minlen) AND (abs($y0 - $y) < $minlen)) {
+								// endpoints are almost identical
+								$xmin = min($xmin, $x);
+								$ymin = min($ymin, $y);
+								$xmax = max($xmax, $x);
+								$ymax = max($ymax, $y);
+							} else {
+								$cos_ang = cos($angle);
+								$sin_ang = sin($angle);
+								$a = (($x0 - $x) / 2);
+								$b = (($y0 - $y) / 2);
+								$xa = ($a * $cos_ang) - ($b * $sin_ang);
+								$ya = ($a * $sin_ang) + ($b * $cos_ang);
+								$rx2 = $rx * $rx;
+								$ry2 = $ry * $ry;
+								$xa2 = $xa * $xa;
+								$ya2 = $ya * $ya;
+								$delta = ($xa2 / $rx2) + ($ya2 / $ry2);
+								if ($delta > 1) {
+									$rx *= sqrt($delta);
+									$ry *= sqrt($delta);
+									$rx2 = $rx * $rx;
+									$ry2 = $ry * $ry;
+								}
+								$numerator = (($rx2 * $ry2) - ($rx2 * $ya2) - ($ry2 * $xa2));
+								if ($numerator < 0) {
+									$root = 0;
+								} else {
+									$root = sqrt($numerator / (($rx2 * $ya2) + ($ry2 * $xa2)));
+								}
+								if ($fa == $fs){
+									$root *= -1;
+								}
+								$cax = $root * (($rx * $ya) / $ry);
+								$cay = -$root * (($ry * $xa) / $rx);
+								// coordinates of ellipse center
+								$cx = ($cax * $cos_ang) - ($cay * $sin_ang) + (($x0 + $x) / 2);
+								$cy = ($cax * $sin_ang) + ($cay * $cos_ang) + (($y0 + $y) / 2);
+								// get angles
+								$angs = $this->getVectorsAngle(1, 0, (($xa - $cax) / $rx), (($cay - $ya) / $ry));
+								$dang = $this->getVectorsAngle((($xa - $cax) / $rx), (($ya - $cay) / $ry), ((-$xa - $cax) / $rx), ((-$ya - $cay) / $ry));
+								if (($fs == 0) AND ($dang > 0)) {
+									$dang -= (2 * M_PI);
+								} elseif (($fs == 1) AND ($dang < 0)) {
+									$dang += (2 * M_PI);
+								}
+								$angf = $angs - $dang;
+								if ((($fs == 0) AND ($angs > $angf)) OR (($fs == 1) AND ($angs < $angf))) {
+									// reverse angles
+									$tmp = $angs;
+									$angs = $angf;
+									$angf = $tmp;
+								}
+								$angs = round(rad2deg($angs), 6);
+								$angf = round(rad2deg($angf), 6);
+								// covent angles to positive values
+								if (($angs < 0) AND ($angf < 0)) {
+									$angs += 360;
+									$angf += 360;
+								}
+								$pie = false;
+								if (($key == 0) AND (isset($paths[($key + 1)][1])) AND (trim($paths[($key + 1)][1]) == 'z')) {
+									$pie = true;
+								}
+								list($axmin, $aymin, $axmax, $aymax) = $this->_outellipticalarc($cx, $cy, $rx, $ry, $ang, $angs, $angf, $pie, 2, false, ($fs == 0), true);
+								$xmin = min($xmin, $x, $axmin);
+								$ymin = min($ymin, $y, $aymin);
+								$xmax = max($xmax, $x, $axmax);
+								$ymax = max($ymax, $y, $aymax);
+							}
+							if ($relcoord) {
+								$xoffset = $x;
+								$yoffset = $y;
+							}
+						}
+					}
+					break;
+				}
+				case 'Z': {
+					$this->_out('h');
+					break;
+				}
+			}
+			$firstcmd = false;
+		} // end foreach
+		if (!empty($op)) {
+			$this->_out($op);
+		}
+		return array($xmin, $ymin, ($xmax - $xmin), ($ymax - $ymin));
+	}
+
+	/**
+	 * Returns the angle in radiants between two vectors
+	 * @param $x1 (int) X coordinate of first vector point
+	 * @param $y1 (int) Y coordinate of first vector point
+	 * @param $x2 (int) X coordinate of second vector point
+	 * @param $y2 (int) Y coordinate of second vector point
+	 * @author Nicola Asuni
+	 * @since 5.0.000 (2010-05-04)
+	 * @protected
+	 */
+	protected function getVectorsAngle($x1, $y1, $x2, $y2) {
+		$dprod = ($x1 * $x2) + ($y1 * $y2);
+		$dist1 = sqrt(($x1 * $x1) + ($y1 * $y1));
+		$dist2 = sqrt(($x2 * $x2) + ($y2 * $y2));
+		$angle = acos($dprod / ($dist1 * $dist2));
+		if (is_nan($angle)) {
+			$angle = M_PI;
+		}
+		if ((($x1 * $y2) - ($x2 * $y1)) < 0) {
+			$angle *= -1;
+		}
+		return $angle;
+	}
+
+	/**
+	 * Sets the opening SVG element handler function for the XML parser. (*** TO BE COMPLETED ***)
+	 * @param $parser (resource) The first parameter, parser, is a reference to the XML parser calling the handler.
+	 * @param $name (string) The second parameter, name, contains the name of the element for which this handler is called. If case-folding is in effect for this parser, the element name will be in uppercase letters.
+	 * @param $attribs (array) The third parameter, attribs, contains an associative array with the element's attributes (if any). The keys of this array are the attribute names, the values are the attribute values. Attribute names are case-folded on the same criteria as element names. Attribute values are not case-folded. The original order of the attributes can be retrieved by walking through attribs the normal way, using each(). The first key in the array was the first attribute, and so on.
+	 * @param $ctm (array) tranformation matrix for clipping mode (starting transformation matrix).
+	 * @author Nicola Asuni
+	 * @since 5.0.000 (2010-05-02)
+	 * @protected
+	 */
+	protected function startSVGElementHandler($parser, $name, $attribs, $ctm=array()) {
+		// check if we are in clip mode
+		if ($this->svgclipmode) {
+			$this->svgclippaths[$this->svgclipid][] = array('name' => $name, 'attribs' => $attribs, 'tm' => $this->svgcliptm[$this->svgclipid]);
+			return;
+		}
+		if ($this->svgdefsmode AND !in_array($name, array('clipPath', 'linearGradient', 'radialGradient', 'stop'))) {
+			if (!isset($attribs['id'])) {
+				$attribs['id'] = 'DF_'.(count($this->svgdefs) + 1);
+			}
+			$this->svgdefs[$attribs['id']] = array('name' => $name, 'attribs' => $attribs);
+			return;
+		}
+		$clipping = false;
+		if ($parser == 'clip-path') {
+			// set clipping mode
+			$clipping = true;
+		}
+		// get styling properties
+		$prev_svgstyle = $this->svgstyles[(count($this->svgstyles) - 1)]; // previous style
+		$svgstyle = $this->svgstyles[0]; // set default style
+		if ($clipping AND !isset($attribs['fill']) AND (!isset($attribs['style']) OR (!preg_match('/[;\"\s]{1}fill[\s]*:[\s]*([^;\"]*)/si', $attribs['style'], $attrval)))) {
+			// default fill attribute for clipping
+			$attribs['fill'] = 'none';
+		}
+		if (isset($attribs['style']) AND !$this->empty_string($attribs['style'])) {
+			// fix style for regular expression
+			$attribs['style'] = ';'.$attribs['style'];
+		}
+		foreach ($prev_svgstyle as $key => $val) {
+			if (in_array($key, $this->svginheritprop)) {
+				// inherit previous value
+				$svgstyle[$key] = $val;
+			}
+			if (isset($attribs[$key]) AND !$this->empty_string($attribs[$key])) {
+				// specific attribute settings
+				if ($attribs[$key] == 'inherit') {
+					$svgstyle[$key] = $val;
+				} else {
+					$svgstyle[$key] = $attribs[$key];
+				}
+			} elseif (isset($attribs['style']) AND !$this->empty_string($attribs['style'])) {
+				// CSS style syntax
+				$attrval = array();
+				if (preg_match('/[;\"\s]{1}'.$key.'[\s]*:[\s]*([^;\"]*)/si', $attribs['style'], $attrval) AND isset($attrval[1])) {
+					if ($attrval[1] == 'inherit') {
+						$svgstyle[$key] = $val;
+					} else {
+						$svgstyle[$key] = $attrval[1];
+					}
+				}
+			}
+		}
+		// transformation matrix
+		if (!empty($ctm)) {
+			$tm = $ctm;
+		} else {
+			//$tm = $this->svgstyles[(count($this->svgstyles) - 1)]['transfmatrix'];
+			$tm = array(1,0,0,1,0,0);
+		}
+		if (isset($attribs['transform']) AND !empty($attribs['transform'])) {
+			$tm = $this->getTransformationMatrixProduct($tm, $this->getSVGTransformMatrix($attribs['transform']));
+		}
+		$svgstyle['transfmatrix'] = $tm;
+		$invisible = false;
+		if (($svgstyle['visibility'] == 'hidden') OR ($svgstyle['visibility'] == 'collapse') OR ($svgstyle['display'] == 'none')) {
+			// the current graphics element is invisible (nothing is painted)
+			$invisible = true;
+		}
+		// process tag
+		switch($name) {
+			case 'defs': {
+				$this->svgdefsmode = true;
+				break;
+			}
+			// clipPath
+			case 'clipPath': {
+				if ($invisible) {
+					break;
+				}
+				$this->svgclipmode = true;
+				if (!isset($attribs['id'])) {
+					$attribs['id'] = 'CP_'.(count($this->svgcliptm) + 1);
+				}
+				$this->svgclipid = $attribs['id'];
+				$this->svgclippaths[$this->svgclipid] = array();
+				$this->svgcliptm[$this->svgclipid] = $tm;
+				break;
+			}
+			case 'svg': {
+				// start of SVG object
+				break;
+			}
+			case 'g': {
+				// group together related graphics elements
+				array_push($this->svgstyles, $svgstyle);
+				$this->StartTransform();
+				$this->SVGTransform($tm);
+				$this->setSVGStyles($svgstyle, $prev_svgstyle);
+				break;
+			}
+			case 'linearGradient': {
+				if ($this->pdfa_mode) {
+					break;
+				}
+				if (!isset($attribs['id'])) {
+					$attribs['id'] = 'GR_'.(count($this->svggradients) + 1);
+				}
+				$this->svggradientid = $attribs['id'];
+				$this->svggradients[$this->svggradientid] = array();
+				$this->svggradients[$this->svggradientid]['type'] = 2;
+				$this->svggradients[$this->svggradientid]['stops'] = array();
+				if (isset($attribs['gradientUnits'])) {
+					$this->svggradients[$this->svggradientid]['gradientUnits'] = $attribs['gradientUnits'];
+				} else {
+					$this->svggradients[$this->svggradientid]['gradientUnits'] = 'objectBoundingBox';
+				}
+				//$attribs['spreadMethod']
+				if (((!isset($attribs['x1'])) AND (!isset($attribs['y1'])) AND (!isset($attribs['x2'])) AND (!isset($attribs['y2'])))
+					OR ((isset($attribs['x1']) AND (substr($attribs['x1'], -1) == '%'))
+						OR (isset($attribs['y1']) AND (substr($attribs['y1'], -1) == '%'))
+						OR (isset($attribs['x2']) AND (substr($attribs['x2'], -1) == '%'))
+						OR (isset($attribs['y2']) AND (substr($attribs['y2'], -1) == '%')))) {
+					$this->svggradients[$this->svggradientid]['mode'] = 'percentage';
+				} else {
+					$this->svggradients[$this->svggradientid]['mode'] = 'measure';
+				}
+				$x1 = (isset($attribs['x1'])?$attribs['x1']:'0');
+				$y1 = (isset($attribs['y1'])?$attribs['y1']:'0');
+				$x2 = (isset($attribs['x2'])?$attribs['x2']:'100');
+				$y2 = (isset($attribs['y2'])?$attribs['y2']:'0');
+				if (isset($attribs['gradientTransform'])) {
+					$this->svggradients[$this->svggradientid]['gradientTransform'] = $this->getSVGTransformMatrix($attribs['gradientTransform']);
+				}
+				$this->svggradients[$this->svggradientid]['coords'] = array($x1, $y1, $x2, $y2);
+				if (isset($attribs['xlink:href']) AND !empty($attribs['xlink:href'])) {
+					// gradient is defined on another place
+					$this->svggradients[$this->svggradientid]['xref'] = substr($attribs['xlink:href'], 1);
+				}
+				break;
+			}
+			case 'radialGradient': {
+				if ($this->pdfa_mode) {
+					break;
+				}
+				if (!isset($attribs['id'])) {
+					$attribs['id'] = 'GR_'.(count($this->svggradients) + 1);
+				}
+				$this->svggradientid = $attribs['id'];
+				$this->svggradients[$this->svggradientid] = array();
+				$this->svggradients[$this->svggradientid]['type'] = 3;
+				$this->svggradients[$this->svggradientid]['stops'] = array();
+				if (isset($attribs['gradientUnits'])) {
+					$this->svggradients[$this->svggradientid]['gradientUnits'] = $attribs['gradientUnits'];
+				} else {
+					$this->svggradients[$this->svggradientid]['gradientUnits'] = 'objectBoundingBox';
+				}
+				//$attribs['spreadMethod']
+				if (((!isset($attribs['cx'])) AND (!isset($attribs['cy'])))
+					OR ((isset($attribs['cx']) AND (substr($attribs['cx'], -1) == '%'))
+						OR (isset($attribs['cy']) AND (substr($attribs['cy'], -1) == '%')) )) {
+					$this->svggradients[$this->svggradientid]['mode'] = 'percentage';
+				} else {
+					$this->svggradients[$this->svggradientid]['mode'] = 'measure';
+				}
+				$cx = (isset($attribs['cx']) ? $attribs['cx'] : 0.5);
+				$cy = (isset($attribs['cy']) ? $attribs['cy'] : 0.5);
+				$fx = (isset($attribs['fx']) ? $attribs['fx'] : $cx);
+				$fy = (isset($attribs['fy']) ? $attribs['fy'] : $cy);
+				$r = (isset($attribs['r']) ? $attribs['r'] : 0.5);
+				if (isset($attribs['gradientTransform'])) {
+					$this->svggradients[$this->svggradientid]['gradientTransform'] = $this->getSVGTransformMatrix($attribs['gradientTransform']);
+				}
+				$this->svggradients[$this->svggradientid]['coords'] = array($cx, $cy, $fx, $fy, $r);
+				if (isset($attribs['xlink:href']) AND !empty($attribs['xlink:href'])) {
+					// gradient is defined on another place
+					$this->svggradients[$this->svggradientid]['xref'] = substr($attribs['xlink:href'], 1);
+				}
+				break;
+			}
+			case 'stop': {
+				// gradient stops
+				if (substr($attribs['offset'], -1) == '%') {
+					$offset = floatval(substr($attribs['offset'], -1)) / 100;
+				} else {
+					$offset = floatval($attribs['offset']);
+					if ($offset > 1) {
+						$offset /= 100;
+					}
+				}
+				$stop_color = isset($svgstyle['stop-color'])?$this->convertHTMLColorToDec($svgstyle['stop-color']):'black';
+				$opacity = isset($svgstyle['stop-opacity'])?$svgstyle['stop-opacity']:1;
+				$this->svggradients[$this->svggradientid]['stops'][] = array('offset' => $offset, 'color' => $stop_color, 'opacity' => $opacity);
+				break;
+			}
+			// paths
+			case 'path': {
+				if ($invisible) {
+					break;
+				}
+				if (isset($attribs['d'])) {
+					$d = trim($attribs['d']);
+					if (!empty($d)) {
+						if ($clipping) {
+							$this->SVGTransform($tm);
+							$this->SVGPath($d, 'CNZ');
+						} else {
+							$this->StartTransform();
+							$this->SVGTransform($tm);
+							$obstyle = $this->setSVGStyles($svgstyle, $prev_svgstyle, 0, 0, 1, 1, 'SVGPath', array($d, 'CNZ'));
+							if (!empty($obstyle)) {
+								$this->SVGPath($d, $obstyle);
+							}
+							$this->StopTransform();
+						}
+					}
+				}
+				break;
+			}
+			// shapes
+			case 'rect': {
+				if ($invisible) {
+					break;
+				}
+				$x = (isset($attribs['x'])?$this->getHTMLUnitToUnits($attribs['x'], 0, $this->svgunit, false):0);
+				$y = (isset($attribs['y'])?$this->getHTMLUnitToUnits($attribs['y'], 0, $this->svgunit, false):0);
+				$w = (isset($attribs['width'])?$this->getHTMLUnitToUnits($attribs['width'], 0, $this->svgunit, false):0);
+				$h = (isset($attribs['height'])?$this->getHTMLUnitToUnits($attribs['height'], 0, $this->svgunit, false):0);
+				$rx = (isset($attribs['rx'])?$this->getHTMLUnitToUnits($attribs['rx'], 0, $this->svgunit, false):0);
+				$ry = (isset($attribs['ry'])?$this->getHTMLUnitToUnits($attribs['ry'], 0, $this->svgunit, false):$rx);
+				if ($clipping) {
+					$this->SVGTransform($tm);
+					$this->RoundedRectXY($x, $y, $w, $h, $rx, $ry, '1111', 'CNZ', array(), array());
+				} else {
+					$this->StartTransform();
+					$this->SVGTransform($tm);
+					$obstyle = $this->setSVGStyles($svgstyle, $prev_svgstyle, $x, $y, $w, $h, 'RoundedRectXY', array($x, $y, $w, $h, $rx, $ry, '1111', 'CNZ'));
+					if (!empty($obstyle)) {
+						$this->RoundedRectXY($x, $y, $w, $h, $rx, $ry, '1111', $obstyle, array(), array());
+					}
+					$this->StopTransform();
+				}
+				break;
+			}
+			case 'circle': {
+				if ($invisible) {
+					break;
+				}
+				$r = (isset($attribs['r']) ? $this->getHTMLUnitToUnits($attribs['r'], 0, $this->svgunit, false) : 0);
+				$cx = (isset($attribs['cx']) ? $this->getHTMLUnitToUnits($attribs['cx'], 0, $this->svgunit, false) : (isset($attribs['x']) ? $this->getHTMLUnitToUnits($attribs['x'], 0, $this->svgunit, false) : 0));
+				$cy = (isset($attribs['cy']) ? $this->getHTMLUnitToUnits($attribs['cy'], 0, $this->svgunit, false) : (isset($attribs['y']) ? $this->getHTMLUnitToUnits($attribs['y'], 0, $this->svgunit, false) : 0));
+				$x = ($cx - $r);
+				$y = ($cy - $r);
+				$w = (2 * $r);
+				$h = $w;
+				if ($clipping) {
+					$this->SVGTransform($tm);
+					$this->Circle($cx, $cy, $r, 0, 360, 'CNZ', array(), array(), 8);
+				} else {
+					$this->StartTransform();
+					$this->SVGTransform($tm);
+					$obstyle = $this->setSVGStyles($svgstyle, $prev_svgstyle, $x, $y, $w, $h, 'Circle', array($cx, $cy, $r, 0, 360, 'CNZ'));
+					if (!empty($obstyle)) {
+						$this->Circle($cx, $cy, $r, 0, 360, $obstyle, array(), array(), 8);
+					}
+					$this->StopTransform();
+				}
+				break;
+			}
+			case 'ellipse': {
+				if ($invisible) {
+					break;
+				}
+				$rx = (isset($attribs['rx']) ? $this->getHTMLUnitToUnits($attribs['rx'], 0, $this->svgunit, false) : 0);
+				$ry = (isset($attribs['ry']) ? $this->getHTMLUnitToUnits($attribs['ry'], 0, $this->svgunit, false) : 0);
+				$cx = (isset($attribs['cx']) ? $this->getHTMLUnitToUnits($attribs['cx'], 0, $this->svgunit, false) : (isset($attribs['x']) ? $this->getHTMLUnitToUnits($attribs['x'], 0, $this->svgunit, false) : 0));
+				$cy = (isset($attribs['cy']) ? $this->getHTMLUnitToUnits($attribs['cy'], 0, $this->svgunit, false) : (isset($attribs['y']) ? $this->getHTMLUnitToUnits($attribs['y'], 0, $this->svgunit, false) : 0));
+				$x = ($cx - $rx);
+				$y = ($cy - $ry);
+				$w = (2 * $rx);
+				$h = (2 * $ry);
+				if ($clipping) {
+					$this->SVGTransform($tm);
+					$this->Ellipse($cx, $cy, $rx, $ry, 0, 0, 360, 'CNZ', array(), array(), 8);
+				} else {
+					$this->StartTransform();
+					$this->SVGTransform($tm);
+					$obstyle = $this->setSVGStyles($svgstyle, $prev_svgstyle, $x, $y, $w, $h, 'Ellipse', array($cx, $cy, $rx, $ry, 0, 0, 360, 'CNZ'));
+					if (!empty($obstyle)) {
+						$this->Ellipse($cx, $cy, $rx, $ry, 0, 0, 360, $obstyle, array(), array(), 8);
+					}
+					$this->StopTransform();
+				}
+				break;
+			}
+			case 'line': {
+				if ($invisible) {
+					break;
+				}
+				$x1 = (isset($attribs['x1'])?$this->getHTMLUnitToUnits($attribs['x1'], 0, $this->svgunit, false):0);
+				$y1 = (isset($attribs['y1'])?$this->getHTMLUnitToUnits($attribs['y1'], 0, $this->svgunit, false):0);
+				$x2 = (isset($attribs['x2'])?$this->getHTMLUnitToUnits($attribs['x2'], 0, $this->svgunit, false):0);
+				$y2 = (isset($attribs['y2'])?$this->getHTMLUnitToUnits($attribs['y2'], 0, $this->svgunit, false):0);
+				$x = $x1;
+				$y = $y1;
+				$w = abs($x2 - $x1);
+				$h = abs($y2 - $y1);
+				if (!$clipping) {
+					$this->StartTransform();
+					$this->SVGTransform($tm);
+					$obstyle = $this->setSVGStyles($svgstyle, $prev_svgstyle, $x, $y, $w, $h, 'Line', array($x1, $y1, $x2, $y2));
+					$this->Line($x1, $y1, $x2, $y2);
+					$this->StopTransform();
+				}
+				break;
+			}
+			case 'polyline':
+			case 'polygon': {
+				if ($invisible) {
+					break;
+				}
+				$points = (isset($attribs['points'])?$attribs['points']:'0 0');
+				$points = trim($points);
+				// note that point may use a complex syntax not covered here
+				$points = preg_split('/[\,\s]+/si', $points);
+				if (count($points) < 4) {
+					break;
+				}
+				$p = array();
+				$xmin = 2147483647;
+				$xmax = 0;
+				$ymin = 2147483647;
+				$ymax = 0;
+				foreach ($points as $key => $val) {
+					$p[$key] = $this->getHTMLUnitToUnits($val, 0, $this->svgunit, false);
+					if (($key % 2) == 0) {
+						// X coordinate
+						$xmin = min($xmin, $p[$key]);
+						$xmax = max($xmax, $p[$key]);
+					} else {
+						// Y coordinate
+						$ymin = min($ymin, $p[$key]);
+						$ymax = max($ymax, $p[$key]);
+					}
+				}
+				$x = $xmin;
+				$y = $ymin;
+				$w = ($xmax - $xmin);
+				$h = ($ymax - $ymin);
+				if ($name == 'polyline') {
+					$this->StartTransform();
+					$this->SVGTransform($tm);
+					$obstyle = $this->setSVGStyles($svgstyle, $prev_svgstyle, $x, $y, $w, $h, 'PolyLine', array($p, 'CNZ'));
+					if (!empty($obstyle)) {
+						$this->PolyLine($p, $obstyle, array(), array());
+					}
+					$this->StopTransform();
+				} else { // polygon
+					if ($clipping) {
+						$this->SVGTransform($tm);
+						$this->Polygon($p, 'CNZ', array(), array(), true);
+					} else {
+						$this->StartTransform();
+						$this->SVGTransform($tm);
+						$obstyle = $this->setSVGStyles($svgstyle, $prev_svgstyle, $x, $y, $w, $h, 'Polygon', array($p, 'CNZ'));
+						if (!empty($obstyle)) {
+							$this->Polygon($p, $obstyle, array(), array(), true);
+						}
+						$this->StopTransform();
+					}
+				}
+				break;
+			}
+			// image
+			case 'image': {
+				if ($invisible) {
+					break;
+				}
+				if (!isset($attribs['xlink:href']) OR empty($attribs['xlink:href'])) {
+					break;
+				}
+				$x = (isset($attribs['x'])?$this->getHTMLUnitToUnits($attribs['x'], 0, $this->svgunit, false):0);
+				$y = (isset($attribs['y'])?$this->getHTMLUnitToUnits($attribs['y'], 0, $this->svgunit, false):0);
+				$w = (isset($attribs['width'])?$this->getHTMLUnitToUnits($attribs['width'], 0, $this->svgunit, false):0);
+				$h = (isset($attribs['height'])?$this->getHTMLUnitToUnits($attribs['height'], 0, $this->svgunit, false):0);
+				$img = $attribs['xlink:href'];
+				if (!$clipping) {
+					$this->StartTransform();
+					$this->SVGTransform($tm);
+					$obstyle = $this->setSVGStyles($svgstyle, $prev_svgstyle, $x, $y, $w, $h);
+					if (preg_match('/^data:image\/[^;]+;base64,/', $img, $m) > 0) {
+						// embedded image encoded as base64
+						$img = '@'.base64_decode(substr($img, strlen($m[0])));
+					} else {
+						// fix image path
+						if (!$this->empty_string($this->svgdir) AND (($img{0} == '.') OR (basename($img) == $img))) {
+							// replace relative path with full server path
+							$img = $this->svgdir.'/'.$img;
+						}
+						if (($img[0] == '/') AND !empty($_SERVER['DOCUMENT_ROOT']) AND ($_SERVER['DOCUMENT_ROOT'] != '/')) {
+							$findroot = strpos($img, $_SERVER['DOCUMENT_ROOT']);
+							if (($findroot === false) OR ($findroot > 1)) {
+								if (substr($_SERVER['DOCUMENT_ROOT'], -1) == '/') {
+									$img = substr($_SERVER['DOCUMENT_ROOT'], 0, -1).$img;
+								} else {
+									$img = $_SERVER['DOCUMENT_ROOT'].$img;
+								}
+							}
+						}
+						$img = urldecode($img);
+						$testscrtype = @parse_url($img);
+						if (!isset($testscrtype['query']) OR empty($testscrtype['query'])) {
+							// convert URL to server path
+							$img = str_replace(K_PATH_URL, K_PATH_MAIN, $img);
+						}
+					}
+					// get image type
+					$imgtype = $this->getImageFileType($img);
+					if (($imgtype == 'eps') OR ($imgtype == 'ai')) {
+						$this->ImageEps($img, $x, $y, $w, $h);
+					} elseif ($imgtype == 'svg') {
+						$this->ImageSVG($img, $x, $y, $w, $h);
+					} else {
+						$this->Image($img, $x, $y, $w, $h);
+					}
+					$this->StopTransform();
+				}
+				break;
+			}
+			// text
+			case 'text':
+			case 'tspan': {
+				// only basic support - advanced features must be implemented
+				$this->svgtextmode['invisible'] = $invisible;
+				if ($invisible) {
+					break;
+				}
+				array_push($this->svgstyles, $svgstyle);
+				if (isset($attribs['x'])) {
+					$x = $this->getHTMLUnitToUnits($attribs['x'], 0, $this->svgunit, false);
+				} elseif ($name == 'tspan') {
+					$x = $this->x;
+				} else {
+					$x = 0;
+				}
+				if (isset($attribs['y'])) {
+					$y = $this->getHTMLUnitToUnits($attribs['y'], 0, $this->svgunit, false);
+				} elseif ($name == 'tspan') {
+					$y = $this->y;
+				} else {
+					$y = 0;
+				}
+				$svgstyle['text-color'] = $svgstyle['fill'];
+				$this->svgtext = '';
+				if (isset($svgstyle['text-anchor'])) {
+					$this->svgtextmode['text-anchor'] = $svgstyle['text-anchor'];
+				} else {
+					$this->svgtextmode['text-anchor'] = 'start';
+				}
+				if (isset($svgstyle['direction'])) {
+					if ($svgstyle['direction'] == 'rtl') {
+						$this->svgtextmode['rtl'] = true;
+					} else {
+						$this->svgtextmode['rtl'] = false;
+					}
+				} else {
+					$this->svgtextmode['rtl'] = false;
+				}
+				if (isset($svgstyle['stroke']) AND ($svgstyle['stroke'] != 'none') AND isset($svgstyle['stroke-width']) AND ($svgstyle['stroke-width'] > 0)) {
+					$this->svgtextmode['stroke'] = $this->getHTMLUnitToUnits($svgstyle['stroke-width'], 0, $this->svgunit, false);
+				} else {
+					$this->svgtextmode['stroke'] = false;
+				}
+				$this->StartTransform();
+				$this->SVGTransform($tm);
+				$obstyle = $this->setSVGStyles($svgstyle, $prev_svgstyle, $x, $y, 1, 1);
+				$this->x = $x;
+				$this->y = $y;
+				break;
+			}
+			// use
+			case 'use': {
+				if (isset($attribs['xlink:href']) AND !empty($attribs['xlink:href'])) {
+					$svgdefid = substr($attribs['xlink:href'], 1);
+					if (isset($this->svgdefs[$svgdefid])) {
+						$use = $this->svgdefs[$svgdefid];
+						if (isset($attribs['xlink:href'])) {
+							unset($attribs['xlink:href']);
+						}
+						if (isset($attribs['id'])) {
+							unset($attribs['id']);
+						}
+						$attribs = array_merge($attribs, $use['attribs']);
+						$this->startSVGElementHandler($parser, $use['name'], $attribs);
+					}
+				}
+				break;
+			}
+			default: {
+				break;
+			}
+		} // end of switch
+	}
+
+	/**
+	 * Sets the closing SVG element handler function for the XML parser.
+	 * @param $parser (resource) The first parameter, parser, is a reference to the XML parser calling the handler.
+	 * @param $name (string) The second parameter, name, contains the name of the element for which this handler is called. If case-folding is in effect for this parser, the element name will be in uppercase letters.
+	 * @author Nicola Asuni
+	 * @since 5.0.000 (2010-05-02)
+	 * @protected
+	 */
+	protected function endSVGElementHandler($parser, $name) {
+		switch($name) {
+			case 'defs': {
+				$this->svgdefsmode = false;
+				break;
+			}
+			// clipPath
+			case 'clipPath': {
+				$this->svgclipmode = false;
+				break;
+			}
+			case 'g': {
+				// ungroup: remove last style from array
+				array_pop($this->svgstyles);
+				$this->StopTransform();
+				break;
+			}
+			case 'text':
+			case 'tspan': {
+				if ($this->svgtextmode['invisible']) {
+					// This implementation must be fixed to following the rule:
+					// If the 'visibility' property is set to hidden on a 'tspan', 'tref' or 'altGlyph' element, then the text is invisible but still takes up space in text layout calculations.
+					break;
+				}
+				// print text
+				$text = $this->svgtext;
+				//$text = $this->stringTrim($text);
+				$textlen = $this->GetStringWidth($text);
+				if ($this->svgtextmode['text-anchor'] != 'start') {
+					// check if string is RTL text
+					if ($this->svgtextmode['text-anchor'] == 'end') {
+						if ($this->svgtextmode['rtl']) {
+							$this->x += $textlen;
+						} else {
+							$this->x -= $textlen;
+						}
+					} elseif ($this->svgtextmode['text-anchor'] == 'middle') {
+						if ($this->svgtextmode['rtl']) {
+							$this->x += ($textlen / 2);
+						} else {
+							$this->x -= ($textlen / 2);
+						}
+					}
+				}
+				$textrendermode = $this->textrendermode;
+				$textstrokewidth = $this->textstrokewidth;
+				$this->setTextRenderingMode($this->svgtextmode['stroke'], true, false);
+				if ($name == 'text') {
+					// store current coordinates
+					$tmpx = $this->x;
+					$tmpy = $this->y;
+				}
+				$this->Cell($textlen, 0, $text, 0, 0, '', false, '', 0, false, 'L', 'T');
+				if ($name == 'text') {
+					// restore coordinates
+					$this->x = $tmpx;
+					$this->y = $tmpy;
+				}
+				// restore previous rendering mode
+				$this->textrendermode = $textrendermode;
+				$this->textstrokewidth = $textstrokewidth;
+				$this->svgtext = '';
+				$this->StopTransform();
+				array_pop($this->svgstyles);
+				break;
+			}
+			default: {
+				break;
+			}
+		}
+	}
+
+	/**
+	 * Sets the character data handler function for the XML parser.
+	 * @param $parser (resource) The first parameter, parser, is a reference to the XML parser calling the handler.
+	 * @param $data (string) The second parameter, data, contains the character data as a string.
+	 * @author Nicola Asuni
+	 * @since 5.0.000 (2010-05-02)
+	 * @protected
+	 */
+	protected function segSVGContentHandler($parser, $data) {
+		$this->svgtext .= $data;
+	}
+
+	// --- END SVG METHODS -----------------------------------------------------
+
+} // END OF TCPDF CLASS
+
+//============================================================+
+// END OF FILE
+//============================================================+
diff --git a/phpmyadmin/libraries/tcpdf/unicode_data.php b/phpmyadmin/libraries/tcpdf/unicode_data.php
new file mode 100644
index 0000000..936f4fe
--- /dev/null
+++ b/phpmyadmin/libraries/tcpdf/unicode_data.php
@@ -0,0 +1,18371 @@
+<?php
+//============================================================+
+// File name   : unicode_data.php
+// Version     : 1.0.009
+// Begin       : 2008-01-01
+// Last Update : 2011-10-01
+// Author      : Nicola Asuni - Tecnick.com LTD - Manor Coach House, Church Hill, Aldershot, Hants, GU12 4RQ, UK - www.tecnick.com - info at tecnick.com
+// License     : GNU-LGPL v3 (http://www.gnu.org/copyleft/lesser.html)
+// -------------------------------------------------------------------
+// Copyright (C) 2008-2012  Nicola Asuni - Tecnick.com LTD
+//
+// This file is part of TCPDF software library.
+//
+// TCPDF is free software: you can redistribute it and/or modify it
+// under the terms of the GNU Lesser General Public License as
+// published by the Free Software Foundation, either version 3 of the
+// License, or (at your option) any later version.
+//
+// TCPDF is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+// See the GNU Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with TCPDF.  If not, see <http://www.gnu.org/licenses/>.
+//
+// See LICENSE.TXT file for more information.
+// -------------------------------------------------------------------
+//
+// Description : Unicode data for TCPDF library.
+//
+//============================================================+
+// THANKS TO
+// Efthimios Mavrogeorgiadis
+// Saleh AlMatrafe
+
+/**
+ * @file
+ * Unicode data class for TCPDF library.
+ * @author Nicola Asuni
+ * @package com.tecnick.tcpdf
+ * @since 2.1.000 (2008-01-08)
+ */
+
+/**
+ * @class TCPDF_UNICODE_DATA
+ * This is a PHP class containing UnicOde data for TCPDF library.
+ * @package com.tecnick.tcpdf
+ * @version 1.0.009
+ * @author Nicola Asuni - info at tecnick.com
+ */
+class TCPDF_UNICODE_DATA {
+
+/**
+ * Unicode code for Left-to-Right Mark.
+ * @public
+ */
+public $uni_LRM = 8206;
+
+/**
+ * Unicode code for Right-to-Left Mark.
+ * @public
+ */
+public $uni_RLM = 8207;
+
+/**
+ * Unicode code for Left-to-Right Embedding.
+ * @public
+ */
+public $uni_LRE = 8234;
+
+/**
+ * Unicode code for Right-to-Left Embedding.
+ * @public
+ */
+public $uni_RLE = 8235;
+
+/**
+ * Unicode code for Pop Directional Format.
+ * @public
+ */
+public $uni_PDF = 8236;
+
+/**
+ * Unicode code for Left-to-Right Override.
+ * @public
+ */
+public $uni_LRO = 8237;
+
+/**
+ * Unicode code for Right-to-Left Override.
+ * @public
+ */
+public $uni_RLO = 8238;
+
+/**
+ * Pattern to test RTL (Righ-To-Left) strings using regular expressions.
+ * @public
+ */
+public $uni_RE_PATTERN_RTL = "/(
+	  \xD6\xBE                                             # R
+	| \xD7[\x80\x83\x86\x90-\xAA\xB0-\xB4]                 # R
+	| \xDF[\x80-\xAA\xB4\xB5\xBA]                          # R
+	| \xE2\x80\x8F                                         # R
+	| \xEF\xAC[\x9D\x9F\xA0-\xA8\xAA-\xB6\xB8-\xBC\xBE]    # R
+	| \xEF\xAD[\x80\x81\x83\x84\x86-\x8F]                  # R
+	| \xF0\x90\xA0[\x80-\x85\x88\x8A-\xB5\xB7\xB8\xBC\xBF] # R
+	| \xF0\x90\xA4[\x80-\x99]                              # R
+	| \xF0\x90\xA8[\x80\x90-\x93\x95-\x97\x99-\xB3]        # R
+	| \xF0\x90\xA9[\x80-\x87\x90-\x98]                     # R
+	| \xE2\x80[\xAB\xAE]                                   # RLE & RLO
+	)/x";
+
+/**
+ * Pattern to test Arabic strings using regular expressions. Source: http://www.w3.org/International/questions/qa-forms-utf-8
+ * @public
+ */
+public $uni_RE_PATTERN_ARABIC = "/(
+		  \xD8[\x80-\x83\x8B\x8D\x9B\x9E\x9F\xA1-\xBA]  # AL
+		| \xD9[\x80-\x8A\xAD-\xAF\xB1-\xBF]             # AL
+		| \xDA[\x80-\xBF]                               # AL
+		| \xDB[\x80-\x95\x9D\xA5\xA6\xAE\xAF\xBA-\xBF]  # AL
+		| \xDC[\x80-\x8D\x90\x92-\xAF]                  # AL
+		| \xDD[\x8D-\xAD]                               # AL
+		| \xDE[\x80-\xA5\xB1]                           # AL
+		| \xEF\xAD[\x90-\xBF]                           # AL
+		| \xEF\xAE[\x80-\xB1]                           # AL
+		| \xEF\xAF[\x93-\xBF]                           # AL
+		| \xEF[\xB0-\xB3][\x80-\xBF]                    # AL
+		| \xEF\xB4[\x80-\xBD]                           # AL
+		| \xEF\xB5[\x90-\xBF]                           # AL
+		| \xEF\xB6[\x80-\x8F\x92-\xBF]                  # AL
+		| \xEF\xB7[\x80-\x87\xB0-\xBC]                  # AL
+		| \xEF\xB9[\xB0-\xB4\xB6-\xBF]                  # AL
+		| \xEF\xBA[\x80-\xBF]                           # AL
+		| \xEF\xBB[\x80-\xBC]                           # AL
+		| \xD9[\xA0-\xA9\xAB\xAC]                       # AN
+		)/x";
+
+/**
+ * Array of Unicode types.
+ * @public
+ */
+public $uni_type = array(
+0=>'BN',
+1=>'BN',
+2=>'BN',
+3=>'BN',
+4=>'BN',
+5=>'BN',
+6=>'BN',
+7=>'BN',
+8=>'BN',
+9=>'S',
+10=>'B',
+11=>'S',
+12=>'WS',
+13=>'B',
+14=>'BN',
+15=>'BN',
+16=>'BN',
+17=>'BN',
+18=>'BN',
+19=>'BN',
+20=>'BN',
+21=>'BN',
+22=>'BN',
+23=>'BN',
+24=>'BN',
+25=>'BN',
+26=>'BN',
+27=>'BN',
+28=>'B',
+29=>'B',
+30=>'B',
+31=>'S',
+32=>'WS',
+33=>'ON',
+34=>'ON',
+35=>'ET',
+36=>'ET',
+37=>'ET',
+38=>'ON',
+39=>'ON',
+40=>'ON',
+41=>'ON',
+42=>'ON',
+43=>'ES',
+44=>'CS',
+45=>'ES',
+46=>'CS',
+47=>'CS',
+48=>'EN',
+49=>'EN',
+50=>'EN',
+51=>'EN',
+52=>'EN',
+53=>'EN',
+54=>'EN',
+55=>'EN',
+56=>'EN',
+57=>'EN',
+58=>'CS',
+59=>'ON',
+60=>'ON',
+61=>'ON',
+62=>'ON',
+63=>'ON',
+64=>'ON',
+65=>'L',
+66=>'L',
+67=>'L',
+68=>'L',
+69=>'L',
+70=>'L',
+71=>'L',
+72=>'L',
+73=>'L',
+74=>'L',
+75=>'L',
+76=>'L',
+77=>'L',
+78=>'L',
+79=>'L',
+80=>'L',
+81=>'L',
+82=>'L',
+83=>'L',
+84=>'L',
+85=>'L',
+86=>'L',
+87=>'L',
+88=>'L',
+89=>'L',
+90=>'L',
+91=>'ON',
+92=>'ON',
+93=>'ON',
+94=>'ON',
+95=>'ON',
+96=>'ON',
+97=>'L',
+98=>'L',
+99=>'L',
+100=>'L',
+101=>'L',
+102=>'L',
+103=>'L',
+104=>'L',
+105=>'L',
+106=>'L',
+107=>'L',
+108=>'L',
+109=>'L',
+110=>'L',
+111=>'L',
+112=>'L',
+113=>'L',
+114=>'L',
+115=>'L',
+116=>'L',
+117=>'L',
+118=>'L',
+119=>'L',
+120=>'L',
+121=>'L',
+122=>'L',
+123=>'ON',
+124=>'ON',
+125=>'ON',
+126=>'ON',
+127=>'BN',
+128=>'BN',
+129=>'BN',
+130=>'BN',
+131=>'BN',
+132=>'BN',
+133=>'B',
+134=>'BN',
+135=>'BN',
+136=>'BN',
+137=>'BN',
+138=>'BN',
+139=>'BN',
+140=>'BN',
+141=>'BN',
+142=>'BN',
+143=>'BN',
+144=>'BN',
+145=>'BN',
+146=>'BN',
+147=>'BN',
+148=>'BN',
+149=>'BN',
+150=>'BN',
+151=>'BN',
+152=>'BN',
+153=>'BN',
+154=>'BN',
+155=>'BN',
+156=>'BN',
+157=>'BN',
+158=>'BN',
+159=>'BN',
+160=>'CS',
+161=>'ON',
+162=>'ET',
+163=>'ET',
+164=>'ET',
+165=>'ET',
+166=>'ON',
+167=>'ON',
+168=>'ON',
+169=>'ON',
+170=>'L',
+171=>'ON',
+172=>'ON',
+173=>'BN',
+174=>'ON',
+175=>'ON',
+176=>'ET',
+177=>'ET',
+178=>'EN',
+179=>'EN',
+180=>'ON',
+181=>'L',
+182=>'ON',
+183=>'ON',
+184=>'ON',
+185=>'EN',
+186=>'L',
+187=>'ON',
+188=>'ON',
+189=>'ON',
+190=>'ON',
+191=>'ON',
+192=>'L',
+193=>'L',
+194=>'L',
+195=>'L',
+196=>'L',
+197=>'L',
+198=>'L',
+199=>'L',
+200=>'L',
+201=>'L',
+202=>'L',
+203=>'L',
+204=>'L',
+205=>'L',
+206=>'L',
+207=>'L',
+208=>'L',
+209=>'L',
+210=>'L',
+211=>'L',
+212=>'L',
+213=>'L',
+214=>'L',
+215=>'ON',
+216=>'L',
+217=>'L',
+218=>'L',
+219=>'L',
+220=>'L',
+221=>'L',
+222=>'L',
+223=>'L',
+224=>'L',
+225=>'L',
+226=>'L',
+227=>'L',
+228=>'L',
+229=>'L',
+230=>'L',
+231=>'L',
+232=>'L',
+233=>'L',
+234=>'L',
+235=>'L',
+236=>'L',
+237=>'L',
+238=>'L',
+239=>'L',
+240=>'L',
+241=>'L',
+242=>'L',
+243=>'L',
+244=>'L',
+245=>'L',
+246=>'L',
+247=>'ON',
+248=>'L',
+249=>'L',
+250=>'L',
+251=>'L',
+252=>'L',
+253=>'L',
+254=>'L',
+255=>'L',
+256=>'L',
+257=>'L',
+258=>'L',
+259=>'L',
+260=>'L',
+261=>'L',
+262=>'L',
+263=>'L',
+264=>'L',
+265=>'L',
+266=>'L',
+267=>'L',
+268=>'L',
+269=>'L',
+270=>'L',
+271=>'L',
+272=>'L',
+273=>'L',
+274=>'L',
+275=>'L',
+276=>'L',
+277=>'L',
+278=>'L',
+279=>'L',
+280=>'L',
+281=>'L',
+282=>'L',
+283=>'L',
+284=>'L',
+285=>'L',
+286=>'L',
+287=>'L',
+288=>'L',
+289=>'L',
+290=>'L',
+291=>'L',
+292=>'L',
+293=>'L',
+294=>'L',
+295=>'L',
+296=>'L',
+297=>'L',
+298=>'L',
+299=>'L',
+300=>'L',
+301=>'L',
+302=>'L',
+303=>'L',
+304=>'L',
+305=>'L',
+306=>'L',
+307=>'L',
+308=>'L',
+309=>'L',
+310=>'L',
+311=>'L',
+312=>'L',
+313=>'L',
+314=>'L',
+315=>'L',
+316=>'L',
+317=>'L',
+318=>'L',
+319=>'L',
+320=>'L',
+321=>'L',
+322=>'L',
+323=>'L',
+324=>'L',
+325=>'L',
+326=>'L',
+327=>'L',
+328=>'L',
+329=>'L',
+330=>'L',
+331=>'L',
+332=>'L',
+333=>'L',
+334=>'L',
+335=>'L',
+336=>'L',
+337=>'L',
+338=>'L',
+339=>'L',
+340=>'L',
+341=>'L',
+342=>'L',
+343=>'L',
+344=>'L',
+345=>'L',
+346=>'L',
+347=>'L',
+348=>'L',
+349=>'L',
+350=>'L',
+351=>'L',
+352=>'L',
+353=>'L',
+354=>'L',
+355=>'L',
+356=>'L',
+357=>'L',
+358=>'L',
+359=>'L',
+360=>'L',
+361=>'L',
+362=>'L',
+363=>'L',
+364=>'L',
+365=>'L',
+366=>'L',
+367=>'L',
+368=>'L',
+369=>'L',
+370=>'L',
+371=>'L',
+372=>'L',
+373=>'L',
+374=>'L',
+375=>'L',
+376=>'L',
+377=>'L',
+378=>'L',
+379=>'L',
+380=>'L',
+381=>'L',
+382=>'L',
+383=>'L',
+384=>'L',
+385=>'L',
+386=>'L',
+387=>'L',
+388=>'L',
+389=>'L',
+390=>'L',
+391=>'L',
+392=>'L',
+393=>'L',
+394=>'L',
+395=>'L',
+396=>'L',
+397=>'L',
+398=>'L',
+399=>'L',
+400=>'L',
+401=>'L',
+402=>'L',
+403=>'L',
+404=>'L',
+405=>'L',
+406=>'L',
+407=>'L',
+408=>'L',
+409=>'L',
+410=>'L',
+411=>'L',
+412=>'L',
+413=>'L',
+414=>'L',
+415=>'L',
+416=>'L',
+417=>'L',
+418=>'L',
+419=>'L',
+420=>'L',
+421=>'L',
+422=>'L',
+423=>'L',
+424=>'L',
+425=>'L',
+426=>'L',
+427=>'L',
+428=>'L',
+429=>'L',
+430=>'L',
+431=>'L',
+432=>'L',
+433=>'L',
+434=>'L',
+435=>'L',
+436=>'L',
+437=>'L',
+438=>'L',
+439=>'L',
+440=>'L',
+441=>'L',
+442=>'L',
+443=>'L',
+444=>'L',
+445=>'L',
+446=>'L',
+447=>'L',
+448=>'L',
+449=>'L',
+450=>'L',
+451=>'L',
+452=>'L',
+453=>'L',
+454=>'L',
+455=>'L',
+456=>'L',
+457=>'L',
+458=>'L',
+459=>'L',
+460=>'L',
+461=>'L',
+462=>'L',
+463=>'L',
+464=>'L',
+465=>'L',
+466=>'L',
+467=>'L',
+468=>'L',
+469=>'L',
+470=>'L',
+471=>'L',
+472=>'L',
+473=>'L',
+474=>'L',
+475=>'L',
+476=>'L',
+477=>'L',
+478=>'L',
+479=>'L',
+480=>'L',
+481=>'L',
+482=>'L',
+483=>'L',
+484=>'L',
+485=>'L',
+486=>'L',
+487=>'L',
+488=>'L',
+489=>'L',
+490=>'L',
+491=>'L',
+492=>'L',
+493=>'L',
+494=>'L',
+495=>'L',
+496=>'L',
+497=>'L',
+498=>'L',
+499=>'L',
+500=>'L',
+501=>'L',
+502=>'L',
+503=>'L',
+504=>'L',
+505=>'L',
+506=>'L',
+507=>'L',
+508=>'L',
+509=>'L',
+510=>'L',
+511=>'L',
+512=>'L',
+513=>'L',
+514=>'L',
+515=>'L',
+516=>'L',
+517=>'L',
+518=>'L',
+519=>'L',
+520=>'L',
+521=>'L',
+522=>'L',
+523=>'L',
+524=>'L',
+525=>'L',
+526=>'L',
+527=>'L',
+528=>'L',
+529=>'L',
+530=>'L',
+531=>'L',
+532=>'L',
+533=>'L',
+534=>'L',
+535=>'L',
+536=>'L',
+537=>'L',
+538=>'L',
+539=>'L',
+540=>'L',
+541=>'L',
+542=>'L',
+543=>'L',
+544=>'L',
+545=>'L',
+546=>'L',
+547=>'L',
+548=>'L',
+549=>'L',
+550=>'L',
+551=>'L',
+552=>'L',
+553=>'L',
+554=>'L',
+555=>'L',
+556=>'L',
+557=>'L',
+558=>'L',
+559=>'L',
+560=>'L',
+561=>'L',
+562=>'L',
+563=>'L',
+564=>'L',
+565=>'L',
+566=>'L',
+567=>'L',
+568=>'L',
+569=>'L',
+570=>'L',
+571=>'L',
+572=>'L',
+573=>'L',
+574=>'L',
+575=>'L',
+576=>'L',
+577=>'L',
+578=>'L',
+579=>'L',
+580=>'L',
+581=>'L',
+582=>'L',
+583=>'L',
+584=>'L',
+585=>'L',
+586=>'L',
+587=>'L',
+588=>'L',
+589=>'L',
+590=>'L',
+591=>'L',
+592=>'L',
+593=>'L',
+594=>'L',
+595=>'L',
+596=>'L',
+597=>'L',
+598=>'L',
+599=>'L',
+600=>'L',
+601=>'L',
+602=>'L',
+603=>'L',
+604=>'L',
+605=>'L',
+606=>'L',
+607=>'L',
+608=>'L',
+609=>'L',
+610=>'L',
+611=>'L',
+612=>'L',
+613=>'L',
+614=>'L',
+615=>'L',
+616=>'L',
+617=>'L',
+618=>'L',
+619=>'L',
+620=>'L',
+621=>'L',
+622=>'L',
+623=>'L',
+624=>'L',
+625=>'L',
+626=>'L',
+627=>'L',
+628=>'L',
+629=>'L',
+630=>'L',
+631=>'L',
+632=>'L',
+633=>'L',
+634=>'L',
+635=>'L',
+636=>'L',
+637=>'L',
+638=>'L',
+639=>'L',
+640=>'L',
+641=>'L',
+642=>'L',
+643=>'L',
+644=>'L',
+645=>'L',
+646=>'L',
+647=>'L',
+648=>'L',
+649=>'L',
+650=>'L',
+651=>'L',
+652=>'L',
+653=>'L',
+654=>'L',
+655=>'L',
+656=>'L',
+657=>'L',
+658=>'L',
+659=>'L',
+660=>'L',
+661=>'L',
+662=>'L',
+663=>'L',
+664=>'L',
+665=>'L',
+666=>'L',
+667=>'L',
+668=>'L',
+669=>'L',
+670=>'L',
+671=>'L',
+672=>'L',
+673=>'L',
+674=>'L',
+675=>'L',
+676=>'L',
+677=>'L',
+678=>'L',
+679=>'L',
+680=>'L',
+681=>'L',
+682=>'L',
+683=>'L',
+684=>'L',
+685=>'L',
+686=>'L',
+687=>'L',
+688=>'L',
+689=>'L',
+690=>'L',
+691=>'L',
+692=>'L',
+693=>'L',
+694=>'L',
+695=>'L',
+696=>'L',
+697=>'ON',
+698=>'ON',
+699=>'L',
+700=>'L',
+701=>'L',
+702=>'L',
+703=>'L',
+704=>'L',
+705=>'L',
+706=>'ON',
+707=>'ON',
+708=>'ON',
+709=>'ON',
+710=>'ON',
+711=>'ON',
+712=>'ON',
+713=>'ON',
+714=>'ON',
+715=>'ON',
+716=>'ON',
+717=>'ON',
+718=>'ON',
+719=>'ON',
+720=>'L',
+721=>'L',
+722=>'ON',
+723=>'ON',
+724=>'ON',
+725=>'ON',
+726=>'ON',
+727=>'ON',
+728=>'ON',
+729=>'ON',
+730=>'ON',
+731=>'ON',
+732=>'ON',
+733=>'ON',
+734=>'ON',
+735=>'ON',
+736=>'L',
+737=>'L',
+738=>'L',
+739=>'L',
+740=>'L',
+741=>'ON',
+742=>'ON',
+743=>'ON',
+744=>'ON',
+745=>'ON',
+746=>'ON',
+747=>'ON',
+748=>'ON',
+749=>'ON',
+750=>'L',
+751=>'ON',
+752=>'ON',
+753=>'ON',
+754=>'ON',
+755=>'ON',
+756=>'ON',
+757=>'ON',
+758=>'ON',
+759=>'ON',
+760=>'ON',
+761=>'ON',
+762=>'ON',
+763=>'ON',
+764=>'ON',
+765=>'ON',
+766=>'ON',
+767=>'ON',
+768=>'NSM',
+769=>'NSM',
+770=>'NSM',
+771=>'NSM',
+772=>'NSM',
+773=>'NSM',
+774=>'NSM',
+775=>'NSM',
+776=>'NSM',
+777=>'NSM',
+778=>'NSM',
+779=>'NSM',
+780=>'NSM',
+781=>'NSM',
+782=>'NSM',
+783=>'NSM',
+784=>'NSM',
+785=>'NSM',
+786=>'NSM',
+787=>'NSM',
+788=>'NSM',
+789=>'NSM',
+790=>'NSM',
+791=>'NSM',
+792=>'NSM',
+793=>'NSM',
+794=>'NSM',
+795=>'NSM',
+796=>'NSM',
+797=>'NSM',
+798=>'NSM',
+799=>'NSM',
+800=>'NSM',
+801=>'NSM',
+802=>'NSM',
+803=>'NSM',
+804=>'NSM',
+805=>'NSM',
+806=>'NSM',
+807=>'NSM',
+808=>'NSM',
+809=>'NSM',
+810=>'NSM',
+811=>'NSM',
+812=>'NSM',
+813=>'NSM',
+814=>'NSM',
+815=>'NSM',
+816=>'NSM',
+817=>'NSM',
+818=>'NSM',
+819=>'NSM',
+820=>'NSM',
+821=>'NSM',
+822=>'NSM',
+823=>'NSM',
+824=>'NSM',
+825=>'NSM',
+826=>'NSM',
+827=>'NSM',
+828=>'NSM',
+829=>'NSM',
+830=>'NSM',
+831=>'NSM',
+832=>'NSM',
+833=>'NSM',
+834=>'NSM',
+835=>'NSM',
+836=>'NSM',
+837=>'NSM',
+838=>'NSM',
+839=>'NSM',
+840=>'NSM',
+841=>'NSM',
+842=>'NSM',
+843=>'NSM',
+844=>'NSM',
+845=>'NSM',
+846=>'NSM',
+847=>'NSM',
+848=>'NSM',
+849=>'NSM',
+850=>'NSM',
+851=>'NSM',
+852=>'NSM',
+853=>'NSM',
+854=>'NSM',
+855=>'NSM',
+856=>'NSM',
+857=>'NSM',
+858=>'NSM',
+859=>'NSM',
+860=>'NSM',
+861=>'NSM',
+862=>'NSM',
+863=>'NSM',
+864=>'NSM',
+865=>'NSM',
+866=>'NSM',
+867=>'NSM',
+868=>'NSM',
+869=>'NSM',
+870=>'NSM',
+871=>'NSM',
+872=>'NSM',
+873=>'NSM',
+874=>'NSM',
+875=>'NSM',
+876=>'NSM',
+877=>'NSM',
+878=>'NSM',
+879=>'NSM',
+884=>'ON',
+885=>'ON',
+890=>'L',
+891=>'L',
+892=>'L',
+893=>'L',
+894=>'ON',
+900=>'ON',
+901=>'ON',
+902=>'L',
+903=>'ON',
+904=>'L',
+905=>'L',
+906=>'L',
+908=>'L',
+910=>'L',
+911=>'L',
+912=>'L',
+913=>'L',
+914=>'L',
+915=>'L',
+916=>'L',
+917=>'L',
+918=>'L',
+919=>'L',
+920=>'L',
+921=>'L',
+922=>'L',
+923=>'L',
+924=>'L',
+925=>'L',
+926=>'L',
+927=>'L',
+928=>'L',
+929=>'L',
+931=>'L',
+932=>'L',
+933=>'L',
+934=>'L',
+935=>'L',
+936=>'L',
+937=>'L',
+938=>'L',
+939=>'L',
+940=>'L',
+941=>'L',
+942=>'L',
+943=>'L',
+944=>'L',
+945=>'L',
+946=>'L',
+947=>'L',
+948=>'L',
+949=>'L',
+950=>'L',
+951=>'L',
+952=>'L',
+953=>'L',
+954=>'L',
+955=>'L',
+956=>'L',
+957=>'L',
+958=>'L',
+959=>'L',
+960=>'L',
+961=>'L',
+962=>'L',
+963=>'L',
+964=>'L',
+965=>'L',
+966=>'L',
+967=>'L',
+968=>'L',
+969=>'L',
+970=>'L',
+971=>'L',
+972=>'L',
+973=>'L',
+974=>'L',
+976=>'L',
+977=>'L',
+978=>'L',
+979=>'L',
+980=>'L',
+981=>'L',
+982=>'L',
+983=>'L',
+984=>'L',
+985=>'L',
+986=>'L',
+987=>'L',
+988=>'L',
+989=>'L',
+990=>'L',
+991=>'L',
+992=>'L',
+993=>'L',
+994=>'L',
+995=>'L',
+996=>'L',
+997=>'L',
+998=>'L',
+999=>'L',
+1000=>'L',
+1001=>'L',
+1002=>'L',
+1003=>'L',
+1004=>'L',
+1005=>'L',
+1006=>'L',
+1007=>'L',
+1008=>'L',
+1009=>'L',
+1010=>'L',
+1011=>'L',
+1012=>'L',
+1013=>'L',
+1014=>'ON',
+1015=>'L',
+1016=>'L',
+1017=>'L',
+1018=>'L',
+1019=>'L',
+1020=>'L',
+1021=>'L',
+1022=>'L',
+1023=>'L',
+1024=>'L',
+1025=>'L',
+1026=>'L',
+1027=>'L',
+1028=>'L',
+1029=>'L',
+1030=>'L',
+1031=>'L',
+1032=>'L',
+1033=>'L',
+1034=>'L',
+1035=>'L',
+1036=>'L',
+1037=>'L',
+1038=>'L',
+1039=>'L',
+1040=>'L',
+1041=>'L',
+1042=>'L',
+1043=>'L',
+1044=>'L',
+1045=>'L',
+1046=>'L',
+1047=>'L',
+1048=>'L',
+1049=>'L',
+1050=>'L',
+1051=>'L',
+1052=>'L',
+1053=>'L',
+1054=>'L',
+1055=>'L',
+1056=>'L',
+1057=>'L',
+1058=>'L',
+1059=>'L',
+1060=>'L',
+1061=>'L',
+1062=>'L',
+1063=>'L',
+1064=>'L',
+1065=>'L',
+1066=>'L',
+1067=>'L',
+1068=>'L',
+1069=>'L',
+1070=>'L',
+1071=>'L',
+1072=>'L',
+1073=>'L',
+1074=>'L',
+1075=>'L',
+1076=>'L',
+1077=>'L',
+1078=>'L',
+1079=>'L',
+1080=>'L',
+1081=>'L',
+1082=>'L',
+1083=>'L',
+1084=>'L',
+1085=>'L',
+1086=>'L',
+1087=>'L',
+1088=>'L',
+1089=>'L',
+1090=>'L',
+1091=>'L',
+1092=>'L',
+1093=>'L',
+1094=>'L',
+1095=>'L',
+1096=>'L',
+1097=>'L',
+1098=>'L',
+1099=>'L',
+1100=>'L',
+1101=>'L',
+1102=>'L',
+1103=>'L',
+1104=>'L',
+1105=>'L',
+1106=>'L',
+1107=>'L',
+1108=>'L',
+1109=>'L',
+1110=>'L',
+1111=>'L',
+1112=>'L',
+1113=>'L',
+1114=>'L',
+1115=>'L',
+1116=>'L',
+1117=>'L',
+1118=>'L',
+1119=>'L',
+1120=>'L',
+1121=>'L',
+1122=>'L',
+1123=>'L',
+1124=>'L',
+1125=>'L',
+1126=>'L',
+1127=>'L',
+1128=>'L',
+1129=>'L',
+1130=>'L',
+1131=>'L',
+1132=>'L',
+1133=>'L',
+1134=>'L',
+1135=>'L',
+1136=>'L',
+1137=>'L',
+1138=>'L',
+1139=>'L',
+1140=>'L',
+1141=>'L',
+1142=>'L',
+1143=>'L',
+1144=>'L',
+1145=>'L',
+1146=>'L',
+1147=>'L',
+1148=>'L',
+1149=>'L',
+1150=>'L',
+1151=>'L',
+1152=>'L',
+1153=>'L',
+1154=>'L',
+1155=>'NSM',
+1156=>'NSM',
+1157=>'NSM',
+1158=>'NSM',
+1160=>'NSM',
+1161=>'NSM',
+1162=>'L',
+1163=>'L',
+1164=>'L',
+1165=>'L',
+1166=>'L',
+1167=>'L',
+1168=>'L',
+1169=>'L',
+1170=>'L',
+1171=>'L',
+1172=>'L',
+1173=>'L',
+1174=>'L',
+1175=>'L',
+1176=>'L',
+1177=>'L',
+1178=>'L',
+1179=>'L',
+1180=>'L',
+1181=>'L',
+1182=>'L',
+1183=>'L',
+1184=>'L',
+1185=>'L',
+1186=>'L',
+1187=>'L',
+1188=>'L',
+1189=>'L',
+1190=>'L',
+1191=>'L',
+1192=>'L',
+1193=>'L',
+1194=>'L',
+1195=>'L',
+1196=>'L',
+1197=>'L',
+1198=>'L',
+1199=>'L',
+1200=>'L',
+1201=>'L',
+1202=>'L',
+1203=>'L',
+1204=>'L',
+1205=>'L',
+1206=>'L',
+1207=>'L',
+1208=>'L',
+1209=>'L',
+1210=>'L',
+1211=>'L',
+1212=>'L',
+1213=>'L',
+1214=>'L',
+1215=>'L',
+1216=>'L',
+1217=>'L',
+1218=>'L',
+1219=>'L',
+1220=>'L',
+1221=>'L',
+1222=>'L',
+1223=>'L',
+1224=>'L',
+1225=>'L',
+1226=>'L',
+1227=>'L',
+1228=>'L',
+1229=>'L',
+1230=>'L',
+1231=>'L',
+1232=>'L',
+1233=>'L',
+1234=>'L',
+1235=>'L',
+1236=>'L',
+1237=>'L',
+1238=>'L',
+1239=>'L',
+1240=>'L',
+1241=>'L',
+1242=>'L',
+1243=>'L',
+1244=>'L',
+1245=>'L',
+1246=>'L',
+1247=>'L',
+1248=>'L',
+1249=>'L',
+1250=>'L',
+1251=>'L',
+1252=>'L',
+1253=>'L',
+1254=>'L',
+1255=>'L',
+1256=>'L',
+1257=>'L',
+1258=>'L',
+1259=>'L',
+1260=>'L',
+1261=>'L',
+1262=>'L',
+1263=>'L',
+1264=>'L',
+1265=>'L',
+1266=>'L',
+1267=>'L',
+1268=>'L',
+1269=>'L',
+1270=>'L',
+1271=>'L',
+1272=>'L',
+1273=>'L',
+1274=>'L',
+1275=>'L',
+1276=>'L',
+1277=>'L',
+1278=>'L',
+1279=>'L',
+1280=>'L',
+1281=>'L',
+1282=>'L',
+1283=>'L',
+1284=>'L',
+1285=>'L',
+1286=>'L',
+1287=>'L',
+1288=>'L',
+1289=>'L',
+1290=>'L',
+1291=>'L',
+1292=>'L',
+1293=>'L',
+1294=>'L',
+1295=>'L',
+1296=>'L',
+1297=>'L',
+1298=>'L',
+1299=>'L',
+1329=>'L',
+1330=>'L',
+1331=>'L',
+1332=>'L',
+1333=>'L',
+1334=>'L',
+1335=>'L',
+1336=>'L',
+1337=>'L',
+1338=>'L',
+1339=>'L',
+1340=>'L',
+1341=>'L',
+1342=>'L',
+1343=>'L',
+1344=>'L',
+1345=>'L',
+1346=>'L',
+1347=>'L',
+1348=>'L',
+1349=>'L',
+1350=>'L',
+1351=>'L',
+1352=>'L',
+1353=>'L',
+1354=>'L',
+1355=>'L',
+1356=>'L',
+1357=>'L',
+1358=>'L',
+1359=>'L',
+1360=>'L',
+1361=>'L',
+1362=>'L',
+1363=>'L',
+1364=>'L',
+1365=>'L',
+1366=>'L',
+1369=>'L',
+1370=>'L',
+1371=>'L',
+1372=>'L',
+1373=>'L',
+1374=>'L',
+1375=>'L',
+1377=>'L',
+1378=>'L',
+1379=>'L',
+1380=>'L',
+1381=>'L',
+1382=>'L',
+1383=>'L',
+1384=>'L',
+1385=>'L',
+1386=>'L',
+1387=>'L',
+1388=>'L',
+1389=>'L',
+1390=>'L',
+1391=>'L',
+1392=>'L',
+1393=>'L',
+1394=>'L',
+1395=>'L',
+1396=>'L',
+1397=>'L',
+1398=>'L',
+1399=>'L',
+1400=>'L',
+1401=>'L',
+1402=>'L',
+1403=>'L',
+1404=>'L',
+1405=>'L',
+1406=>'L',
+1407=>'L',
+1408=>'L',
+1409=>'L',
+1410=>'L',
+1411=>'L',
+1412=>'L',
+1413=>'L',
+1414=>'L',
+1415=>'L',
+1417=>'L',
+1418=>'ON',
+1425=>'NSM',
+1426=>'NSM',
+1427=>'NSM',
+1428=>'NSM',
+1429=>'NSM',
+1430=>'NSM',
+1431=>'NSM',
+1432=>'NSM',
+1433=>'NSM',
+1434=>'NSM',
+1435=>'NSM',
+1436=>'NSM',
+1437=>'NSM',
+1438=>'NSM',
+1439=>'NSM',
+1440=>'NSM',
+1441=>'NSM',
+1442=>'NSM',
+1443=>'NSM',
+1444=>'NSM',
+1445=>'NSM',
+1446=>'NSM',
+1447=>'NSM',
+1448=>'NSM',
+1449=>'NSM',
+1450=>'NSM',
+1451=>'NSM',
+1452=>'NSM',
+1453=>'NSM',
+1454=>'NSM',
+1455=>'NSM',
+1456=>'NSM',
+1457=>'NSM',
+1458=>'NSM',
+1459=>'NSM',
+1460=>'NSM',
+1461=>'NSM',
+1462=>'NSM',
+1463=>'NSM',
+1464=>'NSM',
+1465=>'NSM',
+1466=>'NSM',
+1467=>'NSM',
+1468=>'NSM',
+1469=>'NSM',
+1470=>'R',
+1471=>'NSM',
+1472=>'R',
+1473=>'NSM',
+1474=>'NSM',
+1475=>'R',
+1476=>'NSM',
+1477=>'NSM',
+1478=>'R',
+1479=>'NSM',
+1488=>'R',
+1489=>'R',
+1490=>'R',
+1491=>'R',
+1492=>'R',
+1493=>'R',
+1494=>'R',
+1495=>'R',
+1496=>'R',
+1497=>'R',
+1498=>'R',
+1499=>'R',
+1500=>'R',
+1501=>'R',
+1502=>'R',
+1503=>'R',
+1504=>'R',
+1505=>'R',
+1506=>'R',
+1507=>'R',
+1508=>'R',
+1509=>'R',
+1510=>'R',
+1511=>'R',
+1512=>'R',
+1513=>'R',
+1514=>'R',
+1520=>'R',
+1521=>'R',
+1522=>'R',
+1523=>'R',
+1524=>'R',
+1536=>'AL',
+1537=>'AL',
+1538=>'AL',
+1539=>'AL',
+1547=>'AL',
+1548=>'CS',
+1549=>'AL',
+1550=>'ON',
+1551=>'ON',
+1552=>'NSM',
+1553=>'NSM',
+1554=>'NSM',
+1555=>'NSM',
+1556=>'NSM',
+1557=>'NSM',
+1563=>'AL',
+1566=>'AL',
+1567=>'AL',
+1569=>'AL',
+1570=>'AL',
+1571=>'AL',
+1572=>'AL',
+1573=>'AL',
+1574=>'AL',
+1575=>'AL',
+1576=>'AL',
+1577=>'AL',
+1578=>'AL',
+1579=>'AL',
+1580=>'AL',
+1581=>'AL',
+1582=>'AL',
+1583=>'AL',
+1584=>'AL',
+1585=>'AL',
+1586=>'AL',
+1587=>'AL',
+1588=>'AL',
+1589=>'AL',
+1590=>'AL',
+1591=>'AL',
+1592=>'AL',
+1593=>'AL',
+1594=>'AL',
+1600=>'AL',
+1601=>'AL',
+1602=>'AL',
+1603=>'AL',
+1604=>'AL',
+1605=>'AL',
+1606=>'AL',
+1607=>'AL',
+1608=>'AL',
+1609=>'AL',
+1610=>'AL',
+1611=>'NSM',
+1612=>'NSM',
+1613=>'NSM',
+1614=>'NSM',
+1615=>'NSM',
+1616=>'NSM',
+1617=>'NSM',
+1618=>'NSM',
+1619=>'NSM',
+1620=>'NSM',
+1621=>'NSM',
+1622=>'NSM',
+1623=>'NSM',
+1624=>'NSM',
+1625=>'NSM',
+1626=>'NSM',
+1627=>'NSM',
+1628=>'NSM',
+1629=>'NSM',
+1630=>'NSM',
+1632=>'AN',
+1633=>'AN',
+1634=>'AN',
+1635=>'AN',
+1636=>'AN',
+1637=>'AN',
+1638=>'AN',
+1639=>'AN',
+1640=>'AN',
+1641=>'AN',
+1642=>'ET',
+1643=>'AN',
+1644=>'AN',
+1645=>'AL',
+1646=>'AL',
+1647=>'AL',
+1648=>'NSM',
+1649=>'AL',
+1650=>'AL',
+1651=>'AL',
+1652=>'AL',
+1653=>'AL',
+1654=>'AL',
+1655=>'AL',
+1656=>'AL',
+1657=>'AL',
+1658=>'AL',
+1659=>'AL',
+1660=>'AL',
+1661=>'AL',
+1662=>'AL',
+1663=>'AL',
+1664=>'AL',
+1665=>'AL',
+1666=>'AL',
+1667=>'AL',
+1668=>'AL',
+1669=>'AL',
+1670=>'AL',
+1671=>'AL',
+1672=>'AL',
+1673=>'AL',
+1674=>'AL',
+1675=>'AL',
+1676=>'AL',
+1677=>'AL',
+1678=>'AL',
+1679=>'AL',
+1680=>'AL',
+1681=>'AL',
+1682=>'AL',
+1683=>'AL',
+1684=>'AL',
+1685=>'AL',
+1686=>'AL',
+1687=>'AL',
+1688=>'AL',
+1689=>'AL',
+1690=>'AL',
+1691=>'AL',
+1692=>'AL',
+1693=>'AL',
+1694=>'AL',
+1695=>'AL',
+1696=>'AL',
+1697=>'AL',
+1698=>'AL',
+1699=>'AL',
+1700=>'AL',
+1701=>'AL',
+1702=>'AL',
+1703=>'AL',
+1704=>'AL',
+1705=>'AL',
+1706=>'AL',
+1707=>'AL',
+1708=>'AL',
+1709=>'AL',
+1710=>'AL',
+1711=>'AL',
+1712=>'AL',
+1713=>'AL',
+1714=>'AL',
+1715=>'AL',
+1716=>'AL',
+1717=>'AL',
+1718=>'AL',
+1719=>'AL',
+1720=>'AL',
+1721=>'AL',
+1722=>'AL',
+1723=>'AL',
+1724=>'AL',
+1725=>'AL',
+1726=>'AL',
+1727=>'AL',
+1728=>'AL',
+1729=>'AL',
+1730=>'AL',
+1731=>'AL',
+1732=>'AL',
+1733=>'AL',
+1734=>'AL',
+1735=>'AL',
+1736=>'AL',
+1737=>'AL',
+1738=>'AL',
+1739=>'AL',
+1740=>'AL',
+1741=>'AL',
+1742=>'AL',
+1743=>'AL',
+1744=>'AL',
+1745=>'AL',
+1746=>'AL',
+1747=>'AL',
+1748=>'AL',
+1749=>'AL',
+1750=>'NSM',
+1751=>'NSM',
+1752=>'NSM',
+1753=>'NSM',
+1754=>'NSM',
+1755=>'NSM',
+1756=>'NSM',
+1757=>'AL',
+1758=>'NSM',
+1759=>'NSM',
+1760=>'NSM',
+1761=>'NSM',
+1762=>'NSM',
+1763=>'NSM',
+1764=>'NSM',
+1765=>'AL',
+1766=>'AL',
+1767=>'NSM',
+1768=>'NSM',
+1769=>'ON',
+1770=>'NSM',
+1771=>'NSM',
+1772=>'NSM',
+1773=>'NSM',
+1774=>'AL',
+1775=>'AL',
+1776=>'EN',
+1777=>'EN',
+1778=>'EN',
+1779=>'EN',
+1780=>'EN',
+1781=>'EN',
+1782=>'EN',
+1783=>'EN',
+1784=>'EN',
+1785=>'EN',
+1786=>'AL',
+1787=>'AL',
+1788=>'AL',
+1789=>'AL',
+1790=>'AL',
+1791=>'AL',
+1792=>'AL',
+1793=>'AL',
+1794=>'AL',
+1795=>'AL',
+1796=>'AL',
+1797=>'AL',
+1798=>'AL',
+1799=>'AL',
+1800=>'AL',
+1801=>'AL',
+1802=>'AL',
+1803=>'AL',
+1804=>'AL',
+1805=>'AL',
+1807=>'BN',
+1808=>'AL',
+1809=>'NSM',
+1810=>'AL',
+1811=>'AL',
+1812=>'AL',
+1813=>'AL',
+1814=>'AL',
+1815=>'AL',
+1816=>'AL',
+1817=>'AL',
+1818=>'AL',
+1819=>'AL',
+1820=>'AL',
+1821=>'AL',
+1822=>'AL',
+1823=>'AL',
+1824=>'AL',
+1825=>'AL',
+1826=>'AL',
+1827=>'AL',
+1828=>'AL',
+1829=>'AL',
+1830=>'AL',
+1831=>'AL',
+1832=>'AL',
+1833=>'AL',
+1834=>'AL',
+1835=>'AL',
+1836=>'AL',
+1837=>'AL',
+1838=>'AL',
+1839=>'AL',
+1840=>'NSM',
+1841=>'NSM',
+1842=>'NSM',
+1843=>'NSM',
+1844=>'NSM',
+1845=>'NSM',
+1846=>'NSM',
+1847=>'NSM',
+1848=>'NSM',
+1849=>'NSM',
+1850=>'NSM',
+1851=>'NSM',
+1852=>'NSM',
+1853=>'NSM',
+1854=>'NSM',
+1855=>'NSM',
+1856=>'NSM',
+1857=>'NSM',
+1858=>'NSM',
+1859=>'NSM',
+1860=>'NSM',
+1861=>'NSM',
+1862=>'NSM',
+1863=>'NSM',
+1864=>'NSM',
+1865=>'NSM',
+1866=>'NSM',
+1869=>'AL',
+1870=>'AL',
+1871=>'AL',
+1872=>'AL',
+1873=>'AL',
+1874=>'AL',
+1875=>'AL',
+1876=>'AL',
+1877=>'AL',
+1878=>'AL',
+1879=>'AL',
+1880=>'AL',
+1881=>'AL',
+1882=>'AL',
+1883=>'AL',
+1884=>'AL',
+1885=>'AL',
+1886=>'AL',
+1887=>'AL',
+1888=>'AL',
+1889=>'AL',
+1890=>'AL',
+1891=>'AL',
+1892=>'AL',
+1893=>'AL',
+1894=>'AL',
+1895=>'AL',
+1896=>'AL',
+1897=>'AL',
+1898=>'AL',
+1899=>'AL',
+1900=>'AL',
+1901=>'AL',
+1920=>'AL',
+1921=>'AL',
+1922=>'AL',
+1923=>'AL',
+1924=>'AL',
+1925=>'AL',
+1926=>'AL',
+1927=>'AL',
+1928=>'AL',
+1929=>'AL',
+1930=>'AL',
+1931=>'AL',
+1932=>'AL',
+1933=>'AL',
+1934=>'AL',
+1935=>'AL',
+1936=>'AL',
+1937=>'AL',
+1938=>'AL',
+1939=>'AL',
+1940=>'AL',
+1941=>'AL',
+1942=>'AL',
+1943=>'AL',
+1944=>'AL',
+1945=>'AL',
+1946=>'AL',
+1947=>'AL',
+1948=>'AL',
+1949=>'AL',
+1950=>'AL',
+1951=>'AL',
+1952=>'AL',
+1953=>'AL',
+1954=>'AL',
+1955=>'AL',
+1956=>'AL',
+1957=>'AL',
+1958=>'NSM',
+1959=>'NSM',
+1960=>'NSM',
+1961=>'NSM',
+1962=>'NSM',
+1963=>'NSM',
+1964=>'NSM',
+1965=>'NSM',
+1966=>'NSM',
+1967=>'NSM',
+1968=>'NSM',
+1969=>'AL',
+1984=>'R',
+1985=>'R',
+1986=>'R',
+1987=>'R',
+1988=>'R',
+1989=>'R',
+1990=>'R',
+1991=>'R',
+1992=>'R',
+1993=>'R',
+1994=>'R',
+1995=>'R',
+1996=>'R',
+1997=>'R',
+1998=>'R',
+1999=>'R',
+2000=>'R',
+2001=>'R',
+2002=>'R',
+2003=>'R',
+2004=>'R',
+2005=>'R',
+2006=>'R',
+2007=>'R',
+2008=>'R',
+2009=>'R',
+2010=>'R',
+2011=>'R',
+2012=>'R',
+2013=>'R',
+2014=>'R',
+2015=>'R',
+2016=>'R',
+2017=>'R',
+2018=>'R',
+2019=>'R',
+2020=>'R',
+2021=>'R',
+2022=>'R',
+2023=>'R',
+2024=>'R',
+2025=>'R',
+2026=>'R',
+2027=>'NSM',
+2028=>'NSM',
+2029=>'NSM',
+2030=>'NSM',
+2031=>'NSM',
+2032=>'NSM',
+2033=>'NSM',
+2034=>'NSM',
+2035=>'NSM',
+2036=>'R',
+2037=>'R',
+2038=>'ON',
+2039=>'ON',
+2040=>'ON',
+2041=>'ON',
+2042=>'R',
+2305=>'NSM',
+2306=>'NSM',
+2307=>'L',
+2308=>'L',
+2309=>'L',
+2310=>'L',
+2311=>'L',
+2312=>'L',
+2313=>'L',
+2314=>'L',
+2315=>'L',
+2316=>'L',
+2317=>'L',
+2318=>'L',
+2319=>'L',
+2320=>'L',
+2321=>'L',
+2322=>'L',
+2323=>'L',
+2324=>'L',
+2325=>'L',
+2326=>'L',
+2327=>'L',
+2328=>'L',
+2329=>'L',
+2330=>'L',
+2331=>'L',
+2332=>'L',
+2333=>'L',
+2334=>'L',
+2335=>'L',
+2336=>'L',
+2337=>'L',
+2338=>'L',
+2339=>'L',
+2340=>'L',
+2341=>'L',
+2342=>'L',
+2343=>'L',
+2344=>'L',
+2345=>'L',
+2346=>'L',
+2347=>'L',
+2348=>'L',
+2349=>'L',
+2350=>'L',
+2351=>'L',
+2352=>'L',
+2353=>'L',
+2354=>'L',
+2355=>'L',
+2356=>'L',
+2357=>'L',
+2358=>'L',
+2359=>'L',
+2360=>'L',
+2361=>'L',
+2364=>'NSM',
+2365=>'L',
+2366=>'L',
+2367=>'L',
+2368=>'L',
+2369=>'NSM',
+2370=>'NSM',
+2371=>'NSM',
+2372=>'NSM',
+2373=>'NSM',
+2374=>'NSM',
+2375=>'NSM',
+2376=>'NSM',
+2377=>'L',
+2378=>'L',
+2379=>'L',
+2380=>'L',
+2381=>'NSM',
+2384=>'L',
+2385=>'NSM',
+2386=>'NSM',
+2387=>'NSM',
+2388=>'NSM',
+2392=>'L',
+2393=>'L',
+2394=>'L',
+2395=>'L',
+2396=>'L',
+2397=>'L',
+2398=>'L',
+2399=>'L',
+2400=>'L',
+2401=>'L',
+2402=>'NSM',
+2403=>'NSM',
+2404=>'L',
+2405=>'L',
+2406=>'L',
+2407=>'L',
+2408=>'L',
+2409=>'L',
+2410=>'L',
+2411=>'L',
+2412=>'L',
+2413=>'L',
+2414=>'L',
+2415=>'L',
+2416=>'L',
+2427=>'L',
+2428=>'L',
+2429=>'L',
+2430=>'L',
+2431=>'L',
+2433=>'NSM',
+2434=>'L',
+2435=>'L',
+2437=>'L',
+2438=>'L',
+2439=>'L',
+2440=>'L',
+2441=>'L',
+2442=>'L',
+2443=>'L',
+2444=>'L',
+2447=>'L',
+2448=>'L',
+2451=>'L',
+2452=>'L',
+2453=>'L',
+2454=>'L',
+2455=>'L',
+2456=>'L',
+2457=>'L',
+2458=>'L',
+2459=>'L',
+2460=>'L',
+2461=>'L',
+2462=>'L',
+2463=>'L',
+2464=>'L',
+2465=>'L',
+2466=>'L',
+2467=>'L',
+2468=>'L',
+2469=>'L',
+2470=>'L',
+2471=>'L',
+2472=>'L',
+2474=>'L',
+2475=>'L',
+2476=>'L',
+2477=>'L',
+2478=>'L',
+2479=>'L',
+2480=>'L',
+2482=>'L',
+2486=>'L',
+2487=>'L',
+2488=>'L',
+2489=>'L',
+2492=>'NSM',
+2493=>'L',
+2494=>'L',
+2495=>'L',
+2496=>'L',
+2497=>'NSM',
+2498=>'NSM',
+2499=>'NSM',
+2500=>'NSM',
+2503=>'L',
+2504=>'L',
+2507=>'L',
+2508=>'L',
+2509=>'NSM',
+2510=>'L',
+2519=>'L',
+2524=>'L',
+2525=>'L',
+2527=>'L',
+2528=>'L',
+2529=>'L',
+2530=>'NSM',
+2531=>'NSM',
+2534=>'L',
+2535=>'L',
+2536=>'L',
+2537=>'L',
+2538=>'L',
+2539=>'L',
+2540=>'L',
+2541=>'L',
+2542=>'L',
+2543=>'L',
+2544=>'L',
+2545=>'L',
+2546=>'ET',
+2547=>'ET',
+2548=>'L',
+2549=>'L',
+2550=>'L',
+2551=>'L',
+2552=>'L',
+2553=>'L',
+2554=>'L',
+2561=>'NSM',
+2562=>'NSM',
+2563=>'L',
+2565=>'L',
+2566=>'L',
+2567=>'L',
+2568=>'L',
+2569=>'L',
+2570=>'L',
+2575=>'L',
+2576=>'L',
+2579=>'L',
+2580=>'L',
+2581=>'L',
+2582=>'L',
+2583=>'L',
+2584=>'L',
+2585=>'L',
+2586=>'L',
+2587=>'L',
+2588=>'L',
+2589=>'L',
+2590=>'L',
+2591=>'L',
+2592=>'L',
+2593=>'L',
+2594=>'L',
+2595=>'L',
+2596=>'L',
+2597=>'L',
+2598=>'L',
+2599=>'L',
+2600=>'L',
+2602=>'L',
+2603=>'L',
+2604=>'L',
+2605=>'L',
+2606=>'L',
+2607=>'L',
+2608=>'L',
+2610=>'L',
+2611=>'L',
+2613=>'L',
+2614=>'L',
+2616=>'L',
+2617=>'L',
+2620=>'NSM',
+2622=>'L',
+2623=>'L',
+2624=>'L',
+2625=>'NSM',
+2626=>'NSM',
+2631=>'NSM',
+2632=>'NSM',
+2635=>'NSM',
+2636=>'NSM',
+2637=>'NSM',
+2649=>'L',
+2650=>'L',
+2651=>'L',
+2652=>'L',
+2654=>'L',
+2662=>'L',
+2663=>'L',
+2664=>'L',
+2665=>'L',
+2666=>'L',
+2667=>'L',
+2668=>'L',
+2669=>'L',
+2670=>'L',
+2671=>'L',
+2672=>'NSM',
+2673=>'NSM',
+2674=>'L',
+2675=>'L',
+2676=>'L',
+2689=>'NSM',
+2690=>'NSM',
+2691=>'L',
+2693=>'L',
+2694=>'L',
+2695=>'L',
+2696=>'L',
+2697=>'L',
+2698=>'L',
+2699=>'L',
+2700=>'L',
+2701=>'L',
+2703=>'L',
+2704=>'L',
+2705=>'L',
+2707=>'L',
+2708=>'L',
+2709=>'L',
+2710=>'L',
+2711=>'L',
+2712=>'L',
+2713=>'L',
+2714=>'L',
+2715=>'L',
+2716=>'L',
+2717=>'L',
+2718=>'L',
+2719=>'L',
+2720=>'L',
+2721=>'L',
+2722=>'L',
+2723=>'L',
+2724=>'L',
+2725=>'L',
+2726=>'L',
+2727=>'L',
+2728=>'L',
+2730=>'L',
+2731=>'L',
+2732=>'L',
+2733=>'L',
+2734=>'L',
+2735=>'L',
+2736=>'L',
+2738=>'L',
+2739=>'L',
+2741=>'L',
+2742=>'L',
+2743=>'L',
+2744=>'L',
+2745=>'L',
+2748=>'NSM',
+2749=>'L',
+2750=>'L',
+2751=>'L',
+2752=>'L',
+2753=>'NSM',
+2754=>'NSM',
+2755=>'NSM',
+2756=>'NSM',
+2757=>'NSM',
+2759=>'NSM',
+2760=>'NSM',
+2761=>'L',
+2763=>'L',
+2764=>'L',
+2765=>'NSM',
+2768=>'L',
+2784=>'L',
+2785=>'L',
+2786=>'NSM',
+2787=>'NSM',
+2790=>'L',
+2791=>'L',
+2792=>'L',
+2793=>'L',
+2794=>'L',
+2795=>'L',
+2796=>'L',
+2797=>'L',
+2798=>'L',
+2799=>'L',
+2801=>'ET',
+2817=>'NSM',
+2818=>'L',
+2819=>'L',
+2821=>'L',
+2822=>'L',
+2823=>'L',
+2824=>'L',
+2825=>'L',
+2826=>'L',
+2827=>'L',
+2828=>'L',
+2831=>'L',
+2832=>'L',
+2835=>'L',
+2836=>'L',
+2837=>'L',
+2838=>'L',
+2839=>'L',
+2840=>'L',
+2841=>'L',
+2842=>'L',
+2843=>'L',
+2844=>'L',
+2845=>'L',
+2846=>'L',
+2847=>'L',
+2848=>'L',
+2849=>'L',
+2850=>'L',
+2851=>'L',
+2852=>'L',
+2853=>'L',
+2854=>'L',
+2855=>'L',
+2856=>'L',
+2858=>'L',
+2859=>'L',
+2860=>'L',
+2861=>'L',
+2862=>'L',
+2863=>'L',
+2864=>'L',
+2866=>'L',
+2867=>'L',
+2869=>'L',
+2870=>'L',
+2871=>'L',
+2872=>'L',
+2873=>'L',
+2876=>'NSM',
+2877=>'L',
+2878=>'L',
+2879=>'NSM',
+2880=>'L',
+2881=>'NSM',
+2882=>'NSM',
+2883=>'NSM',
+2887=>'L',
+2888=>'L',
+2891=>'L',
+2892=>'L',
+2893=>'NSM',
+2902=>'NSM',
+2903=>'L',
+2908=>'L',
+2909=>'L',
+2911=>'L',
+2912=>'L',
+2913=>'L',
+2918=>'L',
+2919=>'L',
+2920=>'L',
+2921=>'L',
+2922=>'L',
+2923=>'L',
+2924=>'L',
+2925=>'L',
+2926=>'L',
+2927=>'L',
+2928=>'L',
+2929=>'L',
+2946=>'NSM',
+2947=>'L',
+2949=>'L',
+2950=>'L',
+2951=>'L',
+2952=>'L',
+2953=>'L',
+2954=>'L',
+2958=>'L',
+2959=>'L',
+2960=>'L',
+2962=>'L',
+2963=>'L',
+2964=>'L',
+2965=>'L',
+2969=>'L',
+2970=>'L',
+2972=>'L',
+2974=>'L',
+2975=>'L',
+2979=>'L',
+2980=>'L',
+2984=>'L',
+2985=>'L',
+2986=>'L',
+2990=>'L',
+2991=>'L',
+2992=>'L',
+2993=>'L',
+2994=>'L',
+2995=>'L',
+2996=>'L',
+2997=>'L',
+2998=>'L',
+2999=>'L',
+3000=>'L',
+3001=>'L',
+3006=>'L',
+3007=>'L',
+3008=>'NSM',
+3009=>'L',
+3010=>'L',
+3014=>'L',
+3015=>'L',
+3016=>'L',
+3018=>'L',
+3019=>'L',
+3020=>'L',
+3021=>'NSM',
+3031=>'L',
+3046=>'L',
+3047=>'L',
+3048=>'L',
+3049=>'L',
+3050=>'L',
+3051=>'L',
+3052=>'L',
+3053=>'L',
+3054=>'L',
+3055=>'L',
+3056=>'L',
+3057=>'L',
+3058=>'L',
+3059=>'ON',
+3060=>'ON',
+3061=>'ON',
+3062=>'ON',
+3063=>'ON',
+3064=>'ON',
+3065=>'ET',
+3066=>'ON',
+3073=>'L',
+3074=>'L',
+3075=>'L',
+3077=>'L',
+3078=>'L',
+3079=>'L',
+3080=>'L',
+3081=>'L',
+3082=>'L',
+3083=>'L',
+3084=>'L',
+3086=>'L',
+3087=>'L',
+3088=>'L',
+3090=>'L',
+3091=>'L',
+3092=>'L',
+3093=>'L',
+3094=>'L',
+3095=>'L',
+3096=>'L',
+3097=>'L',
+3098=>'L',
+3099=>'L',
+3100=>'L',
+3101=>'L',
+3102=>'L',
+3103=>'L',
+3104=>'L',
+3105=>'L',
+3106=>'L',
+3107=>'L',
+3108=>'L',
+3109=>'L',
+3110=>'L',
+3111=>'L',
+3112=>'L',
+3114=>'L',
+3115=>'L',
+3116=>'L',
+3117=>'L',
+3118=>'L',
+3119=>'L',
+3120=>'L',
+3121=>'L',
+3122=>'L',
+3123=>'L',
+3125=>'L',
+3126=>'L',
+3127=>'L',
+3128=>'L',
+3129=>'L',
+3134=>'NSM',
+3135=>'NSM',
+3136=>'NSM',
+3137=>'L',
+3138=>'L',
+3139=>'L',
+3140=>'L',
+3142=>'NSM',
+3143=>'NSM',
+3144=>'NSM',
+3146=>'NSM',
+3147=>'NSM',
+3148=>'NSM',
+3149=>'NSM',
+3157=>'NSM',
+3158=>'NSM',
+3168=>'L',
+3169=>'L',
+3174=>'L',
+3175=>'L',
+3176=>'L',
+3177=>'L',
+3178=>'L',
+3179=>'L',
+3180=>'L',
+3181=>'L',
+3182=>'L',
+3183=>'L',
+3202=>'L',
+3203=>'L',
+3205=>'L',
+3206=>'L',
+3207=>'L',
+3208=>'L',
+3209=>'L',
+3210=>'L',
+3211=>'L',
+3212=>'L',
+3214=>'L',
+3215=>'L',
+3216=>'L',
+3218=>'L',
+3219=>'L',
+3220=>'L',
+3221=>'L',
+3222=>'L',
+3223=>'L',
+3224=>'L',
+3225=>'L',
+3226=>'L',
+3227=>'L',
+3228=>'L',
+3229=>'L',
+3230=>'L',
+3231=>'L',
+3232=>'L',
+3233=>'L',
+3234=>'L',
+3235=>'L',
+3236=>'L',
+3237=>'L',
+3238=>'L',
+3239=>'L',
+3240=>'L',
+3242=>'L',
+3243=>'L',
+3244=>'L',
+3245=>'L',
+3246=>'L',
+3247=>'L',
+3248=>'L',
+3249=>'L',
+3250=>'L',
+3251=>'L',
+3253=>'L',
+3254=>'L',
+3255=>'L',
+3256=>'L',
+3257=>'L',
+3260=>'NSM',
+3261=>'L',
+3262=>'L',
+3263=>'L',
+3264=>'L',
+3265=>'L',
+3266=>'L',
+3267=>'L',
+3268=>'L',
+3270=>'L',
+3271=>'L',
+3272=>'L',
+3274=>'L',
+3275=>'L',
+3276=>'NSM',
+3277=>'NSM',
+3285=>'L',
+3286=>'L',
+3294=>'L',
+3296=>'L',
+3297=>'L',
+3298=>'NSM',
+3299=>'NSM',
+3302=>'L',
+3303=>'L',
+3304=>'L',
+3305=>'L',
+3306=>'L',
+3307=>'L',
+3308=>'L',
+3309=>'L',
+3310=>'L',
+3311=>'L',
+3313=>'ON',
+3314=>'ON',
+3330=>'L',
+3331=>'L',
+3333=>'L',
+3334=>'L',
+3335=>'L',
+3336=>'L',
+3337=>'L',
+3338=>'L',
+3339=>'L',
+3340=>'L',
+3342=>'L',
+3343=>'L',
+3344=>'L',
+3346=>'L',
+3347=>'L',
+3348=>'L',
+3349=>'L',
+3350=>'L',
+3351=>'L',
+3352=>'L',
+3353=>'L',
+3354=>'L',
+3355=>'L',
+3356=>'L',
+3357=>'L',
+3358=>'L',
+3359=>'L',
+3360=>'L',
+3361=>'L',
+3362=>'L',
+3363=>'L',
+3364=>'L',
+3365=>'L',
+3366=>'L',
+3367=>'L',
+3368=>'L',
+3370=>'L',
+3371=>'L',
+3372=>'L',
+3373=>'L',
+3374=>'L',
+3375=>'L',
+3376=>'L',
+3377=>'L',
+3378=>'L',
+3379=>'L',
+3380=>'L',
+3381=>'L',
+3382=>'L',
+3383=>'L',
+3384=>'L',
+3385=>'L',
+3390=>'L',
+3391=>'L',
+3392=>'L',
+3393=>'NSM',
+3394=>'NSM',
+3395=>'NSM',
+3398=>'L',
+3399=>'L',
+3400=>'L',
+3402=>'L',
+3403=>'L',
+3404=>'L',
+3405=>'NSM',
+3415=>'L',
+3424=>'L',
+3425=>'L',
+3430=>'L',
+3431=>'L',
+3432=>'L',
+3433=>'L',
+3434=>'L',
+3435=>'L',
+3436=>'L',
+3437=>'L',
+3438=>'L',
+3439=>'L',
+3458=>'L',
+3459=>'L',
+3461=>'L',
+3462=>'L',
+3463=>'L',
+3464=>'L',
+3465=>'L',
+3466=>'L',
+3467=>'L',
+3468=>'L',
+3469=>'L',
+3470=>'L',
+3471=>'L',
+3472=>'L',
+3473=>'L',
+3474=>'L',
+3475=>'L',
+3476=>'L',
+3477=>'L',
+3478=>'L',
+3482=>'L',
+3483=>'L',
+3484=>'L',
+3485=>'L',
+3486=>'L',
+3487=>'L',
+3488=>'L',
+3489=>'L',
+3490=>'L',
+3491=>'L',
+3492=>'L',
+3493=>'L',
+3494=>'L',
+3495=>'L',
+3496=>'L',
+3497=>'L',
+3498=>'L',
+3499=>'L',
+3500=>'L',
+3501=>'L',
+3502=>'L',
+3503=>'L',
+3504=>'L',
+3505=>'L',
+3507=>'L',
+3508=>'L',
+3509=>'L',
+3510=>'L',
+3511=>'L',
+3512=>'L',
+3513=>'L',
+3514=>'L',
+3515=>'L',
+3517=>'L',
+3520=>'L',
+3521=>'L',
+3522=>'L',
+3523=>'L',
+3524=>'L',
+3525=>'L',
+3526=>'L',
+3530=>'NSM',
+3535=>'L',
+3536=>'L',
+3537=>'L',
+3538=>'NSM',
+3539=>'NSM',
+3540=>'NSM',
+3542=>'NSM',
+3544=>'L',
+3545=>'L',
+3546=>'L',
+3547=>'L',
+3548=>'L',
+3549=>'L',
+3550=>'L',
+3551=>'L',
+3570=>'L',
+3571=>'L',
+3572=>'L',
+3585=>'L',
+3586=>'L',
+3587=>'L',
+3588=>'L',
+3589=>'L',
+3590=>'L',
+3591=>'L',
+3592=>'L',
+3593=>'L',
+3594=>'L',
+3595=>'L',
+3596=>'L',
+3597=>'L',
+3598=>'L',
+3599=>'L',
+3600=>'L',
+3601=>'L',
+3602=>'L',
+3603=>'L',
+3604=>'L',
+3605=>'L',
+3606=>'L',
+3607=>'L',
+3608=>'L',
+3609=>'L',
+3610=>'L',
+3611=>'L',
+3612=>'L',
+3613=>'L',
+3614=>'L',
+3615=>'L',
+3616=>'L',
+3617=>'L',
+3618=>'L',
+3619=>'L',
+3620=>'L',
+3621=>'L',
+3622=>'L',
+3623=>'L',
+3624=>'L',
+3625=>'L',
+3626=>'L',
+3627=>'L',
+3628=>'L',
+3629=>'L',
+3630=>'L',
+3631=>'L',
+3632=>'L',
+3633=>'NSM',
+3634=>'L',
+3635=>'L',
+3636=>'NSM',
+3637=>'NSM',
+3638=>'NSM',
+3639=>'NSM',
+3640=>'NSM',
+3641=>'NSM',
+3642=>'NSM',
+3647=>'ET',
+3648=>'L',
+3649=>'L',
+3650=>'L',
+3651=>'L',
+3652=>'L',
+3653=>'L',
+3654=>'L',
+3655=>'NSM',
+3656=>'NSM',
+3657=>'NSM',
+3658=>'NSM',
+3659=>'NSM',
+3660=>'NSM',
+3661=>'NSM',
+3662=>'NSM',
+3663=>'L',
+3664=>'L',
+3665=>'L',
+3666=>'L',
+3667=>'L',
+3668=>'L',
+3669=>'L',
+3670=>'L',
+3671=>'L',
+3672=>'L',
+3673=>'L',
+3674=>'L',
+3675=>'L',
+3713=>'L',
+3714=>'L',
+3716=>'L',
+3719=>'L',
+3720=>'L',
+3722=>'L',
+3725=>'L',
+3732=>'L',
+3733=>'L',
+3734=>'L',
+3735=>'L',
+3737=>'L',
+3738=>'L',
+3739=>'L',
+3740=>'L',
+3741=>'L',
+3742=>'L',
+3743=>'L',
+3745=>'L',
+3746=>'L',
+3747=>'L',
+3749=>'L',
+3751=>'L',
+3754=>'L',
+3755=>'L',
+3757=>'L',
+3758=>'L',
+3759=>'L',
+3760=>'L',
+3761=>'NSM',
+3762=>'L',
+3763=>'L',
+3764=>'NSM',
+3765=>'NSM',
+3766=>'NSM',
+3767=>'NSM',
+3768=>'NSM',
+3769=>'NSM',
+3771=>'NSM',
+3772=>'NSM',
+3773=>'L',
+3776=>'L',
+3777=>'L',
+3778=>'L',
+3779=>'L',
+3780=>'L',
+3782=>'L',
+3784=>'NSM',
+3785=>'NSM',
+3786=>'NSM',
+3787=>'NSM',
+3788=>'NSM',
+3789=>'NSM',
+3792=>'L',
+3793=>'L',
+3794=>'L',
+3795=>'L',
+3796=>'L',
+3797=>'L',
+3798=>'L',
+3799=>'L',
+3800=>'L',
+3801=>'L',
+3804=>'L',
+3805=>'L',
+3840=>'L',
+3841=>'L',
+3842=>'L',
+3843=>'L',
+3844=>'L',
+3845=>'L',
+3846=>'L',
+3847=>'L',
+3848=>'L',
+3849=>'L',
+3850=>'L',
+3851=>'L',
+3852=>'L',
+3853=>'L',
+3854=>'L',
+3855=>'L',
+3856=>'L',
+3857=>'L',
+3858=>'L',
+3859=>'L',
+3860=>'L',
+3861=>'L',
+3862=>'L',
+3863=>'L',
+3864=>'NSM',
+3865=>'NSM',
+3866=>'L',
+3867=>'L',
+3868=>'L',
+3869=>'L',
+3870=>'L',
+3871=>'L',
+3872=>'L',
+3873=>'L',
+3874=>'L',
+3875=>'L',
+3876=>'L',
+3877=>'L',
+3878=>'L',
+3879=>'L',
+3880=>'L',
+3881=>'L',
+3882=>'L',
+3883=>'L',
+3884=>'L',
+3885=>'L',
+3886=>'L',
+3887=>'L',
+3888=>'L',
+3889=>'L',
+3890=>'L',
+3891=>'L',
+3892=>'L',
+3893=>'NSM',
+3894=>'L',
+3895=>'NSM',
+3896=>'L',
+3897=>'NSM',
+3898=>'ON',
+3899=>'ON',
+3900=>'ON',
+3901=>'ON',
+3902=>'L',
+3903=>'L',
+3904=>'L',
+3905=>'L',
+3906=>'L',
+3907=>'L',
+3908=>'L',
+3909=>'L',
+3910=>'L',
+3911=>'L',
+3913=>'L',
+3914=>'L',
+3915=>'L',
+3916=>'L',
+3917=>'L',
+3918=>'L',
+3919=>'L',
+3920=>'L',
+3921=>'L',
+3922=>'L',
+3923=>'L',
+3924=>'L',
+3925=>'L',
+3926=>'L',
+3927=>'L',
+3928=>'L',
+3929=>'L',
+3930=>'L',
+3931=>'L',
+3932=>'L',
+3933=>'L',
+3934=>'L',
+3935=>'L',
+3936=>'L',
+3937=>'L',
+3938=>'L',
+3939=>'L',
+3940=>'L',
+3941=>'L',
+3942=>'L',
+3943=>'L',
+3944=>'L',
+3945=>'L',
+3946=>'L',
+3953=>'NSM',
+3954=>'NSM',
+3955=>'NSM',
+3956=>'NSM',
+3957=>'NSM',
+3958=>'NSM',
+3959=>'NSM',
+3960=>'NSM',
+3961=>'NSM',
+3962=>'NSM',
+3963=>'NSM',
+3964=>'NSM',
+3965=>'NSM',
+3966=>'NSM',
+3967=>'L',
+3968=>'NSM',
+3969=>'NSM',
+3970=>'NSM',
+3971=>'NSM',
+3972=>'NSM',
+3973=>'L',
+3974=>'NSM',
+3975=>'NSM',
+3976=>'L',
+3977=>'L',
+3978=>'L',
+3979=>'L',
+3984=>'NSM',
+3985=>'NSM',
+3986=>'NSM',
+3987=>'NSM',
+3988=>'NSM',
+3989=>'NSM',
+3990=>'NSM',
+3991=>'NSM',
+3993=>'NSM',
+3994=>'NSM',
+3995=>'NSM',
+3996=>'NSM',
+3997=>'NSM',
+3998=>'NSM',
+3999=>'NSM',
+4000=>'NSM',
+4001=>'NSM',
+4002=>'NSM',
+4003=>'NSM',
+4004=>'NSM',
+4005=>'NSM',
+4006=>'NSM',
+4007=>'NSM',
+4008=>'NSM',
+4009=>'NSM',
+4010=>'NSM',
+4011=>'NSM',
+4012=>'NSM',
+4013=>'NSM',
+4014=>'NSM',
+4015=>'NSM',
+4016=>'NSM',
+4017=>'NSM',
+4018=>'NSM',
+4019=>'NSM',
+4020=>'NSM',
+4021=>'NSM',
+4022=>'NSM',
+4023=>'NSM',
+4024=>'NSM',
+4025=>'NSM',
+4026=>'NSM',
+4027=>'NSM',
+4028=>'NSM',
+4030=>'L',
+4031=>'L',
+4032=>'L',
+4033=>'L',
+4034=>'L',
+4035=>'L',
+4036=>'L',
+4037=>'L',
+4038=>'NSM',
+4039=>'L',
+4040=>'L',
+4041=>'L',
+4042=>'L',
+4043=>'L',
+4044=>'L',
+4047=>'L',
+4048=>'L',
+4049=>'L',
+4096=>'L',
+4097=>'L',
+4098=>'L',
+4099=>'L',
+4100=>'L',
+4101=>'L',
+4102=>'L',
+4103=>'L',
+4104=>'L',
+4105=>'L',
+4106=>'L',
+4107=>'L',
+4108=>'L',
+4109=>'L',
+4110=>'L',
+4111=>'L',
+4112=>'L',
+4113=>'L',
+4114=>'L',
+4115=>'L',
+4116=>'L',
+4117=>'L',
+4118=>'L',
+4119=>'L',
+4120=>'L',
+4121=>'L',
+4122=>'L',
+4123=>'L',
+4124=>'L',
+4125=>'L',
+4126=>'L',
+4127=>'L',
+4128=>'L',
+4129=>'L',
+4131=>'L',
+4132=>'L',
+4133=>'L',
+4134=>'L',
+4135=>'L',
+4137=>'L',
+4138=>'L',
+4140=>'L',
+4141=>'NSM',
+4142=>'NSM',
+4143=>'NSM',
+4144=>'NSM',
+4145=>'L',
+4146=>'NSM',
+4150=>'NSM',
+4151=>'NSM',
+4152=>'L',
+4153=>'NSM',
+4160=>'L',
+4161=>'L',
+4162=>'L',
+4163=>'L',
+4164=>'L',
+4165=>'L',
+4166=>'L',
+4167=>'L',
+4168=>'L',
+4169=>'L',
+4170=>'L',
+4171=>'L',
+4172=>'L',
+4173=>'L',
+4174=>'L',
+4175=>'L',
+4176=>'L',
+4177=>'L',
+4178=>'L',
+4179=>'L',
+4180=>'L',
+4181=>'L',
+4182=>'L',
+4183=>'L',
+4184=>'NSM',
+4185=>'NSM',
+4256=>'L',
+4257=>'L',
+4258=>'L',
+4259=>'L',
+4260=>'L',
+4261=>'L',
+4262=>'L',
+4263=>'L',
+4264=>'L',
+4265=>'L',
+4266=>'L',
+4267=>'L',
+4268=>'L',
+4269=>'L',
+4270=>'L',
+4271=>'L',
+4272=>'L',
+4273=>'L',
+4274=>'L',
+4275=>'L',
+4276=>'L',
+4277=>'L',
+4278=>'L',
+4279=>'L',
+4280=>'L',
+4281=>'L',
+4282=>'L',
+4283=>'L',
+4284=>'L',
+4285=>'L',
+4286=>'L',
+4287=>'L',
+4288=>'L',
+4289=>'L',
+4290=>'L',
+4291=>'L',
+4292=>'L',
+4293=>'L',
+4304=>'L',
+4305=>'L',
+4306=>'L',
+4307=>'L',
+4308=>'L',
+4309=>'L',
+4310=>'L',
+4311=>'L',
+4312=>'L',
+4313=>'L',
+4314=>'L',
+4315=>'L',
+4316=>'L',
+4317=>'L',
+4318=>'L',
+4319=>'L',
+4320=>'L',
+4321=>'L',
+4322=>'L',
+4323=>'L',
+4324=>'L',
+4325=>'L',
+4326=>'L',
+4327=>'L',
+4328=>'L',
+4329=>'L',
+4330=>'L',
+4331=>'L',
+4332=>'L',
+4333=>'L',
+4334=>'L',
+4335=>'L',
+4336=>'L',
+4337=>'L',
+4338=>'L',
+4339=>'L',
+4340=>'L',
+4341=>'L',
+4342=>'L',
+4343=>'L',
+4344=>'L',
+4345=>'L',
+4346=>'L',
+4347=>'L',
+4348=>'L',
+4352=>'L',
+4353=>'L',
+4354=>'L',
+4355=>'L',
+4356=>'L',
+4357=>'L',
+4358=>'L',
+4359=>'L',
+4360=>'L',
+4361=>'L',
+4362=>'L',
+4363=>'L',
+4364=>'L',
+4365=>'L',
+4366=>'L',
+4367=>'L',
+4368=>'L',
+4369=>'L',
+4370=>'L',
+4371=>'L',
+4372=>'L',
+4373=>'L',
+4374=>'L',
+4375=>'L',
+4376=>'L',
+4377=>'L',
+4378=>'L',
+4379=>'L',
+4380=>'L',
+4381=>'L',
+4382=>'L',
+4383=>'L',
+4384=>'L',
+4385=>'L',
+4386=>'L',
+4387=>'L',
+4388=>'L',
+4389=>'L',
+4390=>'L',
+4391=>'L',
+4392=>'L',
+4393=>'L',
+4394=>'L',
+4395=>'L',
+4396=>'L',
+4397=>'L',
+4398=>'L',
+4399=>'L',
+4400=>'L',
+4401=>'L',
+4402=>'L',
+4403=>'L',
+4404=>'L',
+4405=>'L',
+4406=>'L',
+4407=>'L',
+4408=>'L',
+4409=>'L',
+4410=>'L',
+4411=>'L',
+4412=>'L',
+4413=>'L',
+4414=>'L',
+4415=>'L',
+4416=>'L',
+4417=>'L',
+4418=>'L',
+4419=>'L',
+4420=>'L',
+4421=>'L',
+4422=>'L',
+4423=>'L',
+4424=>'L',
+4425=>'L',
+4426=>'L',
+4427=>'L',
+4428=>'L',
+4429=>'L',
+4430=>'L',
+4431=>'L',
+4432=>'L',
+4433=>'L',
+4434=>'L',
+4435=>'L',
+4436=>'L',
+4437=>'L',
+4438=>'L',
+4439=>'L',
+4440=>'L',
+4441=>'L',
+4447=>'L',
+4448=>'L',
+4449=>'L',
+4450=>'L',
+4451=>'L',
+4452=>'L',
+4453=>'L',
+4454=>'L',
+4455=>'L',
+4456=>'L',
+4457=>'L',
+4458=>'L',
+4459=>'L',
+4460=>'L',
+4461=>'L',
+4462=>'L',
+4463=>'L',
+4464=>'L',
+4465=>'L',
+4466=>'L',
+4467=>'L',
+4468=>'L',
+4469=>'L',
+4470=>'L',
+4471=>'L',
+4472=>'L',
+4473=>'L',
+4474=>'L',
+4475=>'L',
+4476=>'L',
+4477=>'L',
+4478=>'L',
+4479=>'L',
+4480=>'L',
+4481=>'L',
+4482=>'L',
+4483=>'L',
+4484=>'L',
+4485=>'L',
+4486=>'L',
+4487=>'L',
+4488=>'L',
+4489=>'L',
+4490=>'L',
+4491=>'L',
+4492=>'L',
+4493=>'L',
+4494=>'L',
+4495=>'L',
+4496=>'L',
+4497=>'L',
+4498=>'L',
+4499=>'L',
+4500=>'L',
+4501=>'L',
+4502=>'L',
+4503=>'L',
+4504=>'L',
+4505=>'L',
+4506=>'L',
+4507=>'L',
+4508=>'L',
+4509=>'L',
+4510=>'L',
+4511=>'L',
+4512=>'L',
+4513=>'L',
+4514=>'L',
+4520=>'L',
+4521=>'L',
+4522=>'L',
+4523=>'L',
+4524=>'L',
+4525=>'L',
+4526=>'L',
+4527=>'L',
+4528=>'L',
+4529=>'L',
+4530=>'L',
+4531=>'L',
+4532=>'L',
+4533=>'L',
+4534=>'L',
+4535=>'L',
+4536=>'L',
+4537=>'L',
+4538=>'L',
+4539=>'L',
+4540=>'L',
+4541=>'L',
+4542=>'L',
+4543=>'L',
+4544=>'L',
+4545=>'L',
+4546=>'L',
+4547=>'L',
+4548=>'L',
+4549=>'L',
+4550=>'L',
+4551=>'L',
+4552=>'L',
+4553=>'L',
+4554=>'L',
+4555=>'L',
+4556=>'L',
+4557=>'L',
+4558=>'L',
+4559=>'L',
+4560=>'L',
+4561=>'L',
+4562=>'L',
+4563=>'L',
+4564=>'L',
+4565=>'L',
+4566=>'L',
+4567=>'L',
+4568=>'L',
+4569=>'L',
+4570=>'L',
+4571=>'L',
+4572=>'L',
+4573=>'L',
+4574=>'L',
+4575=>'L',
+4576=>'L',
+4577=>'L',
+4578=>'L',
+4579=>'L',
+4580=>'L',
+4581=>'L',
+4582=>'L',
+4583=>'L',
+4584=>'L',
+4585=>'L',
+4586=>'L',
+4587=>'L',
+4588=>'L',
+4589=>'L',
+4590=>'L',
+4591=>'L',
+4592=>'L',
+4593=>'L',
+4594=>'L',
+4595=>'L',
+4596=>'L',
+4597=>'L',
+4598=>'L',
+4599=>'L',
+4600=>'L',
+4601=>'L',
+4608=>'L',
+4609=>'L',
+4610=>'L',
+4611=>'L',
+4612=>'L',
+4613=>'L',
+4614=>'L',
+4615=>'L',
+4616=>'L',
+4617=>'L',
+4618=>'L',
+4619=>'L',
+4620=>'L',
+4621=>'L',
+4622=>'L',
+4623=>'L',
+4624=>'L',
+4625=>'L',
+4626=>'L',
+4627=>'L',
+4628=>'L',
+4629=>'L',
+4630=>'L',
+4631=>'L',
+4632=>'L',
+4633=>'L',
+4634=>'L',
+4635=>'L',
+4636=>'L',
+4637=>'L',
+4638=>'L',
+4639=>'L',
+4640=>'L',
+4641=>'L',
+4642=>'L',
+4643=>'L',
+4644=>'L',
+4645=>'L',
+4646=>'L',
+4647=>'L',
+4648=>'L',
+4649=>'L',
+4650=>'L',
+4651=>'L',
+4652=>'L',
+4653=>'L',
+4654=>'L',
+4655=>'L',
+4656=>'L',
+4657=>'L',
+4658=>'L',
+4659=>'L',
+4660=>'L',
+4661=>'L',
+4662=>'L',
+4663=>'L',
+4664=>'L',
+4665=>'L',
+4666=>'L',
+4667=>'L',
+4668=>'L',
+4669=>'L',
+4670=>'L',
+4671=>'L',
+4672=>'L',
+4673=>'L',
+4674=>'L',
+4675=>'L',
+4676=>'L',
+4677=>'L',
+4678=>'L',
+4679=>'L',
+4680=>'L',
+4682=>'L',
+4683=>'L',
+4684=>'L',
+4685=>'L',
+4688=>'L',
+4689=>'L',
+4690=>'L',
+4691=>'L',
+4692=>'L',
+4693=>'L',
+4694=>'L',
+4696=>'L',
+4698=>'L',
+4699=>'L',
+4700=>'L',
+4701=>'L',
+4704=>'L',
+4705=>'L',
+4706=>'L',
+4707=>'L',
+4708=>'L',
+4709=>'L',
+4710=>'L',
+4711=>'L',
+4712=>'L',
+4713=>'L',
+4714=>'L',
+4715=>'L',
+4716=>'L',
+4717=>'L',
+4718=>'L',
+4719=>'L',
+4720=>'L',
+4721=>'L',
+4722=>'L',
+4723=>'L',
+4724=>'L',
+4725=>'L',
+4726=>'L',
+4727=>'L',
+4728=>'L',
+4729=>'L',
+4730=>'L',
+4731=>'L',
+4732=>'L',
+4733=>'L',
+4734=>'L',
+4735=>'L',
+4736=>'L',
+4737=>'L',
+4738=>'L',
+4739=>'L',
+4740=>'L',
+4741=>'L',
+4742=>'L',
+4743=>'L',
+4744=>'L',
+4746=>'L',
+4747=>'L',
+4748=>'L',
+4749=>'L',
+4752=>'L',
+4753=>'L',
+4754=>'L',
+4755=>'L',
+4756=>'L',
+4757=>'L',
+4758=>'L',
+4759=>'L',
+4760=>'L',
+4761=>'L',
+4762=>'L',
+4763=>'L',
+4764=>'L',
+4765=>'L',
+4766=>'L',
+4767=>'L',
+4768=>'L',
+4769=>'L',
+4770=>'L',
+4771=>'L',
+4772=>'L',
+4773=>'L',
+4774=>'L',
+4775=>'L',
+4776=>'L',
+4777=>'L',
+4778=>'L',
+4779=>'L',
+4780=>'L',
+4781=>'L',
+4782=>'L',
+4783=>'L',
+4784=>'L',
+4786=>'L',
+4787=>'L',
+4788=>'L',
+4789=>'L',
+4792=>'L',
+4793=>'L',
+4794=>'L',
+4795=>'L',
+4796=>'L',
+4797=>'L',
+4798=>'L',
+4800=>'L',
+4802=>'L',
+4803=>'L',
+4804=>'L',
+4805=>'L',
+4808=>'L',
+4809=>'L',
+4810=>'L',
+4811=>'L',
+4812=>'L',
+4813=>'L',
+4814=>'L',
+4815=>'L',
+4816=>'L',
+4817=>'L',
+4818=>'L',
+4819=>'L',
+4820=>'L',
+4821=>'L',
+4822=>'L',
+4824=>'L',
+4825=>'L',
+4826=>'L',
+4827=>'L',
+4828=>'L',
+4829=>'L',
+4830=>'L',
+4831=>'L',
+4832=>'L',
+4833=>'L',
+4834=>'L',
+4835=>'L',
+4836=>'L',
+4837=>'L',
+4838=>'L',
+4839=>'L',
+4840=>'L',
+4841=>'L',
+4842=>'L',
+4843=>'L',
+4844=>'L',
+4845=>'L',
+4846=>'L',
+4847=>'L',
+4848=>'L',
+4849=>'L',
+4850=>'L',
+4851=>'L',
+4852=>'L',
+4853=>'L',
+4854=>'L',
+4855=>'L',
+4856=>'L',
+4857=>'L',
+4858=>'L',
+4859=>'L',
+4860=>'L',
+4861=>'L',
+4862=>'L',
+4863=>'L',
+4864=>'L',
+4865=>'L',
+4866=>'L',
+4867=>'L',
+4868=>'L',
+4869=>'L',
+4870=>'L',
+4871=>'L',
+4872=>'L',
+4873=>'L',
+4874=>'L',
+4875=>'L',
+4876=>'L',
+4877=>'L',
+4878=>'L',
+4879=>'L',
+4880=>'L',
+4882=>'L',
+4883=>'L',
+4884=>'L',
+4885=>'L',
+4888=>'L',
+4889=>'L',
+4890=>'L',
+4891=>'L',
+4892=>'L',
+4893=>'L',
+4894=>'L',
+4895=>'L',
+4896=>'L',
+4897=>'L',
+4898=>'L',
+4899=>'L',
+4900=>'L',
+4901=>'L',
+4902=>'L',
+4903=>'L',
+4904=>'L',
+4905=>'L',
+4906=>'L',
+4907=>'L',
+4908=>'L',
+4909=>'L',
+4910=>'L',
+4911=>'L',
+4912=>'L',
+4913=>'L',
+4914=>'L',
+4915=>'L',
+4916=>'L',
+4917=>'L',
+4918=>'L',
+4919=>'L',
+4920=>'L',
+4921=>'L',
+4922=>'L',
+4923=>'L',
+4924=>'L',
+4925=>'L',
+4926=>'L',
+4927=>'L',
+4928=>'L',
+4929=>'L',
+4930=>'L',
+4931=>'L',
+4932=>'L',
+4933=>'L',
+4934=>'L',
+4935=>'L',
+4936=>'L',
+4937=>'L',
+4938=>'L',
+4939=>'L',
+4940=>'L',
+4941=>'L',
+4942=>'L',
+4943=>'L',
+4944=>'L',
+4945=>'L',
+4946=>'L',
+4947=>'L',
+4948=>'L',
+4949=>'L',
+4950=>'L',
+4951=>'L',
+4952=>'L',
+4953=>'L',
+4954=>'L',
+4959=>'NSM',
+4960=>'L',
+4961=>'L',
+4962=>'L',
+4963=>'L',
+4964=>'L',
+4965=>'L',
+4966=>'L',
+4967=>'L',
+4968=>'L',
+4969=>'L',
+4970=>'L',
+4971=>'L',
+4972=>'L',
+4973=>'L',
+4974=>'L',
+4975=>'L',
+4976=>'L',
+4977=>'L',
+4978=>'L',
+4979=>'L',
+4980=>'L',
+4981=>'L',
+4982=>'L',
+4983=>'L',
+4984=>'L',
+4985=>'L',
+4986=>'L',
+4987=>'L',
+4988=>'L',
+4992=>'L',
+4993=>'L',
+4994=>'L',
+4995=>'L',
+4996=>'L',
+4997=>'L',
+4998=>'L',
+4999=>'L',
+5000=>'L',
+5001=>'L',
+5002=>'L',
+5003=>'L',
+5004=>'L',
+5005=>'L',
+5006=>'L',
+5007=>'L',
+5008=>'ON',
+5009=>'ON',
+5010=>'ON',
+5011=>'ON',
+5012=>'ON',
+5013=>'ON',
+5014=>'ON',
+5015=>'ON',
+5016=>'ON',
+5017=>'ON',
+5024=>'L',
+5025=>'L',
+5026=>'L',
+5027=>'L',
+5028=>'L',
+5029=>'L',
+5030=>'L',
+5031=>'L',
+5032=>'L',
+5033=>'L',
+5034=>'L',
+5035=>'L',
+5036=>'L',
+5037=>'L',
+5038=>'L',
+5039=>'L',
+5040=>'L',
+5041=>'L',
+5042=>'L',
+5043=>'L',
+5044=>'L',
+5045=>'L',
+5046=>'L',
+5047=>'L',
+5048=>'L',
+5049=>'L',
+5050=>'L',
+5051=>'L',
+5052=>'L',
+5053=>'L',
+5054=>'L',
+5055=>'L',
+5056=>'L',
+5057=>'L',
+5058=>'L',
+5059=>'L',
+5060=>'L',
+5061=>'L',
+5062=>'L',
+5063=>'L',
+5064=>'L',
+5065=>'L',
+5066=>'L',
+5067=>'L',
+5068=>'L',
+5069=>'L',
+5070=>'L',
+5071=>'L',
+5072=>'L',
+5073=>'L',
+5074=>'L',
+5075=>'L',
+5076=>'L',
+5077=>'L',
+5078=>'L',
+5079=>'L',
+5080=>'L',
+5081=>'L',
+5082=>'L',
+5083=>'L',
+5084=>'L',
+5085=>'L',
+5086=>'L',
+5087=>'L',
+5088=>'L',
+5089=>'L',
+5090=>'L',
+5091=>'L',
+5092=>'L',
+5093=>'L',
+5094=>'L',
+5095=>'L',
+5096=>'L',
+5097=>'L',
+5098=>'L',
+5099=>'L',
+5100=>'L',
+5101=>'L',
+5102=>'L',
+5103=>'L',
+5104=>'L',
+5105=>'L',
+5106=>'L',
+5107=>'L',
+5108=>'L',
+5121=>'L',
+5122=>'L',
+5123=>'L',
+5124=>'L',
+5125=>'L',
+5126=>'L',
+5127=>'L',
+5128=>'L',
+5129=>'L',
+5130=>'L',
+5131=>'L',
+5132=>'L',
+5133=>'L',
+5134=>'L',
+5135=>'L',
+5136=>'L',
+5137=>'L',
+5138=>'L',
+5139=>'L',
+5140=>'L',
+5141=>'L',
+5142=>'L',
+5143=>'L',
+5144=>'L',
+5145=>'L',
+5146=>'L',
+5147=>'L',
+5148=>'L',
+5149=>'L',
+5150=>'L',
+5151=>'L',
+5152=>'L',
+5153=>'L',
+5154=>'L',
+5155=>'L',
+5156=>'L',
+5157=>'L',
+5158=>'L',
+5159=>'L',
+5160=>'L',
+5161=>'L',
+5162=>'L',
+5163=>'L',
+5164=>'L',
+5165=>'L',
+5166=>'L',
+5167=>'L',
+5168=>'L',
+5169=>'L',
+5170=>'L',
+5171=>'L',
+5172=>'L',
+5173=>'L',
+5174=>'L',
+5175=>'L',
+5176=>'L',
+5177=>'L',
+5178=>'L',
+5179=>'L',
+5180=>'L',
+5181=>'L',
+5182=>'L',
+5183=>'L',
+5184=>'L',
+5185=>'L',
+5186=>'L',
+5187=>'L',
+5188=>'L',
+5189=>'L',
+5190=>'L',
+5191=>'L',
+5192=>'L',
+5193=>'L',
+5194=>'L',
+5195=>'L',
+5196=>'L',
+5197=>'L',
+5198=>'L',
+5199=>'L',
+5200=>'L',
+5201=>'L',
+5202=>'L',
+5203=>'L',
+5204=>'L',
+5205=>'L',
+5206=>'L',
+5207=>'L',
+5208=>'L',
+5209=>'L',
+5210=>'L',
+5211=>'L',
+5212=>'L',
+5213=>'L',
+5214=>'L',
+5215=>'L',
+5216=>'L',
+5217=>'L',
+5218=>'L',
+5219=>'L',
+5220=>'L',
+5221=>'L',
+5222=>'L',
+5223=>'L',
+5224=>'L',
+5225=>'L',
+5226=>'L',
+5227=>'L',
+5228=>'L',
+5229=>'L',
+5230=>'L',
+5231=>'L',
+5232=>'L',
+5233=>'L',
+5234=>'L',
+5235=>'L',
+5236=>'L',
+5237=>'L',
+5238=>'L',
+5239=>'L',
+5240=>'L',
+5241=>'L',
+5242=>'L',
+5243=>'L',
+5244=>'L',
+5245=>'L',
+5246=>'L',
+5247=>'L',
+5248=>'L',
+5249=>'L',
+5250=>'L',
+5251=>'L',
+5252=>'L',
+5253=>'L',
+5254=>'L',
+5255=>'L',
+5256=>'L',
+5257=>'L',
+5258=>'L',
+5259=>'L',
+5260=>'L',
+5261=>'L',
+5262=>'L',
+5263=>'L',
+5264=>'L',
+5265=>'L',
+5266=>'L',
+5267=>'L',
+5268=>'L',
+5269=>'L',
+5270=>'L',
+5271=>'L',
+5272=>'L',
+5273=>'L',
+5274=>'L',
+5275=>'L',
+5276=>'L',
+5277=>'L',
+5278=>'L',
+5279=>'L',
+5280=>'L',
+5281=>'L',
+5282=>'L',
+5283=>'L',
+5284=>'L',
+5285=>'L',
+5286=>'L',
+5287=>'L',
+5288=>'L',
+5289=>'L',
+5290=>'L',
+5291=>'L',
+5292=>'L',
+5293=>'L',
+5294=>'L',
+5295=>'L',
+5296=>'L',
+5297=>'L',
+5298=>'L',
+5299=>'L',
+5300=>'L',
+5301=>'L',
+5302=>'L',
+5303=>'L',
+5304=>'L',
+5305=>'L',
+5306=>'L',
+5307=>'L',
+5308=>'L',
+5309=>'L',
+5310=>'L',
+5311=>'L',
+5312=>'L',
+5313=>'L',
+5314=>'L',
+5315=>'L',
+5316=>'L',
+5317=>'L',
+5318=>'L',
+5319=>'L',
+5320=>'L',
+5321=>'L',
+5322=>'L',
+5323=>'L',
+5324=>'L',
+5325=>'L',
+5326=>'L',
+5327=>'L',
+5328=>'L',
+5329=>'L',
+5330=>'L',
+5331=>'L',
+5332=>'L',
+5333=>'L',
+5334=>'L',
+5335=>'L',
+5336=>'L',
+5337=>'L',
+5338=>'L',
+5339=>'L',
+5340=>'L',
+5341=>'L',
+5342=>'L',
+5343=>'L',
+5344=>'L',
+5345=>'L',
+5346=>'L',
+5347=>'L',
+5348=>'L',
+5349=>'L',
+5350=>'L',
+5351=>'L',
+5352=>'L',
+5353=>'L',
+5354=>'L',
+5355=>'L',
+5356=>'L',
+5357=>'L',
+5358=>'L',
+5359=>'L',
+5360=>'L',
+5361=>'L',
+5362=>'L',
+5363=>'L',
+5364=>'L',
+5365=>'L',
+5366=>'L',
+5367=>'L',
+5368=>'L',
+5369=>'L',
+5370=>'L',
+5371=>'L',
+5372=>'L',
+5373=>'L',
+5374=>'L',
+5375=>'L',
+5376=>'L',
+5377=>'L',
+5378=>'L',
+5379=>'L',
+5380=>'L',
+5381=>'L',
+5382=>'L',
+5383=>'L',
+5384=>'L',
+5385=>'L',
+5386=>'L',
+5387=>'L',
+5388=>'L',
+5389=>'L',
+5390=>'L',
+5391=>'L',
+5392=>'L',
+5393=>'L',
+5394=>'L',
+5395=>'L',
+5396=>'L',
+5397=>'L',
+5398=>'L',
+5399=>'L',
+5400=>'L',
+5401=>'L',
+5402=>'L',
+5403=>'L',
+5404=>'L',
+5405=>'L',
+5406=>'L',
+5407=>'L',
+5408=>'L',
+5409=>'L',
+5410=>'L',
+5411=>'L',
+5412=>'L',
+5413=>'L',
+5414=>'L',
+5415=>'L',
+5416=>'L',
+5417=>'L',
+5418=>'L',
+5419=>'L',
+5420=>'L',
+5421=>'L',
+5422=>'L',
+5423=>'L',
+5424=>'L',
+5425=>'L',
+5426=>'L',
+5427=>'L',
+5428=>'L',
+5429=>'L',
+5430=>'L',
+5431=>'L',
+5432=>'L',
+5433=>'L',
+5434=>'L',
+5435=>'L',
+5436=>'L',
+5437=>'L',
+5438=>'L',
+5439=>'L',
+5440=>'L',
+5441=>'L',
+5442=>'L',
+5443=>'L',
+5444=>'L',
+5445=>'L',
+5446=>'L',
+5447=>'L',
+5448=>'L',
+5449=>'L',
+5450=>'L',
+5451=>'L',
+5452=>'L',
+5453=>'L',
+5454=>'L',
+5455=>'L',
+5456=>'L',
+5457=>'L',
+5458=>'L',
+5459=>'L',
+5460=>'L',
+5461=>'L',
+5462=>'L',
+5463=>'L',
+5464=>'L',
+5465=>'L',
+5466=>'L',
+5467=>'L',
+5468=>'L',
+5469=>'L',
+5470=>'L',
+5471=>'L',
+5472=>'L',
+5473=>'L',
+5474=>'L',
+5475=>'L',
+5476=>'L',
+5477=>'L',
+5478=>'L',
+5479=>'L',
+5480=>'L',
+5481=>'L',
+5482=>'L',
+5483=>'L',
+5484=>'L',
+5485=>'L',
+5486=>'L',
+5487=>'L',
+5488=>'L',
+5489=>'L',
+5490=>'L',
+5491=>'L',
+5492=>'L',
+5493=>'L',
+5494=>'L',
+5495=>'L',
+5496=>'L',
+5497=>'L',
+5498=>'L',
+5499=>'L',
+5500=>'L',
+5501=>'L',
+5502=>'L',
+5503=>'L',
+5504=>'L',
+5505=>'L',
+5506=>'L',
+5507=>'L',
+5508=>'L',
+5509=>'L',
+5510=>'L',
+5511=>'L',
+5512=>'L',
+5513=>'L',
+5514=>'L',
+5515=>'L',
+5516=>'L',
+5517=>'L',
+5518=>'L',
+5519=>'L',
+5520=>'L',
+5521=>'L',
+5522=>'L',
+5523=>'L',
+5524=>'L',
+5525=>'L',
+5526=>'L',
+5527=>'L',
+5528=>'L',
+5529=>'L',
+5530=>'L',
+5531=>'L',
+5532=>'L',
+5533=>'L',
+5534=>'L',
+5535=>'L',
+5536=>'L',
+5537=>'L',
+5538=>'L',
+5539=>'L',
+5540=>'L',
+5541=>'L',
+5542=>'L',
+5543=>'L',
+5544=>'L',
+5545=>'L',
+5546=>'L',
+5547=>'L',
+5548=>'L',
+5549=>'L',
+5550=>'L',
+5551=>'L',
+5552=>'L',
+5553=>'L',
+5554=>'L',
+5555=>'L',
+5556=>'L',
+5557=>'L',
+5558=>'L',
+5559=>'L',
+5560=>'L',
+5561=>'L',
+5562=>'L',
+5563=>'L',
+5564=>'L',
+5565=>'L',
+5566=>'L',
+5567=>'L',
+5568=>'L',
+5569=>'L',
+5570=>'L',
+5571=>'L',
+5572=>'L',
+5573=>'L',
+5574=>'L',
+5575=>'L',
+5576=>'L',
+5577=>'L',
+5578=>'L',
+5579=>'L',
+5580=>'L',
+5581=>'L',
+5582=>'L',
+5583=>'L',
+5584=>'L',
+5585=>'L',
+5586=>'L',
+5587=>'L',
+5588=>'L',
+5589=>'L',
+5590=>'L',
+5591=>'L',
+5592=>'L',
+5593=>'L',
+5594=>'L',
+5595=>'L',
+5596=>'L',
+5597=>'L',
+5598=>'L',
+5599=>'L',
+5600=>'L',
+5601=>'L',
+5602=>'L',
+5603=>'L',
+5604=>'L',
+5605=>'L',
+5606=>'L',
+5607=>'L',
+5608=>'L',
+5609=>'L',
+5610=>'L',
+5611=>'L',
+5612=>'L',
+5613=>'L',
+5614=>'L',
+5615=>'L',
+5616=>'L',
+5617=>'L',
+5618=>'L',
+5619=>'L',
+5620=>'L',
+5621=>'L',
+5622=>'L',
+5623=>'L',
+5624=>'L',
+5625=>'L',
+5626=>'L',
+5627=>'L',
+5628=>'L',
+5629=>'L',
+5630=>'L',
+5631=>'L',
+5632=>'L',
+5633=>'L',
+5634=>'L',
+5635=>'L',
+5636=>'L',
+5637=>'L',
+5638=>'L',
+5639=>'L',
+5640=>'L',
+5641=>'L',
+5642=>'L',
+5643=>'L',
+5644=>'L',
+5645=>'L',
+5646=>'L',
+5647=>'L',
+5648=>'L',
+5649=>'L',
+5650=>'L',
+5651=>'L',
+5652=>'L',
+5653=>'L',
+5654=>'L',
+5655=>'L',
+5656=>'L',
+5657=>'L',
+5658=>'L',
+5659=>'L',
+5660=>'L',
+5661=>'L',
+5662=>'L',
+5663=>'L',
+5664=>'L',
+5665=>'L',
+5666=>'L',
+5667=>'L',
+5668=>'L',
+5669=>'L',
+5670=>'L',
+5671=>'L',
+5672=>'L',
+5673=>'L',
+5674=>'L',
+5675=>'L',
+5676=>'L',
+5677=>'L',
+5678=>'L',
+5679=>'L',
+5680=>'L',
+5681=>'L',
+5682=>'L',
+5683=>'L',
+5684=>'L',
+5685=>'L',
+5686=>'L',
+5687=>'L',
+5688=>'L',
+5689=>'L',
+5690=>'L',
+5691=>'L',
+5692=>'L',
+5693=>'L',
+5694=>'L',
+5695=>'L',
+5696=>'L',
+5697=>'L',
+5698=>'L',
+5699=>'L',
+5700=>'L',
+5701=>'L',
+5702=>'L',
+5703=>'L',
+5704=>'L',
+5705=>'L',
+5706=>'L',
+5707=>'L',
+5708=>'L',
+5709=>'L',
+5710=>'L',
+5711=>'L',
+5712=>'L',
+5713=>'L',
+5714=>'L',
+5715=>'L',
+5716=>'L',
+5717=>'L',
+5718=>'L',
+5719=>'L',
+5720=>'L',
+5721=>'L',
+5722=>'L',
+5723=>'L',
+5724=>'L',
+5725=>'L',
+5726=>'L',
+5727=>'L',
+5728=>'L',
+5729=>'L',
+5730=>'L',
+5731=>'L',
+5732=>'L',
+5733=>'L',
+5734=>'L',
+5735=>'L',
+5736=>'L',
+5737=>'L',
+5738=>'L',
+5739=>'L',
+5740=>'L',
+5741=>'L',
+5742=>'L',
+5743=>'L',
+5744=>'L',
+5745=>'L',
+5746=>'L',
+5747=>'L',
+5748=>'L',
+5749=>'L',
+5750=>'L',
+5760=>'WS',
+5761=>'L',
+5762=>'L',
+5763=>'L',
+5764=>'L',
+5765=>'L',
+5766=>'L',
+5767=>'L',
+5768=>'L',
+5769=>'L',
+5770=>'L',
+5771=>'L',
+5772=>'L',
+5773=>'L',
+5774=>'L',
+5775=>'L',
+5776=>'L',
+5777=>'L',
+5778=>'L',
+5779=>'L',
+5780=>'L',
+5781=>'L',
+5782=>'L',
+5783=>'L',
+5784=>'L',
+5785=>'L',
+5786=>'L',
+5787=>'ON',
+5788=>'ON',
+5792=>'L',
+5793=>'L',
+5794=>'L',
+5795=>'L',
+5796=>'L',
+5797=>'L',
+5798=>'L',
+5799=>'L',
+5800=>'L',
+5801=>'L',
+5802=>'L',
+5803=>'L',
+5804=>'L',
+5805=>'L',
+5806=>'L',
+5807=>'L',
+5808=>'L',
+5809=>'L',
+5810=>'L',
+5811=>'L',
+5812=>'L',
+5813=>'L',
+5814=>'L',
+5815=>'L',
+5816=>'L',
+5817=>'L',
+5818=>'L',
+5819=>'L',
+5820=>'L',
+5821=>'L',
+5822=>'L',
+5823=>'L',
+5824=>'L',
+5825=>'L',
+5826=>'L',
+5827=>'L',
+5828=>'L',
+5829=>'L',
+5830=>'L',
+5831=>'L',
+5832=>'L',
+5833=>'L',
+5834=>'L',
+5835=>'L',
+5836=>'L',
+5837=>'L',
+5838=>'L',
+5839=>'L',
+5840=>'L',
+5841=>'L',
+5842=>'L',
+5843=>'L',
+5844=>'L',
+5845=>'L',
+5846=>'L',
+5847=>'L',
+5848=>'L',
+5849=>'L',
+5850=>'L',
+5851=>'L',
+5852=>'L',
+5853=>'L',
+5854=>'L',
+5855=>'L',
+5856=>'L',
+5857=>'L',
+5858=>'L',
+5859=>'L',
+5860=>'L',
+5861=>'L',
+5862=>'L',
+5863=>'L',
+5864=>'L',
+5865=>'L',
+5866=>'L',
+5867=>'L',
+5868=>'L',
+5869=>'L',
+5870=>'L',
+5871=>'L',
+5872=>'L',
+5888=>'L',
+5889=>'L',
+5890=>'L',
+5891=>'L',
+5892=>'L',
+5893=>'L',
+5894=>'L',
+5895=>'L',
+5896=>'L',
+5897=>'L',
+5898=>'L',
+5899=>'L',
+5900=>'L',
+5902=>'L',
+5903=>'L',
+5904=>'L',
+5905=>'L',
+5906=>'NSM',
+5907=>'NSM',
+5908=>'NSM',
+5920=>'L',
+5921=>'L',
+5922=>'L',
+5923=>'L',
+5924=>'L',
+5925=>'L',
+5926=>'L',
+5927=>'L',
+5928=>'L',
+5929=>'L',
+5930=>'L',
+5931=>'L',
+5932=>'L',
+5933=>'L',
+5934=>'L',
+5935=>'L',
+5936=>'L',
+5937=>'L',
+5938=>'NSM',
+5939=>'NSM',
+5940=>'NSM',
+5941=>'L',
+5942=>'L',
+5952=>'L',
+5953=>'L',
+5954=>'L',
+5955=>'L',
+5956=>'L',
+5957=>'L',
+5958=>'L',
+5959=>'L',
+5960=>'L',
+5961=>'L',
+5962=>'L',
+5963=>'L',
+5964=>'L',
+5965=>'L',
+5966=>'L',
+5967=>'L',
+5968=>'L',
+5969=>'L',
+5970=>'NSM',
+5971=>'NSM',
+5984=>'L',
+5985=>'L',
+5986=>'L',
+5987=>'L',
+5988=>'L',
+5989=>'L',
+5990=>'L',
+5991=>'L',
+5992=>'L',
+5993=>'L',
+5994=>'L',
+5995=>'L',
+5996=>'L',
+5998=>'L',
+5999=>'L',
+6000=>'L',
+6002=>'NSM',
+6003=>'NSM',
+6016=>'L',
+6017=>'L',
+6018=>'L',
+6019=>'L',
+6020=>'L',
+6021=>'L',
+6022=>'L',
+6023=>'L',
+6024=>'L',
+6025=>'L',
+6026=>'L',
+6027=>'L',
+6028=>'L',
+6029=>'L',
+6030=>'L',
+6031=>'L',
+6032=>'L',
+6033=>'L',
+6034=>'L',
+6035=>'L',
+6036=>'L',
+6037=>'L',
+6038=>'L',
+6039=>'L',
+6040=>'L',
+6041=>'L',
+6042=>'L',
+6043=>'L',
+6044=>'L',
+6045=>'L',
+6046=>'L',
+6047=>'L',
+6048=>'L',
+6049=>'L',
+6050=>'L',
+6051=>'L',
+6052=>'L',
+6053=>'L',
+6054=>'L',
+6055=>'L',
+6056=>'L',
+6057=>'L',
+6058=>'L',
+6059=>'L',
+6060=>'L',
+6061=>'L',
+6062=>'L',
+6063=>'L',
+6064=>'L',
+6065=>'L',
+6066=>'L',
+6067=>'L',
+6068=>'L',
+6069=>'L',
+6070=>'L',
+6071=>'NSM',
+6072=>'NSM',
+6073=>'NSM',
+6074=>'NSM',
+6075=>'NSM',
+6076=>'NSM',
+6077=>'NSM',
+6078=>'L',
+6079=>'L',
+6080=>'L',
+6081=>'L',
+6082=>'L',
+6083=>'L',
+6084=>'L',
+6085=>'L',
+6086=>'NSM',
+6087=>'L',
+6088=>'L',
+6089=>'NSM',
+6090=>'NSM',
+6091=>'NSM',
+6092=>'NSM',
+6093=>'NSM',
+6094=>'NSM',
+6095=>'NSM',
+6096=>'NSM',
+6097=>'NSM',
+6098=>'NSM',
+6099=>'NSM',
+6100=>'L',
+6101=>'L',
+6102=>'L',
+6103=>'L',
+6104=>'L',
+6105=>'L',
+6106=>'L',
+6107=>'ET',
+6108=>'L',
+6109=>'NSM',
+6112=>'L',
+6113=>'L',
+6114=>'L',
+6115=>'L',
+6116=>'L',
+6117=>'L',
+6118=>'L',
+6119=>'L',
+6120=>'L',
+6121=>'L',
+6128=>'ON',
+6129=>'ON',
+6130=>'ON',
+6131=>'ON',
+6132=>'ON',
+6133=>'ON',
+6134=>'ON',
+6135=>'ON',
+6136=>'ON',
+6137=>'ON',
+6144=>'ON',
+6145=>'ON',
+6146=>'ON',
+6147=>'ON',
+6148=>'ON',
+6149=>'ON',
+6150=>'ON',
+6151=>'ON',
+6152=>'ON',
+6153=>'ON',
+6154=>'ON',
+6155=>'NSM',
+6156=>'NSM',
+6157=>'NSM',
+6158=>'WS',
+6160=>'L',
+6161=>'L',
+6162=>'L',
+6163=>'L',
+6164=>'L',
+6165=>'L',
+6166=>'L',
+6167=>'L',
+6168=>'L',
+6169=>'L',
+6176=>'L',
+6177=>'L',
+6178=>'L',
+6179=>'L',
+6180=>'L',
+6181=>'L',
+6182=>'L',
+6183=>'L',
+6184=>'L',
+6185=>'L',
+6186=>'L',
+6187=>'L',
+6188=>'L',
+6189=>'L',
+6190=>'L',
+6191=>'L',
+6192=>'L',
+6193=>'L',
+6194=>'L',
+6195=>'L',
+6196=>'L',
+6197=>'L',
+6198=>'L',
+6199=>'L',
+6200=>'L',
+6201=>'L',
+6202=>'L',
+6203=>'L',
+6204=>'L',
+6205=>'L',
+6206=>'L',
+6207=>'L',
+6208=>'L',
+6209=>'L',
+6210=>'L',
+6211=>'L',
+6212=>'L',
+6213=>'L',
+6214=>'L',
+6215=>'L',
+6216=>'L',
+6217=>'L',
+6218=>'L',
+6219=>'L',
+6220=>'L',
+6221=>'L',
+6222=>'L',
+6223=>'L',
+6224=>'L',
+6225=>'L',
+6226=>'L',
+6227=>'L',
+6228=>'L',
+6229=>'L',
+6230=>'L',
+6231=>'L',
+6232=>'L',
+6233=>'L',
+6234=>'L',
+6235=>'L',
+6236=>'L',
+6237=>'L',
+6238=>'L',
+6239=>'L',
+6240=>'L',
+6241=>'L',
+6242=>'L',
+6243=>'L',
+6244=>'L',
+6245=>'L',
+6246=>'L',
+6247=>'L',
+6248=>'L',
+6249=>'L',
+6250=>'L',
+6251=>'L',
+6252=>'L',
+6253=>'L',
+6254=>'L',
+6255=>'L',
+6256=>'L',
+6257=>'L',
+6258=>'L',
+6259=>'L',
+6260=>'L',
+6261=>'L',
+6262=>'L',
+6263=>'L',
+6272=>'L',
+6273=>'L',
+6274=>'L',
+6275=>'L',
+6276=>'L',
+6277=>'L',
+6278=>'L',
+6279=>'L',
+6280=>'L',
+6281=>'L',
+6282=>'L',
+6283=>'L',
+6284=>'L',
+6285=>'L',
+6286=>'L',
+6287=>'L',
+6288=>'L',
+6289=>'L',
+6290=>'L',
+6291=>'L',
+6292=>'L',
+6293=>'L',
+6294=>'L',
+6295=>'L',
+6296=>'L',
+6297=>'L',
+6298=>'L',
+6299=>'L',
+6300=>'L',
+6301=>'L',
+6302=>'L',
+6303=>'L',
+6304=>'L',
+6305=>'L',
+6306=>'L',
+6307=>'L',
+6308=>'L',
+6309=>'L',
+6310=>'L',
+6311=>'L',
+6312=>'L',
+6313=>'NSM',
+6400=>'L',
+6401=>'L',
+6402=>'L',
+6403=>'L',
+6404=>'L',
+6405=>'L',
+6406=>'L',
+6407=>'L',
+6408=>'L',
+6409=>'L',
+6410=>'L',
+6411=>'L',
+6412=>'L',
+6413=>'L',
+6414=>'L',
+6415=>'L',
+6416=>'L',
+6417=>'L',
+6418=>'L',
+6419=>'L',
+6420=>'L',
+6421=>'L',
+6422=>'L',
+6423=>'L',
+6424=>'L',
+6425=>'L',
+6426=>'L',
+6427=>'L',
+6428=>'L',
+6432=>'NSM',
+6433=>'NSM',
+6434=>'NSM',
+6435=>'L',
+6436=>'L',
+6437=>'L',
+6438=>'L',
+6439=>'NSM',
+6440=>'NSM',
+6441=>'NSM',
+6442=>'NSM',
+6443=>'NSM',
+6448=>'L',
+6449=>'L',
+6450=>'NSM',
+6451=>'L',
+6452=>'L',
+6453=>'L',
+6454=>'L',
+6455=>'L',
+6456=>'L',
+6457=>'NSM',
+6458=>'NSM',
+6459=>'NSM',
+6464=>'ON',
+6468=>'ON',
+6469=>'ON',
+6470=>'L',
+6471=>'L',
+6472=>'L',
+6473=>'L',
+6474=>'L',
+6475=>'L',
+6476=>'L',
+6477=>'L',
+6478=>'L',
+6479=>'L',
+6480=>'L',
+6481=>'L',
+6482=>'L',
+6483=>'L',
+6484=>'L',
+6485=>'L',
+6486=>'L',
+6487=>'L',
+6488=>'L',
+6489=>'L',
+6490=>'L',
+6491=>'L',
+6492=>'L',
+6493=>'L',
+6494=>'L',
+6495=>'L',
+6496=>'L',
+6497=>'L',
+6498=>'L',
+6499=>'L',
+6500=>'L',
+6501=>'L',
+6502=>'L',
+6503=>'L',
+6504=>'L',
+6505=>'L',
+6506=>'L',
+6507=>'L',
+6508=>'L',
+6509=>'L',
+6512=>'L',
+6513=>'L',
+6514=>'L',
+6515=>'L',
+6516=>'L',
+6528=>'L',
+6529=>'L',
+6530=>'L',
+6531=>'L',
+6532=>'L',
+6533=>'L',
+6534=>'L',
+6535=>'L',
+6536=>'L',
+6537=>'L',
+6538=>'L',
+6539=>'L',
+6540=>'L',
+6541=>'L',
+6542=>'L',
+6543=>'L',
+6544=>'L',
+6545=>'L',
+6546=>'L',
+6547=>'L',
+6548=>'L',
+6549=>'L',
+6550=>'L',
+6551=>'L',
+6552=>'L',
+6553=>'L',
+6554=>'L',
+6555=>'L',
+6556=>'L',
+6557=>'L',
+6558=>'L',
+6559=>'L',
+6560=>'L',
+6561=>'L',
+6562=>'L',
+6563=>'L',
+6564=>'L',
+6565=>'L',
+6566=>'L',
+6567=>'L',
+6568=>'L',
+6569=>'L',
+6576=>'L',
+6577=>'L',
+6578=>'L',
+6579=>'L',
+6580=>'L',
+6581=>'L',
+6582=>'L',
+6583=>'L',
+6584=>'L',
+6585=>'L',
+6586=>'L',
+6587=>'L',
+6588=>'L',
+6589=>'L',
+6590=>'L',
+6591=>'L',
+6592=>'L',
+6593=>'L',
+6594=>'L',
+6595=>'L',
+6596=>'L',
+6597=>'L',
+6598=>'L',
+6599=>'L',
+6600=>'L',
+6601=>'L',
+6608=>'L',
+6609=>'L',
+6610=>'L',
+6611=>'L',
+6612=>'L',
+6613=>'L',
+6614=>'L',
+6615=>'L',
+6616=>'L',
+6617=>'L',
+6622=>'ON',
+6623=>'ON',
+6624=>'ON',
+6625=>'ON',
+6626=>'ON',
+6627=>'ON',
+6628=>'ON',
+6629=>'ON',
+6630=>'ON',
+6631=>'ON',
+6632=>'ON',
+6633=>'ON',
+6634=>'ON',
+6635=>'ON',
+6636=>'ON',
+6637=>'ON',
+6638=>'ON',
+6639=>'ON',
+6640=>'ON',
+6641=>'ON',
+6642=>'ON',
+6643=>'ON',
+6644=>'ON',
+6645=>'ON',
+6646=>'ON',
+6647=>'ON',
+6648=>'ON',
+6649=>'ON',
+6650=>'ON',
+6651=>'ON',
+6652=>'ON',
+6653=>'ON',
+6654=>'ON',
+6655=>'ON',
+6656=>'L',
+6657=>'L',
+6658=>'L',
+6659=>'L',
+6660=>'L',
+6661=>'L',
+6662=>'L',
+6663=>'L',
+6664=>'L',
+6665=>'L',
+6666=>'L',
+6667=>'L',
+6668=>'L',
+6669=>'L',
+6670=>'L',
+6671=>'L',
+6672=>'L',
+6673=>'L',
+6674=>'L',
+6675=>'L',
+6676=>'L',
+6677=>'L',
+6678=>'L',
+6679=>'NSM',
+6680=>'NSM',
+6681=>'L',
+6682=>'L',
+6683=>'L',
+6686=>'L',
+6687=>'L',
+6912=>'NSM',
+6913=>'NSM',
+6914=>'NSM',
+6915=>'NSM',
+6916=>'L',
+6917=>'L',
+6918=>'L',
+6919=>'L',
+6920=>'L',
+6921=>'L',
+6922=>'L',
+6923=>'L',
+6924=>'L',
+6925=>'L',
+6926=>'L',
+6927=>'L',
+6928=>'L',
+6929=>'L',
+6930=>'L',
+6931=>'L',
+6932=>'L',
+6933=>'L',
+6934=>'L',
+6935=>'L',
+6936=>'L',
+6937=>'L',
+6938=>'L',
+6939=>'L',
+6940=>'L',
+6941=>'L',
+6942=>'L',
+6943=>'L',
+6944=>'L',
+6945=>'L',
+6946=>'L',
+6947=>'L',
+6948=>'L',
+6949=>'L',
+6950=>'L',
+6951=>'L',
+6952=>'L',
+6953=>'L',
+6954=>'L',
+6955=>'L',
+6956=>'L',
+6957=>'L',
+6958=>'L',
+6959=>'L',
+6960=>'L',
+6961=>'L',
+6962=>'L',
+6963=>'L',
+6964=>'NSM',
+6965=>'L',
+6966=>'NSM',
+6967=>'NSM',
+6968=>'NSM',
+6969=>'NSM',
+6970=>'NSM',
+6971=>'L',
+6972=>'NSM',
+6973=>'L',
+6974=>'L',
+6975=>'L',
+6976=>'L',
+6977=>'L',
+6978=>'NSM',
+6979=>'L',
+6980=>'L',
+6981=>'L',
+6982=>'L',
+6983=>'L',
+6984=>'L',
+6985=>'L',
+6986=>'L',
+6987=>'L',
+6992=>'L',
+6993=>'L',
+6994=>'L',
+6995=>'L',
+6996=>'L',
+6997=>'L',
+6998=>'L',
+6999=>'L',
+7000=>'L',
+7001=>'L',
+7002=>'L',
+7003=>'L',
+7004=>'L',
+7005=>'L',
+7006=>'L',
+7007=>'L',
+7008=>'L',
+7009=>'L',
+7010=>'L',
+7011=>'L',
+7012=>'L',
+7013=>'L',
+7014=>'L',
+7015=>'L',
+7016=>'L',
+7017=>'L',
+7018=>'L',
+7019=>'NSM',
+7020=>'NSM',
+7021=>'NSM',
+7022=>'NSM',
+7023=>'NSM',
+7024=>'NSM',
+7025=>'NSM',
+7026=>'NSM',
+7027=>'NSM',
+7028=>'L',
+7029=>'L',
+7030=>'L',
+7031=>'L',
+7032=>'L',
+7033=>'L',
+7034=>'L',
+7035=>'L',
+7036=>'L',
+7424=>'L',
+7425=>'L',
+7426=>'L',
+7427=>'L',
+7428=>'L',
+7429=>'L',
+7430=>'L',
+7431=>'L',
+7432=>'L',
+7433=>'L',
+7434=>'L',
+7435=>'L',
+7436=>'L',
+7437=>'L',
+7438=>'L',
+7439=>'L',
+7440=>'L',
+7441=>'L',
+7442=>'L',
+7443=>'L',
+7444=>'L',
+7445=>'L',
+7446=>'L',
+7447=>'L',
+7448=>'L',
+7449=>'L',
+7450=>'L',
+7451=>'L',
+7452=>'L',
+7453=>'L',
+7454=>'L',
+7455=>'L',
+7456=>'L',
+7457=>'L',
+7458=>'L',
+7459=>'L',
+7460=>'L',
+7461=>'L',
+7462=>'L',
+7463=>'L',
+7464=>'L',
+7465=>'L',
+7466=>'L',
+7467=>'L',
+7468=>'L',
+7469=>'L',
+7470=>'L',
+7471=>'L',
+7472=>'L',
+7473=>'L',
+7474=>'L',
+7475=>'L',
+7476=>'L',
+7477=>'L',
+7478=>'L',
+7479=>'L',
+7480=>'L',
+7481=>'L',
+7482=>'L',
+7483=>'L',
+7484=>'L',
+7485=>'L',
+7486=>'L',
+7487=>'L',
+7488=>'L',
+7489=>'L',
+7490=>'L',
+7491=>'L',
+7492=>'L',
+7493=>'L',
+7494=>'L',
+7495=>'L',
+7496=>'L',
+7497=>'L',
+7498=>'L',
+7499=>'L',
+7500=>'L',
+7501=>'L',
+7502=>'L',
+7503=>'L',
+7504=>'L',
+7505=>'L',
+7506=>'L',
+7507=>'L',
+7508=>'L',
+7509=>'L',
+7510=>'L',
+7511=>'L',
+7512=>'L',
+7513=>'L',
+7514=>'L',
+7515=>'L',
+7516=>'L',
+7517=>'L',
+7518=>'L',
+7519=>'L',
+7520=>'L',
+7521=>'L',
+7522=>'L',
+7523=>'L',
+7524=>'L',
+7525=>'L',
+7526=>'L',
+7527=>'L',
+7528=>'L',
+7529=>'L',
+7530=>'L',
+7531=>'L',
+7532=>'L',
+7533=>'L',
+7534=>'L',
+7535=>'L',
+7536=>'L',
+7537=>'L',
+7538=>'L',
+7539=>'L',
+7540=>'L',
+7541=>'L',
+7542=>'L',
+7543=>'L',
+7544=>'L',
+7545=>'L',
+7546=>'L',
+7547=>'L',
+7548=>'L',
+7549=>'L',
+7550=>'L',
+7551=>'L',
+7552=>'L',
+7553=>'L',
+7554=>'L',
+7555=>'L',
+7556=>'L',
+7557=>'L',
+7558=>'L',
+7559=>'L',
+7560=>'L',
+7561=>'L',
+7562=>'L',
+7563=>'L',
+7564=>'L',
+7565=>'L',
+7566=>'L',
+7567=>'L',
+7568=>'L',
+7569=>'L',
+7570=>'L',
+7571=>'L',
+7572=>'L',
+7573=>'L',
+7574=>'L',
+7575=>'L',
+7576=>'L',
+7577=>'L',
+7578=>'L',
+7579=>'L',
+7580=>'L',
+7581=>'L',
+7582=>'L',
+7583=>'L',
+7584=>'L',
+7585=>'L',
+7586=>'L',
+7587=>'L',
+7588=>'L',
+7589=>'L',
+7590=>'L',
+7591=>'L',
+7592=>'L',
+7593=>'L',
+7594=>'L',
+7595=>'L',
+7596=>'L',
+7597=>'L',
+7598=>'L',
+7599=>'L',
+7600=>'L',
+7601=>'L',
+7602=>'L',
+7603=>'L',
+7604=>'L',
+7605=>'L',
+7606=>'L',
+7607=>'L',
+7608=>'L',
+7609=>'L',
+7610=>'L',
+7611=>'L',
+7612=>'L',
+7613=>'L',
+7614=>'L',
+7615=>'L',
+7616=>'NSM',
+7617=>'NSM',
+7618=>'NSM',
+7619=>'NSM',
+7620=>'NSM',
+7621=>'NSM',
+7622=>'NSM',
+7623=>'NSM',
+7624=>'NSM',
+7625=>'NSM',
+7626=>'NSM',
+7678=>'NSM',
+7679=>'NSM',
+7680=>'L',
+7681=>'L',
+7682=>'L',
+7683=>'L',
+7684=>'L',
+7685=>'L',
+7686=>'L',
+7687=>'L',
+7688=>'L',
+7689=>'L',
+7690=>'L',
+7691=>'L',
+7692=>'L',
+7693=>'L',
+7694=>'L',
+7695=>'L',
+7696=>'L',
+7697=>'L',
+7698=>'L',
+7699=>'L',
+7700=>'L',
+7701=>'L',
+7702=>'L',
+7703=>'L',
+7704=>'L',
+7705=>'L',
+7706=>'L',
+7707=>'L',
+7708=>'L',
+7709=>'L',
+7710=>'L',
+7711=>'L',
+7712=>'L',
+7713=>'L',
+7714=>'L',
+7715=>'L',
+7716=>'L',
+7717=>'L',
+7718=>'L',
+7719=>'L',
+7720=>'L',
+7721=>'L',
+7722=>'L',
+7723=>'L',
+7724=>'L',
+7725=>'L',
+7726=>'L',
+7727=>'L',
+7728=>'L',
+7729=>'L',
+7730=>'L',
+7731=>'L',
+7732=>'L',
+7733=>'L',
+7734=>'L',
+7735=>'L',
+7736=>'L',
+7737=>'L',
+7738=>'L',
+7739=>'L',
+7740=>'L',
+7741=>'L',
+7742=>'L',
+7743=>'L',
+7744=>'L',
+7745=>'L',
+7746=>'L',
+7747=>'L',
+7748=>'L',
+7749=>'L',
+7750=>'L',
+7751=>'L',
+7752=>'L',
+7753=>'L',
+7754=>'L',
+7755=>'L',
+7756=>'L',
+7757=>'L',
+7758=>'L',
+7759=>'L',
+7760=>'L',
+7761=>'L',
+7762=>'L',
+7763=>'L',
+7764=>'L',
+7765=>'L',
+7766=>'L',
+7767=>'L',
+7768=>'L',
+7769=>'L',
+7770=>'L',
+7771=>'L',
+7772=>'L',
+7773=>'L',
+7774=>'L',
+7775=>'L',
+7776=>'L',
+7777=>'L',
+7778=>'L',
+7779=>'L',
+7780=>'L',
+7781=>'L',
+7782=>'L',
+7783=>'L',
+7784=>'L',
+7785=>'L',
+7786=>'L',
+7787=>'L',
+7788=>'L',
+7789=>'L',
+7790=>'L',
+7791=>'L',
+7792=>'L',
+7793=>'L',
+7794=>'L',
+7795=>'L',
+7796=>'L',
+7797=>'L',
+7798=>'L',
+7799=>'L',
+7800=>'L',
+7801=>'L',
+7802=>'L',
+7803=>'L',
+7804=>'L',
+7805=>'L',
+7806=>'L',
+7807=>'L',
+7808=>'L',
+7809=>'L',
+7810=>'L',
+7811=>'L',
+7812=>'L',
+7813=>'L',
+7814=>'L',
+7815=>'L',
+7816=>'L',
+7817=>'L',
+7818=>'L',
+7819=>'L',
+7820=>'L',
+7821=>'L',
+7822=>'L',
+7823=>'L',
+7824=>'L',
+7825=>'L',
+7826=>'L',
+7827=>'L',
+7828=>'L',
+7829=>'L',
+7830=>'L',
+7831=>'L',
+7832=>'L',
+7833=>'L',
+7834=>'L',
+7835=>'L',
+7840=>'L',
+7841=>'L',
+7842=>'L',
+7843=>'L',
+7844=>'L',
+7845=>'L',
+7846=>'L',
+7847=>'L',
+7848=>'L',
+7849=>'L',
+7850=>'L',
+7851=>'L',
+7852=>'L',
+7853=>'L',
+7854=>'L',
+7855=>'L',
+7856=>'L',
+7857=>'L',
+7858=>'L',
+7859=>'L',
+7860=>'L',
+7861=>'L',
+7862=>'L',
+7863=>'L',
+7864=>'L',
+7865=>'L',
+7866=>'L',
+7867=>'L',
+7868=>'L',
+7869=>'L',
+7870=>'L',
+7871=>'L',
+7872=>'L',
+7873=>'L',
+7874=>'L',
+7875=>'L',
+7876=>'L',
+7877=>'L',
+7878=>'L',
+7879=>'L',
+7880=>'L',
+7881=>'L',
+7882=>'L',
+7883=>'L',
+7884=>'L',
+7885=>'L',
+7886=>'L',
+7887=>'L',
+7888=>'L',
+7889=>'L',
+7890=>'L',
+7891=>'L',
+7892=>'L',
+7893=>'L',
+7894=>'L',
+7895=>'L',
+7896=>'L',
+7897=>'L',
+7898=>'L',
+7899=>'L',
+7900=>'L',
+7901=>'L',
+7902=>'L',
+7903=>'L',
+7904=>'L',
+7905=>'L',
+7906=>'L',
+7907=>'L',
+7908=>'L',
+7909=>'L',
+7910=>'L',
+7911=>'L',
+7912=>'L',
+7913=>'L',
+7914=>'L',
+7915=>'L',
+7916=>'L',
+7917=>'L',
+7918=>'L',
+7919=>'L',
+7920=>'L',
+7921=>'L',
+7922=>'L',
+7923=>'L',
+7924=>'L',
+7925=>'L',
+7926=>'L',
+7927=>'L',
+7928=>'L',
+7929=>'L',
+7936=>'L',
+7937=>'L',
+7938=>'L',
+7939=>'L',
+7940=>'L',
+7941=>'L',
+7942=>'L',
+7943=>'L',
+7944=>'L',
+7945=>'L',
+7946=>'L',
+7947=>'L',
+7948=>'L',
+7949=>'L',
+7950=>'L',
+7951=>'L',
+7952=>'L',
+7953=>'L',
+7954=>'L',
+7955=>'L',
+7956=>'L',
+7957=>'L',
+7960=>'L',
+7961=>'L',
+7962=>'L',
+7963=>'L',
+7964=>'L',
+7965=>'L',
+7968=>'L',
+7969=>'L',
+7970=>'L',
+7971=>'L',
+7972=>'L',
+7973=>'L',
+7974=>'L',
+7975=>'L',
+7976=>'L',
+7977=>'L',
+7978=>'L',
+7979=>'L',
+7980=>'L',
+7981=>'L',
+7982=>'L',
+7983=>'L',
+7984=>'L',
+7985=>'L',
+7986=>'L',
+7987=>'L',
+7988=>'L',
+7989=>'L',
+7990=>'L',
+7991=>'L',
+7992=>'L',
+7993=>'L',
+7994=>'L',
+7995=>'L',
+7996=>'L',
+7997=>'L',
+7998=>'L',
+7999=>'L',
+8000=>'L',
+8001=>'L',
+8002=>'L',
+8003=>'L',
+8004=>'L',
+8005=>'L',
+8008=>'L',
+8009=>'L',
+8010=>'L',
+8011=>'L',
+8012=>'L',
+8013=>'L',
+8016=>'L',
+8017=>'L',
+8018=>'L',
+8019=>'L',
+8020=>'L',
+8021=>'L',
+8022=>'L',
+8023=>'L',
+8025=>'L',
+8027=>'L',
+8029=>'L',
+8031=>'L',
+8032=>'L',
+8033=>'L',
+8034=>'L',
+8035=>'L',
+8036=>'L',
+8037=>'L',
+8038=>'L',
+8039=>'L',
+8040=>'L',
+8041=>'L',
+8042=>'L',
+8043=>'L',
+8044=>'L',
+8045=>'L',
+8046=>'L',
+8047=>'L',
+8048=>'L',
+8049=>'L',
+8050=>'L',
+8051=>'L',
+8052=>'L',
+8053=>'L',
+8054=>'L',
+8055=>'L',
+8056=>'L',
+8057=>'L',
+8058=>'L',
+8059=>'L',
+8060=>'L',
+8061=>'L',
+8064=>'L',
+8065=>'L',
+8066=>'L',
+8067=>'L',
+8068=>'L',
+8069=>'L',
+8070=>'L',
+8071=>'L',
+8072=>'L',
+8073=>'L',
+8074=>'L',
+8075=>'L',
+8076=>'L',
+8077=>'L',
+8078=>'L',
+8079=>'L',
+8080=>'L',
+8081=>'L',
+8082=>'L',
+8083=>'L',
+8084=>'L',
+8085=>'L',
+8086=>'L',
+8087=>'L',
+8088=>'L',
+8089=>'L',
+8090=>'L',
+8091=>'L',
+8092=>'L',
+8093=>'L',
+8094=>'L',
+8095=>'L',
+8096=>'L',
+8097=>'L',
+8098=>'L',
+8099=>'L',
+8100=>'L',
+8101=>'L',
+8102=>'L',
+8103=>'L',
+8104=>'L',
+8105=>'L',
+8106=>'L',
+8107=>'L',
+8108=>'L',
+8109=>'L',
+8110=>'L',
+8111=>'L',
+8112=>'L',
+8113=>'L',
+8114=>'L',
+8115=>'L',
+8116=>'L',
+8118=>'L',
+8119=>'L',
+8120=>'L',
+8121=>'L',
+8122=>'L',
+8123=>'L',
+8124=>'L',
+8125=>'ON',
+8126=>'L',
+8127=>'ON',
+8128=>'ON',
+8129=>'ON',
+8130=>'L',
+8131=>'L',
+8132=>'L',
+8134=>'L',
+8135=>'L',
+8136=>'L',
+8137=>'L',
+8138=>'L',
+8139=>'L',
+8140=>'L',
+8141=>'ON',
+8142=>'ON',
+8143=>'ON',
+8144=>'L',
+8145=>'L',
+8146=>'L',
+8147=>'L',
+8150=>'L',
+8151=>'L',
+8152=>'L',
+8153=>'L',
+8154=>'L',
+8155=>'L',
+8157=>'ON',
+8158=>'ON',
+8159=>'ON',
+8160=>'L',
+8161=>'L',
+8162=>'L',
+8163=>'L',
+8164=>'L',
+8165=>'L',
+8166=>'L',
+8167=>'L',
+8168=>'L',
+8169=>'L',
+8170=>'L',
+8171=>'L',
+8172=>'L',
+8173=>'ON',
+8174=>'ON',
+8175=>'ON',
+8178=>'L',
+8179=>'L',
+8180=>'L',
+8182=>'L',
+8183=>'L',
+8184=>'L',
+8185=>'L',
+8186=>'L',
+8187=>'L',
+8188=>'L',
+8189=>'ON',
+8190=>'ON',
+8192=>'WS',
+8193=>'WS',
+8194=>'WS',
+8195=>'WS',
+8196=>'WS',
+8197=>'WS',
+8198=>'WS',
+8199=>'WS',
+8200=>'WS',
+8201=>'WS',
+8202=>'WS',
+8203=>'BN',
+8204=>'BN',
+8205=>'BN',
+8206=>'L',
+8207=>'R',
+8208=>'ON',
+8209=>'ON',
+8210=>'ON',
+8211=>'ON',
+8212=>'ON',
+8213=>'ON',
+8214=>'ON',
+8215=>'ON',
+8216=>'ON',
+8217=>'ON',
+8218=>'ON',
+8219=>'ON',
+8220=>'ON',
+8221=>'ON',
+8222=>'ON',
+8223=>'ON',
+8224=>'ON',
+8225=>'ON',
+8226=>'ON',
+8227=>'ON',
+8228=>'ON',
+8229=>'ON',
+8230=>'ON',
+8231=>'ON',
+8232=>'WS',
+8233=>'B',
+8234=>'LRE',
+8235=>'RLE',
+8236=>'PDF',
+8237=>'LRO',
+8238=>'RLO',
+8239=>'CS',
+8240=>'ET',
+8241=>'ET',
+8242=>'ET',
+8243=>'ET',
+8244=>'ET',
+8245=>'ON',
+8246=>'ON',
+8247=>'ON',
+8248=>'ON',
+8249=>'ON',
+8250=>'ON',
+8251=>'ON',
+8252=>'ON',
+8253=>'ON',
+8254=>'ON',
+8255=>'ON',
+8256=>'ON',
+8257=>'ON',
+8258=>'ON',
+8259=>'ON',
+8260=>'CS',
+8261=>'ON',
+8262=>'ON',
+8263=>'ON',
+8264=>'ON',
+8265=>'ON',
+8266=>'ON',
+8267=>'ON',
+8268=>'ON',
+8269=>'ON',
+8270=>'ON',
+8271=>'ON',
+8272=>'ON',
+8273=>'ON',
+8274=>'ON',
+8275=>'ON',
+8276=>'ON',
+8277=>'ON',
+8278=>'ON',
+8279=>'ON',
+8280=>'ON',
+8281=>'ON',
+8282=>'ON',
+8283=>'ON',
+8284=>'ON',
+8285=>'ON',
+8286=>'ON',
+8287=>'WS',
+8288=>'BN',
+8289=>'BN',
+8290=>'BN',
+8291=>'BN',
+8298=>'BN',
+8299=>'BN',
+8300=>'BN',
+8301=>'BN',
+8302=>'BN',
+8303=>'BN',
+8304=>'EN',
+8305=>'L',
+8308=>'EN',
+8309=>'EN',
+8310=>'EN',
+8311=>'EN',
+8312=>'EN',
+8313=>'EN',
+8314=>'ES',
+8315=>'ES',
+8316=>'ON',
+8317=>'ON',
+8318=>'ON',
+8319=>'L',
+8320=>'EN',
+8321=>'EN',
+8322=>'EN',
+8323=>'EN',
+8324=>'EN',
+8325=>'EN',
+8326=>'EN',
+8327=>'EN',
+8328=>'EN',
+8329=>'EN',
+8330=>'ES',
+8331=>'ES',
+8332=>'ON',
+8333=>'ON',
+8334=>'ON',
+8336=>'L',
+8337=>'L',
+8338=>'L',
+8339=>'L',
+8340=>'L',
+8352=>'ET',
+8353=>'ET',
+8354=>'ET',
+8355=>'ET',
+8356=>'ET',
+8357=>'ET',
+8358=>'ET',
+8359=>'ET',
+8360=>'ET',
+8361=>'ET',
+8362=>'ET',
+8363=>'ET',
+8364=>'ET',
+8365=>'ET',
+8366=>'ET',
+8367=>'ET',
+8368=>'ET',
+8369=>'ET',
+8370=>'ET',
+8371=>'ET',
+8372=>'ET',
+8373=>'ET',
+8400=>'NSM',
+8401=>'NSM',
+8402=>'NSM',
+8403=>'NSM',
+8404=>'NSM',
+8405=>'NSM',
+8406=>'NSM',
+8407=>'NSM',
+8408=>'NSM',
+8409=>'NSM',
+8410=>'NSM',
+8411=>'NSM',
+8412=>'NSM',
+8413=>'NSM',
+8414=>'NSM',
+8415=>'NSM',
+8416=>'NSM',
+8417=>'NSM',
+8418=>'NSM',
+8419=>'NSM',
+8420=>'NSM',
+8421=>'NSM',
+8422=>'NSM',
+8423=>'NSM',
+8424=>'NSM',
+8425=>'NSM',
+8426=>'NSM',
+8427=>'NSM',
+8428=>'NSM',
+8429=>'NSM',
+8430=>'NSM',
+8431=>'NSM',
+8448=>'ON',
+8449=>'ON',
+8450=>'L',
+8451=>'ON',
+8452=>'ON',
+8453=>'ON',
+8454=>'ON',
+8455=>'L',
+8456=>'ON',
+8457=>'ON',
+8458=>'L',
+8459=>'L',
+8460=>'L',
+8461=>'L',
+8462=>'L',
+8463=>'L',
+8464=>'L',
+8465=>'L',
+8466=>'L',
+8467=>'L',
+8468=>'ON',
+8469=>'L',
+8470=>'ON',
+8471=>'ON',
+8472=>'ON',
+8473=>'L',
+8474=>'L',
+8475=>'L',
+8476=>'L',
+8477=>'L',
+8478=>'ON',
+8479=>'ON',
+8480=>'ON',
+8481=>'ON',
+8482=>'ON',
+8483=>'ON',
+8484=>'L',
+8485=>'ON',
+8486=>'L',
+8487=>'ON',
+8488=>'L',
+8489=>'ON',
+8490=>'L',
+8491=>'L',
+8492=>'L',
+8493=>'L',
+8494=>'ET',
+8495=>'L',
+8496=>'L',
+8497=>'L',
+8498=>'L',
+8499=>'L',
+8500=>'L',
+8501=>'L',
+8502=>'L',
+8503=>'L',
+8504=>'L',
+8505=>'L',
+8506=>'ON',
+8507=>'ON',
+8508=>'L',
+8509=>'L',
+8510=>'L',
+8511=>'L',
+8512=>'ON',
+8513=>'ON',
+8514=>'ON',
+8515=>'ON',
+8516=>'ON',
+8517=>'L',
+8518=>'L',
+8519=>'L',
+8520=>'L',
+8521=>'L',
+8522=>'ON',
+8523=>'ON',
+8524=>'ON',
+8525=>'ON',
+8526=>'L',
+8531=>'ON',
+8532=>'ON',
+8533=>'ON',
+8534=>'ON',
+8535=>'ON',
+8536=>'ON',
+8537=>'ON',
+8538=>'ON',
+8539=>'ON',
+8540=>'ON',
+8541=>'ON',
+8542=>'ON',
+8543=>'ON',
+8544=>'L',
+8545=>'L',
+8546=>'L',
+8547=>'L',
+8548=>'L',
+8549=>'L',
+8550=>'L',
+8551=>'L',
+8552=>'L',
+8553=>'L',
+8554=>'L',
+8555=>'L',
+8556=>'L',
+8557=>'L',
+8558=>'L',
+8559=>'L',
+8560=>'L',
+8561=>'L',
+8562=>'L',
+8563=>'L',
+8564=>'L',
+8565=>'L',
+8566=>'L',
+8567=>'L',
+8568=>'L',
+8569=>'L',
+8570=>'L',
+8571=>'L',
+8572=>'L',
+8573=>'L',
+8574=>'L',
+8575=>'L',
+8576=>'L',
+8577=>'L',
+8578=>'L',
+8579=>'L',
+8580=>'L',
+8592=>'ON',
+8593=>'ON',
+8594=>'ON',
+8595=>'ON',
+8596=>'ON',
+8597=>'ON',
+8598=>'ON',
+8599=>'ON',
+8600=>'ON',
+8601=>'ON',
+8602=>'ON',
+8603=>'ON',
+8604=>'ON',
+8605=>'ON',
+8606=>'ON',
+8607=>'ON',
+8608=>'ON',
+8609=>'ON',
+8610=>'ON',
+8611=>'ON',
+8612=>'ON',
+8613=>'ON',
+8614=>'ON',
+8615=>'ON',
+8616=>'ON',
+8617=>'ON',
+8618=>'ON',
+8619=>'ON',
+8620=>'ON',
+8621=>'ON',
+8622=>'ON',
+8623=>'ON',
+8624=>'ON',
+8625=>'ON',
+8626=>'ON',
+8627=>'ON',
+8628=>'ON',
+8629=>'ON',
+8630=>'ON',
+8631=>'ON',
+8632=>'ON',
+8633=>'ON',
+8634=>'ON',
+8635=>'ON',
+8636=>'ON',
+8637=>'ON',
+8638=>'ON',
+8639=>'ON',
+8640=>'ON',
+8641=>'ON',
+8642=>'ON',
+8643=>'ON',
+8644=>'ON',
+8645=>'ON',
+8646=>'ON',
+8647=>'ON',
+8648=>'ON',
+8649=>'ON',
+8650=>'ON',
+8651=>'ON',
+8652=>'ON',
+8653=>'ON',
+8654=>'ON',
+8655=>'ON',
+8656=>'ON',
+8657=>'ON',
+8658=>'ON',
+8659=>'ON',
+8660=>'ON',
+8661=>'ON',
+8662=>'ON',
+8663=>'ON',
+8664=>'ON',
+8665=>'ON',
+8666=>'ON',
+8667=>'ON',
+8668=>'ON',
+8669=>'ON',
+8670=>'ON',
+8671=>'ON',
+8672=>'ON',
+8673=>'ON',
+8674=>'ON',
+8675=>'ON',
+8676=>'ON',
+8677=>'ON',
+8678=>'ON',
+8679=>'ON',
+8680=>'ON',
+8681=>'ON',
+8682=>'ON',
+8683=>'ON',
+8684=>'ON',
+8685=>'ON',
+8686=>'ON',
+8687=>'ON',
+8688=>'ON',
+8689=>'ON',
+8690=>'ON',
+8691=>'ON',
+8692=>'ON',
+8693=>'ON',
+8694=>'ON',
+8695=>'ON',
+8696=>'ON',
+8697=>'ON',
+8698=>'ON',
+8699=>'ON',
+8700=>'ON',
+8701=>'ON',
+8702=>'ON',
+8703=>'ON',
+8704=>'ON',
+8705=>'ON',
+8706=>'ON',
+8707=>'ON',
+8708=>'ON',
+8709=>'ON',
+8710=>'ON',
+8711=>'ON',
+8712=>'ON',
+8713=>'ON',
+8714=>'ON',
+8715=>'ON',
+8716=>'ON',
+8717=>'ON',
+8718=>'ON',
+8719=>'ON',
+8720=>'ON',
+8721=>'ON',
+8722=>'ES',
+8723=>'ET',
+8724=>'ON',
+8725=>'ON',
+8726=>'ON',
+8727=>'ON',
+8728=>'ON',
+8729=>'ON',
+8730=>'ON',
+8731=>'ON',
+8732=>'ON',
+8733=>'ON',
+8734=>'ON',
+8735=>'ON',
+8736=>'ON',
+8737=>'ON',
+8738=>'ON',
+8739=>'ON',
+8740=>'ON',
+8741=>'ON',
+8742=>'ON',
+8743=>'ON',
+8744=>'ON',
+8745=>'ON',
+8746=>'ON',
+8747=>'ON',
+8748=>'ON',
+8749=>'ON',
+8750=>'ON',
+8751=>'ON',
+8752=>'ON',
+8753=>'ON',
+8754=>'ON',
+8755=>'ON',
+8756=>'ON',
+8757=>'ON',
+8758=>'ON',
+8759=>'ON',
+8760=>'ON',
+8761=>'ON',
+8762=>'ON',
+8763=>'ON',
+8764=>'ON',
+8765=>'ON',
+8766=>'ON',
+8767=>'ON',
+8768=>'ON',
+8769=>'ON',
+8770=>'ON',
+8771=>'ON',
+8772=>'ON',
+8773=>'ON',
+8774=>'ON',
+8775=>'ON',
+8776=>'ON',
+8777=>'ON',
+8778=>'ON',
+8779=>'ON',
+8780=>'ON',
+8781=>'ON',
+8782=>'ON',
+8783=>'ON',
+8784=>'ON',
+8785=>'ON',
+8786=>'ON',
+8787=>'ON',
+8788=>'ON',
+8789=>'ON',
+8790=>'ON',
+8791=>'ON',
+8792=>'ON',
+8793=>'ON',
+8794=>'ON',
+8795=>'ON',
+8796=>'ON',
+8797=>'ON',
+8798=>'ON',
+8799=>'ON',
+8800=>'ON',
+8801=>'ON',
+8802=>'ON',
+8803=>'ON',
+8804=>'ON',
+8805=>'ON',
+8806=>'ON',
+8807=>'ON',
+8808=>'ON',
+8809=>'ON',
+8810=>'ON',
+8811=>'ON',
+8812=>'ON',
+8813=>'ON',
+8814=>'ON',
+8815=>'ON',
+8816=>'ON',
+8817=>'ON',
+8818=>'ON',
+8819=>'ON',
+8820=>'ON',
+8821=>'ON',
+8822=>'ON',
+8823=>'ON',
+8824=>'ON',
+8825=>'ON',
+8826=>'ON',
+8827=>'ON',
+8828=>'ON',
+8829=>'ON',
+8830=>'ON',
+8831=>'ON',
+8832=>'ON',
+8833=>'ON',
+8834=>'ON',
+8835=>'ON',
+8836=>'ON',
+8837=>'ON',
+8838=>'ON',
+8839=>'ON',
+8840=>'ON',
+8841=>'ON',
+8842=>'ON',
+8843=>'ON',
+8844=>'ON',
+8845=>'ON',
+8846=>'ON',
+8847=>'ON',
+8848=>'ON',
+8849=>'ON',
+8850=>'ON',
+8851=>'ON',
+8852=>'ON',
+8853=>'ON',
+8854=>'ON',
+8855=>'ON',
+8856=>'ON',
+8857=>'ON',
+8858=>'ON',
+8859=>'ON',
+8860=>'ON',
+8861=>'ON',
+8862=>'ON',
+8863=>'ON',
+8864=>'ON',
+8865=>'ON',
+8866=>'ON',
+8867=>'ON',
+8868=>'ON',
+8869=>'ON',
+8870=>'ON',
+8871=>'ON',
+8872=>'ON',
+8873=>'ON',
+8874=>'ON',
+8875=>'ON',
+8876=>'ON',
+8877=>'ON',
+8878=>'ON',
+8879=>'ON',
+8880=>'ON',
+8881=>'ON',
+8882=>'ON',
+8883=>'ON',
+8884=>'ON',
+8885=>'ON',
+8886=>'ON',
+8887=>'ON',
+8888=>'ON',
+8889=>'ON',
+8890=>'ON',
+8891=>'ON',
+8892=>'ON',
+8893=>'ON',
+8894=>'ON',
+8895=>'ON',
+8896=>'ON',
+8897=>'ON',
+8898=>'ON',
+8899=>'ON',
+8900=>'ON',
+8901=>'ON',
+8902=>'ON',
+8903=>'ON',
+8904=>'ON',
+8905=>'ON',
+8906=>'ON',
+8907=>'ON',
+8908=>'ON',
+8909=>'ON',
+8910=>'ON',
+8911=>'ON',
+8912=>'ON',
+8913=>'ON',
+8914=>'ON',
+8915=>'ON',
+8916=>'ON',
+8917=>'ON',
+8918=>'ON',
+8919=>'ON',
+8920=>'ON',
+8921=>'ON',
+8922=>'ON',
+8923=>'ON',
+8924=>'ON',
+8925=>'ON',
+8926=>'ON',
+8927=>'ON',
+8928=>'ON',
+8929=>'ON',
+8930=>'ON',
+8931=>'ON',
+8932=>'ON',
+8933=>'ON',
+8934=>'ON',
+8935=>'ON',
+8936=>'ON',
+8937=>'ON',
+8938=>'ON',
+8939=>'ON',
+8940=>'ON',
+8941=>'ON',
+8942=>'ON',
+8943=>'ON',
+8944=>'ON',
+8945=>'ON',
+8946=>'ON',
+8947=>'ON',
+8948=>'ON',
+8949=>'ON',
+8950=>'ON',
+8951=>'ON',
+8952=>'ON',
+8953=>'ON',
+8954=>'ON',
+8955=>'ON',
+8956=>'ON',
+8957=>'ON',
+8958=>'ON',
+8959=>'ON',
+8960=>'ON',
+8961=>'ON',
+8962=>'ON',
+8963=>'ON',
+8964=>'ON',
+8965=>'ON',
+8966=>'ON',
+8967=>'ON',
+8968=>'ON',
+8969=>'ON',
+8970=>'ON',
+8971=>'ON',
+8972=>'ON',
+8973=>'ON',
+8974=>'ON',
+8975=>'ON',
+8976=>'ON',
+8977=>'ON',
+8978=>'ON',
+8979=>'ON',
+8980=>'ON',
+8981=>'ON',
+8982=>'ON',
+8983=>'ON',
+8984=>'ON',
+8985=>'ON',
+8986=>'ON',
+8987=>'ON',
+8988=>'ON',
+8989=>'ON',
+8990=>'ON',
+8991=>'ON',
+8992=>'ON',
+8993=>'ON',
+8994=>'ON',
+8995=>'ON',
+8996=>'ON',
+8997=>'ON',
+8998=>'ON',
+8999=>'ON',
+9000=>'ON',
+9001=>'ON',
+9002=>'ON',
+9003=>'ON',
+9004=>'ON',
+9005=>'ON',
+9006=>'ON',
+9007=>'ON',
+9008=>'ON',
+9009=>'ON',
+9010=>'ON',
+9011=>'ON',
+9012=>'ON',
+9013=>'ON',
+9014=>'L',
+9015=>'L',
+9016=>'L',
+9017=>'L',
+9018=>'L',
+9019=>'L',
+9020=>'L',
+9021=>'L',
+9022=>'L',
+9023=>'L',
+9024=>'L',
+9025=>'L',
+9026=>'L',
+9027=>'L',
+9028=>'L',
+9029=>'L',
+9030=>'L',
+9031=>'L',
+9032=>'L',
+9033=>'L',
+9034=>'L',
+9035=>'L',
+9036=>'L',
+9037=>'L',
+9038=>'L',
+9039=>'L',
+9040=>'L',
+9041=>'L',
+9042=>'L',
+9043=>'L',
+9044=>'L',
+9045=>'L',
+9046=>'L',
+9047=>'L',
+9048=>'L',
+9049=>'L',
+9050=>'L',
+9051=>'L',
+9052=>'L',
+9053=>'L',
+9054=>'L',
+9055=>'L',
+9056=>'L',
+9057=>'L',
+9058=>'L',
+9059=>'L',
+9060=>'L',
+9061=>'L',
+9062=>'L',
+9063=>'L',
+9064=>'L',
+9065=>'L',
+9066=>'L',
+9067=>'L',
+9068=>'L',
+9069=>'L',
+9070=>'L',
+9071=>'L',
+9072=>'L',
+9073=>'L',
+9074=>'L',
+9075=>'L',
+9076=>'L',
+9077=>'L',
+9078=>'L',
+9079=>'L',
+9080=>'L',
+9081=>'L',
+9082=>'L',
+9083=>'ON',
+9084=>'ON',
+9085=>'ON',
+9086=>'ON',
+9087=>'ON',
+9088=>'ON',
+9089=>'ON',
+9090=>'ON',
+9091=>'ON',
+9092=>'ON',
+9093=>'ON',
+9094=>'ON',
+9095=>'ON',
+9096=>'ON',
+9097=>'ON',
+9098=>'ON',
+9099=>'ON',
+9100=>'ON',
+9101=>'ON',
+9102=>'ON',
+9103=>'ON',
+9104=>'ON',
+9105=>'ON',
+9106=>'ON',
+9107=>'ON',
+9108=>'ON',
+9109=>'L',
+9110=>'ON',
+9111=>'ON',
+9112=>'ON',
+9113=>'ON',
+9114=>'ON',
+9115=>'ON',
+9116=>'ON',
+9117=>'ON',
+9118=>'ON',
+9119=>'ON',
+9120=>'ON',
+9121=>'ON',
+9122=>'ON',
+9123=>'ON',
+9124=>'ON',
+9125=>'ON',
+9126=>'ON',
+9127=>'ON',
+9128=>'ON',
+9129=>'ON',
+9130=>'ON',
+9131=>'ON',
+9132=>'ON',
+9133=>'ON',
+9134=>'ON',
+9135=>'ON',
+9136=>'ON',
+9137=>'ON',
+9138=>'ON',
+9139=>'ON',
+9140=>'ON',
+9141=>'ON',
+9142=>'ON',
+9143=>'ON',
+9144=>'ON',
+9145=>'ON',
+9146=>'ON',
+9147=>'ON',
+9148=>'ON',
+9149=>'ON',
+9150=>'ON',
+9151=>'ON',
+9152=>'ON',
+9153=>'ON',
+9154=>'ON',
+9155=>'ON',
+9156=>'ON',
+9157=>'ON',
+9158=>'ON',
+9159=>'ON',
+9160=>'ON',
+9161=>'ON',
+9162=>'ON',
+9163=>'ON',
+9164=>'ON',
+9165=>'ON',
+9166=>'ON',
+9167=>'ON',
+9168=>'ON',
+9169=>'ON',
+9170=>'ON',
+9171=>'ON',
+9172=>'ON',
+9173=>'ON',
+9174=>'ON',
+9175=>'ON',
+9176=>'ON',
+9177=>'ON',
+9178=>'ON',
+9179=>'ON',
+9180=>'ON',
+9181=>'ON',
+9182=>'ON',
+9183=>'ON',
+9184=>'ON',
+9185=>'ON',
+9186=>'ON',
+9187=>'ON',
+9188=>'ON',
+9189=>'ON',
+9190=>'ON',
+9191=>'ON',
+9216=>'ON',
+9217=>'ON',
+9218=>'ON',
+9219=>'ON',
+9220=>'ON',
+9221=>'ON',
+9222=>'ON',
+9223=>'ON',
+9224=>'ON',
+9225=>'ON',
+9226=>'ON',
+9227=>'ON',
+9228=>'ON',
+9229=>'ON',
+9230=>'ON',
+9231=>'ON',
+9232=>'ON',
+9233=>'ON',
+9234=>'ON',
+9235=>'ON',
+9236=>'ON',
+9237=>'ON',
+9238=>'ON',
+9239=>'ON',
+9240=>'ON',
+9241=>'ON',
+9242=>'ON',
+9243=>'ON',
+9244=>'ON',
+9245=>'ON',
+9246=>'ON',
+9247=>'ON',
+9248=>'ON',
+9249=>'ON',
+9250=>'ON',
+9251=>'ON',
+9252=>'ON',
+9253=>'ON',
+9254=>'ON',
+9280=>'ON',
+9281=>'ON',
+9282=>'ON',
+9283=>'ON',
+9284=>'ON',
+9285=>'ON',
+9286=>'ON',
+9287=>'ON',
+9288=>'ON',
+9289=>'ON',
+9290=>'ON',
+9312=>'ON',
+9313=>'ON',
+9314=>'ON',
+9315=>'ON',
+9316=>'ON',
+9317=>'ON',
+9318=>'ON',
+9319=>'ON',
+9320=>'ON',
+9321=>'ON',
+9322=>'ON',
+9323=>'ON',
+9324=>'ON',
+9325=>'ON',
+9326=>'ON',
+9327=>'ON',
+9328=>'ON',
+9329=>'ON',
+9330=>'ON',
+9331=>'ON',
+9332=>'ON',
+9333=>'ON',
+9334=>'ON',
+9335=>'ON',
+9336=>'ON',
+9337=>'ON',
+9338=>'ON',
+9339=>'ON',
+9340=>'ON',
+9341=>'ON',
+9342=>'ON',
+9343=>'ON',
+9344=>'ON',
+9345=>'ON',
+9346=>'ON',
+9347=>'ON',
+9348=>'ON',
+9349=>'ON',
+9350=>'ON',
+9351=>'ON',
+9352=>'EN',
+9353=>'EN',
+9354=>'EN',
+9355=>'EN',
+9356=>'EN',
+9357=>'EN',
+9358=>'EN',
+9359=>'EN',
+9360=>'EN',
+9361=>'EN',
+9362=>'EN',
+9363=>'EN',
+9364=>'EN',
+9365=>'EN',
+9366=>'EN',
+9367=>'EN',
+9368=>'EN',
+9369=>'EN',
+9370=>'EN',
+9371=>'EN',
+9372=>'L',
+9373=>'L',
+9374=>'L',
+9375=>'L',
+9376=>'L',
+9377=>'L',
+9378=>'L',
+9379=>'L',
+9380=>'L',
+9381=>'L',
+9382=>'L',
+9383=>'L',
+9384=>'L',
+9385=>'L',
+9386=>'L',
+9387=>'L',
+9388=>'L',
+9389=>'L',
+9390=>'L',
+9391=>'L',
+9392=>'L',
+9393=>'L',
+9394=>'L',
+9395=>'L',
+9396=>'L',
+9397=>'L',
+9398=>'L',
+9399=>'L',
+9400=>'L',
+9401=>'L',
+9402=>'L',
+9403=>'L',
+9404=>'L',
+9405=>'L',
+9406=>'L',
+9407=>'L',
+9408=>'L',
+9409=>'L',
+9410=>'L',
+9411=>'L',
+9412=>'L',
+9413=>'L',
+9414=>'L',
+9415=>'L',
+9416=>'L',
+9417=>'L',
+9418=>'L',
+9419=>'L',
+9420=>'L',
+9421=>'L',
+9422=>'L',
+9423=>'L',
+9424=>'L',
+9425=>'L',
+9426=>'L',
+9427=>'L',
+9428=>'L',
+9429=>'L',
+9430=>'L',
+9431=>'L',
+9432=>'L',
+9433=>'L',
+9434=>'L',
+9435=>'L',
+9436=>'L',
+9437=>'L',
+9438=>'L',
+9439=>'L',
+9440=>'L',
+9441=>'L',
+9442=>'L',
+9443=>'L',
+9444=>'L',
+9445=>'L',
+9446=>'L',
+9447=>'L',
+9448=>'L',
+9449=>'L',
+9450=>'ON',
+9451=>'ON',
+9452=>'ON',
+9453=>'ON',
+9454=>'ON',
+9455=>'ON',
+9456=>'ON',
+9457=>'ON',
+9458=>'ON',
+9459=>'ON',
+9460=>'ON',
+9461=>'ON',
+9462=>'ON',
+9463=>'ON',
+9464=>'ON',
+9465=>'ON',
+9466=>'ON',
+9467=>'ON',
+9468=>'ON',
+9469=>'ON',
+9470=>'ON',
+9471=>'ON',
+9472=>'ON',
+9473=>'ON',
+9474=>'ON',
+9475=>'ON',
+9476=>'ON',
+9477=>'ON',
+9478=>'ON',
+9479=>'ON',
+9480=>'ON',
+9481=>'ON',
+9482=>'ON',
+9483=>'ON',
+9484=>'ON',
+9485=>'ON',
+9486=>'ON',
+9487=>'ON',
+9488=>'ON',
+9489=>'ON',
+9490=>'ON',
+9491=>'ON',
+9492=>'ON',
+9493=>'ON',
+9494=>'ON',
+9495=>'ON',
+9496=>'ON',
+9497=>'ON',
+9498=>'ON',
+9499=>'ON',
+9500=>'ON',
+9501=>'ON',
+9502=>'ON',
+9503=>'ON',
+9504=>'ON',
+9505=>'ON',
+9506=>'ON',
+9507=>'ON',
+9508=>'ON',
+9509=>'ON',
+9510=>'ON',
+9511=>'ON',
+9512=>'ON',
+9513=>'ON',
+9514=>'ON',
+9515=>'ON',
+9516=>'ON',
+9517=>'ON',
+9518=>'ON',
+9519=>'ON',
+9520=>'ON',
+9521=>'ON',
+9522=>'ON',
+9523=>'ON',
+9524=>'ON',
+9525=>'ON',
+9526=>'ON',
+9527=>'ON',
+9528=>'ON',
+9529=>'ON',
+9530=>'ON',
+9531=>'ON',
+9532=>'ON',
+9533=>'ON',
+9534=>'ON',
+9535=>'ON',
+9536=>'ON',
+9537=>'ON',
+9538=>'ON',
+9539=>'ON',
+9540=>'ON',
+9541=>'ON',
+9542=>'ON',
+9543=>'ON',
+9544=>'ON',
+9545=>'ON',
+9546=>'ON',
+9547=>'ON',
+9548=>'ON',
+9549=>'ON',
+9550=>'ON',
+9551=>'ON',
+9552=>'ON',
+9553=>'ON',
+9554=>'ON',
+9555=>'ON',
+9556=>'ON',
+9557=>'ON',
+9558=>'ON',
+9559=>'ON',
+9560=>'ON',
+9561=>'ON',
+9562=>'ON',
+9563=>'ON',
+9564=>'ON',
+9565=>'ON',
+9566=>'ON',
+9567=>'ON',
+9568=>'ON',
+9569=>'ON',
+9570=>'ON',
+9571=>'ON',
+9572=>'ON',
+9573=>'ON',
+9574=>'ON',
+9575=>'ON',
+9576=>'ON',
+9577=>'ON',
+9578=>'ON',
+9579=>'ON',
+9580=>'ON',
+9581=>'ON',
+9582=>'ON',
+9583=>'ON',
+9584=>'ON',
+9585=>'ON',
+9586=>'ON',
+9587=>'ON',
+9588=>'ON',
+9589=>'ON',
+9590=>'ON',
+9591=>'ON',
+9592=>'ON',
+9593=>'ON',
+9594=>'ON',
+9595=>'ON',
+9596=>'ON',
+9597=>'ON',
+9598=>'ON',
+9599=>'ON',
+9600=>'ON',
+9601=>'ON',
+9602=>'ON',
+9603=>'ON',
+9604=>'ON',
+9605=>'ON',
+9606=>'ON',
+9607=>'ON',
+9608=>'ON',
+9609=>'ON',
+9610=>'ON',
+9611=>'ON',
+9612=>'ON',
+9613=>'ON',
+9614=>'ON',
+9615=>'ON',
+9616=>'ON',
+9617=>'ON',
+9618=>'ON',
+9619=>'ON',
+9620=>'ON',
+9621=>'ON',
+9622=>'ON',
+9623=>'ON',
+9624=>'ON',
+9625=>'ON',
+9626=>'ON',
+9627=>'ON',
+9628=>'ON',
+9629=>'ON',
+9630=>'ON',
+9631=>'ON',
+9632=>'ON',
+9633=>'ON',
+9634=>'ON',
+9635=>'ON',
+9636=>'ON',
+9637=>'ON',
+9638=>'ON',
+9639=>'ON',
+9640=>'ON',
+9641=>'ON',
+9642=>'ON',
+9643=>'ON',
+9644=>'ON',
+9645=>'ON',
+9646=>'ON',
+9647=>'ON',
+9648=>'ON',
+9649=>'ON',
+9650=>'ON',
+9651=>'ON',
+9652=>'ON',
+9653=>'ON',
+9654=>'ON',
+9655=>'ON',
+9656=>'ON',
+9657=>'ON',
+9658=>'ON',
+9659=>'ON',
+9660=>'ON',
+9661=>'ON',
+9662=>'ON',
+9663=>'ON',
+9664=>'ON',
+9665=>'ON',
+9666=>'ON',
+9667=>'ON',
+9668=>'ON',
+9669=>'ON',
+9670=>'ON',
+9671=>'ON',
+9672=>'ON',
+9673=>'ON',
+9674=>'ON',
+9675=>'ON',
+9676=>'ON',
+9677=>'ON',
+9678=>'ON',
+9679=>'ON',
+9680=>'ON',
+9681=>'ON',
+9682=>'ON',
+9683=>'ON',
+9684=>'ON',
+9685=>'ON',
+9686=>'ON',
+9687=>'ON',
+9688=>'ON',
+9689=>'ON',
+9690=>'ON',
+9691=>'ON',
+9692=>'ON',
+9693=>'ON',
+9694=>'ON',
+9695=>'ON',
+9696=>'ON',
+9697=>'ON',
+9698=>'ON',
+9699=>'ON',
+9700=>'ON',
+9701=>'ON',
+9702=>'ON',
+9703=>'ON',
+9704=>'ON',
+9705=>'ON',
+9706=>'ON',
+9707=>'ON',
+9708=>'ON',
+9709=>'ON',
+9710=>'ON',
+9711=>'ON',
+9712=>'ON',
+9713=>'ON',
+9714=>'ON',
+9715=>'ON',
+9716=>'ON',
+9717=>'ON',
+9718=>'ON',
+9719=>'ON',
+9720=>'ON',
+9721=>'ON',
+9722=>'ON',
+9723=>'ON',
+9724=>'ON',
+9725=>'ON',
+9726=>'ON',
+9727=>'ON',
+9728=>'ON',
+9729=>'ON',
+9730=>'ON',
+9731=>'ON',
+9732=>'ON',
+9733=>'ON',
+9734=>'ON',
+9735=>'ON',
+9736=>'ON',
+9737=>'ON',
+9738=>'ON',
+9739=>'ON',
+9740=>'ON',
+9741=>'ON',
+9742=>'ON',
+9743=>'ON',
+9744=>'ON',
+9745=>'ON',
+9746=>'ON',
+9747=>'ON',
+9748=>'ON',
+9749=>'ON',
+9750=>'ON',
+9751=>'ON',
+9752=>'ON',
+9753=>'ON',
+9754=>'ON',
+9755=>'ON',
+9756=>'ON',
+9757=>'ON',
+9758=>'ON',
+9759=>'ON',
+9760=>'ON',
+9761=>'ON',
+9762=>'ON',
+9763=>'ON',
+9764=>'ON',
+9765=>'ON',
+9766=>'ON',
+9767=>'ON',
+9768=>'ON',
+9769=>'ON',
+9770=>'ON',
+9771=>'ON',
+9772=>'ON',
+9773=>'ON',
+9774=>'ON',
+9775=>'ON',
+9776=>'ON',
+9777=>'ON',
+9778=>'ON',
+9779=>'ON',
+9780=>'ON',
+9781=>'ON',
+9782=>'ON',
+9783=>'ON',
+9784=>'ON',
+9785=>'ON',
+9786=>'ON',
+9787=>'ON',
+9788=>'ON',
+9789=>'ON',
+9790=>'ON',
+9791=>'ON',
+9792=>'ON',
+9793=>'ON',
+9794=>'ON',
+9795=>'ON',
+9796=>'ON',
+9797=>'ON',
+9798=>'ON',
+9799=>'ON',
+9800=>'ON',
+9801=>'ON',
+9802=>'ON',
+9803=>'ON',
+9804=>'ON',
+9805=>'ON',
+9806=>'ON',
+9807=>'ON',
+9808=>'ON',
+9809=>'ON',
+9810=>'ON',
+9811=>'ON',
+9812=>'ON',
+9813=>'ON',
+9814=>'ON',
+9815=>'ON',
+9816=>'ON',
+9817=>'ON',
+9818=>'ON',
+9819=>'ON',
+9820=>'ON',
+9821=>'ON',
+9822=>'ON',
+9823=>'ON',
+9824=>'ON',
+9825=>'ON',
+9826=>'ON',
+9827=>'ON',
+9828=>'ON',
+9829=>'ON',
+9830=>'ON',
+9831=>'ON',
+9832=>'ON',
+9833=>'ON',
+9834=>'ON',
+9835=>'ON',
+9836=>'ON',
+9837=>'ON',
+9838=>'ON',
+9839=>'ON',
+9840=>'ON',
+9841=>'ON',
+9842=>'ON',
+9843=>'ON',
+9844=>'ON',
+9845=>'ON',
+9846=>'ON',
+9847=>'ON',
+9848=>'ON',
+9849=>'ON',
+9850=>'ON',
+9851=>'ON',
+9852=>'ON',
+9853=>'ON',
+9854=>'ON',
+9855=>'ON',
+9856=>'ON',
+9857=>'ON',
+9858=>'ON',
+9859=>'ON',
+9860=>'ON',
+9861=>'ON',
+9862=>'ON',
+9863=>'ON',
+9864=>'ON',
+9865=>'ON',
+9866=>'ON',
+9867=>'ON',
+9868=>'ON',
+9869=>'ON',
+9870=>'ON',
+9871=>'ON',
+9872=>'ON',
+9873=>'ON',
+9874=>'ON',
+9875=>'ON',
+9876=>'ON',
+9877=>'ON',
+9878=>'ON',
+9879=>'ON',
+9880=>'ON',
+9881=>'ON',
+9882=>'ON',
+9883=>'ON',
+9884=>'ON',
+9888=>'ON',
+9889=>'ON',
+9890=>'ON',
+9891=>'ON',
+9892=>'ON',
+9893=>'ON',
+9894=>'ON',
+9895=>'ON',
+9896=>'ON',
+9897=>'ON',
+9898=>'ON',
+9899=>'ON',
+9900=>'L',
+9901=>'ON',
+9902=>'ON',
+9903=>'ON',
+9904=>'ON',
+9905=>'ON',
+9906=>'ON',
+9985=>'ON',
+9986=>'ON',
+9987=>'ON',
+9988=>'ON',
+9990=>'ON',
+9991=>'ON',
+9992=>'ON',
+9993=>'ON',
+9996=>'ON',
+9997=>'ON',
+9998=>'ON',
+9999=>'ON',
+10000=>'ON',
+10001=>'ON',
+10002=>'ON',
+10003=>'ON',
+10004=>'ON',
+10005=>'ON',
+10006=>'ON',
+10007=>'ON',
+10008=>'ON',
+10009=>'ON',
+10010=>'ON',
+10011=>'ON',
+10012=>'ON',
+10013=>'ON',
+10014=>'ON',
+10015=>'ON',
+10016=>'ON',
+10017=>'ON',
+10018=>'ON',
+10019=>'ON',
+10020=>'ON',
+10021=>'ON',
+10022=>'ON',
+10023=>'ON',
+10025=>'ON',
+10026=>'ON',
+10027=>'ON',
+10028=>'ON',
+10029=>'ON',
+10030=>'ON',
+10031=>'ON',
+10032=>'ON',
+10033=>'ON',
+10034=>'ON',
+10035=>'ON',
+10036=>'ON',
+10037=>'ON',
+10038=>'ON',
+10039=>'ON',
+10040=>'ON',
+10041=>'ON',
+10042=>'ON',
+10043=>'ON',
+10044=>'ON',
+10045=>'ON',
+10046=>'ON',
+10047=>'ON',
+10048=>'ON',
+10049=>'ON',
+10050=>'ON',
+10051=>'ON',
+10052=>'ON',
+10053=>'ON',
+10054=>'ON',
+10055=>'ON',
+10056=>'ON',
+10057=>'ON',
+10058=>'ON',
+10059=>'ON',
+10061=>'ON',
+10063=>'ON',
+10064=>'ON',
+10065=>'ON',
+10066=>'ON',
+10070=>'ON',
+10072=>'ON',
+10073=>'ON',
+10074=>'ON',
+10075=>'ON',
+10076=>'ON',
+10077=>'ON',
+10078=>'ON',
+10081=>'ON',
+10082=>'ON',
+10083=>'ON',
+10084=>'ON',
+10085=>'ON',
+10086=>'ON',
+10087=>'ON',
+10088=>'ON',
+10089=>'ON',
+10090=>'ON',
+10091=>'ON',
+10092=>'ON',
+10093=>'ON',
+10094=>'ON',
+10095=>'ON',
+10096=>'ON',
+10097=>'ON',
+10098=>'ON',
+10099=>'ON',
+10100=>'ON',
+10101=>'ON',
+10102=>'ON',
+10103=>'ON',
+10104=>'ON',
+10105=>'ON',
+10106=>'ON',
+10107=>'ON',
+10108=>'ON',
+10109=>'ON',
+10110=>'ON',
+10111=>'ON',
+10112=>'ON',
+10113=>'ON',
+10114=>'ON',
+10115=>'ON',
+10116=>'ON',
+10117=>'ON',
+10118=>'ON',
+10119=>'ON',
+10120=>'ON',
+10121=>'ON',
+10122=>'ON',
+10123=>'ON',
+10124=>'ON',
+10125=>'ON',
+10126=>'ON',
+10127=>'ON',
+10128=>'ON',
+10129=>'ON',
+10130=>'ON',
+10131=>'ON',
+10132=>'ON',
+10136=>'ON',
+10137=>'ON',
+10138=>'ON',
+10139=>'ON',
+10140=>'ON',
+10141=>'ON',
+10142=>'ON',
+10143=>'ON',
+10144=>'ON',
+10145=>'ON',
+10146=>'ON',
+10147=>'ON',
+10148=>'ON',
+10149=>'ON',
+10150=>'ON',
+10151=>'ON',
+10152=>'ON',
+10153=>'ON',
+10154=>'ON',
+10155=>'ON',
+10156=>'ON',
+10157=>'ON',
+10158=>'ON',
+10159=>'ON',
+10161=>'ON',
+10162=>'ON',
+10163=>'ON',
+10164=>'ON',
+10165=>'ON',
+10166=>'ON',
+10167=>'ON',
+10168=>'ON',
+10169=>'ON',
+10170=>'ON',
+10171=>'ON',
+10172=>'ON',
+10173=>'ON',
+10174=>'ON',
+10176=>'ON',
+10177=>'ON',
+10178=>'ON',
+10179=>'ON',
+10180=>'ON',
+10181=>'ON',
+10182=>'ON',
+10183=>'ON',
+10184=>'ON',
+10185=>'ON',
+10186=>'ON',
+10192=>'ON',
+10193=>'ON',
+10194=>'ON',
+10195=>'ON',
+10196=>'ON',
+10197=>'ON',
+10198=>'ON',
+10199=>'ON',
+10200=>'ON',
+10201=>'ON',
+10202=>'ON',
+10203=>'ON',
+10204=>'ON',
+10205=>'ON',
+10206=>'ON',
+10207=>'ON',
+10208=>'ON',
+10209=>'ON',
+10210=>'ON',
+10211=>'ON',
+10212=>'ON',
+10213=>'ON',
+10214=>'ON',
+10215=>'ON',
+10216=>'ON',
+10217=>'ON',
+10218=>'ON',
+10219=>'ON',
+10224=>'ON',
+10225=>'ON',
+10226=>'ON',
+10227=>'ON',
+10228=>'ON',
+10229=>'ON',
+10230=>'ON',
+10231=>'ON',
+10232=>'ON',
+10233=>'ON',
+10234=>'ON',
+10235=>'ON',
+10236=>'ON',
+10237=>'ON',
+10238=>'ON',
+10239=>'ON',
+10240=>'L',
+10241=>'L',
+10242=>'L',
+10243=>'L',
+10244=>'L',
+10245=>'L',
+10246=>'L',
+10247=>'L',
+10248=>'L',
+10249=>'L',
+10250=>'L',
+10251=>'L',
+10252=>'L',
+10253=>'L',
+10254=>'L',
+10255=>'L',
+10256=>'L',
+10257=>'L',
+10258=>'L',
+10259=>'L',
+10260=>'L',
+10261=>'L',
+10262=>'L',
+10263=>'L',
+10264=>'L',
+10265=>'L',
+10266=>'L',
+10267=>'L',
+10268=>'L',
+10269=>'L',
+10270=>'L',
+10271=>'L',
+10272=>'L',
+10273=>'L',
+10274=>'L',
+10275=>'L',
+10276=>'L',
+10277=>'L',
+10278=>'L',
+10279=>'L',
+10280=>'L',
+10281=>'L',
+10282=>'L',
+10283=>'L',
+10284=>'L',
+10285=>'L',
+10286=>'L',
+10287=>'L',
+10288=>'L',
+10289=>'L',
+10290=>'L',
+10291=>'L',
+10292=>'L',
+10293=>'L',
+10294=>'L',
+10295=>'L',
+10296=>'L',
+10297=>'L',
+10298=>'L',
+10299=>'L',
+10300=>'L',
+10301=>'L',
+10302=>'L',
+10303=>'L',
+10304=>'L',
+10305=>'L',
+10306=>'L',
+10307=>'L',
+10308=>'L',
+10309=>'L',
+10310=>'L',
+10311=>'L',
+10312=>'L',
+10313=>'L',
+10314=>'L',
+10315=>'L',
+10316=>'L',
+10317=>'L',
+10318=>'L',
+10319=>'L',
+10320=>'L',
+10321=>'L',
+10322=>'L',
+10323=>'L',
+10324=>'L',
+10325=>'L',
+10326=>'L',
+10327=>'L',
+10328=>'L',
+10329=>'L',
+10330=>'L',
+10331=>'L',
+10332=>'L',
+10333=>'L',
+10334=>'L',
+10335=>'L',
+10336=>'L',
+10337=>'L',
+10338=>'L',
+10339=>'L',
+10340=>'L',
+10341=>'L',
+10342=>'L',
+10343=>'L',
+10344=>'L',
+10345=>'L',
+10346=>'L',
+10347=>'L',
+10348=>'L',
+10349=>'L',
+10350=>'L',
+10351=>'L',
+10352=>'L',
+10353=>'L',
+10354=>'L',
+10355=>'L',
+10356=>'L',
+10357=>'L',
+10358=>'L',
+10359=>'L',
+10360=>'L',
+10361=>'L',
+10362=>'L',
+10363=>'L',
+10364=>'L',
+10365=>'L',
+10366=>'L',
+10367=>'L',
+10368=>'L',
+10369=>'L',
+10370=>'L',
+10371=>'L',
+10372=>'L',
+10373=>'L',
+10374=>'L',
+10375=>'L',
+10376=>'L',
+10377=>'L',
+10378=>'L',
+10379=>'L',
+10380=>'L',
+10381=>'L',
+10382=>'L',
+10383=>'L',
+10384=>'L',
+10385=>'L',
+10386=>'L',
+10387=>'L',
+10388=>'L',
+10389=>'L',
+10390=>'L',
+10391=>'L',
+10392=>'L',
+10393=>'L',
+10394=>'L',
+10395=>'L',
+10396=>'L',
+10397=>'L',
+10398=>'L',
+10399=>'L',
+10400=>'L',
+10401=>'L',
+10402=>'L',
+10403=>'L',
+10404=>'L',
+10405=>'L',
+10406=>'L',
+10407=>'L',
+10408=>'L',
+10409=>'L',
+10410=>'L',
+10411=>'L',
+10412=>'L',
+10413=>'L',
+10414=>'L',
+10415=>'L',
+10416=>'L',
+10417=>'L',
+10418=>'L',
+10419=>'L',
+10420=>'L',
+10421=>'L',
+10422=>'L',
+10423=>'L',
+10424=>'L',
+10425=>'L',
+10426=>'L',
+10427=>'L',
+10428=>'L',
+10429=>'L',
+10430=>'L',
+10431=>'L',
+10432=>'L',
+10433=>'L',
+10434=>'L',
+10435=>'L',
+10436=>'L',
+10437=>'L',
+10438=>'L',
+10439=>'L',
+10440=>'L',
+10441=>'L',
+10442=>'L',
+10443=>'L',
+10444=>'L',
+10445=>'L',
+10446=>'L',
+10447=>'L',
+10448=>'L',
+10449=>'L',
+10450=>'L',
+10451=>'L',
+10452=>'L',
+10453=>'L',
+10454=>'L',
+10455=>'L',
+10456=>'L',
+10457=>'L',
+10458=>'L',
+10459=>'L',
+10460=>'L',
+10461=>'L',
+10462=>'L',
+10463=>'L',
+10464=>'L',
+10465=>'L',
+10466=>'L',
+10467=>'L',
+10468=>'L',
+10469=>'L',
+10470=>'L',
+10471=>'L',
+10472=>'L',
+10473=>'L',
+10474=>'L',
+10475=>'L',
+10476=>'L',
+10477=>'L',
+10478=>'L',
+10479=>'L',
+10480=>'L',
+10481=>'L',
+10482=>'L',
+10483=>'L',
+10484=>'L',
+10485=>'L',
+10486=>'L',
+10487=>'L',
+10488=>'L',
+10489=>'L',
+10490=>'L',
+10491=>'L',
+10492=>'L',
+10493=>'L',
+10494=>'L',
+10495=>'L',
+10496=>'ON',
+10497=>'ON',
+10498=>'ON',
+10499=>'ON',
+10500=>'ON',
+10501=>'ON',
+10502=>'ON',
+10503=>'ON',
+10504=>'ON',
+10505=>'ON',
+10506=>'ON',
+10507=>'ON',
+10508=>'ON',
+10509=>'ON',
+10510=>'ON',
+10511=>'ON',
+10512=>'ON',
+10513=>'ON',
+10514=>'ON',
+10515=>'ON',
+10516=>'ON',
+10517=>'ON',
+10518=>'ON',
+10519=>'ON',
+10520=>'ON',
+10521=>'ON',
+10522=>'ON',
+10523=>'ON',
+10524=>'ON',
+10525=>'ON',
+10526=>'ON',
+10527=>'ON',
+10528=>'ON',
+10529=>'ON',
+10530=>'ON',
+10531=>'ON',
+10532=>'ON',
+10533=>'ON',
+10534=>'ON',
+10535=>'ON',
+10536=>'ON',
+10537=>'ON',
+10538=>'ON',
+10539=>'ON',
+10540=>'ON',
+10541=>'ON',
+10542=>'ON',
+10543=>'ON',
+10544=>'ON',
+10545=>'ON',
+10546=>'ON',
+10547=>'ON',
+10548=>'ON',
+10549=>'ON',
+10550=>'ON',
+10551=>'ON',
+10552=>'ON',
+10553=>'ON',
+10554=>'ON',
+10555=>'ON',
+10556=>'ON',
+10557=>'ON',
+10558=>'ON',
+10559=>'ON',
+10560=>'ON',
+10561=>'ON',
+10562=>'ON',
+10563=>'ON',
+10564=>'ON',
+10565=>'ON',
+10566=>'ON',
+10567=>'ON',
+10568=>'ON',
+10569=>'ON',
+10570=>'ON',
+10571=>'ON',
+10572=>'ON',
+10573=>'ON',
+10574=>'ON',
+10575=>'ON',
+10576=>'ON',
+10577=>'ON',
+10578=>'ON',
+10579=>'ON',
+10580=>'ON',
+10581=>'ON',
+10582=>'ON',
+10583=>'ON',
+10584=>'ON',
+10585=>'ON',
+10586=>'ON',
+10587=>'ON',
+10588=>'ON',
+10589=>'ON',
+10590=>'ON',
+10591=>'ON',
+10592=>'ON',
+10593=>'ON',
+10594=>'ON',
+10595=>'ON',
+10596=>'ON',
+10597=>'ON',
+10598=>'ON',
+10599=>'ON',
+10600=>'ON',
+10601=>'ON',
+10602=>'ON',
+10603=>'ON',
+10604=>'ON',
+10605=>'ON',
+10606=>'ON',
+10607=>'ON',
+10608=>'ON',
+10609=>'ON',
+10610=>'ON',
+10611=>'ON',
+10612=>'ON',
+10613=>'ON',
+10614=>'ON',
+10615=>'ON',
+10616=>'ON',
+10617=>'ON',
+10618=>'ON',
+10619=>'ON',
+10620=>'ON',
+10621=>'ON',
+10622=>'ON',
+10623=>'ON',
+10624=>'ON',
+10625=>'ON',
+10626=>'ON',
+10627=>'ON',
+10628=>'ON',
+10629=>'ON',
+10630=>'ON',
+10631=>'ON',
+10632=>'ON',
+10633=>'ON',
+10634=>'ON',
+10635=>'ON',
+10636=>'ON',
+10637=>'ON',
+10638=>'ON',
+10639=>'ON',
+10640=>'ON',
+10641=>'ON',
+10642=>'ON',
+10643=>'ON',
+10644=>'ON',
+10645=>'ON',
+10646=>'ON',
+10647=>'ON',
+10648=>'ON',
+10649=>'ON',
+10650=>'ON',
+10651=>'ON',
+10652=>'ON',
+10653=>'ON',
+10654=>'ON',
+10655=>'ON',
+10656=>'ON',
+10657=>'ON',
+10658=>'ON',
+10659=>'ON',
+10660=>'ON',
+10661=>'ON',
+10662=>'ON',
+10663=>'ON',
+10664=>'ON',
+10665=>'ON',
+10666=>'ON',
+10667=>'ON',
+10668=>'ON',
+10669=>'ON',
+10670=>'ON',
+10671=>'ON',
+10672=>'ON',
+10673=>'ON',
+10674=>'ON',
+10675=>'ON',
+10676=>'ON',
+10677=>'ON',
+10678=>'ON',
+10679=>'ON',
+10680=>'ON',
+10681=>'ON',
+10682=>'ON',
+10683=>'ON',
+10684=>'ON',
+10685=>'ON',
+10686=>'ON',
+10687=>'ON',
+10688=>'ON',
+10689=>'ON',
+10690=>'ON',
+10691=>'ON',
+10692=>'ON',
+10693=>'ON',
+10694=>'ON',
+10695=>'ON',
+10696=>'ON',
+10697=>'ON',
+10698=>'ON',
+10699=>'ON',
+10700=>'ON',
+10701=>'ON',
+10702=>'ON',
+10703=>'ON',
+10704=>'ON',
+10705=>'ON',
+10706=>'ON',
+10707=>'ON',
+10708=>'ON',
+10709=>'ON',
+10710=>'ON',
+10711=>'ON',
+10712=>'ON',
+10713=>'ON',
+10714=>'ON',
+10715=>'ON',
+10716=>'ON',
+10717=>'ON',
+10718=>'ON',
+10719=>'ON',
+10720=>'ON',
+10721=>'ON',
+10722=>'ON',
+10723=>'ON',
+10724=>'ON',
+10725=>'ON',
+10726=>'ON',
+10727=>'ON',
+10728=>'ON',
+10729=>'ON',
+10730=>'ON',
+10731=>'ON',
+10732=>'ON',
+10733=>'ON',
+10734=>'ON',
+10735=>'ON',
+10736=>'ON',
+10737=>'ON',
+10738=>'ON',
+10739=>'ON',
+10740=>'ON',
+10741=>'ON',
+10742=>'ON',
+10743=>'ON',
+10744=>'ON',
+10745=>'ON',
+10746=>'ON',
+10747=>'ON',
+10748=>'ON',
+10749=>'ON',
+10750=>'ON',
+10751=>'ON',
+10752=>'ON',
+10753=>'ON',
+10754=>'ON',
+10755=>'ON',
+10756=>'ON',
+10757=>'ON',
+10758=>'ON',
+10759=>'ON',
+10760=>'ON',
+10761=>'ON',
+10762=>'ON',
+10763=>'ON',
+10764=>'ON',
+10765=>'ON',
+10766=>'ON',
+10767=>'ON',
+10768=>'ON',
+10769=>'ON',
+10770=>'ON',
+10771=>'ON',
+10772=>'ON',
+10773=>'ON',
+10774=>'ON',
+10775=>'ON',
+10776=>'ON',
+10777=>'ON',
+10778=>'ON',
+10779=>'ON',
+10780=>'ON',
+10781=>'ON',
+10782=>'ON',
+10783=>'ON',
+10784=>'ON',
+10785=>'ON',
+10786=>'ON',
+10787=>'ON',
+10788=>'ON',
+10789=>'ON',
+10790=>'ON',
+10791=>'ON',
+10792=>'ON',
+10793=>'ON',
+10794=>'ON',
+10795=>'ON',
+10796=>'ON',
+10797=>'ON',
+10798=>'ON',
+10799=>'ON',
+10800=>'ON',
+10801=>'ON',
+10802=>'ON',
+10803=>'ON',
+10804=>'ON',
+10805=>'ON',
+10806=>'ON',
+10807=>'ON',
+10808=>'ON',
+10809=>'ON',
+10810=>'ON',
+10811=>'ON',
+10812=>'ON',
+10813=>'ON',
+10814=>'ON',
+10815=>'ON',
+10816=>'ON',
+10817=>'ON',
+10818=>'ON',
+10819=>'ON',
+10820=>'ON',
+10821=>'ON',
+10822=>'ON',
+10823=>'ON',
+10824=>'ON',
+10825=>'ON',
+10826=>'ON',
+10827=>'ON',
+10828=>'ON',
+10829=>'ON',
+10830=>'ON',
+10831=>'ON',
+10832=>'ON',
+10833=>'ON',
+10834=>'ON',
+10835=>'ON',
+10836=>'ON',
+10837=>'ON',
+10838=>'ON',
+10839=>'ON',
+10840=>'ON',
+10841=>'ON',
+10842=>'ON',
+10843=>'ON',
+10844=>'ON',
+10845=>'ON',
+10846=>'ON',
+10847=>'ON',
+10848=>'ON',
+10849=>'ON',
+10850=>'ON',
+10851=>'ON',
+10852=>'ON',
+10853=>'ON',
+10854=>'ON',
+10855=>'ON',
+10856=>'ON',
+10857=>'ON',
+10858=>'ON',
+10859=>'ON',
+10860=>'ON',
+10861=>'ON',
+10862=>'ON',
+10863=>'ON',
+10864=>'ON',
+10865=>'ON',
+10866=>'ON',
+10867=>'ON',
+10868=>'ON',
+10869=>'ON',
+10870=>'ON',
+10871=>'ON',
+10872=>'ON',
+10873=>'ON',
+10874=>'ON',
+10875=>'ON',
+10876=>'ON',
+10877=>'ON',
+10878=>'ON',
+10879=>'ON',
+10880=>'ON',
+10881=>'ON',
+10882=>'ON',
+10883=>'ON',
+10884=>'ON',
+10885=>'ON',
+10886=>'ON',
+10887=>'ON',
+10888=>'ON',
+10889=>'ON',
+10890=>'ON',
+10891=>'ON',
+10892=>'ON',
+10893=>'ON',
+10894=>'ON',
+10895=>'ON',
+10896=>'ON',
+10897=>'ON',
+10898=>'ON',
+10899=>'ON',
+10900=>'ON',
+10901=>'ON',
+10902=>'ON',
+10903=>'ON',
+10904=>'ON',
+10905=>'ON',
+10906=>'ON',
+10907=>'ON',
+10908=>'ON',
+10909=>'ON',
+10910=>'ON',
+10911=>'ON',
+10912=>'ON',
+10913=>'ON',
+10914=>'ON',
+10915=>'ON',
+10916=>'ON',
+10917=>'ON',
+10918=>'ON',
+10919=>'ON',
+10920=>'ON',
+10921=>'ON',
+10922=>'ON',
+10923=>'ON',
+10924=>'ON',
+10925=>'ON',
+10926=>'ON',
+10927=>'ON',
+10928=>'ON',
+10929=>'ON',
+10930=>'ON',
+10931=>'ON',
+10932=>'ON',
+10933=>'ON',
+10934=>'ON',
+10935=>'ON',
+10936=>'ON',
+10937=>'ON',
+10938=>'ON',
+10939=>'ON',
+10940=>'ON',
+10941=>'ON',
+10942=>'ON',
+10943=>'ON',
+10944=>'ON',
+10945=>'ON',
+10946=>'ON',
+10947=>'ON',
+10948=>'ON',
+10949=>'ON',
+10950=>'ON',
+10951=>'ON',
+10952=>'ON',
+10953=>'ON',
+10954=>'ON',
+10955=>'ON',
+10956=>'ON',
+10957=>'ON',
+10958=>'ON',
+10959=>'ON',
+10960=>'ON',
+10961=>'ON',
+10962=>'ON',
+10963=>'ON',
+10964=>'ON',
+10965=>'ON',
+10966=>'ON',
+10967=>'ON',
+10968=>'ON',
+10969=>'ON',
+10970=>'ON',
+10971=>'ON',
+10972=>'ON',
+10973=>'ON',
+10974=>'ON',
+10975=>'ON',
+10976=>'ON',
+10977=>'ON',
+10978=>'ON',
+10979=>'ON',
+10980=>'ON',
+10981=>'ON',
+10982=>'ON',
+10983=>'ON',
+10984=>'ON',
+10985=>'ON',
+10986=>'ON',
+10987=>'ON',
+10988=>'ON',
+10989=>'ON',
+10990=>'ON',
+10991=>'ON',
+10992=>'ON',
+10993=>'ON',
+10994=>'ON',
+10995=>'ON',
+10996=>'ON',
+10997=>'ON',
+10998=>'ON',
+10999=>'ON',
+11000=>'ON',
+11001=>'ON',
+11002=>'ON',
+11003=>'ON',
+11004=>'ON',
+11005=>'ON',
+11006=>'ON',
+11007=>'ON',
+11008=>'ON',
+11009=>'ON',
+11010=>'ON',
+11011=>'ON',
+11012=>'ON',
+11013=>'ON',
+11014=>'ON',
+11015=>'ON',
+11016=>'ON',
+11017=>'ON',
+11018=>'ON',
+11019=>'ON',
+11020=>'ON',
+11021=>'ON',
+11022=>'ON',
+11023=>'ON',
+11024=>'ON',
+11025=>'ON',
+11026=>'ON',
+11027=>'ON',
+11028=>'ON',
+11029=>'ON',
+11030=>'ON',
+11031=>'ON',
+11032=>'ON',
+11033=>'ON',
+11034=>'ON',
+11040=>'ON',
+11041=>'ON',
+11042=>'ON',
+11043=>'ON',
+11264=>'L',
+11265=>'L',
+11266=>'L',
+11267=>'L',
+11268=>'L',
+11269=>'L',
+11270=>'L',
+11271=>'L',
+11272=>'L',
+11273=>'L',
+11274=>'L',
+11275=>'L',
+11276=>'L',
+11277=>'L',
+11278=>'L',
+11279=>'L',
+11280=>'L',
+11281=>'L',
+11282=>'L',
+11283=>'L',
+11284=>'L',
+11285=>'L',
+11286=>'L',
+11287=>'L',
+11288=>'L',
+11289=>'L',
+11290=>'L',
+11291=>'L',
+11292=>'L',
+11293=>'L',
+11294=>'L',
+11295=>'L',
+11296=>'L',
+11297=>'L',
+11298=>'L',
+11299=>'L',
+11300=>'L',
+11301=>'L',
+11302=>'L',
+11303=>'L',
+11304=>'L',
+11305=>'L',
+11306=>'L',
+11307=>'L',
+11308=>'L',
+11309=>'L',
+11310=>'L',
+11312=>'L',
+11313=>'L',
+11314=>'L',
+11315=>'L',
+11316=>'L',
+11317=>'L',
+11318=>'L',
+11319=>'L',
+11320=>'L',
+11321=>'L',
+11322=>'L',
+11323=>'L',
+11324=>'L',
+11325=>'L',
+11326=>'L',
+11327=>'L',
+11328=>'L',
+11329=>'L',
+11330=>'L',
+11331=>'L',
+11332=>'L',
+11333=>'L',
+11334=>'L',
+11335=>'L',
+11336=>'L',
+11337=>'L',
+11338=>'L',
+11339=>'L',
+11340=>'L',
+11341=>'L',
+11342=>'L',
+11343=>'L',
+11344=>'L',
+11345=>'L',
+11346=>'L',
+11347=>'L',
+11348=>'L',
+11349=>'L',
+11350=>'L',
+11351=>'L',
+11352=>'L',
+11353=>'L',
+11354=>'L',
+11355=>'L',
+11356=>'L',
+11357=>'L',
+11358=>'L',
+11360=>'L',
+11361=>'L',
+11362=>'L',
+11363=>'L',
+11364=>'L',
+11365=>'L',
+11366=>'L',
+11367=>'L',
+11368=>'L',
+11369=>'L',
+11370=>'L',
+11371=>'L',
+11372=>'L',
+11380=>'L',
+11381=>'L',
+11382=>'L',
+11383=>'L',
+11392=>'L',
+11393=>'L',
+11394=>'L',
+11395=>'L',
+11396=>'L',
+11397=>'L',
+11398=>'L',
+11399=>'L',
+11400=>'L',
+11401=>'L',
+11402=>'L',
+11403=>'L',
+11404=>'L',
+11405=>'L',
+11406=>'L',
+11407=>'L',
+11408=>'L',
+11409=>'L',
+11410=>'L',
+11411=>'L',
+11412=>'L',
+11413=>'L',
+11414=>'L',
+11415=>'L',
+11416=>'L',
+11417=>'L',
+11418=>'L',
+11419=>'L',
+11420=>'L',
+11421=>'L',
+11422=>'L',
+11423=>'L',
+11424=>'L',
+11425=>'L',
+11426=>'L',
+11427=>'L',
+11428=>'L',
+11429=>'L',
+11430=>'L',
+11431=>'L',
+11432=>'L',
+11433=>'L',
+11434=>'L',
+11435=>'L',
+11436=>'L',
+11437=>'L',
+11438=>'L',
+11439=>'L',
+11440=>'L',
+11441=>'L',
+11442=>'L',
+11443=>'L',
+11444=>'L',
+11445=>'L',
+11446=>'L',
+11447=>'L',
+11448=>'L',
+11449=>'L',
+11450=>'L',
+11451=>'L',
+11452=>'L',
+11453=>'L',
+11454=>'L',
+11455=>'L',
+11456=>'L',
+11457=>'L',
+11458=>'L',
+11459=>'L',
+11460=>'L',
+11461=>'L',
+11462=>'L',
+11463=>'L',
+11464=>'L',
+11465=>'L',
+11466=>'L',
+11467=>'L',
+11468=>'L',
+11469=>'L',
+11470=>'L',
+11471=>'L',
+11472=>'L',
+11473=>'L',
+11474=>'L',
+11475=>'L',
+11476=>'L',
+11477=>'L',
+11478=>'L',
+11479=>'L',
+11480=>'L',
+11481=>'L',
+11482=>'L',
+11483=>'L',
+11484=>'L',
+11485=>'L',
+11486=>'L',
+11487=>'L',
+11488=>'L',
+11489=>'L',
+11490=>'L',
+11491=>'L',
+11492=>'L',
+11493=>'ON',
+11494=>'ON',
+11495=>'ON',
+11496=>'ON',
+11497=>'ON',
+11498=>'ON',
+11513=>'ON',
+11514=>'ON',
+11515=>'ON',
+11516=>'ON',
+11517=>'ON',
+11518=>'ON',
+11519=>'ON',
+11520=>'L',
+11521=>'L',
+11522=>'L',
+11523=>'L',
+11524=>'L',
+11525=>'L',
+11526=>'L',
+11527=>'L',
+11528=>'L',
+11529=>'L',
+11530=>'L',
+11531=>'L',
+11532=>'L',
+11533=>'L',
+11534=>'L',
+11535=>'L',
+11536=>'L',
+11537=>'L',
+11538=>'L',
+11539=>'L',
+11540=>'L',
+11541=>'L',
+11542=>'L',
+11543=>'L',
+11544=>'L',
+11545=>'L',
+11546=>'L',
+11547=>'L',
+11548=>'L',
+11549=>'L',
+11550=>'L',
+11551=>'L',
+11552=>'L',
+11553=>'L',
+11554=>'L',
+11555=>'L',
+11556=>'L',
+11557=>'L',
+11568=>'L',
+11569=>'L',
+11570=>'L',
+11571=>'L',
+11572=>'L',
+11573=>'L',
+11574=>'L',
+11575=>'L',
+11576=>'L',
+11577=>'L',
+11578=>'L',
+11579=>'L',
+11580=>'L',
+11581=>'L',
+11582=>'L',
+11583=>'L',
+11584=>'L',
+11585=>'L',
+11586=>'L',
+11587=>'L',
+11588=>'L',
+11589=>'L',
+11590=>'L',
+11591=>'L',
+11592=>'L',
+11593=>'L',
+11594=>'L',
+11595=>'L',
+11596=>'L',
+11597=>'L',
+11598=>'L',
+11599=>'L',
+11600=>'L',
+11601=>'L',
+11602=>'L',
+11603=>'L',
+11604=>'L',
+11605=>'L',
+11606=>'L',
+11607=>'L',
+11608=>'L',
+11609=>'L',
+11610=>'L',
+11611=>'L',
+11612=>'L',
+11613=>'L',
+11614=>'L',
+11615=>'L',
+11616=>'L',
+11617=>'L',
+11618=>'L',
+11619=>'L',
+11620=>'L',
+11621=>'L',
+11631=>'L',
+11648=>'L',
+11649=>'L',
+11650=>'L',
+11651=>'L',
+11652=>'L',
+11653=>'L',
+11654=>'L',
+11655=>'L',
+11656=>'L',
+11657=>'L',
+11658=>'L',
+11659=>'L',
+11660=>'L',
+11661=>'L',
+11662=>'L',
+11663=>'L',
+11664=>'L',
+11665=>'L',
+11666=>'L',
+11667=>'L',
+11668=>'L',
+11669=>'L',
+11670=>'L',
+11680=>'L',
+11681=>'L',
+11682=>'L',
+11683=>'L',
+11684=>'L',
+11685=>'L',
+11686=>'L',
+11688=>'L',
+11689=>'L',
+11690=>'L',
+11691=>'L',
+11692=>'L',
+11693=>'L',
+11694=>'L',
+11696=>'L',
+11697=>'L',
+11698=>'L',
+11699=>'L',
+11700=>'L',
+11701=>'L',
+11702=>'L',
+11704=>'L',
+11705=>'L',
+11706=>'L',
+11707=>'L',
+11708=>'L',
+11709=>'L',
+11710=>'L',
+11712=>'L',
+11713=>'L',
+11714=>'L',
+11715=>'L',
+11716=>'L',
+11717=>'L',
+11718=>'L',
+11720=>'L',
+11721=>'L',
+11722=>'L',
+11723=>'L',
+11724=>'L',
+11725=>'L',
+11726=>'L',
+11728=>'L',
+11729=>'L',
+11730=>'L',
+11731=>'L',
+11732=>'L',
+11733=>'L',
+11734=>'L',
+11736=>'L',
+11737=>'L',
+11738=>'L',
+11739=>'L',
+11740=>'L',
+11741=>'L',
+11742=>'L',
+11776=>'ON',
+11777=>'ON',
+11778=>'ON',
+11779=>'ON',
+11780=>'ON',
+11781=>'ON',
+11782=>'ON',
+11783=>'ON',
+11784=>'ON',
+11785=>'ON',
+11786=>'ON',
+11787=>'ON',
+11788=>'ON',
+11789=>'ON',
+11790=>'ON',
+11791=>'ON',
+11792=>'ON',
+11793=>'ON',
+11794=>'ON',
+11795=>'ON',
+11796=>'ON',
+11797=>'ON',
+11798=>'ON',
+11799=>'ON',
+11804=>'ON',
+11805=>'ON',
+11904=>'ON',
+11905=>'ON',
+11906=>'ON',
+11907=>'ON',
+11908=>'ON',
+11909=>'ON',
+11910=>'ON',
+11911=>'ON',
+11912=>'ON',
+11913=>'ON',
+11914=>'ON',
+11915=>'ON',
+11916=>'ON',
+11917=>'ON',
+11918=>'ON',
+11919=>'ON',
+11920=>'ON',
+11921=>'ON',
+11922=>'ON',
+11923=>'ON',
+11924=>'ON',
+11925=>'ON',
+11926=>'ON',
+11927=>'ON',
+11928=>'ON',
+11929=>'ON',
+11931=>'ON',
+11932=>'ON',
+11933=>'ON',
+11934=>'ON',
+11935=>'ON',
+11936=>'ON',
+11937=>'ON',
+11938=>'ON',
+11939=>'ON',
+11940=>'ON',
+11941=>'ON',
+11942=>'ON',
+11943=>'ON',
+11944=>'ON',
+11945=>'ON',
+11946=>'ON',
+11947=>'ON',
+11948=>'ON',
+11949=>'ON',
+11950=>'ON',
+11951=>'ON',
+11952=>'ON',
+11953=>'ON',
+11954=>'ON',
+11955=>'ON',
+11956=>'ON',
+11957=>'ON',
+11958=>'ON',
+11959=>'ON',
+11960=>'ON',
+11961=>'ON',
+11962=>'ON',
+11963=>'ON',
+11964=>'ON',
+11965=>'ON',
+11966=>'ON',
+11967=>'ON',
+11968=>'ON',
+11969=>'ON',
+11970=>'ON',
+11971=>'ON',
+11972=>'ON',
+11973=>'ON',
+11974=>'ON',
+11975=>'ON',
+11976=>'ON',
+11977=>'ON',
+11978=>'ON',
+11979=>'ON',
+11980=>'ON',
+11981=>'ON',
+11982=>'ON',
+11983=>'ON',
+11984=>'ON',
+11985=>'ON',
+11986=>'ON',
+11987=>'ON',
+11988=>'ON',
+11989=>'ON',
+11990=>'ON',
+11991=>'ON',
+11992=>'ON',
+11993=>'ON',
+11994=>'ON',
+11995=>'ON',
+11996=>'ON',
+11997=>'ON',
+11998=>'ON',
+11999=>'ON',
+12000=>'ON',
+12001=>'ON',
+12002=>'ON',
+12003=>'ON',
+12004=>'ON',
+12005=>'ON',
+12006=>'ON',
+12007=>'ON',
+12008=>'ON',
+12009=>'ON',
+12010=>'ON',
+12011=>'ON',
+12012=>'ON',
+12013=>'ON',
+12014=>'ON',
+12015=>'ON',
+12016=>'ON',
+12017=>'ON',
+12018=>'ON',
+12019=>'ON',
+12032=>'ON',
+12033=>'ON',
+12034=>'ON',
+12035=>'ON',
+12036=>'ON',
+12037=>'ON',
+12038=>'ON',
+12039=>'ON',
+12040=>'ON',
+12041=>'ON',
+12042=>'ON',
+12043=>'ON',
+12044=>'ON',
+12045=>'ON',
+12046=>'ON',
+12047=>'ON',
+12048=>'ON',
+12049=>'ON',
+12050=>'ON',
+12051=>'ON',
+12052=>'ON',
+12053=>'ON',
+12054=>'ON',
+12055=>'ON',
+12056=>'ON',
+12057=>'ON',
+12058=>'ON',
+12059=>'ON',
+12060=>'ON',
+12061=>'ON',
+12062=>'ON',
+12063=>'ON',
+12064=>'ON',
+12065=>'ON',
+12066=>'ON',
+12067=>'ON',
+12068=>'ON',
+12069=>'ON',
+12070=>'ON',
+12071=>'ON',
+12072=>'ON',
+12073=>'ON',
+12074=>'ON',
+12075=>'ON',
+12076=>'ON',
+12077=>'ON',
+12078=>'ON',
+12079=>'ON',
+12080=>'ON',
+12081=>'ON',
+12082=>'ON',
+12083=>'ON',
+12084=>'ON',
+12085=>'ON',
+12086=>'ON',
+12087=>'ON',
+12088=>'ON',
+12089=>'ON',
+12090=>'ON',
+12091=>'ON',
+12092=>'ON',
+12093=>'ON',
+12094=>'ON',
+12095=>'ON',
+12096=>'ON',
+12097=>'ON',
+12098=>'ON',
+12099=>'ON',
+12100=>'ON',
+12101=>'ON',
+12102=>'ON',
+12103=>'ON',
+12104=>'ON',
+12105=>'ON',
+12106=>'ON',
+12107=>'ON',
+12108=>'ON',
+12109=>'ON',
+12110=>'ON',
+12111=>'ON',
+12112=>'ON',
+12113=>'ON',
+12114=>'ON',
+12115=>'ON',
+12116=>'ON',
+12117=>'ON',
+12118=>'ON',
+12119=>'ON',
+12120=>'ON',
+12121=>'ON',
+12122=>'ON',
+12123=>'ON',
+12124=>'ON',
+12125=>'ON',
+12126=>'ON',
+12127=>'ON',
+12128=>'ON',
+12129=>'ON',
+12130=>'ON',
+12131=>'ON',
+12132=>'ON',
+12133=>'ON',
+12134=>'ON',
+12135=>'ON',
+12136=>'ON',
+12137=>'ON',
+12138=>'ON',
+12139=>'ON',
+12140=>'ON',
+12141=>'ON',
+12142=>'ON',
+12143=>'ON',
+12144=>'ON',
+12145=>'ON',
+12146=>'ON',
+12147=>'ON',
+12148=>'ON',
+12149=>'ON',
+12150=>'ON',
+12151=>'ON',
+12152=>'ON',
+12153=>'ON',
+12154=>'ON',
+12155=>'ON',
+12156=>'ON',
+12157=>'ON',
+12158=>'ON',
+12159=>'ON',
+12160=>'ON',
+12161=>'ON',
+12162=>'ON',
+12163=>'ON',
+12164=>'ON',
+12165=>'ON',
+12166=>'ON',
+12167=>'ON',
+12168=>'ON',
+12169=>'ON',
+12170=>'ON',
+12171=>'ON',
+12172=>'ON',
+12173=>'ON',
+12174=>'ON',
+12175=>'ON',
+12176=>'ON',
+12177=>'ON',
+12178=>'ON',
+12179=>'ON',
+12180=>'ON',
+12181=>'ON',
+12182=>'ON',
+12183=>'ON',
+12184=>'ON',
+12185=>'ON',
+12186=>'ON',
+12187=>'ON',
+12188=>'ON',
+12189=>'ON',
+12190=>'ON',
+12191=>'ON',
+12192=>'ON',
+12193=>'ON',
+12194=>'ON',
+12195=>'ON',
+12196=>'ON',
+12197=>'ON',
+12198=>'ON',
+12199=>'ON',
+12200=>'ON',
+12201=>'ON',
+12202=>'ON',
+12203=>'ON',
+12204=>'ON',
+12205=>'ON',
+12206=>'ON',
+12207=>'ON',
+12208=>'ON',
+12209=>'ON',
+12210=>'ON',
+12211=>'ON',
+12212=>'ON',
+12213=>'ON',
+12214=>'ON',
+12215=>'ON',
+12216=>'ON',
+12217=>'ON',
+12218=>'ON',
+12219=>'ON',
+12220=>'ON',
+12221=>'ON',
+12222=>'ON',
+12223=>'ON',
+12224=>'ON',
+12225=>'ON',
+12226=>'ON',
+12227=>'ON',
+12228=>'ON',
+12229=>'ON',
+12230=>'ON',
+12231=>'ON',
+12232=>'ON',
+12233=>'ON',
+12234=>'ON',
+12235=>'ON',
+12236=>'ON',
+12237=>'ON',
+12238=>'ON',
+12239=>'ON',
+12240=>'ON',
+12241=>'ON',
+12242=>'ON',
+12243=>'ON',
+12244=>'ON',
+12245=>'ON',
+12272=>'ON',
+12273=>'ON',
+12274=>'ON',
+12275=>'ON',
+12276=>'ON',
+12277=>'ON',
+12278=>'ON',
+12279=>'ON',
+12280=>'ON',
+12281=>'ON',
+12282=>'ON',
+12283=>'ON',
+12288=>'WS',
+12289=>'ON',
+12290=>'ON',
+12291=>'ON',
+12292=>'ON',
+12293=>'L',
+12294=>'L',
+12295=>'L',
+12296=>'ON',
+12297=>'ON',
+12298=>'ON',
+12299=>'ON',
+12300=>'ON',
+12301=>'ON',
+12302=>'ON',
+12303=>'ON',
+12304=>'ON',
+12305=>'ON',
+12306=>'ON',
+12307=>'ON',
+12308=>'ON',
+12309=>'ON',
+12310=>'ON',
+12311=>'ON',
+12312=>'ON',
+12313=>'ON',
+12314=>'ON',
+12315=>'ON',
+12316=>'ON',
+12317=>'ON',
+12318=>'ON',
+12319=>'ON',
+12320=>'ON',
+12321=>'L',
+12322=>'L',
+12323=>'L',
+12324=>'L',
+12325=>'L',
+12326=>'L',
+12327=>'L',
+12328=>'L',
+12329=>'L',
+12330=>'NSM',
+12331=>'NSM',
+12332=>'NSM',
+12333=>'NSM',
+12334=>'NSM',
+12335=>'NSM',
+12336=>'ON',
+12337=>'L',
+12338=>'L',
+12339=>'L',
+12340=>'L',
+12341=>'L',
+12342=>'ON',
+12343=>'ON',
+12344=>'L',
+12345=>'L',
+12346=>'L',
+12347=>'L',
+12348=>'L',
+12349=>'ON',
+12350=>'ON',
+12351=>'ON',
+12353=>'L',
+12354=>'L',
+12355=>'L',
+12356=>'L',
+12357=>'L',
+12358=>'L',
+12359=>'L',
+12360=>'L',
+12361=>'L',
+12362=>'L',
+12363=>'L',
+12364=>'L',
+12365=>'L',
+12366=>'L',
+12367=>'L',
+12368=>'L',
+12369=>'L',
+12370=>'L',
+12371=>'L',
+12372=>'L',
+12373=>'L',
+12374=>'L',
+12375=>'L',
+12376=>'L',
+12377=>'L',
+12378=>'L',
+12379=>'L',
+12380=>'L',
+12381=>'L',
+12382=>'L',
+12383=>'L',
+12384=>'L',
+12385=>'L',
+12386=>'L',
+12387=>'L',
+12388=>'L',
+12389=>'L',
+12390=>'L',
+12391=>'L',
+12392=>'L',
+12393=>'L',
+12394=>'L',
+12395=>'L',
+12396=>'L',
+12397=>'L',
+12398=>'L',
+12399=>'L',
+12400=>'L',
+12401=>'L',
+12402=>'L',
+12403=>'L',
+12404=>'L',
+12405=>'L',
+12406=>'L',
+12407=>'L',
+12408=>'L',
+12409=>'L',
+12410=>'L',
+12411=>'L',
+12412=>'L',
+12413=>'L',
+12414=>'L',
+12415=>'L',
+12416=>'L',
+12417=>'L',
+12418=>'L',
+12419=>'L',
+12420=>'L',
+12421=>'L',
+12422=>'L',
+12423=>'L',
+12424=>'L',
+12425=>'L',
+12426=>'L',
+12427=>'L',
+12428=>'L',
+12429=>'L',
+12430=>'L',
+12431=>'L',
+12432=>'L',
+12433=>'L',
+12434=>'L',
+12435=>'L',
+12436=>'L',
+12437=>'L',
+12438=>'L',
+12441=>'NSM',
+12442=>'NSM',
+12443=>'ON',
+12444=>'ON',
+12445=>'L',
+12446=>'L',
+12447=>'L',
+12448=>'ON',
+12449=>'L',
+12450=>'L',
+12451=>'L',
+12452=>'L',
+12453=>'L',
+12454=>'L',
+12455=>'L',
+12456=>'L',
+12457=>'L',
+12458=>'L',
+12459=>'L',
+12460=>'L',
+12461=>'L',
+12462=>'L',
+12463=>'L',
+12464=>'L',
+12465=>'L',
+12466=>'L',
+12467=>'L',
+12468=>'L',
+12469=>'L',
+12470=>'L',
+12471=>'L',
+12472=>'L',
+12473=>'L',
+12474=>'L',
+12475=>'L',
+12476=>'L',
+12477=>'L',
+12478=>'L',
+12479=>'L',
+12480=>'L',
+12481=>'L',
+12482=>'L',
+12483=>'L',
+12484=>'L',
+12485=>'L',
+12486=>'L',
+12487=>'L',
+12488=>'L',
+12489=>'L',
+12490=>'L',
+12491=>'L',
+12492=>'L',
+12493=>'L',
+12494=>'L',
+12495=>'L',
+12496=>'L',
+12497=>'L',
+12498=>'L',
+12499=>'L',
+12500=>'L',
+12501=>'L',
+12502=>'L',
+12503=>'L',
+12504=>'L',
+12505=>'L',
+12506=>'L',
+12507=>'L',
+12508=>'L',
+12509=>'L',
+12510=>'L',
+12511=>'L',
+12512=>'L',
+12513=>'L',
+12514=>'L',
+12515=>'L',
+12516=>'L',
+12517=>'L',
+12518=>'L',
+12519=>'L',
+12520=>'L',
+12521=>'L',
+12522=>'L',
+12523=>'L',
+12524=>'L',
+12525=>'L',
+12526=>'L',
+12527=>'L',
+12528=>'L',
+12529=>'L',
+12530=>'L',
+12531=>'L',
+12532=>'L',
+12533=>'L',
+12534=>'L',
+12535=>'L',
+12536=>'L',
+12537=>'L',
+12538=>'L',
+12539=>'ON',
+12540=>'L',
+12541=>'L',
+12542=>'L',
+12543=>'L',
+12549=>'L',
+12550=>'L',
+12551=>'L',
+12552=>'L',
+12553=>'L',
+12554=>'L',
+12555=>'L',
+12556=>'L',
+12557=>'L',
+12558=>'L',
+12559=>'L',
+12560=>'L',
+12561=>'L',
+12562=>'L',
+12563=>'L',
+12564=>'L',
+12565=>'L',
+12566=>'L',
+12567=>'L',
+12568=>'L',
+12569=>'L',
+12570=>'L',
+12571=>'L',
+12572=>'L',
+12573=>'L',
+12574=>'L',
+12575=>'L',
+12576=>'L',
+12577=>'L',
+12578=>'L',
+12579=>'L',
+12580=>'L',
+12581=>'L',
+12582=>'L',
+12583=>'L',
+12584=>'L',
+12585=>'L',
+12586=>'L',
+12587=>'L',
+12588=>'L',
+12593=>'L',
+12594=>'L',
+12595=>'L',
+12596=>'L',
+12597=>'L',
+12598=>'L',
+12599=>'L',
+12600=>'L',
+12601=>'L',
+12602=>'L',
+12603=>'L',
+12604=>'L',
+12605=>'L',
+12606=>'L',
+12607=>'L',
+12608=>'L',
+12609=>'L',
+12610=>'L',
+12611=>'L',
+12612=>'L',
+12613=>'L',
+12614=>'L',
+12615=>'L',
+12616=>'L',
+12617=>'L',
+12618=>'L',
+12619=>'L',
+12620=>'L',
+12621=>'L',
+12622=>'L',
+12623=>'L',
+12624=>'L',
+12625=>'L',
+12626=>'L',
+12627=>'L',
+12628=>'L',
+12629=>'L',
+12630=>'L',
+12631=>'L',
+12632=>'L',
+12633=>'L',
+12634=>'L',
+12635=>'L',
+12636=>'L',
+12637=>'L',
+12638=>'L',
+12639=>'L',
+12640=>'L',
+12641=>'L',
+12642=>'L',
+12643=>'L',
+12644=>'L',
+12645=>'L',
+12646=>'L',
+12647=>'L',
+12648=>'L',
+12649=>'L',
+12650=>'L',
+12651=>'L',
+12652=>'L',
+12653=>'L',
+12654=>'L',
+12655=>'L',
+12656=>'L',
+12657=>'L',
+12658=>'L',
+12659=>'L',
+12660=>'L',
+12661=>'L',
+12662=>'L',
+12663=>'L',
+12664=>'L',
+12665=>'L',
+12666=>'L',
+12667=>'L',
+12668=>'L',
+12669=>'L',
+12670=>'L',
+12671=>'L',
+12672=>'L',
+12673=>'L',
+12674=>'L',
+12675=>'L',
+12676=>'L',
+12677=>'L',
+12678=>'L',
+12679=>'L',
+12680=>'L',
+12681=>'L',
+12682=>'L',
+12683=>'L',
+12684=>'L',
+12685=>'L',
+12686=>'L',
+12688=>'L',
+12689=>'L',
+12690=>'L',
+12691=>'L',
+12692=>'L',
+12693=>'L',
+12694=>'L',
+12695=>'L',
+12696=>'L',
+12697=>'L',
+12698=>'L',
+12699=>'L',
+12700=>'L',
+12701=>'L',
+12702=>'L',
+12703=>'L',
+12704=>'L',
+12705=>'L',
+12706=>'L',
+12707=>'L',
+12708=>'L',
+12709=>'L',
+12710=>'L',
+12711=>'L',
+12712=>'L',
+12713=>'L',
+12714=>'L',
+12715=>'L',
+12716=>'L',
+12717=>'L',
+12718=>'L',
+12719=>'L',
+12720=>'L',
+12721=>'L',
+12722=>'L',
+12723=>'L',
+12724=>'L',
+12725=>'L',
+12726=>'L',
+12727=>'L',
+12736=>'ON',
+12737=>'ON',
+12738=>'ON',
+12739=>'ON',
+12740=>'ON',
+12741=>'ON',
+12742=>'ON',
+12743=>'ON',
+12744=>'ON',
+12745=>'ON',
+12746=>'ON',
+12747=>'ON',
+12748=>'ON',
+12749=>'ON',
+12750=>'ON',
+12751=>'ON',
+12784=>'L',
+12785=>'L',
+12786=>'L',
+12787=>'L',
+12788=>'L',
+12789=>'L',
+12790=>'L',
+12791=>'L',
+12792=>'L',
+12793=>'L',
+12794=>'L',
+12795=>'L',
+12796=>'L',
+12797=>'L',
+12798=>'L',
+12799=>'L',
+12800=>'L',
+12801=>'L',
+12802=>'L',
+12803=>'L',
+12804=>'L',
+12805=>'L',
+12806=>'L',
+12807=>'L',
+12808=>'L',
+12809=>'L',
+12810=>'L',
+12811=>'L',
+12812=>'L',
+12813=>'L',
+12814=>'L',
+12815=>'L',
+12816=>'L',
+12817=>'L',
+12818=>'L',
+12819=>'L',
+12820=>'L',
+12821=>'L',
+12822=>'L',
+12823=>'L',
+12824=>'L',
+12825=>'L',
+12826=>'L',
+12827=>'L',
+12828=>'L',
+12829=>'ON',
+12830=>'ON',
+12832=>'L',
+12833=>'L',
+12834=>'L',
+12835=>'L',
+12836=>'L',
+12837=>'L',
+12838=>'L',
+12839=>'L',
+12840=>'L',
+12841=>'L',
+12842=>'L',
+12843=>'L',
+12844=>'L',
+12845=>'L',
+12846=>'L',
+12847=>'L',
+12848=>'L',
+12849=>'L',
+12850=>'L',
+12851=>'L',
+12852=>'L',
+12853=>'L',
+12854=>'L',
+12855=>'L',
+12856=>'L',
+12857=>'L',
+12858=>'L',
+12859=>'L',
+12860=>'L',
+12861=>'L',
+12862=>'L',
+12863=>'L',
+12864=>'L',
+12865=>'L',
+12866=>'L',
+12867=>'L',
+12880=>'ON',
+12881=>'ON',
+12882=>'ON',
+12883=>'ON',
+12884=>'ON',
+12885=>'ON',
+12886=>'ON',
+12887=>'ON',
+12888=>'ON',
+12889=>'ON',
+12890=>'ON',
+12891=>'ON',
+12892=>'ON',
+12893=>'ON',
+12894=>'ON',
+12895=>'ON',
+12896=>'L',
+12897=>'L',
+12898=>'L',
+12899=>'L',
+12900=>'L',
+12901=>'L',
+12902=>'L',
+12903=>'L',
+12904=>'L',
+12905=>'L',
+12906=>'L',
+12907=>'L',
+12908=>'L',
+12909=>'L',
+12910=>'L',
+12911=>'L',
+12912=>'L',
+12913=>'L',
+12914=>'L',
+12915=>'L',
+12916=>'L',
+12917=>'L',
+12918=>'L',
+12919=>'L',
+12920=>'L',
+12921=>'L',
+12922=>'L',
+12923=>'L',
+12924=>'ON',
+12925=>'ON',
+12926=>'ON',
+12927=>'L',
+12928=>'L',
+12929=>'L',
+12930=>'L',
+12931=>'L',
+12932=>'L',
+12933=>'L',
+12934=>'L',
+12935=>'L',
+12936=>'L',
+12937=>'L',
+12938=>'L',
+12939=>'L',
+12940=>'L',
+12941=>'L',
+12942=>'L',
+12943=>'L',
+12944=>'L',
+12945=>'L',
+12946=>'L',
+12947=>'L',
+12948=>'L',
+12949=>'L',
+12950=>'L',
+12951=>'L',
+12952=>'L',
+12953=>'L',
+12954=>'L',
+12955=>'L',
+12956=>'L',
+12957=>'L',
+12958=>'L',
+12959=>'L',
+12960=>'L',
+12961=>'L',
+12962=>'L',
+12963=>'L',
+12964=>'L',
+12965=>'L',
+12966=>'L',
+12967=>'L',
+12968=>'L',
+12969=>'L',
+12970=>'L',
+12971=>'L',
+12972=>'L',
+12973=>'L',
+12974=>'L',
+12975=>'L',
+12976=>'L',
+12977=>'ON',
+12978=>'ON',
+12979=>'ON',
+12980=>'ON',
+12981=>'ON',
+12982=>'ON',
+12983=>'ON',
+12984=>'ON',
+12985=>'ON',
+12986=>'ON',
+12987=>'ON',
+12988=>'ON',
+12989=>'ON',
+12990=>'ON',
+12991=>'ON',
+12992=>'L',
+12993=>'L',
+12994=>'L',
+12995=>'L',
+12996=>'L',
+12997=>'L',
+12998=>'L',
+12999=>'L',
+13000=>'L',
+13001=>'L',
+13002=>'L',
+13003=>'L',
+13004=>'ON',
+13005=>'ON',
+13006=>'ON',
+13007=>'ON',
+13008=>'L',
+13009=>'L',
+13010=>'L',
+13011=>'L',
+13012=>'L',
+13013=>'L',
+13014=>'L',
+13015=>'L',
+13016=>'L',
+13017=>'L',
+13018=>'L',
+13019=>'L',
+13020=>'L',
+13021=>'L',
+13022=>'L',
+13023=>'L',
+13024=>'L',
+13025=>'L',
+13026=>'L',
+13027=>'L',
+13028=>'L',
+13029=>'L',
+13030=>'L',
+13031=>'L',
+13032=>'L',
+13033=>'L',
+13034=>'L',
+13035=>'L',
+13036=>'L',
+13037=>'L',
+13038=>'L',
+13039=>'L',
+13040=>'L',
+13041=>'L',
+13042=>'L',
+13043=>'L',
+13044=>'L',
+13045=>'L',
+13046=>'L',
+13047=>'L',
+13048=>'L',
+13049=>'L',
+13050=>'L',
+13051=>'L',
+13052=>'L',
+13053=>'L',
+13054=>'L',
+13056=>'L',
+13057=>'L',
+13058=>'L',
+13059=>'L',
+13060=>'L',
+13061=>'L',
+13062=>'L',
+13063=>'L',
+13064=>'L',
+13065=>'L',
+13066=>'L',
+13067=>'L',
+13068=>'L',
+13069=>'L',
+13070=>'L',
+13071=>'L',
+13072=>'L',
+13073=>'L',
+13074=>'L',
+13075=>'L',
+13076=>'L',
+13077=>'L',
+13078=>'L',
+13079=>'L',
+13080=>'L',
+13081=>'L',
+13082=>'L',
+13083=>'L',
+13084=>'L',
+13085=>'L',
+13086=>'L',
+13087=>'L',
+13088=>'L',
+13089=>'L',
+13090=>'L',
+13091=>'L',
+13092=>'L',
+13093=>'L',
+13094=>'L',
+13095=>'L',
+13096=>'L',
+13097=>'L',
+13098=>'L',
+13099=>'L',
+13100=>'L',
+13101=>'L',
+13102=>'L',
+13103=>'L',
+13104=>'L',
+13105=>'L',
+13106=>'L',
+13107=>'L',
+13108=>'L',
+13109=>'L',
+13110=>'L',
+13111=>'L',
+13112=>'L',
+13113=>'L',
+13114=>'L',
+13115=>'L',
+13116=>'L',
+13117=>'L',
+13118=>'L',
+13119=>'L',
+13120=>'L',
+13121=>'L',
+13122=>'L',
+13123=>'L',
+13124=>'L',
+13125=>'L',
+13126=>'L',
+13127=>'L',
+13128=>'L',
+13129=>'L',
+13130=>'L',
+13131=>'L',
+13132=>'L',
+13133=>'L',
+13134=>'L',
+13135=>'L',
+13136=>'L',
+13137=>'L',
+13138=>'L',
+13139=>'L',
+13140=>'L',
+13141=>'L',
+13142=>'L',
+13143=>'L',
+13144=>'L',
+13145=>'L',
+13146=>'L',
+13147=>'L',
+13148=>'L',
+13149=>'L',
+13150=>'L',
+13151=>'L',
+13152=>'L',
+13153=>'L',
+13154=>'L',
+13155=>'L',
+13156=>'L',
+13157=>'L',
+13158=>'L',
+13159=>'L',
+13160=>'L',
+13161=>'L',
+13162=>'L',
+13163=>'L',
+13164=>'L',
+13165=>'L',
+13166=>'L',
+13167=>'L',
+13168=>'L',
+13169=>'L',
+13170=>'L',
+13171=>'L',
+13172=>'L',
+13173=>'L',
+13174=>'L',
+13175=>'ON',
+13176=>'ON',
+13177=>'ON',
+13178=>'ON',
+13179=>'L',
+13180=>'L',
+13181=>'L',
+13182=>'L',
+13183=>'L',
+13184=>'L',
+13185=>'L',
+13186=>'L',
+13187=>'L',
+13188=>'L',
+13189=>'L',
+13190=>'L',
+13191=>'L',
+13192=>'L',
+13193=>'L',
+13194=>'L',
+13195=>'L',
+13196=>'L',
+13197=>'L',
+13198=>'L',
+13199=>'L',
+13200=>'L',
+13201=>'L',
+13202=>'L',
+13203=>'L',
+13204=>'L',
+13205=>'L',
+13206=>'L',
+13207=>'L',
+13208=>'L',
+13209=>'L',
+13210=>'L',
+13211=>'L',
+13212=>'L',
+13213=>'L',
+13214=>'L',
+13215=>'L',
+13216=>'L',
+13217=>'L',
+13218=>'L',
+13219=>'L',
+13220=>'L',
+13221=>'L',
+13222=>'L',
+13223=>'L',
+13224=>'L',
+13225=>'L',
+13226=>'L',
+13227=>'L',
+13228=>'L',
+13229=>'L',
+13230=>'L',
+13231=>'L',
+13232=>'L',
+13233=>'L',
+13234=>'L',
+13235=>'L',
+13236=>'L',
+13237=>'L',
+13238=>'L',
+13239=>'L',
+13240=>'L',
+13241=>'L',
+13242=>'L',
+13243=>'L',
+13244=>'L',
+13245=>'L',
+13246=>'L',
+13247=>'L',
+13248=>'L',
+13249=>'L',
+13250=>'L',
+13251=>'L',
+13252=>'L',
+13253=>'L',
+13254=>'L',
+13255=>'L',
+13256=>'L',
+13257=>'L',
+13258=>'L',
+13259=>'L',
+13260=>'L',
+13261=>'L',
+13262=>'L',
+13263=>'L',
+13264=>'L',
+13265=>'L',
+13266=>'L',
+13267=>'L',
+13268=>'L',
+13269=>'L',
+13270=>'L',
+13271=>'L',
+13272=>'L',
+13273=>'L',
+13274=>'L',
+13275=>'L',
+13276=>'L',
+13277=>'L',
+13278=>'ON',
+13279=>'ON',
+13280=>'L',
+13281=>'L',
+13282=>'L',
+13283=>'L',
+13284=>'L',
+13285=>'L',
+13286=>'L',
+13287=>'L',
+13288=>'L',
+13289=>'L',
+13290=>'L',
+13291=>'L',
+13292=>'L',
+13293=>'L',
+13294=>'L',
+13295=>'L',
+13296=>'L',
+13297=>'L',
+13298=>'L',
+13299=>'L',
+13300=>'L',
+13301=>'L',
+13302=>'L',
+13303=>'L',
+13304=>'L',
+13305=>'L',
+13306=>'L',
+13307=>'L',
+13308=>'L',
+13309=>'L',
+13310=>'L',
+13311=>'ON',
+13312=>'L',
+19893=>'L',
+19904=>'ON',
+19905=>'ON',
+19906=>'ON',
+19907=>'ON',
+19908=>'ON',
+19909=>'ON',
+19910=>'ON',
+19911=>'ON',
+19912=>'ON',
+19913=>'ON',
+19914=>'ON',
+19915=>'ON',
+19916=>'ON',
+19917=>'ON',
+19918=>'ON',
+19919=>'ON',
+19920=>'ON',
+19921=>'ON',
+19922=>'ON',
+19923=>'ON',
+19924=>'ON',
+19925=>'ON',
+19926=>'ON',
+19927=>'ON',
+19928=>'ON',
+19929=>'ON',
+19930=>'ON',
+19931=>'ON',
+19932=>'ON',
+19933=>'ON',
+19934=>'ON',
+19935=>'ON',
+19936=>'ON',
+19937=>'ON',
+19938=>'ON',
+19939=>'ON',
+19940=>'ON',
+19941=>'ON',
+19942=>'ON',
+19943=>'ON',
+19944=>'ON',
+19945=>'ON',
+19946=>'ON',
+19947=>'ON',
+19948=>'ON',
+19949=>'ON',
+19950=>'ON',
+19951=>'ON',
+19952=>'ON',
+19953=>'ON',
+19954=>'ON',
+19955=>'ON',
+19956=>'ON',
+19957=>'ON',
+19958=>'ON',
+19959=>'ON',
+19960=>'ON',
+19961=>'ON',
+19962=>'ON',
+19963=>'ON',
+19964=>'ON',
+19965=>'ON',
+19966=>'ON',
+19967=>'ON',
+19968=>'L',
+40891=>'L',
+40960=>'L',
+40961=>'L',
+40962=>'L',
+40963=>'L',
+40964=>'L',
+40965=>'L',
+40966=>'L',
+40967=>'L',
+40968=>'L',
+40969=>'L',
+40970=>'L',
+40971=>'L',
+40972=>'L',
+40973=>'L',
+40974=>'L',
+40975=>'L',
+40976=>'L',
+40977=>'L',
+40978=>'L',
+40979=>'L',
+40980=>'L',
+40981=>'L',
+40982=>'L',
+40983=>'L',
+40984=>'L',
+40985=>'L',
+40986=>'L',
+40987=>'L',
+40988=>'L',
+40989=>'L',
+40990=>'L',
+40991=>'L',
+40992=>'L',
+40993=>'L',
+40994=>'L',
+40995=>'L',
+40996=>'L',
+40997=>'L',
+40998=>'L',
+40999=>'L',
+41000=>'L',
+41001=>'L',
+41002=>'L',
+41003=>'L',
+41004=>'L',
+41005=>'L',
+41006=>'L',
+41007=>'L',
+41008=>'L',
+41009=>'L',
+41010=>'L',
+41011=>'L',
+41012=>'L',
+41013=>'L',
+41014=>'L',
+41015=>'L',
+41016=>'L',
+41017=>'L',
+41018=>'L',
+41019=>'L',
+41020=>'L',
+41021=>'L',
+41022=>'L',
+41023=>'L',
+41024=>'L',
+41025=>'L',
+41026=>'L',
+41027=>'L',
+41028=>'L',
+41029=>'L',
+41030=>'L',
+41031=>'L',
+41032=>'L',
+41033=>'L',
+41034=>'L',
+41035=>'L',
+41036=>'L',
+41037=>'L',
+41038=>'L',
+41039=>'L',
+41040=>'L',
+41041=>'L',
+41042=>'L',
+41043=>'L',
+41044=>'L',
+41045=>'L',
+41046=>'L',
+41047=>'L',
+41048=>'L',
+41049=>'L',
+41050=>'L',
+41051=>'L',
+41052=>'L',
+41053=>'L',
+41054=>'L',
+41055=>'L',
+41056=>'L',
+41057=>'L',
+41058=>'L',
+41059=>'L',
+41060=>'L',
+41061=>'L',
+41062=>'L',
+41063=>'L',
+41064=>'L',
+41065=>'L',
+41066=>'L',
+41067=>'L',
+41068=>'L',
+41069=>'L',
+41070=>'L',
+41071=>'L',
+41072=>'L',
+41073=>'L',
+41074=>'L',
+41075=>'L',
+41076=>'L',
+41077=>'L',
+41078=>'L',
+41079=>'L',
+41080=>'L',
+41081=>'L',
+41082=>'L',
+41083=>'L',
+41084=>'L',
+41085=>'L',
+41086=>'L',
+41087=>'L',
+41088=>'L',
+41089=>'L',
+41090=>'L',
+41091=>'L',
+41092=>'L',
+41093=>'L',
+41094=>'L',
+41095=>'L',
+41096=>'L',
+41097=>'L',
+41098=>'L',
+41099=>'L',
+41100=>'L',
+41101=>'L',
+41102=>'L',
+41103=>'L',
+41104=>'L',
+41105=>'L',
+41106=>'L',
+41107=>'L',
+41108=>'L',
+41109=>'L',
+41110=>'L',
+41111=>'L',
+41112=>'L',
+41113=>'L',
+41114=>'L',
+41115=>'L',
+41116=>'L',
+41117=>'L',
+41118=>'L',
+41119=>'L',
+41120=>'L',
+41121=>'L',
+41122=>'L',
+41123=>'L',
+41124=>'L',
+41125=>'L',
+41126=>'L',
+41127=>'L',
+41128=>'L',
+41129=>'L',
+41130=>'L',
+41131=>'L',
+41132=>'L',
+41133=>'L',
+41134=>'L',
+41135=>'L',
+41136=>'L',
+41137=>'L',
+41138=>'L',
+41139=>'L',
+41140=>'L',
+41141=>'L',
+41142=>'L',
+41143=>'L',
+41144=>'L',
+41145=>'L',
+41146=>'L',
+41147=>'L',
+41148=>'L',
+41149=>'L',
+41150=>'L',
+41151=>'L',
+41152=>'L',
+41153=>'L',
+41154=>'L',
+41155=>'L',
+41156=>'L',
+41157=>'L',
+41158=>'L',
+41159=>'L',
+41160=>'L',
+41161=>'L',
+41162=>'L',
+41163=>'L',
+41164=>'L',
+41165=>'L',
+41166=>'L',
+41167=>'L',
+41168=>'L',
+41169=>'L',
+41170=>'L',
+41171=>'L',
+41172=>'L',
+41173=>'L',
+41174=>'L',
+41175=>'L',
+41176=>'L',
+41177=>'L',
+41178=>'L',
+41179=>'L',
+41180=>'L',
+41181=>'L',
+41182=>'L',
+41183=>'L',
+41184=>'L',
+41185=>'L',
+41186=>'L',
+41187=>'L',
+41188=>'L',
+41189=>'L',
+41190=>'L',
+41191=>'L',
+41192=>'L',
+41193=>'L',
+41194=>'L',
+41195=>'L',
+41196=>'L',
+41197=>'L',
+41198=>'L',
+41199=>'L',
+41200=>'L',
+41201=>'L',
+41202=>'L',
+41203=>'L',
+41204=>'L',
+41205=>'L',
+41206=>'L',
+41207=>'L',
+41208=>'L',
+41209=>'L',
+41210=>'L',
+41211=>'L',
+41212=>'L',
+41213=>'L',
+41214=>'L',
+41215=>'L',
+41216=>'L',
+41217=>'L',
+41218=>'L',
+41219=>'L',
+41220=>'L',
+41221=>'L',
+41222=>'L',
+41223=>'L',
+41224=>'L',
+41225=>'L',
+41226=>'L',
+41227=>'L',
+41228=>'L',
+41229=>'L',
+41230=>'L',
+41231=>'L',
+41232=>'L',
+41233=>'L',
+41234=>'L',
+41235=>'L',
+41236=>'L',
+41237=>'L',
+41238=>'L',
+41239=>'L',
+41240=>'L',
+41241=>'L',
+41242=>'L',
+41243=>'L',
+41244=>'L',
+41245=>'L',
+41246=>'L',
+41247=>'L',
+41248=>'L',
+41249=>'L',
+41250=>'L',
+41251=>'L',
+41252=>'L',
+41253=>'L',
+41254=>'L',
+41255=>'L',
+41256=>'L',
+41257=>'L',
+41258=>'L',
+41259=>'L',
+41260=>'L',
+41261=>'L',
+41262=>'L',
+41263=>'L',
+41264=>'L',
+41265=>'L',
+41266=>'L',
+41267=>'L',
+41268=>'L',
+41269=>'L',
+41270=>'L',
+41271=>'L',
+41272=>'L',
+41273=>'L',
+41274=>'L',
+41275=>'L',
+41276=>'L',
+41277=>'L',
+41278=>'L',
+41279=>'L',
+41280=>'L',
+41281=>'L',
+41282=>'L',
+41283=>'L',
+41284=>'L',
+41285=>'L',
+41286=>'L',
+41287=>'L',
+41288=>'L',
+41289=>'L',
+41290=>'L',
+41291=>'L',
+41292=>'L',
+41293=>'L',
+41294=>'L',
+41295=>'L',
+41296=>'L',
+41297=>'L',
+41298=>'L',
+41299=>'L',
+41300=>'L',
+41301=>'L',
+41302=>'L',
+41303=>'L',
+41304=>'L',
+41305=>'L',
+41306=>'L',
+41307=>'L',
+41308=>'L',
+41309=>'L',
+41310=>'L',
+41311=>'L',
+41312=>'L',
+41313=>'L',
+41314=>'L',
+41315=>'L',
+41316=>'L',
+41317=>'L',
+41318=>'L',
+41319=>'L',
+41320=>'L',
+41321=>'L',
+41322=>'L',
+41323=>'L',
+41324=>'L',
+41325=>'L',
+41326=>'L',
+41327=>'L',
+41328=>'L',
+41329=>'L',
+41330=>'L',
+41331=>'L',
+41332=>'L',
+41333=>'L',
+41334=>'L',
+41335=>'L',
+41336=>'L',
+41337=>'L',
+41338=>'L',
+41339=>'L',
+41340=>'L',
+41341=>'L',
+41342=>'L',
+41343=>'L',
+41344=>'L',
+41345=>'L',
+41346=>'L',
+41347=>'L',
+41348=>'L',
+41349=>'L',
+41350=>'L',
+41351=>'L',
+41352=>'L',
+41353=>'L',
+41354=>'L',
+41355=>'L',
+41356=>'L',
+41357=>'L',
+41358=>'L',
+41359=>'L',
+41360=>'L',
+41361=>'L',
+41362=>'L',
+41363=>'L',
+41364=>'L',
+41365=>'L',
+41366=>'L',
+41367=>'L',
+41368=>'L',
+41369=>'L',
+41370=>'L',
+41371=>'L',
+41372=>'L',
+41373=>'L',
+41374=>'L',
+41375=>'L',
+41376=>'L',
+41377=>'L',
+41378=>'L',
+41379=>'L',
+41380=>'L',
+41381=>'L',
+41382=>'L',
+41383=>'L',
+41384=>'L',
+41385=>'L',
+41386=>'L',
+41387=>'L',
+41388=>'L',
+41389=>'L',
+41390=>'L',
+41391=>'L',
+41392=>'L',
+41393=>'L',
+41394=>'L',
+41395=>'L',
+41396=>'L',
+41397=>'L',
+41398=>'L',
+41399=>'L',
+41400=>'L',
+41401=>'L',
+41402=>'L',
+41403=>'L',
+41404=>'L',
+41405=>'L',
+41406=>'L',
+41407=>'L',
+41408=>'L',
+41409=>'L',
+41410=>'L',
+41411=>'L',
+41412=>'L',
+41413=>'L',
+41414=>'L',
+41415=>'L',
+41416=>'L',
+41417=>'L',
+41418=>'L',
+41419=>'L',
+41420=>'L',
+41421=>'L',
+41422=>'L',
+41423=>'L',
+41424=>'L',
+41425=>'L',
+41426=>'L',
+41427=>'L',
+41428=>'L',
+41429=>'L',
+41430=>'L',
+41431=>'L',
+41432=>'L',
+41433=>'L',
+41434=>'L',
+41435=>'L',
+41436=>'L',
+41437=>'L',
+41438=>'L',
+41439=>'L',
+41440=>'L',
+41441=>'L',
+41442=>'L',
+41443=>'L',
+41444=>'L',
+41445=>'L',
+41446=>'L',
+41447=>'L',
+41448=>'L',
+41449=>'L',
+41450=>'L',
+41451=>'L',
+41452=>'L',
+41453=>'L',
+41454=>'L',
+41455=>'L',
+41456=>'L',
+41457=>'L',
+41458=>'L',
+41459=>'L',
+41460=>'L',
+41461=>'L',
+41462=>'L',
+41463=>'L',
+41464=>'L',
+41465=>'L',
+41466=>'L',
+41467=>'L',
+41468=>'L',
+41469=>'L',
+41470=>'L',
+41471=>'L',
+41472=>'L',
+41473=>'L',
+41474=>'L',
+41475=>'L',
+41476=>'L',
+41477=>'L',
+41478=>'L',
+41479=>'L',
+41480=>'L',
+41481=>'L',
+41482=>'L',
+41483=>'L',
+41484=>'L',
+41485=>'L',
+41486=>'L',
+41487=>'L',
+41488=>'L',
+41489=>'L',
+41490=>'L',
+41491=>'L',
+41492=>'L',
+41493=>'L',
+41494=>'L',
+41495=>'L',
+41496=>'L',
+41497=>'L',
+41498=>'L',
+41499=>'L',
+41500=>'L',
+41501=>'L',
+41502=>'L',
+41503=>'L',
+41504=>'L',
+41505=>'L',
+41506=>'L',
+41507=>'L',
+41508=>'L',
+41509=>'L',
+41510=>'L',
+41511=>'L',
+41512=>'L',
+41513=>'L',
+41514=>'L',
+41515=>'L',
+41516=>'L',
+41517=>'L',
+41518=>'L',
+41519=>'L',
+41520=>'L',
+41521=>'L',
+41522=>'L',
+41523=>'L',
+41524=>'L',
+41525=>'L',
+41526=>'L',
+41527=>'L',
+41528=>'L',
+41529=>'L',
+41530=>'L',
+41531=>'L',
+41532=>'L',
+41533=>'L',
+41534=>'L',
+41535=>'L',
+41536=>'L',
+41537=>'L',
+41538=>'L',
+41539=>'L',
+41540=>'L',
+41541=>'L',
+41542=>'L',
+41543=>'L',
+41544=>'L',
+41545=>'L',
+41546=>'L',
+41547=>'L',
+41548=>'L',
+41549=>'L',
+41550=>'L',
+41551=>'L',
+41552=>'L',
+41553=>'L',
+41554=>'L',
+41555=>'L',
+41556=>'L',
+41557=>'L',
+41558=>'L',
+41559=>'L',
+41560=>'L',
+41561=>'L',
+41562=>'L',
+41563=>'L',
+41564=>'L',
+41565=>'L',
+41566=>'L',
+41567=>'L',
+41568=>'L',
+41569=>'L',
+41570=>'L',
+41571=>'L',
+41572=>'L',
+41573=>'L',
+41574=>'L',
+41575=>'L',
+41576=>'L',
+41577=>'L',
+41578=>'L',
+41579=>'L',
+41580=>'L',
+41581=>'L',
+41582=>'L',
+41583=>'L',
+41584=>'L',
+41585=>'L',
+41586=>'L',
+41587=>'L',
+41588=>'L',
+41589=>'L',
+41590=>'L',
+41591=>'L',
+41592=>'L',
+41593=>'L',
+41594=>'L',
+41595=>'L',
+41596=>'L',
+41597=>'L',
+41598=>'L',
+41599=>'L',
+41600=>'L',
+41601=>'L',
+41602=>'L',
+41603=>'L',
+41604=>'L',
+41605=>'L',
+41606=>'L',
+41607=>'L',
+41608=>'L',
+41609=>'L',
+41610=>'L',
+41611=>'L',
+41612=>'L',
+41613=>'L',
+41614=>'L',
+41615=>'L',
+41616=>'L',
+41617=>'L',
+41618=>'L',
+41619=>'L',
+41620=>'L',
+41621=>'L',
+41622=>'L',
+41623=>'L',
+41624=>'L',
+41625=>'L',
+41626=>'L',
+41627=>'L',
+41628=>'L',
+41629=>'L',
+41630=>'L',
+41631=>'L',
+41632=>'L',
+41633=>'L',
+41634=>'L',
+41635=>'L',
+41636=>'L',
+41637=>'L',
+41638=>'L',
+41639=>'L',
+41640=>'L',
+41641=>'L',
+41642=>'L',
+41643=>'L',
+41644=>'L',
+41645=>'L',
+41646=>'L',
+41647=>'L',
+41648=>'L',
+41649=>'L',
+41650=>'L',
+41651=>'L',
+41652=>'L',
+41653=>'L',
+41654=>'L',
+41655=>'L',
+41656=>'L',
+41657=>'L',
+41658=>'L',
+41659=>'L',
+41660=>'L',
+41661=>'L',
+41662=>'L',
+41663=>'L',
+41664=>'L',
+41665=>'L',
+41666=>'L',
+41667=>'L',
+41668=>'L',
+41669=>'L',
+41670=>'L',
+41671=>'L',
+41672=>'L',
+41673=>'L',
+41674=>'L',
+41675=>'L',
+41676=>'L',
+41677=>'L',
+41678=>'L',
+41679=>'L',
+41680=>'L',
+41681=>'L',
+41682=>'L',
+41683=>'L',
+41684=>'L',
+41685=>'L',
+41686=>'L',
+41687=>'L',
+41688=>'L',
+41689=>'L',
+41690=>'L',
+41691=>'L',
+41692=>'L',
+41693=>'L',
+41694=>'L',
+41695=>'L',
+41696=>'L',
+41697=>'L',
+41698=>'L',
+41699=>'L',
+41700=>'L',
+41701=>'L',
+41702=>'L',
+41703=>'L',
+41704=>'L',
+41705=>'L',
+41706=>'L',
+41707=>'L',
+41708=>'L',
+41709=>'L',
+41710=>'L',
+41711=>'L',
+41712=>'L',
+41713=>'L',
+41714=>'L',
+41715=>'L',
+41716=>'L',
+41717=>'L',
+41718=>'L',
+41719=>'L',
+41720=>'L',
+41721=>'L',
+41722=>'L',
+41723=>'L',
+41724=>'L',
+41725=>'L',
+41726=>'L',
+41727=>'L',
+41728=>'L',
+41729=>'L',
+41730=>'L',
+41731=>'L',
+41732=>'L',
+41733=>'L',
+41734=>'L',
+41735=>'L',
+41736=>'L',
+41737=>'L',
+41738=>'L',
+41739=>'L',
+41740=>'L',
+41741=>'L',
+41742=>'L',
+41743=>'L',
+41744=>'L',
+41745=>'L',
+41746=>'L',
+41747=>'L',
+41748=>'L',
+41749=>'L',
+41750=>'L',
+41751=>'L',
+41752=>'L',
+41753=>'L',
+41754=>'L',
+41755=>'L',
+41756=>'L',
+41757=>'L',
+41758=>'L',
+41759=>'L',
+41760=>'L',
+41761=>'L',
+41762=>'L',
+41763=>'L',
+41764=>'L',
+41765=>'L',
+41766=>'L',
+41767=>'L',
+41768=>'L',
+41769=>'L',
+41770=>'L',
+41771=>'L',
+41772=>'L',
+41773=>'L',
+41774=>'L',
+41775=>'L',
+41776=>'L',
+41777=>'L',
+41778=>'L',
+41779=>'L',
+41780=>'L',
+41781=>'L',
+41782=>'L',
+41783=>'L',
+41784=>'L',
+41785=>'L',
+41786=>'L',
+41787=>'L',
+41788=>'L',
+41789=>'L',
+41790=>'L',
+41791=>'L',
+41792=>'L',
+41793=>'L',
+41794=>'L',
+41795=>'L',
+41796=>'L',
+41797=>'L',
+41798=>'L',
+41799=>'L',
+41800=>'L',
+41801=>'L',
+41802=>'L',
+41803=>'L',
+41804=>'L',
+41805=>'L',
+41806=>'L',
+41807=>'L',
+41808=>'L',
+41809=>'L',
+41810=>'L',
+41811=>'L',
+41812=>'L',
+41813=>'L',
+41814=>'L',
+41815=>'L',
+41816=>'L',
+41817=>'L',
+41818=>'L',
+41819=>'L',
+41820=>'L',
+41821=>'L',
+41822=>'L',
+41823=>'L',
+41824=>'L',
+41825=>'L',
+41826=>'L',
+41827=>'L',
+41828=>'L',
+41829=>'L',
+41830=>'L',
+41831=>'L',
+41832=>'L',
+41833=>'L',
+41834=>'L',
+41835=>'L',
+41836=>'L',
+41837=>'L',
+41838=>'L',
+41839=>'L',
+41840=>'L',
+41841=>'L',
+41842=>'L',
+41843=>'L',
+41844=>'L',
+41845=>'L',
+41846=>'L',
+41847=>'L',
+41848=>'L',
+41849=>'L',
+41850=>'L',
+41851=>'L',
+41852=>'L',
+41853=>'L',
+41854=>'L',
+41855=>'L',
+41856=>'L',
+41857=>'L',
+41858=>'L',
+41859=>'L',
+41860=>'L',
+41861=>'L',
+41862=>'L',
+41863=>'L',
+41864=>'L',
+41865=>'L',
+41866=>'L',
+41867=>'L',
+41868=>'L',
+41869=>'L',
+41870=>'L',
+41871=>'L',
+41872=>'L',
+41873=>'L',
+41874=>'L',
+41875=>'L',
+41876=>'L',
+41877=>'L',
+41878=>'L',
+41879=>'L',
+41880=>'L',
+41881=>'L',
+41882=>'L',
+41883=>'L',
+41884=>'L',
+41885=>'L',
+41886=>'L',
+41887=>'L',
+41888=>'L',
+41889=>'L',
+41890=>'L',
+41891=>'L',
+41892=>'L',
+41893=>'L',
+41894=>'L',
+41895=>'L',
+41896=>'L',
+41897=>'L',
+41898=>'L',
+41899=>'L',
+41900=>'L',
+41901=>'L',
+41902=>'L',
+41903=>'L',
+41904=>'L',
+41905=>'L',
+41906=>'L',
+41907=>'L',
+41908=>'L',
+41909=>'L',
+41910=>'L',
+41911=>'L',
+41912=>'L',
+41913=>'L',
+41914=>'L',
+41915=>'L',
+41916=>'L',
+41917=>'L',
+41918=>'L',
+41919=>'L',
+41920=>'L',
+41921=>'L',
+41922=>'L',
+41923=>'L',
+41924=>'L',
+41925=>'L',
+41926=>'L',
+41927=>'L',
+41928=>'L',
+41929=>'L',
+41930=>'L',
+41931=>'L',
+41932=>'L',
+41933=>'L',
+41934=>'L',
+41935=>'L',
+41936=>'L',
+41937=>'L',
+41938=>'L',
+41939=>'L',
+41940=>'L',
+41941=>'L',
+41942=>'L',
+41943=>'L',
+41944=>'L',
+41945=>'L',
+41946=>'L',
+41947=>'L',
+41948=>'L',
+41949=>'L',
+41950=>'L',
+41951=>'L',
+41952=>'L',
+41953=>'L',
+41954=>'L',
+41955=>'L',
+41956=>'L',
+41957=>'L',
+41958=>'L',
+41959=>'L',
+41960=>'L',
+41961=>'L',
+41962=>'L',
+41963=>'L',
+41964=>'L',
+41965=>'L',
+41966=>'L',
+41967=>'L',
+41968=>'L',
+41969=>'L',
+41970=>'L',
+41971=>'L',
+41972=>'L',
+41973=>'L',
+41974=>'L',
+41975=>'L',
+41976=>'L',
+41977=>'L',
+41978=>'L',
+41979=>'L',
+41980=>'L',
+41981=>'L',
+41982=>'L',
+41983=>'L',
+41984=>'L',
+41985=>'L',
+41986=>'L',
+41987=>'L',
+41988=>'L',
+41989=>'L',
+41990=>'L',
+41991=>'L',
+41992=>'L',
+41993=>'L',
+41994=>'L',
+41995=>'L',
+41996=>'L',
+41997=>'L',
+41998=>'L',
+41999=>'L',
+42000=>'L',
+42001=>'L',
+42002=>'L',
+42003=>'L',
+42004=>'L',
+42005=>'L',
+42006=>'L',
+42007=>'L',
+42008=>'L',
+42009=>'L',
+42010=>'L',
+42011=>'L',
+42012=>'L',
+42013=>'L',
+42014=>'L',
+42015=>'L',
+42016=>'L',
+42017=>'L',
+42018=>'L',
+42019=>'L',
+42020=>'L',
+42021=>'L',
+42022=>'L',
+42023=>'L',
+42024=>'L',
+42025=>'L',
+42026=>'L',
+42027=>'L',
+42028=>'L',
+42029=>'L',
+42030=>'L',
+42031=>'L',
+42032=>'L',
+42033=>'L',
+42034=>'L',
+42035=>'L',
+42036=>'L',
+42037=>'L',
+42038=>'L',
+42039=>'L',
+42040=>'L',
+42041=>'L',
+42042=>'L',
+42043=>'L',
+42044=>'L',
+42045=>'L',
+42046=>'L',
+42047=>'L',
+42048=>'L',
+42049=>'L',
+42050=>'L',
+42051=>'L',
+42052=>'L',
+42053=>'L',
+42054=>'L',
+42055=>'L',
+42056=>'L',
+42057=>'L',
+42058=>'L',
+42059=>'L',
+42060=>'L',
+42061=>'L',
+42062=>'L',
+42063=>'L',
+42064=>'L',
+42065=>'L',
+42066=>'L',
+42067=>'L',
+42068=>'L',
+42069=>'L',
+42070=>'L',
+42071=>'L',
+42072=>'L',
+42073=>'L',
+42074=>'L',
+42075=>'L',
+42076=>'L',
+42077=>'L',
+42078=>'L',
+42079=>'L',
+42080=>'L',
+42081=>'L',
+42082=>'L',
+42083=>'L',
+42084=>'L',
+42085=>'L',
+42086=>'L',
+42087=>'L',
+42088=>'L',
+42089=>'L',
+42090=>'L',
+42091=>'L',
+42092=>'L',
+42093=>'L',
+42094=>'L',
+42095=>'L',
+42096=>'L',
+42097=>'L',
+42098=>'L',
+42099=>'L',
+42100=>'L',
+42101=>'L',
+42102=>'L',
+42103=>'L',
+42104=>'L',
+42105=>'L',
+42106=>'L',
+42107=>'L',
+42108=>'L',
+42109=>'L',
+42110=>'L',
+42111=>'L',
+42112=>'L',
+42113=>'L',
+42114=>'L',
+42115=>'L',
+42116=>'L',
+42117=>'L',
+42118=>'L',
+42119=>'L',
+42120=>'L',
+42121=>'L',
+42122=>'L',
+42123=>'L',
+42124=>'L',
+42128=>'ON',
+42129=>'ON',
+42130=>'ON',
+42131=>'ON',
+42132=>'ON',
+42133=>'ON',
+42134=>'ON',
+42135=>'ON',
+42136=>'ON',
+42137=>'ON',
+42138=>'ON',
+42139=>'ON',
+42140=>'ON',
+42141=>'ON',
+42142=>'ON',
+42143=>'ON',
+42144=>'ON',
+42145=>'ON',
+42146=>'ON',
+42147=>'ON',
+42148=>'ON',
+42149=>'ON',
+42150=>'ON',
+42151=>'ON',
+42152=>'ON',
+42153=>'ON',
+42154=>'ON',
+42155=>'ON',
+42156=>'ON',
+42157=>'ON',
+42158=>'ON',
+42159=>'ON',
+42160=>'ON',
+42161=>'ON',
+42162=>'ON',
+42163=>'ON',
+42164=>'ON',
+42165=>'ON',
+42166=>'ON',
+42167=>'ON',
+42168=>'ON',
+42169=>'ON',
+42170=>'ON',
+42171=>'ON',
+42172=>'ON',
+42173=>'ON',
+42174=>'ON',
+42175=>'ON',
+42176=>'ON',
+42177=>'ON',
+42178=>'ON',
+42179=>'ON',
+42180=>'ON',
+42181=>'ON',
+42182=>'ON',
+42752=>'ON',
+42753=>'ON',
+42754=>'ON',
+42755=>'ON',
+42756=>'ON',
+42757=>'ON',
+42758=>'ON',
+42759=>'ON',
+42760=>'ON',
+42761=>'ON',
+42762=>'ON',
+42763=>'ON',
+42764=>'ON',
+42765=>'ON',
+42766=>'ON',
+42767=>'ON',
+42768=>'ON',
+42769=>'ON',
+42770=>'ON',
+42771=>'ON',
+42772=>'ON',
+42773=>'ON',
+42774=>'ON',
+42775=>'ON',
+42776=>'ON',
+42777=>'ON',
+42778=>'ON',
+42784=>'ON',
+42785=>'ON',
+43008=>'L',
+43009=>'L',
+43010=>'NSM',
+43011=>'L',
+43012=>'L',
+43013=>'L',
+43014=>'NSM',
+43015=>'L',
+43016=>'L',
+43017=>'L',
+43018=>'L',
+43019=>'NSM',
+43020=>'L',
+43021=>'L',
+43022=>'L',
+43023=>'L',
+43024=>'L',
+43025=>'L',
+43026=>'L',
+43027=>'L',
+43028=>'L',
+43029=>'L',
+43030=>'L',
+43031=>'L',
+43032=>'L',
+43033=>'L',
+43034=>'L',
+43035=>'L',
+43036=>'L',
+43037=>'L',
+43038=>'L',
+43039=>'L',
+43040=>'L',
+43041=>'L',
+43042=>'L',
+43043=>'L',
+43044=>'L',
+43045=>'NSM',
+43046=>'NSM',
+43047=>'L',
+43048=>'ON',
+43049=>'ON',
+43050=>'ON',
+43051=>'ON',
+43072=>'L',
+43073=>'L',
+43074=>'L',
+43075=>'L',
+43076=>'L',
+43077=>'L',
+43078=>'L',
+43079=>'L',
+43080=>'L',
+43081=>'L',
+43082=>'L',
+43083=>'L',
+43084=>'L',
+43085=>'L',
+43086=>'L',
+43087=>'L',
+43088=>'L',
+43089=>'L',
+43090=>'L',
+43091=>'L',
+43092=>'L',
+43093=>'L',
+43094=>'L',
+43095=>'L',
+43096=>'L',
+43097=>'L',
+43098=>'L',
+43099=>'L',
+43100=>'L',
+43101=>'L',
+43102=>'L',
+43103=>'L',
+43104=>'L',
+43105=>'L',
+43106=>'L',
+43107=>'L',
+43108=>'L',
+43109=>'L',
+43110=>'L',
+43111=>'L',
+43112=>'L',
+43113=>'L',
+43114=>'L',
+43115=>'L',
+43116=>'L',
+43117=>'L',
+43118=>'L',
+43119=>'L',
+43120=>'L',
+43121=>'L',
+43122=>'L',
+43123=>'L',
+43124=>'ON',
+43125=>'ON',
+43126=>'ON',
+43127=>'ON',
+44032=>'L',
+55203=>'L',
+55296=>'L',
+56191=>'L',
+56192=>'L',
+56319=>'L',
+56320=>'L',
+57343=>'L',
+57344=>'L',
+63743=>'L',
+63744=>'L',
+63745=>'L',
+63746=>'L',
+63747=>'L',
+63748=>'L',
+63749=>'L',
+63750=>'L',
+63751=>'L',
+63752=>'L',
+63753=>'L',
+63754=>'L',
+63755=>'L',
+63756=>'L',
+63757=>'L',
+63758=>'L',
+63759=>'L',
+63760=>'L',
+63761=>'L',
+63762=>'L',
+63763=>'L',
+63764=>'L',
+63765=>'L',
+63766=>'L',
+63767=>'L',
+63768=>'L',
+63769=>'L',
+63770=>'L',
+63771=>'L',
+63772=>'L',
+63773=>'L',
+63774=>'L',
+63775=>'L',
+63776=>'L',
+63777=>'L',
+63778=>'L',
+63779=>'L',
+63780=>'L',
+63781=>'L',
+63782=>'L',
+63783=>'L',
+63784=>'L',
+63785=>'L',
+63786=>'L',
+63787=>'L',
+63788=>'L',
+63789=>'L',
+63790=>'L',
+63791=>'L',
+63792=>'L',
+63793=>'L',
+63794=>'L',
+63795=>'L',
+63796=>'L',
+63797=>'L',
+63798=>'L',
+63799=>'L',
+63800=>'L',
+63801=>'L',
+63802=>'L',
+63803=>'L',
+63804=>'L',
+63805=>'L',
+63806=>'L',
+63807=>'L',
+63808=>'L',
+63809=>'L',
+63810=>'L',
+63811=>'L',
+63812=>'L',
+63813=>'L',
+63814=>'L',
+63815=>'L',
+63816=>'L',
+63817=>'L',
+63818=>'L',
+63819=>'L',
+63820=>'L',
+63821=>'L',
+63822=>'L',
+63823=>'L',
+63824=>'L',
+63825=>'L',
+63826=>'L',
+63827=>'L',
+63828=>'L',
+63829=>'L',
+63830=>'L',
+63831=>'L',
+63832=>'L',
+63833=>'L',
+63834=>'L',
+63835=>'L',
+63836=>'L',
+63837=>'L',
+63838=>'L',
+63839=>'L',
+63840=>'L',
+63841=>'L',
+63842=>'L',
+63843=>'L',
+63844=>'L',
+63845=>'L',
+63846=>'L',
+63847=>'L',
+63848=>'L',
+63849=>'L',
+63850=>'L',
+63851=>'L',
+63852=>'L',
+63853=>'L',
+63854=>'L',
+63855=>'L',
+63856=>'L',
+63857=>'L',
+63858=>'L',
+63859=>'L',
+63860=>'L',
+63861=>'L',
+63862=>'L',
+63863=>'L',
+63864=>'L',
+63865=>'L',
+63866=>'L',
+63867=>'L',
+63868=>'L',
+63869=>'L',
+63870=>'L',
+63871=>'L',
+63872=>'L',
+63873=>'L',
+63874=>'L',
+63875=>'L',
+63876=>'L',
+63877=>'L',
+63878=>'L',
+63879=>'L',
+63880=>'L',
+63881=>'L',
+63882=>'L',
+63883=>'L',
+63884=>'L',
+63885=>'L',
+63886=>'L',
+63887=>'L',
+63888=>'L',
+63889=>'L',
+63890=>'L',
+63891=>'L',
+63892=>'L',
+63893=>'L',
+63894=>'L',
+63895=>'L',
+63896=>'L',
+63897=>'L',
+63898=>'L',
+63899=>'L',
+63900=>'L',
+63901=>'L',
+63902=>'L',
+63903=>'L',
+63904=>'L',
+63905=>'L',
+63906=>'L',
+63907=>'L',
+63908=>'L',
+63909=>'L',
+63910=>'L',
+63911=>'L',
+63912=>'L',
+63913=>'L',
+63914=>'L',
+63915=>'L',
+63916=>'L',
+63917=>'L',
+63918=>'L',
+63919=>'L',
+63920=>'L',
+63921=>'L',
+63922=>'L',
+63923=>'L',
+63924=>'L',
+63925=>'L',
+63926=>'L',
+63927=>'L',
+63928=>'L',
+63929=>'L',
+63930=>'L',
+63931=>'L',
+63932=>'L',
+63933=>'L',
+63934=>'L',
+63935=>'L',
+63936=>'L',
+63937=>'L',
+63938=>'L',
+63939=>'L',
+63940=>'L',
+63941=>'L',
+63942=>'L',
+63943=>'L',
+63944=>'L',
+63945=>'L',
+63946=>'L',
+63947=>'L',
+63948=>'L',
+63949=>'L',
+63950=>'L',
+63951=>'L',
+63952=>'L',
+63953=>'L',
+63954=>'L',
+63955=>'L',
+63956=>'L',
+63957=>'L',
+63958=>'L',
+63959=>'L',
+63960=>'L',
+63961=>'L',
+63962=>'L',
+63963=>'L',
+63964=>'L',
+63965=>'L',
+63966=>'L',
+63967=>'L',
+63968=>'L',
+63969=>'L',
+63970=>'L',
+63971=>'L',
+63972=>'L',
+63973=>'L',
+63974=>'L',
+63975=>'L',
+63976=>'L',
+63977=>'L',
+63978=>'L',
+63979=>'L',
+63980=>'L',
+63981=>'L',
+63982=>'L',
+63983=>'L',
+63984=>'L',
+63985=>'L',
+63986=>'L',
+63987=>'L',
+63988=>'L',
+63989=>'L',
+63990=>'L',
+63991=>'L',
+63992=>'L',
+63993=>'L',
+63994=>'L',
+63995=>'L',
+63996=>'L',
+63997=>'L',
+63998=>'L',
+63999=>'L',
+64000=>'L',
+64001=>'L',
+64002=>'L',
+64003=>'L',
+64004=>'L',
+64005=>'L',
+64006=>'L',
+64007=>'L',
+64008=>'L',
+64009=>'L',
+64010=>'L',
+64011=>'L',
+64012=>'L',
+64013=>'L',
+64014=>'L',
+64015=>'L',
+64016=>'L',
+64017=>'L',
+64018=>'L',
+64019=>'L',
+64020=>'L',
+64021=>'L',
+64022=>'L',
+64023=>'L',
+64024=>'L',
+64025=>'L',
+64026=>'L',
+64027=>'L',
+64028=>'L',
+64029=>'L',
+64030=>'L',
+64031=>'L',
+64032=>'L',
+64033=>'L',
+64034=>'L',
+64035=>'L',
+64036=>'L',
+64037=>'L',
+64038=>'L',
+64039=>'L',
+64040=>'L',
+64041=>'L',
+64042=>'L',
+64043=>'L',
+64044=>'L',
+64045=>'L',
+64048=>'L',
+64049=>'L',
+64050=>'L',
+64051=>'L',
+64052=>'L',
+64053=>'L',
+64054=>'L',
+64055=>'L',
+64056=>'L',
+64057=>'L',
+64058=>'L',
+64059=>'L',
+64060=>'L',
+64061=>'L',
+64062=>'L',
+64063=>'L',
+64064=>'L',
+64065=>'L',
+64066=>'L',
+64067=>'L',
+64068=>'L',
+64069=>'L',
+64070=>'L',
+64071=>'L',
+64072=>'L',
+64073=>'L',
+64074=>'L',
+64075=>'L',
+64076=>'L',
+64077=>'L',
+64078=>'L',
+64079=>'L',
+64080=>'L',
+64081=>'L',
+64082=>'L',
+64083=>'L',
+64084=>'L',
+64085=>'L',
+64086=>'L',
+64087=>'L',
+64088=>'L',
+64089=>'L',
+64090=>'L',
+64091=>'L',
+64092=>'L',
+64093=>'L',
+64094=>'L',
+64095=>'L',
+64096=>'L',
+64097=>'L',
+64098=>'L',
+64099=>'L',
+64100=>'L',
+64101=>'L',
+64102=>'L',
+64103=>'L',
+64104=>'L',
+64105=>'L',
+64106=>'L',
+64112=>'L',
+64113=>'L',
+64114=>'L',
+64115=>'L',
+64116=>'L',
+64117=>'L',
+64118=>'L',
+64119=>'L',
+64120=>'L',
+64121=>'L',
+64122=>'L',
+64123=>'L',
+64124=>'L',
+64125=>'L',
+64126=>'L',
+64127=>'L',
+64128=>'L',
+64129=>'L',
+64130=>'L',
+64131=>'L',
+64132=>'L',
+64133=>'L',
+64134=>'L',
+64135=>'L',
+64136=>'L',
+64137=>'L',
+64138=>'L',
+64139=>'L',
+64140=>'L',
+64141=>'L',
+64142=>'L',
+64143=>'L',
+64144=>'L',
+64145=>'L',
+64146=>'L',
+64147=>'L',
+64148=>'L',
+64149=>'L',
+64150=>'L',
+64151=>'L',
+64152=>'L',
+64153=>'L',
+64154=>'L',
+64155=>'L',
+64156=>'L',
+64157=>'L',
+64158=>'L',
+64159=>'L',
+64160=>'L',
+64161=>'L',
+64162=>'L',
+64163=>'L',
+64164=>'L',
+64165=>'L',
+64166=>'L',
+64167=>'L',
+64168=>'L',
+64169=>'L',
+64170=>'L',
+64171=>'L',
+64172=>'L',
+64173=>'L',
+64174=>'L',
+64175=>'L',
+64176=>'L',
+64177=>'L',
+64178=>'L',
+64179=>'L',
+64180=>'L',
+64181=>'L',
+64182=>'L',
+64183=>'L',
+64184=>'L',
+64185=>'L',
+64186=>'L',
+64187=>'L',
+64188=>'L',
+64189=>'L',
+64190=>'L',
+64191=>'L',
+64192=>'L',
+64193=>'L',
+64194=>'L',
+64195=>'L',
+64196=>'L',
+64197=>'L',
+64198=>'L',
+64199=>'L',
+64200=>'L',
+64201=>'L',
+64202=>'L',
+64203=>'L',
+64204=>'L',
+64205=>'L',
+64206=>'L',
+64207=>'L',
+64208=>'L',
+64209=>'L',
+64210=>'L',
+64211=>'L',
+64212=>'L',
+64213=>'L',
+64214=>'L',
+64215=>'L',
+64216=>'L',
+64217=>'L',
+64256=>'L',
+64257=>'L',
+64258=>'L',
+64259=>'L',
+64260=>'L',
+64261=>'L',
+64262=>'L',
+64275=>'L',
+64276=>'L',
+64277=>'L',
+64278=>'L',
+64279=>'L',
+64285=>'R',
+64286=>'NSM',
+64287=>'R',
+64288=>'R',
+64289=>'R',
+64290=>'R',
+64291=>'R',
+64292=>'R',
+64293=>'R',
+64294=>'R',
+64295=>'R',
+64296=>'R',
+64297=>'ES',
+64298=>'R',
+64299=>'R',
+64300=>'R',
+64301=>'R',
+64302=>'R',
+64303=>'R',
+64304=>'R',
+64305=>'R',
+64306=>'R',
+64307=>'R',
+64308=>'R',
+64309=>'R',
+64310=>'R',
+64312=>'R',
+64313=>'R',
+64314=>'R',
+64315=>'R',
+64316=>'R',
+64318=>'R',
+64320=>'R',
+64321=>'R',
+64323=>'R',
+64324=>'R',
+64326=>'R',
+64327=>'R',
+64328=>'R',
+64329=>'R',
+64330=>'R',
+64331=>'R',
+64332=>'R',
+64333=>'R',
+64334=>'R',
+64335=>'R',
+64336=>'AL',
+64337=>'AL',
+64338=>'AL',
+64339=>'AL',
+64340=>'AL',
+64341=>'AL',
+64342=>'AL',
+64343=>'AL',
+64344=>'AL',
+64345=>'AL',
+64346=>'AL',
+64347=>'AL',
+64348=>'AL',
+64349=>'AL',
+64350=>'AL',
+64351=>'AL',
+64352=>'AL',
+64353=>'AL',
+64354=>'AL',
+64355=>'AL',
+64356=>'AL',
+64357=>'AL',
+64358=>'AL',
+64359=>'AL',
+64360=>'AL',
+64361=>'AL',
+64362=>'AL',
+64363=>'AL',
+64364=>'AL',
+64365=>'AL',
+64366=>'AL',
+64367=>'AL',
+64368=>'AL',
+64369=>'AL',
+64370=>'AL',
+64371=>'AL',
+64372=>'AL',
+64373=>'AL',
+64374=>'AL',
+64375=>'AL',
+64376=>'AL',
+64377=>'AL',
+64378=>'AL',
+64379=>'AL',
+64380=>'AL',
+64381=>'AL',
+64382=>'AL',
+64383=>'AL',
+64384=>'AL',
+64385=>'AL',
+64386=>'AL',
+64387=>'AL',
+64388=>'AL',
+64389=>'AL',
+64390=>'AL',
+64391=>'AL',
+64392=>'AL',
+64393=>'AL',
+64394=>'AL',
+64395=>'AL',
+64396=>'AL',
+64397=>'AL',
+64398=>'AL',
+64399=>'AL',
+64400=>'AL',
+64401=>'AL',
+64402=>'AL',
+64403=>'AL',
+64404=>'AL',
+64405=>'AL',
+64406=>'AL',
+64407=>'AL',
+64408=>'AL',
+64409=>'AL',
+64410=>'AL',
+64411=>'AL',
+64412=>'AL',
+64413=>'AL',
+64414=>'AL',
+64415=>'AL',
+64416=>'AL',
+64417=>'AL',
+64418=>'AL',
+64419=>'AL',
+64420=>'AL',
+64421=>'AL',
+64422=>'AL',
+64423=>'AL',
+64424=>'AL',
+64425=>'AL',
+64426=>'AL',
+64427=>'AL',
+64428=>'AL',
+64429=>'AL',
+64430=>'AL',
+64431=>'AL',
+64432=>'AL',
+64433=>'AL',
+64467=>'AL',
+64468=>'AL',
+64469=>'AL',
+64470=>'AL',
+64471=>'AL',
+64472=>'AL',
+64473=>'AL',
+64474=>'AL',
+64475=>'AL',
+64476=>'AL',
+64477=>'AL',
+64478=>'AL',
+64479=>'AL',
+64480=>'AL',
+64481=>'AL',
+64482=>'AL',
+64483=>'AL',
+64484=>'AL',
+64485=>'AL',
+64486=>'AL',
+64487=>'AL',
+64488=>'AL',
+64489=>'AL',
+64490=>'AL',
+64491=>'AL',
+64492=>'AL',
+64493=>'AL',
+64494=>'AL',
+64495=>'AL',
+64496=>'AL',
+64497=>'AL',
+64498=>'AL',
+64499=>'AL',
+64500=>'AL',
+64501=>'AL',
+64502=>'AL',
+64503=>'AL',
+64504=>'AL',
+64505=>'AL',
+64506=>'AL',
+64507=>'AL',
+64508=>'AL',
+64509=>'AL',
+64510=>'AL',
+64511=>'AL',
+64512=>'AL',
+64513=>'AL',
+64514=>'AL',
+64515=>'AL',
+64516=>'AL',
+64517=>'AL',
+64518=>'AL',
+64519=>'AL',
+64520=>'AL',
+64521=>'AL',
+64522=>'AL',
+64523=>'AL',
+64524=>'AL',
+64525=>'AL',
+64526=>'AL',
+64527=>'AL',
+64528=>'AL',
+64529=>'AL',
+64530=>'AL',
+64531=>'AL',
+64532=>'AL',
+64533=>'AL',
+64534=>'AL',
+64535=>'AL',
+64536=>'AL',
+64537=>'AL',
+64538=>'AL',
+64539=>'AL',
+64540=>'AL',
+64541=>'AL',
+64542=>'AL',
+64543=>'AL',
+64544=>'AL',
+64545=>'AL',
+64546=>'AL',
+64547=>'AL',
+64548=>'AL',
+64549=>'AL',
+64550=>'AL',
+64551=>'AL',
+64552=>'AL',
+64553=>'AL',
+64554=>'AL',
+64555=>'AL',
+64556=>'AL',
+64557=>'AL',
+64558=>'AL',
+64559=>'AL',
+64560=>'AL',
+64561=>'AL',
+64562=>'AL',
+64563=>'AL',
+64564=>'AL',
+64565=>'AL',
+64566=>'AL',
+64567=>'AL',
+64568=>'AL',
+64569=>'AL',
+64570=>'AL',
+64571=>'AL',
+64572=>'AL',
+64573=>'AL',
+64574=>'AL',
+64575=>'AL',
+64576=>'AL',
+64577=>'AL',
+64578=>'AL',
+64579=>'AL',
+64580=>'AL',
+64581=>'AL',
+64582=>'AL',
+64583=>'AL',
+64584=>'AL',
+64585=>'AL',
+64586=>'AL',
+64587=>'AL',
+64588=>'AL',
+64589=>'AL',
+64590=>'AL',
+64591=>'AL',
+64592=>'AL',
+64593=>'AL',
+64594=>'AL',
+64595=>'AL',
+64596=>'AL',
+64597=>'AL',
+64598=>'AL',
+64599=>'AL',
+64600=>'AL',
+64601=>'AL',
+64602=>'AL',
+64603=>'AL',
+64604=>'AL',
+64605=>'AL',
+64606=>'AL',
+64607=>'AL',
+64608=>'AL',
+64609=>'AL',
+64610=>'AL',
+64611=>'AL',
+64612=>'AL',
+64613=>'AL',
+64614=>'AL',
+64615=>'AL',
+64616=>'AL',
+64617=>'AL',
+64618=>'AL',
+64619=>'AL',
+64620=>'AL',
+64621=>'AL',
+64622=>'AL',
+64623=>'AL',
+64624=>'AL',
+64625=>'AL',
+64626=>'AL',
+64627=>'AL',
+64628=>'AL',
+64629=>'AL',
+64630=>'AL',
+64631=>'AL',
+64632=>'AL',
+64633=>'AL',
+64634=>'AL',
+64635=>'AL',
+64636=>'AL',
+64637=>'AL',
+64638=>'AL',
+64639=>'AL',
+64640=>'AL',
+64641=>'AL',
+64642=>'AL',
+64643=>'AL',
+64644=>'AL',
+64645=>'AL',
+64646=>'AL',
+64647=>'AL',
+64648=>'AL',
+64649=>'AL',
+64650=>'AL',
+64651=>'AL',
+64652=>'AL',
+64653=>'AL',
+64654=>'AL',
+64655=>'AL',
+64656=>'AL',
+64657=>'AL',
+64658=>'AL',
+64659=>'AL',
+64660=>'AL',
+64661=>'AL',
+64662=>'AL',
+64663=>'AL',
+64664=>'AL',
+64665=>'AL',
+64666=>'AL',
+64667=>'AL',
+64668=>'AL',
+64669=>'AL',
+64670=>'AL',
+64671=>'AL',
+64672=>'AL',
+64673=>'AL',
+64674=>'AL',
+64675=>'AL',
+64676=>'AL',
+64677=>'AL',
+64678=>'AL',
+64679=>'AL',
+64680=>'AL',
+64681=>'AL',
+64682=>'AL',
+64683=>'AL',
+64684=>'AL',
+64685=>'AL',
+64686=>'AL',
+64687=>'AL',
+64688=>'AL',
+64689=>'AL',
+64690=>'AL',
+64691=>'AL',
+64692=>'AL',
+64693=>'AL',
+64694=>'AL',
+64695=>'AL',
+64696=>'AL',
+64697=>'AL',
+64698=>'AL',
+64699=>'AL',
+64700=>'AL',
+64701=>'AL',
+64702=>'AL',
+64703=>'AL',
+64704=>'AL',
+64705=>'AL',
+64706=>'AL',
+64707=>'AL',
+64708=>'AL',
+64709=>'AL',
+64710=>'AL',
+64711=>'AL',
+64712=>'AL',
+64713=>'AL',
+64714=>'AL',
+64715=>'AL',
+64716=>'AL',
+64717=>'AL',
+64718=>'AL',
+64719=>'AL',
+64720=>'AL',
+64721=>'AL',
+64722=>'AL',
+64723=>'AL',
+64724=>'AL',
+64725=>'AL',
+64726=>'AL',
+64727=>'AL',
+64728=>'AL',
+64729=>'AL',
+64730=>'AL',
+64731=>'AL',
+64732=>'AL',
+64733=>'AL',
+64734=>'AL',
+64735=>'AL',
+64736=>'AL',
+64737=>'AL',
+64738=>'AL',
+64739=>'AL',
+64740=>'AL',
+64741=>'AL',
+64742=>'AL',
+64743=>'AL',
+64744=>'AL',
+64745=>'AL',
+64746=>'AL',
+64747=>'AL',
+64748=>'AL',
+64749=>'AL',
+64750=>'AL',
+64751=>'AL',
+64752=>'AL',
+64753=>'AL',
+64754=>'AL',
+64755=>'AL',
+64756=>'AL',
+64757=>'AL',
+64758=>'AL',
+64759=>'AL',
+64760=>'AL',
+64761=>'AL',
+64762=>'AL',
+64763=>'AL',
+64764=>'AL',
+64765=>'AL',
+64766=>'AL',
+64767=>'AL',
+64768=>'AL',
+64769=>'AL',
+64770=>'AL',
+64771=>'AL',
+64772=>'AL',
+64773=>'AL',
+64774=>'AL',
+64775=>'AL',
+64776=>'AL',
+64777=>'AL',
+64778=>'AL',
+64779=>'AL',
+64780=>'AL',
+64781=>'AL',
+64782=>'AL',
+64783=>'AL',
+64784=>'AL',
+64785=>'AL',
+64786=>'AL',
+64787=>'AL',
+64788=>'AL',
+64789=>'AL',
+64790=>'AL',
+64791=>'AL',
+64792=>'AL',
+64793=>'AL',
+64794=>'AL',
+64795=>'AL',
+64796=>'AL',
+64797=>'AL',
+64798=>'AL',
+64799=>'AL',
+64800=>'AL',
+64801=>'AL',
+64802=>'AL',
+64803=>'AL',
+64804=>'AL',
+64805=>'AL',
+64806=>'AL',
+64807=>'AL',
+64808=>'AL',
+64809=>'AL',
+64810=>'AL',
+64811=>'AL',
+64812=>'AL',
+64813=>'AL',
+64814=>'AL',
+64815=>'AL',
+64816=>'AL',
+64817=>'AL',
+64818=>'AL',
+64819=>'AL',
+64820=>'AL',
+64821=>'AL',
+64822=>'AL',
+64823=>'AL',
+64824=>'AL',
+64825=>'AL',
+64826=>'AL',
+64827=>'AL',
+64828=>'AL',
+64829=>'AL',
+64830=>'ON',
+64831=>'ON',
+64848=>'AL',
+64849=>'AL',
+64850=>'AL',
+64851=>'AL',
+64852=>'AL',
+64853=>'AL',
+64854=>'AL',
+64855=>'AL',
+64856=>'AL',
+64857=>'AL',
+64858=>'AL',
+64859=>'AL',
+64860=>'AL',
+64861=>'AL',
+64862=>'AL',
+64863=>'AL',
+64864=>'AL',
+64865=>'AL',
+64866=>'AL',
+64867=>'AL',
+64868=>'AL',
+64869=>'AL',
+64870=>'AL',
+64871=>'AL',
+64872=>'AL',
+64873=>'AL',
+64874=>'AL',
+64875=>'AL',
+64876=>'AL',
+64877=>'AL',
+64878=>'AL',
+64879=>'AL',
+64880=>'AL',
+64881=>'AL',
+64882=>'AL',
+64883=>'AL',
+64884=>'AL',
+64885=>'AL',
+64886=>'AL',
+64887=>'AL',
+64888=>'AL',
+64889=>'AL',
+64890=>'AL',
+64891=>'AL',
+64892=>'AL',
+64893=>'AL',
+64894=>'AL',
+64895=>'AL',
+64896=>'AL',
+64897=>'AL',
+64898=>'AL',
+64899=>'AL',
+64900=>'AL',
+64901=>'AL',
+64902=>'AL',
+64903=>'AL',
+64904=>'AL',
+64905=>'AL',
+64906=>'AL',
+64907=>'AL',
+64908=>'AL',
+64909=>'AL',
+64910=>'AL',
+64911=>'AL',
+64914=>'AL',
+64915=>'AL',
+64916=>'AL',
+64917=>'AL',
+64918=>'AL',
+64919=>'AL',
+64920=>'AL',
+64921=>'AL',
+64922=>'AL',
+64923=>'AL',
+64924=>'AL',
+64925=>'AL',
+64926=>'AL',
+64927=>'AL',
+64928=>'AL',
+64929=>'AL',
+64930=>'AL',
+64931=>'AL',
+64932=>'AL',
+64933=>'AL',
+64934=>'AL',
+64935=>'AL',
+64936=>'AL',
+64937=>'AL',
+64938=>'AL',
+64939=>'AL',
+64940=>'AL',
+64941=>'AL',
+64942=>'AL',
+64943=>'AL',
+64944=>'AL',
+64945=>'AL',
+64946=>'AL',
+64947=>'AL',
+64948=>'AL',
+64949=>'AL',
+64950=>'AL',
+64951=>'AL',
+64952=>'AL',
+64953=>'AL',
+64954=>'AL',
+64955=>'AL',
+64956=>'AL',
+64957=>'AL',
+64958=>'AL',
+64959=>'AL',
+64960=>'AL',
+64961=>'AL',
+64962=>'AL',
+64963=>'AL',
+64964=>'AL',
+64965=>'AL',
+64966=>'AL',
+64967=>'AL',
+65008=>'AL',
+65009=>'AL',
+65010=>'AL',
+65011=>'AL',
+65012=>'AL',
+65013=>'AL',
+65014=>'AL',
+65015=>'AL',
+65016=>'AL',
+65017=>'AL',
+65018=>'AL',
+65019=>'AL',
+65020=>'AL',
+65021=>'ON',
+65024=>'NSM',
+65025=>'NSM',
+65026=>'NSM',
+65027=>'NSM',
+65028=>'NSM',
+65029=>'NSM',
+65030=>'NSM',
+65031=>'NSM',
+65032=>'NSM',
+65033=>'NSM',
+65034=>'NSM',
+65035=>'NSM',
+65036=>'NSM',
+65037=>'NSM',
+65038=>'NSM',
+65039=>'NSM',
+65040=>'ON',
+65041=>'ON',
+65042=>'ON',
+65043=>'ON',
+65044=>'ON',
+65045=>'ON',
+65046=>'ON',
+65047=>'ON',
+65048=>'ON',
+65049=>'ON',
+65056=>'NSM',
+65057=>'NSM',
+65058=>'NSM',
+65059=>'NSM',
+65072=>'ON',
+65073=>'ON',
+65074=>'ON',
+65075=>'ON',
+65076=>'ON',
+65077=>'ON',
+65078=>'ON',
+65079=>'ON',
+65080=>'ON',
+65081=>'ON',
+65082=>'ON',
+65083=>'ON',
+65084=>'ON',
+65085=>'ON',
+65086=>'ON',
+65087=>'ON',
+65088=>'ON',
+65089=>'ON',
+65090=>'ON',
+65091=>'ON',
+65092=>'ON',
+65093=>'ON',
+65094=>'ON',
+65095=>'ON',
+65096=>'ON',
+65097=>'ON',
+65098=>'ON',
+65099=>'ON',
+65100=>'ON',
+65101=>'ON',
+65102=>'ON',
+65103=>'ON',
+65104=>'CS',
+65105=>'ON',
+65106=>'CS',
+65108=>'ON',
+65109=>'CS',
+65110=>'ON',
+65111=>'ON',
+65112=>'ON',
+65113=>'ON',
+65114=>'ON',
+65115=>'ON',
+65116=>'ON',
+65117=>'ON',
+65118=>'ON',
+65119=>'ET',
+65120=>'ON',
+65121=>'ON',
+65122=>'ES',
+65123=>'ES',
+65124=>'ON',
+65125=>'ON',
+65126=>'ON',
+65128=>'ON',
+65129=>'ET',
+65130=>'ET',
+65131=>'ON',
+65136=>'AL',
+65137=>'AL',
+65138=>'AL',
+65139=>'AL',
+65140=>'AL',
+65142=>'AL',
+65143=>'AL',
+65144=>'AL',
+65145=>'AL',
+65146=>'AL',
+65147=>'AL',
+65148=>'AL',
+65149=>'AL',
+65150=>'AL',
+65151=>'AL',
+65152=>'AL',
+65153=>'AL',
+65154=>'AL',
+65155=>'AL',
+65156=>'AL',
+65157=>'AL',
+65158=>'AL',
+65159=>'AL',
+65160=>'AL',
+65161=>'AL',
+65162=>'AL',
+65163=>'AL',
+65164=>'AL',
+65165=>'AL',
+65166=>'AL',
+65167=>'AL',
+65168=>'AL',
+65169=>'AL',
+65170=>'AL',
+65171=>'AL',
+65172=>'AL',
+65173=>'AL',
+65174=>'AL',
+65175=>'AL',
+65176=>'AL',
+65177=>'AL',
+65178=>'AL',
+65179=>'AL',
+65180=>'AL',
+65181=>'AL',
+65182=>'AL',
+65183=>'AL',
+65184=>'AL',
+65185=>'AL',
+65186=>'AL',
+65187=>'AL',
+65188=>'AL',
+65189=>'AL',
+65190=>'AL',
+65191=>'AL',
+65192=>'AL',
+65193=>'AL',
+65194=>'AL',
+65195=>'AL',
+65196=>'AL',
+65197=>'AL',
+65198=>'AL',
+65199=>'AL',
+65200=>'AL',
+65201=>'AL',
+65202=>'AL',
+65203=>'AL',
+65204=>'AL',
+65205=>'AL',
+65206=>'AL',
+65207=>'AL',
+65208=>'AL',
+65209=>'AL',
+65210=>'AL',
+65211=>'AL',
+65212=>'AL',
+65213=>'AL',
+65214=>'AL',
+65215=>'AL',
+65216=>'AL',
+65217=>'AL',
+65218=>'AL',
+65219=>'AL',
+65220=>'AL',
+65221=>'AL',
+65222=>'AL',
+65223=>'AL',
+65224=>'AL',
+65225=>'AL',
+65226=>'AL',
+65227=>'AL',
+65228=>'AL',
+65229=>'AL',
+65230=>'AL',
+65231=>'AL',
+65232=>'AL',
+65233=>'AL',
+65234=>'AL',
+65235=>'AL',
+65236=>'AL',
+65237=>'AL',
+65238=>'AL',
+65239=>'AL',
+65240=>'AL',
+65241=>'AL',
+65242=>'AL',
+65243=>'AL',
+65244=>'AL',
+65245=>'AL',
+65246=>'AL',
+65247=>'AL',
+65248=>'AL',
+65249=>'AL',
+65250=>'AL',
+65251=>'AL',
+65252=>'AL',
+65253=>'AL',
+65254=>'AL',
+65255=>'AL',
+65256=>'AL',
+65257=>'AL',
+65258=>'AL',
+65259=>'AL',
+65260=>'AL',
+65261=>'AL',
+65262=>'AL',
+65263=>'AL',
+65264=>'AL',
+65265=>'AL',
+65266=>'AL',
+65267=>'AL',
+65268=>'AL',
+65269=>'AL',
+65270=>'AL',
+65271=>'AL',
+65272=>'AL',
+65273=>'AL',
+65274=>'AL',
+65275=>'AL',
+65276=>'AL',
+65279=>'BN',
+65281=>'ON',
+65282=>'ON',
+65283=>'ET',
+65284=>'ET',
+65285=>'ET',
+65286=>'ON',
+65287=>'ON',
+65288=>'ON',
+65289=>'ON',
+65290=>'ON',
+65291=>'ES',
+65292=>'CS',
+65293=>'ES',
+65294=>'CS',
+65295=>'CS',
+65296=>'EN',
+65297=>'EN',
+65298=>'EN',
+65299=>'EN',
+65300=>'EN',
+65301=>'EN',
+65302=>'EN',
+65303=>'EN',
+65304=>'EN',
+65305=>'EN',
+65306=>'CS',
+65307=>'ON',
+65308=>'ON',
+65309=>'ON',
+65310=>'ON',
+65311=>'ON',
+65312=>'ON',
+65313=>'L',
+65314=>'L',
+65315=>'L',
+65316=>'L',
+65317=>'L',
+65318=>'L',
+65319=>'L',
+65320=>'L',
+65321=>'L',
+65322=>'L',
+65323=>'L',
+65324=>'L',
+65325=>'L',
+65326=>'L',
+65327=>'L',
+65328=>'L',
+65329=>'L',
+65330=>'L',
+65331=>'L',
+65332=>'L',
+65333=>'L',
+65334=>'L',
+65335=>'L',
+65336=>'L',
+65337=>'L',
+65338=>'L',
+65339=>'ON',
+65340=>'ON',
+65341=>'ON',
+65342=>'ON',
+65343=>'ON',
+65344=>'ON',
+65345=>'L',
+65346=>'L',
+65347=>'L',
+65348=>'L',
+65349=>'L',
+65350=>'L',
+65351=>'L',
+65352=>'L',
+65353=>'L',
+65354=>'L',
+65355=>'L',
+65356=>'L',
+65357=>'L',
+65358=>'L',
+65359=>'L',
+65360=>'L',
+65361=>'L',
+65362=>'L',
+65363=>'L',
+65364=>'L',
+65365=>'L',
+65366=>'L',
+65367=>'L',
+65368=>'L',
+65369=>'L',
+65370=>'L',
+65371=>'ON',
+65372=>'ON',
+65373=>'ON',
+65374=>'ON',
+65375=>'ON',
+65376=>'ON',
+65377=>'ON',
+65378=>'ON',
+65379=>'ON',
+65380=>'ON',
+65381=>'ON',
+65382=>'L',
+65383=>'L',
+65384=>'L',
+65385=>'L',
+65386=>'L',
+65387=>'L',
+65388=>'L',
+65389=>'L',
+65390=>'L',
+65391=>'L',
+65392=>'L',
+65393=>'L',
+65394=>'L',
+65395=>'L',
+65396=>'L',
+65397=>'L',
+65398=>'L',
+65399=>'L',
+65400=>'L',
+65401=>'L',
+65402=>'L',
+65403=>'L',
+65404=>'L',
+65405=>'L',
+65406=>'L',
+65407=>'L',
+65408=>'L',
+65409=>'L',
+65410=>'L',
+65411=>'L',
+65412=>'L',
+65413=>'L',
+65414=>'L',
+65415=>'L',
+65416=>'L',
+65417=>'L',
+65418=>'L',
+65419=>'L',
+65420=>'L',
+65421=>'L',
+65422=>'L',
+65423=>'L',
+65424=>'L',
+65425=>'L',
+65426=>'L',
+65427=>'L',
+65428=>'L',
+65429=>'L',
+65430=>'L',
+65431=>'L',
+65432=>'L',
+65433=>'L',
+65434=>'L',
+65435=>'L',
+65436=>'L',
+65437=>'L',
+65438=>'L',
+65439=>'L',
+65440=>'L',
+65441=>'L',
+65442=>'L',
+65443=>'L',
+65444=>'L',
+65445=>'L',
+65446=>'L',
+65447=>'L',
+65448=>'L',
+65449=>'L',
+65450=>'L',
+65451=>'L',
+65452=>'L',
+65453=>'L',
+65454=>'L',
+65455=>'L',
+65456=>'L',
+65457=>'L',
+65458=>'L',
+65459=>'L',
+65460=>'L',
+65461=>'L',
+65462=>'L',
+65463=>'L',
+65464=>'L',
+65465=>'L',
+65466=>'L',
+65467=>'L',
+65468=>'L',
+65469=>'L',
+65470=>'L',
+65474=>'L',
+65475=>'L',
+65476=>'L',
+65477=>'L',
+65478=>'L',
+65479=>'L',
+65482=>'L',
+65483=>'L',
+65484=>'L',
+65485=>'L',
+65486=>'L',
+65487=>'L',
+65490=>'L',
+65491=>'L',
+65492=>'L',
+65493=>'L',
+65494=>'L',
+65495=>'L',
+65498=>'L',
+65499=>'L',
+65500=>'L',
+65504=>'ET',
+65505=>'ET',
+65506=>'ON',
+65507=>'ON',
+65508=>'ON',
+65509=>'ET',
+65510=>'ET',
+65512=>'ON',
+65513=>'ON',
+65514=>'ON',
+65515=>'ON',
+65516=>'ON',
+65517=>'ON',
+65518=>'ON',
+65529=>'ON',
+65530=>'ON',
+65531=>'ON',
+65532=>'ON',
+65533=>'ON',
+65536=>'L',
+65537=>'L',
+65538=>'L',
+65539=>'L',
+65540=>'L',
+65541=>'L',
+65542=>'L',
+65543=>'L',
+65544=>'L',
+65545=>'L',
+65546=>'L',
+65547=>'L',
+65549=>'L',
+65550=>'L',
+65551=>'L',
+65552=>'L',
+65553=>'L',
+65554=>'L',
+65555=>'L',
+65556=>'L',
+65557=>'L',
+65558=>'L',
+65559=>'L',
+65560=>'L',
+65561=>'L',
+65562=>'L',
+65563=>'L',
+65564=>'L',
+65565=>'L',
+65566=>'L',
+65567=>'L',
+65568=>'L',
+65569=>'L',
+65570=>'L',
+65571=>'L',
+65572=>'L',
+65573=>'L',
+65574=>'L',
+65576=>'L',
+65577=>'L',
+65578=>'L',
+65579=>'L',
+65580=>'L',
+65581=>'L',
+65582=>'L',
+65583=>'L',
+65584=>'L',
+65585=>'L',
+65586=>'L',
+65587=>'L',
+65588=>'L',
+65589=>'L',
+65590=>'L',
+65591=>'L',
+65592=>'L',
+65593=>'L',
+65594=>'L',
+65596=>'L',
+65597=>'L',
+65599=>'L',
+65600=>'L',
+65601=>'L',
+65602=>'L',
+65603=>'L',
+65604=>'L',
+65605=>'L',
+65606=>'L',
+65607=>'L',
+65608=>'L',
+65609=>'L',
+65610=>'L',
+65611=>'L',
+65612=>'L',
+65613=>'L',
+65616=>'L',
+65617=>'L',
+65618=>'L',
+65619=>'L',
+65620=>'L',
+65621=>'L',
+65622=>'L',
+65623=>'L',
+65624=>'L',
+65625=>'L',
+65626=>'L',
+65627=>'L',
+65628=>'L',
+65629=>'L',
+65664=>'L',
+65665=>'L',
+65666=>'L',
+65667=>'L',
+65668=>'L',
+65669=>'L',
+65670=>'L',
+65671=>'L',
+65672=>'L',
+65673=>'L',
+65674=>'L',
+65675=>'L',
+65676=>'L',
+65677=>'L',
+65678=>'L',
+65679=>'L',
+65680=>'L',
+65681=>'L',
+65682=>'L',
+65683=>'L',
+65684=>'L',
+65685=>'L',
+65686=>'L',
+65687=>'L',
+65688=>'L',
+65689=>'L',
+65690=>'L',
+65691=>'L',
+65692=>'L',
+65693=>'L',
+65694=>'L',
+65695=>'L',
+65696=>'L',
+65697=>'L',
+65698=>'L',
+65699=>'L',
+65700=>'L',
+65701=>'L',
+65702=>'L',
+65703=>'L',
+65704=>'L',
+65705=>'L',
+65706=>'L',
+65707=>'L',
+65708=>'L',
+65709=>'L',
+65710=>'L',
+65711=>'L',
+65712=>'L',
+65713=>'L',
+65714=>'L',
+65715=>'L',
+65716=>'L',
+65717=>'L',
+65718=>'L',
+65719=>'L',
+65720=>'L',
+65721=>'L',
+65722=>'L',
+65723=>'L',
+65724=>'L',
+65725=>'L',
+65726=>'L',
+65727=>'L',
+65728=>'L',
+65729=>'L',
+65730=>'L',
+65731=>'L',
+65732=>'L',
+65733=>'L',
+65734=>'L',
+65735=>'L',
+65736=>'L',
+65737=>'L',
+65738=>'L',
+65739=>'L',
+65740=>'L',
+65741=>'L',
+65742=>'L',
+65743=>'L',
+65744=>'L',
+65745=>'L',
+65746=>'L',
+65747=>'L',
+65748=>'L',
+65749=>'L',
+65750=>'L',
+65751=>'L',
+65752=>'L',
+65753=>'L',
+65754=>'L',
+65755=>'L',
+65756=>'L',
+65757=>'L',
+65758=>'L',
+65759=>'L',
+65760=>'L',
+65761=>'L',
+65762=>'L',
+65763=>'L',
+65764=>'L',
+65765=>'L',
+65766=>'L',
+65767=>'L',
+65768=>'L',
+65769=>'L',
+65770=>'L',
+65771=>'L',
+65772=>'L',
+65773=>'L',
+65774=>'L',
+65775=>'L',
+65776=>'L',
+65777=>'L',
+65778=>'L',
+65779=>'L',
+65780=>'L',
+65781=>'L',
+65782=>'L',
+65783=>'L',
+65784=>'L',
+65785=>'L',
+65786=>'L',
+65792=>'L',
+65793=>'ON',
+65794=>'L',
+65799=>'L',
+65800=>'L',
+65801=>'L',
+65802=>'L',
+65803=>'L',
+65804=>'L',
+65805=>'L',
+65806=>'L',
+65807=>'L',
+65808=>'L',
+65809=>'L',
+65810=>'L',
+65811=>'L',
+65812=>'L',
+65813=>'L',
+65814=>'L',
+65815=>'L',
+65816=>'L',
+65817=>'L',
+65818=>'L',
+65819=>'L',
+65820=>'L',
+65821=>'L',
+65822=>'L',
+65823=>'L',
+65824=>'L',
+65825=>'L',
+65826=>'L',
+65827=>'L',
+65828=>'L',
+65829=>'L',
+65830=>'L',
+65831=>'L',
+65832=>'L',
+65833=>'L',
+65834=>'L',
+65835=>'L',
+65836=>'L',
+65837=>'L',
+65838=>'L',
+65839=>'L',
+65840=>'L',
+65841=>'L',
+65842=>'L',
+65843=>'L',
+65847=>'L',
+65848=>'L',
+65849=>'L',
+65850=>'L',
+65851=>'L',
+65852=>'L',
+65853=>'L',
+65854=>'L',
+65855=>'L',
+65856=>'ON',
+65857=>'ON',
+65858=>'ON',
+65859=>'ON',
+65860=>'ON',
+65861=>'ON',
+65862=>'ON',
+65863=>'ON',
+65864=>'ON',
+65865=>'ON',
+65866=>'ON',
+65867=>'ON',
+65868=>'ON',
+65869=>'ON',
+65870=>'ON',
+65871=>'ON',
+65872=>'ON',
+65873=>'ON',
+65874=>'ON',
+65875=>'ON',
+65876=>'ON',
+65877=>'ON',
+65878=>'ON',
+65879=>'ON',
+65880=>'ON',
+65881=>'ON',
+65882=>'ON',
+65883=>'ON',
+65884=>'ON',
+65885=>'ON',
+65886=>'ON',
+65887=>'ON',
+65888=>'ON',
+65889=>'ON',
+65890=>'ON',
+65891=>'ON',
+65892=>'ON',
+65893=>'ON',
+65894=>'ON',
+65895=>'ON',
+65896=>'ON',
+65897=>'ON',
+65898=>'ON',
+65899=>'ON',
+65900=>'ON',
+65901=>'ON',
+65902=>'ON',
+65903=>'ON',
+65904=>'ON',
+65905=>'ON',
+65906=>'ON',
+65907=>'ON',
+65908=>'ON',
+65909=>'ON',
+65910=>'ON',
+65911=>'ON',
+65912=>'ON',
+65913=>'ON',
+65914=>'ON',
+65915=>'ON',
+65916=>'ON',
+65917=>'ON',
+65918=>'ON',
+65919=>'ON',
+65920=>'ON',
+65921=>'ON',
+65922=>'ON',
+65923=>'ON',
+65924=>'ON',
+65925=>'ON',
+65926=>'ON',
+65927=>'ON',
+65928=>'ON',
+65929=>'ON',
+65930=>'ON',
+66304=>'L',
+66305=>'L',
+66306=>'L',
+66307=>'L',
+66308=>'L',
+66309=>'L',
+66310=>'L',
+66311=>'L',
+66312=>'L',
+66313=>'L',
+66314=>'L',
+66315=>'L',
+66316=>'L',
+66317=>'L',
+66318=>'L',
+66319=>'L',
+66320=>'L',
+66321=>'L',
+66322=>'L',
+66323=>'L',
+66324=>'L',
+66325=>'L',
+66326=>'L',
+66327=>'L',
+66328=>'L',
+66329=>'L',
+66330=>'L',
+66331=>'L',
+66332=>'L',
+66333=>'L',
+66334=>'L',
+66336=>'L',
+66337=>'L',
+66338=>'L',
+66339=>'L',
+66352=>'L',
+66353=>'L',
+66354=>'L',
+66355=>'L',
+66356=>'L',
+66357=>'L',
+66358=>'L',
+66359=>'L',
+66360=>'L',
+66361=>'L',
+66362=>'L',
+66363=>'L',
+66364=>'L',
+66365=>'L',
+66366=>'L',
+66367=>'L',
+66368=>'L',
+66369=>'L',
+66370=>'L',
+66371=>'L',
+66372=>'L',
+66373=>'L',
+66374=>'L',
+66375=>'L',
+66376=>'L',
+66377=>'L',
+66378=>'L',
+66432=>'L',
+66433=>'L',
+66434=>'L',
+66435=>'L',
+66436=>'L',
+66437=>'L',
+66438=>'L',
+66439=>'L',
+66440=>'L',
+66441=>'L',
+66442=>'L',
+66443=>'L',
+66444=>'L',
+66445=>'L',
+66446=>'L',
+66447=>'L',
+66448=>'L',
+66449=>'L',
+66450=>'L',
+66451=>'L',
+66452=>'L',
+66453=>'L',
+66454=>'L',
+66455=>'L',
+66456=>'L',
+66457=>'L',
+66458=>'L',
+66459=>'L',
+66460=>'L',
+66461=>'L',
+66463=>'L',
+66464=>'L',
+66465=>'L',
+66466=>'L',
+66467=>'L',
+66468=>'L',
+66469=>'L',
+66470=>'L',
+66471=>'L',
+66472=>'L',
+66473=>'L',
+66474=>'L',
+66475=>'L',
+66476=>'L',
+66477=>'L',
+66478=>'L',
+66479=>'L',
+66480=>'L',
+66481=>'L',
+66482=>'L',
+66483=>'L',
+66484=>'L',
+66485=>'L',
+66486=>'L',
+66487=>'L',
+66488=>'L',
+66489=>'L',
+66490=>'L',
+66491=>'L',
+66492=>'L',
+66493=>'L',
+66494=>'L',
+66495=>'L',
+66496=>'L',
+66497=>'L',
+66498=>'L',
+66499=>'L',
+66504=>'L',
+66505=>'L',
+66506=>'L',
+66507=>'L',
+66508=>'L',
+66509=>'L',
+66510=>'L',
+66511=>'L',
+66512=>'L',
+66513=>'L',
+66514=>'L',
+66515=>'L',
+66516=>'L',
+66517=>'L',
+66560=>'L',
+66561=>'L',
+66562=>'L',
+66563=>'L',
+66564=>'L',
+66565=>'L',
+66566=>'L',
+66567=>'L',
+66568=>'L',
+66569=>'L',
+66570=>'L',
+66571=>'L',
+66572=>'L',
+66573=>'L',
+66574=>'L',
+66575=>'L',
+66576=>'L',
+66577=>'L',
+66578=>'L',
+66579=>'L',
+66580=>'L',
+66581=>'L',
+66582=>'L',
+66583=>'L',
+66584=>'L',
+66585=>'L',
+66586=>'L',
+66587=>'L',
+66588=>'L',
+66589=>'L',
+66590=>'L',
+66591=>'L',
+66592=>'L',
+66593=>'L',
+66594=>'L',
+66595=>'L',
+66596=>'L',
+66597=>'L',
+66598=>'L',
+66599=>'L',
+66600=>'L',
+66601=>'L',
+66602=>'L',
+66603=>'L',
+66604=>'L',
+66605=>'L',
+66606=>'L',
+66607=>'L',
+66608=>'L',
+66609=>'L',
+66610=>'L',
+66611=>'L',
+66612=>'L',
+66613=>'L',
+66614=>'L',
+66615=>'L',
+66616=>'L',
+66617=>'L',
+66618=>'L',
+66619=>'L',
+66620=>'L',
+66621=>'L',
+66622=>'L',
+66623=>'L',
+66624=>'L',
+66625=>'L',
+66626=>'L',
+66627=>'L',
+66628=>'L',
+66629=>'L',
+66630=>'L',
+66631=>'L',
+66632=>'L',
+66633=>'L',
+66634=>'L',
+66635=>'L',
+66636=>'L',
+66637=>'L',
+66638=>'L',
+66639=>'L',
+66640=>'L',
+66641=>'L',
+66642=>'L',
+66643=>'L',
+66644=>'L',
+66645=>'L',
+66646=>'L',
+66647=>'L',
+66648=>'L',
+66649=>'L',
+66650=>'L',
+66651=>'L',
+66652=>'L',
+66653=>'L',
+66654=>'L',
+66655=>'L',
+66656=>'L',
+66657=>'L',
+66658=>'L',
+66659=>'L',
+66660=>'L',
+66661=>'L',
+66662=>'L',
+66663=>'L',
+66664=>'L',
+66665=>'L',
+66666=>'L',
+66667=>'L',
+66668=>'L',
+66669=>'L',
+66670=>'L',
+66671=>'L',
+66672=>'L',
+66673=>'L',
+66674=>'L',
+66675=>'L',
+66676=>'L',
+66677=>'L',
+66678=>'L',
+66679=>'L',
+66680=>'L',
+66681=>'L',
+66682=>'L',
+66683=>'L',
+66684=>'L',
+66685=>'L',
+66686=>'L',
+66687=>'L',
+66688=>'L',
+66689=>'L',
+66690=>'L',
+66691=>'L',
+66692=>'L',
+66693=>'L',
+66694=>'L',
+66695=>'L',
+66696=>'L',
+66697=>'L',
+66698=>'L',
+66699=>'L',
+66700=>'L',
+66701=>'L',
+66702=>'L',
+66703=>'L',
+66704=>'L',
+66705=>'L',
+66706=>'L',
+66707=>'L',
+66708=>'L',
+66709=>'L',
+66710=>'L',
+66711=>'L',
+66712=>'L',
+66713=>'L',
+66714=>'L',
+66715=>'L',
+66716=>'L',
+66717=>'L',
+66720=>'L',
+66721=>'L',
+66722=>'L',
+66723=>'L',
+66724=>'L',
+66725=>'L',
+66726=>'L',
+66727=>'L',
+66728=>'L',
+66729=>'L',
+67584=>'R',
+67585=>'R',
+67586=>'R',
+67587=>'R',
+67588=>'R',
+67589=>'R',
+67592=>'R',
+67594=>'R',
+67595=>'R',
+67596=>'R',
+67597=>'R',
+67598=>'R',
+67599=>'R',
+67600=>'R',
+67601=>'R',
+67602=>'R',
+67603=>'R',
+67604=>'R',
+67605=>'R',
+67606=>'R',
+67607=>'R',
+67608=>'R',
+67609=>'R',
+67610=>'R',
+67611=>'R',
+67612=>'R',
+67613=>'R',
+67614=>'R',
+67615=>'R',
+67616=>'R',
+67617=>'R',
+67618=>'R',
+67619=>'R',
+67620=>'R',
+67621=>'R',
+67622=>'R',
+67623=>'R',
+67624=>'R',
+67625=>'R',
+67626=>'R',
+67627=>'R',
+67628=>'R',
+67629=>'R',
+67630=>'R',
+67631=>'R',
+67632=>'R',
+67633=>'R',
+67634=>'R',
+67635=>'R',
+67636=>'R',
+67637=>'R',
+67639=>'R',
+67640=>'R',
+67644=>'R',
+67647=>'R',
+67840=>'R',
+67841=>'R',
+67842=>'R',
+67843=>'R',
+67844=>'R',
+67845=>'R',
+67846=>'R',
+67847=>'R',
+67848=>'R',
+67849=>'R',
+67850=>'R',
+67851=>'R',
+67852=>'R',
+67853=>'R',
+67854=>'R',
+67855=>'R',
+67856=>'R',
+67857=>'R',
+67858=>'R',
+67859=>'R',
+67860=>'R',
+67861=>'R',
+67862=>'R',
+67863=>'R',
+67864=>'R',
+67865=>'R',
+67871=>'ON',
+68096=>'R',
+68097=>'NSM',
+68098=>'NSM',
+68099=>'NSM',
+68101=>'NSM',
+68102=>'NSM',
+68108=>'NSM',
+68109=>'NSM',
+68110=>'NSM',
+68111=>'NSM',
+68112=>'R',
+68113=>'R',
+68114=>'R',
+68115=>'R',
+68117=>'R',
+68118=>'R',
+68119=>'R',
+68121=>'R',
+68122=>'R',
+68123=>'R',
+68124=>'R',
+68125=>'R',
+68126=>'R',
+68127=>'R',
+68128=>'R',
+68129=>'R',
+68130=>'R',
+68131=>'R',
+68132=>'R',
+68133=>'R',
+68134=>'R',
+68135=>'R',
+68136=>'R',
+68137=>'R',
+68138=>'R',
+68139=>'R',
+68140=>'R',
+68141=>'R',
+68142=>'R',
+68143=>'R',
+68144=>'R',
+68145=>'R',
+68146=>'R',
+68147=>'R',
+68152=>'NSM',
+68153=>'NSM',
+68154=>'NSM',
+68159=>'NSM',
+68160=>'R',
+68161=>'R',
+68162=>'R',
+68163=>'R',
+68164=>'R',
+68165=>'R',
+68166=>'R',
+68167=>'R',
+68176=>'R',
+68177=>'R',
+68178=>'R',
+68179=>'R',
+68180=>'R',
+68181=>'R',
+68182=>'R',
+68183=>'R',
+68184=>'R',
+73728=>'L',
+73729=>'L',
+73730=>'L',
+73731=>'L',
+73732=>'L',
+73733=>'L',
+73734=>'L',
+73735=>'L',
+73736=>'L',
+73737=>'L',
+73738=>'L',
+73739=>'L',
+73740=>'L',
+73741=>'L',
+73742=>'L',
+73743=>'L',
+73744=>'L',
+73745=>'L',
+73746=>'L',
+73747=>'L',
+73748=>'L',
+73749=>'L',
+73750=>'L',
+73751=>'L',
+73752=>'L',
+73753=>'L',
+73754=>'L',
+73755=>'L',
+73756=>'L',
+73757=>'L',
+73758=>'L',
+73759=>'L',
+73760=>'L',
+73761=>'L',
+73762=>'L',
+73763=>'L',
+73764=>'L',
+73765=>'L',
+73766=>'L',
+73767=>'L',
+73768=>'L',
+73769=>'L',
+73770=>'L',
+73771=>'L',
+73772=>'L',
+73773=>'L',
+73774=>'L',
+73775=>'L',
+73776=>'L',
+73777=>'L',
+73778=>'L',
+73779=>'L',
+73780=>'L',
+73781=>'L',
+73782=>'L',
+73783=>'L',
+73784=>'L',
+73785=>'L',
+73786=>'L',
+73787=>'L',
+73788=>'L',
+73789=>'L',
+73790=>'L',
+73791=>'L',
+73792=>'L',
+73793=>'L',
+73794=>'L',
+73795=>'L',
+73796=>'L',
+73797=>'L',
+73798=>'L',
+73799=>'L',
+73800=>'L',
+73801=>'L',
+73802=>'L',
+73803=>'L',
+73804=>'L',
+73805=>'L',
+73806=>'L',
+73807=>'L',
+73808=>'L',
+73809=>'L',
+73810=>'L',
+73811=>'L',
+73812=>'L',
+73813=>'L',
+73814=>'L',
+73815=>'L',
+73816=>'L',
+73817=>'L',
+73818=>'L',
+73819=>'L',
+73820=>'L',
+73821=>'L',
+73822=>'L',
+73823=>'L',
+73824=>'L',
+73825=>'L',
+73826=>'L',
+73827=>'L',
+73828=>'L',
+73829=>'L',
+73830=>'L',
+73831=>'L',
+73832=>'L',
+73833=>'L',
+73834=>'L',
+73835=>'L',
+73836=>'L',
+73837=>'L',
+73838=>'L',
+73839=>'L',
+73840=>'L',
+73841=>'L',
+73842=>'L',
+73843=>'L',
+73844=>'L',
+73845=>'L',
+73846=>'L',
+73847=>'L',
+73848=>'L',
+73849=>'L',
+73850=>'L',
+73851=>'L',
+73852=>'L',
+73853=>'L',
+73854=>'L',
+73855=>'L',
+73856=>'L',
+73857=>'L',
+73858=>'L',
+73859=>'L',
+73860=>'L',
+73861=>'L',
+73862=>'L',
+73863=>'L',
+73864=>'L',
+73865=>'L',
+73866=>'L',
+73867=>'L',
+73868=>'L',
+73869=>'L',
+73870=>'L',
+73871=>'L',
+73872=>'L',
+73873=>'L',
+73874=>'L',
+73875=>'L',
+73876=>'L',
+73877=>'L',
+73878=>'L',
+73879=>'L',
+73880=>'L',
+73881=>'L',
+73882=>'L',
+73883=>'L',
+73884=>'L',
+73885=>'L',
+73886=>'L',
+73887=>'L',
+73888=>'L',
+73889=>'L',
+73890=>'L',
+73891=>'L',
+73892=>'L',
+73893=>'L',
+73894=>'L',
+73895=>'L',
+73896=>'L',
+73897=>'L',
+73898=>'L',
+73899=>'L',
+73900=>'L',
+73901=>'L',
+73902=>'L',
+73903=>'L',
+73904=>'L',
+73905=>'L',
+73906=>'L',
+73907=>'L',
+73908=>'L',
+73909=>'L',
+73910=>'L',
+73911=>'L',
+73912=>'L',
+73913=>'L',
+73914=>'L',
+73915=>'L',
+73916=>'L',
+73917=>'L',
+73918=>'L',
+73919=>'L',
+73920=>'L',
+73921=>'L',
+73922=>'L',
+73923=>'L',
+73924=>'L',
+73925=>'L',
+73926=>'L',
+73927=>'L',
+73928=>'L',
+73929=>'L',
+73930=>'L',
+73931=>'L',
+73932=>'L',
+73933=>'L',
+73934=>'L',
+73935=>'L',
+73936=>'L',
+73937=>'L',
+73938=>'L',
+73939=>'L',
+73940=>'L',
+73941=>'L',
+73942=>'L',
+73943=>'L',
+73944=>'L',
+73945=>'L',
+73946=>'L',
+73947=>'L',
+73948=>'L',
+73949=>'L',
+73950=>'L',
+73951=>'L',
+73952=>'L',
+73953=>'L',
+73954=>'L',
+73955=>'L',
+73956=>'L',
+73957=>'L',
+73958=>'L',
+73959=>'L',
+73960=>'L',
+73961=>'L',
+73962=>'L',
+73963=>'L',
+73964=>'L',
+73965=>'L',
+73966=>'L',
+73967=>'L',
+73968=>'L',
+73969=>'L',
+73970=>'L',
+73971=>'L',
+73972=>'L',
+73973=>'L',
+73974=>'L',
+73975=>'L',
+73976=>'L',
+73977=>'L',
+73978=>'L',
+73979=>'L',
+73980=>'L',
+73981=>'L',
+73982=>'L',
+73983=>'L',
+73984=>'L',
+73985=>'L',
+73986=>'L',
+73987=>'L',
+73988=>'L',
+73989=>'L',
+73990=>'L',
+73991=>'L',
+73992=>'L',
+73993=>'L',
+73994=>'L',
+73995=>'L',
+73996=>'L',
+73997=>'L',
+73998=>'L',
+73999=>'L',
+74000=>'L',
+74001=>'L',
+74002=>'L',
+74003=>'L',
+74004=>'L',
+74005=>'L',
+74006=>'L',
+74007=>'L',
+74008=>'L',
+74009=>'L',
+74010=>'L',
+74011=>'L',
+74012=>'L',
+74013=>'L',
+74014=>'L',
+74015=>'L',
+74016=>'L',
+74017=>'L',
+74018=>'L',
+74019=>'L',
+74020=>'L',
+74021=>'L',
+74022=>'L',
+74023=>'L',
+74024=>'L',
+74025=>'L',
+74026=>'L',
+74027=>'L',
+74028=>'L',
+74029=>'L',
+74030=>'L',
+74031=>'L',
+74032=>'L',
+74033=>'L',
+74034=>'L',
+74035=>'L',
+74036=>'L',
+74037=>'L',
+74038=>'L',
+74039=>'L',
+74040=>'L',
+74041=>'L',
+74042=>'L',
+74043=>'L',
+74044=>'L',
+74045=>'L',
+74046=>'L',
+74047=>'L',
+74048=>'L',
+74049=>'L',
+74050=>'L',
+74051=>'L',
+74052=>'L',
+74053=>'L',
+74054=>'L',
+74055=>'L',
+74056=>'L',
+74057=>'L',
+74058=>'L',
+74059=>'L',
+74060=>'L',
+74061=>'L',
+74062=>'L',
+74063=>'L',
+74064=>'L',
+74065=>'L',
+74066=>'L',
+74067=>'L',
+74068=>'L',
+74069=>'L',
+74070=>'L',
+74071=>'L',
+74072=>'L',
+74073=>'L',
+74074=>'L',
+74075=>'L',
+74076=>'L',
+74077=>'L',
+74078=>'L',
+74079=>'L',
+74080=>'L',
+74081=>'L',
+74082=>'L',
+74083=>'L',
+74084=>'L',
+74085=>'L',
+74086=>'L',
+74087=>'L',
+74088=>'L',
+74089=>'L',
+74090=>'L',
+74091=>'L',
+74092=>'L',
+74093=>'L',
+74094=>'L',
+74095=>'L',
+74096=>'L',
+74097=>'L',
+74098=>'L',
+74099=>'L',
+74100=>'L',
+74101=>'L',
+74102=>'L',
+74103=>'L',
+74104=>'L',
+74105=>'L',
+74106=>'L',
+74107=>'L',
+74108=>'L',
+74109=>'L',
+74110=>'L',
+74111=>'L',
+74112=>'L',
+74113=>'L',
+74114=>'L',
+74115=>'L',
+74116=>'L',
+74117=>'L',
+74118=>'L',
+74119=>'L',
+74120=>'L',
+74121=>'L',
+74122=>'L',
+74123=>'L',
+74124=>'L',
+74125=>'L',
+74126=>'L',
+74127=>'L',
+74128=>'L',
+74129=>'L',
+74130=>'L',
+74131=>'L',
+74132=>'L',
+74133=>'L',
+74134=>'L',
+74135=>'L',
+74136=>'L',
+74137=>'L',
+74138=>'L',
+74139=>'L',
+74140=>'L',
+74141=>'L',
+74142=>'L',
+74143=>'L',
+74144=>'L',
+74145=>'L',
+74146=>'L',
+74147=>'L',
+74148=>'L',
+74149=>'L',
+74150=>'L',
+74151=>'L',
+74152=>'L',
+74153=>'L',
+74154=>'L',
+74155=>'L',
+74156=>'L',
+74157=>'L',
+74158=>'L',
+74159=>'L',
+74160=>'L',
+74161=>'L',
+74162=>'L',
+74163=>'L',
+74164=>'L',
+74165=>'L',
+74166=>'L',
+74167=>'L',
+74168=>'L',
+74169=>'L',
+74170=>'L',
+74171=>'L',
+74172=>'L',
+74173=>'L',
+74174=>'L',
+74175=>'L',
+74176=>'L',
+74177=>'L',
+74178=>'L',
+74179=>'L',
+74180=>'L',
+74181=>'L',
+74182=>'L',
+74183=>'L',
+74184=>'L',
+74185=>'L',
+74186=>'L',
+74187=>'L',
+74188=>'L',
+74189=>'L',
+74190=>'L',
+74191=>'L',
+74192=>'L',
+74193=>'L',
+74194=>'L',
+74195=>'L',
+74196=>'L',
+74197=>'L',
+74198=>'L',
+74199=>'L',
+74200=>'L',
+74201=>'L',
+74202=>'L',
+74203=>'L',
+74204=>'L',
+74205=>'L',
+74206=>'L',
+74207=>'L',
+74208=>'L',
+74209=>'L',
+74210=>'L',
+74211=>'L',
+74212=>'L',
+74213=>'L',
+74214=>'L',
+74215=>'L',
+74216=>'L',
+74217=>'L',
+74218=>'L',
+74219=>'L',
+74220=>'L',
+74221=>'L',
+74222=>'L',
+74223=>'L',
+74224=>'L',
+74225=>'L',
+74226=>'L',
+74227=>'L',
+74228=>'L',
+74229=>'L',
+74230=>'L',
+74231=>'L',
+74232=>'L',
+74233=>'L',
+74234=>'L',
+74235=>'L',
+74236=>'L',
+74237=>'L',
+74238=>'L',
+74239=>'L',
+74240=>'L',
+74241=>'L',
+74242=>'L',
+74243=>'L',
+74244=>'L',
+74245=>'L',
+74246=>'L',
+74247=>'L',
+74248=>'L',
+74249=>'L',
+74250=>'L',
+74251=>'L',
+74252=>'L',
+74253=>'L',
+74254=>'L',
+74255=>'L',
+74256=>'L',
+74257=>'L',
+74258=>'L',
+74259=>'L',
+74260=>'L',
+74261=>'L',
+74262=>'L',
+74263=>'L',
+74264=>'L',
+74265=>'L',
+74266=>'L',
+74267=>'L',
+74268=>'L',
+74269=>'L',
+74270=>'L',
+74271=>'L',
+74272=>'L',
+74273=>'L',
+74274=>'L',
+74275=>'L',
+74276=>'L',
+74277=>'L',
+74278=>'L',
+74279=>'L',
+74280=>'L',
+74281=>'L',
+74282=>'L',
+74283=>'L',
+74284=>'L',
+74285=>'L',
+74286=>'L',
+74287=>'L',
+74288=>'L',
+74289=>'L',
+74290=>'L',
+74291=>'L',
+74292=>'L',
+74293=>'L',
+74294=>'L',
+74295=>'L',
+74296=>'L',
+74297=>'L',
+74298=>'L',
+74299=>'L',
+74300=>'L',
+74301=>'L',
+74302=>'L',
+74303=>'L',
+74304=>'L',
+74305=>'L',
+74306=>'L',
+74307=>'L',
+74308=>'L',
+74309=>'L',
+74310=>'L',
+74311=>'L',
+74312=>'L',
+74313=>'L',
+74314=>'L',
+74315=>'L',
+74316=>'L',
+74317=>'L',
+74318=>'L',
+74319=>'L',
+74320=>'L',
+74321=>'L',
+74322=>'L',
+74323=>'L',
+74324=>'L',
+74325=>'L',
+74326=>'L',
+74327=>'L',
+74328=>'L',
+74329=>'L',
+74330=>'L',
+74331=>'L',
+74332=>'L',
+74333=>'L',
+74334=>'L',
+74335=>'L',
+74336=>'L',
+74337=>'L',
+74338=>'L',
+74339=>'L',
+74340=>'L',
+74341=>'L',
+74342=>'L',
+74343=>'L',
+74344=>'L',
+74345=>'L',
+74346=>'L',
+74347=>'L',
+74348=>'L',
+74349=>'L',
+74350=>'L',
+74351=>'L',
+74352=>'L',
+74353=>'L',
+74354=>'L',
+74355=>'L',
+74356=>'L',
+74357=>'L',
+74358=>'L',
+74359=>'L',
+74360=>'L',
+74361=>'L',
+74362=>'L',
+74363=>'L',
+74364=>'L',
+74365=>'L',
+74366=>'L',
+74367=>'L',
+74368=>'L',
+74369=>'L',
+74370=>'L',
+74371=>'L',
+74372=>'L',
+74373=>'L',
+74374=>'L',
+74375=>'L',
+74376=>'L',
+74377=>'L',
+74378=>'L',
+74379=>'L',
+74380=>'L',
+74381=>'L',
+74382=>'L',
+74383=>'L',
+74384=>'L',
+74385=>'L',
+74386=>'L',
+74387=>'L',
+74388=>'L',
+74389=>'L',
+74390=>'L',
+74391=>'L',
+74392=>'L',
+74393=>'L',
+74394=>'L',
+74395=>'L',
+74396=>'L',
+74397=>'L',
+74398=>'L',
+74399=>'L',
+74400=>'L',
+74401=>'L',
+74402=>'L',
+74403=>'L',
+74404=>'L',
+74405=>'L',
+74406=>'L',
+74407=>'L',
+74408=>'L',
+74409=>'L',
+74410=>'L',
+74411=>'L',
+74412=>'L',
+74413=>'L',
+74414=>'L',
+74415=>'L',
+74416=>'L',
+74417=>'L',
+74418=>'L',
+74419=>'L',
+74420=>'L',
+74421=>'L',
+74422=>'L',
+74423=>'L',
+74424=>'L',
+74425=>'L',
+74426=>'L',
+74427=>'L',
+74428=>'L',
+74429=>'L',
+74430=>'L',
+74431=>'L',
+74432=>'L',
+74433=>'L',
+74434=>'L',
+74435=>'L',
+74436=>'L',
+74437=>'L',
+74438=>'L',
+74439=>'L',
+74440=>'L',
+74441=>'L',
+74442=>'L',
+74443=>'L',
+74444=>'L',
+74445=>'L',
+74446=>'L',
+74447=>'L',
+74448=>'L',
+74449=>'L',
+74450=>'L',
+74451=>'L',
+74452=>'L',
+74453=>'L',
+74454=>'L',
+74455=>'L',
+74456=>'L',
+74457=>'L',
+74458=>'L',
+74459=>'L',
+74460=>'L',
+74461=>'L',
+74462=>'L',
+74463=>'L',
+74464=>'L',
+74465=>'L',
+74466=>'L',
+74467=>'L',
+74468=>'L',
+74469=>'L',
+74470=>'L',
+74471=>'L',
+74472=>'L',
+74473=>'L',
+74474=>'L',
+74475=>'L',
+74476=>'L',
+74477=>'L',
+74478=>'L',
+74479=>'L',
+74480=>'L',
+74481=>'L',
+74482=>'L',
+74483=>'L',
+74484=>'L',
+74485=>'L',
+74486=>'L',
+74487=>'L',
+74488=>'L',
+74489=>'L',
+74490=>'L',
+74491=>'L',
+74492=>'L',
+74493=>'L',
+74494=>'L',
+74495=>'L',
+74496=>'L',
+74497=>'L',
+74498=>'L',
+74499=>'L',
+74500=>'L',
+74501=>'L',
+74502=>'L',
+74503=>'L',
+74504=>'L',
+74505=>'L',
+74506=>'L',
+74507=>'L',
+74508=>'L',
+74509=>'L',
+74510=>'L',
+74511=>'L',
+74512=>'L',
+74513=>'L',
+74514=>'L',
+74515=>'L',
+74516=>'L',
+74517=>'L',
+74518=>'L',
+74519=>'L',
+74520=>'L',
+74521=>'L',
+74522=>'L',
+74523=>'L',
+74524=>'L',
+74525=>'L',
+74526=>'L',
+74527=>'L',
+74528=>'L',
+74529=>'L',
+74530=>'L',
+74531=>'L',
+74532=>'L',
+74533=>'L',
+74534=>'L',
+74535=>'L',
+74536=>'L',
+74537=>'L',
+74538=>'L',
+74539=>'L',
+74540=>'L',
+74541=>'L',
+74542=>'L',
+74543=>'L',
+74544=>'L',
+74545=>'L',
+74546=>'L',
+74547=>'L',
+74548=>'L',
+74549=>'L',
+74550=>'L',
+74551=>'L',
+74552=>'L',
+74553=>'L',
+74554=>'L',
+74555=>'L',
+74556=>'L',
+74557=>'L',
+74558=>'L',
+74559=>'L',
+74560=>'L',
+74561=>'L',
+74562=>'L',
+74563=>'L',
+74564=>'L',
+74565=>'L',
+74566=>'L',
+74567=>'L',
+74568=>'L',
+74569=>'L',
+74570=>'L',
+74571=>'L',
+74572=>'L',
+74573=>'L',
+74574=>'L',
+74575=>'L',
+74576=>'L',
+74577=>'L',
+74578=>'L',
+74579=>'L',
+74580=>'L',
+74581=>'L',
+74582=>'L',
+74583=>'L',
+74584=>'L',
+74585=>'L',
+74586=>'L',
+74587=>'L',
+74588=>'L',
+74589=>'L',
+74590=>'L',
+74591=>'L',
+74592=>'L',
+74593=>'L',
+74594=>'L',
+74595=>'L',
+74596=>'L',
+74597=>'L',
+74598=>'L',
+74599=>'L',
+74600=>'L',
+74601=>'L',
+74602=>'L',
+74603=>'L',
+74604=>'L',
+74605=>'L',
+74606=>'L',
+74752=>'L',
+74753=>'L',
+74754=>'L',
+74755=>'L',
+74756=>'L',
+74757=>'L',
+74758=>'L',
+74759=>'L',
+74760=>'L',
+74761=>'L',
+74762=>'L',
+74763=>'L',
+74764=>'L',
+74765=>'L',
+74766=>'L',
+74767=>'L',
+74768=>'L',
+74769=>'L',
+74770=>'L',
+74771=>'L',
+74772=>'L',
+74773=>'L',
+74774=>'L',
+74775=>'L',
+74776=>'L',
+74777=>'L',
+74778=>'L',
+74779=>'L',
+74780=>'L',
+74781=>'L',
+74782=>'L',
+74783=>'L',
+74784=>'L',
+74785=>'L',
+74786=>'L',
+74787=>'L',
+74788=>'L',
+74789=>'L',
+74790=>'L',
+74791=>'L',
+74792=>'L',
+74793=>'L',
+74794=>'L',
+74795=>'L',
+74796=>'L',
+74797=>'L',
+74798=>'L',
+74799=>'L',
+74800=>'L',
+74801=>'L',
+74802=>'L',
+74803=>'L',
+74804=>'L',
+74805=>'L',
+74806=>'L',
+74807=>'L',
+74808=>'L',
+74809=>'L',
+74810=>'L',
+74811=>'L',
+74812=>'L',
+74813=>'L',
+74814=>'L',
+74815=>'L',
+74816=>'L',
+74817=>'L',
+74818=>'L',
+74819=>'L',
+74820=>'L',
+74821=>'L',
+74822=>'L',
+74823=>'L',
+74824=>'L',
+74825=>'L',
+74826=>'L',
+74827=>'L',
+74828=>'L',
+74829=>'L',
+74830=>'L',
+74831=>'L',
+74832=>'L',
+74833=>'L',
+74834=>'L',
+74835=>'L',
+74836=>'L',
+74837=>'L',
+74838=>'L',
+74839=>'L',
+74840=>'L',
+74841=>'L',
+74842=>'L',
+74843=>'L',
+74844=>'L',
+74845=>'L',
+74846=>'L',
+74847=>'L',
+74848=>'L',
+74849=>'L',
+74850=>'L',
+74864=>'L',
+74865=>'L',
+74866=>'L',
+74867=>'L',
+118784=>'L',
+118785=>'L',
+118786=>'L',
+118787=>'L',
+118788=>'L',
+118789=>'L',
+118790=>'L',
+118791=>'L',
+118792=>'L',
+118793=>'L',
+118794=>'L',
+118795=>'L',
+118796=>'L',
+118797=>'L',
+118798=>'L',
+118799=>'L',
+118800=>'L',
+118801=>'L',
+118802=>'L',
+118803=>'L',
+118804=>'L',
+118805=>'L',
+118806=>'L',
+118807=>'L',
+118808=>'L',
+118809=>'L',
+118810=>'L',
+118811=>'L',
+118812=>'L',
+118813=>'L',
+118814=>'L',
+118815=>'L',
+118816=>'L',
+118817=>'L',
+118818=>'L',
+118819=>'L',
+118820=>'L',
+118821=>'L',
+118822=>'L',
+118823=>'L',
+118824=>'L',
+118825=>'L',
+118826=>'L',
+118827=>'L',
+118828=>'L',
+118829=>'L',
+118830=>'L',
+118831=>'L',
+118832=>'L',
+118833=>'L',
+118834=>'L',
+118835=>'L',
+118836=>'L',
+118837=>'L',
+118838=>'L',
+118839=>'L',
+118840=>'L',
+118841=>'L',
+118842=>'L',
+118843=>'L',
+118844=>'L',
+118845=>'L',
+118846=>'L',
+118847=>'L',
+118848=>'L',
+118849=>'L',
+118850=>'L',
+118851=>'L',
+118852=>'L',
+118853=>'L',
+118854=>'L',
+118855=>'L',
+118856=>'L',
+118857=>'L',
+118858=>'L',
+118859=>'L',
+118860=>'L',
+118861=>'L',
+118862=>'L',
+118863=>'L',
+118864=>'L',
+118865=>'L',
+118866=>'L',
+118867=>'L',
+118868=>'L',
+118869=>'L',
+118870=>'L',
+118871=>'L',
+118872=>'L',
+118873=>'L',
+118874=>'L',
+118875=>'L',
+118876=>'L',
+118877=>'L',
+118878=>'L',
+118879=>'L',
+118880=>'L',
+118881=>'L',
+118882=>'L',
+118883=>'L',
+118884=>'L',
+118885=>'L',
+118886=>'L',
+118887=>'L',
+118888=>'L',
+118889=>'L',
+118890=>'L',
+118891=>'L',
+118892=>'L',
+118893=>'L',
+118894=>'L',
+118895=>'L',
+118896=>'L',
+118897=>'L',
+118898=>'L',
+118899=>'L',
+118900=>'L',
+118901=>'L',
+118902=>'L',
+118903=>'L',
+118904=>'L',
+118905=>'L',
+118906=>'L',
+118907=>'L',
+118908=>'L',
+118909=>'L',
+118910=>'L',
+118911=>'L',
+118912=>'L',
+118913=>'L',
+118914=>'L',
+118915=>'L',
+118916=>'L',
+118917=>'L',
+118918=>'L',
+118919=>'L',
+118920=>'L',
+118921=>'L',
+118922=>'L',
+118923=>'L',
+118924=>'L',
+118925=>'L',
+118926=>'L',
+118927=>'L',
+118928=>'L',
+118929=>'L',
+118930=>'L',
+118931=>'L',
+118932=>'L',
+118933=>'L',
+118934=>'L',
+118935=>'L',
+118936=>'L',
+118937=>'L',
+118938=>'L',
+118939=>'L',
+118940=>'L',
+118941=>'L',
+118942=>'L',
+118943=>'L',
+118944=>'L',
+118945=>'L',
+118946=>'L',
+118947=>'L',
+118948=>'L',
+118949=>'L',
+118950=>'L',
+118951=>'L',
+118952=>'L',
+118953=>'L',
+118954=>'L',
+118955=>'L',
+118956=>'L',
+118957=>'L',
+118958=>'L',
+118959=>'L',
+118960=>'L',
+118961=>'L',
+118962=>'L',
+118963=>'L',
+118964=>'L',
+118965=>'L',
+118966=>'L',
+118967=>'L',
+118968=>'L',
+118969=>'L',
+118970=>'L',
+118971=>'L',
+118972=>'L',
+118973=>'L',
+118974=>'L',
+118975=>'L',
+118976=>'L',
+118977=>'L',
+118978=>'L',
+118979=>'L',
+118980=>'L',
+118981=>'L',
+118982=>'L',
+118983=>'L',
+118984=>'L',
+118985=>'L',
+118986=>'L',
+118987=>'L',
+118988=>'L',
+118989=>'L',
+118990=>'L',
+118991=>'L',
+118992=>'L',
+118993=>'L',
+118994=>'L',
+118995=>'L',
+118996=>'L',
+118997=>'L',
+118998=>'L',
+118999=>'L',
+119000=>'L',
+119001=>'L',
+119002=>'L',
+119003=>'L',
+119004=>'L',
+119005=>'L',
+119006=>'L',
+119007=>'L',
+119008=>'L',
+119009=>'L',
+119010=>'L',
+119011=>'L',
+119012=>'L',
+119013=>'L',
+119014=>'L',
+119015=>'L',
+119016=>'L',
+119017=>'L',
+119018=>'L',
+119019=>'L',
+119020=>'L',
+119021=>'L',
+119022=>'L',
+119023=>'L',
+119024=>'L',
+119025=>'L',
+119026=>'L',
+119027=>'L',
+119028=>'L',
+119029=>'L',
+119040=>'L',
+119041=>'L',
+119042=>'L',
+119043=>'L',
+119044=>'L',
+119045=>'L',
+119046=>'L',
+119047=>'L',
+119048=>'L',
+119049=>'L',
+119050=>'L',
+119051=>'L',
+119052=>'L',
+119053=>'L',
+119054=>'L',
+119055=>'L',
+119056=>'L',
+119057=>'L',
+119058=>'L',
+119059=>'L',
+119060=>'L',
+119061=>'L',
+119062=>'L',
+119063=>'L',
+119064=>'L',
+119065=>'L',
+119066=>'L',
+119067=>'L',
+119068=>'L',
+119069=>'L',
+119070=>'L',
+119071=>'L',
+119072=>'L',
+119073=>'L',
+119074=>'L',
+119075=>'L',
+119076=>'L',
+119077=>'L',
+119078=>'L',
+119082=>'L',
+119083=>'L',
+119084=>'L',
+119085=>'L',
+119086=>'L',
+119087=>'L',
+119088=>'L',
+119089=>'L',
+119090=>'L',
+119091=>'L',
+119092=>'L',
+119093=>'L',
+119094=>'L',
+119095=>'L',
+119096=>'L',
+119097=>'L',
+119098=>'L',
+119099=>'L',
+119100=>'L',
+119101=>'L',
+119102=>'L',
+119103=>'L',
+119104=>'L',
+119105=>'L',
+119106=>'L',
+119107=>'L',
+119108=>'L',
+119109=>'L',
+119110=>'L',
+119111=>'L',
+119112=>'L',
+119113=>'L',
+119114=>'L',
+119115=>'L',
+119116=>'L',
+119117=>'L',
+119118=>'L',
+119119=>'L',
+119120=>'L',
+119121=>'L',
+119122=>'L',
+119123=>'L',
+119124=>'L',
+119125=>'L',
+119126=>'L',
+119127=>'L',
+119128=>'L',
+119129=>'L',
+119130=>'L',
+119131=>'L',
+119132=>'L',
+119133=>'L',
+119134=>'L',
+119135=>'L',
+119136=>'L',
+119137=>'L',
+119138=>'L',
+119139=>'L',
+119140=>'L',
+119141=>'L',
+119142=>'L',
+119143=>'NSM',
+119144=>'NSM',
+119145=>'NSM',
+119146=>'L',
+119147=>'L',
+119148=>'L',
+119149=>'L',
+119150=>'L',
+119151=>'L',
+119152=>'L',
+119153=>'L',
+119154=>'L',
+119155=>'BN',
+119156=>'BN',
+119157=>'BN',
+119158=>'BN',
+119159=>'BN',
+119160=>'BN',
+119161=>'BN',
+119162=>'BN',
+119163=>'NSM',
+119164=>'NSM',
+119165=>'NSM',
+119166=>'NSM',
+119167=>'NSM',
+119168=>'NSM',
+119169=>'NSM',
+119170=>'NSM',
+119171=>'L',
+119172=>'L',
+119173=>'NSM',
+119174=>'NSM',
+119175=>'NSM',
+119176=>'NSM',
+119177=>'NSM',
+119178=>'NSM',
+119179=>'NSM',
+119180=>'L',
+119181=>'L',
+119182=>'L',
+119183=>'L',
+119184=>'L',
+119185=>'L',
+119186=>'L',
+119187=>'L',
+119188=>'L',
+119189=>'L',
+119190=>'L',
+119191=>'L',
+119192=>'L',
+119193=>'L',
+119194=>'L',
+119195=>'L',
+119196=>'L',
+119197=>'L',
+119198=>'L',
+119199=>'L',
+119200=>'L',
+119201=>'L',
+119202=>'L',
+119203=>'L',
+119204=>'L',
+119205=>'L',
+119206=>'L',
+119207=>'L',
+119208=>'L',
+119209=>'L',
+119210=>'NSM',
+119211=>'NSM',
+119212=>'NSM',
+119213=>'NSM',
+119214=>'L',
+119215=>'L',
+119216=>'L',
+119217=>'L',
+119218=>'L',
+119219=>'L',
+119220=>'L',
+119221=>'L',
+119222=>'L',
+119223=>'L',
+119224=>'L',
+119225=>'L',
+119226=>'L',
+119227=>'L',
+119228=>'L',
+119229=>'L',
+119230=>'L',
+119231=>'L',
+119232=>'L',
+119233=>'L',
+119234=>'L',
+119235=>'L',
+119236=>'L',
+119237=>'L',
+119238=>'L',
+119239=>'L',
+119240=>'L',
+119241=>'L',
+119242=>'L',
+119243=>'L',
+119244=>'L',
+119245=>'L',
+119246=>'L',
+119247=>'L',
+119248=>'L',
+119249=>'L',
+119250=>'L',
+119251=>'L',
+119252=>'L',
+119253=>'L',
+119254=>'L',
+119255=>'L',
+119256=>'L',
+119257=>'L',
+119258=>'L',
+119259=>'L',
+119260=>'L',
+119261=>'L',
+119296=>'ON',
+119297=>'ON',
+119298=>'ON',
+119299=>'ON',
+119300=>'ON',
+119301=>'ON',
+119302=>'ON',
+119303=>'ON',
+119304=>'ON',
+119305=>'ON',
+119306=>'ON',
+119307=>'ON',
+119308=>'ON',
+119309=>'ON',
+119310=>'ON',
+119311=>'ON',
+119312=>'ON',
+119313=>'ON',
+119314=>'ON',
+119315=>'ON',
+119316=>'ON',
+119317=>'ON',
+119318=>'ON',
+119319=>'ON',
+119320=>'ON',
+119321=>'ON',
+119322=>'ON',
+119323=>'ON',
+119324=>'ON',
+119325=>'ON',
+119326=>'ON',
+119327=>'ON',
+119328=>'ON',
+119329=>'ON',
+119330=>'ON',
+119331=>'ON',
+119332=>'ON',
+119333=>'ON',
+119334=>'ON',
+119335=>'ON',
+119336=>'ON',
+119337=>'ON',
+119338=>'ON',
+119339=>'ON',
+119340=>'ON',
+119341=>'ON',
+119342=>'ON',
+119343=>'ON',
+119344=>'ON',
+119345=>'ON',
+119346=>'ON',
+119347=>'ON',
+119348=>'ON',
+119349=>'ON',
+119350=>'ON',
+119351=>'ON',
+119352=>'ON',
+119353=>'ON',
+119354=>'ON',
+119355=>'ON',
+119356=>'ON',
+119357=>'ON',
+119358=>'ON',
+119359=>'ON',
+119360=>'ON',
+119361=>'ON',
+119362=>'NSM',
+119363=>'NSM',
+119364=>'NSM',
+119365=>'ON',
+119552=>'ON',
+119553=>'ON',
+119554=>'ON',
+119555=>'ON',
+119556=>'ON',
+119557=>'ON',
+119558=>'ON',
+119559=>'ON',
+119560=>'ON',
+119561=>'ON',
+119562=>'ON',
+119563=>'ON',
+119564=>'ON',
+119565=>'ON',
+119566=>'ON',
+119567=>'ON',
+119568=>'ON',
+119569=>'ON',
+119570=>'ON',
+119571=>'ON',
+119572=>'ON',
+119573=>'ON',
+119574=>'ON',
+119575=>'ON',
+119576=>'ON',
+119577=>'ON',
+119578=>'ON',
+119579=>'ON',
+119580=>'ON',
+119581=>'ON',
+119582=>'ON',
+119583=>'ON',
+119584=>'ON',
+119585=>'ON',
+119586=>'ON',
+119587=>'ON',
+119588=>'ON',
+119589=>'ON',
+119590=>'ON',
+119591=>'ON',
+119592=>'ON',
+119593=>'ON',
+119594=>'ON',
+119595=>'ON',
+119596=>'ON',
+119597=>'ON',
+119598=>'ON',
+119599=>'ON',
+119600=>'ON',
+119601=>'ON',
+119602=>'ON',
+119603=>'ON',
+119604=>'ON',
+119605=>'ON',
+119606=>'ON',
+119607=>'ON',
+119608=>'ON',
+119609=>'ON',
+119610=>'ON',
+119611=>'ON',
+119612=>'ON',
+119613=>'ON',
+119614=>'ON',
+119615=>'ON',
+119616=>'ON',
+119617=>'ON',
+119618=>'ON',
+119619=>'ON',
+119620=>'ON',
+119621=>'ON',
+119622=>'ON',
+119623=>'ON',
+119624=>'ON',
+119625=>'ON',
+119626=>'ON',
+119627=>'ON',
+119628=>'ON',
+119629=>'ON',
+119630=>'ON',
+119631=>'ON',
+119632=>'ON',
+119633=>'ON',
+119634=>'ON',
+119635=>'ON',
+119636=>'ON',
+119637=>'ON',
+119638=>'ON',
+119648=>'L',
+119649=>'L',
+119650=>'L',
+119651=>'L',
+119652=>'L',
+119653=>'L',
+119654=>'L',
+119655=>'L',
+119656=>'L',
+119657=>'L',
+119658=>'L',
+119659=>'L',
+119660=>'L',
+119661=>'L',
+119662=>'L',
+119663=>'L',
+119664=>'L',
+119665=>'L',
+119808=>'L',
+119809=>'L',
+119810=>'L',
+119811=>'L',
+119812=>'L',
+119813=>'L',
+119814=>'L',
+119815=>'L',
+119816=>'L',
+119817=>'L',
+119818=>'L',
+119819=>'L',
+119820=>'L',
+119821=>'L',
+119822=>'L',
+119823=>'L',
+119824=>'L',
+119825=>'L',
+119826=>'L',
+119827=>'L',
+119828=>'L',
+119829=>'L',
+119830=>'L',
+119831=>'L',
+119832=>'L',
+119833=>'L',
+119834=>'L',
+119835=>'L',
+119836=>'L',
+119837=>'L',
+119838=>'L',
+119839=>'L',
+119840=>'L',
+119841=>'L',
+119842=>'L',
+119843=>'L',
+119844=>'L',
+119845=>'L',
+119846=>'L',
+119847=>'L',
+119848=>'L',
+119849=>'L',
+119850=>'L',
+119851=>'L',
+119852=>'L',
+119853=>'L',
+119854=>'L',
+119855=>'L',
+119856=>'L',
+119857=>'L',
+119858=>'L',
+119859=>'L',
+119860=>'L',
+119861=>'L',
+119862=>'L',
+119863=>'L',
+119864=>'L',
+119865=>'L',
+119866=>'L',
+119867=>'L',
+119868=>'L',
+119869=>'L',
+119870=>'L',
+119871=>'L',
+119872=>'L',
+119873=>'L',
+119874=>'L',
+119875=>'L',
+119876=>'L',
+119877=>'L',
+119878=>'L',
+119879=>'L',
+119880=>'L',
+119881=>'L',
+119882=>'L',
+119883=>'L',
+119884=>'L',
+119885=>'L',
+119886=>'L',
+119887=>'L',
+119888=>'L',
+119889=>'L',
+119890=>'L',
+119891=>'L',
+119892=>'L',
+119894=>'L',
+119895=>'L',
+119896=>'L',
+119897=>'L',
+119898=>'L',
+119899=>'L',
+119900=>'L',
+119901=>'L',
+119902=>'L',
+119903=>'L',
+119904=>'L',
+119905=>'L',
+119906=>'L',
+119907=>'L',
+119908=>'L',
+119909=>'L',
+119910=>'L',
+119911=>'L',
+119912=>'L',
+119913=>'L',
+119914=>'L',
+119915=>'L',
+119916=>'L',
+119917=>'L',
+119918=>'L',
+119919=>'L',
+119920=>'L',
+119921=>'L',
+119922=>'L',
+119923=>'L',
+119924=>'L',
+119925=>'L',
+119926=>'L',
+119927=>'L',
+119928=>'L',
+119929=>'L',
+119930=>'L',
+119931=>'L',
+119932=>'L',
+119933=>'L',
+119934=>'L',
+119935=>'L',
+119936=>'L',
+119937=>'L',
+119938=>'L',
+119939=>'L',
+119940=>'L',
+119941=>'L',
+119942=>'L',
+119943=>'L',
+119944=>'L',
+119945=>'L',
+119946=>'L',
+119947=>'L',
+119948=>'L',
+119949=>'L',
+119950=>'L',
+119951=>'L',
+119952=>'L',
+119953=>'L',
+119954=>'L',
+119955=>'L',
+119956=>'L',
+119957=>'L',
+119958=>'L',
+119959=>'L',
+119960=>'L',
+119961=>'L',
+119962=>'L',
+119963=>'L',
+119964=>'L',
+119966=>'L',
+119967=>'L',
+119970=>'L',
+119973=>'L',
+119974=>'L',
+119977=>'L',
+119978=>'L',
+119979=>'L',
+119980=>'L',
+119982=>'L',
+119983=>'L',
+119984=>'L',
+119985=>'L',
+119986=>'L',
+119987=>'L',
+119988=>'L',
+119989=>'L',
+119990=>'L',
+119991=>'L',
+119992=>'L',
+119993=>'L',
+119995=>'L',
+119997=>'L',
+119998=>'L',
+119999=>'L',
+120000=>'L',
+120001=>'L',
+120002=>'L',
+120003=>'L',
+120005=>'L',
+120006=>'L',
+120007=>'L',
+120008=>'L',
+120009=>'L',
+120010=>'L',
+120011=>'L',
+120012=>'L',
+120013=>'L',
+120014=>'L',
+120015=>'L',
+120016=>'L',
+120017=>'L',
+120018=>'L',
+120019=>'L',
+120020=>'L',
+120021=>'L',
+120022=>'L',
+120023=>'L',
+120024=>'L',
+120025=>'L',
+120026=>'L',
+120027=>'L',
+120028=>'L',
+120029=>'L',
+120030=>'L',
+120031=>'L',
+120032=>'L',
+120033=>'L',
+120034=>'L',
+120035=>'L',
+120036=>'L',
+120037=>'L',
+120038=>'L',
+120039=>'L',
+120040=>'L',
+120041=>'L',
+120042=>'L',
+120043=>'L',
+120044=>'L',
+120045=>'L',
+120046=>'L',
+120047=>'L',
+120048=>'L',
+120049=>'L',
+120050=>'L',
+120051=>'L',
+120052=>'L',
+120053=>'L',
+120054=>'L',
+120055=>'L',
+120056=>'L',
+120057=>'L',
+120058=>'L',
+120059=>'L',
+120060=>'L',
+120061=>'L',
+120062=>'L',
+120063=>'L',
+120064=>'L',
+120065=>'L',
+120066=>'L',
+120067=>'L',
+120068=>'L',
+120069=>'L',
+120071=>'L',
+120072=>'L',
+120073=>'L',
+120074=>'L',
+120077=>'L',
+120078=>'L',
+120079=>'L',
+120080=>'L',
+120081=>'L',
+120082=>'L',
+120083=>'L',
+120084=>'L',
+120086=>'L',
+120087=>'L',
+120088=>'L',
+120089=>'L',
+120090=>'L',
+120091=>'L',
+120092=>'L',
+120094=>'L',
+120095=>'L',
+120096=>'L',
+120097=>'L',
+120098=>'L',
+120099=>'L',
+120100=>'L',
+120101=>'L',
+120102=>'L',
+120103=>'L',
+120104=>'L',
+120105=>'L',
+120106=>'L',
+120107=>'L',
+120108=>'L',
+120109=>'L',
+120110=>'L',
+120111=>'L',
+120112=>'L',
+120113=>'L',
+120114=>'L',
+120115=>'L',
+120116=>'L',
+120117=>'L',
+120118=>'L',
+120119=>'L',
+120120=>'L',
+120121=>'L',
+120123=>'L',
+120124=>'L',
+120125=>'L',
+120126=>'L',
+120128=>'L',
+120129=>'L',
+120130=>'L',
+120131=>'L',
+120132=>'L',
+120134=>'L',
+120138=>'L',
+120139=>'L',
+120140=>'L',
+120141=>'L',
+120142=>'L',
+120143=>'L',
+120144=>'L',
+120146=>'L',
+120147=>'L',
+120148=>'L',
+120149=>'L',
+120150=>'L',
+120151=>'L',
+120152=>'L',
+120153=>'L',
+120154=>'L',
+120155=>'L',
+120156=>'L',
+120157=>'L',
+120158=>'L',
+120159=>'L',
+120160=>'L',
+120161=>'L',
+120162=>'L',
+120163=>'L',
+120164=>'L',
+120165=>'L',
+120166=>'L',
+120167=>'L',
+120168=>'L',
+120169=>'L',
+120170=>'L',
+120171=>'L',
+120172=>'L',
+120173=>'L',
+120174=>'L',
+120175=>'L',
+120176=>'L',
+120177=>'L',
+120178=>'L',
+120179=>'L',
+120180=>'L',
+120181=>'L',
+120182=>'L',
+120183=>'L',
+120184=>'L',
+120185=>'L',
+120186=>'L',
+120187=>'L',
+120188=>'L',
+120189=>'L',
+120190=>'L',
+120191=>'L',
+120192=>'L',
+120193=>'L',
+120194=>'L',
+120195=>'L',
+120196=>'L',
+120197=>'L',
+120198=>'L',
+120199=>'L',
+120200=>'L',
+120201=>'L',
+120202=>'L',
+120203=>'L',
+120204=>'L',
+120205=>'L',
+120206=>'L',
+120207=>'L',
+120208=>'L',
+120209=>'L',
+120210=>'L',
+120211=>'L',
+120212=>'L',
+120213=>'L',
+120214=>'L',
+120215=>'L',
+120216=>'L',
+120217=>'L',
+120218=>'L',
+120219=>'L',
+120220=>'L',
+120221=>'L',
+120222=>'L',
+120223=>'L',
+120224=>'L',
+120225=>'L',
+120226=>'L',
+120227=>'L',
+120228=>'L',
+120229=>'L',
+120230=>'L',
+120231=>'L',
+120232=>'L',
+120233=>'L',
+120234=>'L',
+120235=>'L',
+120236=>'L',
+120237=>'L',
+120238=>'L',
+120239=>'L',
+120240=>'L',
+120241=>'L',
+120242=>'L',
+120243=>'L',
+120244=>'L',
+120245=>'L',
+120246=>'L',
+120247=>'L',
+120248=>'L',
+120249=>'L',
+120250=>'L',
+120251=>'L',
+120252=>'L',
+120253=>'L',
+120254=>'L',
+120255=>'L',
+120256=>'L',
+120257=>'L',
+120258=>'L',
+120259=>'L',
+120260=>'L',
+120261=>'L',
+120262=>'L',
+120263=>'L',
+120264=>'L',
+120265=>'L',
+120266=>'L',
+120267=>'L',
+120268=>'L',
+120269=>'L',
+120270=>'L',
+120271=>'L',
+120272=>'L',
+120273=>'L',
+120274=>'L',
+120275=>'L',
+120276=>'L',
+120277=>'L',
+120278=>'L',
+120279=>'L',
+120280=>'L',
+120281=>'L',
+120282=>'L',
+120283=>'L',
+120284=>'L',
+120285=>'L',
+120286=>'L',
+120287=>'L',
+120288=>'L',
+120289=>'L',
+120290=>'L',
+120291=>'L',
+120292=>'L',
+120293=>'L',
+120294=>'L',
+120295=>'L',
+120296=>'L',
+120297=>'L',
+120298=>'L',
+120299=>'L',
+120300=>'L',
+120301=>'L',
+120302=>'L',
+120303=>'L',
+120304=>'L',
+120305=>'L',
+120306=>'L',
+120307=>'L',
+120308=>'L',
+120309=>'L',
+120310=>'L',
+120311=>'L',
+120312=>'L',
+120313=>'L',
+120314=>'L',
+120315=>'L',
+120316=>'L',
+120317=>'L',
+120318=>'L',
+120319=>'L',
+120320=>'L',
+120321=>'L',
+120322=>'L',
+120323=>'L',
+120324=>'L',
+120325=>'L',
+120326=>'L',
+120327=>'L',
+120328=>'L',
+120329=>'L',
+120330=>'L',
+120331=>'L',
+120332=>'L',
+120333=>'L',
+120334=>'L',
+120335=>'L',
+120336=>'L',
+120337=>'L',
+120338=>'L',
+120339=>'L',
+120340=>'L',
+120341=>'L',
+120342=>'L',
+120343=>'L',
+120344=>'L',
+120345=>'L',
+120346=>'L',
+120347=>'L',
+120348=>'L',
+120349=>'L',
+120350=>'L',
+120351=>'L',
+120352=>'L',
+120353=>'L',
+120354=>'L',
+120355=>'L',
+120356=>'L',
+120357=>'L',
+120358=>'L',
+120359=>'L',
+120360=>'L',
+120361=>'L',
+120362=>'L',
+120363=>'L',
+120364=>'L',
+120365=>'L',
+120366=>'L',
+120367=>'L',
+120368=>'L',
+120369=>'L',
+120370=>'L',
+120371=>'L',
+120372=>'L',
+120373=>'L',
+120374=>'L',
+120375=>'L',
+120376=>'L',
+120377=>'L',
+120378=>'L',
+120379=>'L',
+120380=>'L',
+120381=>'L',
+120382=>'L',
+120383=>'L',
+120384=>'L',
+120385=>'L',
+120386=>'L',
+120387=>'L',
+120388=>'L',
+120389=>'L',
+120390=>'L',
+120391=>'L',
+120392=>'L',
+120393=>'L',
+120394=>'L',
+120395=>'L',
+120396=>'L',
+120397=>'L',
+120398=>'L',
+120399=>'L',
+120400=>'L',
+120401=>'L',
+120402=>'L',
+120403=>'L',
+120404=>'L',
+120405=>'L',
+120406=>'L',
+120407=>'L',
+120408=>'L',
+120409=>'L',
+120410=>'L',
+120411=>'L',
+120412=>'L',
+120413=>'L',
+120414=>'L',
+120415=>'L',
+120416=>'L',
+120417=>'L',
+120418=>'L',
+120419=>'L',
+120420=>'L',
+120421=>'L',
+120422=>'L',
+120423=>'L',
+120424=>'L',
+120425=>'L',
+120426=>'L',
+120427=>'L',
+120428=>'L',
+120429=>'L',
+120430=>'L',
+120431=>'L',
+120432=>'L',
+120433=>'L',
+120434=>'L',
+120435=>'L',
+120436=>'L',
+120437=>'L',
+120438=>'L',
+120439=>'L',
+120440=>'L',
+120441=>'L',
+120442=>'L',
+120443=>'L',
+120444=>'L',
+120445=>'L',
+120446=>'L',
+120447=>'L',
+120448=>'L',
+120449=>'L',
+120450=>'L',
+120451=>'L',
+120452=>'L',
+120453=>'L',
+120454=>'L',
+120455=>'L',
+120456=>'L',
+120457=>'L',
+120458=>'L',
+120459=>'L',
+120460=>'L',
+120461=>'L',
+120462=>'L',
+120463=>'L',
+120464=>'L',
+120465=>'L',
+120466=>'L',
+120467=>'L',
+120468=>'L',
+120469=>'L',
+120470=>'L',
+120471=>'L',
+120472=>'L',
+120473=>'L',
+120474=>'L',
+120475=>'L',
+120476=>'L',
+120477=>'L',
+120478=>'L',
+120479=>'L',
+120480=>'L',
+120481=>'L',
+120482=>'L',
+120483=>'L',
+120484=>'L',
+120485=>'L',
+120488=>'L',
+120489=>'L',
+120490=>'L',
+120491=>'L',
+120492=>'L',
+120493=>'L',
+120494=>'L',
+120495=>'L',
+120496=>'L',
+120497=>'L',
+120498=>'L',
+120499=>'L',
+120500=>'L',
+120501=>'L',
+120502=>'L',
+120503=>'L',
+120504=>'L',
+120505=>'L',
+120506=>'L',
+120507=>'L',
+120508=>'L',
+120509=>'L',
+120510=>'L',
+120511=>'L',
+120512=>'L',
+120513=>'L',
+120514=>'L',
+120515=>'L',
+120516=>'L',
+120517=>'L',
+120518=>'L',
+120519=>'L',
+120520=>'L',
+120521=>'L',
+120522=>'L',
+120523=>'L',
+120524=>'L',
+120525=>'L',
+120526=>'L',
+120527=>'L',
+120528=>'L',
+120529=>'L',
+120530=>'L',
+120531=>'L',
+120532=>'L',
+120533=>'L',
+120534=>'L',
+120535=>'L',
+120536=>'L',
+120537=>'L',
+120538=>'L',
+120539=>'L',
+120540=>'L',
+120541=>'L',
+120542=>'L',
+120543=>'L',
+120544=>'L',
+120545=>'L',
+120546=>'L',
+120547=>'L',
+120548=>'L',
+120549=>'L',
+120550=>'L',
+120551=>'L',
+120552=>'L',
+120553=>'L',
+120554=>'L',
+120555=>'L',
+120556=>'L',
+120557=>'L',
+120558=>'L',
+120559=>'L',
+120560=>'L',
+120561=>'L',
+120562=>'L',
+120563=>'L',
+120564=>'L',
+120565=>'L',
+120566=>'L',
+120567=>'L',
+120568=>'L',
+120569=>'L',
+120570=>'L',
+120571=>'L',
+120572=>'L',
+120573=>'L',
+120574=>'L',
+120575=>'L',
+120576=>'L',
+120577=>'L',
+120578=>'L',
+120579=>'L',
+120580=>'L',
+120581=>'L',
+120582=>'L',
+120583=>'L',
+120584=>'L',
+120585=>'L',
+120586=>'L',
+120587=>'L',
+120588=>'L',
+120589=>'L',
+120590=>'L',
+120591=>'L',
+120592=>'L',
+120593=>'L',
+120594=>'L',
+120595=>'L',
+120596=>'L',
+120597=>'L',
+120598=>'L',
+120599=>'L',
+120600=>'L',
+120601=>'L',
+120602=>'L',
+120603=>'L',
+120604=>'L',
+120605=>'L',
+120606=>'L',
+120607=>'L',
+120608=>'L',
+120609=>'L',
+120610=>'L',
+120611=>'L',
+120612=>'L',
+120613=>'L',
+120614=>'L',
+120615=>'L',
+120616=>'L',
+120617=>'L',
+120618=>'L',
+120619=>'L',
+120620=>'L',
+120621=>'L',
+120622=>'L',
+120623=>'L',
+120624=>'L',
+120625=>'L',
+120626=>'L',
+120627=>'L',
+120628=>'L',
+120629=>'L',
+120630=>'L',
+120631=>'L',
+120632=>'L',
+120633=>'L',
+120634=>'L',
+120635=>'L',
+120636=>'L',
+120637=>'L',
+120638=>'L',
+120639=>'L',
+120640=>'L',
+120641=>'L',
+120642=>'L',
+120643=>'L',
+120644=>'L',
+120645=>'L',
+120646=>'L',
+120647=>'L',
+120648=>'L',
+120649=>'L',
+120650=>'L',
+120651=>'L',
+120652=>'L',
+120653=>'L',
+120654=>'L',
+120655=>'L',
+120656=>'L',
+120657=>'L',
+120658=>'L',
+120659=>'L',
+120660=>'L',
+120661=>'L',
+120662=>'L',
+120663=>'L',
+120664=>'L',
+120665=>'L',
+120666=>'L',
+120667=>'L',
+120668=>'L',
+120669=>'L',
+120670=>'L',
+120671=>'L',
+120672=>'L',
+120673=>'L',
+120674=>'L',
+120675=>'L',
+120676=>'L',
+120677=>'L',
+120678=>'L',
+120679=>'L',
+120680=>'L',
+120681=>'L',
+120682=>'L',
+120683=>'L',
+120684=>'L',
+120685=>'L',
+120686=>'L',
+120687=>'L',
+120688=>'L',
+120689=>'L',
+120690=>'L',
+120691=>'L',
+120692=>'L',
+120693=>'L',
+120694=>'L',
+120695=>'L',
+120696=>'L',
+120697=>'L',
+120698=>'L',
+120699=>'L',
+120700=>'L',
+120701=>'L',
+120702=>'L',
+120703=>'L',
+120704=>'L',
+120705=>'L',
+120706=>'L',
+120707=>'L',
+120708=>'L',
+120709=>'L',
+120710=>'L',
+120711=>'L',
+120712=>'L',
+120713=>'L',
+120714=>'L',
+120715=>'L',
+120716=>'L',
+120717=>'L',
+120718=>'L',
+120719=>'L',
+120720=>'L',
+120721=>'L',
+120722=>'L',
+120723=>'L',
+120724=>'L',
+120725=>'L',
+120726=>'L',
+120727=>'L',
+120728=>'L',
+120729=>'L',
+120730=>'L',
+120731=>'L',
+120732=>'L',
+120733=>'L',
+120734=>'L',
+120735=>'L',
+120736=>'L',
+120737=>'L',
+120738=>'L',
+120739=>'L',
+120740=>'L',
+120741=>'L',
+120742=>'L',
+120743=>'L',
+120744=>'L',
+120745=>'L',
+120746=>'L',
+120747=>'L',
+120748=>'L',
+120749=>'L',
+120750=>'L',
+120751=>'L',
+120752=>'L',
+120753=>'L',
+120754=>'L',
+120755=>'L',
+120756=>'L',
+120757=>'L',
+120758=>'L',
+120759=>'L',
+120760=>'L',
+120761=>'L',
+120762=>'L',
+120763=>'L',
+120764=>'L',
+120765=>'L',
+120766=>'L',
+120767=>'L',
+120768=>'L',
+120769=>'L',
+120770=>'L',
+120771=>'L',
+120772=>'L',
+120773=>'L',
+120774=>'L',
+120775=>'L',
+120776=>'L',
+120777=>'L',
+120778=>'L',
+120779=>'L',
+120782=>'EN',
+120783=>'EN',
+120784=>'EN',
+120785=>'EN',
+120786=>'EN',
+120787=>'EN',
+120788=>'EN',
+120789=>'EN',
+120790=>'EN',
+120791=>'EN',
+120792=>'EN',
+120793=>'EN',
+120794=>'EN',
+120795=>'EN',
+120796=>'EN',
+120797=>'EN',
+120798=>'EN',
+120799=>'EN',
+120800=>'EN',
+120801=>'EN',
+120802=>'EN',
+120803=>'EN',
+120804=>'EN',
+120805=>'EN',
+120806=>'EN',
+120807=>'EN',
+120808=>'EN',
+120809=>'EN',
+120810=>'EN',
+120811=>'EN',
+120812=>'EN',
+120813=>'EN',
+120814=>'EN',
+120815=>'EN',
+120816=>'EN',
+120817=>'EN',
+120818=>'EN',
+120819=>'EN',
+120820=>'EN',
+120821=>'EN',
+120822=>'EN',
+120823=>'EN',
+120824=>'EN',
+120825=>'EN',
+120826=>'EN',
+120827=>'EN',
+120828=>'EN',
+120829=>'EN',
+120830=>'EN',
+120831=>'EN',
+131072=>'L',
+173782=>'L',
+194560=>'L',
+194561=>'L',
+194562=>'L',
+194563=>'L',
+194564=>'L',
+194565=>'L',
+194566=>'L',
+194567=>'L',
+194568=>'L',
+194569=>'L',
+194570=>'L',
+194571=>'L',
+194572=>'L',
+194573=>'L',
+194574=>'L',
+194575=>'L',
+194576=>'L',
+194577=>'L',
+194578=>'L',
+194579=>'L',
+194580=>'L',
+194581=>'L',
+194582=>'L',
+194583=>'L',
+194584=>'L',
+194585=>'L',
+194586=>'L',
+194587=>'L',
+194588=>'L',
+194589=>'L',
+194590=>'L',
+194591=>'L',
+194592=>'L',
+194593=>'L',
+194594=>'L',
+194595=>'L',
+194596=>'L',
+194597=>'L',
+194598=>'L',
+194599=>'L',
+194600=>'L',
+194601=>'L',
+194602=>'L',
+194603=>'L',
+194604=>'L',
+194605=>'L',
+194606=>'L',
+194607=>'L',
+194608=>'L',
+194609=>'L',
+194610=>'L',
+194611=>'L',
+194612=>'L',
+194613=>'L',
+194614=>'L',
+194615=>'L',
+194616=>'L',
+194617=>'L',
+194618=>'L',
+194619=>'L',
+194620=>'L',
+194621=>'L',
+194622=>'L',
+194623=>'L',
+194624=>'L',
+194625=>'L',
+194626=>'L',
+194627=>'L',
+194628=>'L',
+194629=>'L',
+194630=>'L',
+194631=>'L',
+194632=>'L',
+194633=>'L',
+194634=>'L',
+194635=>'L',
+194636=>'L',
+194637=>'L',
+194638=>'L',
+194639=>'L',
+194640=>'L',
+194641=>'L',
+194642=>'L',
+194643=>'L',
+194644=>'L',
+194645=>'L',
+194646=>'L',
+194647=>'L',
+194648=>'L',
+194649=>'L',
+194650=>'L',
+194651=>'L',
+194652=>'L',
+194653=>'L',
+194654=>'L',
+194655=>'L',
+194656=>'L',
+194657=>'L',
+194658=>'L',
+194659=>'L',
+194660=>'L',
+194661=>'L',
+194662=>'L',
+194663=>'L',
+194664=>'L',
+194665=>'L',
+194666=>'L',
+194667=>'L',
+194668=>'L',
+194669=>'L',
+194670=>'L',
+194671=>'L',
+194672=>'L',
+194673=>'L',
+194674=>'L',
+194675=>'L',
+194676=>'L',
+194677=>'L',
+194678=>'L',
+194679=>'L',
+194680=>'L',
+194681=>'L',
+194682=>'L',
+194683=>'L',
+194684=>'L',
+194685=>'L',
+194686=>'L',
+194687=>'L',
+194688=>'L',
+194689=>'L',
+194690=>'L',
+194691=>'L',
+194692=>'L',
+194693=>'L',
+194694=>'L',
+194695=>'L',
+194696=>'L',
+194697=>'L',
+194698=>'L',
+194699=>'L',
+194700=>'L',
+194701=>'L',
+194702=>'L',
+194703=>'L',
+194704=>'L',
+194705=>'L',
+194706=>'L',
+194707=>'L',
+194708=>'L',
+194709=>'L',
+194710=>'L',
+194711=>'L',
+194712=>'L',
+194713=>'L',
+194714=>'L',
+194715=>'L',
+194716=>'L',
+194717=>'L',
+194718=>'L',
+194719=>'L',
+194720=>'L',
+194721=>'L',
+194722=>'L',
+194723=>'L',
+194724=>'L',
+194725=>'L',
+194726=>'L',
+194727=>'L',
+194728=>'L',
+194729=>'L',
+194730=>'L',
+194731=>'L',
+194732=>'L',
+194733=>'L',
+194734=>'L',
+194735=>'L',
+194736=>'L',
+194737=>'L',
+194738=>'L',
+194739=>'L',
+194740=>'L',
+194741=>'L',
+194742=>'L',
+194743=>'L',
+194744=>'L',
+194745=>'L',
+194746=>'L',
+194747=>'L',
+194748=>'L',
+194749=>'L',
+194750=>'L',
+194751=>'L',
+194752=>'L',
+194753=>'L',
+194754=>'L',
+194755=>'L',
+194756=>'L',
+194757=>'L',
+194758=>'L',
+194759=>'L',
+194760=>'L',
+194761=>'L',
+194762=>'L',
+194763=>'L',
+194764=>'L',
+194765=>'L',
+194766=>'L',
+194767=>'L',
+194768=>'L',
+194769=>'L',
+194770=>'L',
+194771=>'L',
+194772=>'L',
+194773=>'L',
+194774=>'L',
+194775=>'L',
+194776=>'L',
+194777=>'L',
+194778=>'L',
+194779=>'L',
+194780=>'L',
+194781=>'L',
+194782=>'L',
+194783=>'L',
+194784=>'L',
+194785=>'L',
+194786=>'L',
+194787=>'L',
+194788=>'L',
+194789=>'L',
+194790=>'L',
+194791=>'L',
+194792=>'L',
+194793=>'L',
+194794=>'L',
+194795=>'L',
+194796=>'L',
+194797=>'L',
+194798=>'L',
+194799=>'L',
+194800=>'L',
+194801=>'L',
+194802=>'L',
+194803=>'L',
+194804=>'L',
+194805=>'L',
+194806=>'L',
+194807=>'L',
+194808=>'L',
+194809=>'L',
+194810=>'L',
+194811=>'L',
+194812=>'L',
+194813=>'L',
+194814=>'L',
+194815=>'L',
+194816=>'L',
+194817=>'L',
+194818=>'L',
+194819=>'L',
+194820=>'L',
+194821=>'L',
+194822=>'L',
+194823=>'L',
+194824=>'L',
+194825=>'L',
+194826=>'L',
+194827=>'L',
+194828=>'L',
+194829=>'L',
+194830=>'L',
+194831=>'L',
+194832=>'L',
+194833=>'L',
+194834=>'L',
+194835=>'L',
+194836=>'L',
+194837=>'L',
+194838=>'L',
+194839=>'L',
+194840=>'L',
+194841=>'L',
+194842=>'L',
+194843=>'L',
+194844=>'L',
+194845=>'L',
+194846=>'L',
+194847=>'L',
+194848=>'L',
+194849=>'L',
+194850=>'L',
+194851=>'L',
+194852=>'L',
+194853=>'L',
+194854=>'L',
+194855=>'L',
+194856=>'L',
+194857=>'L',
+194858=>'L',
+194859=>'L',
+194860=>'L',
+194861=>'L',
+194862=>'L',
+194863=>'L',
+194864=>'L',
+194865=>'L',
+194866=>'L',
+194867=>'L',
+194868=>'L',
+194869=>'L',
+194870=>'L',
+194871=>'L',
+194872=>'L',
+194873=>'L',
+194874=>'L',
+194875=>'L',
+194876=>'L',
+194877=>'L',
+194878=>'L',
+194879=>'L',
+194880=>'L',
+194881=>'L',
+194882=>'L',
+194883=>'L',
+194884=>'L',
+194885=>'L',
+194886=>'L',
+194887=>'L',
+194888=>'L',
+194889=>'L',
+194890=>'L',
+194891=>'L',
+194892=>'L',
+194893=>'L',
+194894=>'L',
+194895=>'L',
+194896=>'L',
+194897=>'L',
+194898=>'L',
+194899=>'L',
+194900=>'L',
+194901=>'L',
+194902=>'L',
+194903=>'L',
+194904=>'L',
+194905=>'L',
+194906=>'L',
+194907=>'L',
+194908=>'L',
+194909=>'L',
+194910=>'L',
+194911=>'L',
+194912=>'L',
+194913=>'L',
+194914=>'L',
+194915=>'L',
+194916=>'L',
+194917=>'L',
+194918=>'L',
+194919=>'L',
+194920=>'L',
+194921=>'L',
+194922=>'L',
+194923=>'L',
+194924=>'L',
+194925=>'L',
+194926=>'L',
+194927=>'L',
+194928=>'L',
+194929=>'L',
+194930=>'L',
+194931=>'L',
+194932=>'L',
+194933=>'L',
+194934=>'L',
+194935=>'L',
+194936=>'L',
+194937=>'L',
+194938=>'L',
+194939=>'L',
+194940=>'L',
+194941=>'L',
+194942=>'L',
+194943=>'L',
+194944=>'L',
+194945=>'L',
+194946=>'L',
+194947=>'L',
+194948=>'L',
+194949=>'L',
+194950=>'L',
+194951=>'L',
+194952=>'L',
+194953=>'L',
+194954=>'L',
+194955=>'L',
+194956=>'L',
+194957=>'L',
+194958=>'L',
+194959=>'L',
+194960=>'L',
+194961=>'L',
+194962=>'L',
+194963=>'L',
+194964=>'L',
+194965=>'L',
+194966=>'L',
+194967=>'L',
+194968=>'L',
+194969=>'L',
+194970=>'L',
+194971=>'L',
+194972=>'L',
+194973=>'L',
+194974=>'L',
+194975=>'L',
+194976=>'L',
+194977=>'L',
+194978=>'L',
+194979=>'L',
+194980=>'L',
+194981=>'L',
+194982=>'L',
+194983=>'L',
+194984=>'L',
+194985=>'L',
+194986=>'L',
+194987=>'L',
+194988=>'L',
+194989=>'L',
+194990=>'L',
+194991=>'L',
+194992=>'L',
+194993=>'L',
+194994=>'L',
+194995=>'L',
+194996=>'L',
+194997=>'L',
+194998=>'L',
+194999=>'L',
+195000=>'L',
+195001=>'L',
+195002=>'L',
+195003=>'L',
+195004=>'L',
+195005=>'L',
+195006=>'L',
+195007=>'L',
+195008=>'L',
+195009=>'L',
+195010=>'L',
+195011=>'L',
+195012=>'L',
+195013=>'L',
+195014=>'L',
+195015=>'L',
+195016=>'L',
+195017=>'L',
+195018=>'L',
+195019=>'L',
+195020=>'L',
+195021=>'L',
+195022=>'L',
+195023=>'L',
+195024=>'L',
+195025=>'L',
+195026=>'L',
+195027=>'L',
+195028=>'L',
+195029=>'L',
+195030=>'L',
+195031=>'L',
+195032=>'L',
+195033=>'L',
+195034=>'L',
+195035=>'L',
+195036=>'L',
+195037=>'L',
+195038=>'L',
+195039=>'L',
+195040=>'L',
+195041=>'L',
+195042=>'L',
+195043=>'L',
+195044=>'L',
+195045=>'L',
+195046=>'L',
+195047=>'L',
+195048=>'L',
+195049=>'L',
+195050=>'L',
+195051=>'L',
+195052=>'L',
+195053=>'L',
+195054=>'L',
+195055=>'L',
+195056=>'L',
+195057=>'L',
+195058=>'L',
+195059=>'L',
+195060=>'L',
+195061=>'L',
+195062=>'L',
+195063=>'L',
+195064=>'L',
+195065=>'L',
+195066=>'L',
+195067=>'L',
+195068=>'L',
+195069=>'L',
+195070=>'L',
+195071=>'L',
+195072=>'L',
+195073=>'L',
+195074=>'L',
+195075=>'L',
+195076=>'L',
+195077=>'L',
+195078=>'L',
+195079=>'L',
+195080=>'L',
+195081=>'L',
+195082=>'L',
+195083=>'L',
+195084=>'L',
+195085=>'L',
+195086=>'L',
+195087=>'L',
+195088=>'L',
+195089=>'L',
+195090=>'L',
+195091=>'L',
+195092=>'L',
+195093=>'L',
+195094=>'L',
+195095=>'L',
+195096=>'L',
+195097=>'L',
+195098=>'L',
+195099=>'L',
+195100=>'L',
+195101=>'L',
+917505=>'BN',
+917536=>'BN',
+917537=>'BN',
+917538=>'BN',
+917539=>'BN',
+917540=>'BN',
+917541=>'BN',
+917542=>'BN',
+917543=>'BN',
+917544=>'BN',
+917545=>'BN',
+917546=>'BN',
+917547=>'BN',
+917548=>'BN',
+917549=>'BN',
+917550=>'BN',
+917551=>'BN',
+917552=>'BN',
+917553=>'BN',
+917554=>'BN',
+917555=>'BN',
+917556=>'BN',
+917557=>'BN',
+917558=>'BN',
+917559=>'BN',
+917560=>'BN',
+917561=>'BN',
+917562=>'BN',
+917563=>'BN',
+917564=>'BN',
+917565=>'BN',
+917566=>'BN',
+917567=>'BN',
+917568=>'BN',
+917569=>'BN',
+917570=>'BN',
+917571=>'BN',
+917572=>'BN',
+917573=>'BN',
+917574=>'BN',
+917575=>'BN',
+917576=>'BN',
+917577=>'BN',
+917578=>'BN',
+917579=>'BN',
+917580=>'BN',
+917581=>'BN',
+917582=>'BN',
+917583=>'BN',
+917584=>'BN',
+917585=>'BN',
+917586=>'BN',
+917587=>'BN',
+917588=>'BN',
+917589=>'BN',
+917590=>'BN',
+917591=>'BN',
+917592=>'BN',
+917593=>'BN',
+917594=>'BN',
+917595=>'BN',
+917596=>'BN',
+917597=>'BN',
+917598=>'BN',
+917599=>'BN',
+917600=>'BN',
+917601=>'BN',
+917602=>'BN',
+917603=>'BN',
+917604=>'BN',
+917605=>'BN',
+917606=>'BN',
+917607=>'BN',
+917608=>'BN',
+917609=>'BN',
+917610=>'BN',
+917611=>'BN',
+917612=>'BN',
+917613=>'BN',
+917614=>'BN',
+917615=>'BN',
+917616=>'BN',
+917617=>'BN',
+917618=>'BN',
+917619=>'BN',
+917620=>'BN',
+917621=>'BN',
+917622=>'BN',
+917623=>'BN',
+917624=>'BN',
+917625=>'BN',
+917626=>'BN',
+917627=>'BN',
+917628=>'BN',
+917629=>'BN',
+917630=>'BN',
+917631=>'BN',
+917760=>'NSM',
+917761=>'NSM',
+917762=>'NSM',
+917763=>'NSM',
+917764=>'NSM',
+917765=>'NSM',
+917766=>'NSM',
+917767=>'NSM',
+917768=>'NSM',
+917769=>'NSM',
+917770=>'NSM',
+917771=>'NSM',
+917772=>'NSM',
+917773=>'NSM',
+917774=>'NSM',
+917775=>'NSM',
+917776=>'NSM',
+917777=>'NSM',
+917778=>'NSM',
+917779=>'NSM',
+917780=>'NSM',
+917781=>'NSM',
+917782=>'NSM',
+917783=>'NSM',
+917784=>'NSM',
+917785=>'NSM',
+917786=>'NSM',
+917787=>'NSM',
+917788=>'NSM',
+917789=>'NSM',
+917790=>'NSM',
+917791=>'NSM',
+917792=>'NSM',
+917793=>'NSM',
+917794=>'NSM',
+917795=>'NSM',
+917796=>'NSM',
+917797=>'NSM',
+917798=>'NSM',
+917799=>'NSM',
+917800=>'NSM',
+917801=>'NSM',
+917802=>'NSM',
+917803=>'NSM',
+917804=>'NSM',
+917805=>'NSM',
+917806=>'NSM',
+917807=>'NSM',
+917808=>'NSM',
+917809=>'NSM',
+917810=>'NSM',
+917811=>'NSM',
+917812=>'NSM',
+917813=>'NSM',
+917814=>'NSM',
+917815=>'NSM',
+917816=>'NSM',
+917817=>'NSM',
+917818=>'NSM',
+917819=>'NSM',
+917820=>'NSM',
+917821=>'NSM',
+917822=>'NSM',
+917823=>'NSM',
+917824=>'NSM',
+917825=>'NSM',
+917826=>'NSM',
+917827=>'NSM',
+917828=>'NSM',
+917829=>'NSM',
+917830=>'NSM',
+917831=>'NSM',
+917832=>'NSM',
+917833=>'NSM',
+917834=>'NSM',
+917835=>'NSM',
+917836=>'NSM',
+917837=>'NSM',
+917838=>'NSM',
+917839=>'NSM',
+917840=>'NSM',
+917841=>'NSM',
+917842=>'NSM',
+917843=>'NSM',
+917844=>'NSM',
+917845=>'NSM',
+917846=>'NSM',
+917847=>'NSM',
+917848=>'NSM',
+917849=>'NSM',
+917850=>'NSM',
+917851=>'NSM',
+917852=>'NSM',
+917853=>'NSM',
+917854=>'NSM',
+917855=>'NSM',
+917856=>'NSM',
+917857=>'NSM',
+917858=>'NSM',
+917859=>'NSM',
+917860=>'NSM',
+917861=>'NSM',
+917862=>'NSM',
+917863=>'NSM',
+917864=>'NSM',
+917865=>'NSM',
+917866=>'NSM',
+917867=>'NSM',
+917868=>'NSM',
+917869=>'NSM',
+917870=>'NSM',
+917871=>'NSM',
+917872=>'NSM',
+917873=>'NSM',
+917874=>'NSM',
+917875=>'NSM',
+917876=>'NSM',
+917877=>'NSM',
+917878=>'NSM',
+917879=>'NSM',
+917880=>'NSM',
+917881=>'NSM',
+917882=>'NSM',
+917883=>'NSM',
+917884=>'NSM',
+917885=>'NSM',
+917886=>'NSM',
+917887=>'NSM',
+917888=>'NSM',
+917889=>'NSM',
+917890=>'NSM',
+917891=>'NSM',
+917892=>'NSM',
+917893=>'NSM',
+917894=>'NSM',
+917895=>'NSM',
+917896=>'NSM',
+917897=>'NSM',
+917898=>'NSM',
+917899=>'NSM',
+917900=>'NSM',
+917901=>'NSM',
+917902=>'NSM',
+917903=>'NSM',
+917904=>'NSM',
+917905=>'NSM',
+917906=>'NSM',
+917907=>'NSM',
+917908=>'NSM',
+917909=>'NSM',
+917910=>'NSM',
+917911=>'NSM',
+917912=>'NSM',
+917913=>'NSM',
+917914=>'NSM',
+917915=>'NSM',
+917916=>'NSM',
+917917=>'NSM',
+917918=>'NSM',
+917919=>'NSM',
+917920=>'NSM',
+917921=>'NSM',
+917922=>'NSM',
+917923=>'NSM',
+917924=>'NSM',
+917925=>'NSM',
+917926=>'NSM',
+917927=>'NSM',
+917928=>'NSM',
+917929=>'NSM',
+917930=>'NSM',
+917931=>'NSM',
+917932=>'NSM',
+917933=>'NSM',
+917934=>'NSM',
+917935=>'NSM',
+917936=>'NSM',
+917937=>'NSM',
+917938=>'NSM',
+917939=>'NSM',
+917940=>'NSM',
+917941=>'NSM',
+917942=>'NSM',
+917943=>'NSM',
+917944=>'NSM',
+917945=>'NSM',
+917946=>'NSM',
+917947=>'NSM',
+917948=>'NSM',
+917949=>'NSM',
+917950=>'NSM',
+917951=>'NSM',
+917952=>'NSM',
+917953=>'NSM',
+917954=>'NSM',
+917955=>'NSM',
+917956=>'NSM',
+917957=>'NSM',
+917958=>'NSM',
+917959=>'NSM',
+917960=>'NSM',
+917961=>'NSM',
+917962=>'NSM',
+917963=>'NSM',
+917964=>'NSM',
+917965=>'NSM',
+917966=>'NSM',
+917967=>'NSM',
+917968=>'NSM',
+917969=>'NSM',
+917970=>'NSM',
+917971=>'NSM',
+917972=>'NSM',
+917973=>'NSM',
+917974=>'NSM',
+917975=>'NSM',
+917976=>'NSM',
+917977=>'NSM',
+917978=>'NSM',
+917979=>'NSM',
+917980=>'NSM',
+917981=>'NSM',
+917982=>'NSM',
+917983=>'NSM',
+917984=>'NSM',
+917985=>'NSM',
+917986=>'NSM',
+917987=>'NSM',
+917988=>'NSM',
+917989=>'NSM',
+917990=>'NSM',
+917991=>'NSM',
+917992=>'NSM',
+917993=>'NSM',
+917994=>'NSM',
+917995=>'NSM',
+917996=>'NSM',
+917997=>'NSM',
+917998=>'NSM',
+917999=>'NSM',
+983040=>'L',
+1048573=>'L',
+1048576=>'L',
+1114109=>'L'
+);
+
+/**
+ * Mirror unicode characters. For information on bidi mirroring, see UAX #9: Bidirectional Algorithm, at http://www.unicode.org/unicode/reports/tr9/
+ * @public
+ */
+public $uni_mirror = array (
+0x0028=>0x0029,
+0x0029=>0x0028,
+0x003C=>0x003E,
+0x003E=>0x003C,
+0x005B=>0x005D,
+0x005D=>0x005B,
+0x007B=>0x007D,
+0x007D=>0x007B,
+0x00AB=>0x00BB,
+0x00BB=>0x00AB,
+0x0F3A=>0x0F3B,
+0x0F3B=>0x0F3A,
+0x0F3C=>0x0F3D,
+0x0F3D=>0x0F3C,
+0x169B=>0x169C,
+0x169C=>0x169B,
+0x2018=>0x2019,
+0x2019=>0x2018,
+0x201C=>0x201D,
+0x201D=>0x201C,
+0x2039=>0x203A,
+0x203A=>0x2039,
+0x2045=>0x2046,
+0x2046=>0x2045,
+0x207D=>0x207E,
+0x207E=>0x207D,
+0x208D=>0x208E,
+0x208E=>0x208D,
+0x2208=>0x220B,
+0x2209=>0x220C,
+0x220A=>0x220D,
+0x220B=>0x2208,
+0x220C=>0x2209,
+0x220D=>0x220A,
+0x2215=>0x29F5,
+0x223C=>0x223D,
+0x223D=>0x223C,
+0x2243=>0x22CD,
+0x2252=>0x2253,
+0x2253=>0x2252,
+0x2254=>0x2255,
+0x2255=>0x2254,
+0x2264=>0x2265,
+0x2265=>0x2264,
+0x2266=>0x2267,
+0x2267=>0x2266,
+0x2268=>0x2269,
+0x2269=>0x2268,
+0x226A=>0x226B,
+0x226B=>0x226A,
+0x226E=>0x226F,
+0x226F=>0x226E,
+0x2270=>0x2271,
+0x2271=>0x2270,
+0x2272=>0x2273,
+0x2273=>0x2272,
+0x2274=>0x2275,
+0x2275=>0x2274,
+0x2276=>0x2277,
+0x2277=>0x2276,
+0x2278=>0x2279,
+0x2279=>0x2278,
+0x227A=>0x227B,
+0x227B=>0x227A,
+0x227C=>0x227D,
+0x227D=>0x227C,
+0x227E=>0x227F,
+0x227F=>0x227E,
+0x2280=>0x2281,
+0x2281=>0x2280,
+0x2282=>0x2283,
+0x2283=>0x2282,
+0x2284=>0x2285,
+0x2285=>0x2284,
+0x2286=>0x2287,
+0x2287=>0x2286,
+0x2288=>0x2289,
+0x2289=>0x2288,
+0x228A=>0x228B,
+0x228B=>0x228A,
+0x228F=>0x2290,
+0x2290=>0x228F,
+0x2291=>0x2292,
+0x2292=>0x2291,
+0x2298=>0x29B8,
+0x22A2=>0x22A3,
+0x22A3=>0x22A2,
+0x22A6=>0x2ADE,
+0x22A8=>0x2AE4,
+0x22A9=>0x2AE3,
+0x22AB=>0x2AE5,
+0x22B0=>0x22B1,
+0x22B1=>0x22B0,
+0x22B2=>0x22B3,
+0x22B3=>0x22B2,
+0x22B4=>0x22B5,
+0x22B5=>0x22B4,
+0x22B6=>0x22B7,
+0x22B7=>0x22B6,
+0x22C9=>0x22CA,
+0x22CA=>0x22C9,
+0x22CB=>0x22CC,
+0x22CC=>0x22CB,
+0x22CD=>0x2243,
+0x22D0=>0x22D1,
+0x22D1=>0x22D0,
+0x22D6=>0x22D7,
+0x22D7=>0x22D6,
+0x22D8=>0x22D9,
+0x22D9=>0x22D8,
+0x22DA=>0x22DB,
+0x22DB=>0x22DA,
+0x22DC=>0x22DD,
+0x22DD=>0x22DC,
+0x22DE=>0x22DF,
+0x22DF=>0x22DE,
+0x22E0=>0x22E1,
+0x22E1=>0x22E0,
+0x22E2=>0x22E3,
+0x22E3=>0x22E2,
+0x22E4=>0x22E5,
+0x22E5=>0x22E4,
+0x22E6=>0x22E7,
+0x22E7=>0x22E6,
+0x22E8=>0x22E9,
+0x22E9=>0x22E8,
+0x22EA=>0x22EB,
+0x22EB=>0x22EA,
+0x22EC=>0x22ED,
+0x22ED=>0x22EC,
+0x22F0=>0x22F1,
+0x22F1=>0x22F0,
+0x22F2=>0x22FA,
+0x22F3=>0x22FB,
+0x22F4=>0x22FC,
+0x22F6=>0x22FD,
+0x22F7=>0x22FE,
+0x22FA=>0x22F2,
+0x22FB=>0x22F3,
+0x22FC=>0x22F4,
+0x22FD=>0x22F6,
+0x22FE=>0x22F7,
+0x2308=>0x2309,
+0x2309=>0x2308,
+0x230A=>0x230B,
+0x230B=>0x230A,
+0x2329=>0x232A,
+0x232A=>0x2329,
+0x2768=>0x2769,
+0x2769=>0x2768,
+0x276A=>0x276B,
+0x276B=>0x276A,
+0x276C=>0x276D,
+0x276D=>0x276C,
+0x276E=>0x276F,
+0x276F=>0x276E,
+0x2770=>0x2771,
+0x2771=>0x2770,
+0x2772=>0x2773,
+0x2773=>0x2772,
+0x2774=>0x2775,
+0x2775=>0x2774,
+0x27C3=>0x27C4,
+0x27C4=>0x27C3,
+0x27C5=>0x27C6,
+0x27C6=>0x27C5,
+0x27D5=>0x27D6,
+0x27D6=>0x27D5,
+0x27DD=>0x27DE,
+0x27DE=>0x27DD,
+0x27E2=>0x27E3,
+0x27E3=>0x27E2,
+0x27E4=>0x27E5,
+0x27E5=>0x27E4,
+0x27E6=>0x27E7,
+0x27E7=>0x27E6,
+0x27E8=>0x27E9,
+0x27E9=>0x27E8,
+0x27EA=>0x27EB,
+0x27EB=>0x27EA,
+0x2983=>0x2984,
+0x2984=>0x2983,
+0x2985=>0x2986,
+0x2986=>0x2985,
+0x2987=>0x2988,
+0x2988=>0x2987,
+0x2989=>0x298A,
+0x298A=>0x2989,
+0x298B=>0x298C,
+0x298C=>0x298B,
+0x298D=>0x2990,
+0x298E=>0x298F,
+0x298F=>0x298E,
+0x2990=>0x298D,
+0x2991=>0x2992,
+0x2992=>0x2991,
+0x2993=>0x2994,
+0x2994=>0x2993,
+0x2995=>0x2996,
+0x2996=>0x2995,
+0x2997=>0x2998,
+0x2998=>0x2997,
+0x29B8=>0x2298,
+0x29C0=>0x29C1,
+0x29C1=>0x29C0,
+0x29C4=>0x29C5,
+0x29C5=>0x29C4,
+0x29CF=>0x29D0,
+0x29D0=>0x29CF,
+0x29D1=>0x29D2,
+0x29D2=>0x29D1,
+0x29D4=>0x29D5,
+0x29D5=>0x29D4,
+0x29D8=>0x29D9,
+0x29D9=>0x29D8,
+0x29DA=>0x29DB,
+0x29DB=>0x29DA,
+0x29F5=>0x2215,
+0x29F8=>0x29F9,
+0x29F9=>0x29F8,
+0x29FC=>0x29FD,
+0x29FD=>0x29FC,
+0x2A2B=>0x2A2C,
+0x2A2C=>0x2A2B,
+0x2A2D=>0x2A2E,
+0x2A2E=>0x2A2D,
+0x2A34=>0x2A35,
+0x2A35=>0x2A34,
+0x2A3C=>0x2A3D,
+0x2A3D=>0x2A3C,
+0x2A64=>0x2A65,
+0x2A65=>0x2A64,
+0x2A79=>0x2A7A,
+0x2A7A=>0x2A79,
+0x2A7D=>0x2A7E,
+0x2A7E=>0x2A7D,
+0x2A7F=>0x2A80,
+0x2A80=>0x2A7F,
+0x2A81=>0x2A82,
+0x2A82=>0x2A81,
+0x2A83=>0x2A84,
+0x2A84=>0x2A83,
+0x2A8B=>0x2A8C,
+0x2A8C=>0x2A8B,
+0x2A91=>0x2A92,
+0x2A92=>0x2A91,
+0x2A93=>0x2A94,
+0x2A94=>0x2A93,
+0x2A95=>0x2A96,
+0x2A96=>0x2A95,
+0x2A97=>0x2A98,
+0x2A98=>0x2A97,
+0x2A99=>0x2A9A,
+0x2A9A=>0x2A99,
+0x2A9B=>0x2A9C,
+0x2A9C=>0x2A9B,
+0x2AA1=>0x2AA2,
+0x2AA2=>0x2AA1,
+0x2AA6=>0x2AA7,
+0x2AA7=>0x2AA6,
+0x2AA8=>0x2AA9,
+0x2AA9=>0x2AA8,
+0x2AAA=>0x2AAB,
+0x2AAB=>0x2AAA,
+0x2AAC=>0x2AAD,
+0x2AAD=>0x2AAC,
+0x2AAF=>0x2AB0,
+0x2AB0=>0x2AAF,
+0x2AB3=>0x2AB4,
+0x2AB4=>0x2AB3,
+0x2ABB=>0x2ABC,
+0x2ABC=>0x2ABB,
+0x2ABD=>0x2ABE,
+0x2ABE=>0x2ABD,
+0x2ABF=>0x2AC0,
+0x2AC0=>0x2ABF,
+0x2AC1=>0x2AC2,
+0x2AC2=>0x2AC1,
+0x2AC3=>0x2AC4,
+0x2AC4=>0x2AC3,
+0x2AC5=>0x2AC6,
+0x2AC6=>0x2AC5,
+0x2ACD=>0x2ACE,
+0x2ACE=>0x2ACD,
+0x2ACF=>0x2AD0,
+0x2AD0=>0x2ACF,
+0x2AD1=>0x2AD2,
+0x2AD2=>0x2AD1,
+0x2AD3=>0x2AD4,
+0x2AD4=>0x2AD3,
+0x2AD5=>0x2AD6,
+0x2AD6=>0x2AD5,
+0x2ADE=>0x22A6,
+0x2AE3=>0x22A9,
+0x2AE4=>0x22A8,
+0x2AE5=>0x22AB,
+0x2AEC=>0x2AED,
+0x2AED=>0x2AEC,
+0x2AF7=>0x2AF8,
+0x2AF8=>0x2AF7,
+0x2AF9=>0x2AFA,
+0x2AFA=>0x2AF9,
+0x2E02=>0x2E03,
+0x2E03=>0x2E02,
+0x2E04=>0x2E05,
+0x2E05=>0x2E04,
+0x2E09=>0x2E0A,
+0x2E0A=>0x2E09,
+0x2E0C=>0x2E0D,
+0x2E0D=>0x2E0C,
+0x2E1C=>0x2E1D,
+0x2E1D=>0x2E1C,
+0x3008=>0x3009,
+0x3009=>0x3008,
+0x300A=>0x300B,
+0x300B=>0x300A,
+0x300C=>0x300D,
+0x300D=>0x300C,
+0x300E=>0x300F,
+0x300F=>0x300E,
+0x3010=>0x3011,
+0x3011=>0x3010,
+0x3014=>0x3015,
+0x3015=>0x3014,
+0x3016=>0x3017,
+0x3017=>0x3016,
+0x3018=>0x3019,
+0x3019=>0x3018,
+0x301A=>0x301B,
+0x301B=>0x301A,
+0x301D=>0x301E,
+0x301E=>0x301D,
+0xFE59=>0xFE5A,
+0xFE5A=>0xFE59,
+0xFE5B=>0xFE5C,
+0xFE5C=>0xFE5B,
+0xFE5D=>0xFE5E,
+0xFE5E=>0xFE5D,
+0xFE64=>0xFE65,
+0xFE65=>0xFE64,
+0xFF08=>0xFF09,
+0xFF09=>0xFF08,
+0xFF1C=>0xFF1E,
+0xFF1E=>0xFF1C,
+0xFF3B=>0xFF3D,
+0xFF3D=>0xFF3B,
+0xFF5B=>0xFF5D,
+0xFF5D=>0xFF5B,
+0xFF5F=>0xFF60,
+0xFF60=>0xFF5F,
+0xFF62=>0xFF63,
+0xFF63=>0xFF62);
+
+/**
+ * Arabic shape substitutions: char code => (isolated, final, initial, medial).
+ * @public
+ */
+public $uni_arabicsubst = array(
+1569=>array(65152),
+1570=>array(65153, 65154, 65153, 65154),
+1571=>array(65155, 65156, 65155, 65156),
+1572=>array(65157, 65158),
+1573=>array(65159, 65160, 65159, 65160),
+1574=>array(65161, 65162, 65163, 65164),
+1575=>array(65165, 65166, 65165, 65166),
+1576=>array(65167, 65168, 65169, 65170),
+1577=>array(65171, 65172),
+1578=>array(65173, 65174, 65175, 65176),
+1579=>array(65177, 65178, 65179, 65180),
+1580=>array(65181, 65182, 65183, 65184),
+1581=>array(65185, 65186, 65187, 65188),
+1582=>array(65189, 65190, 65191, 65192),
+1583=>array(65193, 65194, 65193, 65194),
+1584=>array(65195, 65196, 65195, 65196),
+1585=>array(65197, 65198, 65197, 65198),
+1586=>array(65199, 65200, 65199, 65200),
+1587=>array(65201, 65202, 65203, 65204),
+1588=>array(65205, 65206, 65207, 65208),
+1589=>array(65209, 65210, 65211, 65212),
+1590=>array(65213, 65214, 65215, 65216),
+1591=>array(65217, 65218, 65219, 65220),
+1592=>array(65221, 65222, 65223, 65224),
+1593=>array(65225, 65226, 65227, 65228),
+1594=>array(65229, 65230, 65231, 65232),
+1601=>array(65233, 65234, 65235, 65236),
+1602=>array(65237, 65238, 65239, 65240),
+1603=>array(65241, 65242, 65243, 65244),
+1604=>array(65245, 65246, 65247, 65248),
+1605=>array(65249, 65250, 65251, 65252),
+1606=>array(65253, 65254, 65255, 65256),
+1607=>array(65257, 65258, 65259, 65260),
+1608=>array(65261, 65262, 65261, 65262),
+1609=>array(65263, 65264, 64488, 64489),
+1610=>array(65265, 65266, 65267, 65268),
+1649=>array(64336, 64337),
+1655=>array(64477),
+1657=>array(64358, 64359, 64360, 64361),
+1658=>array(64350, 64351, 64352, 64353),
+1659=>array(64338, 64339, 64340, 64341),
+1662=>array(64342, 64343, 64344, 64345),
+1663=>array(64354, 64355, 64356, 64357),
+1664=>array(64346, 64347, 64348, 64349),
+1667=>array(64374, 64375, 64376, 64377),
+1668=>array(64370, 64371, 64372, 64373),
+1670=>array(64378, 64379, 64380, 64381),
+1671=>array(64382, 64383, 64384, 64385),
+1672=>array(64392, 64393),
+1676=>array(64388, 64389),
+1677=>array(64386, 64387),
+1678=>array(64390, 64391),
+1681=>array(64396, 64397),
+1688=>array(64394, 64395, 64394, 64395),
+1700=>array(64362, 64363, 64364, 64365),
+1702=>array(64366, 64367, 64368, 64369),
+1705=>array(64398, 64399, 64400, 64401),
+1709=>array(64467, 64468, 64469, 64470),
+1711=>array(64402, 64403, 64404, 64405),
+1713=>array(64410, 64411, 64412, 64413),
+1715=>array(64406, 64407, 64408, 64409),
+1722=>array(64414, 64415),
+1723=>array(64416, 64417, 64418, 64419),
+1726=>array(64426, 64427, 64428, 64429),
+1728=>array(64420, 64421),
+1729=>array(64422, 64423, 64424, 64425),
+1733=>array(64480, 64481),
+1734=>array(64473, 64474),
+1735=>array(64471, 64472),
+1736=>array(64475, 64476),
+1737=>array(64482, 64483),
+1739=>array(64478, 64479),
+1740=>array(64508, 64509, 64510, 64511),
+1744=>array(64484, 64485, 64486, 64487),
+1746=>array(64430, 64431),
+1747=>array(64432, 64433)
+);
+
+/**
+ * Arabic laa letter: (char code => isolated, final, initial, medial).
+ * @public
+ */
+public $uni_laa_array = array (
+1570 =>array(65269, 65270, 65269, 65270),
+1571 =>array(65271, 65272, 65271, 65272),
+1573 =>array(65273, 65274, 65273, 65274),
+1575 =>array(65275, 65276, 65275, 65276)
+);
+
+/**
+ * Array of character substitutions for sequences of two diacritics symbols.
+ * Putting the combining mark and character in the same glyph allows us to avoid the two marks overlapping each other in an illegible manner.
+ * second NSM char code => substitution char
+ * @public
+ */
+public $uni_diacritics = array (
+1612=>64606, # Shadda + Dammatan
+1613=>64607, # Shadda + Kasratan
+1614=>64608, # Shadda + Fatha
+1615=>64609, # Shadda + Damma
+1616=>64610  # Shadda + Kasra
+);
+
+/**
+ * Array of character substitutions from UTF-8 Unicode to Latin1.
+ * @public
+ */
+public $uni_utf8tolatin = array (
+8364=>128, # Euro1
+338=>140,  # OE
+352=>138,  # Scaron
+376=>159,  # Ydieresis
+381=>142,  # Zcaron2
+8226=>149, # bullet3
+710=>136,  # circumflex
+8224=>134, # dagger
+8225=>135, # daggerdbl
+8230=>133, # ellipsis
+8212=>151, # emdash
+8211=>150, # endash
+402=>131,  # florin
+8249=>139, # guilsinglleft
+8250=>155, # guilsinglright
+339=>156,  # oe
+8240=>137, # perthousand
+8222=>132, # quotedblbase
+8220=>147, # quotedblleft
+8221=>148, # quotedblright
+8216=>145, # quoteleft
+8217=>146, # quoteright
+8218=>130, # quotesinglbase
+353=>154,  # scaron
+732=>152,  # tilde
+8482=>153, # trademark
+382=>158   # zcaron2
+);
+
+} // --- END OF CLASS ---
+
+//============================================================+
+// END OF FILE
+//============================================================+
diff --git a/phpmyadmin/libraries/transformations.lib.php b/phpmyadmin/libraries/transformations.lib.php
new file mode 100644
index 0000000..c653a9a
--- /dev/null
+++ b/phpmyadmin/libraries/transformations.lib.php
@@ -0,0 +1,412 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * Set of functions used with the relation and pdf feature
+ *
+ * This file also provides basic functions to use in other plungins!
+ * These are declared in the 'GLOBAL Plugin functions' section
+ *
+ * Please use short and expressive names.
+ * For now, special characters which aren't allowed in
+ * filenames or functions should not be used.
+ *
+ * Please provide a comment for your function,
+ * what it does and what parameters are available.
+ *
+ * @package PhpMyAdmin
+ */
+if (! defined('PHPMYADMIN')) {
+    exit;
+}
+
+/**
+ * Returns array of options from string with options separated by comma,
+ * removes quotes
+ *
+ * <code>
+ * PMA_transformation_getOptions("'option ,, quoted',abd,'2,3',");
+ * // array {
+ * //     'option ,, quoted',
+ * //     'abc',
+ * //     '2,3',
+ * //     '',
+ * // }
+ * </code>
+ *
+ * @param string $option_string comma separated options
+ *
+ * @return array options
+ */
+function PMA_transformation_getOptions($option_string)
+{
+    $result = array();
+
+    if (! strlen($option_string)
+        || ! $transform_options = preg_split('/,/', $option_string)
+    ) {
+        return $result;
+    }
+
+    while (($option = array_shift($transform_options)) !== null) {
+        $trimmed = trim($option);
+        if (strlen($trimmed) > 1
+            && $trimmed[0] == "'"
+            && $trimmed[strlen($trimmed) - 1] == "'"
+        ) {
+            // '...'
+            $option = substr($trimmed, 1, -1);
+        } elseif (isset($trimmed[0]) && $trimmed[0] == "'") {
+            // '...,
+            $trimmed = ltrim($option);
+            while (($option = array_shift($transform_options)) !== null) {
+                // ...,
+                $trimmed .= ',' . $option;
+                $rtrimmed = rtrim($trimmed);
+                if ($rtrimmed[strlen($rtrimmed) - 1] == "'") {
+                    // ,...'
+                    break;
+                }
+            }
+            $option = substr($rtrimmed, 1, -1);
+        }
+        $result[] = stripslashes($option);
+    }
+
+    return $result;
+}
+
+/**
+ * Gets all available MIME-types
+ *
+ * @access  public
+ * @staticvar   array   mimetypes
+ * @return array    array[mimetype], array[transformation]
+ */
+function PMA_getAvailableMIMEtypes()
+{
+    static $stack = null;
+
+    if (null !== $stack) {
+        return $stack;
+    }
+
+    $stack = array();
+    $filestack = array();
+
+    $handle = opendir('./libraries/plugins/transformations');
+
+    if (! $handle) {
+        return $stack;
+    }
+
+    while ($file = readdir($handle)) {
+        $filestack[] = $file;
+    }
+
+    closedir($handle);
+    sort($filestack);
+
+    foreach ($filestack as $file) {
+        if (preg_match('|^.*_.*_.*\.class\.php$|', $file)) {
+            // File contains transformation functions.
+            $parts = explode('_', str_replace('.class.php', '', $file));
+            $mimetype = $parts[0] . "/" . $parts[1];
+            $stack['mimetype'][$mimetype] = $mimetype;
+            $stack['transformation'][] = $mimetype . ': ' . $parts[2];
+            $stack['transformation_file'][] = $file;
+
+        } elseif (preg_match('|^.*\.class.php$|', $file)) {
+            // File is a plain mimetype, no functions.
+            $base = str_replace('.class.php', '', $file);
+
+            if ($base != 'global') {
+                $mimetype = str_replace('_', '/', $base);
+                $stack['mimetype'][$mimetype] = $mimetype;
+                $stack['empty_mimetype'][$mimetype] = $mimetype;
+            }
+        }
+    }
+
+    return $stack;
+}
+
+/**
+ * Returns the description of the transformation
+ *
+ * @param string $file           transformation file
+ * @param string $html_formatted whether the description should be formatted
+ *                               as HTML
+ *
+ * @return the description of the transformation
+ */
+function PMA_getTransformationDescription($file, $html_formatted = true)
+{
+    // get the transformation class name
+    $class_name = explode(".class.php", $file);
+    $class_name = $class_name[0];
+
+    // include and instantiate the class
+    include_once 'libraries/plugins/transformations/' . $file;
+    /* Temporary workaround for bug #3783 :
+       Calling a method from a variable class is not possible before PHP 5.3. */
+    $functionGetInfo = $class_name . "_getInfo";
+    return $functionGetInfo();
+}
+
+/**
+ * Gets the mimetypes for all columns of a table
+ *
+ * @param string $db     the name of the db to check for
+ * @param string $table  the name of the table to check for
+ * @param string $strict whether to include only results having a mimetype set
+ *
+ * @access  public
+ *
+ * @return array [field_name][field_key] = field_value
+ */
+function PMA_getMIME($db, $table, $strict = false)
+{
+    $cfgRelation = PMA_getRelationsParam();
+
+    if (! $cfgRelation['commwork']) {
+        return false;
+    }
+
+    $com_qry  = '
+         SELECT `column_name`,
+                `mimetype`,
+                `transformation`,
+                `transformation_options`
+         FROM ' . PMA_Util::backquote($cfgRelation['db']) . '.'
+        . PMA_Util::backquote($cfgRelation['column_info']) . '
+         WHERE `db_name`    = \'' . PMA_Util::sqlAddSlashes($db) . '\'
+           AND `table_name` = \'' . PMA_Util::sqlAddSlashes($table) . '\'
+           AND ( `mimetype` != \'\'' . (!$strict ? '
+              OR `transformation` != \'\'
+              OR `transformation_options` != \'\'' : '') . ')';
+    $result = PMA_DBI_fetch_result(
+        $com_qry, 'column_name', null, $GLOBALS['controllink']
+    );
+
+    foreach ($result as $column => $values) {
+        // replacements in mimetype and transformation
+        $values = str_replace("jpeg", "JPEG", $values);
+        $values = str_replace("png", "PNG", $values);
+        $values = str_replace("octet-stream", "Octetstream", $values);
+
+        // convert mimetype to new format (f.e. Text_Plain, etc)
+        $delimiter_space = '- ';
+        $delimiter = "_";
+        $values['mimetype'] = str_replace(
+            $delimiter_space,
+            $delimiter,
+            ucwords(
+                str_replace(
+                    $delimiter,
+                    $delimiter_space,
+                    $values['mimetype']
+                )
+            )
+        );
+
+        // convert transformation to new format (class name)
+        // f.e. Text_Plain_Substring.class.php
+        $values = str_replace("__", "_", $values);
+        $values = str_replace(".inc.php", ".class.php", $values);
+
+        $values['transformation'] = str_replace(
+            $delimiter_space,
+            $delimiter,
+            ucwords(
+                str_replace(
+                    $delimiter,
+                    $delimiter_space,
+                    $values['transformation']
+                )
+            )
+        );
+
+        $result[$column] = $values;
+    }
+
+    return $result;
+} // end of the 'PMA_getMIME()' function
+
+/**
+ * Set a single mimetype to a certain value.
+ *
+ * @param string $db                     the name of the db
+ * @param string $table                  the name of the table
+ * @param string $key                    the name of the column
+ * @param string $mimetype               the mimetype of the column
+ * @param string $transformation         the transformation of the column
+ * @param string $transformation_options the transformation options of the column
+ * @param string $forcedelete            force delete, will erase any existing
+ *                                       comments for this column
+ *
+ * @access  public
+ *
+ * @return boolean  true, if comment-query was made.
+ */
+function PMA_setMIME($db, $table, $key, $mimetype, $transformation,
+    $transformation_options, $forcedelete = false
+) {
+    $cfgRelation = PMA_getRelationsParam();
+
+    if (! $cfgRelation['commwork']) {
+        return false;
+    }
+
+    // convert mimetype to old format (f.e. text_plain)
+    $mimetype = strtolower($mimetype);
+    // old format has octet-stream instead of octetstream for mimetype
+    if (strstr($mimetype, "octetstream")) {
+        $mimetype = "application_octet-stream";
+    }
+
+    // convert transformation to old format (f.e. text_plain__substring.inc.php)
+    $transformation = strtolower($transformation);
+    $transformation = str_replace(".class.php", ".inc.php", $transformation);
+    $last_pos = strrpos($transformation, "_");
+    $transformation = substr($transformation, 0, $last_pos) . "_"
+        . substr($transformation, $last_pos);
+
+    $test_qry = '
+         SELECT `mimetype`,
+                `comment`
+           FROM ' . PMA_Util::backquote($cfgRelation['db']) . '.'
+        . PMA_Util::backquote($cfgRelation['column_info']) . '
+          WHERE `db_name`     = \'' . PMA_Util::sqlAddSlashes($db) . '\'
+            AND `table_name`  = \'' . PMA_Util::sqlAddSlashes($table) . '\'
+            AND `column_name` = \'' . PMA_Util::sqlAddSlashes($key) . '\'';
+    
+    $test_rs   = PMA_queryAsControlUser($test_qry, true, PMA_DBI_QUERY_STORE);
+
+    if ($test_rs && PMA_DBI_num_rows($test_rs) > 0) {
+        $row = @PMA_DBI_fetch_assoc($test_rs);
+        PMA_DBI_free_result($test_rs);
+
+        if (! $forcedelete
+            && (strlen($mimetype) || strlen($transformation)
+            || strlen($transformation_options) || strlen($row['comment']))
+        ) {
+            $upd_query = '
+                UPDATE ' . PMA_Util::backquote($cfgRelation['db']) . '.'
+                . PMA_Util::backquote($cfgRelation['column_info']) . '
+                   SET `mimetype`               = \'' . PMA_Util::sqlAddSlashes($mimetype) . '\',
+                       `transformation`         = \'' . PMA_Util::sqlAddSlashes($transformation) . '\',
+                       `transformation_options` = \'' . PMA_Util::sqlAddSlashes($transformation_options) . '\'';
+        } else {
+            $upd_query = 'DELETE FROM ' . PMA_Util::backquote($cfgRelation['db']) . '.' . PMA_Util::backquote($cfgRelation['column_info']);
+        }
+        $upd_query .= '
+            WHERE `db_name`     = \'' . PMA_Util::sqlAddSlashes($db) . '\'
+              AND `table_name`  = \'' . PMA_Util::sqlAddSlashes($table) . '\'
+              AND `column_name` = \'' . PMA_Util::sqlAddSlashes($key) . '\'';
+    } elseif (strlen($mimetype) || strlen($transformation)
+     || strlen($transformation_options)) {
+
+        $upd_query = 'INSERT INTO ' . PMA_Util::backquote($cfgRelation['db']) . '.' . PMA_Util::backquote($cfgRelation['column_info'])
+                   . ' (db_name, table_name, column_name, mimetype, transformation, transformation_options) '
+                   . ' VALUES('
+                   . '\'' . PMA_Util::sqlAddSlashes($db) . '\','
+                   . '\'' . PMA_Util::sqlAddSlashes($table) . '\','
+                   . '\'' . PMA_Util::sqlAddSlashes($key) . '\','
+                   . '\'' . PMA_Util::sqlAddSlashes($mimetype) . '\','
+                   . '\'' . PMA_Util::sqlAddSlashes($transformation) . '\','
+                   . '\'' . PMA_Util::sqlAddSlashes($transformation_options) . '\')';
+    }
+
+    if (isset($upd_query)) {
+        return PMA_queryAsControlUser($upd_query);
+    } else {
+        return false;
+    }
+} // end of 'PMA_setMIME()' function
+
+
+/**
+ * GLOBAL Plugin functions
+ */
+
+
+/**
+ * Replaces "[__BUFFER__]" occurences found in $options['string'] with the text
+ * in $buffer, after performing a regular expression search and replace on
+ * $buffer using $options['regex'] and $options['regex_replace'].
+ *
+ * @param string $buffer  text that will be replaced in $options['string'],
+ *                        after being formatted
+ * @param array  $options the options required to format $buffer
+ *     = array (
+ *         'string'        => 'string', // text containing "[__BUFFER__]"
+ *         'regex'         => 'mixed',  // the pattern to search for
+ *         'regex_replace' => 'mixed',  // string or array of strings to replace
+ *                                      // with
+ *     );
+ *
+ * @return string containing the text with all the replacements
+ */
+function PMA_transformation_global_html_replace($buffer, $options = array())
+{
+    if ( ! isset($options['string']) ) {
+        $options['string'] = '';
+    }
+
+    if (isset($options['regex']) && isset($options['regex_replace'])) {
+        $buffer = preg_replace(
+            '@' . str_replace('@', '\@', $options['regex']) . '@si',
+            $options['regex_replace'],
+            $buffer
+        );
+    }
+
+    // Replace occurences of [__BUFFER__] with actual text
+    $return = str_replace("[__BUFFER__]", $buffer, $options['string']);
+    return $return;
+}
+
+
+/**
+ * Delete related transformation details
+ * after deleting database. table or column
+ *
+ * @param string $db     Database name
+ * @param string $table  Table name
+ * @param string $column Column name
+ *
+ * @return boolean State of the query execution
+ */
+function PMA_clearTransformations($db, $table = '', $column = '')
+{
+    $cfgRelation = PMA_getRelationsParam();
+
+    if (! isset($cfgRelation['column_info'])) {
+        return false;
+    }
+
+    $delete_sql = 'DELETE FROM '
+        . PMA_Util::backquote($cfgRelation['db']) . '.'
+        . PMA_Util::backquote($cfgRelation['column_info'])
+        . ' WHERE ';
+    
+    if (($column != '') && ($table != '')) {
+        
+        $delete_sql .= '`db_name` = \'' . $db . '\' AND '
+            . '`table_name` = \'' . $table . '\' AND '
+            . '`column_name` = \'' . $column . '\' ';
+        
+    } else if ($table != '') {
+        
+        $delete_sql .= '`db_name` = \'' . $db . '\' AND '
+            . '`table_name` = \'' . $table . '\' ';
+        
+    } else {
+        $delete_sql .= '`db_name` = \'' . $db . '\' ';
+    }
+    
+    return PMA_DBI_try_query($delete_sql);
+    
+}
+
+?>
diff --git a/phpmyadmin/libraries/url_generating.lib.php b/phpmyadmin/libraries/url_generating.lib.php
new file mode 100644
index 0000000..e995710
--- /dev/null
+++ b/phpmyadmin/libraries/url_generating.lib.php
@@ -0,0 +1,302 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * URL/hidden inputs generating.
+ *
+ * @package PhpMyAdmin
+ */
+if (! defined('PHPMYADMIN')) {
+    exit;
+}
+
+/**
+ * Generates text with hidden inputs.
+ *
+ * @param string $db     optional database name
+ *                       (can also be an array of parameters)
+ * @param string $table  optional table name
+ * @param int    $indent indenting level
+ * @param string $skip   do not generate a hidden field for this parameter
+ *                       (can be an array of strings)
+ *
+ * @see PMA_generate_common_url()
+ *
+ * @return string   string with input fields
+ *
+ * @global  string   the current language
+ * @global  string   the current conversion charset
+ * @global  string   the current connection collation
+ * @global  string   the current server
+ * @global  array    the configuration array
+ * @global  boolean  whether recoding is allowed or not
+ *
+ * @access  public
+ */
+function PMA_generate_common_hidden_inputs($db = '', $table = '',
+    $indent = 0, $skip = array()
+) {
+    if (is_array($db)) {
+        $params  =& $db;
+        $_indent = empty($table) ? $indent : $table;
+        $_skip   = empty($indent) ? $skip : $indent;
+        $indent  =& $_indent;
+        $skip    =& $_skip;
+    } else {
+        $params = array();
+        if (strlen($db)) {
+            $params['db'] = $db;
+        }
+        if (strlen($table)) {
+            $params['table'] = $table;
+        }
+    }
+
+    if (! empty($GLOBALS['server'])
+        && $GLOBALS['server'] != $GLOBALS['cfg']['ServerDefault']
+    ) {
+        $params['server'] = $GLOBALS['server'];
+    }
+    if (empty($_COOKIE['pma_lang']) && ! empty($GLOBALS['lang'])) {
+        $params['lang'] = $GLOBALS['lang'];
+    }
+    if (empty($_COOKIE['pma_collation_connection'])
+        && ! empty($GLOBALS['collation_connection'])
+    ) {
+        $params['collation_connection'] = $GLOBALS['collation_connection'];
+    }
+
+    $params['token'] = $_SESSION[' PMA_token '];
+
+    if (! is_array($skip)) {
+        if (isset($params[$skip])) {
+            unset($params[$skip]);
+        }
+    } else {
+        foreach ($skip as $skipping) {
+            if (isset($params[$skipping])) {
+                unset($params[$skipping]);
+            }
+        }
+    }
+
+    return PMA_getHiddenFields($params);
+}
+
+/**
+ * create hidden form fields from array with name => value
+ *
+ * <code>
+ * $values = array(
+ *     'aaa' => aaa,
+ *     'bbb' => array(
+ *          'bbb_0',
+ *          'bbb_1',
+ *     ),
+ *     'ccc' => array(
+ *          'a' => 'ccc_a',
+ *          'b' => 'ccc_b',
+ *     ),
+ * );
+ * echo PMA_getHiddenFields($values);
+ *
+ * // produces:
+ * <input type="hidden" name="aaa" Value="aaa" />
+ * <input type="hidden" name="bbb[0]" Value="bbb_0" />
+ * <input type="hidden" name="bbb[1]" Value="bbb_1" />
+ * <input type="hidden" name="ccc[a]" Value="ccc_a" />
+ * <input type="hidden" name="ccc[b]" Value="ccc_b" />
+ * </code>
+ *
+ * @param array  $values hidden values
+ * @param string $pre    prefix
+ *
+ * @return string form fields of type hidden
+ */
+function PMA_getHiddenFields($values, $pre = '')
+{
+    $fields = '';
+
+    foreach ($values as $name => $value) {
+        if (! empty($pre)) {
+            $name = $pre. '[' . $name . ']';
+        }
+
+        if (is_array($value)) {
+            $fields .= PMA_getHiddenFields($value, $name);
+        } else {
+            // do not generate an ending "\n" because
+            // PMA_generate_common_hidden_inputs() is sometimes called
+            // from a JS document.write()
+            $fields .= '<input type="hidden" name="' . htmlspecialchars($name)
+                . '" value="' . htmlspecialchars($value) . '" />';
+        }
+    }
+
+    return $fields;
+}
+
+/**
+ * Generates text with URL parameters.
+ *
+ * <code>
+ * // OLD (deprecated) style
+ * // note the ?
+ * echo 'script.php?' . PMA_generate_common_url('mysql', 'rights');
+ * // produces with cookies enabled:
+ * // script.php?db=mysql&table=rights
+ * // with cookies disabled:
+ * // script.php?server=1&lang=en&db=mysql&table=rights
+ *
+ * // NEW style
+ * $params['myparam'] = 'myvalue';
+ * $params['db']      = 'mysql';
+ * $params['table']   = 'rights';
+ * // note the missing ?
+ * echo 'script.php' . PMA_generate_common_url($params);
+ * // produces with cookies enabled:
+ * // script.php?myparam=myvalue&db=mysql&table=rights
+ * // with cookies disabled:
+ * // script.php?server=1&lang=en&myparam=myvalue&db=mysql&table=rights
+ *
+ * // note the missing ?
+ * echo 'script.php' . PMA_generate_common_url();
+ * // produces with cookies enabled:
+ * // script.php
+ * // with cookies disabled:
+ * // script.php?server=1&lang=en
+ * </code>
+ *
+ * @param mixed  assoc. array with url params or optional string with database name
+ *               if first param is an array there is also an ? prefixed to the url
+ *
+ * @param string - if first param is array: 'html' to use htmlspecialchars()
+ *               on the resulting URL (for a normal URL displayed in HTML)
+ *               or something else to avoid using htmlspecialchars() (for
+ *               a URL sent via a header); if not set,'html' is assumed
+ *               - if first param is not array:  optional table name
+ *
+ * @param string - if first param is array: optional character to
+ *               use instead of '?'
+ *               - if first param is not array: optional character to use
+ *               instead of '&' for dividing URL parameters
+ *
+ * @return string   string with URL parameters
+ * @access  public
+ */
+function PMA_generate_common_url()
+{
+    $args = func_get_args();
+
+    if (isset($args[0]) && is_array($args[0])) {
+        // new style
+        $params = $args[0];
+
+        if (isset($args[1])) {
+            $encode = $args[1];
+        } else {
+            $encode = 'html';
+        }
+
+        if (isset($args[2])) {
+            $questionmark = $args[2];
+        } else {
+            $questionmark = '?';
+        }
+    } else {
+        // old style
+
+        if (PMA_isValid($args[0])) {
+            $params['db'] = $args[0];
+        }
+
+        if (PMA_isValid($args[1])) {
+            $params['table'] = $args[1];
+        }
+
+        if (isset($args[2]) && $args[2] !== '&') {
+            $encode = 'text';
+        } else {
+            $encode = 'html';
+        }
+
+        $questionmark = '';
+    }
+
+    $separator = PMA_get_arg_separator();
+
+    // avoid overwriting when creating navi panel links to servers
+    if (isset($GLOBALS['server'])
+        && $GLOBALS['server'] != $GLOBALS['cfg']['ServerDefault']
+        && ! isset($params['server'])
+    ) {
+        $params['server'] = $GLOBALS['server'];
+    }
+
+    if (empty($_COOKIE['pma_lang']) && ! empty($GLOBALS['lang'])) {
+        $params['lang'] = $GLOBALS['lang'];
+    }
+    if (empty($_COOKIE['pma_collation_connection'])
+        && ! empty($GLOBALS['collation_connection'])
+    ) {
+        $params['collation_connection'] = $GLOBALS['collation_connection'];
+    }
+
+    if (isset($_SESSION[' PMA_token '])) {
+        $params['token'] = $_SESSION[' PMA_token '];
+    }
+
+    if (empty($params)) {
+        return '';
+    }
+
+    $query = $questionmark . http_build_query($params, null, $separator);
+
+    if ($encode === 'html') {
+        $query = htmlspecialchars($query);
+    }
+
+    return $query;
+}
+
+/**
+ * Returns url separator
+ *
+ * extracted from arg_separator.input as set in php.ini
+ * we do not use arg_separator.output to avoid problems with & and &
+ *
+ * @param string $encode whether to encode separator or not,
+ * currently 'none' or 'html'
+ *
+ * @return string  character used for separating url parts usally ; or &
+ * @access  public
+ */
+function PMA_get_arg_separator($encode = 'none')
+{
+    static $separator = null;
+
+    if (null === $separator) {
+        // use separators defined by php, but prefer ';'
+        // as recommended by W3C
+        // (see http://www.w3.org/TR/1999/REC-html401-19991224/appendix/notes.html#h-B.2.2)
+        $php_arg_separator_input = ini_get('arg_separator.input');
+        if (strpos($php_arg_separator_input, ';') !== false) {
+            $separator = ';';
+        } elseif (strlen($php_arg_separator_input) > 0) {
+            $separator = $php_arg_separator_input{0};
+        } else {
+            $separator = '&';
+        }
+    }
+
+    switch ($encode) {
+    case 'html':
+        return htmlentities($separator);
+        break;
+    case 'text' :
+    case 'none' :
+    default :
+        return $separator;
+    }
+}
+
+?>
diff --git a/phpmyadmin/libraries/user_preferences.inc.php b/phpmyadmin/libraries/user_preferences.inc.php
new file mode 100644
index 0000000..b0ed4cc
--- /dev/null
+++ b/phpmyadmin/libraries/user_preferences.inc.php
@@ -0,0 +1,71 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * Common header for user preferences pages
+ *
+ * @package PhpMyAdmin
+ */
+if (!defined('PHPMYADMIN')) {
+    exit;
+}
+// build user preferences menu
+
+$form_param = filter_input(INPUT_GET, 'form');
+if (! isset($forms[$form_param])) {
+    $forms_keys = array_keys($forms);
+    $form_param = array_shift($forms_keys);
+}
+$tabs_icons = array(
+    'Features'    => 'b_tblops.png',
+    'Sql_queries' => 'b_sql.png',
+    'Navi_panel'  => 'b_select.png',
+    'Main_panel'  => 'b_props.png',
+    'Import'      => 'b_import.png',
+    'Export'      => 'b_export.png');
+echo '<ul id="topmenu2">';
+echo PMA_Util::getHtmlTab(
+    array(
+        'link' => 'prefs_manage.php',
+        'text' => __('Manage your settings')
+    )
+) . "\n";
+echo '<li>   </li>' . "\n";
+$script_name = basename($GLOBALS['PMA_PHP_SELF']);
+foreach (array_keys($forms) as $formset) {
+    $tab = array(
+        'link' => 'prefs_forms.php',
+        'text' => PMA_lang('Form_' . $formset),
+        'icon' => $tabs_icons[$formset],
+        'active' => ($script_name == 'prefs_forms.php' && $formset == $form_param));
+    echo PMA_Util::getHtmlTab($tab, array('form' => $formset)) . "\n";
+}
+echo '</ul><div class="clearfloat"></div>';
+
+// show "configuration saved" message and reload navigation panel if needed
+if (!empty($_GET['saved'])) {
+    PMA_Message::rawSuccess(__('Configuration has been saved'))->display();
+}
+
+/* debug code
+$arr = ConfigFile::getInstance()->getConfigArray();
+$arr2 = array();
+foreach ($arr as $k => $v) {
+    $arr2[] = "<b>$k</b> " . var_export($v, true);
+}
+$arr2 = implode(', ', $arr2);
+$arr2 .= '<br />Blacklist: ' . (empty($cfg['UserprefsDisallow'])
+        ? '<i>empty</i>'
+        : implode(', ', $cfg['UserprefsDisallow']));
+$msg = PMA_Message::notice('Settings: ' . $arr2);
+$msg->display();
+//*/
+
+// warn about using session storage for settings
+$cfgRelation = PMA_getRelationsParam();
+if (! $cfgRelation['userconfigwork']) {
+    $msg = __('Your preferences will be saved for current session only. Storing them permanently requires %sphpMyAdmin configuration storage%s.');
+    $msg = PMA_sanitize(
+        sprintf($msg, '[doc at linked-tables]', '[/doc]')
+    );
+    PMA_Message::notice($msg)->display();
+}
diff --git a/phpmyadmin/libraries/user_preferences.lib.php b/phpmyadmin/libraries/user_preferences.lib.php
new file mode 100644
index 0000000..94699ad
--- /dev/null
+++ b/phpmyadmin/libraries/user_preferences.lib.php
@@ -0,0 +1,288 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * Functions for displaying user preferences pages
+ *
+ * @package PhpMyAdmin
+ */
+if (! defined('PHPMYADMIN')) {
+    exit;
+}
+
+/**
+ * Common initialization for user preferences modification pages
+ *
+ * @return void
+ */
+function PMA_userprefsPageInit()
+{
+    $forms_all_keys = PMA_readUserprefsFieldNames($GLOBALS['forms']);
+    $cf = ConfigFile::getInstance();
+    $cf->resetConfigData(); // start with a clean instance
+    $cf->setAllowedKeys($forms_all_keys);
+    $cf->setCfgUpdateReadMapping(
+        array(
+            'Server/hide_db' => 'Servers/1/hide_db',
+            'Server/only_db' => 'Servers/1/only_db'
+        )
+    );
+    $cf->updateWithGlobalConfig($GLOBALS['cfg']);
+}
+
+/**
+ * Loads user preferences
+ *
+ * Returns an array:
+ * * config_data - path => value pairs
+ * * mtime - last modification time
+ * * type - 'db' (config read from pmadb) or 'session' (read from user session)
+ *
+ * @return array
+ */
+function PMA_loadUserprefs()
+{
+    $cfgRelation = PMA_getRelationsParam();
+    if (! $cfgRelation['userconfigwork']) {
+        // no pmadb table, use session storage
+        if (! isset($_SESSION['userconfig'])) {
+            $_SESSION['userconfig'] = array(
+                'db' => array(),
+                'ts' => time());
+        }
+        return array(
+            'config_data' => $_SESSION['userconfig']['db'],
+            'mtime' => $_SESSION['userconfig']['ts'],
+            'type' => 'session');
+    }
+    // load configuration from pmadb
+    $query_table = PMA_Util::backquote($cfgRelation['db']) . '.'
+        . PMA_Util::backquote($cfgRelation['userconfig']);
+    $query = '
+        SELECT `config_data`, UNIX_TIMESTAMP(`timevalue`) ts
+        FROM ' . $query_table . '
+          WHERE `username` = \'' . PMA_Util::sqlAddSlashes($cfgRelation['user']) . '\'';
+    $row = PMA_DBI_fetch_single_row($query, 'ASSOC', $GLOBALS['controllink']);
+
+    return array(
+        'config_data' => $row ? (array)json_decode($row['config_data']) : array(),
+        'mtime' => $row ? $row['ts'] : time(),
+        'type' => 'db');
+}
+
+/**
+ * Saves user preferences
+ *
+ * @param array $config_array configuration array
+ *
+ * @return true|PMA_Message
+ */
+function PMA_saveUserprefs(array $config_array)
+{
+    $cfgRelation = PMA_getRelationsParam();
+    $server = isset($GLOBALS['server'])
+        ? $GLOBALS['server']
+        : $GLOBALS['cfg']['ServerDefault'];
+    $cache_key = 'server_' . $server;
+    if (! $cfgRelation['userconfigwork']) {
+        // no pmadb table, use session storage
+        $_SESSION['userconfig'] = array(
+            'db' => $config_array,
+            'ts' => time());
+        if (isset($_SESSION['cache'][$cache_key]['userprefs'])) {
+            unset($_SESSION['cache'][$cache_key]['userprefs']);
+        }
+        return true;
+    }
+
+    // save configuration to pmadb
+    $query_table = PMA_Util::backquote($cfgRelation['db']) . '.'
+        . PMA_Util::backquote($cfgRelation['userconfig']);
+    $query = '
+        SELECT `username`
+        FROM ' . $query_table . '
+          WHERE `username` = \'' . PMA_Util::sqlAddSlashes($cfgRelation['user']) . '\'';
+
+    $has_config = PMA_DBI_fetch_value($query, 0, 0, $GLOBALS['controllink']);
+    $config_data = json_encode($config_array);
+    if ($has_config) {
+        $query = '
+            UPDATE ' . $query_table . '
+            SET `config_data` = \'' . PMA_Util::sqlAddSlashes($config_data) . '\'
+            WHERE `username` = \'' . PMA_Util::sqlAddSlashes($cfgRelation['user']) . '\'';
+    } else {
+        $query = '
+            INSERT INTO ' . $query_table . ' (`username`, `config_data`)
+            VALUES (\'' . PMA_Util::sqlAddSlashes($cfgRelation['user']) . '\',
+                \'' . PMA_Util::sqlAddSlashes($config_data) . '\')';
+    }
+    if (isset($_SESSION['cache'][$cache_key]['userprefs'])) {
+        unset($_SESSION['cache'][$cache_key]['userprefs']);
+    }
+    if (!PMA_DBI_try_query($query, $GLOBALS['controllink'])) {
+        $message = PMA_Message::error(__('Could not save configuration'));
+        $message->addMessage('<br /><br />');
+        $message->addMessage(
+            PMA_Message::rawError(PMA_DBI_getError($GLOBALS['controllink']))
+        );
+        return $message;
+    }
+    return true;
+}
+
+/**
+ * Returns a user preferences array filtered by $cfg['UserprefsDisallow']
+ * (blacklist) and keys from user preferences form (whitelist)
+ *
+ * @param array $config_data path => value pairs
+ *
+ * @return array
+ */
+function PMA_applyUserprefs(array $config_data)
+{
+    $cfg = array();
+    $blacklist = array_flip($GLOBALS['cfg']['UserprefsDisallow']);
+    if (!$GLOBALS['cfg']['UserprefsDeveloperTab']) {
+        // disallow everything in the Developers tab
+        $blacklist['Error_Handler/display'] = true;
+        $blacklist['Error_Handler/gather'] = true;
+        $blacklist['DBG/sql'] = true;
+    }
+    $whitelist = array_flip(PMA_readUserprefsFieldNames());
+    // whitelist some additional fields which are custom handled
+    $whitelist['ThemeDefault'] = true;
+    $whitelist['fontsize'] = true;
+    $whitelist['lang'] = true;
+    $whitelist['collation_connection'] = true;
+    $whitelist['Server/hide_db'] = true;
+    $whitelist['Server/only_db'] = true;
+    foreach ($config_data as $path => $value) {
+        if (! isset($whitelist[$path]) || isset($blacklist[$path])) {
+            continue;
+        }
+        PMA_arrayWrite($path, $cfg, $value);
+    }
+    return $cfg;
+}
+
+/**
+ * Reads user preferences field names
+ *
+ * @param array|null $forms
+ *
+ * @return array
+ */
+function PMA_readUserprefsFieldNames(array $forms = null)
+{
+    static $names;
+
+    // return cached results
+    if ($names !== null) {
+        return $names;
+    }
+    if (is_null($forms)) {
+        $forms = array();
+        include 'libraries/config/user_preferences.forms.php';
+    }
+    $names = array();
+    foreach ($forms as $formset) {
+        foreach ($formset as $form) {
+            foreach ($form as $k => $v) {
+                $names[] = is_int($k) ? $v : $k;
+            }
+        }
+    }
+    return $names;
+}
+
+/**
+ * Updates one user preferences option (loads and saves to database).
+ *
+ * No validation is done!
+ *
+ * @param string $path          configuration
+ * @param mixed  $value         value
+ * @param mixed  $default_value default value
+ *
+ * @return void
+ */
+function PMA_persistOption($path, $value, $default_value)
+{
+    $prefs = PMA_loadUserprefs();
+    if ($value === $default_value) {
+        if (isset($prefs['config_data'][$path])) {
+            unset($prefs['config_data'][$path]);
+        } else {
+            return;
+        }
+    } else {
+        $prefs['config_data'][$path] = $value;
+    }
+    PMA_saveUserprefs($prefs['config_data']);
+}
+
+/**
+ * Redirects after saving new user preferences
+ *
+ * @param string $file_name
+ * @param array  $params
+ * @param string $hash
+ *
+ * @return void
+ */
+function PMA_userprefsRedirect($file_name,
+    $params = null, $hash = null
+) {
+    // redirect
+    $url_params = array('saved' => 1);
+    if (is_array($params)) {
+        $url_params = array_merge($params, $url_params);
+    }
+    if ($hash) {
+        $hash = '#' . urlencode($hash);
+    }
+    PMA_sendHeaderLocation(
+        $GLOBALS['cfg']['PmaAbsoluteUri'] . $file_name
+        . PMA_generate_common_url($url_params, '&') . $hash
+    );
+}
+
+/**
+ * Shows form which allows to quickly load
+ * settings stored in browser's local storage
+ *
+ * @return string
+ */
+function PMA_userprefsAutoloadGetHeader()
+{
+    $retval = '';
+
+    if (isset($_REQUEST['prefs_autoload'])
+        && $_REQUEST['prefs_autoload'] == 'hide'
+    ) {
+        $_SESSION['userprefs_autoload'] = true;
+    } else {
+        $script_name = basename(basename($GLOBALS['PMA_PHP_SELF']));
+        $return_url = htmlspecialchars(
+            $script_name . '?' . http_build_query($_GET, '', '&')
+        );
+
+        $retval .= '<div id="prefs_autoload" class="notice" style="display:none">';
+        $retval .= '<form action="prefs_manage.php" method="post">';
+        $retval .= PMA_generate_common_hidden_inputs();
+        $retval .= '<input type="hidden" name="json" value="" />';
+        $retval .= '<input type="hidden" name="submit_import" value="1" />';
+        $retval .= '<input type="hidden" name="return_url" value="' . $return_url . '" />';
+        $retval .=  __(
+            'Your browser has phpMyAdmin configuration for this domain. '
+            . 'Would you like to import it for current session?'
+        );
+        $retval .= '<br />';
+        $retval .= '<a href="#yes">' . __('Yes') . '</a>';
+        $retval .= ' / ';
+        $retval .= '<a href="#no">' . __('No') . '</a>';
+        $retval .= '</form>';
+        $retval .= '</div>';
+    }
+    return $retval;
+}
+?>
diff --git a/phpmyadmin/libraries/vendor_config.php b/phpmyadmin/libraries/vendor_config.php
new file mode 100644
index 0000000..92356f3
--- /dev/null
+++ b/phpmyadmin/libraries/vendor_config.php
@@ -0,0 +1,76 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * File for vendor customisation, you can change here paths or some behaviour,
+ * which vendors such as Linux distibutions might want to change.
+ *
+ * For changing this file you should know what you are doing. For this reason
+ * options here are not part of normal configuration.
+ *
+ * @package PhpMyAdmin
+ */
+if (! defined('PHPMYADMIN')) {
+    exit;
+}
+
+/**
+ * Path to changelog file, can be gzip compressed. Useful when you want to
+ * have documentation somewhere else, eg. /usr/share/doc.
+ */
+define('CHANGELOG_FILE', './ChangeLog');
+
+/**
+ * Path to license file. Useful when you want to have documentation somewhere
+ * else, eg. /usr/share/doc.
+ */
+define('LICENSE_FILE', './LICENSE');
+
+/**
+ * Path to config file generated using setup script.
+ */
+define('SETUP_CONFIG_FILE', './config/config.inc.php');
+
+/**
+ * Whether setup requires writable directory where config
+ * file will be generated.
+ */
+define('SETUP_DIR_WRITABLE', true);
+
+/**
+ * Directory where configuration files are stored.
+ * It is not used directly in code, just a convenient
+ * define used further in this file.
+ */
+define('CONFIG_DIR', './');
+
+/**
+ * Filename of a configuration file.
+ */
+define('CONFIG_FILE', CONFIG_DIR . 'config.inc.php');
+
+/**
+ * Filename of custom header file.
+ */
+define('CUSTOM_HEADER_FILE', CONFIG_DIR . 'config.header.inc.php');
+
+/**
+ * Filename of custom footer file.
+ */
+define('CUSTOM_FOOTER_FILE', CONFIG_DIR . 'config.footer.inc.php');
+
+/**
+ * Default value for check for version upgrades.
+ */
+define('VERSION_CHECK_DEFAULT', true);
+
+/**
+ * Path to gettext.inc file. Useful when you want php-gettext somewhere else,
+ * eg. /usr/share/php/gettext/gettext.inc.
+ */
+define('GETTEXT_INC', './libraries/php-gettext/gettext.inc');
+/**
+ * Path to tcpdf.php file. Useful when you want to use system tcpdf,
+ * eg. /usr/share/php/tcpdf/tcpdf.php.
+ */
+define('TCPDF_INC', './libraries/tcpdf/tcpdf.php');
+?>
diff --git a/phpmyadmin/libraries/zip.lib.php b/phpmyadmin/libraries/zip.lib.php
new file mode 100644
index 0000000..6ecea2f
--- /dev/null
+++ b/phpmyadmin/libraries/zip.lib.php
@@ -0,0 +1,216 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * Zip file creation
+ *
+ * @package PhpMyAdmin
+ */
+if (! defined('PHPMYADMIN')) {
+    exit;
+}
+
+/**
+ * Zip file creation class.
+ * Makes zip files.
+ *
+ * @access  public
+ * @package PhpMyAdmin
+ * @see     Official ZIP file format: http://www.pkware.com/support/zip-app-note
+ */
+class ZipFile
+{
+    /**
+     * Whether to echo zip as it's built or return as string from -> file
+     *
+     * @var  boolean  $doWrite
+     */
+    var $doWrite      = false;
+
+    /**
+     * Array to store compressed data
+     *
+     * @var  array    $datasec
+     */
+    var $datasec      = array();
+
+    /**
+     * Central directory
+     *
+     * @var  array    $ctrl_dir
+     */
+    var $ctrl_dir     = array();
+
+    /**
+     * End of central directory record
+     *
+     * @var  string   $eof_ctrl_dir
+     */
+    var $eof_ctrl_dir = "\x50\x4b\x05\x06\x00\x00\x00\x00";
+
+    /**
+     * Last offset position
+     *
+     * @var  integer  $old_offset
+     */
+    var $old_offset   = 0;
+
+
+    /**
+     * Sets member variable this -> doWrite to true
+     * - Should be called immediately after class instantiantion
+     * - If set to true, then ZIP archive are echo'ed to STDOUT as each
+     *   file is added via this -> addfile(), and central directories are
+     *   echoed to STDOUT on final call to this -> file().  Also,
+     *   this -> file() returns an empty string so it is safe to issue a
+     *   "echo $zipfile;" command
+     *
+     * @access public
+     *
+     * @return void
+     */
+    function setDoWrite()
+    {
+        $this -> doWrite = true;
+    } // end of the 'setDoWrite()' method
+
+    /**
+     * Converts an Unix timestamp to a four byte DOS date and time format (date
+     * in high two bytes, time in low two bytes allowing magnitude comparison).
+     *
+     * @param integer $unixtime the current Unix timestamp
+     *
+     * @return integer the current date in a four byte DOS format
+     *
+     * @access private
+     */
+    function unix2DosTime($unixtime = 0)
+    {
+        $timearray = ($unixtime == 0) ? getdate() : getdate($unixtime);
+
+        if ($timearray['year'] < 1980) {
+            $timearray['year']    = 1980;
+            $timearray['mon']     = 1;
+            $timearray['mday']    = 1;
+            $timearray['hours']   = 0;
+            $timearray['minutes'] = 0;
+            $timearray['seconds'] = 0;
+        } // end if
+
+        return (($timearray['year'] - 1980) << 25)
+            | ($timearray['mon'] << 21)
+            | ($timearray['mday'] << 16)
+            | ($timearray['hours'] << 11)
+            | ($timearray['minutes'] << 5)
+            | ($timearray['seconds'] >> 1);
+    } // end of the 'unix2DosTime()' method
+
+
+    /**
+     * Adds "file" to archive
+     *
+     * @param string  $data file contents
+     * @param string  $name name of the file in the archive (may contains the path)
+     * @param integer $time the current timestamp
+     *
+     * @access public
+     *
+     * @return void
+     */
+    function addFile($data, $name, $time = 0)
+    {
+        $name     = str_replace('\\', '/', $name);
+
+        $dtime    = substr("00000000" . dechex($this->unix2DosTime($time)), -8);
+        $hexdtime = '\x' . $dtime[6] . $dtime[7]
+                  . '\x' . $dtime[4] . $dtime[5]
+                  . '\x' . $dtime[2] . $dtime[3]
+                  . '\x' . $dtime[0] . $dtime[1];
+        eval('$hexdtime = "' . $hexdtime . '";');
+
+        $fr   = "\x50\x4b\x03\x04";
+        $fr   .= "\x14\x00";            // ver needed to extract
+        $fr   .= "\x00\x00";            // gen purpose bit flag
+        $fr   .= "\x08\x00";            // compression method
+        $fr   .= $hexdtime;             // last mod time and date
+
+        // "local file header" segment
+        $unc_len = strlen($data);
+        $crc     = crc32($data);
+        $zdata   = gzcompress($data);
+        $zdata   = substr(substr($zdata, 0, strlen($zdata) - 4), 2); // fix crc bug
+        $c_len   = strlen($zdata);
+        $fr      .= pack('V', $crc);             // crc32
+        $fr      .= pack('V', $c_len);           // compressed filesize
+        $fr      .= pack('V', $unc_len);         // uncompressed filesize
+        $fr      .= pack('v', strlen($name));    // length of filename
+        $fr      .= pack('v', 0);                // extra field length
+        $fr      .= $name;
+
+        // "file data" segment
+        $fr .= $zdata;
+
+        // echo this entry on the fly, ...
+        if ( $this -> doWrite) {
+            echo $fr;
+        } else {                     // ... OR add this entry to array
+            $this -> datasec[] = $fr;
+        }
+
+        // now add to central directory record
+        $cdrec = "\x50\x4b\x01\x02";
+        $cdrec .= "\x00\x00";                // version made by
+        $cdrec .= "\x14\x00";                // version needed to extract
+        $cdrec .= "\x00\x00";                // gen purpose bit flag
+        $cdrec .= "\x08\x00";                // compression method
+        $cdrec .= $hexdtime;                 // last mod time & date
+        $cdrec .= pack('V', $crc);           // crc32
+        $cdrec .= pack('V', $c_len);         // compressed filesize
+        $cdrec .= pack('V', $unc_len);       // uncompressed filesize
+        $cdrec .= pack('v', strlen($name)); // length of filename
+        $cdrec .= pack('v', 0);             // extra field length
+        $cdrec .= pack('v', 0);             // file comment length
+        $cdrec .= pack('v', 0);             // disk number start
+        $cdrec .= pack('v', 0);             // internal file attributes
+        $cdrec .= pack('V', 32);            // external file attributes
+                                            // - 'archive' bit set
+
+        $cdrec .= pack('V', $this -> old_offset); // relative offset of local header
+        $this -> old_offset += strlen($fr);
+
+        $cdrec .= $name;
+
+        // optional extra field, file comment goes here
+        // save to central directory
+        $this -> ctrl_dir[] = $cdrec;
+    } // end of the 'addFile()' method
+
+
+    /**
+     * Echo central dir if ->doWrite==true, else build string to return
+     *
+     * @return string  if ->doWrite {empty string} else the ZIP file contents
+     *
+     * @access public
+     */
+    function file()
+    {
+        $ctrldir = implode('', $this -> ctrl_dir);
+        $header = $ctrldir .
+            $this -> eof_ctrl_dir .
+            pack('v', sizeof($this -> ctrl_dir)) . //total #of entries "on this disk"
+            pack('v', sizeof($this -> ctrl_dir)) . //total #of entries overall
+            pack('V', strlen($ctrldir)) .          //size of central dir
+            pack('V', $this -> old_offset) .       //offset to start of central dir
+            "\x00\x00";                            //.zip file comment length
+
+        if ( $this -> doWrite ) { // Send central directory & end ctrl dir to STDOUT
+            echo $header;
+            return "";            // Return empty string
+        } else {                  // Return entire ZIP archive as string
+            $data = implode('', $this -> datasec);
+            return $data . $header;
+        }
+    } // end of the 'file()' method
+
+} // end of the 'ZipFile' class
+?>
diff --git a/phpmyadmin/libraries/zip_extension.lib.php b/phpmyadmin/libraries/zip_extension.lib.php
new file mode 100644
index 0000000..db493e7
--- /dev/null
+++ b/phpmyadmin/libraries/zip_extension.lib.php
@@ -0,0 +1,188 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * Interface for the zip extension
+ *
+ * @package PhpMyAdmin
+ */
+if (! defined('PHPMYADMIN')) {
+    exit;
+}
+
+/**
+ * Gets zip file contents
+ *
+ * @param string $file           zip file
+ * @param string $specific_entry regular expression to match a file
+ *
+ * @return array ($error_message, $file_data); $error_message
+ *                  is empty if no error
+ */
+function PMA_getZipContents($file, $specific_entry = null)
+{
+    $error_message = '';
+    $file_data = '';
+    $zip_handle = zip_open($file);
+    if (is_resource($zip_handle)) {
+        $first_zip_entry = zip_read($zip_handle);
+        if (false === $first_zip_entry) {
+            $error_message = __('No files found inside ZIP archive!');
+        } else {
+            /* Is the the zip really an ODS file? */
+            $read = zip_entry_read($first_zip_entry);
+            $ods_mime = 'application/vnd.oasis.opendocument.spreadsheet';
+            if (!strcmp($ods_mime, $read)) {
+                $specific_entry = '/^content\.xml$/';
+            }
+
+            if (isset($specific_entry)) {
+                /* Return the correct contents, not just the first entry */
+                for ( ; ; ) {
+                    $entry = zip_read($zip_handle);
+                    if (is_resource($entry)) {
+                        if (preg_match($specific_entry, zip_entry_name($entry))) {
+                            zip_entry_open($zip_handle, $entry, 'r');
+                            $file_data = zip_entry_read(
+                                $entry,
+                                zip_entry_filesize($entry)
+                            );
+                            zip_entry_close($entry);
+                            break;
+                        }
+                    } else {
+                        /**
+                         * Either we have reached the end of the zip and still
+                         * haven't found $specific_entry or there was a parsing
+                         * error that we must display
+                         */
+                        if ($entry === false) {
+                            $error_message = __('Error in ZIP archive:')
+                                . ' Could not find "' . $specific_entry . '"';
+                        } else {
+                            $error_message = __('Error in ZIP archive:')
+                                . ' ' . PMA_getZipError($zip_handle);
+                        }
+
+                        break;
+                    }
+                }
+            } else {
+                zip_entry_open($zip_handle, $first_zip_entry, 'r');
+                /* File pointer has already been moved,
+                 * so include what was read above */
+                $file_data = $read;
+                $file_data .= zip_entry_read(
+                    $first_zip_entry,
+                    zip_entry_filesize($first_zip_entry)
+                );
+                zip_entry_close($first_zip_entry);
+            }
+        }
+    } else {
+        $error_message = __('Error in ZIP archive:')
+            . ' ' . PMA_getZipError($zip_handle);
+    }
+    zip_close($zip_handle);
+    return (array('error' => $error_message, 'data' => $file_data));
+}
+
+/**
+ * Returns the file name of the first file that matches the given $file_regexp.
+ *
+ * @param string $file_regexp regular expression for the file name to match
+ * @param string $file        zip archive
+ *
+ * @return string the file name of the first file that matches the given regexp
+ */
+function PMA_findFileFromZipArchive ($file_regexp, $file)
+{
+    $zip_handle = zip_open($file);
+    if (is_resource($zip_handle)) {
+        $entry = zip_read($zip_handle);
+        while (is_resource($entry)) {
+            if (preg_match($file_regexp, zip_entry_name($entry))) {
+                $file_name = zip_entry_name($entry);
+                zip_close($zip_handle);
+                return $file_name;
+            }
+            $entry = zip_read($zip_handle);
+        }
+    }
+    zip_close($zip_handle);
+    return false;
+}
+
+/**
+ * Returns the number of files in the zip archive.
+ *
+ * @param string $file zip archive
+ *
+ * @return int the number of files in the zip archive
+ */
+function PMA_getNoOfFilesInZip($file)
+{
+    $count = 0;
+    $zip_handle = zip_open($file);
+    if (is_resource($zip_handle)) {
+        $entry = zip_read($zip_handle);
+        while (is_resource($entry)) {
+            $count++;
+            $entry = zip_read($zip_handle);
+        }
+    }
+    zip_close($zip_handle);
+    return $count;
+}
+
+/**
+ * Extracts a set of files from the given zip archive to a given destinations.
+ *
+ * @param string $zip_path    path to the zip archive
+ * @param string $destination destination to extract files
+ * @param array  $entries     files in archive that should be extracted
+ *
+ * @return bool true on sucess, false otherwise
+ */
+function PMA_zipExtract($zip_path, $destination, $entries)
+{
+    $zip = new ZipArchive;
+    if ($zip->open($zip_path) === true) {
+        $zip->extractTo($destination, $entries);
+        $zip->close();
+        return true;
+    }
+    return false;
+}
+
+/**
+  * Gets zip error message
+  *
+  * @param integer $code error code
+  *
+  * @return string error message
+ */
+function PMA_getZipError($code)
+{
+    // I don't think this needs translation
+    switch ($code) {
+    case ZIPARCHIVE::ER_MULTIDISK:
+        $message = 'Multi-disk zip archives not supported';
+        break;
+    case ZIPARCHIVE::ER_READ:
+        $message = 'Read error';
+        break;
+    case ZIPARCHIVE::ER_CRC:
+        $message = 'CRC error';
+        break;
+    case ZIPARCHIVE::ER_NOZIP:
+        $message = 'Not a zip archive';
+        break;
+    case ZIPARCHIVE::ER_INCONS:
+        $message = 'Zip archive inconsistent';
+        break;
+    default:
+        $message = $code;
+    }
+    return $message;
+}
+?>
diff --git a/phpmyadmin/license.php b/phpmyadmin/license.php
new file mode 100644
index 0000000..d076cae
--- /dev/null
+++ b/phpmyadmin/license.php
@@ -0,0 +1,31 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * Simple script to set correct charset for the license
+ *
+ * Note: please do not fold this script into a general script
+ * that would read any file using a GET parameter, it would open a hole
+ *
+ * @package PhpMyAdmin
+ */
+
+/**
+ * Gets core libraries and defines some variables
+ */
+require 'libraries/common.inc.php';
+
+/**
+ *
+ */
+header('Content-type: text/plain; charset=utf-8');
+
+$filename = LICENSE_FILE;
+
+// Check if the file is available, some distributions remove these.
+if (is_readable($filename)) {
+    readfile($filename);
+} else {
+    printf(__('The %s file is not available on this system, please visit www.phpmyadmin.net for more information.'), $filename);
+}
+
+?>
diff --git a/phpmyadmin/locale/ar/LC_MESSAGES/phpmyadmin.mo b/phpmyadmin/locale/ar/LC_MESSAGES/phpmyadmin.mo
new file mode 100644
index 0000000..385a367
Binary files /dev/null and b/phpmyadmin/locale/ar/LC_MESSAGES/phpmyadmin.mo differ
diff --git a/phpmyadmin/locale/bg/LC_MESSAGES/phpmyadmin.mo b/phpmyadmin/locale/bg/LC_MESSAGES/phpmyadmin.mo
new file mode 100644
index 0000000..3ec56be
Binary files /dev/null and b/phpmyadmin/locale/bg/LC_MESSAGES/phpmyadmin.mo differ
diff --git a/phpmyadmin/locale/ca/LC_MESSAGES/phpmyadmin.mo b/phpmyadmin/locale/ca/LC_MESSAGES/phpmyadmin.mo
new file mode 100644
index 0000000..0e723ab
Binary files /dev/null and b/phpmyadmin/locale/ca/LC_MESSAGES/phpmyadmin.mo differ
diff --git a/phpmyadmin/locale/cs/LC_MESSAGES/phpmyadmin.mo b/phpmyadmin/locale/cs/LC_MESSAGES/phpmyadmin.mo
new file mode 100644
index 0000000..2812fc5
Binary files /dev/null and b/phpmyadmin/locale/cs/LC_MESSAGES/phpmyadmin.mo differ
diff --git a/phpmyadmin/locale/da/LC_MESSAGES/phpmyadmin.mo b/phpmyadmin/locale/da/LC_MESSAGES/phpmyadmin.mo
new file mode 100644
index 0000000..061a7ee
Binary files /dev/null and b/phpmyadmin/locale/da/LC_MESSAGES/phpmyadmin.mo differ
diff --git a/phpmyadmin/locale/de/LC_MESSAGES/phpmyadmin.mo b/phpmyadmin/locale/de/LC_MESSAGES/phpmyadmin.mo
new file mode 100644
index 0000000..2acd00a
Binary files /dev/null and b/phpmyadmin/locale/de/LC_MESSAGES/phpmyadmin.mo differ
diff --git a/phpmyadmin/locale/el/LC_MESSAGES/phpmyadmin.mo b/phpmyadmin/locale/el/LC_MESSAGES/phpmyadmin.mo
new file mode 100644
index 0000000..d1ea48d
Binary files /dev/null and b/phpmyadmin/locale/el/LC_MESSAGES/phpmyadmin.mo differ
diff --git a/phpmyadmin/locale/en_GB/LC_MESSAGES/phpmyadmin.mo b/phpmyadmin/locale/en_GB/LC_MESSAGES/phpmyadmin.mo
new file mode 100644
index 0000000..65fc604
Binary files /dev/null and b/phpmyadmin/locale/en_GB/LC_MESSAGES/phpmyadmin.mo differ
diff --git a/phpmyadmin/locale/es/LC_MESSAGES/phpmyadmin.mo b/phpmyadmin/locale/es/LC_MESSAGES/phpmyadmin.mo
new file mode 100644
index 0000000..41fc51f
Binary files /dev/null and b/phpmyadmin/locale/es/LC_MESSAGES/phpmyadmin.mo differ
diff --git a/phpmyadmin/locale/et/LC_MESSAGES/phpmyadmin.mo b/phpmyadmin/locale/et/LC_MESSAGES/phpmyadmin.mo
new file mode 100644
index 0000000..0fa08a0
Binary files /dev/null and b/phpmyadmin/locale/et/LC_MESSAGES/phpmyadmin.mo differ
diff --git a/phpmyadmin/locale/fi/LC_MESSAGES/phpmyadmin.mo b/phpmyadmin/locale/fi/LC_MESSAGES/phpmyadmin.mo
new file mode 100644
index 0000000..b468bb4
Binary files /dev/null and b/phpmyadmin/locale/fi/LC_MESSAGES/phpmyadmin.mo differ
diff --git a/phpmyadmin/locale/fr/LC_MESSAGES/phpmyadmin.mo b/phpmyadmin/locale/fr/LC_MESSAGES/phpmyadmin.mo
new file mode 100644
index 0000000..8270e37
Binary files /dev/null and b/phpmyadmin/locale/fr/LC_MESSAGES/phpmyadmin.mo differ
diff --git a/phpmyadmin/locale/gl/LC_MESSAGES/phpmyadmin.mo b/phpmyadmin/locale/gl/LC_MESSAGES/phpmyadmin.mo
new file mode 100644
index 0000000..36794b3
Binary files /dev/null and b/phpmyadmin/locale/gl/LC_MESSAGES/phpmyadmin.mo differ
diff --git a/phpmyadmin/locale/hi/LC_MESSAGES/phpmyadmin.mo b/phpmyadmin/locale/hi/LC_MESSAGES/phpmyadmin.mo
new file mode 100644
index 0000000..30b2389
Binary files /dev/null and b/phpmyadmin/locale/hi/LC_MESSAGES/phpmyadmin.mo differ
diff --git a/phpmyadmin/locale/hr/LC_MESSAGES/phpmyadmin.mo b/phpmyadmin/locale/hr/LC_MESSAGES/phpmyadmin.mo
new file mode 100644
index 0000000..46224c6
Binary files /dev/null and b/phpmyadmin/locale/hr/LC_MESSAGES/phpmyadmin.mo differ
diff --git a/phpmyadmin/locale/hu/LC_MESSAGES/phpmyadmin.mo b/phpmyadmin/locale/hu/LC_MESSAGES/phpmyadmin.mo
new file mode 100644
index 0000000..b617707
Binary files /dev/null and b/phpmyadmin/locale/hu/LC_MESSAGES/phpmyadmin.mo differ
diff --git a/phpmyadmin/locale/id/LC_MESSAGES/phpmyadmin.mo b/phpmyadmin/locale/id/LC_MESSAGES/phpmyadmin.mo
new file mode 100644
index 0000000..5618938
Binary files /dev/null and b/phpmyadmin/locale/id/LC_MESSAGES/phpmyadmin.mo differ
diff --git a/phpmyadmin/locale/it/LC_MESSAGES/phpmyadmin.mo b/phpmyadmin/locale/it/LC_MESSAGES/phpmyadmin.mo
new file mode 100644
index 0000000..45ab636
Binary files /dev/null and b/phpmyadmin/locale/it/LC_MESSAGES/phpmyadmin.mo differ
diff --git a/phpmyadmin/locale/ja/LC_MESSAGES/phpmyadmin.mo b/phpmyadmin/locale/ja/LC_MESSAGES/phpmyadmin.mo
new file mode 100644
index 0000000..ba9f73e
Binary files /dev/null and b/phpmyadmin/locale/ja/LC_MESSAGES/phpmyadmin.mo differ
diff --git a/phpmyadmin/locale/ko/LC_MESSAGES/phpmyadmin.mo b/phpmyadmin/locale/ko/LC_MESSAGES/phpmyadmin.mo
new file mode 100644
index 0000000..e4749e0
Binary files /dev/null and b/phpmyadmin/locale/ko/LC_MESSAGES/phpmyadmin.mo differ
diff --git a/phpmyadmin/locale/lt/LC_MESSAGES/phpmyadmin.mo b/phpmyadmin/locale/lt/LC_MESSAGES/phpmyadmin.mo
new file mode 100644
index 0000000..bceb2f4
Binary files /dev/null and b/phpmyadmin/locale/lt/LC_MESSAGES/phpmyadmin.mo differ
diff --git a/phpmyadmin/locale/nb/LC_MESSAGES/phpmyadmin.mo b/phpmyadmin/locale/nb/LC_MESSAGES/phpmyadmin.mo
new file mode 100644
index 0000000..b44699e
Binary files /dev/null and b/phpmyadmin/locale/nb/LC_MESSAGES/phpmyadmin.mo differ
diff --git a/phpmyadmin/locale/nl/LC_MESSAGES/phpmyadmin.mo b/phpmyadmin/locale/nl/LC_MESSAGES/phpmyadmin.mo
new file mode 100644
index 0000000..3942a19
Binary files /dev/null and b/phpmyadmin/locale/nl/LC_MESSAGES/phpmyadmin.mo differ
diff --git a/phpmyadmin/locale/pl/LC_MESSAGES/phpmyadmin.mo b/phpmyadmin/locale/pl/LC_MESSAGES/phpmyadmin.mo
new file mode 100644
index 0000000..26b54e3
Binary files /dev/null and b/phpmyadmin/locale/pl/LC_MESSAGES/phpmyadmin.mo differ
diff --git a/phpmyadmin/locale/pt/LC_MESSAGES/phpmyadmin.mo b/phpmyadmin/locale/pt/LC_MESSAGES/phpmyadmin.mo
new file mode 100644
index 0000000..89e282c
Binary files /dev/null and b/phpmyadmin/locale/pt/LC_MESSAGES/phpmyadmin.mo differ
diff --git a/phpmyadmin/locale/pt_BR/LC_MESSAGES/phpmyadmin.mo b/phpmyadmin/locale/pt_BR/LC_MESSAGES/phpmyadmin.mo
new file mode 100644
index 0000000..ba056d4
Binary files /dev/null and b/phpmyadmin/locale/pt_BR/LC_MESSAGES/phpmyadmin.mo differ
diff --git a/phpmyadmin/locale/ro/LC_MESSAGES/phpmyadmin.mo b/phpmyadmin/locale/ro/LC_MESSAGES/phpmyadmin.mo
new file mode 100644
index 0000000..914ef8a
Binary files /dev/null and b/phpmyadmin/locale/ro/LC_MESSAGES/phpmyadmin.mo differ
diff --git a/phpmyadmin/locale/ru/LC_MESSAGES/phpmyadmin.mo b/phpmyadmin/locale/ru/LC_MESSAGES/phpmyadmin.mo
new file mode 100644
index 0000000..a964248
Binary files /dev/null and b/phpmyadmin/locale/ru/LC_MESSAGES/phpmyadmin.mo differ
diff --git a/phpmyadmin/locale/si/LC_MESSAGES/phpmyadmin.mo b/phpmyadmin/locale/si/LC_MESSAGES/phpmyadmin.mo
new file mode 100644
index 0000000..aa619df
Binary files /dev/null and b/phpmyadmin/locale/si/LC_MESSAGES/phpmyadmin.mo differ
diff --git a/phpmyadmin/locale/sk/LC_MESSAGES/phpmyadmin.mo b/phpmyadmin/locale/sk/LC_MESSAGES/phpmyadmin.mo
new file mode 100644
index 0000000..76b9264
Binary files /dev/null and b/phpmyadmin/locale/sk/LC_MESSAGES/phpmyadmin.mo differ
diff --git a/phpmyadmin/locale/sl/LC_MESSAGES/phpmyadmin.mo b/phpmyadmin/locale/sl/LC_MESSAGES/phpmyadmin.mo
new file mode 100644
index 0000000..e03c165
Binary files /dev/null and b/phpmyadmin/locale/sl/LC_MESSAGES/phpmyadmin.mo differ
diff --git a/phpmyadmin/locale/sr at latin/LC_MESSAGES/phpmyadmin.mo b/phpmyadmin/locale/sr at latin/LC_MESSAGES/phpmyadmin.mo
new file mode 100644
index 0000000..70715f1
Binary files /dev/null and b/phpmyadmin/locale/sr at latin/LC_MESSAGES/phpmyadmin.mo differ
diff --git a/phpmyadmin/locale/sv/LC_MESSAGES/phpmyadmin.mo b/phpmyadmin/locale/sv/LC_MESSAGES/phpmyadmin.mo
new file mode 100644
index 0000000..5f76bcb
Binary files /dev/null and b/phpmyadmin/locale/sv/LC_MESSAGES/phpmyadmin.mo differ
diff --git a/phpmyadmin/locale/th/LC_MESSAGES/phpmyadmin.mo b/phpmyadmin/locale/th/LC_MESSAGES/phpmyadmin.mo
new file mode 100644
index 0000000..6dfaae8
Binary files /dev/null and b/phpmyadmin/locale/th/LC_MESSAGES/phpmyadmin.mo differ
diff --git a/phpmyadmin/locale/tr/LC_MESSAGES/phpmyadmin.mo b/phpmyadmin/locale/tr/LC_MESSAGES/phpmyadmin.mo
new file mode 100644
index 0000000..0fb1d74
Binary files /dev/null and b/phpmyadmin/locale/tr/LC_MESSAGES/phpmyadmin.mo differ
diff --git a/phpmyadmin/locale/uk/LC_MESSAGES/phpmyadmin.mo b/phpmyadmin/locale/uk/LC_MESSAGES/phpmyadmin.mo
new file mode 100644
index 0000000..ce673ac
Binary files /dev/null and b/phpmyadmin/locale/uk/LC_MESSAGES/phpmyadmin.mo differ
diff --git a/phpmyadmin/locale/uz/LC_MESSAGES/phpmyadmin.mo b/phpmyadmin/locale/uz/LC_MESSAGES/phpmyadmin.mo
new file mode 100644
index 0000000..714143e
Binary files /dev/null and b/phpmyadmin/locale/uz/LC_MESSAGES/phpmyadmin.mo differ
diff --git a/phpmyadmin/locale/uz at latin/LC_MESSAGES/phpmyadmin.mo b/phpmyadmin/locale/uz at latin/LC_MESSAGES/phpmyadmin.mo
new file mode 100644
index 0000000..321f1be
Binary files /dev/null and b/phpmyadmin/locale/uz at latin/LC_MESSAGES/phpmyadmin.mo differ
diff --git a/phpmyadmin/locale/zh_CN/LC_MESSAGES/phpmyadmin.mo b/phpmyadmin/locale/zh_CN/LC_MESSAGES/phpmyadmin.mo
new file mode 100644
index 0000000..233fb82
Binary files /dev/null and b/phpmyadmin/locale/zh_CN/LC_MESSAGES/phpmyadmin.mo differ
diff --git a/phpmyadmin/locale/zh_TW/LC_MESSAGES/phpmyadmin.mo b/phpmyadmin/locale/zh_TW/LC_MESSAGES/phpmyadmin.mo
new file mode 100644
index 0000000..c156970
Binary files /dev/null and b/phpmyadmin/locale/zh_TW/LC_MESSAGES/phpmyadmin.mo differ
diff --git a/phpmyadmin/navigation.php b/phpmyadmin/navigation.php
new file mode 100644
index 0000000..4b4b3b3
--- /dev/null
+++ b/phpmyadmin/navigation.php
@@ -0,0 +1,27 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * the navigation frame - displays server, db and table selection tree
+ *
+ * @package PhpMyAdmin-Navigation
+ */
+
+// Include common functionalities
+require_once './libraries/common.inc.php';
+
+// Also initialises the collapsible tree class
+require_once './libraries/navigation/Navigation.class.php';
+
+// Do the magic
+$response = PMA_Response::getInstance();
+if ($response->isAjax()) {
+    $navigation = new PMA_Navigation();
+    $response->addJSON('message', $navigation->getDisplay());
+} else {
+    $response->addHTML(
+        PMA_Message::error(
+            __('Fatal error: The navigation can only be accessed via AJAX')
+        )
+    );
+}
+?>
diff --git a/phpmyadmin/phpinfo.php b/phpmyadmin/phpinfo.php
new file mode 100644
index 0000000..5854ff4
--- /dev/null
+++ b/phpmyadmin/phpinfo.php
@@ -0,0 +1,21 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * phpinfo() wrapper to allow displaying only when configured to do so.
+ *
+ * @package PhpMyAdmin
+ */
+
+/**
+ * Gets core libraries and defines some variables
+ */
+require_once 'libraries/common.inc.php';
+PMA_Response::getInstance()->disable();
+
+/**
+ * Displays PHP information
+ */
+if ($GLOBALS['cfg']['ShowPhpInfo']) {
+    phpinfo();
+}
+?>
diff --git a/phpmyadmin/phpmyadmin.css.php b/phpmyadmin/phpmyadmin.css.php
new file mode 100644
index 0000000..bfe4d47
--- /dev/null
+++ b/phpmyadmin/phpmyadmin.css.php
@@ -0,0 +1,31 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ *
+ * @package PhpMyAdmin
+ */
+
+/**
+ *
+ */
+
+define('PMA_MINIMUM_COMMON', true);
+require_once 'libraries/common.inc.php';
+
+// MSIE 6 (at least some unpatched versions) has problems loading CSS
+// when zlib_compression is on
+if (PMA_USR_BROWSER_AGENT == 'IE' && PMA_USR_BROWSER_VER == '6'
+    && (ini_get('zlib.output_compression'))
+) {
+    @ini_set('zlib.output_compression', 'Off');
+}
+
+// Send correct type:
+header('Content-Type: text/css; charset=UTF-8');
+
+// Cache output in client - the nocache query parameter makes sure that this
+// file is reloaded when config changes
+header('Expires: ' . gmdate('D, d M Y H:i:s', time() + 3600) . ' GMT');
+
+$_SESSION['PMA_Theme_Manager']->printCss();
+?>
diff --git a/phpmyadmin/phpunit.xml.nocoverage b/phpmyadmin/phpunit.xml.nocoverage
new file mode 100644
index 0000000..6f1967a
--- /dev/null
+++ b/phpmyadmin/phpunit.xml.nocoverage
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<phpunit bootstrap="test/bootstrap-dist.php"
+         backupGlobals="false"
+         backupStaticAttributes="false"
+         strict="true"
+         colors="true"
+         verbose="true">
+
+    <selenium>
+        <browser name="Firefox on localhost"
+                 browser="*firefox"
+                 host="127.0.0.1"
+                 port="4444"
+                 timeout="30000"/>
+    </selenium>
+
+    <php>
+        <const name="TESTSUITE_SERVER" value="localhost"/>
+        <const name="TESTSUITE_USER" value="root"/>
+        <const name="TESTSUITE_PASSWORD" value=""/>
+        <const name="TESTSUITE_DATABASE" value="test"/>
+        <const name="TESTSUITE_PHPMYADMIN_HOST" value="http://localhost" />
+        <const name="TESTSUITE_PHPMYADMIN_URL" value="/phpmyadmin" />
+    </php>
+
+    <testsuites>
+        <testsuite name="Classes">
+            <directory suffix="_test.php">test/classes</directory>
+        </testsuite>
+        <testsuite name="Unit">
+            <file>test/Environment_test.php</file>
+            <directory suffix="_test.php">test/libraries/core</directory>
+            <directory suffix="_test.php">test/libraries/common</directory>
+            <directory suffix="_test.php">test/libraries/rte</directory>
+            <directory suffix="_test.php">test/libraries</directory>
+        </testsuite>
+        <!--<testsuite name="Selenium">-->
+            <!--<directory suffix="Test.php">test/selenium</directory>-->
+        <!--</testsuite>-->
+    </testsuites>
+
+    <logging>
+        <log type="junit" target="build/logs/junit.xml" logIncompleteSkipped="false"/>
+    </logging>
+
+</phpunit>
+
diff --git a/phpmyadmin/pmd_display_field.php b/phpmyadmin/pmd_display_field.php
new file mode 100644
index 0000000..affece4
--- /dev/null
+++ b/phpmyadmin/pmd_display_field.php
@@ -0,0 +1,61 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * @package PhpMyAdmin-Designer
+ */
+
+/**
+ *
+ */
+require_once './libraries/common.inc.php';
+
+PMA_Response::getInstance()->disable();
+
+require_once 'libraries/pmd_common.php';
+
+$post_params = array(
+    'T',
+    'F'
+);
+
+foreach ($post_params as $one_post_param) {
+    if (isset($_POST[$one_post_param])) {
+        $GLOBALS[$one_post_param] = $_POST[$one_post_param];
+    }
+}
+
+$table = $T;
+$display_field = $F;
+
+if ($cfgRelation['displaywork']) {
+
+    $disp     = PMA_getDisplayField($db, $table);
+    if ($disp) {
+        if ($display_field != $disp) {
+            $upd_query = 'UPDATE ' . PMA_Util::backquote($GLOBALS['cfgRelation']['db']) . '.' . PMA_Util::backquote($cfgRelation['table_info'])
+                       . ' SET display_field = \'' . PMA_Util::sqlAddSlashes($display_field) . '\''
+                       . ' WHERE db_name  = \'' . PMA_Util::sqlAddSlashes($db) . '\''
+                       . ' AND table_name = \'' . PMA_Util::sqlAddSlashes($table) . '\'';
+        } else {
+            $upd_query = 'DELETE FROM ' . PMA_Util::backquote($GLOBALS['cfgRelation']['db']) . '.' . PMA_Util::backquote($cfgRelation['table_info'])
+                       . ' WHERE db_name  = \'' . PMA_Util::sqlAddSlashes($db) . '\''
+                       . ' AND table_name = \'' . PMA_Util::sqlAddSlashes($table) . '\'';
+        }
+    } elseif ($display_field != '') {
+        $upd_query = 'INSERT INTO ' . PMA_Util::backquote($GLOBALS['cfgRelation']['db']) . '.' . PMA_Util::backquote($cfgRelation['table_info'])
+                   . '(db_name, table_name, display_field) '
+                   . ' VALUES('
+                   . '\'' . PMA_Util::sqlAddSlashes($db) . '\','
+                   . '\'' . PMA_Util::sqlAddSlashes($table) . '\','
+                   . '\'' . PMA_Util::sqlAddSlashes($display_field) . '\')';
+    }
+
+    if (isset($upd_query)) {
+        $upd_rs    = PMA_queryAsControlUser($upd_query);
+    }
+} // end if
+
+header("Content-Type: text/xml; charset=utf-8");
+header("Cache-Control: no-cache");
+die("<root act='save_pos' return='" . __('Modifications have been saved') . "'></root>");
+?>
diff --git a/phpmyadmin/pmd_general.php b/phpmyadmin/pmd_general.php
new file mode 100644
index 0000000..f392694
--- /dev/null
+++ b/phpmyadmin/pmd_general.php
@@ -0,0 +1,879 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * phpMyAdmin designer general code
+ *
+ * @package PhpMyAdmin-Designer
+ */
+
+/**
+ *
+ */
+require_once 'libraries/common.inc.php';
+require_once 'libraries/pmd_common.php';
+
+/**
+ * Sets globals from $_GET
+ */
+$get_params = array(
+    'db',
+    'table',
+    'token'
+);
+foreach ($get_params as $one_get_param) {
+    if (isset($_GET[$one_get_param])) {
+        $GLOBALS[$one_get_param] = $_GET[$one_get_param];
+    }
+}
+
+$script_display_field = get_tables_info();
+$tab_column       = get_columns_info();
+$script_tables    = get_script_tabs();
+$script_contr     = get_script_contr();
+$tab_pos          = get_tab_pos();
+$tables_pk_or_unique_keys = get_pk_or_unique_keys();
+$tables_all_keys  = get_all_keys();
+
+$params = array('lang' => $GLOBALS['lang']);
+if (isset($GLOBALS['db'])) {
+    $params['db'] = $GLOBALS['db'];
+}
+
+$response = PMA_Response::getInstance();
+$response->getFooter()->setMinimal();
+$header   = $response->getHeader();
+$header->setBodyId('pmd_body');
+$scripts = $header->getScripts();
+$scripts->addFile('pmd/ajax.js');
+$scripts->addFile('pmd/history.js');
+$scripts->addFile('pmd/move.js');
+$scripts->addFile('pmd/iecanvas.js', true);
+$scripts->addFile('pmd/init.js');
+$scripts->addFile('jquery/jquery.fullscreen.js');
+
+require 'libraries/db_common.inc.php';
+require 'libraries/db_info.inc.php';
+
+// Embed some data into HTML, later it will be read
+// by pmd/init.js and converted to JS variables.
+echo '<div id="script_server" class="hide">';
+echo htmlspecialchars($GLOBALS['server']);
+echo '</div>';
+echo '<div id="script_db" class="hide">';
+echo htmlspecialchars($GLOBALS['db']);
+echo '</div>';
+echo '<div id="script_token" class="hide">';
+echo htmlspecialchars($GLOBALS['token']);
+echo '</div>';
+echo '<div id="script_tables" class="hide">';
+echo htmlspecialchars(json_encode($script_tables));
+echo '</div>';
+echo '<div id="script_contr" class="hide">';
+echo htmlspecialchars(json_encode($script_contr));
+echo '</div>';
+echo '<div id="script_display_field" class="hide">';
+echo htmlspecialchars(json_encode($script_display_field));
+echo '</div>';
+
+?>
+<div class="pmd_header" id="top_menu">
+    <a href="#" onclick="Show_left_menu(document.getElementById('key_Show_left_menu')); return false"
+        class="M_butt first" target="_self">
+        <img id='key_Show_left_menu' title="<?php echo __('Show/Hide left menu'); ?>" alt="v"
+            src="<?php echo $_SESSION['PMA_Theme']->getImgPath('pmd/downarrow2_m.png'); ?>" />
+    </a>
+    <a href="#" id="enterFullscreen" onclick="Enter_fullscreen(); return false" class="M_butt" target="_self">
+        <img title="<?php echo __('View in fullscreen') ?>" alt=""
+            src="<?php echo $_SESSION['PMA_Theme']->getImgPath('pmd/viewInFullscreen.png'); ?>" />
+    </a>
+    <a href="#" id="exitFullscreen" onclick="Exit_fullscreen(); return false" class="M_butt hide" target="_self">
+        <img title="<?php echo __('Exit fullscreen') ?>" alt=""
+            src="<?php echo $_SESSION['PMA_Theme']->getImgPath('pmd/exitFullscreen.png'); ?>" />
+    </a>
+    <img class="M_bord" src="<?php echo $_SESSION['PMA_Theme']->getImgPath('pmd/bord.png'); ?>" alt="" />
+    <a href="#" onclick="Save2(); return false" class="M_butt" target="_self">
+        <img title="<?php echo __('Save position') ?>" alt=""
+            src="<?php echo $_SESSION['PMA_Theme']->getImgPath('pmd/save.png'); ?>" />
+    </a>
+    <a href="#" onclick="Start_table_new(); return false"
+        class="M_butt" target="_self">
+        <img title="<?php echo __('Create table')?>" alt=""
+            src="<?php echo $_SESSION['PMA_Theme']->getImgPath('pmd/table.png'); ?>" />
+    </a>
+    <a href="#" onclick="Start_relation(); return false" class="M_butt" id="rel_button" target="_self">
+        <img title="<?php echo __('Create relation') ?>" alt=""
+            src="<?php echo $_SESSION['PMA_Theme']->getImgPath('pmd/relation.png'); ?>" />
+    </a>
+    <a href="#" onclick="Start_display_field(); return false"
+        class="M_butt" id="display_field_button" target="_self">
+        <img title="<?php echo __('Choose column to display') ?>" alt=""
+            src="<?php echo $_SESSION['PMA_Theme']->getImgPath('pmd/display_field.png'); ?>" />
+    </a>
+    <a href="#" onclick="location.reload(); return false" class="M_butt" target="_self">
+        <img title="<?php echo __('Reload'); ?>" alt=""
+            src="<?php echo $_SESSION['PMA_Theme']->getImgPath('pmd/reload.png'); ?>" />
+    </a>
+    <a href="<?php echo PMA_Util::getDocuLink('faq', 'faq6-31') ?>" target="documentation" class="M_butt" target="_self">
+        <img title="<?php echo __('Help'); ?>" alt=""
+            src="<?php echo $_SESSION['PMA_Theme']->getImgPath('pmd/help.png'); ?>" />
+    </a>
+    <img class="M_bord" src="<?php echo $_SESSION['PMA_Theme']->getImgPath('pmd/bord.png'); ?>" alt="" />
+    <a href="#" onclick="Angular_direct(); return false"
+        class="M_butt" id="angular_direct_button" target="_self">
+        <img title="<?php echo __('Angular links') . ' / ' . __('Direct links'); ?>" alt=""
+            src="<?php echo $_SESSION['PMA_Theme']->getImgPath('pmd/ang_direct.png'); ?>" />
+    </a>
+    <a href="#" onclick="Grid(); return false" class="M_butt" id="grid_button" target="_self">
+        <img title="<?php echo __('Snap to grid') ?>"
+            src="<?php echo $_SESSION['PMA_Theme']->getImgPath('pmd/grid.png'); ?>" alt="" />
+    </a>
+    <img class="M_bord" src="<?php echo $_SESSION['PMA_Theme']->getImgPath('pmd/bord.png'); ?>" alt="" />
+    <a href="#" onclick="Small_tab_all(document.getElementById('key_SB_all')); return false"
+        class="M_butt" target="_self">
+        <img id='key_SB_all' title="<?php echo __('Small/Big All'); ?>" alt="v"
+            src="<?php echo $_SESSION['PMA_Theme']->getImgPath('pmd/downarrow1.png'); ?>" />
+    </a>
+    <a href="#" onclick="Small_tab_invert(); return false" class="M_butt" target="_self" >
+        <img title="<?php echo __('Toggle small/big'); ?>" alt="key"
+            src="<?php echo $_SESSION['PMA_Theme']->getImgPath('pmd/bottom.png'); ?>" />
+    </a>
+    <a href="#" onclick="Relation_lines_invert(); return false" class="M_butt" target="_self" >
+        <img title="<?php echo __('Toggle relation lines'); ?>" alt="key"
+            src="<?php echo $_SESSION['PMA_Theme']->getImgPath('pmd/toggle_lines.png'); ?>" />
+    </a>
+    <img class="M_bord" src="<?php echo $_SESSION['PMA_Theme']->getImgPath('pmd/bord.png'); ?>" alt="" />
+    <a href="#" onclick="PDF_save(); return false" class="M_butt ajax">
+        <img src="<?php echo $_SESSION['PMA_Theme']->getImgPath('pmd/pdf.png'); ?>" alt="key"
+            width="20" height="20" title="<?php echo __('Import/Export coordinates for PDF schema'); ?>" />
+    </a>
+<?php
+if (isset($_REQUEST['query'])) {
+    echo '<a href="#" onclick="build_query(\'SQL Query on Database\', 0)" onmousedown="return false;"
+    class="M_butt" target="_self">';
+    echo '<img src="'. $_SESSION['PMA_Theme']->getImgPath('pmd/query_builder.png') . '" alt="key" width="20" height="20" title="';
+    echo __('Build Query');
+    echo '"/></a>';
+}
+?>
+    <a href="#" onclick="Top_menu_right(document.getElementById('key_Left_Right')); return false"
+        class="M_butt last" target="_self">
+        <img src="<?php echo $_SESSION['PMA_Theme']->getImgPath('pmd/2rightarrow_m.png'); ?>"
+            id="key_Left_Right" alt=">" title="<?php echo __('Move Menu'); ?>" />
+    </a>
+</div>
+
+<div id="canvas_outer">
+<form action="" method="post" name="form1">
+<div id="osn_tab">
+  <canvas class="pmd" id="canvas" width="100" height="100" onclick="Canvas_click(this)"></canvas>
+</div>
+<div id="layer_menu" style="display:none;">
+<div class="center" style="padding-top:5px;">
+    <a href="#"
+        onclick="Hide_tab_all(document.getElementById('key_HS_all')); return false" class="M_butt" target="_self">
+    <img title="<?php echo __('Hide/Show all'); ?>" alt="v"
+        src="<?php echo $_SESSION['PMA_Theme']->getImgPath('pmd/downarrow1.png'); ?>" id='key_HS_all' /></a>
+    <a href="#"
+        onclick="No_have_constr(document.getElementById('key_HS')); return false" class="M_butt" target="_self">
+    <img title="<?php echo __('Hide/Show Tables with no relation'); ?>" alt="v"
+        src="<?php echo $_SESSION['PMA_Theme']->getImgPath('pmd/downarrow2.png'); ?>" id='key_HS' /></a>
+</div>
+
+<div id="id_scroll_tab" class="scroll_tab">
+    <table width="100%" style="padding-left: 3px;">
+<?php
+$name_cnt = count($GLOBALS['PMD']['TABLE_NAME']);
+for ($i = 0; $i < $name_cnt; $i++) {
+
+    echo '<tr><td title="' . __('Structure') . '" width="1px" '
+        . 'onmouseover="this.className=\'L_butt2_2\'" '
+        . 'onmouseout="this.className=\'L_butt2_1\'" class="L_butt2_1">';
+    echo '<img '
+        . 'onclick="Start_tab_upd(\'' . $GLOBALS['PMD_URL']["TABLE_NAME_SMALL"][$i] . '\');" '
+        . 'src="' . $_SESSION['PMA_Theme']->getImgPath('pmd/exec.png') . '" alt="" />';
+    echo '</td>';
+    echo '<td width="1px">';
+    echo '<input onclick="VisibleTab(this,\'' . $GLOBALS['PMD_URL']["TABLE_NAME"][$i] . '\')" '
+        . 'title="' . __('Hide') . '" '
+        . 'id="check_vis_' . $GLOBALS['PMD_URL']["TABLE_NAME"][$i] . '" '
+        . 'style="margin:0px;" type="checkbox" '
+        . 'value="' . $GLOBALS['PMD_URL']["TABLE_NAME"][$i] . '"';
+    if (isset($tab_pos[$GLOBALS['PMD']["TABLE_NAME"][$i]])) {
+        echo $tab_pos[$GLOBALS['PMD']["TABLE_NAME"][$i]]["H"] ? 'checked="checked"' : '';
+    } else {
+        echo 'checked="checked"';
+    }
+    echo '/></td>';
+    echo '<td class="pmd_Tabs" onmouseover="this.className=\'pmd_Tabs2\'" '
+        . 'onmouseout="this.className=\'pmd_Tabs\'" '
+        . 'onclick="Select_tab(\'' . $GLOBALS['PMD_URL']["TABLE_NAME"][$i] . '\');">';
+    echo $GLOBALS['PMD_OUT']["TABLE_NAME"][$i];
+    echo '</td>';
+    echo '</tr>';
+}
+echo '</table>';
+echo '</div>';
+
+echo '<div class="center">';
+echo __('Number of tables') . ': ' . $name_cnt;
+echo '</div>';
+echo '<div class="floatright">';
+echo '<div id="layer_menu_sizer" onmousedown="layer_menu_cur_click=1">';
+echo '</div>';
+echo '</div>';
+echo '</div>';
+
+for ($i = 0; $i < count($GLOBALS['PMD']["TABLE_NAME"]); $i++) {
+    $t_n = $GLOBALS['PMD']["TABLE_NAME"][$i];
+    $t_n_url = $GLOBALS['PMD_URL']["TABLE_NAME"][$i];
+
+    ?>
+<input name="t_x[<?php echo $t_n_url ?>]" type="hidden" id="t_x_<?php echo $t_n_url ?>_" />
+<input name="t_y[<?php echo $t_n_url ?>]" type="hidden" id="t_y_<?php echo $t_n_url ?>_" />
+<input name="t_v[<?php echo $t_n_url ?>]" type="hidden" id="t_v_<?php echo $t_n_url ?>_" />
+<input name="t_h[<?php echo $t_n_url ?>]" type="hidden" id="t_h_<?php echo $t_n_url ?>_" />
+
+<table id="<?php echo $t_n_url ?>" cellpadding="0" cellspacing="0" class="pmd_tab"
+   style="position: absolute;
+          left: <?php
+          echo isset($tab_pos[$t_n]) ? $tab_pos[$t_n]["X"] : rand(20, 700); ?>px;
+          top: <?php
+          echo isset($tab_pos[$t_n]) ? $tab_pos[$t_n]["Y"] : rand(20, 550); ?>px;
+          visibility: <?php
+          echo ! isset($tab_pos[$t_n]) || $tab_pos[$t_n]["H"]
+            ? "visible"
+            : "hidden"; ?>;
+         z-index: 1;">
+<thead>
+<tr>
+    <?php
+    if (isset($_REQUEST['query'])) {
+        echo '<td class="select_all">';
+        echo '<input type="checkbox" value="select_all_'.htmlspecialchars($t_n_url).'" style="margin: 0px;" ';
+        echo 'id="select_all_'.htmlspecialchars($t_n_url).'" title="select all" ';
+        echo 'onclick="Select_all(\''. htmlspecialchars($t_n_url) .'\',\''.htmlspecialchars($GLOBALS['PMD_OUT']["OWNER"][$i]).'\')"></td>';
+    }
+    ?>
+    <td class="small_tab" onmouseover="this.className='small_tab2';"
+        onmouseout="this.className='small_tab';"
+        id="id_hide_tbody_<?php echo $t_n_url ?>"
+        onclick="Small_tab('<?php echo $t_n_url ?>', 1)"><?php
+        // no space alloawd here, between tags and content !!!
+        // JavaScript function does require this
+    if (! isset($tab_pos[$t_n]) || ! empty($tab_pos[$t_n]["V"])) {
+        echo 'v';
+    } else {
+        echo '>';
+    }
+        ?></td>
+    <td class="small_tab_pref" onmouseover="this.className='small_tab_pref2';"
+        onmouseout="this.className='small_tab_pref';"
+        onclick="Start_tab_upd('<?php echo $GLOBALS['PMD_URL']["TABLE_NAME_SMALL"][$i]; ?>');">
+        <img src="<?php echo $_SESSION['PMA_Theme']->getImgPath('pmd/exec_small.png'); ?>" alt="" /></td>
+    <td id="id_zag_<?php echo $t_n_url ?>" class="tab_zag nowrap"
+        onmousedown="cur_click=document.getElementById('<?php echo $t_n_url ?>');"/
+        onmouseover="Table_onover('<?php echo $t_n_url ?>',0,<?php echo (isset($_REQUEST['query'])? 1 : 0 )?> )"
+        onmouseout="Table_onover('<?php echo $t_n_url ?>',1,<?php echo (isset($_REQUEST['query']) ? 1 : 0 )?>)">
+        <span class='owner'>
+        <?php
+        echo $GLOBALS['PMD_OUT']["OWNER"][$i];
+        echo '.</span>';
+        echo $GLOBALS['PMD_OUT']["TABLE_NAME_SMALL"][$i];
+        ?></td>
+    <?php
+    if (isset($_REQUEST['query'])) {
+        echo '<td class="tab_zag"  onmouseover="Table_onover(\''.htmlspecialchars($t_n_url).'\',0,1)"  id="id_zag_'.htmlspecialchars($t_n_url).'_2"';
+        echo 'onmousedown="cur_click=document.getElementById(\''.htmlspecialchars($t_n_url).'\');"';
+        echo 'onmouseout="Table_onover(\''.htmlspecialchars($t_n_url).'\',1,1)">';
+    }
+    ?>
+</tr>
+</thead>
+<tbody id="id_tbody_<?php echo $t_n_url ?>"
+    <?php
+    if (isset($tab_pos[$t_n]) && empty($tab_pos[$t_n]["V"])) {
+        echo 'style="display: none;"';
+    }
+    echo '>';
+    $display_field = PMA_getDisplayField($db, $GLOBALS['PMD']["TABLE_NAME_SMALL"][$i]);
+    for ($j = 0, $id_cnt = count($tab_column[$t_n]["COLUMN_ID"]); $j < $id_cnt; $j++) {
+        ?>
+<tr id="id_tr_<?php
+        echo $GLOBALS['PMD_URL']["TABLE_NAME_SMALL"][$i] . '.'
+            . urlencode($tab_column[$t_n]["COLUMN_NAME"][$j]) ?>"
+        <?php
+    if ($display_field == $tab_column[$t_n]["COLUMN_NAME"][$j]) {
+        echo ' class="tab_field_3" ';
+    } else {
+        echo ' class="tab_field" ';
+    }
+        ?>
+    onmouseover="old_class = this.className; this.className = 'tab_field_2';"
+    onmouseout="this.className = old_class;"
+    onmousedown="Click_field('<?php
+    echo $GLOBALS['PMD_URL']["TABLE_NAME_SMALL"][$i]."','".urlencode($tab_column[$t_n]["COLUMN_NAME"][$j])."',";
+    if (!PMA_Util::isForeignKeySupported($GLOBALS['PMD']['TABLE_TYPE'][$i])) {
+        echo (isset($tables_pk_or_unique_keys[$t_n . "." . $tab_column[$t_n]["COLUMN_NAME"][$j]]) ? 1 : 0);
+    } else {
+        // if foreign keys are supported, it's not necessary that the
+        // index is a primary key
+        echo (isset($tables_all_keys[$t_n.".".$tab_column[$t_n]["COLUMN_NAME"][$j]]) ? 1 : 0);
+    }
+        ?>)">
+    <?php
+    if (isset($_REQUEST['query'])) {
+        echo '<td class="select_all">';
+        echo '<input value="'.htmlspecialchars($t_n_url).urlencode($tab_column[$t_n]["COLUMN_NAME"][$j]).'"';
+        echo 'type="checkbox" id="select_'.htmlspecialchars($t_n_url).'._'.urlencode($tab_column[$t_n]["COLUMN_NAME"][$j]).'" ';
+        echo 'style="margin: 0px;" title="select_'.urlencode($tab_column[$t_n]["COLUMN_NAME"][$j]).'" ';
+        echo 'onclick="store_column(\''.urlencode($GLOBALS['PMD_OUT']["TABLE_NAME_SMALL"][$i]).'\',\''.htmlspecialchars($GLOBALS['PMD_OUT']["OWNER"][$i]).'\',\''.urlencode($tab_column[$t_n]["COLUMN_NAME"][$j]).'\')"></td>';
+    }?>
+    <td width="10px" colspan="3"
+        id="<?php echo $t_n_url.".".urlencode($tab_column[$t_n]["COLUMN_NAME"][$j]) ?>">
+        <div class="nowrap">
+        <?php
+        if (isset($tables_pk_or_unique_keys[$t_n.".".$tab_column[$t_n]["COLUMN_NAME"][$j]])) {
+            ?>
+                <img src="<?php echo $_SESSION['PMA_Theme']->getImgPath(); ?>pmd/FieldKey_small.png"
+                    alt="*" />
+            <?php
+        } else {
+            ?>
+                    <img src="<?php echo $_SESSION['PMA_Theme']->getImgPath(); ?>pmd/Field_small<?php
+            if (strstr($tab_column[$t_n]["TYPE"][$j], 'char')
+                || strstr($tab_column[$t_n]["TYPE"][$j], 'text')
+            ) {
+                echo '_char';
+            } elseif (strstr($tab_column[$t_n]["TYPE"][$j], 'int')
+                || strstr($tab_column[$t_n]["TYPE"][$j], 'float')
+                || strstr($tab_column[$t_n]["TYPE"][$j], 'double')
+                || strstr($tab_column[$t_n]["TYPE"][$j], 'decimal')
+            ) {
+                echo '_int';
+            } elseif (strstr($tab_column[$t_n]["TYPE"][$j], 'date')
+                || strstr($tab_column[$t_n]["TYPE"][$j], 'time')
+                || strstr($tab_column[$t_n]["TYPE"][$j], 'year')
+            ) {
+                echo '_date';
+            }
+            ?>.png" alt="*" />
+            <?php
+        }
+        echo htmlspecialchars(
+            $tab_column[$t_n]["COLUMN_NAME"][$j] . " : " . $tab_column[$t_n]["TYPE"][$j],
+            ENT_QUOTES
+        );
+        echo "</div>\n</td>\n";
+        if (isset($_REQUEST['query'])) {
+            //$temp = $GLOBALS['PMD_OUT']["OWNER"][$i].'.'.$GLOBALS['PMD_OUT']["TABLE_NAME_SMALL"][$i];
+            echo '<td class="small_tab_pref" onmouseover="this.className=\'small_tab_pref2\';"';
+            echo 'onmouseout="this.className=\'small_tab_pref\';"';
+            echo 'onclick="Click_option(\'pmd_optionse\',\''
+                . urlencode($tab_column[$t_n]["COLUMN_NAME"][$j]) . '\',\''
+                . $GLOBALS['PMD_OUT']["TABLE_NAME_SMALL"][$i].'\')" >';
+            echo  '<img src="'
+                . $_SESSION['PMA_Theme']->getImgPath('pmd/exec_small.png')
+                . '" title="options" alt="" /></td> ';
+        }
+        echo "</tr>\n";
+    }
+    echo "</tbody>\n</table>\n";
+}
+?>
+</form>
+</div>
+<div id="pmd_hint"></div>
+
+<table id="layer_new_relation" style="display:none;"
+    width="5%" cellpadding="0" cellspacing="0">
+<tbody>
+<tr>
+    <td class="frams1" width="10px"></td>
+    <td class="frams5" width="99%" ></td>
+    <td class="frams2" width="10px"><div class="bor"></div></td>
+</tr>
+<tr>
+    <td class="frams8"></td>
+    <td class="input_tab">
+        <table width="168" class="center" cellpadding="2" cellspacing="0">
+        <thead>
+        <tr>
+            <td colspan="2" class="center nowrap"><strong><?php echo __('Create relation'); ?></strong></td>
+        </tr>
+        </thead>
+        <tbody id="foreign_relation">
+        <tr>
+        <td colspan="2" class="center nowrap"><strong>FOREIGN KEY</strong></td>
+        </tr>
+        <tr>
+            <td width="58" class="nowrap">on delete</td>
+            <td width="102"><select name="on_delete" id="on_delete">
+                    <option value="nix" selected="selected">--</option>
+                    <option value="CASCADE">CASCADE</option>
+                    <option value="SET NULL">SET NULL</option>
+                    <option value="NO ACTION">NO ACTION</option>
+                    <option value="RESTRICT">RESTRICT</option>
+                </select>
+            </td>
+        </tr>
+        <tr>
+            <td class="nowrap">on update</td>
+            <td><select name="on_update" id="on_update">
+                    <option value="nix" selected="selected">--</option>
+                    <option value="CASCADE">CASCADE</option>
+                    <option value="SET NULL">SET NULL</option>
+                    <option value="NO ACTION">NO ACTION</option>
+                    <option value="RESTRICT">RESTRICT</option>
+                </select>
+            </td>
+        </tr>
+        </tbody>
+        <tbody>
+        <tr>
+            <td colspan="2" class="center nowrap">
+                <input type="button" class="butt" name="Button"
+                    value="<?php echo __('OK'); ?>" onclick="New_relation()" />
+                <input type="button" class="butt" name="Button"
+                    value="<?php echo __('Cancel'); ?>"
+                    onclick="document.getElementById('layer_new_relation').style.display = 'none';" />
+            </td>
+        </tr>
+        </tbody>
+        </table>
+    </td>
+    <td class="frams6"></td>
+</tr>
+<tr>
+    <td class="frams4"><div class="bor"></div></td>
+    <td class="frams7"></td>
+    <td class="frams3"></td>
+</tr>
+</tbody>
+</table>
+
+<table id="layer_upd_relation" style="display:none;"
+    width="5%" cellpadding="0" cellspacing="0">
+<tbody>
+<tr>
+    <td class="frams1" width="10px"></td>
+    <td class="frams5" width="99%"></td>
+    <td class="frams2" width="10px"><div class="bor"></div></td>
+</tr>
+<tr>
+    <td class="frams8"></td>
+    <td class="input_tab">
+        <table width="100%" class="center" cellpadding="2" cellspacing="0">
+        <tr>
+            <td colspan="3" class="center nowrap"><strong><?php echo __('Delete relation'); ?></strong></td>
+        </tr>
+        <tr>
+            <td colspan="3" class="center nowrap">
+                <input name="Button" type="button" class="butt"
+                    onclick="Upd_relation()" value="<?php echo __('Delete'); ?>" />
+                <input type="button" class="butt" name="Button"
+                    value="<?php echo __('Cancel'); ?>"
+                    onclick="document.getElementById('layer_upd_relation').style.display = 'none'; Re_load();" />
+            </td>
+        </tr>
+    </table></td>
+    <td class="frams6"></td>
+</tr>
+<tr>
+    <td class="frams4"><div class="bor"></div></td>
+    <td class="frams7"></td>
+    <td class="frams3"></td>
+</tr>
+</tbody>
+</table>
+
+<table id="pmd_optionse" style="display:none;"
+    width="5%" cellpadding="0" cellspacing="0">
+<tbody>
+<tr>
+    <td class="frams1" width="10px"></td>
+    <td class="frams5" width="99%" ></td>
+    <td class="frams2" width="10px"><div class="bor"></div></td>
+</tr>
+<tr>
+    <td class="frams8"></td>
+    <td class="input_tab">
+        <table width="168" class="center" cellpadding="2" cellspacing="0">
+       <thead>
+        <tr>
+            <td colspan="2" rowspan="2" id="option_col_name" class="center nowrap"></td>
+        </tr>
+        </thead>
+        <tbody id="where">
+        <tr><td class="center nowrap"><b>WHERE</b></td></tr>
+        <tr>
+        <td width="58" class="nowrap"><?php echo __('Relation operator'); ?></td>
+            <td width="102"><select name="rel_opt" id="rel_opt">
+                    <option value="--" selected="selected"> -- </option>
+                    <option value="="> = </option>
+                    <option value=">"> > </option>
+                    <option value="<"> < </option>
+                    <option value=">="> >= </option>
+                    <option value="<="> <= </option>
+                    <option value="NOT"> NOT </option>
+                    <option value="IN"> IN </option>
+                    <option value="EXCEPT"> <?php echo __('Except'); ?> </option>
+                    <option value="NOT IN"> NOT IN </option>
+                </select>
+            </td>
+        </tr>
+        <tr>
+        <td class="nowrap"><?php echo __('Value'); ?>/<br /><?php echo __('subquery'); ?></td>
+            <td><textarea id="Query" value="" cols="18"></textarea>
+            </td>
+        </tr>
+        <tr><td class="center nowrap"><b><?php echo __('Rename to'); ?></b></td></tr>
+        <tr>
+        <td width="58" class="nowrap"><?php echo __('New name'); ?></td>
+            <td width="102"><input type="text" value="" id="new_name"/></td>
+        </tr>
+        <tr><td class="center nowrap"><b><?php echo __('Aggregate'); ?></b></td></tr>
+         <tr>
+         <td width="58" class="nowrap"><?php echo __('Operator'); ?></td>
+            <td width="102"><select name="operator" id="operator">
+                    <option value="---" selected="selected">---</option>
+                    <option value="sum" > SUM </option>
+                    <option value="min"> MIN </option>
+                    <option value="max"> MAX </option>
+                    <option value="avg"> AVG </option>
+                    <option value="count"> COUNT </option>
+                    </select>
+           </td></tr>
+           <tr>
+                <td width="58" class="center nowrap"><b>GROUP BY</b></td>
+                <td><input type="checkbox" value="groupby" id="groupby"/></td>
+           </tr>
+           <tr>
+                <td width="58" class="center nowrap"><b>ORDER BY</b></td>
+                <td><input type="checkbox" value="orderby" id="orderby"/></td>
+           </tr>
+          <tr><td class="center nowrap"><b>HAVING</b></td></tr>
+          <tr>
+          <td width="58" class="nowrap"><?php echo __('Operator'); ?></td>
+            <td width="102"><select name="h_operator" id="h_operator">
+                    <option value="---" selected="selected">---</option>
+                    <option value="None" > <?php echo __('None'); ?> </option>
+                    <option value="sum" > SUM </option>
+                    <option value="min"> MIN </option>
+                    <option value="max"> MAX </option>
+                    <option value="avg"> AVG </option>
+                    <option value="count"> COUNT </option>
+                    </select>
+               </td></tr>
+            <tr>
+            <td width="58" class="nowrap"><?php echo __('Relation operator'); ?></td>
+            <td width="102"><select name="h_rel_opt" id="h_rel_opt">
+                    <option value="--" selected="selected"> -- </option>
+                    <option value="="> = </option>
+                    <option value=">"> > </option>
+                    <option value="<"> < </option>
+                    <option value=">="> >= </option>
+                    <option value="<="> <= </option>
+                    <option value="NOT"> NOT </option>
+                    <option value="IN"> IN </option>
+                    <option value="EXCEPT"> <?php echo __('Except'); ?> </option>
+                    <option value="NOT IN"> NOT IN </option>
+                </select>
+            </td>
+            </tr>
+            <tr>
+            <td width="58" class="nowrap"><?php echo __('Value'); ?>/<br/><?php echo __('subquery'); ?></td>
+                <td width="102"><textarea id="having" value="" cols="18"></textarea></td>
+            </tr>
+        </tbody>
+        <tbody>
+        <tr>
+            <td colspan="2" class="center nowrap">
+                <input type="button" class="butt" name="Button"
+                    value="<?php echo __('OK'); ?>" onclick="add_object()" />
+                <input type="button" class="butt" name="Button"
+                    value="<?php echo __('Cancel'); ?>"
+                    onclick="Close_option()" />
+            </td>
+        </tr>
+        </tbody>
+        </table>
+    </td>
+    <td class="frams6"></td>
+</tr>
+<tr>
+    <td class="frams4"><div class="bor"></div></td>
+    <td class="frams7"></td>
+    <td class="frams3"></td>
+</tr>
+</tbody>
+</table>
+
+<table id="query_rename_to" style="display:none;"
+    width="5%" cellpadding="0" cellspacing="0">
+<tbody>
+<tr>
+    <td class="frams1" width="10px"></td>
+    <td class="frams5" width="99%" ></td>
+    <td class="frams2" width="10px"><div class="bor"></div></td>
+</tr>
+<tr>
+    <td class="frams8"></td>
+    <td class="input_tab">
+        <table width="168" class="center" cellpadding="2" cellspacing="0">
+        <thead>
+        <tr>
+        <td colspan="2" class="center nowrap"><strong><?php echo __('Rename to'); ?></strong></td>
+        </tr>
+        </thead>
+        <tbody id="rename_to">
+        <tr>
+        <td width="58" class="nowrap"><?php echo __('New name'); ?></td>
+            <td width="102">
+                <input type="text" value="" id="e_rename"/>
+            </td>
+        </tr>
+        </tbody>
+        <tbody>
+        <tr>
+            <td colspan="2" class="center nowrap">
+                <input type="button" class="butt" name="Button"
+                    value="<?php echo __('OK'); ?>" onclick="edit('Rename')" />
+                <input type="button" class="butt" name="Button"
+                    value="<?php echo __('Cancel'); ?>"
+                    onclick="document.getElementById('query_rename_to').style.display = 'none';" />
+            </td>
+        </tr>
+        </tbody>
+        </table>
+    </td>
+    <td class="frams6"></td>
+</tr>
+<tr>
+    <td class="frams4"><div class="bor"></div></td>
+    <td class="frams7"></td>
+    <td class="frams3"></td>
+</tr>
+</tbody>
+</table>
+
+<table id="query_having" style="display:none;"
+    width="5%" cellpadding="0" cellspacing="0">
+<tbody>
+    <tr>
+        <td class="frams1" width="10px"></td>
+        <td class="frams5" width="99%" ></td>
+        <td class="frams2" width="10px"><div class="bor"></div></td>
+    </tr>
+<tr>
+    <td class="frams8"></td>
+    <td class="input_tab">
+    <table width="168" class="center" cellpadding="2" cellspacing="0">
+       <thead>
+        <tr>
+          <td colspan="2" class="center nowrap"><strong>HAVING</strong></td>
+        </tr>
+        </thead>
+        <tbody id="rename_to">
+        <tr>
+        <td width="58" class="nowrap"><?php echo __('Operator'); ?></td>
+            <td width="102"><select name="hoperator" id="hoperator">
+                    <option value="---" selected="selected">---</option>
+                    <option value="None" > None </option>
+                    <option value="sum" > SUM </option>
+                    <option value="min"> MIN </option>
+                    <option value="max"> MAX </option>
+                    <option value="avg"> AVG </option>
+                    <option value="count"> COUNT </option>
+                    </select>
+           </td></tr>
+        <tr>
+        <tr>
+        <td width="58" class="nowrap"><?php echo __('Operator'); ?></td>
+            <td width="102"><select name="hrel_opt" id="hrel_opt">
+                <option value="--" selected="selected"> -- </option>
+                    <option value="="> = </option>
+                    <option value=">"> > </option>
+                    <option value="<"> < </option>
+                    <option value=">="> >= </option>
+                    <option value="<="> <= </option>
+                    <option value="NOT"> NOT </option>
+                    <option value="IN"> IN </option>
+                    <option value="EXCEPT"> <?php echo __('Except'); ?> </option>
+                    <option value="NOT IN"> NOT IN </option>
+                </select>
+            </td>
+        </tr>
+        <tr>
+        <td class="nowrap"><?php echo __('Value'); ?>/<br /><?php echo __('subquery'); ?></td>
+            <td><textarea id="hQuery" value="" cols="18"></textarea>
+            </td>
+            </tr>
+         </tbody>
+        <tbody>
+        <tr>
+            <td colspan="2" class="center nowrap">
+                <input type="button" class="butt" name="Button"
+                    value="<?php echo __('OK'); ?>" onclick="edit('Having')" />
+                <input type="button" class="butt" name="Button"
+                    value="<?php echo __('Cancel'); ?>"
+                    onclick="document.getElementById('query_having').style.display = 'none';" />
+            </td>
+        </tr>
+        </tbody>
+        </table>
+    </td>
+    <td class="frams6"></td>
+</tr>
+<tr>
+    <td class="frams4"><div class="bor"></div></td>
+    <td class="frams7"></td>
+    <td class="frams3"></td>
+</tr>
+</tbody>
+</table>
+
+<table id="query_Aggregate" style="display:none;"
+    width="5%" cellpadding="0" cellspacing="0">
+<tbody>
+<tr>
+    <td class="frams1" width="10px"></td>
+    <td class="frams5" width="99%" ></td>
+    <td class="frams2" width="10px"><div class="bor"></div></td>
+</tr>
+<tr>
+    <td class="frams8"></td>
+    <td class="input_tab">
+        <table width="168" class="center" cellpadding="2" cellspacing="0">
+        <thead>
+        <tr>
+        <td colspan="2" class="center nowrap"><strong><?php echo __('Aggregate'); ?></strong></td>
+        </tr>
+        </thead>
+        <tbody>
+        <tr>
+        <td width="58" class="nowrap"><?php echo __('Operator'); ?></td>
+            <td width="102">
+                <select name="operator" id="e_operator">
+                    <option value="---" selected="selected">---</option>
+                    <option value="sum" > SUM </option>
+                    <option value="min"> MIN </option>
+                    <option value="max"> MAX </option>
+                       <option value="avg"> AVG </option>
+                    <option value="avg"> COUNT </option>
+                </select>
+           </td></tr>
+        </tbody>
+        <tbody>
+        <tr>
+            <td colspan="2" class="center nowrap">
+                <input type="button" class="butt" name="Button"
+                    value="<?php echo __('OK'); ?>" onclick="edit('Aggregate')" />
+                <input type="button" class="butt" name="Button"
+                    value="<?php echo __('Cancel'); ?>"
+                    onclick="document.getElementById('query_Aggregate').style.display = 'none';" />
+            </td>
+        </tr>
+        </tbody>
+        </table>
+    </td>
+    <td class="frams6"></td>
+</tr>
+<tr>
+    <td class="frams4"><div class="bor"></div></td>
+    <td class="frams7"></td>
+    <td class="frams3"></td>
+</tr>
+</tbody>
+</table>
+
+<table id="query_where" style="display:none;"
+    width="5%" cellpadding="0" cellspacing="0">
+<tbody>
+    <tr>
+        <td class="frams1" width="10px"></td>
+        <td class="frams5" width="99%" ></td>
+        <td class="frams2" width="10px"><div class="bor"></div></td>
+    </tr>
+<tr>
+    <td class="frams8"></td>
+    <td class="input_tab">
+    <table width="168" class="center" cellpadding="2" cellspacing="0">
+       <thead>
+        <tr>
+          <td colspan="2" class="center nowrap"><strong>WHERE</strong></td>
+        </tr>
+        </thead>
+        <tbody id="rename_to">
+        <tr>
+        <td width="58" class="nowrap"><?php echo __('Operator'); ?></td>
+            <td width="102"><select name="erel_opt" id="erel_opt">
+                <option value="--" selected="selected"> -- </option>
+                    <option value="=" > = </option>
+                    <option value=">"> > </option>
+                    <option value="<"> < </option>
+                    <option value=">="> >= </option>
+                    <option value="<="> <= </option>
+                    <option value="NOT"> NOT </option>
+                    <option value="IN"> IN </option>
+                    <option value="EXCEPT"> <?php echo __('Except'); ?> </option>
+                    <option value="NOT IN"> NOT IN </option>
+                </select>
+            </td>
+        </tr>
+        <tr>
+        <td class="nowrap"><?php echo __('Value'); ?>/<br /><?php echo __('subquery'); ?></td>
+            <td><textarea id="eQuery" value="" cols="18"></textarea>
+            </td>
+            </tr>
+         </tbody>
+        <tbody>
+        <tr>
+            <td colspan="2" class="center nowrap">
+                <input type="button" class="butt" name="Button"
+                    value="<?php echo __('OK'); ?>" onclick="edit('Where')" />
+                <input type="button" class="butt" name="Button"
+                    value="<?php echo __('Cancel'); ?>"
+                    onclick="document.getElementById('query_where').style.display = 'none';" />
+            </td>
+        </tr>
+        </tbody>
+        </table>
+    </td>
+    <td class="frams6"></td>
+</tr>
+<tr>
+    <td class="frams4"><div class="bor"></div></td>
+    <td class="frams7"></td>
+    <td class="frams3"></td>
+</tr>
+</tbody>
+</table>
+
+<?php
+if (! empty($_REQUEST['query'])) {
+    echo '<div class="panel">';
+    echo '<div style="clear:both;"></div>';
+    echo '<div id="ab"></div>';
+    echo '<div style="clear:both;"></div>';
+    echo '</div>';
+    echo '<a class="trigger" href="#">' . __('Active options') . '</a>';
+    echo '<div id="filter"></div>';
+    echo '<div id="box">';
+    echo '<span id="boxtitle"></span>';
+    echo '<form method="post" action="db_qbe.php">';
+    echo '<textarea cols="80" name="sql_query" id="textSqlquery" rows="15"></textarea><div id="tblfooter">';
+    echo '  <input type="submit" name="submit_sql" class="btn" />';
+    echo '  <input type="button" name="cancel" value="' . __('Cancel') . '" onclick="closebox()" class="btn" />';
+    echo PMA_generate_common_hidden_inputs($GLOBALS['db']);
+    echo '</div></p>';
+    echo '</form></div>';
+
+} ?>
+
+
+<!-- cache images -->
+<img src="<?php echo $_SESSION['PMA_Theme']->getImgPath('pmd/2leftarrow_m.png'); ?>" width="0" height="0" alt="" />
+<img src="<?php echo $_SESSION['PMA_Theme']->getImgPath('pmd/rightarrow1.png'); ?>" width="0" height="0" alt="" />
+<img src="<?php echo $_SESSION['PMA_Theme']->getImgPath('pmd/rightarrow2.png'); ?>" width="0" height="0" alt="" />
+<img src="<?php echo $_SESSION['PMA_Theme']->getImgPath('pmd/uparrow2_m.png'); ?>" width="0" height="0" alt="" />
+<div id="PMA_disable_floating_menubar"></div>
diff --git a/phpmyadmin/pmd_pdf.php b/phpmyadmin/pmd_pdf.php
new file mode 100644
index 0000000..c45eaa2
--- /dev/null
+++ b/phpmyadmin/pmd_pdf.php
@@ -0,0 +1,156 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ *
+ * @package PhpMyAdmin-Designer
+ */
+
+require_once './libraries/common.inc.php';
+require_once 'libraries/pmd_common.php';
+
+/**
+  * Sets globals from $_POST
+  */
+$post_params = array(
+    'db',
+    'mode',
+    'newpage',
+    'pdf_page_number',
+    'scale'
+);
+
+foreach ($post_params as $one_post_param) {
+    if (isset($_POST[$one_post_param])) {
+        $GLOBALS[$one_post_param] = $_POST[$one_post_param];
+    }
+}
+
+/**
+ * If called directly from the designer, first save the positions
+ */
+if (! isset($scale)) {
+    $no_die_save_pos = 1;
+    include_once 'pmd_save_pos.php';
+}
+
+if (isset($mode)) {
+    if ('create_export' != $mode && empty($pdf_page_number)) {
+        die("<script>alert('Pages not found!');history.go(-2);</script>");
+    }
+
+    $pmd_table = PMA_Util::backquote($GLOBALS['cfgRelation']['db']) . '.'
+        . PMA_Util::backquote($GLOBALS['cfgRelation']['designer_coords']);
+    $pma_table = PMA_Util::backquote($GLOBALS['cfgRelation']['db']) . '.'
+        . PMA_Util::backquote($cfgRelation['table_coords']);
+    $scale_q = PMA_Util::sqlAddSlashes($scale);
+
+    if ('create_export' == $mode) {
+        $pdf_page_number = PMA_REL_createPage($newpage, $cfgRelation, $db);
+        if ($pdf_page_number > 0) {
+            $message = PMA_Message::success(__('Page has been created'));
+            $mode = 'export';
+        } else {
+            $message = PMA_Message::error(__('Page creation failed'));
+        }
+    }
+
+    $pdf_page_number_q = PMA_Util::sqlAddSlashes($pdf_page_number);
+
+    if ('export' == $mode) {
+        $sql = "REPLACE INTO " . $pma_table
+            . " (db_name, table_name, pdf_page_number, x, y)"
+            . " SELECT db_name, table_name, " . $pdf_page_number_q . ","
+            . " ROUND(x/" . $scale_q . ") , ROUND(y/" . $scale_q . ") y"
+            . " FROM " . $pmd_table
+            . " WHERE db_name = '" . PMA_Util::sqlAddSlashes($db) . "'";
+
+        PMA_queryAsControlUser($sql, true, PMA_DBI_QUERY_STORE);
+    }
+
+    if ('import' == $mode) {
+        PMA_queryAsControlUser(
+            'UPDATE ' . $pma_table . ',' . $pmd_table .
+            ' SET ' . $pmd_table . '.`x`= ' . $pma_table . '.`x` * '. $scale_q . ',
+            ' . $pmd_table . '.`y`= ' . $pma_table . '.`y` * '. $scale_q .'
+            WHERE
+            ' . $pmd_table . '.`db_name`=' . $pma_table . '.`db_name`
+            AND
+            ' . $pmd_table . '.`table_name` = ' . $pma_table . '.`table_name`
+            AND
+            ' . $pmd_table . '.`db_name`=\''. PMA_Util::sqlAddSlashes($db) . '\'
+            AND pdf_page_number = ' . $pdf_page_number_q . ';',
+            true, PMA_DBI_QUERY_STORE
+        );
+    }
+}
+
+$response = PMA_Response::getInstance();
+$response->getFooter()->setMinimal();
+
+?>
+<br/>
+<div>
+<?php
+if (! empty($message)) {
+    $message->display();
+}
+?>
+  <form name="form1" method="post" action="pmd_pdf.php">
+<?php
+echo PMA_generate_common_hidden_inputs($db);
+echo '<div>';
+echo '<fieldset><legend>' . __('Import/Export coordinates for PDF schema') . '</legend>';
+
+$choices = array();
+
+$table_info_result = PMA_queryAsControlUser(
+    'SELECT * FROM ' . PMA_Util::backquote($GLOBALS['cfgRelation']['db'])
+    . '.' . PMA_Util::backquote($cfgRelation['pdf_pages'])
+    . ' WHERE db_name = \'' . PMA_Util::sqlAddSlashes($db) . '\''
+);
+
+if (PMA_DBI_num_rows($table_info_result) > 0) {
+    echo '<p>' . __('Page') . ':';
+    echo '<select name="pdf_page_number">';
+
+    while ($page = PMA_DBI_fetch_assoc($table_info_result)) {
+        echo '<option value="' . $page['page_nr'] . '">';
+        echo htmlspecialchars($page['page_descr']);
+        echo '</option>';
+    }
+    echo '</select>';
+    echo '</p>';
+    $choices['import'] = __('Import from selected page');
+    $choices['export'] = __('Export to selected page');
+}
+$choices['create_export'] = __('Create a page and export to it');
+
+if (1 == count($choices)) {
+    echo $choices['create_export'];
+    echo '<input type="hidden" name="mode" value="create_export" />';
+} else {
+    echo PMA_Util::getRadioFields(
+        'mode', $choices, $checked_choice = '', $line_break = true,
+        $escape_label = false, $class = ''
+    );
+}
+echo '<br />';
+echo '<label for="newpage">' . __('New page name: ') . '</label>';
+echo '<input id="newpage" type="text" name="newpage" />';
+
+echo '<p>' . __('Export/Import to scale') . ':';
+?>
+      <select name="scale">
+        <option value="1">1:1</option>
+        <option value="2">1:2</option>
+        <option value="3" selected="selected">1:3 (<?php echo __('recommended'); ?>)</option>
+        <option value="4">1:4</option>
+        <option value="5">1:5</option>
+      </select>
+      </p>
+      <input type="submit" value="<?php echo __('Go'); ?>"/>
+    </fieldset>
+    </div>
+  </form>
+</div>
+
diff --git a/phpmyadmin/pmd_relation_new.php b/phpmyadmin/pmd_relation_new.php
new file mode 100644
index 0000000..27572f1
--- /dev/null
+++ b/phpmyadmin/pmd_relation_new.php
@@ -0,0 +1,119 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ *
+ * @package PhpMyAdmin-Designer
+ */
+
+/**
+ *
+ */
+require_once './libraries/common.inc.php';
+
+PMA_Response::getInstance()->disable();
+
+require_once 'libraries/pmd_common.php';
+$die_save_pos = 0;
+require_once 'pmd_save_pos.php';
+extract($_POST, EXTR_SKIP);
+
+$tables = PMA_DBI_get_tables_full($db, $T1);
+$type_T1 = strtoupper($tables[$T1]['ENGINE']);
+$tables = PMA_DBI_get_tables_full($db, $T2);
+$type_T2 = strtoupper($tables[$T2]['ENGINE']);
+
+// native foreign key
+if (PMA_Util::isForeignKeySupported($type_T1)
+    && PMA_Util::isForeignKeySupported($type_T2)
+    && $type_T1 == $type_T2
+) {
+    // relation exists?
+    $existrel_foreign = PMA_getForeigners($db, $T2, '', 'foreign');
+    if (isset($existrel_foreign[$F2])
+        && isset($existrel_foreign[$F2]['constraint'])
+    ) {
+         PMD_return_new(0, __('Error: relation already exists.'));
+    }
+    // note: in InnoDB, the index does not requires to be on a PRIMARY
+    // or UNIQUE key
+    // improve: check all other requirements for InnoDB relations
+    $result = PMA_DBI_query(
+        'SHOW INDEX FROM ' . PMA_Util::backquote($db)
+        . '.' . PMA_Util::backquote($T1) . ';'
+    );
+    $index_array1 = array(); // will be use to emphasis prim. keys in the table view
+    while ($row = PMA_DBI_fetch_assoc($result)) {
+        $index_array1[$row['Column_name']] = 1;
+    }
+    PMA_DBI_free_result($result);
+
+    $result = PMA_DBI_query(
+        'SHOW INDEX FROM ' . PMA_Util::backquote($db)
+        . '.' . PMA_Util::backquote($T2) . ';'
+    );
+    $index_array2 = array(); // will be used to emphasis prim. keys in the table view
+    while ($row = PMA_DBI_fetch_assoc($result)) {
+        $index_array2[$row['Column_name']] = 1;
+    }
+    PMA_DBI_free_result($result);
+
+    if (! empty($index_array1[$F1]) && ! empty($index_array2[$F2])) {
+        $upd_query  = 'ALTER TABLE ' . PMA_Util::backquote($db)
+            . '.' . PMA_Util::backquote($T2)
+            . ' ADD FOREIGN KEY ('
+            . PMA_Util::backquote($F2) . ')'
+            . ' REFERENCES '
+            . PMA_Util::backquote($db) . '.'
+            . PMA_Util::backquote($T1) . '('
+            . PMA_Util::backquote($F1) . ')';
+
+        if ($on_delete != 'nix') {
+            $upd_query   .= ' ON DELETE ' . $on_delete;
+        }
+        if ($on_update != 'nix') {
+            $upd_query   .= ' ON UPDATE ' . $on_update;
+        }
+        $upd_query .= ';';
+        PMA_DBI_try_query($upd_query) or PMD_return_new(0, __('Error: Relation not added.'));
+        PMD_return_new(1, __('FOREIGN KEY relation added'));
+    }
+} else { // internal (pmadb) relation
+    if ($GLOBALS['cfgRelation']['relwork'] == false) {
+        PMD_return_new(0, __('General relation features') . ':' . __('Disabled'));
+    } else {
+        // no need to recheck if the keys are primary or unique at this point,
+        // this was checked on the interface part
+
+        $q  = 'INSERT INTO ' . PMA_Util::backquote($GLOBALS['cfgRelation']['db']) . '.' . PMA_Util::backquote($cfgRelation['relation'])
+                            . '(master_db, master_table, master_field, foreign_db, foreign_table, foreign_field)'
+                            . ' values('
+                            . '\'' . PMA_Util::sqlAddSlashes($db) . '\', '
+                            . '\'' . PMA_Util::sqlAddSlashes($T2) . '\', '
+                            . '\'' . PMA_Util::sqlAddSlashes($F2) . '\', '
+                            . '\'' . PMA_Util::sqlAddSlashes($db) . '\', '
+                            . '\'' . PMA_Util::sqlAddSlashes($T1) . '\','
+                            . '\'' . PMA_Util::sqlAddSlashes($F1) . '\')';
+
+        if (PMA_queryAsControlUser($q, false, PMA_DBI_QUERY_STORE)) {
+            PMD_return_new(1, __('Internal relation added'));
+        } else {
+            PMD_return_new(0, __('Error: Relation not added.'));
+        }
+    }
+}
+
+function PMD_return_new($b,$ret)
+{
+    global $db,$T1,$F1,$T2,$F2;
+    header("Content-Type: text/xml; charset=utf-8");
+    header("Cache-Control: no-cache");
+    die('<root act="relation_new" return="'.$ret.'" b="'.$b.
+    '" DB1="'.urlencode($db).
+    '" T1="'.urlencode($T1).
+    '" F1="'.urlencode($F1).
+    '" DB2="'.urlencode($db).
+    '" T2="'.urlencode($T2).
+    '" F2="'.urlencode($F2).
+    '"></root>');
+}
+?>
diff --git a/phpmyadmin/pmd_relation_upd.php b/phpmyadmin/pmd_relation_upd.php
new file mode 100644
index 0000000..0599fe8
--- /dev/null
+++ b/phpmyadmin/pmd_relation_upd.php
@@ -0,0 +1,75 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ *
+ * @package PhpMyAdmin-Designer
+ */
+
+/**
+ *
+ */
+require_once './libraries/common.inc.php';
+
+PMA_Response::getInstance()->disable();
+
+require_once 'libraries/pmd_common.php';
+extract($_POST, EXTR_SKIP);
+extract($_GET, EXTR_SKIP);
+$die_save_pos = 0;
+require_once 'pmd_save_pos.php';
+list($DB1, $T1) = explode(".", $T1);
+list($DB2, $T2) = explode(".", $T2);
+
+$tables = PMA_DBI_get_tables_full($db, $T1);
+$type_T1 = strtoupper($tables[$T1]['ENGINE']);
+$tables = PMA_DBI_get_tables_full($db, $T2);
+$type_T2 = strtoupper($tables[$T2]['ENGINE']);
+
+$try_to_delete_internal_relation = false;
+
+if (PMA_Util::isForeignKeySupported($type_T1)
+    && PMA_Util::isForeignKeySupported($type_T2)
+    && $type_T1 == $type_T2
+) {
+    // InnoDB
+    $existrel_foreign = PMA_getForeigners($DB2, $T2, '', 'foreign');
+
+    if (isset($existrel_foreign[$F2]['constraint'])) {
+        $upd_query  = 'ALTER TABLE ' . PMA_Util::backquote($DB2)
+            . '.' . PMA_Util::backquote($T2) . ' DROP FOREIGN KEY '
+            . PMA_Util::backquote($existrel_foreign[$F2]['constraint'])
+            . ';';
+        $upd_rs     = PMA_DBI_query($upd_query);
+    } else {
+        // there can be an internal relation even if InnoDB
+        $try_to_delete_internal_relation = true;
+    }
+} else {
+    $try_to_delete_internal_relation = true;
+}
+if ($try_to_delete_internal_relation) {
+    // internal relations
+    PMA_queryAsControlUser(
+        'DELETE FROM '
+        . PMA_Util::backquote($GLOBALS['cfgRelation']['db']) . '.'
+        . $cfg['Server']['relation'].' WHERE '
+        . 'master_db = \'' . PMA_Util::sqlAddSlashes($DB2) . '\''
+        . ' AND master_table = \'' . PMA_Util::sqlAddSlashes($T2) . '\''
+        . ' AND master_field = \'' . PMA_Util::sqlAddSlashes($F2) . '\''
+        . ' AND foreign_db = \'' . PMA_Util::sqlAddSlashes($DB1) . '\''
+        . ' AND foreign_table = \'' . PMA_Util::sqlAddSlashes($T1) . '\''
+        . ' AND foreign_field = \'' . PMA_Util::sqlAddSlashes($F1) . '\'',
+        false,
+        PMA_DBI_QUERY_STORE
+    );
+}
+PMD_return_upd(1, __('Relation deleted'));
+
+function PMD_return_upd($b, $ret)
+{
+    global $K;
+    header("Content-Type: text/xml; charset=utf-8");
+    header("Cache-Control: no-cache");
+    die('<root act="relation_upd" return="'.$ret.'" b="'.$b.'" K="'.$K.'"></root>');
+}
+?>
diff --git a/phpmyadmin/pmd_save_pos.php b/phpmyadmin/pmd_save_pos.php
new file mode 100644
index 0000000..bb97f31
--- /dev/null
+++ b/phpmyadmin/pmd_save_pos.php
@@ -0,0 +1,84 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ *
+ * @package PhpMyAdmin-Designer
+ */
+
+/**
+ *
+ */
+require_once './libraries/common.inc.php';
+require_once 'libraries/pmd_common.php';
+
+$cfgRelation = PMA_getRelationsParam();
+
+if (! $cfgRelation['designerwork']) {
+    PMD_err_sav();
+}
+
+/**
+ * Sets globals from $_POST
+ */
+$post_params = array(
+    'IS_AJAX',
+    'die_save_pos',
+    'server',
+    't_h',
+    't_v',
+    't_x',
+    't_y'
+);
+
+foreach ($post_params as $one_post_param) {
+    if (isset($_POST[$one_post_param])) {
+        $GLOBALS[$one_post_param] = $_POST[$one_post_param];
+    }
+}
+
+foreach ($t_x as $key => $value) {
+    // table name decode (post PDF exp/imp)
+    $KEY = empty($IS_AJAX) ? urldecode($key) : $key;
+    list($DB,$TAB) = explode(".", $KEY);
+    PMA_queryAsControlUser(
+        'DELETE FROM ' . PMA_Util::backquote($GLOBALS['cfgRelation']['db'])
+        . '.' . PMA_Util::backquote($GLOBALS['cfgRelation']['designer_coords'])
+        . ' WHERE `db_name` = \'' . PMA_Util::sqlAddSlashes($DB) . '\''
+        . ' AND `table_name` = \'' . PMA_Util::sqlAddSlashes($TAB) . '\'',
+        true, PMA_DBI_QUERY_STORE
+    );
+
+    PMA_queryAsControlUser(
+        'INSERT INTO ' . PMA_Util::backquote($GLOBALS['cfgRelation']['db'])
+        . '.' . PMA_Util::backquote($GLOBALS['cfgRelation']['designer_coords'])
+        . ' (db_name, table_name, x, y, v, h)'
+        . ' VALUES ('
+        . '\'' . PMA_Util::sqlAddSlashes($DB) . '\', '
+        . '\'' . PMA_Util::sqlAddSlashes($TAB) . '\', '
+        . '\'' . PMA_Util::sqlAddSlashes($t_x[$key]) . '\', '
+        . '\'' . PMA_Util::sqlAddSlashes($t_y[$key]) . '\', '
+        . '\'' . PMA_Util::sqlAddSlashes($t_v[$key]) . '\', '
+        . '\'' . PMA_Util::sqlAddSlashes($t_h[$key]) . '\')',
+        true, PMA_DBI_QUERY_STORE
+    );
+}
+//----------------------------------------------------------------------------
+
+function PMD_err_sav()
+{
+    global $die_save_pos; // if this file included
+    if (! empty($die_save_pos)) {
+        header("Content-Type: text/xml; charset=utf-8");
+        header("Cache-Control: no-cache");
+        die('<root act="save_pos" return="' . __('Error saving coordinates for Designer.') . '"></root>');
+    }
+}
+
+if (! empty($die_save_pos)) {
+    header("Content-Type: text/xml; charset=utf-8");
+    header("Cache-Control: no-cache");
+    ?>
+    <root act='save_pos' return='<?php echo __('Modifications have been saved'); ?>'></root>
+    <?php
+}
+?>
diff --git a/phpmyadmin/prefs_forms.php b/phpmyadmin/prefs_forms.php
new file mode 100644
index 0000000..52d25d9
--- /dev/null
+++ b/phpmyadmin/prefs_forms.php
@@ -0,0 +1,91 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * User preferences page
+ *
+ * @package PhpMyAdmin
+ */
+
+/**
+ * Gets some core libraries and displays a top message if required
+ */
+require_once 'libraries/common.inc.php';
+require_once 'libraries/user_preferences.lib.php';
+require_once 'libraries/config/config_functions.lib.php';
+require_once 'libraries/config/messages.inc.php';
+require_once 'libraries/config/ConfigFile.class.php';
+require_once 'libraries/config/Form.class.php';
+require_once 'libraries/config/FormDisplay.class.php';
+require 'libraries/config/user_preferences.forms.php';
+
+PMA_userprefsPageInit();
+
+// handle form processing
+
+$form_param = filter_input(INPUT_GET, 'form');
+if (! isset($forms[$form_param])) {
+    $forms_keys = array_keys($forms);
+    $form_param = array_shift($forms_keys);
+}
+
+$form_display = new FormDisplay();
+foreach ($forms[$form_param] as $form_name => $form) {
+    // skip Developer form if no setting is available
+    if ($form_name == 'Developer' && !$GLOBALS['cfg']['UserprefsDeveloperTab']) {
+        continue;
+    }
+    $form_display->registerForm($form_name, $form, 1);
+}
+
+if (isset($_POST['revert'])) {
+    // revert erroneous fields to their default values
+    $form_display->fixErrors();
+    // redirect
+    $url_params = array('form' => $form_param);
+    PMA_sendHeaderLocation(
+        $cfg['PmaAbsoluteUri'] . 'prefs_forms.php'
+        . PMA_generate_common_url($url_params, '&')
+    );
+    exit;
+}
+
+$error = null;
+if ($form_display->process(false) && !$form_display->hasErrors()) {
+    // save settings
+    $result = PMA_saveUserprefs(ConfigFile::getInstance()->getConfigArray());
+    if ($result === true) {
+        // reload config
+        $GLOBALS['PMA_Config']->loadUserPreferences();
+        $hash = ltrim(filter_input(INPUT_POST, 'tab_hash'), '#');
+        PMA_userprefsRedirect(
+            'prefs_forms.php',
+            array('form' => $form_param),
+            $hash
+        );
+        exit;
+    } else {
+        $error = $result;
+    }
+}
+
+// display forms
+$response = PMA_Response::getInstance();
+$header   = $response->getHeader();
+$scripts  = $header->getScripts();
+$scripts->addFile('config.js');
+
+require 'libraries/user_preferences.inc.php';
+if ($error) {
+    $error->display();
+}
+if ($form_display->hasErrors()) {
+    // form has errors
+    ?>
+    <div class="error config-form">
+        <b><?php echo __('Cannot save settings, submitted form contains errors') ?></b>
+        <?php $form_display->displayErrors(); ?>
+    </div>
+    <?php
+}
+$form_display->display(true, true);
+?>
diff --git a/phpmyadmin/prefs_manage.php b/phpmyadmin/prefs_manage.php
new file mode 100644
index 0000000..e85ab3d
--- /dev/null
+++ b/phpmyadmin/prefs_manage.php
@@ -0,0 +1,331 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * User preferences management page
+ *
+ * @package PhpMyAdmin
+ */
+
+/**
+ * Gets some core libraries and displays a top message if required
+ */
+require_once 'libraries/common.inc.php';
+require_once 'libraries/user_preferences.lib.php';
+require_once 'libraries/config/config_functions.lib.php';
+require_once 'libraries/config/messages.inc.php';
+require_once 'libraries/config/ConfigFile.class.php';
+require_once 'libraries/config/Form.class.php';
+require_once 'libraries/config/FormDisplay.class.php';
+require 'libraries/config/user_preferences.forms.php';
+
+PMA_userprefsPageInit();
+
+$error = '';
+if (isset($_POST['submit_export'])
+    && filter_input(INPUT_POST, 'export_type') == 'text_file'
+) {
+    // export to JSON file
+    PMA_Response::getInstance()->disable();
+    $filename = 'phpMyAdmin-config-' . urlencode(PMA_getenv('HTTP_HOST')) . '.json';
+    PMA_downloadHeader($filename, 'application/json');
+    $settings = PMA_loadUserprefs();
+    echo json_encode($settings['config_data']);
+    exit;
+} else if (isset($_POST['submit_get_json'])) {
+    $settings = PMA_loadUserprefs();
+    $response = PMA_Response::getInstance();
+    $response->addJSON('prefs', json_encode($settings['config_data']));
+    $response->addJSON('mtime', $settings['mtime']);
+    exit;
+} else if (isset($_POST['submit_import'])) {
+    // load from JSON file
+    $json = '';
+    if (filter_input(INPUT_POST, 'import_type') == 'text_file'
+        && isset($_FILES['import_file'])
+        && $_FILES['import_file']['error'] == UPLOAD_ERR_OK
+        && is_uploaded_file($_FILES['import_file']['tmp_name'])
+    ) {
+        // read JSON from uploaded file
+        $open_basedir = @ini_get('open_basedir');
+        $file_to_unlink = '';
+        $import_file = $_FILES['import_file']['tmp_name'];
+
+        // If we are on a server with open_basedir, we must move the file
+        // before opening it. The doc explains how to create the "./tmp"
+        // directory
+        if (!empty($open_basedir)) {
+            $tmp_subdir = (PMA_IS_WINDOWS ? '.\\tmp\\' : 'tmp/');
+            if (is_writable($tmp_subdir)) {
+                $import_file_new = tempnam($tmp_subdir, 'prefs');
+                if (move_uploaded_file($import_file, $import_file_new)) {
+                    $import_file = $import_file_new;
+                    $file_to_unlink = $import_file_new;
+                }
+            }
+        }
+        $json = file_get_contents($import_file);
+        if ($file_to_unlink) {
+            unlink($file_to_unlink);
+        }
+    } else {
+        // read from POST value (json)
+        $json = filter_input(INPUT_POST, 'json');
+    }
+
+    // hide header message
+    $_SESSION['userprefs_autoload'] = true;
+
+    $config = json_decode($json, true);
+    $return_url = filter_input(INPUT_POST, 'return_url');
+    if (! is_array($config)) {
+        $error = __('Could not import configuration');
+    } else {
+        // sanitize input values: treat them as though
+        // they came from HTTP POST request
+        $form_display = new FormDisplay();
+        foreach ($forms as $formset_id => $formset) {
+            foreach ($formset as $form_name => $form) {
+                $form_display->registerForm($formset_id . ': ' . $form_name, $form);
+            }
+        }
+        $cf = ConfigFile::getInstance();
+        $new_config = $cf->getFlatDefaultConfig();
+        if (!empty($_POST['import_merge'])) {
+            $new_config = array_merge($new_config, $cf->getConfigArray());
+        }
+        $new_config = array_merge($new_config, $config);
+        $_POST_bak = $_POST;
+        foreach ($new_config as $k => $v) {
+            $_POST[str_replace('/', '-', $k)] = $v;
+        }
+        $cf->resetConfigData();
+        $all_ok = $form_display->process(true, false);
+        $all_ok = $all_ok && !$form_display->hasErrors();
+        $_POST = $_POST_bak;
+
+        if (!$all_ok && isset($_POST['fix_errors'])) {
+            $form_display->fixErrors();
+            $all_ok = true;
+        }
+        if (!$all_ok) {
+            // mimic original form and post json in a hidden field
+            include 'libraries/user_preferences.inc.php';
+            $msg = PMA_Message::error(__('Configuration contains incorrect data for some fields.'));
+            $msg->display();
+            echo '<div class="config-form">';
+            $form_display->displayErrors();
+            echo '</div>';
+            ?>
+            <form action="prefs_manage.php" method="post">
+                <?php echo PMA_generate_common_hidden_inputs() . "\n"; ?>
+                <input type="hidden" name="json" value="<?php echo htmlspecialchars($json) ?>" />
+                <input type="hidden" name="fix_errors" value="1" />
+                <?php if (! empty($_POST['import_merge'])) { ?>
+                <input type="hidden" name="import_merge" value="1" />
+                <?php } ?>
+                <?php if ($return_url) { ?>
+                <input type="hidden" name="return_url" value="<?php echo htmlspecialchars($return_url) ?>" />
+                <?php } ?>
+                <p><?php echo __('Do you want to import remaining settings?') ?></p>
+                <input type="submit" name="submit_import" value="<?php echo __('Yes') ?>" />
+                <input type="submit" name="submit_ignore" value="<?php echo __('No') ?>" />
+            </form>
+            <?php
+            exit;
+        }
+
+        // check for ThemeDefault and fontsize
+        $params = array();
+        if (isset($config['ThemeDefault'])
+            && $_SESSION['PMA_Theme_Manager']->theme->getId() != $config['ThemeDefault']
+            && $_SESSION['PMA_Theme_Manager']->checkTheme($config['ThemeDefault'])
+        ) {
+            $_SESSION['PMA_Theme_Manager']->setActiveTheme($config['ThemeDefault']);
+            $_SESSION['PMA_Theme_Manager']->setThemeCookie();
+        }
+        if (isset($config['fontsize'])
+            && $config['fontsize'] != $GLOBALS['PMA_Config']->get('fontsize')
+        ) {
+            $params['set_fontsize'] = $config['fontsize'];
+        }
+        if (isset($config['lang'])
+            && $config['lang'] != $GLOBALS['lang']
+        ) {
+            $params['lang'] = $config['lang'];
+        }
+        if (isset($config['collation_connection'])
+            && $config['collation_connection'] != $GLOBALS['collation_connection']
+        ) {
+            $params['collation_connection'] = $config['collation_connection'];
+        }
+
+        // save settings
+        $result = PMA_saveUserprefs($cf->getConfigArray());
+        if ($result === true) {
+            if ($return_url) {
+                $query = explode('&', parse_url($return_url, PHP_URL_QUERY));
+                $return_url = parse_url($return_url, PHP_URL_PATH);
+                foreach ($query as $q) {
+                    $pos = strpos($q, '=');
+                    $k = substr($q, 0, $pos);
+                    if ($k == 'token') {
+                        continue;
+                    }
+                    $params[$k] = substr($q, $pos+1);
+                }
+            } else {
+                $return_url = 'prefs_manage.php';
+            }
+            // reload config
+            $GLOBALS['PMA_Config']->loadUserPreferences();
+            PMA_userprefsRedirect($return_url, $params);
+            exit;
+        } else {
+            $error = $result;
+        }
+    }
+} else if (isset($_POST['submit_clear'])) {
+    $result = PMA_saveUserprefs(array());
+    if ($result === true) {
+        $params = array();
+        if ($_SESSION['PMA_Theme_Manager']->theme->getId() != 'original') {
+            $GLOBALS['PMA_Config']->removeCookie(
+                $_SESSION['PMA_Theme_Manager']->getThemeCookieName()
+            );
+            unset($_SESSION['PMA_Theme_Manager']);
+            unset($_SESSION['PMA_Theme']);
+        }
+        if ($GLOBALS['PMA_Config']->get('fontsize') != '82%') {
+            $GLOBALS['PMA_Config']->removeCookie('pma_fontsize');
+        }
+        $GLOBALS['PMA_Config']->removeCookie('pma_collaction_connection');
+        $GLOBALS['PMA_Config']->removeCookie('pma_lang');
+        PMA_userprefsRedirect('prefs_manage.php', $params);
+        exit;
+    } else {
+        $error = $result;
+    }
+    exit;
+}
+
+$response = PMA_Response::getInstance();
+$header   = $response->getHeader();
+$scripts = $header->getScripts();
+$scripts->addFile('config.js');
+
+require 'libraries/user_preferences.inc.php';
+if ($error) {
+    if (!$error instanceof PMA_Message) {
+        $error = PMA_Message::error($error);
+    }
+    $error->display();
+}
+?>
+<script type="text/javascript">
+<?php
+PMA_printJsValue("PMA_messages['strSavedOn']", __('Saved on: @DATE@'));
+?>
+</script>
+<div id="maincontainer">
+    <div id="main_pane_left">
+        <div class="group">
+            <h2><?php echo __('Import') ?></h2>
+            <form class="group-cnt prefs-form disableAjax" name="prefs_import" action="prefs_manage.php" method="post" enctype="multipart/form-data">
+                <?php
+                echo PMA_Util::generateHiddenMaxFileSize($max_upload_size) . "\n";
+                echo PMA_generate_common_hidden_inputs() . "\n";
+                ?>
+                <input type="hidden" name="json" value="" />
+                <input type="radio" id="import_text_file" name="import_type" value="text_file" checked="checked" />
+                <label for="import_text_file"><?php echo __('Import from file') ?></label>
+                <div id="opts_import_text_file" class="prefsmanage_opts">
+                    <label for="input_import_file"><?php echo __('Browse your computer:'); ?></label>
+                    <input type="file" name="import_file" id="input_import_file" />
+                </div>
+                <input type="radio" id="import_local_storage" name="import_type" value="local_storage" disabled="disabled" />
+                <label for="import_local_storage"><?php echo __('Import from browser\'s storage') ?></label>
+                <div id="opts_import_local_storage" class="prefsmanage_opts disabled">
+                    <div class="localStorage-supported">
+                        <?php echo __('Settings will be imported from your browser\'s local storage.') ?>
+                        <br />
+                        <div class="localStorage-exists">
+                            <?php echo __('Saved on: @DATE@') ?>
+                        </div>
+                        <div class="localStorage-empty">
+                            <?php  PMA_Message::notice(__('You have no saved settings!'))->display() ?>
+                        </div>
+                    </div>
+                    <div class="localStorage-unsupported">
+                        <?php PMA_Message::notice(__('This feature is not supported by your web browser'))->display() ?>
+                    </div>
+                </div>
+
+                <input type="checkbox" id="import_merge" name="import_merge" />
+                <label for="import_merge"><?php echo __('Merge with current configuration') ?></label>
+                <br /><br />
+                <input type="submit" name="submit_import" value="<?php echo __('Go'); ?>" />
+            </form>
+        </div>
+        <?php
+        if (file_exists('setup/index.php')) {
+            // show only if setup script is available, allows to disable this message
+            // by simply removing setup directory
+        ?>
+        <div class="group">
+            <h2><?php echo __('More settings') ?></h2>
+            <div class="group-cnt">
+                <?php
+                echo sprintf(__('You can set more settings by modifying config.inc.php, eg. by using %sSetup script%s.'), '<a href="setup/index.php" target="_blank">', '</a>');
+                echo PMA_Util::showDocu('setup', 'setup-script');
+                ?>
+            </div>
+        </div>
+        <?php
+        }
+        ?>
+    </div>
+    <div id="main_pane_right">
+        <div class="group">
+            <h2><?php echo __('Export') ?></h2>
+            <div class="click-hide-message group-cnt" style="display:none">
+                <?php
+                PMA_Message::rawSuccess(__('Configuration has been saved'))->display();
+                ?>
+            </div>
+            <form class="group-cnt prefs-form disableAjax" name="prefs_export" action="prefs_manage.php" method="post">
+            <?php echo PMA_generate_common_hidden_inputs() . "\n" ?>
+                <div style="padding-bottom:0.5em">
+                    <input type="radio" id="export_text_file" name="export_type" value="text_file" checked="checked" />
+                    <label for="export_text_file"><?php echo __('Save as file') ?></label>
+                    <br />
+                    <input type="radio" id="export_local_storage" name="export_type" value="local_storage" disabled="disabled" />
+                    <label for="export_local_storage"><?php echo __('Save to browser\'s storage') ?></label>
+                </div>
+                <div id="opts_export_local_storage" class="prefsmanage_opts disabled">
+                    <span class="localStorage-supported">
+                        <?php echo __('Settings will be saved in your browser\'s local storage.') ?>
+                        <span class="localStorage-exists">
+                            <br /><b><?php echo __('Existing settings will be overwritten!') ?></b>
+                        </span>
+                    </span>
+                    <div class="localStorage-unsupported">
+                        <?php PMA_Message::notice(__('This feature is not supported by your web browser'))->display() ?>
+                    </div>
+                </div>
+                <br />
+                <input type="submit" name="submit_export" value="<?php echo __('Go'); ?>" />
+            </form>
+        </div>
+        <div class="group">
+            <h2><?php echo __('Reset') ?></h2>
+            <form class="group-cnt prefs-form disableAjax" name="prefs_reset" action="prefs_manage.php" method="post">
+            <?php echo PMA_generate_common_hidden_inputs() . "\n" ?>
+                <?php echo __('You can reset all your settings and restore them to default values.') ?>
+                <br /><br />
+                <input type="submit" name="submit_clear" value="<?php echo __('Reset') ?>" />
+            </form>
+
+        </div>
+    </div>
+    <br class="clearfloat" />
+</div>
diff --git a/phpmyadmin/print.css b/phpmyadmin/print.css
new file mode 100644
index 0000000..1aa2f98
--- /dev/null
+++ b/phpmyadmin/print.css
@@ -0,0 +1,92 @@
+.nowrap {
+    white-space: nowrap;
+}
+
+.hide {
+    display: none;
+}
+
+body, table, th, td {
+    color:             #000;
+    background-color:  #fff;
+}
+
+img {
+    border: 0;
+}
+
+table, th, td {
+    border: .1em solid #000;
+}
+
+table {
+    border-collapse:   collapse;
+    border-spacing:    0;
+}
+
+th, td {
+    padding:           0.2em;
+}
+
+th {
+    font-weight:       bold;
+    background-color:  #e5e5e5;
+}
+
+th.vtop, td.vtop {
+    vertical-align: top;
+}
+
+th.vbottom, td.vbottom {
+    vertical-align: bottom;
+}
+
+ at media print {
+    .print_ignore {
+        display: none;
+    }
+
+    .nowrap {
+        white-space: nowrap;
+    }
+
+    .hide {
+        display: none;
+    }
+
+    body, table, th, td {
+        color:             #000;
+        background-color:  #fff;
+    }
+
+    img {
+        border: 0;
+    }
+
+    table, th, td {
+        border: .1em solid #000;
+    }
+
+    table {
+        border-collapse:   collapse;
+        border-spacing:    0;
+    }
+
+    th, td {
+        padding:           0.2em;
+    }
+
+    th {
+        font-weight:       bold;
+        background-color:  #e5e5e5;
+    }
+
+    th.vtop, td.vtop {
+        vertical-align: top;
+    }
+
+    th.vbottom, td.vbottom {
+        vertical-align: bottom;
+    }
+}
+
diff --git a/phpmyadmin/querywindow.php b/phpmyadmin/querywindow.php
new file mode 100644
index 0000000..1c5e82c
--- /dev/null
+++ b/phpmyadmin/querywindow.php
@@ -0,0 +1,207 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * this file is register_globals safe
+ *
+ * @todo    move JavaScript out of here into .js files
+ * @package PhpMyAdmin
+ */
+
+/**
+ *
+ */
+require_once 'libraries/common.inc.php';
+
+$is_superuser = PMA_isSuperuser();
+
+/**
+ * Gets a core script and starts output buffering work
+ */
+require_once 'libraries/sql_query_form.lib.php';
+
+/**
+ * load relation params
+ */
+$cfgRelation = PMA_getRelationsParam();
+
+/**
+ * load bookmark support
+ */
+require_once 'libraries/bookmark.lib.php';
+
+$querydisplay_tabs = array(
+    'sql',
+    'files',
+    'history',
+    'full',
+);
+
+if (isset($_REQUEST['querydisplay_tab'])
+    && in_array($_REQUEST['querydisplay_tab'], $querydisplay_tabs)
+) {
+    $querydisplay_tab = $_REQUEST['querydisplay_tab'];
+} else {
+    $querydisplay_tab = $GLOBALS['cfg']['QueryWindowDefTab'];
+}
+
+/**
+ * $_REQUEST['no_js'] is set if open new window by JavaScript failed
+ * so this page is loaded in main frame
+ */
+$no_js = PMA_ifSetOr($_REQUEST['no_js'], false);
+
+if ($no_js) {
+    $querydisplay_tab = 'full';
+    $tabs = false;
+} else {
+    $tabs = array();
+    $tabs['sql']['icon'] = 'b_sql.png';
+    $tabs['sql']['text'] = __('SQL');
+    $tabs['sql']['fragment'] = '#';
+    $tabs['sql']['attr'] = 'onclick="PMA_querywindowCommit(\'sql\');return false;"';
+    $tabs['sql']['active'] = (bool) ($querydisplay_tab == 'sql');
+    $tabs['import']['icon'] = 'b_import.png';
+    $tabs['import']['text'] = __('Import files');
+    $tabs['import']['fragment'] = '#';
+    $tabs['import']['attr']
+        = 'onclick="PMA_querywindowCommit(\'files\');return false;"';
+    $tabs['import']['active'] = (bool) ($querydisplay_tab == 'files');
+    $tabs['history']['icon'] = 'b_bookmark.png';
+    $tabs['history']['text'] = __('SQL history');
+    $tabs['history']['fragment'] = '#';
+    $tabs['history']['attr']
+        = 'onclick="PMA_querywindowCommit(\'history\');return false;"';
+    $tabs['history']['active'] = (bool) ($querydisplay_tab == 'history');
+
+    if ($GLOBALS['cfg']['QueryWindowDefTab'] == 'full') {
+        $tabs['all']['text'] = __('All');
+        $tabs['all']['fragment'] = '#';
+        $tabs['all']['attr']
+            = 'onclick="PMA_querywindowCommit(\'full\');return false;"';
+        $tabs['all']['active'] = (bool) ($querydisplay_tab == 'full');
+    }
+}
+
+$titles['Change'] = PMA_Util::getIcon('b_edit.png', __('Change'));
+$url_query = PMA_generate_common_url($db, $table);
+
+if (! empty($sql_query)) {
+    $show_query = 1;
+}
+
+if ($no_js) {
+    // ... we redirect to appropriate query sql page
+    // works only full if $db and $table is also stored/grabbed from $_COOKIE
+    if (strlen($table)) {
+        include 'tbl_sql.php';
+    } elseif (strlen($db)) {
+        include 'db_sql.php';
+    } else {
+        include 'server_sql.php';
+    }
+    exit;
+}
+
+/**
+ * Defines the query to be displayed in the query textarea
+ */
+if (! empty($show_query)) {
+    $query_to_display = $sql_query;
+} else if (! empty($_REQUEST['sql_query'])) {
+    $query_to_display = htmlspecialchars($_REQUEST['sql_query']);
+    $show_query = 1;
+} else {
+    $query_to_display = '';
+}
+$sql_query = '';
+
+/**
+ * prepare JavaScript functionality
+ */
+$response = PMA_Response::getInstance();
+$response->getFooter()->setMinimal();
+$header = $response->getHeader();
+$header->disableMenu();
+$header->setBodyId('bodyquerywindow');
+$scripts = $header->getScripts();
+$scripts->addFile('common.js');
+$scripts->addFile('querywindow.js');
+
+if (PMA_isValid($_REQUEST['auto_commit'], 'identical', 'true')) {
+    $scripts->addEvent('load', 'PMA_queryAutoCommit');
+}
+// always set focus to the textarea
+if ($querydisplay_tab == 'sql' || $querydisplay_tab == 'full') {
+    $scripts->addEvent('load', 'PMA_querywindowSetFocus');
+}
+
+echo '<div id="querywindowcontainer">';
+
+if ($tabs) {
+    echo PMA_Util::getHtmlTabs($tabs, array(), 'topmenu', true);
+    unset($tabs);
+}
+
+PMA_sqlQueryForm($query_to_display, $querydisplay_tab);
+
+// Hidden forms and query frame interaction stuff
+
+$_sql_history = PMA_getHistory($GLOBALS['cfg']['Server']['user']);
+if (! empty($_sql_history)
+    && ($querydisplay_tab == 'history' || $querydisplay_tab == 'full')
+) {
+    $tab = $querydisplay_tab != 'full' ? 'sql' : 'full';
+    echo __('SQL history') . ':<br />'
+        . '<ul>';
+    foreach ($_sql_history as $query) {
+        echo '<li>' . "\n";
+
+        // edit link
+        $url_params = array(
+            'querydisplay_tab' => $tab,
+            'sql_query' => $query['sqlquery'],
+            'db' => $query['db'],
+            'table' => $query['table'],
+        );
+        echo '<a href="querywindow.php' . PMA_generate_common_url($url_params)
+            . '">' . $titles['Change'] . '</a>';
+
+        // execute link
+        $url_params['auto_commit'] = 'true';
+        echo '<a href="import.php' . PMA_generate_common_url($url_params) . '"'
+            . ' target="frame_content">';
+
+        if (! empty($query['db'])) {
+            echo '[';
+            echo htmlspecialchars(PMA_Util::backquote($query['db']));
+            if (! empty($query['table'])) {
+                echo '.' . htmlspecialchars(PMA_Util::backquote($query['table']));
+            }
+            echo  '] ';
+        }
+        if (strlen($query['sqlquery']) > 120) {
+            echo '<span title="' . htmlspecialchars($query['sqlquery']) . '">';
+            echo htmlspecialchars(substr($query['sqlquery'], 0, 50)) . ' [...] ';
+            echo htmlspecialchars(substr($query['sqlquery'], -50));
+            echo '</span>';
+        } else {
+            echo htmlspecialchars($query['sqlquery']);
+        }
+        echo '</a>' . "\n";
+        echo '</li>' . "\n";
+    }
+    unset($tab, $_sql_history, $query);
+    echo '</ul>' . "\n";
+}
+
+echo '<form action="querywindow.php" method="post" name="hiddenqueryform"';
+echo ' id="hiddenqueryform">';
+echo PMA_generate_common_hidden_inputs('', '');
+echo '<input type="hidden" name="db" value="' . htmlspecialchars($db) . '" />';
+echo '<input type="hidden" name="table" value="'
+    . htmlspecialchars($table) . '" />';
+echo '<input type="hidden" name="sql_query" value="" />';
+echo '<input type="hidden" name="querydisplay_tab" value="'
+    . $querydisplay_tab . '" />';
+echo '</form>';
+echo '</div>';
diff --git a/phpmyadmin/robots.txt b/phpmyadmin/robots.txt
new file mode 100644
index 0000000..1f53798
--- /dev/null
+++ b/phpmyadmin/robots.txt
@@ -0,0 +1,2 @@
+User-agent: *
+Disallow: /
diff --git a/phpmyadmin/schema_edit.php b/phpmyadmin/schema_edit.php
new file mode 100644
index 0000000..498ccb7
--- /dev/null
+++ b/phpmyadmin/schema_edit.php
@@ -0,0 +1,126 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ *
+ * @package PhpMyAdmin
+ */
+
+/**
+ * Gets some core libraries
+ */
+
+require_once 'libraries/common.inc.php';
+require_once 'libraries/db_common.inc.php';
+require 'libraries/StorageEngine.class.php';
+
+$active_page = 'db_operations.php';
+require_once 'libraries/db_common.inc.php';
+$url_query .= '&goto=schema_edit.php';
+require_once 'libraries/db_info.inc.php';
+
+/**
+ * get all variables needed for exporting relational schema
+ * in $cfgRelation
+ */
+$cfgRelation = PMA_getRelationsParam();
+
+/**
+ * Now in ./libraries/relation.lib.php we check for all tables
+ * that we need, but if we don't find them we are quiet about it
+ * so people can't work without relational variables.
+ * This page is absolutely useless if you didn't set up your tables
+ * correctly, so it is a good place to see which tables we can and
+ * complain ;-)
+ */
+if (! $cfgRelation['relwork']) {
+    echo sprintf(__('<b>%s</b> table not found or not set in %s'), 'relation', 'config.inc.php') . '<br />' . "\n"
+         . PMA_Util::showDocu('config', 'cfg_Servers_relation') . "\n";
+    exit;
+}
+
+if (! $cfgRelation['displaywork']) {
+    echo sprintf(__('<b>%s</b> table not found or not set in %s'), 'table_info', 'config.inc.php') . '<br />' . "\n"
+         . PMA_Util::showDocu('config', 'cfg_Servers_table_info') . "\n";
+    exit;
+}
+
+if (! isset($cfgRelation['table_coords'])) {
+    echo sprintf(__('<b>%s</b> table not found or not set in %s'), 'table_coords', 'config.inc.php') . '<br />' . "\n"
+         . PMA_Util::showDocu('config', 'cfg_Servers_table_coords') . "\n";
+    exit;
+}
+if (! isset($cfgRelation['pdf_pages'])) {
+    echo sprintf(__('<b>%s</b> table not found or not set in %s'), 'pdf_page', 'config.inc.php') . '<br />' . "\n"
+         . PMA_Util::showDocu('config', 'cfg_Servers_pdf_pages') . "\n";
+    exit;
+}
+
+if ($cfgRelation['pdfwork']) {
+
+    /**
+     * User object created for presenting the HTML options
+     * so, user can interact with it and perform export of relations schema
+     */
+
+    include_once 'libraries/schema/User_Schema.class.php';
+    $user_schema = new PMA_User_Schema();
+
+    /**
+     * This function will process the user defined pages
+     * and tables which will be exported as Relational schema
+     * you can set the table positions on the paper via scratchboard
+     * for table positions, put the x,y co-ordinates
+     *
+     * @param string $do It tells what the Schema is supposed to do
+     *                  create and select a page, generate schema etc
+     */
+    if (isset($_REQUEST['do'])) {
+        $user_schema->setAction($_REQUEST['do']);
+        $user_schema->processUserChoice();
+    }
+
+    /**
+     * Show some possibility to select a page for the export of relation schema
+     * Lists all pages created before and can select and edit from them
+     */
+
+    $user_schema->selectPage();
+
+    /**
+     * Create a new page where relations will be drawn
+     */
+
+    $user_schema->showCreatePageDialog($db);
+
+    /**
+     * After selection of page or creating a page
+     * It will show you the list of tables
+     * A dashboard will also be shown where you can position the tables
+     */
+
+    $user_schema->showTableDashBoard();
+
+    if (isset($_REQUEST['do'])
+        && ($_REQUEST['do'] == 'edcoord'
+        || ($_REQUEST['do']== 'selectpage' && isset($user_schema->chosenPage) && $user_schema->chosenPage != 0)
+        || ($_REQUEST['do'] == 'createpage' && isset($user_schema->chosenPage) && $user_schema->chosenPage != 0))
+    ) {
+
+        /**
+         * show Export schema generation options
+         */
+        $user_schema->displaySchemaGenerationOptions();
+
+        if ((isset($showwysiwyg) && $showwysiwyg == '1')) {
+            ?>
+            <script type="text/javascript">
+            //<![CDATA[
+            ToggleDragDrop('pdflayout');
+            //]]>
+            </script>
+            <?php
+        }
+    } // end if
+} // end if ($cfgRelation['pdfwork'])
+
+?>
diff --git a/phpmyadmin/schema_export.php b/phpmyadmin/schema_export.php
new file mode 100644
index 0000000..90f684a
--- /dev/null
+++ b/phpmyadmin/schema_export.php
@@ -0,0 +1,66 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ *
+ * @package PhpMyAdmin
+ */
+
+/**
+ * Gets some core libraries
+ */
+require_once 'libraries/common.inc.php';
+require 'libraries/StorageEngine.class.php';
+
+/**
+ * get all variables needed for exporting relational schema
+ * in $cfgRelation
+ */
+$cfgRelation = PMA_getRelationsParam();
+
+require_once 'libraries/transformations.lib.php';
+require_once 'libraries/Index.class.php';
+require_once 'libraries/schema/Export_Relation_Schema.class.php';
+
+/**
+ * get all the export options and verify
+ * call and include the appropriate Schema Class depending on $export_type
+ * default is PDF
+ */
+
+$post_params = array(
+    'all_tables_same_width',
+    'chpage',
+    'db',
+    'do',
+    'export_type',
+    'orientation',
+    'paper',
+    'names',
+    'pdf_page_number',
+    'show_color',
+    'show_grid',
+    'show_keys',
+    'show_table_dimension',
+    'with_doc'
+);
+foreach ($post_params as $one_post_param) {
+    if (isset($_POST[$one_post_param])) {
+        $GLOBALS[$one_post_param] = $_POST[$one_post_param];
+    }
+}
+
+if (! isset($export_type) || ! preg_match('/^[a-zA-Z]+$/', $export_type)) {
+    $export_type = 'pdf';
+}
+PMA_DBI_select_db($db);
+
+$path = PMA_securePath(ucfirst($export_type));
+if (!file_exists('libraries/schema/' . $path . '_Relation_Schema.class.php')) {
+    PMA_Export_Relation_Schema::dieSchema(
+        $_POST['chpage'],
+        $export_type,
+        __('File doesn\'t exist')
+    );
+}
+require "libraries/schema/".$path.'_Relation_Schema.class.php';
+$obj_schema = eval("new PMA_".$path."_Relation_Schema();");
diff --git a/phpmyadmin/server_binlog.php b/phpmyadmin/server_binlog.php
new file mode 100644
index 0000000..20f9070
--- /dev/null
+++ b/phpmyadmin/server_binlog.php
@@ -0,0 +1,219 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * display the binary logs and the content of the selected
+ *
+ * @package PhpMyAdmin
+ */
+
+/**
+ *
+ */
+require_once 'libraries/common.inc.php';
+
+/**
+ * Does the common work, provides $binary_logs
+ */
+require_once 'libraries/server_common.inc.php';
+
+$url_params = array();
+
+/**
+ * Need to find the real end of rows?
+ */
+if (! isset($_REQUEST['pos'])) {
+    $pos = 0;
+} else {
+    /* We need this to be a integer */
+    $pos = (int) $_REQUEST['pos'];
+}
+
+if (! isset($_REQUEST['log'])
+    || ! array_key_exists($_REQUEST['log'], $binary_logs)
+) {
+    $_REQUEST['log'] = '';
+} else {
+    $url_params['log'] = $_REQUEST['log'];
+}
+
+$sql_query = 'SHOW BINLOG EVENTS';
+if (! empty($_REQUEST['log'])) {
+    $sql_query .= ' IN \'' . $_REQUEST['log'] . '\'';
+}
+if ($GLOBALS['cfg']['MaxRows'] !== 'all') {
+    $sql_query .= ' LIMIT ' . $pos . ', ' . (int) $GLOBALS['cfg']['MaxRows'];
+}
+
+/**
+ * Sends the query
+ */
+$result = PMA_DBI_query($sql_query);
+
+/**
+ * prepare some vars for displaying the result table
+ */
+// Gets the list of fields properties
+if (isset($result) && $result) {
+    $num_rows = PMA_DBI_num_rows($result);
+} else {
+    $num_rows = 0;
+}
+
+if (empty($_REQUEST['dontlimitchars'])) {
+    $dontlimitchars = false;
+} else {
+    $dontlimitchars = true;
+    $url_params['dontlimitchars'] = 1;
+}
+
+/**
+ * Displays the sub-page heading
+ */
+echo '<h2>' . "\n"
+   . PMA_Util::getImage('s_tbl.png')
+   . '    ' . __('Binary log') . "\n"
+   . '</h2>' . "\n";
+
+/**
+ * Display log selector.
+ */
+if (count($binary_logs) > 1) {
+    echo '<form action="server_binlog.php" method="get">';
+    echo PMA_generate_common_hidden_inputs($url_params);
+    echo '<fieldset><legend>';
+    echo __('Select binary log to view');
+    echo '</legend><select name="log">';
+    $full_size = 0;
+    foreach ($binary_logs as $each_log) {
+        echo '<option value="' . $each_log['Log_name'] . '"';
+        if ($each_log['Log_name'] == $_REQUEST['log']) {
+            echo ' selected="selected"';
+        }
+        echo '>' . $each_log['Log_name'];
+        if (isset($each_log['File_size'])) {
+            $full_size += $each_log['File_size'];
+            echo ' ('
+                . implode(
+                    ' ',
+                    PMA_Util::formatByteDown(
+                        $each_log['File_size'], 3, 2
+                    )
+                )
+                . ')';
+        }
+        echo '</option>';
+    }
+    echo '</select> ';
+    echo count($binary_logs) . ' ' . __('Files') . ', ';
+    if ($full_size > 0) {
+        echo implode(
+            ' ', PMA_Util::formatByteDown($full_size)
+        );
+    }
+    echo '</fieldset>';
+    echo '<fieldset class="tblFooters">';
+    echo '<input type="submit" value="' . __('Go') . '" />';
+    echo '</fieldset>';
+    echo '</form>';
+}
+
+echo PMA_Util::getMessage(PMA_Message::success());
+
+/**
+ * Displays the page
+ */
+echo '<table cellpadding="2" cellspacing="1">'
+    . '<thead>'
+    . '<tr>'
+    . '<td colspan="6" class="center">';
+
+// we do not now how much rows are in the binlog
+// so we can just force 'NEXT' button
+if ($pos > 0) {
+    $this_url_params = $url_params;
+    if ($pos > $GLOBALS['cfg']['MaxRows']) {
+        $this_url_params['pos'] = $pos - $GLOBALS['cfg']['MaxRows'];
+    }
+
+    echo '<a href="server_binlog.php'
+        . PMA_generate_common_url($this_url_params) . '"';
+    if ($GLOBALS['cfg']['NavigationBarIconic']) {
+        echo ' title="' . _pgettext('Previous page', 'Previous') . '">';
+    } else {
+        echo '>' . _pgettext('Previous page', 'Previous');
+    } // end if... else...
+    echo ' < </a> - ';
+}
+
+$this_url_params = $url_params;
+if ($pos > 0) {
+    $this_url_params['pos'] = $pos;
+}
+if ($dontlimitchars) {
+    unset($this_url_params['dontlimitchars']);
+    $tempTitle = __('Truncate Shown Queries');
+    $tempImgMode = 'partial';
+} else {
+    $this_url_params['dontlimitchars'] = 1;
+    $tempTitle = __('Show Full Queries');
+    $tempImgMode = 'full';
+}
+echo '<a href="server_binlog.php' . PMA_generate_common_url($this_url_params)
+    . '" title="' . $tempTitle . '">'
+    . '<img src="' .$pmaThemeImage . 's_' . $tempImgMode . 'text.png"'
+    . 'alt="' . $tempTitle . '" /></a>';
+
+// we do not now how much rows are in the binlog
+// so we can just force 'NEXT' button
+if ($num_rows >= $GLOBALS['cfg']['MaxRows']) {
+    $this_url_params = $url_params;
+    $this_url_params['pos'] = $pos + $GLOBALS['cfg']['MaxRows'];
+    echo ' - <a href="server_binlog.php' . PMA_generate_common_url($this_url_params)
+        . '"';
+    if ($GLOBALS['cfg']['NavigationBarIconic']) {
+        echo ' title="' . _pgettext('Next page', 'Next') . '">';
+    } else {
+        echo '>' . _pgettext('Next page', 'Next');
+    } // end if... else...
+    echo ' > </a>';
+}
+
+echo  '</td>'
+    . '</tr>'
+    . '<tr>'
+    . '<th>' . __('Log name') . '</th>'
+    . '<th>' . __('Position') . '</th>'
+    . '<th>' . __('Event type') . '</th>'
+    . '<th>' . __('Server ID') . '</th>'
+    . '<th>' . __('Original position') . '</th>'
+    . '<th>' . __('Information') . '</th>'
+    . '</tr>'
+    . '</thead>'
+    . '<tbody>';
+
+$odd_row = true;
+while ($value = PMA_DBI_fetch_assoc($result)) {
+    if (! $dontlimitchars
+        && PMA_strlen($value['Info']) > $GLOBALS['cfg']['LimitChars']
+    ) {
+        $value['Info'] = PMA_substr(
+            $value['Info'], 0, $GLOBALS['cfg']['LimitChars']
+        ) . '...';
+    }
+
+    echo '<tr class="noclick ' . ($odd_row ? 'odd' : 'even') . '">'
+        . '<td> ' . $value['Log_name'] . ' </td>'
+        . '<td class="right"> ' . $value['Pos'] . ' </td>'
+        . '<td> ' . $value['Event_type'] . ' </td>'
+        . '<td class="right"> ' . $value['Server_id'] . ' </td>'
+        . '<td class="right"> '
+        . (isset($value['Orig_log_pos'])
+        ? $value['Orig_log_pos'] : $value['End_log_pos'])
+        . ' </td>'
+        . '<td> ' . htmlspecialchars($value['Info']) . ' </td>'
+        . '</tr>';
+
+    $odd_row = !$odd_row;
+}
+echo '</tbody>'
+    . '</table>';
diff --git a/phpmyadmin/server_collations.php b/phpmyadmin/server_collations.php
new file mode 100644
index 0000000..2af1647
--- /dev/null
+++ b/phpmyadmin/server_collations.php
@@ -0,0 +1,84 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ *
+ * @package PhpMyAdmin
+ */
+
+/**
+ * requirements
+ */
+require_once 'libraries/common.inc.php';
+
+/**
+ * Does the common work
+ */
+require 'libraries/server_common.inc.php';
+
+
+/**
+ * Displays the sub-page heading
+ */
+echo '<h2>' . "\n"
+   . '    ' . PMA_Util::getImage('s_asci.png')
+   . '' . __('Character Sets and Collations') . "\n"
+   . '</h2>' . "\n";
+
+/**
+ * Includes the required charset library
+ */
+require_once 'libraries/mysql_charsets.lib.php';
+
+
+/**
+ * Outputs the result
+ */
+echo '<div id="div_mysql_charset_collations">' . "\n"
+   . '<table class="data noclick">' . "\n"
+   . '<tr><th>' . __('Collation') . '</th>' . "\n"
+   . '    <th>' . __('Description') . '</th>' . "\n"
+   . '</tr>' . "\n";
+
+$i = 0;
+$table_row_count = count($mysql_charsets) + count($mysql_collations);
+
+foreach ($mysql_charsets as $current_charset) {
+    if ($i >= $table_row_count / 2) {
+        $i = 0;
+        echo '</table>' . "\n"
+           . '<table class="data noclick">' . "\n"
+           . '<tr><th>' . __('Collation') . '</th>' . "\n"
+           . '    <th>' . __('Description') . '</th>' . "\n"
+           . '</tr>' . "\n";
+    }
+    $i++;
+    echo '<tr><th colspan="2" class="right">' . "\n"
+       . '        ' . htmlspecialchars($current_charset) . "\n"
+       . (empty($mysql_charsets_descriptions[$current_charset])
+            ? ''
+            : '        (<i>' . htmlspecialchars(
+                $mysql_charsets_descriptions[$current_charset]
+            ) . '</i>)' . "\n")
+       . '    </th>' . "\n"
+       . '</tr>' . "\n";
+    $odd_row = true;
+    foreach ($mysql_collations[$current_charset] as $current_collation) {
+        $i++;
+        echo '<tr class="'
+           . ($odd_row ? 'odd' : 'even')
+           . ($mysql_default_collations[$current_charset] == $current_collation
+                ? ' marked'
+                : '')
+           . ($mysql_collations_available[$current_collation] ? '' : ' disabled')
+           . '">' . "\n"
+           . '    <td>' . htmlspecialchars($current_collation) . '</td>' . "\n"
+           . '    <td>' . PMA_getCollationDescr($current_collation) . '</td>' . "\n"
+           . '</tr>' . "\n";
+        $odd_row = !$odd_row;
+    }
+}
+unset($table_row_count);
+echo '</table>' . "\n"
+   . '</div>' . "\n";
+
+?>
diff --git a/phpmyadmin/server_databases.php b/phpmyadmin/server_databases.php
new file mode 100644
index 0000000..0cda459
--- /dev/null
+++ b/phpmyadmin/server_databases.php
@@ -0,0 +1,349 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ *
+ * @package PhpMyAdmin
+ */
+
+/**
+ * Does the common work
+ */
+require_once 'libraries/common.inc.php';
+$response = PMA_Response::getInstance();
+$header   = $response->getHeader();
+$scripts  = $header->getScripts();
+$scripts->addFile('server_databases.js');
+
+require 'libraries/server_common.inc.php';
+if (! PMA_DRIZZLE) {
+    include_once 'libraries/replication.inc.php';
+} else {
+    $replication_types = array();
+    $replication_info = null;
+}
+require 'libraries/build_html_for_db.lib.php';
+
+/**
+ * Sets globals from $_POST
+ */
+$post_params = array(
+    'mult_btn',
+    'query_type',
+    'selected'
+);
+foreach ($post_params as $one_post_param) {
+    if (isset($_POST[$one_post_param])) {
+        $GLOBALS[$one_post_param] = $_POST[$one_post_param];
+    }
+}
+
+/**
+ * avoids 'undefined index' errors
+ */
+if (empty($_REQUEST['sort_by'])) {
+    $sort_by = 'SCHEMA_NAME';
+} else {
+    $sort_by_whitelist = array(
+        'SCHEMA_NAME',
+        'DEFAULT_COLLATION_NAME',
+        'SCHEMA_TABLES',
+        'SCHEMA_TABLE_ROWS',
+        'SCHEMA_DATA_LENGTH',
+        'SCHEMA_INDEX_LENGTH',
+        'SCHEMA_LENGTH',
+        'SCHEMA_DATA_FREE'
+    );
+    if (in_array($_REQUEST['sort_by'], $sort_by_whitelist)) {
+        $sort_by = $_REQUEST['sort_by'];
+    } else {
+        $sort_by = 'SCHEMA_NAME';
+    }
+}
+
+if (isset($_REQUEST['sort_order'])
+    && strtolower($_REQUEST['sort_order']) == 'desc'
+) {
+    $sort_order = 'desc';
+} else {
+    $sort_order = 'asc';
+}
+
+$dbstats    = empty($_REQUEST['dbstats']) ? 0 : 1;
+$pos        = empty($_REQUEST['pos']) ? 0 : (int) $_REQUEST['pos'];
+
+
+/**
+ * Drops multiple databases
+ */
+
+// workaround for IE behavior (it returns some coordinates based on where
+// the mouse was on the Drop image):
+if (isset($_REQUEST['drop_selected_dbs_x'])) {
+    $_REQUEST['drop_selected_dbs'] = true;
+}
+
+if ((isset($_REQUEST['drop_selected_dbs']) || isset($_REQUEST['query_type']))
+    && ($is_superuser || $cfg['AllowUserDropDatabase'])
+) {
+    if (! isset($_REQUEST['selected_dbs']) && ! isset($_REQUEST['query_type'])) {
+        $message = PMA_Message::error(__('No databases selected.'));
+    } else {
+        $action = 'server_databases.php';
+        $submit_mult = 'drop_db';
+        $err_url = 'server_databases.php?' . PMA_generate_common_url();
+        if (isset($_REQUEST['selected_dbs'])
+            && !isset($_REQUEST['is_js_confirmed'])
+        ) {
+            $selected_db = $_REQUEST['selected_dbs'];
+        }
+        if (isset($_REQUEST['is_js_confirmed'])) {
+            $_REQUEST = array(
+                'query_type' => $submit_mult,
+                'selected' => $_REQUEST['selected_dbs'],
+                'mult_btn' => __('Yes'),
+                'db' => $GLOBALS['db'],
+                'table' => $GLOBALS['table']);
+        }
+        include 'libraries/mult_submits.inc.php';
+        unset($action, $submit_mult, $err_url, $selected_db, $GLOBALS['db']);
+        if (empty($message)) {
+            if ($mult_btn == __('Yes')) {
+                $number_of_databases = count($selected);
+            } else {
+                $number_of_databases = 0;
+            }
+            $message = PMA_Message::success(
+                _ngettext(
+                    '%1$d database has been dropped successfully.',
+                    '%1$d databases have been dropped successfully.',
+                    $number_of_databases
+                )
+            );
+            $message->addParam($number_of_databases);
+        }
+    }
+    if ($GLOBALS['is_ajax_request'] && $message instanceof PMA_Message) {
+        $response = PMA_Response::getInstance();
+        $response->isSuccess($message->isSuccess());
+        $response->addJSON('message', $message);
+        exit;
+    }
+}
+
+/**
+ * Displays the sub-page heading
+ */
+echo '<h2>' . "\n"
+   . PMA_Util::getImage('s_db.png')
+   . ($dbstats ? __('Databases statistics') : __('Databases')) . "\n"
+   .'</h2>' . "\n";
+
+/**
+ * Create database.
+ */
+if ($cfg['ShowCreateDb']) {
+    echo '<ul><li id="li_create_database" class="no_bullets">' . "\n";
+    include 'libraries/display_create_database.lib.php';
+    echo '    </li>' . "\n";
+    echo '</ul>' . "\n";
+}
+
+/**
+ * Gets the databases list
+ */
+if ($server > 0) {
+    $databases = PMA_DBI_get_databases_full(
+        null, $dbstats, null, $sort_by, $sort_order, $pos, true
+    );
+    $databases_count = count($GLOBALS['pma']->databases);
+} else {
+    $databases_count = 0;
+}
+
+
+/**
+ * Displays the page
+ */
+if ($databases_count > 0) {
+    echo '<div id="tableslistcontainer">';
+    reset($databases);
+    $first_database = current($databases);
+    // table col order
+    $column_order = PMA_getColumnOrder();
+
+    $_url_params = array(
+        'pos' => $pos,
+        'dbstats' => $dbstats,
+        'sort_by' => $sort_by,
+        'sort_order' => $sort_order,
+    );
+
+    echo PMA_Util::getListNavigator(
+        $databases_count, $pos, $_url_params, 'server_databases.php',
+        'frame_content', $GLOBALS['cfg']['MaxDbList']
+    );
+
+    $_url_params['pos'] = $pos;
+    $_url_params['drop_selected_dbs'] = 1;
+
+    echo '<form class="ajax" action="server_databases.php" ';
+    echo 'method="post" name="dbStatsForm" id="dbStatsForm">' . "\n";
+    echo PMA_generate_common_hidden_inputs($_url_params);
+
+    $_url_params['sort_by'] = 'SCHEMA_NAME';
+    $_url_params['sort_order'] = ($sort_by == 'SCHEMA_NAME' && $sort_order == 'asc') ? 'desc' : 'asc';
+
+    echo '<table id="tabledatabases" class="data">' . "\n"
+       . '<thead>' . "\n"
+       . '<tr>' . "\n"
+       . ($is_superuser || $cfg['AllowUserDropDatabase'] ? '        <th></th>' . "\n" : '')
+       . '    <th><a href="server_databases.php' . PMA_generate_common_url($_url_params) . '">' . "\n"
+       . '            ' . __('Database') . "\n"
+       . ($sort_by == 'SCHEMA_NAME' ? '                ' . PMA_Util::getImage('s_' . $sort_order . '.png', ($sort_order == 'asc' ? __('Ascending') : __('Descending'))) . "\n" : '')
+       . '        </a></th>' . "\n";
+    $table_columns = 3;
+    foreach ($column_order as $stat_name => $stat) {
+        if (array_key_exists($stat_name, $first_database)) {
+            if ($stat['format'] === 'byte') {
+                $table_columns += 2;
+                $colspan = ' colspan="2"';
+            } else {
+                $table_columns++;
+                $colspan = '';
+            }
+            $_url_params['sort_by'] = $stat_name;
+            $_url_params['sort_order'] = ($sort_by == $stat_name && $sort_order == 'desc') ? 'asc' : 'desc';
+            echo '    <th' . $colspan . '>'
+                . '<a href="server_databases.php' . PMA_generate_common_url($_url_params) . '">' . "\n"
+                . '            ' . $stat['disp_name'] . "\n"
+                . ($sort_by == $stat_name ? '            ' . PMA_Util::getImage('s_' . $sort_order . '.png', ($sort_order == 'asc' ? __('Ascending') : __('Descending'))) . "\n" : '')
+                . '        </a></th>' . "\n";
+        }
+    }
+
+    foreach ($replication_types as $type) {
+        if ($type=="master") {
+            $name = __('Master replication');
+        } elseif ($type == "slave") {
+            $name = __('Slave replication');
+        }
+        if (${"server_{$type}_status"}) {
+            echo '    <th>'. $name .'</th>' . "\n";
+        }
+    }
+
+    if ($is_superuser && ! PMA_DRIZZLE) {
+        echo '    <th>' . ($cfg['PropertiesIconic'] ? '' : __('Action')) . "\n"
+           . '    </th>' . "\n";
+    }
+    echo '</tr>' . "\n"
+       . '</thead>' . "\n"
+       . '<tbody>' . "\n";
+
+    $odd_row = true;
+    foreach ($databases as $current) {
+        $tr_class = $odd_row ? 'odd' : 'even';
+        if (PMA_is_system_schema($current['SCHEMA_NAME'], true)) {
+            $tr_class .= ' noclick';
+        }
+        echo '<tr class="' . $tr_class . '">' . "\n";
+        $odd_row = ! $odd_row;
+
+        list($column_order, $generated_html) = PMA_buildHtmlForDb(
+            $current,
+            $is_superuser,
+            $url_query,
+            $column_order,
+            $replication_types,
+            $replication_info
+        );
+
+        echo $generated_html;
+
+        echo '</tr>' . "\n";
+    } // end foreach ($databases as $key => $current)
+    unset($current, $odd_row);
+
+    echo '</tbody><tfoot><tr>' . "\n";
+    if ($is_superuser || $cfg['AllowUserDropDatabase']) {
+        echo '    <th></th>' . "\n";
+    }
+    echo '    <th>' . __('Total') . ': <span id="databases_count">' . $databases_count . '</span></th>' . "\n";
+    foreach ($column_order as $stat_name => $stat) {
+        if (array_key_exists($stat_name, $first_database)) {
+            if ($stat['format'] === 'byte') {
+                list($value, $unit) = PMA_Util::formatByteDown($stat['footer'], 3, 1);
+            } elseif ($stat['format'] === 'number') {
+                $value = PMA_Util::formatNumber($stat['footer'], 0);
+            } else {
+                $value = htmlentities($stat['footer'], 0);
+            }
+            echo '    <th class="value">';
+            if (isset($stat['description_function'])) {
+                echo '<dfn title="' . $stat['description_function']($stat['footer']) . '">';
+            }
+            echo $value;
+            if (isset($stat['description_function'])) {
+                echo '</dfn>';
+            }
+            echo '</th>' . "\n";
+            if ($stat['format'] === 'byte') {
+                echo '    <th class="unit">' . $unit . '</th>' . "\n";
+            }
+        }
+    }
+
+    foreach ($replication_types as $type) {
+        if (${"server_{$type}_status"}) {
+            echo '    <th></th>' . "\n";
+        }
+    }
+
+    if ($is_superuser) {
+        echo '    <th></th>' . "\n";
+    }
+    echo '</tr>' . "\n";
+    echo '</tfoot>' . "\n"
+        .'</table>' . "\n";
+    unset($column_order, $stat_name, $stat, $databases, $table_columns);
+
+    if ($is_superuser || $cfg['AllowUserDropDatabase']) {
+        $common_url_query = PMA_generate_common_url(
+            array(
+                'sort_by' => $sort_by,
+                'sort_order' => $sort_order,
+                'dbstats' => $dbstats
+            )
+        );
+        echo '<img class="selectallarrow" src="' . $pmaThemeImage . 'arrow_' . $text_dir . '.png"'
+           . ' width="38" height="22" alt="' . __('With selected:') . '" />' . "\n"
+           . '<input type="checkbox" id="checkall" title="' . __('Check All') . '" /> '
+           . '<label for="checkall">' . __('Check All') . '</label> '
+           . '<i style="margin-left: 2em">' . __('With selected:') . '</i>' . "\n";
+        echo PMA_Util::getButtonOrImage(
+            '',
+            'mult_submit' . ' ajax',
+            'drop_selected_dbs',
+            __('Drop'), 'b_deltbl.png'
+        );
+    }
+
+    if (empty($dbstats)) {
+        echo '<ul><li id="li_switch_dbstats"><strong>' . "\n";
+            echo '<a href="server_databases.php?' . $url_query . '&dbstats=1"'
+                . ' title="' . __('Enable Statistics') . '">' . "\n"
+                . '            ' . __('Enable Statistics');
+        echo '</a></strong><br />' . "\n";
+        PMA_Message::notice(
+            __('Note: Enabling the database statistics here might cause heavy traffic between the web server and the MySQL server.')
+        )->display();
+        echo '</li>' . "\n" . '</ul>' . "\n";
+    }
+    echo '</form>';
+    echo '</div>';
+} else {
+    echo __('No databases');
+}
+unset($databases_count);
+
+?>
diff --git a/phpmyadmin/server_engines.php b/phpmyadmin/server_engines.php
new file mode 100644
index 0000000..7ca28d1
--- /dev/null
+++ b/phpmyadmin/server_engines.php
@@ -0,0 +1,129 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * display list of server engines and additonal information about them
+ *
+ * @package PhpMyAdmin
+ */
+
+/**
+ * requirements
+ */
+require_once 'libraries/common.inc.php';
+
+/**
+ * Does the common work
+ */
+require 'libraries/server_common.inc.php';
+require 'libraries/StorageEngine.class.php';
+
+/**
+ * Did the user request information about a certain storage engine?
+ */
+if (empty($_REQUEST['engine'])
+    || ! PMA_StorageEngine::isValid($_REQUEST['engine'])
+) {
+
+    /**
+     * Displays the sub-page heading
+     */
+    echo '<h2>' . "\n"
+       . PMA_Util::getImage('b_engine.png')
+       . "\n" . __('Storage Engines') . "\n"
+       . '</h2>' . "\n";
+
+
+    /**
+     * Displays the table header
+     */
+    echo '<table class="noclick">' . "\n"
+       . '<thead>' . "\n"
+       . '<tr><th>' . __('Storage Engine') . '</th>' . "\n"
+       . '    <th>' . __('Description') . '</th>' . "\n"
+       . '</tr>' . "\n"
+       . '</thead>' . "\n"
+       . '<tbody>' . "\n";
+
+
+    /**
+     * Listing the storage engines
+     */
+    $odd_row = true;
+    foreach (PMA_StorageEngine::getStorageEngines() as $engine => $details) {
+        echo '<tr class="'
+           . ($odd_row ? 'odd' : 'even')
+           . ($details['Support'] == 'NO' || $details['Support'] == 'DISABLED'
+                ? ' disabled'
+                : '')
+           . '">' . "\n"
+           . '    <td><a rel="newpage" href="server_engines.php'
+           . PMA_generate_common_url(array('engine' => $engine)) . '">' . "\n"
+           . '            ' . htmlspecialchars($details['Engine']) . "\n"
+           . '        </a></td>' . "\n"
+           . '    <td>' . htmlspecialchars($details['Comment']) . '</td>' . "\n"
+           . '</tr>' . "\n";
+        $odd_row = !$odd_row;
+    }
+
+    unset($odd_row, $engine, $details);
+    echo '</tbody>' . "\n"
+       . '</table>' . "\n";
+
+} else {
+
+    /**
+     * Displays details about a given Storage Engine
+     */
+
+    $engine_plugin = PMA_StorageEngine::getEngine($_REQUEST['engine']);
+    echo '<h2>' . "\n"
+       . PMA_Util::getImage('b_engine.png')
+       . '    ' . htmlspecialchars($engine_plugin->getTitle()) . "\n"
+       . '    ' . PMA_Util::showMySQLDocu('', $engine_plugin->getMysqlHelpPage()) . "\n"
+       . '</h2>' . "\n\n";
+    echo '<p>' . "\n"
+       . '    <em>' . "\n"
+       . '        ' . htmlspecialchars($engine_plugin->getComment()) . "\n"
+       . '    </em>' . "\n"
+       . '</p>' . "\n\n";
+    $infoPages = $engine_plugin->getInfoPages();
+    if (! empty($infoPages) && is_array($infoPages)) {
+        echo '<p>' . "\n"
+           . '    <strong>[</strong>' . "\n";
+        if (empty($_REQUEST['page'])) {
+            echo '    <strong>' . __('Variables') . '</strong>' . "\n";
+        } else {
+            echo '    <a href="server_engines.php'
+                . PMA_generate_common_url(array('engine' => $_REQUEST['engine']))
+                . '">' . __('Variables') . '</a>' . "\n";
+        }
+        foreach ($infoPages as $current => $label) {
+            echo '    <strong>|</strong>' . "\n";
+            if (isset($_REQUEST['page']) && $_REQUEST['page'] == $current) {
+                echo '    <strong>' . $label . '</strong>' . "\n";
+            } else {
+                echo '    <a href="server_engines.php'
+                    . PMA_generate_common_url(
+                        array('engine' => $_REQUEST['engine'], 'page' => $current)
+                    )
+                    . '">' . htmlspecialchars($label) . '</a>' . "\n";
+            }
+        }
+        unset($current, $label);
+        echo '    <strong>]</strong>' . "\n"
+           . '</p>' . "\n\n";
+    }
+    unset($infoPages, $page_output);
+    if (! empty($_REQUEST['page'])) {
+        $page_output = $engine_plugin->getPage($_REQUEST['page']);
+    }
+    if (! empty($page_output)) {
+        echo $page_output;
+    } else {
+        echo '<p> ' . $engine_plugin->getSupportInformationMessage() . "\n"
+           . '</p>' . "\n"
+           . $engine_plugin->getHtmlVariables();
+    }
+}
+
+?>
diff --git a/phpmyadmin/server_export.php b/phpmyadmin/server_export.php
new file mode 100644
index 0000000..001abf2
--- /dev/null
+++ b/phpmyadmin/server_export.php
@@ -0,0 +1,73 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ *
+ * @package PhpMyAdmin
+ */
+
+/**
+ * Does the common work
+ */
+require_once 'libraries/common.inc.php';
+
+$response = PMA_Response::getInstance();
+$header   = $response->getHeader();
+$scripts  = $header->getScripts();
+$scripts->addFile('export.js');
+
+require 'libraries/server_common.inc.php';
+
+$export_page_title = __('View dump (schema) of databases') . "\n";
+
+$multi_values = '<div style="text-align: left">';
+$multi_values .= '<a href="#"';
+$multi_values .= ' onclick="setSelectOptions(\'dump\', \'db_select[]\', true); return false;">';
+$multi_values .= __('Select All');
+$multi_values .= '</a>';
+$multi_values .= ' / ';
+$multi_values .= '<a href="#"';
+$multi_values .= ' onclick="setSelectOptions(\'dump\', \'db_select[]\', false); return false;">';
+$multi_values .= __('Unselect All') . '</a><br />';
+
+$multi_values .= '<select name="db_select[]" id="db_select" size="10" multiple="multiple">';
+$multi_values .= "\n";
+
+// Check if the selected databases are defined in $_GET (from clicking Back button on export.php)
+if (isset($_GET['db_select'])) {
+    $_GET['db_select'] = urldecode($_GET['db_select']);
+    $_GET['db_select'] = explode(",", $_GET['db_select']);
+}
+
+foreach ($GLOBALS['pma']->databases as $current_db) {
+    if ($current_db == 'information_schema'
+        || $current_db == 'performance_schema'
+        || $current_db == 'mysql'
+    ) {
+        continue;
+    }
+    if (isset($_GET['db_select'])) {
+        if (in_array($current_db, $_GET['db_select'])) {
+            $is_selected = ' selected="selected"';
+        } else {
+            $is_selected = '';
+        }
+    } elseif (isset($tmp_select)) {
+        if (strpos(' ' . $tmp_select, '|' . $current_db . '|')) {
+            $is_selected = ' selected="selected"';
+        } else {
+            $is_selected = '';
+        }
+    } else {
+        $is_selected = ' selected="selected"';
+    }
+    $current_db   = htmlspecialchars($current_db);
+    $multi_values .= '                <option value="' . $current_db . '"'
+        . $is_selected . '>' . $current_db . '</option>' . "\n";
+} // end while
+$multi_values .= "\n";
+$multi_values .= '</select></div>';
+
+$export_type = 'server';
+require_once 'libraries/display_export.lib.php';
+
+?>
diff --git a/phpmyadmin/server_import.php b/phpmyadmin/server_import.php
new file mode 100644
index 0000000..2a7d38f
--- /dev/null
+++ b/phpmyadmin/server_import.php
@@ -0,0 +1,27 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ *
+ * @package PhpMyAdmin
+ */
+
+/**
+ *
+ */
+require_once 'libraries/common.inc.php';
+
+$response = PMA_Response::getInstance();
+$header   = $response->getHeader();
+$scripts  = $header->getScripts();
+$scripts->addFile('import.js');
+
+/**
+ * Does the common work
+ */
+require 'libraries/server_common.inc.php';
+
+$import_type = 'server';
+require 'libraries/display_import.lib.php';
+
+?>
+
diff --git a/phpmyadmin/server_plugins.php b/phpmyadmin/server_plugins.php
new file mode 100644
index 0000000..ffaf6ab
--- /dev/null
+++ b/phpmyadmin/server_plugins.php
@@ -0,0 +1,184 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ *
+ * @package PhpMyAdmin
+ */
+
+/**
+ * requirements
+ */
+require_once 'libraries/common.inc.php';
+
+/**
+ * JS includes
+ */
+$response = PMA_Response::getInstance();
+$header   = $response->getHeader();
+$scripts  = $header->getScripts();
+$scripts->addFile('jquery/jquery.tablesorter.js');
+$scripts->addFile('server_plugins.js');
+
+/**
+ * Does the common work
+ */
+require 'libraries/server_common.inc.php';
+
+/**
+ * Displays the sub-page heading
+ */
+echo '<h2>' . "\n"
+   . PMA_Util::getImage('b_engine.png')
+   . "\n" . __('Plugins') . "\n"
+   . '</h2>' . "\n";
+
+/**
+ * Prepare plugin list
+ */
+$sql = "SELECT p.plugin_name, p.plugin_type, p.is_active, m.module_name, m.module_library,
+        m.module_version, m.module_author, m.module_description, m.module_license
+    FROM data_dictionary.plugins p
+        JOIN data_dictionary.modules m USING (module_name)
+    ORDER BY m.module_name, p.plugin_type, p.plugin_name";
+$res = PMA_DBI_query($sql);
+$plugins = array();
+$modules = array();
+while ($row = PMA_DBI_fetch_assoc($res)) {
+    $plugins[$row['plugin_type']][] = $row;
+    $modules[$row['module_name']]['info'] = $row;
+    $modules[$row['module_name']]['plugins'][$row['plugin_type']][] = $row;
+}
+PMA_DBI_free_result($res);
+
+// sort plugin list (modules are already sorted)
+ksort($plugins);
+
+/**
+ * Displays the page
+ */
+?>
+<script type="text/javascript">
+pma_theme_image = '<?php echo $GLOBALS['pmaThemeImage']; ?>';
+</script>
+<div id="pluginsTabs">
+    <ul>
+        <li><a href="#plugins_plugins"><?php echo __('Plugins'); ?></a></li>
+        <li><a href="#plugins_modules"><?php echo __('Modules'); ?></a></li>
+    </ul>
+
+    <div id="plugins_plugins">
+        <div id="sectionlinks">
+        <?php
+        foreach ($plugins as $plugin_type => $plugin_list) {
+            $key = 'plugins-' . preg_replace('/[^a-z]/', '', strtolower($plugin_type));
+            echo '<a href="#' . $key . '">' . htmlspecialchars($plugin_type) . '</a>' . "\n";
+        }
+        ?>
+        </div>
+        <br />
+        <?php
+        foreach ($plugins as $plugin_type => $plugin_list) {
+            $key = 'plugins-' . preg_replace('/[^a-z]/', '', strtolower($plugin_type));
+            sort($plugin_list);
+            ?>
+            <table class="data_full_width" id="<?php echo $key; ?>">
+            <caption class="tblHeaders">
+                <a class="top" href="#serverinfo"><?php
+                    echo __('Begin');
+                    echo PMA_Util::getImage('s_asc.png');
+                    ?></a>
+                <?php echo htmlspecialchars($plugin_type); ?>
+            </caption>
+            <thead>
+                <tr>
+                    <th><?php echo __('Plugin'); ?></th>
+                    <th><?php echo __('Module'); ?></th>
+                    <th><?php echo __('Library'); ?></th>
+                    <th><?php echo __('Version'); ?></th>
+                    <th><?php echo __('Author'); ?></th>
+                    <th><?php echo __('License'); ?></th>
+                </tr>
+            </thead>
+            <tbody>
+            <?php
+            $odd_row = false;
+            foreach ($plugin_list as $plugin) {
+                $odd_row = !$odd_row;
+            ?>
+            <tr class="noclick <?php echo $odd_row ? 'odd' : 'even'; ?>">
+                <th><?php echo htmlspecialchars($plugin['plugin_name']); ?></th>
+                <td><?php echo htmlspecialchars($plugin['module_name']); ?></td>
+                <td><?php echo htmlspecialchars($plugin['module_library']); ?></td>
+                <td><?php echo htmlspecialchars($plugin['module_version']); ?></td>
+                <td><?php echo htmlspecialchars($plugin['module_author']); ?></td>
+                <td><?php echo htmlspecialchars($plugin['module_license']); ?></td>
+            </tr>
+            <?php
+            }
+            ?>
+            </tbody>
+            </table>
+            <?php
+        }
+        ?>
+    </div>
+    <div id="plugins_modules">
+        <table class="data_full_width">
+        <thead>
+            <tr>
+                <th><?php echo __('Module'); ?></th>
+                <th><?php echo __('Description'); ?></th>
+                <th><?php echo __('Library'); ?></th>
+                <th><?php echo __('Version'); ?></th>
+                <th><?php echo __('Author'); ?></th>
+                <th><?php echo __('License'); ?></th>
+            </tr>
+        </thead>
+        <tbody>
+        <?php
+        $odd_row = false;
+        foreach ($modules as $module_name => $module) {
+            $odd_row = !$odd_row;
+        ?>
+            <tr class="noclick <?php echo $odd_row ? 'odd' : 'even'; ?>">
+                <th rowspan="2"><?php echo htmlspecialchars($module_name); ?></th>
+                <td><?php echo htmlspecialchars($module['info']['module_description']); ?></td>
+                <td><?php echo htmlspecialchars($module['info']['module_library']); ?></td>
+                <td><?php echo htmlspecialchars($module['info']['module_version']); ?></td>
+                <td><?php echo htmlspecialchars($module['info']['module_author']); ?></td>
+                <td><?php echo htmlspecialchars($module['info']['module_license']); ?></td>
+            </tr>
+            <tr class="noclick <?php echo $odd_row ? 'odd' : 'even'; ?>">
+                <td colspan="5">
+                    <table>
+                        <tbody>
+                        <?php
+                        foreach ($module['plugins'] as $plugin_type => $plugin_list) {
+                        ?>
+                            <tr class="noclick">
+                                <td><b class="plugin-type"><?php echo htmlspecialchars($plugin_type); ?></b></td>
+                                <td>
+                                <?php
+                                for ($i = 0; $i < count($plugin_list); $i++) {
+                                    echo ($i != 0 ? '<br />' : '') . htmlspecialchars($plugin_list[$i]['plugin_name']);
+                                    if (!$plugin_list[$i]['is_active']) {
+                                        echo ' <small class="attention">' . __('disabled') . '</small>';
+                                    }
+                                }
+                                ?>
+                                </td>
+                            </tr>
+                        <?php
+                        }
+                        ?>
+                        </tbody>
+                    </table>
+                </td>
+            </tr>
+        <?php
+        }
+        ?>
+        </tbody>
+        </table>
+    </div>
+</div>
diff --git a/phpmyadmin/server_privileges.php b/phpmyadmin/server_privileges.php
new file mode 100644
index 0000000..244ace4
--- /dev/null
+++ b/phpmyadmin/server_privileges.php
@@ -0,0 +1,490 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ *
+ * @package PhpMyAdmin
+ */
+
+/**
+ *
+ */
+require_once 'libraries/common.inc.php';
+
+/**
+ * functions implementation for this script
+ */
+require_once 'libraries/display_change_password.lib.php';
+require_once 'libraries/server_privileges.lib.php';
+
+/**
+ * Does the common work
+ */
+$response = PMA_Response::getInstance();
+$header   = $response->getHeader();
+$scripts  = $header->getScripts();
+$scripts->addFile('server_privileges.js');
+
+$_add_user_error = false;
+
+if (isset ($_REQUEST['username'])) {
+    $username = $_REQUEST['username'];
+}
+if (isset ($_REQUEST['hostname'])) {
+    $hostname = $_REQUEST['hostname'];
+}
+
+/**
+ * Sets globals from $_POST patterns, for privileges and max_* vars
+ */
+
+$post_patterns = array(
+    '/_priv$/i',
+    '/^max_/i'
+);
+foreach (array_keys($_POST) as $post_key) {
+    foreach ($post_patterns as $one_post_pattern) {
+        if (preg_match($one_post_pattern, $post_key)) {
+            $GLOBALS[$post_key] = $_POST[$post_key];
+        }
+    }
+}
+
+require 'libraries/server_common.inc.php';
+
+$conditional_class = 'ajax';
+
+/**
+ * Messages are built using the message name
+ */
+$strPrivDescAllPrivileges = __('Includes all privileges except GRANT.');
+$strPrivDescAlter = __('Allows altering the structure of existing tables.');
+$strPrivDescAlterRoutine = __('Allows altering and dropping stored routines.');
+$strPrivDescCreateDb = __('Allows creating new databases and tables.');
+$strPrivDescCreateRoutine = __('Allows creating stored routines.');
+$strPrivDescCreateTbl = __('Allows creating new tables.');
+$strPrivDescCreateTmpTable = __('Allows creating temporary tables.');
+$strPrivDescCreateUser = __('Allows creating, dropping and renaming user accounts.');
+$strPrivDescCreateView = __('Allows creating new views.');
+$strPrivDescDelete = __('Allows deleting data.');
+$strPrivDescDropDb = __('Allows dropping databases and tables.');
+$strPrivDescDropTbl = __('Allows dropping tables.');
+$strPrivDescEvent = __('Allows to set up events for the event scheduler');
+$strPrivDescExecute = __('Allows executing stored routines.');
+$strPrivDescFile = __('Allows importing data from and exporting data into files.');
+$strPrivDescGrant = __('Allows adding users and privileges without reloading the privilege tables.');
+$strPrivDescIndex = __('Allows creating and dropping indexes.');
+$strPrivDescInsert = __('Allows inserting and replacing data.');
+$strPrivDescLockTables = __('Allows locking tables for the current thread.');
+$strPrivDescMaxConnections = __('Limits the number of new connections the user may open per hour.');
+$strPrivDescMaxQuestions = __('Limits the number of queries the user may send to the server per hour.');
+$strPrivDescMaxUpdates = __('Limits the number of commands that change any table or database the user may execute per hour.');
+$strPrivDescMaxUserConnections = __('Limits the number of simultaneous connections the user may have.');
+$strPrivDescProcess = __('Allows viewing processes of all users');
+$strPrivDescReferences = __('Has no effect in this MySQL version.');
+$strPrivDescReload = __('Allows reloading server settings and flushing the server\'s caches.');
+$strPrivDescReplClient = __('Allows the user to ask where the slaves / masters are.');
+$strPrivDescReplSlave = __('Needed for the replication slaves.');
+$strPrivDescSelect = __('Allows reading data.');
+$strPrivDescShowDb = __('Gives access to the complete list of databases.');
+$strPrivDescShowView = __('Allows performing SHOW CREATE VIEW queries.');
+$strPrivDescShutdown = __('Allows shutting down the server.');
+$strPrivDescSuper = __('Allows connecting, even if maximum number of connections is reached; required for most administrative operations like setting global variables or killing threads of other users.');
+$strPrivDescTrigger = __('Allows creating and dropping triggers');
+$strPrivDescUpdate = __('Allows changing data.');
+$strPrivDescUsage = __('No privileges.');
+
+/**
+ * Checks if a dropdown box has been used for selecting a database / table
+ */
+if (PMA_isValid($_REQUEST['pred_tablename'])) {
+    $tablename = $_REQUEST['pred_tablename'];
+} elseif (PMA_isValid($_REQUEST['tablename'])) {
+    $tablename = $_REQUEST['tablename'];
+} else {
+    unset($tablename);
+}
+
+if (PMA_isValid($_REQUEST['pred_dbname'])) {
+    $dbname = $_REQUEST['pred_dbname'];
+    unset($pred_dbname);
+} elseif (PMA_isValid($_REQUEST['dbname'])) {
+    $dbname = $_REQUEST['dbname'];
+} else {
+    unset($dbname);
+    unset($tablename);
+}
+
+if (isset($dbname)) {
+    $unescaped_db = PMA_Util::unescapeMysqlWildcards($dbname);
+    $db_and_table = PMA_Util::backquote($unescaped_db) . '.';
+    if (isset($tablename)) {
+        $db_and_table .= PMA_Util::backquote($tablename);
+    } else {
+        $db_and_table .= '*';
+    }
+} else {
+    $db_and_table = '*.*';
+}
+
+// check if given $dbname is a wildcard or not
+if (isset($dbname)) {
+    //if (preg_match('/\\\\(?:_|%)/i', $dbname)) {
+    if (preg_match('/(?<!\\\\)(?:_|%)/i', $dbname)) {
+        $dbname_is_wildcard = true;
+    } else {
+        $dbname_is_wildcard = false;
+    }
+}
+
+/**
+ * Checks if the user is allowed to do what he tries to...
+ */
+if (! $is_superuser) {
+    $response->addHTML(
+        '<h2>' . "\n"
+        . PMA_Util::getIcon('b_usrlist.png')
+        . __('Privileges') . "\n"
+        . '</h2>' . "\n"
+    );
+    $response->addHTML(PMA_Message::error(__('No Privileges'))->getDisplay());
+    exit;
+}
+
+/**
+ * Changes / copies a user, part I
+ */
+if (isset($_REQUEST['change_copy'])) {
+    $user_host_condition = ' WHERE `User` = '
+        . "'". PMA_Util::sqlAddSlashes($_REQUEST['old_username']) . "'"
+        . ' AND `Host` = '
+        . "'" . PMA_Util::sqlAddSlashes($_REQUEST['old_hostname']) . "';";
+    $row = PMA_DBI_fetch_single_row(
+        'SELECT * FROM `mysql`.`user` ' . $user_host_condition
+    );
+    if (! $row) {
+        PMA_Message::notice(__('No user found.'))->display();
+        unset($_REQUEST['change_copy']);
+    } else {
+        extract($row, EXTR_OVERWRITE);
+        // Recent MySQL versions have the field "Password" in mysql.user,
+        // so the previous extract creates $Password but this script
+        // uses $password
+        if (! isset($password) && isset($Password)) {
+            $password = $Password;
+        }
+        $queries = array();
+    }
+}
+
+/**
+ * Adds a user
+ *   (Changes / copies a user, part II)
+ */
+if (isset($_REQUEST['adduser_submit']) || isset($_REQUEST['change_copy'])) {
+    $sql_query = '';
+    if ($_POST['pred_username'] == 'any') {
+        $username = '';
+    }
+    switch ($_POST['pred_hostname']) {
+    case 'any':
+        $hostname = '%';
+        break;
+    case 'localhost':
+        $hostname = 'localhost';
+        break;
+    case 'hosttable':
+        $hostname = '';
+        break;
+    case 'thishost':
+        $_user_name = PMA_DBI_fetch_value('SELECT USER()');
+        $hostname = substr($_user_name, (strrpos($_user_name, '@') + 1));
+        unset($_user_name);
+        break;
+    }
+    $sql = "SELECT '1' FROM `mysql`.`user`"
+        . " WHERE `User` = '" . PMA_Util::sqlAddSlashes($username) . "'"
+        . " AND `Host` = '" . PMA_Util::sqlAddSlashes($hostname) . "';";
+    if (PMA_DBI_fetch_value($sql) == 1) {
+        $message = PMA_Message::error(__('The user %s already exists!'));
+        $message->addParam('[em]\'' . $username . '\'@\'' . $hostname . '\'[/em]');
+        $_REQUEST['adduser'] = true;
+        $_add_user_error = true;
+    } else {
+        list($create_user_real, $create_user_show, $real_sql_query, $sql_query)
+            = PMA_getSqlQueriesForDisplayAndAddUser(
+                $username, $hostname, (isset ($password) ? $password : '')
+            );
+
+        if (empty($_REQUEST['change_copy'])) {
+            $_error = false;
+
+            if (isset($create_user_real)) {
+                if (! PMA_DBI_try_query($create_user_real)) {
+                    $_error = true;
+                }
+                $sql_query = $create_user_show . $sql_query;
+            }
+            list($sql_query, $message) = PMA_addUserAndCreateDatabase(
+                $_error, $real_sql_query, $sql_query, $username, $hostname,
+                isset($dbname) ? $dbname : null
+            );
+
+        } else {
+            if (isset($create_user_real)) {
+                $queries[] = $create_user_real;
+            }
+            $queries[] = $real_sql_query;
+            // we put the query containing the hidden password in
+            // $queries_for_display, at the same position occupied
+            // by the real query in $queries
+            $tmp_count = count($queries);
+            if (isset($create_user_real)) {
+                $queries_for_display[$tmp_count - 2] = $create_user_show;
+            }
+            $queries_for_display[$tmp_count - 1] = $sql_query;
+        }
+        unset($res, $real_sql_query);
+    }
+}
+
+/**
+ * Changes / copies a user, part III
+ */
+if (isset($_REQUEST['change_copy'])) {
+    $queries = PMA_getDbSpecificPrivsQueriesForChangeOrCopyUser(
+        $queries, $username, $hostname
+    );
+}
+
+/**
+ * Updates privileges
+ */
+if (! empty($_POST['update_privs'])) {
+    list($sql_query, $message) = PMA_updatePrivileges(
+        $username,
+        $hostname,
+        (isset($tablename) ? $tablename : ''),
+        (isset($dbname) ? $dbname : '')
+    );
+}
+
+/**
+ * Revokes Privileges
+ */
+if (isset($_REQUEST['revokeall'])) {
+    list ($message, $sql_query) = PMA_getMessageAndSqlQueryForPrivilegesRevoke(
+        $db_and_table,
+        (isset($dbname) ? $dbname : ''),
+        (isset($tablename) ? $tablename : ''),
+        $username, $hostname
+    );
+}
+
+/**
+ * Updates the password
+ */
+if (isset($_REQUEST['change_pw'])) {
+    $message = PMA_getMessageForUpdatePassword(
+        $err_url, $username, $hostname
+    );
+}
+
+/**
+ * Deletes users
+ *   (Changes / copies a user, part IV)
+ */
+if (isset($_REQUEST['delete'])
+    || (isset($_REQUEST['change_copy']) && $_REQUEST['mode'] < 4)
+) {
+    if (isset($_REQUEST['change_copy'])) {
+        $selected_usr = array(
+            $_REQUEST['old_username'] . '&#27;' . $_REQUEST['old_hostname']
+        );
+    } else {
+        $selected_usr = $_REQUEST['selected_usr'];
+        $queries = array();
+    }
+    foreach ($selected_usr as $each_user) {
+        list($this_user, $this_host) = explode('&#27;', $each_user);
+        $queries[] = '# '
+            . sprintf(
+                __('Deleting %s'),
+                '\'' . $this_user . '\'@\'' . $this_host . '\''
+            )
+            . ' ...';
+        $queries[] = 'DROP USER \''
+            . PMA_Util::sqlAddSlashes($this_user)
+            . '\'@\'' . PMA_Util::sqlAddSlashes($this_host) . '\';';
+
+        if (isset($_REQUEST['drop_users_db'])) {
+            $queries[] = 'DROP DATABASE IF EXISTS '
+                . PMA_Util::backquote($this_user) . ';';
+            $GLOBALS['reload'] = true;
+        }
+    }
+    if (empty($_REQUEST['change_copy'])) {
+        list($sql_query, $message) = PMA_deleteUser($queries);
+    }
+}
+
+/**
+ * Changes / copies a user, part V
+ */
+if (isset($_REQUEST['change_copy'])) {
+    $tmp_count = 0;
+    foreach ($queries as $sql_query) {
+        if ($sql_query{0} != '#') {
+            PMA_DBI_query($sql_query);
+        }
+        // when there is a query containing a hidden password, take it
+        // instead of the real query sent
+        if (isset($queries_for_display[$tmp_count])) {
+            $queries[$tmp_count] = $queries_for_display[$tmp_count];
+        }
+        $tmp_count++;
+    }
+    $message = PMA_Message::success();
+    $sql_query = join("\n", $queries);
+}
+
+/**
+ * Reloads the privilege tables into memory
+ */
+if (isset($_REQUEST['flush_privileges'])) {
+    $sql_query = 'FLUSH PRIVILEGES;';
+    PMA_DBI_query($sql_query);
+    $message = PMA_Message::success(__('The privileges were reloaded successfully.'));
+}
+
+/**
+ * some standard links
+ */
+list($link_edit, $link_revoke, $link_export)
+    = PMA_getStandardLinks($conditional_class);
+
+/**
+ * If we are in an Ajax request for Create User/Edit User/Revoke User/
+ * Flush Privileges, show $message and exit.
+ */
+if ($GLOBALS['is_ajax_request']
+    && empty($_REQUEST['ajax_page_request'])
+    && ! isset($_REQUEST['export'])
+    && (! isset($_REQUEST['submit_mult']) || $_REQUEST['submit_mult'] != 'export')
+    && (! isset($_REQUEST['adduser']) || $_add_user_error)
+    && (! isset($_REQUEST['initial']) || empty($_REQUEST['initial']))
+    && ! isset($_REQUEST['showall'])
+    && ! isset($_REQUEST['edit_user_dialog'])
+    && ! isset($_REQUEST['db_specific'])
+) {
+    $extra_data = PMA_getExtraDataForAjaxBehavior(
+        (isset($password) ? $password : ''),
+        $link_export,
+        (isset($sql_query) ? $sql_query : ''),
+        $link_edit,
+        (isset($hostname) ? $hostname : ''),
+        (isset($username) ? $username : '')
+    );
+
+    if (! empty($message) && $message instanceof PMA_Message) {
+        $response = PMA_Response::getInstance();
+        $response->isSuccess($message->isSuccess());
+        $response->addJSON('message', $message);
+        $response->addJSON($extra_data);
+        exit;
+    }
+}
+
+/**
+ * Displays the links
+ */
+if (isset($_REQUEST['viewing_mode']) && $_REQUEST['viewing_mode'] == 'db') {
+    $_REQUEST['db'] = $_REQUEST['checkprivs'];
+
+    $url_query .= '&goto=db_operations.php';
+
+    // Gets the database structure
+    $sub_part = '_structure';
+    ob_start();
+    include 'libraries/db_info.inc.php';
+    $content = ob_get_contents();
+    ob_end_clean();
+    $response->addHTML($content . "\n");
+} else {
+    if (! empty($GLOBALS['message'])) {
+        $response->addHTML(PMA_Util::getMessage($GLOBALS['message']));
+        unset($GLOBALS['message']);
+    }
+}
+
+/**
+ * Displays the page
+ */
+
+// export user definition
+if (isset($_REQUEST['export'])
+    || (isset($_REQUEST['submit_mult']) && $_REQUEST['submit_mult'] == 'export')
+) {
+    list($title, $export) = PMA_getHtmlForExportUserDefinition(
+        isset($username) ? $username : null,
+        isset($hostname) ? $hostname : null
+    );
+
+    unset($username, $hostname, $grants, $one_grant);
+
+    $response = PMA_Response::getInstance();
+    if ($GLOBALS['is_ajax_request']) {
+        $response->addJSON('message', $export);
+        $response->addJSON('title', $title);
+        exit;
+    } else {
+        $response->addHTML("<h2>$title</h2>$export");
+    }
+}
+
+if (empty($_REQUEST['adduser'])
+    && (! isset($_REQUEST['checkprivs'])
+    || ! strlen($_REQUEST['checkprivs']))
+) {
+    if (! isset($username)) {
+        // No username is given --> display the overview
+        $response->addHTML(
+            PMA_getHtmlForDisplayUserOverviewPage(
+                $link_edit, $pmaThemeImage, $text_dir,
+                $conditional_class, $link_export
+            )
+        );
+    } else {
+        // A user was selected -> display the user's properties
+
+        // In an Ajax request, prevent cached values from showing
+        if ($GLOBALS['is_ajax_request'] == true) {
+            header('Cache-Control: no-cache');
+        }
+        $url_dbname = urlencode(
+            str_replace(
+                array('\_', '\%'),
+                array('_', '%'), $_REQUEST['dbname']
+            )
+        );
+        $response->addHTML(
+            PMA_getHtmlForDisplayUserProperties(
+                ((isset ($dbname_is_wildcard)) ? $dbname_is_wildcard : ''),
+                $url_dbname, $username, $hostname, $link_edit, $link_revoke,
+                (isset($dbname) ? $dbname : ''),
+                (isset($tablename) ? $tablename : '')
+            )
+        );
+    }
+} elseif (isset($_REQUEST['adduser'])) {
+    // Add user
+    $response->addHTML(
+        PMA_getHtmlForAddUser((isset($dbname) ? $dbname : ''))
+    );
+} else {
+    // check the privileges for a particular database.
+    $response->addHTML(
+        PMA_getHtmlForSpecificDbPrivileges($link_edit, $conditional_class)
+    );
+} // end if (empty($_REQUEST['adduser']) && empty($checkprivs))... elseif... else...
+
+?>
diff --git a/phpmyadmin/server_replication.php b/phpmyadmin/server_replication.php
new file mode 100644
index 0000000..37a48d2
--- /dev/null
+++ b/phpmyadmin/server_replication.php
@@ -0,0 +1,349 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ *
+ * @package PhpMyAdmin
+ */
+
+/**
+ *
+ */
+require_once 'libraries/common.inc.php';
+
+/**
+ * Does the common work
+ */
+$response = PMA_Response::getInstance();
+$header   = $response->getHeader();
+$scripts  = $header->getScripts();
+$scripts->addFile('server_privileges.js');
+$scripts->addFile('replication.js');
+
+require 'libraries/server_common.inc.php';
+require 'libraries/replication.inc.php';
+require 'libraries/replication_gui.lib.php';
+
+/**
+ * Checks if the user is allowed to do what he tries to...
+ */
+if (! $is_superuser) {
+    echo '<h2>' . "\n"
+        . PMA_Util::getIcon('s_replication.png')
+        . __('Replication') . "\n"
+        . '</h2>' . "\n";
+    PMA_Message::error(__('No Privileges'))->display();
+    exit;
+}
+
+/**
+ * Sets globals from $_REQUEST
+ */
+$request_params = array(
+    'hostname',
+    'mr_adduser',
+    'mr_configure',
+    'pma_pw',
+    'port',
+    'repl_clear_scr',
+    'repl_data',
+    'sl_configure',
+    'slave_changemaster',
+    'sr_skip_errors_count',
+    'sr_slave_action',
+    'sr_slave_control_parm',
+    'sr_slave_server_control',
+    'sr_slave_skip_error',
+    'sr_take_action',
+    'url_params',
+    'username'
+);
+
+foreach ($request_params as $one_request_param) {
+    if (isset($_REQUEST[$one_request_param])) {
+        $GLOBALS[$one_request_param] = $_REQUEST[$one_request_param];
+    }
+}
+
+/**
+ * Handling control requests
+ */
+if (isset($GLOBALS['sr_take_action'])) {
+    $refresh = false;
+    if (isset($GLOBALS['slave_changemaster'])) {
+        $_SESSION['replication']['m_username'] = $sr['username'] = PMA_Util::sqlAddSlashes($GLOBALS['username']);
+        $_SESSION['replication']['m_password'] = $sr['pma_pw']   = PMA_Util::sqlAddSlashes($GLOBALS['pma_pw']);
+        $_SESSION['replication']['m_hostname'] = $sr['hostname'] = PMA_Util::sqlAddSlashes($GLOBALS['hostname']);
+        $_SESSION['replication']['m_port']     = $sr['port']     = PMA_Util::sqlAddSlashes($GLOBALS['port']);
+        $_SESSION['replication']['m_correct']  = '';
+        $_SESSION['replication']['sr_action_status'] = 'error';
+        $_SESSION['replication']['sr_action_info'] = __('Unknown error');
+
+        // Attempt to connect to the new master server
+        $link_to_master = PMA_replication_connect_to_master(
+            $sr['username'], $sr['pma_pw'], $sr['hostname'], $sr['port']
+        );
+
+        if (! $link_to_master) {
+            $_SESSION['replication']['sr_action_status'] = 'error';
+            $_SESSION['replication']['sr_action_info'] = sprintf(
+                __('Unable to connect to master %s.'),
+                htmlspecialchars($sr['hostname'])
+            );
+        } else {
+            // Read the current master position
+            $position = PMA_replication_slave_bin_log_master($link_to_master);
+
+            if (empty($position)) {
+                $_SESSION['replication']['sr_action_status'] = 'error';
+                $_SESSION['replication']['sr_action_info'] = __('Unable to read master log position. Possible privilege problem on master.');
+            } else {
+                $_SESSION['replication']['m_correct']  = true;
+
+                if (! PMA_replication_slave_change_master($sr['username'], $sr['pma_pw'], $sr['hostname'], $sr['port'], $position, true, false)) {
+                    $_SESSION['replication']['sr_action_status'] = 'error';
+                    $_SESSION['replication']['sr_action_info'] = __('Unable to change master');
+                } else {
+                    $_SESSION['replication']['sr_action_status'] = 'success';
+                    $_SESSION['replication']['sr_action_info'] = sprintf(
+                        __('Master server changed successfully to %s'),
+                        htmlspecialchars($sr['hostname'])
+                    );
+                }
+            }
+        }
+    } elseif (isset($GLOBALS['sr_slave_server_control'])) {
+        if ($GLOBALS['sr_slave_action'] == 'reset') {
+            PMA_replication_slave_control("STOP");
+            PMA_DBI_try_query("RESET SLAVE;");
+            PMA_replication_slave_control("START");
+        } else {
+            PMA_replication_slave_control(
+                $GLOBALS['sr_slave_action'],
+                $GLOBALS['sr_slave_control_parm']
+            );
+        }
+        $refresh = true;
+
+    } elseif (isset($GLOBALS['sr_slave_skip_error'])) {
+        $count = 1;
+        if (isset($GLOBALS['sr_skip_errors_count'])) {
+            $count = $GLOBALS['sr_skip_errors_count'] * 1;
+        }
+        PMA_replication_slave_control("STOP");
+        PMA_DBI_try_query("SET GLOBAL SQL_SLAVE_SKIP_COUNTER = ".$count.";");
+        PMA_replication_slave_control("START");
+
+    }
+
+    if ($refresh) {
+        Header("Location: server_replication.php" . PMA_generate_common_url($GLOBALS['url_params']));
+    }
+    unset($refresh);
+}
+
+
+echo '<div id="replication">';
+echo ' <h2>';
+echo '   ' . PMA_Util::getImage('s_replication.png');
+echo     __('Replication');
+echo ' </h2>';
+
+// Display error messages
+if (isset($_SESSION['replication']['sr_action_status'])
+    && isset($_SESSION['replication']['sr_action_info'])
+) {
+    if ($_SESSION['replication']['sr_action_status'] == 'error') {
+        PMA_Message::error($_SESSION['replication']['sr_action_info'])->display();
+        $_SESSION['replication']['sr_action_status'] = 'unknown';
+    } elseif ($_SESSION['replication']['sr_action_status'] == 'success') {
+        PMA_Message::success($_SESSION['replication']['sr_action_info'])->display();
+        $_SESSION['replication']['sr_action_status'] = 'unknown';
+    }
+}
+
+if ($server_master_status) {
+    if (! isset($GLOBALS['repl_clear_scr'])) {
+        echo '<fieldset>';
+        echo '<legend>' . __('Master replication') . '</legend>';
+        echo __('This server is configured as master in a replication process.');
+        echo '<ul>';
+        echo '  <li><a href="#" id="master_status_href">' . __('Show master status') . '</a>';
+        PMA_replication_print_status_table('master', true, false);
+        echo '  </li>';
+
+        echo '  <li><a href="#" id="master_slaves_href">' . __('Show connected slaves') . '</a>';
+        PMA_replication_print_slaves_table(true);
+        echo '  </li>';
+
+        $_url_params = $GLOBALS['url_params'];
+        $_url_params['mr_adduser'] = true;
+        $_url_params['repl_clear_scr'] = true;
+
+        echo '  <li><a href="server_replication.php' . PMA_generate_common_url($_url_params) . '" id="master_addslaveuser_href">';
+        echo __('Add slave replication user') . '</a></li>';
+    }
+
+    // Display 'Add replication slave user' form
+    if (isset($GLOBALS['mr_adduser'])) {
+        PMA_replication_gui_master_addslaveuser();
+    } elseif (! isset($GLOBALS['repl_clear_scr'])) {
+        echo "</ul>";
+        echo "</fieldset>";
+    }
+} elseif (! isset($GLOBALS['mr_configure']) && ! isset($GLOBALS['repl_clear_scr'])) {
+    $_url_params = $GLOBALS['url_params'];
+    $_url_params['mr_configure'] = true;
+
+    echo '<fieldset>';
+    echo '<legend>' . __('Master replication') . '</legend>';
+    echo sprintf(__('This server is not configured as master in a replication process. Would you like to <a href="%s">configure</a> it?'), 'server_replication.php' . PMA_generate_common_url($_url_params));
+    echo '</fieldset>';
+}
+
+if (isset($GLOBALS['mr_configure'])) {
+    // Render the 'Master configuration' section
+    echo '<fieldset>';
+    echo '<legend>' . __('Master configuration') . '</legend>';
+    echo __('This server is not configured as master server in a replication process. You can choose from either replicating all databases and ignoring certain (useful if you want to replicate majority of databases) or you can choose to ignore all databases by default and allow only certain databases to be replicated. Please select the mode:') . '<br /><br />';
+
+    echo '<select name="db_type" id="db_type">';
+    echo '<option value="all">' . __('Replicate all databases; Ignore:') . '</option>';
+    echo '<option value="ign">' . __('Ignore all databases; Replicate:') . '</option>';
+    echo '</select>';
+    echo '<br /><br />';
+    echo __('Please select databases:') . '<br />';
+    echo PMA_replication_db_multibox();
+    echo '<br /><br />';
+    echo __('Now, add the following lines at the end of [mysqld] section in your my.cnf and please restart the MySQL server afterwards.') . '<br />';
+    echo '<pre id="rep"></pre>';
+    echo __('Once you restarted MySQL server, please click on Go button. Afterwards, you should see a message informing you, that this server <b>is</b> configured as master');
+    echo '</fieldset>';
+    echo '<fieldset class="tblFooters">';
+    echo ' <form method="post" action="server_replication.php" >';
+    echo PMA_generate_common_hidden_inputs('', '');
+    echo '  <input type="submit" value="' . __('Go') . '" id="goButton" />';
+    echo ' </form>';
+    echo '</fieldset>';
+
+    exit;
+}
+
+echo '</div>';
+
+if (! isset($GLOBALS['repl_clear_scr'])) {
+    // Render the 'Slave configuration' section
+    echo '<fieldset>';
+    echo '<legend>' . __('Slave replication') . '</legend>';
+    if ($server_slave_status) {
+        echo '<div id="slave_configuration_gui">';
+
+        $_url_params = $GLOBALS['url_params'];
+        $_url_params['sr_take_action'] = true;
+        $_url_params['sr_slave_server_control'] = true;
+
+        if ($server_slave_replication[0]['Slave_IO_Running'] == 'No') {
+            $_url_params['sr_slave_action'] = 'start';
+        } else {
+            $_url_params['sr_slave_action'] = 'stop';
+        }
+
+        $_url_params['sr_slave_control_parm'] = 'IO_THREAD';
+        $slave_control_io_link = 'server_replication.php' . PMA_generate_common_url($_url_params);
+
+        if ($server_slave_replication[0]['Slave_SQL_Running'] == 'No') {
+            $_url_params['sr_slave_action'] = 'start';
+        } else {
+            $_url_params['sr_slave_action'] = 'stop';
+        }
+
+        $_url_params['sr_slave_control_parm'] = 'SQL_THREAD';
+        $slave_control_sql_link = 'server_replication.php' . PMA_generate_common_url($_url_params);
+
+        if ($server_slave_replication[0]['Slave_IO_Running'] == 'No'
+            || $server_slave_replication[0]['Slave_SQL_Running'] == 'No'
+        ) {
+            $_url_params['sr_slave_action'] = 'start';
+        } else {
+            $_url_params['sr_slave_action'] = 'stop';
+        }
+
+        $_url_params['sr_slave_control_parm'] = null;
+        $slave_control_full_link = 'server_replication.php' . PMA_generate_common_url($_url_params);
+
+        $_url_params['sr_slave_action'] = 'reset';
+        $slave_control_reset_link = 'server_replication.php' . PMA_generate_common_url($_url_params);
+
+        $_url_params = $GLOBALS['url_params'];
+        $_url_params['sr_slave_skip_error'] = true;
+        $slave_skip_error_link = 'server_replication.php' . PMA_generate_common_url($_url_params);
+
+        if ($server_slave_replication[0]['Slave_SQL_Running'] == 'No') {
+            PMA_Message::error(__('Slave SQL Thread not running!'))->display();
+        }
+        if ($server_slave_replication[0]['Slave_IO_Running'] == 'No') {
+            PMA_Message::error(__('Slave IO Thread not running!'))->display();
+        }
+
+        $_url_params = $GLOBALS['url_params'];
+        $_url_params['sl_configure'] = true;
+        $_url_params['repl_clear_scr'] = true;
+
+        $reconfiguremaster_link = 'server_replication.php' . PMA_generate_common_url($_url_params);
+
+        echo __('Server is configured as slave in a replication process. Would you like to:');
+        echo '<br />';
+        echo '<ul>';
+        echo ' <li><a href="#" id="slave_status_href">' . __('See slave status table') . '</a>';
+        PMA_replication_print_status_table('slave', true, false);
+        echo ' </li>';
+
+        echo ' <li><a href="#" id="slave_control_href">' . __('Control slave:') . '</a>';
+        echo ' <div id="slave_control_gui" style="display: none">';
+        echo '  <ul>';
+        echo '   <li><a href="'. $slave_control_full_link . '">' . (($server_slave_replication[0]['Slave_IO_Running'] == 'No' || $server_slave_replication[0]['Slave_SQL_Running'] == 'No') ? __('Full start') : __('Full stop')) . ' </a></li>';
+        echo '   <li><a href="'. $slave_control_reset_link . '">' . __('Reset slave') . '</a></li>';
+        if ($server_slave_replication[0]['Slave_SQL_Running'] == 'No') {
+            echo '   <li><a href="' . $slave_control_sql_link . '">' . __('Start SQL Thread only') . '</a></li>';
+        } else {
+            echo '   <li><a href="' . $slave_control_sql_link . '">' . __('Stop SQL Thread only') . '</a></li>';
+        }
+        if ($server_slave_replication[0]['Slave_IO_Running'] == 'No') {
+            echo '   <li><a href="' . $slave_control_io_link . '">' . __('Start IO Thread only') . '</a></li>';
+        } else {
+            echo '   <li><a href="' . $slave_control_io_link . '">' . __('Stop IO Thread only') . '</a></li>';
+        }
+        echo '  </ul>';
+        echo ' </div>';
+        echo ' </li>';
+        echo ' <li><a href="#" id="slave_errormanagement_href">' . __('Error management:') . '</a>';
+        echo ' <div id="slave_errormanagement_gui" style="display: none">';
+        PMA_Message::error(__('Skipping errors might lead into unsynchronized master and slave!'))->display();
+        echo '  <ul>';
+        echo '   <li><a href="' . $slave_skip_error_link . '">' . __('Skip current error') . '</a></li>';
+        echo '   <li>' . __('Skip next');
+        echo '    <form method="post" action="server_replication.php">';
+        echo PMA_generate_common_hidden_inputs('', '');
+        echo '      <input type="text" name="sr_skip_errors_count" value="1" style="width: 30px" />' . __('errors.');
+        echo '              <input type="submit" name="sr_slave_skip_error" value="' . __('Go') . '" />';
+        echo '      <input type="hidden" name="sr_take_action" value="1" />';
+        echo '    </form></li>';
+        echo '  </ul>';
+        echo ' </div>';
+        echo ' </li>';
+        echo ' <li><a href="' . $reconfiguremaster_link . '">' . __('Change or reconfigure master server') . '</a></li>';
+        echo '</ul>';
+        echo '</div>';
+
+    } elseif (! isset($GLOBALS['sl_configure'])) {
+        $_url_params = $GLOBALS['url_params'];
+        $_url_params['sl_configure'] = true;
+        $_url_params['repl_clear_scr'] = true;
+
+        echo sprintf(__('This server is not configured as slave in a replication process. Would you like to <a href="%s">configure</a> it?'), 'server_replication.php' . PMA_generate_common_url($_url_params));
+    }
+    echo '</fieldset>';
+}
+if (isset($GLOBALS['sl_configure'])) {
+    PMA_replication_gui_changemaster("slave_changemaster");
+}
+?>
diff --git a/phpmyadmin/server_sql.php b/phpmyadmin/server_sql.php
new file mode 100644
index 0000000..408d2b2
--- /dev/null
+++ b/phpmyadmin/server_sql.php
@@ -0,0 +1,30 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ *
+ * @package PhpMyAdmin
+ */
+
+/**
+ *
+ */
+require_once 'libraries/common.inc.php';
+
+/**
+ * Does the common work
+ */
+$response = PMA_Response::getInstance();
+$header   = $response->getHeader();
+$scripts  = $header->getScripts();
+$scripts->addFile('makegrid.js');
+$scripts->addFile('sql.js');
+
+require_once 'libraries/server_common.inc.php';
+require_once 'libraries/sql_query_form.lib.php';
+
+/**
+ * Query box, bookmark, insert data from textfile
+ */
+PMA_sqlQueryForm();
+
+?>
diff --git a/phpmyadmin/server_status.php b/phpmyadmin/server_status.php
new file mode 100644
index 0000000..27d3c6a
--- /dev/null
+++ b/phpmyadmin/server_status.php
@@ -0,0 +1,496 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * object the server status page: processes, connections and traffic
+ *
+ * @package PhpMyAdmin
+ */
+
+require_once 'libraries/common.inc.php';
+require_once 'libraries/server_common.inc.php';
+require_once 'libraries/ServerStatusData.class.php';
+
+/**
+ * Replication library
+ */
+if (PMA_DRIZZLE) {
+    $server_master_status = false;
+    $server_slave_status = false;
+} else {
+    include_once 'libraries/replication.inc.php';
+    include_once 'libraries/replication_gui.lib.php';
+}
+
+$ServerStatusData = new PMA_ServerStatusData();
+
+/**
+ * Kills a selected process
+ */
+if (! empty($_REQUEST['kill'])) {
+    if (PMA_DBI_try_query('KILL ' . $_REQUEST['kill'] . ';')) {
+        $message = PMA_Message::success(__('Thread %s was successfully killed.'));
+    } else {
+        $message = PMA_Message::error(
+            __(
+                'phpMyAdmin was unable to kill thread %s.'
+                . ' It probably has already been closed.'
+            )
+        );
+    }
+    $message->addParam($_REQUEST['kill']);
+}
+
+/**
+ * start output
+ */
+$response = PMA_Response::getInstance();
+$response->addHTML('<div>');
+$response->addHTML($ServerStatusData->getMenuHtml());
+$response->addHTML(getServerTrafficHtml($ServerStatusData));
+$response->addHTML('</div>');
+
+exit;
+
+/**
+ * Prints server traffic information
+ *
+ * @param Object $ServerStatusData An instance of the PMA_ServerStatusData class
+ *
+ * @return string
+ */
+function getServerTrafficHtml($ServerStatusData)
+{
+    $hour_factor    = 3600 / $ServerStatusData->status['Uptime'];
+    $start_time = PMA_DBI_fetch_value(
+        'SELECT UNIX_TIMESTAMP() - ' . $ServerStatusData->status['Uptime']
+    );
+
+    $retval  = '<h3>';
+    $retval .= sprintf(
+        __('Network traffic since startup: %s'),
+        implode(
+            ' ',
+            PMA_Util::formatByteDown(
+                $ServerStatusData->status['Bytes_received'] + $ServerStatusData->status['Bytes_sent'],
+                3,
+                1
+            )
+        )
+    );
+    $retval .= '</h3>';
+    $retval .= '<p>';
+    $retval .= sprintf(
+        __('This MySQL server has been running for %1$s. It started up on %2$s.'),
+        PMA_Util::timespanFormat($ServerStatusData->status['Uptime']),
+        PMA_Util::localisedDate($start_time)
+    ) . "\n";
+    $retval .= '</p>';
+
+    if ($GLOBALS['server_master_status'] || $GLOBALS['server_slave_status']) {
+        $retval .= '<p class="notice">';
+        if ($GLOBALS['server_master_status'] && $GLOBALS['server_slave_status']) {
+            $retval .= __(
+                'This MySQL server works as <b>master</b> and '
+                . '<b>slave</b> in <b>replication</b> process.'
+            );
+        } elseif ($GLOBALS['server_master_status']) {
+            $retval .= __(
+                'This MySQL server works as <b>master</b> '
+                . 'in <b>replication</b> process.'
+            );
+        } elseif ($GLOBALS['server_slave_status']) {
+            $retval .= __(
+                'This MySQL server works as <b>slave</b> '
+                . 'in <b>replication</b> process.'
+            );
+        }
+        $retval .= ' ';
+        $retval .= __(
+            'For further information about replication status on the server, '
+            . 'please visit the <a href="#replication">replication section</a>.'
+        );
+        $retval .= '</p>';
+    }
+
+    /*
+     * if the server works as master or slave in replication process,
+     * display useful information
+     */
+    if ($GLOBALS['server_master_status'] || $GLOBALS['server_slave_status']) {
+        $retval .= '<hr class="clearfloat" />';
+        $retval .= '<h3><a name="replication">';
+        $retval .= __('Replication status');
+        $retval .= '</a></h3>';
+        foreach ($GLOBALS['replication_types'] as $type) {
+            if (isset(${"server_{$type}_status"}) && ${"server_{$type}_status"}) {
+                PMA_replication_print_status_table($type);
+            }
+        }
+    }
+
+    $retval .= '<table id="serverstatustraffic" class="data noclick">';
+    $retval .= '<thead>';
+    $retval .= '<tr>';
+    $retval .= '<th colspan="2">';
+    $retval .= __('Traffic') . ' ';
+    $retval .=  PMA_Util::showHint(
+        __(
+            'On a busy server, the byte counters may overrun, so those statistics '
+            . 'as reported by the MySQL server may be incorrect.'
+        )
+    );
+    $retval .= '</th>';
+    $retval .= '<th>ø ' . __('per hour') . '</th>';
+    $retval .= '</tr>';
+    $retval .= '</thead>';
+    $retval .= '<tbody>';
+    $retval .= '<tr class="odd">';
+    $retval .= '<th class="name">' . __('Received') . '</th>';
+    $retval .= '<td class="value">';
+    $retval .= implode(
+        ' ',
+        PMA_Util::formatByteDown(
+            $ServerStatusData->status['Bytes_received'], 3, 1
+        )
+    );
+    $retval .= '</td>';
+    $retval .= '<td class="value">';
+    $retval .= implode(
+        ' ',
+        PMA_Util::formatByteDown(
+            $ServerStatusData->status['Bytes_received'] * $hour_factor, 3, 1
+        )
+    );
+    $retval .= '</td>';
+    $retval .= '</tr>';
+    $retval .= '<tr class="even">';
+    $retval .= '<th class="name">' . __('Sent') . '</th>';
+    $retval .= '<td class="value">';
+    $retval .= implode(
+        ' ',
+        PMA_Util::formatByteDown(
+            $ServerStatusData->status['Bytes_sent'], 3, 1
+        )
+    );
+    $retval .= '</td>';
+    $retval .= '<td class="value"><?php echo';
+    $retval .= implode(
+        ' ',
+        PMA_Util::formatByteDown(
+            $ServerStatusData->status['Bytes_sent'] * $hour_factor, 3, 1
+        )
+    );
+    $retval .= '</td>';
+    $retval .= '</tr>';
+    $retval .= '<tr class="odd">';
+    $retval .= '<th class="name">' . __('Total') . '</th>';
+    $retval .= '<td class="value">';
+    $retval .= implode(
+        ' ',
+        PMA_Util::formatByteDown(
+            $ServerStatusData->status['Bytes_received'] + $ServerStatusData->status['Bytes_sent'], 3, 1
+        )
+    );
+    $retval .= '</td>';
+    $retval .= '<td class="value">';
+    $retval .= implode(
+        ' ',
+        PMA_Util::formatByteDown(
+            ($ServerStatusData->status['Bytes_received'] + $ServerStatusData->status['Bytes_sent'])
+            * $hour_factor, 3, 1
+        )
+    );
+    $retval .= '</td>';
+    $retval .= '</tr>';
+    $retval .= '</tbody>';
+    $retval .= '</table>';
+
+    $retval .= '<table id="serverstatusconnections" class="data noclick">';
+    $retval .= '<thead>';
+    $retval .= '<tr>';
+    $retval .= '<th colspan="2">' . __('Connections') . '</th>';
+    $retval .= '<th>ø ' . __('per hour') . '</th>';
+    $retval .= '<th>%</th>';
+    $retval .= '</tr>';
+    $retval .= '</thead>';
+    $retval .= '<tbody>';
+    $retval .= '<tr class="odd">';
+    $retval .= '<th class="name">' . __('max. concurrent connections') . '</th>';
+    $retval .= '<td class="value">';
+    $retval .= PMA_Util::formatNumber(
+        $ServerStatusData->status['Max_used_connections'], 0
+    );
+    $retval .= '</td>';
+    $retval .= '<td class="value">--- </td>';
+    $retval .= '<td class="value">--- </td>';
+    $retval .= '</tr>';
+    $retval .= '<tr class="even">';
+    $retval .= '<th class="name">' . __('Failed attempts') . '</th>';
+    $retval .= '<td class="value">';
+    $retval .= PMA_Util::formatNumber(
+        $ServerStatusData->status['Aborted_connects'], 4, 1, true
+    );
+    $retval .= '</td>';
+    $retval .= '<td class="value">';
+    $retval .= PMA_Util::formatNumber(
+        $ServerStatusData->status['Aborted_connects'] * $hour_factor, 4, 2, true
+    );
+    $retval .= '</td>';
+    $retval .= '<td class="value">';
+    if ($ServerStatusData->status['Connections'] > 0) {
+        $retval .= PMA_Util::formatNumber(
+            $ServerStatusData->status['Aborted_connects'] * 100 / $ServerStatusData->status['Connections'],
+            0, 2, true
+        );
+        $retval .= '%';
+    } else {
+        $retval .= '--- ';
+    }
+    $retval .= '</td>';
+    $retval .= '</tr>';
+    $retval .= '<tr class="odd">';
+    $retval .= '<th class="name">' . __('Aborted') . '</th>';
+    $retval .= '<td class="value">';
+    $retval .= PMA_Util::formatNumber(
+        $ServerStatusData->status['Aborted_clients'], 4, 1, true
+    );
+    $retval .= '</td>';
+    $retval .= '<td class="value">';
+    $retval .= PMA_Util::formatNumber(
+        $ServerStatusData->status['Aborted_clients'] * $hour_factor, 4, 2, true
+    );
+    $retval .= '</td>';
+    $retval .= '<td class="value">';
+    if ($ServerStatusData->status['Connections'] > 0) {
+        $retval .= PMA_Util::formatNumber(
+            $ServerStatusData->status['Aborted_clients'] * 100 / $ServerStatusData->status['Connections'],
+            0, 2, true
+        );
+        $retval .= '%';
+    } else {
+        $retval .= '--- ';
+    }
+    $retval .= '</td>';
+    $retval .= '</tr>';
+    $retval .= '<tr class="even">';
+    $retval .= '<th class="name">' . __('Total') . '</th>';
+    $retval .= '<td class="value">';
+    $retval .= PMA_Util::formatNumber(
+        $ServerStatusData->status['Connections'], 4, 0
+    );
+    $retval .= '</td>';
+    $retval .= '<td class="value">';
+    $retval .= PMA_Util::formatNumber(
+        $ServerStatusData->status['Connections'] * $hour_factor, 4, 2
+    );
+    $retval .= '</td>';
+    $retval .= '<td class="value">';
+    $retval .= PMA_Util::formatNumber(100, 0, 2);
+    $retval .= '%</td>';
+    $retval .= '</tr>';
+    $retval .= '</tbody>';
+    $retval .= '</table>';
+
+    $url_params = array();
+
+    $show_full_sql = ! empty($_REQUEST['full']);
+    if ($show_full_sql) {
+        $url_params['full'] = 1;
+        $full_text_link = 'server_status.php' . PMA_generate_common_url(
+            array(), 'html', '?'
+        );
+    } else {
+        $full_text_link = 'server_status.php' . PMA_generate_common_url(
+            array('full' => 1)
+        );
+    }
+
+    // This array contains display name and real column name of each
+    // sortable column in the table
+    $sortable_columns = array(
+        array(
+            'column_name' => __('ID'),
+            'order_by_field' => 'Id'
+        ),
+        array(
+            'column_name' => __('User'),
+            'order_by_field' => 'User'
+        ),
+        array(
+            'column_name' => __('Host'),
+            'order_by_field' => 'Host'
+        ),
+        array(
+            'column_name' => __('Database'),
+            'order_by_field' => 'db'
+        ),
+        array(
+            'column_name' => __('Command'),
+            'order_by_field' => 'Command'
+        ),
+        array(
+            'column_name' => __('Time'),
+            'order_by_field' => 'Time'
+        ),
+        array(
+            'column_name' => __('Status'),
+            'order_by_field' => 'State'
+        ),
+        array(
+            'column_name' => __('SQL query'),
+            'order_by_field' => 'Info'
+        )
+    );
+    $sortable_columns_count = count($sortable_columns);
+
+    if (PMA_DRIZZLE) {
+        $sql_query = "SELECT
+                p.id       AS Id,
+                p.username AS User,
+                p.host     AS Host,
+                p.db       AS db,
+                p.command  AS Command,
+                p.time     AS Time,
+                p.state    AS State,
+                " . ($show_full_sql ? 's.query' : 'left(p.info, ' . (int)$GLOBALS['cfg']['MaxCharactersInDisplayedSQL'] . ')') . " AS Info
+            FROM data_dictionary.PROCESSLIST p
+                " . ($show_full_sql ? 'LEFT JOIN data_dictionary.SESSIONS s ON s.session_id = p.id' : '');
+        if (! empty($_REQUEST['order_by_field'])
+            && ! empty($_REQUEST['sort_order'])
+        ) {
+            $sql_query .= ' ORDER BY p.' . $_REQUEST['order_by_field'] . ' ' . $_REQUEST['sort_order'];
+        }
+    } else {
+        $sql_query = $show_full_sql
+            ? 'SHOW FULL PROCESSLIST'
+            : 'SHOW PROCESSLIST';
+        if (! empty($_REQUEST['order_by_field'])
+            && ! empty($_REQUEST['sort_order'])
+        ) {
+            $sql_query = 'SELECT * FROM `INFORMATION_SCHEMA`.`PROCESSLIST` ORDER BY `'
+                . $_REQUEST['order_by_field'] . '` ' . $_REQUEST['sort_order'];
+        }
+    }
+
+    $result = PMA_DBI_query($sql_query);
+
+    /**
+     * Displays the page
+     */
+    $retval .= '<table id="tableprocesslist" class="data clearfloat noclick sortable">';
+    $retval .= '<thead>';
+    $retval .= '<tr>';
+    $retval .= '<th>' . __('Processes') . '</th>';
+    foreach ($sortable_columns as $column) {
+
+        $is_sorted = ! empty($_REQUEST['order_by_field'])
+            && ! empty($_REQUEST['sort_order'])
+            && ($_REQUEST['order_by_field'] == $column['order_by_field']);
+
+        $column['sort_order'] = 'ASC';
+        if ($is_sorted && $_REQUEST['sort_order'] === 'ASC') {
+            $column['sort_order'] = 'DESC';
+        }
+
+        if ($is_sorted) {
+            if ($_REQUEST['sort_order'] == 'ASC') {
+                $asc_display_style = 'inline';
+                $desc_display_style = 'none';
+            } elseif ($_REQUEST['sort_order'] == 'DESC') {
+                $desc_display_style = 'inline';
+                $asc_display_style = 'none';
+            }
+        }
+
+        $retval .= '<th>';
+        $retval .= '<a href="server_status.php' . PMA_generate_common_url($column) . '" ';
+        if ($is_sorted) {
+            $retval .= 'onmouseout="$(\'.soimg\').toggle()" '
+                . 'onmouseover="$(\'.soimg\').toggle()"';
+        }
+        $retval .= '>';
+
+        $retval .= $column['column_name'];
+
+        if ($is_sorted) {
+            $retval .= '<img class="icon ic_s_desc soimg" alt="'
+                . __('Descending') . '" title="" src="themes/dot.gif" '
+                . 'style="display: ' . $desc_display_style . '" />';
+            $retval .= '<img class="icon ic_s_asc soimg hide" alt="'
+                . __('Ascending') . '" title="" src="themes/dot.gif" '
+                . 'style="display: ' . $asc_display_style . '" />';
+        }
+
+        $retval .= '</a>';
+
+        if (! PMA_DRIZZLE && (0 === --$sortable_columns_count)) {
+            $retval .= '<a href="' . $full_text_link . '">';
+            if ($show_full_sql) {
+                $retval .= PMA_Util::getImage(
+                    's_partialtext.png',
+                    __('Truncate Shown Queries')
+                );
+            } else {
+                $retval .= PMA_Util::getImage(
+                    's_fulltext.png',
+                    __('Show Full Queries')
+                );
+            }
+            $retval .= '</a>';
+        }
+        $retval .= '</th>';
+    }
+
+    $retval .= '</tr>';
+    $retval .= '</thead>';
+    $retval .= '<tbody>';
+
+    $odd_row = true;
+    while ($process = PMA_DBI_fetch_assoc($result)) {
+
+        // Array keys need to modify due to the way it has used
+        // to display column values
+        if (! empty($_REQUEST['order_by_field'])
+            && ! empty($_REQUEST['sort_order'])
+        ) {
+            foreach (array_keys($process) as $key) {
+                $new_key = ucfirst(strtolower($key));
+                $process[$new_key] = $process[$key];
+                unset($process[$key]);
+            }
+        }
+
+        $url_params['kill'] = $process['Id'];
+        $kill_process = 'server_status.php' . PMA_generate_common_url($url_params);
+
+        $retval .= '<tr class="' . ($odd_row ? 'odd' : 'even') . '">';
+        $retval .= '<td><a href="' . $kill_process . '">' . __('Kill') . '</a></td>';
+        $retval .= '<td class="value">' . $process['Id'] . '</td>';
+        $retval .= '<td>' . $process['User'] . '</td>';
+        $retval .= '<td>' . $process['Host'] . '</td>';
+        $retval .= '<td>' . ((! isset($process['db']) || ! strlen($process['db'])) ? '<i>' . __('None') . '</i>' : $process['db']) . '</td>';
+        $retval .= '<td>' . $process['Command'] . '</td>';
+        $retval .= '<td class="value">' . $process['Time'] . '</td>';
+        $retval .= '<td>' . (empty($process['State']) ? '---' : $process['State']) . '</td>';
+        $retval .= '<td>';
+
+        if (empty($process['Info'])) {
+            $retval .= '---';
+        } else {
+            if (! $show_full_sql && strlen($process['Info']) > $GLOBALS['cfg']['MaxCharactersInDisplayedSQL']) {
+                $retval .= htmlspecialchars(substr($process['Info'], 0, $GLOBALS['cfg']['MaxCharactersInDisplayedSQL'])) . '[...]';
+            } else {
+                $retval .= PMA_SQP_formatHtml(PMA_SQP_parse($process['Info']));
+            }
+        }
+        $retval .= '</td>';
+        $retval .= '</tr>';
+        $odd_row = ! $odd_row;
+    }
+    $retval .= '</tbody>';
+    $retval .= '</table>';
+
+    return $retval;
+}
+
+?>
diff --git a/phpmyadmin/server_status_advisor.php b/phpmyadmin/server_status_advisor.php
new file mode 100644
index 0000000..e17bf0f
--- /dev/null
+++ b/phpmyadmin/server_status_advisor.php
@@ -0,0 +1,74 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * displays the advisor feature
+ *
+ * @package PhpMyAdmin
+ */
+
+require_once 'libraries/common.inc.php';
+require_once 'libraries/Advisor.class.php';
+require_once 'libraries/ServerStatusData.class.php';
+if (PMA_DRIZZLE) {
+    $server_master_status = false;
+    $server_slave_status = false;
+} else {
+    include_once 'libraries/replication.inc.php';
+    include_once 'libraries/replication_gui.lib.php';
+}
+
+$ServerStatusData = new PMA_ServerStatusData();
+
+$response = PMA_Response::getInstance();
+$scripts = $response->getHeader()->getScripts();
+$scripts->addFile('server_status_advisor.js');
+
+$output  = '<div>';
+$output .= $ServerStatusData->getMenuHtml();
+$output .= '<a href="#openAdvisorInstructions">';
+$output .= PMA_Util::getIcon('b_help.png', __('Instructions'));
+$output .= '</a>';
+$output .= '<div id="statustabs_advisor"></div>';
+$output .= '<div id="advisorInstructionsDialog" style="display:none;">';
+$output .= '<p>';
+$output .= __(
+    'The Advisor system can provide recommendations '
+    . 'on server variables by analyzing the server status variables.'
+);
+$output .= '</p>';
+$output .= '<p>';
+$output .= __(
+    'Do note however that this system provides recommendations '
+    . 'based on simple calculations and by rule of thumb which may '
+    . 'not necessarily apply to your system.'
+);
+$output .= '</p>';
+$output .= '<p>';
+$output .= __(
+    'Prior to changing any of the configuration, be sure to know '
+    . 'what you are changing (by reading the documentation) and how '
+    . 'to undo the change. Wrong tuning can have a very negative '
+    . 'effect on performance.'
+);
+$output .= '</p>';
+$output .= '<p>';
+$output .= __(
+    'The best way to tune your system would be to change only one '
+    . 'setting at a time, observe or benchmark your database, and undo '
+    . 'the change if there was no clearly measurable improvement.'
+);
+$output .= '</p>';
+$output .= '</div>';
+$output .= '<div id="advisorData" style="display:none;">';
+$advisor = new Advisor();
+$output .= htmlspecialchars(
+    json_encode(
+        $advisor->run()
+    )
+);
+$output .= '</div>';
+$output .= '</div>';
+
+$response->addHTML($output);
+
+?>
diff --git a/phpmyadmin/server_status_monitor.php b/phpmyadmin/server_status_monitor.php
new file mode 100644
index 0000000..7463cc3
--- /dev/null
+++ b/phpmyadmin/server_status_monitor.php
@@ -0,0 +1,756 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * Server status monitor feature
+ *
+ * @package PhpMyAdmin
+ */
+
+require_once 'libraries/common.inc.php';
+require_once 'libraries/server_common.inc.php';
+require_once 'libraries/ServerStatusData.class.php';
+if (PMA_DRIZZLE) {
+    $server_master_status = false;
+    $server_slave_status = false;
+} else {
+    include_once 'libraries/replication.inc.php';
+    include_once 'libraries/replication_gui.lib.php';
+}
+
+/**
+ * Ajax request
+ */
+if (isset($_REQUEST['ajax_request']) && $_REQUEST['ajax_request'] == true) {
+    // Send with correct charset
+    header('Content-Type: text/html; charset=UTF-8');
+
+    // real-time charting data
+    if (isset($_REQUEST['chart_data'])) {
+        switch($_REQUEST['type']) {
+        case 'chartgrid': // Data for the monitor
+            $ret = json_decode($_REQUEST['requiredData'], true);
+            $statusVars = array();
+            $serverVars = array();
+            $sysinfo = $cpuload = $memory = 0;
+            $pName = '';
+
+            /* Accumulate all required variables and data */
+            // For each chart
+            foreach ($ret as $chart_id => $chartNodes) {
+                // For each data series
+                foreach ($chartNodes as $node_id => $nodeDataPoints) {
+                    // For each data point in the series (usually just 1)
+                    foreach ($nodeDataPoints as $point_id => $dataPoint) {
+                        $pName = $dataPoint['name'];
+
+                        switch ($dataPoint['type']) {
+                        /* We only collect the status and server variables here to
+                         * read them all in one query,
+                         * and only afterwards assign them.
+                         * Also do some white list filtering on the names
+                        */
+                        case 'servervar':
+                            if (! preg_match('/[^a-zA-Z_]+/', $pName)) {
+                                $serverVars[] = $pName;
+                            }
+                            break;
+
+                        case 'statusvar':
+                            if (! preg_match('/[^a-zA-Z_]+/', $pName)) {
+                                $statusVars[] = $pName;
+                            }
+                            break;
+
+                        case 'proc':
+                            $result = PMA_DBI_query('SHOW PROCESSLIST');
+                            $ret[$chart_id][$node_id][$point_id]['value']
+                                = PMA_DBI_num_rows($result);
+                            break;
+
+                        case 'cpu':
+                            if (!$sysinfo) {
+                                include_once 'libraries/sysinfo.lib.php';
+                                $sysinfo = PMA_getSysInfo();
+                            }
+                            if (!$cpuload) {
+                                $cpuload = $sysinfo->loadavg();
+                            }
+
+                            if (PMA_getSysInfoOs() == 'Linux') {
+                                $ret[$chart_id][$node_id][$point_id]['idle']
+                                    = $cpuload['idle'];
+                                $ret[$chart_id][$node_id][$point_id]['busy']
+                                    = $cpuload['busy'];
+                            } else {
+                                $ret[$chart_id][$node_id][$point_id]['value']
+                                    = $cpuload['loadavg'];
+                            }
+
+                            break;
+
+                        case 'memory':
+                            if (!$sysinfo) {
+                                include_once 'libraries/sysinfo.lib.php';
+                                $sysinfo = PMA_getSysInfo();
+                            }
+                            if (!$memory) {
+                                $memory  = $sysinfo->memory();
+                            }
+
+                            $ret[$chart_id][$node_id][$point_id]['value']
+                                = $memory[$pName];
+                            break;
+                        } /* switch */
+                    } /* foreach */
+                } /* foreach */
+            } /* foreach */
+
+            // Retrieve all required status variables
+            if (count($statusVars)) {
+                $statusVarValues = PMA_DBI_fetch_result(
+                    "SHOW GLOBAL STATUS WHERE Variable_name='"
+                    . implode("' OR Variable_name='", $statusVars) . "'",
+                    0,
+                    1
+                );
+            } else {
+                $statusVarValues = array();
+            }
+
+            // Retrieve all required server variables
+            if (count($serverVars)) {
+                $serverVarValues = PMA_DBI_fetch_result(
+                    "SHOW GLOBAL VARIABLES WHERE Variable_name='"
+                    . implode("' OR Variable_name='", $serverVars) . "'",
+                    0,
+                    1
+                );
+            } else {
+                $serverVarValues = array();
+            }
+
+            // ...and now assign them
+            foreach ($ret as $chart_id => $chartNodes) {
+                foreach ($chartNodes as $node_id => $nodeDataPoints) {
+                    foreach ($nodeDataPoints as $point_id => $dataPoint) {
+                        switch($dataPoint['type']) {
+                        case 'statusvar':
+                            $ret[$chart_id][$node_id][$point_id]['value']
+                                = $statusVarValues[$dataPoint['name']];
+                            break;
+                        case 'servervar':
+                            $ret[$chart_id][$node_id][$point_id]['value']
+                                = $serverVarValues[$dataPoint['name']];
+                            break;
+                        }
+                    }
+                }
+            }
+
+            $ret['x'] = microtime(true) * 1000;
+
+            PMA_Response::getInstance()->addJSON('message', $ret);
+            exit;
+        }
+    }
+
+    if (isset($_REQUEST['log_data'])) {
+        if (PMA_MYSQL_INT_VERSION < 50106) {
+            // Table logging is only available since 5.1.6
+            exit('""');
+        }
+
+        $start = intval($_REQUEST['time_start']);
+        $end = intval($_REQUEST['time_end']);
+
+        if ($_REQUEST['type'] == 'slow') {
+            $q = 'SELECT start_time, user_host, ';
+            $q .= 'Sec_to_Time(Sum(Time_to_Sec(query_time))) as query_time, ';
+            $q .= 'Sec_to_Time(Sum(Time_to_Sec(lock_time))) as lock_time, ';
+            $q .= 'SUM(rows_sent) AS rows_sent, ';
+            $q .= 'SUM(rows_examined) AS rows_examined, db, sql_text, ';
+            $q .= 'COUNT(sql_text) AS \'#\' ';
+            $q .= 'FROM `mysql`.`slow_log` ';
+            $q .= 'WHERE start_time > FROM_UNIXTIME(' . $start . ') ';
+            $q .= 'AND start_time < FROM_UNIXTIME(' . $end . ') GROUP BY sql_text';
+
+            $result = PMA_DBI_try_query($q);
+
+            $return = array('rows' => array(), 'sum' => array());
+            $type = '';
+
+            while ($row = PMA_DBI_fetch_assoc($result)) {
+                $type = strtolower(
+                    substr($row['sql_text'], 0, strpos($row['sql_text'], ' '))
+                );
+
+                switch($type) {
+                case 'insert':
+                case 'update':
+                    //Cut off big inserts and updates, but append byte count instead
+                    if (strlen($row['sql_text']) > 220) {
+                        $implode_sql_text = implode(
+                            ' ',
+                            PMA_Util::formatByteDown(
+                                strlen($row['sql_text']), 2, 2
+                            )
+                        );
+                        $row['sql_text'] = substr($row['sql_text'], 0, 200)
+                            . '... [' . $implode_sql_text . ']';
+                    }
+                    break;
+                default:
+                    break;
+                }
+
+                if (! isset($return['sum'][$type])) {
+                    $return['sum'][$type] = 0;
+                }
+                $return['sum'][$type] += $row['#'];
+                $return['rows'][] = $row;
+            }
+
+            $return['sum']['TOTAL'] = array_sum($return['sum']);
+            $return['numRows'] = count($return['rows']);
+
+            PMA_DBI_free_result($result);
+
+            PMA_Response::getInstance()->addJSON('message', $return);
+            exit;
+        }
+
+        if ($_REQUEST['type'] == 'general') {
+            $limitTypes = '';
+            if (isset($_REQUEST['limitTypes']) && $_REQUEST['limitTypes']) {
+                $limitTypes
+                    = 'AND argument REGEXP \'^(INSERT|SELECT|UPDATE|DELETE)\' ';
+            }
+
+            $q = 'SELECT TIME(event_time) as event_time, user_host, thread_id, ';
+            $q .= 'server_id, argument, count(argument) as \'#\' ';
+            $q .= 'FROM `mysql`.`general_log` ';
+            $q .= 'WHERE command_type=\'Query\' ';
+            $q .= 'AND event_time > FROM_UNIXTIME(' . $start . ') ';
+            $q .= 'AND event_time < FROM_UNIXTIME(' . $end . ') ';
+            $q .= $limitTypes . 'GROUP by argument'; // HAVING count > 1';
+
+            $result = PMA_DBI_try_query($q);
+
+            $return = array('rows' => array(), 'sum' => array());
+            $type = '';
+            $insertTables = array();
+            $insertTablesFirst = -1;
+            $i = 0;
+            $removeVars = isset($_REQUEST['removeVariables'])
+                && $_REQUEST['removeVariables'];
+
+            while ($row = PMA_DBI_fetch_assoc($result)) {
+                preg_match('/^(\w+)\s/', $row['argument'], $match);
+                $type = strtolower($match[1]);
+
+                if (! isset($return['sum'][$type])) {
+                    $return['sum'][$type] = 0;
+                }
+                $return['sum'][$type] += $row['#'];
+
+                switch($type) {
+                case 'insert':
+                    // Group inserts if selected
+                    if ($removeVars
+                        && preg_match(
+                            '/^INSERT INTO (`|\'|"|)([^\s\\1]+)\\1/i',
+                            $row['argument'], $matches
+                        )
+                    ) {
+                        $insertTables[$matches[2]]++;
+                        if ($insertTables[$matches[2]] > 1) {
+                            $return['rows'][$insertTablesFirst]['#']
+                                = $insertTables[$matches[2]];
+
+                            // Add a ... to the end of this query to indicate that
+                            // there's been other queries
+                            $temp = $return['rows'][$insertTablesFirst]['argument'];
+                            if ($temp[strlen($temp) - 1] != '.') {
+                                $return['rows'][$insertTablesFirst]['argument']
+                                    .= '<br/>...';
+                            }
+
+                            // Group this value, thus do not add to the result list
+                            continue 2;
+                        } else {
+                            $insertTablesFirst = $i;
+                            $insertTables[$matches[2]] += $row['#'] - 1;
+                        }
+                    }
+                    // No break here
+
+                case 'update':
+                    // Cut off big inserts and updates,
+                    // but append byte count therefor
+                    if (strlen($row['argument']) > 220) {
+                        $row['argument'] = substr($row['argument'], 0, 200)
+                            . '... ['
+                            .  implode(
+                                ' ',
+                                PMA_Util::formatByteDown(
+                                    strlen($row['argument']),
+                                    2,
+                                    2
+                                )
+                            )
+                            . ']';
+                    }
+                    break;
+
+                default:
+                    break;
+                }
+
+                $return['rows'][] = $row;
+                $i++;
+            }
+
+            $return['sum']['TOTAL'] = array_sum($return['sum']);
+            $return['numRows'] = count($return['rows']);
+
+            PMA_DBI_free_result($result);
+
+            PMA_Response::getInstance()->addJSON('message', $return);
+            exit;
+        }
+    }
+
+    if (isset($_REQUEST['logging_vars'])) {
+        if (isset($_REQUEST['varName']) && isset($_REQUEST['varValue'])) {
+            $value = PMA_Util::sqlAddSlashes($_REQUEST['varValue']);
+            if (! is_numeric($value)) {
+                $value="'" . $value . "'";
+            }
+
+            if (! preg_match("/[^a-zA-Z0-9_]+/", $_REQUEST['varName'])) {
+                PMA_DBI_query(
+                    'SET GLOBAL ' . $_REQUEST['varName'] . ' = ' . $value
+                );
+            }
+
+        }
+
+        $loggingVars = PMA_DBI_fetch_result(
+            'SHOW GLOBAL VARIABLES WHERE Variable_name IN'
+            . ' ("general_log","slow_query_log","long_query_time","log_output")',
+            0,
+            1
+        );
+        PMA_Response::getInstance()->addJSON('message', $loggingVars);
+        exit;
+    }
+
+    if (isset($_REQUEST['query_analyzer'])) {
+        $return = array();
+
+        if (strlen($_REQUEST['database'])) {
+            PMA_DBI_select_db($_REQUEST['database']);
+        }
+
+        if ($profiling = PMA_Util::profilingSupported()) {
+            PMA_DBI_query('SET PROFILING=1;');
+        }
+
+        // Do not cache query
+        $query = preg_replace(
+            '/^(\s*SELECT)/i',
+            '\\1 SQL_NO_CACHE',
+            $_REQUEST['query']
+        );
+
+        $result = PMA_DBI_try_query($query);
+        $return['affectedRows'] = $GLOBALS['cached_affected_rows'];
+
+        $result = PMA_DBI_try_query('EXPLAIN ' . $query);
+        while ($row = PMA_DBI_fetch_assoc($result)) {
+            $return['explain'][] = $row;
+        }
+
+        // In case an error happened
+        $return['error'] = PMA_DBI_getError();
+
+        PMA_DBI_free_result($result);
+
+        if ($profiling) {
+            $return['profiling'] = array();
+            $result = PMA_DBI_try_query(
+                'SELECT seq,state,duration FROM INFORMATION_SCHEMA.PROFILING'
+                . ' WHERE QUERY_ID=1 ORDER BY seq'
+            );
+            while ($row = PMA_DBI_fetch_assoc($result)) {
+                $return['profiling'][]= $row;
+            }
+            PMA_DBI_free_result($result);
+        }
+
+        PMA_Response::getInstance()->addJSON('message', $return);
+        exit;
+    }
+}
+
+/**
+ * JS Includes
+ */
+$header   = $response->getHeader();
+$scripts  = $header->getScripts();
+$scripts->addFile('jquery/jquery.tablesorter.js');
+$scripts->addFile('jquery/jquery.json-2.4.js');
+$scripts->addFile('jquery/jquery.sortableTable.js');
+$scripts->addFile('jquery/jquery-ui-timepicker-addon.js');
+/* < IE 9 doesn't support canvas natively */
+if (PMA_USR_BROWSER_AGENT == 'IE' && PMA_USR_BROWSER_VER < 9) {
+    $scripts->addFile('jqplot/excanvas.js');
+}
+$scripts->addFile('canvg/canvg.js');
+// for charting
+$scripts->addFile('jqplot/jquery.jqplot.js');
+$scripts->addFile('jqplot/plugins/jqplot.pieRenderer.js');
+$scripts->addFile('jqplot/plugins/jqplot.canvasTextRenderer.js');
+$scripts->addFile('jqplot/plugins/jqplot.canvasAxisLabelRenderer.js');
+$scripts->addFile('jqplot/plugins/jqplot.dateAxisRenderer.js');
+$scripts->addFile('jqplot/plugins/jqplot.highlighter.js');
+$scripts->addFile('jqplot/plugins/jqplot.cursor.js');
+$scripts->addFile('jqplot/plugins/jqplot.byteFormatter.js');
+$scripts->addFile('date.js');
+
+$scripts->addFile('server_status_monitor.js');
+$scripts->addFile('server_status_sorter.js');
+
+
+/**
+ * start output
+ */
+$ServerStatusData = new PMA_ServerStatusData();
+
+/**
+ * Define some data needed on the client side
+ */
+$input = '<input type="hidden" name="%s" value="%s" />';
+$form  = '<form id="js_data" class="hide">';
+$form .= sprintf($input, 'server_time', microtime(true) * 1000);
+$form .= sprintf($input, 'server_os', PHP_OS);
+$form .= sprintf($input, 'is_superuser', PMA_isSuperuser());
+$form .= sprintf($input, 'server_db_isLocal', $ServerStatusData->db_isLocal);
+$form .= '</form>';
+/**
+ * Define some links used on client side
+ */
+$links  = '<div id="profiling_docu" class="hide">';
+$links .= PMA_Util::showMySQLDocu('general-thread-states', 'general-thread-states');
+$links .= '</div>';
+$links .= '<div id="explain_docu" class="hide">';
+$links .= PMA_Util::showMySQLDocu('explain-output', 'explain-output');
+$links .= '</div>';
+
+/**
+ * Output
+ */
+$response->addHTML('<div>');
+$response->addHTML($ServerStatusData->getMenuHtml());
+$response->addHTML(getPrintMonitorHtml($ServerStatusData));
+$response->addHTML($form);
+$response->addHTML($links);
+$response->addHTML('</div>');
+exit;
+
+/**
+ * Prints html with monitor
+ *
+ * @param object $ServerStatusData An instance of the PMA_ServerStatusData class
+ *
+ * @return string
+ */
+function getPrintMonitorHtml($ServerStatusData)
+{
+    $retval  = '<div class="tabLinks">';
+    $retval .= '<a href="#pauseCharts">';
+    $retval .= PMA_Util::getImage('play.png') . __('Start Monitor');
+    $retval .= '</a>';
+    $retval .= '<a href="#settingsPopup" class="popupLink">';
+    $retval .= PMA_Util::getImage('s_cog.png') .  __('Settings');
+    $retval .= '</a>';
+    if (! PMA_DRIZZLE) {
+        $retval .= '<a href="#monitorInstructionsDialog">';
+        $retval .= PMA_Util::getImage('b_help.png') . __('Instructions/Setup');
+    }
+    $retval .= '<a href="#endChartEditMode" style="display:none;">';
+    $retval .= PMA_Util::getImage('s_okay.png');
+    $retval .= __('Done dragging (rearranging) charts');
+    $retval .= '</a>';
+    $retval .= '</div>';
+
+    $retval .= '<div class="popupContent settingsPopup">';
+    $retval .= '<a href="#addNewChart">';
+    $retval .= PMA_Util::getImage('b_chart.png') . __('Add chart');
+    $retval .= '</a>';
+    $retval .= '<a href="#rearrangeCharts">';
+    $retval .= PMA_Util::getImage('b_tblops.png') . __('Enable charts dragging');
+    $retval .= '</a>';
+    $retval .= '<div class="clearfloat paddingtop"></div>';
+    $retval .= '<div class="floatleft">';
+    $retval .= __('Refresh rate') . '<br />';
+    $retval .= PMA_getRefreshList(
+        'gridChartRefresh',
+        5,
+        Array(2, 3, 4, 5, 10, 20, 40, 60, 120, 300, 600, 1200)
+    );
+    $retval .= '<br />';
+    $retval .= '</div>';
+    $retval .= '<div class="floatleft">';
+    $retval .= __('Chart columns');
+    $retval .= '<br />';
+    $retval .= '<select name="chartColumns">';
+    $retval .= '<option>1</option>';
+    $retval .= '<option>2</option>';
+    $retval .= '<option>3</option>';
+    $retval .= '<option>4</option>';
+    $retval .= '<option>5</option>';
+    $retval .= '<option>6</option>';
+    $retval .= '<option>7</option>';
+    $retval .= '<option>8</option>';
+    $retval .= '<option>9</option>';
+    $retval .= '<option>10</option>';
+    $retval .= '</select>';
+    $retval .= '</div>';
+    $retval .= '<div class="clearfloat paddingtop">';
+    $retval .= '<b>' . __('Chart arrangement') . '</b> ';
+    $retval .= PMA_Util::showHint(
+        __(
+            'The arrangement of the charts is stored to the browsers local storage. '
+            . 'You may want to export it if you have a complicated set up.'
+        )
+    );
+    $retval .= '<br/>';
+    $retval .= '<a class="ajax" href="#importMonitorConfig">';
+    $retval .= __('Import');
+    $retval .= '</a>';
+    $retval .= '  ';
+    $retval .= '<a class="disableAjax" href="#exportMonitorConfig">';
+    $retval .= __('Export');
+    $retval .= '</a>';
+    $retval .= '  ';
+    $retval .= '<a href="#clearMonitorConfig">';
+    $retval .= __('Reset to default');
+    $retval .= '</a>';
+    $retval .= '</div>';
+    $retval .= '</div>';
+
+    $retval .= '<div id="monitorInstructionsDialog" title="';
+    $retval .= __('Monitor Instructions') . '" style="display:none;">';
+    $retval .= __(
+        'The phpMyAdmin Monitor can assist you in optimizing the server'
+        . ' configuration and track down time intensive queries. For the latter you'
+        . ' will need to set log_output to \'TABLE\' and have either the'
+        . ' slow_query_log or general_log enabled. Note however, that the'
+        . ' general_log produces a lot of data and increases server load'
+        . ' by up to 15%'
+    );
+
+    if (PMA_MYSQL_INT_VERSION < 50106) {
+        $retval .= '<p>';
+        $retval .= PMA_Util::getImage('s_attention.png');
+        $retval .=  __(
+            'Unfortunately your Database server does not support logging to table,'
+            . ' which is a requirement for analyzing the database logs with'
+            . ' phpMyAdmin. Logging to table is supported by MySQL 5.1.6 and'
+            . ' onwards. You may still use the server charting features however.'
+        );
+        $retval .= '</p>';
+    } else {
+        $retval .= '<p></p>';
+        $retval .= '<img class="ajaxIcon" src="';
+        $retval .= $GLOBALS['pmaThemeImage'] . 'ajax_clock_small.gif"';
+        $retval .= ' alt="' . __('Loading') . '" />';
+        $retval .= '<div class="ajaxContent"></div>';
+        $retval .= '<div class="monitorUse" style="display:none;">';
+        $retval .= '<p></p>';
+        $retval .= '<strong>';
+        $retval .= __('Using the monitor:');
+        $retval .= '</strong><p>';
+        $retval .= __(
+            'Your browser will refresh all displayed charts in a regular interval.'
+            . ' You may add charts and change the refresh rate under \'Settings\','
+            . ' or remove any chart using the cog icon on each respective chart.'
+        );
+        $retval .= '</p><p>';
+        $retval .= __(
+            'To display queries from the logs, select the relevant time span on any'
+            . ' chart by holding down the left mouse button and panning over the'
+            . ' chart. Once confirmed, this will load a table of grouped queries,'
+            . ' there you may click on any occuring SELECT statements to further'
+            . ' analyze them.'
+        );
+        $retval .= '</p>';
+        $retval .= '<p>';
+        $retval .= PMA_Util::getImage('s_attention.png');
+        $retval .= '<strong>';
+        $retval .= __('Please note:');
+        $retval .= '</strong><br />';
+        $retval .= __(
+            'Enabling the general_log may increase the server load by'
+            . ' 5-15%. Also be aware that generating statistics from the logs is a'
+            . ' load intensive task, so it is advisable to select only a small time'
+            . ' span and to disable the general_log and empty its table once'
+            . ' monitoring is not required any more.'
+        );
+        $retval .= '</p>';
+        $retval .= '</div>';
+    }
+    $retval .= '</div>';
+
+    $retval .= '<div id="addChartDialog" title="' . __('Add chart') . '" style="display:none;">';
+    $retval .= '<div id="tabGridVariables">';
+    $retval .= '<p><input type="text" name="chartTitle" value="' . __('Chart Title') . '" /></p>';
+    $retval .= '<input type="radio" name="chartType" value="preset" id="chartPreset" />';
+    $retval .= '<label for="chartPreset">' . __('Preset chart') . '</label>';
+    $retval .= '<select name="presetCharts"></select><br/>';
+    $retval .= '<input type="radio" name="chartType" value="variable" id="chartStatusVar" checked="checked" />';
+    $retval .= '<label for="chartStatusVar">';
+    $retval .= __('Status variable(s)');
+    $retval .= '</label><br/>';
+    $retval .= '<div id="chartVariableSettings">';
+    $retval .= '<label for="chartSeries">' . __('Select series:') . '</label><br />';
+    $retval .= '<select id="chartSeries" name="varChartList" size="1">';
+    $retval .= '<option>' . __('Commonly monitored') . '</option>';
+    $retval .= '<option>Processes</option>';
+    $retval .= '<option>Questions</option>';
+    $retval .= '<option>Connections</option>';
+    $retval .= '<option>Bytes_sent</option>';
+    $retval .= '<option>Bytes_received</option>';
+    $retval .= '<option>Threads_connected</option>';
+    $retval .= '<option>Created_tmp_disk_tables</option>';
+    $retval .= '<option>Handler_read_first</option>';
+    $retval .= '<option>Innodb_buffer_pool_wait_free</option>';
+    $retval .= '<option>Key_reads</option>';
+    $retval .= '<option>Open_tables</option>';
+    $retval .= '<option>Select_full_join</option>';
+    $retval .= '<option>Slow_queries</option>';
+    $retval .= '</select><br />';
+    $retval .= '<label for="variableInput">';
+    $retval .= __('or type variable name:');
+    $retval .= ' </label>';
+    $retval .= '<input type="text" name="variableInput" id="variableInput" />';
+    $retval .= '<p></p>';
+    $retval .= '<input type="checkbox" name="differentialValue"';
+    $retval .= ' id="differentialValue" value="differential" checked="checked" />';
+    $retval .= '<label for="differentialValue">';
+    $retval .= __('Display as differential value');
+    $retval .= '</label><br />';
+    $retval .= '<input type="checkbox" id="useDivisor" name="useDivisor" value="1" />';
+    $retval .= '<label for="useDivisor">' . __('Apply a divisor') . '</label>';
+    $retval .= '<span class="divisorInput" style="display:none;">';
+    $retval .= '<input type="text" name="valueDivisor" size="4" value="1" />';
+    $retval .= '(<a href="#kibDivisor">' . __('KiB') . '</a>, ';
+    $retval .= '<a href="#mibDivisor">' . __('MiB') . '</a>)';
+    $retval .= '</span><br />';
+    $retval .= '<input type="checkbox" id="useUnit" name="useUnit" value="1" />';
+    $retval .= '<label for="useUnit">';
+    $retval .= __('Append unit to data values');
+    $retval .= '</label>';
+    $retval .= '<span class="unitInput" style="display:none;">';
+    $retval .= '<input type="text" name="valueUnit" size="4" value="" />';
+    $retval .= '</span>';
+    $retval .= '<p>';
+    $retval .= '<a href="#submitAddSeries"><b>' . __('Add this series') . '</b></a>';
+    $retval .= '<span id="clearSeriesLink" style="display:none;">';
+    $retval .= ' | <a href="#submitClearSeries">' . __('Clear series') . '</a>';
+    $retval .= '</span>';
+    $retval .= '</p>';
+    $retval .= __('Series in Chart:');
+    $retval .= '<br/>';
+    $retval .= '<span id="seriesPreview">';
+    $retval .= '<i>' . __('None') . '</i>';
+    $retval .= '</span>';
+    $retval .= '</div>';
+    $retval .= '</div>';
+    $retval .= '</div>';
+
+    if (! PMA_DRIZZLE) {
+        $retval .= '<div id="logAnalyseDialog" title="';
+        $retval .= __('Log statistics') . '" style="display:none;">';
+        $retval .= '<p>' . __('Selected time range:');
+        $retval .= '<input type="text" name="dateStart" class="datetimefield" value="" /> - ';
+        $retval .= '<input type="text" name="dateEnd" class="datetimefield" value="" />';
+        $retval .= '</p>';
+        $retval .= '<input type="checkbox" id="limitTypes" value="1" checked="checked" />';
+        $retval .= '<label for="limitTypes">';
+        $retval .= __('Only retrieve SELECT,INSERT,UPDATE and DELETE Statements');
+        $retval .= '</label>';
+        $retval .= '<br/>';
+        $retval .= '<input type="checkbox" id="removeVariables" value="1" checked="checked" />';
+        $retval .= '<label for="removeVariables">';
+        $retval .= __('Remove variable data in INSERT statements for better grouping');
+        $retval .= '</label>';
+        $retval .= '<p>';
+        $retval .= __('Choose from which log you want the statistics to be generated from.');
+        $retval .= '</p>';
+        $retval .= '<p>';
+        $retval .= __('Results are grouped by query text.');
+        $retval .= '</p>';
+        $retval .= '</div>';
+        $retval .= '<div id="queryAnalyzerDialog" title="';
+        $retval .= __('Query analyzer') . '" style="display:none;">';
+        $retval .= '<textarea id="sqlquery"> </textarea>';
+        $retval .= '<p></p>';
+        $retval .= '<div class="placeHolder"></div>';
+        $retval .= '</div>';
+    }
+
+    $retval .= '<table class="clearfloat" id="chartGrid"></table>';
+    $retval .= '<div id="logTable">';
+    $retval .= '<br/>';
+    $retval .= '</div>';
+
+    $retval .= '<script type="text/javascript">';
+    $retval .= 'variableNames = [ ';
+    $i=0;
+    foreach ($ServerStatusData->status as $name=>$value) {
+        if (is_numeric($value)) {
+            if ($i++ > 0) {
+                $retval .= ", ";
+            }
+            $retval .= "'" . $name . "'";
+        }
+    }
+    $retval .= '];';
+    $retval .= '</script>';
+
+    return $retval;
+}
+
+/**
+ * Builds a <select> list for refresh rates
+ *
+ * @param string $name         Name of select
+ * @param int    $defaultRate  Currently chosen rate
+ * @param array  $refreshRates List of refresh rates
+ *
+ * @return string
+ */
+function PMA_getRefreshList($name,
+    $defaultRate = 5,
+    $refreshRates = Array(1, 2, 5, 10, 20, 40, 60, 120, 300, 600)
+) {
+    $return = '<select name="' . $name . '" id="id_' . $name
+        . '" class="refreshRate">';
+    foreach ($refreshRates as $rate) {
+        $selected = ($rate == $defaultRate)?' selected="selected"':'';
+        $return .= '<option value="' . $rate . '"' . $selected . '>';
+        if ($rate < 60) {
+            $return .= sprintf(_ngettext('%d second', '%d seconds', $rate), $rate);
+        } else {
+            $rate = $rate / 60;
+            $return .= sprintf(_ngettext('%d minute', '%d minutes', $rate), $rate);
+        }
+        $return .=  '</option>';
+    }
+    $return .= '</select>';
+    return $return;
+}
+
+?>
diff --git a/phpmyadmin/server_status_queries.php b/phpmyadmin/server_status_queries.php
new file mode 100644
index 0000000..01d2173
--- /dev/null
+++ b/phpmyadmin/server_status_queries.php
@@ -0,0 +1,162 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * Displays query statistics for the server
+ *
+ * @package PhpMyAdmin
+ */
+
+require_once 'libraries/common.inc.php';
+require_once 'libraries/server_common.inc.php';
+require_once 'libraries/ServerStatusData.class.php';
+if (PMA_DRIZZLE) {
+    $server_master_status = false;
+    $server_slave_status = false;
+} else {
+    include_once 'libraries/replication.inc.php';
+    include_once 'libraries/replication_gui.lib.php';
+}
+
+$ServerStatusData = new PMA_ServerStatusData();
+
+$response = PMA_Response::getInstance();
+$header   = $response->getHeader();
+$scripts  = $header->getScripts();
+$scripts->addFile('server_status_queries.js');
+/* < IE 9 doesn't support canvas natively */
+if (PMA_USR_BROWSER_AGENT == 'IE' && PMA_USR_BROWSER_VER < 9) {
+    $scripts->addFile('jqplot/excanvas.js');
+}
+
+// for charting
+$scripts->addFile('jqplot/jquery.jqplot.js');
+$scripts->addFile('jqplot/plugins/jqplot.pieRenderer.js');
+$scripts->addFile('jqplot/plugins/jqplot.canvasTextRenderer.js');
+$scripts->addFile('jqplot/plugins/jqplot.canvasAxisLabelRenderer.js');
+$scripts->addFile('jqplot/plugins/jqplot.dateAxisRenderer.js');
+$scripts->addFile('jqplot/plugins/jqplot.highlighter.js');
+$scripts->addFile('jqplot/plugins/jqplot.cursor.js');
+$scripts->addFile('jquery/jquery.tablesorter.js');
+$scripts->addFile('server_status_sorter.js');
+
+// Add the html content to the response
+$response->addHTML('<div>');
+$response->addHTML($ServerStatusData->getMenuHtml());
+$response->addHTML(getQueryStatisticsHtml($ServerStatusData));
+$response->addHTML('</div>');
+exit;
+
+/**
+ * Returns the html content for the query statistics
+ *
+ * @param object $ServerStatusData An instance of the PMA_ServerStatusData class
+ *
+ * @return string
+ */
+function getQueryStatisticsHtml($ServerStatusData)
+{
+    $retval = '';
+
+    $hour_factor   = 3600 / $ServerStatusData->status['Uptime'];
+    $used_queries = $ServerStatusData->used_queries;
+    $total_queries = array_sum($used_queries);
+
+    $retval .= '<h3 id="serverstatusqueries">';
+    /* l10n: Questions is the name of a MySQL Status variable */
+    $retval .= sprintf(
+        __('Questions since startup: %s'),
+        PMA_Util::formatNumber($total_queries, 0)
+    );
+    $retval .= ' ';
+    $retval .= PMA_Util::showMySQLDocu(
+        'server-status-variables',
+        'server-status-variables',
+        false,
+        'statvar_Questions'
+    );
+    $retval .= '<br />';
+    $retval .= '<span>';
+    $retval .= 'ø ' . __('per hour') . ': ';
+    $retval .= PMA_Util::formatNumber($total_queries * $hour_factor, 0);
+    $retval .= '<br />';
+    $retval .= 'ø ' . __('per minute') . ': ';
+    $retval .= PMA_Util::formatNumber($total_queries * 60 / $ServerStatusData->status['Uptime'], 0);
+    $retval .= '<br />';
+    if ($total_queries / $ServerStatusData->status['Uptime'] >= 1) {
+        $retval .= 'ø ' . __('per second') . ': ';
+        $retval .= PMA_Util::formatNumber($total_queries / $ServerStatusData->status['Uptime'], 0);
+    }
+    $retval .= '</span>';
+    $retval .= '</h3>';
+
+    // reverse sort by value to show most used statements first
+    arsort($used_queries);
+
+    $odd_row        = true;
+    $perc_factor    = 100 / $total_queries; //(- $ServerStatusData->status['Connections']);
+
+    $retval .= '<table id="serverstatusqueriesdetails" class="data sortable noclick">';
+    $retval .= '<col class="namecol" />';
+    $retval .= '<col class="valuecol" span="3" />';
+    $retval .= '<thead>';
+    $retval .= '<tr><th>' . __('Statements') . '</th>';
+    $retval .= '<th>';
+    /* l10n: # = Amount of queries */
+    $retval .= __('#');
+    $retval .= '</th>';
+    $retval .= '<th>ø ' . __('per hour') . '</th>';
+    $retval .= '<th>%</th>';
+    $retval .= '</tr>';
+    $retval .= '</thead>';
+    $retval .= '<tbody>';
+
+    $chart_json = array();
+    $query_sum = array_sum($used_queries);
+    $other_sum = 0;
+    foreach ($used_queries as $name => $value) {
+        $odd_row = !$odd_row;
+        // For the percentage column, use Questions - Connections, because
+        // the number of connections is not an item of the Query types
+        // but is included in Questions. Then the total of the percentages is 100.
+        $name = str_replace(array('Com_', '_'), array('', ' '), $name);
+        // Group together values that make out less than 2% into "Other", but only
+        // if we have more than 6 fractions already
+        if ($value < $query_sum * 0.02 && count($chart_json)>6) {
+            $other_sum += $value;
+        } else {
+            $chart_json[$name] = $value;
+        }
+        $retval .= '<tr class="';
+        $retval .= $odd_row ? 'odd' : 'even';
+        $retval .= '">';
+        $retval .= '<th class="name">' . htmlspecialchars($name) . '</th>';
+        $retval .= '<td class="value">';
+        $retval .= htmlspecialchars(PMA_Util::formatNumber($value, 5, 0, true));
+        $retval .= '</td>';
+        $retval .= '<td class="value">';
+        $retval .= htmlspecialchars(
+            PMA_Util::formatNumber($value * $hour_factor, 4, 1, true)
+        );
+        $retval .= '</td>';
+        $retval .= '<td class="value">';
+        $retval .= htmlspecialchars(
+            PMA_Util::formatNumber($value * $perc_factor, 0, 2)
+        );
+        $retval .= '</td>';
+        $retval .= '</tr>';
+    }
+    $retval .= '</tbody>';
+    $retval .= '</table>';
+
+    $retval .= '<div id="serverstatusquerieschart"></div>';
+    $retval .= '<div id="serverstatusquerieschart_data" style="display:none;">';
+    if ($other_sum > 0) {
+        $chart_json[__('Other')] = $other_sum;
+    }
+    $retval .= htmlspecialchars(json_encode($chart_json));
+    $retval .= '</div>';
+
+    return $retval;
+}
+
+?>
diff --git a/phpmyadmin/server_status_variables.php b/phpmyadmin/server_status_variables.php
new file mode 100644
index 0000000..93dc968
--- /dev/null
+++ b/phpmyadmin/server_status_variables.php
@@ -0,0 +1,767 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * Displays a list of server status variables
+ *
+ * @package PhpMyAdmin
+ */
+
+require_once 'libraries/common.inc.php';
+require_once 'libraries/server_common.inc.php';
+require_once 'libraries/ServerStatusData.class.php';
+if (PMA_DRIZZLE) {
+    $server_master_status = false;
+    $server_slave_status = false;
+} else {
+    include_once 'libraries/replication.inc.php';
+    include_once 'libraries/replication_gui.lib.php';
+}
+
+/**
+ * flush status variables if requested
+ */
+if (isset($_REQUEST['flush'])) {
+    $_flush_commands = array(
+        'STATUS',
+        'TABLES',
+        'QUERY CACHE',
+    );
+
+    if (in_array($_REQUEST['flush'], $_flush_commands)) {
+        PMA_DBI_query('FLUSH ' . $_REQUEST['flush'] . ';');
+    }
+    unset($_flush_commands);
+}
+
+$ServerStatusData = new PMA_ServerStatusData();
+
+$response = PMA_Response::getInstance();
+$header   = $response->getHeader();
+$scripts  = $header->getScripts();
+$scripts->addFile('server_status_variables.js');
+$scripts->addFile('jquery/jquery.tablesorter.js');
+$scripts->addFile('server_status_sorter.js');
+
+$response->addHTML('<div>');
+$response->addHTML($ServerStatusData->getMenuHtml());
+$response->addHTML(getFilterHtml($ServerStatusData));
+$response->addHTML(getLinkSuggestionsHtml($ServerStatusData));
+$response->addHTML(getVariablesTableHtml($ServerStatusData));
+$response->addHTML('</div>');
+
+exit;
+
+/**
+ * Returns the html for the list filter
+ *
+ * @param Object $ServerStatusData An instance of the PMA_ServerStatusData class
+ *
+ * @return string
+ */
+function getFilterHtml($ServerStatusData)
+{
+    $filterAlert = '';
+    if (! empty($_REQUEST['filterAlert'])) {
+        $filterAlert = ' checked="checked"';
+    }
+    $filterText = '';
+    if (! empty($_REQUEST['filterText'])) {
+        $filterText = htmlspecialchars($_REQUEST['filterText']);
+    }
+    $dontFormat = '';
+    if (! empty($_REQUEST['dontFormat'])) {
+        $dontFormat = ' checked="checked"';
+    }
+
+    $retval  = '';
+    $retval .= '<fieldset id="tableFilter">';
+    $retval .= '<legend>' . __('Filters') . '</legend>';
+    $retval .= '<form action="server_status_variables.php?' . PMA_generate_common_url() . '">';
+    $retval .= '<input type="submit" value="' . __('Refresh') . '" />';
+    $retval .= '<div class="formelement">';
+    $retval .= '<label for="filterText">' . __('Containing the word:') . '</label>';
+    $retval .= '<input name="filterText" type="text" id="filterText" '
+        . 'style="vertical-align: baseline;" value="' . $filterText . '" />';
+    $retval .= '</div>';
+    $retval .= '<div class="formelement">';
+    $retval .= '<input' . $filterAlert . ' type="checkbox" name="filterAlert" id="filterAlert" />';
+    $retval .= '<label for="filterAlert">';
+    $retval .= __('Show only alert values');
+    $retval .= '</label>';
+    $retval .= '</div>';
+    $retval .= '<div class="formelement">';
+    $retval .= '<select id="filterCategory" name="filterCategory">';
+    $retval .= '<option value="">' . __('Filter by category…') . '</option>';
+
+    foreach ($ServerStatusData->sections as $section_id => $section_name) {
+        if (isset($ServerStatusData->categoryUsed[$section_id])) {
+            if (! empty($_REQUEST['filterCategory'])
+                && $_REQUEST['filterCategory'] == $section_id
+            ) {
+                $selected = ' selected="selected"';
+            } else {
+                $selected = '';
+            }
+            $retval .= '<option' . $selected . ' value="' . $section_id. '">';
+            $retval .= htmlspecialchars($section_name) . '</option>';
+        }
+    }
+    $retval .= '</select>';
+    $retval .= '</div>';
+    $retval .= '<div class="formelement">';
+    $retval .= '<input' . $dontFormat . ' type="checkbox" name="dontFormat" id="dontFormat" />';
+    $retval .= '<label for="dontFormat">';
+    $retval .= __('Show unformatted values');
+    $retval .= '</label>';
+    $retval .= '</div>';
+    $retval .= '</form>';
+    $retval .= '</fieldset>';
+
+    return $retval;
+}
+
+/**
+ * Prints the suggestion links
+ *
+ * @param Object $ServerStatusData An instance of the PMA_ServerStatusData class
+ *
+ * @return string
+ */
+function getLinkSuggestionsHtml($ServerStatusData)
+{
+    $retval  = '<div id="linkSuggestions" class="defaultLinks" style="display:none">';
+    $retval .= '<p class="notice">' . __('Related links:');
+    foreach ($ServerStatusData->links as $section_name => $section_links) {
+        $retval .= '<span class="status_' . $section_name . '"> ';
+        $i=0;
+        foreach ($section_links as $link_name => $link_url) {
+            if ($i > 0) {
+                $retval .= ', ';
+            }
+            if ('doc' == $link_name) {
+                $retval .= PMA_Util::showMySQLDocu($link_url, $link_url);
+            } else {
+                $retval .= '<a href="' . $link_url . '">' . $link_name . '</a>';
+            }
+            $i++;
+        }
+        $retval .= '</span>';
+    }
+    unset($link_url, $link_name, $i);
+    $retval .= '</p>';
+    $retval .= '</div>';
+
+    return $retval;
+}
+
+/**
+ * Returns a table with variables information
+ *
+ * @param Object $ServerStatusData An instance of the PMA_ServerStatusData class
+ *
+ * @return string
+ */
+function getVariablesTableHtml($ServerStatusData)
+{
+    $retval  = '';
+    $strShowStatus = getStatusVariablesDescriptions();
+    /**
+     * define some alerts
+     */
+    // name => max value before alert
+    $alerts = array(
+        // lower is better
+        // variable => max value
+        'Aborted_clients' => 0,
+        'Aborted_connects' => 0,
+
+        'Binlog_cache_disk_use' => 0,
+
+        'Created_tmp_disk_tables' => 0,
+
+        'Handler_read_rnd' => 0,
+        'Handler_read_rnd_next' => 0,
+
+        'Innodb_buffer_pool_pages_dirty' => 0,
+        'Innodb_buffer_pool_reads' => 0,
+        'Innodb_buffer_pool_wait_free' => 0,
+        'Innodb_log_waits' => 0,
+        'Innodb_row_lock_time_avg' => 10, // ms
+        'Innodb_row_lock_time_max' => 50, // ms
+        'Innodb_row_lock_waits' => 0,
+
+        'Slow_queries' => 0,
+        'Delayed_errors' => 0,
+        'Select_full_join' => 0,
+        'Select_range_check' => 0,
+        'Sort_merge_passes' => 0,
+        'Opened_tables' => 0,
+        'Table_locks_waited' => 0,
+        'Qcache_lowmem_prunes' => 0,
+
+        'Qcache_free_blocks' => isset($ServerStatusData->server_status['Qcache_total_blocks'])
+            ? $ServerStatusData->server_status['Qcache_total_blocks'] / 5 : 0,
+        'Slow_launch_threads' => 0,
+
+        // depends on Key_read_requests
+        // normaly lower then 1:0.01
+        'Key_reads' => isset($ServerStatusData->status['Key_read_requests'])
+            ? (0.01 * $ServerStatusData->status['Key_read_requests']) : 0,
+        // depends on Key_write_requests
+        // normaly nearly 1:1
+        'Key_writes' => isset($ServerStatusData->status['Key_write_requests'])
+            ? (0.9 * $ServerStatusData->status['Key_write_requests']) : 0,
+
+        'Key_buffer_fraction' => 0.5,
+
+        // alert if more than 95% of thread cache is in use
+        'Threads_cached' => isset($ServerStatusData->variables['thread_cache_size'])
+            ? 0.95 * $ServerStatusData->variables['thread_cache_size'] : 0
+
+        // higher is better
+        // variable => min value
+        //'Handler read key' => '> ',
+    );
+
+    $retval .= '<table class="data sortable noclick" id="serverstatusvariables">';
+    $retval .= '<col class="namecol" />';
+    $retval .= '<col class="valuecol" />';
+    $retval .= '<col class="descrcol" />';
+    $retval .= '<thead>';
+    $retval .= '<tr>';
+    $retval .= '<th>' . __('Variable') . '</th>';
+    $retval .= '<th>' . __('Value') . '</th>';
+    $retval .= '<th>' . __('Description') . '</th>';
+    $retval .= '</tr>';
+    $retval .= '</thead>';
+    $retval .= '<tbody>';
+
+    $odd_row = false;
+    foreach ($ServerStatusData->status as $name => $value) {
+        $odd_row = !$odd_row;
+        $retval .= '<tr class="' . ($odd_row ? 'odd' : 'even')
+            . (isset($ServerStatusData->allocationMap[$name])?' s_' . $ServerStatusData->allocationMap[$name] : '')
+            . '">';
+
+        $retval .= '<th class="name">';
+        $retval .= htmlspecialchars(str_replace('_', ' ', $name));
+        /* Fields containing % are calculated, they can not be described in MySQL documentation */
+        if (strpos($name, '%') === false) {
+            $retval .= PMA_Util::showMySQLDocu(
+                'server-status-variables',
+                'server-status-variables',
+                false,
+                'statvar_' . $name
+            );
+        }
+        $retval .= '</th>';
+
+        $retval .= '<td class="value"><span class="formatted">';
+        if (isset($alerts[$name])) {
+            if ($value > $alerts[$name]) {
+                $retval .= '<span class="attention">';
+            } else {
+                $retval .= '<span class="allfine">';
+            }
+        }
+        if ('%' === substr($name, -1, 1)) {
+            $retval .= htmlspecialchars(PMA_Util::formatNumber($value, 0, 2)) . ' %';
+        } elseif (strpos($name, 'Uptime') !== false) {
+            $retval .= htmlspecialchars(
+                PMA_Util::timespanFormat($value)
+            );
+        } elseif (is_numeric($value) && $value == (int) $value && $value > 1000) {
+            $retval .= '<abbr title="'
+                // makes available the raw value as a title
+                . htmlspecialchars(PMA_Util::formatNumber($value, 0))
+                . '">'
+                . htmlspecialchars(PMA_Util::formatNumber($value, 3, 1));
+        } elseif (is_numeric($value) && $value == (int) $value) {
+            $retval .= htmlspecialchars(PMA_Util::formatNumber($value, 3, 0));
+        } elseif (is_numeric($value)) {
+            $retval .= htmlspecialchars(PMA_Util::formatNumber($value, 3, 1));
+        } else {
+            $retval .= htmlspecialchars($value);
+        }
+        if (isset($alerts[$name])) {
+            $retval .= '</span>';
+        }
+        $retval .= '</span>';
+        $retval .= '<span style="display:none;" class="original">';
+        $retval .= $value;
+        $retval .= '</span>';
+        $retval .= '</td>';
+        $retval .= '<td class="descr">';
+
+        if (isset($strShowStatus[$name])) {
+            $retval .= $strShowStatus[$name];
+        }
+
+        if (isset($ServerStatusData->links[$name])) {
+            foreach ($ServerStatusData->links[$name] as $link_name => $link_url) {
+                if ('doc' == $link_name) {
+                    $retval .= PMA_Util::showMySQLDocu($link_url, $link_url);
+                } else {
+                    $retval .= ' <a href="' . $link_url . '">' . $link_name . '</a>';
+                }
+            }
+            unset($link_url, $link_name);
+        }
+        $retval .= '</td>';
+        $retval .= '</tr>';
+    }
+    $retval .= '</tbody>';
+    $retval .= '</table>';
+
+    return $retval;
+}
+
+/**
+ * Returns a list of variable descriptions
+ *
+ * @return array
+ */
+function getStatusVariablesDescriptions()
+{
+    /**
+     * Messages are built using the message name
+     */
+    return array(
+        'Aborted_clients' => __(
+            'The number of connections that were aborted because the client died'
+            . ' without closing the connection properly.'
+        ),
+        'Aborted_connects' => __(
+            'The number of failed attempts to connect to the MySQL server.'
+        ),
+        'Binlog_cache_disk_use' => __(
+            'The number of transactions that used the temporary binary log cache'
+            . ' but that exceeded the value of binlog_cache_size and used a'
+            . ' temporary file to store statements from the transaction.'
+        ),
+        'Binlog_cache_use' => __(
+            'The number of transactions that used the temporary binary log cache.'
+        ),
+        'Connections' => __(
+            'The number of connection attempts (successful or not)'
+            . ' to the MySQL server.'
+        ),
+        'Created_tmp_disk_tables' => __(
+            'The number of temporary tables on disk created automatically by'
+            . ' the server while executing statements. If'
+            . ' Created_tmp_disk_tables is big, you may want to increase the'
+            . ' tmp_table_size  value to cause temporary tables to be'
+            . ' memory-based instead of disk-based.'
+        ),
+        'Created_tmp_files' => __(
+            'How many temporary files mysqld has created.'
+        ),
+        'Created_tmp_tables' => __(
+            'The number of in-memory temporary tables created automatically'
+            . ' by the server while executing statements.'
+        ),
+        'Delayed_errors' => __(
+            'The number of rows written with INSERT DELAYED for which some'
+            . ' error occurred (probably duplicate key).'
+        ),
+        'Delayed_insert_threads' => __(
+            'The number of INSERT DELAYED handler threads in use. Every'
+            . ' different table on which one uses INSERT DELAYED gets'
+            . ' its own thread.'
+        ),
+        'Delayed_writes' => __(
+            'The number of INSERT DELAYED rows written.'
+        ),
+        'Flush_commands'  => __(
+            'The number of executed FLUSH statements.'
+        ),
+        'Handler_commit' => __(
+            'The number of internal COMMIT statements.'
+        ),
+        'Handler_delete' => __(
+            'The number of times a row was deleted from a table.'
+        ),
+        'Handler_discover' => __(
+            'The MySQL server can ask the NDB Cluster storage engine if it'
+            . ' knows about a table with a given name. This is called discovery.'
+            . ' Handler_discover indicates the number of time tables have been'
+            . ' discovered.'
+        ),
+        'Handler_read_first' => __(
+            'The number of times the first entry was read from an index. If this'
+            . ' is high, it suggests that the server is doing a lot of full'
+            . ' index scans; for example, SELECT col1 FROM foo, assuming that'
+            . ' col1 is indexed.'
+        ),
+        'Handler_read_key' => __(
+            'The number of requests to read a row based on a key. If this is'
+            . ' high, it is a good indication that your queries and tables'
+            . ' are properly indexed.'
+        ),
+        'Handler_read_next' => __(
+            'The number of requests to read the next row in key order. This is'
+            . ' incremented if you are querying an index column with a range'
+            . ' constraint or if you are doing an index scan.'
+        ),
+        'Handler_read_prev' => __(
+            'The number of requests to read the previous row in key order.'
+            . ' This read method is mainly used to optimize ORDER BY … DESC.'
+        ),
+        'Handler_read_rnd' => __(
+            'The number of requests to read a row based on a fixed position.'
+            . ' This is high if you are doing a lot of queries that require'
+            . ' sorting of the result. You probably have a lot of queries that'
+            . ' require MySQL to scan whole tables or you have joins that'
+            . ' don\'t use keys properly.'
+        ),
+        'Handler_read_rnd_next' => __(
+            'The number of requests to read the next row in the data file.'
+            . ' This is high if you are doing a lot of table scans. Generally'
+            . ' this suggests that your tables are not properly indexed or that'
+            . ' your queries are not written to take advantage of the indexes'
+            . ' you have.'
+        ),
+        'Handler_rollback' => __(
+            'The number of internal ROLLBACK statements.'
+        ),
+        'Handler_update' => __(
+            'The number of requests to update a row in a table.'
+        ),
+        'Handler_write' => __(
+            'The number of requests to insert a row in a table.'
+        ),
+        'Innodb_buffer_pool_pages_data' => __(
+            'The number of pages containing data (dirty or clean).'
+        ),
+        'Innodb_buffer_pool_pages_dirty' => __(
+            'The number of pages currently dirty.'
+        ),
+        'Innodb_buffer_pool_pages_flushed' => __(
+            'The number of buffer pool pages that have been requested'
+            . ' to be flushed.'
+        ),
+        'Innodb_buffer_pool_pages_free' => __(
+            'The number of free pages.'
+        ),
+        'Innodb_buffer_pool_pages_latched' => __(
+            'The number of latched pages in InnoDB buffer pool. These are pages'
+            . ' currently being read or written or that can\'t be flushed or'
+            . ' removed for some other reason.'
+        ),
+        'Innodb_buffer_pool_pages_misc' => __(
+            'The number of pages busy because they have been allocated for'
+            . ' administrative overhead such as row locks or the adaptive'
+            . ' hash index. This value can also be calculated as'
+            . ' Innodb_buffer_pool_pages_total - Innodb_buffer_pool_pages_free'
+            . ' - Innodb_buffer_pool_pages_data.'
+        ),
+        'Innodb_buffer_pool_pages_total' => __(
+            'Total size of buffer pool, in pages.'
+        ),
+        'Innodb_buffer_pool_read_ahead_rnd' => __(
+            'The number of "random" read-aheads InnoDB initiated. This happens'
+            . ' when a query is to scan a large portion of a table but in'
+            . ' random order.'
+        ),
+        'Innodb_buffer_pool_read_ahead_seq' => __(
+            'The number of sequential read-aheads InnoDB initiated. This'
+            . ' happens when InnoDB does a sequential full table scan.'
+        ),
+        'Innodb_buffer_pool_read_requests' => __(
+            'The number of logical read requests InnoDB has done.'
+        ),
+        'Innodb_buffer_pool_reads' => __(
+            'The number of logical reads that InnoDB could not satisfy'
+            . ' from buffer pool and had to do a single-page read.'
+        ),
+        'Innodb_buffer_pool_wait_free' => __(
+            'Normally, writes to the InnoDB buffer pool happen in the'
+            . ' background. However, if it\'s necessary to read or create a page'
+            . ' and no clean pages are available, it\'s necessary to wait for'
+            . ' pages to be flushed first. This counter counts instances of'
+            . ' these waits. If the buffer pool size was set properly, this'
+            . ' value should be small.'
+        ),
+        'Innodb_buffer_pool_write_requests' => __(
+            'The number writes done to the InnoDB buffer pool.'
+        ),
+        'Innodb_data_fsyncs' => __(
+            'The number of fsync() operations so far.'
+        ),
+        'Innodb_data_pending_fsyncs' => __(
+            'The current number of pending fsync() operations.'
+        ),
+        'Innodb_data_pending_reads' => __(
+            'The current number of pending reads.'
+        ),
+        'Innodb_data_pending_writes' => __(
+            'The current number of pending writes.'
+        ),
+        'Innodb_data_read' => __(
+            'The amount of data read so far, in bytes.'
+        ),
+        'Innodb_data_reads' => __(
+            'The total number of data reads.'
+        ),
+        'Innodb_data_writes' => __(
+            'The total number of data writes.'
+        ),
+        'Innodb_data_written' => __(
+            'The amount of data written so far, in bytes.'
+        ),
+        'Innodb_dblwr_pages_written' => __(
+            'The number of pages that have been written for'
+            . ' doublewrite operations.'
+        ),
+        'Innodb_dblwr_writes' => __(
+            'The number of doublewrite operations that have been performed.'
+        ),
+        'Innodb_log_waits' => __(
+            'The number of waits we had because log buffer was too small and'
+            . ' we had to wait for it to be flushed before continuing.'
+        ),
+        'Innodb_log_write_requests' => __(
+            'The number of log write requests.'
+        ),
+        'Innodb_log_writes' => __(
+            'The number of physical writes to the log file.'
+        ),
+        'Innodb_os_log_fsyncs' => __(
+            'The number of fsync() writes done to the log file.'
+        ),
+        'Innodb_os_log_pending_fsyncs' => __(
+            'The number of pending log file fsyncs.'
+        ),
+        'Innodb_os_log_pending_writes' => __(
+            'Pending log file writes.'
+        ),
+        'Innodb_os_log_written' => __(
+            'The number of bytes written to the log file.'
+        ),
+        'Innodb_pages_created' => __(
+            'The number of pages created.'
+        ),
+        'Innodb_page_size' => __(
+            'The compiled-in InnoDB page size (default 16KB). Many values are'
+            . ' counted in pages; the page size allows them to be easily'
+            . ' converted to bytes.'
+        ),
+        'Innodb_pages_read' => __(
+            'The number of pages read.'
+        ),
+        'Innodb_pages_written' => __(
+            'The number of pages written.'
+        ),
+        'Innodb_row_lock_current_waits' => __(
+            'The number of row locks currently being waited for.'
+        ),
+        'Innodb_row_lock_time_avg' => __(
+            'The average time to acquire a row lock, in milliseconds.'
+        ),
+        'Innodb_row_lock_time' => __(
+            'The total time spent in acquiring row locks, in milliseconds.'
+        ),
+        'Innodb_row_lock_time_max' => __(
+            'The maximum time to acquire a row lock, in milliseconds.'
+        ),
+        'Innodb_row_lock_waits' => __(
+            'The number of times a row lock had to be waited for.'
+        ),
+        'Innodb_rows_deleted' => __(
+            'The number of rows deleted from InnoDB tables.'
+        ),
+        'Innodb_rows_inserted' => __(
+            'The number of rows inserted in InnoDB tables.'
+        ),
+        'Innodb_rows_read' => __(
+            'The number of rows read from InnoDB tables.'
+        ),
+        'Innodb_rows_updated' => __(
+            'The number of rows updated in InnoDB tables.'
+        ),
+        'Key_blocks_not_flushed' => __(
+            'The number of key blocks in the key cache that have changed but'
+            . ' haven\'t yet been flushed to disk. It used to be known as'
+            . ' Not_flushed_key_blocks.'
+        ),
+        'Key_blocks_unused' => __(
+            'The number of unused blocks in the key cache. You can use this'
+            . ' value to determine how much of the key cache is in use.'
+        ),
+        'Key_blocks_used' => __(
+            'The number of used blocks in the key cache. This value is a'
+            . ' high-water mark that indicates the maximum number of blocks'
+            . ' that have ever been in use at one time.'
+        ),
+        'Key_buffer_fraction_%' => __(
+            'Percentage of used key cache (calculated value)'
+        ),
+        'Key_read_requests' => __(
+            'The number of requests to read a key block from the cache.'
+        ),
+        'Key_reads' => __(
+            'The number of physical reads of a key block from disk. If Key_reads'
+            . ' is big, then your key_buffer_size value is probably too small.'
+            . ' The cache miss rate can be calculated as'
+            . ' Key_reads/Key_read_requests.'
+        ),
+        'Key_read_ratio_%' => __(
+            'Key cache miss calculated as rate of physical reads compared'
+            . ' to read requests (calculated value)'
+        ),
+        'Key_write_requests' => __(
+            'The number of requests to write a key block to the cache.'
+        ),
+        'Key_writes' => __(
+            'The number of physical writes of a key block to disk.'
+        ),
+        'Key_write_ratio_%' => __(
+            'Percentage of physical writes compared'
+            . ' to write requests (calculated value)'
+        ),
+        'Last_query_cost' => __(
+            'The total cost of the last compiled query as computed by the query'
+            . ' optimizer. Useful for comparing the cost of different query'
+            . ' plans for the same query. The default value of 0 means that'
+            . ' no query has been compiled yet.'
+        ),
+        'Max_used_connections' => __(
+            'The maximum number of connections that have been in use'
+            . ' simultaneously since the server started.'
+        ),
+        'Not_flushed_delayed_rows' => __(
+            'The number of rows waiting to be written in INSERT DELAYED queues.'
+        ),
+        'Opened_tables' => __(
+            'The number of tables that have been opened. If opened tables is'
+            . ' big, your table cache value is probably too small.'
+        ),
+        'Open_files' => __(
+            'The number of files that are open.'
+        ),
+        'Open_streams' => __(
+            'The number of streams that are open (used mainly for logging).'
+        ),
+        'Open_tables' => __(
+            'The number of tables that are open.'
+        ),
+        'Qcache_free_blocks' => __(
+            'The number of free memory blocks in query cache. High numbers can'
+            . ' indicate fragmentation issues, which may be solved by issuing'
+            . ' a FLUSH QUERY CACHE statement.'
+        ),
+        'Qcache_free_memory' => __(
+            'The amount of free memory for query cache.'
+        ),
+        'Qcache_hits' => __(
+            'The number of cache hits.'
+        ),
+        'Qcache_inserts' => __(
+            'The number of queries added to the cache.'
+        ),
+        'Qcache_lowmem_prunes' => __(
+            'The number of queries that have been removed from the cache to'
+            . ' free up memory for caching new queries. This information can'
+            . ' help you tune the query cache size. The query cache uses a'
+            . ' least recently used (LRU) strategy to decide which queries'
+            . ' to remove from the cache.'
+        ),
+        'Qcache_not_cached' => __(
+            'The number of non-cached queries (not cachable, or not cached'
+            . ' due to the query_cache_type setting).'
+        ),
+        'Qcache_queries_in_cache' => __(
+            'The number of queries registered in the cache.'
+        ),
+        'Qcache_total_blocks' => __(
+            'The total number of blocks in the query cache.'
+        ),
+        'Rpl_status' => __(
+            'The status of failsafe replication (not yet implemented).'
+        ),
+        'Select_full_join' => __(
+            'The number of joins that do not use indexes. If this value is'
+            . ' not 0, you should carefully check the indexes of your tables.'
+        ),
+        'Select_full_range_join' => __(
+            'The number of joins that used a range search on a reference table.'
+        ),
+        'Select_range_check' => __(
+            'The number of joins without keys that check for key usage after'
+            . ' each row. (If this is not 0, you should carefully check the'
+            . ' indexes of your tables.)'
+        ),
+        'Select_range' => __(
+            'The number of joins that used ranges on the first table. (It\'s'
+            . ' normally not critical even if this is big.)'
+        ),
+        'Select_scan' => __(
+            'The number of joins that did a full scan of the first table.'
+        ),
+        'Slave_open_temp_tables' => __(
+            'The number of temporary tables currently'
+            . ' open by the slave SQL thread.'
+        ),
+        'Slave_retried_transactions' => __(
+            'Total (since startup) number of times the replication slave SQL'
+            . ' thread has retried transactions.'
+        ),
+        'Slave_running' => __(
+            'This is ON if this server is a slave that is connected to a master.'
+        ),
+        'Slow_launch_threads' => __(
+            'The number of threads that have taken more than slow_launch_time'
+            . ' seconds to create.'
+        ),
+        'Slow_queries' => __(
+            'The number of queries that have taken more than long_query_time'
+            . ' seconds.'
+        ),
+        'Sort_merge_passes' => __(
+            'The number of merge passes the sort algorithm has had to do.'
+            . ' If this value is large, you should consider increasing the'
+            . ' value of the sort_buffer_size system variable.'
+        ),
+        'Sort_range' => __(
+            'The number of sorts that were done with ranges.'
+        ),
+        'Sort_rows' => __(
+            'The number of sorted rows.'
+        ),
+        'Sort_scan' => __(
+            'The number of sorts that were done by scanning the table.'
+        ),
+        'Table_locks_immediate' => __(
+            'The number of times that a table lock was acquired immediately.'
+        ),
+        'Table_locks_waited' => __(
+            'The number of times that a table lock could not be acquired'
+            . ' immediately and a wait was needed. If this is high, and you have'
+            . ' performance problems, you should first optimize your queries,'
+            . ' and then either split your table or tables or use replication.'
+        ),
+        'Threads_cached' => __(
+            'The number of threads in the thread cache. The cache hit rate can'
+            . ' be calculated as Threads_created/Connections. If this value is'
+            . ' red you should raise your thread_cache_size.'
+        ),
+        'Threads_connected' => __(
+            'The number of currently open connections.'
+        ),
+        'Threads_created' => __(
+            'The number of threads created to handle connections. If'
+            . ' Threads_created is big, you may want to increase the'
+            . ' thread_cache_size value. (Normally this doesn\'t give a notable'
+            . ' performance improvement if you have a good thread'
+            . ' implementation.)'
+        ),
+        'Threads_cache_hitrate_%' => __(
+            'Thread cache hit rate (calculated value)'
+        ),
+        'Threads_running' => __(
+            'The number of threads that are not sleeping.'
+        )
+    );
+}
+
+?>
diff --git a/phpmyadmin/server_variables.php b/phpmyadmin/server_variables.php
new file mode 100644
index 0000000..d1d6b91
--- /dev/null
+++ b/phpmyadmin/server_variables.php
@@ -0,0 +1,247 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * Server variables
+ *
+ * @package PhpMyAdmin
+ */
+
+require_once 'libraries/common.inc.php';
+
+$response = PMA_Response::getInstance();
+$header   = $response->getHeader();
+$scripts  = $header->getScripts();
+$scripts->addFile('server_variables.js');
+
+/**
+ * Does the common work
+ */
+require 'libraries/server_common.inc.php';
+
+/**
+ * Required to display documentation links
+ */
+require 'libraries/server_variables_doc.php';
+
+/**
+ * Ajax request
+ */
+
+if (isset($_REQUEST['ajax_request']) && $_REQUEST['ajax_request'] == true) {
+    $response = PMA_Response::getInstance();
+
+    if (isset($_REQUEST['type'])) {
+        if ($_REQUEST['type'] === 'getval') {
+            // Send with correct charset
+            header('Content-Type: text/html; charset=UTF-8');
+            $varValue = PMA_DBI_fetch_single_row(
+                'SHOW GLOBAL VARIABLES WHERE Variable_name="'
+                . PMA_Util::sqlAddSlashes($_REQUEST['varName']) . '";',
+                'NUM'
+            );
+            if (isset($VARIABLE_DOC_LINKS[$_REQUEST['varName']][3])
+                && $VARIABLE_DOC_LINKS[$_REQUEST['varName']][3] == 'byte'
+            ) {
+                $response->addJSON(
+                    'message',
+                    implode(
+                        ' ', PMA_Util::formatByteDown($varValue[1], 3, 3)
+                    )
+                );
+            } else {
+                $response->addJSON(
+                    'message',
+                    $varValue[1]
+                );
+            }
+        } else if ($_REQUEST['type'] === 'setval') {
+            $value = $_REQUEST['varValue'];
+
+            if (isset($VARIABLE_DOC_LINKS[$_REQUEST['varName']][3])
+                && $VARIABLE_DOC_LINKS[$_REQUEST['varName']][3] == 'byte'
+                && preg_match(
+                    '/^\s*(\d+(\.\d+)?)\s*(mb|kb|mib|kib|gb|gib)\s*$/i',
+                    $value,
+                    $matches
+                )
+            ) {
+                $exp = array(
+                    'kb' => 1,
+                    'kib' => 1,
+                    'mb' => 2,
+                    'mib' => 2,
+                    'gb' => 3,
+                    'gib' => 3
+                );
+                $value = floatval($matches[1]) * PMA_Util::pow(
+                    1024,
+                    $exp[strtolower($matches[3])]
+                );
+            } else {
+                $value = PMA_Util::sqlAddSlashes($value);
+            }
+
+            if (! is_numeric($value)) {
+                $value="'" . $value . "'";
+            }
+
+            if (! preg_match("/[^a-zA-Z0-9_]+/", $_REQUEST['varName'])
+                && PMA_DBI_query(
+                    'SET GLOBAL ' . $_REQUEST['varName'] . ' = ' . $value
+                )
+            ) {
+                // Some values are rounded down etc.
+                $varValue = PMA_DBI_fetch_single_row(
+                    'SHOW GLOBAL VARIABLES WHERE Variable_name="'
+                    . PMA_Util::sqlAddSlashes($_REQUEST['varName'])
+                    . '";', 'NUM'
+                );
+                $response->addJSON(
+                    'variable',
+                    formatVariable($_REQUEST['varName'], $varValue[1])
+                );
+            } else {
+                $response->isSuccess(false);
+                $response->addJSON(
+                    'error',
+                    __('Setting variable failed')
+                );
+            }
+        }
+        exit;
+    }
+}
+
+/**
+ * Displays the sub-page heading
+ */
+$output = '<h2>' . PMA_Util::getImage('s_vars.png')
+    . '' . __('Server variables and settings') . "\n"
+    . PMA_Util::showMySQLDocu(
+        'server_system_variables', 'server_system_variables'
+    )
+    . '</h2>' . "\n";
+
+/**
+ * Link templates
+ */
+$url = htmlspecialchars('server_variables.php?' . PMA_generate_common_url());
+$output .= '<a style="display: none;" href="#" class="editLink">';
+$output .= PMA_Util::getIcon('b_edit.png', __('Edit')) . '</a>';
+$output .= '<a style="display: none;" href="' . $url . '" class="ajax saveLink">';
+$output .= PMA_Util::getIcon('b_save.png', __('Save')) . '</a> ';
+$output .= '<a style="display: none;" href="#" class="cancelLink">';
+$output .= PMA_Util::getIcon('b_close.png', __('Cancel')) . '</a> ';
+$output .= PMA_Util::getImage(
+    'b_help.png',
+    __('Documentation'),
+    array(
+        'style' => 'display:none',
+        'id' => 'docImage'
+    )
+);
+
+/**
+ * Sends the queries and buffers the results
+ */
+$serverVarsSession = PMA_DBI_fetch_result('SHOW SESSION VARIABLES;', 0, 1);
+$serverVars = PMA_DBI_fetch_result('SHOW GLOBAL VARIABLES;', 0, 1);
+
+
+/**
+ * Displays the page
+ */
+$value = ! empty($_REQUEST['filter']) ? htmlspecialchars($_REQUEST['filter']) : '';
+$output .= '<fieldset id="tableFilter">'
+    . '<legend>' . __('Filters') . '</legend>'
+    . '<div class="formelement">'
+    . '<label for="filterText">' .  __('Containing the word:') . '</label>'
+    . '<input name="filterText" type="text" id="filterText"'
+    . ' style="vertical-align: baseline;" value="' . $value . '" />'
+    . '</div>'
+    . '</fieldset>';
+
+$output .= '<div id="serverVariables" class="data filteredData noclick">'
+    . '<div class="var-header var-row">'
+    . '<div class="var-name">' .  __('Variable') . '</div>'
+    . '<div class="var-value valueHeader">'
+    . __('Session value') . ' / ' . __('Global value')
+    . '</div>'
+    . '<div style="clear:both"></div>'
+    . '</div>';
+
+$odd_row = true;
+foreach ($serverVars as $name => $value) {
+    $has_session_value = isset($serverVarsSession[$name])
+        && $serverVarsSession[$name] != $value;
+    $row_class = ($odd_row ? ' odd' : ' even')
+        . ($has_session_value ? ' diffSession' : '');
+
+    $output .= '<div class="var-row' . $row_class . '">'
+        . '<div class="var-name">';
+
+    // To display variable documentation link
+    if (isset($VARIABLE_DOC_LINKS[$name])) {
+        $output .= '<span title="' . htmlspecialchars(str_replace('_', ' ', $name)) . '">';
+        $output .= PMA_Util::showMySQLDocu(
+            $VARIABLE_DOC_LINKS[$name][1],
+            $VARIABLE_DOC_LINKS[$name][1],
+            false,
+            $VARIABLE_DOC_LINKS[$name][2] . '_' . $VARIABLE_DOC_LINKS[$name][0],
+            true
+        );
+        $output .= htmlspecialchars(str_replace('_', ' ', $name));
+        $output .= '</a>';
+        $output .= '</span>';
+    } else {
+        $output .= htmlspecialchars(str_replace('_', ' ', $name));
+    }
+    $output .= '</div>'
+        . '<div class="var-value value' . (PMA_isSuperuser() ? ' editable' : '') . '"> '
+        . formatVariable($name, $value)
+        . '</div>'
+        . '<div style="clear:both"></div>'
+        . '</div>';
+
+    if ($has_session_value) {
+        $output .= '<div class="var-row' . ($odd_row ? ' odd' : ' even') . '">'
+            . '<div class="var-name session">(' . __('Session value') . ')</div>'
+            . '<div class="var-value value"> ' . formatVariable($name, $serverVarsSession[$name]) . '</div>'
+            . '<div style="clear:both"></div>'
+            . '</div>';
+    }
+
+    $odd_row = ! $odd_row;
+}
+$output .= '</div>';
+
+$response->addHtml($output);
+
+/**
+ * Format Variable
+ *
+ * @param string  $name  variable name
+ * @param numeric $value variable value
+ *
+ * @return formatted string
+ */
+function formatVariable($name, $value)
+{
+    global $VARIABLE_DOC_LINKS;
+
+    if (is_numeric($value)) {
+        if (isset($VARIABLE_DOC_LINKS[$name][3])
+            && $VARIABLE_DOC_LINKS[$name][3]=='byte'
+        ) {
+            return '<abbr title="'
+                . PMA_Util::formatNumber($value, 0) . '">'
+                . implode(' ', PMA_Util::formatByteDown($value, 3, 3))
+                . '</abbr>';
+        } else {
+            return PMA_Util::formatNumber($value, 0);
+        }
+    }
+    return htmlspecialchars($value);
+}
+
+?>
diff --git a/phpmyadmin/setup/ajax.js b/phpmyadmin/setup/ajax.js
new file mode 100644
index 0000000..98d985a
--- /dev/null
+++ b/phpmyadmin/setup/ajax.js
@@ -0,0 +1,11 @@
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * Dummy implementation of the ajax page loader
+ */
+var AJAX = {
+    registerOnload: function (idx, func) {
+        $(document).ready(func);
+    },
+    registerTeardown: function (idx, func) {
+    }
+};
diff --git a/phpmyadmin/setup/config.php b/phpmyadmin/setup/config.php
new file mode 100644
index 0000000..e923211
--- /dev/null
+++ b/phpmyadmin/setup/config.php
@@ -0,0 +1,78 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * Front controller for config view / download and clear
+ *
+ * @package PhpMyAdmin-Setup
+ */
+
+/**
+ * Core libraries.
+ */
+require './lib/common.inc.php';
+require_once './libraries/config/Form.class.php';
+require_once './libraries/config/FormDisplay.class.php';
+require_once './setup/lib/ConfigGenerator.class.php';
+
+require './libraries/config/setup.forms.php';
+
+$form_display = new FormDisplay();
+$form_display->registerForm('_config.php', $forms['_config.php']);
+$form_display->save('_config.php');
+$config_file_path = ConfigFile::getInstance()->getFilePath();
+
+if (isset($_POST['eol'])) {
+    $_SESSION['eol'] = ($_POST['eol'] == 'unix') ? 'unix' : 'win';
+}
+
+if (PMA_ifSetOr($_POST['submit_clear'], '')) {
+    //
+    // Clear current config and return to main page
+    //
+    ConfigFile::getInstance()->resetConfigData();
+    // drop post data
+    header('HTTP/1.1 303 See Other');
+    header('Location: index.php');
+    exit;
+} elseif (PMA_ifSetOr($_POST['submit_download'], '')) {
+    //
+    // Output generated config file
+    //
+    PMA_downloadHeader('config.inc.php', 'text/plain');
+    echo ConfigGenerator::getConfigFile();
+    exit;
+} elseif (PMA_ifSetOr($_POST['submit_save'], '')) {
+    //
+    // Save generated config file on the server
+    //
+    file_put_contents($config_file_path, ConfigGenerator::getConfigFile());
+    header('HTTP/1.1 303 See Other');
+    header('Location: index.php?action_done=config_saved');
+    exit;
+} elseif (PMA_ifSetOr($_POST['submit_load'], '')) {
+    //
+    // Load config file from the server
+    //
+    $cfg = array();
+    include_once $config_file_path;
+    ConfigFile::getInstance()->setConfigData($cfg);
+    header('HTTP/1.1 303 See Other');
+    header('Location: index.php');
+    exit;
+} elseif (PMA_ifSetOr($_POST['submit_delete'], '')) {
+    //
+    // Delete config file on the server
+    //
+    @unlink($config_file_path);
+    header('HTTP/1.1 303 See Other');
+    header('Location: index.php');
+    exit;
+} else {
+    //
+    // Show generated config file in a <textarea>
+    //
+    header('HTTP/1.1 303 See Other');
+    header('Location: index.php?page=config');
+    exit;
+}
+?>
diff --git a/phpmyadmin/setup/frames/.htaccess b/phpmyadmin/setup/frames/.htaccess
new file mode 100644
index 0000000..56baee6
--- /dev/null
+++ b/phpmyadmin/setup/frames/.htaccess
@@ -0,0 +1,3 @@
+# This folder does not require access over HTTP
+# (the following directive denies access by default)
+Order allow,deny
diff --git a/phpmyadmin/setup/frames/config.inc.php b/phpmyadmin/setup/frames/config.inc.php
new file mode 100644
index 0000000..c409c64
--- /dev/null
+++ b/phpmyadmin/setup/frames/config.inc.php
@@ -0,0 +1,48 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * Config file view and save screen
+ *
+ * @package PhpMyAdmin-Setup
+ */
+
+if (!defined('PHPMYADMIN')) {
+    exit;
+}
+
+/**
+ * Core libraries.
+ */
+require_once './libraries/config/FormDisplay.class.php';
+require_once './setup/lib/index.lib.php';
+require_once './setup/lib/ConfigGenerator.class.php';
+
+$config_readable = false;
+$config_writable = false;
+$config_exists = false;
+check_config_rw($config_readable, $config_writable, $config_exists);
+?>
+<h2><?php echo __('Configuration file') ?></h2>
+<?php PMA_displayFormTop('config.php'); ?>
+<input type="hidden" name="eol" value="<?php echo htmlspecialchars(PMA_ifSetOr($_GET['eol'], 'unix')) ?>" />
+<?php PMA_displayFieldsetTop('', '', null, array('class' => 'simple')); ?>
+<tr>
+    <td>
+        <textarea cols="50" rows="20" name="textconfig" id="textconfig" spellcheck="false"><?php
+            echo htmlspecialchars(ConfigGenerator::getConfigFile())
+        ?></textarea>
+    </td>
+</tr>
+<tr>
+    <td class="lastrow" style="text-align: left">
+        <input type="submit" name="submit_download" value="<?php echo __('Download') ?>" class="green" />
+        <input type="submit" name="submit_save" value="<?php echo __('Save') ?>"<?php
+if (!$config_writable) {
+    echo ' disabled="disabled"';
+} ?> />
+    </td>
+</tr>
+<?php
+PMA_displayFieldsetBottomSimple();
+PMA_displayFormBottom();
+?>
diff --git a/phpmyadmin/setup/frames/form.inc.php b/phpmyadmin/setup/frames/form.inc.php
new file mode 100644
index 0000000..cf188eb
--- /dev/null
+++ b/phpmyadmin/setup/frames/form.inc.php
@@ -0,0 +1,36 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * Form edit view
+ *
+ * @package PhpMyAdmin-Setup
+ */
+
+if (!defined('PHPMYADMIN')) {
+    exit;
+}
+
+/**
+ * Core libraries.
+ */
+require_once './libraries/config/Form.class.php';
+require_once './libraries/config/FormDisplay.class.php';
+require_once './setup/lib/form_processing.lib.php';
+
+require './libraries/config/setup.forms.php';
+
+$formset_id = filter_input(INPUT_GET, 'formset');
+$mode = filter_input(INPUT_GET, 'mode');
+if (! isset($forms[$formset_id])) {
+    PMA_fatalError(__('Incorrect formset, check $formsets array in setup/frames/form.inc.php'));
+}
+
+if (isset($GLOBALS['strConfigFormset_' . $formset_id])) {
+    echo '<h2>' . $GLOBALS['strConfigFormset_' . $formset_id] . '</h2>';
+}
+$form_display = new FormDisplay();
+foreach ($forms[$formset_id] as $form_name => $form) {
+    $form_display->registerForm($form_name, $form);
+}
+process_formset($form_display);
+?>
diff --git a/phpmyadmin/setup/frames/index.inc.php b/phpmyadmin/setup/frames/index.inc.php
new file mode 100644
index 0000000..ddc6af5
--- /dev/null
+++ b/phpmyadmin/setup/frames/index.inc.php
@@ -0,0 +1,276 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * Overview (main page)
+ *
+ * @package PhpMyAdmin-Setup
+ */
+
+if (!defined('PHPMYADMIN')) {
+    exit;
+}
+
+/**
+ * Core libraries.
+ */
+require_once './libraries/display_select_lang.lib.php';
+require_once './libraries/config/FormDisplay.class.php';
+require_once './setup/lib/index.lib.php';
+
+// prepare unfiltered language list
+$all_languages = PMA_langList();
+uasort($all_languages, 'PMA_languageCmp');
+
+$cf = ConfigFile::getInstance();
+$separator = PMA_get_arg_separator('html');
+
+// message handling
+messages_begin();
+
+//
+// Check phpMyAdmin version
+//
+if (isset($_GET['version_check'])) {
+    PMA_version_check();
+}
+
+//
+// Perform various security, compatibility and consistency checks
+//
+perform_config_checks();
+
+//
+// Check whether we can read/write configuration
+//
+$config_readable = false;
+$config_writable = false;
+$config_exists = false;
+check_config_rw($config_readable, $config_writable, $config_exists);
+if (!$config_writable || !$config_readable) {
+    messages_set(
+        'error', 'config_rw', __('Cannot load or save configuration'),
+        PMA_lang(__('Please create web server writable folder [em]config[/em] in phpMyAdmin top level directory as described in [doc at setup_script]documentation[/doc]. Otherwise you will be only able to download or display it.'))
+    );
+}
+//
+// Check https connection
+//
+$is_https = !empty($_SERVER['HTTPS']) && strtolower($_SERVER['HTTPS']) == 'on';
+if (!$is_https) {
+    $text = __('You are not using a secure connection; all data (including potentially sensitive information, like passwords) is transferred unencrypted!');
+
+    if (!empty($_SERVER['REQUEST_URI']) && !empty($_SERVER['HTTP_HOST'])) {
+        $link = 'https://' . htmlspecialchars($_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI']);
+        $strInsecureConnectionMsg2 = __('If your server is also configured to accept HTTPS requests follow [a@%s]this link[/a] to use a secure connection.');
+        $strInsecureConnectionMsg2 = sprintf($strInsecureConnectionMsg2, $link);
+        $text .= ' ' . PMA_lang($strInsecureConnectionMsg2);
+    }
+    messages_set('notice', 'no_https', __('Insecure connection'), $text);
+}
+?>
+
+<form id="select_lang" method="post" action="<?php echo htmlspecialchars($_SERVER['REQUEST_URI']) ?>">
+    <?php echo PMA_generate_common_hidden_inputs() ?>
+    <bdo lang="en" dir="ltr"><label for="lang">
+    <?php echo __('Language') . (__('Language') != 'Language' ? ' - Language' : '') ?>
+    </label></bdo><br />
+    <select id="lang" name="lang" class="autosubmit" lang="en" dir="ltr">
+    <?php
+    // create language list
+    $lang_list = array();
+    foreach ($all_languages as $each_lang_key => $each_lang) {
+        $lang_name = PMA_langName($each_lang);
+        //Is current one active?
+        $selected = ($GLOBALS['lang'] == $each_lang_key) ? ' selected="selected"' : '';
+        echo '<option value="' . $each_lang_key . '"' . $selected . '>' . $lang_name
+            . '</option>' . "\n";
+    }
+    ?>
+    </select>
+</form>
+
+<?php
+// Check for done action info and set notice message if present
+switch ($action_done) {
+case 'config_saved':
+    /* Use uniqid to display this message every time configuration is saved */
+    messages_set(
+        'notice', uniqid('config_saved'), __('Configuration saved.'),
+        PMA_lang(__('Configuration saved to file config/config.inc.php in phpMyAdmin top level directory, copy it to top level one and delete directory config to use it.'))
+    );
+    break;
+default:
+    break;
+}
+?>
+
+<h2><?php echo __('Overview') ?></h2>
+
+<?php
+// message handling
+messages_end();
+messages_show_html();
+?>
+
+<a href="#" id="show_hidden_messages" style="display:none"><?php echo __('Show hidden messages (#MSG_COUNT)') ?></a>
+
+<fieldset class="simple"><legend><?php echo __('Servers') ?></legend>
+<?php
+//
+// Display server list
+//
+PMA_displayFormTop(
+    'index.php', 'get',
+    array(
+        'page' => 'servers',
+        'mode' => 'add'
+    )
+);
+?>
+<div class="form">
+<?php if ($cf->getServerCount() > 0) { ?>
+<table cellspacing="0" class="datatable" style="table-layout: fixed">
+<tr>
+    <th>#</th>
+    <th><?php echo __('Name') ?></th>
+    <th><?php echo __('Authentication type') ?></th>
+    <th colspan="2">DSN</th>
+</tr>
+<?php foreach ($cf->getServers() as $id => $server) { ?>
+<tr>
+    <td><?php echo $id ?></td>
+    <td><?php echo htmlspecialchars($cf->getServerName($id)) ?></td>
+    <td><?php echo htmlspecialchars($cf->getValue("Servers/$id/auth_type")) ?></td>
+    <td><?php echo htmlspecialchars($cf->getServerDSN($id)) ?></td>
+    <td style="white-space: nowrap">
+        <small>
+        <a href="<?php echo "?page=servers{$separator}mode=edit{$separator}id=$id" ?>"><?php echo __('Edit') ?></a>
+        | <a href="<?php echo "?page=servers{$separator}mode=remove{$separator}id=$id" ?>"><?php echo __('Delete') ?></a>
+        </small>
+    </td>
+</tr>
+<?php } ?>
+</table>
+<?php } else { ?>
+<table width="100%">
+<tr>
+    <td>
+        <i><?php echo __('There are no configured servers') ?></i>
+    </td>
+</tr>
+</table>
+<?php } ?>
+<table width="100%">
+<tr>
+    <td class="lastrow" style="text-align: left">
+        <input type="submit" name="submit" value="<?php echo __('New server') ?>" />
+    </td>
+</tr>
+</table>
+</div>
+<?php
+PMA_displayFormBottom();
+?>
+</fieldset>
+
+<fieldset class="simple"><legend><?php echo __('Configuration file') ?></legend>
+<?php
+//
+// Display config file settings and load/save form
+//
+$form_display = new FormDisplay();
+
+PMA_displayFormTop('config.php');
+?>
+<table width="100%" cellspacing="0">
+<?php
+
+// Display language list
+$opts = array(
+    'doc' => $form_display->getDocLink('DefaultLang'),
+    'wiki' => $form_display->getWikiLink('DefaultLang'),
+    'values' => array(),
+    'values_escaped' => true);
+foreach ($all_languages as $each_lang_key => $each_lang) {
+    $lang_name = PMA_langName($each_lang);
+    $opts['values'][$each_lang_key] = $lang_name;
+}
+PMA_displayInput(
+    'DefaultLang', __('Default language'), 'select',
+    $cf->getValue('DefaultLang'), '', true, $opts
+);
+
+// Display server list
+$opts = array(
+    'doc' => $form_display->getDocLink('ServerDefault'),
+    'wiki' => $form_display->getWikiLink('ServerDefault'),
+    'values' => array(),
+    'values_disabled' => array());
+if ($cf->getServerCount() > 0) {
+    $opts['values']['0'] = __('let the user choose');
+    $opts['values']['-'] = '------------------------------';
+    if ($cf->getServerCount() == 1) {
+        $opts['values_disabled'][] = '0';
+    }
+    $opts['values_disabled'][] = '-';
+
+    foreach ($cf->getServers() as $id => $server) {
+        $opts['values'][(string)$id] = $cf->getServerName($id) . " [$id]";
+    }
+} else {
+    $opts['values']['1'] = __('- none -');
+    $opts['values_escaped'] = true;
+}
+PMA_displayInput(
+    'ServerDefault', __('Default server'), 'select',
+    $cf->getValue('ServerDefault'), '', true, $opts
+);
+
+// Display EOL list
+$opts = array(
+    'values' => array(
+        'unix' => 'UNIX / Linux (\n)',
+        'win' => 'Windows (\r\n)'),
+    'values_escaped' => true);
+$eol = PMA_ifSetOr($_SESSION['eol'], (PMA_IS_WINDOWS ? 'win' : 'unix'));
+PMA_displayInput(
+    'eol', __('End of line'), 'select',
+    $eol, '', true, $opts
+);
+?>
+<tr>
+    <td colspan="2" class="lastrow" style="text-align: left">
+        <input type="submit" name="submit_display" value="<?php echo __('Display') ?>" />
+        <input type="submit" name="submit_download" value="<?php echo __('Download') ?>" />
+           
+        <input type="submit" name="submit_save" value="<?php echo __('Save') ?>"<?php
+if (!$config_writable) {
+    echo ' disabled="disabled"';
+} ?> />
+        <input type="submit" name="submit_load" value="<?php echo __('Load') ?>"<?php
+if (!$config_exists) {
+    echo ' disabled="disabled"';
+} ?> />
+        <input type="submit" name="submit_delete" value="<?php echo __('Delete')
+        ?>"<?php
+if (!$config_exists || !$config_writable) {
+    echo ' disabled="disabled"';
+} ?> />
+           
+        <input type="submit" name="submit_clear" value="<?php echo __('Clear')
+        ?>" class="red" />
+    </td>
+</tr>
+</table>
+<?php
+PMA_displayFormBottom();
+?>
+</fieldset>
+<div id="footer">
+    <a href="http://phpmyadmin.net"><?php echo __('phpMyAdmin homepage') ?></a>
+    <a href="http://sourceforge.net/donate/index.php?group_id=23067"><?php
+    echo __('Donate') ?></a>
+    <a href="?version_check=1<?php
+    echo "{$separator}token="
+    . $_SESSION[' PMA_token '] ?>"><?php echo __('Check for latest version') ?></a>
+</div>
diff --git a/phpmyadmin/setup/frames/menu.inc.php b/phpmyadmin/setup/frames/menu.inc.php
new file mode 100644
index 0000000..69563a2
--- /dev/null
+++ b/phpmyadmin/setup/frames/menu.inc.php
@@ -0,0 +1,23 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * Menu items
+ *
+ * @package PhpMyAdmin-Setup
+ */
+
+if (!defined('PHPMYADMIN')) {
+    exit;
+}
+
+$separator = PMA_get_arg_separator('html');
+?>
+<ul>
+    <li><a href="index.php"><?php echo __('Overview') ?></a></li>
+    <li><a href="?page=form<?php echo $separator ?>formset=Features"><?php echo __('Features') ?></a></li>
+    <li><a href="?page=form<?php echo $separator ?>formset=Sql_queries"><?php echo __('SQL queries') ?></a></li>
+    <li><a href="?page=form<?php echo $separator ?>formset=Navi_panel"><?php echo __('Navigation panel') ?></a></li>
+    <li><a href="?page=form<?php echo $separator ?>formset=Main_panel"><?php echo __('Main panel') ?></a></li>
+    <li><a href="?page=form<?php echo $separator ?>formset=Import"><?php echo __('Import') ?></a></li>
+    <li><a href="?page=form<?php echo $separator ?>formset=Export"><?php echo __('Export') ?></a></li>
+</ul>
diff --git a/phpmyadmin/setup/frames/servers.inc.php b/phpmyadmin/setup/frames/servers.inc.php
new file mode 100644
index 0000000..d28a17d
--- /dev/null
+++ b/phpmyadmin/setup/frames/servers.inc.php
@@ -0,0 +1,49 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * Server create and edit view
+ *
+ * @package PhpMyAdmin-Setup
+ */
+
+if (!defined('PHPMYADMIN')) {
+    exit;
+}
+
+/**
+ * Core libraries.
+ */
+require_once './libraries/config/Form.class.php';
+require_once './libraries/config/FormDisplay.class.php';
+require_once './setup/lib/form_processing.lib.php';
+
+require './libraries/config/setup.forms.php';
+
+$mode = filter_input(INPUT_GET, 'mode');
+$id = filter_input(INPUT_GET, 'id', FILTER_VALIDATE_INT);
+
+$cf = ConfigFile::getInstance();
+$server_exists = !empty($id) && $cf->get("Servers/$id") !== null;
+
+if ($mode == 'edit' && $server_exists) {
+    $page_title = __('Edit server')
+        . ' ' . $id . ' <small>(' . htmlspecialchars($cf->getServerDSN($id)) . ')</small>';
+} elseif ($mode == 'remove' && $server_exists) {
+    $cf->removeServer($id);
+    header('Location: index.php');
+    exit;
+} elseif ($mode == 'revert' && $server_exists) {
+    // handled by process_formset()
+} else {
+    $page_title = __('Add a new server');
+    $id = 0;
+}
+if (isset($page_title)) {
+    echo '<h2>' . $page_title . '</h2>';
+}
+$form_display = new FormDisplay();
+foreach ($forms['Servers'] as $form_name => $form) {
+    $form_display->registerForm($form_name, $form, $id);
+}
+process_formset($form_display);
+?>
diff --git a/phpmyadmin/setup/index.php b/phpmyadmin/setup/index.php
new file mode 100644
index 0000000..7c7c12c
--- /dev/null
+++ b/phpmyadmin/setup/index.php
@@ -0,0 +1,60 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * Front controller for setup script
+ *
+ * @package PhpMyAdmin-Setup
+ * @license http://www.gnu.org/licenses/gpl.html GNU GPL 2.0
+ */
+
+/**
+ * Core libraries.
+ */
+require './lib/common.inc.php';
+
+$page = filter_input(INPUT_GET, 'page');
+$page = preg_replace('/[^a-z]/', '', $page);
+if ($page === '') {
+    $page = 'index';
+}
+if (!file_exists("./setup/frames/$page.inc.php")) {
+    // it will happen only when entering URL by hand, we don't care for these cases
+    PMA_fatalError(__('Wrong GET file attribute value'));
+}
+
+// Handle done action info
+$action_done = filter_input(INPUT_GET, 'action_done');
+$action_done = preg_replace('/[^a-z_]/', '', $action_done);
+
+PMA_noCacheHeader();
+
+?>
+<!DOCTYPE HTML>
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta charset="utf-8" />
+<title>phpMyAdmin setup</title>
+<link href="../favicon.ico" rel="icon" type="image/x-icon" />
+<link href="../favicon.ico" rel="shortcut icon" type="image/x-icon" />
+<link href="styles.css" rel="stylesheet" type="text/css" />
+<script type="text/javascript" src="../js/jquery/jquery-1.8.3.js"></script>
+<script type="text/javascript" src="../js/jquery/jquery-ui-1.9.2.custom.js"></script>
+<script type="text/javascript" src="../js/jquery/jquery.json-2.4.js"></script>
+<script type="text/javascript" src="ajax.js"></script>
+<script type="text/javascript" src="../js/config.js"></script>
+<script type="text/javascript" src="scripts.js"></script>
+</head>
+<body>
+<h1><span class="blue">php</span><span class="orange">MyAdmin</span>  setup</h1>
+<div id="menu">
+<?php
+require './setup/frames/menu.inc.php';
+?>
+</div>
+<div id="page">
+<?php
+require "./setup/frames/$page.inc.php";
+?>
+</div>
+</body>
+</html>
diff --git a/phpmyadmin/setup/lib/.htaccess b/phpmyadmin/setup/lib/.htaccess
new file mode 100644
index 0000000..56baee6
--- /dev/null
+++ b/phpmyadmin/setup/lib/.htaccess
@@ -0,0 +1,3 @@
+# This folder does not require access over HTTP
+# (the following directive denies access by default)
+Order allow,deny
diff --git a/phpmyadmin/setup/lib/ConfigGenerator.class.php b/phpmyadmin/setup/lib/ConfigGenerator.class.php
new file mode 100644
index 0000000..8dc359b
--- /dev/null
+++ b/phpmyadmin/setup/lib/ConfigGenerator.class.php
@@ -0,0 +1,154 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * Config file generator
+ *
+ * @package PhpMyAdmin-Setup
+ */
+
+/**
+ * Config file generation class
+ *
+ * @package PhpMyAdmin
+ */
+class ConfigGenerator
+{
+    /**
+     * Creates config file
+     *
+     * @return string
+     */
+    public static function getConfigFile()
+    {
+        $cf = ConfigFile::getInstance();
+
+        $crlf = (isset($_SESSION['eol']) && $_SESSION['eol'] == 'win') ? "\r\n" : "\n";
+        $c = $cf->getConfig();
+
+        // header
+        $ret = '<?php' . $crlf
+            . '/*' . $crlf
+            . ' * Generated configuration file' . $crlf
+            . ' * Generated by: phpMyAdmin '
+                    . $GLOBALS['PMA_Config']->get('PMA_VERSION')
+                    . ' setup script' . $crlf
+            . ' * Date: ' . date(DATE_RFC1123) . $crlf
+            . ' */' . $crlf . $crlf;
+
+        // servers
+        if ($cf->getServerCount() > 0) {
+            $ret .= "/* Servers configuration */$crlf\$i = 0;" . $crlf . $crlf;
+            foreach ($c['Servers'] as $id => $server) {
+                $ret .= '/* Server: ' . strtr($cf->getServerName($id) . " [$id] ", '*/', '-') . "*/" . $crlf
+                    . '$i++;' . $crlf;
+                foreach ($server as $k => $v) {
+                    $k = preg_replace('/[^A-Za-z0-9_]/', '_', $k);
+                    $ret .= "\$cfg['Servers'][\$i]['$k'] = "
+                        . (is_array($v) && self::_isZeroBasedArray($v)
+                                ? self::_exportZeroBasedArray($v, $crlf)
+                                : var_export($v, true))
+                        . ';' . $crlf;
+                }
+                $ret .= $crlf;
+            }
+            $ret .= '/* End of servers configuration */' . $crlf . $crlf;
+        }
+        unset($c['Servers']);
+
+        // other settings
+        $persistKeys = $cf->getPersistKeysMap();
+
+        foreach ($c as $k => $v) {
+            $k = preg_replace('/[^A-Za-z0-9_]/', '_', $k);
+            $ret .= self::_getVarExport($k, $v, $crlf);
+            if (isset($persistKeys[$k])) {
+                unset($persistKeys[$k]);
+            }
+        }
+        // keep 1d array keys which are present in $persist_keys (config.values.php)
+        foreach (array_keys($persistKeys) as $k) {
+            if (strpos($k, '/') === false) {
+                $k = preg_replace('/[^A-Za-z0-9_]/', '_', $k);
+                $ret .= self::_getVarExport($k, $cf->getDefault($k), $crlf);
+            }
+        }
+        $ret .= '?>';
+
+        return $ret;
+    }
+
+    /**
+     * Returns exported configuration variable
+     *
+     * @param string $var_name
+     * @param mixed  $var_value
+     * @param string $crlf
+     *
+     * @return string
+     */
+    private static function _getVarExport($var_name, $var_value, $crlf)
+    {
+        if (!is_array($var_value) || empty($var_value)) {
+            return "\$cfg['$var_name'] = " . var_export($var_value, true) . ';' . $crlf;
+        }
+        $ret = '';
+        if (self::_isZeroBasedArray($var_value)) {
+            $ret = "\$cfg['$var_name'] = " . self::_exportZeroBasedArray($var_value, $crlf)
+                . ';' . $crlf;
+        } else {
+            // string keys: $cfg[key][subkey] = value
+            foreach ($var_value as $k => $v) {
+                $k = preg_replace('/[^A-Za-z0-9_]/', '_', $k);
+                $ret .= "\$cfg['$var_name']['$k'] = " . var_export($v, true) . ';' . $crlf;
+            }
+        }
+        return $ret;
+    }
+
+    /**
+     * Check whether $array is a continuous 0-based array
+     *
+     * @param array $array
+     *
+     * @return boolean
+     */
+    private static function _isZeroBasedArray(array $array)
+    {
+        for ($i = 0; $i < count($array); $i++) {
+            if (! isset($array[$i])) {
+                return false;
+            }
+        }
+        return true;
+    }
+
+    /**
+     * Exports continuous 0-based array
+     *
+     * @param array $array
+     * @param string $crlf
+     *
+     * @return string
+     */
+    private static function _exportZeroBasedArray(array $array, $crlf)
+    {
+        $retv = array();
+        foreach ($array as $v) {
+            $retv[] = var_export($v, true);
+        }
+        $ret = "array(";
+        if (count($retv) <= 4) {
+            // up to 4 values - one line
+            $ret .= implode(', ', $retv);
+        } else {
+            // more than 4 values - value per line
+            $imax = count($retv);
+            for ($i = 0; $i < $imax; $i++) {
+                $ret .= ($i > 0 ? ',' : '') . $crlf . '    ' . $retv[$i];
+            }
+        }
+        $ret .= ')';
+        return $ret;
+    }
+}
+?>
diff --git a/phpmyadmin/setup/lib/common.inc.php b/phpmyadmin/setup/lib/common.inc.php
new file mode 100644
index 0000000..4744321
--- /dev/null
+++ b/phpmyadmin/setup/lib/common.inc.php
@@ -0,0 +1,56 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * Loads libraries/common.inc.php and preforms some additional actions
+ *
+ * @package PhpMyAdmin-Setup
+ */
+
+/**
+ * Do not include full common.
+ * @ignore
+ */
+define('PMA_MINIMUM_COMMON', true);
+define('PMA_SETUP', true);
+chdir('..');
+
+if (!file_exists('./libraries/common.inc.php')) {
+    PMA_fatalError('Bad invocation!');
+}
+
+require_once './libraries/common.inc.php';
+require_once './libraries/Util.class.php';
+require_once './libraries/config/config_functions.lib.php';
+require_once './libraries/config/messages.inc.php';
+require_once './libraries/config/ConfigFile.class.php';
+require_once './libraries/url_generating.lib.php';
+require_once './libraries/user_preferences.lib.php';
+
+// use default error handler
+restore_error_handler();
+
+// Save current language in a cookie, required since we use PMA_MINIMUM_COMMON
+$GLOBALS['PMA_Config']->setCookie('pma_lang', $GLOBALS['lang']);
+
+ConfigFile::getInstance()->setPersistKeys(
+    array(
+        'DefaultLang',
+        'ServerDefault',
+        'UploadDir',
+        'SaveDir',
+        'Servers/1/verbose',
+        'Servers/1/host',
+        'Servers/1/port',
+        'Servers/1/socket',
+        'Servers/1/extension',
+        'Servers/1/connect_type',
+        'Servers/1/auth_type',
+        'Servers/1/user',
+        'Servers/1/password'
+    )
+);
+
+// allows for redirection even after sending some data
+ob_start();
+
+?>
diff --git a/phpmyadmin/setup/lib/form_processing.lib.php b/phpmyadmin/setup/lib/form_processing.lib.php
new file mode 100644
index 0000000..d9b6e6a
--- /dev/null
+++ b/phpmyadmin/setup/lib/form_processing.lib.php
@@ -0,0 +1,62 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * Formset processing library
+ *
+ * @package PhpMyAdmin-Setup
+ */
+
+/**
+ * Processes forms registered in $form_display, handles error correction
+ *
+ * @param FormDisplay $form_display
+ *
+ * @return void
+ */
+function process_formset(FormDisplay $form_display)
+{
+    if (filter_input(INPUT_GET, 'mode') == 'revert') {
+        // revert erroneous fields to their default values
+        $form_display->fixErrors();
+        // drop post data
+        header('HTTP/1.1 303 See Other');
+        header('Location: index.php');
+        exit;
+    }
+    if (!$form_display->process(false)) {
+        // handle form view and failed POST
+        $form_display->display(true, true);
+    } else {
+        // check for form errors
+        if ($form_display->hasErrors()) {
+            // form has errors, show warning
+            $separator = PMA_get_arg_separator('html');
+            $page = filter_input(INPUT_GET, 'page');
+            $formset = filter_input(INPUT_GET, 'formset');
+            $formset = $formset ? "{$separator}formset=$formset" : '';
+            $id = filter_input(INPUT_GET, 'id', FILTER_VALIDATE_INT);
+            if ($id === null && $page == 'servers') {
+                // we've just added a new server, get it's id
+                $id = ConfigFile::getInstance()->getServerCount();
+            }
+            $id = $id ? "{$separator}id=$id" : '';
+            ?>
+            <div class="error">
+                <h4><?php echo __('Warning') ?></h4>
+                <?php echo __('Submitted form contains errors') ?><br />
+                <a href="?page=<?php echo $page . $formset . $id . $separator ?>mode=revert"><?php echo __('Try to revert erroneous fields to their default values') ?></a>
+            </div>
+            <?php $form_display->displayErrors() ?>
+            <a class="btn" href="index.php"><?php echo __('Ignore errors') ?></a>
+             
+            <a class="btn" href="?page=<?php echo $page . $formset . $id . $separator ?>mode=edit"><?php echo __('Show form') ?></a>
+            <?php
+        } else {
+            // drop post data
+            header('HTTP/1.1 303 See Other');
+            header('Location: index.php');
+            exit;
+        }
+    }
+}
+?>
diff --git a/phpmyadmin/setup/lib/index.lib.php b/phpmyadmin/setup/lib/index.lib.php
new file mode 100644
index 0000000..fe82b1e
--- /dev/null
+++ b/phpmyadmin/setup/lib/index.lib.php
@@ -0,0 +1,605 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * Various checks and message functions used on index page.
+ *
+ * @package PhpMyAdmin-Setup
+ */
+
+if (!defined('PHPMYADMIN')) {
+    exit;
+}
+
+/**
+ * Initializes message list
+ *
+ * @return void
+ */
+function messages_begin()
+{
+    if (! isset($_SESSION['messages']) || !is_array($_SESSION['messages'])) {
+        $_SESSION['messages'] = array('error' => array(), 'notice' => array());
+    } else {
+        // reset message states
+        foreach ($_SESSION['messages'] as &$messages) {
+            foreach ($messages as &$msg) {
+                $msg['fresh'] = false;
+                $msg['active'] = false;
+            }
+        }
+    }
+}
+
+/**
+ * Adds a new message to message list
+ *
+ * @param string $type    one of: notice, error
+ * @param string $id      unique message identifier
+ * @param string $title   language string id (in $str array)
+ * @param string $message message text
+ *
+ * @return void
+ */
+function messages_set($type, $id, $title, $message)
+{
+    $fresh = ! isset($_SESSION['messages'][$type][$id]);
+    $_SESSION['messages'][$type][$id] = array(
+        'fresh' => $fresh,
+        'active' => true,
+        'title' => $title,
+        'message' => $message);
+}
+
+/**
+ * Cleans up message list
+ *
+ * @return void
+ */
+function messages_end()
+{
+    foreach ($_SESSION['messages'] as &$messages) {
+        $remove_ids = array();
+        foreach ($messages as $id => &$msg) {
+            if ($msg['active'] == false) {
+                $remove_ids[] = $id;
+            }
+        }
+        foreach ($remove_ids as $id) {
+            unset($messages[$id]);
+        }
+    }
+}
+
+/**
+ * Prints message list, must be called after messages_end()
+ *
+ * @return void
+ */
+function messages_show_html()
+{
+    $old_ids = array();
+    foreach ($_SESSION['messages'] as $type => $messages) {
+        foreach ($messages as $id => $msg) {
+            echo '<div class="' . $type . '" id="' . $id . '">'
+                . '<h4>' . $msg['title'] . '</h4>'
+                . $msg['message'] . '</div>';
+            if (!$msg['fresh'] && $type != 'error') {
+                $old_ids[] = $id;
+            }
+        }
+    }
+
+    echo "\n" . '<script type="text/javascript">';
+    foreach ($old_ids as $id) {
+        echo "\nhiddenMessages.push('$id');";
+    }
+    echo "\n</script>\n";
+}
+
+/**
+ * Checks for newest phpMyAdmin version and sets result as a new notice
+ *
+ * @return void
+ */
+function PMA_version_check()
+{
+    // version check messages should always be visible so let's make
+    // a unique message id each time we run it
+    $message_id = uniqid('version_check');
+    // wait 3s at most for server response, it's enough to get information
+    // from a working server
+    $connection_timeout = 3;
+
+    $url = 'http://phpmyadmin.net/home_page/version.php';
+    $context = stream_context_create(
+        array(
+            'http' => array('timeout' => $connection_timeout)
+        )
+    );
+    $data = @file_get_contents($url, null, $context);
+    if ($data === false) {
+        if (function_exists('curl_init')) {
+            $ch = curl_init($url);
+            curl_setopt($ch, CURLOPT_HEADER, false);
+            curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
+            curl_setopt($ch, CURLOPT_TIMEOUT, $connection_timeout);
+            $data = curl_exec($ch);
+            curl_close($ch);
+        } else {
+            messages_set(
+                'error',
+                $message_id,
+                __('Version check'),
+                __('Neither URL wrapper nor CURL is available. Version check is not possible.')
+            );
+            return;
+        }
+    }
+
+    if (empty($data)) {
+        messages_set(
+            'error',
+            $message_id,
+            __('Version check'),
+            __('Reading of version failed. Maybe you\'re offline or the upgrade server does not respond.')
+        );
+        return;
+    }
+
+    /* Format: version\ndate\n(download\n)* */
+    $data_list = explode("\n", $data);
+
+    if (count($data_list) > 1) {
+        $version = $data_list[0];
+        $date = $data_list[1];
+    } else {
+        $version = $date = '';
+    }
+
+    $version_upstream = version_to_int($version);
+    if ($version_upstream === false) {
+        messages_set(
+            'error',
+            $message_id,
+            __('Version check'),
+            __('Got invalid version string from server')
+        );
+        return;
+    }
+
+    $version_local = version_to_int($GLOBALS['PMA_Config']->get('PMA_VERSION'));
+    if ($version_local === false) {
+        messages_set(
+            'error',
+            $message_id,
+            __('Version check'),
+            __('Unparsable version string')
+        );
+        return;
+    }
+
+    if ($version_upstream > $version_local) {
+        $version = htmlspecialchars($version);
+        $date = htmlspecialchars($date);
+        messages_set(
+            'notice',
+            $message_id,
+            __('Version check'),
+            sprintf(__('A newer version of phpMyAdmin is available and you should consider upgrading. The newest version is %s, released on %s.'), $version, $date)
+        );
+    } else {
+        if ($version_local % 100 == 0) {
+            messages_set(
+                'notice',
+                $message_id,
+                __('Version check'),
+                PMA_sanitize(sprintf(__('You are using Git version, run [kbd]git pull[/kbd] :-)[br]The latest stable version is %s, released on %s.'), $version, $date))
+            );
+        } else {
+            messages_set(
+                'notice',
+                $message_id,
+                __('Version check'),
+                __('No newer stable version is available')
+            );
+        }
+    }
+}
+
+/**
+ * Calculates numerical equivalent of phpMyAdmin version string
+ *
+ * @param string $version version
+ *
+ * @return mixed false on failure, integer on success
+ */
+function version_to_int($version)
+{
+    $matches = array();
+    if (!preg_match('/^(\d+)\.(\d+)\.(\d+)((\.|-(pl|rc|dev|beta|alpha))(\d+)?(-dev)?)?$/', $version, $matches)) {
+        return false;
+    }
+    if (!empty($matches[6])) {
+        switch ($matches[6]) {
+        case 'pl':
+            $added = 60;
+            break;
+        case 'rc':
+            $added = 30;
+            break;
+        case 'beta':
+            $added = 20;
+            break;
+        case 'alpha':
+            $added = 10;
+            break;
+        case 'dev':
+            $added = 0;
+            break;
+        default:
+            messages_set(
+                'notice',
+                'version_match',
+                __('Version check'),
+                'Unknown version part: ' . htmlspecialchars($matches[6])
+            );
+            $added = 0;
+            break;
+        }
+    } else {
+        $added = 50; // for final
+    }
+    if (!empty($matches[7])) {
+        $added = $added + $matches[7];
+    }
+    return $matches[1] * 1000000 + $matches[2] * 10000 + $matches[3] * 100 + $added;
+}
+
+/**
+ * Checks whether config file is readable/writable
+ *
+ * @param bool &$is_readable
+ * @param bool &$is_writable
+ * @param bool &$file_exists
+ *
+ * @return void
+ */
+function check_config_rw(&$is_readable, &$is_writable, &$file_exists)
+{
+    $file_path = ConfigFile::getInstance()->getFilePath();
+    $file_dir = dirname($file_path);
+    $is_readable = true;
+    $is_writable = is_dir($file_dir);
+    if (SETUP_DIR_WRITABLE) {
+        $is_writable = $is_writable && is_writable($file_dir);
+    }
+    $file_exists = file_exists($file_path);
+    if ($file_exists) {
+        $is_readable = is_readable($file_path);
+        $is_writable = $is_writable && is_writable($file_path);
+    }
+}
+
+/**
+ * Performs various compatibility, security and consistency checks on current config
+ *
+ * Outputs results to message list, must be called between messages_begin()
+ * and messages_end()
+ *
+ * @return void
+ */
+function perform_config_checks()
+{
+    $cf = ConfigFile::getInstance();
+    $blowfish_secret = $cf->get('blowfish_secret');
+    $blowfish_secret_set = false;
+    $cookie_auth_used = false;
+
+    $strAllowArbitraryServerWarning = __('This %soption%s should be disabled as it allows attackers to bruteforce login to any MySQL server. If you feel this is necessary, use %strusted proxies list%s. However, IP-based protection may not be reliable if your IP belongs to an ISP where thousands of users, including you, are connected to.');
+    $strAllowArbitraryServerWarning = sprintf($strAllowArbitraryServerWarning, '[a@?page=form&formset=Features#tab_Security]', '[/a]', '[a@?page=form&formset=Features#tab_Security]', '[/a]');
+    $strBlowfishSecretMsg = __('You didn\'t have blowfish secret set and have enabled cookie authentication, so a key was automatically generated for you. It is used to encrypt cookies; you don\'t need to remember it.');
+    $strBZipDumpWarning = __('%sBzip2 compression and decompression%s requires functions (%s) which are unavailable on this system.');
+    $strBZipDumpWarning = sprintf($strBZipDumpWarning, '[a@?page=form&formset=Features#tab_Import_export]', '[/a]', '%s');
+    $strDirectoryNotice = __('This value should be double checked to ensure that this directory is neither world accessible nor readable or writable by other users on your server.');
+    $strForceSSLNotice = __('This %soption%s should be enabled if your web server supports it.');
+    $strForceSSLNotice = sprintf($strForceSSLNotice, '[a@?page=form&formset=Features#tab_Security]', '[/a]');
+    $strGZipDumpWarning = __('%sGZip compression and decompression%s requires functions (%s) which are unavailable on this system.');
+    $strGZipDumpWarning = sprintf($strGZipDumpWarning, '[a@?page=form&formset=Features#tab_Import_export]', '[/a]', '%s');
+    $strLoginCookieValidityWarning = __('%sLogin cookie validity%s greater than 1440 seconds may cause random session invalidation if %ssession.gc_maxlifetime%s is lower than its value (currently %d).');
+    $strLoginCookieValidityWarning = sprintf($strLoginCookieValidityWarning, '[a@?page=form&formset=Features#tab_Security]', '[/a]', '[a@' . PMA_getPHPDocLink('session.configuration.php#ini.session.gc-maxlifetime') . ']', '[/a]', ini_get('session.gc_maxlifetime'));
+    $strLoginCookieValidityWarning2 = __('%sLogin cookie validity%s should be set to 1800 seconds (30 minutes) at most. Values larger than 1800 may pose a security risk such as impersonation.');
+    $strLoginCookieValidityWarning2 = sprintf($strLoginCookieValidityWarning2, '[a@?page=form&formset=Features#tab_Security]', '[/a]');
+    $strLoginCookieValidityWarning3 = __('If using cookie authentication and %sLogin cookie store%s is not 0, %sLogin cookie validity%s must be set to a value less or equal to it.');
+    $strLoginCookieValidityWarning3 = sprintf($strLoginCookieValidityWarning3, '[a@?page=form&formset=Features#tab_Security]', '[/a]', '[a@?page=form&formset=Features#tab_Security]', '[/a]');
+    $strSecurityInfoMsg = __('If you feel this is necessary, use additional protection settings - %shost authentication%s settings and %strusted proxies list%s. However, IP-based protection may not be reliable if your IP belongs to an ISP where thousands of users, including you, are connected to.');
+    $strSecurityInfoMsg = sprintf($strSecurityInfoMsg, '[a@?page=servers&mode=edit&id=%1$d#tab_Server_config]', '[/a]', '[a@?page=form&formset=Features#tab_Security]', '[/a]');
+    $strServerAuthConfigMsg = __('You set the [kbd]config[/kbd] authentication type and included username and password for auto-login, which is not a desirable option for live hosts. Anyone who knows or guesses your phpMyAdmin URL can directly access your phpMyAdmin panel. Set %sauthentication type%s to [kbd]cookie[/kbd] or [kbd]http[/kbd].');
+    $strServerAuthConfigMsg = sprintf($strServerAuthConfigMsg, '[a@?page=servers&mode=edit&id=%1$d#tab_Server]', '[/a]');
+    $strZipDumpExportWarning = __('%sZip compression%s requires functions (%s) which are unavailable on this system.');
+    $strZipDumpExportWarning = sprintf($strZipDumpExportWarning, '[a@?page=form&formset=Features#tab_Import_export]', '[/a]', '%s');
+    $strZipDumpImportWarning = __('%sZip decompression%s requires functions (%s) which are unavailable on this system.');
+    $strZipDumpImportWarning = sprintf($strZipDumpImportWarning, '[a@?page=form&formset=Features#tab_Import_export]', '[/a]', '%s');
+
+    for ($i = 1, $server_cnt = $cf->getServerCount(); $i <= $server_cnt; $i++) {
+        $cookie_auth_server = ($cf->getValue("Servers/$i/auth_type") == 'cookie');
+        $cookie_auth_used |= $cookie_auth_server;
+        $server_name = $cf->getServerName($i);
+        if ($server_name == 'localhost') {
+            $server_name .=  " [$i]";
+        }
+        $server_name = htmlspecialchars($server_name);
+
+        if ($cookie_auth_server && $blowfish_secret === null) {
+            $blowfish_secret = uniqid('', true);
+            $blowfish_secret_set = true;
+            $cf->set('blowfish_secret', $blowfish_secret);
+        }
+
+        //
+        // $cfg['Servers'][$i]['ssl']
+        // should be enabled if possible
+        //
+        if (!$cf->getValue("Servers/$i/ssl")) {
+            $title = PMA_lang(PMA_lang_name('Servers/1/ssl')) . " ($server_name)";
+            messages_set(
+                'notice',
+                "Servers/$i/ssl",
+                $title,
+                __('You should use SSL connections if your database server supports it.')
+            );
+        }
+
+        //
+        // $cfg['Servers'][$i]['extension']
+        // warn about using 'mysql'
+        //
+        if ($cf->getValue("Servers/$i/extension") == 'mysql') {
+            $title = PMA_lang(PMA_lang_name('Servers/1/extension'))
+                . " ($server_name)";
+            messages_set(
+                'notice',
+                "Servers/$i/extension",
+                $title,
+                __('You should use mysqli for performance reasons.')
+            );
+        }
+
+        //
+        // $cfg['Servers'][$i]['auth_type']
+        // warn about full user credentials if 'auth_type' is 'config'
+        //
+        if ($cf->getValue("Servers/$i/auth_type") == 'config'
+            && $cf->getValue("Servers/$i/user") != ''
+            && $cf->getValue("Servers/$i/password") != ''
+        ) {
+            $title = PMA_lang(PMA_lang_name('Servers/1/auth_type'))
+                . " ($server_name)";
+            messages_set(
+                'notice',
+                "Servers/$i/auth_type",
+                $title,
+                PMA_lang($strServerAuthConfigMsg, $i) . ' '
+                . PMA_lang($strSecurityInfoMsg, $i)
+            );
+        }
+
+        //
+        // $cfg['Servers'][$i]['AllowRoot']
+        // $cfg['Servers'][$i]['AllowNoPassword']
+        // serious security flaw
+        //
+        if ($cf->getValue("Servers/$i/AllowRoot")
+            && $cf->getValue("Servers/$i/AllowNoPassword")
+        ) {
+            $title = PMA_lang(PMA_lang_name('Servers/1/AllowNoPassword'))
+                . " ($server_name)";
+            messages_set(
+                'notice',
+                "Servers/$i/AllowNoPassword",
+                $title,
+                __('You allow for connecting to the server without a password.') . ' '
+                . PMA_lang($strSecurityInfoMsg, $i)
+            );
+        }
+    }
+
+    //
+    // $cfg['blowfish_secret']
+    // it's required for 'cookie' authentication
+    //
+    if ($cookie_auth_used) {
+        if ($blowfish_secret_set) {
+            // 'cookie' auth used, blowfish_secret was generated
+            messages_set(
+                'notice',
+                'blowfish_secret_created',
+                PMA_lang(PMA_lang_name('blowfish_secret')),
+                $strBlowfishSecretMsg
+            );
+        } else {
+            $blowfish_warnings = array();
+            // check length
+            if (strlen($blowfish_secret) < 8) {
+                // too short key
+                $blowfish_warnings[] = __('Key is too short, it should have at least 8 characters.');
+            }
+            // check used characters
+            $has_digits = (bool) preg_match('/\d/', $blowfish_secret);
+            $has_chars = (bool) preg_match('/\S/', $blowfish_secret);
+            $has_nonword = (bool) preg_match('/\W/', $blowfish_secret);
+            if (!$has_digits || !$has_chars || !$has_nonword) {
+                $blowfish_warnings[] = PMA_lang(__('Key should contain letters, numbers [em]and[/em] special characters.'));
+            }
+            if (!empty($blowfish_warnings)) {
+                messages_set(
+                    'error',
+                    'blowfish_warnings' . count($blowfish_warnings),
+                    PMA_lang(PMA_lang_name('blowfish_secret')),
+                    implode('<br />', $blowfish_warnings)
+                );
+            }
+        }
+    }
+
+    //
+    // $cfg['ForceSSL']
+    // should be enabled if possible
+    //
+    if (!$cf->getValue('ForceSSL')) {
+        messages_set(
+            'notice',
+            'ForceSSL',
+            PMA_lang(PMA_lang_name('ForceSSL')),
+            PMA_lang($strForceSSLNotice)
+        );
+    }
+
+    //
+    // $cfg['AllowArbitraryServer']
+    // should be disabled
+    //
+    if ($cf->getValue('AllowArbitraryServer')) {
+        messages_set(
+            'notice',
+            'AllowArbitraryServer',
+            PMA_lang(PMA_lang_name('AllowArbitraryServer')),
+            PMA_lang($strAllowArbitraryServerWarning)
+        );
+    }
+
+    //
+    // $cfg['LoginCookieValidity']
+    // value greater than session.gc_maxlifetime will cause
+    // random session invalidation after that time
+    if ($cf->getValue('LoginCookieValidity') > 1440
+        || $cf->getValue('LoginCookieValidity') > ini_get('session.gc_maxlifetime')
+    ) {
+        $message_type = $cf->getValue('LoginCookieValidity') > ini_get('session.gc_maxlifetime')
+            ? 'error'
+            : 'notice';
+        messages_set(
+            $message_type,
+            'LoginCookieValidity',
+            PMA_lang(PMA_lang_name('LoginCookieValidity')),
+            PMA_lang($strLoginCookieValidityWarning)
+        );
+    }
+
+    //
+    // $cfg['LoginCookieValidity']
+    // should be at most 1800 (30 min)
+    //
+    if ($cf->getValue('LoginCookieValidity') > 1800) {
+        messages_set(
+            'notice',
+            'LoginCookieValidity',
+            PMA_lang(PMA_lang_name('LoginCookieValidity')),
+            PMA_lang($strLoginCookieValidityWarning2)
+        );
+    }
+
+    //
+    // $cfg['LoginCookieValidity']
+    // $cfg['LoginCookieStore']
+    // LoginCookieValidity must be less or equal to LoginCookieStore
+    //
+    if ($cf->getValue('LoginCookieStore') != 0
+        && $cf->getValue('LoginCookieValidity') > $cf->getValue('LoginCookieStore')
+    ) {
+        messages_set(
+            'error',
+            'LoginCookieValidity',
+            PMA_lang(PMA_lang_name('LoginCookieValidity')),
+            PMA_lang($strLoginCookieValidityWarning3)
+        );
+    }
+
+    //
+    // $cfg['SaveDir']
+    // should not be world-accessible
+    //
+    if ($cf->getValue('SaveDir') != '') {
+        messages_set(
+            'notice',
+            'SaveDir',
+            PMA_lang(PMA_lang_name('SaveDir')),
+            PMA_lang($strDirectoryNotice)
+        );
+    }
+
+    //
+    // $cfg['TempDir']
+    // should not be world-accessible
+    //
+    if ($cf->getValue('TempDir') != '') {
+        messages_set(
+            'notice',
+            'TempDir',
+            PMA_lang(PMA_lang_name('TempDir')),
+            PMA_lang($strDirectoryNotice)
+        );
+    }
+
+    //
+    // $cfg['GZipDump']
+    // requires zlib functions
+    //
+    if ($cf->getValue('GZipDump')
+        && (@!function_exists('gzopen') || @!function_exists('gzencode'))
+    ) {
+        messages_set(
+            'error',
+            'GZipDump',
+            PMA_lang(PMA_lang_name('GZipDump')),
+            PMA_lang($strGZipDumpWarning, 'gzencode')
+        );
+    }
+
+    //
+    // $cfg['BZipDump']
+    // requires bzip2 functions
+    //
+    if ($cf->getValue('BZipDump')
+        && (!@function_exists('bzopen') || !@function_exists('bzcompress'))
+    ) {
+        $functions = @function_exists('bzopen')
+                ? '' :
+                'bzopen';
+        $functions .= @function_exists('bzcompress')
+                ? ''
+                : ($functions ? ', ' : '') . 'bzcompress';
+        messages_set(
+            'error',
+            'BZipDump',
+            PMA_lang(PMA_lang_name('BZipDump')),
+            PMA_lang($strBZipDumpWarning, $functions)
+        );
+    }
+
+    //
+    // $cfg['ZipDump']
+    // requires zip_open in import
+    //
+    if ($cf->getValue('ZipDump') && !@function_exists('zip_open')) {
+        messages_set(
+            'error',
+            'ZipDump_import',
+            PMA_lang(PMA_lang_name('ZipDump')),
+            PMA_lang($strZipDumpImportWarning, 'zip_open')
+        );
+    }
+
+    //
+    // $cfg['ZipDump']
+    // requires gzcompress in export
+    //
+    if ($cf->getValue('ZipDump') && !@function_exists('gzcompress')) {
+        messages_set(
+            'error',
+            'ZipDump_export',
+            PMA_lang(PMA_lang_name('ZipDump')),
+            PMA_lang($strZipDumpExportWarning, 'gzcompress')
+        );
+    }
+}
+?>
diff --git a/phpmyadmin/setup/scripts.js b/phpmyadmin/setup/scripts.js
new file mode 100644
index 0000000..fe7f0e2
--- /dev/null
+++ b/phpmyadmin/setup/scripts.js
@@ -0,0 +1,204 @@
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * Functions used in Setup configuration forms
+ */
+
+// show this window in top frame
+if (top != self) {
+    window.top.location.href = location;
+}
+
+// ------------------------------------------------------------------
+// Messages
+//
+
+// stores hidden message ids
+var hiddenMessages = [];
+
+$(function() {
+    var hidden = hiddenMessages.length;
+    for (var i = 0; i < hidden; i++) {
+        $('#'+hiddenMessages[i]).css('display', 'none');
+    }
+    if (hidden > 0) {
+        var link = $('#show_hidden_messages');
+        link.click(function(e) {
+            e.preventDefault();
+            for (var i = 0; i < hidden; i++) {
+                $('#'+hiddenMessages[i]).show(500);
+            }
+            $(this).remove();
+        });
+        link.html(link.html().replace('#MSG_COUNT', hidden));
+        link.css('display', '');
+    }
+});
+
+//
+// END: Messages
+// ------------------------------------------------------------------
+
+// ------------------------------------------------------------------
+// Form validation and field operations
+//
+
+/**
+ * Automatic form submission on change.
+ */
+$('.autosubmit').live('change', function(e) {
+    e.target.form.submit();
+});
+
+$.extend(true, validators, {
+    // field validators
+    _field: {
+        /**
+         * hide_db field
+         *
+         * @param {boolean} isKeyUp
+         */
+        hide_db: function(isKeyUp) {
+            if (!isKeyUp && this.value != '') {
+                var data = {};
+                data[this.id] = this.value;
+                ajaxValidate(this, 'Servers/1/hide_db', data);
+            }
+            return true;
+        },
+        /**
+         * TrustedProxies field
+         *
+         * @param {boolean} isKeyUp
+         */
+        TrustedProxies: function(isKeyUp) {
+            if (!isKeyUp && this.value != '') {
+                var data = {};
+                data[this.id] = this.value;
+                ajaxValidate(this, 'TrustedProxies', data);
+            }
+            return true;
+        }
+    },
+    // fieldset validators
+    _fieldset: {
+        /**
+         * Validates Server fieldset
+         *
+         * @param {boolean} isKeyUp
+         */
+        Server: function(isKeyUp) {
+            if (!isKeyUp) {
+                ajaxValidate(this, 'Server', getAllValues());
+            }
+            return true;
+        },
+        /**
+         * Validates Server_login_options fieldset
+         *
+         * @param {boolean} isKeyUp
+         */
+        Server_login_options: function(isKeyUp) {
+            return validators._fieldset.Server.apply(this, [isKeyUp]);
+        },
+        /**
+         * Validates Server_pmadb fieldset
+         *
+         * @param {boolean} isKeyUp
+         */
+        Server_pmadb: function(isKeyUp) {
+            if (isKeyUp) {
+                return true;
+            }
+
+            var prefix = getIdPrefix($(this).find('input'));
+            var pmadb_active = $('#' + prefix + 'pmadb').val() != '';
+            if (pmadb_active) {
+                ajaxValidate(this, 'Server_pmadb', getAllValues());
+            }
+
+            return true;
+        }
+    }
+});
+
+/**
+ * Calls server-side validation procedures
+ *
+ * @param {Element} parent  input field in <fieldset> or <fieldset>
+ * @param {String}  id      validator id
+ * @param {Object}  values  values hash {element1_id: value, ...}
+ */
+function ajaxValidate(parent, id, values)
+{
+    parent = $(parent);
+    // ensure that parent is a fieldset
+    if (parent.attr('tagName') != 'FIELDSET') {
+        parent = parent.closest('fieldset');
+        if (parent.length == 0) {
+            return false;
+        }
+    }
+
+    if (parent.data('ajax') != null) {
+        parent.data('ajax').abort();
+    }
+
+    parent.data('ajax', $.ajax({
+        url: 'validate.php',
+        cache: false,
+        type: 'POST',
+        data: {
+            token: parent.closest('form').find('input[name=token]').val(),
+            id: id,
+            values: $.toJSON(values)
+        },
+        success: function(response) {
+            if (response == null) {
+                return;
+            }
+
+            var error = {};
+            if (typeof response != 'object') {
+                error[parent.id] = [response];
+            } else if (typeof response['error'] != 'undefined') {
+                error[parent.id] = [response['error']];
+            } else {
+                for (var key in response) {
+                    var value = response[key];
+                    error[key] = jQuery.isArray(value) ? value : [value];
+                }
+            }
+            displayErrors(error);
+        },
+        complete: function() {
+            parent.removeData('ajax');
+        }
+    }));
+
+    return true;
+}
+
+//
+// END: Form validation and field operations
+// ------------------------------------------------------------------
+
+// ------------------------------------------------------------------
+// User preferences allow/disallow UI
+//
+
+$(function() {
+   $('.userprefs-allow').click(function(e) {
+       if (this != e.target) {
+           return;
+       }
+       var el = $(this).find('input');
+       if (el.prop('disabled')) {
+           return;
+       }
+       el.prop('checked', !el.prop('checked'));
+   });
+});
+
+//
+// END: User preferences allow/disallow UI
+// ------------------------------------------------------------------
diff --git a/phpmyadmin/setup/styles.css b/phpmyadmin/setup/styles.css
new file mode 100644
index 0000000..9f2d2ec
--- /dev/null
+++ b/phpmyadmin/setup/styles.css
@@ -0,0 +1,631 @@
+/* global styles */
+
+body {
+    padding-bottom: 1em;
+    color: #444;
+    font: .8em sans-serif;
+    background: url(../themes/pmahomme/img/left_nav_bg.png) repeat-y 80px 0 #f3f3f3;
+}
+
+input,
+button,
+select,
+textarea,
+th,
+td {
+    font: 1em sans-serif;
+}
+
+img {
+    border: 0;
+}
+
+a,
+a:link,
+a:visited,
+a:active {
+    text-decoration: none;
+    color: #235a81;
+    cursor: pointer;
+    outline: none;
+
+}
+
+a:hover {
+    text-decoration: underline;
+    color: #235a81;
+}
+
+h1 {
+    font-size: 1.5em;
+}
+
+/* language selection box */
+
+#select_lang {
+    position: absolute;
+    right: 1em;
+    top: 1em;
+}
+
+/* menu */
+
+#menu {
+    float: left;
+    width: 220px;
+    font-size: 1.1em;
+}
+
+#menu ul {
+    margin: 1em 1em 1em .5em;
+    padding: 0;
+    list-style: none;
+}
+
+#menu li a {
+    padding: .5em .6em;
+    margin-right: .6em;
+    display: block;
+    color: #333;
+    text-decoration: none;
+    zoom: 1; /* IE fix */
+}
+
+#menu li a:hover, #menu li a:active {
+    background-color: #e4e4e4;
+}
+
+/* page contents and footer layout */
+
+#page {
+    margin-left: 220px;
+}
+
+#footer {
+    margin-top: 1em;
+}
+
+#footer a {
+    margin-right: 0.5em;
+    text-decoration: none;
+    font-size: small;
+}
+
+/* phpMyAdmin logo colors */
+
+.blue {
+    color: #7584B3;
+}
+
+.orange {
+    color: #FFAD17;
+}
+
+.red {
+    color: #C00;
+}
+
+/* main page messages */
+
+/* message boxes: error, confirmation */
+.success h4,
+.notice h4,
+div.error h4 {
+    border-bottom: 1px solid;
+    font-weight: bold;
+    margin: 0 0 .2em 0;
+}
+
+div.success,
+div.notice,
+div.error {
+    margin: .5em 0 1.3em 0;
+    border: 1px solid;
+    background-repeat: no-repeat;
+    background-position: 10px 10px;
+    padding: 10px 10px 10px 25px;
+
+    -moz-border-radius: 5px;
+    -webkit-border-radius: 5px;
+    border-radius: 5px;
+
+    -moz-box-shadow: 0 1px 1px #fff inset;
+    -webkit-box-shadow: 0 1px 1px #fff inset;
+    box-shadow: 0 1px 1px #fff inset;
+}
+
+.success a,
+.notice a,
+.error a {
+    text-decoration: underline;
+}
+
+.success {
+    color: #000;
+    background-color: #ebf8a4;
+}
+
+h1.success,
+div.success {
+    border-color: #a2d246;
+    background-image: url(../themes/pmahomme/img/s_success.png);
+    background-repeat: no-repeat;
+    background-position: 5px 10px;
+}
+.success h4 {
+    border-color: #00FF00;
+}
+
+.notice {
+    color: #000;
+    background-color: #e8eef1;
+}
+
+h1.notice,
+div.notice {
+    border-color: #3a6c7e;
+    background-image: url(../themes/pmahomme/img/s_notice.png);
+    background-repeat: no-repeat;
+    background-position: 5px 10px;
+}
+
+.notice h4 {
+    border-color: #ffb10a;
+}
+
+.error {
+    border: 1px solid maroon !important;
+    color: #000;
+    background: pink;
+}
+
+h1.error,
+div.error {
+    border-color: #333;
+    background-image: url(../themes/pmahomme/img/s_error.png);
+    background-repeat: no-repeat;
+    background-position: 5px 10px;
+}
+
+div.error h4 {
+    border-color: #ff0000;
+}
+
+div.notice[id^=version_check] {
+    border-color: #002DFF;
+    background-color: #EEF;
+}
+
+div.notice[id^=version_check] h4 {
+    border-color: #002DFF;
+}
+
+
+
+/* form tabs */
+
+ul.tabs {
+    margin: 1.1em .2em 0;
+    padding: 0 0 .3em 0;
+    list-style: none;
+    font-weight: bold;
+}
+
+ul.tabs li {
+    float: left;
+    margin-bottom: -1px;
+}
+
+ul.tabs li a {
+    display: block;
+    margin: .1em .2em 0;
+    white-space: nowrap;
+    text-decoration: none;
+    border: 1px solid #D5D5D5;
+    border-bottom: 1px solid #aaa;
+}
+
+ul.tabs li a {
+    padding: 7px 10px;
+    -webkit-border-radius: 5px 5px 0 0;
+    -moz-border-radius: 5px 5px 0 0;
+    border-radius: 5px 5px 0 0;
+    background: #f2f2f2;
+    color: #555;
+    text-shadow: 0 1px 0 #fff;
+}
+
+ul.tabs li a:hover,
+ul.tabs li a:active {
+    background: #e5e5e5;
+}
+
+ul.tabs li.active a {
+    background-color: #fff;
+    margin-top: 1px;
+    color: #000;
+    text-shadow: none;
+    border-color: #aaa;
+    border-bottom: 1px solid #fff;
+}
+
+.tabs_contents {
+    margin-top: 1em;
+}
+
+.tabs_contents fieldset {
+    margin-top: 0;
+}
+
+.tabs_contents legend {
+    display: none;
+}
+
+/* "restore default value" and "set value: foo" buttons */
+
+.restore-default img, .set-value img {
+    margin-bottom: -3px;
+}
+
+.userprefs-comment {
+    cursor: help;
+    float: right;
+}
+
+/* forms */
+
+fieldset {
+    margin-top: 1em;
+    border-radius: 4px 4px 0 0;
+    -moz-border-radius: 4px 4px 0 0;
+    -webkit-border-radius: 4px 4px 0 0;
+    border: #aaa solid 1px;
+    padding: 1.5em;
+    background: #eee;
+    text-shadow: 0 1px 0 #fff;
+    -moz-box-shadow: 1px 1px 2px #fff inset;
+    -webkit-box-shadow: 1px 1px 2px #fff inset;
+    box-shadow: 1px 1px 2px #fff inset;
+}
+
+fieldset.optbox {
+    padding: 0;
+}
+
+fieldset fieldset {
+    margin: .8em;
+    background: #fff;
+    border: 1px solid #aaa;
+    background: #E8E8E8;
+
+}
+
+fieldset legend {
+    font-weight: bold;
+    color: #444;
+    padding: 5px 10px;
+    border-radius: 2px;
+    -moz-border-radius: 2px;
+    -webkit-border-radius: 2px;
+    border: 1px solid #aaa;
+    background-color: #fff;
+    -moz-box-shadow: 3px 3px 15px #bbb;
+    -webkit-box-shadow: 3px 3px 15px #bbb;
+    box-shadow: 3px 3px 15px #bbb;
+}
+
+.form {
+    border: 2px #DEE1FF solid;
+}
+
+fieldset p {
+    margin: 0;
+    padding: .5em;
+    background: #fff;
+    border-top: 0;
+}
+
+fieldset .errors { /* form error list */
+    margin: 0 -2px 1em -2px;
+    padding: 0.5em 1.5em;
+    background: #FBEAD9;
+    border: 1px #C83838 solid;
+    border-width: 1px 0;
+    list-style: none;
+    font-family: sans-serif;
+    font-size: small;
+}
+
+fieldset .inline_errors { /* field error list */
+    margin: 0.3em 0.3em 0.3em 0;
+    padding: 0;
+    list-style: none;
+    color: #9A0000;
+    font-size: small;
+}
+
+table caption, table th, table td {
+    text-shadow: 0 1px 0 #FFFFFF;
+}
+
+fieldset th {
+    width: 40%;
+    min-width: 350px;
+    padding: 0.3em 0.3em 0.3em 0.5em;
+    text-align: left;
+    font-weight: bold;
+    vertical-align: top;
+}
+
+fieldset.simple th {
+    width: auto;
+    min-width: 0;
+}
+
+fieldset .doc {
+    margin-left: 1em;
+}
+
+fieldset td {
+    padding-top: 0.3em;
+    vertical-align: top;
+}
+
+fieldset td.userprefs-allow {
+    padding: 0;
+    vertical-align: middle;
+    text-align: center;
+    width: 3em;
+}
+
+fieldset td.userprefs-allow:hover {
+    cursor: pointer;
+    background-color: #EEE;
+}
+
+fieldset th small {
+    display: block;
+    font-weight: normal;
+    font-family: sans-serif;
+    font-size: x-small;
+    color: #666;
+}
+
+fieldset th, fieldset td, .form .lastrow {
+    border-top: 1px solid #D5D5D5;
+}
+
+fieldset .group-header th {
+    background: #EAEDFF;
+    border: none;
+}
+
+fieldset .group-field-1 th, fieldset .group-header-2 th {
+    padding-left: 1em;
+}
+
+fieldset .group-field-2 th, fieldset .group-header-3 th {
+    padding-left: 2em;
+}
+
+fieldset .group-field-3 th {
+    padding-left: 3em;
+}
+
+fieldset .lastrow, .form .lastrow {
+    border-top: 1px #000 solid;
+    background: #D3DCE3;
+    padding: .5em;
+    text-align: center;
+}
+
+input[type=text] {
+    border-radius: 2px;
+    -moz-border-radius: 2px;
+    -webkit-border-radius: 2px;
+
+    box-shadow: 0 1px 2px #ddd;
+    -moz-box-shadow: 0 1px 2px #ddd;
+    -webkit-box-shadow: 0 1px 2px #ddd;
+
+    background: white;
+    border: 1px solid #aaa;
+    color: #555;
+    padding: 4px;
+    margin: 6px;
+
+}
+
+input[type=password] {
+    border-radius: 2px;
+    -moz-border-radius: 2px;
+    -webkit-border-radius: 2px;
+
+    box-shadow: 0 1px 2px #ddd;
+    -moz-box-shadow: 0 1px 2px #ddd;
+    -webkit-box-shadow: 0 1px 2px #ddd;
+
+    background: white;
+    border: 1px solid #aaa;
+    color: #555;
+    padding: 4px;
+    margin: 6px;
+
+}
+
+input[type=submit],
+button[type=submit]:not(.mult_submit) {
+    font-weight: bold !important;
+}
+
+input[type=submit],
+button[type=submit]:not(.mult_submit),
+input[type=reset],
+input[name=submit_reset],
+input.button {
+    margin-left: 14px;
+    border: 1px solid #aaa;
+    padding: 3px 7px;
+    color: #111;
+    text-decoration: none;
+    background: #ddd;
+
+    border-radius: 12px;
+    -webkit-border-radius: 12px;
+    -moz-border-radius: 12px;
+
+    text-shadow: 0 1px 0 #fff;
+
+    background-image: url(../themes/svg_gradient.php?from=ffffff&to=cccccc);
+    background-size: 100% 100%;
+    background: -webkit-gradient(linear, left top, left bottom, from(#ffffff), to(#cccccc));
+    background: -webkit-linear-gradient(top, #ffffff, #cccccc);
+    background: -moz-linear-gradient(top, #ffffff, #cccccc);
+    background: -ms-linear-gradient(top, #ffffff, #cccccc);
+    background: -o-linear-gradient(top, #ffffff, #cccccc);
+}
+
+input[type=submit]:hover,
+button[type=submit]:not(.mult_submit):hover,
+input[type=reset]:hover,
+input[name=submit_reset]:hover,
+input.button:hover {
+    position: relative;
+    background-image: url(../themes/svg_gradient.php?from=cccccc&to=dddddd);
+    background-size: 100% 100%;
+    background: -webkit-gradient(linear, left top, left bottom, from(#cccccc), to(#dddddd));
+    background: -webkit-linear-gradient(top, #cccccc, #dddddd);
+    background: -moz-linear-gradient(top, #cccccc, #dddddd);
+    background: -ms-linear-gradient(top, #cccccc, #dddddd);
+    background: -o-linear-gradient(top, #cccccc, #dddddd);
+    cursor: pointer;
+}
+
+input[type=submit]:active,
+button[type=submit]:not(.mult_submit):active,
+input[type=reset]:active,
+input[name=submit_reset]:active,
+input.button:active {
+    position: relative;
+    top: 1px;
+    left: 1px;
+}
+
+input[type="checkbox"],
+input[type="radio"] {
+    vertical-align: -11%;
+}
+
+
+select {
+    -moz-border-radius: 2px;
+    -webkit-border-radius: 2px;
+    border-radius: 2px;
+
+    -moz-box-shadow: 0 1px 2px #ddd;
+    -webkit-box-shadow: 0 1px 2px #ddd;
+    box-shadow: 0 1px 2px #ddd;
+
+    border: 1px solid #aaa;
+    color: #333;
+    padding: 3px;
+    background: white;
+}
+
+fieldset.simple th, fieldset.simple td {
+    border-top: none;
+    border-bottom: 1px #555 dotted;
+}
+
+fieldset.simple .lastrow {
+    border: 0;
+}
+
+/* form elements */
+
+span.checkbox {
+    padding: 2px;
+    display: inline-block;
+}
+
+.custom { /* customized field */
+    background: #FFC;
+}
+
+.checkbox.custom {
+    padding: 1px;
+    border: 1px #EDEC90 solid;
+}
+
+.field-error {
+    border-color: #C11 !important;
+}
+
+.field-comment {
+
+    position: relative;
+}
+
+.field-comment-mark {
+    cursor: help;
+    padding: 0 0.2em;
+    font-weight: bold;
+    font-style: italic;
+}
+
+.field-comment-warning {
+    color: #A00;
+}
+
+.green { /* default form button */
+    color: #080 !important;
+}
+
+table.datatable {
+    margin: 0.5em 0 1em;
+}
+
+table.datatable th {
+    padding: 0 1em 0 0.5em;
+    border-bottom: 1px #999 solid;
+    text-align: left;
+}
+
+table.datatable td {
+    padding: 1px 0.5em;
+    border-bottom: 1px #DEE1FF solid;
+}
+
+/* textarea with config file's contents */
+
+#textconfig {
+    width: 100%;
+    border: 0;
+}
+
+/* error list */
+
+dd {
+    margin-left: 0.5em;
+}
+
+dd:before {
+    content: "\25B8  ";
+}
+
+/* links on failed validation page, when saving a form */
+
+a.btn {
+    padding: 1px 5px;
+    text-decoration: none;
+    background: #E2E8FF;
+    border: 1px #A6C8FF solid;
+    border-top-color: #AFD0FF;
+    border-left-color: #AFD0FF;
+    font-weight: bold;
+}
+
+a.btn:hover, a.btn:active {
+    background: #E6F5FF;
+    color: #004C96;
+}
diff --git a/phpmyadmin/setup/validate.php b/phpmyadmin/setup/validate.php
new file mode 100644
index 0000000..2cb8c93
--- /dev/null
+++ b/phpmyadmin/setup/validate.php
@@ -0,0 +1,30 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * Validation callback.
+ *
+ * @package PhpMyAdmin-Setup
+ */
+
+/**
+ * Core libraries.
+ */
+require './lib/common.inc.php';
+
+$validators = array();
+require './libraries/config/validate.lib.php';
+
+header('Content-type: application/json');
+
+$vids = explode(',', filter_input(INPUT_POST, 'id'));
+$values = json_decode(filter_input(INPUT_POST, 'values'));
+if (!($values instanceof stdClass)) {
+    PMA_fatalError(__('Wrong data'));
+}
+$values = (array)$values;
+$result = PMA_config_validate($vids, $values, true);
+if ($result === false) {
+    $result = 'Wrong data or no validation for ' . $vids;
+}
+echo $result !== true ? json_encode($result) : '';
+?>
diff --git a/phpmyadmin/show_config_errors.php b/phpmyadmin/show_config_errors.php
new file mode 100644
index 0000000..0d0cdf4
--- /dev/null
+++ b/phpmyadmin/show_config_errors.php
@@ -0,0 +1,40 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * Simple wrapper just to enable error reporting and include config
+ *
+ * @package PhpMyAdmin
+ */
+
+// rfc2616 - Section 14.21
+header('Expires: ' . date(DATE_RFC1123));
+// HTTP/1.1
+header(
+    'Cache-Control: no-store, no-cache, must-revalidate,'
+    . '  pre-check=0, post-check=0, max-age=0'
+);
+if (isset($_SERVER['HTTP_USER_AGENT'])
+    && stristr($_SERVER['HTTP_USER_AGENT'], 'MSIE')
+) {
+
+    /* FIXME: Why is this special case for IE needed? */
+    header('Pragma: public');
+} else {
+    header('Pragma: no-cache'); // HTTP/1.0
+    // test case: exporting a database into a .gz file with Safari
+    // would produce files not having the current time
+    // (added this header for Safari but should not harm other browsers)
+    header('Last-Modified: ' . date(DATE_RFC1123));
+}
+header('Content-Type: text/html; charset=utf-8');
+
+require 'libraries/vendor_config.php';
+
+error_reporting(E_ALL);
+/**
+ * Read config file.
+ */
+if (is_readable(CONFIG_FILE)) {
+    include CONFIG_FILE;
+}
+?>
diff --git a/phpmyadmin/sql.php b/phpmyadmin/sql.php
new file mode 100644
index 0000000..cfe8dea
--- /dev/null
+++ b/phpmyadmin/sql.php
@@ -0,0 +1,1740 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * SQL executor
+ *
+ * @todo    we must handle the case if sql.php is called directly with a query
+ *          that returns 0 rows - to prevent cyclic redirects or includes
+ * @package PhpMyAdmin
+ */
+
+/**
+ * Gets some core libraries
+ */
+require_once 'libraries/common.inc.php';
+require_once 'libraries/Table.class.php';
+require_once 'libraries/Header.class.php';
+require_once 'libraries/check_user_privileges.lib.php';
+require_once 'libraries/bookmark.lib.php';
+
+$response = PMA_Response::getInstance();
+$header   = $response->getHeader();
+$scripts  = $header->getScripts();
+$scripts->addFile('jquery/jquery-ui-timepicker-addon.js');
+$scripts->addFile('tbl_change.js');
+// the next one needed because sql.php may do a "goto" to tbl_structure.php
+$scripts->addFile('tbl_structure.js');
+$scripts->addFile('indexes.js');
+$scripts->addFile('gis_data_editor.js');
+
+/**
+ * Set ajax_reload in the response if it was already set
+ */
+if (isset($ajax_reload) && $ajax_reload['reload'] === true) {
+    $response->addJSON('ajax_reload', $ajax_reload);
+}
+
+/**
+ * Sets globals from $_POST
+ */
+$post_params = array(
+    'bkm_all_users',
+    'fields',
+    'store_bkm'
+);
+foreach ($post_params as $one_post_param) {
+    if (isset($_POST[$one_post_param])) {
+        $GLOBALS[$one_post_param] = $_POST[$one_post_param];
+    }
+}
+
+/**
+ * Sets globals from $_GET
+ */
+$get_params = array(
+    'id_bookmark',
+    'label',
+    'sql_query'
+);
+foreach ($get_params as $one_get_param) {
+    if (isset($_GET[$one_get_param])) {
+        $GLOBALS[$one_get_param] = $_GET[$one_get_param];
+    }
+}
+
+
+if (isset($_REQUEST['printview'])) {
+    $GLOBALS['printview'] = $_REQUEST['printview'];
+}
+
+if (!isset($_SESSION['is_multi_query'])) {
+    $_SESSION['is_multi_query'] = false;
+}
+
+/**
+ * Defines the url to return to in case of error in a sql statement
+ */
+// Security checkings
+if (! empty($goto)) {
+    $is_gotofile     = preg_replace('@^([^?]+).*$@s', '\\1', $goto);
+    if (! @file_exists('' . $is_gotofile)) {
+        unset($goto);
+    } else {
+        $is_gotofile = ($is_gotofile == $goto);
+    }
+} else {
+    if (empty($table)) {
+        $goto = $cfg['DefaultTabDatabase'];
+    } else {
+        $goto = $cfg['DefaultTabTable'];
+    }
+    $is_gotofile  = true;
+} // end if
+
+if (! isset($err_url)) {
+    $err_url = (! empty($back) ? $back : $goto)
+        . '?' . PMA_generate_common_url($db)
+        . ((strpos(' ' . $goto, 'db_') != 1 && strlen($table))
+            ? '&table=' . urlencode($table)
+            : ''
+        );
+} // end if
+
+// Coming from a bookmark dialog
+if (isset($fields['query'])) {
+    $sql_query = $fields['query'];
+}
+
+// This one is just to fill $db
+if (isset($fields['dbase'])) {
+    $db = $fields['dbase'];
+}
+
+/**
+ * During grid edit, if we have a relational field, show the dropdown for it
+ *
+ * Logic taken from libraries/DisplayResults.class.php
+ *
+ * This doesn't seem to be the right place to do this, but I can't think of any
+ * better place either.
+ */
+if (isset($_REQUEST['get_relational_values'])
+    && $_REQUEST['get_relational_values'] == true
+) {
+    $column = $_REQUEST['column'];
+    $foreigners = PMA_getForeigners($db, $table, $column);
+
+    $display_field = PMA_getDisplayField(
+        $foreigners[$column]['foreign_db'],
+        $foreigners[$column]['foreign_table']
+    );
+
+    $foreignData = PMA_getForeignData($foreigners, $column, false, '', '');
+
+    if ($_SESSION['tmp_user_values']['relational_display'] == 'D'
+        && isset($display_field)
+        && strlen($display_field)
+        && isset($_REQUEST['relation_key_or_display_column'])
+        && $_REQUEST['relation_key_or_display_column']
+    ) {
+        $curr_value = $_REQUEST['relation_key_or_display_column'];
+    } else {
+        $curr_value = $_REQUEST['curr_value'];
+    }
+    if ($foreignData['disp_row'] == null) {
+        //Handle the case when number of values
+        //is more than $cfg['ForeignKeyMaxLimit']
+        $_url_params = array(
+                'db' => $db,
+                'table' => $table,
+                'field' => $column
+        );
+
+        $dropdown = '<span class="curr_value">'
+            . htmlspecialchars($_REQUEST['curr_value'])
+            . '</span>'
+            . '<a href="browse_foreigners.php'
+            . PMA_generate_common_url($_url_params) . '"'
+            . ' target="_blank" class="browse_foreign" ' .'>'
+            . __('Browse foreign values')
+            . '</a>';
+    } else {
+        $dropdown = PMA_foreignDropdown(
+            $foreignData['disp_row'],
+            $foreignData['foreign_field'],
+            $foreignData['foreign_display'],
+            $curr_value,
+            $cfg['ForeignKeyMaxLimit']
+        );
+        $dropdown = '<select>' . $dropdown . '</select>';
+    }
+
+    $response = PMA_Response::getInstance();
+    $response->addJSON('dropdown', $dropdown);
+    exit;
+}
+
+/**
+ * Just like above, find possible values for enum fields during grid edit.
+ *
+ * Logic taken from libraries/DisplayResults.class.php
+ */
+if (isset($_REQUEST['get_enum_values']) && $_REQUEST['get_enum_values'] == true) {
+    $field_info_query = PMA_DBI_get_columns_sql($db, $table, $_REQUEST['column']);
+
+    $field_info_result = PMA_DBI_fetch_result(
+        $field_info_query, null, null, null, PMA_DBI_QUERY_STORE
+    );
+
+    $values = PMA_Util::parseEnumSetValues($field_info_result[0]['Type']);
+
+    $dropdown = '<option value=""> </option>';
+    foreach ($values as $value) {
+        $dropdown .= '<option value="' . $value . '"';
+        if ($value == $_REQUEST['curr_value']) {
+            $dropdown .= ' selected="selected"';
+        }
+        $dropdown .= '>' . $value . '</option>';
+    }
+
+    $dropdown = '<select>' . $dropdown . '</select>';
+
+    $response = PMA_Response::getInstance();
+    $response->addJSON('dropdown', $dropdown);
+    exit;
+}
+
+/**
+ * Find possible values for set fields during grid edit.
+ */
+if (isset($_REQUEST['get_set_values']) && $_REQUEST['get_set_values'] == true) {
+    $field_info_query = PMA_DBI_get_columns_sql($db, $table, $_REQUEST['column']);
+
+    $field_info_result = PMA_DBI_fetch_result(
+        $field_info_query, null, null, null, PMA_DBI_QUERY_STORE
+    );
+
+    $values = PMA_Util::parseEnumSetValues($field_info_result[0]['Type']);
+
+    $select = '';
+       
+    //converts characters of $_REQUEST['curr_value'] to HTML entities
+    $converted_curr_value = htmlentities(
+        $_REQUEST['curr_value'], ENT_COMPAT, "UTF-8"
+    );
+
+    $selected_values = explode(',', $converted_curr_value);
+    
+    foreach ($values as $value) {       
+        $select .= '<option value="' . $value . '"';
+        if ($value == $converted_curr_value 
+            || in_array($value, $selected_values, true)
+        ) {
+            $select .= ' selected="selected" ';
+        }
+        $select .= '>' . $value . '</option>';
+    }  
+
+    $select_size = (sizeof($values) > 10) ? 10 : sizeof($values);
+    $select = '<select multiple="multiple" size="' . $select_size . '">'
+        . $select . '</select>';
+
+    $response = PMA_Response::getInstance();
+    $response->addJSON('select', $select);
+    exit;
+}
+
+/**
+ * Check ajax request to set the column order
+ */
+if (isset($_REQUEST['set_col_prefs']) && $_REQUEST['set_col_prefs'] == true) {
+    $pmatable = new PMA_Table($table, $db);
+    $retval = false;
+
+    // set column order
+    if (isset($_REQUEST['col_order'])) {
+        $col_order = explode(',', $_REQUEST['col_order']);
+        $retval = $pmatable->setUiProp(
+            PMA_Table::PROP_COLUMN_ORDER,
+            $col_order,
+            $_REQUEST['table_create_time']
+        );
+        if (gettype($retval) != 'boolean') {
+            $response = PMA_Response::getInstance();
+            $response->isSuccess(false);
+            $response->addJSON('message', $retval->getString());
+            exit;
+        }
+    }
+
+    // set column visibility
+    if ($retval === true && isset($_REQUEST['col_visib'])) {
+        $col_visib = explode(',', $_REQUEST['col_visib']);
+        $retval = $pmatable->setUiProp(
+            PMA_Table::PROP_COLUMN_VISIB, $col_visib,
+            $_REQUEST['table_create_time']
+        );
+        if (gettype($retval) != 'boolean') {
+            $response = PMA_Response::getInstance();
+            $response->isSuccess(false);
+            $response->addJSON('message', $retval->getString());
+            exit;
+        }
+    }
+
+    $response = PMA_Response::getInstance();
+    $response->isSuccess($retval == true);
+    exit;
+}
+
+// Default to browse if no query set and we have table
+// (needed for browsing from DefaultTabTable)
+if (empty($sql_query) && strlen($table) && strlen($db)) {
+    include_once 'libraries/bookmark.lib.php';
+    $book_sql_query = PMA_Bookmark_get(
+        $db,
+        '\'' . PMA_Util::sqlAddSlashes($table) . '\'',
+        'label',
+        false,
+        true
+    );
+
+    if (! empty($book_sql_query)) {
+        $GLOBALS['using_bookmark_message'] = PMA_message::notice(
+            __('Using bookmark "%s" as default browse query.')
+        );
+        $GLOBALS['using_bookmark_message']->addParam($table);
+        $GLOBALS['using_bookmark_message']->addMessage(
+            PMA_Util::showDocu('faq', 'faq6-22')
+        );
+        $sql_query = $book_sql_query;
+    } else {
+        $sql_query = 'SELECT * FROM ' . PMA_Util::backquote($table);
+    }
+    unset($book_sql_query);
+
+    // set $goto to what will be displayed if query returns 0 rows
+    $goto = '';
+} else {
+    // Now we can check the parameters
+    PMA_Util::checkParameters(array('sql_query'));
+}
+
+// instead of doing the test twice
+$is_drop_database = preg_match(
+    '/DROP[[:space:]]+(DATABASE|SCHEMA)[[:space:]]+/i',
+    $sql_query
+);
+
+/**
+ * Check rights in case of DROP DATABASE
+ *
+ * This test may be bypassed if $is_js_confirmed = 1 (already checked with js)
+ * but since a malicious user may pass this variable by url/form, we don't take
+ * into account this case.
+ */
+if (! defined('PMA_CHK_DROP')
+    && ! $cfg['AllowUserDropDatabase']
+    && $is_drop_database
+    && ! $is_superuser
+) {
+    PMA_Util::mysqlDie(
+        __('"DROP DATABASE" statements are disabled.'),
+        '',
+        '',
+        $err_url
+    );
+} // end if
+
+// Include PMA_Index class for use in PMA_DisplayResults class
+require_once './libraries/Index.class.php';
+
+require_once 'libraries/DisplayResults.class.php';
+
+$displayResultsObject = new PMA_DisplayResults(
+    $GLOBALS['db'], $GLOBALS['table'], $GLOBALS['goto'], $GLOBALS['sql_query']
+);
+
+$displayResultsObject->setConfigParamsForDisplayTable();
+
+/**
+ * Need to find the real end of rows?
+ */
+if (isset($find_real_end) && $find_real_end) {
+    $unlim_num_rows = PMA_Table::countRecords($db, $table, true);
+    $_SESSION['tmp_user_values']['pos'] = @((ceil(
+        $unlim_num_rows / $_SESSION['tmp_user_values']['max_rows']
+    ) - 1) * $_SESSION['tmp_user_values']['max_rows']);
+}
+
+
+/**
+ * Bookmark add
+ */
+if (isset($store_bkm)) {
+    $result = PMA_Bookmark_save(
+        $fields,
+        (isset($bkm_all_users) && $bkm_all_users == 'true' ? true : false)
+    );
+    $response = PMA_Response::getInstance();
+    if ($response->isAjax()) {
+        if ($result) {
+            $msg = PMA_message::success(__('Bookmark %s created'));
+            $msg->addParam($fields['label']);
+            $response->addJSON('message', $msg);
+        } else {
+            $msg = PMA_message::error(__('Bookmark not created'));
+            $response->isSuccess(false);
+            $response->addJSON('message', $msg);
+        }
+        exit;
+    } else {
+        // go back to sql.php to redisplay query; do not use & in this case:
+        PMA_sendHeaderLocation(
+            $cfg['PmaAbsoluteUri'] . $goto . '&label=' . $fields['label']
+        );
+    }
+} // end if
+
+/**
+ * Parse and analyze the query
+ */
+require_once 'libraries/parse_analyze.lib.php';
+
+/**
+ * Sets or modifies the $goto variable if required
+ */
+if ($goto == 'sql.php') {
+    $is_gotofile = false;
+    $goto = 'sql.php?'
+          . PMA_generate_common_url($db, $table)
+          . '&sql_query=' . urlencode($sql_query);
+} // end if
+
+/**
+ * Go back to further page if table should not be dropped
+ */
+if (isset($_REQUEST['btnDrop']) && $_REQUEST['btnDrop'] == __('No')) {
+    if (! empty($back)) {
+        $goto = $back;
+    }
+    if ($is_gotofile) {
+        if (strpos($goto, 'db_') === 0 && strlen($table)) {
+            $table = '';
+        }
+        $active_page = $goto;
+        include '' . PMA_securePath($goto);
+    } else {
+        PMA_sendHeaderLocation(
+            $cfg['PmaAbsoluteUri'] . str_replace('&', '&', $goto)
+        );
+    }
+    exit();
+} // end if
+
+
+/**
+ * Displays the confirm page if required
+ *
+ * This part of the script is bypassed if $is_js_confirmed = 1 (already checked
+ * with js) because possible security issue is not so important here: at most,
+ * the confirm message isn't displayed.
+ *
+ * Also bypassed if only showing php code.or validating a SQL query
+ */
+// if we are coming from a "Create PHP code" or a "Without PHP Code"
+// dialog, we won't execute the query anyway, so don't confirm
+if (! $cfg['Confirm']
+    || isset($_REQUEST['is_js_confirmed'])
+    || isset($_REQUEST['btnDrop'])
+    || isset($GLOBALS['show_as_php'])
+    || ! empty($GLOBALS['validatequery'])
+) {
+    $do_confirm = false;
+} else {
+    $do_confirm = isset($analyzed_sql[0]['queryflags']['need_confirm']);
+}
+
+if ($do_confirm) {
+    $stripped_sql_query = $sql_query;
+    $input = '<input type="hidden" name="%s" value="%s" />';
+    $output = '';
+    if ($is_drop_database) {
+        $output .= '<h1 class="error">';
+        $output .= __('You are about to DESTROY a complete database!');
+        $output .= '</h1>';
+    }
+    $form  = '<form class="disableAjax" action="sql.php" method="post">';
+    $form .= PMA_generate_common_hidden_inputs($db, $table);
+
+    $form .= sprintf(
+        $input, 'sql_query', htmlspecialchars($sql_query)
+    );
+    $form .= sprintf(
+        $input, 'message_to_show',
+        (isset($message_to_show) ? PMA_sanitize($message_to_show, true) : '')
+    );
+    $form .= sprintf(
+        $input, 'goto', $goto
+    );
+    $form .= sprintf(
+        $input, 'back',
+        (isset($back) ? PMA_sanitize($back, true) : '')
+    );
+    $form .= sprintf(
+        $input, 'reload',
+        (isset($reload) ? PMA_sanitize($reload, true) : '')
+    );
+    $form .= sprintf(
+        $input, 'purge',
+        (isset($purge) ? PMA_sanitize($purge, true) : '')
+    );
+    $form .= sprintf(
+        $input, 'dropped_column',
+        (isset($dropped_column) ? PMA_sanitize($dropped_column, true) : '')
+    );
+    $form .= sprintf(
+        $input, 'show_query',
+        (isset($message_to_show) ? PMA_sanitize($show_query, true) : '')
+    );
+    $form = str_replace('%', '%%', $form) . '%s</form>';
+
+    $output .='<fieldset class="confirmation">'
+        .'<legend>'
+        . __('Do you really want to execute the following query?')
+        . '</legend>'
+        .'<code>' . htmlspecialchars($stripped_sql_query) . '</code>'
+        .'</fieldset>'
+        .'<fieldset class="tblFooters">';
+
+    $yes_input  = sprintf($input, 'btnDrop', __('Yes'));
+    $yes_input .= '<input type="submit" value="' . __('Yes') . '" id="buttonYes" />';
+    $no_input   = sprintf($input, 'btnDrop', __('No'));
+    $no_input  .= '<input type="submit" value="' . __('No') . '" id="buttonNo" />';
+
+    $output .= sprintf($form, $yes_input);
+    $output .= sprintf($form, $no_input);
+
+    $output .='</fieldset>';
+    $output .= '';
+
+    PMA_Response::getInstance()->addHTML($output);
+
+    exit;
+} // end if $do_confirm
+
+
+// Defines some variables
+// A table has to be created, renamed, dropped -> navi frame should be reloaded
+/**
+ * @todo use the parser/analyzer
+ */
+
+if (empty($reload)
+    && preg_match('/^(CREATE|ALTER|DROP)\s+(VIEW|TABLE|DATABASE|SCHEMA)\s+/i', $sql_query)
+) {
+    $reload = 1;
+}
+
+// $is_group added for use in calculation of total number of rows.
+// $is_count is changed for more correct "LIMIT" clause
+//  appending in queries like
+//  "SELECT COUNT(...) FROM ... GROUP BY ..."
+
+/**
+ * @todo detect all this with the parser, to avoid problems finding
+ * those strings in comments or backquoted identifiers
+ */
+list($is_group, $is_func, $is_count, $is_export, $is_analyse, $is_explain,
+    $is_delete, $is_affected, $is_insert, $is_replace, $is_show, $is_maint)
+        = PMA_getDisplayPropertyParams(
+            $sql_query, $is_select
+        );
+
+// assign default full_sql_query
+$full_sql_query = $sql_query;
+
+// Handle remembered sorting order, only for single table query
+if ($GLOBALS['cfg']['RememberSorting']
+    && ! ($is_count || $is_export || $is_func || $is_analyse)
+    && isset($analyzed_sql[0]['select_expr'])
+    && (count($analyzed_sql[0]['select_expr']) == 0)
+    && isset($analyzed_sql[0]['queryflags']['select_from'])
+    && count($analyzed_sql[0]['table_ref']) == 1
+) {
+    PMA_handleSortOrder($db, $table, $analyzed_sql, $full_sql_query);
+}
+
+$sql_limit_to_append = '';
+// Do append a "LIMIT" clause?
+if (($_SESSION['tmp_user_values']['max_rows'] != 'all')
+    && ! ($is_count || $is_export || $is_func || $is_analyse)
+    && isset($analyzed_sql[0]['queryflags']['select_from'])
+    && ! isset($analyzed_sql[0]['queryflags']['offset'])
+    && empty($analyzed_sql[0]['limit_clause'])
+) {
+    $sql_limit_to_append = ' LIMIT ' . $_SESSION['tmp_user_values']['pos']
+        . ', ' . $_SESSION['tmp_user_values']['max_rows'] . " ";
+    $full_sql_query = PMA_getSqlWithLimitClause(
+        $full_sql_query,
+        $analyzed_sql,
+        $sql_limit_to_append
+    );
+
+    /**
+     * @todo pretty printing of this modified query
+     */
+    if (isset($display_query)) {
+        // if the analysis of the original query revealed that we found
+        // a section_after_limit, we now have to analyze $display_query
+        // to display it correctly
+
+        if (! empty($analyzed_sql[0]['section_after_limit'])
+            && trim($analyzed_sql[0]['section_after_limit']) != ';'
+        ) {
+            $analyzed_display_query = PMA_SQP_analyze(
+                PMA_SQP_parse($display_query)
+            );
+            $display_query  = $analyzed_display_query[0]['section_before_limit']
+                . "\n" . $sql_limit_to_append
+                . $analyzed_display_query[0]['section_after_limit'];
+        }
+    }
+}
+
+if (strlen($db)) {
+    PMA_DBI_select_db($db);
+}
+
+//  E x e c u t e    t h e    q u e r y
+
+// Only if we didn't ask to see the php code
+if (isset($GLOBALS['show_as_php']) || ! empty($GLOBALS['validatequery'])) {
+    unset($result);
+    $num_rows = 0;
+    $unlim_num_rows = 0;
+} else {
+    if (isset($_SESSION['profiling']) && PMA_Util::profilingSupported()) {
+        PMA_DBI_query('SET PROFILING=1;');
+    }
+
+    // Measure query time.
+    $querytime_before = array_sum(explode(' ', microtime()));
+
+    $result   = @PMA_DBI_try_query($full_sql_query, null, PMA_DBI_QUERY_STORE);
+
+    // If a stored procedure was called, there may be more results that are
+    // queued up and waiting to be flushed from the buffer. So let's do that.
+    do {
+        PMA_DBI_store_result();
+        if (! PMA_DBI_more_results()) {
+            break;
+        }
+    } while (PMA_DBI_next_result());
+
+    $is_procedure = false;
+    
+    // Since multiple query execution is anyway handled,
+    // ignore the WHERE clause of the first sql statement
+    // which might contain a phrase like 'call '
+    if (preg_match("/\bcall\b/i", $full_sql_query)
+        && empty($analyzed_sql[0]['where_clause'])
+    ) {
+        $is_procedure = true;
+    }
+
+    $querytime_after = array_sum(explode(' ', microtime()));
+
+    $GLOBALS['querytime'] = $querytime_after - $querytime_before;
+
+    // Displays an error message if required and stop parsing the script
+    $error = PMA_DBI_getError();
+    if ($error) {
+        if ($is_gotofile) {
+            if (strpos($goto, 'db_') === 0 && strlen($table)) {
+                $table = '';
+            }
+            $active_page = $goto;
+            $message = PMA_Message::rawError($error);
+
+            if ($GLOBALS['is_ajax_request'] == true) {
+                $response = PMA_Response::getInstance();
+                $response->isSuccess(false);
+                $response->addJSON('message', $message);
+                exit;
+            }
+
+            /**
+             * Go to target path.
+             */
+            include '' . PMA_securePath($goto);
+        } else {
+            $full_err_url = $err_url;
+            if (preg_match('@^(db|tbl)_@', $err_url)) {
+                $full_err_url .=  '&show_query=1&sql_query='
+                    . urlencode($sql_query);
+            }
+            PMA_Util::mysqlDie($error, $full_sql_query, '', $full_err_url);
+        }
+        exit;
+    }
+    unset($error);
+
+    // If there are no errors and bookmarklabel was given,
+    // store the query as a bookmark
+    if (! empty($bkm_label) && ! empty($import_text)) {
+        include_once 'libraries/bookmark.lib.php';
+        $bfields = array(
+                     'dbase' => $db,
+                     'user'  => $cfg['Bookmark']['user'],
+                     'query' => urlencode($import_text),
+                     'label' => $bkm_label
+        );
+
+        // Should we replace bookmark?
+        if (isset($bkm_replace)) {
+            $bookmarks = PMA_Bookmark_getList($db);
+            foreach ($bookmarks as $key => $val) {
+                if ($val == $bkm_label) {
+                    PMA_Bookmark_delete($db, $key);
+                }
+            }
+        }
+
+        PMA_Bookmark_save($bfields, isset($bkm_all_users));
+
+        $bookmark_created = true;
+    } // end store bookmarks
+
+    // Gets the number of rows affected/returned
+    // (This must be done immediately after the query because
+    // mysql_affected_rows() reports about the last query done)
+
+    if (! $is_affected) {
+        $num_rows = ($result) ? @PMA_DBI_num_rows($result) : 0;
+    } elseif (! isset($num_rows)) {
+        $num_rows = @PMA_DBI_affected_rows();
+    }
+
+    // Grabs the profiling results
+    if (isset($_SESSION['profiling']) && PMA_Util::profilingSupported()) {
+        $profiling_results = PMA_DBI_fetch_result('SHOW PROFILE;');
+    }
+
+    // Checks if the current database has changed
+    // This could happen if the user sends a query like "USE `database`;"
+    /**
+     * commented out auto-switching to active database - really required?
+     * bug #2558 win: table list disappears (mixed case db names)
+     * https://sourceforge.net/p/phpmyadmin/bugs/2558/
+     * @todo RELEASE test and comit or rollback before release
+    $current_db = PMA_DBI_fetch_value('SELECT DATABASE()');
+    if ($db !== $current_db) {
+        $db     = $current_db;
+        $reload = 1;
+    }
+    unset($current_db);
+     */
+
+    // tmpfile remove after convert encoding appended by Y.Kawada
+    if (function_exists('PMA_kanji_file_conv')
+        && (isset($textfile) && file_exists($textfile))
+    ) {
+        unlink($textfile);
+    }
+
+    // Counts the total number of rows for the same 'SELECT' query without the
+    // 'LIMIT' clause that may have been programatically added
+
+    $justBrowsing = false;
+    if (empty($sql_limit_to_append)) {
+        $unlim_num_rows         = $num_rows;
+        // if we did not append a limit, set this to get a correct
+        // "Showing rows..." message
+        //$_SESSION['tmp_user_values']['max_rows'] = 'all';
+    } elseif ($is_select) {
+
+        //    c o u n t    q u e r y
+
+        // If we are "just browsing", there is only one table,
+        // and no WHERE clause (or just 'WHERE 1 '),
+        // we do a quick count (which uses MaxExactCount) because
+        // SQL_CALC_FOUND_ROWS is not quick on large InnoDB tables
+
+        // However, do not count again if we did it previously
+        // due to $find_real_end == true
+        if (! $is_group
+            && ! isset($analyzed_sql[0]['queryflags']['union'])
+            && ! isset($analyzed_sql[0]['queryflags']['distinct'])
+            && ! isset($analyzed_sql[0]['table_ref'][1]['table_name'])
+            && (empty($analyzed_sql[0]['where_clause'])
+            || $analyzed_sql[0]['where_clause'] == '1 ')
+            && ! isset($find_real_end)
+        ) {
+            // "j u s t   b r o w s i n g"
+            $justBrowsing = true;
+            $unlim_num_rows = PMA_Table::countRecords(
+                $db, 
+                $table, 
+                $force_exact = true
+            );
+
+        } else { // n o t   " j u s t   b r o w s i n g "
+
+            // add select expression after the SQL_CALC_FOUND_ROWS
+
+            // for UNION, just adding SQL_CALC_FOUND_ROWS
+            // after the first SELECT works.
+
+            // take the left part, could be:
+            // SELECT
+            // (SELECT
+            $count_query = PMA_SQP_formatHtml(
+                $parsed_sql,
+                'query_only',
+                0,
+                $analyzed_sql[0]['position_of_first_select'] + 1
+            );
+            $count_query .= ' SQL_CALC_FOUND_ROWS ';
+            // add everything that was after the first SELECT
+            $count_query .= PMA_SQP_formatHtml(
+                $parsed_sql,
+                'query_only',
+                $analyzed_sql[0]['position_of_first_select'] + 1
+            );
+            // ensure there is no semicolon at the end of the
+            // count query because we'll probably add
+            // a LIMIT 1 clause after it
+            $count_query = rtrim($count_query);
+            $count_query = rtrim($count_query, ';');
+
+            // if using SQL_CALC_FOUND_ROWS, add a LIMIT to avoid
+            // long delays. Returned count will be complete anyway.
+            // (but a LIMIT would disrupt results in an UNION)
+
+            if (! isset($analyzed_sql[0]['queryflags']['union'])) {
+                $count_query .= ' LIMIT 1';
+            }
+
+            // run the count query
+
+            PMA_DBI_try_query($count_query);
+            // if (mysql_error()) {
+            // void.
+            // I tried the case
+            // (SELECT `User`, `Host`, `Db`, `Select_priv` FROM `db`)
+            // UNION (SELECT `User`, `Host`, "%" AS "Db",
+            // `Select_priv`
+            // FROM `user`) ORDER BY `User`, `Host`, `Db`;
+            // and although the generated count_query is wrong
+            // the SELECT FOUND_ROWS() work! (maybe it gets the
+            // count from the latest query that worked)
+            //
+            // another case where the count_query is wrong:
+            // SELECT COUNT(*), f1 from t1 group by f1
+            // and you click to sort on count(*)
+            // }
+            $unlim_num_rows = PMA_DBI_fetch_value('SELECT FOUND_ROWS()');
+        } // end else "just browsing"
+
+    } else { // not $is_select
+         $unlim_num_rows         = 0;
+    } // end rows total count
+
+    // if a table or database gets dropped, check column comments.
+    if (isset($purge) && $purge == '1') {
+        /**
+         * Cleanup relations.
+         */
+        include_once 'libraries/relation_cleanup.lib.php';
+
+        if (strlen($table) && strlen($db)) {
+            PMA_relationsCleanupTable($db, $table);
+        } elseif (strlen($db)) {
+            PMA_relationsCleanupDatabase($db);
+        } else {
+            // VOID. No DB/Table gets deleted.
+        } // end if relation-stuff
+    } // end if ($purge)
+
+    // If a column gets dropped, do relation magic.
+    if (isset($dropped_column)
+        && strlen($db)
+        && strlen($table)
+        && ! empty($dropped_column)
+    ) {
+        include_once 'libraries/relation_cleanup.lib.php';
+        PMA_relationsCleanupColumn($db, $table, $dropped_column);
+        // to refresh the list of indexes (Ajax mode)
+        $extra_data['indexes_list'] = PMA_Index::getView($table, $db);
+    } // end if column was dropped
+} // end else "didn't ask to see php code"
+
+// No rows returned -> move back to the calling page
+if ((0 == $num_rows && 0 == $unlim_num_rows) || $is_affected) {
+    // Delete related tranformation information
+    if (!empty($analyzed_sql[0]['querytype'])
+        && (($analyzed_sql[0]['querytype'] == 'ALTER')
+        || ($analyzed_sql[0]['querytype'] == 'DROP'))
+    ) {
+        include_once 'libraries/transformations.lib.php';
+        if ($analyzed_sql[0]['querytype'] == 'ALTER') {
+            if (stripos($analyzed_sql[0]['unsorted_query'], 'DROP') !== false) {
+                $drop_column = PMA_getColumnNameInColumnDropSql(
+                    $analyzed_sql[0]['unsorted_query']
+                );
+
+                if ($drop_column != '') {
+                    PMA_clearTransformations($db, $table, $drop_column);
+                }
+            }
+
+        } else if (($analyzed_sql[0]['querytype'] == 'DROP') && ($table != '')) {
+            PMA_clearTransformations($db, $table);
+        }
+    }
+
+    if ($is_delete) {
+        $message = PMA_Message::getMessageForDeletedRows($num_rows);
+    } elseif ($is_insert) {
+        if ($is_replace) {
+            // For replace we get DELETED + INSERTED row count,
+            // so we have to call it affected
+            $message = PMA_Message::getMessageForAffectedRows($num_rows);
+        } else {
+            $message = PMA_Message::getMessageForInsertedRows($num_rows);
+        }
+        $insert_id = PMA_DBI_insert_id();
+        if ($insert_id != 0) {
+            // insert_id is id of FIRST record inserted in one insert,
+            // so if we inserted multiple rows, we had to increment this
+            $message->addMessage('[br]');
+            // need to use a temporary because the Message class
+            // currently supports adding parameters only to the first
+            // message
+            $_inserted = PMA_Message::notice(__('Inserted row id: %1$d'));
+            $_inserted->addParam($insert_id + $num_rows - 1);
+            $message->addMessage($_inserted);
+        }
+    } elseif ($is_affected) {
+        $message = PMA_Message::getMessageForAffectedRows($num_rows);
+
+        // Ok, here is an explanation for the !$is_select.
+        // The form generated by sql_query_form.lib.php
+        // and db_sql.php has many submit buttons
+        // on the same form, and some confusion arises from the
+        // fact that $message_to_show is sent for every case.
+        // The $message_to_show containing a success message and sent with
+        // the form should not have priority over errors
+    } elseif (! empty($message_to_show) && ! $is_select) {
+        $message = PMA_Message::rawSuccess(htmlspecialchars($message_to_show));
+    } elseif (! empty($GLOBALS['show_as_php'])) {
+        $message = PMA_Message::success(__('Showing as PHP code'));
+    } elseif (isset($GLOBALS['show_as_php'])) {
+        /* User disable showing as PHP, query is only displayed */
+        $message = PMA_Message::notice(__('Showing SQL query'));
+    } elseif (! empty($GLOBALS['validatequery'])) {
+        $message = PMA_Message::notice(__('Validated SQL'));
+    } else {
+        $message = PMA_Message::success(
+            __('MySQL returned an empty result set (i.e. zero rows).')
+        );
+    }
+
+    if (isset($GLOBALS['querytime'])) {
+        $_querytime = PMA_Message::notice('(' . __('Query took %01.4f sec') . ')');
+        $_querytime->addParam($GLOBALS['querytime']);
+        $message->addMessage($_querytime);
+    }
+
+    if ($GLOBALS['is_ajax_request'] == true) {
+        if ($cfg['ShowSQL']) {
+            $extra_data['sql_query'] = PMA_Util::getMessage(
+                $message, $GLOBALS['sql_query'], 'success'
+            );
+        }
+        if (isset($GLOBALS['reload']) && $GLOBALS['reload'] == 1) {
+            $extra_data['reload'] = 1;
+            $extra_data['db'] = $GLOBALS['db'];
+        }
+        $response = PMA_Response::getInstance();
+        $response->isSuccess($message->isSuccess());
+        // No need to manually send the message
+        // The Response class will handle that automatically
+        $response->addJSON(isset($extra_data) ? $extra_data : array());
+        if (empty($_REQUEST['ajax_page_request'])) {
+            $response->addJSON('message', $message);
+            exit;
+        }
+    }
+
+    if ($is_gotofile) {
+        $goto = PMA_securePath($goto);
+        // Checks for a valid target script
+        $is_db = $is_table = false;
+        if (isset($_REQUEST['purge']) && $_REQUEST['purge'] == '1') {
+            $table = '';
+            unset($url_params['table']);
+        }
+        include 'libraries/db_table_exists.lib.php';
+
+        if (strpos($goto, 'tbl_') === 0 && ! $is_table) {
+            if (strlen($table)) {
+                $table = '';
+            }
+            $goto = 'db_sql.php';
+        }
+        if (strpos($goto, 'db_') === 0 && ! $is_db) {
+            if (strlen($db)) {
+                $db = '';
+            }
+            $goto = 'index.php';
+        }
+        // Loads to target script
+        if (strlen($goto) > 0) {
+            $active_page = $goto;
+            include '' . $goto;
+        } else {
+            // Echo at least one character to prevent showing last page from history
+            echo " ";
+        }
+        
+    } else {
+        // avoid a redirect loop when last record was deleted
+        if (0 == $num_rows && 'sql.php' == $cfg['DefaultTabTable']) {
+            $goto = str_replace('sql.php', 'tbl_structure.php', $goto);
+        }
+        PMA_sendHeaderLocation(
+            $cfg['PmaAbsoluteUri'] . str_replace('&', '&', $goto)
+            . '&message=' . urlencode($message)
+        );
+    } // end else
+    exit();
+    // end no rows returned
+} else {
+    // At least one row is returned -> displays a table with results
+    //If we are retrieving the full value of a truncated field or the original
+    // value of a transformed field, show it here and exit
+    if ($GLOBALS['grid_edit'] == true) {
+        $row = PMA_DBI_fetch_row($result);
+        $response = PMA_Response::getInstance();
+        $response->addJSON('value', $row[0]);
+        exit;
+    }
+
+    if (isset($_REQUEST['ajax_request']) && isset($_REQUEST['table_maintenance'])) {
+        $response = PMA_Response::getInstance();
+        $header   = $response->getHeader();
+        $scripts  = $header->getScripts();
+        $scripts->addFile('makegrid.js');
+        $scripts->addFile('sql.js');
+
+        // Gets the list of fields properties
+        if (isset($result) && $result) {
+            $fields_meta = PMA_DBI_get_fields_meta($result);
+            $fields_cnt  = count($fields_meta);
+        }
+
+        if (empty($disp_mode)) {
+            // see the "PMA_setDisplayMode()" function in
+            // libraries/DisplayResults.class.php
+            $disp_mode = 'urdr111101';
+        }
+
+        // hide edit and delete links for information_schema
+        if (PMA_is_system_schema($db)) {
+            $disp_mode = 'nnnn110111';
+        }
+
+        if (isset($message)) {
+            $message = PMA_Message::success($message);
+            echo PMA_Util::getMessage(
+                $message, $GLOBALS['sql_query'], 'success'
+            );
+        }
+
+        // Should be initialized these parameters before parsing
+        $showtable = isset($showtable) ? $showtable : null;
+        $printview = isset($printview) ? $printview : null;
+        $url_query = isset($url_query) ? $url_query : null;
+
+        if (!empty($sql_data) && ($sql_data['valid_queries'] > 1)) {
+
+            $_SESSION['is_multi_query'] = true;
+            echo getTableHtmlForMultipleQueries(
+                $displayResultsObject, $db, $sql_data, $goto,
+                $pmaThemeImage, $text_dir, $printview, $url_query,
+                $disp_mode, $sql_limit_to_append, false
+            );
+        } else {
+            $_SESSION['is_multi_query'] = false;
+            $displayResultsObject->setProperties(
+                $unlim_num_rows, $fields_meta, $is_count, $is_export, $is_func,
+                $is_analyse, $num_rows, $fields_cnt, $querytime, $pmaThemeImage,
+                $text_dir, $is_maint, $is_explain, $is_show, $showtable,
+                $printview, $url_query, false
+            );
+
+            echo $displayResultsObject->getTable(
+                $result, $disp_mode, $analyzed_sql
+            );
+            exit();
+        }
+    }
+
+    // Displays the headers
+    if (isset($show_query)) {
+        unset($show_query);
+    }
+    if (isset($printview) && $printview == '1') {
+        PMA_Util::checkParameters(array('db', 'full_sql_query'));
+
+        $response = PMA_Response::getInstance();
+        $header = $response->getHeader();
+        $header->enablePrintView();
+
+        $hostname = '';
+        if ($cfg['Server']['verbose']) {
+            $hostname = $cfg['Server']['verbose'];
+        } else {
+            $hostname = $cfg['Server']['host'];
+            if (! empty($cfg['Server']['port'])) {
+                $hostname .= $cfg['Server']['port'];
+            }
+        }
+
+        $versions  = "phpMyAdmin " . PMA_VERSION;
+        $versions .= " / ";
+        $versions .= "MySQL " . PMA_MYSQL_STR_VERSION;
+
+        echo "<h1>" . __('SQL result') . "</h1>";
+        echo "<p>";
+        echo "<strong>" . __('Host') . ":</strong> $hostname<br />";
+        echo "<strong>" . __('Database') . ":</strong> "
+            . htmlspecialchars($db) . "<br />";
+        echo "<strong>" . __('Generation Time') . ":</strong> "
+            . PMA_Util::localisedDate() . "<br />";
+        echo "<strong>" . __('Generated by') . ":</strong> $versions<br />";
+        echo "<strong>" . __('SQL query') . ":</strong> "
+            . htmlspecialchars($full_sql_query) . ";";
+        if (isset($num_rows)) {
+            echo "<br />";
+            echo "<strong>" . __('Rows') . ":</strong> $num_rows";
+        }
+        echo "</p>";
+    } else {
+        $response = PMA_Response::getInstance();
+        $header = $response->getHeader();
+        $scripts = $header->getScripts();
+        $scripts->addFile('makegrid.js');
+        $scripts->addFile('sql.js');
+
+        unset($message);
+
+        if (! $GLOBALS['is_ajax_request']) {
+            if (strlen($table)) {
+                include 'libraries/tbl_common.inc.php';
+                $url_query .= '&goto=tbl_sql.php&back=tbl_sql.php';
+                include 'libraries/tbl_info.inc.php';
+            } elseif (strlen($db)) {
+                include 'libraries/db_common.inc.php';
+                include 'libraries/db_info.inc.php';
+            } else {
+                include 'libraries/server_common.inc.php';
+            }
+        } else {
+            //we don't need to buffer the output in getMessage here.
+            //set a global variable and check against it in the function
+            $GLOBALS['buffer_message'] = false;
+        }
+    }
+
+    if (strlen($db)) {
+        $cfgRelation = PMA_getRelationsParam();
+    }
+
+    // Gets the list of fields properties
+    if (isset($result) && $result) {
+        $fields_meta = PMA_DBI_get_fields_meta($result);
+        $fields_cnt  = count($fields_meta);
+    }
+
+    //begin the sqlqueryresults div here. container div
+    echo '<div id="sqlqueryresults"';
+    echo ' class="ajax"';
+    echo '>';
+
+    // Display previous update query (from tbl_replace)
+    if (isset($disp_query) && ($cfg['ShowSQL'] == true) && empty($sql_data)) {
+        echo PMA_Util::getMessage($disp_message, $disp_query, 'success');
+    }
+
+    if (isset($profiling_results)) {
+        // pma_token/url_query needed for chart export
+        echo '<script type="text/javascript">';
+        echo 'pma_token = \'' . $_SESSION[' PMA_token '] . '\';';
+        echo 'url_query = \''
+            . (isset($url_query) ? $url_query : PMA_generate_common_url($db))
+            . '\';';
+        echo 'AJAX.registerOnload(\'sql.js\',makeProfilingChart);';
+        echo '</script>';
+
+        echo '<fieldset><legend>' . __('Profiling') . '</legend>' . "\n";
+        echo '<div style="float: left;">';
+        echo '<table>' . "\n";
+        echo ' <tr>' .  "\n";
+        echo '  <th>' . __('Status')
+            . PMA_Util::showMySQLDocu(
+                'general-thread-states', 'general-thread-states'
+            )
+            .  '</th>' . "\n";
+        echo '  <th>' . __('Time') . '</th>' . "\n";
+        echo ' </tr>' .  "\n";
+
+        $chart_json = Array();
+        foreach ($profiling_results as $one_result) {
+            echo ' <tr>' .  "\n";
+            echo '<td>' . ucwords($one_result['Status']) . '</td>' .  "\n";
+            echo '<td class="right">'
+                . (PMA_Util::formatNumber($one_result['Duration'], 3, 1))
+                . 's</td>' .  "\n";
+            if (isset($chart_json[ucwords($one_result['Status'])])) {
+                $chart_json[ucwords($one_result['Status'])]
+                    += $one_result['Duration'];
+            } else {
+                $chart_json[ucwords($one_result['Status'])]
+                    = $one_result['Duration'];
+            }
+        }
+
+        echo '</table>' . "\n";
+        echo '</div>';
+        //require_once 'libraries/chart.lib.php';
+        echo '<div id="profilingChartData" style="display:none;">';
+        echo json_encode($chart_json);
+        echo '</div>';
+        echo '<div id="profilingchart" style="display:none;">';
+        echo '</div>';
+        echo '<script type="text/javascript">';
+        echo 'if($.jqplot !== undefined && $.jqplot.PieRenderer !== undefined) {';
+        echo 'makeProfilingChart();';
+        echo '}';
+        echo '</script>';
+        echo '</fieldset>' . "\n";
+    }
+
+    // Displays the results in a table
+    if (empty($disp_mode)) {
+        // see the "PMA_setDisplayMode()" function in
+        // libraries/DisplayResults.class.php
+        $disp_mode = 'urdr111101';
+    }
+
+    $resultSetContainsUniqueKey = PMA_resultSetContainsUniqueKey(
+        $db, $table, $fields_meta
+    );
+
+    // hide edit and delete links:
+    // - for information_schema
+    // - if the result set does not contain all the columns of a unique key
+    //   and we are not just browing all the columns of an updatable view
+    $updatableView
+        = $justBrowsing
+        && trim($analyzed_sql[0]['select_expr_clause']) == '*'
+        && PMA_Table::isUpdatableView($db, $table);
+    $editable = $resultSetContainsUniqueKey || $updatableView;
+    if (!empty($table) && (PMA_is_system_schema($db) || !$editable)) {
+        $disp_mode = 'nnnn110111';
+        $msg = PMA_message::notice(
+            __(
+                'This table does not contain a unique column.'
+                . ' Grid edit, checkbox, Edit, Copy and Delete features'
+                . ' are not available.'
+            )
+        );
+        $msg->display();
+    }
+
+    if (isset($label)) {
+        $msg = PMA_message::success(__('Bookmark %s created'));
+        $msg->addParam($label);
+        $msg->display();
+    }
+
+    // Should be initialized these parameters before parsing
+    $showtable = isset($showtable) ? $showtable : null;
+    $printview = isset($printview) ? $printview : null;
+    $url_query = isset($url_query) ? $url_query : null;
+
+    if (! empty($sql_data) && ($sql_data['valid_queries'] > 1) || $is_procedure) {
+
+        $_SESSION['is_multi_query'] = true;
+        echo getTableHtmlForMultipleQueries(
+            $displayResultsObject, $db, $sql_data, $goto,
+            $pmaThemeImage, $text_dir, $printview, $url_query,
+            $disp_mode, $sql_limit_to_append, $editable
+        );
+    } else {
+        $_SESSION['is_multi_query'] = false;
+        $displayResultsObject->setProperties(
+            $unlim_num_rows, $fields_meta, $is_count, $is_export, $is_func,
+            $is_analyse, $num_rows, $fields_cnt, $querytime, $pmaThemeImage,
+            $text_dir, $is_maint, $is_explain, $is_show, $showtable,
+            $printview, $url_query, $editable
+        );
+
+        echo $displayResultsObject->getTable($result, $disp_mode, $analyzed_sql);
+        PMA_DBI_free_result($result);
+    }
+
+    // BEGIN INDEX CHECK See if indexes should be checked.
+    if (isset($query_type)
+        && $query_type == 'check_tbl'
+        && isset($selected)
+        && is_array($selected)
+    ) {
+        foreach ($selected as $idx => $tbl_name) {
+            $check = PMA_Index::findDuplicates($tbl_name, $db);
+            if (! empty($check)) {
+                printf(__('Problems with indexes of table `%s`'), $tbl_name);
+                echo $check;
+            }
+        }
+    } // End INDEX CHECK
+
+    // Bookmark support if required
+    if ($disp_mode[7] == '1'
+        && (! empty($cfg['Bookmark']) && empty($id_bookmark))
+        && ! empty($sql_query)
+    ) {
+        echo "\n";
+        $goto = 'sql.php?'
+              . PMA_generate_common_url($db, $table)
+              . '&sql_query=' . urlencode($sql_query)
+              . '&id_bookmark=1';
+
+        echo '<form action="sql.php" method="post"'
+            . ' onsubmit="return ! emptyFormElements(this, \'fields[label]\');"'
+            . ' id="bookmarkQueryForm">';
+        echo PMA_generate_common_hidden_inputs();
+        echo '<input type="hidden" name="goto" value="' . $goto . '" />';
+        echo '<input type="hidden" name="fields[dbase]"'
+            . ' value="' . htmlspecialchars($db) . '" />';
+        echo '<input type="hidden" name="fields[user]"'
+            . ' value="' . $cfg['Bookmark']['user'] . '" />';
+        echo '<input type="hidden" name="fields[query]"' . ' value="'
+            . urlencode(isset($complete_query) ? $complete_query : $sql_query)
+            . '" />';
+        echo '<fieldset>';
+        echo '<legend>';
+        echo PMA_Util::getIcon(
+            'b_bookmark.png', __('Bookmark this SQL query'), true
+        );
+        echo '</legend>';
+        echo '<div class="formelement">';
+        echo '<label for="fields_label_">' . __('Label') . ':</label>';
+        echo '<input type="text" id="fields_label_"'
+            . ' name="fields[label]" value="" />';
+        echo '</div>';
+        echo '<div class="formelement">';
+        echo '<input type="checkbox" name="bkm_all_users"'
+            . ' id="bkm_all_users" value="true" />';
+        echo '<label for="bkm_all_users">'
+            . __('Let every user access this bookmark')
+            . '</label>';
+        echo '</div>';
+        echo '<div class="clearfloat"></div>';
+        echo '</fieldset>';
+        echo '<fieldset class="tblFooters">';
+        echo '<input type="hidden" name="store_bkm" value="1" />';
+        echo '<input type="submit"'
+            . ' value="' . __('Bookmark this SQL query') . '" />';
+        echo '</fieldset>';
+        echo '</form>';
+    } // end bookmark support
+
+    // Do print the page if required
+    if (isset($printview) && $printview == '1') {
+        echo PMA_Util::getButton();
+    } // end print case
+    echo '</div>'; // end sqlqueryresults div
+} // end rows returned
+
+$_SESSION['is_multi_query'] = false;
+
+/**
+ * Displays the footer
+ */
+if (! isset($_REQUEST['table_maintenance'])) {
+    exit;
+}
+
+
+// These functions will need for use set the required parameters for display results
+
+/**
+ * Initialize some parameters needed to display results
+ *
+ * @param string  $sql_query SQL statement
+ * @param boolean $is_select select query or not
+ *
+ * @return  array set of parameters
+ *
+ * @access  public
+ */
+function PMA_getDisplayPropertyParams($sql_query, $is_select)
+{
+    $is_explain = $is_count = $is_export = $is_delete = $is_insert = $is_affected = $is_show = $is_maint = $is_analyse = $is_group = $is_func = $is_replace = false;
+
+    if ($is_select) {
+        $is_group = preg_match('@(GROUP[[:space:]]+BY|HAVING|SELECT[[:space:]]+DISTINCT)[[:space:]]+ at i', $sql_query);
+        $is_func =  ! $is_group && (preg_match('@[[:space:]]+(SUM|AVG|STD|STDDEV|MIN|MAX|BIT_OR|BIT_AND)\s*\(@i', $sql_query));
+        $is_count = ! $is_group && (preg_match('@^SELECT[[:space:]]+COUNT\((.*\.+)?.*\)@i', $sql_query));
+        $is_export   = preg_match('@[[:space:]]+INTO[[:space:]]+OUTFILE[[:space:]]+ at i', $sql_query);
+        $is_analyse  = preg_match('@[[:space:]]+PROCEDURE[[:space:]]+ANALYSE at i', $sql_query);
+    } elseif (preg_match('@^EXPLAIN[[:space:]]+ at i', $sql_query)) {
+        $is_explain  = true;
+    } elseif (preg_match('@^DELETE[[:space:]]+ at i', $sql_query)) {
+        $is_delete   = true;
+        $is_affected = true;
+    } elseif (preg_match('@^(INSERT|LOAD[[:space:]]+DATA|REPLACE)[[:space:]]+ at i', $sql_query)) {
+        $is_insert   = true;
+        $is_affected = true;
+        if (preg_match('@^(REPLACE)[[:space:]]+ at i', $sql_query)) {
+            $is_replace = true;
+        }
+    } elseif (preg_match('@^UPDATE[[:space:]]+ at i', $sql_query)) {
+        $is_affected = true;
+    } elseif (preg_match('@^[[:space:]]*SHOW[[:space:]]+ at i', $sql_query)) {
+        $is_show     = true;
+    } elseif (preg_match('@^(CHECK|ANALYZE|REPAIR|OPTIMIZE)[[:space:]]+TABLE[[:space:]]+ at i', $sql_query)) {
+        $is_maint    = true;
+    }
+
+    return array(
+        $is_group, $is_func, $is_count, $is_export, $is_analyse, $is_explain,
+        $is_delete, $is_affected, $is_insert, $is_replace,$is_show, $is_maint
+    );
+}
+
+/**
+ * Get the database name inside a USE query
+ *
+ * @param string $sql       SQL query
+ * @param array  $databases array with all databases
+ *
+ * @return strin $db new database name
+ */
+function PMA_getNewDatabase($sql, $databases)
+{
+    $db = '';
+    // loop through all the databases
+    foreach ($databases as $database) {
+        if (strpos($sql, $database['SCHEMA_NAME']) !== false) {
+            $db = $database;
+            break;
+        }
+    }
+    return $db;
+}
+
+/**
+ * Get the table name in a sql query
+ * If there are several tables in the SQL query,
+ * first table wil lreturn
+ *
+ * @param string $sql    SQL query
+ * @param array  $tables array of names in current database
+ *
+ * @return string $table table name
+ */
+function PMA_getTableNameBySQL($sql, $tables)
+{
+    $table = '';
+
+    // loop through all the tables in the database
+    foreach ($tables as $tbl) {
+        if (strpos($sql, $tbl)) {
+            $table .= ' ' . $tbl;
+        }
+    }
+
+    if (count(explode(' ', trim($table))) > 1) {
+        $tmp_array = explode(' ', trim($table));
+        return $tmp_array[0];
+    }
+
+    return trim($table);
+}
+
+
+/**
+ * Generate table html when SQL statement have multiple queries
+ * which return displayable results
+ *
+ * @param PMA_DisplayResults $displayResultsObject object
+ * @param string             $db                   database name
+ * @param array              $sql_data             information about SQL statement
+ * @param string             $goto                 URL to go back in case of errors
+ * @param string             $pmaThemeImage        path for theme images directory
+ * @param string             $text_dir             text direction
+ * @param string             $printview            whether printview is enabled
+ * @param string             $url_query            URL query
+ * @param array              $disp_mode            the display mode
+ * @param string             $sql_limit_to_append  limit clause
+ * @param bool               $editable             whether result set is editable
+ *
+ * @return string   $table_html   html content
+ */
+function getTableHtmlForMultipleQueries(
+    $displayResultsObject, $db, $sql_data, $goto, $pmaThemeImage,
+    $text_dir, $printview, $url_query, $disp_mode, $sql_limit_to_append,
+    $editable
+) {
+    $table_html = '';
+
+    $tables_array = PMA_DBI_get_tables($db);
+    $databases_array = PMA_DBI_get_databases_full();
+    $multi_sql = implode(";", $sql_data['valid_sql']);
+    $querytime_before = array_sum(explode(' ', microtime()));
+
+    // Assignment for variable is not needed since the results are
+    // looiping using the connection
+    @PMA_DBI_try_multi_query($multi_sql);
+
+    $querytime_after = array_sum(explode(' ', microtime()));
+    $querytime = $querytime_after - $querytime_before;
+    $sql_no = 0;
+
+    do {
+        $analyzed_sql = array();
+        $is_affected = false;
+
+        $result = PMA_DBI_store_result();
+        $fields_meta = ($result !== false)
+            ? PMA_DBI_get_fields_meta($result)
+            : array();
+        $fields_cnt  = count($fields_meta);
+
+        // Initialize needed params related to each query in multiquery statement
+        if (isset($sql_data['valid_sql'][$sql_no])) {
+            // 'Use' query can change the database
+            if (stripos($sql_data['valid_sql'][$sql_no], "use ")) {
+                $db = PMA_getNewDatabase(
+                    $sql_data['valid_sql'][$sql_no],
+                    $databases_array
+                );
+            }
+            $parsed_sql = PMA_SQP_parse($sql_data['valid_sql'][$sql_no]);
+            $table = PMA_getTableNameBySQL(
+                $sql_data['valid_sql'][$sql_no],
+                $tables_array
+            );
+
+            $analyzed_sql = PMA_SQP_analyze($parsed_sql);
+            $is_select = isset($analyzed_sql[0]['queryflags']['select_from']);
+            $unlim_num_rows = PMA_Table::countRecords($db, $table, true);
+            $showtable = PMA_Table::sGetStatusInfo($db, $table, null, true);
+            $url_query = PMA_generate_common_url($db, $table);
+
+            list($is_group, $is_func, $is_count, $is_export, $is_analyse,
+                $is_explain, $is_delete, $is_affected, $is_insert, $is_replace,
+                $is_show, $is_maint)
+                    = PMA_getDisplayPropertyParams(
+                        $sql_data['valid_sql'][$sql_no], $is_select
+                    );
+
+            // Handle remembered sorting order, only for single table query
+            if ($GLOBALS['cfg']['RememberSorting']
+                && ! ($is_count || $is_export || $is_func || $is_analyse)
+                && isset($analyzed_sql[0]['select_expr'])
+                && (count($analyzed_sql[0]['select_expr']) == 0)
+                && isset($analyzed_sql[0]['queryflags']['select_from'])
+                && count($analyzed_sql[0]['table_ref']) == 1
+            ) {
+                PMA_handleSortOrder(
+                    $db,
+                    $table,
+                    $analyzed_sql,
+                    $sql_data['valid_sql'][$sql_no]
+                );
+            }
+
+            // Do append a "LIMIT" clause?
+            if (($_SESSION['tmp_user_values']['max_rows'] != 'all')
+                && ! ($is_count || $is_export || $is_func || $is_analyse)
+                && isset($analyzed_sql[0]['queryflags']['select_from'])
+                && ! isset($analyzed_sql[0]['queryflags']['offset'])
+                && empty($analyzed_sql[0]['limit_clause'])
+            ) {
+                $sql_limit_to_append = ' LIMIT '
+                    . $_SESSION['tmp_user_values']['pos']
+                    . ', ' . $_SESSION['tmp_user_values']['max_rows'] . " ";
+                $sql_data['valid_sql'][$sql_no] = PMA_getSqlWithLimitClause(
+                    $sql_data['valid_sql'][$sql_no],
+                    $analyzed_sql,
+                    $sql_limit_to_append
+                );
+            }
+
+            // Set the needed properties related to executing sql query
+            $displayResultsObject->__set('db', $db);
+            $displayResultsObject->__set('table', $table);
+            $displayResultsObject->__set('goto', $goto);
+        }
+
+        if (! $is_affected) {
+            $num_rows = ($result) ? @PMA_DBI_num_rows($result) : 0;
+        } elseif (! isset($num_rows)) {
+            $num_rows = @PMA_DBI_affected_rows();
+        }
+
+        if (isset($sql_data['valid_sql'][$sql_no])) {
+
+            $displayResultsObject->__set(
+                'sql_query',
+                $sql_data['valid_sql'][$sql_no]
+            );
+            $displayResultsObject->setProperties(
+                $unlim_num_rows, $fields_meta, $is_count, $is_export, $is_func,
+                $is_analyse, $num_rows, $fields_cnt, $querytime, $pmaThemeImage,
+                $text_dir, $is_maint, $is_explain, $is_show, $showtable,
+                $printview, $url_query, $editable
+            );
+        }
+
+        if ($num_rows == 0) {
+            continue;
+        }
+
+        // With multiple results, operations are limied
+        $disp_mode = 'nnnn000000';
+        $is_limited_display = true;
+
+        // Collect the tables
+        $table_html .= $displayResultsObject->getTable(
+            $result, $disp_mode, $analyzed_sql, $is_limited_display
+        );
+
+        // Free the result to save the memory
+        PMA_DBI_free_result($result);
+
+        $sql_no++;
+
+    } while (PMA_DBI_more_results() && PMA_DBI_next_result());
+
+    return $table_html;
+}
+
+/**
+ * Handle remembered sorting order, only for single table query
+ *
+ * @param string $db              database name
+ * @param string $table           table name
+ * @param array  &$analyzed_sql   the analyzed query
+ * @param string &$full_sql_query SQL query
+ *
+ * @return void
+ */
+function PMA_handleSortOrder($db, $table, &$analyzed_sql, &$full_sql_query)
+{
+    $pmatable = new PMA_Table($table, $db);
+    if (empty($analyzed_sql[0]['order_by_clause'])) {
+        $sorted_col = $pmatable->getUiProp(PMA_Table::PROP_SORTED_COLUMN);
+        if ($sorted_col) {
+            // retrieve the remembered sorting order for current table
+            $sql_order_to_append = ' ORDER BY ' . $sorted_col . ' ';
+            $full_sql_query = $analyzed_sql[0]['section_before_limit']
+                . $sql_order_to_append . $analyzed_sql[0]['limit_clause']
+                . ' ' . $analyzed_sql[0]['section_after_limit'];
+
+            // update the $analyzed_sql
+            $analyzed_sql[0]['section_before_limit'] .= $sql_order_to_append;
+            $analyzed_sql[0]['order_by_clause'] = $sorted_col;
+        }
+    } else {
+        // store the remembered table into session
+        $pmatable->setUiProp(
+            PMA_Table::PROP_SORTED_COLUMN,
+            $analyzed_sql[0]['order_by_clause']
+        );
+    }
+}
+
+/**
+ * Append limit clause to SQL query
+ *
+ * @param string $full_sql_query      SQL query
+ * @param array  $analyzed_sql        the analyzed query
+ * @param string $sql_limit_to_append clause to append
+ *
+ * @return string limit clause appended SQL query
+ */
+function PMA_getSqlWithLimitClause($full_sql_query, $analyzed_sql,
+    $sql_limit_to_append
+) {
+    return $analyzed_sql[0]['section_before_limit'] . "\n"
+        . $sql_limit_to_append . $analyzed_sql[0]['section_after_limit'];
+}
+
+
+/**
+ * Get column name from a drop SQL statement
+ *
+ * @param string $sql SQL query
+ *
+ * @return string $drop_column Name of the column
+ */
+function PMA_getColumnNameInColumnDropSql($sql)
+{
+    $tmpArray1 = explode('DROP', $sql);
+    $str_to_check = trim($tmpArray1[1]);
+
+    if (stripos($str_to_check, 'COLUMN') !== false) {
+        $tmpArray2 = explode('COLUMN', $str_to_check);
+        $str_to_check = trim($tmpArray2[1]);
+    }
+
+    $tmpArray3 = explode(' ', $str_to_check);
+    $str_to_check = trim($tmpArray3[0]);
+
+    $drop_column = str_replace(';', '', trim($str_to_check));
+    $drop_column = str_replace('`', '', $drop_column);
+
+    return $drop_column;
+}
+
+/**
+ * Verify whether the result set contains all the columns 
+ * of at least one unique key
+ *
+ * @param string $db          database name
+ * @param string $table       table name
+ * @param string $fields_meta meta fields
+ *
+ * @return boolean whether the result set contains a unique key
+ */
+function PMA_resultSetContainsUniqueKey($db, $table, $fields_meta)
+{
+    $resultSetColumnNames = array();
+    foreach ($fields_meta as $oneMeta) {
+        $resultSetColumnNames[] = $oneMeta->name;
+    }
+    foreach (PMA_Index::getFromTable($table, $db) as $index) {
+        if ($index->isUnique()) {
+            $indexColumns = $index->getColumns();
+            $numberFound = 0;
+            foreach ($indexColumns as $indexColumnName => $dummy) {
+                if (in_array($indexColumnName, $resultSetColumnNames)) {
+                    $numberFound++;
+                }
+            }
+            if ($numberFound == count($indexColumns)) {
+                return true;
+            }
+        }
+    }
+    return false;
+}
+
+?>
diff --git a/phpmyadmin/tbl_addfield.php b/phpmyadmin/tbl_addfield.php
new file mode 100644
index 0000000..3d5f085
--- /dev/null
+++ b/phpmyadmin/tbl_addfield.php
@@ -0,0 +1,250 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ *
+ * @package PhpMyAdmin
+ */
+
+/**
+ * Get some core libraries
+ */
+require_once 'libraries/common.inc.php';
+
+$response = PMA_Response::getInstance();
+$header   = $response->getHeader();
+$scripts  = $header->getScripts();
+$scripts->addFile('tbl_structure.js');
+
+// Check parameters
+PMA_Util::checkParameters(array('db', 'table'));
+
+
+/**
+ * Defines the url to return to in case of error in a sql statement
+ */
+$err_url = 'tbl_sql.php?' . PMA_generate_common_url($db, $table);
+
+/**
+ * The form used to define the field to add has been submitted
+ */
+$abort = false;
+
+// check number of fields to be created
+if (isset($_REQUEST['submit_num_fields'])) {
+    if (isset($_REQUEST['orig_after_field'])) {
+        $_REQUEST['after_field'] = $_REQUEST['orig_after_field'];
+    }
+    if (isset($_REQUEST['orig_field_where'])) {
+        $_REQUEST['field_where'] = $_REQUEST['orig_field_where'];
+    }
+    $num_fields = $_REQUEST['orig_num_fields'] + $_REQUEST['added_fields'];
+    $regenerate = true;
+} elseif (isset($_REQUEST['num_fields']) && intval($_REQUEST['num_fields']) > 0) {
+    $num_fields = (int) $_REQUEST['num_fields'];
+} else {
+    $num_fields = 1;
+}
+
+if (isset($_REQUEST['do_save_data'])) {
+    //avoid an incorrect calling of PMA_updateColumns() via
+    //tbl_structure.php below
+    unset($_REQUEST['do_save_data']);
+
+    $query = '';
+    $definitions = array();
+
+    // Transforms the radio button field_key into 3 arrays
+    $field_cnt      = count($_REQUEST['field_name']);
+    $field_primary  = array();
+    $field_index    = array();
+    $field_unique   = array();
+    $field_fulltext = array();
+    for ($i = 0; $i < $field_cnt; ++$i) {
+        if (isset($_REQUEST['field_key'][$i])
+            && strlen($_REQUEST['field_name'][$i])
+        ) {
+            if ($_REQUEST['field_key'][$i] == 'primary_' . $i) {
+                $field_primary[] = $i;
+            }
+            if ($_REQUEST['field_key'][$i] == 'index_' . $i) {
+                $field_index[]   = $i;
+            }
+            if ($_REQUEST['field_key'][$i] == 'unique_' . $i) {
+                $field_unique[]  = $i;
+            }
+            if ($_REQUEST['field_key'][$i] == 'fulltext_' . $i) {
+                $field_fulltext[]  = $i;
+            }
+        } // end if
+    } // end for
+
+    // Builds the field creation statement and alters the table
+    for ($i = 0; $i < $field_cnt; ++$i) {
+        // '0' is also empty for php :-(
+        if (empty($_REQUEST['field_name'][$i]) && $_REQUEST['field_name'][$i] != '0') {
+            continue;
+        }
+
+        $definition = ' ADD ' . PMA_Table::generateFieldSpec(
+            $_REQUEST['field_name'][$i],
+            $_REQUEST['field_type'][$i],
+            $i,
+            $_REQUEST['field_length'][$i],
+            $_REQUEST['field_attribute'][$i],
+            isset($_REQUEST['field_collation'][$i])
+                ? $_REQUEST['field_collation'][$i]
+                : '',
+            isset($_REQUEST['field_null'][$i])
+                ? $_REQUEST['field_null'][$i]
+                : 'NOT NULL',
+            $_REQUEST['field_default_type'][$i],
+            $_REQUEST['field_default_value'][$i],
+            isset($_REQUEST['field_extra'][$i])
+                ? $_REQUEST['field_extra'][$i]
+                : false,
+            isset($_REQUEST['field_comments'][$i])
+                ? $_REQUEST['field_comments'][$i]
+                : '',
+            $field_primary
+        );
+
+        if ($_REQUEST['field_where'] != 'last') {
+            // Only the first field can be added somewhere other than at the end
+            if ($i == 0) {
+                if ($_REQUEST['field_where'] == 'first') {
+                    $definition .= ' FIRST';
+                } else {
+                    $definition .= ' AFTER ' . PMA_Util::backquote($_REQUEST['after_field']);
+                }
+            } else {
+                $definition .= ' AFTER ' . PMA_Util::backquote($_REQUEST['field_name'][$i-1]);
+            }
+        }
+        $definitions[] = $definition;
+    } // end for
+
+    // Builds the primary keys statements and updates the table
+    if (count($field_primary)) {
+        $fields = array();
+        foreach ($field_primary as $field_nr) {
+            $fields[] = PMA_Util::backquote($_REQUEST['field_name'][$field_nr]);
+        }
+        $definitions[] = ' ADD PRIMARY KEY (' . implode(', ', $fields) . ') ';
+        unset($fields);
+    }
+
+    // Builds the indexes statements and updates the table
+    if (count($field_index)) {
+        $fields = array();
+        foreach ($field_index as $field_nr) {
+            $fields[] = PMA_Util::backquote($_REQUEST['field_name'][$field_nr]);
+        }
+        $definitions[] = ' ADD INDEX (' . implode(', ', $fields) . ') ';
+        unset($fields);
+    }
+
+    // Builds the uniques statements and updates the table
+    if (count($field_unique)) {
+        $fields = array();
+        foreach ($field_unique as $field_nr) {
+            $fields[] = PMA_Util::backquote($_REQUEST['field_name'][$field_nr]);
+        }
+        $definitions[] = ' ADD UNIQUE (' . implode(', ', $fields) . ') ';
+        unset($fields);
+    }
+
+    // Builds the fulltext statements and updates the table
+    if (count($field_fulltext)) {
+        $fields = array();
+        foreach ($field_fulltext as $field_nr) {
+            $fields[] = PMA_Util::backquote($_REQUEST['field_name'][$field_nr]);
+        }
+        $definitions[] = ' ADD FULLTEXT (' . implode(', ', $fields) . ') ';
+        unset($fields);
+    }
+
+    // To allow replication, we first select the db to use and then run queries
+    // on this db.
+    PMA_DBI_select_db($db) or PMA_Util::mysqlDie(PMA_DBI_getError(), 'USE ' . PMA_Util::backquote($db), '', $err_url);
+    $sql_query    = 'ALTER TABLE ' . PMA_Util::backquote($table) . ' ' . implode(', ', $definitions) . ';';
+    $result = PMA_DBI_try_query($sql_query);
+
+    if ($result === true) {
+        // If comments were sent, enable relation stuff
+        include_once 'libraries/transformations.lib.php';
+
+        // Update comment table for mime types [MIME]
+        if (isset($_REQUEST['field_mimetype'])
+            && is_array($_REQUEST['field_mimetype'])
+            && $cfg['BrowseMIME']
+        ) {
+            foreach ($_REQUEST['field_mimetype'] as $fieldindex => $mimetype) {
+                if (isset($_REQUEST['field_name'][$fieldindex])
+                    && strlen($_REQUEST['field_name'][$fieldindex])
+                ) {
+                    PMA_setMIME(
+                        $db, $table,
+                        $_REQUEST['field_name'][$fieldindex],
+                        $mimetype,
+                        $_REQUEST['field_transformation'][$fieldindex],
+                        $_REQUEST['field_transformation_options'][$fieldindex]
+                    );
+                }
+            }
+        }
+
+        // Go back to the structure sub-page
+        $message = PMA_Message::success(__('Table %1$s has been altered successfully'));
+        $message->addParam($table);
+
+        if ($GLOBALS['is_ajax_request'] == true) {
+            $response->addJSON('message', $message);
+            $response->addJSON(
+                'sql_query',
+                PMA_Util::getMessage(null, $sql_query)
+            );
+            exit;
+        }
+
+        $active_page = 'tbl_structure.php';
+        $abort = true;
+        include 'tbl_structure.php';
+    } else {
+        $error_message_html = PMA_Util::mysqlDie('', '', '', $err_url, false);
+        $response->addHTML($error_message_html);
+        if ($GLOBALS['is_ajax_request'] == true) {
+            exit;
+        }
+        // An error happened while inserting/updating a table definition.
+        // to prevent total loss of that data, we embed the form once again.
+        // The variable $regenerate will be used to restore data in libraries/tbl_columns_definition_form.inc.php
+        $num_fields = $_REQUEST['orig_num_fields'];
+        if (isset($_REQUEST['orig_after_field'])) {
+            $_REQUEST['after_field'] = $_REQUEST['orig_after_field'];
+        }
+        if (isset($_REQUEST['orig_field_where'])) {
+            $_REQUEST['field_where'] = $_REQUEST['orig_field_where'];
+        }
+        $regenerate = true;
+    }
+} // end do alter table
+
+/**
+ * Displays the form used to define the new field
+ */
+if ($abort == false) {
+    /**
+     * Gets tables informations
+     */
+    include_once 'libraries/tbl_common.inc.php';
+    include_once 'libraries/tbl_info.inc.php';
+
+    $active_page = 'tbl_structure.php';
+    /**
+     * Display the form
+     */
+    $action = 'tbl_addfield.php';
+    include_once 'libraries/tbl_columns_definition_form.inc.php';
+}
+
+?>
diff --git a/phpmyadmin/tbl_change.php b/phpmyadmin/tbl_change.php
new file mode 100644
index 0000000..795eaee
--- /dev/null
+++ b/phpmyadmin/tbl_change.php
@@ -0,0 +1,437 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * Displays form for editing and inserting new table rows
+ *
+ * register_globals_save (mark this file save for disabling register globals)
+ *
+ * @package PhpMyAdmin
+ */
+
+/**
+ * Gets the variables sent or posted to this script and displays the header
+ */
+require_once 'libraries/common.inc.php';
+
+/**
+ * Ensures db and table are valid, else moves to the "parent" script
+ */
+require_once 'libraries/db_table_exists.lib.php';
+
+/**
+ * functions implementation for this script
+ */
+require_once 'libraries/insert_edit.lib.php';
+
+/**
+ * Sets global variables.
+ * Here it's better to use a if, instead of the '?' operator
+ * to avoid setting a variable to '' when it's not present in $_REQUEST
+ */
+
+if (isset($_REQUEST['where_clause'])) {
+    $where_clause = $_REQUEST['where_clause'];
+}
+if (isset($_SESSION['edit_next'])) {
+    $where_clause = $_SESSION['edit_next'];
+    unset($_SESSION['edit_next']);
+    $after_insert = 'edit_next';
+}
+if (isset($_REQUEST['ShowFunctionFields'])) {
+    $cfg['ShowFunctionFields'] = $_REQUEST['ShowFunctionFields'];
+}
+if (isset($_REQUEST['ShowFieldTypesInDataEditView'])) {
+    $cfg['ShowFieldTypesInDataEditView'] = $_REQUEST['ShowFieldTypesInDataEditView'];
+}
+if (isset($_REQUEST['after_insert'])) {
+    $after_insert = $_REQUEST['after_insert'];
+}
+/**
+ * file listing
+ */
+require_once 'libraries/file_listing.lib.php';
+
+
+/**
+ * Defines the url to return to in case of error in a sql statement
+ * (at this point, $GLOBALS['goto'] will be set but could be empty)
+ */
+if (empty($GLOBALS['goto'])) {
+    if (strlen($table)) {
+        // avoid a problem (see bug #2202709)
+        $GLOBALS['goto'] = 'tbl_sql.php';
+    } else {
+        $GLOBALS['goto'] = 'db_sql.php';
+    }
+}
+/**
+ * @todo check if we could replace by "db_|tbl_" - please clarify!?
+ */
+$_url_params = array(
+    'db' => $db,
+    'sql_query' => $_REQUEST['sql_query']
+);
+
+if (preg_match('@^tbl_@', $GLOBALS['goto'])) {
+    $_url_params['table'] = $table;
+}
+
+$err_url = $GLOBALS['goto'] . PMA_generate_common_url($_url_params);
+unset($_url_params);
+
+
+/**
+ * Sets parameters for links
+ * where is this variable used?
+ * replace by PMA_generate_common_url($url_params);
+ */
+$url_query = PMA_generate_common_url($url_params, 'html', '');
+
+/**
+ * get table information
+ * @todo should be done by a Table object
+ */
+require_once 'libraries/tbl_info.inc.php';
+
+/**
+ * Get comments for table fileds/columns
+ */
+$comments_map = array();
+
+if ($GLOBALS['cfg']['ShowPropertyComments']) {
+    $comments_map = PMA_getComments($db, $table);
+}
+
+/**
+ * START REGULAR OUTPUT
+ */
+
+/**
+ * Load JavaScript files
+ */
+$response = PMA_Response::getInstance();
+$header   = $response->getHeader();
+$scripts  = $header->getScripts();
+$scripts->addFile('functions.js');
+$scripts->addFile('tbl_change.js');
+$scripts->addFile('jquery/jquery-ui-timepicker-addon.js');
+$scripts->addFile('gis_data_editor.js');
+
+/**
+ * Displays the query submitted and its result
+ *
+ * @todo where does $disp_message and $disp_query come from???
+ */
+if (! empty($disp_message)) {
+    if (! isset($disp_query)) {
+        $disp_query     = null;
+    }
+    $response->addHTML(PMA_Util::getMessage($disp_message, $disp_query));
+}
+
+/**
+ * Get the analysis of SHOW CREATE TABLE for this table
+ */
+$analyzed_sql = PMA_Table::analyzeStructure($db, $table);
+
+/**
+ * Get the list of the fields of the current table
+ */
+PMA_DBI_select_db($db);
+$table_fields = array_values(PMA_DBI_get_columns($db, $table));
+
+$paramTableDbArray = array($table, $db);
+
+/**
+ * Determine what to do, edit or insert? 
+ */
+if (isset($where_clause)) {
+    // we are editing
+    $insert_mode = false;
+    $where_clause_array = PMA_getWhereClauseArray($where_clause);
+    list($where_clauses, $result, $rows, $found_unique_key)
+        = PMA_analyzeWhereClauses($where_clause_array, $table, $db);
+} else {
+    // we are inserting
+    $insert_mode = true;
+    $where_clause = null;
+    list($result, $rows) = PMA_loadFirstRow($table, $db);
+    $where_clauses = null;
+    $where_clause_array = null;
+    $found_unique_key = false;
+}
+
+// Copying a row - fetched data will be inserted as a new row,
+// therefore the where clause is needless.
+if (isset($_REQUEST['default_action']) && $_REQUEST['default_action'] === 'insert') {
+    $where_clause = $where_clauses = null;
+}
+
+// retrieve keys into foreign fields, if any
+$foreigners = PMA_getForeigners($db, $table);
+
+// Retrieve form parameters for insert/edit form
+$_form_params = PMA_getFormParametersForInsertForm(
+    $db, $table, $where_clauses, $where_clause_array, $err_url
+);
+
+/**
+ * Displays the form
+ */
+// autocomplete feature of IE kills the "onchange" event handler and it
+//        must be replaced by the "onpropertychange" one in this case
+$chg_evt_handler = (PMA_USR_BROWSER_AGENT == 'IE'
+    && PMA_USR_BROWSER_VER >= 5
+    && PMA_USR_BROWSER_VER < 7
+)
+     ? 'onpropertychange'
+     : 'onchange';
+// Had to put the URI because when hosted on an https server,
+// some browsers send wrongly this form to the http server.
+
+$html_output = '';
+// Set if we passed the first timestamp field
+$timestamp_seen = false;
+$columns_cnt     = count($table_fields);
+
+$tabindex              = 0;
+$tabindex_for_function = +3000;
+$tabindex_for_null     = +6000;
+$tabindex_for_value    = 0;
+$o_rows                = 0;
+$biggest_max_file_size = 0;
+
+$url_params['db'] = $db;
+$url_params['table'] = $table;
+$url_params = PMA_urlParamsInEditMode(
+    $url_params, $where_clause_array, $where_clause
+);
+
+//Insert/Edit form
+//If table has blob fields we have to disable ajax.
+$has_blob_field = false;
+foreach ($table_fields as $column) {
+    if (PMA_isColumnBlob($column)) {
+        $has_blob_field = true;
+        break;
+    }
+}
+$html_output .='<form id="insertForm" ';
+if ($has_blob_field && $is_upload) {
+    $html_output .='class="disableAjax" ';
+}
+$html_output .='method="post" action="tbl_replace.php" name="insertForm" ';
+if ($is_upload) {
+    $html_output .= ' enctype="multipart/form-data"';
+}
+$html_output .= '>';
+$html_output .= PMA_generate_common_hidden_inputs($_form_params);
+
+$titles['Browse'] = PMA_Util::getIcon('b_browse.png', __('Browse foreign values'));
+
+// user can toggle the display of Function column and column types
+// (currently does not work for multi-edits)
+if (! $cfg['ShowFunctionFields'] || ! $cfg['ShowFieldTypesInDataEditView']) {
+    $html_output .= __('Show');
+}
+
+if (! $cfg['ShowFunctionFields']) {
+    $html_output .= PMA_showFunctionFieldsInEditMode($url_params, false);
+}
+
+if (! $cfg['ShowFieldTypesInDataEditView']) {
+    $html_output .= PMA_showColumnTypesInDataEditView($url_params, false);
+}
+
+foreach ($rows as $row_id => $current_row) {
+    if ($current_row === false) {
+        unset($current_row);
+    }
+
+    $jsvkey = $row_id;
+    $rownumber_param = '&rownumber=' . $row_id;
+    $vkey = '[multi_edit][' . $jsvkey . ']';
+
+    $current_result = (isset($result) && is_array($result) && isset($result[$row_id])
+        ? $result[$row_id]
+        : $result);
+    if ($insert_mode && $row_id > 0) {
+        $html_output .= '<input type="checkbox" checked="checked"'
+            . ' name="insert_ignore_' . $row_id . '"'
+            . ' id="insert_ignore_' . $row_id . '" />'
+            .'<label for="insert_ignore_' . $row_id . '">'
+            . __('Ignore')
+            . '</label><br />' . "\n";
+    }
+
+    $html_output .= PMA_getHeadAndFootOfInsertRowTable($url_params)
+        . '<tbody>';
+
+    // Sets a multiplier used for input-field counts
+    // (as zero cannot be used, advance the counter plus one)
+    $m_rows = $o_rows + 1;
+    //store the default value for CharEditing
+    $default_char_editing  = $cfg['CharEditing'];
+
+    $odd_row = true;
+    for ($i = 0; $i < $columns_cnt; $i++) {
+        if (! isset($table_fields[$i]['processed'])) {
+            $column = $table_fields[$i];
+            $column = PMA_analyzeTableColumnsArray(
+                $column, $comments_map, $timestamp_seen
+            );
+        }
+
+        $extracted_columnspec
+            = PMA_Util::extractColumnSpec($column['Type']);
+
+        if (-1 === $column['len']) {
+            $column['len'] = PMA_DBI_field_len($current_result, $i);
+            // length is unknown for geometry fields,
+            // make enough space to edit very simple WKTs
+            if (-1 === $column['len']) {
+                $column['len'] = 30;
+            }
+        }
+        //Call validation when the form submited...
+        $unnullify_trigger = $chg_evt_handler
+            . "=\"return verificationsAfterFieldChange('"
+            . PMA_escapeJsString($column['Field_md5']) . "', '"
+            . PMA_escapeJsString($jsvkey) . "','".$column['pma_type'] . "')\"";
+
+        // Use an MD5 as an array index to avoid having special characters
+        // in the name atttibute (see bug #1746964 )
+        $column_name_appendix = $vkey . '[' . $column['Field_md5'] . ']';
+
+        if ($column['Type'] == 'datetime'
+            && ! isset($column['Default'])
+            && ! is_null($column['Default'])
+            && ($insert_mode || ! isset($current_row[$column['Field']]))
+        ) {
+            // INSERT case or
+            // UPDATE case with an NULL value
+            $current_row[$column['Field']] = date('Y-m-d H:i:s', time());
+        }
+
+        $html_output .= '<tr class="noclick ' . ($odd_row ? 'odd' : 'even' ) . '">'
+            . '<td ' . ($cfg['LongtextDoubleTextarea'] && strstr($column['True_Type'], 'longtext') ? 'rowspan="2"' : '') . 'class="center">'
+            . $column['Field_title']
+            . '<input type="hidden" name="fields_name' . $column_name_appendix . '" value="' . $column['Field_html'] . '"/>'
+            . '</td>';
+        if ($cfg['ShowFieldTypesInDataEditView']) {
+             $html_output .= '<td class="center' . $column['wrap'] . '">'
+                . '<span class="column_type">' . $column['pma_type'] . '</span>'
+                . '</td>';
+        } //End if
+
+        // Get a list of GIS data types.
+        $gis_data_types = PMA_Util::getGISDatatypes();
+
+        // Prepares the field value
+        $real_null_value = false;
+        $special_chars_encoded = '';
+        if (isset($current_row)) {
+            // (we are editing)
+            list(
+                $real_null_value, $special_chars_encoded, $special_chars,
+                $data, $backup_field
+            )
+                = PMA_getSpecialCharsAndBackupFieldForExistingRow(
+                    $current_row, $column, $extracted_columnspec,
+                    $real_null_value, $gis_data_types, $column_name_appendix
+                );
+        } else {
+            // (we are inserting)
+            // display default values
+            list($real_null_value, $data, $special_chars, $backup_field, $special_chars_encoded)
+                = PMA_getSpecialCharsAndBackupFieldForInsertingMode($column, $real_null_value);
+        }
+
+        $idindex = ($o_rows * $columns_cnt) + $i + 1;
+        $tabindex = $idindex;
+
+        // Get a list of data types that are not yet supported.
+        $no_support_types = PMA_Util::unsupportedDatatypes();
+
+        // The function column
+        // -------------------
+        if ($cfg['ShowFunctionFields']) {
+            $html_output .= PMA_getFunctionColumn(
+                $column, $is_upload, $column_name_appendix,
+                $unnullify_trigger, $no_support_types, $tabindex_for_function,
+                $tabindex, $idindex, $insert_mode
+            );
+        }
+
+        // The null column
+        // ---------------
+        $foreignData = PMA_getForeignData(
+            $foreigners, $column['Field'], false, '', ''
+        );
+        $html_output .= PMA_getNullColumn(
+            $column, $column_name_appendix, $real_null_value,
+            $tabindex, $tabindex_for_null, $idindex, $vkey, $foreigners,
+            $foreignData
+        );
+
+        // The value column (depends on type)
+        // ----------------
+        // See bug #1667887 for the reason why we don't use the maxlength
+        // HTML attribute
+        $html_output .= '        <td>' . "\n";
+        // Will be used by js/tbl_change.js to set the default value
+        // for the "Continue insertion" feature
+        $html_output .= '<span class="default_value hide">'
+            . $special_chars . '</span>';
+
+        $html_output .= PMA_getValueColumn(
+            $column, $backup_field, $column_name_appendix, $unnullify_trigger,
+            $tabindex, $tabindex_for_value, $idindex, $data, $special_chars,
+            $foreignData, $odd_row, $paramTableDbArray, $rownumber_param, $titles,
+            $text_dir, $special_chars_encoded, $vkey, $is_upload,
+            $biggest_max_file_size, $default_char_editing,
+            $no_support_types, $gis_data_types, $extracted_columnspec
+        );
+
+        $html_output .= '</td>'
+        . '</tr>';
+
+        $odd_row = !$odd_row;
+    } // end for
+    $o_rows++;
+    $html_output .= '  </tbody>'
+        . '</table><br />';
+} // end foreach on multi-edit
+
+$html_output .='<div id="gis_editor"></div>'
+    . '<div id="popup_background"></div>'
+    . '<br />';
+
+if (! isset($after_insert)) {
+    $after_insert = 'back';
+}
+
+//action panel
+$html_output .= PMA_getActionsPanel(
+    $where_clause, $after_insert, $tabindex,
+    $tabindex_for_value, $found_unique_key
+);
+
+if ($biggest_max_file_size > 0) {
+    $html_output .= '        '
+        . PMA_Util::generateHiddenMaxFileSize(
+            $biggest_max_file_size
+        ) . "\n";
+}
+$html_output .= '</form>';
+// end Insert/Edit form
+
+if ($insert_mode) {
+    //Continue insertion form
+    $html_output .= PMA_getContinueInsertionForm(
+        $table, $db, $where_clause_array, $err_url
+    );
+}
+$response->addHTML($html_output);
+
+?>
diff --git a/phpmyadmin/tbl_chart.php b/phpmyadmin/tbl_chart.php
new file mode 100644
index 0000000..6cba7dd
--- /dev/null
+++ b/phpmyadmin/tbl_chart.php
@@ -0,0 +1,266 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * handles creation of the chart
+ *
+ * @package PhpMyAdmin
+ */
+
+require_once 'libraries/common.inc.php';
+
+/*
+ * Execute the query and return the result
+ */
+if (isset($_REQUEST['ajax_request'])
+    && isset($_REQUEST['pos'])
+    && isset($_REQUEST['session_max_rows'])
+) {
+    $response = PMA_Response::getInstance();
+
+    if (strlen($GLOBALS['table']) && strlen($GLOBALS['db'])) {
+        include './libraries/tbl_common.inc.php';
+    } else {
+        $response->isSuccess(false);
+        $response->addJSON('message', __('Error'));
+        exit;
+    }
+
+    $sql_with_limit = 'SELECT * FROM( ' . $sql_query . ' ) AS `temp_res` LIMIT '
+        . $_REQUEST['pos'] . ', ' . $_REQUEST['session_max_rows'];
+    $data = array();
+    $result = PMA_DBI_try_query($sql_with_limit);
+    while ($row = PMA_DBI_fetch_assoc($result)) {
+        $data[] = $row;
+    }
+
+    if (empty($data)) {
+        $response->isSuccess(false);
+        $response->addJSON('message', __('No data to display'));
+        exit;
+    }
+    $sanitized_data = array();
+
+    foreach ($data as $data_row_number => $data_row) {
+        $tmp_row = array();
+        foreach ($data_row as $data_column => $data_value) {
+            $tmp_row[htmlspecialchars($data_column)] = htmlspecialchars($data_value);
+        }
+        $sanitized_data[] = $tmp_row;
+    }
+    $response->isSuccess(true);
+    $response->addJSON('message', null);
+    $response->addJSON('chartData', json_encode($sanitized_data));
+    unset($sanitized_data);
+    exit;
+}
+
+$response = PMA_Response::getInstance();
+// Throw error if no sql query is set
+if (! isset($sql_query) || $sql_query == '') {
+    $response->isSuccess(false);
+    $response->addHTML(
+        PMA_Message::error(__('No SQL query was set to fetch data.'))
+    );
+    exit;
+}
+$header   = $response->getHeader();
+$scripts  = $header->getScripts();
+$scripts->addFile('chart.js');
+$scripts->addFile('tbl_chart.js');
+$scripts->addFile('jqplot/jquery.jqplot.js');
+$scripts->addFile('jqplot/plugins/jqplot.barRenderer.js');
+$scripts->addFile('jqplot/plugins/jqplot.canvasAxisLabelRenderer.js');
+$scripts->addFile('jqplot/plugins/jqplot.canvasTextRenderer.js');
+$scripts->addFile('jqplot/plugins/jqplot.categoryAxisRenderer.js');
+$scripts->addFile('jqplot/plugins/jqplot.dateAxisRenderer.js');
+$scripts->addFile('jqplot/plugins/jqplot.pointLabels.js');
+$scripts->addFile('jqplot/plugins/jqplot.pieRenderer.js');
+$scripts->addFile('jqplot/plugins/jqplot.highlighter.js');
+/* < IE 9 doesn't support canvas natively */
+if (PMA_USR_BROWSER_AGENT == 'IE' && PMA_USR_BROWSER_VER < 9) {
+    $scripts->addFile('canvg/flashcanvas.js');
+}
+
+/**
+ * Runs common work
+ */
+if (strlen($GLOBALS['table'])) {
+    $url_params['goto'] = $cfg['DefaultTabTable'];
+    $url_params['back'] = 'tbl_sql.php';
+    include 'libraries/tbl_common.inc.php';
+    include 'libraries/tbl_info.inc.php';
+} elseif (strlen($GLOBALS['db'])) {
+    $url_params['goto'] = $cfg['DefaultTabDatabase'];
+    $url_params['back'] = 'sql.php';
+    include 'libraries/db_common.inc.php';
+    include 'libraries/db_info.inc.php';
+} else {
+    $url_params['goto'] = $cfg['DefaultTabServer'];
+    $url_params['back'] = 'sql.php';
+    include 'libraries/server_common.inc.php';
+}
+
+$data = array();
+
+$result = PMA_DBI_try_query($sql_query);
+$fields_meta = PMA_DBI_get_fields_meta($result);
+while ($row = PMA_DBI_fetch_assoc($result)) {
+    $data[] = $row;
+}
+
+$keys = array_keys($data[0]);
+
+$numeric_types = array('int', 'real');
+$numeric_column_count = 0;
+foreach ($keys as $idx => $key) {
+    if (in_array($fields_meta[$idx]->type, $numeric_types)) {
+        $numeric_column_count++;
+    }
+}
+if ($numeric_column_count == 0) {
+    $response->isSuccess(false);
+    $response->addJSON(
+        'message',
+        __('No numeric columns present in the table to plot.')
+    );
+    exit;
+}
+
+// get settings if any posted
+$chartSettings = array();
+if (PMA_isValid($_REQUEST['chartSettings'], 'array')) {
+    $chartSettings = $_REQUEST['chartSettings'];
+}
+
+$url_params['db'] = $GLOBALS['db'];
+$url_params['reload'] = 1;
+
+/**
+ * Displays the page
+ */
+// pma_token/url_query needed for chart export
+$htmlString = '<script type="text/javascript">'
+    . "pma_token = '" . $_SESSION[' PMA_token '] . "';"
+    . "url_query = '" . $url_query . "';"
+    . '</script>'
+    . '<!-- Display Chart options -->'
+    . '<div id="div_view_options">'
+    . '<form method="post" id="tblchartform" action="tbl_chart.php" class="ajax">'
+    . PMA_generate_common_hidden_inputs($url_params)
+    . '<fieldset>'
+    . '<legend>' . __('Display chart') . '</legend>'
+    . '<div style="float:left; width:420px;">'
+    . '<input type="radio" name="chartType" value="bar" id="radio_bar" />'
+    . '<label for ="radio_bar">' . _pgettext('Chart type', 'Bar') . '</label>'
+    . '<input type="radio" name="chartType" value="column" id="radio_column" />'
+    . '<label for ="radio_column">' . _pgettext('Chart type', 'Column') . '</label>'
+    . '<input type="radio" name="chartType" value="line" id="radio_line"'
+    . ' checked="checked" />'
+    . '<label for ="radio_line">' . _pgettext('Chart type', 'Line') . '</label>'
+    . '<input type="radio" name="chartType" value="spline" id="radio_spline" />'
+    . '<label for ="radio_spline">' . _pgettext('Chart type', 'Spline') . '</label>'
+    . '<input type="radio" name="chartType" value="area" id="radio_area" />'
+    . '<label for ="radio_area">' . _pgettext('Chart type', 'Area') . '</label>'
+    . '<span class="span_pie" style="display:none;">'
+    . '<input type="radio" name="chartType" value="pie" id="radio_pie" />'
+    . '<label for ="radio_pie">' . _pgettext('Chart type', 'Pie') . '</label>'
+    . '</span>'
+    . '<span class="span_timeline" style="display:none;">'
+    . '<input type="radio" name="chartType" value="timeline" id="radio_timeline" />'
+    . '<label for ="radio_timeline">' . _pgettext('Chart type', 'Timeline')
+    . '</label>'
+    . '</span>'
+    . '<br /><br />'
+    . '<span class="barStacked">'
+    . '<input type="checkbox" name="barStacked" value="1"'
+    . ' id="checkbox_barStacked" />'
+    . '<label for ="checkbox_barStacked">' . __('Stacked') . '</label>'
+    . '</span>'
+    . '<br /><br />'
+    . '<input type="text" name="chartTitle" value="' . __('Chart title') . '">'
+    . '</div>';
+
+$htmlString .= '<div style="float:left; padding-left:40px;">'
+    . '<label for="select_chartXAxis">' .  __('X-Axis:') . '</label>'
+    . '<select name="chartXAxis" id="select_chartXAxis">';
+
+$yaxis = null;
+foreach ($keys as $idx => $key) {
+    if ($yaxis === null) {
+        $htmlString .= '<option value="' . htmlspecialchars($idx)
+            . '" selected="selected">' . htmlspecialchars($key) . '</option>';
+        $yaxis = $idx;
+    } else {
+        $htmlString .= '<option value="' . htmlspecialchars($idx) . '">'
+            . htmlspecialchars($key) . '</option>';
+    }
+}
+
+$htmlString .= '</select><br />'
+    . '<label for="select_chartSeries">' . __('Series:') . '</label>'
+    . '<select name="chartSeries" id="select_chartSeries" multiple="multiple">';
+
+foreach ($keys as $idx => $key) {
+    if (in_array($fields_meta[$idx]->type, $numeric_types)) {
+        if ($idx == $yaxis && $numeric_column_count > 1) {
+            $htmlString .= '<option value="' . htmlspecialchars($idx) . '">'
+                . htmlspecialchars($key) . '</option>';
+        } else {
+            $htmlString .= '<option value="' . htmlspecialchars($idx)
+                . '" selected="selected">' . htmlspecialchars($key)
+                . '</option>';
+        }
+    }
+}
+
+$htmlString .= '</select>'
+    . '<input type="hidden" name="dateTimeCols" value="';
+
+$date_time_types = array('date', 'datetime', 'timestamp');
+foreach ($keys as $idx => $key) {
+    if (in_array($fields_meta[$idx]->type, $date_time_types)) {
+        $htmlString .= $idx . " ";
+    }
+}
+$htmlString .= '" />'
+    . '</div>';
+
+$htmlString .= '<div style="float:left; padding-left:40px;">'
+    . '<label for="xaxis_label">' . __('X-Axis label:') . '</label>'
+    . '<input style="margin-top:0;" type="text" name="xaxis_label" id="xaxis_label"'
+    . ' value="'
+    . (($yaxis == -1) ? __('X Values') : htmlspecialchars($keys[$yaxis]))
+    . '" /><br />'
+    . '<label for="yaxis_label">' . __('Y-Axis label:') . '</label>'
+    . '<input type="text" name="yaxis_label" id="yaxis_label" value="'
+    . __('Y Values') . '" /><br />'
+    . '</div>'
+    . '<p style="clear:both;"> </p>'
+    . '<fieldset>'
+    . '<div>'
+    . '<label for="pos">' . __('Start row') . ': ' . "\n" . '</label>'
+    . '<input type="text" name="pos" size="3" value="'
+    . $_SESSION['tmp_user_values']['pos'] . '" />'
+    . '<label for="session_max_rows">'
+    . __('Number of rows') . ': ' . "\n" . '</label>'
+    . '<input type="text" name="session_max_rows" size="3" value="'
+    . (($_SESSION['tmp_user_values']['max_rows'] != 'all')
+        ? $_SESSION['tmp_user_values']['max_rows']
+        : $GLOBALS['cfg']['MaxRows'])
+    . '" />'
+    . '<input type="submit" name="submit" class="Go" value="' . __('Go') . '" />'
+    . '<input type="hidden" name="sql_query" value="'
+    . htmlspecialchars($sql_query) . '" />'
+    . '</div>'
+    . '</fieldset>'
+    . '<p style="clear:both;"> </p>'
+    . '<div id="resizer" style="width:600px; height:400px;">'
+    . '<div id="querychart">'
+    . '</div>'
+    . '</div>'
+    . '</fieldset>'
+    . '</form>'
+    . '</div>';
+
+$response->addHTML($htmlString);
+?>
diff --git a/phpmyadmin/tbl_create.php b/phpmyadmin/tbl_create.php
new file mode 100644
index 0000000..bc6524e
--- /dev/null
+++ b/phpmyadmin/tbl_create.php
@@ -0,0 +1,450 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * @package PhpMyAdmin
+ */
+
+/**
+ * Get some core libraries
+ */
+require_once 'libraries/common.inc.php';
+
+$action = 'tbl_create.php';
+
+$titles = PMA_Util::buildActionTitles();
+
+// Check parameters
+PMA_Util::checkParameters(array('db'));
+
+/* Check if database name is empty */
+if (strlen($db) == 0) {
+    PMA_Util::mysqlDie(
+        __('The database name is empty!'), '', '', 'index.php'
+    );
+}
+
+/**
+ * Defines the url to return to in case of error in a sql statement
+ */
+if (PMA_DBI_get_columns($db, $table)) {
+    // table exists already
+    PMA_Util::mysqlDie(
+        sprintf(__('Table %s already exists!'), htmlspecialchars($table)),
+        '',
+        '',
+        'db_structure.php?' . PMA_generate_common_url($db)
+    );
+}
+
+$err_url = 'tbl_create.php?' . PMA_generate_common_url($db, $table);
+
+// check number of fields to be created
+if (isset($_REQUEST['submit_num_fields'])) {
+    $regenerate = true; // for libraries/tbl_columns_definition_form.inc.php
+    $num_fields = $_REQUEST['orig_num_fields'] + $_REQUEST['added_fields'];
+} elseif (isset($_REQUEST['num_fields']) && intval($_REQUEST['num_fields']) > 0) {
+    $num_fields = (int) $_REQUEST['num_fields'];
+} else {
+    $num_fields = 4;
+}
+
+/**
+ * Selects the database to work with
+ */
+if (!PMA_DBI_select_db($db)) {
+    PMA_Util::mysqlDie(
+        sprintf(__('\'%s\' database does not exist.'), htmlspecialchars($db)),
+        '',
+        '',
+        'index.php'
+    );
+}
+
+/**
+ * The form used to define the structure of the table has been submitted
+ */
+if (isset($_REQUEST['do_save_data'])) {
+    $sql_query = '';
+
+    // Transforms the radio button field_key into 3 arrays
+    $field_cnt = count($_REQUEST['field_name']);
+    for ($i = 0; $i < $field_cnt; ++$i) {
+        if (isset($_REQUEST['field_key'][$i])) {
+            if ($_REQUEST['field_key'][$i] == 'primary_' . $i) {
+                $field_primary[] = $i;
+            }
+            if ($_REQUEST['field_key'][$i] == 'index_' . $i) {
+                $field_index[]   = $i;
+            }
+            if ($_REQUEST['field_key'][$i] == 'unique_' . $i) {
+                $field_unique[]  = $i;
+            }
+        } // end if
+    } // end for
+
+    // Builds the fields creation statements
+    for ($i = 0; $i < $field_cnt; $i++) {
+        // '0' is also empty for php :-(
+        if (empty($_REQUEST['field_name'][$i])
+            && $_REQUEST['field_name'][$i] != '0'
+        ) {
+            continue;
+        }
+
+        $query = PMA_Table::generateFieldSpec(
+            $_REQUEST['field_name'][$i],
+            $_REQUEST['field_type'][$i],
+            $i,
+            $_REQUEST['field_length'][$i],
+            $_REQUEST['field_attribute'][$i],
+            isset($_REQUEST['field_collation'][$i])
+                ? $_REQUEST['field_collation'][$i]
+                : '',
+            isset($_REQUEST['field_null'][$i])
+                ? $_REQUEST['field_null'][$i]
+                : 'NOT NULL',
+            $_REQUEST['field_default_type'][$i],
+            $_REQUEST['field_default_value'][$i],
+            isset($_REQUEST['field_extra'][$i])
+                ? $_REQUEST['field_extra'][$i]
+                : false,
+            isset($_REQUEST['field_comments'][$i])
+                ? $_REQUEST['field_comments'][$i]
+                : '',
+            $field_primary,
+            ''
+        );
+
+        $query .= ', ';
+        $sql_query .= $query;
+    } // end for
+    unset($field_cnt, $query);
+    $sql_query = preg_replace('@, $@', '', $sql_query);
+
+    // Builds the primary keys statements
+    $primary     = '';
+    $primary_cnt = (isset($field_primary) ? count($field_primary) : 0);
+    for ($i = 0; $i < $primary_cnt; $i++) {
+        $j = $field_primary[$i];
+        if (isset($_REQUEST['field_name'][$j])
+            && strlen($_REQUEST['field_name'][$j])
+        ) {
+            $primary .= PMA_Util::backquote($_REQUEST['field_name'][$j]) . ', ';
+        }
+    } // end for
+    unset($primary_cnt);
+    $primary = preg_replace('@, $@', '', $primary);
+    if (strlen($primary)) {
+        $sql_query .= ', PRIMARY KEY (' . $primary . ')';
+    }
+    unset($primary);
+
+    // Builds the indexes statements
+    $index     = '';
+    $index_cnt = (isset($field_index) ? count($field_index) : 0);
+    for ($i = 0;$i < $index_cnt; $i++) {
+        $j = $field_index[$i];
+        if (isset($_REQUEST['field_name'][$j])
+            && strlen($_REQUEST['field_name'][$j])
+        ) {
+            $index .= PMA_Util::backquote($_REQUEST['field_name'][$j]) . ', ';
+        }
+    } // end for
+    unset($index_cnt);
+    $index = preg_replace('@, $@', '', $index);
+    if (strlen($index)) {
+        $sql_query .= ', INDEX (' . $index . ')';
+    }
+    unset($index);
+
+    // Builds the uniques statements
+    $unique     = '';
+    $unique_cnt = (isset($field_unique) ? count($field_unique) : 0);
+    for ($i = 0; $i < $unique_cnt; $i++) {
+        $j = $field_unique[$i];
+        if (isset($_REQUEST['field_name'][$j])
+            && strlen($_REQUEST['field_name'][$j])
+        ) {
+            $unique .= PMA_Util::backquote($_REQUEST['field_name'][$j]) . ', ';
+        }
+    } // end for
+    unset($unique_cnt);
+    $unique = preg_replace('@, $@', '', $unique);
+    if (strlen($unique)) {
+        $sql_query .= ', UNIQUE (' . $unique . ')';
+    }
+    unset($unique);
+
+    // Builds the FULLTEXT statements
+    $fulltext     = '';
+    $fulltext_cnt = (isset($field_fulltext) ? count($field_fulltext) : 0);
+    for ($i = 0; $i < $fulltext_cnt; $i++) {
+        $j = $field_fulltext[$i];
+        if (isset($_REQUEST['field_name'][$j])
+            && strlen($_REQUEST['field_name'][$j])
+        ) {
+            $fulltext .= PMA_Util::backquote($_REQUEST['field_name'][$j]) . ', ';
+        }
+    } // end for
+
+    $fulltext = preg_replace('@, $@', '', $fulltext);
+    if (strlen($fulltext)) {
+        $sql_query .= ', FULLTEXT (' . $fulltext . ')';
+    }
+    unset($fulltext);
+
+    // Builds the 'create table' statement
+    $sql_query = 'CREATE TABLE ' . PMA_Util::backquote($db) . '.'
+        . PMA_Util::backquote($table) . ' (' . $sql_query . ')';
+
+    // Adds table type, character set, comments and partition definition
+    if (!empty($_REQUEST['tbl_storage_engine'])
+        && ($_REQUEST['tbl_storage_engine'] != 'Default')
+    ) {
+        $sql_query .= ' ENGINE = ' . $_REQUEST['tbl_storage_engine'];
+    }
+    if (!empty($_REQUEST['tbl_collation'])) {
+        $sql_query .= PMA_generateCharsetQueryPart($_REQUEST['tbl_collation']);
+    }
+    if (!empty($_REQUEST['comment'])) {
+        $sql_query .= ' COMMENT = \''
+            . PMA_Util::sqlAddSlashes($_REQUEST['comment']) . '\'';
+    }
+    if (!empty($_REQUEST['partition_definition'])) {
+        $sql_query .= ' ' . PMA_Util::sqlAddSlashes(
+            $_REQUEST['partition_definition']
+        );
+    }
+    $sql_query .= ';';
+
+    // Executes the query
+    $result = PMA_DBI_try_query($sql_query);
+
+    if ($result) {
+
+        // If comments were sent, enable relation stuff
+        include_once 'libraries/transformations.lib.php';
+
+        // Update comment table for mime types [MIME]
+        if (isset($_REQUEST['field_mimetype'])
+            && is_array($_REQUEST['field_mimetype'])
+            && $cfg['BrowseMIME']
+        ) {
+            foreach ($_REQUEST['field_mimetype'] as $fieldindex => $mimetype) {
+                if (isset($_REQUEST['field_name'][$fieldindex])
+                    && strlen($_REQUEST['field_name'][$fieldindex])
+                ) {
+                    PMA_setMIME(
+                        $db, $table, $_REQUEST['field_name'][$fieldindex], $mimetype,
+                        $_REQUEST['field_transformation'][$fieldindex],
+                        $_REQUEST['field_transformation_options'][$fieldindex]
+                    );
+                }
+            }
+        }
+
+        $message = PMA_Message::success(__('Table %1$s has been created.'));
+        $message->addParam(
+            PMA_Util::backquote($db) . '.' . PMA_Util::backquote($table)
+        );
+
+        if ($GLOBALS['is_ajax_request'] == true) {
+
+            /**
+             * construct the html for the newly created table's row to be appended
+             * to the list of tables.
+             *
+             * Logic taken from db_structure.php
+             */
+
+            $tbl_url_params = array();
+            $tbl_url_params['db'] = $db;
+            $tbl_url_params['table'] = $table;
+            $is_show_stats = $cfg['ShowStats'];
+
+            $tbl_stats_result = PMA_DBI_query(
+                'SHOW TABLE STATUS FROM ' . PMA_Util::backquote($db)
+                . ' LIKE \'' . PMA_Util::sqlAddSlashes($table, true) . '\';'
+            );
+            $tbl_stats = PMA_DBI_fetch_assoc($tbl_stats_result);
+            PMA_DBI_free_result($tbl_stats_result);
+            unset($tbl_stats_result);
+
+            if ($is_show_stats) {
+                $sum_size       = (double) 0;
+                $overhead_size  = (double) 0;
+                $overhead_check = '';
+
+                $tblsize = doubleval($tbl_stats['Data_length'])
+                    + doubleval($tbl_stats['Index_length']);
+                $sum_size += $tblsize;
+                list($formatted_size, $unit) = PMA_Util::formatByteDown(
+                    $tblsize,
+                    3,
+                    ($tblsize > 0) ? 1 : 0
+                );
+                if (isset($tbl_stats['Data_free']) && $tbl_stats['Data_free'] > 0) {
+                    list($formatted_overhead, $overhead_unit) = PMA_Util::formatByteDown(
+                        $tbl_stats['Data_free'],
+                        3,
+                        ($tbl_stats['Data_free'] > 0) ? 1 : 0
+                    );
+                    $overhead_size += $tbl_stats['Data_free'];
+                }
+
+                if (isset($formatted_overhead)) {
+                    $overhead = '<span>' . $formatted_overhead . '</span>'
+                        . '<span class="unit">' . $overhead_unit . '</span>';
+                    unset($formatted_overhead);
+                } else {
+                    $overhead = '-';
+                }
+            }
+
+            $new_table_string = '<tr>' . "\n";
+            $new_table_string .= '<td class="center">'
+                . '<input type="checkbox" id="checkbox_tbl_"'
+                . ' name="selected_tbl[]" value="'.htmlspecialchars($table).'" />'
+                . '</td>' . "\n";
+
+            $new_table_string .= '<th>';
+            $new_table_string .= '<a href="sql.php'
+                . PMA_generate_common_url($tbl_url_params) . '">'
+                . htmlspecialchars($table) . '</a>';
+
+            if (PMA_Tracker::isActive()) {
+                $truename = str_replace(' ', ' ', htmlspecialchars($table));
+                if (PMA_Tracker::isTracked($db, $truename)) {
+                    $new_table_string .= '<a href="tbl_tracking.php'
+                        . PMA_generate_common_url($tbl_url_params) . '">';
+                    $new_table_string .= PMA_Util::getImage(
+                        'eye.png', __('Tracking is active.')
+                    );
+                } elseif (PMA_Tracker::getVersion($db, $truename) > 0) {
+                    $new_table_string .= '<a href="tbl_tracking.php'
+                       . PMA_generate_common_url($tbl_url_params) . '">';
+                    $new_table_string .= PMA_Util::getImage(
+                        'eye_grey.png', __('Tracking is not active.')
+                    );
+                }
+                unset($truename);
+            }
+            $new_table_string .= '</th>' . "\n";
+
+            $new_table_string .= '<td>' . $titles['NoBrowse'] . '</td>' . "\n";
+
+            $new_table_string .= '<td>'
+                . '<a href="tbl_structure.php'
+                . PMA_generate_common_url($tbl_url_params) . '">'
+                . $titles['Structure']
+                . '</a>'
+                . '</td>' . "\n";
+
+            $new_table_string .= '<td>' . $titles['NoSearch'] . '</td>' . "\n";
+
+            $new_table_string .= '<td>'
+                . '<a href="tbl_change.php'
+                . PMA_generate_common_url($tbl_url_params) . '">'
+                . $titles['Insert']
+                . '</a>'
+                . '</td>' . "\n";
+
+            $new_table_string .= '<td>' . $titles['NoEmpty'] . '</td>' . "\n";
+
+            $new_table_string .= '<td>'
+                . '<a class="drop_table_anchor" href="sql.php'
+                . PMA_generate_common_url($tbl_url_params) . '&sql_query='
+                . urlencode('DROP TABLE ' . PMA_Util::backquote($table)) . '">'
+                . $titles['Drop']
+                . '</a>'
+                . '</td>' . "\n";
+
+            $new_table_string .= '<td class="value">'
+                . $tbl_stats['Rows']
+                . '</td>' . "\n";
+
+            $new_table_string .= '<td class="nowrap">'
+                . $tbl_stats['Engine']
+                . '</td>' . "\n";
+
+            $new_table_string .= '<td>'
+                . '<dfn title="' . PMA_getCollationDescr($tbl_stats['Collation']) . '">'
+                . $tbl_stats['Collation']
+                .'</dfn>'
+                . '</td>' . "\n";
+
+            if ($is_show_stats) {
+                $new_table_string .= '<td class="value tbl_size">'
+                    . '<a href="tbl_structure.php'
+                    . PMA_generate_common_url($tbl_url_params) . '#showusage" >'
+                    . '<span>' . $formatted_size . '</span>'
+                    . '<span class="unit">' . $unit . '</span>'
+                    . '</a>'
+                    . '</td>' . "\n" ;
+
+                $new_table_string .= '<td class="value tbl_overhead">'
+                    . $overhead
+                    . '</td>' . "\n" ;
+            }
+            $new_table_string .= '</tr>' . "\n";
+
+            $formatted_sql = PMA_Util::getMessage(
+                $message, $sql_query, 'success'
+            );
+
+            $response = PMA_Response::getInstance();
+            $response->addJSON('message', $message);
+            $response->addJSON('formatted_sql', $formatted_sql);
+            $response->addJSON('new_table_string', $new_table_string);
+        } else {
+
+            $display_query = $sql_query;
+            $sql_query = '';
+
+            // read table info on this newly created table, in case
+            // the next page is Structure
+            $reread_info = true;
+            include 'libraries/tbl_info.inc.php';
+
+            // do not switch to sql.php
+            // as there is no row to be displayed on a new table
+            if ($cfg['DefaultTabTable'] === 'sql.php') {
+                include 'tbl_structure.php';
+            } else {
+                include '' . $cfg['DefaultTabTable'];
+            }
+        }
+    } else {
+        if ($GLOBALS['is_ajax_request'] == true) {
+            $response = PMA_Response::getInstance();
+            $response->isSuccess(false);
+            $response->addJSON('message', PMA_DBI_getError());
+        } else {
+            echo PMA_Util::mysqlDie('', '', '', $err_url, false);
+            // An error happened while inserting/updating a table definition.
+            // To prevent total loss of that data, we embed the form once again.
+            // The variable $regenerate will be used to restore data in
+            // libraries/tbl_columns_definition_form.inc.php
+            $num_fields = $_REQUEST['orig_num_fields'];
+            $regenerate = true;
+        }
+    }
+    exit;
+} // end do create table
+
+/**
+ * Displays the form used to define the structure of the table
+ */
+
+// This div is used to show the content(eg: create table form with more columns)
+// fetched with AJAX subsequently.
+if ($GLOBALS['is_ajax_request'] != true) {
+    echo('<div id="create_table_div">');
+}
+
+require 'libraries/tbl_columns_definition_form.inc.php';
+
+if ($GLOBALS['is_ajax_request'] != true) {
+    echo('</div>');
+}
+?>
diff --git a/phpmyadmin/tbl_export.php b/phpmyadmin/tbl_export.php
new file mode 100644
index 0000000..fbc585c
--- /dev/null
+++ b/phpmyadmin/tbl_export.php
@@ -0,0 +1,85 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ *
+ * @package PhpMyAdmin
+ */
+
+/**
+ *
+ */
+require_once 'libraries/common.inc.php';
+
+$response = PMA_Response::getInstance();
+$header   = $response->getHeader();
+$scripts  = $header->getScripts();
+$scripts->addFile('export.js');
+
+/**
+ * Gets tables informations and displays top links
+ */
+require_once 'libraries/tbl_common.inc.php';
+$url_query .= '&goto=tbl_export.php&back=tbl_export.php';
+require_once 'libraries/tbl_info.inc.php';
+
+// Dump of a table
+
+$export_page_title = __('View dump (schema) of table');
+
+// When we have some query, we need to remove LIMIT from that and possibly
+// generate WHERE clause (if we are asked to export specific rows)
+
+if (! empty($sql_query)) {
+    // Parse query so we can work with tokens
+    $parsed_sql = PMA_SQP_parse($sql_query);
+    $analyzed_sql = PMA_SQP_analyze($parsed_sql);
+
+    // Need to generate WHERE clause?
+    if (isset($where_clause)) {
+
+        // Regular expressions which can appear in sql query,
+        // before the sql segment which remains as it is.
+        $regex_array = array(
+            '/\bwhere\b/i', '/\bgroup by\b/i', '/\bhaving\b/i', '/\border by\b/i'
+        );
+        
+        $first_occurring_regex = PMA_getFirstOccurringRegularExpression(
+            $regex_array, $sql_query
+        );
+        unset($regex_array);
+
+        // The part "SELECT `id`, `name` FROM `customers`"
+        // is not modified by the next code segment, when exporting 
+        // the result set from a query such as
+        // "SELECT `id`, `name` FROM `customers` WHERE id NOT IN
+        //  ( SELECT id FROM companies WHERE name LIKE '%u%')"
+        if (! is_null($first_occurring_regex)) {
+            $temp_sql_array = preg_split($first_occurring_regex, $sql_query);
+            $sql_query = $temp_sql_array[0];
+        }
+        unset($first_occurring_regex, $temp_sql_array);
+
+        // Append the where clause using the primary key of each row
+        if (is_array($where_clause) && (count($where_clause) > 0)) {
+            $sql_query .= ' WHERE (' . implode(') OR (', $where_clause) . ')';
+        }
+
+        if (!empty($analyzed_sql[0]['group_by_clause'])) {
+            $sql_query .= ' GROUP BY ' . $analyzed_sql[0]['group_by_clause'];
+        }
+        if (!empty($analyzed_sql[0]['having_clause'])) {
+            $sql_query .= ' HAVING ' . $analyzed_sql[0]['having_clause'];
+        }
+        if (!empty($analyzed_sql[0]['order_by_clause'])) {
+            $sql_query .= ' ORDER BY ' . $analyzed_sql[0]['order_by_clause'];
+        }
+    } else {
+        // Just crop LIMIT clause
+        $sql_query = $analyzed_sql[0]['section_before_limit'] . $analyzed_sql[0]['section_after_limit'];
+    }
+    echo PMA_Util::getMessage(PMA_Message::success());
+}
+
+$export_type = 'table';
+require_once 'libraries/display_export.lib.php';
+?>
diff --git a/phpmyadmin/tbl_get_field.php b/phpmyadmin/tbl_get_field.php
new file mode 100644
index 0000000..ada209f
--- /dev/null
+++ b/phpmyadmin/tbl_get_field.php
@@ -0,0 +1,67 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * Provides download to a given field defined in parameters.
+ *
+ * @package PhpMyAdmin
+ */
+
+/**
+ * Common functions.
+ */
+require_once 'libraries/common.inc.php';
+require_once 'libraries/mime.lib.php';
+
+/**
+ * Sets globals from $_GET
+ */
+$get_params = array(
+    'where_clause',
+    'transform_key'
+);
+
+foreach ($get_params as $one_get_param) {
+    if (isset($_GET[$one_get_param])) {
+        $GLOBALS[$one_get_param] = $_GET[$one_get_param];
+    }
+}
+
+/* Check parameters */
+PMA_Util::checkParameters(
+    array('db', 'table', 'where_clause', 'transform_key')
+);
+
+/* Select database */
+if (!PMA_DBI_select_db($db)) {
+    PMA_Util::mysqlDie(
+        sprintf(__('\'%s\' database does not exist.'), htmlspecialchars($db)),
+        '', ''
+    );
+}
+
+/* Check if table exists */
+if (!PMA_DBI_get_columns($db, $table)) {
+    PMA_Util::mysqlDie(__('Invalid table name'));
+}
+
+/* Grab data */
+$sql = 'SELECT ' . PMA_Util::backquote($transform_key)
+    . ' FROM ' . PMA_Util::backquote($table)
+    . ' WHERE ' . $where_clause . ';';
+$result = PMA_DBI_fetch_value($sql);
+
+/* Check return code */
+if ($result === false) {
+    PMA_Util::mysqlDie(__('MySQL returned an empty result set (i.e. zero rows).'), $sql);
+}
+
+/* Avoid corrupting data */
+ at ini_set('url_rewriter.tags', '');
+
+PMA_downloadHeader(
+    $table . '-' .  $transform_key . '.bin',
+    PMA_detectMIME($result),
+    strlen($result)
+);
+echo $result;
+?>
diff --git a/phpmyadmin/tbl_gis_visualization.php b/phpmyadmin/tbl_gis_visualization.php
new file mode 100644
index 0000000..f272417
--- /dev/null
+++ b/phpmyadmin/tbl_gis_visualization.php
@@ -0,0 +1,220 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * handles creation of the GIS visualizations.
+ *
+ * @package PhpMyAdmin
+ */
+
+require_once 'libraries/common.inc.php';
+
+// Runs common work
+require_once 'libraries/db_common.inc.php';
+$url_params['goto'] = $cfg['DefaultTabDatabase'];
+$url_params['back'] = 'sql.php';
+
+// Import visualization functions
+require_once 'libraries/gis_visualization.lib.php';
+
+$response = PMA_Response::getInstance();
+// Throw error if no sql query is set
+if (! isset($sql_query) || $sql_query == '') {
+    $response->isSuccess(false);
+    $response->addHTML(
+        PMA_Message::error(__('No SQL query was set to fetch data.'))
+    );
+    exit;
+}
+
+// Execute the query and return the result
+$result = PMA_DBI_try_query($sql_query);
+// Get the meta data of results
+$meta = PMA_DBI_get_fields_meta($result);
+
+// Find the candidate fields for label column and spatial column
+$labelCandidates = array(); $spatialCandidates = array();
+foreach ($meta as $column_meta) {
+    if ($column_meta->type == 'geometry') {
+        $spatialCandidates[] = $column_meta->name;
+    } else {
+        $labelCandidates[] = $column_meta->name;
+    }
+}
+
+// Get settings if any posted
+$visualizationSettings = array();
+if (PMA_isValid($_REQUEST['visualizationSettings'], 'array')) {
+    $visualizationSettings = $_REQUEST['visualizationSettings'];
+}
+
+if (! isset($visualizationSettings['labelColumn']) && isset($labelCandidates[0])) {
+    $visualizationSettings['labelColumn'] = '';
+}
+
+// If spatial column is not set, use first geometric colum as spatial column
+if (! isset($visualizationSettings['spatialColumn'])) {
+    $visualizationSettings['spatialColumn'] = $spatialCandidates[0];
+}
+
+// Convert geometric columns from bytes to text.
+$modified_query = PMA_GIS_modifyQuery($sql_query, $visualizationSettings);
+$modified_result = PMA_DBI_try_query($modified_query);
+
+$data = array();
+while ($row = PMA_DBI_fetch_assoc($modified_result)) {
+    $data[] = $row;
+}
+
+if (isset($_REQUEST['saveToFile'])) {
+    $response->disable();
+    $file_name = $_REQUEST['fileName'];
+    if ($file_name == '') {
+        $file_name = $visualizationSettings['spatialColumn'];
+    }
+
+    $save_format = $_REQUEST['fileFormat'];
+    PMA_GIS_saveToFile($data, $visualizationSettings, $save_format, $file_name);
+    exit();
+}
+
+$header = $response->getHeader();
+$scripts = $header->getScripts();
+$scripts->addFile('openlayers/OpenLayers.js');
+$scripts->addFile('jquery/jquery.svg.js');
+$scripts->addFile('tbl_gis_visualization.js');
+$scripts->addFile('OpenStreetMap.js');
+
+// If all the rows contain SRID, use OpenStreetMaps on the initial loading.
+if (! isset($_REQUEST['displayVisualization'])) {
+    $visualizationSettings['choice'] = 'useBaseLayer';
+    foreach ($data as $row) {
+        if ($row['srid'] == 0) {
+            unset($visualizationSettings['choice']);
+            break;
+        }
+    }
+}
+
+$svg_support = (PMA_USR_BROWSER_AGENT == 'IE' && PMA_USR_BROWSER_VER <= 8)
+    ? false : true;
+$format = $svg_support ? 'svg' : 'png';
+
+// get the chart and settings after chart generation
+$visualization = PMA_GIS_visualizationResults(
+    $data, $visualizationSettings, $format
+);
+
+/**
+ * Displays the page
+ */
+?>
+<!-- Display visualization options -->
+<div id="div_view_options">
+<fieldset>
+    <legend><?php echo __('Display GIS Visualization'); ?></legend>
+    <div style="width: 400px; float: left;">
+    <form method="post" action="tbl_gis_visualization.php">
+    <?php echo PMA_generate_common_hidden_inputs($url_params); ?>
+    <table class="gis_table">
+    <tr><td><label for="labelColumn"><?php echo __("Label column"); ?></label></td>
+        <td><select name="visualizationSettings[labelColumn]" id="labelColumn">
+            <option value=""><?php echo __("-- None --"); ?></option>
+        <?php
+
+foreach ($labelCandidates as $labelCandidate) {
+    echo('<option value="' . htmlspecialchars($labelCandidate) . '"');
+    if ($labelCandidate == $visualizationSettings['labelColumn']) {
+        echo(' selected="selected"');
+    }
+    echo('>' . htmlspecialchars($labelCandidate) . '</option>');
+}
+        ?>
+        </select></td>
+    </tr>
+
+    <tr><td><label for="spatial Column"><?php echo __("Spatial column"); ?></label></td>
+        <td><select name="visualizationSettings[spatialColumn]" id="spatialColumn">
+        <?php
+
+foreach ($spatialCandidates as $spatialCandidate) {
+    echo('<option value="' . htmlspecialchars($spatialCandidate) . '"');
+    if ($spatialCandidate == $visualizationSettings['spatialColumn']) {
+        echo(' selected="selected"');
+    }
+    echo('>' . htmlspecialchars($spatialCandidate) . '</option>');
+}
+        ?>
+        </select></td>
+    </tr>
+    <tr><td></td>
+        <td class="button"><input type="submit" name="displayVisualizationBtn" value="<?php echo __('Redraw'); ?>" /></td>
+    </tr>
+<?php
+if (! $GLOBALS['PMA_Config']->isHttps()) {
+    ?>
+    <tr><td class="choice" colspan="2">
+        <input type="checkbox" name="visualizationSettings[choice]" id="choice" value="useBaseLayer"
+    <?php
+    if (isset($visualizationSettings['choice'])) {
+        echo(' checked="checked"');
+    }
+    ?>
+        />
+        <label for="choice"><?php echo __("Use OpenStreetMaps as Base Layer"); ?></label>
+    </td></tr>
+    <?php
+}
+?>
+    </table>
+    <input type="hidden" name="displayVisualization" value="redraw">
+    <input type="hidden" name="sql_query" value="<?php echo htmlspecialchars($sql_query); ?>" />
+    </form>
+    </div>
+
+    <div  style="float:left;">
+    <form method="post" class="disableAjax"  action="tbl_gis_visualization.php">
+    <?php echo PMA_generate_common_hidden_inputs($url_params); ?>
+    <table class="gis_table">
+    <tr><td><label for="fileName"><?php echo __("File name"); ?></label></td>
+        <td><input type="text" name="fileName" id="fileName" /></td>
+    </tr>
+    <tr><td><label for="fileFormat"><?php echo __("Format"); ?></label></td>
+        <td><select name="fileFormat" id="fileFormat">
+            <option value="png">PNG</option>
+            <option value="pdf">PDF</option>
+            <?php
+
+if ($svg_support) {
+    echo ('<option value="svg" selected="selected">SVG</option>');
+}
+            ?>
+        </select></td>
+    </tr>
+    <tr><td></td>
+        <td class="button"><input type="submit" name="saveToFileBtn" value="<?php echo __('Download'); ?>" /></td>
+    </tr>
+    </table>
+    <input type="hidden" name="saveToFile" value="download">
+    <input type="hidden" name="sql_query" value="<?php echo htmlspecialchars($sql_query); ?>" />
+    </form>
+    </div>
+
+    <div style="clear:both;"> </div>
+
+    <div id="placeholder" style="width:<?php echo htmlspecialchars($visualizationSettings['width']); ?>px;height:<?php echo htmlspecialchars($visualizationSettings['height']); ?>px;">
+        <?php echo $visualization; ?>
+    </div>
+    <div id="openlayersmap"></div>
+    <input type="hidden" id="pmaThemeImage" value="<?php echo($GLOBALS['pmaThemeImage']); ?>" />
+    <script language="javascript" type="text/javascript">
+        function drawOpenLayers()
+        {
+            <?php
+            if (! $GLOBALS['PMA_Config']->isHttps()) {
+                echo (PMA_GIS_visualizationResults($data, $visualizationSettings, 'ol'));
+            }
+            ?>
+        }
+    </script>
+</fieldset>
+</div>
diff --git a/phpmyadmin/tbl_import.php b/phpmyadmin/tbl_import.php
new file mode 100644
index 0000000..9c399e0
--- /dev/null
+++ b/phpmyadmin/tbl_import.php
@@ -0,0 +1,30 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ *
+ * @package PhpMyAdmin
+ */
+
+/**
+ *
+ */
+require_once 'libraries/common.inc.php';
+
+$response = PMA_Response::getInstance();
+$header   = $response->getHeader();
+$scripts  = $header->getScripts();
+$scripts->addFile('import.js');
+
+/**
+ * Gets tables informations and displays top links
+ */
+require_once 'libraries/tbl_common.inc.php';
+$url_query .= '&goto=tbl_import.php&back=tbl_import.php';
+
+require_once 'libraries/tbl_info.inc.php';
+
+$import_type = 'table';
+require_once 'libraries/display_import.lib.php';
+
+?>
+
diff --git a/phpmyadmin/tbl_indexes.php b/phpmyadmin/tbl_indexes.php
new file mode 100644
index 0000000..a778814
--- /dev/null
+++ b/phpmyadmin/tbl_indexes.php
@@ -0,0 +1,365 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * Displays index edit/creation form and handles it
+ *
+ * @package PhpMyAdmin
+ */
+
+/**
+ * Gets some core libraries
+ */
+require_once 'libraries/common.inc.php';
+require_once 'libraries/Index.class.php';
+require_once 'libraries/tbl_common.inc.php';
+
+// Get fields and stores their name/type
+$fields = array();
+foreach (PMA_DBI_get_columns_full($db, $table) as $row) {
+    if (preg_match('@^(set|enum)\((.+)\)$@i', $row['Type'], $tmp)) {
+        $tmp[2] = substr(
+            preg_replace('@([^,])\'\'@', '\\1\\\'', ',' . $tmp[2]), 1
+        );
+        $fields[$row['Field']] = $tmp[1] . '('
+            . str_replace(',', ', ', $tmp[2]) . ')';
+    } else {
+        $fields[$row['Field']] = $row['Type'];
+    }
+} // end while
+
+// Prepares the form values
+if (isset($_REQUEST['index'])) {
+    if (is_array($_REQUEST['index'])) {
+        // coming already from form
+        $index = new PMA_Index($_REQUEST['index']);
+    } else {
+        $index = PMA_Index::singleton($db, $table, $_REQUEST['index']);
+    }
+} else {
+    $index = new PMA_Index;
+}
+
+/**
+ * Process the data from the edit/create index form,
+ * run the query to build the new index
+ * and moves back to "tbl_sql.php"
+ */
+if (isset($_REQUEST['do_save_data'])) {
+    $error = false;
+
+    // $sql_query is the one displayed in the query box
+    $sql_query = 'ALTER TABLE ' . PMA_Util::backquote($db)
+        . '.' . PMA_Util::backquote($table);
+
+    // Drops the old index
+    if (! empty($_REQUEST['old_index'])) {
+        if ($_REQUEST['old_index'] == 'PRIMARY') {
+            $sql_query .= ' DROP PRIMARY KEY,';
+        } else {
+            $sql_query .= ' DROP INDEX '
+                . PMA_Util::backquote($_REQUEST['old_index']) . ',';
+        }
+    } // end if
+
+    // Builds the new one
+    switch ($index->getType()) {
+    case 'PRIMARY':
+        if ($index->getName() == '') {
+            $index->setName('PRIMARY');
+        } elseif ($index->getName() != 'PRIMARY') {
+            $error = PMA_Message::error(
+                __('The name of the primary key must be "PRIMARY"!')
+            );
+        }
+        $sql_query .= ' ADD PRIMARY KEY';
+        break;
+    case 'FULLTEXT':
+    case 'UNIQUE':
+    case 'INDEX':
+    case 'SPATIAL':
+        if ($index->getName() == 'PRIMARY') {
+            $error = PMA_Message::error(__('Can\'t rename index to PRIMARY!'));
+        }
+        $sql_query .= ' ADD ' . $index->getType() . ' '
+            . ($index->getName() ? PMA_Util::backquote($index->getName()) : '');
+        break;
+    } // end switch
+
+    $index_fields = array();
+    foreach ($index->getColumns() as $key => $column) {
+        $index_fields[$key] = PMA_Util::backquote($column->getName());
+        if ($column->getSubPart()) {
+            $index_fields[$key] .= '(' . $column->getSubPart() . ')';
+        }
+    } // end while
+
+    if (empty($index_fields)) {
+        $error = PMA_Message::error(__('No index parts defined!'));
+    } else {
+        $sql_query .= ' (' . implode(', ', $index_fields) . ')';
+    }
+
+    if (PMA_MYSQL_INT_VERSION > 50500) {
+        $sql_query .= "COMMENT '" 
+            . PMA_Util::sqlAddSlashes($index->getComment()) 
+            . "'";
+    }
+    $sql_query .= ';';
+
+    if (! $error) {
+        PMA_DBI_query($sql_query);
+        $message = PMA_Message::success(
+            __('Table %1$s has been altered successfully')
+        );
+        $message->addParam($table);
+
+        if ($GLOBALS['is_ajax_request'] == true) {
+            $response = PMA_Response::getInstance();
+            $response->addJSON('message', $message);
+            $response->addJSON('index_table', PMA_Index::getView($table, $db));
+            $response->addJSON(
+                'sql_query',
+                PMA_Util::getMessage(null, $sql_query)
+            );
+        } else {
+            $active_page = 'tbl_structure.php';
+            include 'tbl_structure.php';
+        }
+        exit;
+    } else {
+        if ($GLOBALS['is_ajax_request'] == true) {
+            $response = PMA_Response::getInstance();
+            $response->isSuccess(false);
+            $response->addJSON('message', $error);
+            exit;
+        } else {
+            $error->display();
+        }
+    }
+} // end builds the new index
+
+
+/**
+ * Display the form to edit/create an index
+ */
+
+// Displays headers (if needed)
+$response = PMA_Response::getInstance();
+$header   = $response->getHeader();
+$scripts  = $header->getScripts();
+$scripts->addFile('indexes.js');
+require_once 'libraries/tbl_info.inc.php';
+
+if (isset($_REQUEST['index']) && is_array($_REQUEST['index'])) {
+    // coming already from form
+    $add_fields
+        = count($_REQUEST['index']['columns']['names']) - $index->getColumnCount();
+    if (isset($_REQUEST['add_fields'])) {
+        $add_fields += $_REQUEST['added_fields'];
+    }
+} elseif (isset($_REQUEST['create_index'])) {
+    $add_fields = $_REQUEST['added_fields'];
+} else {
+    $add_fields = 1;
+}
+
+// end preparing form values
+?>
+
+<form action="tbl_indexes.php" method="post" name="index_frm" id="index_frm" class="ajax"
+    onsubmit="if (typeof(this.elements['index[Key_name]'].disabled) != 'undefined') {
+        this.elements['index[Key_name]'].disabled = false}">
+<?php
+$form_params = array(
+    'db'    => $db,
+    'table' => $table,
+);
+
+if (isset($_REQUEST['create_index'])) {
+    $form_params['create_index'] = 1;
+} elseif (isset($_REQUEST['old_index'])) {
+    $form_params['old_index'] = $_REQUEST['old_index'];
+} elseif (isset($_REQUEST['index'])) {
+    $form_params['old_index'] = $_REQUEST['index'];
+}
+
+echo PMA_generate_common_hidden_inputs($form_params);
+?>
+<fieldset id="index_edit_fields">
+<?php
+if ($GLOBALS['is_ajax_request'] != true) {
+    ?>
+    <legend>
+    <?php
+    if (isset($_REQUEST['create_index'])) {
+        echo __('Add index');
+    } else {
+        echo __('Edit index');
+    }
+    ?>
+    </legend>
+    <?php
+}
+?>
+<div class='index_info'>
+    <div>
+        <div class="label">
+            <strong>
+                <label for="input_index_name">
+                    <?php echo __('Index name:'); ?>
+                    <?php
+echo PMA_Util::showHint(
+    PMA_Message::notice(
+        __(
+            '("PRIMARY" <b>must</b> be the name of'
+            . ' and <b>only of</b> a primary key!)'
+        )
+    )
+);
+                    ?>
+                </label>
+            </strong>
+        </div>
+        <input type="text" name="index[Key_name]" id="input_index_name" size="25"
+            value="<?php echo htmlspecialchars($index->getName()); ?>"
+            onfocus="this.select()" />
+    </div>
+<?php
+if (PMA_MYSQL_INT_VERSION > 50500) {
+?>
+    <div>
+        <div class="label">
+            <strong>
+                <label for="input_index_comment">
+                    <?php echo __('Comment:'); ?>
+                </label>
+            </strong>
+        </div>
+        <input type="text" name="index[Index_comment]" id="input_index_comment" size="30"
+            value="<?php echo htmlspecialchars($index->getComment()); ?>"
+            onfocus="this.select()" />
+    </div>
+<?php
+}
+?>
+    <div>
+        <div class="label">
+            <strong>
+                <label for="select_index_type">
+                    <?php echo __('Index type:'); ?>
+                    <?php echo PMA_Util::showMySQLDocu('SQL-Syntax', 'ALTER_TABLE'); ?>
+                </label>
+            </strong>
+        </div>
+        <select name="index[Index_type]" id="select_index_type" >
+            <?php echo $index->generateIndexSelector(); ?>
+        </select>
+    </div>
+    <div class="clearfloat"></div>
+</div>
+
+<table id="index_columns">
+<thead>
+<tr><th><?php echo __('Column'); ?></th>
+    <th><?php echo __('Size'); ?></th>
+</tr>
+</thead>
+<tbody>
+<?php
+$odd_row = true;
+$spatial_types = array(
+    'geometry', 'point', 'linestring', 'polygon', 'multipoint',
+    'multilinestring', 'multipolygon', 'geomtrycollection'
+);
+foreach ($index->getColumns() as $column) {
+    ?>
+    <tr class="<?php echo $odd_row ? 'odd' : 'even'; ?> noclick">
+      <td>
+        <select name="index[columns][names][]">
+            <option value="">-- <?php echo __('Ignore'); ?> --</option>
+    <?php
+    foreach ($fields as $field_name => $field_type) {
+        if (($index->getType() != 'FULLTEXT'
+            || preg_match('/(char|text)/i', $field_type))
+            && ($index->getType() != 'SPATIAL'
+            || in_array($field_type, $spatial_types))
+        ) {
+            echo '<option value="' . htmlspecialchars($field_name) . '"'
+                 . (($field_name == $column->getName())
+                    ? ' selected="selected"'
+                    : '') . '>'
+                 . htmlspecialchars($field_name) . ' ['
+                 . htmlspecialchars($field_type) . ']'
+                 . '</option>' . "\n";
+        }
+    } // end foreach $fields
+    ?>
+        </select>
+      </td>
+      <td>
+        <input type="text" size="5" onfocus="this.select()"
+            name="index[columns][sub_parts][]"
+            value="<?php
+    if ($index->getType() != 'SPATIAL') {
+        echo $column->getSubPart();
+    }
+      ?>"/>
+      </td>
+    </tr>
+    <?php
+    $odd_row = !$odd_row;
+} // end foreach $edited_index_info['Sequences']
+for ($i = 0; $i < $add_fields; $i++) {
+    ?>
+    <tr class="<?php echo $odd_row ? 'odd' : 'even'; ?> noclick">
+      <td>
+        <select name="index[columns][names][]">
+            <option value="">-- <?php echo __('Ignore'); ?> --</option>
+    <?php
+    foreach ($fields as $field_name => $field_type) {
+        echo '<option value="' . htmlspecialchars($field_name) . '">'
+             . htmlspecialchars($field_name) . ' ['
+             . htmlspecialchars($field_type) . ']'
+             . '</option>' . "\n";
+    } // end foreach $fields
+    ?>
+        </select>
+      </td>
+      <td>
+        <input type="text" size="5" onfocus="this.select()"
+            name="index[columns][sub_parts][]" value="" />
+      </td>
+    </tr>
+    <?php
+    $odd_row = !$odd_row;
+} // end foreach $edited_index_info['Sequences']
+?>
+</tbody>
+</table>
+</fieldset>
+<fieldset class="tblFooters">
+<?php
+if ($GLOBALS['is_ajax_request'] != true || ! empty($_REQUEST['ajax_page_request'])) {
+    ?>
+    <input type="submit" name="do_save_data" value="<?php echo __('Save'); ?>" />
+    <span id="addMoreColumns">
+    <?php
+    echo __('Or') . ' ';
+    printf(
+        __('Add %s column(s) to index') . "\n",
+        '<input type="text" name="added_fields" size="2" value="1" />'
+    );
+    echo '<input type="submit" name="add_fields" value="' . __('Go') . '" />' . "\n";
+    ?>
+    </span>
+    <?php
+} else {
+    $btn_value = sprintf(__('Add %s column(s) to index'), 1);
+    echo '<div class="slider"></div>';
+    echo '<div class="add_fields">';
+    echo '<input type="submit" value="' . $btn_value . '" />';
+    echo '</div>';
+}
+?>
+</fieldset>
+</form>
diff --git a/phpmyadmin/tbl_move_copy.php b/phpmyadmin/tbl_move_copy.php
new file mode 100644
index 0000000..b21f295
--- /dev/null
+++ b/phpmyadmin/tbl_move_copy.php
@@ -0,0 +1,103 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ *
+ * @package PhpMyAdmin
+ */
+
+/**
+ * Gets some core libraries
+ */
+require_once 'libraries/common.inc.php';
+
+// Check parameters
+PMA_Util::checkParameters(array('db', 'table'));
+
+/**
+ * Defines the url to return to in case of error in a sql statement
+ */
+$err_url = 'tbl_sql.php?' . PMA_generate_common_url($db, $table);
+
+
+/**
+ * Selects the database to work with
+ */
+PMA_DBI_select_db($db);
+
+$goto = $cfg['DefaultTabTable'];
+
+/**
+ * $_REQUEST['target_db'] could be empty in case we came from an input field
+ * (when there are many databases, no drop-down)
+ */
+if (empty($_REQUEST['target_db'])) {
+    $_REQUEST['target_db'] = $db;
+}
+
+/**
+ * A target table name has been sent to this script -> do the work
+ */
+if (PMA_isValid($_REQUEST['new_name'])) {
+    if ($db == $_REQUEST['target_db'] && $table == $_REQUEST['new_name']) {
+        if (isset($_REQUEST['submit_move'])) {
+            $message = PMA_Message::error(__('Can\'t move table to same one!'));
+        } else {
+            $message = PMA_Message::error(__('Can\'t copy table to same one!'));
+        }
+        $result = false;
+    } else {
+        $result = PMA_Table::moveCopy(
+            $db, $table, $_REQUEST['target_db'], $_REQUEST['new_name'],
+            $_REQUEST['what'], isset($_REQUEST['submit_move']), 'one_table'
+        );
+
+        if (isset($_REQUEST['submit_move'])) {
+            $message = PMA_Message::success(__('Table %s has been moved to %s.'));
+        } else {
+            $message = PMA_Message::success(__('Table %s has been copied to %s.'));
+        }
+        $old = PMA_Util::backquote($db) . '.'
+            . PMA_Util::backquote($table);
+        $message->addParam($old);
+        $new = PMA_Util::backquote($_REQUEST['target_db']) . '.'
+            . PMA_Util::backquote($_REQUEST['new_name']);
+        $message->addParam($new);
+
+        /* Check: Work on new table or on old table? */
+        if (isset($_REQUEST['submit_move'])
+            || PMA_isValid($_REQUEST['switch_to_new'])
+        ) {
+            $db    = $_REQUEST['target_db'];
+            $table = $_REQUEST['new_name'];
+        }
+        $reload = 1;
+    }
+} else {
+    /**
+     * No new name for the table!
+     */
+    $message = PMA_Message::error(__('The table name is empty!'));
+    $result = false;
+}
+
+if ($GLOBALS['is_ajax_request'] == true) {
+    $response = PMA_Response::getInstance();
+    $response->addJSON('message', $message);
+    if ($message->isSuccess()) {
+        $response->addJSON('db', $GLOBALS['db']);
+        $response->addJSON(
+            'sql_query',
+            PMA_Util::getMessage(null, $sql_query)
+        );
+    } else {
+        $response->isSuccess(false);
+    }
+    exit;
+}
+
+/**
+ * Back to the calling script
+ */
+$_message = $message;
+unset($message);
+?>
diff --git a/phpmyadmin/tbl_operations.php b/phpmyadmin/tbl_operations.php
new file mode 100644
index 0000000..f487ea9
--- /dev/null
+++ b/phpmyadmin/tbl_operations.php
@@ -0,0 +1,378 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ *
+ * @package PhpMyAdmin
+ */
+
+/**
+ *
+ */
+require_once 'libraries/common.inc.php';
+
+/**
+ * functions implementation for this script
+ */
+require_once 'libraries/operations.lib.php';
+
+$pma_table = new PMA_Table($GLOBALS['table'], $GLOBALS['db']);
+$response = PMA_Response::getInstance();
+
+/**
+ * Runs common work
+ */
+require 'libraries/tbl_common.inc.php';
+$url_query .= '&goto=tbl_operations.php&back=tbl_operations.php';
+$url_params['goto'] = $url_params['back'] = 'tbl_operations.php';
+
+/**
+ * Gets relation settings
+ */
+$cfgRelation = PMA_getRelationsParam();
+
+/**
+ * Gets available MySQL charsets and storage engines
+ */
+require_once 'libraries/mysql_charsets.lib.php';
+require_once 'libraries/StorageEngine.class.php';
+
+/**
+ * Class for partition management
+ */
+require_once 'libraries/Partition.class.php';
+
+// reselect current db (needed in some cases probably due to
+// the calling of relation.lib.php)
+PMA_DBI_select_db($GLOBALS['db']);
+
+/**
+ * Gets tables informations
+ */
+require 'libraries/tbl_info.inc.php';
+
+// define some variables here, for improved syntax in the conditionals
+$is_myisam_or_aria = $is_isam = $is_innodb = $is_berkeleydb = $is_aria = $is_pbxt = false;
+// set initial value of these variables, based on the current table engine
+list($is_myisam_or_aria, $is_innodb, $is_isam,
+    $is_berkeleydb, $is_aria, $is_pbxt
+) = PMA_setGlobalVariablesForEngine($tbl_storage_engine);
+
+if ($is_aria) {
+    // the value for transactional can be implicit
+    // (no create option found, in this case it means 1)
+    // or explicit (option found with a value of 0 or 1)
+    // ($transactional may have been set by libraries/tbl_info.inc.php,
+    // from the $create_options)
+    $transactional = (isset($transactional) && $transactional == '0')
+        ? '0'
+        : '1';
+    $page_checksum = (isset($page_checksum)) ? $page_checksum : '';
+}
+
+$reread_info = false;
+$table_alters = array();
+
+/**
+ * If the table has to be moved to some other database
+ */
+if (isset($_REQUEST['submit_move']) || isset($_REQUEST['submit_copy'])) {
+    $_message = '';
+    include_once 'tbl_move_copy.php';
+}
+/**
+ * If the table has to be maintained
+ */
+if (isset($_REQUEST['table_maintenance'])) {
+    include_once 'sql.php';
+    unset($result);
+}
+/**
+ * Updates table comment, type and options if required
+ */
+if (isset($_REQUEST['submitoptions'])) {
+    $_message = '';
+    $warning_messages = array();
+
+    if (isset($_REQUEST['new_name'])) {
+        if ($pma_table->rename($_REQUEST['new_name'])) {
+            $_message .= $pma_table->getLastMessage();
+            $result = true;
+            $GLOBALS['table'] = $pma_table->getName();
+            $reread_info = true;
+            $reload = true;
+        } else {
+            $_message .= $pma_table->getLastError();
+            $result = false;
+        }
+    }
+
+    if (! empty($_REQUEST['new_tbl_storage_engine'])
+        && strtolower($_REQUEST['new_tbl_storage_engine'])
+            !== strtolower($tbl_storage_engine)
+    ) {
+        $new_tbl_storage_engine = $_REQUEST['new_tbl_storage_engine'];
+        // reset the globals for the new engine
+        list($is_myisam_or_aria, $is_innodb, $is_isam,
+            $is_berkeleydb, $is_aria, $is_pbxt
+        ) = PMA_setGlobalVariablesForEngine($new_tbl_storage_engine);
+
+        if ($is_aria) {
+            $transactional = (isset($transactional) && $transactional == '0')
+                ? '0'
+                : '1';
+            $page_checksum = (isset($page_checksum)) ? $page_checksum : '';
+        }
+    } else {
+        $new_tbl_storage_engine = '';
+    }
+
+    $table_alters = PMA_getTableAltersArray(
+        $is_myisam_or_aria, $is_isam, $pack_keys,
+        (empty($checksum) ? '0' : '1'),
+        $is_aria,
+        ((isset($page_checksum)) ? $page_checksum : ''),
+        (empty($delay_key_write) ? '0' : '1'),
+        $is_innodb, $is_pbxt, $row_format,
+        $new_tbl_storage_engine,
+        ((isset($transactional) && $transactional == '0') ? '0' : '1'),
+        $tbl_collation
+    );
+
+    if (count($table_alters) > 0) {
+        $sql_query      = 'ALTER TABLE '
+            . PMA_Util::backquote($GLOBALS['table']);
+        $sql_query     .= "\r\n" . implode("\r\n", $table_alters);
+        $sql_query     .= ';';
+        $result        .= PMA_DBI_query($sql_query) ? true : false;
+        $reread_info    = true;
+        unset($table_alters);
+        $warning_messages = PMA_getWarningMessagesArray();
+    }
+}
+/**
+ * Reordering the table has been requested by the user
+ */
+if (isset($_REQUEST['submitorderby']) && ! empty($_REQUEST['order_field'])) {
+    list($sql_query, $result) = PMA_getQueryAndResultForReorderingTable();
+} // end if
+
+/**
+ * A partition operation has been requested by the user
+ */
+if (isset($_REQUEST['submit_partition'])
+    && ! empty($_REQUEST['partition_operation'])
+) {
+    list($sql_query, $result) = PMA_getQueryAndResultForPartition();
+} // end if
+
+if ($reread_info) {
+    // to avoid showing the old value (for example the AUTO_INCREMENT) after
+    // a change, clear the cache
+    PMA_Table::$cache = array();
+    $page_checksum = $checksum = $delay_key_write = 0;
+    include 'libraries/tbl_info.inc.php';
+}
+unset($reread_info);
+
+if (isset($result) && empty($message_to_show)) {
+    // set to success by default, because result set could be empty
+    // (for example, a table rename)
+    $_type = 'success';
+    if (empty($_message)) {
+        $_message = $result
+            ? PMA_Message::success(
+                __('Your SQL query has been executed successfully')
+            )
+            : PMA_Message::error(__('Error'));
+        // $result should exist, regardless of $_message
+        $_type = $result ? 'success' : 'error';
+
+        if (isset($GLOBALS['ajax_request'])
+            && $GLOBALS['ajax_request'] == true
+        ) {
+            $response = PMA_Response::getInstance();
+            $response->isSuccess($_message->isSuccess());
+            $response->addJSON('message', $_message);
+            $response->addJSON(
+                'sql_query', PMA_Util::getMessage(null, $sql_query)
+            );
+            exit;
+        }
+    }
+    if (! empty($warning_messages)) {
+        $_message = new PMA_Message;
+        $_message->addMessages($warning_messages);
+        $_message->isError(true);
+        if ($GLOBALS['ajax_request'] == true) {
+            $response = PMA_Response::getInstance();
+            $response->isSuccess(false);
+            $response->addJSON('message', $_message);
+            exit;
+        }
+        unset($warning_messages);
+    }
+
+    $response->addHTML(
+        PMA_Util::getMessage($_message, $sql_query, $_type)
+    );
+    unset($_message, $_type);
+}
+
+$url_params['goto']
+    = $url_params['back']
+        = 'tbl_operations.php';
+
+/**
+ * Get columns names
+ */
+$columns = PMA_DBI_get_columns($GLOBALS['db'], $GLOBALS['table']);
+
+/**
+ * Displays the page
+ */
+/**
+ * Order the table
+ */
+$response->addHTML(PMA_getHtmlForOrderTheTable($columns));
+
+/**
+ * Move table
+ */
+$response->addHTML(PMA_getHtmlForMoveTable());
+
+if (strstr($show_comment, '; InnoDB free') === false) {
+    if (strstr($show_comment, 'InnoDB free') === false) {
+        // only user entered comment
+        $comment = $show_comment;
+    } else {
+        // here we have just InnoDB generated part
+        $comment = '';
+    }
+} else {
+    // remove InnoDB comment from end, just the minimal part (*? is non greedy)
+    $comment = preg_replace('@; InnoDB free:.*?$@', '', $show_comment);
+}
+
+// PACK_KEYS: MyISAM or ISAM
+// DELAY_KEY_WRITE, CHECKSUM, : MyISAM only
+// AUTO_INCREMENT: MyISAM and InnoDB since 5.0.3, PBXT
+
+// Here should be version check for InnoDB, however it is supported
+// in >5.0.4, >4.1.12 and >4.0.11, so I decided not to
+// check for version
+
+$response->addHTML(
+    PMA_getTableOptionDiv(
+        $comment, $tbl_collation, $tbl_storage_engine,
+        $is_myisam_or_aria, $is_isam, $pack_keys,
+        $auto_increment,
+        (empty($delay_key_write) ? '0' : '1'),
+        ((isset($transactional) && $transactional == '0') ? '0' : '1'),
+        ((isset($page_checksum)) ? $page_checksum : ''),
+        $is_innodb, $is_pbxt, $is_aria, (empty($checksum) ? '0' : '1')
+    )
+);
+
+/**
+ * Copy table
+ */
+$response->addHTML(PMA_getHtmlForCopytable());
+
+$response->addHTML('<br class="clearfloat"/>');
+
+/**
+ * Table maintenance
+ */
+$response->addHTML(
+    PMA_getHtmlForTableMaintenance(
+        $is_myisam_or_aria,
+        $is_innodb,
+        $is_berkeleydb,
+        $url_params
+    )
+);
+
+if (! (isset($db_is_information_schema) && $db_is_information_schema)) {
+    $truncate_table_url_params = array();
+    $drop_table_url_params = array();
+
+    if (! $tbl_is_view
+        && ! (isset($db_is_information_schema) && $db_is_information_schema)
+    ) {
+        $this_sql_query = 'TRUNCATE TABLE '
+            . PMA_Util::backquote($GLOBALS['table']);
+        $truncate_table_url_params = array_merge(
+            $url_params,
+            array(
+                'sql_query' => $this_sql_query,
+                'goto' => 'tbl_structure.php',
+                'reload' => '1',
+                'message_to_show' => sprintf(
+                    __('Table %s has been emptied'),
+                    htmlspecialchars($table)
+                ),
+            )
+        );
+    }
+    if (! (isset($db_is_information_schema) && $db_is_information_schema)) {
+        $this_sql_query = 'DROP TABLE '
+            . PMA_Util::backquote($GLOBALS['table']);
+        $drop_table_url_params = array_merge(
+            $url_params,
+            array(
+                'sql_query' => $this_sql_query,
+                'goto' => 'db_operations.php',
+                'reload' => '1',
+                'purge' => '1',
+                'message_to_show' => sprintf(
+                    ($tbl_is_view
+                        ? __('View %s has been dropped')
+                        : __('Table %s has been dropped')
+                    ),
+                    htmlspecialchars($table)
+                ),
+                // table name is needed to avoid running
+                // PMA_relationsCleanupDatabase() on the whole db later
+                'table' => $GLOBALS['table'],
+            )
+        );
+    }
+    $response->addHTML(
+        PMA_getHtmlForDeleteDataOrTable(
+            $truncate_table_url_params,
+            $drop_table_url_params
+        )
+    );
+}
+$response->addHTML('<br class="clearfloat">');
+
+if (PMA_Partition::havePartitioning()) {
+    $partition_names = PMA_Partition::getPartitionNames($db, $table);
+    // show the Partition maintenance section only if we detect a partition
+    if (! is_null($partition_names[0])) {
+        $response->addHTML(
+            PMA_getHtmlForPartitionMaintenance($partition_names, $url_params)
+        );
+    } // end if
+} // end if
+unset($partition_names);
+
+// Referential integrity check
+// The Referential integrity check was intended for the non-InnoDB
+// tables for which the relations are defined in pmadb
+// so I assume that if the current table is InnoDB, I don't display
+// this choice (InnoDB maintains integrity by itself)
+
+if ($cfgRelation['relwork'] && ! $is_innodb) {
+    PMA_DBI_select_db($GLOBALS['db']);
+    $foreign = PMA_getForeigners($GLOBALS['db'], $GLOBALS['table']);
+
+    if ($foreign) {
+        $response->addHTML(
+            PMA_getHtmlForReferentialIntegrityCheck($foreign, $url_params)
+        );
+    } // end if ($foreign)
+
+} // end  if (!empty($cfg['Server']['relation']))
+
+?>
diff --git a/phpmyadmin/tbl_printview.php b/phpmyadmin/tbl_printview.php
new file mode 100644
index 0000000..78bb961
--- /dev/null
+++ b/phpmyadmin/tbl_printview.php
@@ -0,0 +1,463 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * Print view for table
+ *
+ * @package PhpMyAdmin
+ */
+
+/**
+ *
+ */
+require_once 'libraries/common.inc.php';
+
+$response = PMA_Response::getInstance();
+$response->getHeader()->enablePrintView();
+
+require 'libraries/tbl_common.inc.php';
+
+// Check parameters
+
+if (! isset($the_tables) || ! is_array($the_tables)) {
+    $the_tables = array();
+}
+
+/**
+ * Gets the relations settings
+ */
+require_once 'libraries/transformations.lib.php';
+require_once 'libraries/Index.class.php';
+
+$cfgRelation = PMA_getRelationsParam();
+
+/**
+ * Defines the url to return to in case of error in a sql statement
+ */
+if (strlen($table)) {
+    $err_url = 'tbl_sql.php?' . PMA_generate_common_url($db, $table);
+} else {
+    $err_url = 'db_sql.php?' . PMA_generate_common_url($db);
+}
+
+
+/**
+ * Selects the database
+ */
+PMA_DBI_select_db($db);
+
+
+/**
+ * Multi-tables printview
+ */
+if (isset($selected_tbl) && is_array($selected_tbl)) {
+    $the_tables   = $selected_tbl;
+} elseif (strlen($table)) {
+    $the_tables[] = $table;
+}
+$multi_tables     = (count($the_tables) > 1);
+
+if ($multi_tables) {
+    $tbl_list     = '';
+    foreach ($the_tables as $key => $table) {
+        $tbl_list .= (empty($tbl_list) ? '' : ', ')
+                  . PMA_Util::backquote($table);
+    }
+    echo '<strong>'.  __('Showing tables') . ': '
+        . htmlspecialchars($tbl_list) . '</strong>' . "\n";
+    echo '<hr />' . "\n";
+} // end if
+
+$tables_cnt = count($the_tables);
+$counter    = 0;
+
+foreach ($the_tables as $key => $table) {
+    if ($counter + 1 >= $tables_cnt) {
+        $breakstyle = '';
+    } else {
+        $breakstyle = ' style="page-break-after: always;"';
+    }
+    $counter++;
+    echo '<div' . $breakstyle . '>' . "\n";
+    echo '<h1>' . htmlspecialchars($table) . '</h1>' . "\n";
+
+    /**
+     * Gets table informations
+     */
+    $showtable    = PMA_Table::sGetStatusInfo($db, $table);
+    $num_rows     = (isset($showtable['Rows']) ? $showtable['Rows'] : 0);
+    $show_comment = (isset($showtable['Comment']) ? $showtable['Comment'] : '');
+
+    $tbl_is_view = PMA_Table::isView($db, $table);
+
+    /**
+     * Gets fields properties
+     */
+    $columns = PMA_DBI_get_columns($db, $table);
+
+
+    // We need this to correctly learn if a TIMESTAMP is NOT NULL, since
+    // SHOW FULL FIELDS or INFORMATION_SCHEMA incorrectly says NULL
+    // and SHOW CREATE TABLE says NOT NULL (tested
+    // in MySQL 4.0.25 and 5.0.21, http://bugs.mysql.com/20910).
+
+    $show_create_table = PMA_DBI_fetch_value(
+        'SHOW CREATE TABLE ' . PMA_Util::backquote($db) . '.'
+        . PMA_Util::backquote($table),
+        0, 1
+    );
+    $analyzed_sql = PMA_SQP_analyze(PMA_SQP_parse($show_create_table));
+
+    // Check if we can use Relations
+    // Find which tables are related with the current one and write it in
+    // an array
+    $res_rel  = PMA_getForeigners($db, $table);
+    $have_rel = (bool) count($res_rel);
+
+    /**
+     * Displays the comments of the table if MySQL >= 3.23
+     */
+    if (!empty($show_comment)) {
+        echo __('Table comments') . ': '
+            . htmlspecialchars($show_comment) . '<br /><br />';
+    }
+
+    /**
+     * Displays the table structure
+     */
+    echo '<table style="width: 100%;">';
+    echo '<thead>';
+    echo '<tr>';
+    echo '<th>' . __('Column') . '</th>';
+    echo '<th>' . __('Type') . '</th>';
+    echo '<th>' . __('Null') . '</th>';
+    echo '<th>' . __('Default') . '</th>';
+    if ($have_rel) {
+        echo '<th>' . __('Links to') . '</th>' . "\n";
+    }
+    echo '    <th>' . __('Comments') . '</th>' . "\n";
+    if ($cfgRelation['mimework']) {
+        echo '    <th>MIME</th>' . "\n";
+    }
+    echo '</tr>';
+    echo '</thead>';
+    echo '<tbody>';
+    foreach ($columns as $row) {
+        $extracted_columnspec = PMA_Util::extractColumnSpec($row['Type']);
+        $type = $extracted_columnspec['print_type'];
+        $attribute = $extracted_columnspec['attribute'];
+
+        if (! isset($row['Default'])) {
+            if ($row['Null'] != ''  && $row['Null'] != 'NO') {
+                $row['Default'] = '<i>NULL</i>';
+            }
+        } else {
+            $row['Default'] = htmlspecialchars($row['Default']);
+        }
+        $field_name = htmlspecialchars($row['Field']);
+
+        // here, we have a TIMESTAMP that SHOW FULL COLUMNS reports as having the
+        // NULL attribute, but SHOW CREATE TABLE says the contrary. Believe
+        // the latter.
+        /**
+         * @todo merge this logic with the one in tbl_structure.php
+         * or move it in a function similar to PMA_DBI_get_columns_full()
+         * but based on SHOW CREATE TABLE because information_schema
+         * cannot be trusted in this case (MySQL bug)
+         */
+        if (! empty($analyzed_sql[0]['create_table_fields'][$field_name]['type'])
+            && $analyzed_sql[0]['create_table_fields'][$field_name]['type'] == 'TIMESTAMP'
+            && $analyzed_sql[0]['create_table_fields'][$field_name]['timestamp_not_null']
+        ) {
+            $row['Null'] = '';
+        }
+
+        echo "\n";
+        echo '<tr><td>';
+
+        if (isset($pk_array[$row['Field']])) {
+            echo '    <u>' . $field_name . '</u>' . "\n";
+        } else {
+            echo '    ' . $field_name . "\n";
+        }
+        echo '</td>';
+        echo '<td>' . $type. '<bdo dir="ltr"></bdo></td>';
+        echo '<td>';
+        echo (($row['Null'] == '' || $row['Null'] == 'NO')
+            ? __('No')
+            : __('Yes'));
+        echo ' </td>';
+        echo '<td>';
+        if (isset($row['Default'])) {
+            echo $row['Default'];
+        }
+        echo ' </td>';
+        if ($have_rel) {
+            echo '    <td>';
+            if (isset($res_rel[$field_name])) {
+                echo htmlspecialchars(
+                    $res_rel[$field_name]['foreign_table']
+                    . ' -> ' . $res_rel[$field_name]['foreign_field']
+                );
+            }
+            echo ' </td>' . "\n";
+        }
+        echo '    <td>';
+        $comments = PMA_getComments($db, $table);
+        if (isset($comments[$field_name])) {
+            echo htmlspecialchars($comments[$field_name]);
+        }
+        echo ' </td>' . "\n";
+        if ($cfgRelation['mimework']) {
+            $mime_map = PMA_getMIME($db, $table, true);
+
+            echo '    <td>';
+            if (isset($mime_map[$field_name])) {
+                echo htmlspecialchars(
+                    str_replace('_', '/', $mime_map[$field_name]['mimetype'])
+                );
+            }
+            echo ' </td>' . "\n";
+        }
+        echo '</tr>';
+    } // end foreach
+    echo '</tbody>';
+    echo '</table>';
+    if (! $tbl_is_view && !PMA_is_system_schema($db)) {
+        /**
+         * Displays indexes
+         */
+        echo PMA_Index::getView($table, $db, true);
+
+        /**
+         * Displays Space usage and row statistics
+         *
+         */
+        if ($cfg['ShowStats']) {
+            $nonisam     = false;
+            if (isset($showtable['Type'])
+                && ! preg_match('@ISAM|HEAP at i', $showtable['Type'])
+            ) {
+                $nonisam = true;
+            }
+            if ($nonisam == false) {
+                // Gets some sizes
+
+                $mergetable = PMA_Table::isMerge($db, $table);
+
+                list($data_size, $data_unit) = PMA_Util::formatByteDown(
+                    $showtable['Data_length']
+                );
+                if ($mergetable == false) {
+                    list($index_size, $index_unit)
+                        = PMA_Util::formatByteDown(
+                            $showtable['Index_length']
+                        );
+                }
+                if (isset($showtable['Data_free']) && $showtable['Data_free'] > 0) {
+                    list($free_size, $free_unit)
+                        = PMA_Util::formatByteDown(
+                            $showtable['Data_free']
+                        );
+                    list($effect_size, $effect_unit)
+                        = PMA_Util::formatByteDown(
+                            $showtable['Data_length'] + $showtable['Index_length']
+                            - $showtable['Data_free']
+                        );
+                } else {
+                    unset($free_size);
+                    unset($free_unit);
+                    list($effect_size, $effect_unit)
+                        = PMA_Util::formatByteDown(
+                            $showtable['Data_length'] + $showtable['Index_length']
+                        );
+                }
+                list($tot_size, $tot_unit) = PMA_Util::formatByteDown(
+                    $showtable['Data_length'] + $showtable['Index_length']
+                );
+                if ($num_rows > 0) {
+                    list($avg_size, $avg_unit)
+                        = PMA_Util::formatByteDown(
+                            ($showtable['Data_length'] + $showtable['Index_length'])
+                            / $showtable['Rows'],
+                            6,
+                            1
+                        );
+                }
+
+                // Displays them
+                echo '<br /><br />';
+
+                echo '<table cellspacing="0" cellpadding="0">';
+                echo "\n";
+                echo '<tr>';
+
+                // Space usage
+                echo '<td class="vtop">';
+                echo '<big>' . __('Space usage') . ':</big>';
+                echo '<table width="100%">';
+                echo '<tr>';
+                echo '<td style="padding-right: 10px">' . __('Data') . '</td>';
+                echo '<td class="right">' . $data_size . '</td>';
+                echo '<td>' . $data_unit . '</td>';
+                echo '</tr>';
+                if (isset($index_size)) {
+                    echo "\n";
+                    echo '<tr>';
+                    echo '<td style="padding-right: 10px">' . __('Index') . '</td>';
+                    echo '<td class="right">' . $index_size . '</td>';
+                    echo '<td>' . $index_unit. '</td>';
+                    echo '</tr>';
+                }
+                if (isset($free_size)) {
+                    echo "\n";
+                    echo '<tr style="color: #bb0000">';
+                    echo '<td style="padding-right: 10px">';
+                    echo __('Overhead');
+                    echo '</td>';
+                    echo '<td class="right">' . $free_size . '</td>';
+                    echo '<td>' . $free_unit . '</td>';
+                    echo '</tr>';
+                    echo '<tr>';
+                    echo '<td style="padding-right: 10px">';
+                    echo __('Effective');
+                    echo '</td>';
+                    echo '<td class="right">' . $effect_size . '</td>';
+                    echo '<td>' . $effect_unit . '</td>';
+                    echo '</tr>';
+                }
+                if (isset($tot_size) && $mergetable == false) {
+                    echo "\n";
+                    echo '<tr>';
+                    echo '<td style="padding-right: 10px">' . __('Total') . '</td>';
+                    echo '<td class="right">' . $tot_size . '</td>';
+                    echo '<td>' . $tot_unit . '</td>';
+                    echo '</tr>';
+                }
+                echo "\n";
+                echo '</table>';
+                echo '</td>';
+
+                echo '<td width="20"> </td>';
+
+                // Rows Statistic
+                echo "\n";
+                echo '<td class="vtop">';
+                echo '<big>' . __('Row Statistics') . ':</big>';
+                echo '<table width="100%">';
+                if (isset($showtable['Row_format'])) {
+                    echo "\n";
+                    echo '<tr>';
+                    echo '<td>' . __('Format') . '</td>';
+                    echo '<td class="' . $cell_align_left . '">';
+                    if ($showtable['Row_format'] == 'Fixed') {
+                        echo __('static');
+                    } elseif ($showtable['Row_format'] == 'Dynamic') {
+                        echo __('dynamic');
+                    } else {
+                        echo $showtable['Row_format'];
+                    }
+                    echo '</td>';
+                    echo '</tr>';
+                }
+                if (isset($showtable['Rows'])) {
+                    echo "\n";
+                    echo '<tr>';
+                    echo '<td>' . __('Rows') . '</td>';
+                    echo '<td class="right">';
+                    echo PMA_Util::formatNumber($showtable['Rows'], 0);
+                    echo '</td>';
+                    echo '</tr>';
+                }
+                if (isset($showtable['Avg_row_length'])
+                    && $showtable['Avg_row_length'] > 0
+                ) {
+                    echo "\n";
+                    echo '<tr>';
+                    echo '<td>' . __('Row length') . ' ø</td>';
+                    echo '<td>';
+                    echo PMA_Util::formatNumber(
+                        $showtable['Avg_row_length'], 0
+                    );
+                    echo '</td>';
+                    echo '</tr>';
+                }
+                if (isset($showtable['Data_length'])
+                    && $showtable['Rows'] > 0
+                    && $mergetable == false
+                ) {
+                    echo "\n";
+                    echo '<tr>';
+                    echo '<td>' . __('Row size') . ' ø</td>';
+                    echo '<td class="right">';
+                    echo $avg_size . ' ' . $avg_unit;
+                    echo '</td>';
+                    echo '</tr>';
+                }
+                if (isset($showtable['Auto_increment'])) {
+                    echo "\n";
+                    echo '<tr>';
+                    echo '<td>' . __('Next autoindex'). ' </td>';
+                    echo '<td class="right">';
+                    echo PMA_Util::formatNumber(
+                        $showtable['Auto_increment'], 0
+                    );
+                    echo '</td>';
+                    echo '</tr>';
+                }
+                if (isset($showtable['Create_time'])) {
+                    echo "\n";
+                    echo '<tr>';
+                    echo '<td>' . __('Creation') . '</td>';
+                    echo '<td class="right">';
+                    echo PMA_Util::localisedDate(
+                        strtotime($showtable['Create_time'])
+                    );
+                    echo '</td>';
+                    echo '</tr>';
+                }
+                if (isset($showtable['Update_time'])) {
+                    echo "\n";
+                    echo '<tr>';
+                    echo '<td>' . __('Last update') . '</td>';
+                    echo '<td class="right">';
+                    echo PMA_Util::localisedDate(
+                        strtotime($showtable['Update_time'])
+                    );
+                    echo '</td>';
+                    echo '</tr>';
+                }
+                if (isset($showtable['Check_time'])) {
+                    echo "\n";
+                    echo '<tr>';
+                    echo '<td>' . __('Last check') . '</td>';
+                    echo '<td class="right">';
+                    echo PMA_Util::localisedDate(
+                        strtotime($showtable['Check_time'])
+                    );
+                    echo '</td>';
+                    echo '</tr>';
+                }
+
+                echo "\n";
+                echo '</table>';
+                echo '</td>';
+                echo '</tr>';
+                echo '</table>';
+            } // end if ($nonisam == false)
+        } // end if ($cfg['ShowStats'])
+    }
+    if ($multi_tables) {
+        unset($num_rows, $show_comment);
+        echo '<hr />' . "\n";
+    } // end if
+    echo '</div>' . "\n";
+
+} // end while
+
+/**
+ * Displays the footer
+ */
+echo PMA_Util::getButton();
+
+echo "<div id='PMA_disable_floating_menubar'></div>\n";
+?>
diff --git a/phpmyadmin/tbl_relation.php b/phpmyadmin/tbl_relation.php
new file mode 100644
index 0000000..20ee482
--- /dev/null
+++ b/phpmyadmin/tbl_relation.php
@@ -0,0 +1,689 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * Display table relations for viewing and editing
+ *
+ * includes phpMyAdmin relations and InnoDB relations
+ *
+ * @todo fix name handling: currently names with dots (.) are not properly handled
+ * for internal relations (but foreign keys relations are correct)
+ * @todo foreign key constraints require both fields being of equal type and size
+ * @todo check foreign fields to be from same type and size, all other makes no sense
+ * @todo add an link to create an index required for constraints,
+ * or an option to do automatically
+ * @todo if above todos are fullfilled we can add all fields meet requirements
+ * in the select dropdown
+ * @package PhpMyAdmin
+ */
+
+/**
+ * Gets some core libraries
+ */
+require_once 'libraries/common.inc.php';
+require_once 'libraries/index.lib.php';
+
+$response = PMA_Response::getInstance();
+$header   = $response->getHeader();
+$scripts  = $header->getScripts();
+$scripts->addFile('tbl_relation.js');
+$scripts->addFile('indexes.js');
+
+/**
+ * Sets globals from $_POST
+ */
+$post_params = array(
+    'destination',
+    'destination_foreign',
+    'display_field',
+    'fields_name',
+    'on_delete',
+    'on_update'
+);
+
+foreach ($post_params as $one_post_param) {
+    if (isset($_POST[$one_post_param])) {
+        $GLOBALS[$one_post_param] = $_POST[$one_post_param];
+    }
+}
+
+/**
+ * Gets tables informations
+ */
+require_once 'libraries/tbl_info.inc.php';
+
+$options_array = array(
+    'CASCADE'   => 'CASCADE',
+    'SET_NULL'  => 'SET NULL',
+    'NO_ACTION' => 'NO ACTION',
+    'RESTRICT'  => 'RESTRICT',
+);
+
+/**
+ * Gets the relation settings
+ */
+$cfgRelation = PMA_getRelationsParam();
+
+/**
+ * Updates
+ */
+if ($cfgRelation['relwork']) {
+    $existrel = PMA_getForeigners($db, $table, '', 'internal');
+}
+if (PMA_Util::isForeignKeySupported($tbl_storage_engine)) {
+    $existrel_foreign = PMA_getForeigners($db, $table, '', 'foreign');
+}
+if ($cfgRelation['displaywork']) {
+    $disp     = PMA_getDisplayField($db, $table);
+}
+
+// will be used in the logic for internal relations and foreign keys:
+$multi_edit_columns_name = isset($_REQUEST['fields_name'])
+    ? $_REQUEST['fields_name']
+    : null;
+
+$html_output = '';
+
+// u p d a t e s   f o r   I n t e r n a l    r e l a t i o n s
+if (isset($destination) && $cfgRelation['relwork']) {
+
+    foreach ($destination as $master_field_md5 => $foreign_string) {
+        $upd_query = false;
+
+        // Map the fieldname's md5 back to its real name
+        $master_field = $multi_edit_columns_name[$master_field_md5];
+
+        if (! empty($foreign_string)) {
+            $foreign_string = trim($foreign_string, '`');
+            list($foreign_db, $foreign_table, $foreign_field)
+                = explode('.', $foreign_string);
+            if (! isset($existrel[$master_field])) {
+                $upd_query  = 'INSERT INTO '
+                    . PMA_Util::backquote($GLOBALS['cfgRelation']['db'])
+                    . '.' . PMA_Util::backquote($cfgRelation['relation'])
+                    . '(master_db, master_table, master_field, foreign_db,'
+                    . ' foreign_table, foreign_field)'
+                    . ' values('
+                    . '\'' . PMA_Util::sqlAddSlashes($db) . '\', '
+                    . '\'' . PMA_Util::sqlAddSlashes($table) . '\', '
+                    . '\'' . PMA_Util::sqlAddSlashes($master_field) . '\', '
+                    . '\'' . PMA_Util::sqlAddSlashes($foreign_db) . '\', '
+                    . '\'' . PMA_Util::sqlAddSlashes($foreign_table) . '\','
+                    . '\'' . PMA_Util::sqlAddSlashes($foreign_field) . '\')';
+            } elseif ($existrel[$master_field]['foreign_db'] . '.' .$existrel[$master_field]['foreign_table'] . '.' . $existrel[$master_field]['foreign_field'] != $foreign_string) {
+                $upd_query  = 'UPDATE '
+                    . PMA_Util::backquote($GLOBALS['cfgRelation']['db'])
+                    . '.' . PMA_Util::backquote($cfgRelation['relation']) . ' SET'
+                    . ' foreign_db       = \''
+                    . PMA_Util::sqlAddSlashes($foreign_db) . '\', '
+                    . ' foreign_table    = \''
+                    . PMA_Util::sqlAddSlashes($foreign_table) . '\', '
+                    . ' foreign_field    = \''
+                    . PMA_Util::sqlAddSlashes($foreign_field) . '\' '
+                    . ' WHERE master_db  = \'' . PMA_Util::sqlAddSlashes($db) . '\''
+                    . ' AND master_table = \''
+                    . PMA_Util::sqlAddSlashes($table) . '\''
+                    . ' AND master_field = \''
+                    . PMA_Util::sqlAddSlashes($master_field) . '\'';
+            } // end if... else....
+        } elseif (isset($existrel[$master_field])) {
+            $upd_query = 'DELETE FROM '
+                . PMA_Util::backquote($GLOBALS['cfgRelation']['db'])
+                . '.' . PMA_Util::backquote($cfgRelation['relation'])
+                . ' WHERE master_db  = \'' . PMA_Util::sqlAddSlashes($db) . '\''
+                . ' AND master_table = \'' . PMA_Util::sqlAddSlashes($table) . '\''
+                . ' AND master_field = \'' . PMA_Util::sqlAddSlashes($master_field)
+                . '\'';
+        } // end if... else....
+        if ($upd_query) {
+            PMA_queryAsControlUser($upd_query);
+        }
+    } // end while
+} // end if (updates for internal relations)
+
+// u p d a t e s    f o r    f o r e i g n    k e y s
+// (for now, one index name only; we keep the definitions if the
+// foreign db is not the same)
+
+if (isset($_REQUEST['destination_foreign'])) {
+    $display_query = '';
+    $seen_error = false;
+    foreach ($_REQUEST['destination_foreign'] as $master_field_md5 => $foreign_string) {
+        $create = false;
+        $drop = false;
+
+        // Map the fieldname's md5 back to it's real name
+        $master_field = $multi_edit_columns_name[$master_field_md5];
+
+        if (! empty($foreign_string)) {
+            list($foreign_db, $foreign_table, $foreign_field)
+                = PMA_backquoteSplit($foreign_string);
+            if (! isset($existrel_foreign[$master_field])) {
+                // no key defined for this field
+                $create = true;
+            } elseif (PMA_Util::backquote($existrel_foreign[$master_field]['foreign_db']) != $foreign_db
+                || PMA_Util::backquote($existrel_foreign[$master_field]['foreign_table']) != $foreign_table
+                || PMA_Util::backquote($existrel_foreign[$master_field]['foreign_field']) != $foreign_field
+                || $_REQUEST['constraint_name'][$master_field_md5] != $existrel_foreign[$master_field]['constraint']
+                || ($_REQUEST['on_delete'][$master_field_md5] != (! empty($existrel_foreign[$master_field]['on_delete']) ? $existrel_foreign[$master_field]['on_delete'] : 'RESTRICT'))
+                || ($_REQUEST['on_update'][$master_field_md5] != (! empty($existrel_foreign[$master_field]['on_update']) ? $existrel_foreign[$master_field]['on_update'] : 'RESTRICT'))
+            ) {
+                // another foreign key is already defined for this field
+                // or an option has been changed for ON DELETE or ON UPDATE
+                $drop = true;
+                $create = true;
+            } // end if... else....
+        } elseif (isset($existrel_foreign[$master_field])) {
+            $drop = true;
+        } // end if... else....
+
+        $tmp_error_drop = false;
+        if ($drop) {
+            $drop_query = PMA_getSQLToDropForeignKey(
+                $table, $existrel_foreign[$master_field]['constraint']
+            );
+            $display_query .= $drop_query . "\n";
+            PMA_DBI_try_query($drop_query);
+            $tmp_error_drop = PMA_DBI_getError();
+
+            if (! empty($tmp_error_drop)) {
+                $seen_error = true;
+                $html_output .= PMA_Util::mysqlDie(
+                    $tmp_error_drop, $drop_query, false, '', false
+                );
+                continue;
+            }
+        }
+        $tmp_error_create = false;
+        if ($create) {
+            $create_query = PMA_getSQLToCreateForeignKey(
+                $table, $master_field, $foreign_db, $foreign_table, $foreign_field,
+                $_REQUEST['constraint_name'][$master_field_md5],
+                $options_array[$_REQUEST['on_delete'][$master_field_md5]],
+                $options_array[$_REQUEST['on_update'][$master_field_md5]]
+            );
+
+            $display_query .= $create_query . "\n";
+            PMA_DBI_try_query($create_query);
+            $tmp_error_create = PMA_DBI_getError();
+            if (! empty($tmp_error_create)) {
+                $seen_error = true;
+
+                if (substr($tmp_error_create, 1, 4) == '1005') {
+                    $message = PMA_Message::error(
+                        __('Error creating foreign key on %1$s (check data types)')
+                    );
+                    $message->addParam($master_field);
+                    $message->display();
+                } else {
+                    $html_output .= PMA_Util::mysqlDie(
+                        $tmp_error_create, $create_query, false, '', false
+                    );
+                }
+                $html_output .= PMA_Util::showMySQLDocu(
+                    'manual_Table_types', 'InnoDB_foreign_key_constraints'
+                ) . "\n";
+            }
+
+            // this is an alteration and the old constraint has been dropped
+            // without creation of a new one
+            if ($drop && $create && empty($tmp_error_drop)
+                && ! empty($tmp_error_create)
+            ) {
+                // a rollback may be better here
+                $sql_query_recreate = '# Restoring the dropped constraint...' . "\n";
+                $sql_query_recreate .= PMA_getSQLToCreateForeignKey(
+                    $table, $master_field,
+                    PMA_Util::backquote($existrel_foreign[$master_field]['foreign_db']),
+                    PMA_Util::backquote($existrel_foreign[$master_field]['foreign_table']),
+                    PMA_Util::backquote($existrel_foreign[$master_field]['foreign_field']),
+                    $existrel_foreign[$master_field]['constraint'],
+                    $options_array[$existrel_foreign[$master_field]['on_delete']],
+                    $options_array[$existrel_foreign[$master_field]['on_update']]
+                );
+                $display_query .= $sql_query_recreate . "\n";
+                PMA_DBI_try_query($sql_query_recreate);
+            }
+        }
+    } // end foreach
+    if (! empty($display_query) && ! $seen_error) {
+        $html_output .= PMA_Util::getMessage(
+            __('Your SQL query has been executed successfully'),
+            null, 'success'
+        );
+    }
+} // end if isset($destination_foreign)
+
+
+// U p d a t e s   f o r   d i s p l a y   f i e l d
+
+if ($cfgRelation['displaywork'] && isset($display_field)) {
+    $upd_query = false;
+    if ($disp) {
+        if ($display_field != '') {
+            $upd_query = 'UPDATE '
+                . PMA_Util::backquote($GLOBALS['cfgRelation']['db'])
+                . '.' . PMA_Util::backquote($cfgRelation['table_info'])
+                . ' SET display_field = \''
+                . PMA_Util::sqlAddSlashes($display_field) . '\''
+                . ' WHERE db_name  = \'' . PMA_Util::sqlAddSlashes($db) . '\''
+                . ' AND table_name = \'' . PMA_Util::sqlAddSlashes($table) . '\'';
+        } else {
+            $upd_query = 'DELETE FROM '
+                . PMA_Util::backquote($GLOBALS['cfgRelation']['db'])
+                . '.' . PMA_Util::backquote($cfgRelation['table_info'])
+                . ' WHERE db_name  = \'' . PMA_Util::sqlAddSlashes($db) . '\''
+                . ' AND table_name = \'' . PMA_Util::sqlAddSlashes($table) . '\'';
+        }
+    } elseif ($display_field != '') {
+        $upd_query = 'INSERT INTO '
+            . PMA_Util::backquote($GLOBALS['cfgRelation']['db'])
+            . '.' . PMA_Util::backquote($cfgRelation['table_info'])
+            . '(db_name, table_name, display_field) VALUES('
+            . '\'' . PMA_Util::sqlAddSlashes($db) . '\','
+            . '\'' . PMA_Util::sqlAddSlashes($table) . '\','
+            . '\'' . PMA_Util::sqlAddSlashes($display_field) . '\')';
+    }
+
+    if ($upd_query) {
+        PMA_queryAsControlUser($upd_query);
+    }
+} // end if
+
+// If we did an update, refresh our data
+if (isset($destination) && $cfgRelation['relwork']) {
+    $existrel = PMA_getForeigners($db, $table, '', 'internal');
+}
+if (isset($destination_foreign)
+    && PMA_Util::isForeignKeySupported($tbl_storage_engine)
+) {
+    $existrel_foreign = PMA_getForeigners($db, $table, '', 'foreign');
+}
+
+if ($cfgRelation['displaywork']) {
+    $disp     = PMA_getDisplayField($db, $table);
+}
+
+
+/**
+ * Dialog
+ */
+
+// common form
+$html_output .= '<form method="post" action="tbl_relation.php">' . "\n"
+    . PMA_generate_common_hidden_inputs($db, $table);
+
+
+// relations
+
+if ($cfgRelation['relwork']
+    || PMA_Util::isForeignKeySupported($tbl_storage_engine)
+) {
+    // To choose relations we first need all tables names in current db
+    // and if the main table supports foreign keys
+    // we use SHOW TABLE STATUS because we need to find other tables of the
+    // same engine.
+
+    if (PMA_Util::isForeignKeySupported($tbl_storage_engine)) {
+        $tab_query = 'SHOW TABLE STATUS FROM ' . PMA_Util::backquote($db);
+        // [0] of the row is the name
+        // [1] is the type
+    } else {
+        $tab_query = 'SHOW TABLES FROM ' . PMA_Util::backquote($db);
+        // [0] of the row is the name
+    }
+
+    $tab_rs = PMA_DBI_query($tab_query, null, PMA_DBI_QUERY_STORE);
+    $selectboxall[] = '';
+    $selectboxall_foreign[] = '';
+
+    while ($curr_table = PMA_DBI_fetch_row($tab_rs)) {
+        $current_table = new PMA_Table($curr_table[0], $db);
+
+        // explicitely ask for non-quoted list of indexed columns
+        $selectboxall = array_merge(
+            $selectboxall,
+            $current_table->getUniqueColumns($backquoted = false)
+        );
+
+        // if foreign keys are supported, collect all keys from other
+        // tables of the same engine
+        if (PMA_Util::isForeignKeySupported($tbl_storage_engine)
+            && isset($curr_table[1])
+            && strtoupper($curr_table[1]) == $tbl_storage_engine
+        ) {
+             // explicitely ask for non-quoted list of indexed columns
+             // need to obtain backquoted values to support dots inside values
+             $selectboxall_foreign = array_merge(
+                 $selectboxall_foreign,
+                 $current_table->getIndexedColumns($backquoted = true)
+             );
+        }
+    } // end while over tables
+} // end if
+
+// Now find out the columns of our $table
+// need to use PMA_DBI_QUERY_STORE with PMA_DBI_num_rows() in mysqli
+$columns = PMA_DBI_get_columns($db, $table);
+
+if (count($columns) > 0) {
+
+    foreach ($columns as $row) {
+        $save_row[] = $row;
+    }
+
+    $saved_row_cnt  = count($save_row);
+    $html_output .= '<fieldset>'
+        . '<legend>' . __('Relations'). '</legend>'
+        . '<table>'
+        . '<tr><th>' . __('Column') . '</th>';
+
+    if ($cfgRelation['relwork']) {
+        $html_output .= '<th>' . __('Internal relation');
+        if (PMA_Util::isForeignKeySupported($tbl_storage_engine)) {
+            $html_output .= PMA_Util::showHint(
+                __(
+                    'An internal relation is not necessary when a corresponding'
+                    . ' FOREIGN KEY relation exists.'
+                )
+            );
+        }
+        $html_output .= '</th>';
+    }
+
+    if (PMA_Util::isForeignKeySupported($tbl_storage_engine)) {
+        // this does not have to be translated, it's part of the MySQL syntax
+        $html_output .= '<th colspan="2">' . __('Foreign key constraint')
+            . ' (' . $tbl_storage_engine . ')';
+        $html_output .= '</th>';
+    }
+    $html_output .= '</tr>';
+
+    $odd_row = true;
+    for ($i = 0; $i < $saved_row_cnt; $i++) {
+        $myfield = $save_row[$i]['Field'];
+        // Use an md5 as array index to avoid having special characters
+        // in the name atttibure (see bug #1746964 )
+        $myfield_md5 = md5($myfield);
+        $myfield_html = htmlspecialchars($myfield);
+
+        $html_output .= '<tr class="' . ($odd_row ? 'odd' : 'even') . '">'
+            . '<td class="center">'
+            . '<strong>' . $myfield_html . '</strong>'
+            . '<input type="hidden" name="fields_name[' . $myfield_md5 . ']"'
+            . ' value="' . $myfield_html . '"/>'
+            . '</td>';
+        $odd_row = ! $odd_row;
+
+        if ($cfgRelation['relwork']) {
+            $html_output .= '<td><select name="destination[' . $myfield_md5 . ']">';
+            // PMA internal relations
+            if (isset($existrel[$myfield])) {
+                $foreign_field    = $existrel[$myfield]['foreign_db'] . '.'
+                         . $existrel[$myfield]['foreign_table'] . '.'
+                         . $existrel[$myfield]['foreign_field'];
+            } else {
+                $foreign_field    = false;
+            }
+            $seen_key = false;
+            foreach ($selectboxall as $value) {
+                $html_output .= '<option value="' . htmlspecialchars($value) . '"';
+                if ($foreign_field && $value == $foreign_field) {
+                    $html_output .= ' selected="selected"';
+                    $seen_key = true;
+                }
+                $html_output .= '>' . htmlspecialchars($value) . '</option>'. "\n";
+            } // end while
+
+            // if the link defined in relationtable points to a foreign field
+            // that is not a key in the foreign table, we show the link
+            // (will not be shown with an arrow)
+            if ($foreign_field && !$seen_key) {
+                $html_output .= '<option value="' . htmlspecialchars($foreign_field)
+                    . '"'
+                    . ' selected="selected">' . $foreign_field . '</option>'. "\n";
+            }
+            $html_output .= '</select>'
+                . '</td>';
+        } // end if (internal relations)
+
+        if (PMA_Util::isForeignKeySupported($tbl_storage_engine)) {
+            $html_output .= '<td>';
+            if (!empty($save_row[$i]['Key'])) {
+                $html_output .= '<span class="formelement">'
+                    . '<select name="destination_foreign[' . $myfield_md5 . ']"'
+                    . ' class="referenced_column_dropdown">';
+                if (isset($existrel_foreign[$myfield])) {
+                    // need to PMA_Util::backquote to support a dot character inside
+                    // an element
+                    $foreign_field = PMA_Util::backquote(
+                        $existrel_foreign[$myfield]['foreign_db']
+                    )
+                    . '.' . PMA_Util::backquote(
+                        $existrel_foreign[$myfield]['foreign_table']
+                    )
+                    . '.' . PMA_Util::backquote(
+                        $existrel_foreign[$myfield]['foreign_field']
+                    );
+                } else {
+                    $foreign_field    = false;
+                }
+
+                $found_foreign_field = false;
+                foreach ($selectboxall_foreign as $value) {
+                    $html_output .= '<option value="'
+                        . htmlspecialchars($value) . '"';
+                    if ($foreign_field && $value == $foreign_field) {
+                        $html_output .= ' selected="selected"';
+                        $found_foreign_field = true;
+                    }
+                    $html_output .= '>' . htmlspecialchars($value)
+                        . '</option>'. "\n";
+                } // end while
+
+                // we did not find the foreign field in the tables of current db,
+                // must be defined in another db so show it to avoid erasing it
+                if (!$found_foreign_field && $foreign_field) {
+                    $html_output .= '<option value="'
+                        . htmlspecialchars($foreign_field) . '"'
+                        . ' selected="selected"'
+                        . '>' . $foreign_field . '</option>' . "\n";
+                }
+                $html_output .= '</select>'
+                    . '</span>';
+
+                // For constraint name
+                $html_output .= '<span class="formelement">';
+                $constraint_name = isset($existrel_foreign[$myfield]['constraint'])
+                    ? $existrel_foreign[$myfield]['constraint'] : '';
+                $html_output .= __('Constraint name');
+                $html_output .= '<input type="text" name="constraint_name['
+                    . $myfield_md5 . ']"'
+                    . ' value="' . $constraint_name . '"/>';
+                $html_output .= '</span>' . "\n";
+
+                $html_output .= '<span class="formelement">';
+                // For ON DELETE and ON UPDATE, the default action
+                // is RESTRICT as per MySQL doc; however, a SHOW CREATE TABLE
+                // won't display the clause if it's set as RESTRICT.
+                $on_delete = isset($existrel_foreign[$myfield]['on_delete'])
+                    ? $existrel_foreign[$myfield]['on_delete'] : 'RESTRICT';
+                $html_output .= PMA_generateDropdown(
+                    'ON DELETE',
+                    'on_delete[' . $myfield_md5 . ']',
+                    $options_array,
+                    $on_delete
+                );
+                $html_output .= '</span>' . "\n";
+
+                $html_output .= '<span class="formelement">' . "\n";
+                $on_update = isset($existrel_foreign[$myfield]['on_update'])
+                    ? $existrel_foreign[$myfield]['on_update'] : 'RESTRICT';
+                $html_output .= PMA_generateDropdown(
+                    'ON UPDATE',
+                    'on_update[' . $myfield_md5 . ']',
+                    $options_array,
+                    $on_update
+                );
+                $html_output .= '</span>' . "\n";
+            } else {
+                $html_output .= __('No index defined! Create one below');
+            } // end if (a key exists)
+            $html_output .= '</td>';
+        } // end if (InnoDB)
+        $html_output .= '</tr>';
+    } // end for
+
+    unset( $myfield, $myfield_md5, $myfield_html);
+    $html_output .= '</table>' . "\n"
+        . '</fieldset>' . "\n";
+
+    if ($cfgRelation['displaywork']) {
+        // Get "display_field" infos
+        $disp = PMA_getDisplayField($db, $table);
+        $html_output .= '<fieldset>'
+            . '<label>' . __('Choose column to display') . ': </label>'
+            . '<select name="display_field">'
+            . '<option value="">---</option>';
+
+        foreach ($save_row AS $row) {
+            $html_output .= '<option value="'
+                . htmlspecialchars($row['Field']) . '"';
+            if (isset($disp) && $row['Field'] == $disp) {
+                $html_output .= ' selected="selected"';
+            }
+            $html_output .= '>' . htmlspecialchars($row['Field'])
+                . '</option>'. "\n";
+        } // end while
+
+        $html_output .= '</select>'
+            . '</fieldset>';
+    } // end if (displayworks)
+
+    $html_output .= '<fieldset class="tblFooters">'
+        . '<input type="submit" value="' . __('Save') . '" />'
+        . '</fieldset>'
+        . '</form>';
+} // end if (we have columns in this table)
+
+if (PMA_Util::isForeignKeySupported($tbl_storage_engine)) {
+    $html_output .= '<div id="index_div" class="ajax" >'
+        . PMA_getHtmlForDisplayIndexes();
+}
+// Render HTML output
+PMA_Response::getInstance()->addHTML($html_output);
+
+/**
+ * Generate dropdown choices
+ *
+ * @param string $dropdown_question Message to display
+ * @param string $select_name       Name of the <select> field
+ * @param array  $choices           Choices for dropdown
+ * @param string $selected_value    Selected value
+ *
+ * @return string The html code for existing value (for selected)
+ *
+ * @access public
+ */
+function PMA_generateDropdown(
+    $dropdown_question, $select_name, $choices, $selected_value
+) {
+    $html_output = htmlspecialchars($dropdown_question) . '  '
+        . '<select name="' . htmlspecialchars($select_name) . '">' . "\n";
+
+    foreach ($choices as $one_value => $one_label) {
+        $html_output .= '<option value="' . htmlspecialchars($one_value) . '"';
+        if ($selected_value == $one_value) {
+            $html_output .= ' selected="selected" ';
+        }
+        $html_output .= '>' . htmlspecialchars($one_label) . '</option>' . "\n";
+    }
+    $html_output .= '</select>' . "\n";
+
+    return $html_output;
+}
+
+/**
+ * Split a string on backquote pairs
+ *
+ * @param string $text original string
+ *
+ * @return array containing the elements (and their surrounding backquotes)
+ *
+ * @access public
+ */
+function PMA_backquoteSplit($text)
+{
+    $elements = array();
+    $final_pos = strlen($text) - 1;
+    $pos = 0;
+    while ($pos <= $final_pos) {
+        $first_backquote = strpos($text, '`', $pos);
+        $second_backquote = strpos($text, '`', $first_backquote + 1);
+        // after the second one, there might be another one which means
+        // this is an escaped backquote
+        if ($second_backquote < $final_pos && '`' == $text[$second_backquote + 1]) {
+            $second_backquote = strpos($text, '`', $second_backquote + 2);
+        }
+        if (false === $first_backquote || false === $second_backquote) {
+            break;
+        }
+        $elements[] = substr(
+            $text, $first_backquote, $second_backquote - $first_backquote + 1
+        );
+        $pos = $second_backquote + 1;
+    }
+    return($elements);
+}
+
+/**
+ * Returns the DROP query for a foreign key constraint
+ *
+ * @param string $table table of the foreign key
+ * @param string $fk    foreign key name
+ *
+ * @return string DROP query for the foreign key constraint
+ */
+function PMA_getSQLToDropForeignKey($table, $fk)
+{
+    return 'ALTER TABLE ' . PMA_Util::backquote($table)
+        . ' DROP FOREIGN KEY ' . PMA_Util::backquote($fk) . ';';
+}
+
+/**
+ * Returns the SQL query for foreign key constraint creation
+ *
+ * @param string $table        table name
+ * @param string $field        field name
+ * @param string $foreignDb    back-quoted foreign database name
+ * @param string $foreignTable back-quoted foreign table name
+ * @param string $foreignField back-quoted foreign field name
+ * @param string $name         name of the constraint
+ * @param string $onDelete     on delete action
+ * @param string $onUpdate     on update action
+ *
+ * @return string SQL query for foreign key constraint creation
+ */
+function PMA_getSQLToCreateForeignKey($table, $field, $foreignDb, $foreignTable,
+    $foreignField, $name = null, $onDelete = null, $onUpdate = null
+) {
+    $sql_query  = 'ALTER TABLE ' . PMA_Util::backquote($table) . ' ADD ';
+    // if user entered a constraint name
+    if (! empty($name)) {
+        $sql_query .= ' CONSTRAINT ' . PMA_Util::backquote($name);
+    }
+
+    $sql_query .= ' FOREIGN KEY (' . PMA_Util::backquote($field) . ')'
+        . ' REFERENCES ' . $foreignDb . '.' . $foreignTable
+        . '(' . $foreignField . ')';
+
+    if (! empty($onDelete)) {
+        $sql_query .= ' ON DELETE ' . $onDelete;
+    }
+    if (! empty($onUpdate)) {
+        $sql_query .= ' ON UPDATE ' . $onUpdate;
+    }
+    $sql_query .= ';';
+
+    return $sql_query;
+}
+?>
diff --git a/phpmyadmin/tbl_replace.php b/phpmyadmin/tbl_replace.php
new file mode 100644
index 0000000..55e53d9
--- /dev/null
+++ b/phpmyadmin/tbl_replace.php
@@ -0,0 +1,398 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * Manipulation of table data like inserting, replacing and updating
+ *
+ * Usally called as form action from tbl_change.php to insert or update table rows
+ *
+ * @todo 'edit_next' tends to not work as expected if used ...
+ * at least there is no order by it needs the original query
+ * and the row number and than replace the LIMIT clause
+ *
+ * @package PhpMyAdmin
+ */
+
+/**
+ * Gets some core libraries
+ */
+require_once 'libraries/common.inc.php';
+
+/**
+ * functions implementation for this script
+ */
+require_once 'libraries/insert_edit.lib.php';
+
+// Check parameters
+PMA_Util::checkParameters(array('db', 'table', 'goto'));
+
+PMA_DBI_select_db($GLOBALS['db']);
+
+/**
+ * Initializes some variables
+ */
+$goto_include = false;
+
+$response = PMA_Response::getInstance();
+$header = $response->getHeader();
+$scripts = $header->getScripts();
+$scripts->addFile('makegrid.js');
+// Needed for generation of Inline Edit anchors
+$scripts->addFile('sql.js');
+$scripts->addFile('indexes.js');
+$scripts->addFile('gis_data_editor.js');
+
+// check whether insert row moode, if so include tbl_change.php
+PMA_isInsertRow();
+
+$after_insert_actions = array('new_insert', 'same_insert', 'edit_next');
+if (isset($_REQUEST['after_insert'])
+    && in_array($_REQUEST['after_insert'], $after_insert_actions)
+) {
+    $url_params['after_insert'] = $_REQUEST['after_insert'];
+    if (isset($_REQUEST['where_clause'])) {
+        foreach ($_REQUEST['where_clause'] as $one_where_clause) {
+            if ($_REQUEST['after_insert'] == 'same_insert') {
+                $url_params['where_clause'][] = $one_where_clause;
+            } elseif ($_REQUEST['after_insert'] == 'edit_next') {
+                PMA_setSessionForEditNext($one_where_clause);
+            }
+        }
+    }
+}
+//get $goto_include for different cases
+$goto_include = PMA_getGotoInclude($goto_include);
+
+// Defines the url to return in case of failure of the query
+$err_url = PMA_getErrorUrl($url_params);
+
+/**
+ * Prepares the update/insert of a row
+ */
+list($loop_array, $using_key, $is_insert, $is_insertignore)
+    = PMA_getParamsForUpdateOrInsert();
+
+$query = array();
+$value_sets = array();
+$func_no_param = array(
+    'CONNECTION_ID',
+    'CURRENT_USER',
+    'CURDATE',
+    'CURTIME',
+    'CURRENT_DATE',
+    'CURRENT_TIME',
+    'DATABASE',
+    'LAST_INSERT_ID',
+    'NOW',
+    'PI',
+    'RAND',
+    'SYSDATE',
+    'UNIX_TIMESTAMP',
+    'USER',
+    'UTC_DATE',
+    'UTC_TIME',
+    'UTC_TIMESTAMP',
+    'UUID',
+    'UUID_SHORT',
+    'VERSION',
+);
+$func_optional_param = array(
+    'RAND',
+    'UNIX_TIMESTAMP',
+);
+
+$gis_from_text_functions = array(
+    'GeomFromText',
+    'GeomCollFromText',
+    'LineFromText',
+    'MLineFromText',
+    'PointFromText',
+    'MPointFromText',
+    'PolyFromText',
+    'MPolyFromText',
+);
+
+$gis_from_wkb_functions = array(
+    'GeomFromWKB',
+    'GeomCollFromWKB',
+    'LineFromWKB',
+    'MLineFromWKB',
+    'PointFromWKB',
+    'MPointFromWKB',
+    'PolyFromWKB',
+    'MPolyFromWKB',
+);
+
+// to create an object of PMA_File class
+require_once './libraries/File.class.php';
+
+$query_fields = array();
+foreach ($loop_array as $rownumber => $where_clause) {
+    // skip fields to be ignored
+    if (! $using_key && isset($_REQUEST['insert_ignore_' . $where_clause])) {
+        continue;
+    }
+
+    // Defines the SET part of the sql query
+    $query_values = array();
+
+    // Map multi-edit keys to single-level arrays, dependent on how we got the fields
+    $multi_edit_colummns
+        = isset($_REQUEST['fields']['multi_edit'][$rownumber])
+        ? $_REQUEST['fields']['multi_edit'][$rownumber]
+        : array();
+    $multi_edit_columns_name
+        = isset($_REQUEST['fields_name']['multi_edit'][$rownumber])
+        ? $_REQUEST['fields_name']['multi_edit'][$rownumber]
+        : null;
+    $multi_edit_columns_prev
+        = isset($_REQUEST['fields_prev']['multi_edit'][$rownumber])
+        ? $_REQUEST['fields_prev']['multi_edit'][$rownumber]
+        : null;
+    $multi_edit_funcs
+        = isset($_REQUEST['funcs']['multi_edit'][$rownumber])
+        ? $_REQUEST['funcs']['multi_edit'][$rownumber]
+        : null;
+    $multi_edit_columns_type
+        = isset($_REQUEST['fields_type']['multi_edit'][$rownumber])
+        ? $_REQUEST['fields_type']['multi_edit'][$rownumber]
+        : null;
+    $multi_edit_columns_null
+        = isset($_REQUEST['fields_null']['multi_edit'][$rownumber])
+        ? $_REQUEST['fields_null']['multi_edit'][$rownumber]
+        : null;
+    $multi_edit_columns_null_prev
+        = isset($_REQUEST['fields_null_prev']['multi_edit'][$rownumber])
+        ? $_REQUEST['fields_null_prev']['multi_edit'][$rownumber]
+        : null;
+    $multi_edit_auto_increment
+        = isset($_REQUEST['auto_increment']['multi_edit'][$rownumber])
+        ? $_REQUEST['auto_increment']['multi_edit'][$rownumber]
+        : null;
+
+    // When a select field is nullified, it's not present in $_REQUEST
+    // so initialize it; this way, the foreach($multi_edit_colummns) will process it
+    foreach ($multi_edit_columns_name as $key => $val) {
+        if (! isset($multi_edit_colummns[$key])) {
+            $multi_edit_colummns[$key] = '';
+        }
+    }
+
+    // Iterate in the order of $multi_edit_columns_name,
+    // not $multi_edit_colummns, to avoid problems
+    // when inserting multiple entries
+    foreach ($multi_edit_columns_name as $key => $colummn_name) {
+        $current_value = $multi_edit_colummns[$key];
+        // Note: $key is an md5 of the fieldname. The actual fieldname is
+        // available in $multi_edit_columns_name[$key]
+
+        $file_to_insert = new PMA_File();
+        $file_to_insert->checkTblChangeForm($key, $rownumber);
+
+        $possibly_uploaded_val = $file_to_insert->getContent();
+
+        if ($file_to_insert->isError()) {
+            $message .= $file_to_insert->getError();
+        }
+        // delete $file_to_insert temporary variable
+        $file_to_insert->cleanUp();
+
+        $current_value = PMA_getCurrentValueForDifferentTypes(
+            $possibly_uploaded_val, $key, $multi_edit_columns_type,
+            $current_value, $multi_edit_auto_increment,
+            $rownumber, $multi_edit_columns_name, $multi_edit_columns_null,
+            $multi_edit_columns_null_prev, $is_insert,
+            $using_key, $where_clause, $table
+        );
+
+        $current_value_as_an_array = PMA_getCurrentValueAsAnArrayForMultipleEdit(
+            $multi_edit_colummns, $multi_edit_columns_name, $multi_edit_funcs,
+            $gis_from_text_functions, $current_value, $gis_from_wkb_functions,
+            $func_optional_param, $func_no_param, $key
+        );
+
+        list($query_values, $query_fields)
+            = PMA_getQueryValuesForInsertAndUpdateInMultipleEdit(
+                $multi_edit_columns_name, $multi_edit_columns_null, $current_value,
+                $multi_edit_columns_prev, $multi_edit_funcs, $is_insert,
+                $query_values, $query_fields, $current_value_as_an_array,
+                $value_sets, $key, $multi_edit_columns_null_prev
+            );
+    } //end of foreach
+
+    if (count($query_values) > 0) {
+        if ($is_insert) {
+            $value_sets[] = implode(', ', $query_values);
+        } else {
+            // build update query
+            $query[] = 'UPDATE ' . PMA_Util::backquote($GLOBALS['db'])
+                . '.' . PMA_Util::backquote($GLOBALS['table'])
+                . ' SET ' . implode(', ', $query_values)
+                . ' WHERE ' . $where_clause
+                . ($_REQUEST['clause_is_unique'] ? '' : ' LIMIT 1');
+        }
+    }
+} // end foreach ($loop_array as $where_clause)
+unset($multi_edit_columns_name, $multi_edit_columns_prev, $multi_edit_funcs,
+    $multi_edit_columns_type, $multi_edit_columns_null, $func_no_param,
+    $multi_edit_auto_increment, $current_value_as_an_array, $key, $current_value,
+    $loop_array, $where_clause, $using_key,  $multi_edit_columns_null_prev);
+
+// Builds the sql query
+if ($is_insert && count($value_sets) > 0) {
+    $query = PMA_buildSqlQuery($is_insertignore, $query_fields, $value_sets);
+} elseif (empty($query)) {
+    // No change -> move back to the calling script
+    //
+    // Note: logic passes here for inline edit
+    $message = PMA_Message::success(__('No change'));
+    $active_page = $goto_include;
+    include '' . PMA_securePath($goto_include);
+    exit;
+}
+unset($multi_edit_colummns, $is_insertignore);
+
+/**
+ * Executes the sql query and get the result, then move back to the calling
+ * page
+ */
+list ($url_params, $total_affected_rows, $last_messages, $warning_messages,
+    $error_messages, $return_to_sql_query)
+        = PMA_executeSqlQuery($url_params, $query);
+
+if ($is_insert && count($value_sets) > 0) {
+    $message = PMA_Message::getMessageForInsertedRows($total_affected_rows);
+} else {
+    $message = PMA_Message::getMessageForAffectedRows($total_affected_rows);
+}
+
+$message->addMessages($last_messages, '<br />');
+
+if (! empty($warning_messages)) {
+    $message->addMessages($warning_messages, '<br />');
+    $message->isError(true);
+}
+if (! empty($error_messages)) {
+    $message->addMessages($error_messages);
+    $message->isError(true);
+}
+unset(
+    $error_messages, $warning_messages, $total_affected_rows,
+    $last_messages, $last_message
+);
+
+/**
+ * The following section only applies to grid editing.
+ * However, verifying isAjax() is not enough to ensure we are coming from
+ * grid editing. If we are coming from the Edit or Copy link in Browse mode,
+ * ajax_page_request is present in the POST parameters.
+ */
+if ($response->isAjax() && ! isset($_POST['ajax_page_request'])) {
+    /**
+     * If we are in grid editing, we need to process the relational and
+     * transformed fields, if they were edited. After that, output the correct
+     * link/transformed value and exit
+     *
+     * Logic taken from libraries/DisplayResults.class.php
+     */
+
+    if (isset($_REQUEST['rel_fields_list']) && $_REQUEST['rel_fields_list'] != '') {
+
+        $map = PMA_getForeigners($db, $table, '', 'both');
+
+        $relation_fields = array();
+        parse_str($_REQUEST['rel_fields_list'], $relation_fields);
+
+        // loop for each relation cell
+        foreach ($relation_fields as $cell_index => $curr_cell_rel_field) {
+            foreach ($curr_cell_rel_field as $relation_field => $relation_field_value) {
+                $where_comparison = "='" . $relation_field_value . "'";
+                $dispval = PMA_getDisplayValueForForeignTableColumn(
+                    $where_comparison, $relation_field_value, $map, $relation_field
+                );
+
+                $extra_data['relations'][$cell_index] = PMA_getLinkForRelationalDisplayField(
+                    $map, $relation_field, $where_comparison,
+                    $dispval, $relation_field_value
+                );
+            }
+        }   // end of loop for each relation cell
+    }
+    if (isset($_REQUEST['do_transformations'])
+        && $_REQUEST['do_transformations'] == true
+    ) {
+        include_once 'libraries/transformations.lib.php';
+        //if some posted fields need to be transformed, generate them here.
+        $mime_map = PMA_getMIME($db, $table);
+
+        if ($mime_map === false) {
+            $mime_map = array();
+        }
+        $edited_values = array();
+        parse_str($_REQUEST['transform_fields_list'], $edited_values);
+
+        if (! isset($extra_data)) {
+            $extra_data = array();
+        }
+        foreach ($mime_map as $transformation) {
+            $file = PMA_securePath($transformation['transformation']);
+            // if only an underscore in the file name, nothing to transform
+            if ($file != '_') {
+                $column_name = $transformation['column_name'];
+                $extra_data = PMA_transformEditedValues(
+                    $db, $table, $transformation, $edited_values, $file,
+                    $column_name, $extra_data
+                );
+            }
+        }   // end of loop for each $mime_map
+    }
+    
+    // Need to check the inline edited value can be truncated by MySQL
+    // without informing while saving
+    $column_name = $_REQUEST['fields_name']['multi_edit'][0][0];
+    
+    PMA_verifyWhetherValueCanBeTruncatedAndAppendExtraData(
+        $db, $table, $column_name, $extra_data
+    );
+    
+    /**Get the total row count of the table*/
+    $extra_data['row_count'] = PMA_Table::countRecords(
+        $_REQUEST['db'], $_REQUEST['table']
+    );
+
+    $extra_data['sql_query']
+        = PMA_Util::getMessage($message, $GLOBALS['display_query']);
+
+    $response = PMA_Response::getInstance();
+    $response->isSuccess($message->isSuccess());
+    $response->addJSON('message', $message);
+    $response->addJSON($extra_data);
+    exit;
+}
+
+if (! empty($return_to_sql_query)) {
+    $disp_query = $GLOBALS['sql_query'];
+    $disp_message = $message;
+    unset($message);
+    $GLOBALS['sql_query'] = $return_to_sql_query;
+}
+
+$scripts->addFile('tbl_change.js');
+
+$active_page = $goto_include;
+
+/**
+ * If user asked for "and then Insert another new row" we have to remove
+ * WHERE clause information so that tbl_change.php does not go back
+ * to the current record
+ */
+if (isset($_REQUEST['after_insert']) && 'new_insert' == $_REQUEST['after_insert']) {
+    unset($_REQUEST['where_clause']);
+}
+
+/**
+ * Load target page.
+ */
+require '' . PMA_securePath($goto_include);
+exit;
+
+?>
diff --git a/phpmyadmin/tbl_row_action.php b/phpmyadmin/tbl_row_action.php
new file mode 100644
index 0000000..d55e5e0
--- /dev/null
+++ b/phpmyadmin/tbl_row_action.php
@@ -0,0 +1,143 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * handle row specifc actions like edit, delete, export
+ *
+ * @package PhpMyAdmin
+ */
+
+/**
+ *
+ */
+require_once 'libraries/common.inc.php';
+require_once 'libraries/mysql_charsets.lib.php';
+
+/**
+ * No rows were selected => show again the query and tell that user.
+ */
+if (! PMA_isValid($_REQUEST['rows_to_delete'], 'array')
+    && ! isset($_REQUEST['mult_btn'])
+) {
+    $disp_message = __('No rows selected');
+    $disp_query = '';
+    include 'sql.php';
+    exit;
+}
+
+if (isset($_REQUEST['submit_mult'])) {
+    $submit_mult = $_REQUEST['submit_mult'];
+    // workaround for IE problem:
+} elseif (isset($_REQUEST['submit_mult_delete_x'])) {
+    $submit_mult = 'row_delete';
+} elseif (isset($_REQUEST['submit_mult_change_x'])) {
+    $submit_mult = 'row_edit';
+} elseif (isset($_REQUEST['submit_mult_export_x'])) {
+    $submit_mult = 'row_export';
+}
+
+// If the 'Ask for confirmation' button was pressed, this can only come
+// from 'delete' mode, so we set it straight away.
+if (isset($_REQUEST['mult_btn'])) {
+    $submit_mult = 'row_delete';
+}
+
+switch($submit_mult) {
+case 'row_delete':
+case 'row_edit':
+case 'row_export':
+    // leave as is
+    break;
+
+case 'export':
+    $submit_mult = 'row_export';
+    break;
+
+case 'delete':
+    $submit_mult = 'row_delete';
+    break;
+
+default:
+case 'edit':
+    $submit_mult = 'row_edit';
+    break;
+}
+
+if (!empty($submit_mult)) {
+    switch($submit_mult) {
+    case 'row_edit':
+        // As we got the rows to be edited from the
+        // 'rows_to_delete' checkbox, we use the index of it as the
+        // indicating WHERE clause. Then we build the array which is used
+        // for the tbl_change.php script.
+        $where_clause = array();
+        foreach ($_REQUEST['rows_to_delete'] as $i => $i_where_clause) {
+            $where_clause[] = urldecode($i_where_clause);
+        }
+
+        $active_page = 'tbl_change.php';
+        include 'tbl_change.php';
+        break;
+
+    case 'row_export':
+        // Needed to allow SQL export
+        $single_table = true;
+
+        // As we got the rows to be exported from the
+        // 'rows_to_delete' checkbox, we use the index of it as the
+        // indicating WHERE clause. Then we build the array which is used
+        // for the tbl_change.php script.
+        $where_clause = array();
+        foreach ($_REQUEST['rows_to_delete'] as $i => $i_where_clause) {
+            $where_clause[] = urldecode($i_where_clause);
+        }
+
+        $active_page = 'tbl_export.php';
+        include 'tbl_export.php';
+        break;
+
+    case 'row_delete':
+    default:
+        $action = 'tbl_row_action.php';
+        $err_url = 'tbl_row_action.php'
+            . PMA_generate_common_url($GLOBALS['url_params']);
+        if (! isset($_REQUEST['mult_btn'])) {
+            $original_sql_query = $sql_query;
+            if (! empty($url_query)) {
+                $original_url_query = $url_query;
+            }
+        }
+        include 'libraries/mult_submits.inc.php';
+        $_url_params = $GLOBALS['url_params'];
+        $_url_params['goto'] = 'tbl_sql.php';
+        $url_query = PMA_generate_common_url($_url_params);
+
+
+        /**
+         * Show result of multi submit operation
+         */
+        // sql_query is not set when user does not confirm multi-delete
+        if ((! empty($submit_mult) || isset($_REQUEST['mult_btn']))
+            && ! empty($sql_query)
+        ) {
+            $disp_message = __('Your SQL query has been executed successfully');
+            $disp_query = $sql_query;
+        }
+
+        if (isset($original_sql_query)) {
+            $sql_query = $original_sql_query;
+        }
+
+        if (isset($original_url_query)) {
+            $url_query = $original_url_query;
+        }
+
+        // this is because sql.php could call tbl_structure
+        // which would think it needs to call mult_submits.inc.php:
+        unset($submit_mult, $_REQUEST['mult_btn']);
+
+        $active_page = 'sql.php';
+        include 'sql.php';
+        break;
+    }
+}
+?>
diff --git a/phpmyadmin/tbl_select.php b/phpmyadmin/tbl_select.php
new file mode 100644
index 0000000..e25c630
--- /dev/null
+++ b/phpmyadmin/tbl_select.php
@@ -0,0 +1,69 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * Handles table search tab
+ *
+ * display table search form, create SQL query from form data
+ * and include sql.php to execute it
+ *
+ * @package PhpMyAdmin
+ */
+
+/**
+ * Gets some core libraries
+ */
+require_once 'libraries/common.inc.php';
+require_once 'libraries/mysql_charsets.lib.php';
+require_once 'libraries/TableSearch.class.php';
+
+$response = PMA_Response::getInstance();
+$header   = $response->getHeader();
+$scripts  = $header->getScripts();
+$scripts->addFile('makegrid.js');
+$scripts->addFile('sql.js');
+$scripts->addFile('tbl_select.js');
+$scripts->addFile('tbl_change.js');
+$scripts->addFile('jquery/jquery-ui-timepicker-addon.js');
+$scripts->addFile('gis_data_editor.js');
+
+$post_params = array(
+    'ajax_request',
+    'session_max_rows'
+);
+foreach ($post_params as $one_post_param) {
+    if (isset($_POST[$one_post_param])) {
+        $GLOBALS[$one_post_param] = $_POST[$one_post_param];
+    }
+}
+
+$table_search = new PMA_TableSearch($db, $table, "normal");
+
+/**
+ * Not selection yet required -> displays the selection form
+ */
+if (! isset($_POST['columnsToDisplay']) && ! isset($_POST['displayAllColumns'])) {
+    // Gets some core libraries
+    include_once 'libraries/tbl_common.inc.php';
+    //$err_url   = 'tbl_select.php' . $err_url;
+    $url_query .= '&goto=tbl_select.php&back=tbl_select.php';
+    /**
+     * Gets table's information
+     */
+    include_once 'libraries/tbl_info.inc.php';
+
+    if (! isset($goto)) {
+        $goto = $GLOBALS['cfg']['DefaultTabTable'];
+    }
+    // Defines the url to return to in case of error in the next sql statement
+    $err_url   = $goto . '?' . PMA_generate_common_url($db, $table);
+    // Displays the table search form
+    $response->addHTML($table_search->getSelectionForm($goto));
+
+} else {
+    /**
+     * Selection criteria have been submitted -> do the work
+     */
+    $sql_query = $table_search->buildSqlQuery();
+    include 'sql.php';
+}
+?>
diff --git a/phpmyadmin/tbl_sql.php b/phpmyadmin/tbl_sql.php
new file mode 100644
index 0000000..b06be27
--- /dev/null
+++ b/phpmyadmin/tbl_sql.php
@@ -0,0 +1,46 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ *
+ * @package PhpMyAdmin
+ */
+
+/**
+ *
+ */
+require_once 'libraries/common.inc.php';
+
+/**
+ * Runs common work
+ */
+$response = PMA_Response::getInstance();
+$header   = $response->getHeader();
+$scripts  = $header->getScripts();
+$scripts->addFile('makegrid.js');
+$scripts->addFile('sql.js');
+
+require 'libraries/tbl_common.inc.php';
+$url_query .= '&goto=tbl_sql.php&back=tbl_sql.php';
+
+require_once 'libraries/sql_query_form.lib.php';
+
+$err_url   = 'tbl_sql.php' . $err_url;
+// After a syntax error, we return to this script
+// with the typed query in the textarea.
+$goto = 'tbl_sql.php';
+$back = 'tbl_sql.php';
+
+/**
+ * Get table information
+ */
+require_once 'libraries/tbl_info.inc.php';
+
+/**
+ * Query box, bookmark, insert data from textfile
+ */
+PMA_sqlQueryForm(
+    true, false,
+    isset($_REQUEST['delimiter']) ? htmlspecialchars($_REQUEST['delimiter']) : ';'
+);
+
+?>
diff --git a/phpmyadmin/tbl_structure.php b/phpmyadmin/tbl_structure.php
new file mode 100644
index 0000000..1999883
--- /dev/null
+++ b/phpmyadmin/tbl_structure.php
@@ -0,0 +1,466 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * Displays table structure infos like fields/columns, indexes, size, rows
+ * and allows manipulation of indexes and columns/fields
+ *
+ * @package PhpMyAdmin
+ */
+
+/**
+ *
+ */
+require_once 'libraries/common.inc.php';
+require_once 'libraries/mysql_charsets.lib.php';
+
+/**
+ * Function implementations for this script
+ */
+require_once 'libraries/structure.lib.php';
+require_once 'libraries/index.lib.php';
+
+$response = PMA_Response::getInstance();
+$header   = $response->getHeader();
+$scripts  = $header->getScripts();
+$scripts->addFile('tbl_structure.js');
+$scripts->addFile('indexes.js');
+
+/**
+ * Handle column moving
+ */
+if (isset($_REQUEST['move_columns'])
+    && is_array($_REQUEST['move_columns'])
+    && $response->isAjax() 
+) {
+    PMA_moveColumns($db, $table);
+    exit;
+}
+
+/**
+ * A click on Change has been made for one column 
+ */
+if (isset($_REQUEST['change_column'])) {
+    PMA_displayHtmlForColumnChange($db, $table, null, 'tbl_structure.php');
+    exit;
+}
+/**
+ * Modifications have been submitted -> updates the table
+ */
+if (isset($_REQUEST['do_save_data'])) {
+    $regenerate = PMA_updateColumns($db, $table);
+    if ($regenerate) {
+        // This happens when updating failed
+        // @todo: do something appropriate
+    } else {
+        // continue to show the table's structure
+        unset($_REQUEST['selected']);
+        unset($_REQUEST['true_selected']);
+    }
+}
+
+/**
+ * handle multiple field commands if required
+ *
+ * submit_mult_*_x comes from IE if <input type="img" ...> is used
+ */
+if (isset($_REQUEST['submit_mult_change_x'])) {
+    $submit_mult = 'change';
+} elseif (isset($_REQUEST['submit_mult_drop_x'])) {
+    $submit_mult = 'drop';
+} elseif (isset($_REQUEST['submit_mult_primary_x'])) {
+    $submit_mult = 'primary';
+} elseif (isset($_REQUEST['submit_mult_index_x'])) {
+    $submit_mult = 'index';
+} elseif (isset($_REQUEST['submit_mult_unique_x'])) {
+    $submit_mult = 'unique';
+} elseif (isset($_REQUEST['submit_mult_spatial_x'])) {
+    $submit_mult = 'spatial';
+} elseif (isset($_REQUEST['submit_mult_fulltext_x'])) {
+    $submit_mult = 'ftext';
+} elseif (isset($_REQUEST['submit_mult_browse_x'])) {
+    $submit_mult = 'browse';
+} elseif (isset($_REQUEST['submit_mult'])) {
+    $submit_mult = $_REQUEST['submit_mult'];
+} elseif (isset($_REQUEST['mult_btn']) && $_REQUEST['mult_btn'] == __('Yes')) {
+    $submit_mult = 'row_delete';
+    if (isset($_REQUEST['selected'])) {
+        $_REQUEST['selected_fld'] = $_REQUEST['selected'];
+    }
+}
+if (! empty($submit_mult)) {
+    if (isset($_REQUEST['selected_fld'])) {
+        $err_url = 'tbl_structure.php?' . PMA_generate_common_url($db, $table);
+        if ($submit_mult == 'browse') {
+            // browsing the table displaying only selected fields/columns
+            $GLOBALS['active_page'] = 'sql.php';
+            $sql_query = '';
+            foreach ($_REQUEST['selected_fld'] as $idx => $sval) {
+                if ($sql_query == '') {
+                    $sql_query .= 'SELECT ' . PMA_Util::backquote($sval);
+                } else {
+                    $sql_query .=  ', ' . PMA_Util::backquote($sval);
+                }
+            }
+            $sql_query .= ' FROM ' . PMA_Util::backquote($db)
+            . '.' . PMA_Util::backquote($table);
+            include 'sql.php';
+            exit;
+        } else {
+            // handle multiple field commands
+            // handle confirmation of deleting multiple fields/columns
+            $action = 'tbl_structure.php';
+            include 'libraries/mult_submits.inc.php';
+            /**
+             * if $submit_mult == 'change', execution will have stopped
+             * at this point
+             */
+
+            if (empty($message)) {
+                $message = PMA_Message::success();
+            }
+        }
+    } else {
+        $response = PMA_Response::getInstance();
+        $response->isSuccess(false);
+        $response->addJSON('message', __('No column selected.'));
+    }
+}
+
+/**
+ * Gets the relation settings
+ */
+$cfgRelation = PMA_getRelationsParam();
+
+/**
+ * Runs common work
+ */
+require_once 'libraries/tbl_common.inc.php';
+$url_query .= '&goto=tbl_structure.php&back=tbl_structure.php';
+$url_params['goto'] = 'tbl_structure.php';
+$url_params['back'] = 'tbl_structure.php';
+
+// Check column names for MySQL reserved words
+if ($cfg['ReservedWordDisableWarning'] === false) {
+    $pma_table = new PMA_Table($table, $db);
+    $columns = $pma_table->getReservedColumnNames();
+    if (! empty($columns)) {
+        foreach ($columns as $column) {
+            $msg = PMA_message::notice(
+                __('The column name \'%s\' is a MySQL reserved keyword.')
+            );
+            $msg->addParam($column);
+            $response->addHTML($msg);
+        }
+    }
+}
+
+/**
+ * Prepares the table structure display
+ */
+
+
+/**
+ * Gets tables informations
+ */
+require_once 'libraries/tbl_info.inc.php';
+
+require_once 'libraries/Index.class.php';
+
+// 2. Gets table keys and retains them
+// @todo should be: $server->db($db)->table($table)->primary()
+$primary = PMA_Index::getPrimary($table, $db);
+
+$columns_with_unique_index = array();
+foreach (PMA_Index::getFromTable($table, $db) as $index) {
+    if ($index->isUnique() && $index->getChoice() == 'UNIQUE') {
+        $columns = $index->getColumns();
+        foreach ($columns as $column_name => $dummy) {
+            $columns_with_unique_index[$column_name] = 1;
+        }
+    }
+}
+unset($index, $columns, $column_name, $dummy);
+
+// 3. Get fields
+$fields = (array) PMA_DBI_get_columns($db, $table, null, true);
+
+// Get more complete field information
+// For now, this is done just for MySQL 4.1.2+ new TIMESTAMP options
+// but later, if the analyser returns more information, it
+// could be executed for any MySQL version and replace
+// the info given by SHOW FULL COLUMNS FROM.
+//
+// We also need this to correctly learn if a TIMESTAMP is NOT NULL, since
+// SHOW FULL COLUMNS or INFORMATION_SCHEMA incorrectly says NULL
+// and SHOW CREATE TABLE says NOT NULL (tested
+// in MySQL 4.0.25 and 5.0.21, http://bugs.mysql.com/20910).
+
+$show_create_table = PMA_DBI_fetch_value(
+    'SHOW CREATE TABLE ' . PMA_Util::backquote($db) . '.'
+    . PMA_Util::backquote($table),
+    0, 1
+);
+$analyzed_sql = PMA_SQP_analyze(PMA_SQP_parse($show_create_table));
+
+/**
+ * prepare table infos
+ */
+// action titles (image or string)
+$titles = PMA_getActionTitlesArray();
+
+// hidden action titles (image and string)
+$hidden_titles = PMA_getHiddenTitlesArray();
+
+/**
+ * Displays the table structure ('show table' works correct since 3.23.03)
+ */
+/* TABLE INFORMATION */
+// table header
+
+
+$HideStructureActions = '';
+if ($GLOBALS['cfg']['PropertiesIconic'] !== true
+    && $GLOBALS['cfg']['HideStructureActions'] === true
+) {
+    $HideStructureActions .= ' HideStructureActions';
+}
+
+$html_form = '<form method="post" action="tbl_structure.php" name="fieldsForm" '
+. 'id="fieldsForm" class="ajax' . $HideStructureActions . '">';
+
+$response->addHTML($html_form);
+$response->addHTML(PMA_generate_common_hidden_inputs($db, $table));
+
+$tabletype = '<input type="hidden" name="table_type" value=';
+if ($db_is_information_schema) {
+    $tabletype .= '"information_schema" />';
+} else if ($tbl_is_view) {
+    $tabletype .= '"view" />';
+} else {
+    $tabletype .= '"table" />';
+}
+$response->addHTML($tabletype);
+
+$tablestructure = '<table id="tablestructure" class="data">';
+$response->addHTML($tablestructure);
+
+
+$response->addHTML(
+    PMA_getHtmlForTableStructureHeader(
+        $db_is_information_schema,
+        $tbl_is_view
+    )
+);
+
+$response->addHTML('<tbody>');
+
+// table body
+
+// prepare comments
+$comments_map = array();
+$mime_map = array();
+
+if ($GLOBALS['cfg']['ShowPropertyComments']) {
+    include_once 'libraries/transformations.lib.php';
+    $comments_map = PMA_getComments($db, $table);
+    if ($cfgRelation['mimework'] && $cfg['BrowseMIME']) {
+        $mime_map = PMA_getMIME($db, $table, true);
+    }
+}
+
+$rownum    = 0;
+$columns_list = array();
+$save_row  = array();
+$odd_row   = true;
+foreach ($fields as $row) {
+    $save_row[] = $row;
+    $rownum++;
+    $columns_list[]   = $row['Field'];
+
+    $type             = $row['Type'];
+    $extracted_columnspec = PMA_Util::extractColumnSpec($row['Type']);
+
+    if ('set' == $extracted_columnspec['type']
+        || 'enum' == $extracted_columnspec['type']
+    ) {
+        $type_nowrap  = '';
+    } else {
+        $type_nowrap  = ' class="nowrap"';
+    }
+    $type         = $extracted_columnspec['print_type'];
+    if (empty($type)) {
+        $type     = ' ';
+    }
+
+    $field_charset = '';
+    if ($extracted_columnspec['can_contain_collation']
+        && ! empty($row['Collation'])
+    ) {
+        $field_charset = $row['Collation'];
+    }
+
+    // Display basic mimetype [MIME]
+    if ($cfgRelation['commwork']
+        && $cfgRelation['mimework']
+        && $cfg['BrowseMIME']
+        && isset($mime_map[$row['Field']]['mimetype'])
+    ) {
+        $type_mime = '<br />MIME: '
+        . str_replace('_', '/', $mime_map[$row['Field']]['mimetype']);
+    } else {
+        $type_mime = '';
+    }
+
+    $attribute = $extracted_columnspec['attribute'];
+
+    // prepare a common variable to reuse below; however, 
+    // in case of a VIEW, $analyzed_sql[0]['create_table_fields'] is empty
+    if (isset($analyzed_sql[0]['create_table_fields'][$row['Field']])) {
+        $tempField = $analyzed_sql[0]['create_table_fields'][$row['Field']];
+    } else {
+        $tempField = array(); 
+    }
+
+    // MySQL 4.1.2+ TIMESTAMP options
+    // (if on_update_current_timestamp is set, then it's TRUE)
+    if (isset($tempField['on_update_current_timestamp'])) {
+        $attribute = 'on update CURRENT_TIMESTAMP';
+    }
+
+    // here, we have a TIMESTAMP that SHOW FULL COLUMNS reports as having the
+    // NULL attribute, but SHOW CREATE TABLE says the contrary. Believe
+    // the latter.
+    if (! empty($tempField['type'])
+        && $tempField['type'] == 'TIMESTAMP'
+        && $tempField['timestamp_not_null']
+    ) {
+        $row['Null'] = '';
+    }
+
+
+    if (! isset($row['Default'])) {
+        if ($row['Null'] == 'YES') {
+            $row['Default'] = '<i>NULL</i>';
+        }
+    } else {
+        $row['Default'] = htmlspecialchars($row['Default']);
+    }
+
+    $field_encoded = urlencode($row['Field']);
+    $field_name    = htmlspecialchars($row['Field']);
+    $displayed_field_name = $field_name;
+
+    // underline commented fields and display a hover-title (CSS only)
+
+    if (isset($comments_map[$row['Field']])) {
+        $displayed_field_name = '<span class="commented_column" title="'
+        . htmlspecialchars($comments_map[$row['Field']]) . '">'
+        . $field_name . '</span>';
+    }
+
+    if ($primary && $primary->hasColumn($field_name)) {
+        $displayed_field_name = '<u>' . $field_name . '</u>';
+    }
+    $response->addHTML(
+        '<tr class="' . ($odd_row ? 'odd': 'even') . '">'
+    );
+    $odd_row = !$odd_row;
+
+    $response->addHTML(
+        PMA_getHtmlTableStructureRow(
+            $row, $rownum, $displayed_field_name,
+            $type_nowrap, $extracted_columnspec, $type_mime,
+            $field_charset, $attribute, $tbl_is_view,
+            $db_is_information_schema, $url_query, $field_encoded, $titles, $table
+        )
+    );
+
+    if (! $tbl_is_view && ! $db_is_information_schema) {
+        $response->addHTML(
+            PMA_getHtmlForActionsInTableStructure(
+                $type, $tbl_storage_engine, $primary,
+                $field_name, $url_query, $titles, $row, $rownum,
+                $hidden_titles, $columns_with_unique_index
+            )
+        );
+    } // end if (! $tbl_is_view && ! $db_is_information_schema)
+
+    $response->addHTML('</tr>');
+
+    unset($field_charset);
+} // end foreach
+
+$response->addHTML('</tbody></table>');
+
+$response->addHTML(
+    PMA_getHtmlForCheckAllTableColumn(
+        $pmaThemeImage, $text_dir, $tbl_is_view,
+        $db_is_information_schema, $tbl_storage_engine
+    )
+);
+
+$response->addHTML(
+    '</form><hr />'
+);
+$response->addHTML(
+    PMA_getHtmlDivForMoveColumnsDialog()
+);
+
+/**
+ * Work on the table
+ */
+
+if ($tbl_is_view) {
+    $response->addHTML(PMA_getHtmlForEditView($url_params));
+}
+$response->addHTML(
+    PMA_getHtmlForOptionalActionLinks(
+        $url_query, $tbl_is_view, $db_is_information_schema,
+        $tbl_storage_engine, $cfgRelation
+    )
+);
+
+if (! $tbl_is_view && ! $db_is_information_schema) {
+    $response->addHTML('<br />');
+    $response->addHTML(PMA_getHtmlForAddColumn($columns_list));
+    $response->addHTML(
+        '<div id="index_div" class="ajax" >'
+    );
+}
+
+/**
+ * Displays indexes
+ */
+
+if (! $tbl_is_view
+    && ! $db_is_information_schema
+    && 'ARCHIVE' !=  $tbl_storage_engine
+) {
+    //return the list of index
+    $response->addJSON('indexes_list', PMA_Index::getView($GLOBALS['table'], $GLOBALS['db']));
+    $response->addHTML(PMA_getHtmlForDisplayIndexes());
+}
+
+/**
+ * Displays Space usage and row statistics
+ */
+// BEGIN - Calc Table Space
+// Get valid statistics whatever is the table type
+if ($cfg['ShowStats']) {
+    //get table stats in HTML format
+    $tablestats = PMA_getHtmlForDisplayTableStats(
+             $showtable, $table_info_num_rows, $tbl_is_view,
+             $db_is_information_schema, $tbl_storage_engine,
+             $url_query, $tbl_collation
+         );
+    //returning the response in JSON format to be used by Ajax
+    $response->addJSON('tableStat', $tablestats);
+    $response->addHTML($tablestats);
+}
+// END - Calc Table Space
+
+$response->addHTML(
+    '<div class="clearfloat"></div>'
+);
+
+?>
diff --git a/phpmyadmin/tbl_tracking.php b/phpmyadmin/tbl_tracking.php
new file mode 100644
index 0000000..e0fdb22
--- /dev/null
+++ b/phpmyadmin/tbl_tracking.php
@@ -0,0 +1,889 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * Table tracking page
+ *
+ * @package PhpMyAdmin
+ */
+
+// Run common work
+require_once './libraries/common.inc.php';
+
+define('TABLE_MAY_BE_ABSENT', true);
+require './libraries/tbl_common.inc.php';
+$url_query .= '&goto=tbl_tracking.php&back=tbl_tracking.php';
+$url_params['goto'] = 'tbl_tracking.php';;
+$url_params['back'] = 'tbl_tracking.php';
+
+// Init vars for tracking report
+if (isset($_REQUEST['report']) || isset($_REQUEST['report_export'])) {
+    $data = PMA_Tracker::getTrackedData(
+        $_REQUEST['db'], $_REQUEST['table'], $_REQUEST['version']
+    );
+
+    $selection_schema = false;
+    $selection_data   = false;
+    $selection_both  = false;
+
+    if (! isset($_REQUEST['logtype'])) {
+        $_REQUEST['logtype'] = 'schema_and_data';
+    }
+    if ($_REQUEST['logtype'] == 'schema') {
+        $selection_schema = true;
+    } elseif ($_REQUEST['logtype'] == 'data') {
+        $selection_data   = true;
+    } else {
+        $selection_both   = true;
+    }
+    if (! isset($_REQUEST['date_from'])) {
+        $_REQUEST['date_from'] = $data['date_from'];
+    }
+    if (! isset($_REQUEST['date_to'])) {
+        $_REQUEST['date_to'] = $data['date_to'];
+    }
+    if (! isset($_REQUEST['users'])) {
+        $_REQUEST['users'] = '*';
+    }
+    $filter_ts_from = strtotime($_REQUEST['date_from']);
+    $filter_ts_to   = strtotime($_REQUEST['date_to']);
+    $filter_users   = array_map('trim', explode(',', $_REQUEST['users']));
+}
+
+// Prepare export
+if (isset($_REQUEST['report_export'])) {
+
+    /**
+     * Filters tracking entries
+     *
+     * @param array  $data           the entries to filter
+     * @param string $filter_ts_from "from" date
+     * @param string $filter_ts_to   "to" date
+     * @param string $filter_users   users
+     *
+     * @return array filtered entries
+     */
+    function PMA_filter_tracking(
+        $data, $filter_ts_from, $filter_ts_to, $filter_users
+    ) {
+        $tmp_entries = array();
+        $id = 0;
+        foreach ( $data as $entry ) {
+            $timestamp = strtotime($entry['date']);
+
+            if ($timestamp >= $filter_ts_from
+                && $timestamp <= $filter_ts_to
+                && (in_array('*', $filter_users) || in_array($entry['username'], $filter_users))
+            ) {
+                $tmp_entries[] = array( 'id' => $id,
+                                    'timestamp' => $timestamp,
+                                    'username'  => $entry['username'],
+                                    'statement' => $entry['statement']
+                             );
+            }
+            $id++;
+        }
+        return($tmp_entries);
+    }
+
+    $entries = array();
+    // Filtering data definition statements
+    if ($_REQUEST['logtype'] == 'schema'
+        || $_REQUEST['logtype'] == 'schema_and_data'
+    ) {
+        $entries = array_merge(
+            $entries,
+            PMA_filter_tracking(
+                $data['ddlog'], $filter_ts_from, $filter_ts_to, $filter_users
+            )
+        );
+    }
+
+    // Filtering data manipulation statements
+    if ($_REQUEST['logtype'] == 'data'
+        || $_REQUEST['logtype'] == 'schema_and_data'
+    ) {
+        $entries = array_merge(
+            $entries,
+            PMA_filter_tracking(
+                $data['dmlog'], $filter_ts_from, $filter_ts_to, $filter_users
+            )
+        );
+    }
+
+    // Sort it
+    foreach ($entries as $key => $row) {
+        $ids[$key]        = $row['id'];
+        $timestamps[$key] = $row['timestamp'];
+        $usernames[$key]  = $row['username'];
+        $statements[$key] = $row['statement'];
+    }
+
+    array_multisort(
+        $timestamps, SORT_ASC, $ids, SORT_ASC, $usernames,
+        SORT_ASC, $statements, SORT_ASC, $entries
+    );
+
+}
+
+// Export as file download
+if (isset($_REQUEST['report_export'])
+    && $_REQUEST['export_type'] == 'sqldumpfile'
+) {
+    @ini_set('url_rewriter.tags', '');
+
+    $dump = "# " . sprintf(
+        __('Tracking report for table `%s`'), htmlspecialchars($_REQUEST['table'])
+    )
+    . "\n" . "# " . date('Y-m-d H:i:s') . "\n";
+    foreach ($entries as $entry) {
+        $dump .= $entry['statement'];
+    }
+    $filename = 'log_' . htmlspecialchars($_REQUEST['table']) . '.sql';
+    PMA_downloadHeader($filename, 'text/x-sql', strlen($dump));
+
+    echo $dump;
+    exit();
+}
+
+
+/**
+ * Gets tables informations
+ */
+
+echo '<br />';
+
+/**
+ * Actions
+ */
+
+// Create tracking version
+if (isset($_REQUEST['submit_create_version'])) {
+    $tracking_set = '';
+
+    if ($_REQUEST['alter_table'] == true) {
+        $tracking_set .= 'ALTER TABLE,';
+    }
+    if ($_REQUEST['rename_table'] == true) {
+        $tracking_set .= 'RENAME TABLE,';
+    }
+    if ($_REQUEST['create_table'] == true) {
+        $tracking_set .= 'CREATE TABLE,';
+    }
+    if ($_REQUEST['drop_table'] == true) {
+        $tracking_set .= 'DROP TABLE,';
+    }
+    if ($_REQUEST['create_index'] == true) {
+        $tracking_set .= 'CREATE INDEX,';
+    }
+    if ($_REQUEST['drop_index'] == true) {
+        $tracking_set .= 'DROP INDEX,';
+    }
+    if ($_REQUEST['insert'] == true) {
+        $tracking_set .= 'INSERT,';
+    }
+    if ($_REQUEST['update'] == true) {
+        $tracking_set .= 'UPDATE,';
+    }
+    if ($_REQUEST['delete'] == true) {
+        $tracking_set .= 'DELETE,';
+    }
+    if ($_REQUEST['truncate'] == true) {
+        $tracking_set .= 'TRUNCATE,';
+    }
+    $tracking_set = rtrim($tracking_set, ',');
+
+    $versionCreated = PMA_Tracker::createVersion(
+        $GLOBALS['db'],
+        $GLOBALS['table'],
+        $_REQUEST['version'],
+        $tracking_set,
+        PMA_Table::isView($GLOBALS['db'], $GLOBALS['table'])
+    );
+    if ($versionCreated) {
+        $msg = PMA_Message::success(
+            sprintf(
+                __('Version %1$s was created, tracking for %2$s is active.'),
+                htmlspecialchars($_REQUEST['version']),
+                htmlspecialchars($GLOBALS['db'] . '.' . $GLOBALS['table'])
+            )
+        );
+        $msg->display();
+    }
+}
+
+// Deactivate tracking
+if (isset($_REQUEST['submit_deactivate_now'])) {
+    $deactivated = PMA_Tracker::deactivateTracking(
+        $GLOBALS['db'], $GLOBALS['table'], $_REQUEST['version']
+    );
+    if ($deactivated) {
+        $msg = PMA_Message::success(
+            sprintf(
+                __('Tracking for %1$s was deactivated at version %2$s.'),
+                htmlspecialchars($GLOBALS['db'] . '.' . $GLOBALS['table']),
+                htmlspecialchars($_REQUEST['version'])
+            )
+        );
+        $msg->display();
+    }
+}
+
+// Activate tracking
+if (isset($_REQUEST['submit_activate_now'])) {
+    $activated = PMA_Tracker::activateTracking(
+        $GLOBALS['db'], $GLOBALS['table'], $_REQUEST['version']
+    );
+    if ($activated) {
+        $msg = PMA_Message::success(
+            sprintf(
+                __('Tracking for %1$s was activated at version %2$s.'),
+                htmlspecialchars($GLOBALS['db'] . '.' . $GLOBALS['table']),
+                htmlspecialchars($_REQUEST['version'])
+            )
+        );
+        $msg->display();
+    }
+}
+
+// Export as SQL execution
+if (isset($_REQUEST['report_export']) && $_REQUEST['export_type'] == 'execution') {
+    foreach ($entries as $entry) {
+        $sql_result = PMA_DBI_query("/*NOTRACK*/\n" . $entry['statement']);
+    }
+    $msg = PMA_Message::success(__('SQL statements executed.'));
+    $msg->display();
+}
+
+// Export as SQL dump
+if (isset($_REQUEST['report_export']) && $_REQUEST['export_type'] == 'sqldump') {
+    $new_query = "# "
+        . __('You can execute the dump by creating and using a temporary database. Please ensure that you have the privileges to do so.')
+        . "\n"
+        . "# " . __('Comment out these two lines if you do not need them.') . "\n"
+        . "\n"
+        . "CREATE database IF NOT EXISTS pma_temp_db; \n"
+        . "USE pma_temp_db; \n"
+        . "\n";
+
+    foreach ($entries as $entry) {
+        $new_query .= $entry['statement'];
+    }
+    $msg = PMA_Message::success(
+        __('SQL statements exported. Please copy the dump or execute it.')
+    );
+    $msg->display();
+
+    $db_temp = $db;
+    $table_temp = $table;
+
+    $db = $table = '';
+    include_once './libraries/sql_query_form.lib.php';
+
+    PMA_sqlQueryForm($new_query, 'sql');
+
+    $db = $db_temp;
+    $table = $table_temp;
+}
+
+/*
+ * Schema snapshot
+ */
+if (isset($_REQUEST['snapshot'])) {
+    echo '<h3>' . __('Structure snapshot')
+        . '  [<a href="tbl_tracking.php?' . $url_query . '">' . __('Close')
+        . '</a>]</h3>';
+    $data = PMA_Tracker::getTrackedData(
+        $_REQUEST['db'], $_REQUEST['table'], $_REQUEST['version']
+    );
+
+    // Get first DROP TABLE/VIEW and CREATE TABLE/VIEW statements
+    $drop_create_statements = $data['ddlog'][0]['statement'];
+
+    if (strstr($data['ddlog'][0]['statement'], 'DROP TABLE')
+        || strstr($data['ddlog'][0]['statement'], 'DROP VIEW')) {
+        $drop_create_statements .= $data['ddlog'][1]['statement'];
+    }
+    // Print SQL code
+    echo PMA_Util::getMessage(
+        sprintf(
+            __('Version %s snapshot (SQL code)'),
+            htmlspecialchars($_REQUEST['version'])
+        ),
+        $drop_create_statements
+    );
+
+    // Unserialize snapshot
+    $temp = unserialize($data['schema_snapshot']);
+    $columns = $temp['COLUMNS'];
+    $indexes = $temp['INDEXES'];
+    echo '<h3>' . __('Structure') . '</h3>';
+    echo '<table id="tablestructure" class="data">';
+    echo '<thead>';
+    echo '<tr>';
+    echo '<th>' . __('Column') . '</th>';
+    echo '<th>' . __('Type') . '</th>';
+    echo '<th>' . __('Collation') . '</th>';
+    echo '<th>' . __('Null') . '</th>';
+    echo '<th>' . __('Default') . '</th>';
+    echo '<th>' . __('Extra') . '</th>';
+    echo '<th>' . __('Comment') . '</th>';
+    echo '</tr>';
+    echo '</thead>';
+    echo '<tbody>';
+    $style = 'odd';
+    foreach ($columns as $field_index => $field) {
+        echo '<tr class="noclick ' . $style . '">';
+        if ($field['Key'] == 'PRI') {
+            echo '<td><b><u>' . htmlspecialchars($field['Field']) . '</u></b></td>';
+        } else {
+            echo '<td><b>' . htmlspecialchars($field['Field']) . '</b></td>';
+        }
+        echo "\n";
+        echo '<td>' . htmlspecialchars($field['Type']) . '</td>';
+        echo '<td>' . htmlspecialchars($field['Collation']) . '</td>';
+        echo '<td>' . (($field['Null'] == 'YES') ? __('Yes') : __('No')) . '</td>';
+        echo '<td>';
+        if (isset($field['Default'])) {
+            $extracted_columnspec = PMA_Util::extractColumnSpec($field['Type']);
+            if ($extracted_columnspec['type'] == 'bit') {
+                // here, $field['Default'] contains something like b'010'
+                echo PMA_Util::convertBitDefaultValue($field['Default']);
+            } else {
+                echo htmlspecialchars($field['Default']);
+            }
+        } else {
+            if ($field['Null'] == 'YES') {
+                echo '<i>NULL</i>';
+            } else {
+                echo '<i>' . _pgettext('None for default', 'None') . '</i>';
+            }
+        }
+        echo '</td>';
+        echo '<td>' . htmlspecialchars($field['Extra']) . '</td>';
+        echo '<td>' . htmlspecialchars($field['Comment']) . '</td>';
+        echo '</tr>';
+
+        if ($style == 'even') {
+            $style = 'odd';
+        } else {
+            $style = 'even';
+        }
+    }
+
+    echo '</tbody>';
+    echo '</table>';
+
+    if (count($indexes) > 0) {
+        echo '<h3>' . __('Indexes') . '</h3>';
+        echo '<table id="tablestructure_indexes" class="data">';
+        echo '<thead>';
+        echo '<tr>';
+        echo '<th>' . __('Keyname') . '</th>';
+        echo '<th>' . __('Type') . '</th>';
+        echo '<th>' . __('Unique') . '</th>';
+        echo '<th>' . __('Packed') . '</th>';
+        echo '<th>' . __('Column') . '</th>';
+        echo '<th>' . __('Cardinality') . '</th>';
+        echo '<th>' . __('Collation') . '</th>';
+        echo '<th>' . __('Null') . '</th>';
+        echo '<th>' . __('Comment') . '</th>';
+        echo '</tr>';
+        echo '<tbody>';
+
+        $style = 'odd';
+        foreach ($indexes as $indexes_index => $index) {
+            if ($index['Non_unique'] == 0) {
+                $str_unique = __('Yes');
+            } else {
+                $str_unique = __('No');
+            }
+            if ($index['Packed'] != '') {
+                $str_packed = __('Yes');
+            } else {
+                $str_packed = __('No');
+            }
+
+            echo '<tr class="noclick ' . $style . '">';
+            echo '<td><b>' . htmlspecialchars($index['Key_name']) . '</b></td>';
+            echo '<td>' . htmlspecialchars($index['Index_type']) . '</td>';
+            echo '<td>' . $str_unique . '</td>';
+            echo '<td>' . $str_packed . '</td>';
+            echo '<td>' . htmlspecialchars($index['Column_name']) . '</td>';
+            echo '<td>' . htmlspecialchars($index['Cardinality']) . '</td>';
+            echo '<td>' . htmlspecialchars($index['Collation']) . '</td>';
+            echo '<td>' . htmlspecialchars($index['Null']) . '</td>';
+            echo '<td>' . htmlspecialchars($index['Comment']) . '</td>';
+            echo '</tr>';
+
+            if ($style == 'even') {
+                $style = 'odd';
+            } else {
+                $style = 'even';
+            }
+        }
+        echo '</tbody>';
+        echo '</table>';
+    } // endif
+    echo '<br /><hr /><br />';
+}
+// end of snapshot report
+
+/*
+ *  Tracking report
+ */
+if (isset($_REQUEST['report'])
+    && (isset($_REQUEST['delete_ddlog']) || isset($_REQUEST['delete_dmlog']))
+) {
+
+    if (isset($_REQUEST['delete_ddlog'])) {
+
+        // Delete ddlog row data
+        $delete_id = $_REQUEST['delete_ddlog'];
+
+        // Only in case of valable id
+        if ($delete_id == (int)$delete_id) {
+            unset($data['ddlog'][$delete_id]);
+
+            $successfullyDeleted = PMA_Tracker::changeTrackingData(
+                $_REQUEST['db'], $_REQUEST['table'],
+                $_REQUEST['version'], 'DDL', $data['ddlog']
+            );
+            if ($successfullyDeleted) {
+                $msg = PMA_Message::success(
+                    __('Tracking data definition successfully deleted')
+                );
+            } else {
+                $msg = PMA_Message::rawError(__('Query error'));
+            }
+            $msg->display();
+        }
+    }
+
+    if (isset($_REQUEST['delete_dmlog'])) {
+
+        // Delete dmlog row data
+        $delete_id = $_REQUEST['delete_dmlog'];
+
+        // Only in case of valable id
+        if ($delete_id == (int)$delete_id) {
+            unset($data['dmlog'][$delete_id]);
+
+            $successfullyDeleted = PMA_Tracker::changeTrackingData(
+                $_REQUEST['db'], $_REQUEST['table'],
+                $_REQUEST['version'], 'DML', $data['dmlog']
+            );
+            if ($successfullyDeleted) {
+                $msg = PMA_Message::success(
+                    __('Tracking data manipulation successfully deleted')
+                );
+            } else {
+                $msg = PMA_Message::rawError(__('Query error'));
+            }
+            $msg->display();
+        }
+    }
+}
+
+if (isset($_REQUEST['report']) || isset($_REQUEST['report_export'])) {
+    echo '<h3>' . __('Tracking report')
+        . '  [<a href="tbl_tracking.php?' . $url_query . '">' . __('Close')
+        . '</a>]</h3>';
+
+    echo '<small>' . __('Tracking statements') . ' '
+        . htmlspecialchars($data['tracking']) . '</small><br/>';
+    echo '<br/>';
+
+    echo '<form method="post" action="tbl_tracking.php'
+        . PMA_generate_common_url(
+            $url_params + array('report' => 'true', 'version' => $_REQUEST['version'])
+        )
+        . '">';
+
+    $str1 = '<select name="logtype">'
+        . '<option value="schema"'
+        . ($selection_schema ? ' selected="selected"' : '') . '>'
+        . __('Structure only') . '</option>'
+        . '<option value="data"'
+        . ($selection_data ? ' selected="selected"' : ''). '>'
+        . __('Data only') . '</option>'
+        . '<option value="schema_and_data"'
+        . ($selection_both ? ' selected="selected"' : '') . '>'
+        . __('Structure and data') . '</option>'
+        . '</select>';
+    $str2 = '<input type="text" name="date_from" value="'
+        . htmlspecialchars($_REQUEST['date_from']) . '" size="19" />';
+    $str3 = '<input type="text" name="date_to" value="'
+        . htmlspecialchars($_REQUEST['date_to']) . '" size="19" />';
+    $str4 = '<input type="text" name="users" value="'
+        . htmlspecialchars($_REQUEST['users']) . '" />';
+    $str5 = '<input type="hidden" name="list_report" value="1" />'
+      . '<input type="submit" value="' . __('Go') . '" />';
+
+    printf(
+        __('Show %1$s with dates from %2$s to %3$s by user %4$s %5$s'),
+        $str1, $str2, $str3, $str4, $str5
+    );
+
+    // Prepare delete link content here
+    $drop_image_or_text = '';
+    if (true == $GLOBALS['cfg']['PropertiesIconic']) {
+        $drop_image_or_text .= PMA_Util::getImage(
+            'b_drop.png', __('Delete tracking data row from report')
+        );
+    }
+    if ('both' === $GLOBALS['cfg']['PropertiesIconic']
+        || false === $GLOBALS['cfg']['PropertiesIconic']
+    ) {
+        $drop_image_or_text .= __('Delete');
+    }
+
+    /*
+     *  First, list tracked data definition statements
+     */
+    $i = 1;
+    if (count($data['ddlog']) == 0 && count($data['dmlog']) == 0) {
+        $msg = PMA_Message::notice(__('No data'));
+        $msg->display();
+    }
+
+    if ($selection_schema || $selection_both  && count($data['ddlog']) > 0) {
+        echo '<table id="ddl_versions" class="data" width="100%">';
+        echo '<thead>';
+        echo '<tr>';
+        echo '<th width="18">#</th>';
+        echo '<th width="100">' . __('Date') . '</th>';
+        echo '<th width="60">' . __('Username') . '</th>';
+        echo '<th>' . __('Data definition statement') . '</th>';
+        echo '<th>' . __('Delete') . '</th>';
+        echo '</tr>';
+        echo '</thead>';
+        echo '<tbody>';
+
+        $style = 'odd';
+        foreach ($data['ddlog'] as $entry) {
+            if (strlen($entry['statement']) > $GLOBALS['cfg']['MaxCharactersInDisplayedSQL']) {
+                $statement = substr(
+                    $entry['statement'],
+                    0,
+                    $GLOBALS['cfg']['MaxCharactersInDisplayedSQL']
+                ) . '[...]';
+            } else {
+                $statement  = PMA_Util::formatSql(PMA_SQP_parse($entry['statement']));
+            }
+            $timestamp = strtotime($entry['date']);
+
+            if ($timestamp >= $filter_ts_from
+                && $timestamp <= $filter_ts_to
+                && (in_array('*', $filter_users) || in_array($entry['username'], $filter_users))
+            ) {
+                echo '<tr class="noclick ' . $style . '">';
+                echo '<td><small>' . $i . '</small></td>';
+                echo '<td><small>' . htmlspecialchars($entry['date']) . '</small></td>';
+                echo '<td><small>' . htmlspecialchars($entry['username']) . '</small></td>';
+                echo '<td>' . $statement . '</td>';
+                echo '<td class="nowrap"><a href="tbl_tracking.php?'
+                    . $url_query . '&report=true&version='
+                    . $version['version'] . '&delete_ddlog='
+                    . ($i - 1) . '">' . $drop_image_or_text
+                    . '</a></td>';
+                echo '</tr>';
+
+                if ($style == 'even') {
+                    $style = 'odd';
+                } else {
+                    $style = 'even';
+                }
+                $i++;
+            }
+        }
+        echo '</tbody>';
+        echo '</table>';
+
+    } //endif
+
+    // Memorize data definition amount
+    $ddlog_count = $i;
+
+    /*
+     *  Secondly, list tracked data manipulation statements
+     */
+
+    if (($selection_data || $selection_both) && count($data['dmlog']) > 0) {
+        echo '<table id="dml_versions" class="data" width="100%">';
+        echo '<thead>';
+        echo '<tr>';
+        echo '<th width="18">#</th>';
+        echo '<th width="100">' . __('Date') . '</th>';
+        echo '<th width="60">' . __('Username') . '</th>';
+        echo '<th>' . __('Data manipulation statement') . '</th>';
+        echo '<th>' . __('Delete') . '</th>';
+        echo '</tr>';
+        echo '</thead>';
+        echo '<tbody>';
+
+        $style = 'odd';
+        foreach ($data['dmlog'] as $entry) {
+            if (strlen($entry['statement']) > $GLOBALS['cfg']['MaxCharactersInDisplayedSQL']) {
+                $statement = substr(
+                    $entry['statement'],
+                    0,
+                    $GLOBALS['cfg']['MaxCharactersInDisplayedSQL']
+                ) . '[...]';
+            } else {
+                $statement  = PMA_Util::formatSql(PMA_SQP_parse($entry['statement']));
+            }
+            $timestamp = strtotime($entry['date']);
+
+            if ($timestamp >= $filter_ts_from
+                && $timestamp <= $filter_ts_to
+                && (in_array('*', $filter_users) || in_array($entry['username'], $filter_users))
+            ) {
+                echo '<tr class="noclick ' . $style . '">';
+                echo '<td><small>' . $i . '</small></td>';
+                echo '<td><small>' . htmlspecialchars($entry['date']) . '</small></td>';
+                echo '<td><small>' . htmlspecialchars($entry['username']) . '</small></td>';
+                echo '<td>' . $statement . '</td>';
+                echo '<td class="nowrap"><a href="tbl_tracking.php?' . $url_query
+                    . '&report=true&version=' . $version['version']
+                    . '&delete_dmlog=' . ($i - $ddlog_count) . '">'
+                    . $drop_image_or_text
+                    . '</a></td>';
+                echo '</tr>';
+
+                if ($style == 'even') {
+                    $style = 'odd';
+                } else {
+                    $style = 'even';
+                }
+                $i++;
+            }
+        }
+        echo '</tbody>';
+        echo '</table>';
+    }
+    echo '</form>';
+    echo '<form method="post" action="tbl_tracking.php'
+        . PMA_generate_common_url(
+            $url_params + array('report' => 'true', 'version' => $_REQUEST['version'])
+        )
+        . '">';
+    printf(
+        __('Show %1$s with dates from %2$s to %3$s by user %4$s %5$s'),
+        $str1, $str2, $str3, $str4, $str5
+    );
+
+    $str_export1 =  '<select name="export_type">'
+        . '<option value="sqldumpfile">' . __('SQL dump (file download)') . '</option>'
+        . '<option value="sqldump">' . __('SQL dump') . '</option>'
+        . '<option value="execution" onclick="alert(\''
+        . PMA_escapeJsString(__('This option will replace your table and contained data.'))
+        .'\')">' . __('SQL execution') . '</option>' . '</select>';
+
+    $str_export2 = '<input type="hidden" name="report_export" value="1" />'
+                 . '<input type="submit" value="' . __('Go') .'" />';
+    echo '</form>';
+    echo '<form class="disableAjax" method="post" action="tbl_tracking.php'
+        . PMA_generate_common_url(
+            $url_params + array('report' => 'true', 'version' => $_REQUEST['version'])
+        )
+        . '">';
+    echo '<input type="hidden" name="logtype" value="'
+        . htmlspecialchars($_REQUEST['logtype']) . '" />';
+    echo '<input type="hidden" name="date_from" value="'
+        . htmlspecialchars($_REQUEST['date_from']) . '" />';
+    echo '<input type="hidden" name="date_to" value="'
+        . htmlspecialchars($_REQUEST['date_to']) . '" />';
+    echo '<input type="hidden" name="users" value="'
+        . htmlspecialchars($_REQUEST['users']) . '" />';
+    echo "<br/>" . sprintf(__('Export as %s'), $str_export1)
+        . $str_export2 . "<br/>";
+    echo '</form>';
+    echo "<br/><br/><hr/><br/>\n";
+} // end of report
+
+
+/*
+ * List selectable tables
+ */
+
+$sql_query = " SELECT DISTINCT db_name, table_name FROM " .
+             PMA_Util::backquote($GLOBALS['cfg']['Server']['pmadb']) . "." .
+             PMA_Util::backquote($GLOBALS['cfg']['Server']['tracking']) .
+             " WHERE db_name = '" . PMA_Util::sqlAddSlashes($GLOBALS['db']) . "' " .
+             " ORDER BY db_name, table_name";
+
+$sql_result = PMA_queryAsControlUser($sql_query);
+
+if (PMA_DBI_num_rows($sql_result) > 0) {
+    echo '<form method="post" action="tbl_tracking.php?' . $url_query . '">';
+    echo '<select name="table">';
+    while ($entries = PMA_DBI_fetch_array($sql_result)) {
+        if (PMA_Tracker::isTracked($entries['db_name'], $entries['table_name'])) {
+            $status = ' (' . __('active') . ')';
+        } else {
+            $status = ' (' . __('not active') . ')';
+        }
+        if ($entries['table_name'] == $_REQUEST['table']) {
+            $s = ' selected="selected"';
+        } else {
+            $s = '';
+        }
+        echo '<option value="' . htmlspecialchars($entries['table_name']) . '"' . $s . '>' . htmlspecialchars($entries['db_name']) . ' . ' . htmlspecialchars($entries['table_name']) . $status . '</option>' . "\n";
+    }
+    echo '</select>';
+    echo '<input type="hidden" name="show_versions_submit" value="1" />';
+    echo '<input type="submit" value="' . __('Show versions') . '" />';
+    echo '</form>';
+}
+echo '<br />';
+
+/*
+ * List versions of current table
+ */
+
+$sql_query = " SELECT * FROM " .
+     PMA_Util::backquote($GLOBALS['cfg']['Server']['pmadb']) . "." .
+     PMA_Util::backquote($GLOBALS['cfg']['Server']['tracking']) .
+     " WHERE db_name = '" . PMA_Util::sqlAddSlashes($_REQUEST['db']) . "' ".
+     " AND table_name = '" . PMA_Util::sqlAddSlashes($_REQUEST['table']) ."' ".
+     " ORDER BY version DESC ";
+
+$sql_result = PMA_queryAsControlUser($sql_query);
+
+$last_version = 0;
+$maxversion = PMA_DBI_fetch_array($sql_result);
+$last_version = $maxversion['version'];
+
+if ($last_version > 0) {
+    echo '<table id="versions" class="data">';
+    echo '<thead>';
+    echo '<tr>';
+    echo '<th>' . __('Database') . '</th>';
+    echo '<th>' . __('Table') . '</th>';
+    echo '<th>' . __('Version') . '</th>';
+    echo '<th>' . __('Created') . '</th>';
+    echo '<th>' . __('Updated') . '</th>';
+    echo '<th>' . __('Status') . '</th>';
+    echo '<th>' . __('Show') . '</th>';
+    echo '</tr>';
+    echo '</thead>';
+    echo '<tbody>';
+
+    $style = 'odd';
+    PMA_DBI_data_seek($sql_result, 0);
+    while ($version = PMA_DBI_fetch_array($sql_result)) {
+        if ($version['tracking_active'] == 1) {
+            $version_status = __('active');
+        } else {
+            $version_status = __('not active');
+        }
+        if ($version['version'] == $last_version) {
+            if ($version['tracking_active'] == 1) {
+                $tracking_active = true;
+            } else {
+                $tracking_active = false;
+            }
+        }
+        echo '<tr class="noclick ' . $style . '">';
+        echo '<td>' . htmlspecialchars($version['db_name']) . '</td>';
+        echo '<td>' . htmlspecialchars($version['table_name']) . '</td>';
+        echo '<td>' . htmlspecialchars($version['version']) . '</td>';
+        echo '<td>' . htmlspecialchars($version['date_created']) . '</td>';
+        echo '<td>' . htmlspecialchars($version['date_updated']) . '</td>';
+        echo '<td>' . $version_status . '</td>';
+        echo '<td><a href="tbl_tracking.php';
+        echo PMA_generate_common_url(
+            $url_params + array('report' => 'true', 'version' => $version['version'])
+        );
+        echo '">' . __('Tracking report') . '</a>';
+        echo '| <a href="tbl_tracking.php';
+        echo PMA_generate_common_url(
+            $url_params + array('snapshot' => 'true', 'version' => $version['version'])
+        );
+        echo '">' . __('Structure snapshot') . '</a>';
+        echo '</td>';
+        echo '</tr>';
+
+        if ($style == 'even') {
+            $style = 'odd';
+        } else {
+            $style = 'even';
+        }
+    }
+
+    echo '</tbody>';
+    echo '</table>';
+
+    if ($tracking_active) {
+        echo '<div id="div_deactivate_tracking">';
+        echo '<form method="post" action="tbl_tracking.php?' . $url_query . '">';
+        echo '<fieldset>';
+        echo '<legend>';
+        printf(
+            __('Deactivate tracking for %s'),
+            htmlspecialchars($GLOBALS['db'] . '.' . $GLOBALS['table'])
+        );
+        echo '</legend>';
+        echo '<input type="hidden" name="version" value="' . $last_version . '" />';
+        echo '<input type="hidden" name="submit_deactivate_now" value="1" />';
+        echo '<input type="submit" value="' . __('Deactivate now') . '" />';
+        echo '</fieldset>';
+        echo '</form>';
+        echo '</div>';
+    } else {
+        echo '<div id="div_activate_tracking">';
+        echo '<form method="post" action="tbl_tracking.php?' . $url_query . '">';
+        echo '<fieldset>';
+        echo '<legend>';
+        printf(
+            __('Activate tracking for %s'),
+            htmlspecialchars($GLOBALS['db'] . '.' . $GLOBALS['table'])
+        );
+        echo '</legend>';
+        echo '<input type="hidden" name="version" value="' . $last_version . '" />';
+        echo '<input type="hidden" name="submit_activate_now" value="1" />';
+        echo '<input type="submit" value="' . __('Activate now') . '" />';
+        echo '</fieldset>';
+        echo '</form>';
+        echo '</div>';
+    }
+}
+
+echo '<div id="div_create_version">';
+echo '<form method="post" action="tbl_tracking.php?' . $url_query . '">';
+echo PMA_generate_common_hidden_inputs($GLOBALS['db'], $GLOBALS['table']);
+echo '<fieldset>';
+echo '<legend>';
+printf(
+    __('Create version %1$s of %2$s'),
+    ($last_version + 1),
+    htmlspecialchars($GLOBALS['db'] . '.' . $GLOBALS['table'])
+);
+echo '</legend>';
+
+echo '<input type="hidden" name="version" value="' . ($last_version + 1) . '" />';
+
+echo '<p>' . __('Track these data definition statements:') . '</p>';
+echo '<input type="checkbox" name="alter_table" value="true" checked="checked" /> ALTER TABLE<br/>';
+echo '<input type="checkbox" name="rename_table" value="true" checked="checked" /> RENAME TABLE<br/>';
+echo '<input type="checkbox" name="create_table" value="true" checked="checked" /> CREATE TABLE<br/>';
+echo '<input type="checkbox" name="drop_table" value="true" checked="checked" /> DROP TABLE<br/>';
+echo '<br/>';
+echo '<input type="checkbox" name="create_index" value="true" checked="checked" /> CREATE INDEX<br/>';
+echo '<input type="checkbox" name="drop_index" value="true" checked="checked" /> DROP INDEX<br/>';
+echo '<p>' . __('Track these data manipulation statements:') . '</p>';
+echo '<input type="checkbox" name="insert" value="true" checked="checked" /> INSERT<br/>';
+echo '<input type="checkbox" name="update" value="true" checked="checked" /> UPDATE<br/>';
+echo '<input type="checkbox" name="delete" value="true" checked="checked" /> DELETE<br/>';
+echo '<input type="checkbox" name="truncate" value="true" checked="checked" /> TRUNCATE<br/>';
+
+echo '</fieldset>';
+echo '<fieldset class="tblFooters">';
+
+echo '<input type="hidden" name="submit_create_version" value="1" />';
+echo '<input type="submit" value="' . __('Create version') . '" />';
+echo '</fieldset>';
+echo '</form>';
+echo '</div>';
+
+echo '<br class="clearfloat"/>';
diff --git a/phpmyadmin/tbl_triggers.php b/phpmyadmin/tbl_triggers.php
new file mode 100644
index 0000000..9c87e67
--- /dev/null
+++ b/phpmyadmin/tbl_triggers.php
@@ -0,0 +1,10 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * Triggers management.
+ *
+ * @package PhpMyAdmin
+ */
+
+require_once './db_triggers.php';
+?>
diff --git a/phpmyadmin/tbl_zoom_select.php b/phpmyadmin/tbl_zoom_select.php
new file mode 100644
index 0000000..f2ab6e6
--- /dev/null
+++ b/phpmyadmin/tbl_zoom_select.php
@@ -0,0 +1,171 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * Handles table zoom search tab
+ *
+ * display table zoom search form, create SQL queries from form data
+ *
+ * @package PhpMyAdmin
+ */
+
+/**
+ * Gets some core libraries
+ */
+require_once './libraries/common.inc.php';
+require_once './libraries/mysql_charsets.lib.php';
+require_once './libraries/TableSearch.class.php';
+require_once './libraries/tbl_info.inc.php';
+
+$response = PMA_Response::getInstance();
+$header   = $response->getHeader();
+$scripts  = $header->getScripts();
+$scripts->addFile('makegrid.js');
+$scripts->addFile('sql.js');
+$scripts->addFile('date.js');
+/* < IE 9 doesn't support canvas natively */
+if (PMA_USR_BROWSER_AGENT == 'IE' && PMA_USR_BROWSER_VER < 9) {
+    $scripts->addFile('canvg/flashcanvas.js');
+}
+$scripts->addFile('jqplot/jquery.jqplot.js');
+$scripts->addFile('jqplot/plugins/jqplot.canvasTextRenderer.js');
+$scripts->addFile('jqplot/plugins/jqplot.canvasAxisLabelRenderer.js');
+$scripts->addFile('jqplot/plugins/jqplot.dateAxisRenderer.js');
+$scripts->addFile('jqplot/plugins/jqplot.highlighter.js');
+$scripts->addFile('jqplot/plugins/jqplot.cursor.js');
+$scripts->addFile('canvg/canvg.js');
+$scripts->addFile('jquery/jquery-ui-timepicker-addon.js');
+$scripts->addFile('tbl_zoom_plot_jqplot.js');
+
+/**
+ * Sets globals from $_POST
+ */
+$post_params = array(
+    'dataLabel',
+    'maxPlotLimit',
+    'zoom_submit'
+);
+foreach ($post_params as $one_post_param) {
+    if (isset($_POST[$one_post_param])) {
+        $GLOBALS[$one_post_param] = $_POST[$one_post_param];
+    }
+}
+
+$table_search = new PMA_TableSearch($db, $table, "zoom");
+
+/**
+ * Handle AJAX request for data row on point select
+ * @var post_params Object containing parameters for the POST request
+ */
+
+if (isset($_REQUEST['get_data_row']) && $_REQUEST['get_data_row'] == true) {
+    $extra_data = array();
+    $row_info_query = 'SELECT * FROM `' . $_REQUEST['db'] . '`.`'
+        . $_REQUEST['table'] . '` WHERE ' .  $_REQUEST['where_clause'];
+    $result = PMA_DBI_query($row_info_query . ";", null, PMA_DBI_QUERY_STORE);
+    $fields_meta = PMA_DBI_get_fields_meta($result);
+    while ($row = PMA_DBI_fetch_assoc($result)) {
+        // for bit fields we need to convert them to printable form
+        $i = 0;
+        foreach ($row as $col => $val) {
+            if ($fields_meta[$i]->type == 'bit') {
+                $row[$col] = PMA_Util::printableBitValue($val, $fields_meta[$i]->length);
+            }
+            $i++;
+        }
+        $extra_data['row_info'] = $row;
+    }
+    PMA_Response::getInstance()->addJSON($extra_data);
+    exit;
+}
+
+/**
+ * Handle AJAX request for changing field information
+ * (value,collation,operators,field values) in input form
+ * @var post_params Object containing parameters for the POST request
+ */
+
+if (isset($_REQUEST['change_tbl_info']) && $_REQUEST['change_tbl_info'] == true) {
+    $response = PMA_Response::getInstance();
+    $field = $_REQUEST['field'];
+    if ($field == 'pma_null') {
+        $response->addJSON('field_type', '');
+        $response->addJSON('field_collation', '');
+        $response->addJSON('field_operators', '');
+        $response->addJSON('field_value', '');
+        exit;
+    }
+    $key = array_search($field, $table_search->getColumnNames());
+    $properties = $table_search->getColumnProperties($_REQUEST['it'], $key);
+    $response->addJSON('field_type', $properties['type']);
+    $response->addJSON('field_collation', $properties['collation']);
+    $response->addJSON('field_operators', $properties['func']);
+    $response->addJSON('field_value', $properties['value']);
+    exit;
+}
+
+// Gets some core libraries
+require_once './libraries/tbl_common.inc.php';
+$url_query .= '&goto=tbl_select.php&back=tbl_select.php';
+
+// Gets tables informations
+require_once './libraries/tbl_info.inc.php';
+
+if (! isset($goto)) {
+    $goto = $GLOBALS['cfg']['DefaultTabTable'];
+}
+// Defines the url to return to in case of error in the next sql statement
+$err_url   = $goto . '?' . PMA_generate_common_url($db, $table);
+
+//Set default datalabel if not selected
+if ( !isset($_POST['zoom_submit']) || $_POST['dataLabel'] == '') {
+    $dataLabel = PMA_getDisplayField($db, $table);
+}
+
+// Displays the zoom search form
+$response->addHTML($table_search->getSelectionForm($goto, $dataLabel));
+
+/*
+ * Handle the input criteria and generate the query result
+ * Form for displaying query results
+ */
+if (isset($zoom_submit)
+    && $_POST['criteriaColumnNames'][0] != 'pma_null'
+    && $_POST['criteriaColumnNames'][1] != 'pma_null'
+    && $_POST['criteriaColumnNames'][0] != $_POST['criteriaColumnNames'][1]
+) {
+    //Query generation part
+    $sql_query = $table_search->buildSqlQuery();
+    $sql_query .= ' LIMIT ' . $maxPlotLimit;
+
+    //Query execution part
+    $result = PMA_DBI_query($sql_query . ";", null, PMA_DBI_QUERY_STORE);
+    $fields_meta = PMA_DBI_get_fields_meta($result);
+    while ($row = PMA_DBI_fetch_assoc($result)) {
+        //Need a row with indexes as 0,1,2 for the getUniqueCondition
+        // hence using a temporary array
+        $tmpRow = array();
+        foreach ($row as $val) {
+            $tmpRow[] = $val;
+        }
+        //Get unique conditon on each row (will be needed for row update)
+        $uniqueCondition = PMA_Util::getUniqueCondition(
+            $result, count($table_search->getColumnNames()), $fields_meta, $tmpRow,
+            true
+        );
+        //Append it to row array as where_clause
+        $row['where_clause'] = $uniqueCondition[0];
+
+        $tmpData = array(
+            $_POST['criteriaColumnNames'][0] => $row[$_POST['criteriaColumnNames'][0]],
+            $_POST['criteriaColumnNames'][1] => $row[$_POST['criteriaColumnNames'][1]],
+            'where_clause' => $uniqueCondition[0]
+        );
+        $tmpData[$dataLabel] = ($dataLabel) ? $row[$dataLabel] : '';
+        $data[] = $tmpData;
+    }
+    unset($tmpData);
+
+    //Displays form for point data and scatter plot
+    $response->addHTML($table_search->getZoomResultsForm($goto, $data));
+}
+?>
diff --git a/phpmyadmin/themes.php b/phpmyadmin/themes.php
new file mode 100644
index 0000000..4328383
--- /dev/null
+++ b/phpmyadmin/themes.php
@@ -0,0 +1,31 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ *
+ * @package PhpMyAdmin
+ */
+
+/**
+ * get some globals
+ */
+require './libraries/common.inc.php';
+$response = PMA_Response::getInstance();
+$response->getFooter()->setMinimal();
+$header = $response->getHeader();
+$header->setBodyId('bodythemes');
+$header->setTitle('phpMyAdmin - ' . __('Theme'));
+$header->disableMenu();
+
+$hash    = '#pma_' . preg_replace('/([0-9]*)\.([0-9]*)\..*/', '\1_\2', PMA_VERSION);
+$url     = PMA_linkURL('http://www.phpmyadmin.net/home_page/themes.php') . $hash;
+$output  = '<h1>phpMyAdmin - ' . __('Theme') . '</h1>';
+$output .= '<p>';
+$output .= '<a href="' . $url . '" class="_blank">';
+$output .= __('Get more themes!');
+$output .= '</a>';
+$output .= '</p>';
+$output .= $_SESSION['PMA_Theme_Manager']->getPrintPreviews();
+
+$response->addHTML($output);
+
+?>
diff --git a/phpmyadmin/themes/dot.gif b/phpmyadmin/themes/dot.gif
new file mode 100644
index 0000000..35d42e8
Binary files /dev/null and b/phpmyadmin/themes/dot.gif differ
diff --git a/phpmyadmin/themes/original/css/common.css.php b/phpmyadmin/themes/original/css/common.css.php
new file mode 100644
index 0000000..45bd562
--- /dev/null
+++ b/phpmyadmin/themes/original/css/common.css.php
@@ -0,0 +1,2521 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * Common styles for the original theme
+ *
+ * @package    PhpMyAdmin-theme
+ * @subpackage Original
+ */
+
+// unplanned execution path
+if (! defined('PMA_MINIMUM_COMMON') && ! defined('TESTSUITE')) {
+    exit();
+}
+?>
+/******************************************************************************/
+
+/* general tags */
+html {
+    font-size: <?php echo $_SESSION['PMA_Theme']->getFontSize(); ?>
+}
+
+input,
+select,
+textarea {
+    font-size: 1em;
+}
+
+
+body {
+<?php if (! empty($GLOBALS['cfg']['FontFamily'])) { ?>
+    font-family:        <?php echo $GLOBALS['cfg']['FontFamily']; ?>;
+<?php } ?>
+    padding:            0;
+    margin: 0;
+    margin-<?php echo $left; ?>: 240px;
+    color:              <?php echo $GLOBALS['cfg']['MainColor']; ?>;
+    background:         <?php echo $GLOBALS['cfg']['MainBackground']; ?>;
+}
+
+body#loginform {
+    margin: 0;
+}
+
+#page_content {
+    margin: 0 .5em;
+}
+
+<?php if (! empty($GLOBALS['cfg']['FontFamilyFixed'])) { ?>
+textarea, tt, pre, code {
+    font-family:        <?php echo $GLOBALS['cfg']['FontFamilyFixed']; ?>;
+}
+<?php } ?>
+h1 {
+    font-size:          140%;
+    font-weight:        bold;
+}
+
+h2 {
+    font-size:          120%;
+    font-weight:        bold;
+}
+
+h3 {
+    font-weight:        bold;
+}
+
+a, a:link,
+a:visited,
+a:active {
+    text-decoration:    none;
+    color:              #0000FF;
+    cursor:             pointer;
+}
+
+a:hover {
+    text-decoration:    underline;
+    color:              #FF0000;
+}
+
+dfn {
+    font-style:         normal;
+}
+
+dfn:hover {
+    font-style:         normal;
+    cursor:             help;
+}
+
+th {
+    font-weight:        bold;
+    color:              <?php echo $GLOBALS['cfg']['ThColor']; ?>;
+    background:         <?php echo $GLOBALS['cfg']['ThBackground']; ?>;
+}
+
+a img {
+    border:             0;
+}
+
+hr {
+    color:              <?php echo $GLOBALS['cfg']['MainColor']; ?>;
+    background-color:   <?php echo $GLOBALS['cfg']['MainColor']; ?>;
+    border:             0;
+    height:             1px;
+}
+
+form {
+    padding:            0;
+    margin:             0;
+    display:            inline;
+}
+
+textarea {
+    overflow:           visible;
+    height:             <?php echo ceil($GLOBALS['cfg']['TextareaRows'] * 1.2); ?>em;
+}
+
+textarea.char {
+    height:             <?php echo ceil($GLOBALS['cfg']['CharTextareaRows'] * 1.2); ?>em;
+}
+
+fieldset {
+    margin-top:         1em;
+    border:             <?php echo $GLOBALS['cfg']['MainColor']; ?> solid 1px;
+    padding:            0.5em;
+    background:         <?php echo $GLOBALS['cfg']['BgOne']; ?>;
+}
+
+fieldset fieldset {
+    margin:             0.8em;
+}
+
+fieldset legend {
+    font-weight:        bold;
+    color:              #444444;
+    background-color:   <?php echo 'OPERA' != PMA_USR_BROWSER_AGENT ? 'transparent' : $GLOBALS['cfg']['BgOne']; ?>;
+}
+
+.some-margin {
+    margin: .5em;
+    margin-top: 1em;
+}
+
+/* buttons in some browsers (eg. Konqueror) are block elements,
+   this breaks design */
+button {
+    display:            inline;
+}
+
+table caption,
+table th,
+table td {
+    padding:            0.1em 0.5em 0.1em 0.5em;
+    margin:             0.1em;
+    vertical-align:     top;
+}
+
+img,
+input,
+select,
+button {
+    vertical-align:     middle;
+}
+
+/******************************************************************************/
+/* classes */
+.clearfloat {
+    clear: both;
+}
+
+.floatleft {
+    float: <?php echo $left; ?>;
+    margin-<?php echo $right; ?>: 1em;
+}
+
+table.nospacing {
+    border-spacing: 0;
+}
+
+table.nopadding tr th, table.nopadding tr td {
+    padding: 0;
+}
+
+th.left, td.left {
+    text-align: left;
+}
+
+th.center, td.center {
+    text-align: center;
+}
+
+th.right, td.right {
+    text-align: right;
+}
+
+tr.vtop, th.vtop, td.vtop {
+    vertical-align: top;
+}
+
+tr.vmiddle, th.vmiddle, td.vmiddle {
+    vertical-align: middle;
+}
+
+tr.vbottom, th.vbottom, td.vbottom {
+    vertical-align: bottom;
+}
+
+.paddingtop {
+    padding-top: 1em;
+}
+
+div.tools {
+    border: 1px solid #000000;
+    padding: 0.2em;
+}
+
+div.tools,
+fieldset.tblFooters {
+    margin-top:         0;
+    margin-bottom:      0.5em;
+    /* avoid a thick line since this should be used under another fieldset */
+    border-top:         0;
+    text-align:         <?php echo $right; ?>;
+    float:              none;
+    clear:              both;
+}
+
+div.null_div {
+    height: 20px;
+    text-align: center;
+    font-style:normal;
+    min-width:50px;
+}
+
+fieldset .formelement {
+    float:              <?php echo $left; ?>;
+    margin-<?php echo $right; ?>:       0.5em;
+    /* IE */
+    white-space:        nowrap;
+}
+
+/* revert for Gecko */
+fieldset div[class=formelement] {
+    white-space:        normal;
+}
+
+button.mult_submit {
+    border:             none;
+    background-color:   transparent;
+}
+
+/* odd items 1,3,5,7,... */
+table tr.odd th,
+.odd {
+    background: <?php echo $GLOBALS['cfg']['BgOne']; ?>;
+}
+
+/* even items 2,4,6,8,... */
+table tr.even th,
+.even {
+    background: <?php echo $GLOBALS['cfg']['BgTwo']; ?>;
+}
+
+/* odd table rows 1,3,5,7,... */
+table tr.odd th,
+table tr.odd,
+table tr.even th,
+table tr.even {
+    text-align:         <?php echo $left; ?>;
+}
+
+<?php if ($GLOBALS['cfg']['BrowseMarkerEnable']) { ?>
+/* marked table rows */
+td.marked,
+table tr.marked td,
+table tr.marked th,
+table tr.marked {
+    background:   <?php echo $GLOBALS['cfg']['BrowseMarkerBackground']; ?>;
+    color:   <?php echo $GLOBALS['cfg']['BrowseMarkerColor']; ?>;
+}
+<?php } ?>
+
+<?php if ($GLOBALS['cfg']['BrowsePointerEnable']) { ?>
+/* hovered items */
+.odd:hover,
+.even:hover,
+.hover {
+    background: <?php echo $GLOBALS['cfg']['BrowsePointerBackground']; ?>;
+    color: <?php echo $GLOBALS['cfg']['BrowsePointerColor']; ?>;
+}
+
+/* hovered table rows */
+table tr.odd:hover th,
+table tr.even:hover th,
+table tr.hover th {
+    background:   <?php echo $GLOBALS['cfg']['BrowsePointerBackground']; ?>;
+    color:   <?php echo $GLOBALS['cfg']['BrowsePointerColor']; ?>;
+}
+<?php } ?>
+
+/**
+ * marks table rows/cells if the db field is in a where condition
+ */
+td.condition,
+th.condition {
+    border: 1px solid <?php echo $GLOBALS['cfg']['BrowseMarkerBackground']; ?>;
+}
+
+/**
+ * cells with the value NULL
+ */
+td.null {
+    font-style: italic;
+    text-align: <?php echo $right; ?>;
+}
+
+table .valueHeader {
+    text-align:         <?php echo $right; ?>;
+    white-space:        normal;
+}
+table .value {
+    text-align:         <?php echo $right; ?>;
+    white-space:        normal;
+}
+/* IE doesnt handles 'pre' right */
+table [class=value] {
+    white-space:        normal;
+}
+
+
+<?php if (! empty($GLOBALS['cfg']['FontFamilyFixed'])) { ?>
+.value {
+    font-family:        <?php echo $GLOBALS['cfg']['FontFamilyFixed']; ?>;
+}
+<?php } ?>
+.attention {
+    color:              red;
+    font-weight:        bold;
+}
+.allfine {
+    color:              green;
+}
+
+
+img.lightbulb {
+    cursor:             pointer;
+}
+
+.pdflayout {
+    overflow:           hidden;
+    clip:               inherit;
+    background-color:   #FFFFFF;
+    display:            none;
+    border:             1px solid #000000;
+    position:           relative;
+}
+
+.pdflayout_table {
+    background:         #D3DCE3;
+    color:              #000000;
+    overflow:           hidden;
+    clip:               inherit;
+    z-index:            2;
+    display:            inline;
+    visibility:         inherit;
+    cursor:             move;
+    position:           absolute;
+    font-size:          80%;
+    border:             1px dashed #000000;
+}
+
+/* MySQL Parser */
+.syntax {
+    font-size:          80%;
+}
+
+.syntax a {
+    text-decoration: none;
+    border-bottom:1px dotted black;
+}
+
+.syntax_comment {
+    padding-left:       4pt;
+    padding-right:      4pt;
+}
+
+.syntax_digit {
+}
+
+.syntax_digit_hex {
+}
+
+.syntax_digit_integer {
+}
+
+.syntax_digit_float {
+}
+
+.syntax_punct {
+}
+
+.syntax_alpha {
+}
+
+.syntax_alpha_columnType {
+    text-transform:     uppercase;
+}
+
+.syntax_alpha_columnAttrib {
+    text-transform:     uppercase;
+}
+
+.syntax_alpha_reservedWord {
+    text-transform:     uppercase;
+    font-weight:        bold;
+}
+
+.syntax_alpha_functionName {
+    text-transform:     uppercase;
+}
+
+.syntax_alpha_identifier {
+}
+
+.syntax_alpha_charset {
+}
+
+.syntax_alpha_variable {
+}
+
+.syntax_quote {
+    white-space:        pre;
+}
+
+.syntax_quote_backtick {
+}
+
+/* leave some space between icons and text */
+.icon {
+    vertical-align:     middle;
+    margin-right:       0.3em;
+    margin-left:        0.3em;
+}
+
+/* no extra space in table cells */
+td .icon {
+    margin: 0;
+}
+
+.selectallarrow {
+    margin-<?php echo $right; ?>: 0.3em;
+    margin-<?php echo $left; ?>: 0.6em;
+}
+
+/* message boxes: error, confirmation */
+#pma_errors {
+    padding: 0 0.5em;
+}
+
+.success h1,
+.notice h1,
+div.error h1 {
+    border-bottom:      2px solid;
+    font-weight:        bold;
+    text-align:         <?php echo $left; ?>;
+    margin:             0 0 0.2em 0;
+}
+
+div.success,
+div.notice,
+div.error {
+    margin:             0.3em 0 0 0;
+    border:             2px solid;
+    background-repeat:  no-repeat;
+        <?php if ($GLOBALS['text_dir'] === 'ltr') { ?>
+    background-position: 10px 50%;
+    padding:            0.1em 0.1em 0.1em 36px;
+        <?php } else { ?>
+    background-position: 99% 50%;
+    padding:            0.1em 46px 0.1em 0.1em;
+        <?php } ?>
+}
+
+.success {
+    color:              #000000;
+    background-color:   #f0fff0;
+}
+h1.success,
+div.success {
+    border-color:       #00FF00;
+}
+.success h1 {
+    border-color:       #00FF00;
+}
+
+.notice {
+    color:              #000000;
+    background-color:   #FFFFDD;
+}
+h1.notice,
+div.notice {
+    border-color:       #FFD700;
+}
+.notice h1 {
+    border-color:       #FFD700;
+}
+
+.error {
+    background-color:   #FFFFCC;
+    color:              #ff0000;
+}
+
+h1.error,
+div.error {
+    border-color:       #ff0000;
+}
+div.error h1 {
+    border-color:       #ff0000;
+}
+
+.confirmation {
+    background-color:   #FFFFCC;
+}
+fieldset.confirmation {
+    border:             0.1em solid #FF0000;
+}
+fieldset.confirmation legend {
+    border-left:        0.1em solid #FF0000;
+    border-right:       0.1em solid #FF0000;
+    font-weight:        bold;
+    background-image:   url(<?php echo $_SESSION['PMA_Theme']->getImgPath('s_really.png');?>);
+    background-repeat:  no-repeat;
+        <?php if ($GLOBALS['text_dir'] === 'ltr') { ?>
+    background-position: 5px 50%;
+    padding:            0.2em 0.2em 0.2em 25px;
+        <?php } else { ?>
+    background-position: 97% 50%;
+    padding:            0.2em 25px 0.2em 0.2em;
+        <?php } ?>
+}
+/* end messageboxes */
+
+
+.tblcomment {
+    font-size:          70%;
+    font-weight:        normal;
+    color:              #000099;
+}
+
+.tblHeaders {
+    font-weight:        bold;
+    color:              <?php echo $GLOBALS['cfg']['ThColor']; ?>;
+    background:         <?php echo $GLOBALS['cfg']['ThBackground']; ?>;
+}
+
+div.tools,
+.tblFooters {
+    font-weight:        normal;
+    color:              <?php echo $GLOBALS['cfg']['ThColor']; ?>;
+    background:         <?php echo $GLOBALS['cfg']['ThBackground']; ?>;
+}
+
+.tblHeaders a:link,
+.tblHeaders a:active,
+.tblHeaders a:visited,
+div.tools a:link,
+div.tools a:visited,
+div.tools a:active,
+.tblFooters a:link,
+.tblFooters a:active,
+.tblFooters a:visited {
+    color:              #0000FF;
+}
+
+.tblHeaders a:hover,
+div.tools a:hover,
+.tblFooters a:hover {
+    color:              #FF0000;
+}
+
+/* forbidden, no privilegs */
+.noPrivileges {
+    color:              #FF0000;
+    font-weight:        bold;
+}
+
+/* disabled text */
+.disabled,
+.disabled a:link,
+.disabled a:active,
+.disabled a:visited {
+    color:              #666666;
+}
+
+.disabled a:hover {
+    color:              #666666;
+    text-decoration:    none;
+}
+
+tr.disabled td,
+td.disabled {
+    background-color:   #cccccc;
+}
+
+.nowrap {
+    white-space:        nowrap;
+}
+
+/**
+ * zoom search
+ */
+div#resizer {
+    width:              600px;
+    height:             400px;
+}
+div#querychart {
+    float:              left;
+    width:              600px;
+}
+
+/**
+ * login form
+ */
+body#loginform h1,
+body#loginform a.logo {
+    display: block;
+    text-align: center;
+}
+
+body#loginform {
+    margin-top: 1em;
+    text-align: center;
+}
+
+body#loginform div.container {
+    text-align: <?php echo $left; ?>;
+    width: 30em;
+    margin: 0 auto;
+}
+
+form.login label {
+    float: <?php echo $left; ?>;
+    width: 10em;
+    font-weight: bolder;
+}
+
+.commented_column {
+    border-bottom: 1px dashed black;
+}
+
+.column_attribute {
+    font-size: 70%;
+}
+
+/******************************************************************************/
+/* specific elements */
+
+/* topmenu */
+ul#topmenu, ul#topmenu2, ul.tabs {
+    font-weight:        bold;
+    list-style-type:    none;
+    margin:             0;
+    padding:            0;
+}
+
+ul#topmenu2 {
+    margin: 0.25em 0.5em 0;
+    height: 2em;
+    clear: both;
+}
+
+ul#topmenu li, ul#topmenu2 li {
+    float:              <?php echo $left; ?>;
+    margin:             0;
+    padding:            0;
+    vertical-align:     middle;
+}
+
+#topmenu img, #topmenu2 img {
+    vertical-align:     middle;
+    margin-<?php echo $right; ?>:       0.1em;
+}
+
+/* default tab styles */
+ul#topmenu a, ul#topmenu span {
+    display:            block;
+    margin:             2px 2px 0;
+    padding:            2px 2px 0;
+    white-space:        nowrap;
+}
+
+ul#topmenu2 a {
+    display:            block;
+    margin:             0.1em;
+    padding:            0.2em;
+    white-space:        nowrap;
+}
+
+fieldset.caution a {
+    color:              #FF0000;
+}
+fieldset.caution a:hover {
+    color:              #ffffff;
+    background-color:   #FF0000;
+}
+
+#topmenu {
+    margin-top:         0.5em;
+    padding:            0.1em 0.3em 0.1em 0.3em;
+}
+
+ul#topmenu ul {
+    -moz-box-shadow:    2px 2px 3px #666;
+    -webkit-box-shadow: 2px 2px 3px #666;
+    box-shadow:         2px 2px 3px #666;
+}
+
+ul#topmenu > li {
+    border-bottom:      1pt solid black;
+}
+
+/* default tab styles */
+ul#topmenu a, ul#topmenu span {
+    background-color:   <?php echo $GLOBALS['cfg']['BgOne']; ?>;
+    border:             0 solid <?php echo $GLOBALS['cfg']['BgTwo']; ?>;
+    border-width:       1pt 1pt 0 1pt;
+    -moz-border-radius: 0.4em 0.4em 0 0;
+    border-radius:      0.4em 0.4em 0 0;
+}
+
+ul#topmenu ul a {
+    border-width:       1pt 0 0 0;
+    -moz-border-radius: 0;
+    border-radius:      0;
+}
+
+ul#topmenu ul li:first-child a {
+    border-width:       0;
+}
+
+/* enabled hover/active tabs */
+ul#topmenu > li > a:hover,
+ul#topmenu > li > .tabactive {
+    margin:             0;
+    padding:            2px 4px;
+    text-decoration:    none;
+}
+
+ul#topmenu ul a:hover,
+ul#topmenu ul .tabactive {
+    text-decoration:    none;
+}
+
+ul#topmenu a.tab:hover,
+ul#topmenu .tabactive {
+    background-color:   <?php echo $GLOBALS['cfg']['MainBackground']; ?>;
+}
+
+ul#topmenu2 a.tab:hover,
+ul#topmenu2 a.tabactive {
+    background-color:   <?php echo $GLOBALS['cfg']['BgOne']; ?>;
+    -moz-border-radius: 0.3em;
+    border-radius:      0.3em;
+    text-decoration:    none;
+}
+
+/* to be able to cancel the bottom border, use <li class="active"> */
+ul#topmenu > li.active {
+     border-bottom:      1pt solid <?php echo $GLOBALS['cfg']['MainBackground']; ?>;
+}
+/* end topmenu */
+
+/* zoom search */
+div#dataDisplay input, div#dataDisplay select {
+    margin: 0;
+    margin-<?php echo $right; ?>: 0.5em;
+}
+div#dataDisplay th {
+    line-height: 2em;
+}
+
+/* Calendar */
+table.calendar {
+    width:              100%;
+}
+table.calendar td {
+    text-align:         center;
+}
+table.calendar td a {
+    display:            block;
+}
+
+table.calendar td a:hover {
+    background-color:   #CCFFCC;
+}
+
+table.calendar th {
+    background-color:   #D3DCE3;
+}
+
+table.calendar td.selected {
+    background-color:   #FFCC99;
+}
+
+img.calendar {
+    border:             none;
+}
+form.clock {
+    text-align:         center;
+}
+/* end Calendar */
+
+
+/* table stats */
+div#tablestatistics table {
+    float: <?php echo $left; ?>;
+    margin-top: 0.5em;
+    margin-bottom: 0.5em;
+    margin-<?php echo $right; ?>: 0.5em;
+}
+/* END table stats */
+
+
+/* server privileges */
+#tableuserrights td,
+#tablespecificuserrights td,
+#tabledatabases td {
+    vertical-align: middle;
+}
+/* END server privileges */
+
+
+
+/* Heading */
+#topmenucontainer {
+    background: white;
+    padding-<?php echo $right; ?>: 1em;
+    width: 100%;
+}
+
+#serverinfo {
+    background: white;
+    font-weight:        bold;
+    padding-bottom: 0.5em;
+    width: 10000px;
+    overflow: hidden;
+}
+
+#serverinfo .item {
+    white-space:        nowrap;
+    float: <?php echo $left; ?>
+}
+
+#goto_pagetop {
+    position: fixed;
+    padding: .1em .3em;
+    top: 0;
+    <?php echo $right; ?>: 0;
+    z-index: 900;
+    background: white;
+}
+
+#span_table_comment {
+    font-weight:        normal;
+    font-style:         italic;
+    white-space:        nowrap;
+}
+
+#serverinfo img {
+    margin:             0 0.1em 0 0.2em;
+}
+
+
+#textSQLDUMP {
+    width:              95%;
+    height:             95%;
+    font-family:        "Courier New", Courier, mono;
+    font-size:          110%;
+}
+
+#TooltipContainer {
+    position:           absolute;
+    z-index:            99;
+    width:              20em;
+    height:             auto;
+    overflow:           visible;
+    visibility:         hidden;
+    background-color:   #ffffcc;
+    color:              #006600;
+    border:             0.1em solid #000000;
+    padding:            0.5em;
+}
+
+/* user privileges */
+#fieldset_add_user_login div.item {
+    border-bottom:      1px solid silver;
+    padding-bottom:     0.3em;
+    margin-bottom:      0.3em;
+}
+
+#fieldset_add_user_login label {
+    float:              <?php echo $left; ?>;
+    display:            block;
+    width:              10em;
+    max-width:          100%;
+    text-align:         <?php echo $right; ?>;
+    padding-<?php echo $right; ?>:      0.5em;
+}
+
+#fieldset_add_user_login span.options #select_pred_username,
+#fieldset_add_user_login span.options #select_pred_hostname,
+#fieldset_add_user_login span.options #select_pred_password {
+    width:              100%;
+    max-width:          100%;
+}
+
+#fieldset_add_user_login span.options {
+    float: <?php echo $left; ?>;
+    display: block;
+    width: 12em;
+    max-width: 100%;
+    padding-<?php echo $right; ?>: 0.5em;
+}
+
+#fieldset_add_user_login input {
+    width: 12em;
+    clear: <?php echo $right; ?>;
+    max-width: 100%;
+}
+
+#fieldset_add_user_login span.options input {
+    width: auto;
+}
+
+#fieldset_user_priv div.item {
+    float: <?php echo $left; ?>;
+    width: 9em;
+    max-width: 100%;
+}
+
+#fieldset_user_priv div.item div.item {
+    float: none;
+}
+
+#fieldset_user_priv div.item label {
+    white-space: nowrap;
+}
+
+#fieldset_user_priv div.item select {
+    width: 100%;
+}
+
+#fieldset_user_global_rights fieldset {
+    float: <?php echo $left; ?>;
+}
+/* END user privileges */
+
+
+/* serverstatus */
+
+.linkElem:hover {
+    text-decoration:    underline;
+    color:              #235a81;
+    cursor: pointer;
+}
+
+h3#serverstatusqueries span {
+    font-size:60%;
+    display:inline;
+}
+
+img.sortableIcon {
+    float:right;
+    background-repeat:no-repeat;
+    margin:0;
+}
+
+.buttonlinks {
+    float: <?php echo $right; ?>;
+    white-space: nowrap;
+}
+
+/* Also used for the variables page */
+fieldset#tableFilter {
+    margin-bottom:1em;
+}
+
+div#serverStatusTabs {
+    margin-top:1em;
+}
+
+caption a.top {
+    float: <?php echo $right; ?>;
+}
+
+div#serverstatusquerieschart {
+    float:<?php echo $left; ?>;
+    width:500px;
+    height:350px;
+    padding-<?php echo $left; ?>: 30px;
+}
+
+div#serverstatus table#serverstatusqueriesdetails {
+    float: <?php echo $left; ?>;
+}
+
+table#serverstatustraffic {
+    float: <?php echo $left; ?>;
+}
+table#serverstatusconnections {
+    float: <?php echo $left; ?>;
+    margin-<?php echo $left; ?>: 30px;
+}
+
+table#serverstatusvariables {
+    width: 100%;
+    margin-bottom: 1em;
+}
+table#serverstatusvariables .name {
+    width: 18em;
+    white-space:nowrap;
+}
+table#serverstatusvariables .value {
+    width: 6em;
+}
+table#serverstatusconnections {
+    float: <?php echo $left; ?>;
+    margin-<?php echo $left; ?>: 30px;
+}
+
+div#serverstatus table tbody td.descr a,
+div#serverstatus table .tblFooters a {
+    white-space: nowrap;
+}
+
+div.liveChart {
+    clear:both;
+    min-width:500px;
+    height:400px;
+    padding-bottom:80px;
+}
+
+#addChartDialog input[type="text"] {
+    margin: 0;
+    padding:3px;
+}
+
+div#chartVariableSettings {
+    border:1px solid #ddd;
+    background-color:#E6E6E6;
+    margin-left:10px;
+}
+
+table#chartGrid div.monitorChart {
+    background: #EBEBEB;
+}
+
+div#serverstatus div.tabLinks {
+    float:<?php echo $left; ?>;
+    padding-bottom: 10px;
+}
+
+.popupContent {
+    display: none;
+    position: absolute;
+    border: 1px solid #CCC;
+    margin:0;
+    padding:3px;
+    -moz-box-shadow:    1px 1px 6px #ddd;
+    -webkit-box-shadow: 2px 2px 3px #666;
+    box-shadow:         2px 2px 3px #666;
+    background-color:white;
+    z-index: 2;
+}
+
+div#logTable {
+    padding-top: 10px;
+    clear: both;
+}
+
+div#logTable table {
+    width:100%;
+}
+
+.smallIndent {
+    padding-left: 7px;
+}
+
+/* end serverstatus */
+
+/* server variables */
+#serverVariables {
+    min-width: 30em;
+}
+#serverVariables .var-row > div {
+    white-space: nowrap;
+    overflow: hidden;
+    text-overflow: ellipsis;
+    line-height: 2em;
+}
+
+#serverVariables .var-header {
+    font-weight:        bold;
+    color:              <?php echo $GLOBALS['cfg']['ThColor']; ?>;
+    background:         <?php echo $GLOBALS['cfg']['ThBackground']; ?>;
+}
+#serverVariables .var-header .var-value {
+    text-align: <?php echo $left; ?>;
+}
+#serverVariables .var-row {
+    padding: 0.5em;
+    min-height: 18px;
+}
+#serverVariables .var-name {
+    width: 45%;
+    float: <?php echo $left; ?>;
+    font-weight: bold;
+}
+#serverVariables .var-name.session {
+    font-weight: normal;
+    font-style: italic;
+}
+#serverVariables .var-value {
+    width: 50%;
+    float: <?php echo $right; ?>;
+    text-align: <?php echo $right; ?>;
+}
+
+/* server variables editor */
+#serverVariables .editLink {
+    padding-<?php echo $right; ?>: 1em;
+    float: <?php echo $left; ?>;
+    font-family: sans-serif;
+}
+#serverVariables .serverVariableEditor {
+    width: 100%;
+    overflow: hidden;
+}
+#serverVariables .serverVariableEditor input {
+    width: 100%;
+    margin: 0 0.5em;
+    box-sizing: border-box;
+    -ms-box-sizing: border-box;
+    -moz-box-sizing: border-box;
+    -webkit-box-sizing: border-box;
+    height: 2.2em;
+}
+#serverVariables .serverVariableEditor div {
+    display: block;
+    overflow: hidden;
+    padding-<?php echo $right; ?>: 1em;
+}
+#serverVariables .serverVariableEditor a {
+    float: <?php echo $right; ?>;
+    margin: 0 0.5em;
+    line-height: 2em;
+}
+/* end server variables */
+
+/* querywindow */
+body#bodyquerywindow {
+    margin: 0;
+    padding: 0;
+    background-image: none;
+    background-color: #F5F5F5;
+}
+
+div#querywindowcontainer {
+    margin: 0;
+    padding: 0;
+    width: 100%;
+}
+
+div#querywindowcontainer fieldset {
+    margin-top: 0;
+}
+/* END querywindow */
+
+/* profiling */
+
+div#profilingchart {
+    width: 550px;
+    height: 370px;
+    float: left;
+}
+
+/* END profiling */
+
+/* querybox */
+
+div#sqlquerycontainer {
+    float: <?php echo $left; ?>;
+    width: 69%;
+    /* height: 15em; */
+}
+
+div#tablefieldscontainer {
+    float: <?php echo $right; ?>;
+    width: 29%;
+    /* height: 15em; */
+}
+
+div#tablefieldscontainer select {
+    width: 100%;
+    /* height: 12em; */
+}
+
+textarea#sqlquery {
+    width: 100%;
+    /* height: 100%; */
+}
+textarea#sql_query_edit {
+    height: 7em;
+    width: 95%;
+    display: block;
+}
+div#queryboxcontainer div#bookmarkoptions {
+    margin-top: .5em;
+}
+/* end querybox */
+
+/* main page */
+#maincontainer {
+    background-image: url(<?php echo $_SESSION['PMA_Theme']->getImgPath('logo_right.png');?>);
+    background-position: <?php echo $right; ?> bottom;
+    background-repeat: no-repeat;
+}
+
+#mysqlmaininformation,
+#pmamaininformation {
+    float: <?php echo $left; ?>;
+    width: 49%;
+}
+
+#maincontainer ul {
+    list-style-type: disc;
+    vertical-align: middle;
+}
+
+#maincontainer li {
+    margin:  0.2em 0em;
+}
+/* END main page */
+
+/* iconic view for ul items */
+
+li.no_bullets {
+    list-style-type:none !important;    
+    margin-left: -25px !important;      //align with other list items which have bullets
+}
+
+/* END iconic view for ul items */
+
+#body_browse_foreigners {
+    background:         <?php echo $GLOBALS['cfg']['NaviBackground']; ?>;
+    margin: .5em .5em 0 .5em;
+}
+
+#bodyquerywindow {
+    background:         <?php echo $GLOBALS['cfg']['NaviBackground']; ?>;
+}
+
+#bodythemes {
+    width: 500px;
+    margin: auto;
+    text-align: center;
+}
+
+#bodythemes img {
+    border: .1em solid #000;
+}
+
+#bodythemes a:hover img {
+    border: .1em solid red;
+}
+
+#fieldset_select_fields {
+    float: <?php echo $left; ?>;
+}
+
+#selflink {
+    clear: both;
+    display: block;
+    margin-top: 1em;
+    margin-bottom: 1em;
+    width: 98%;
+    margin-left: 1%;
+    border-top: .1em solid silver;
+    text-align: <?php echo $right; ?>;
+}
+
+#table_innodb_bufferpool_usage,
+#table_innodb_bufferpool_activity {
+    float: <?php echo $left; ?>;
+}
+
+#div_mysql_charset_collations table {
+    float: <?php echo $left; ?>;
+}
+
+.operations_half_width {
+    width: 48%;
+    float: <?php echo $left; ?>;
+}
+
+.operations_full_width {
+    width: 100%;
+    clear: both;
+}
+
+#qbe_div_table_list {
+    float: <?php echo $left; ?>;
+}
+
+#qbe_div_sql_query {
+    float: <?php echo $left; ?>;
+}
+
+label.desc {
+    width: 30em;
+    float: <?php echo $left; ?>;
+}
+
+label.desc sup {
+    position: absolute;
+}
+
+code.sql,
+div.sqlvalidate {
+    display:            block;
+    padding:            0.3em;
+    margin-top:         0;
+    margin-bottom:      0;
+    border:             <?php echo $GLOBALS['cfg']['MainColor']; ?> solid 1px;
+    border-top:         0;
+    border-bottom:      0;
+    max-height:         10em;
+    overflow:           auto;
+    background:         <?php echo $GLOBALS['cfg']['BgOne']; ?>;
+}
+
+#main_pane_left {
+    width:              60%;
+    float:              <?php echo $left; ?>;
+    padding-top:        1em;
+}
+
+#main_pane_right {
+    margin-<?php echo $left; ?>: 60%;
+    padding-top: 1em;
+    padding-<?php echo $left; ?>: 1em;
+}
+
+.group {
+    border-<?php echo $left; ?>: 0.3em solid <?php echo $GLOBALS['cfg']['ThBackground']; ?>;
+    margin-bottom:      1em;
+}
+
+.group h2 {
+    background:         <?php echo $GLOBALS['cfg']['ThBackground']; ?>;
+    padding:            0.1em 0.3em;
+    margin-top:         0;
+}
+
+.group-cnt {
+    padding: 0 0 0 0.5em;
+    display: inline-block;
+    width: 98%;
+}
+
+textarea#partitiondefinition {
+    height:3em;
+}
+
+
+/* for elements that should be revealed only via js */
+.hide {
+    display:            none;
+}
+
+#list_server {
+    list-style-image: none;
+}
+
+/**
+  *  Progress bar styles
+  */
+div.upload_progress
+{
+    width: 400px;
+    margin: 3em auto;
+    text-align: center;
+}
+
+div.upload_progress_bar_outer
+{
+    border: 1px solid #000;
+    width: 202px;
+    position: relative;
+    margin: 0 auto 1em;
+    color: <?php echo $GLOBALS['cfg']['MainColor']; ?>;
+}
+
+div.upload_progress_bar_inner
+{
+    background-color: <?php echo $GLOBALS['cfg']['NaviBackground']; ?>;
+    width: 0;
+    height: 12px;
+    margin: 1px;
+    overflow: hidden;
+    color: <?php echo $GLOBALS['cfg']['BrowseMarkerColor']; ?>;
+    position: relative;
+}
+
+div.upload_progress_bar_outer div.percentage
+{
+    position: absolute;
+    top: 0;
+    left: 0;
+    width: 202px;
+}
+
+div.upload_progress_bar_inner div.percentage
+{
+    top: -1px;
+    left: -1px;
+}
+
+div#statustext {
+    margin-top: .5em;
+}
+
+table#serverconnection_src_remote,
+table#serverconnection_trg_remote,
+table#serverconnection_src_local,
+table#serverconnection_trg_local  {
+  float: left;
+}
+/**
+  *  Validation error message styles
+  */
+input[type=text].invalid_value,
+.invalid_value {
+    background: #FFCCCC;
+}
+
+/**
+  *  Ajax notification styling
+  */
+ .ajax_notification {
+    top: 0;           /** The notification needs to be shown on the top of the page */
+    position: fixed;
+    margin-top: 0;
+    margin-right: auto;
+    margin-bottom: 0;
+    margin-left: auto;
+    padding: 3px 5px;   /** Keep a little space on the sides of the text */
+    width: 350px;
+    background-color: #FFD700;
+    z-index: 1100;      /** If this is not kept at a high z-index, the jQueryUI modal dialogs (z-index:1000) might hide this */
+    text-align: center;
+    display: block;
+    left: 0;
+    right: 0;
+    background-image: url(<?php echo $_SESSION['PMA_Theme']->getImgPath('ajax_clock_small.gif');?>);
+    background-repeat: no-repeat;
+    background-position: 2%;
+ }
+
+ #loading_parent {
+    /** Need this parent to properly center the notification division */
+    position: relative;
+    width: 100%;
+ }
+/**
+  * Export and Import styles
+  */
+
+.exportoptions h3, .importoptions h3 {
+    border-bottom: 1px #999999 solid;
+    font-size: 110%;
+}
+
+.exportoptions ul, .importoptions ul, .format_specific_options ul {
+    list-style-type: none;
+    margin-bottom: 15px;
+}
+
+.exportoptions li, .importoptions li {
+    margin: 7px;
+}
+.exportoptions label, .importoptions label, .exportoptions p, .importoptions p {
+    margin: 5px;
+    float: none;
+}
+
+#csv_options label.desc, #ldi_options label.desc, #latex_options label.desc, #output label.desc{
+    float: left;
+    width: 15em;
+}
+
+.exportoptions, .importoptions {
+    margin: 20px 30px 30px 10px
+}
+
+.format_specific_options h3 {
+    margin: 10px 0 0 10px;
+    border: 0;
+}
+
+.format_specific_options {
+    border: 1px solid #999;
+    margin: 7px 0;
+    padding: 3px;
+}
+
+p.desc {
+    margin: 5px;
+}
+
+/**
+  * Export styles only
+  */
+select#db_select,
+select#table_select {
+    width: 400px;
+}
+
+.export_sub_options {
+    margin: 20px 0 0 30px;
+}
+
+.export_sub_options h4 {
+    border-bottom: 1px #999 solid;
+}
+
+.export_sub_options li.subgroup {
+    display: inline-block;
+    margin-top: 0;
+}
+
+.export_sub_options li {
+    margin-bottom: 0;
+}
+
+#quick_or_custom,
+#output_quick_export {
+    display: none;
+}
+/**
+ * Import styles only
+ */
+
+.importoptions #import_notification {
+    margin: 10px 0;
+    font-style: italic;
+}
+
+input#input_import_file {
+    margin: 5px;
+}
+
+.formelementrow {
+    margin: 5px 0 5px 0;
+}
+
+#popup_background {
+    display: none;
+    position: fixed;
+    _position: absolute; /* hack for IE6 */
+    width: 100%;
+    height: 100%;
+    top: 0;
+    left: 0;
+    background: #000;
+    z-index: 1000;
+    overflow: hidden;
+}
+
+/**
+ * Create table styles
+ */
+#create_table_form table.table-name td {
+    vertical-align: middle;
+}
+
+/**
+ * Table structure styles
+ */
+#fieldsForm ul.table-structure-actions {
+    margin: 0;
+    padding: 0;
+    list-style: none;
+}
+#fieldsForm ul.table-structure-actions li {
+    float: <?php echo $left; ?>;
+    margin-<?php echo $right; ?>: 0.5em; /* same as padding of "table td" */
+}
+#fieldsForm ul.table-structure-actions .submenu li {
+    padding: 0.3em;
+    margin: 0.1em;
+}
+
+.margin#change_column_dialog {
+    margin: 0 .5em;
+}
+
+/**
+ * Indexes
+ */
+#index_frm .index_info input,
+#index_frm .index_info select {
+    width: 100%;
+    box-sizing:         border-box;
+    -ms-box-sizing:     border-box;
+    -moz-box-sizing:    border-box;
+    -webkit-box-sizing: border-box;
+}
+
+#index_frm .slider {
+    width: 10em;
+    margin: .6em;
+    float: <?php echo $left; ?>;
+}
+
+#index_frm .add_fields {
+    float: <?php echo $left; ?>;
+}
+
+#index_frm .add_fields input {
+    margin-<?php echo $left; ?>: 1em;
+}
+
+#index_frm input {
+    margin: 0;
+}
+
+#index_frm td {
+    vertical-align: middle;
+}
+
+table#index_columns {
+    width: 100%;
+}
+
+table#index_columns select {
+    width: 100%;
+}
+
+#move_columns_dialog div {
+    padding: 1em;
+}
+
+#move_columns_dialog ul {
+    list-style: none;
+    margin: 0;
+    padding: 0;
+}
+
+#move_columns_dialog li {
+    background: <?php echo $GLOBALS['cfg']['ThBackground']; ?>;
+    border: 1px solid #aaa;
+    color: <?php echo $GLOBALS['cfg']['ThColor']; ?>;
+    font-weight: bold;
+    margin: .4em;
+    padding: .2em;
+    -webkit-border-radius: 2px;
+    -moz-border-radius: 2px;
+    border-radius: 2px;
+}
+
+/* config forms */
+.config-form ul.tabs {
+    margin:      1.1em 0.2em 0;
+    padding:     0 0 0.3em 0;
+    list-style:  none;
+    font-weight: bold;
+}
+
+.config-form ul.tabs li {
+    float: <?php echo $left; ?>;
+}
+
+.config-form ul.tabs li a {
+    display:          block;
+    margin:           0.1em 0.2em 0;
+    padding:          0.1em 0.4em;
+    white-space:      nowrap;
+    text-decoration:  none;
+    border:           1px solid <?php echo $GLOBALS['cfg']['BgTwo']; ?>;
+    border-bottom:    none;
+}
+
+.config-form ul.tabs li a:hover,
+.config-form ul.tabs li a:active,
+.config-form ul.tabs li a.active {
+    margin:           0;
+    padding:          0.1em 0.6em 0.2em;
+}
+
+.config-form ul.tabs li.active a {
+    background-color: <?php echo $GLOBALS['cfg']['BgOne']; ?>;
+}
+
+.config-form fieldset {
+    margin-top:   0;
+    padding:      0;
+    clear:        both;
+    /*border-color: <?php echo $GLOBALS['cfg']['BgTwo']; ?>;*/
+}
+
+.config-form legend {
+    display: none;
+}
+
+.config-form fieldset p {
+    margin:    0;
+    padding:   0.5em;
+    background: <?php echo $GLOBALS['cfg']['BgTwo']; ?>;
+}
+
+.config-form fieldset .errors { /* form error list */
+    margin:       0 -2px 1em -2px;
+    padding: .5em 1.5em;
+    background:   #FBEAD9;
+    border:       0 #C83838 solid;
+    border-width: 1px 0;
+    list-style:   none;
+    font-family:  sans-serif;
+    font-size:    small;
+}
+
+.config-form fieldset .inline_errors { /* field error list */
+    margin: .3em .3em .3em 0;
+    padding:    0;
+    list-style: none;
+    color:      #9A0000;
+    font-size:  small;
+}
+
+.config-form fieldset th {
+    padding: .3em .3em .3em .5em;
+    text-align:     left;
+    vertical-align: top;
+    width:          40%;
+    background:     transparent;
+}
+
+.config-form fieldset .doc,
+.config-form fieldset .disabled-notice {
+    margin-left: 1em;
+}
+
+.config-form fieldset .disabled-notice {
+    font-size: 80%;
+    text-transform: uppercase;
+    color: #E00;
+    cursor: help;
+}
+
+.config-form fieldset td {
+    padding-top: .3em;
+    padding-bottom: .3em;
+    vertical-align: top;
+}
+
+.config-form fieldset th small {
+    display:     block;
+    font-weight: normal;
+    font-family: sans-serif;
+    font-size:   x-small;
+    color:       #444;
+}
+
+.config-form fieldset th,
+.config-form fieldset td {
+    border-top: 1px <?php echo $GLOBALS['cfg']['BgTwo']; ?> solid;
+}
+
+fieldset .group-header th {
+    background: <?php echo $GLOBALS['cfg']['BgTwo']; ?>;
+}
+
+fieldset .group-header + tr th {
+    padding-top: .6em;
+}
+
+fieldset .group-field-1 th,
+fieldset .group-header-2 th {
+    padding-left: 1.5em;
+}
+
+fieldset .group-field-2 th,
+fieldset .group-header-3 th {
+    padding-left: 3em;
+}
+
+fieldset .group-field-3 th {
+    padding-left: 4.5em;
+}
+
+fieldset .disabled-field th,
+fieldset .disabled-field th small,
+fieldset .disabled-field td {
+    color: #666;
+    background-color: #ddd;
+}
+
+.config-form .lastrow {
+    border-top: 1px #000 solid;
+}
+
+.config-form .lastrow {
+    background: <?php echo $GLOBALS['cfg']['ThBackground']; ?>;;
+    padding: .5em;
+    text-align: center;
+}
+
+.config-form .lastrow input {
+    font-weight: bold;
+}
+
+/* form elements */
+
+.config-form span.checkbox {
+    padding: 2px;
+    display: inline-block;
+}
+
+.config-form .custom { /* customized field */
+    background: #FFC;
+}
+
+.config-form span.checkbox.custom {
+    padding:    1px;
+    border:     1px #EDEC90 solid;
+    background: #FFC;
+}
+
+.config-form .field-error {
+    border-color: #A11 !important;
+}
+
+.config-form input[type="text"],
+.config-form select,
+.config-form textarea {
+    border: 1px #A7A6AA solid;
+    height: auto;
+}
+
+.config-form input[type="text"]:focus,
+.config-form select:focus,
+.config-form textarea:focus {
+    border:     1px #6676FF solid;
+    background: #F7FBFF;
+}
+
+.config-form .field-comment-mark {
+    font-family: serif;
+    color: #007;
+    cursor: help;
+    padding: 0 0.2em;
+    font-weight: bold;
+    font-style: italic;
+}
+
+.config-form .field-comment-warning {
+    color: #A00;
+}
+
+/* error list */
+.config-form dd {
+    margin-left: .5em;
+}
+
+.config-form dd:before {
+    content: "\25B8  ";
+}
+
+.click-hide-message {
+    cursor: pointer;
+}
+
+.prefsmanage_opts {
+    margin-<?php echo $left; ?>: 2em;
+}
+
+#prefs_autoload {
+    margin-bottom: .5em;
+}
+
+#placeholder .button {
+    position: absolute;
+    cursor: pointer;
+}
+
+#placeholder div.button {
+    font-size: smaller;
+    color: #999;
+    background-color: #eee;
+    padding: 2px;
+}
+
+.wrapper {
+    float: <?php echo $left; ?>;
+    margin-bottom: 0.5em;
+}
+.toggleButton {
+    position: relative;
+    cursor: pointer;
+    font-size: .8em;
+    text-align: center;
+    line-height: 1.4em;
+    height: 1.55em;
+    overflow: hidden;
+    border-right: .1em solid #888;
+    border-left: .1em solid #888;
+}
+.toggleButton table,
+.toggleButton td,
+.toggleButton img {
+    padding: 0;
+    position: relative;
+}
+.toggleButton .container {
+    position: absolute;
+}
+.toggleButton .toggleOn {
+    color: #fff;
+    padding: 0 1em;
+}
+.toggleButton .toggleOff {
+    padding: 0 1em;
+}
+
+.doubleFieldset fieldset {
+    width: 48%;
+    float: <?php echo $left; ?>;
+    padding: 0;
+}
+.doubleFieldset fieldset.left {
+    margin-<?php echo $right; ?>: 1%;
+}
+.doubleFieldset fieldset.right {
+    margin-<?php echo $left; ?>: 1%;
+}
+.doubleFieldset legend {
+    margin-<?php echo $left; ?>: 0.5em;
+}
+.doubleFieldset div.wrap {
+    padding: 0.5em;
+}
+
+#table_columns input[type="text"],
+#table_columns select {
+    width:              10em;
+    box-sizing:         border-box;
+    -ms-box-sizing:     border-box;
+    -moz-box-sizing:    border-box;
+    -webkit-box-sizing: border-box;
+}
+
+#placeholder {
+    position: relative;
+    border: 1px solid #aaa;
+    float: right;
+    overflow: hidden;
+}
+
+.placeholderDrag {
+    cursor: move;
+}
+
+#placeholder .button {
+    position: absolute;
+}
+
+#left_arrow {
+    left: 8px;
+    top: 26px;
+}
+
+#right_arrow {
+    left: 26px;
+    top: 26px;
+}
+
+#up_arrow {
+    left: 17px;
+    top: 8px;
+}
+
+#down_arrow {
+    left: 17px;
+    top: 44px;
+}
+
+#zoom_in {
+    left: 17px;
+    top: 67px;
+}
+
+#zoom_world {
+    left: 17px;
+    top: 85px;
+}
+
+#zoom_out {
+    left: 17px;
+    top: 103px;
+}
+
+.colborder {
+    cursor: col-resize;
+    height: 100%;
+    margin-left: -5px;
+    position: absolute;
+    width: 5px;
+}
+
+.colborder_active {
+    border-right: 2px solid #a44;
+}
+
+.pma_table td {
+    position: static;
+}
+
+.pma_table th.draggable span,
+.pma_table tbody td span {
+    display: block;
+    overflow: hidden;
+}
+
+.modal-copy input {
+    display: block;
+    width: 100%;
+    margin-top: 1.5em;
+    padding: .3em 0;
+}
+
+.cRsz {
+    position: absolute;
+}
+
+.draggable {
+    cursor: move;
+}
+
+.cCpy {
+    background: #000;
+    color: #FFF;
+    font-weight: bold;
+    margin: 0.1em;
+    padding: 0.3em;
+    position: absolute;
+}
+
+.cPointer {
+    background: url(<?php echo $_SESSION['PMA_Theme']->getImgPath('col_pointer.png');?>);
+    height: 20px;
+    margin-left: -5px;  /* must be minus half of its width */
+    margin-top: -10px;
+    position: absolute;
+    width: 10px;
+}
+
+.tooltip {
+    background: #333 !important;
+    opacity: .8 !important;
+    border: 1px solid #000 !important;
+    -moz-border-radius: .3em !important;
+    -webkit-border-radius: .3em !important;
+    border-radius: .3em !important;
+    text-shadow: -1px -1px #000 !important;
+    font-size: .8em !important;
+    font-weight: bold !important;
+    padding: 1px 3px !important;
+}
+
+.tooltip * {
+    background: none !important;
+    color: #FFF !important;
+}
+
+
+.data_full_width {
+    width: 100%;
+}
+
+.cDrop {
+    left: 0;
+    position: absolute;
+    top: 0;
+}
+
+.coldrop {
+    background: url(<?php echo $_SESSION['PMA_Theme']->getImgPath('col_drop.png');?>);
+    cursor: pointer;
+    height: 16px;
+    margin-left: 0.5em;
+    margin-top: 0.3em;
+    position: absolute;
+    width: 16px;
+}
+
+.coldrop:hover,
+.coldrop-hover {
+    background-color: #999;
+}
+
+.cList {
+    background: #EEE;
+    border: solid 1px #999;
+    position: absolute;
+}
+
+.cList .lDiv div {
+    padding: .2em .5em .2em .2em;
+}
+
+.cList .lDiv div:hover {
+    background: #DDD;
+    cursor: pointer;
+}
+
+.cList .lDiv div input {
+    cursor: pointer;
+}
+
+.showAllColBtn {
+    border-bottom: solid 1px #999;
+    border-top: solid 1px #999;
+    cursor: pointer;
+    font-size: .9em;
+    font-weight: bold;
+    padding: .35em 1em;
+    text-align: center;
+}
+
+.showAllColBtn:hover {
+    background: #DDD;
+}
+
+.navigation {
+    background: #E5E5E5;
+    border: 1px solid black;
+    margin: 0.8em 0;
+}
+
+.navigation td {
+    margin: 0;
+    padding: 0;
+    vertical-align: middle;
+    white-space: nowrap;
+}
+
+.navigation_separator {
+    color: #555;
+    display: inline-block;
+    text-align: center;
+    width: 1.2em;
+    text-shadow: 1px 0 #FFF;
+}
+
+.navigation input[type=submit] {
+    background: none;
+    border: 0;
+    margin: 0;
+    padding: 0.3em 0.5em;
+    min-width: 1.5em;
+    font-weight: bold;
+}
+
+.navigation input[type=submit]:hover, .navigation input.edit_mode_active {
+    background: #333;
+    color: white;
+    cursor: pointer;
+}
+
+.navigation select {
+    margin: 0 .8em;
+}
+
+.cEdit {
+    margin: 0;
+    padding: 0;
+    position: absolute;
+}
+
+.cEdit input[type=text] {
+    background: #FFF;
+    height: 100%;
+    margin: 0;
+    padding: 0;
+}
+
+.cEdit .edit_area {
+    background: #FFF;
+    border: 1px solid #999;
+    min-width: 10em;
+    padding: .3em .5em;
+}
+
+.cEdit .edit_area select,
+.cEdit .edit_area textarea {
+    width: 97%;
+}
+
+.cEdit .cell_edit_hint {
+    color: #555;
+    font-size: .8em;
+    margin: .3em .2em;
+}
+
+.cEdit .edit_box {
+    overflow: hidden;
+    padding: 0;
+}
+
+.cEdit .edit_box_posting {
+    background: #FFF url(<?php echo $_SESSION['PMA_Theme']->getImgPath('ajax_clock_small.gif');?>) no-repeat right center;
+    padding-right: 1.5em;
+}
+
+.cEdit .edit_area_loading {
+    background: #FFF url(<?php echo $_SESSION['PMA_Theme']->getImgPath('ajax_clock_small.gif');?>) no-repeat center;
+    height: 10em;
+}
+
+.cEdit .goto_link {
+    background: #EEE;
+    color: #555;
+    padding: .2em .3em;
+}
+
+.saving_edited_data {
+    background: url(<?php echo $_SESSION['PMA_Theme']->getImgPath('ajax_clock_small.gif');?>) no-repeat left;
+    padding-left: 20px;
+}
+
+/* css for timepicker */
+.ui-timepicker-div .ui-widget-header { margin-bottom: 8px; }
+.ui-timepicker-div dl { text-align: left; }
+.ui-timepicker-div dl dt { height: 25px; }
+.ui-timepicker-div dl dd { margin: -25px 0 10px 65px; }
+.ui-timepicker-div td { font-size: 90%; }
+
+input.btn {
+    color: #333;
+    background-color: #D0DCE0;
+}
+
+body .ui-widget {
+    font-size: 1em;
+}
+
+.ui-dialog fieldset legend a {
+    color: #0000FF;
+}
+
+/* jqPlot */
+
+/*rules for the plot target div.  These will be cascaded down to all plot elements according to css rules*/
+.jqplot-target {
+    position: relative;
+    color: #222222;
+    font-family: "Trebuchet MS", Arial, Helvetica, sans-serif;
+    font-size: 1em;
+/*    height: 300px;
+    width: 400px;*/
+}
+
+/*rules applied to all axes*/
+.jqplot-axis {
+    font-size: 0.75em;
+}
+
+.jqplot-xaxis {
+    margin-top: 10px;
+}
+
+.jqplot-x2axis {
+    margin-bottom: 10px;
+}
+
+.jqplot-yaxis {
+    margin-right: 10px;
+}
+
+.jqplot-y2axis, .jqplot-y3axis, .jqplot-y4axis, .jqplot-y5axis, .jqplot-y6axis, .jqplot-y7axis, .jqplot-y8axis, .jqplot-y9axis, .jqplot-yMidAxis {
+    margin-left: 10px;
+    margin-right: 10px;
+}
+
+/*rules applied to all axis tick divs*/
+.jqplot-axis-tick, .jqplot-xaxis-tick, .jqplot-yaxis-tick, .jqplot-x2axis-tick, .jqplot-y2axis-tick, .jqplot-y3axis-tick, .jqplot-y4axis-tick, .jqplot-y5axis-tick, .jqplot-y6axis-tick, .jqplot-y7axis-tick, .jqplot-y8axis-tick, .jqplot-y9axis-tick, .jqplot-yMidAxis-tick {
+    position: absolute;
+    white-space: pre;
+}
+
+
+.jqplot-xaxis-tick {
+    top: 0px;
+    /* initial position untill tick is drawn in proper place */
+    left: 15px;
+/*    padding-top: 10px;*/
+    vertical-align: top;
+}
+
+.jqplot-x2axis-tick {
+    bottom: 0px;
+    /* initial position untill tick is drawn in proper place */
+    left: 15px;
+/*    padding-bottom: 10px;*/
+    vertical-align: bottom;
+}
+
+.jqplot-yaxis-tick {
+    right: 0px;
+    /* initial position untill tick is drawn in proper place */
+    top: 15px;
+/*    padding-right: 10px;*/
+    text-align: right;
+}
+
+.jqplot-yaxis-tick.jqplot-breakTick {
+    right: -20px;
+    margin-right: 0px;
+    padding:1px 5px 1px 5px;
+/*  background-color: white;*/
+    z-index: 2;
+    font-size: 1.5em;
+}
+
+.jqplot-y2axis-tick, .jqplot-y3axis-tick, .jqplot-y4axis-tick, .jqplot-y5axis-tick, .jqplot-y6axis-tick, .jqplot-y7axis-tick, .jqplot-y8axis-tick, .jqplot-y9axis-tick {
+    left: 0px;
+    /* initial position untill tick is drawn in proper place */
+    top: 15px;
+/*    padding-left: 10px;*/
+/*    padding-right: 15px;*/
+    text-align: left;
+}
+
+.jqplot-yMidAxis-tick {
+    text-align: center;
+    white-space: nowrap;
+}
+
+.jqplot-xaxis-label {
+    margin-top: 10px;
+    font-size: 11pt;
+    position: absolute;
+}
+
+.jqplot-x2axis-label {
+    margin-bottom: 10px;
+    font-size: 11pt;
+    position: absolute;
+}
+
+.jqplot-yaxis-label {
+    margin-right: 10px;
+/*    text-align: center;*/
+    font-size: 11pt;
+    position: absolute;
+}
+
+.jqplot-yMidAxis-label {
+    font-size: 11pt;
+    position: absolute;
+}
+
+.jqplot-y2axis-label, .jqplot-y3axis-label, .jqplot-y4axis-label, .jqplot-y5axis-label, .jqplot-y6axis-label, .jqplot-y7axis-label, .jqplot-y8axis-label, .jqplot-y9axis-label {
+/*    text-align: center;*/
+    font-size: 11pt;
+    margin-left: 10px;
+    position: absolute;
+}
+
+.jqplot-meterGauge-tick {
+    font-size: 0.75em;
+    color: #999999;
+}
+
+.jqplot-meterGauge-label {
+    font-size: 1em;
+    color: #999999;
+}
+
+table.jqplot-table-legend {
+    margin-top: 12px;
+    margin-bottom: 12px;
+    margin-left: 12px;
+    margin-right: 12px;
+}
+
+table.jqplot-table-legend, table.jqplot-cursor-legend {
+    background-color: rgba(255,255,255,0.6);
+    border: 1px solid #cccccc;
+    position: absolute;
+    font-size: 0.75em;
+}
+
+td.jqplot-table-legend {
+    vertical-align:middle;
+}
+
+/*
+These rules could be used instead of assigning
+element styles and relying on js object properties.
+*/
+
+/*
+td.jqplot-table-legend-swatch {
+    padding-top: 0.5em;
+    text-align: center;
+}
+
+tr.jqplot-table-legend:first td.jqplot-table-legend-swatch {
+    padding-top: 0px;
+}
+*/
+
+td.jqplot-seriesToggle:hover, td.jqplot-seriesToggle:active {
+    cursor: pointer;
+}
+
+.jqplot-table-legend .jqplot-series-hidden {
+    text-decoration: line-through;
+}
+
+div.jqplot-table-legend-swatch-outline {
+    border: 1px solid #cccccc;
+    padding:1px;
+}
+
+div.jqplot-table-legend-swatch {
+    width:0px;
+    height:0px;
+    border-top-width: 5px;
+    border-bottom-width: 5px;
+    border-left-width: 6px;
+    border-right-width: 6px;
+    border-top-style: solid;
+    border-bottom-style: solid;
+    border-left-style: solid;
+    border-right-style: solid;
+}
+
+.jqplot-title {
+    top: 0px;
+    left: 0px;
+    padding-bottom: 0.5em;
+    font-size: 1.2em;
+}
+
+table.jqplot-cursor-tooltip {
+    border: 1px solid #cccccc;
+    font-size: 0.75em;
+}
+
+
+.jqplot-cursor-tooltip {
+    border: 1px solid #cccccc;
+    font-size: 0.75em;
+    white-space: nowrap;
+    background: rgba(208,208,208,0.5);
+    padding: 1px;
+}
+
+.jqplot-highlighter-tooltip, .jqplot-canvasOverlay-tooltip {
+    border: 1px solid #cccccc;
+    font-size: 0.75em;
+    white-space: nowrap;
+    background: rgba(208,208,208,0.5);
+    padding: 1px;
+}
+
+.jqplot-point-label {
+    font-size: 0.75em;
+    z-index: 2;
+}
+
+td.jqplot-cursor-legend-swatch {
+    vertical-align: middle;
+    text-align: center;
+}
+
+div.jqplot-cursor-legend-swatch {
+    width: 1.2em;
+    height: 0.7em;
+}
+
+.jqplot-error {
+/*   Styles added to the plot target container when there is an error go here.*/
+    text-align: center;
+}
+
+.jqplot-error-message {
+/*    Styling of the custom error message div goes here.*/
+    position: relative;
+    top: 46%;
+    display: inline-block;
+}
+
+div.jqplot-bubble-label {
+    font-size: 0.8em;
+/*    background: rgba(90%, 90%, 90%, 0.15);*/
+    padding-left: 2px;
+    padding-right: 2px;
+    color: rgb(20%, 20%, 20%);
+}
+
+div.jqplot-bubble-label.jqplot-bubble-label-highlight {
+    background: rgba(90%, 90%, 90%, 0.7);
+}
+
+div.jqplot-noData-container {
+    text-align: center;
+    background-color: rgba(96%, 96%, 96%, 0.3);
+}
diff --git a/phpmyadmin/themes/original/css/navigation.css.php b/phpmyadmin/themes/original/css/navigation.css.php
new file mode 100644
index 0000000..7db6fb8
--- /dev/null
+++ b/phpmyadmin/themes/original/css/navigation.css.php
@@ -0,0 +1,252 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * Navigation styles for the original theme
+ *
+ * @package    PhpMyAdmin-theme
+ * @subpackage Original
+ */
+
+// unplanned execution path
+if (! defined('PMA_MINIMUM_COMMON') && ! defined('TESTSUITE')) {
+    exit();
+}
+?>
+
+/******************************************************************************/
+/* Navigation */
+
+#pma_navigation {
+    background: <?php echo $GLOBALS['cfg']['NaviBackground']; ?>;
+    color: <?php echo $GLOBALS['cfg']['NaviColor']; ?>;
+    width: <?php echo $GLOBALS['cfg']['NaviWidth']; ?>px;
+    overflow: hidden;
+    overflow-y: auto;
+    position: fixed;
+    top: 0;
+    <?php echo $left; ?>: 0;
+    height: 100%;
+    border-<?php echo $right; ?>: 1px solid gray;
+    z-index: 800;
+}
+
+#pma_navigation_content {
+    width: 100%;
+    position: absolute;
+    top: 0;
+    <?php echo $left; ?>: 0;
+    z-index: 0;
+    padding-bottom: 1em;
+}
+
+#pma_navigation ul {
+    margin: 0;
+}
+
+#pma_navigation form {
+    margin: 0;
+    padding: 0;
+    display: inline;
+}
+
+#pma_navigation select#select_server,
+#pma_navigation select#lightm_db {
+    width: 100%;
+}
+
+/******************************************************************************/
+/* specific elements */
+
+#pma_navigation div.pageselector {
+    text-align: center;
+    margin: 0 0 0;
+    margin-<?php echo $left; ?>: 0.75em;
+    border-<?php echo $left; ?>: 1px solid #666;
+}
+
+#pma_navigation div#pmalogo {
+    <?php //better echo $GLOBALS['cfg']['logoBGC']; ?>
+    background-color: <?php echo $GLOBALS['cfg']['NaviBackground']; ?>;
+    padding: .3em;
+}
+
+#pma_navigation div#recentTableList {
+    text-align: center;
+    margin-bottom: 0.5em;
+}
+
+#pma_navigation #pmalogo,
+#pma_navigation #serverChoice,
+#pma_navigation #leftframelinks,
+#pma_navigation #recentTableList,
+#pma_navigation #databaseList,
+#pma_navigation div.pageselector.dbselector {
+    text-align:         center;
+    margin-bottom:      0.3em;
+    padding-bottom:     0.3em;
+    border: 0;
+}
+
+#pma_navigation #recentTableList select,
+#pma_navigation #serverChoice select
+ {
+    width: 80%;
+}
+
+#pma_navigation #recentTableList {
+    margin-bottom: 0;
+    padding-bottom: 0;
+}
+
+#pma_navigation_content > img.throbber {
+    display: block;
+    margin: 0 auto;
+}
+
+/* Navigation tree*/
+#pma_navigation_tree {
+    margin: 0.5em 0 0;
+    margin-<?php echo $left; ?>: 1em;
+    color: #444;
+}
+#pma_navigation_tree a {
+    color: <?php echo $GLOBALS['cfg']['NaviColor']; ?>;
+}
+#pma_navigation_tree a:hover {
+    text-decoration: underline;
+}
+#pma_navigation_tree li.activePointer {
+    color: <?php echo $GLOBALS['cfg']['NaviPointerColor']; ?>;
+    background-color: <?php echo $GLOBALS['cfg']['NaviPointerBackground']; ?>;
+}
+#pma_navigation_tree ul {
+    clear: both;
+    padding: 0;
+    list-style-type: none;
+    margin: 0;
+}
+#pma_navigation_tree ul ul {
+    position: relative;
+}
+#pma_navigation_tree li {
+    white-space: nowrap;
+    clear: both;
+    min-height: 16px;
+}
+#pma_navigation_tree img {
+    margin: 0;
+}
+#pma_navigation_tree div.block {
+    position: relative;
+    width:1.5em;
+    height:1.5em;
+    min-width: 16px;
+    min-height: 16px;
+    float: <?php echo $left; ?>;
+}
+#pma_navigation_tree div.block i,
+#pma_navigation_tree div.block b {
+    width: 1.5em;
+    height: 1.5em;
+    min-width: 16px;
+    min-height: 8px;
+    position: absolute;
+    bottom: 0.7em;
+    <?php echo $left; ?>: 0.75em;
+    z-index: 0;
+}
+#pma_navigation_tree div.block i {
+    border-<?php echo $left; ?>: 1px solid #666;
+    border-bottom: 1px solid #666;
+}
+#pma_navigation_tree div.block i.first { /* Removes top segment */
+    border-<?php echo $left; ?>: 0;
+}
+#pma_navigation_tree div.block b { /* Bottom segment for the tree element connections */
+    display: block;
+    height: 0.75em;
+    bottom: 0;
+    <?php echo $left; ?>: 0.75em;
+    border-<?php echo $left; ?>: 1px solid #666;
+}
+#pma_navigation_tree div.block a,
+#pma_navigation_tree div.block u {
+    position: absolute;
+    <?php echo $left; ?>: 50%;
+    top: 50%;
+    z-index: 10;
+}
+#pma_navigation_tree div.block img {
+    position: relative;
+    top: -0.6em;
+    <?php echo $left; ?>: 0;
+    margin-<?php echo $left; ?>: -5px;
+}
+#pma_navigation_tree li.last > ul {
+    background: none;
+}
+#pma_navigation_tree li > a, #pma_navigation_tree li > i {
+    line-height: 1.5em;
+    height: 1.5em;
+    padding-<?php echo $left; ?>: 0.3em;
+}
+#pma_navigation_tree .list_container {
+    border-<?php echo $left; ?>: 1px solid #666;
+    margin-<?php echo $left; ?>: 0.75em;
+    padding-<?php echo $left; ?>: 0.75em;
+}
+#pma_navigation_tree .last > .list_container {
+    border-<?php echo $left; ?>: 0 solid #666;
+}
+
+/* Fast filter */
+li.fast_filter {
+    padding-<?php echo $left; ?>: 0.75em;
+    margin-<?php echo $left; ?>: 0.75em;
+    padding-<?php echo $right; ?>: 35px;
+    border-<?php echo $left; ?>: 1px solid #666;
+}
+li.fast_filter input {
+    padding-<?php echo $right; ?>: .4em;
+    width: 100%;
+}
+li.fast_filter span {
+    position: relative;
+    <?php echo $right; ?>: 1.5em;
+    padding: 0.2em;
+    cursor: pointer;
+    font-weight: bold;
+    color: #800;
+}
+li.fast_filter.db_fast_filter {
+    border: 0;
+}
+
+/* Resize handler */
+#pma_navigation_resizer {
+    width: 3px;
+    height: 100%;
+    background-color: #aaa;
+    cursor: col-resize;
+    position: fixed;
+    top: 0;
+    <?php echo $left; ?>: 240px;
+    z-index: 801;
+}
+#pma_navigation_collapser {
+    width: 20px;
+    height: 22px;
+    line-height: 22px;
+    background: #eee;
+    color: #555;
+    font-weight: bold;
+    position: fixed;
+    top: 0;
+    <?php echo $left; ?>: <?php echo $GLOBALS['cfg']['NaviWidth']; ?>px;
+    text-align: center;
+    cursor: pointer;
+    z-index: 800;
+    text-shadow: 0px 1px 0px #fff;
+    filter: dropshadow(color=#fff, offx=0, offy=1);
+    border: 1px solid #888;
+}
diff --git a/phpmyadmin/themes/original/img/ajax_clock_small.gif b/phpmyadmin/themes/original/img/ajax_clock_small.gif
new file mode 100644
index 0000000..bde4932
Binary files /dev/null and b/phpmyadmin/themes/original/img/ajax_clock_small.gif differ
diff --git a/phpmyadmin/themes/original/img/arrow_ltr.png b/phpmyadmin/themes/original/img/arrow_ltr.png
new file mode 100644
index 0000000..7ff8ed9
Binary files /dev/null and b/phpmyadmin/themes/original/img/arrow_ltr.png differ
diff --git a/phpmyadmin/themes/original/img/arrow_rtl.png b/phpmyadmin/themes/original/img/arrow_rtl.png
new file mode 100644
index 0000000..0192d10
Binary files /dev/null and b/phpmyadmin/themes/original/img/arrow_rtl.png differ
diff --git a/phpmyadmin/themes/original/img/b_bookmark.png b/phpmyadmin/themes/original/img/b_bookmark.png
new file mode 100644
index 0000000..e2afe3f
Binary files /dev/null and b/phpmyadmin/themes/original/img/b_bookmark.png differ
diff --git a/phpmyadmin/themes/original/img/b_browse.png b/phpmyadmin/themes/original/img/b_browse.png
new file mode 100644
index 0000000..1d88b2a
Binary files /dev/null and b/phpmyadmin/themes/original/img/b_browse.png differ
diff --git a/phpmyadmin/themes/original/img/b_calendar.png b/phpmyadmin/themes/original/img/b_calendar.png
new file mode 100644
index 0000000..34381b3
Binary files /dev/null and b/phpmyadmin/themes/original/img/b_calendar.png differ
diff --git a/phpmyadmin/themes/original/img/b_chart.png b/phpmyadmin/themes/original/img/b_chart.png
new file mode 100644
index 0000000..0e2cc49
Binary files /dev/null and b/phpmyadmin/themes/original/img/b_chart.png differ
diff --git a/phpmyadmin/themes/original/img/b_close.png b/phpmyadmin/themes/original/img/b_close.png
new file mode 100644
index 0000000..2c234b6
Binary files /dev/null and b/phpmyadmin/themes/original/img/b_close.png differ
diff --git a/phpmyadmin/themes/original/img/b_column_add.png b/phpmyadmin/themes/original/img/b_column_add.png
new file mode 100644
index 0000000..25dc546
Binary files /dev/null and b/phpmyadmin/themes/original/img/b_column_add.png differ
diff --git a/phpmyadmin/themes/original/img/b_comment.png b/phpmyadmin/themes/original/img/b_comment.png
new file mode 100644
index 0000000..203c880
Binary files /dev/null and b/phpmyadmin/themes/original/img/b_comment.png differ
diff --git a/phpmyadmin/themes/original/img/b_dbstatistics.png b/phpmyadmin/themes/original/img/b_dbstatistics.png
new file mode 100644
index 0000000..bfb2ad5
Binary files /dev/null and b/phpmyadmin/themes/original/img/b_dbstatistics.png differ
diff --git a/phpmyadmin/themes/original/img/b_deltbl.png b/phpmyadmin/themes/original/img/b_deltbl.png
new file mode 100644
index 0000000..0e3fb29
Binary files /dev/null and b/phpmyadmin/themes/original/img/b_deltbl.png differ
diff --git a/phpmyadmin/themes/original/img/b_docs.png b/phpmyadmin/themes/original/img/b_docs.png
new file mode 100644
index 0000000..46e2d2c
Binary files /dev/null and b/phpmyadmin/themes/original/img/b_docs.png differ
diff --git a/phpmyadmin/themes/original/img/b_drop.png b/phpmyadmin/themes/original/img/b_drop.png
new file mode 100644
index 0000000..510bb28
Binary files /dev/null and b/phpmyadmin/themes/original/img/b_drop.png differ
diff --git a/phpmyadmin/themes/original/img/b_edit.png b/phpmyadmin/themes/original/img/b_edit.png
new file mode 100644
index 0000000..d2a5095
Binary files /dev/null and b/phpmyadmin/themes/original/img/b_edit.png differ
diff --git a/phpmyadmin/themes/original/img/b_empty.png b/phpmyadmin/themes/original/img/b_empty.png
new file mode 100644
index 0000000..6fa18ad
Binary files /dev/null and b/phpmyadmin/themes/original/img/b_empty.png differ
diff --git a/phpmyadmin/themes/original/img/b_engine.png b/phpmyadmin/themes/original/img/b_engine.png
new file mode 100644
index 0000000..c8019fd
Binary files /dev/null and b/phpmyadmin/themes/original/img/b_engine.png differ
diff --git a/phpmyadmin/themes/original/img/b_event_add.png b/phpmyadmin/themes/original/img/b_event_add.png
new file mode 100644
index 0000000..ef594b1
Binary files /dev/null and b/phpmyadmin/themes/original/img/b_event_add.png differ
diff --git a/phpmyadmin/themes/original/img/b_events.png b/phpmyadmin/themes/original/img/b_events.png
new file mode 100644
index 0000000..86bcc87
Binary files /dev/null and b/phpmyadmin/themes/original/img/b_events.png differ
diff --git a/phpmyadmin/themes/original/img/b_export.png b/phpmyadmin/themes/original/img/b_export.png
new file mode 100644
index 0000000..1a6d159
Binary files /dev/null and b/phpmyadmin/themes/original/img/b_export.png differ
diff --git a/phpmyadmin/themes/original/img/b_ftext.png b/phpmyadmin/themes/original/img/b_ftext.png
new file mode 100644
index 0000000..6014ebc
Binary files /dev/null and b/phpmyadmin/themes/original/img/b_ftext.png differ
diff --git a/phpmyadmin/themes/original/img/b_globe.gif b/phpmyadmin/themes/original/img/b_globe.gif
new file mode 100644
index 0000000..ef03dcf
Binary files /dev/null and b/phpmyadmin/themes/original/img/b_globe.gif differ
diff --git a/phpmyadmin/themes/original/img/b_group.png b/phpmyadmin/themes/original/img/b_group.png
new file mode 100644
index 0000000..4530760
Binary files /dev/null and b/phpmyadmin/themes/original/img/b_group.png differ
diff --git a/phpmyadmin/themes/original/img/b_help.png b/phpmyadmin/themes/original/img/b_help.png
new file mode 100644
index 0000000..2fe513b
Binary files /dev/null and b/phpmyadmin/themes/original/img/b_help.png differ
diff --git a/phpmyadmin/themes/original/img/b_home.png b/phpmyadmin/themes/original/img/b_home.png
new file mode 100644
index 0000000..ea03206
Binary files /dev/null and b/phpmyadmin/themes/original/img/b_home.png differ
diff --git a/phpmyadmin/themes/original/img/b_import.png b/phpmyadmin/themes/original/img/b_import.png
new file mode 100644
index 0000000..9356a3a
Binary files /dev/null and b/phpmyadmin/themes/original/img/b_import.png differ
diff --git a/phpmyadmin/themes/original/img/b_index.png b/phpmyadmin/themes/original/img/b_index.png
new file mode 100644
index 0000000..11064c1
Binary files /dev/null and b/phpmyadmin/themes/original/img/b_index.png differ
diff --git a/phpmyadmin/themes/original/img/b_index_add.png b/phpmyadmin/themes/original/img/b_index_add.png
new file mode 100644
index 0000000..e51a622
Binary files /dev/null and b/phpmyadmin/themes/original/img/b_index_add.png differ
diff --git a/phpmyadmin/themes/original/img/b_info.png b/phpmyadmin/themes/original/img/b_info.png
new file mode 100644
index 0000000..cfd49e5
Binary files /dev/null and b/phpmyadmin/themes/original/img/b_info.png differ
diff --git a/phpmyadmin/themes/original/img/b_inline_edit.png b/phpmyadmin/themes/original/img/b_inline_edit.png
new file mode 100644
index 0000000..01335be
Binary files /dev/null and b/phpmyadmin/themes/original/img/b_inline_edit.png differ
diff --git a/phpmyadmin/themes/original/img/b_insrow.png b/phpmyadmin/themes/original/img/b_insrow.png
new file mode 100644
index 0000000..0532871
Binary files /dev/null and b/phpmyadmin/themes/original/img/b_insrow.png differ
diff --git a/phpmyadmin/themes/original/img/b_minus.png b/phpmyadmin/themes/original/img/b_minus.png
new file mode 100644
index 0000000..e28166f
Binary files /dev/null and b/phpmyadmin/themes/original/img/b_minus.png differ
diff --git a/phpmyadmin/themes/original/img/b_more.png b/phpmyadmin/themes/original/img/b_more.png
new file mode 100644
index 0000000..681f862
Binary files /dev/null and b/phpmyadmin/themes/original/img/b_more.png differ
diff --git a/phpmyadmin/themes/original/img/b_move.png b/phpmyadmin/themes/original/img/b_move.png
new file mode 100644
index 0000000..1ce3b1c
Binary files /dev/null and b/phpmyadmin/themes/original/img/b_move.png differ
diff --git a/phpmyadmin/themes/original/img/b_newdb.png b/phpmyadmin/themes/original/img/b_newdb.png
new file mode 100644
index 0000000..fccc394
Binary files /dev/null and b/phpmyadmin/themes/original/img/b_newdb.png differ
diff --git a/phpmyadmin/themes/original/img/b_newtbl.png b/phpmyadmin/themes/original/img/b_newtbl.png
new file mode 100644
index 0000000..7402ad8
Binary files /dev/null and b/phpmyadmin/themes/original/img/b_newtbl.png differ
diff --git a/phpmyadmin/themes/original/img/b_nextpage.png b/phpmyadmin/themes/original/img/b_nextpage.png
new file mode 100644
index 0000000..6169d53
Binary files /dev/null and b/phpmyadmin/themes/original/img/b_nextpage.png differ
diff --git a/phpmyadmin/themes/original/img/b_plus.png b/phpmyadmin/themes/original/img/b_plus.png
new file mode 100644
index 0000000..90c15d8
Binary files /dev/null and b/phpmyadmin/themes/original/img/b_plus.png differ
diff --git a/phpmyadmin/themes/original/img/b_primary.png b/phpmyadmin/themes/original/img/b_primary.png
new file mode 100644
index 0000000..94f2407
Binary files /dev/null and b/phpmyadmin/themes/original/img/b_primary.png differ
diff --git a/phpmyadmin/themes/original/img/b_print.png b/phpmyadmin/themes/original/img/b_print.png
new file mode 100644
index 0000000..9e5df80
Binary files /dev/null and b/phpmyadmin/themes/original/img/b_print.png differ
diff --git a/phpmyadmin/themes/original/img/b_props.png b/phpmyadmin/themes/original/img/b_props.png
new file mode 100644
index 0000000..5ea2251
Binary files /dev/null and b/phpmyadmin/themes/original/img/b_props.png differ
diff --git a/phpmyadmin/themes/original/img/b_relations.png b/phpmyadmin/themes/original/img/b_relations.png
new file mode 100644
index 0000000..0ef2521
Binary files /dev/null and b/phpmyadmin/themes/original/img/b_relations.png differ
diff --git a/phpmyadmin/themes/original/img/b_routine_add.png b/phpmyadmin/themes/original/img/b_routine_add.png
new file mode 100644
index 0000000..2d14442
Binary files /dev/null and b/phpmyadmin/themes/original/img/b_routine_add.png differ
diff --git a/phpmyadmin/themes/original/img/b_routines.png b/phpmyadmin/themes/original/img/b_routines.png
new file mode 100644
index 0000000..2cc102d
Binary files /dev/null and b/phpmyadmin/themes/original/img/b_routines.png differ
diff --git a/phpmyadmin/themes/original/img/b_save.png b/phpmyadmin/themes/original/img/b_save.png
new file mode 100644
index 0000000..29d03b4
Binary files /dev/null and b/phpmyadmin/themes/original/img/b_save.png differ
diff --git a/phpmyadmin/themes/original/img/b_sbrowse.png b/phpmyadmin/themes/original/img/b_sbrowse.png
new file mode 100644
index 0000000..98e1254
Binary files /dev/null and b/phpmyadmin/themes/original/img/b_sbrowse.png differ
diff --git a/phpmyadmin/themes/original/img/b_search.png b/phpmyadmin/themes/original/img/b_search.png
new file mode 100644
index 0000000..13f6ee8
Binary files /dev/null and b/phpmyadmin/themes/original/img/b_search.png differ
diff --git a/phpmyadmin/themes/original/img/b_selboard.png b/phpmyadmin/themes/original/img/b_selboard.png
new file mode 100644
index 0000000..c54a20f
Binary files /dev/null and b/phpmyadmin/themes/original/img/b_selboard.png differ
diff --git a/phpmyadmin/themes/original/img/b_select.png b/phpmyadmin/themes/original/img/b_select.png
new file mode 100644
index 0000000..7f95764
Binary files /dev/null and b/phpmyadmin/themes/original/img/b_select.png differ
diff --git a/phpmyadmin/themes/original/img/b_snewtbl.png b/phpmyadmin/themes/original/img/b_snewtbl.png
new file mode 100644
index 0000000..f881dfd
Binary files /dev/null and b/phpmyadmin/themes/original/img/b_snewtbl.png differ
diff --git a/phpmyadmin/themes/original/img/b_spatial.png b/phpmyadmin/themes/original/img/b_spatial.png
new file mode 100644
index 0000000..5e6c8c7
Binary files /dev/null and b/phpmyadmin/themes/original/img/b_spatial.png differ
diff --git a/phpmyadmin/themes/original/img/b_sql.png b/phpmyadmin/themes/original/img/b_sql.png
new file mode 100644
index 0000000..c1c387e
Binary files /dev/null and b/phpmyadmin/themes/original/img/b_sql.png differ
diff --git a/phpmyadmin/themes/original/img/b_sqlhelp.png b/phpmyadmin/themes/original/img/b_sqlhelp.png
new file mode 100644
index 0000000..c9447b6
Binary files /dev/null and b/phpmyadmin/themes/original/img/b_sqlhelp.png differ
diff --git a/phpmyadmin/themes/original/img/b_table_add.png b/phpmyadmin/themes/original/img/b_table_add.png
new file mode 100644
index 0000000..e3ee208
Binary files /dev/null and b/phpmyadmin/themes/original/img/b_table_add.png differ
diff --git a/phpmyadmin/themes/original/img/b_tblanalyse.png b/phpmyadmin/themes/original/img/b_tblanalyse.png
new file mode 100644
index 0000000..604f1d5
Binary files /dev/null and b/phpmyadmin/themes/original/img/b_tblanalyse.png differ
diff --git a/phpmyadmin/themes/original/img/b_tblexport.png b/phpmyadmin/themes/original/img/b_tblexport.png
new file mode 100644
index 0000000..15ede20
Binary files /dev/null and b/phpmyadmin/themes/original/img/b_tblexport.png differ
diff --git a/phpmyadmin/themes/original/img/b_tblimport.png b/phpmyadmin/themes/original/img/b_tblimport.png
new file mode 100644
index 0000000..4a99880
Binary files /dev/null and b/phpmyadmin/themes/original/img/b_tblimport.png differ
diff --git a/phpmyadmin/themes/original/img/b_tblops.png b/phpmyadmin/themes/original/img/b_tblops.png
new file mode 100644
index 0000000..da5dbc1
Binary files /dev/null and b/phpmyadmin/themes/original/img/b_tblops.png differ
diff --git a/phpmyadmin/themes/original/img/b_tbloptimize.png b/phpmyadmin/themes/original/img/b_tbloptimize.png
new file mode 100644
index 0000000..04e7c3e
Binary files /dev/null and b/phpmyadmin/themes/original/img/b_tbloptimize.png differ
diff --git a/phpmyadmin/themes/original/img/b_tipp.png b/phpmyadmin/themes/original/img/b_tipp.png
new file mode 100644
index 0000000..ef73a7a
Binary files /dev/null and b/phpmyadmin/themes/original/img/b_tipp.png differ
diff --git a/phpmyadmin/themes/original/img/b_trigger_add.png b/phpmyadmin/themes/original/img/b_trigger_add.png
new file mode 100644
index 0000000..8a754df
Binary files /dev/null and b/phpmyadmin/themes/original/img/b_trigger_add.png differ
diff --git a/phpmyadmin/themes/original/img/b_triggers.png b/phpmyadmin/themes/original/img/b_triggers.png
new file mode 100644
index 0000000..84a89ef
Binary files /dev/null and b/phpmyadmin/themes/original/img/b_triggers.png differ
diff --git a/phpmyadmin/themes/original/img/b_unique.png b/phpmyadmin/themes/original/img/b_unique.png
new file mode 100644
index 0000000..40c9b5d
Binary files /dev/null and b/phpmyadmin/themes/original/img/b_unique.png differ
diff --git a/phpmyadmin/themes/original/img/b_usradd.png b/phpmyadmin/themes/original/img/b_usradd.png
new file mode 100644
index 0000000..9af3f79
Binary files /dev/null and b/phpmyadmin/themes/original/img/b_usradd.png differ
diff --git a/phpmyadmin/themes/original/img/b_usrcheck.png b/phpmyadmin/themes/original/img/b_usrcheck.png
new file mode 100644
index 0000000..96c77f4
Binary files /dev/null and b/phpmyadmin/themes/original/img/b_usrcheck.png differ
diff --git a/phpmyadmin/themes/original/img/b_usrdrop.png b/phpmyadmin/themes/original/img/b_usrdrop.png
new file mode 100644
index 0000000..8598235
Binary files /dev/null and b/phpmyadmin/themes/original/img/b_usrdrop.png differ
diff --git a/phpmyadmin/themes/original/img/b_usredit.png b/phpmyadmin/themes/original/img/b_usredit.png
new file mode 100644
index 0000000..ac4af9b
Binary files /dev/null and b/phpmyadmin/themes/original/img/b_usredit.png differ
diff --git a/phpmyadmin/themes/original/img/b_usrlist.png b/phpmyadmin/themes/original/img/b_usrlist.png
new file mode 100644
index 0000000..42d02d5
Binary files /dev/null and b/phpmyadmin/themes/original/img/b_usrlist.png differ
diff --git a/phpmyadmin/themes/original/img/b_view.png b/phpmyadmin/themes/original/img/b_view.png
new file mode 100644
index 0000000..96f90eb
Binary files /dev/null and b/phpmyadmin/themes/original/img/b_view.png differ
diff --git a/phpmyadmin/themes/original/img/b_view_add.png b/phpmyadmin/themes/original/img/b_view_add.png
new file mode 100644
index 0000000..6f7a11e
Binary files /dev/null and b/phpmyadmin/themes/original/img/b_view_add.png differ
diff --git a/phpmyadmin/themes/original/img/b_views.png b/phpmyadmin/themes/original/img/b_views.png
new file mode 100644
index 0000000..c2d9f5b
Binary files /dev/null and b/phpmyadmin/themes/original/img/b_views.png differ
diff --git a/phpmyadmin/themes/original/img/bd_browse.png b/phpmyadmin/themes/original/img/bd_browse.png
new file mode 100644
index 0000000..18a1211
Binary files /dev/null and b/phpmyadmin/themes/original/img/bd_browse.png differ
diff --git a/phpmyadmin/themes/original/img/bd_deltbl.png b/phpmyadmin/themes/original/img/bd_deltbl.png
new file mode 100644
index 0000000..3f91af2
Binary files /dev/null and b/phpmyadmin/themes/original/img/bd_deltbl.png differ
diff --git a/phpmyadmin/themes/original/img/bd_drop.png b/phpmyadmin/themes/original/img/bd_drop.png
new file mode 100644
index 0000000..97a3da5
Binary files /dev/null and b/phpmyadmin/themes/original/img/bd_drop.png differ
diff --git a/phpmyadmin/themes/original/img/bd_edit.png b/phpmyadmin/themes/original/img/bd_edit.png
new file mode 100644
index 0000000..e81ccd8
Binary files /dev/null and b/phpmyadmin/themes/original/img/bd_edit.png differ
diff --git a/phpmyadmin/themes/original/img/bd_empty.png b/phpmyadmin/themes/original/img/bd_empty.png
new file mode 100644
index 0000000..7c4ae3e
Binary files /dev/null and b/phpmyadmin/themes/original/img/bd_empty.png differ
diff --git a/phpmyadmin/themes/original/img/bd_export.png b/phpmyadmin/themes/original/img/bd_export.png
new file mode 100644
index 0000000..bb697b0
Binary files /dev/null and b/phpmyadmin/themes/original/img/bd_export.png differ
diff --git a/phpmyadmin/themes/original/img/bd_ftext.png b/phpmyadmin/themes/original/img/bd_ftext.png
new file mode 100644
index 0000000..fb0c302
Binary files /dev/null and b/phpmyadmin/themes/original/img/bd_ftext.png differ
diff --git a/phpmyadmin/themes/original/img/bd_index.png b/phpmyadmin/themes/original/img/bd_index.png
new file mode 100644
index 0000000..d6e417c
Binary files /dev/null and b/phpmyadmin/themes/original/img/bd_index.png differ
diff --git a/phpmyadmin/themes/original/img/bd_insrow.png b/phpmyadmin/themes/original/img/bd_insrow.png
new file mode 100644
index 0000000..5162577
Binary files /dev/null and b/phpmyadmin/themes/original/img/bd_insrow.png differ
diff --git a/phpmyadmin/themes/original/img/bd_nextpage.png b/phpmyadmin/themes/original/img/bd_nextpage.png
new file mode 100644
index 0000000..f8e25f5
Binary files /dev/null and b/phpmyadmin/themes/original/img/bd_nextpage.png differ
diff --git a/phpmyadmin/themes/original/img/bd_primary.png b/phpmyadmin/themes/original/img/bd_primary.png
new file mode 100644
index 0000000..58f9cfd
Binary files /dev/null and b/phpmyadmin/themes/original/img/bd_primary.png differ
diff --git a/phpmyadmin/themes/original/img/bd_sbrowse.png b/phpmyadmin/themes/original/img/bd_sbrowse.png
new file mode 100644
index 0000000..8539599
Binary files /dev/null and b/phpmyadmin/themes/original/img/bd_sbrowse.png differ
diff --git a/phpmyadmin/themes/original/img/bd_select.png b/phpmyadmin/themes/original/img/bd_select.png
new file mode 100644
index 0000000..1659a65
Binary files /dev/null and b/phpmyadmin/themes/original/img/bd_select.png differ
diff --git a/phpmyadmin/themes/original/img/bd_spatial.png b/phpmyadmin/themes/original/img/bd_spatial.png
new file mode 100644
index 0000000..d1ee4d6
Binary files /dev/null and b/phpmyadmin/themes/original/img/bd_spatial.png differ
diff --git a/phpmyadmin/themes/original/img/bd_unique.png b/phpmyadmin/themes/original/img/bd_unique.png
new file mode 100644
index 0000000..ee0fde9
Binary files /dev/null and b/phpmyadmin/themes/original/img/bd_unique.png differ
diff --git a/phpmyadmin/themes/original/img/cleardot.gif b/phpmyadmin/themes/original/img/cleardot.gif
new file mode 100644
index 0000000..a9d7bea
Binary files /dev/null and b/phpmyadmin/themes/original/img/cleardot.gif differ
diff --git a/phpmyadmin/themes/original/img/col_drop.png b/phpmyadmin/themes/original/img/col_drop.png
new file mode 100644
index 0000000..681f862
Binary files /dev/null and b/phpmyadmin/themes/original/img/col_drop.png differ
diff --git a/phpmyadmin/themes/original/img/col_pointer.png b/phpmyadmin/themes/original/img/col_pointer.png
new file mode 100644
index 0000000..1fb353f
Binary files /dev/null and b/phpmyadmin/themes/original/img/col_pointer.png differ
diff --git a/phpmyadmin/themes/original/img/col_pointer_ver.png b/phpmyadmin/themes/original/img/col_pointer_ver.png
new file mode 100644
index 0000000..02977f2
Binary files /dev/null and b/phpmyadmin/themes/original/img/col_pointer_ver.png differ
diff --git a/phpmyadmin/themes/original/img/east-mini.png b/phpmyadmin/themes/original/img/east-mini.png
new file mode 100644
index 0000000..bee419d
Binary files /dev/null and b/phpmyadmin/themes/original/img/east-mini.png differ
diff --git a/phpmyadmin/themes/original/img/error.ico b/phpmyadmin/themes/original/img/error.ico
new file mode 100644
index 0000000..b5c0618
Binary files /dev/null and b/phpmyadmin/themes/original/img/error.ico differ
diff --git a/phpmyadmin/themes/original/img/eye.png b/phpmyadmin/themes/original/img/eye.png
new file mode 100644
index 0000000..ed38db2
Binary files /dev/null and b/phpmyadmin/themes/original/img/eye.png differ
diff --git a/phpmyadmin/themes/original/img/eye_grey.png b/phpmyadmin/themes/original/img/eye_grey.png
new file mode 100644
index 0000000..6fcae47
Binary files /dev/null and b/phpmyadmin/themes/original/img/eye_grey.png differ
diff --git a/phpmyadmin/themes/original/img/logo_left.png b/phpmyadmin/themes/original/img/logo_left.png
new file mode 100644
index 0000000..e24bcc3
Binary files /dev/null and b/phpmyadmin/themes/original/img/logo_left.png differ
diff --git a/phpmyadmin/themes/original/img/logo_right.png b/phpmyadmin/themes/original/img/logo_right.png
new file mode 100644
index 0000000..d61c628
Binary files /dev/null and b/phpmyadmin/themes/original/img/logo_right.png differ
diff --git a/phpmyadmin/themes/original/img/more.png b/phpmyadmin/themes/original/img/more.png
new file mode 100644
index 0000000..32aaf61
Binary files /dev/null and b/phpmyadmin/themes/original/img/more.png differ
diff --git a/phpmyadmin/themes/original/img/new_data.png b/phpmyadmin/themes/original/img/new_data.png
new file mode 100644
index 0000000..6f4e186
Binary files /dev/null and b/phpmyadmin/themes/original/img/new_data.png differ
diff --git a/phpmyadmin/themes/original/img/new_data_hovered.png b/phpmyadmin/themes/original/img/new_data_hovered.png
new file mode 100644
index 0000000..a470dbb
Binary files /dev/null and b/phpmyadmin/themes/original/img/new_data_hovered.png differ
diff --git a/phpmyadmin/themes/original/img/new_data_selected.png b/phpmyadmin/themes/original/img/new_data_selected.png
new file mode 100644
index 0000000..a75abe3
Binary files /dev/null and b/phpmyadmin/themes/original/img/new_data_selected.png differ
diff --git a/phpmyadmin/themes/original/img/new_data_selected_hovered.png b/phpmyadmin/themes/original/img/new_data_selected_hovered.png
new file mode 100644
index 0000000..04a2ad8
Binary files /dev/null and b/phpmyadmin/themes/original/img/new_data_selected_hovered.png differ
diff --git a/phpmyadmin/themes/original/img/new_struct.png b/phpmyadmin/themes/original/img/new_struct.png
new file mode 100644
index 0000000..6b77c13
Binary files /dev/null and b/phpmyadmin/themes/original/img/new_struct.png differ
diff --git a/phpmyadmin/themes/original/img/new_struct_hovered.png b/phpmyadmin/themes/original/img/new_struct_hovered.png
new file mode 100644
index 0000000..9c353c6
Binary files /dev/null and b/phpmyadmin/themes/original/img/new_struct_hovered.png differ
diff --git a/phpmyadmin/themes/original/img/new_struct_selected.png b/phpmyadmin/themes/original/img/new_struct_selected.png
new file mode 100644
index 0000000..142bf11
Binary files /dev/null and b/phpmyadmin/themes/original/img/new_struct_selected.png differ
diff --git a/phpmyadmin/themes/original/img/new_struct_selected_hovered.png b/phpmyadmin/themes/original/img/new_struct_selected_hovered.png
new file mode 100644
index 0000000..9a82bc4
Binary files /dev/null and b/phpmyadmin/themes/original/img/new_struct_selected_hovered.png differ
diff --git a/phpmyadmin/themes/original/img/north-mini.png b/phpmyadmin/themes/original/img/north-mini.png
new file mode 100644
index 0000000..8283839
Binary files /dev/null and b/phpmyadmin/themes/original/img/north-mini.png differ
diff --git a/phpmyadmin/themes/original/img/pause.png b/phpmyadmin/themes/original/img/pause.png
new file mode 100644
index 0000000..46a6318
Binary files /dev/null and b/phpmyadmin/themes/original/img/pause.png differ
diff --git a/phpmyadmin/themes/original/img/play.png b/phpmyadmin/themes/original/img/play.png
new file mode 100644
index 0000000..6169d53
Binary files /dev/null and b/phpmyadmin/themes/original/img/play.png differ
diff --git a/phpmyadmin/themes/original/img/s_asc.png b/phpmyadmin/themes/original/img/s_asc.png
new file mode 100644
index 0000000..3e5050f
Binary files /dev/null and b/phpmyadmin/themes/original/img/s_asc.png differ
diff --git a/phpmyadmin/themes/original/img/s_asci.png b/phpmyadmin/themes/original/img/s_asci.png
new file mode 100644
index 0000000..d160eb1
Binary files /dev/null and b/phpmyadmin/themes/original/img/s_asci.png differ
diff --git a/phpmyadmin/themes/original/img/s_cancel.png b/phpmyadmin/themes/original/img/s_cancel.png
new file mode 100644
index 0000000..fd782ab
Binary files /dev/null and b/phpmyadmin/themes/original/img/s_cancel.png differ
diff --git a/phpmyadmin/themes/original/img/s_cog.png b/phpmyadmin/themes/original/img/s_cog.png
new file mode 100644
index 0000000..b8c9713
Binary files /dev/null and b/phpmyadmin/themes/original/img/s_cog.png differ
diff --git a/phpmyadmin/themes/original/img/s_db.png b/phpmyadmin/themes/original/img/s_db.png
new file mode 100644
index 0000000..0f723a9
Binary files /dev/null and b/phpmyadmin/themes/original/img/s_db.png differ
diff --git a/phpmyadmin/themes/original/img/s_desc.png b/phpmyadmin/themes/original/img/s_desc.png
new file mode 100644
index 0000000..7dcb98b
Binary files /dev/null and b/phpmyadmin/themes/original/img/s_desc.png differ
diff --git a/phpmyadmin/themes/original/img/s_error.png b/phpmyadmin/themes/original/img/s_error.png
new file mode 100644
index 0000000..9db50e5
Binary files /dev/null and b/phpmyadmin/themes/original/img/s_error.png differ
diff --git a/phpmyadmin/themes/original/img/s_error2.png b/phpmyadmin/themes/original/img/s_error2.png
new file mode 100644
index 0000000..e4f02e9
Binary files /dev/null and b/phpmyadmin/themes/original/img/s_error2.png differ
diff --git a/phpmyadmin/themes/original/img/s_fulltext.png b/phpmyadmin/themes/original/img/s_fulltext.png
new file mode 100644
index 0000000..9f8db13
Binary files /dev/null and b/phpmyadmin/themes/original/img/s_fulltext.png differ
diff --git a/phpmyadmin/themes/original/img/s_host.png b/phpmyadmin/themes/original/img/s_host.png
new file mode 100644
index 0000000..3d30f1c
Binary files /dev/null and b/phpmyadmin/themes/original/img/s_host.png differ
diff --git a/phpmyadmin/themes/original/img/s_lang.png b/phpmyadmin/themes/original/img/s_lang.png
new file mode 100644
index 0000000..d205d19
Binary files /dev/null and b/phpmyadmin/themes/original/img/s_lang.png differ
diff --git a/phpmyadmin/themes/original/img/s_loggoff.png b/phpmyadmin/themes/original/img/s_loggoff.png
new file mode 100644
index 0000000..ec55b56
Binary files /dev/null and b/phpmyadmin/themes/original/img/s_loggoff.png differ
diff --git a/phpmyadmin/themes/original/img/s_notice.png b/phpmyadmin/themes/original/img/s_notice.png
new file mode 100644
index 0000000..aacc430
Binary files /dev/null and b/phpmyadmin/themes/original/img/s_notice.png differ
diff --git a/phpmyadmin/themes/original/img/s_partialtext.png b/phpmyadmin/themes/original/img/s_partialtext.png
new file mode 100644
index 0000000..e671140
Binary files /dev/null and b/phpmyadmin/themes/original/img/s_partialtext.png differ
diff --git a/phpmyadmin/themes/original/img/s_passwd.png b/phpmyadmin/themes/original/img/s_passwd.png
new file mode 100644
index 0000000..82d6f26
Binary files /dev/null and b/phpmyadmin/themes/original/img/s_passwd.png differ
diff --git a/phpmyadmin/themes/original/img/s_really.png b/phpmyadmin/themes/original/img/s_really.png
new file mode 100644
index 0000000..f9902ef
Binary files /dev/null and b/phpmyadmin/themes/original/img/s_really.png differ
diff --git a/phpmyadmin/themes/original/img/s_reload.png b/phpmyadmin/themes/original/img/s_reload.png
new file mode 100644
index 0000000..0be96c7
Binary files /dev/null and b/phpmyadmin/themes/original/img/s_reload.png differ
diff --git a/phpmyadmin/themes/original/img/s_replication.png b/phpmyadmin/themes/original/img/s_replication.png
new file mode 100644
index 0000000..f51a177
Binary files /dev/null and b/phpmyadmin/themes/original/img/s_replication.png differ
diff --git a/phpmyadmin/themes/original/img/s_rights.png b/phpmyadmin/themes/original/img/s_rights.png
new file mode 100644
index 0000000..fce7a81
Binary files /dev/null and b/phpmyadmin/themes/original/img/s_rights.png differ
diff --git a/phpmyadmin/themes/original/img/s_sortable.png b/phpmyadmin/themes/original/img/s_sortable.png
new file mode 100644
index 0000000..361a14a
Binary files /dev/null and b/phpmyadmin/themes/original/img/s_sortable.png differ
diff --git a/phpmyadmin/themes/original/img/s_status.png b/phpmyadmin/themes/original/img/s_status.png
new file mode 100644
index 0000000..0680c59
Binary files /dev/null and b/phpmyadmin/themes/original/img/s_status.png differ
diff --git a/phpmyadmin/themes/original/img/s_success.png b/phpmyadmin/themes/original/img/s_success.png
new file mode 100644
index 0000000..d2e6121
Binary files /dev/null and b/phpmyadmin/themes/original/img/s_success.png differ
diff --git a/phpmyadmin/themes/original/img/s_sync.png b/phpmyadmin/themes/original/img/s_sync.png
new file mode 100644
index 0000000..8545ba1
Binary files /dev/null and b/phpmyadmin/themes/original/img/s_sync.png differ
diff --git a/phpmyadmin/themes/original/img/s_tbl.png b/phpmyadmin/themes/original/img/s_tbl.png
new file mode 100644
index 0000000..6ae8c4d
Binary files /dev/null and b/phpmyadmin/themes/original/img/s_tbl.png differ
diff --git a/phpmyadmin/themes/original/img/s_theme.png b/phpmyadmin/themes/original/img/s_theme.png
new file mode 100644
index 0000000..6196810
Binary files /dev/null and b/phpmyadmin/themes/original/img/s_theme.png differ
diff --git a/phpmyadmin/themes/original/img/s_top.png b/phpmyadmin/themes/original/img/s_top.png
new file mode 100644
index 0000000..de05174
Binary files /dev/null and b/phpmyadmin/themes/original/img/s_top.png differ
diff --git a/phpmyadmin/themes/original/img/s_vars.png b/phpmyadmin/themes/original/img/s_vars.png
new file mode 100644
index 0000000..5bc92cd
Binary files /dev/null and b/phpmyadmin/themes/original/img/s_vars.png differ
diff --git a/phpmyadmin/themes/original/img/s_views.png b/phpmyadmin/themes/original/img/s_views.png
new file mode 100644
index 0000000..fc4e151
Binary files /dev/null and b/phpmyadmin/themes/original/img/s_views.png differ
diff --git a/phpmyadmin/themes/original/img/south-mini.png b/phpmyadmin/themes/original/img/south-mini.png
new file mode 100644
index 0000000..954c202
Binary files /dev/null and b/phpmyadmin/themes/original/img/south-mini.png differ
diff --git a/phpmyadmin/themes/original/img/spacer.png b/phpmyadmin/themes/original/img/spacer.png
new file mode 100644
index 0000000..c6008d7
Binary files /dev/null and b/phpmyadmin/themes/original/img/spacer.png differ
diff --git a/phpmyadmin/themes/original/img/sprites.png b/phpmyadmin/themes/original/img/sprites.png
new file mode 100644
index 0000000..d7c911d
Binary files /dev/null and b/phpmyadmin/themes/original/img/sprites.png differ
diff --git a/phpmyadmin/themes/original/img/toggle-ltr.png b/phpmyadmin/themes/original/img/toggle-ltr.png
new file mode 100644
index 0000000..9d08d61
Binary files /dev/null and b/phpmyadmin/themes/original/img/toggle-ltr.png differ
diff --git a/phpmyadmin/themes/original/img/toggle-rtl.png b/phpmyadmin/themes/original/img/toggle-rtl.png
new file mode 100644
index 0000000..c2ef16f
Binary files /dev/null and b/phpmyadmin/themes/original/img/toggle-rtl.png differ
diff --git a/phpmyadmin/themes/original/img/vertical_line.png b/phpmyadmin/themes/original/img/vertical_line.png
new file mode 100644
index 0000000..188417b
Binary files /dev/null and b/phpmyadmin/themes/original/img/vertical_line.png differ
diff --git a/phpmyadmin/themes/original/img/west-mini.png b/phpmyadmin/themes/original/img/west-mini.png
new file mode 100644
index 0000000..a13f083
Binary files /dev/null and b/phpmyadmin/themes/original/img/west-mini.png differ
diff --git a/phpmyadmin/themes/original/img/window-new.png b/phpmyadmin/themes/original/img/window-new.png
new file mode 100644
index 0000000..431fe85
Binary files /dev/null and b/phpmyadmin/themes/original/img/window-new.png differ
diff --git a/phpmyadmin/themes/original/img/zoom-minus-mini.png b/phpmyadmin/themes/original/img/zoom-minus-mini.png
new file mode 100644
index 0000000..4262ad4
Binary files /dev/null and b/phpmyadmin/themes/original/img/zoom-minus-mini.png differ
diff --git a/phpmyadmin/themes/original/img/zoom-plus-mini.png b/phpmyadmin/themes/original/img/zoom-plus-mini.png
new file mode 100644
index 0000000..4fabfd1
Binary files /dev/null and b/phpmyadmin/themes/original/img/zoom-plus-mini.png differ
diff --git a/phpmyadmin/themes/original/img/zoom-world-mini.png b/phpmyadmin/themes/original/img/zoom-world-mini.png
new file mode 100644
index 0000000..f50ca66
Binary files /dev/null and b/phpmyadmin/themes/original/img/zoom-world-mini.png differ
diff --git a/phpmyadmin/themes/original/info.inc.php b/phpmyadmin/themes/original/info.inc.php
new file mode 100644
index 0000000..28866d6
--- /dev/null
+++ b/phpmyadmin/themes/original/info.inc.php
@@ -0,0 +1,15 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * Theme information
+ *
+ * @package    PhpMyAdmin-theme
+ * @subpackage Original
+ */
+
+/**
+ *
+ */
+$theme_name = 'Original';
+$theme_full_version = '2.9';
+?>
diff --git a/phpmyadmin/themes/original/jquery/images/ui-bg_flat_0_aaaaaa_40x100.png b/phpmyadmin/themes/original/jquery/images/ui-bg_flat_0_aaaaaa_40x100.png
new file mode 100644
index 0000000..5b5dab2
Binary files /dev/null and b/phpmyadmin/themes/original/jquery/images/ui-bg_flat_0_aaaaaa_40x100.png differ
diff --git a/phpmyadmin/themes/original/jquery/images/ui-bg_flat_75_ffffff_40x100.png b/phpmyadmin/themes/original/jquery/images/ui-bg_flat_75_ffffff_40x100.png
new file mode 100644
index 0000000..ac8b229
Binary files /dev/null and b/phpmyadmin/themes/original/jquery/images/ui-bg_flat_75_ffffff_40x100.png differ
diff --git a/phpmyadmin/themes/original/jquery/images/ui-bg_glass_55_fbf9ee_1x400.png b/phpmyadmin/themes/original/jquery/images/ui-bg_glass_55_fbf9ee_1x400.png
new file mode 100644
index 0000000..ad3d634
Binary files /dev/null and b/phpmyadmin/themes/original/jquery/images/ui-bg_glass_55_fbf9ee_1x400.png differ
diff --git a/phpmyadmin/themes/original/jquery/images/ui-bg_glass_65_ffffff_1x400.png b/phpmyadmin/themes/original/jquery/images/ui-bg_glass_65_ffffff_1x400.png
new file mode 100644
index 0000000..42ccba2
Binary files /dev/null and b/phpmyadmin/themes/original/jquery/images/ui-bg_glass_65_ffffff_1x400.png differ
diff --git a/phpmyadmin/themes/original/jquery/images/ui-bg_glass_75_dadada_1x400.png b/phpmyadmin/themes/original/jquery/images/ui-bg_glass_75_dadada_1x400.png
new file mode 100644
index 0000000..1d43b47
Binary files /dev/null and b/phpmyadmin/themes/original/jquery/images/ui-bg_glass_75_dadada_1x400.png differ
diff --git a/phpmyadmin/themes/original/jquery/images/ui-bg_glass_75_e6e6e6_1x400.png b/phpmyadmin/themes/original/jquery/images/ui-bg_glass_75_e6e6e6_1x400.png
new file mode 100644
index 0000000..86c2baa
Binary files /dev/null and b/phpmyadmin/themes/original/jquery/images/ui-bg_glass_75_e6e6e6_1x400.png differ
diff --git a/phpmyadmin/themes/original/jquery/images/ui-bg_glass_95_fef1ec_1x400.png b/phpmyadmin/themes/original/jquery/images/ui-bg_glass_95_fef1ec_1x400.png
new file mode 100644
index 0000000..4443fdc
Binary files /dev/null and b/phpmyadmin/themes/original/jquery/images/ui-bg_glass_95_fef1ec_1x400.png differ
diff --git a/phpmyadmin/themes/original/jquery/images/ui-bg_highlight-soft_75_cccccc_1x100.png b/phpmyadmin/themes/original/jquery/images/ui-bg_highlight-soft_75_cccccc_1x100.png
new file mode 100644
index 0000000..7c9fa6c
Binary files /dev/null and b/phpmyadmin/themes/original/jquery/images/ui-bg_highlight-soft_75_cccccc_1x100.png differ
diff --git a/phpmyadmin/themes/original/jquery/images/ui-icons_222222_256x240.png b/phpmyadmin/themes/original/jquery/images/ui-icons_222222_256x240.png
new file mode 100644
index 0000000..b273ff1
Binary files /dev/null and b/phpmyadmin/themes/original/jquery/images/ui-icons_222222_256x240.png differ
diff --git a/phpmyadmin/themes/original/jquery/images/ui-icons_2e83ff_256x240.png b/phpmyadmin/themes/original/jquery/images/ui-icons_2e83ff_256x240.png
new file mode 100644
index 0000000..09d1cdc
Binary files /dev/null and b/phpmyadmin/themes/original/jquery/images/ui-icons_2e83ff_256x240.png differ
diff --git a/phpmyadmin/themes/original/jquery/images/ui-icons_454545_256x240.png b/phpmyadmin/themes/original/jquery/images/ui-icons_454545_256x240.png
new file mode 100644
index 0000000..59bd45b
Binary files /dev/null and b/phpmyadmin/themes/original/jquery/images/ui-icons_454545_256x240.png differ
diff --git a/phpmyadmin/themes/original/jquery/images/ui-icons_888888_256x240.png b/phpmyadmin/themes/original/jquery/images/ui-icons_888888_256x240.png
new file mode 100644
index 0000000..6d02426
Binary files /dev/null and b/phpmyadmin/themes/original/jquery/images/ui-icons_888888_256x240.png differ
diff --git a/phpmyadmin/themes/original/jquery/images/ui-icons_cd0a0a_256x240.png b/phpmyadmin/themes/original/jquery/images/ui-icons_cd0a0a_256x240.png
new file mode 100644
index 0000000..2ab019b
Binary files /dev/null and b/phpmyadmin/themes/original/jquery/images/ui-icons_cd0a0a_256x240.png differ
diff --git a/phpmyadmin/themes/original/jquery/jquery-ui-1.9.2.custom.css b/phpmyadmin/themes/original/jquery/jquery-ui-1.9.2.custom.css
new file mode 100644
index 0000000..b08d903
--- /dev/null
+++ b/phpmyadmin/themes/original/jquery/jquery-ui-1.9.2.custom.css
@@ -0,0 +1,462 @@
+/*! jQuery UI - v1.9.2 - 2012-12-19
+* http://jqueryui.com
+* Includes: jquery.ui.core.css, jquery.ui.resizable.css, jquery.ui.selectable.css, jquery.ui.accordion.css, jquery.ui.autocomplete.css, jquery.ui.button.css, jquery.ui.datepicker.css, jquery.ui.dialog.css, jquery.ui.menu.css, jquery.ui.progressbar.css, jquery.ui.slider.css, jquery.ui.spinner.css, jquery.ui.tabs.css, jquery.ui.tooltip.css
+* To view and modify this theme, visit http://jqueryui.com/themeroller/?ffDefault=Verdana%2CArial%2Csans-serif&fwDefault=normal&fsDefault=1.1em&cornerRadius=4px&bgColorHeader=cccccc&bgTextureHeader=03_highlight_soft.png&bgImgOpacityHeader=75&borderColorHeader=aaaaaa&fcHeader=222222&iconColorHeader=222222&bgColorContent=ffffff&bgTextureContent=01_flat.png&bgImgOpacityContent=75&borderColorContent=aaaaaa&fcContent=222222&iconColorContent=222222&bgColorDefault=e6e6e6&bgTextureDefault=02_gla [...]
+* Copyright (c) 2012 jQuery Foundation and other contributors Licensed MIT */
+
+/* Layout helpers
+----------------------------------*/
+.ui-helper-hidden { display: none; }
+.ui-helper-hidden-accessible { border: 0; clip: rect(0 0 0 0); height: 1px; margin: -1px; overflow: hidden; padding: 0; position: absolute; width: 1px; }
+.ui-helper-reset { margin: 0; padding: 0; border: 0; outline: 0; line-height: 1.3; text-decoration: none; font-size: 100%; list-style: none; }
+.ui-helper-clearfix:before, .ui-helper-clearfix:after { content: ""; display: table; }
+.ui-helper-clearfix:after { clear: both; }
+.ui-helper-clearfix { zoom: 1; }
+.ui-helper-zfix { width: 100%; height: 100%; top: 0; left: 0; position: absolute; opacity: 0; filter:Alpha(Opacity=0); }
+
+
+/* Interaction Cues
+----------------------------------*/
+.ui-state-disabled { cursor: default !important; }
+
+
+/* Icons
+----------------------------------*/
+
+/* states and images */
+.ui-icon { display: block; text-indent: -99999px; overflow: hidden; background-repeat: no-repeat; }
+
+
+/* Misc visuals
+----------------------------------*/
+
+/* Overlays */
+.ui-widget-overlay { position: absolute; top: 0; left: 0; width: 100%; height: 100%; }
+.ui-resizable { position: relative;}
+.ui-resizable-handle { position: absolute;font-size: 0.1px; display: block; }
+.ui-resizable-disabled .ui-resizable-handle, .ui-resizable-autohide .ui-resizable-handle { display: none; }
+.ui-resizable-n { cursor: n-resize; height: 7px; width: 100%; top: -5px; left: 0; }
+.ui-resizable-s { cursor: s-resize; height: 7px; width: 100%; bottom: -5px; left: 0; }
+.ui-resizable-e { cursor: e-resize; width: 7px; right: -5px; top: 0; height: 100%; }
+.ui-resizable-w { cursor: w-resize; width: 7px; left: -5px; top: 0; height: 100%; }
+.ui-resizable-se { cursor: se-resize; width: 12px; height: 12px; right: 1px; bottom: 1px; }
+.ui-resizable-sw { cursor: sw-resize; width: 9px; height: 9px; left: -5px; bottom: -5px; }
+.ui-resizable-nw { cursor: nw-resize; width: 9px; height: 9px; left: -5px; top: -5px; }
+.ui-resizable-ne { cursor: ne-resize; width: 9px; height: 9px; right: -5px; top: -5px;}.ui-selectable-helper { position: absolute; z-index: 100; border:1px dotted black; }
+.ui-accordion .ui-accordion-header { display: block; cursor: pointer; position: relative; margin-top: 2px; padding: .5em .5em .5em .7em; zoom: 1; }
+.ui-accordion .ui-accordion-icons { padding-left: 2.2em; }
+.ui-accordion .ui-accordion-noicons { padding-left: .7em; }
+.ui-accordion .ui-accordion-icons .ui-accordion-icons { padding-left: 2.2em; }
+.ui-accordion .ui-accordion-header .ui-accordion-header-icon { position: absolute; left: .5em; top: 50%; margin-top: -8px; }
+.ui-accordion .ui-accordion-content { padding: 1em 2.2em; border-top: 0; overflow: auto; zoom: 1; }
+.ui-autocomplete {
+	position: absolute;
+	top: 0;
+	left: 0;
+	cursor: default;
+}
+
+/* workarounds */
+* html .ui-autocomplete { width:1px; } /* without this, the menu expands to 100% in IE6 */
+.ui-button { display: inline-block; position: relative; padding: 0; margin-right: .1em; cursor: pointer; text-align: center; zoom: 1; overflow: visible; } /* the overflow property removes extra width in IE */
+.ui-button, .ui-button:link, .ui-button:visited, .ui-button:hover, .ui-button:active { text-decoration: none; }
+.ui-button-icon-only { width: 2.2em; } /* to make room for the icon, a width needs to be set here */
+button.ui-button-icon-only { width: 2.4em; } /* button elements seem to need a little more width */
+.ui-button-icons-only { width: 3.4em; } 
+button.ui-button-icons-only { width: 3.7em; } 
+
+/*button text element */
+.ui-button .ui-button-text { display: block; line-height: 1.4;  }
+.ui-button-text-only .ui-button-text { padding: .4em 1em; }
+.ui-button-icon-only .ui-button-text, .ui-button-icons-only .ui-button-text { padding: .4em; text-indent: -9999999px; }
+.ui-button-text-icon-primary .ui-button-text, .ui-button-text-icons .ui-button-text { padding: .4em 1em .4em 2.1em; }
+.ui-button-text-icon-secondary .ui-button-text, .ui-button-text-icons .ui-button-text { padding: .4em 2.1em .4em 1em; }
+.ui-button-text-icons .ui-button-text { padding-left: 2.1em; padding-right: 2.1em; }
+/* no icon support for input elements, provide padding by default */
+input.ui-button { padding: .4em 1em; }
+
+/*button icon element(s) */
+.ui-button-icon-only .ui-icon, .ui-button-text-icon-primary .ui-icon, .ui-button-text-icon-secondary .ui-icon, .ui-button-text-icons .ui-icon, .ui-button-icons-only .ui-icon { position: absolute; top: 50%; margin-top: -8px; }
+.ui-button-icon-only .ui-icon { left: 50%; margin-left: -8px; }
+.ui-button-text-icon-primary .ui-button-icon-primary, .ui-button-text-icons .ui-button-icon-primary, .ui-button-icons-only .ui-button-icon-primary { left: .5em; }
+.ui-button-text-icon-secondary .ui-button-icon-secondary, .ui-button-text-icons .ui-button-icon-secondary, .ui-button-icons-only .ui-button-icon-secondary { right: .5em; }
+.ui-button-text-icons .ui-button-icon-secondary, .ui-button-icons-only .ui-button-icon-secondary { right: .5em; }
+
+/*button sets*/
+.ui-buttonset { margin-right: 7px; }
+.ui-buttonset .ui-button { margin-left: 0; margin-right: -.3em; }
+
+/* workarounds */
+button.ui-button::-moz-focus-inner { border: 0; padding: 0; } /* reset extra padding in Firefox */
+.ui-datepicker { width: 17em; padding: .2em .2em 0; display: none; }
+.ui-datepicker .ui-datepicker-header { position:relative; padding:.2em 0; }
+.ui-datepicker .ui-datepicker-prev, .ui-datepicker .ui-datepicker-next { position:absolute; top: 2px; width: 1.8em; height: 1.8em; }
+.ui-datepicker .ui-datepicker-prev-hover, .ui-datepicker .ui-datepicker-next-hover { top: 1px; }
+.ui-datepicker .ui-datepicker-prev { left:2px; }
+.ui-datepicker .ui-datepicker-next { right:2px; }
+.ui-datepicker .ui-datepicker-prev-hover { left:1px; }
+.ui-datepicker .ui-datepicker-next-hover { right:1px; }
+.ui-datepicker .ui-datepicker-prev span, .ui-datepicker .ui-datepicker-next span { display: block; position: absolute; left: 50%; margin-left: -8px; top: 50%; margin-top: -8px;  }
+.ui-datepicker .ui-datepicker-title { margin: 0 2.3em; line-height: 1.8em; text-align: center; }
+.ui-datepicker .ui-datepicker-title select { font-size:1em; margin:1px 0; }
+.ui-datepicker select.ui-datepicker-month-year {width: 100%;}
+.ui-datepicker select.ui-datepicker-month, 
+.ui-datepicker select.ui-datepicker-year { width: 49%;}
+.ui-datepicker table {width: 100%; font-size: .9em; border-collapse: collapse; margin:0 0 .4em; }
+.ui-datepicker th { padding: .7em .3em; text-align: center; font-weight: bold; border: 0;  }
+.ui-datepicker td { border: 0; padding: 1px; }
+.ui-datepicker td span, .ui-datepicker td a { display: block; padding: .2em; text-align: right; text-decoration: none; }
+.ui-datepicker .ui-datepicker-buttonpane { background-image: none; margin: .7em 0 0 0; padding:0 .2em; border-left: 0; border-right: 0; border-bottom: 0; }
+.ui-datepicker .ui-datepicker-buttonpane button { float: right; margin: .5em .2em .4em; cursor: pointer; padding: .2em .6em .3em .6em; width:auto; overflow:visible; }
+.ui-datepicker .ui-datepicker-buttonpane button.ui-datepicker-current { float:left; }
+
+/* with multiple calendars */
+.ui-datepicker.ui-datepicker-multi { width:auto; }
+.ui-datepicker-multi .ui-datepicker-group { float:left; }
+.ui-datepicker-multi .ui-datepicker-group table { width:95%; margin:0 auto .4em; }
+.ui-datepicker-multi-2 .ui-datepicker-group { width:50%; }
+.ui-datepicker-multi-3 .ui-datepicker-group { width:33.3%; }
+.ui-datepicker-multi-4 .ui-datepicker-group { width:25%; }
+.ui-datepicker-multi .ui-datepicker-group-last .ui-datepicker-header { border-left-width:0; }
+.ui-datepicker-multi .ui-datepicker-group-middle .ui-datepicker-header { border-left-width:0; }
+.ui-datepicker-multi .ui-datepicker-buttonpane { clear:left; }
+.ui-datepicker-row-break { clear:both; width:100%; font-size:0em; }
+
+/* RTL support */
+.ui-datepicker-rtl { direction: rtl; }
+.ui-datepicker-rtl .ui-datepicker-prev { right: 2px; left: auto; }
+.ui-datepicker-rtl .ui-datepicker-next { left: 2px; right: auto; }
+.ui-datepicker-rtl .ui-datepicker-prev:hover { right: 1px; left: auto; }
+.ui-datepicker-rtl .ui-datepicker-next:hover { left: 1px; right: auto; }
+.ui-datepicker-rtl .ui-datepicker-buttonpane { clear:right; }
+.ui-datepicker-rtl .ui-datepicker-buttonpane button { float: left; }
+.ui-datepicker-rtl .ui-datepicker-buttonpane button.ui-datepicker-current { float:right; }
+.ui-datepicker-rtl .ui-datepicker-group { float:right; }
+.ui-datepicker-rtl .ui-datepicker-group-last .ui-datepicker-header { border-right-width:0; border-left-width:1px; }
+.ui-datepicker-rtl .ui-datepicker-group-middle .ui-datepicker-header { border-right-width:0; border-left-width:1px; }
+
+/* IE6 IFRAME FIX (taken from datepicker 1.5.3 */
+.ui-datepicker-cover {
+    position: absolute; /*must have*/
+    z-index: -1; /*must have*/
+    filter: mask(); /*must have*/
+    top: -4px; /*must have*/
+    left: -4px; /*must have*/
+    width: 200px; /*must have*/
+    height: 200px; /*must have*/
+}.ui-dialog { position: absolute; top: 0; left: 0; padding: .2em; width: 300px; overflow: hidden; }
+.ui-dialog .ui-dialog-titlebar { padding: .4em 1em; position: relative;  }
+.ui-dialog .ui-dialog-title { float: left; margin: .1em 16px .1em 0; }
+.ui-dialog .ui-dialog-titlebar-close { position: absolute; right: .3em; top: 50%; width: 19px; margin: -10px 0 0 0; padding: 1px; height: 18px; }
+.ui-dialog .ui-dialog-titlebar-close span { display: block; margin: 1px; }
+.ui-dialog .ui-dialog-titlebar-close:hover, .ui-dialog .ui-dialog-titlebar-close:focus { padding: 0; }
+.ui-dialog .ui-dialog-content { position: relative; border: 0; padding: .5em 1em; background: none; overflow: auto; zoom: 1; }
+.ui-dialog .ui-dialog-buttonpane { text-align: left; border-width: 1px 0 0 0; background-image: none; margin: .5em 0 0 0; padding: .3em 1em .5em .4em; }
+.ui-dialog .ui-dialog-buttonpane .ui-dialog-buttonset { float: right; }
+.ui-dialog .ui-dialog-buttonpane button { margin: .5em .4em .5em 0; cursor: pointer; }
+.ui-dialog .ui-resizable-se { width: 14px; height: 14px; right: 3px; bottom: 3px; }
+.ui-draggable .ui-dialog-titlebar { cursor: move; }
+.ui-menu { list-style:none; padding: 2px; margin: 0; display:block; outline: none; }
+.ui-menu .ui-menu { margin-top: -3px; position: absolute; }
+.ui-menu .ui-menu-item { margin: 0; padding: 0; zoom: 1; width: 100%; }
+.ui-menu .ui-menu-divider { margin: 5px -2px 5px -2px; height: 0; font-size: 0; line-height: 0; border-width: 1px 0 0 0; }
+.ui-menu .ui-menu-item a { text-decoration: none; display: block; padding: 2px .4em; line-height: 1.5; zoom: 1; font-weight: normal; }
+.ui-menu .ui-menu-item a.ui-state-focus,
+.ui-menu .ui-menu-item a.ui-state-active { font-weight: normal; margin: -1px; }
+
+.ui-menu .ui-state-disabled { font-weight: normal; margin: .4em 0 .2em; line-height: 1.5; }
+.ui-menu .ui-state-disabled a { cursor: default; }
+
+/* icon support */
+.ui-menu-icons { position: relative; }
+.ui-menu-icons .ui-menu-item a { position: relative; padding-left: 2em; }
+
+/* left-aligned */
+.ui-menu .ui-icon { position: absolute; top: .2em; left: .2em; }
+
+/* right-aligned */
+.ui-menu .ui-menu-icon { position: static; float: right; }
+.ui-progressbar { height:2em; text-align: left; overflow: hidden; }
+.ui-progressbar .ui-progressbar-value {margin: -1px; height:100%; }.ui-slider { position: relative; text-align: left; }
+.ui-slider .ui-slider-handle { position: absolute; z-index: 2; width: 1.2em; height: 1.2em; cursor: default; }
+.ui-slider .ui-slider-range { position: absolute; z-index: 1; font-size: .7em; display: block; border: 0; background-position: 0 0; }
+
+.ui-slider-horizontal { height: .8em; }
+.ui-slider-horizontal .ui-slider-handle { top: -.3em; margin-left: -.6em; }
+.ui-slider-horizontal .ui-slider-range { top: 0; height: 100%; }
+.ui-slider-horizontal .ui-slider-range-min { left: 0; }
+.ui-slider-horizontal .ui-slider-range-max { right: 0; }
+
+.ui-slider-vertical { width: .8em; height: 100px; }
+.ui-slider-vertical .ui-slider-handle { left: -.3em; margin-left: 0; margin-bottom: -.6em; }
+.ui-slider-vertical .ui-slider-range { left: 0; width: 100%; }
+.ui-slider-vertical .ui-slider-range-min { bottom: 0; }
+.ui-slider-vertical .ui-slider-range-max { top: 0; }.ui-spinner { position:relative; display: inline-block; overflow: hidden; padding: 0; vertical-align: middle; }
+.ui-spinner-input { border: none; background: none; padding: 0; margin: .2em 0; vertical-align: middle; margin-left: .4em; margin-right: 22px; }
+.ui-spinner-button { width: 16px; height: 50%; font-size: .5em; padding: 0; margin: 0; text-align: center; position: absolute; cursor: default; display: block; overflow: hidden; right: 0; }
+.ui-spinner a.ui-spinner-button { border-top: none; border-bottom: none; border-right: none; } /* more specificity required here to overide default borders */
+.ui-spinner .ui-icon { position: absolute; margin-top: -8px; top: 50%; left: 0; } /* vertical centre icon */
+.ui-spinner-up { top: 0; }
+.ui-spinner-down { bottom: 0; }
+
+/* TR overrides */
+.ui-spinner .ui-icon-triangle-1-s {
+	/* need to fix icons sprite */
+	background-position:-65px -16px;
+}
+.ui-tabs { position: relative; padding: .2em; zoom: 1; } /* position: relative prevents IE scroll bug (element with position: relative inside container with overflow: auto appear as "fixed") */
+.ui-tabs .ui-tabs-nav { margin: 0; padding: .2em .2em 0; }
+.ui-tabs .ui-tabs-nav li { list-style: none; float: left; position: relative; top: 0; margin: 1px .2em 0 0; border-bottom: 0; padding: 0; white-space: nowrap; }
+.ui-tabs .ui-tabs-nav li a { float: left; padding: .5em 1em; text-decoration: none; }
+.ui-tabs .ui-tabs-nav li.ui-tabs-active { margin-bottom: -1px; padding-bottom: 1px; }
+.ui-tabs .ui-tabs-nav li.ui-tabs-active a, .ui-tabs .ui-tabs-nav li.ui-state-disabled a, .ui-tabs .ui-tabs-nav li.ui-tabs-loading a { cursor: text; }
+.ui-tabs .ui-tabs-nav li a, .ui-tabs-collapsible .ui-tabs-nav li.ui-tabs-active a { cursor: pointer; } /* first selector in group seems obsolete, but required to overcome bug in Opera applying cursor: text overall if defined elsewhere... */
+.ui-tabs .ui-tabs-panel { display: block; border-width: 0; padding: 1em 1.4em; background: none; }
+.ui-tooltip {
+	padding: 8px;
+	position: absolute;
+	z-index: 9999;
+	max-width: 300px;
+	-webkit-box-shadow: 0 0 5px #aaa;
+	box-shadow: 0 0 5px #aaa;
+}
+/* Fades and background-images don't work well together in IE6, drop the image */
+* html .ui-tooltip {
+	background-image: none;
+}
+body .ui-tooltip { border-width: 2px; }
+
+/* Component containers
+----------------------------------*/
+.ui-widget { font-family: Verdana,Arial,sans-serif; font-size: 1.1em; }
+.ui-widget .ui-widget { font-size: 1em; }
+.ui-widget input, .ui-widget select, .ui-widget textarea, .ui-widget button { font-family: Verdana,Arial,sans-serif; font-size: 1em; }
+.ui-widget-content { border: 1px solid #aaaaaa; background: #ffffff url(images/ui-bg_flat_75_ffffff_40x100.png) 50% 50% repeat-x; color: #222222; }
+.ui-widget-content a { color: #222222; }
+.ui-widget-header { border: 1px solid #aaaaaa; background: #cccccc url(images/ui-bg_highlight-soft_75_cccccc_1x100.png) 50% 50% repeat-x; color: #222222; font-weight: bold; }
+.ui-widget-header a { color: #222222; }
+
+/* Interaction states
+----------------------------------*/
+.ui-state-default, .ui-widget-content .ui-state-default, .ui-widget-header .ui-state-default { border: 1px solid #d3d3d3; background: #e6e6e6 url(images/ui-bg_glass_75_e6e6e6_1x400.png) 50% 50% repeat-x; font-weight: normal; color: #555555; }
+.ui-state-default a, .ui-state-default a:link, .ui-state-default a:visited { color: #555555; text-decoration: none; }
+.ui-state-hover, .ui-widget-content .ui-state-hover, .ui-widget-header .ui-state-hover, .ui-state-focus, .ui-widget-content .ui-state-focus, .ui-widget-header .ui-state-focus { border: 1px solid #999999; background: #dadada url(images/ui-bg_glass_75_dadada_1x400.png) 50% 50% repeat-x; font-weight: normal; color: #212121; }
+.ui-state-hover a, .ui-state-hover a:hover, .ui-state-hover a:link, .ui-state-hover a:visited { color: #212121; text-decoration: none; }
+.ui-state-active, .ui-widget-content .ui-state-active, .ui-widget-header .ui-state-active { border: 1px solid #aaaaaa; background: #ffffff url(images/ui-bg_glass_65_ffffff_1x400.png) 50% 50% repeat-x; font-weight: normal; color: #212121; }
+.ui-state-active a, .ui-state-active a:link, .ui-state-active a:visited { color: #212121; text-decoration: none; }
+
+/* Interaction Cues
+----------------------------------*/
+.ui-state-highlight, .ui-widget-content .ui-state-highlight, .ui-widget-header .ui-state-highlight  {border: 1px solid #fcefa1; background: #fbf9ee url(images/ui-bg_glass_55_fbf9ee_1x400.png) 50% 50% repeat-x; color: #363636; }
+.ui-state-highlight a, .ui-widget-content .ui-state-highlight a,.ui-widget-header .ui-state-highlight a { color: #363636; }
+.ui-state-error, .ui-widget-content .ui-state-error, .ui-widget-header .ui-state-error {border: 1px solid #cd0a0a; background: #fef1ec url(images/ui-bg_glass_95_fef1ec_1x400.png) 50% 50% repeat-x; color: #cd0a0a; }
+.ui-state-error a, .ui-widget-content .ui-state-error a, .ui-widget-header .ui-state-error a { color: #cd0a0a; }
+.ui-state-error-text, .ui-widget-content .ui-state-error-text, .ui-widget-header .ui-state-error-text { color: #cd0a0a; }
+.ui-priority-primary, .ui-widget-content .ui-priority-primary, .ui-widget-header .ui-priority-primary { font-weight: bold; }
+.ui-priority-secondary, .ui-widget-content .ui-priority-secondary,  .ui-widget-header .ui-priority-secondary { opacity: .7; filter:Alpha(Opacity=70); font-weight: normal; }
+.ui-state-disabled, .ui-widget-content .ui-state-disabled, .ui-widget-header .ui-state-disabled { opacity: .35; filter:Alpha(Opacity=35); background-image: none; }
+.ui-state-disabled .ui-icon { filter:Alpha(Opacity=35); } /* For IE8 - See #6059 */
+
+/* Icons
+----------------------------------*/
+
+/* states and images */
+.ui-icon { width: 16px; height: 16px; background-image: url(images/ui-icons_222222_256x240.png); }
+.ui-widget-content .ui-icon {background-image: url(images/ui-icons_222222_256x240.png); }
+.ui-widget-header .ui-icon {background-image: url(images/ui-icons_222222_256x240.png); }
+.ui-state-default .ui-icon { background-image: url(images/ui-icons_888888_256x240.png); }
+.ui-state-hover .ui-icon, .ui-state-focus .ui-icon {background-image: url(images/ui-icons_454545_256x240.png); }
+.ui-state-active .ui-icon {background-image: url(images/ui-icons_454545_256x240.png); }
+.ui-state-highlight .ui-icon {background-image: url(images/ui-icons_2e83ff_256x240.png); }
+.ui-state-error .ui-icon, .ui-state-error-text .ui-icon {background-image: url(images/ui-icons_cd0a0a_256x240.png); }
+
+/* positioning */
+.ui-icon-carat-1-n { background-position: 0 0; }
+.ui-icon-carat-1-ne { background-position: -16px 0; }
+.ui-icon-carat-1-e { background-position: -32px 0; }
+.ui-icon-carat-1-se { background-position: -48px 0; }
+.ui-icon-carat-1-s { background-position: -64px 0; }
+.ui-icon-carat-1-sw { background-position: -80px 0; }
+.ui-icon-carat-1-w { background-position: -96px 0; }
+.ui-icon-carat-1-nw { background-position: -112px 0; }
+.ui-icon-carat-2-n-s { background-position: -128px 0; }
+.ui-icon-carat-2-e-w { background-position: -144px 0; }
+.ui-icon-triangle-1-n { background-position: 0 -16px; }
+.ui-icon-triangle-1-ne { background-position: -16px -16px; }
+.ui-icon-triangle-1-e { background-position: -32px -16px; }
+.ui-icon-triangle-1-se { background-position: -48px -16px; }
+.ui-icon-triangle-1-s { background-position: -64px -16px; }
+.ui-icon-triangle-1-sw { background-position: -80px -16px; }
+.ui-icon-triangle-1-w { background-position: -96px -16px; }
+.ui-icon-triangle-1-nw { background-position: -112px -16px; }
+.ui-icon-triangle-2-n-s { background-position: -128px -16px; }
+.ui-icon-triangle-2-e-w { background-position: -144px -16px; }
+.ui-icon-arrow-1-n { background-position: 0 -32px; }
+.ui-icon-arrow-1-ne { background-position: -16px -32px; }
+.ui-icon-arrow-1-e { background-position: -32px -32px; }
+.ui-icon-arrow-1-se { background-position: -48px -32px; }
+.ui-icon-arrow-1-s { background-position: -64px -32px; }
+.ui-icon-arrow-1-sw { background-position: -80px -32px; }
+.ui-icon-arrow-1-w { background-position: -96px -32px; }
+.ui-icon-arrow-1-nw { background-position: -112px -32px; }
+.ui-icon-arrow-2-n-s { background-position: -128px -32px; }
+.ui-icon-arrow-2-ne-sw { background-position: -144px -32px; }
+.ui-icon-arrow-2-e-w { background-position: -160px -32px; }
+.ui-icon-arrow-2-se-nw { background-position: -176px -32px; }
+.ui-icon-arrowstop-1-n { background-position: -192px -32px; }
+.ui-icon-arrowstop-1-e { background-position: -208px -32px; }
+.ui-icon-arrowstop-1-s { background-position: -224px -32px; }
+.ui-icon-arrowstop-1-w { background-position: -240px -32px; }
+.ui-icon-arrowthick-1-n { background-position: 0 -48px; }
+.ui-icon-arrowthick-1-ne { background-position: -16px -48px; }
+.ui-icon-arrowthick-1-e { background-position: -32px -48px; }
+.ui-icon-arrowthick-1-se { background-position: -48px -48px; }
+.ui-icon-arrowthick-1-s { background-position: -64px -48px; }
+.ui-icon-arrowthick-1-sw { background-position: -80px -48px; }
+.ui-icon-arrowthick-1-w { background-position: -96px -48px; }
+.ui-icon-arrowthick-1-nw { background-position: -112px -48px; }
+.ui-icon-arrowthick-2-n-s { background-position: -128px -48px; }
+.ui-icon-arrowthick-2-ne-sw { background-position: -144px -48px; }
+.ui-icon-arrowthick-2-e-w { background-position: -160px -48px; }
+.ui-icon-arrowthick-2-se-nw { background-position: -176px -48px; }
+.ui-icon-arrowthickstop-1-n { background-position: -192px -48px; }
+.ui-icon-arrowthickstop-1-e { background-position: -208px -48px; }
+.ui-icon-arrowthickstop-1-s { background-position: -224px -48px; }
+.ui-icon-arrowthickstop-1-w { background-position: -240px -48px; }
+.ui-icon-arrowreturnthick-1-w { background-position: 0 -64px; }
+.ui-icon-arrowreturnthick-1-n { background-position: -16px -64px; }
+.ui-icon-arrowreturnthick-1-e { background-position: -32px -64px; }
+.ui-icon-arrowreturnthick-1-s { background-position: -48px -64px; }
+.ui-icon-arrowreturn-1-w { background-position: -64px -64px; }
+.ui-icon-arrowreturn-1-n { background-position: -80px -64px; }
+.ui-icon-arrowreturn-1-e { background-position: -96px -64px; }
+.ui-icon-arrowreturn-1-s { background-position: -112px -64px; }
+.ui-icon-arrowrefresh-1-w { background-position: -128px -64px; }
+.ui-icon-arrowrefresh-1-n { background-position: -144px -64px; }
+.ui-icon-arrowrefresh-1-e { background-position: -160px -64px; }
+.ui-icon-arrowrefresh-1-s { background-position: -176px -64px; }
+.ui-icon-arrow-4 { background-position: 0 -80px; }
+.ui-icon-arrow-4-diag { background-position: -16px -80px; }
+.ui-icon-extlink { background-position: -32px -80px; }
+.ui-icon-newwin { background-position: -48px -80px; }
+.ui-icon-refresh { background-position: -64px -80px; }
+.ui-icon-shuffle { background-position: -80px -80px; }
+.ui-icon-transfer-e-w { background-position: -96px -80px; }
+.ui-icon-transferthick-e-w { background-position: -112px -80px; }
+.ui-icon-folder-collapsed { background-position: 0 -96px; }
+.ui-icon-folder-open { background-position: -16px -96px; }
+.ui-icon-document { background-position: -32px -96px; }
+.ui-icon-document-b { background-position: -48px -96px; }
+.ui-icon-note { background-position: -64px -96px; }
+.ui-icon-mail-closed { background-position: -80px -96px; }
+.ui-icon-mail-open { background-position: -96px -96px; }
+.ui-icon-suitcase { background-position: -112px -96px; }
+.ui-icon-comment { background-position: -128px -96px; }
+.ui-icon-person { background-position: -144px -96px; }
+.ui-icon-print { background-position: -160px -96px; }
+.ui-icon-trash { background-position: -176px -96px; }
+.ui-icon-locked { background-position: -192px -96px; }
+.ui-icon-unlocked { background-position: -208px -96px; }
+.ui-icon-bookmark { background-position: -224px -96px; }
+.ui-icon-tag { background-position: -240px -96px; }
+.ui-icon-home { background-position: 0 -112px; }
+.ui-icon-flag { background-position: -16px -112px; }
+.ui-icon-calendar { background-position: -32px -112px; }
+.ui-icon-cart { background-position: -48px -112px; }
+.ui-icon-pencil { background-position: -64px -112px; }
+.ui-icon-clock { background-position: -80px -112px; }
+.ui-icon-disk { background-position: -96px -112px; }
+.ui-icon-calculator { background-position: -112px -112px; }
+.ui-icon-zoomin { background-position: -128px -112px; }
+.ui-icon-zoomout { background-position: -144px -112px; }
+.ui-icon-search { background-position: -160px -112px; }
+.ui-icon-wrench { background-position: -176px -112px; }
+.ui-icon-gear { background-position: -192px -112px; }
+.ui-icon-heart { background-position: -208px -112px; }
+.ui-icon-star { background-position: -224px -112px; }
+.ui-icon-link { background-position: -240px -112px; }
+.ui-icon-cancel { background-position: 0 -128px; }
+.ui-icon-plus { background-position: -16px -128px; }
+.ui-icon-plusthick { background-position: -32px -128px; }
+.ui-icon-minus { background-position: -48px -128px; }
+.ui-icon-minusthick { background-position: -64px -128px; }
+.ui-icon-close { background-position: -80px -128px; }
+.ui-icon-closethick { background-position: -96px -128px; }
+.ui-icon-key { background-position: -112px -128px; }
+.ui-icon-lightbulb { background-position: -128px -128px; }
+.ui-icon-scissors { background-position: -144px -128px; }
+.ui-icon-clipboard { background-position: -160px -128px; }
+.ui-icon-copy { background-position: -176px -128px; }
+.ui-icon-contact { background-position: -192px -128px; }
+.ui-icon-image { background-position: -208px -128px; }
+.ui-icon-video { background-position: -224px -128px; }
+.ui-icon-script { background-position: -240px -128px; }
+.ui-icon-alert { background-position: 0 -144px; }
+.ui-icon-info { background-position: -16px -144px; }
+.ui-icon-notice { background-position: -32px -144px; }
+.ui-icon-help { background-position: -48px -144px; }
+.ui-icon-check { background-position: -64px -144px; }
+.ui-icon-bullet { background-position: -80px -144px; }
+.ui-icon-radio-on { background-position: -96px -144px; }
+.ui-icon-radio-off { background-position: -112px -144px; }
+.ui-icon-pin-w { background-position: -128px -144px; }
+.ui-icon-pin-s { background-position: -144px -144px; }
+.ui-icon-play { background-position: 0 -160px; }
+.ui-icon-pause { background-position: -16px -160px; }
+.ui-icon-seek-next { background-position: -32px -160px; }
+.ui-icon-seek-prev { background-position: -48px -160px; }
+.ui-icon-seek-end { background-position: -64px -160px; }
+.ui-icon-seek-start { background-position: -80px -160px; }
+/* ui-icon-seek-first is deprecated, use ui-icon-seek-start instead */
+.ui-icon-seek-first { background-position: -80px -160px; }
+.ui-icon-stop { background-position: -96px -160px; }
+.ui-icon-eject { background-position: -112px -160px; }
+.ui-icon-volume-off { background-position: -128px -160px; }
+.ui-icon-volume-on { background-position: -144px -160px; }
+.ui-icon-power { background-position: 0 -176px; }
+.ui-icon-signal-diag { background-position: -16px -176px; }
+.ui-icon-signal { background-position: -32px -176px; }
+.ui-icon-battery-0 { background-position: -48px -176px; }
+.ui-icon-battery-1 { background-position: -64px -176px; }
+.ui-icon-battery-2 { background-position: -80px -176px; }
+.ui-icon-battery-3 { background-position: -96px -176px; }
+.ui-icon-circle-plus { background-position: 0 -192px; }
+.ui-icon-circle-minus { background-position: -16px -192px; }
+.ui-icon-circle-close { background-position: -32px -192px; }
+.ui-icon-circle-triangle-e { background-position: -48px -192px; }
+.ui-icon-circle-triangle-s { background-position: -64px -192px; }
+.ui-icon-circle-triangle-w { background-position: -80px -192px; }
+.ui-icon-circle-triangle-n { background-position: -96px -192px; }
+.ui-icon-circle-arrow-e { background-position: -112px -192px; }
+.ui-icon-circle-arrow-s { background-position: -128px -192px; }
+.ui-icon-circle-arrow-w { background-position: -144px -192px; }
+.ui-icon-circle-arrow-n { background-position: -160px -192px; }
+.ui-icon-circle-zoomin { background-position: -176px -192px; }
+.ui-icon-circle-zoomout { background-position: -192px -192px; }
+.ui-icon-circle-check { background-position: -208px -192px; }
+.ui-icon-circlesmall-plus { background-position: 0 -208px; }
+.ui-icon-circlesmall-minus { background-position: -16px -208px; }
+.ui-icon-circlesmall-close { background-position: -32px -208px; }
+.ui-icon-squaresmall-plus { background-position: -48px -208px; }
+.ui-icon-squaresmall-minus { background-position: -64px -208px; }
+.ui-icon-squaresmall-close { background-position: -80px -208px; }
+.ui-icon-grip-dotted-vertical { background-position: 0 -224px; }
+.ui-icon-grip-dotted-horizontal { background-position: -16px -224px; }
+.ui-icon-grip-solid-vertical { background-position: -32px -224px; }
+.ui-icon-grip-solid-horizontal { background-position: -48px -224px; }
+.ui-icon-gripsmall-diagonal-se { background-position: -64px -224px; }
+.ui-icon-grip-diagonal-se { background-position: -80px -224px; }
+
+
+/* Misc visuals
+----------------------------------*/
+
+/* Corner radius */
+.ui-corner-all, .ui-corner-top, .ui-corner-left, .ui-corner-tl { -moz-border-radius-topleft: 4px; -webkit-border-top-left-radius: 4px; -khtml-border-top-left-radius: 4px; border-top-left-radius: 4px; }
+.ui-corner-all, .ui-corner-top, .ui-corner-right, .ui-corner-tr { -moz-border-radius-topright: 4px; -webkit-border-top-right-radius: 4px; -khtml-border-top-right-radius: 4px; border-top-right-radius: 4px; }
+.ui-corner-all, .ui-corner-bottom, .ui-corner-left, .ui-corner-bl { -moz-border-radius-bottomleft: 4px; -webkit-border-bottom-left-radius: 4px; -khtml-border-bottom-left-radius: 4px; border-bottom-left-radius: 4px; }
+.ui-corner-all, .ui-corner-bottom, .ui-corner-right, .ui-corner-br { -moz-border-radius-bottomright: 4px; -webkit-border-bottom-right-radius: 4px; -khtml-border-bottom-right-radius: 4px; border-bottom-right-radius: 4px; }
+
+/* Overlays */
+.ui-widget-overlay { background: #aaaaaa url(images/ui-bg_flat_0_aaaaaa_40x100.png) 50% 50% repeat-x; opacity: .3;filter:Alpha(Opacity=30); }
+.ui-widget-shadow { margin: -8px 0 0 -8px; padding: 8px; background: #aaaaaa url(images/ui-bg_flat_0_aaaaaa_40x100.png) 50% 50% repeat-x; opacity: .3;filter:Alpha(Opacity=30); -moz-border-radius: 8px; -khtml-border-radius: 8px; -webkit-border-radius: 8px; border-radius: 8px; }
\ No newline at end of file
diff --git a/phpmyadmin/themes/original/layout.inc.php b/phpmyadmin/themes/original/layout.inc.php
new file mode 100644
index 0000000..46e2f01
--- /dev/null
+++ b/phpmyadmin/themes/original/layout.inc.php
@@ -0,0 +1,138 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * configures general layout
+ * for detailed layout configuration please refer to the css files
+ *
+ * @package    PhpMyAdmin-theme
+ * @subpackage Original
+ */
+
+/**
+ * navi frame
+ */
+// navi frame width
+$GLOBALS['cfg']['NaviWidth']                = 240;
+
+// foreground (text) color for the navi frame
+$GLOBALS['cfg']['NaviColor']                = '#000000';
+
+// background for the navi frame
+$GLOBALS['cfg']['NaviBackground']           = '#D0DCE0';
+
+// foreground (text) color of the pointer in navi frame
+$GLOBALS['cfg']['NaviPointerColor']         = '#000000';
+// background of the pointer in navi frame
+$GLOBALS['cfg']['NaviPointerBackground']    = '#9999CC';
+
+/**
+ * main frame
+ */
+// foreground (text) color for the main frame
+$GLOBALS['cfg']['MainColor']                = '#000000';
+
+// background for the main frame
+$GLOBALS['cfg']['MainBackground']           = '#F5F5F5';
+
+// foreground (text) color of the pointer in browse mode
+$GLOBALS['cfg']['BrowsePointerColor']       = '#000000';
+
+// background of the pointer in browse mode
+$GLOBALS['cfg']['BrowsePointerBackground']  = '#CCFFCC';
+
+// foreground (text) color of the marker (visually marks row by clicking on it)
+// in browse mode
+$GLOBALS['cfg']['BrowseMarkerColor']        = '#000000';
+
+// background of the marker (visually marks row by clicking on it) in browse mode
+$GLOBALS['cfg']['BrowseMarkerBackground']   = '#FFCC99';
+
+/**
+ * fonts
+ */
+/**
+ * the font family as a valid css font family value,
+ * if not set the browser default will be used
+ * (depending on browser, DTD and system settings)
+ */
+$GLOBALS['cfg']['FontFamily']           = 'sans-serif';
+/**
+ * fixed width font family, used in textarea
+ */
+$GLOBALS['cfg']['FontFamilyFixed']      = 'monospace';
+
+/**
+ * tables
+ */
+// border
+$GLOBALS['cfg']['Border']               = 0;
+// table header and footer color
+$GLOBALS['cfg']['ThBackground']         = '#D3DCE3';
+// table header and footer background
+$GLOBALS['cfg']['ThColor']              = '#000000';
+// table data row background
+$GLOBALS['cfg']['BgOne']                = '#E5E5E5';
+// table data row background, alternate
+$GLOBALS['cfg']['BgTwo']                = '#D5D5D5';
+
+/**
+ * query window
+ */
+// Width of Query window
+$GLOBALS['cfg']['QueryWindowWidth']     = 600;
+// Height of Query window
+$GLOBALS['cfg']['QueryWindowHeight']    = 400;
+
+/**
+ * SQL Parser Settings
+ * Syntax colouring data
+ */
+$GLOBALS['cfg']['SQP']['fmtColor']      = array(
+    'comment'            => '#808000',
+    'comment_mysql'      => '',
+    'comment_ansi'       => '',
+    'comment_c'          => '',
+    'digit'              => '',
+    'digit_hex'          => 'teal',
+    'digit_integer'      => 'teal',
+    'digit_float'        => 'aqua',
+    'punct'              => 'fuchsia',
+    'alpha'              => '',
+    'alpha_columnType'   => '#FF9900',
+    'alpha_columnAttrib' => '#0000FF',
+    'alpha_reservedWord' => '#990099',
+    'alpha_functionName' => '#FF0000',
+    'alpha_identifier'   => 'black',
+    'alpha_charset'      => '#6495ed',
+    'alpha_variable'     => '#800000',
+    'quote'              => '#008000',
+    'quote_double'       => '',
+    'quote_single'       => '',
+    'quote_backtick'     => ''
+);
+
+/**
+ * Chart colors
+ */
+
+ $GLOBALS['cfg']['chartColor'] = array(
+    'gradientIntensity'       => 0,
+    // The style of the chart title.
+    'titleColor'              => '#000000',
+    'titleBgColor'            => $GLOBALS['cfg']['ThBackground'],
+    // Chart border (0 for no border)
+    'border'                  => '#CCCCCC',
+    // Chart background color.
+    'bgColor'                 => $GLOBALS['cfg']['BgTwo'],
+    // when graph area gradient is used, this is the color of the graph
+    // area border
+    'graphAreaColor'          =>  '#D5D9DD',
+    // the background color of the inner graph area
+    'graphAreaGradientColor'  => $GLOBALS['cfg']['BgOne'],
+    // the color of the grid lines in the graph area
+    'gridColor'               => '#E6E6E6',
+    // the color of the scale and the labels
+    'scaleColor'              => '#D5D9DD',
+ );
+
+?>
diff --git a/phpmyadmin/themes/original/screen.png b/phpmyadmin/themes/original/screen.png
new file mode 100644
index 0000000..c2f4053
Binary files /dev/null and b/phpmyadmin/themes/original/screen.png differ
diff --git a/phpmyadmin/themes/original/sprites.lib.php b/phpmyadmin/themes/original/sprites.lib.php
new file mode 100644
index 0000000..91ba82a
--- /dev/null
+++ b/phpmyadmin/themes/original/sprites.lib.php
@@ -0,0 +1,625 @@
+<?php
+/* AUTOGENERATED CONTENT - DO NOT EDIT */
+/* ALL CHANGES WILL BE UNDONE */
+/* RUN './scripts/generate-sprites' TO UPDATE THIS FILE */
+function PMA_sprites()
+{
+    return array(
+        'b_bookmark' => array(
+            'position' => '1',
+            'width'    => '16',
+            'height'   => '16'
+        ),
+        'b_browse' => array(
+            'position' => '2',
+            'width'    => '16',
+            'height'   => '16'
+        ),
+        'b_calendar' => array(
+            'position' => '3',
+            'width'    => '16',
+            'height'   => '16'
+        ),
+        'b_chart' => array(
+            'position' => '4',
+            'width'    => '16',
+            'height'   => '16'
+        ),
+        'b_close' => array(
+            'position' => '5',
+            'width'    => '16',
+            'height'   => '16'
+        ),
+        'b_column_add' => array(
+            'position' => '6',
+            'width'    => '16',
+            'height'   => '16'
+        ),
+        'b_comment' => array(
+            'position' => '7',
+            'width'    => '16',
+            'height'   => '16'
+        ),
+        'bd_browse' => array(
+            'position' => '8',
+            'width'    => '16',
+            'height'   => '16'
+        ),
+        'b_dbstatistics' => array(
+            'position' => '9',
+            'width'    => '16',
+            'height'   => '16'
+        ),
+        'bd_deltbl' => array(
+            'position' => '10',
+            'width'    => '16',
+            'height'   => '16'
+        ),
+        'bd_drop' => array(
+            'position' => '11',
+            'width'    => '16',
+            'height'   => '16'
+        ),
+        'bd_edit' => array(
+            'position' => '12',
+            'width'    => '16',
+            'height'   => '16'
+        ),
+        'b_deltbl' => array(
+            'position' => '13',
+            'width'    => '16',
+            'height'   => '16'
+        ),
+        'bd_empty' => array(
+            'position' => '14',
+            'width'    => '16',
+            'height'   => '16'
+        ),
+        'bd_export' => array(
+            'position' => '15',
+            'width'    => '16',
+            'height'   => '16'
+        ),
+        'bd_ftext' => array(
+            'position' => '16',
+            'width'    => '16',
+            'height'   => '16'
+        ),
+        'bd_index' => array(
+            'position' => '17',
+            'width'    => '16',
+            'height'   => '16'
+        ),
+        'bd_insrow' => array(
+            'position' => '18',
+            'width'    => '16',
+            'height'   => '16'
+        ),
+        'bd_nextpage' => array(
+            'position' => '19',
+            'width'    => '8',
+            'height'   => '13'
+        ),
+        'b_docs' => array(
+            'position' => '20',
+            'width'    => '16',
+            'height'   => '16'
+        ),
+        'bd_primary' => array(
+            'position' => '21',
+            'width'    => '16',
+            'height'   => '16'
+        ),
+        'b_drop' => array(
+            'position' => '22',
+            'width'    => '16',
+            'height'   => '16'
+        ),
+        'bd_sbrowse' => array(
+            'position' => '23',
+            'width'    => '10',
+            'height'   => '10'
+        ),
+        'bd_select' => array(
+            'position' => '24',
+            'width'    => '16',
+            'height'   => '16'
+        ),
+        'bd_spatial' => array(
+            'position' => '25',
+            'width'    => '16',
+            'height'   => '16'
+        ),
+        'bd_unique' => array(
+            'position' => '26',
+            'width'    => '16',
+            'height'   => '16'
+        ),
+        'b_edit' => array(
+            'position' => '27',
+            'width'    => '16',
+            'height'   => '16'
+        ),
+        'b_empty' => array(
+            'position' => '28',
+            'width'    => '16',
+            'height'   => '16'
+        ),
+        'b_engine' => array(
+            'position' => '29',
+            'width'    => '16',
+            'height'   => '16'
+        ),
+        'b_event_add' => array(
+            'position' => '30',
+            'width'    => '16',
+            'height'   => '16'
+        ),
+        'b_events' => array(
+            'position' => '31',
+            'width'    => '16',
+            'height'   => '16'
+        ),
+        'b_export' => array(
+            'position' => '32',
+            'width'    => '16',
+            'height'   => '16'
+        ),
+        'b_ftext' => array(
+            'position' => '33',
+            'width'    => '16',
+            'height'   => '16'
+        ),
+        'b_group' => array(
+            'position' => '34',
+            'width'    => '16',
+            'height'   => '16'
+        ),
+        'b_help' => array(
+            'position' => '35',
+            'width'    => '11',
+            'height'   => '11'
+        ),
+        'b_home' => array(
+            'position' => '36',
+            'width'    => '16',
+            'height'   => '16'
+        ),
+        'b_import' => array(
+            'position' => '37',
+            'width'    => '16',
+            'height'   => '16'
+        ),
+        'b_index_add' => array(
+            'position' => '38',
+            'width'    => '16',
+            'height'   => '16'
+        ),
+        'b_index' => array(
+            'position' => '39',
+            'width'    => '16',
+            'height'   => '16'
+        ),
+        'b_info' => array(
+            'position' => '40',
+            'width'    => '11',
+            'height'   => '11'
+        ),
+        'b_inline_edit' => array(
+            'position' => '41',
+            'width'    => '16',
+            'height'   => '16'
+        ),
+        'b_insrow' => array(
+            'position' => '42',
+            'width'    => '16',
+            'height'   => '16'
+        ),
+        'b_minus' => array(
+            'position' => '43',
+            'width'    => '9',
+            'height'   => '9'
+        ),
+        'b_more' => array(
+            'position' => '44',
+            'width'    => '16',
+            'height'   => '16'
+        ),
+        'b_move' => array(
+            'position' => '45',
+            'width'    => '16',
+            'height'   => '16'
+        ),
+        'b_newdb' => array(
+            'position' => '46',
+            'width'    => '16',
+            'height'   => '16'
+        ),
+        'b_newtbl' => array(
+            'position' => '47',
+            'width'    => '16',
+            'height'   => '16'
+        ),
+        'b_nextpage' => array(
+            'position' => '48',
+            'width'    => '16',
+            'height'   => '16'
+        ),
+        'b_plus' => array(
+            'position' => '49',
+            'width'    => '9',
+            'height'   => '9'
+        ),
+        'b_primary' => array(
+            'position' => '50',
+            'width'    => '16',
+            'height'   => '16'
+        ),
+        'b_print' => array(
+            'position' => '51',
+            'width'    => '16',
+            'height'   => '16'
+        ),
+        'b_props' => array(
+            'position' => '52',
+            'width'    => '16',
+            'height'   => '16'
+        ),
+        'b_relations' => array(
+            'position' => '53',
+            'width'    => '16',
+            'height'   => '16'
+        ),
+        'b_routine_add' => array(
+            'position' => '54',
+            'width'    => '16',
+            'height'   => '16'
+        ),
+        'b_routines' => array(
+            'position' => '55',
+            'width'    => '16',
+            'height'   => '16'
+        ),
+        'b_save' => array(
+            'position' => '56',
+            'width'    => '16',
+            'height'   => '16'
+        ),
+        'b_sbrowse' => array(
+            'position' => '57',
+            'width'    => '10',
+            'height'   => '10'
+        ),
+        'b_search' => array(
+            'position' => '58',
+            'width'    => '16',
+            'height'   => '16'
+        ),
+        'b_selboard' => array(
+            'position' => '59',
+            'width'    => '16',
+            'height'   => '16'
+        ),
+        'b_select' => array(
+            'position' => '60',
+            'width'    => '16',
+            'height'   => '16'
+        ),
+        'b_snewtbl' => array(
+            'position' => '61',
+            'width'    => '10',
+            'height'   => '10'
+        ),
+        'b_spatial' => array(
+            'position' => '62',
+            'width'    => '16',
+            'height'   => '16'
+        ),
+        'b_sqlhelp' => array(
+            'position' => '63',
+            'width'    => '16',
+            'height'   => '16'
+        ),
+        'b_sql' => array(
+            'position' => '64',
+            'width'    => '16',
+            'height'   => '16'
+        ),
+        'b_table_add' => array(
+            'position' => '65',
+            'width'    => '16',
+            'height'   => '16'
+        ),
+        'b_tblanalyse' => array(
+            'position' => '66',
+            'width'    => '16',
+            'height'   => '16'
+        ),
+        'b_tblexport' => array(
+            'position' => '67',
+            'width'    => '16',
+            'height'   => '16'
+        ),
+        'b_tblimport' => array(
+            'position' => '68',
+            'width'    => '16',
+            'height'   => '16'
+        ),
+        'b_tblops' => array(
+            'position' => '69',
+            'width'    => '16',
+            'height'   => '16'
+        ),
+        'b_tbloptimize' => array(
+            'position' => '70',
+            'width'    => '16',
+            'height'   => '16'
+        ),
+        'b_tipp' => array(
+            'position' => '71',
+            'width'    => '16',
+            'height'   => '16'
+        ),
+        'b_trigger_add' => array(
+            'position' => '72',
+            'width'    => '16',
+            'height'   => '16'
+        ),
+        'b_triggers' => array(
+            'position' => '73',
+            'width'    => '16',
+            'height'   => '16'
+        ),
+        'b_unique' => array(
+            'position' => '74',
+            'width'    => '16',
+            'height'   => '16'
+        ),
+        'b_usradd' => array(
+            'position' => '75',
+            'width'    => '16',
+            'height'   => '16'
+        ),
+        'b_usrcheck' => array(
+            'position' => '76',
+            'width'    => '16',
+            'height'   => '16'
+        ),
+        'b_usrdrop' => array(
+            'position' => '77',
+            'width'    => '16',
+            'height'   => '16'
+        ),
+        'b_usredit' => array(
+            'position' => '78',
+            'width'    => '16',
+            'height'   => '16'
+        ),
+        'b_usrlist' => array(
+            'position' => '79',
+            'width'    => '16',
+            'height'   => '16'
+        ),
+        'b_view_add' => array(
+            'position' => '80',
+            'width'    => '16',
+            'height'   => '16'
+        ),
+        'b_view' => array(
+            'position' => '81',
+            'width'    => '16',
+            'height'   => '16'
+        ),
+        'b_views' => array(
+            'position' => '82',
+            'width'    => '16',
+            'height'   => '16'
+        ),
+        'col_drop' => array(
+            'position' => '83',
+            'width'    => '16',
+            'height'   => '16'
+        ),
+        'eye_grey' => array(
+            'position' => '84',
+            'width'    => '16',
+            'height'   => '16'
+        ),
+        'eye' => array(
+            'position' => '85',
+            'width'    => '16',
+            'height'   => '16'
+        ),
+        'more' => array(
+            'position' => '86',
+            'width'    => '13',
+            'height'   => '16'
+        ),
+        'new_data_hovered' => array(
+            'position' => '87',
+            'width'    => '16',
+            'height'   => '16'
+        ),
+        'new_data' => array(
+            'position' => '88',
+            'width'    => '16',
+            'height'   => '16'
+        ),
+        'new_data_selected_hovered' => array(
+            'position' => '89',
+            'width'    => '16',
+            'height'   => '16'
+        ),
+        'new_data_selected' => array(
+            'position' => '90',
+            'width'    => '16',
+            'height'   => '16'
+        ),
+        'new_struct_hovered' => array(
+            'position' => '91',
+            'width'    => '16',
+            'height'   => '16'
+        ),
+        'new_struct' => array(
+            'position' => '92',
+            'width'    => '16',
+            'height'   => '16'
+        ),
+        'new_struct_selected_hovered' => array(
+            'position' => '93',
+            'width'    => '16',
+            'height'   => '16'
+        ),
+        'new_struct_selected' => array(
+            'position' => '94',
+            'width'    => '16',
+            'height'   => '16'
+        ),
+        'pause' => array(
+            'position' => '95',
+            'width'    => '16',
+            'height'   => '16'
+        ),
+        'play' => array(
+            'position' => '96',
+            'width'    => '16',
+            'height'   => '16'
+        ),
+        's_asci' => array(
+            'position' => '97',
+            'width'    => '16',
+            'height'   => '16'
+        ),
+        's_asc' => array(
+            'position' => '98',
+            'width'    => '11',
+            'height'   => '9'
+        ),
+        's_cancel' => array(
+            'position' => '99',
+            'width'    => '16',
+            'height'   => '16'
+        ),
+        's_cog' => array(
+            'position' => '100',
+            'width'    => '16',
+            'height'   => '16'
+        ),
+        's_db' => array(
+            'position' => '101',
+            'width'    => '16',
+            'height'   => '16'
+        ),
+        's_desc' => array(
+            'position' => '102',
+            'width'    => '11',
+            'height'   => '9'
+        ),
+        's_error2' => array(
+            'position' => '103',
+            'width'    => '11',
+            'height'   => '11'
+        ),
+        's_error' => array(
+            'position' => '104',
+            'width'    => '16',
+            'height'   => '16'
+        ),
+        's_host' => array(
+            'position' => '105',
+            'width'    => '16',
+            'height'   => '16'
+        ),
+        's_lang' => array(
+            'position' => '106',
+            'width'    => '16',
+            'height'   => '16'
+        ),
+        's_loggoff' => array(
+            'position' => '107',
+            'width'    => '16',
+            'height'   => '16'
+        ),
+        's_notice' => array(
+            'position' => '108',
+            'width'    => '16',
+            'height'   => '16'
+        ),
+        's_passwd' => array(
+            'position' => '109',
+            'width'    => '16',
+            'height'   => '16'
+        ),
+        's_really' => array(
+            'position' => '110',
+            'width'    => '11',
+            'height'   => '11'
+        ),
+        's_reload' => array(
+            'position' => '111',
+            'width'    => '16',
+            'height'   => '16'
+        ),
+        's_replication' => array(
+            'position' => '112',
+            'width'    => '16',
+            'height'   => '16'
+        ),
+        's_rights' => array(
+            'position' => '113',
+            'width'    => '16',
+            'height'   => '16'
+        ),
+        's_sortable' => array(
+            'position' => '114',
+            'width'    => '11',
+            'height'   => '15'
+        ),
+        's_status' => array(
+            'position' => '115',
+            'width'    => '16',
+            'height'   => '16'
+        ),
+        's_success' => array(
+            'position' => '116',
+            'width'    => '16',
+            'height'   => '16'
+        ),
+        's_sync' => array(
+            'position' => '117',
+            'width'    => '16',
+            'height'   => '16'
+        ),
+        's_tbl' => array(
+            'position' => '118',
+            'width'    => '16',
+            'height'   => '16'
+        ),
+        's_theme' => array(
+            'position' => '119',
+            'width'    => '16',
+            'height'   => '16'
+        ),
+        's_top' => array(
+            'position' => '120',
+            'width'    => '16',
+            'height'   => '16'
+        ),
+        's_vars' => array(
+            'position' => '121',
+            'width'    => '16',
+            'height'   => '16'
+        ),
+        's_views' => array(
+            'position' => '122',
+            'width'    => '10',
+            'height'   => '10'
+        ),
+        'window-new' => array(
+            'position' => '123',
+            'width'    => '16',
+            'height'   => '16'
+        ),
+    );
+}
+?>
diff --git a/phpmyadmin/themes/pmahomme/css/codemirror.css.php b/phpmyadmin/themes/pmahomme/css/codemirror.css.php
new file mode 100644
index 0000000..d7b9a5a
--- /dev/null
+++ b/phpmyadmin/themes/pmahomme/css/codemirror.css.php
@@ -0,0 +1,162 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * Styles for CodeMirror editor
+ * for the pmahomme theme
+ *
+ * @package    PhpMyAdmin-theme
+ * @subpackage PMAHomme
+ */
+
+// unplanned execution path
+if (! defined('PMA_MINIMUM_COMMON') && ! defined('TESTSUITE')) {
+    exit();
+}
+?>
+.CodeMirror {
+  line-height: 1em;
+  font-family: monospace;
+  background: #fff;
+  border: 1px solid #000;
+  /* Necessary so the scrollbar can be absolutely positioned within the wrapper on Lion. */
+  position: relative;
+  /* This prevents unwanted scrollbars from showing up on the body and wrapper in IE. */
+  overflow: hidden;
+}
+
+.CodeMirror-scroll {
+  overflow: auto;
+  height: <?php echo ceil($GLOBALS['cfg']['TextareaRows'] * 1.2); ?>em;
+  /* This is needed to prevent an IE[67] bug where the scrolled content
+     is visible outside of the scrolling box. */
+  position: relative;
+  outline: none;
+}
+
+/* Vertical scrollbar */
+.CodeMirror-scrollbar {
+  position: absolute;
+  right: 0; top: 0;
+  overflow-x: hidden;
+  overflow-y: scroll;
+  z-index: 5;
+}
+.CodeMirror-scrollbar-inner {
+  /* This needs to have a nonzero width in order for the scrollbar to appear
+     in Firefox and IE9. */
+  width: 1px;
+}
+.CodeMirror-scrollbar.cm-sb-overlap {
+  /* Ensure that the scrollbar appears in Lion, and that it overlaps the content
+     rather than sitting to the right of it. */
+  position: absolute;
+  z-index: 1;
+  float: none;
+  right: 0;
+  min-width: 12px;
+}
+.CodeMirror-scrollbar.cm-sb-nonoverlap {
+  min-width: 12px;
+}
+.CodeMirror-scrollbar.cm-sb-ie7 {
+  min-width: 18px;
+}
+
+.CodeMirror-gutter {
+  position: absolute; left: 0; top: 0;
+  z-index: 10;
+  background-color: #f7f7f7;
+  border-right: 1px solid #eee;
+  min-width: 2em;
+  height: 100%;
+}
+.CodeMirror-gutter-text {
+  color: #aaa;
+  text-align: right;
+  padding: .4em .2em .4em .4em;
+  white-space: pre !important;
+  cursor: default;
+}
+.CodeMirror-lines {
+  padding: .4em;
+  white-space: pre;
+  cursor: text;
+}
+
+.CodeMirror pre {
+  -moz-border-radius: 0;
+  -webkit-border-radius: 0;
+  -o-border-radius: 0;
+  border-radius: 0;
+  border-width: 0; margin: 0; padding: 0; background: transparent;
+  font-family: inherit;
+  font-size: inherit;
+  padding: 0; margin: 0;
+  white-space: pre;
+  word-wrap: normal;
+  line-height: inherit;
+  color: inherit;
+  overflow: visible;
+}
+
+.CodeMirror-wrap pre {
+  word-wrap: break-word;
+  white-space: pre-wrap;
+  word-break: normal;
+}
+.CodeMirror-wrap .CodeMirror-scroll {
+  overflow-x: hidden;
+}
+
+.CodeMirror textarea {
+  outline: none !important;
+  font-family: inherit !important;
+  font-size: inherit !important;
+}
+
+.CodeMirror pre.CodeMirror-cursor {
+  z-index: 10;
+  position: absolute;
+  visibility: hidden;
+  border-<?php echo $left; ?>: 1px solid black !important;
+  border-<?php echo $right; ?>: none;
+  width: 0;
+}
+.cm-keymap-fat-cursor pre.CodeMirror-cursor {
+  width: auto;
+  border: 0;
+  background: transparent;
+  background: rgba(0, 200, 0, .4);
+  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr=#6600c800, endColorstr=#4c00c800);
+}
+/* Kludge to turn off filter in ie9+, which also accepts rgba */
+.cm-keymap-fat-cursor pre.CodeMirror-cursor:not(#nonsense_id) {
+  filter: progid:DXImageTransform.Microsoft.gradient(enabled=false);
+}
+.CodeMirror pre.CodeMirror-cursor.CodeMirror-overwrite {}
+.CodeMirror-focused pre.CodeMirror-cursor {
+  visibility: visible;
+}
+
+div.CodeMirror-selected { background: #d9d9d9; }
+.CodeMirror-focused div.CodeMirror-selected { background: #d7d4f0; }
+
+.CodeMirror-searching {
+  background: #ffa;
+  background: rgba(255, 255, 0, .4);
+}
+
+
+div.CodeMirror span.CodeMirror-matchingbracket {color: #0f0;}
+div.CodeMirror span.CodeMirror-nonmatchingbracket {color: #f22;}
+
+ at media print {
+
+  /* Hide the cursor when printing */
+  .CodeMirror pre.CodeMirror-cursor {
+    visibility: hidden;
+  }
+
+}
+
+<?php echo $_SESSION['PMA_Theme']->getCssCodeMirror(); ?>
diff --git a/phpmyadmin/themes/pmahomme/css/common.css.php b/phpmyadmin/themes/pmahomme/css/common.css.php
new file mode 100644
index 0000000..0787c72
--- /dev/null
+++ b/phpmyadmin/themes/pmahomme/css/common.css.php
@@ -0,0 +1,2756 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * Common styles for the pmahomme theme
+ *
+ * @package    PhpMyAdmin-theme
+ * @subpackage PMAHomme
+ */
+
+// unplanned execution path
+if (! defined('PMA_MINIMUM_COMMON') && ! defined('TESTSUITE')) {
+    exit();
+}
+?>
+/******************************************************************************/
+
+/* general tags */
+html {
+    font-size: <?php echo $_SESSION['PMA_Theme']->getFontSize(); ?>
+}
+
+input,
+select,
+textarea {
+    font-size: 1em;
+}
+
+
+body {
+<?php if (! empty($GLOBALS['cfg']['FontFamily'])) { ?>
+    font-family: <?php echo $GLOBALS['cfg']['FontFamily']; ?>;
+<?php } ?>
+    padding: 0;
+    margin: 0;
+    margin-<?php echo $left; ?>: 240px;
+    color: #444;
+    background: #fff;
+}
+
+body#loginform {
+    margin: 0;
+}
+
+#page_content {
+    margin: 0 .5em;
+}
+
+<?php if (! empty($GLOBALS['cfg']['FontFamilyFixed'])) { ?>
+textarea,
+tt,
+pre,
+code {
+    font-family: <?php echo $GLOBALS['cfg']['FontFamilyFixed']; ?>;
+}
+<?php } ?>
+
+
+h1 {
+    font-size: 140%;
+    font-weight: bold;
+}
+
+h2 {
+    font-size: 2em;
+    font-weight: normal;
+    text-shadow: 0 1px 0 #fff;
+    padding: 10px 0 10px;
+    padding-<?php echo $left; ?>: 3px;
+    color: #777;
+}
+
+/* Hiding icons in the page titles */
+h2 img {
+    display: none;
+}
+
+h2 a img {
+    display: inline;
+}
+
+.data,
+.data_full_width {
+    margin: 0 0 12px;
+}
+
+.data_full_width {
+    width: 100%;
+}
+
+#table_results td.data {
+border-right: 1px solid #bbb;
+}
+
+h3 {
+    font-weight: bold;
+}
+
+a,
+a:link,
+a:visited,
+a:active {
+    text-decoration: none;
+    color: #235a81;
+    cursor: pointer;
+    outline: none;
+
+}
+
+a:hover {
+    text-decoration: underline;
+    color: #235a81;
+}
+
+#initials_table {
+    background: #f3f3f3;
+    border: 1px solid #aaa;
+    margin-bottom: 10px;
+    -moz-border-radius: 5px;
+    -webkit-border-radius: 5px;
+    border-radius: 5px;
+}
+
+#initials_table td {
+    padding: 8px !important;
+}
+
+#initials_table a {
+    border: 1px solid #aaa;
+    background: #fff;
+    padding: 4px 8px;
+    -moz-border-radius: 5px;
+    -webkit-border-radius: 5px;
+    border-radius: 5px;
+    <?php echo $_SESSION['PMA_Theme']->getCssGradient('ffffff', 'cccccc'); ?>
+}
+
+dfn {
+    font-style: normal;
+}
+
+dfn:hover {
+    font-style: normal;
+    cursor: help;
+}
+
+th {
+    font-weight: bold;
+    color: <?php echo $GLOBALS['cfg']['ThColor']; ?>;
+    background: #f3f3f3;
+    <?php echo $_SESSION['PMA_Theme']->getCssGradient('ffffff', 'cccccc'); ?>
+}
+
+a img {
+    border: 0;
+}
+
+hr {
+    color: <?php echo $GLOBALS['cfg']['MainColor']; ?>;
+    background-color: <?php echo $GLOBALS['cfg']['MainColor']; ?>;
+    border: 0;
+    height: 1px;
+}
+
+form {
+    padding: 0;
+    margin: 0;
+    display: inline;
+}
+
+input[type=text] {
+    border-radius: 2px;
+    -moz-border-radius: 2px;
+    -webkit-border-radius: 2px;
+
+    box-shadow: 0 1px 2px #ddd;
+    -moz-box-shadow: 0 1px 2px #ddd;
+    -webkit-box-shadow: 0 1px 2px #ddd;
+
+    background: white;
+    border: 1px solid #aaa;
+    color: #555;
+    padding: 4px;
+    margin: 6px;
+
+}
+
+input[type=password] {
+    border-radius: 2px;
+    -moz-border-radius: 2px;
+    -webkit-border-radius: 2px;
+
+    box-shadow: 0 1px 2px #ddd;
+    -moz-box-shadow: 0 1px 2px #ddd;
+    -webkit-box-shadow: 0 1px 2px #ddd;
+
+    background: white;
+    border: 1px solid #aaa;
+    color: #555;
+    padding: 4px;
+    margin: 6px;
+
+}
+
+input[type=submit],
+button[type=submit]:not(.mult_submit) {
+    font-weight: bold !important;
+}
+
+input[type=submit],
+button[type=submit]:not(.mult_submit),
+input[type=reset],
+input[name=submit_reset],
+input.button {
+    margin-left: 14px;
+    border: 1px solid #aaa;
+    padding: 3px 7px;
+    color: #111;
+    text-decoration: none;
+    background: #ddd;
+
+    border-radius: 12px;
+    -webkit-border-radius: 12px;
+    -moz-border-radius: 12px;
+
+    text-shadow: 0 1px 0 #fff;
+
+    <?php echo $_SESSION['PMA_Theme']->getCssGradient('ffffff', 'cccccc'); ?>
+}
+
+input[type=submit]:hover,
+button[type=submit]:not(.mult_submit):hover,
+input[type=reset]:hover,
+input[name=submit_reset]:hover,
+input.button:hover {
+    position: relative;
+    <?php echo $_SESSION['PMA_Theme']->getCssGradient('cccccc', 'dddddd'); ?>
+    cursor: pointer;
+}
+
+input[type=submit]:active,
+button[type=submit]:not(.mult_submit):active,
+input[type=reset]:active,
+input[name=submit_reset]:active,
+input.button:active {
+    position: relative;
+    top: 1px;
+    left: 1px;
+}
+
+textarea {
+    overflow: visible;
+    height: <?php echo ceil($GLOBALS['cfg']['TextareaRows'] * 1.2); ?>em;
+}
+
+textarea.char {
+    height: <?php echo ceil($GLOBALS['cfg']['CharTextareaRows'] * 1.2); ?>em;
+}
+
+fieldset {
+    margin-top: 1em;
+    border-radius: 4px 4px 0 0;
+    -moz-border-radius: 4px 4px 0 0;
+    -webkit-border-radius: 4px 4px 0 0;
+    border: #aaa solid 1px;
+    padding: 1.5em;
+    background: #eee;
+    text-shadow: <?php echo $GLOBALS['text_dir'] === 'rtl' ? '-' : ''; ?>1px 1px 2px #fff inset;
+    -moz-box-shadow: <?php echo $GLOBALS['text_dir'] === 'rtl' ? '-' : ''; ?>1px 1px 2px #fff inset;
+    -webkit-box-shadow: <?php echo $GLOBALS['text_dir'] === 'rtl' ? '-' : ''; ?>1px 1px 2px #fff inset;
+    box-shadow: <?php echo $GLOBALS['text_dir'] === 'rtl' ? '-' : ''; ?>1px 1px 2px #fff inset;
+}
+
+fieldset fieldset {
+    margin: .8em;
+    background: #fff;
+    border: 1px solid #aaa;
+    background: #E8E8E8;
+
+}
+
+fieldset legend {
+    font-weight: bold;
+    color: #444;
+    padding: 5px 10px;
+    border-radius: 2px;
+    -moz-border-radius: 2px;
+    -webkit-border-radius: 2px;
+    border: 1px solid #aaa;
+    background-color: #fff;
+    -moz-box-shadow: <?php echo $GLOBALS['text_dir'] === 'rtl' ? '-' : ''; ?>3px 3px 15px #bbb;
+    -webkit-box-shadow: <?php echo $GLOBALS['text_dir'] === 'rtl' ? '-' : ''; ?>3px 3px 15px #bbb;
+    box-shadow: <?php echo $GLOBALS['text_dir'] === 'rtl' ? '-' : ''; ?>3px 3px 15px #bbb;
+}
+
+.some-margin {
+    margin: 1.5em;
+}
+
+/* buttons in some browsers (eg. Konqueror) are block elements,
+   this breaks design */
+button {
+    display: inline;
+}
+
+table caption,
+table th,
+table td {
+    padding: .3em;
+    margin: .1em;
+    vertical-align: top;
+    text-shadow: 0 1px 0 #fff;
+}
+
+/* 3.4 */
+table {
+    border-collapse: collapse;
+}
+
+th {
+    border-right: 1px solid #fff;
+    text-align: left;
+}
+
+
+img,
+button {
+    vertical-align: middle;
+}
+
+input[type="checkbox"],
+input[type="radio"] {
+    vertical-align: -11%;
+}
+
+
+select {
+    -moz-border-radius: 2px;
+    -webkit-border-radius: 2px;
+    border-radius: 2px;
+
+    -moz-box-shadow: 0 1px 2px #ddd;
+    -webkit-box-shadow: 0 1px 2px #ddd;
+    box-shadow: 0 1px 2px #ddd;
+
+    border: 1px solid #aaa;
+    color: #333;
+    padding: 3px;
+    background: white;
+}
+
+select[multiple] {
+    <?php echo $_SESSION['PMA_Theme']->getCssGradient('ffffff', 'f2f2f2'); ?>
+}
+
+/******************************************************************************/
+/* classes */
+.clearfloat {
+    clear: both;
+}
+
+.floatleft {
+    float: <?php echo $left; ?>;
+    margin-<?php echo $right; ?>: 1em;
+}
+
+.floatright {
+    float: <?php echo $right; ?>;
+}
+
+.center {
+    text-align: center;
+}
+
+table.nospacing {
+    border-spacing: 0;
+}
+
+table.nopadding tr th, table.nopadding tr td {
+    padding: 0;
+}
+
+th.left, td.left {
+    text-align: left;
+}
+
+th.center, td.center {
+    text-align: center;
+}
+
+th.right, td.right {
+    text-align: right;
+}
+
+tr.vtop th, tr.vtop td, th.vtop, td.vtop {
+    vertical-align: top;
+}
+
+tr.vmiddle th, tr.vmiddle td, th.vmiddle, td.vmiddle {
+    vertical-align: middle;
+}
+
+tr.vbottom th, tr.vbottom td, th.vbottom, td.vbottom {
+    vertical-align: bottom;
+}
+
+.paddingtop {
+    padding-top: 1em;
+}
+
+.separator {
+    color: #fff;
+    text-shadow: 0 1px 0 #000;
+}
+
+div.tools {
+    /* border: 1px solid #000; */
+    padding: .2em;
+}
+
+div.tools a {
+    color: #3a7ead !important;
+}
+
+div.tools,
+fieldset.tblFooters {
+    margin-top: 0;
+    margin-bottom: .5em;
+    /* avoid a thick line since this should be used under another fieldset */
+    border-top: 0;
+    text-align: <?php echo $right; ?>;
+    float: none;
+    clear: both;
+    -webkit-border-radius: 0 0 4px 4px;
+    -moz-border-radius: 0 0 4px 4px;
+    border-radius: 0 0 4px 5px;
+}
+
+div.null_div {
+    height: 20px;
+    text-align: center;
+    font-style: normal;
+    min-width: 50px;
+}
+
+fieldset .formelement {
+    float: <?php echo $left; ?>;
+    margin-<?php echo $right; ?>: .5em;
+    /* IE */
+    white-space: nowrap;
+}
+
+/* revert for Gecko */
+fieldset div[class=formelement] {
+    white-space: normal;
+}
+
+button.mult_submit {
+    border: none;
+    background-color: transparent;
+}
+
+/* odd items 1,3,5,7,... */
+table tr.odd th,
+.odd {
+    background: #fff;
+    <?php echo $_SESSION['PMA_Theme']->getCssIEClearFilter(); ?>
+}
+
+/* even items 2,4,6,8,... */
+/* (tested on CRTs and ACLs) */
+table tr.even th,
+.even {
+    background: #DFDFDF;
+    <?php echo $_SESSION['PMA_Theme']->getCssIEClearFilter(); ?>
+}
+
+/* odd table rows 1,3,5,7,... */
+table tr.odd th,
+table tr.odd,
+table tr.even th,
+table tr.even {
+    text-align: <?php echo $left; ?>;
+}
+
+<?php if ($GLOBALS['cfg']['BrowseMarkerEnable']) { ?>
+/* marked table rows */
+td.marked,
+table tr.marked td,
+table tr.marked th,
+table tr.marked {
+    <?php echo $_SESSION['PMA_Theme']->getCssGradient('ced6df', 'b6c6d7'); ?>
+    color: <?php echo $GLOBALS['cfg']['BrowseMarkerColor']; ?>;
+}
+<?php } ?>
+
+<?php if ($GLOBALS['cfg']['BrowsePointerEnable']) { ?>
+/* hovered items */
+.odd:hover,
+.even:hover,
+.hover {
+    <?php echo $_SESSION['PMA_Theme']->getCssGradient('ced6df', 'b6c6d7'); ?>
+    color: <?php echo $GLOBALS['cfg']['BrowsePointerColor']; ?>;
+}
+
+/* hovered table rows */
+table tr.odd:hover th,
+table tr.even:hover th,
+table tr.hover th {
+    <?php echo $_SESSION['PMA_Theme']->getCssGradient('ced6df', 'b6c6d7'); ?>
+    color: <?php echo $GLOBALS['cfg']['BrowsePointerColor']; ?>;
+}
+<?php } ?>
+
+/**
+ * marks table rows/cells if the db field is in a where condition
+ */
+.condition {
+    border-color: <?php echo $GLOBALS['cfg']['BrowseMarkerBackground']; ?> !important;
+}
+
+th.condition {
+    border-width: 1px 1px 0 1px;
+    border-style: solid;
+}
+
+td.condition {
+    border-width: 0 1px 0 1px;
+    border-style: solid;
+}
+
+tr:last-child td.condition {
+    border-width: 0 1px 1px 1px;
+}
+
+<?php if ($GLOBALS['text_dir'] === 'ltr') { ?>
+/* for first th which must have right border set (ltr only) */
+.before-condition {
+    border-right: 1px solid <?php echo $GLOBALS['cfg']['BrowseMarkerBackground']; ?>;
+}
+<?php } ?>
+
+/**
+ * cells with the value NULL
+ */
+td.null {
+    font-style: italic;
+    text-align: <?php echo $right; ?>;
+}
+
+table .valueHeader {
+    text-align: <?php echo $right; ?>;
+    white-space: normal;
+}
+table .value {
+    text-align: <?php echo $right; ?>;
+    white-space: normal;
+}
+/* IE doesnt handles 'pre' right */
+table [class=value] {
+    white-space: normal;
+}
+
+
+<?php if (! empty($GLOBALS['cfg']['FontFamilyFixed'])) { ?>
+.value {
+    font-family: <?php echo $GLOBALS['cfg']['FontFamilyFixed']; ?>;
+}
+<?php } ?>
+.attention {
+    color: red;
+    font-weight: bold;
+}
+.allfine {
+    color: green;
+}
+
+
+img.lightbulb {
+    cursor: pointer;
+}
+
+.pdflayout {
+    overflow: hidden;
+    clip: inherit;
+    background-color: #fff;
+    display: none;
+    border: 1px solid #000;
+    position: relative;
+}
+
+.pdflayout_table {
+    background: #D3DCE3;
+    color: #000;
+    overflow: hidden;
+    clip: inherit;
+    z-index: 2;
+    display: inline;
+    visibility: inherit;
+    cursor: move;
+    position: absolute;
+    font-size: 80%;
+    border: 1px dashed #000;
+}
+
+/* MySQL Parser */
+.syntax {
+    font-family: Verdana, 'Segoe UI', Arial, Tahoma;
+    font-size: 110%;
+}
+
+.syntax a {
+    text-decoration: none;
+    border-bottom: 1px dotted #000;
+}
+
+.syntax_comment {
+    padding-left: 4pt;
+    padding-right: 4pt;
+}
+
+.syntax_digit {
+}
+
+.syntax_digit_hex {
+}
+
+.syntax_digit_integer {
+}
+
+.syntax_digit_float {
+}
+
+.syntax_punct {
+}
+
+.syntax_alpha {
+}
+
+.syntax_alpha_columnType {
+    text-transform: uppercase;
+}
+
+.syntax_alpha_columnAttrib {
+    text-transform: uppercase;
+}
+
+.syntax_alpha_reservedWord {
+    text-transform: uppercase;
+    font-weight: bold;
+}
+
+.syntax_alpha_functionName {
+    text-transform: uppercase;
+}
+
+.syntax_alpha_identifier {
+}
+
+.syntax_alpha_charset {
+}
+
+.syntax_alpha_variable {
+}
+
+.syntax_quote {
+    white-space: pre;
+}
+
+.syntax_quote_backtick {
+}
+
+/* no extra space in table cells */
+td .icon {
+    margin: 0;
+}
+
+.selectallarrow {
+    margin-<?php echo $right; ?>: .3em;
+    margin-<?php echo $left; ?>: .6em;
+}
+
+/* message boxes: error, confirmation */
+#pma_errors {
+    padding: 0 0.5em;
+}
+
+.success h1,
+.notice h1,
+div.error h1 {
+    border-bottom: 2px solid;
+    font-weight: bold;
+    text-align: <?php echo $left; ?>;
+    margin: 0 0 .2em 0;
+}
+
+div.success,
+div.notice,
+div.error {
+    margin: .5em 0 1.3em;
+    border: 1px solid;
+    background-repeat: no-repeat;
+        <?php if ($GLOBALS['text_dir'] === 'ltr') { ?>
+    background-position: 10px 50%;
+    padding: 10px 10px 10px 10px;
+        <?php } else { ?>
+    background-position: 99% 50%;
+    padding: 10px 35px 10px 10px;
+        <?php } ?>
+
+    -moz-border-radius: 5px;
+    -webkit-border-radius: 5px;
+    border-radius: 5px;
+
+    -moz-box-shadow: 0 1px 1px #fff inset;
+    -webkit-box-shadow: 0 1px 1px #fff inset;
+    box-shadow: 0 1px 1px #fff inset;
+}
+
+.success a,
+.notice a,
+.error a {
+    text-decoration: underline;
+}
+
+.success {
+    color: #000;
+    background-color: #ebf8a4;
+}
+
+h1.success,
+div.success {
+    border-color: #a2d246;    
+}
+.success h1 {
+    border-color: #00FF00;
+}
+
+.notice {
+    color: #000;
+    background-color: #e8eef1;
+}
+
+h1.notice,
+div.notice {
+    border-color: #3a6c7e;
+}
+
+.notice h1 {
+    border-color: #ffb10a;
+}
+
+.error {
+    border: 1px solid maroon !important;
+    color: #000;
+    background: pink;
+}
+
+h1.error,
+div.error {
+    border-color: #333; 
+}
+
+div.error h1 {
+    border-color: #ff0000;
+}
+
+.confirmation {
+    color: #000;
+    background-color: pink;
+}
+
+fieldset.confirmation {
+}
+
+fieldset.confirmation legend {
+}
+
+/* end messageboxes */
+
+.tblcomment {
+    font-size: 70%;
+    font-weight: normal;
+    color: #000099;
+}
+
+.tblHeaders {
+    font-weight: bold;
+    color: <?php echo $GLOBALS['cfg']['ThColor']; ?>;
+    background: <?php echo $GLOBALS['cfg']['ThBackground']; ?>;
+}
+
+div.tools,
+.tblFooters {
+    font-weight: normal;
+    color: <?php echo $GLOBALS['cfg']['ThColor']; ?>;
+    background: <?php echo $GLOBALS['cfg']['ThBackground']; ?>;
+}
+
+.tblHeaders a:link,
+.tblHeaders a:active,
+.tblHeaders a:visited,
+div.tools a:link,
+div.tools a:visited,
+div.tools a:active,
+.tblFooters a:link,
+.tblFooters a:active,
+.tblFooters a:visited {
+    color: #0000FF;
+}
+
+.tblHeaders a:hover,
+div.tools a:hover,
+.tblFooters a:hover {
+    color: #FF0000;
+}
+
+/* forbidden, no privileges */
+.noPrivileges {
+    color: #FF0000;
+    font-weight: bold;
+}
+
+/* disabled text */
+.disabled,
+.disabled a:link,
+.disabled a:active,
+.disabled a:visited {
+    color: #666;
+}
+
+.disabled a:hover {
+    color: #666;
+    text-decoration: none;
+}
+
+tr.disabled td,
+td.disabled {
+    background-color: #f3f3f3;
+    color: #aaa;
+}
+
+.nowrap {
+    white-space: nowrap;
+}
+
+/**
+ * login form
+ */
+body#loginform h1,
+body#loginform a.logo {
+    display: block;
+    text-align: center;
+}
+
+body#loginform {
+    margin-top: 1em;
+    text-align: center;
+}
+
+body#loginform div.container {
+    text-align: <?php echo $left; ?>;
+    width: 30em;
+    margin: 0 auto;
+}
+
+form.login label {
+    float: <?php echo $left; ?>;
+    width: 10em;
+    font-weight: bolder;
+}
+
+.commented_column {
+    border-bottom: 1px dashed #000;
+}
+
+.column_attribute {
+    font-size: 70%;
+}
+
+/******************************************************************************/
+/* specific elements */
+
+/* topmenu */
+#topmenu a {
+    text-shadow: 0 1px 0 #fff;
+}
+
+#topmenu .error {
+    background: #eee;border: 0 !important;color: #aaa;
+}
+
+ul#topmenu,
+ul#topmenu2,
+ul.tabs {
+    font-weight: bold;
+    list-style-type: none;
+    margin: 0;
+    padding: 0;
+
+}
+
+ul#topmenu2 {
+    margin: .25em .5em 0;
+    height: 2em;
+    clear: both;
+}
+
+ul#topmenu li,
+ul#topmenu2 li {
+    float: <?php echo $left; ?>;
+    margin: 0;
+    vertical-align: middle;
+}
+
+#topmenu img,
+#topmenu2 img {
+    margin-right: .5em;
+    vertical-align: -3px;
+}
+
+.menucontainer {
+    <?php echo $_SESSION['PMA_Theme']->getCssGradient('ffffff', 'dcdcdc'); ?>
+    border-top: 1px solid #aaa;
+}
+
+/* default tab styles */
+.tabactive {
+    background: #fff !important;
+}
+
+ul#topmenu2 a {
+    display: block;
+    margin: 7px 6px 7px;
+    margin-<?php echo $left; ?>: 0;
+    padding: 4px 10px;
+    white-space: nowrap;
+    border: 1px solid #ddd;
+    border-radius: 20px;
+    -moz-border-radius: 20px;
+    -webkit-border-radius: 20px;
+    background: #f2f2f2;
+
+}
+
+fieldset.caution a {
+    color: #FF0000;
+}
+fieldset.caution a:hover {
+    color: #fff;
+    background-color: #FF0000;
+}
+
+#topmenu {
+    margin-top: .5em;
+    padding: .1em .3em;
+}
+
+ul#topmenu ul {
+    -moz-box-shadow: <?php echo $GLOBALS['text_dir'] === 'rtl' ? '-' : ''; ?>1px 1px 6px #ddd;
+    -webkit-box-shadow: <?php echo $GLOBALS['text_dir'] === 'rtl' ? '-' : ''; ?>2px 2px 3px #666;
+    box-shadow: <?php echo $GLOBALS['text_dir'] === 'rtl' ? '-' : ''; ?>2px 2px 3px #666;
+}
+
+ul#topmenu ul.only {
+    <?php echo $left; ?>: 0;
+}
+
+ul#topmenu > li {
+    border-right: 1px solid #fff;
+    border-left: 1px solid #ccc;
+}
+
+/* default tab styles */
+ul#topmenu a,
+ul#topmenu span {
+    padding: .6em;
+}
+
+ul#topmenu ul a {
+    border-width: 1pt 0 0 0;
+    -moz-border-radius: 0;
+    -webkit-border-radius: 0;
+    border-radius: 0;
+}
+
+ul#topmenu ul li:first-child a {
+    border-width: 0;
+}
+
+/* enabled hover/active tabs */
+ul#topmenu > li > a:hover,
+ul#topmenu > li > .tabactive {
+    text-decoration: none;
+}
+
+ul#topmenu ul a:hover,
+ul#topmenu ul .tabactive {
+    text-decoration: none;
+}
+
+ul#topmenu a.tab:hover,
+ul#topmenu .tabactive {
+    /* background-color: <?php echo $GLOBALS['cfg']['MainBackground']; ?>;  */
+}
+
+ul#topmenu2 a.tab:hover,
+ul#topmenu2 a.tabactive {
+    background-color: <?php echo $GLOBALS['cfg']['BgOne']; ?>;
+    border-radius: .3em;
+    -moz-border-radius: .3em;
+    -webkit-border-radius: .3em;
+    text-decoration: none;
+}
+
+/* to be able to cancel the bottom border, use <li class="active"> */
+ul#topmenu > li.active {
+    /* border-bottom: 0pt solid <?php echo $GLOBALS['cfg']['MainBackground']; ?>; */
+    border-right: 0;
+}
+/* end topmenu */
+
+/* zoom search */
+div#dataDisplay input,
+div#dataDisplay select {
+    margin: 0;
+    margin-<?php echo $right; ?>: .5em;
+}
+div#dataDisplay th {
+    line-height: 2em;
+}
+
+/* Calendar */
+table.calendar {
+    width: 100%;
+}
+table.calendar td {
+    text-align: center;
+}
+table.calendar td a {
+    display: block;
+}
+
+table.calendar td a:hover {
+    background-color: #CCFFCC;
+}
+
+table.calendar th {
+    background-color: #D3DCE3;
+}
+
+table.calendar td.selected {
+    background-color: #FFCC99;
+}
+
+img.calendar {
+    border: none;
+}
+form.clock {
+    text-align: center;
+}
+/* end Calendar */
+
+
+/* table stats */
+div#tablestatistics table {
+    float: <?php echo $left; ?>;
+    margin-bottom: .5em;
+    margin-<?php echo $right; ?>: 1.5em;
+    margin-top: .5em;
+}
+
+/* END table stats */
+
+
+/* server privileges */
+#tableuserrights td,
+#tablespecificuserrights td,
+#tabledatabases td {
+    vertical-align: middle;
+}
+/* END server privileges */
+
+
+/* Heading */
+#topmenucontainer {
+    padding-<?php echo $right; ?>: 1em;
+    width: 100%;
+}
+
+#serverinfo {
+    border-bottom: 1px solid #fff;
+    background: #888;
+    padding: .3em .9em;
+    padding-<?php echo $left; ?>: 2.2em;
+    text-shadow: 0 1px 0 #000;
+    width: 10000px;
+    overflow: hidden;
+}
+
+#serverinfo .item {
+    white-space: nowrap;
+    color: #fff;
+    float: <?php echo $left; ?>
+}
+
+#goto_pagetop {
+    position: fixed;
+    padding: .25em .25em .2em;
+    top: 0;
+    <?php echo $right; ?>: 0;
+    z-index: 900;
+    background: #888;
+}
+
+#span_table_comment {
+    font-weight: normal;
+    font-style: italic;
+    white-space: nowrap;
+}
+
+#serverinfo img {
+    margin: 0 .1em 0;
+    margin-<?php echo $left; ?>: .2em;
+}
+
+
+#textSQLDUMP {
+    width: 95%;
+    height: 95%;
+    font-family: Consolas, "Courier New", Courier, mono;
+    font-size: 110%;
+}
+
+#TooltipContainer {
+    position: absolute;
+    z-index: 99;
+    width: 20em;
+    height: auto;
+    overflow: visible;
+    visibility: hidden;
+    background-color: #ffffcc;
+    color: #006600;
+    border: .1em solid #000;
+    padding: .5em;
+}
+
+/* user privileges */
+#fieldset_add_user_login div.item {
+    border-bottom: 1px solid silver;
+    padding-bottom: .3em;
+    margin-bottom: .3em;
+}
+
+#fieldset_add_user_login label {
+    float: <?php echo $left; ?>;
+    display: block;
+    width: 10em;
+    max-width: 100%;
+    text-align: <?php echo $right; ?>;
+    padding-<?php echo $right; ?>: .5em;
+}
+
+#fieldset_add_user_login span.options #select_pred_username,
+#fieldset_add_user_login span.options #select_pred_hostname,
+#fieldset_add_user_login span.options #select_pred_password {
+    width: 100%;
+    max-width: 100%;
+}
+
+#fieldset_add_user_login span.options {
+    float: <?php echo $left; ?>;
+    display: block;
+    width: 12em;
+    max-width: 100%;
+    padding-<?php echo $right; ?>: .5em;
+}
+
+#fieldset_add_user_login input {
+    width: 12em;
+    clear: <?php echo $right; ?>;
+    max-width: 100%;
+}
+
+#fieldset_add_user_login span.options input {
+    width: auto;
+}
+
+#fieldset_user_priv div.item {
+    float: <?php echo $left; ?>;
+    width: 9em;
+    max-width: 100%;
+}
+
+#fieldset_user_priv div.item div.item {
+    float: none;
+}
+
+#fieldset_user_priv div.item label {
+    white-space: nowrap;
+}
+
+#fieldset_user_priv div.item select {
+    width: 100%;
+}
+
+#fieldset_user_global_rights fieldset {
+    float: <?php echo $left; ?>;
+}
+/* END user privileges */
+
+
+/* serverstatus */
+
+.linkElem:hover {
+    text-decoration: underline;
+    color: #235a81;
+    cursor: pointer;
+}
+
+h3#serverstatusqueries span {
+    font-size: 60%;
+    display: inline;
+}
+
+img.sortableIcon {
+    float: <?php echo $right; ?>;
+    background-repeat: no-repeat;
+    margin: 0;
+}
+
+.buttonlinks {
+    float: <?php echo $right; ?>;
+    white-space: nowrap;
+}
+
+/* Also used for the variables page */
+fieldset#tableFilter {
+    margin-bottom: 1em;
+}
+
+div#serverStatusTabs {
+    margin-top: 1em;
+}
+
+caption a.top {
+    float: <?php echo $right; ?>;
+}
+
+div#serverstatusquerieschart {
+    float: <?php echo $left; ?>;
+    width: 500px;
+    height: 350px;
+    padding-<?php echo $left; ?>: 30px;
+}
+
+table#serverstatusqueriesdetails,
+table#serverstatustraffic {
+    float: <?php echo $left; ?>;
+}
+
+table#serverstatusqueriesdetails th {
+    min-width: 35px;
+}
+
+table#serverstatusvariables {
+    width: 100%;
+    margin-bottom: 1em;
+}
+table#serverstatusvariables .name {
+    width: 18em;
+    white-space: nowrap;
+}
+table#serverstatusvariables .value {
+    width: 6em;
+}
+table#serverstatusconnections {
+    float: <?php echo $left; ?>;
+    margin-<?php echo $left; ?>: 30px;
+}
+
+div#serverstatus table tbody td.descr a,
+div#serverstatus table .tblFooters a {
+    white-space: nowrap;
+}
+
+div.liveChart {
+    clear: both;
+    min-width: 500px;
+    height: 400px;
+    padding-bottom: 80px;
+}
+
+#addChartDialog input[type="text"] {
+    margin: 0;
+    padding: 3px;
+}
+
+div#chartVariableSettings {
+    border: 1px solid #ddd;
+    background-color: #E6E6E6;
+    margin-left: 10px;
+}
+
+table#chartGrid div.monitorChart {
+    background: #EBEBEB;
+}
+
+div#serverstatus div.tabLinks {
+    float: <?php echo $left; ?>;
+    padding-bottom: 10px;
+}
+
+.popupContent {
+    display: none;
+    position: absolute;
+    border: 1px solid #CCC;
+    margin: 0;
+    padding: 3px;
+    -moz-box-shadow: <?php echo $GLOBALS['text_dir'] === 'rtl' ? '-' : ''; ?>2px 2px 3px #666;
+    -webkit-box-shadow: <?php echo $GLOBALS['text_dir'] === 'rtl' ? '-' : ''; ?>2px 2px 3px #666;
+    box-shadow: <?php echo $GLOBALS['text_dir'] === 'rtl' ? '-' : ''; ?>2px 2px 3px #666;
+    background-color: #fff;
+    z-index: 2;
+}
+
+div#logTable {
+    padding-top: 10px;
+    clear: both;
+}
+
+div#logTable table {
+    width: 100%;
+}
+
+div#queryAnalyzerDialog {
+    min-width: 700px;
+}
+
+div#queryAnalyzerDialog div.CodeMirror-scroll {
+    height: auto;
+}
+
+div#queryAnalyzerDialog div#queryProfiling {
+    height: 300px;
+}
+
+div#queryAnalyzerDialog td.explain {
+    width: 250px;
+}
+
+div#queryAnalyzerDialog table.queryNums {
+    display: none;
+    border: 0;
+    text-align: left;
+}
+
+.smallIndent {
+    padding-<?php echo $left; ?>: 7px;
+}
+
+/* end serverstatus */
+
+/* server variables */
+#serverVariables {
+    min-width: 30em;
+}
+#serverVariables .var-row > div {
+    white-space: nowrap;
+    overflow: hidden;
+    text-overflow: ellipsis;
+    line-height: 2em;
+}
+#serverVariables .var-header {
+    color: <?php echo $GLOBALS['cfg']['ThColor']; ?>;
+    background: #f3f3f3;
+    <?php echo $_SESSION['PMA_Theme']->getCssGradient('ffffff', 'cccccc'); ?>
+    font-weight: bold;
+}
+#serverVariables .var-header .var-value {
+    text-align: <?php echo $left; ?>;
+}
+#serverVariables .var-row {
+    padding: 0.5em;
+    min-height: 18px;
+}
+#serverVariables .var-name {
+    width: 45%;
+    float: <?php echo $left; ?>;
+    font-weight: bold;
+}
+#serverVariables .var-name.session {
+    font-weight: normal;
+    font-style: italic;
+}
+#serverVariables .var-value {
+    width: 50%;
+    float: <?php echo $right; ?>;
+    text-align: <?php echo $right; ?>;
+}
+#serverVariables .var-doc {
+    overflow:visible;
+    float: <?php echo $right; ?>;
+}
+
+/* server variables editor */
+#serverVariables .editLink {
+    padding-<?php echo $right; ?>: 1em;
+    float: <?php echo $left; ?>;
+    font-family: sans-serif;
+}
+#serverVariables .serverVariableEditor {
+    width: 100%;
+    overflow: hidden;
+}
+#serverVariables .serverVariableEditor input {
+    width: 100%;
+    margin: 0 0.5em;
+    box-sizing: border-box;
+    -ms-box-sizing: border-box;
+    -moz-box-sizing: border-box;
+    -webkit-box-sizing: border-box;
+    height: 2.2em;
+}
+#serverVariables .serverVariableEditor div {
+    display: block;
+    overflow: hidden;
+    padding-<?php echo $right; ?>: 1em;
+}
+#serverVariables .serverVariableEditor a {
+    float: <?php echo $right; ?>;
+    margin: 0 0.5em;
+    line-height: 2em;
+}
+/* end server variables */
+
+
+p.notice {
+    margin: 1.5em 0;
+    border: 1px solid #000;
+    background-repeat: no-repeat;
+        <?php if ($GLOBALS['text_dir'] === 'ltr') { ?>
+    background-position: 10px 50%;
+    padding: 10px 10px 10px 25px;
+        <?php } else { ?>
+    background-position: 99% 50%;
+    padding: 25px 10px 10px 10px
+        <?php } ?>
+    -moz-border-radius: 5px;
+    -webkit-border-radius: 5px;
+    border-radius: 5px;
+    -moz-box-shadow: 0 1px 2px #fff inset;
+    -webkit-box-shadow: 0 1px 2px #fff inset;
+    box-shadow: 0 1px 2px #fff; inset;
+    background: #555;
+    color: #d4fb6a;
+}
+
+p.notice a {
+    color: #fff;
+    text-decoration: underline;
+}
+
+/* querywindow */
+body#bodyquerywindow {
+    margin: 0;
+    padding: 0;
+    background-image: none;
+    background-color: #F5F5F5;
+}
+
+div#querywindowcontainer {
+    margin: 0;
+    padding: 0;
+    width: 100%;
+}
+
+div#querywindowcontainer fieldset {
+    margin-top: 0;
+}
+/* END querywindow */
+
+/* profiling */
+
+div#profilingchart {
+    width: 550px;
+    height: 370px;
+    float: <?php echo $left; ?>;
+}
+
+/* END profiling */
+
+/* table charting */
+
+#resizer {
+    border: 1px solid silver;
+}
+#inner-resizer { /* make room for the resize handle */
+    padding: 10px;
+}
+
+/* END table charting */
+
+/* querybox */
+
+#togglequerybox {
+    margin: 0 10px;
+}
+
+#serverstatus h3
+{
+    margin: 15px 0;
+    font-weight: normal;
+    color: #999;
+    font-size: 1.7em;
+}
+#sectionlinks {
+    padding: 16px;
+    background: #f3f3f3;
+    border: 1px solid #aaa;
+    border-radius: 5px;
+    -webkit-border-radius: 5px;
+    -moz-border-radius: 5px;
+    box-shadow: 0 1px 1px #fff inset;
+    -webkit-box-shadow: 0 1px 1px #fff inset;
+    -moz-box-shadow: 0 1px 1px #fff inset;
+}
+#sectionlinks a,
+.buttonlinks a,
+a.button {
+    font-size: .88em;
+    font-weight: bold;
+    text-shadow: 0 1px 0 #fff;
+    line-height: 35px;
+    margin-<?php echo $left; ?>: 7px;
+    border: 1px solid #aaa;
+    padding: 5px 10px;
+    color: #111;
+    text-decoration: none;
+    background: #ddd;
+    white-space: nowrap;
+    border-radius: 20px;
+    -webkit-border-radius: 20px;
+    -moz-border-radius: 20px;
+    box-shadow: <?php echo $GLOBALS['text_dir'] === 'rtl' ? '-' : ''; ?>1px 1px 2px rgba(0,0,0,.5);
+    /*
+    -webkit-box-shadow: <?php echo $GLOBALS['text_dir'] === 'rtl' ? '-' : ''; ?>1px 1px 2px rgba(0,0,0,.5);
+    -moz-box-shadow: <?php echo $GLOBALS['text_dir'] === 'rtl' ? '-' : ''; ?>1px 1px 2px rgba(0,0,0,.5);
+    text-shadow: #fff 0 1px 0;
+    */
+    <?php echo $_SESSION['PMA_Theme']->getCssGradient('ffffff', 'cccccc'); ?>
+}
+#sectionlinks a:hover,
+.buttonlinks a:hover,
+a.button:hover {
+    <?php echo $_SESSION['PMA_Theme']->getCssGradient('cccccc', 'dddddd'); ?>
+}
+
+div#sqlquerycontainer {
+    float: <?php echo $left; ?>;
+    width: 69%;
+    /* height: 15em; */
+}
+
+div#tablefieldscontainer {
+    float: <?php echo $right; ?>;
+    width: 29%;
+    /* height: 15em; */
+}
+
+div#tablefieldscontainer select {
+    width: 100%;
+    background: #fff;
+    /* height: 12em; */
+}
+
+textarea#sqlquery {
+    width: 100%;
+    /* height: 100%; */
+    -moz-border-radius: 4px;
+    -webkit-border-radius: 4px;
+    border-radius: 4px;
+    border: 1px solid #aaa;
+    padding: 5px;
+    font-family: inherit;
+}
+textarea#sql_query_edit {
+    height: 7em;
+    width: 95%;
+    display: block;
+}
+div#queryboxcontainer div#bookmarkoptions {
+    margin-top: .5em;
+}
+/* end querybox */
+
+/* main page */
+#maincontainer {
+    /* background-image: url(<?php echo $_SESSION['PMA_Theme']->getImgPath('logo_right.png');?>); */
+    /* background-position: <?php echo $right; ?> bottom; */
+    /* background-repeat: no-repeat; */
+}
+
+#mysqlmaininformation,
+#pmamaininformation {
+    float: <?php echo $left; ?>;
+    width: 49%;
+}
+
+#maincontainer ul {
+    list-style-type: disc;
+    vertical-align: middle;
+}
+
+#maincontainer li {
+    margin-bottom: .3em;
+}
+/* END main page */
+
+
+/* iconic view for ul items */
+
+li.no_bullets {
+    list-style-type:none !important;    
+    margin-left: -25px !important;      //align with other list items which have bullets
+}
+
+/* END iconic view for ul items */
+
+#body_browse_foreigners {
+    background: <?php echo $GLOBALS['cfg']['NaviBackground']; ?>;
+    margin: .5em .5em 0 .5em;
+}
+
+#bodyquerywindow {
+    background: <?php echo $GLOBALS['cfg']['NaviBackground']; ?>;
+}
+
+#bodythemes {
+    width: 500px;
+    margin: auto;
+    text-align: center;
+}
+
+#bodythemes img {
+    border: .1em solid #000;
+}
+
+#bodythemes a:hover img {
+    border: .1em solid red;
+}
+
+#fieldset_select_fields {
+    float: <?php echo $left; ?>;
+}
+
+#selflink {
+    clear: both;
+    display: block;
+    margin-top: 1em;
+    margin-bottom: 1em;
+    width: 98%;
+    margin-<?php echo $left; ?>: 1%;
+    border-top: .1em solid silver;
+    text-align: <?php echo $right; ?>;
+}
+
+#table_innodb_bufferpool_usage,
+#table_innodb_bufferpool_activity {
+    float: <?php echo $left; ?>;
+}
+
+#div_mysql_charset_collations table {
+    float: <?php echo $left; ?>;
+}
+
+.operations_half_width {
+    width: 48%;
+    float: <?php echo $left; ?>;
+}
+
+.operations_full_width {
+    width: 100%;
+    clear: both;
+}
+
+#qbe_div_table_list {
+    float: <?php echo $left; ?>;
+}
+
+#qbe_div_sql_query {
+    float: <?php echo $left; ?>;
+}
+
+label.desc {
+    width: 30em;
+    float: <?php echo $left; ?>;
+}
+
+label.desc sup {
+    position: absolute;
+}
+
+code.sql,
+div.sqlvalidate {
+    display: block;
+    padding: 1em;
+    margin-top: 0;
+    margin-bottom: 0;
+    max-height: 10em;
+    overflow: auto;
+    background: <?php echo $GLOBALS['cfg']['BgOne']; ?>;
+}
+
+#main_pane_left {
+    width: 60%;
+    float: <?php echo $left; ?>;
+    padding-top: 1em;
+}
+
+#main_pane_right {
+    margin-<?php echo $left; ?>: 60%;
+    padding-top: 1em;
+    padding-<?php echo $left; ?>: 1em;
+}
+
+.group {
+
+    border: 1px solid #999;
+    background: #f3f3f3;
+    -moz-border-radius: 4px;
+    -webkit-border-radius: 4px;
+    border-radius: 4px;
+    -moz-box-shadow: <?php echo $GLOBALS['text_dir'] === 'rtl' ? '-' : ''; ?>2px 2px 5px #ccc;
+    -webkit-box-shadow: <?php echo $GLOBALS['text_dir'] === 'rtl' ? '-' : ''; ?>2px 2px 5px #ccc;
+    box-shadow: <?php echo $GLOBALS['text_dir'] === 'rtl' ? '-' : ''; ?>2px 2px 5px #ccc;
+    margin-bottom: 1em;
+    padding-bottom: 1em;
+}
+
+.group h2 {
+    background-color: #bbb;
+    padding: .1em .3em;
+    margin-top: 0;
+    color: #fff;
+    font-size: 1.6em;
+    font-weight: normal;
+    text-shadow: 0 1px 0 #777;
+    -moz-box-shadow: <?php echo $GLOBALS['text_dir'] === 'rtl' ? '-' : ''; ?>1px 1px 15px #999 inset;
+    -webkit-box-shadow: <?php echo $GLOBALS['text_dir'] === 'rtl' ? '-' : ''; ?>1px 1px 15px #999 inset;
+    box-shadow: <?php echo $GLOBALS['text_dir'] === 'rtl' ? '-' : ''; ?>1px 1px 15px #999 inset;
+}
+
+.group-cnt {
+    padding: 0;
+    padding-<?php echo $left; ?>: .5em;
+    display: inline-block;
+    width: 98%;
+}
+
+textarea#partitiondefinition {
+    height: 3em;
+}
+
+
+/* for elements that should be revealed only via js */
+.hide {
+    display: none;
+}
+
+#list_server {
+    list-style-image: none;
+}
+
+/**
+  *  Progress bar styles
+  */
+div.upload_progress
+{
+    width: 400px;
+    margin: 3em auto;
+    text-align: center;
+}
+
+div.upload_progress_bar_outer
+{
+    border: 1px solid #000;
+    width: 202px;
+    position: relative;
+    margin: 0 auto 1em;
+    color: <?php echo $GLOBALS['cfg']['MainColor']; ?>;
+}
+
+div.upload_progress_bar_inner
+{
+    background-color: <?php echo $GLOBALS['cfg']['NaviBackground']; ?>;
+    width: 0;
+    height: 12px;
+    margin: 1px;
+    overflow: hidden;
+    color: <?php echo $GLOBALS['cfg']['BrowseMarkerColor']; ?>;
+    position: relative;
+}
+
+div.upload_progress_bar_outer div.percentage
+{
+    position: absolute;
+    top: 0;
+    <?php echo $left; ?>: 0;
+    width: 202px;
+}
+
+div.upload_progress_bar_inner div.percentage
+{
+    top: -1px;
+    <?php echo $left; ?>: -1px;
+}
+
+div#statustext {
+    margin-top: .5em;
+}
+
+table#serverconnection_src_remote,
+table#serverconnection_trg_remote,
+table#serverconnection_src_local,
+table#serverconnection_trg_local  {
+  float: <?php echo $left; ?>;
+}
+/**
+  *  Validation error message styles
+  */
+input[type=text].invalid_value,
+.invalid_value {
+    background: #FFCCCC;
+}
+
+/**
+  *  Ajax notification styling
+  */
+ .ajax_notification {
+    top: 0;           /** The notification needs to be shown on the top of the page */
+    position: fixed;
+    margin-top: 0;
+    margin-right: auto;
+    margin-bottom: 0;
+    margin-<?php echo $left; ?>: auto;
+    padding: 5px;   /** Keep a little space on the sides of the text */
+    width: 350px;
+
+    z-index: 1100;      /** If this is not kept at a high z-index, the jQueryUI modal dialogs (z-index: 1000) might hide this */
+    text-align: center;
+    display: inline;
+    left: 0;
+    right: 0;
+    background-image: url(<?php echo $_SESSION['PMA_Theme']->getImgPath('ajax_clock_small.gif');?>);
+    background-repeat: no-repeat;
+    background-position: 2%;
+    border: 1px solid #e2b709;
+ }
+
+/* additional styles */
+.ajax_notification {
+    margin-top: 200px;
+    background: #ffe57e;
+    border-radius: 5px;
+    -moz-border-radius: 5px;
+    -webkit-border-radius: 5px;
+    box-shadow: 0 5px 90px #888;
+    -moz-box-shadow: 0 5px 90px #888;
+    -webkit-box-shadow: 0 5px 90px #888;
+}
+
+#loading_parent {
+    /** Need this parent to properly center the notification division */
+    position: relative;
+    width: 100%;
+ }
+/**
+  * Export and Import styles
+  */
+
+.exportoptions h3,
+.importoptions h3 {
+    border-bottom: 1px #999 solid;
+    font-size: 110%;
+}
+
+.exportoptions ul,
+.importoptions ul,
+.format_specific_options ul {
+    list-style-type: none;
+    margin-bottom: 15px;
+}
+
+.exportoptions li,
+.importoptions li {
+    margin: 7px;
+}
+.exportoptions label,
+.importoptions label,
+.exportoptions p,
+.importoptions p {
+    margin: 5px;
+    float: none;
+}
+
+#csv_options label.desc,
+#ldi_options label.desc,
+#latex_options label.desc,
+#output label.desc {
+    float: <?php echo $left; ?>;
+    width: 15em;
+}
+
+.exportoptions,
+.importoptions {
+    margin: 20px 30px 30px;
+    margin-<?php echo $left; ?>: 10px;
+}
+
+.exportoptions #buttonGo,
+.importoptions #buttonGo {
+    font-weight: bold;
+    margin-<?php echo $left; ?>: 14px;
+    border: 1px solid #aaa;
+    padding: 5px 12px;
+    color: #111;
+    text-decoration: none;
+    background: #ddd;
+
+    border-radius: 12px;
+    -webkit-border-radius: 12px;
+    -moz-border-radius: 12px;
+
+    text-shadow: 0 1px 0 #fff;
+
+    <?php echo $_SESSION['PMA_Theme']->getCssGradient('ffffff', 'cccccc'); ?>
+    cursor: pointer;
+}
+#buttonGo:hover {
+    <?php echo $_SESSION['PMA_Theme']->getCssGradient('cccccc', 'dddddd'); ?>
+}
+
+.format_specific_options h3 {
+    margin: 10px 0 0;
+    margin-<?php echo $left; ?>: 10px;
+    border: 0;
+}
+
+.format_specific_options {
+    border: 1px solid #999;
+    margin: 7px 0;
+    padding: 3px;
+}
+
+p.desc {
+    margin: 5px;
+}
+
+/**
+  * Export styles only
+  */
+select#db_select,
+select#table_select {
+    width: 400px;
+}
+
+.export_sub_options {
+    margin: 20px 0 0;
+    margin-<?php echo $left; ?>: 30px;
+}
+
+.export_sub_options h4 {
+    border-bottom: 1px #999 solid;
+}
+
+.export_sub_options li.subgroup {
+    display: inline-block;
+    margin-top: 0;
+}
+
+.export_sub_options li {
+    margin-bottom: 0;
+}
+
+#quick_or_custom,
+#output_quick_export {
+    display: none;
+}
+/**
+ * Import styles only
+ */
+
+.importoptions #import_notification {
+    margin: 10px 0;
+    font-style: italic;
+}
+
+input#input_import_file {
+    margin: 5px;
+}
+
+.formelementrow {
+    margin: 5px 0 5px 0;
+}
+
+#popup_background {
+    display: none;
+    position: fixed;
+    _position: absolute; /* hack for IE6 */
+    width: 100%;
+    height: 100%;
+    top: 0;
+    <?php echo $left; ?>: 0;
+    background: #000;
+    z-index: 1000;
+    overflow: hidden;
+}
+
+/**
+ * Table structure styles
+ */
+#fieldsForm ul.table-structure-actions {
+    margin: 0;
+    padding: 0;
+    list-style: none;
+}
+#fieldsForm ul.table-structure-actions li {
+    float: <?php echo $left; ?>;
+    margin-<?php echo $right; ?>: 0.3em; /* same as padding of "table td" */
+}
+#fieldsForm ul.table-structure-actions .submenu li {
+    padding: 0;
+    margin: 0;
+}
+#fieldsForm ul.table-structure-actions .submenu li span {
+    padding: 0.3em;
+    margin: 0.1em;
+}
+/**
+ * Indexes
+ */
+#index_frm .index_info input,
+#index_frm .index_info select {
+    width: 14em;
+    box-sizing: border-box;
+    -ms-box-sizing: border-box;
+    -moz-box-sizing: border-box;
+    -webkit-box-sizing: border-box;
+}
+
+#index_frm .index_info div {
+    padding: .2em 0;
+}
+
+#index_frm .index_info .label {
+    float: <?php echo $left; ?>;
+    min-width: 12em;
+}
+
+#index_frm .slider {
+    width: 10em;
+    margin: .6em;
+    float: <?php echo $left; ?>;
+}
+
+#index_frm .add_fields {
+    float: <?php echo $left; ?>;
+}
+
+#index_frm .add_fields input {
+    margin-<?php echo $left; ?>: 1em;
+}
+
+#index_frm input {
+    margin: 0;
+}
+
+#index_frm td {
+    vertical-align: middle;
+}
+
+table#index_columns {
+    width: 100%;
+}
+
+table#index_columns select {
+    width: 100%;
+}
+
+#move_columns_dialog div {
+    padding: 1em;
+}
+
+#move_columns_dialog ul {
+    list-style: none;
+    margin: 0;
+    padding: 0;
+}
+
+#move_columns_dialog li {
+    background: <?php echo $GLOBALS['cfg']['ThBackground']; ?>;
+    border: 1px solid #aaa;
+    color: <?php echo $GLOBALS['cfg']['ThColor']; ?>;
+    font-weight: bold;
+    margin: .4em;
+    padding: .2em;
+    -webkit-border-radius: 2px;
+    -moz-border-radius: 2px;
+    border-radius: 2px;
+}
+
+.margin#change_column_dialog {
+    margin: 0 .5em;
+}
+
+/* config forms */
+.config-form ul.tabs {
+    margin: 1.1em .2em 0;
+    padding: 0 0 .3em 0;
+    list-style: none;
+    font-weight: bold;
+}
+
+.config-form ul.tabs li {
+    float: <?php echo $left; ?>;
+    margin-bottom: -1px;
+}
+
+.config-form ul.tabs li a {
+    display: block;
+    margin: .1em .2em 0;
+    white-space: nowrap;
+    text-decoration: none;
+    border: 1px solid <?php echo $GLOBALS['cfg']['BgTwo']; ?>;
+    border-bottom: 1px solid #aaa;
+}
+
+.config-form ul.tabs li a {
+    padding: 7px 10px;
+    -webkit-border-radius: 5px 5px 0 0;
+    -moz-border-radius: 5px 5px 0 0;
+    border-radius: 5px 5px 0 0;
+    background: #f2f2f2;
+    color: #555;
+    text-shadow: 0 1px 0 #fff;
+}
+
+.config-form ul.tabs li a:hover,
+.config-form ul.tabs li a:active {
+    background: #e5e5e5;
+}
+
+.config-form ul.tabs li.active a {
+    background-color: #fff;
+    margin-top: 1px;
+    color: #000;
+    text-shadow: none;
+    border-color: #aaa;
+    border-bottom: 1px solid #fff;
+}
+
+.config-form fieldset {
+    margin-top: 0;
+    padding: 0;
+    clear: both;
+    -webkit-border-radius: 0;
+    -moz-border-radius: 0;
+    border-radius: 0;
+}
+
+.config-form legend {
+    display: none;
+}
+
+.config-form fieldset p {
+    margin: 0;
+    padding: .5em;
+    background: #fff;
+    border-top: 0;
+}
+
+.config-form fieldset .errors { /* form error list */
+    margin: 0 -2px 1em;
+    padding: .5em 1.5em;
+    background: #FBEAD9;
+    border: 0 #C83838 solid;
+    border-width: 1px 0;
+    list-style: none;
+    font-family: sans-serif;
+    font-size: small;
+}
+
+.config-form fieldset .inline_errors { /* field error list */
+    margin: .3em .3em .3em;
+    margin-<?php echo $left; ?>: 0;
+    padding: 0;
+    list-style: none;
+    color: #9A0000;
+    font-size: small;
+}
+
+.config-form fieldset th {
+    padding: .3em .3em .3em;
+    padding-<?php echo $left; ?>: .5em;
+    text-align: <?php echo $left; ?>;
+    vertical-align: top;
+    width: 40%;
+    background: transparent;
+    filter: none;
+}
+
+.config-form fieldset .doc,
+.config-form fieldset .disabled-notice {
+    margin-<?php echo $left; ?>: 1em;
+}
+
+.config-form fieldset .disabled-notice {
+    font-size: 80%;
+    text-transform: uppercase;
+    color: #E00;
+    cursor: help;
+}
+
+.config-form fieldset td {
+    padding-top: .3em;
+    padding-bottom: .3em;
+    vertical-align: top;
+}
+
+.config-form fieldset th small {
+    display: block;
+    font-weight: normal;
+    font-family: sans-serif;
+    font-size: x-small;
+    color: #444;
+}
+
+.config-form fieldset th,
+.config-form fieldset td {
+    border-top: 1px <?php echo $GLOBALS['cfg']['BgTwo']; ?> solid;
+    border-<?php echo $right; ?>: none;
+}
+
+fieldset .group-header th {
+    background: <?php echo $GLOBALS['cfg']['BgTwo']; ?>;
+}
+
+fieldset .group-header + tr th {
+    padding-top: .6em;
+}
+
+fieldset .group-field-1 th,
+fieldset .group-header-2 th {
+    padding-<?php echo $left; ?>: 1.5em;
+}
+
+fieldset .group-field-2 th,
+fieldset .group-header-3 th {
+    padding-<?php echo $left; ?>: 3em;
+}
+
+fieldset .group-field-3 th {
+    padding-<?php echo $left; ?>: 4.5em;
+}
+
+fieldset .disabled-field th,
+fieldset .disabled-field th small,
+fieldset .disabled-field td {
+    color: #666;
+    background-color: #ddd;
+}
+
+.config-form .lastrow {
+    border-top: 1px #000 solid;
+}
+
+.config-form .lastrow {
+    background: <?php echo $GLOBALS['cfg']['ThBackground']; ?>;;
+    padding: .5em;
+    text-align: center;
+}
+
+.config-form .lastrow input {
+    font-weight: bold;
+}
+
+/* form elements */
+
+.config-form span.checkbox {
+    padding: 2px;
+    display: inline-block;
+}
+
+.config-form .custom { /* customized field */
+    background: #FFC;
+}
+
+.config-form span.checkbox.custom {
+    padding: 1px;
+    border: 1px #EDEC90 solid;
+    background: #FFC;
+}
+
+.config-form .field-error {
+    border-color: #A11 !important;
+}
+
+.config-form input[type="text"],
+.config-form select,
+.config-form textarea {
+    border: 1px #A7A6AA solid;
+    height: auto;
+}
+
+.config-form input[type="text"]:focus,
+.config-form select:focus,
+.config-form textarea:focus {
+    border: 1px #6676FF solid;
+    background: #F7FBFF;
+}
+
+.config-form .field-comment-mark {
+    font-family: serif;
+    color: #007;
+    cursor: help;
+    padding: 0 .2em;
+    font-weight: bold;
+    font-style: italic;
+}
+
+.config-form .field-comment-warning {
+    color: #A00;
+}
+
+/* error list */
+.config-form dd {
+    margin-<?php echo $left; ?>: .5em;
+}
+
+.config-form dd:before {
+    content: "\25B8  ";
+}
+
+.click-hide-message {
+    cursor: pointer;
+}
+
+.prefsmanage_opts {
+    margin-<?php echo $left; ?>: 2em;
+}
+
+#prefs_autoload {
+    margin-bottom: .5em;
+}
+
+#placeholder .button {
+    position: absolute;
+    cursor: pointer;
+}
+
+#placeholder div.button {
+    font-size: smaller;
+    color: #999;
+    background-color: #eee;
+    padding: 2px;
+}
+
+.wrapper {
+    float: <?php echo $left; ?>;
+    margin-bottom: 1.5em;
+}
+.toggleButton {
+    position: relative;
+    cursor: pointer;
+    font-size: .8em;
+    text-align: center;
+    line-height: 1.4em;
+    height: 1.55em;
+    overflow: hidden;
+    border-right: .1em solid #888;
+    border-left: .1em solid #888;
+    -webkit-border-radius: .3em;
+    -moz-border-radius: .3em;
+    border-radius: .3em;
+}
+.toggleButton table,
+.toggleButton td,
+.toggleButton img {
+    padding: 0;
+    position: relative;
+}
+.toggleButton .container {
+    position: absolute;
+}
+.toggleButton .toggleOn {
+    color: #fff;
+    padding: 0 1em;
+    text-shadow: 0 0 .2em #000;
+}
+.toggleButton .toggleOff {
+    padding: 0 1em;
+}
+
+.doubleFieldset fieldset {
+    width: 48%;
+    float: <?php echo $left; ?>;
+    padding: 0;
+}
+.doubleFieldset fieldset.left {
+    margin-<?php echo $right; ?>: 1%;
+}
+.doubleFieldset fieldset.right {
+    margin-<?php echo $left; ?>: 1%;
+}
+.doubleFieldset legend {
+    margin-<?php echo $left; ?>: 1.5em;
+}
+.doubleFieldset div.wrap {
+    padding: 1.5em;
+}
+
+#table_columns input[type="text"],
+#table_columns select {
+    width: 10em;
+    box-sizing: border-box;
+    -ms-box-sizing: border-box;
+    -moz-box-sizing: border-box;
+    -webkit-box-sizing: border-box;
+}
+
+#table_columns select {
+    margin: 0 6px;
+}
+
+#placeholder {
+    position: relative;
+    border: 1px solid #aaa;
+    float: <?php echo $right; ?>;
+    overflow: hidden;
+}
+
+.placeholderDrag {
+    cursor: move;
+}
+
+#placeholder .button {
+    position: absolute;
+}
+
+#left_arrow {
+    left: 8px;
+    top: 26px;
+}
+
+#right_arrow {
+    left: 26px;
+    top: 26px;
+}
+
+#up_arrow {
+    left: 17px;
+    top: 8px;
+}
+
+#down_arrow {
+    left: 17px;
+    top: 44px;
+}
+
+#zoom_in {
+    left: 17px;
+    top: 67px;
+}
+
+#zoom_world {
+    left: 17px;
+    top: 85px;
+}
+
+#zoom_out {
+    left: 17px;
+    top: 103px;
+}
+
+.colborder {
+    cursor: col-resize;
+    height: 100%;
+    margin-<?php echo $left; ?>: -6px;
+    position: absolute;
+    width: 5px;
+}
+
+.colborder_active {
+    border-<?php echo $right; ?>: 2px solid #a44;
+}
+
+.pma_table td {
+    position: static;
+}
+
+.pma_table th.draggable span,
+.pma_table tbody td span {
+    display: block;
+    overflow: hidden;
+}
+
+.modal-copy input {
+    display: block;
+    width: 100%;
+    margin-top: 1.5em;
+    padding: .3em 0;
+}
+
+.cRsz {
+    position: absolute;
+}
+
+.cCpy {
+    background: #333;
+    color: #FFF;
+    font-weight: bold;
+    margin: .1em;
+    padding: .3em;
+    position: absolute;
+    text-shadow: -1px -1px #000;
+
+    -moz-box-shadow: 0 0 .7em #000;
+    -webkit-box-shadow: 0 0 .7em #000;
+    box-shadow: 0 0 .7em #000;
+    -moz-border-radius: .3em;
+    -webkit-border-radius: .3em;
+    border-radius: .3em;
+}
+
+.cPointer {
+    background: url(<?php echo $_SESSION['PMA_Theme']->getImgPath('col_pointer.png');?>);
+    height: 20px;
+    margin-<?php echo $left; ?>: -5px;  /* must be minus half of its width */
+    margin-top: -10px;
+    position: absolute;
+    width: 10px;
+}
+
+.tooltip {
+    background: #333 !important;
+    opacity: .8 !important;
+    border: 1px solid #000 !important;
+    -moz-border-radius: .3em !important;
+    -webkit-border-radius: .3em !important;
+    border-radius: .3em !important;
+    text-shadow: -1px -1px #000 !important;
+    font-size: .8em !important;
+    font-weight: bold !important;
+    padding: 1px 3px !important;
+}
+
+.tooltip * {
+    background: none !important;
+    color: #FFF !important;
+}
+
+.cDrop {
+    left: 0;
+    position: absolute;
+    top: 0;
+}
+
+.coldrop {
+    background: url(<?php echo $_SESSION['PMA_Theme']->getImgPath('col_drop.png');?>);
+    cursor: pointer;
+    height: 16px;
+    margin-<?php echo $left; ?>: .3em;
+    margin-top: .3em;
+    position: absolute;
+    width: 16px;
+}
+
+.coldrop:hover,
+.coldrop-hover {
+    background-color: #999;
+}
+
+.cList {
+    background: #EEE;
+    border: solid 1px #999;
+    position: absolute;
+    -moz-box-shadow: 0 .2em .5em #333;
+    -webkit-box-shadow: 0 .2em .5em #333;
+    box-shadow: 0 .2em .5em #333;
+}
+
+.cList .lDiv div {
+    padding: .2em .5em .2em;
+    padding-<?php echo $left; ?>: .2em;
+}
+
+.cList .lDiv div:hover {
+    background: #DDD;
+    cursor: pointer;
+}
+
+.cList .lDiv div input {
+    cursor: pointer;
+}
+
+.showAllColBtn {
+    border-bottom: solid 1px #999;
+    border-top: solid 1px #999;
+    cursor: pointer;
+    font-size: .9em;
+    font-weight: bold;
+    padding: .35em 1em;
+    text-align: center;
+}
+
+.showAllColBtn:hover {
+    background: #DDD;
+}
+
+#page_content {
+    background-color: white;
+}
+
+.navigation {
+    margin: .8em 0;
+
+    border-radius: 5px;
+    -webkit-border-radius: 5px;
+    -moz-border-radius: 5px;
+
+    <?php echo $_SESSION['PMA_Theme']->getCssGradient('eeeeee', 'cccccc'); ?>
+}
+
+.navigation td {
+    margin: 0;
+    padding: 0;
+    vertical-align: middle;
+    white-space: nowrap;
+}
+
+.navigation_separator {
+    color: #999;
+    display: inline-block;
+    font-size: 1.5em;
+    text-align: center;
+    height: 1.4em;
+    width: 1.2em;
+    text-shadow: 1px 0 #FFF;
+}
+
+.navigation input[type=submit] {
+    background: none;
+    border: 0;
+    filter: none;
+    margin: 0;
+    padding: .8em .5em;
+
+    border-radius: 0;
+    -webkit-border-radius: 0;
+    -moz-border-radius: 0;
+}
+
+.navigation input[type=submit]:hover,
+.navigation input.edit_mode_active {
+    color: #fff;
+    cursor: pointer;
+    text-shadow: none;
+
+    <?php echo $_SESSION['PMA_Theme']->getCssGradient('333333', '555555'); ?>
+}
+
+.navigation select {
+    margin: 0 .8em;
+}
+
+.cEdit {
+    margin: 0;
+    padding: 0;
+    position: absolute;
+}
+
+.cEdit input[type=text] {
+    background: #FFF;
+    height: 100%;
+    margin: 0;
+    padding: 0;
+}
+
+.cEdit .edit_area {
+    background: #FFF;
+    border: 1px solid #999;
+    min-width: 10em;
+    padding: .3em .5em;
+}
+
+.cEdit .edit_area select,
+.cEdit .edit_area textarea {
+    width: 97%;
+}
+
+.cEdit .cell_edit_hint {
+    color: #555;
+    font-size: .8em;
+    margin: .3em .2em;
+}
+
+.cEdit .edit_box {
+    overflow: hidden;
+    padding: 0;
+}
+
+.cEdit .edit_box_posting {
+    background: #FFF url(<?php echo $_SESSION['PMA_Theme']->getImgPath('ajax_clock_small.gif');?>) no-repeat right center;
+    padding-<?php echo $right; ?>: 1.5em;
+}
+
+.cEdit .edit_area_loading {
+    background: #FFF url(<?php echo $_SESSION['PMA_Theme']->getImgPath('ajax_clock_small.gif');?>) no-repeat center;
+    height: 10em;
+}
+
+.cEdit .goto_link {
+    background: #EEE;
+    color: #555;
+    padding: .2em .3em;
+}
+
+.saving_edited_data {
+    background: url(<?php echo $_SESSION['PMA_Theme']->getImgPath('ajax_clock_small.gif');?>) no-repeat left;
+    padding-<?php echo $left; ?>: 20px;
+}
+
+/* css for timepicker */
+.ui-timepicker-div .ui-widget-header { margin-bottom: 8px; }
+.ui-timepicker-div dl { text-align: <?php echo $left; ?>; }
+.ui-timepicker-div dl dt { height: 25px; margin-bottom: -25px; }
+.ui-timepicker-div dl dd { margin: 0 10px 10px 65px; }
+.ui-timepicker-div td { font-size: 90%; }
+.ui-tpicker-grid-label { background: none; border: none; margin: 0; padding: 0; }
+.ui-timepicker-rtl { direction: rtl; }
+.ui-timepicker-rtl dl { text-align: right; }
+.ui-timepicker-rtl dl dd { margin: 0 65px 10px 10px; }
+
+input.btn {
+    color: #333;
+    background-color: #D0DCE0;
+}
+
+body .ui-widget {
+    font-size: 1em;
+}
+
+.ui-dialog fieldset legend a {
+    color: #235A81;
+}
+
diff --git a/phpmyadmin/themes/pmahomme/css/enum_editor.css.php b/phpmyadmin/themes/pmahomme/css/enum_editor.css.php
new file mode 100644
index 0000000..da9bc07
--- /dev/null
+++ b/phpmyadmin/themes/pmahomme/css/enum_editor.css.php
@@ -0,0 +1,80 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * ENUM editor styles for the pmahomme theme
+ *
+ * @package    PhpMyAdmin-theme
+ * @subpackage PMAHomme
+ */
+
+// unplanned execution path
+if (! defined('PMA_MINIMUM_COMMON') && ! defined('TESTSUITE')) {
+    exit();
+}
+?>
+
+/**
+ * ENUM/SET editor styles
+ */
+p.enum_notice {
+    margin: 5px 2px;
+    font-size: 80%;
+}
+
+#enum_editor p {
+    margin-top: 0;
+    font-style: italic;
+}
+
+#enum_editor .values,
+#enum_editor .add {
+    width: 100%;
+}
+
+#enum_editor .add td {
+    vertical-align: middle;
+    width: 50%;
+    padding: 0 0 0;
+    padding-<?php echo $left; ?>: 1em;
+}
+
+#enum_editor .values td.drop {
+    width: 1.8em;
+    cursor: pointer;
+    vertical-align: middle;
+}
+
+#enum_editor .values input {
+    margin: .1em 0;
+    padding-<?php echo $right; ?>: 2em;
+    width: 100%;
+}
+
+#enum_editor .values img {
+    width: 1.8em;
+    vertical-align: middle;
+}
+
+#enum_editor input.add_value {
+    margin: 0;
+    margin-<?php echo $right; ?>: 0.4em;
+}
+
+#enum_editor_output textarea {
+    width: 100%;
+    float: <?php echo $right; ?>;
+    margin: 1em 0 0 0;
+}
+
+/**
+ * ENUM/SET editor integration for the routines editor
+ */
+.enum_hint {
+    position: relative;
+}
+
+.enum_hint a {
+    position: absolute;
+    <?php echo $left; ?>: 81%;
+    bottom: .35em;
+}
diff --git a/phpmyadmin/themes/pmahomme/css/gis.css.php b/phpmyadmin/themes/pmahomme/css/gis.css.php
new file mode 100644
index 0000000..66348e3
--- /dev/null
+++ b/phpmyadmin/themes/pmahomme/css/gis.css.php
@@ -0,0 +1,65 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * GIS styles for the pmahomme theme
+ *
+ * @package    PhpMyAdmin-theme
+ * @subpackage PMAHomme
+ */
+
+// unplanned execution path
+if (! defined('PMA_MINIMUM_COMMON') && ! defined('TESTSUITE')) {
+    exit();
+}
+?>
+
+.gis_table td {
+    vertical-align: middle;
+}
+
+.gis_table select {
+    min-width: 151px;
+    margin: 6px;
+}
+
+.gis_table .button {
+   text-align: <?php echo $right; ?>;
+}
+
+/**
+ * GIS data editor styles
+ */
+a.close_gis_editor {
+    float: <?php echo $right; ?>;
+}
+
+#gis_editor {
+    display: none;
+    position: fixed;
+    _position: absolute; /* hack for IE */
+    z-index: 1001;
+    overflow-y: auto;
+    overflow-x: hidden;
+}
+
+#gis_data {
+    min-height: 230px;
+}
+
+#gis_data_textarea {
+    height: 6em;
+}
+
+#gis_data_editor {
+    background: #D0DCE0;
+    padding: 15px;
+    min-height: 500px;
+}
+
+#gis_data_editor .choice {
+    display: none;
+}
+
+#gis_data_editor input[type="text"] {
+    width: 75px;
+}
diff --git a/phpmyadmin/themes/pmahomme/css/jqplot.css.php b/phpmyadmin/themes/pmahomme/css/jqplot.css.php
new file mode 100644
index 0000000..e4c56bf
--- /dev/null
+++ b/phpmyadmin/themes/pmahomme/css/jqplot.css.php
@@ -0,0 +1,277 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * Styles for jqplot 
+ * for the pmahomme theme
+ *
+ * @package    PhpMyAdmin-theme
+ * @subpackage PMAHomme
+ */
+
+// unplanned execution path
+if (! defined('PMA_MINIMUM_COMMON') && ! defined('TESTSUITE')) {
+    exit();
+}
+?>
+
+/* jqPlot */
+
+/*rules for the plot target div.  These will be cascaded down to all plot elements according to css rules*/
+.jqplot-target {
+    position: relative;
+    color: #222222;
+    font-family: "Trebuchet MS", Arial, Helvetica, sans-serif;
+    font-size: 1em;
+/*    height: 300px;
+    width: 590px;*/
+}
+
+/*rules applied to all axes*/
+.jqplot-axis {
+    font-size: 0.75em;
+}
+
+.jqplot-xaxis {
+    margin-top: 10px;
+}
+
+.jqplot-x2axis {
+    margin-bottom: 10px;
+}
+
+.jqplot-yaxis {
+    margin-<?php echo $right; ?>: 10px;
+}
+
+.jqplot-y2axis, .jqplot-y3axis, .jqplot-y4axis, .jqplot-y5axis, .jqplot-y6axis, .jqplot-y7axis, .jqplot-y8axis, .jqplot-y9axis, .jqplot-yMidAxis {
+    margin-left: 10px;
+    margin-right: 10px;
+}
+
+/*rules applied to all axis tick divs*/
+.jqplot-axis-tick, .jqplot-xaxis-tick, .jqplot-yaxis-tick, .jqplot-x2axis-tick, .jqplot-y2axis-tick, .jqplot-y3axis-tick, .jqplot-y4axis-tick, .jqplot-y5axis-tick, .jqplot-y6axis-tick, .jqplot-y7axis-tick, .jqplot-y8axis-tick, .jqplot-y9axis-tick, .jqplot-yMidAxis-tick {
+    position: absolute;
+    white-space: pre;
+}
+
+
+.jqplot-xaxis-tick {
+    top: 0px;
+    /* initial position untill tick is drawn in proper place */
+    <?php echo $left; ?>: 15px;
+/*    padding-top: 10px;*/
+    vertical-align: top;
+}
+
+.jqplot-x2axis-tick {
+    bottom: 0px;
+    /* initial position untill tick is drawn in proper place */
+    <?php echo $left; ?>: 15px;
+/*    padding-bottom: 10px;*/
+    vertical-align: bottom;
+}
+
+.jqplot-yaxis-tick {
+    <?php echo $right; ?>: 0px;
+    /* initial position untill tick is drawn in proper place */
+    top: 15px;
+/*    padding-right: 10px;*/
+    text-align: <?php echo $right; ?>;
+}
+
+.jqplot-yaxis-tick.jqplot-breakTick {
+	<?php echo $right; ?>: -20px;
+	margin-<?php echo $right; ?>: 0px;
+	padding:1px 5px 1px;
+/*	background-color: white;*/
+	z-index: 2;
+	font-size: 1.5em;
+}
+
+.jqplot-y2axis-tick, .jqplot-y3axis-tick, .jqplot-y4axis-tick, .jqplot-y5axis-tick, .jqplot-y6axis-tick, .jqplot-y7axis-tick, .jqplot-y8axis-tick, .jqplot-y9axis-tick {
+    <?php echo $left; ?>: 0px;
+    /* initial position untill tick is drawn in proper place */
+    top: 15px;
+/*    padding-left: 10px;*/
+/*    padding-right: 15px;*/
+    text-align: <?php echo $left; ?>;
+}
+
+.jqplot-yMidAxis-tick {
+    text-align: center;
+    white-space: nowrap;
+}
+
+.jqplot-xaxis-label {
+    margin-top: 10px;
+    font-size: 11pt;
+    position: absolute;
+}
+
+.jqplot-x2axis-label {
+    margin-bottom: 10px;
+    font-size: 11pt;
+    position: absolute;
+}
+
+.jqplot-yaxis-label {
+    margin-right: 10px;
+/*    text-align: center;*/
+    font-size: 11pt;
+    position: absolute;
+}
+
+.jqplot-yMidAxis-label {
+    font-size: 11pt;
+    position: absolute;
+}
+
+.jqplot-y2axis-label, .jqplot-y3axis-label, .jqplot-y4axis-label, .jqplot-y5axis-label, .jqplot-y6axis-label, .jqplot-y7axis-label, .jqplot-y8axis-label, .jqplot-y9axis-label {
+/*    text-align: center;*/
+    font-size: 11pt;
+    margin-<?php echo $left; ?>: 10px;
+    position: absolute;
+}
+
+.jqplot-meterGauge-tick {
+    font-size: 0.75em;
+    color: #999999;
+}
+
+.jqplot-meterGauge-label {
+    font-size: 1em;
+    color: #999999;
+}
+
+table.jqplot-table-legend {
+    margin-top: 12px;
+    margin-bottom: 12px;
+    margin-left: 12px;
+    margin-right: 12px;
+}
+
+table.jqplot-table-legend, table.jqplot-cursor-legend {
+    background-color: rgba(255,255,255,0.6);
+    border: 1px solid #cccccc;
+    position: absolute;
+    font-size: 0.75em;
+}
+
+td.jqplot-table-legend {
+    vertical-align: middle;
+}
+
+/*
+These rules could be used instead of assigning
+element styles and relying on js object properties.
+*/
+
+/*
+td.jqplot-table-legend-swatch {
+    padding-top: 0.5em;
+    text-align: center;
+}
+
+tr.jqplot-table-legend:first td.jqplot-table-legend-swatch {
+    padding-top: 0px;
+}
+*/
+
+td.jqplot-seriesToggle:hover, td.jqplot-seriesToggle:active {
+    cursor: pointer;
+}
+
+.jqplot-table-legend .jqplot-series-hidden {
+    text-decoration: line-through;
+}
+
+div.jqplot-table-legend-swatch-outline {
+    border: 1px solid #cccccc;
+    padding: 1px;
+}
+
+div.jqplot-table-legend-swatch {
+    width: 0;
+    height: 0;
+    border-top-width: 5px;
+    border-bottom-width: 5px;
+    border-left-width: 6px;
+    border-right-width: 6px;
+    border-top-style: solid;
+    border-bottom-style: solid;
+    border-left-style: solid;
+    border-right-style: solid;
+}
+
+.jqplot-title {
+    top: 0px;
+    <?php echo $left; ?>: 0px;
+    padding-bottom: 0.5em;
+    font-size: 1.2em;
+}
+
+table.jqplot-cursor-tooltip {
+    border: 1px solid #cccccc;
+    font-size: 0.75em;
+}
+
+
+.jqplot-cursor-tooltip {
+    border: 1px solid #cccccc;
+    font-size: 0.75em;
+    white-space: nowrap;
+    background: rgba(208,208,208,0.5);
+    padding: 1px;
+}
+
+.jqplot-highlighter-tooltip, .jqplot-canvasOverlay-tooltip {
+    border: 1px solid #cccccc;
+    font-size: 0.75em;
+    white-space: nowrap;
+    background: rgba(208,208,208,0.5);
+    padding: 1px;
+}
+
+.jqplot-point-label {
+    font-size: 0.75em;
+    z-index: 2;
+}
+      
+td.jqplot-cursor-legend-swatch {
+    vertical-align: middle;
+    text-align: center;
+}
+
+div.jqplot-cursor-legend-swatch {
+    width: 1.2em;
+    height: 0.7em;
+}
+
+.jqplot-error {
+/*   Styles added to the plot target container when there is an error go here.*/
+    text-align: center;
+}
+
+.jqplot-error-message {
+/*    Styling of the custom error message div goes here.*/
+    position: relative;
+    top: 46%;
+    display: inline-block;
+}
+
+div.jqplot-bubble-label {
+    font-size: 0.8em;
+/*    background: rgba(90%, 90%, 90%, 0.15);*/
+    padding-left: 2px;
+    padding-right: 2px;
+    color: rgb(20%, 20%, 20%);
+}
+
+div.jqplot-bubble-label.jqplot-bubble-label-highlight {
+    background: rgba(90%, 90%, 90%, 0.7);
+}
+
+div.jqplot-noData-container {
+	text-align: center;
+	background-color: rgba(96%, 96%, 96%, 0.3);
+}
diff --git a/phpmyadmin/themes/pmahomme/css/navigation.css.php b/phpmyadmin/themes/pmahomme/css/navigation.css.php
new file mode 100644
index 0000000..a853c47
--- /dev/null
+++ b/phpmyadmin/themes/pmahomme/css/navigation.css.php
@@ -0,0 +1,242 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * Navigation styles for the pmahomme theme
+ *
+ * @package    PhpMyAdmin-theme
+ * @subpackage PMAHomme
+ */
+
+// unplanned execution path
+if (! defined('PMA_MINIMUM_COMMON') && ! defined('TESTSUITE')) {
+    exit();
+}
+?>
+
+/******************************************************************************/
+/* Navigation */
+
+#pma_navigation {
+    width: <?php echo $GLOBALS['cfg']['NaviWidth']; ?>px;
+    overflow: hidden;
+    overflow-y: auto;
+    position: fixed;
+    top: 0;
+    <?php echo $left; ?>: 0;
+    height: 100%;
+    background: url(./themes/pmahomme/img/left_nav_bg.png) repeat-y right 0% <?php echo $GLOBALS['cfg']['NaviBackground']; ?>;
+    color: <?php echo $GLOBALS['cfg']['NaviColor']; ?>;
+    z-index: 800;
+}
+
+#pma_navigation_content {
+    width: 100%;
+    position: absolute;
+    top: 0;
+    <?php echo $left; ?>: 0;
+    z-index: 0;
+}
+
+#pma_navigation ul {
+    margin: 0;
+}
+
+#pma_navigation form {
+    margin: 0;
+    padding: 0;
+    display: inline;
+}
+
+#pma_navigation select#select_server,
+#pma_navigation select#lightm_db {
+    width: 100%;
+}
+
+/******************************************************************************/
+/* specific elements */
+
+#pma_navigation div.pageselector {
+    text-align: center;
+    margin: 0;
+    margin-<?php echo $left; ?>: 0.75em;
+    border-<?php echo $left; ?>: 1px solid #666;
+}
+
+#pma_navigation div#pmalogo {
+    <?php //better echo $GLOBALS['cfg']['logoBGC']; ?>
+}
+
+#pma_navigation #pmalogo,
+#pma_navigation #serverChoice,
+#pma_navigation #leftframelinks,
+#pma_navigation #recentTableList,
+#pma_navigation #databaseList,
+#pma_navigation div.pageselector.dbselector {
+    text-align: center;
+    margin: 5px 10px 0px;
+    border: 0;
+}
+
+#pma_navigation #recentTableList select,
+#pma_navigation #serverChoice select
+ {
+    width: 80%;
+}
+
+#pma_navigation_content > img.throbber {
+    display: block;
+    margin: .3em auto 0;
+}
+
+/* Navigation tree*/
+#pma_navigation_tree {
+    margin: 5px 0 0;
+    margin-<?php echo $left; ?>: 10px;
+    color: #444;
+}
+#pma_navigation_tree a {
+    color: <?php echo $GLOBALS['cfg']['NaviColor']; ?>;
+}
+#pma_navigation_tree a:hover {
+    text-decoration: underline;
+}
+#pma_navigation_tree li.activePointer {
+    color: <?php echo $GLOBALS['cfg']['NaviPointerColor']; ?>;
+    background-color: <?php echo $GLOBALS['cfg']['NaviPointerBackground']; ?>;
+}
+#pma_navigation_tree ul {
+    clear: both;
+    padding: 0;
+    list-style-type: none;
+    margin: 0;
+}
+#pma_navigation_tree ul ul {
+    position: relative;
+}
+#pma_navigation_tree li {
+    white-space: nowrap;
+    clear: both;
+    min-height: 16px;
+}
+#pma_navigation_tree img {
+    margin: 0;
+}
+#pma_navigation_tree div.block {
+    position: relative;
+    width: 1.5em;
+    height: 1.5em;
+    min-width: 16px;
+    min-height: 16px;
+    float: <?php echo $left; ?>;
+}
+#pma_navigation_tree div.block i,
+#pma_navigation_tree div.block b {
+    width: 1.5em;
+    height: 1.5em;
+    min-width: 16px;
+    min-height: 8px;
+    position: absolute;
+    bottom: 0.7em;
+    <?php echo $left; ?>: 0.75em;
+    z-index: 0;
+}
+#pma_navigation_tree div.block i { /* Top and right segments for the tree element connections */
+    display: block;
+    border-<?php echo $left; ?>: 1px solid #666;
+    border-bottom: 1px solid #666;
+}
+#pma_navigation_tree div.block i.first { /* Removes top segment */
+    border-<?php echo $left; ?>: 0;
+}
+#pma_navigation_tree div.block b { /* Bottom segment for the tree element connections */
+    display: block;
+    height: 0.75em;
+    bottom: 0;
+    <?php echo $left; ?>: 0.75em;
+    border-<?php echo $left; ?>: 1px solid #666;
+}
+#pma_navigation_tree div.block a,
+#pma_navigation_tree div.block u {
+    position: absolute;
+    <?php echo $left; ?>: 50%;
+    top: 50%;
+    z-index: 10;
+}
+#pma_navigation_tree div.block img {
+    position: relative;
+    top: -0.6em;
+    <?php echo $left; ?>: 0;
+    margin-<?php echo $left; ?>: -7px;
+}
+#pma_navigation_tree div.throbber img {
+    top: 2px;
+    <?php echo $left; ?>: 2px;
+}
+#pma_navigation_tree li.last > ul {
+    background: none;
+}
+#pma_navigation_tree li > a, #pma_navigation_tree li > i {
+    line-height: 1.5em;
+    height: 1.5em;
+    padding-<?php echo $left; ?>: 0.3em;
+}
+#pma_navigation_tree .list_container {
+    border-<?php echo $left; ?>: 1px solid #666;
+    margin-<?php echo $left; ?>: 0.75em;
+    padding-<?php echo $left; ?>: 0.75em;
+}
+#pma_navigation_tree .last > .list_container {
+    border-<?php echo $left; ?>: 0 solid #666;
+}
+
+/* Fast filter */
+li.fast_filter {
+    padding-<?php echo $left; ?>: 0.75em;
+    margin-<?php echo $left; ?>: 0.75em;
+    padding-<?php echo $right; ?>: 35px;
+    border-<?php echo $left; ?>: 1px solid #666;
+}
+li.fast_filter input {
+    padding-<?php echo $right; ?>: .4em;
+    width: 100%;
+}
+li.fast_filter span {
+    position: relative;
+    <?php echo $right; ?>: 1.5em;
+    padding: 0.2em;
+    cursor: pointer;
+    font-weight: bold;
+    color: #800;
+}
+li.fast_filter.db_fast_filter {
+    border: 0;
+}
+
+/* Resize handler */
+#pma_navigation_resizer {
+    width: 3px;
+    height: 100%;
+    background-color: #aaa;
+    cursor: col-resize;
+    position: fixed;
+    top: 0;
+    <?php echo $left; ?>: 240px;
+    z-index: 801;
+}
+#pma_navigation_collapser {
+    width: 20px;
+    height: 22px;
+    line-height: 22px;
+    background: #eee;
+    color: #555;
+    font-weight: bold;
+    position: fixed;
+    top: 0;
+    <?php echo $left; ?>: <?php echo $GLOBALS['cfg']['NaviWidth']; ?>px;
+    text-align: center;
+    cursor: pointer;
+    z-index: 800;
+    text-shadow: 0px 1px 0px #fff;
+    filter: dropshadow(color=#fff, offx=0, offy=1);
+    border: 1px solid #888;
+}
diff --git a/phpmyadmin/themes/pmahomme/css/pmd.css.php b/phpmyadmin/themes/pmahomme/css/pmd.css.php
new file mode 100644
index 0000000..97b175f
--- /dev/null
+++ b/phpmyadmin/themes/pmahomme/css/pmd.css.php
@@ -0,0 +1,529 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * Designer styles for the pmahomme theme
+ *
+ * @package    PhpMyAdmin-theme
+ * @subpackage PMAHomme
+ */
+
+// unplanned execution path
+if (! defined('PMA_MINIMUM_COMMON') && ! defined('TESTSUITE')) {
+    exit();
+}
+?>
+
+/* Designer */
+.input_tab {
+    background-color: #A6C7E1;
+    color: #000;
+}
+
+.content_fullscreen {
+    position: relative;
+    overflow: auto;
+}
+
+#canvas_outer {
+    position: relative;
+}
+
+#canvas {
+    background-color: #fff;
+    color: #000;
+}
+
+canvas.pmd {
+    display: inline-block;
+    overflow: hidden;
+    text-align: left;
+}
+
+canvas.pmd * {
+    behavior: url(#default#VML);
+}
+
+.pmd_tab {
+    background-color: #fff;
+    color: #000;
+    border-collapse: collapse;
+    border: 1px solid #aaa;
+    z-index: 1;
+    -moz-user-select: none;
+}
+
+.tab_zag {
+    background-image: url(<?php echo $_SESSION['PMA_Theme']->getImgPath('pmd/Header.png'); ?>);
+    background-repeat: repeat-x;
+    text-align: center;
+    cursor: move;
+    padding: 1px;
+    font-weight: bold;
+}
+
+.tab_zag_2 {
+    background-image: url(<?php echo $_SESSION['PMA_Theme']->getImgPath('pmd/Header_Linked.png'); ?>);
+    background-repeat: repeat-x;
+    text-align: center;
+    cursor: move;
+    padding: 1px;
+    font-weight: bold;
+}
+
+.tab_field {
+    background: #fff;
+    color: #000;
+    cursor: default;
+}
+
+.tab_field_2 {
+    background-color: #CCFFCC;
+    color: #000;
+    background-repeat: repeat-x;
+    cursor: default;
+}
+
+.tab_field_3 {
+    background-color: #FFE6E6; /*#DDEEFF*/
+    color: #000;
+    cursor: default;
+}
+
+#pmd_hint {
+    white-space: nowrap;
+    position: absolute;
+    background-color: #99FF99;
+    color: #000;
+    <?php echo $left; ?>: 200px;
+    top: 50px;
+    z-index: 3;
+    border: #00CC66 solid 1px;
+    display: none;
+}
+
+.scroll_tab {
+    overflow: auto;
+    width: 100%;
+    height: 500px;
+}
+
+.pmd_Tabs {
+    cursor: default;
+    color: #0055bb;
+    white-space: nowrap;
+    text-decoration: none;
+    text-indent: 3px;
+    font-weight: bold;
+    margin-left: 2px;
+    text-align: <?php echo $left; ?>;
+    background-color: #fff;
+    background-image: url(<?php echo $_SESSION['PMA_Theme']->getImgPath('pmd/left_panel_butt.png'); ?>);
+    border: #ccc solid 1px;
+}
+
+.pmd_Tabs2 {
+    cursor: default;
+    color: #0055bb;
+    background: #FFEE99;
+    text-indent: 3px;
+    font-weight: bold;
+    white-space: nowrap;
+    text-decoration: none;
+    border: #9999FF solid 1px;
+    text-align: <?php echo $left; ?>;
+}
+
+.owner {
+    font-weight: normal;
+    color: #888;
+}
+
+.option_tab {
+    padding-left: 2px;
+    padding-right: 2px;
+    width: 5px;
+}
+
+.select_all {
+    vertical-align: top;
+    padding-left: 2px;
+    padding-right: 2px;
+    cursor: default;
+    width: 1px;
+    color: #000;
+    background-image: url(<?php echo $_SESSION['PMA_Theme']->getImgPath('pmd/Header.png'); ?>);
+    background-repeat: repeat-x;
+}
+
+.small_tab {
+    vertical-align: top;
+    background-color: #0064ea;
+    color: #fff;
+    background-image: url(<?php echo $_SESSION['PMA_Theme']->getImgPath('pmd/small_tab.png'); ?>);
+    cursor: default;
+    text-align: center;
+    font-weight: bold;
+    padding-left: 2px;
+    padding-right: 2px;
+    width: 1px;
+    text-decoration: none;
+}
+
+.small_tab2 {
+    vertical-align: top;
+    color: #fff;
+    background-color: #FF9966;
+    cursor: default;
+    padding-left: 2px;
+    padding-right: 2px;
+    text-align: center;
+    font-weight: bold;
+    width: 1px;
+    text-decoration: none;
+}
+
+.small_tab_pref {
+    background-image: url(<?php echo $_SESSION['PMA_Theme']->getImgPath('pmd/Header.png'); ?>);
+    background-repeat: repeat-x;
+    text-align: center;
+    width: 1px;
+}
+
+.small_tab_pref2 {
+    vertical-align: top;
+    color: #fff;
+    background-color: #FF9966;
+    cursor: default;
+    text-align: center;
+    font-weight: bold;
+    width: 1px;
+    text-decoration: none;
+}
+
+.butt {
+    border: #4477aa solid 1px;
+    font-weight: bold;
+    height: 19px;
+    width: 70px;
+    background-color: #fff;
+    color: #000;
+    vertical-align: baseline;
+}
+
+.L_butt2_1 {
+    padding: 1px;
+    text-decoration: none;
+    vertical-align: middle;
+    cursor: default;
+}
+
+.L_butt2_2 {
+    padding: 0;
+    border: #0099CC solid 1px;
+    background: #FFEE99;
+    color: #000;
+    text-decoration: none;
+    vertical-align: middle;
+    cursor: default;
+}
+
+/* ---------------------------------------------------------------------------*/
+.bor {
+    width: 10px;
+    height: 10px;
+}
+
+.frams1 {
+    background: url(<?php echo $_SESSION['PMA_Theme']->getImgPath('pmd/1.png'); ?>) no-repeat right bottom;
+}
+
+.frams2 {
+    background: url(<?php echo $_SESSION['PMA_Theme']->getImgPath('pmd/2.png'); ?>) no-repeat left bottom;
+}
+
+.frams3 {
+    background: url(<?php echo $_SESSION['PMA_Theme']->getImgPath('pmd/3.png'); ?>) no-repeat left top;
+}
+
+.frams4 {
+    background: url(<?php echo $_SESSION['PMA_Theme']->getImgPath('pmd/4.png'); ?>) no-repeat right top;
+}
+
+.frams5 {
+    background: url(<?php echo $_SESSION['PMA_Theme']->getImgPath('pmd/5.png'); ?>) repeat-x center bottom;
+}
+
+.frams6 {
+    background: url(<?php echo $_SESSION['PMA_Theme']->getImgPath('pmd/6.png'); ?>) repeat-y left;
+}
+
+.frams7 {
+    background: url(<?php echo $_SESSION['PMA_Theme']->getImgPath('pmd/7.png'); ?>) repeat-x top;
+}
+
+.frams8 {
+    background: url(<?php echo $_SESSION['PMA_Theme']->getImgPath('pmd/8.png'); ?>) repeat-y right;
+}
+
+#osn_tab {
+    background-color: #fff;
+    color: #000;
+    border: #A9A9A9 solid 1px;
+}
+
+.pmd_header {
+    background-color: #EAEEF0;
+    color: #000;
+    text-align: center;
+    font-weight: bold;
+    margin: 0;
+    padding: 0;
+    background-image: url(<?php echo $_SESSION['PMA_Theme']->getImgPath('pmd/top_panel.png'); ?>);
+    background-position: top;
+    background-repeat: repeat-x;
+    border-right: #999 solid 1px;
+    border-left: #999 solid 1px;
+    height: 28px;
+    z-index: 101;
+    width: 100%
+}
+
+.pmd_header a {
+    display: block;
+    float: <?php echo $left; ?>;
+    margin: 3px 1px 4px;
+    height: 20px;
+    border: 1px dotted #fff;
+}
+
+.pmd_header .M_bord {
+    display: block;
+    float: <?php echo $left; ?>;
+    margin: 4px;
+    height: 20px;
+    width: 2px;
+}
+
+.pmd_header a.first {
+    margin-right: 1em;
+}
+
+.pmd_header a.last {
+    margin-left: 1em;
+}
+
+a.M_butt_Selected_down_IE,
+a.M_butt_Selected_down {
+    border: 1px solid #C0C0BB;
+    background-color: #99FF99;
+    color: #000;
+}
+
+a.M_butt_Selected_down_IE:hover,
+a.M_butt_Selected_down:hover,
+a.M_butt:hover {
+    border: 1px solid #0099CC;
+    background-color: #FFEE99;
+    color: #000;
+}
+
+#layer_menu {
+    z-index: 100;
+    position: absolute;
+    <?php echo $left; ?>: 0;
+    background-color: #EAEEF0;
+    border: #999 solid 1px;
+}
+
+#layer_upd_relation {
+    position: absolute;
+    <?php echo $left; ?>: 637px;
+    top: 224px;
+    z-index: 100;
+}
+
+#layer_new_relation {
+    position: absolute;
+    <?php echo $left; ?>: 636px;
+    top: 85px;
+    z-index: 100;
+    width: 153px;
+}
+
+#pmd_optionse {
+    position: absolute;
+    <?php echo $left; ?>: 636px;
+    top: 85px;
+    z-index: 100;
+    width: 153px;
+}
+
+#layer_menu_sizer {
+    background-image: url(<?php echo $_SESSION['PMA_Theme']->getImgPath('pmd/resize.png'); ?>);
+    cursor: nw-resize;
+    width: 16px;
+    height: 16px;
+}
+
+.panel {
+    position: fixed;
+    top: 60px;
+    <?php echo $right; ?>: 0;
+    display: none;
+    background: #FFF;
+    border: 1px solid gray;
+    width: 350 px;
+    height: auto;
+    padding: 30px 170px 30px;
+    padding-<?php echo $left; ?>: 30px;
+    color: #FFF;
+    z-index: 102;
+}
+
+a.trigger {
+    position: fixed;
+    text-decoration: none;
+    top: 60px;
+    <?php echo $right; ?>: 0;
+    color: #fff;
+    padding: 10px 40px 10px 15px;
+    background: #333 url(<?php echo $_SESSION['PMA_Theme']->getImgPath('pmd/plus.png'); ?>) 85% 55% no-repeat;
+    border: 1px solid #444;
+    display: block;
+    z-index: 102;
+}
+
+a.trigger:hover {
+    color: #080808;
+    background: #fff696 url(<?php echo $_SESSION['PMA_Theme']->getImgPath('pmd/plus.png'); ?>) 85% 55% no-repeat;
+    border: 1px solid #999;
+}
+
+a.active.trigger {
+    background: #222 url(<?php echo $_SESSION['PMA_Theme']->getImgPath('pmd/minus.png'); ?>) 85% 55% no-repeat;
+    z-index: 999;
+}
+
+a.active.trigger:hover {
+    background: #fff696 url(<?php echo $_SESSION['PMA_Theme']->getImgPath('pmd/minus.png'); ?>) 85% 55% no-repeat;
+}
+
+h2.tiger {
+    background-repeat: repeat-x;
+    padding: 1px;
+    font-weight: bold;
+    padding: 50px 20px 50px;
+    margin: 0 0 5px 0;
+    width: 250px;
+    float: <?php echo $left; ?>;
+    color : #333;
+    text-align: center;
+}
+
+h2.tiger a {
+    background-image: url(<?php echo $_SESSION['PMA_Theme']->getImgPath('pmd/Header.png'); ?>);
+    text-align: center;
+    text-decoration: none;
+    color : #333;
+    display: block;
+}
+
+h2.tiger a:hover {
+    color: #000;
+    background-image: url(<?php echo $_SESSION['PMA_Theme']->getImgPath('pmd/Header_Linked.png'); ?>);
+}
+
+h2.active {
+    background-image: url(<?php echo $_SESSION['PMA_Theme']->getImgPath('pmd/Header.png'); ?>);
+    background-repeat: repeat-x;
+    padding: 1px;
+    background-position: left bottom;
+}
+
+.toggle_container {
+    margin: 0 0 5px;
+    padding: 0;
+    border-top: 1px solid #d6d6d6;
+    background: #FFF;
+    width: 250px;
+    overflow: hidden;
+    font-size: 1.2em;
+    clear: both;
+}
+
+.toggle_container .block {
+    background-color: #DBE4E8;
+    padding: 40px 15px 40px 15px; /*--Padding of Container--*/
+    border:1px solid #999;
+    color: #000;
+}
+
+.history_table {
+    text-align: center;
+    background-color: #9999CC;
+}
+
+.history_table2 {
+    text-align: center;
+    background-color: #DBE4E8;
+}
+
+#filter {
+    display: none;
+    position: absolute;
+    top: 0%;
+    left: 0%;
+    width: 100%;
+    height: 100%;
+    background-color: #CCA;
+    z-index: 10;
+    opacity: .5;
+    filter: alpha(opacity=50);
+}
+
+#box {
+    display: none;
+    position: absolute;
+    top: 20%;
+    <?php echo $left; ?>: 30%;
+    width: 500px;
+    height: 220px;
+    padding: 48px;
+    margin: 0;
+    border: 1px solid #000;
+    background-color: #fff;
+    z-index: 101;
+    overflow: visible;
+}
+
+#boxtitle {
+    position: absolute;
+    float: center;
+    top: 0;
+    <?php echo $left; ?>: 0;
+    width: 593px;
+    height: 20px;
+    padding: 0;
+    padding-top: 4px;
+    margin: 0;
+    border-bottom: 4px solid #3CF;
+    background-color: #D0DCE0;
+    color: black;
+    font-weight: bold;
+    padding-<?php echo $left; ?>: 2px;
+    text-align: <?php echo $left; ?>;
+}
+
+#tblfooter {
+    background-color: #D3DCE3;
+    float: <?php echo $right; ?>;
+    padding-top: 10px;
+    color: black;
+    font-weight: normal;
+}
+
+#foreignkeychk {
+    text-align: <?php echo $left; ?>;
+    position: absolute;
+    cursor: pointer;
+}
diff --git a/phpmyadmin/themes/pmahomme/css/resizable-menu.css.php b/phpmyadmin/themes/pmahomme/css/resizable-menu.css.php
new file mode 100644
index 0000000..21d90dc
--- /dev/null
+++ b/phpmyadmin/themes/pmahomme/css/resizable-menu.css.php
@@ -0,0 +1,57 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * Styles for the resizable menus
+ *
+ * used by js/jquery/jquery.menuResizer-1.0.js
+ *
+ * @package    PhpMyAdmin-theme
+ * @subpackage PMAHomme
+ */
+
+// unplanned execution path
+if (! defined('PMA_MINIMUM_COMMON') && ! defined('TESTSUITE')) {
+    exit();
+}
+?>
+ul.resizable-menu a,
+ul.resizable-menu span {
+    display: block;
+    margin: 0;
+    padding: 0;
+    white-space: nowrap;
+}
+
+ul.resizable-menu .submenu {
+    display: none;
+    position: relative;
+}
+
+ul.resizable-menu .shown {
+    display: inline-block;
+}
+
+ul.resizable-menu ul {
+    margin: 0;
+    padding: 0;
+    position: absolute;
+    list-style-type: none;
+    display: none;
+    border: 1px #ddd solid;
+    z-index: 2;
+    <?php echo $right; ?>: 0;
+}
+
+ul.resizable-menu li:hover {
+    <?php echo $_SESSION['PMA_Theme']->getCssGradient('ffffff', 'e5e5e5'); ?>
+}
+
+ul.resizable-menu li:hover ul,
+ul.resizable-menu .submenuhover ul {
+    display: block;
+    background: #fff;
+}
+
+ul.resizable-menu ul li {
+    width: 100%;
+}
diff --git a/phpmyadmin/themes/pmahomme/css/rte.css.php b/phpmyadmin/themes/pmahomme/css/rte.css.php
new file mode 100644
index 0000000..0db21a8
--- /dev/null
+++ b/phpmyadmin/themes/pmahomme/css/rte.css.php
@@ -0,0 +1,43 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * Styles for management of Routines, Triggers and Events
+ * for the pmahomme theme
+ *
+ * @package    PhpMyAdmin-theme
+ * @subpackage PMAHomme
+ */
+
+// unplanned execution path
+if (! defined('PMA_MINIMUM_COMMON') && ! defined('TESTSUITE')) {
+    exit();
+}
+?>
+
+.rte_table {
+    table-layout: fixed;
+}
+
+.rte_table td {
+    vertical-align: middle;
+    padding: 0.2em;
+}
+
+.rte_table tr td:nth-child(1) {
+    font-weight: bold;
+}
+
+.rte_table input,
+.rte_table select,
+.rte_table textarea {
+    width: 100%;
+    margin: 0;
+    box-sizing: border-box;
+    -ms-box-sizing: border-box;
+    -moz-box-sizing: border-box;
+    -webkit-box-sizing: border-box;
+}
+
+.rte_table .routine_params_table {
+    width: 100%;
+}
diff --git a/phpmyadmin/themes/pmahomme/img/ajax_clock_small.gif b/phpmyadmin/themes/pmahomme/img/ajax_clock_small.gif
new file mode 100644
index 0000000..bde4932
Binary files /dev/null and b/phpmyadmin/themes/pmahomme/img/ajax_clock_small.gif differ
diff --git a/phpmyadmin/themes/pmahomme/img/arrow_ltr.png b/phpmyadmin/themes/pmahomme/img/arrow_ltr.png
new file mode 100644
index 0000000..7ff8ed9
Binary files /dev/null and b/phpmyadmin/themes/pmahomme/img/arrow_ltr.png differ
diff --git a/phpmyadmin/themes/pmahomme/img/arrow_rtl.png b/phpmyadmin/themes/pmahomme/img/arrow_rtl.png
new file mode 100644
index 0000000..0192d10
Binary files /dev/null and b/phpmyadmin/themes/pmahomme/img/arrow_rtl.png differ
diff --git a/phpmyadmin/themes/pmahomme/img/asc_order.png b/phpmyadmin/themes/pmahomme/img/asc_order.png
new file mode 100644
index 0000000..f8d09cc
Binary files /dev/null and b/phpmyadmin/themes/pmahomme/img/asc_order.png differ
diff --git a/phpmyadmin/themes/pmahomme/img/b_bookmark.png b/phpmyadmin/themes/pmahomme/img/b_bookmark.png
new file mode 100644
index 0000000..0bc3caf
Binary files /dev/null and b/phpmyadmin/themes/pmahomme/img/b_bookmark.png differ
diff --git a/phpmyadmin/themes/pmahomme/img/b_browse.png b/phpmyadmin/themes/pmahomme/img/b_browse.png
new file mode 100644
index 0000000..64dbe2c
Binary files /dev/null and b/phpmyadmin/themes/pmahomme/img/b_browse.png differ
diff --git a/phpmyadmin/themes/pmahomme/img/b_calendar.png b/phpmyadmin/themes/pmahomme/img/b_calendar.png
new file mode 100644
index 0000000..23254a6
Binary files /dev/null and b/phpmyadmin/themes/pmahomme/img/b_calendar.png differ
diff --git a/phpmyadmin/themes/pmahomme/img/b_chart.png b/phpmyadmin/themes/pmahomme/img/b_chart.png
new file mode 100644
index 0000000..741e9b5
Binary files /dev/null and b/phpmyadmin/themes/pmahomme/img/b_chart.png differ
diff --git a/phpmyadmin/themes/pmahomme/img/b_close.png b/phpmyadmin/themes/pmahomme/img/b_close.png
new file mode 100644
index 0000000..2c234b6
Binary files /dev/null and b/phpmyadmin/themes/pmahomme/img/b_close.png differ
diff --git a/phpmyadmin/themes/pmahomme/img/b_column_add.png b/phpmyadmin/themes/pmahomme/img/b_column_add.png
new file mode 100644
index 0000000..25dc546
Binary files /dev/null and b/phpmyadmin/themes/pmahomme/img/b_column_add.png differ
diff --git a/phpmyadmin/themes/pmahomme/img/b_comment.png b/phpmyadmin/themes/pmahomme/img/b_comment.png
new file mode 100644
index 0000000..b6c3969
Binary files /dev/null and b/phpmyadmin/themes/pmahomme/img/b_comment.png differ
diff --git a/phpmyadmin/themes/pmahomme/img/b_dbstatistics.png b/phpmyadmin/themes/pmahomme/img/b_dbstatistics.png
new file mode 100644
index 0000000..741e9b5
Binary files /dev/null and b/phpmyadmin/themes/pmahomme/img/b_dbstatistics.png differ
diff --git a/phpmyadmin/themes/pmahomme/img/b_deltbl.png b/phpmyadmin/themes/pmahomme/img/b_deltbl.png
new file mode 100644
index 0000000..867996b
Binary files /dev/null and b/phpmyadmin/themes/pmahomme/img/b_deltbl.png differ
diff --git a/phpmyadmin/themes/pmahomme/img/b_docs.png b/phpmyadmin/themes/pmahomme/img/b_docs.png
new file mode 100644
index 0000000..0bf0563
Binary files /dev/null and b/phpmyadmin/themes/pmahomme/img/b_docs.png differ
diff --git a/phpmyadmin/themes/pmahomme/img/b_docsql.png b/phpmyadmin/themes/pmahomme/img/b_docsql.png
new file mode 100644
index 0000000..81c8b04
Binary files /dev/null and b/phpmyadmin/themes/pmahomme/img/b_docsql.png differ
diff --git a/phpmyadmin/themes/pmahomme/img/b_drop.png b/phpmyadmin/themes/pmahomme/img/b_drop.png
new file mode 100644
index 0000000..012acf1
Binary files /dev/null and b/phpmyadmin/themes/pmahomme/img/b_drop.png differ
diff --git a/phpmyadmin/themes/pmahomme/img/b_edit.png b/phpmyadmin/themes/pmahomme/img/b_edit.png
new file mode 100644
index 0000000..a6426ae
Binary files /dev/null and b/phpmyadmin/themes/pmahomme/img/b_edit.png differ
diff --git a/phpmyadmin/themes/pmahomme/img/b_empty.png b/phpmyadmin/themes/pmahomme/img/b_empty.png
new file mode 100644
index 0000000..fd6ec8d
Binary files /dev/null and b/phpmyadmin/themes/pmahomme/img/b_empty.png differ
diff --git a/phpmyadmin/themes/pmahomme/img/b_engine.png b/phpmyadmin/themes/pmahomme/img/b_engine.png
new file mode 100644
index 0000000..4d5f80d
Binary files /dev/null and b/phpmyadmin/themes/pmahomme/img/b_engine.png differ
diff --git a/phpmyadmin/themes/pmahomme/img/b_event_add.png b/phpmyadmin/themes/pmahomme/img/b_event_add.png
new file mode 100644
index 0000000..ef594b1
Binary files /dev/null and b/phpmyadmin/themes/pmahomme/img/b_event_add.png differ
diff --git a/phpmyadmin/themes/pmahomme/img/b_events.png b/phpmyadmin/themes/pmahomme/img/b_events.png
new file mode 100644
index 0000000..86bcc87
Binary files /dev/null and b/phpmyadmin/themes/pmahomme/img/b_events.png differ
diff --git a/phpmyadmin/themes/pmahomme/img/b_export.png b/phpmyadmin/themes/pmahomme/img/b_export.png
new file mode 100644
index 0000000..be8193a
Binary files /dev/null and b/phpmyadmin/themes/pmahomme/img/b_export.png differ
diff --git a/phpmyadmin/themes/pmahomme/img/b_firstpage.png b/phpmyadmin/themes/pmahomme/img/b_firstpage.png
new file mode 100644
index 0000000..e1242e6
Binary files /dev/null and b/phpmyadmin/themes/pmahomme/img/b_firstpage.png differ
diff --git a/phpmyadmin/themes/pmahomme/img/b_ftext.png b/phpmyadmin/themes/pmahomme/img/b_ftext.png
new file mode 100644
index 0000000..f991a4d
Binary files /dev/null and b/phpmyadmin/themes/pmahomme/img/b_ftext.png differ
diff --git a/phpmyadmin/themes/pmahomme/img/b_globe.gif b/phpmyadmin/themes/pmahomme/img/b_globe.gif
new file mode 100644
index 0000000..ef03dcf
Binary files /dev/null and b/phpmyadmin/themes/pmahomme/img/b_globe.gif differ
diff --git a/phpmyadmin/themes/pmahomme/img/b_group.png b/phpmyadmin/themes/pmahomme/img/b_group.png
new file mode 100644
index 0000000..4530760
Binary files /dev/null and b/phpmyadmin/themes/pmahomme/img/b_group.png differ
diff --git a/phpmyadmin/themes/pmahomme/img/b_help.png b/phpmyadmin/themes/pmahomme/img/b_help.png
new file mode 100644
index 0000000..730b7f9
Binary files /dev/null and b/phpmyadmin/themes/pmahomme/img/b_help.png differ
diff --git a/phpmyadmin/themes/pmahomme/img/b_home.png b/phpmyadmin/themes/pmahomme/img/b_home.png
new file mode 100644
index 0000000..75966aa
Binary files /dev/null and b/phpmyadmin/themes/pmahomme/img/b_home.png differ
diff --git a/phpmyadmin/themes/pmahomme/img/b_import.png b/phpmyadmin/themes/pmahomme/img/b_import.png
new file mode 100644
index 0000000..7b6e779
Binary files /dev/null and b/phpmyadmin/themes/pmahomme/img/b_import.png differ
diff --git a/phpmyadmin/themes/pmahomme/img/b_index.png b/phpmyadmin/themes/pmahomme/img/b_index.png
new file mode 100644
index 0000000..93bf593
Binary files /dev/null and b/phpmyadmin/themes/pmahomme/img/b_index.png differ
diff --git a/phpmyadmin/themes/pmahomme/img/b_index_add.png b/phpmyadmin/themes/pmahomme/img/b_index_add.png
new file mode 100644
index 0000000..a703bd6
Binary files /dev/null and b/phpmyadmin/themes/pmahomme/img/b_index_add.png differ
diff --git a/phpmyadmin/themes/pmahomme/img/b_info.png b/phpmyadmin/themes/pmahomme/img/b_info.png
new file mode 100644
index 0000000..cfd49e5
Binary files /dev/null and b/phpmyadmin/themes/pmahomme/img/b_info.png differ
diff --git a/phpmyadmin/themes/pmahomme/img/b_inline_edit.png b/phpmyadmin/themes/pmahomme/img/b_inline_edit.png
new file mode 100644
index 0000000..5afdba1
Binary files /dev/null and b/phpmyadmin/themes/pmahomme/img/b_inline_edit.png differ
diff --git a/phpmyadmin/themes/pmahomme/img/b_insrow.png b/phpmyadmin/themes/pmahomme/img/b_insrow.png
new file mode 100644
index 0000000..0532871
Binary files /dev/null and b/phpmyadmin/themes/pmahomme/img/b_insrow.png differ
diff --git a/phpmyadmin/themes/pmahomme/img/b_lastpage.png b/phpmyadmin/themes/pmahomme/img/b_lastpage.png
new file mode 100644
index 0000000..03102d9
Binary files /dev/null and b/phpmyadmin/themes/pmahomme/img/b_lastpage.png differ
diff --git a/phpmyadmin/themes/pmahomme/img/b_minus.png b/phpmyadmin/themes/pmahomme/img/b_minus.png
new file mode 100644
index 0000000..c0575ca
Binary files /dev/null and b/phpmyadmin/themes/pmahomme/img/b_minus.png differ
diff --git a/phpmyadmin/themes/pmahomme/img/b_more.png b/phpmyadmin/themes/pmahomme/img/b_more.png
new file mode 100644
index 0000000..681f862
Binary files /dev/null and b/phpmyadmin/themes/pmahomme/img/b_more.png differ
diff --git a/phpmyadmin/themes/pmahomme/img/b_move.png b/phpmyadmin/themes/pmahomme/img/b_move.png
new file mode 100644
index 0000000..8fd0f30
Binary files /dev/null and b/phpmyadmin/themes/pmahomme/img/b_move.png differ
diff --git a/phpmyadmin/themes/pmahomme/img/b_newdb.png b/phpmyadmin/themes/pmahomme/img/b_newdb.png
new file mode 100644
index 0000000..22d1fe0
Binary files /dev/null and b/phpmyadmin/themes/pmahomme/img/b_newdb.png differ
diff --git a/phpmyadmin/themes/pmahomme/img/b_newtbl.png b/phpmyadmin/themes/pmahomme/img/b_newtbl.png
new file mode 100644
index 0000000..7402ad8
Binary files /dev/null and b/phpmyadmin/themes/pmahomme/img/b_newtbl.png differ
diff --git a/phpmyadmin/themes/pmahomme/img/b_nextpage.png b/phpmyadmin/themes/pmahomme/img/b_nextpage.png
new file mode 100644
index 0000000..6169d53
Binary files /dev/null and b/phpmyadmin/themes/pmahomme/img/b_nextpage.png differ
diff --git a/phpmyadmin/themes/pmahomme/img/b_pdfdoc.png b/phpmyadmin/themes/pmahomme/img/b_pdfdoc.png
new file mode 100644
index 0000000..f5759ea
Binary files /dev/null and b/phpmyadmin/themes/pmahomme/img/b_pdfdoc.png differ
diff --git a/phpmyadmin/themes/pmahomme/img/b_plus.png b/phpmyadmin/themes/pmahomme/img/b_plus.png
new file mode 100644
index 0000000..32f9fa2
Binary files /dev/null and b/phpmyadmin/themes/pmahomme/img/b_plus.png differ
diff --git a/phpmyadmin/themes/pmahomme/img/b_prevpage.png b/phpmyadmin/themes/pmahomme/img/b_prevpage.png
new file mode 100644
index 0000000..0a3b85d
Binary files /dev/null and b/phpmyadmin/themes/pmahomme/img/b_prevpage.png differ
diff --git a/phpmyadmin/themes/pmahomme/img/b_primary.png b/phpmyadmin/themes/pmahomme/img/b_primary.png
new file mode 100644
index 0000000..d27b04b
Binary files /dev/null and b/phpmyadmin/themes/pmahomme/img/b_primary.png differ
diff --git a/phpmyadmin/themes/pmahomme/img/b_print.png b/phpmyadmin/themes/pmahomme/img/b_print.png
new file mode 100644
index 0000000..830defc
Binary files /dev/null and b/phpmyadmin/themes/pmahomme/img/b_print.png differ
diff --git a/phpmyadmin/themes/pmahomme/img/b_props.png b/phpmyadmin/themes/pmahomme/img/b_props.png
new file mode 100644
index 0000000..c0895fe
Binary files /dev/null and b/phpmyadmin/themes/pmahomme/img/b_props.png differ
diff --git a/phpmyadmin/themes/pmahomme/img/b_relations.png b/phpmyadmin/themes/pmahomme/img/b_relations.png
new file mode 100644
index 0000000..0ef2521
Binary files /dev/null and b/phpmyadmin/themes/pmahomme/img/b_relations.png differ
diff --git a/phpmyadmin/themes/pmahomme/img/b_routine_add.png b/phpmyadmin/themes/pmahomme/img/b_routine_add.png
new file mode 100644
index 0000000..2d14442
Binary files /dev/null and b/phpmyadmin/themes/pmahomme/img/b_routine_add.png differ
diff --git a/phpmyadmin/themes/pmahomme/img/b_routines.png b/phpmyadmin/themes/pmahomme/img/b_routines.png
new file mode 100644
index 0000000..2cc102d
Binary files /dev/null and b/phpmyadmin/themes/pmahomme/img/b_routines.png differ
diff --git a/phpmyadmin/themes/pmahomme/img/b_save.png b/phpmyadmin/themes/pmahomme/img/b_save.png
new file mode 100644
index 0000000..4192901
Binary files /dev/null and b/phpmyadmin/themes/pmahomme/img/b_save.png differ
diff --git a/phpmyadmin/themes/pmahomme/img/b_sbrowse.png b/phpmyadmin/themes/pmahomme/img/b_sbrowse.png
new file mode 100644
index 0000000..64dbe2c
Binary files /dev/null and b/phpmyadmin/themes/pmahomme/img/b_sbrowse.png differ
diff --git a/phpmyadmin/themes/pmahomme/img/b_sdb.png b/phpmyadmin/themes/pmahomme/img/b_sdb.png
new file mode 100644
index 0000000..0f57239
Binary files /dev/null and b/phpmyadmin/themes/pmahomme/img/b_sdb.png differ
diff --git a/phpmyadmin/themes/pmahomme/img/b_search.png b/phpmyadmin/themes/pmahomme/img/b_search.png
new file mode 100644
index 0000000..b6ac5b9
Binary files /dev/null and b/phpmyadmin/themes/pmahomme/img/b_search.png differ
diff --git a/phpmyadmin/themes/pmahomme/img/b_selboard.png b/phpmyadmin/themes/pmahomme/img/b_selboard.png
new file mode 100644
index 0000000..3caa949
Binary files /dev/null and b/phpmyadmin/themes/pmahomme/img/b_selboard.png differ
diff --git a/phpmyadmin/themes/pmahomme/img/b_select.png b/phpmyadmin/themes/pmahomme/img/b_select.png
new file mode 100644
index 0000000..0fab0e6
Binary files /dev/null and b/phpmyadmin/themes/pmahomme/img/b_select.png differ
diff --git a/phpmyadmin/themes/pmahomme/img/b_snewtbl.png b/phpmyadmin/themes/pmahomme/img/b_snewtbl.png
new file mode 100644
index 0000000..1d8b3ef
Binary files /dev/null and b/phpmyadmin/themes/pmahomme/img/b_snewtbl.png differ
diff --git a/phpmyadmin/themes/pmahomme/img/b_spatial.png b/phpmyadmin/themes/pmahomme/img/b_spatial.png
new file mode 100644
index 0000000..5e6c8c7
Binary files /dev/null and b/phpmyadmin/themes/pmahomme/img/b_spatial.png differ
diff --git a/phpmyadmin/themes/pmahomme/img/b_sql.png b/phpmyadmin/themes/pmahomme/img/b_sql.png
new file mode 100644
index 0000000..a4d3f02
Binary files /dev/null and b/phpmyadmin/themes/pmahomme/img/b_sql.png differ
diff --git a/phpmyadmin/themes/pmahomme/img/b_sqldoc.png b/phpmyadmin/themes/pmahomme/img/b_sqldoc.png
new file mode 100644
index 0000000..34d943b
Binary files /dev/null and b/phpmyadmin/themes/pmahomme/img/b_sqldoc.png differ
diff --git a/phpmyadmin/themes/pmahomme/img/b_sqlhelp.png b/phpmyadmin/themes/pmahomme/img/b_sqlhelp.png
new file mode 100644
index 0000000..08a13f2
Binary files /dev/null and b/phpmyadmin/themes/pmahomme/img/b_sqlhelp.png differ
diff --git a/phpmyadmin/themes/pmahomme/img/b_table_add.png b/phpmyadmin/themes/pmahomme/img/b_table_add.png
new file mode 100644
index 0000000..98753b2
Binary files /dev/null and b/phpmyadmin/themes/pmahomme/img/b_table_add.png differ
diff --git a/phpmyadmin/themes/pmahomme/img/b_tblanalyse.png b/phpmyadmin/themes/pmahomme/img/b_tblanalyse.png
new file mode 100644
index 0000000..604f1d5
Binary files /dev/null and b/phpmyadmin/themes/pmahomme/img/b_tblanalyse.png differ
diff --git a/phpmyadmin/themes/pmahomme/img/b_tblexport.png b/phpmyadmin/themes/pmahomme/img/b_tblexport.png
new file mode 100644
index 0000000..be8193a
Binary files /dev/null and b/phpmyadmin/themes/pmahomme/img/b_tblexport.png differ
diff --git a/phpmyadmin/themes/pmahomme/img/b_tblimport.png b/phpmyadmin/themes/pmahomme/img/b_tblimport.png
new file mode 100644
index 0000000..7b6e779
Binary files /dev/null and b/phpmyadmin/themes/pmahomme/img/b_tblimport.png differ
diff --git a/phpmyadmin/themes/pmahomme/img/b_tblops.png b/phpmyadmin/themes/pmahomme/img/b_tblops.png
new file mode 100644
index 0000000..153b267
Binary files /dev/null and b/phpmyadmin/themes/pmahomme/img/b_tblops.png differ
diff --git a/phpmyadmin/themes/pmahomme/img/b_tbloptimize.png b/phpmyadmin/themes/pmahomme/img/b_tbloptimize.png
new file mode 100644
index 0000000..04e7c3e
Binary files /dev/null and b/phpmyadmin/themes/pmahomme/img/b_tbloptimize.png differ
diff --git a/phpmyadmin/themes/pmahomme/img/b_tipp.png b/phpmyadmin/themes/pmahomme/img/b_tipp.png
new file mode 100644
index 0000000..13e0517
Binary files /dev/null and b/phpmyadmin/themes/pmahomme/img/b_tipp.png differ
diff --git a/phpmyadmin/themes/pmahomme/img/b_trigger_add.png b/phpmyadmin/themes/pmahomme/img/b_trigger_add.png
new file mode 100644
index 0000000..8a754df
Binary files /dev/null and b/phpmyadmin/themes/pmahomme/img/b_trigger_add.png differ
diff --git a/phpmyadmin/themes/pmahomme/img/b_triggers.png b/phpmyadmin/themes/pmahomme/img/b_triggers.png
new file mode 100644
index 0000000..84a89ef
Binary files /dev/null and b/phpmyadmin/themes/pmahomme/img/b_triggers.png differ
diff --git a/phpmyadmin/themes/pmahomme/img/b_unique.png b/phpmyadmin/themes/pmahomme/img/b_unique.png
new file mode 100644
index 0000000..0ec7d57
Binary files /dev/null and b/phpmyadmin/themes/pmahomme/img/b_unique.png differ
diff --git a/phpmyadmin/themes/pmahomme/img/b_usradd.png b/phpmyadmin/themes/pmahomme/img/b_usradd.png
new file mode 100644
index 0000000..50fc6a2
Binary files /dev/null and b/phpmyadmin/themes/pmahomme/img/b_usradd.png differ
diff --git a/phpmyadmin/themes/pmahomme/img/b_usrcheck.png b/phpmyadmin/themes/pmahomme/img/b_usrcheck.png
new file mode 100644
index 0000000..a3edfb1
Binary files /dev/null and b/phpmyadmin/themes/pmahomme/img/b_usrcheck.png differ
diff --git a/phpmyadmin/themes/pmahomme/img/b_usrdrop.png b/phpmyadmin/themes/pmahomme/img/b_usrdrop.png
new file mode 100644
index 0000000..7d5e699
Binary files /dev/null and b/phpmyadmin/themes/pmahomme/img/b_usrdrop.png differ
diff --git a/phpmyadmin/themes/pmahomme/img/b_usredit.png b/phpmyadmin/themes/pmahomme/img/b_usredit.png
new file mode 100644
index 0000000..79393d6
Binary files /dev/null and b/phpmyadmin/themes/pmahomme/img/b_usredit.png differ
diff --git a/phpmyadmin/themes/pmahomme/img/b_usrlist.png b/phpmyadmin/themes/pmahomme/img/b_usrlist.png
new file mode 100644
index 0000000..2a67259
Binary files /dev/null and b/phpmyadmin/themes/pmahomme/img/b_usrlist.png differ
diff --git a/phpmyadmin/themes/pmahomme/img/b_view.png b/phpmyadmin/themes/pmahomme/img/b_view.png
new file mode 100644
index 0000000..96f90eb
Binary files /dev/null and b/phpmyadmin/themes/pmahomme/img/b_view.png differ
diff --git a/phpmyadmin/themes/pmahomme/img/b_view_add.png b/phpmyadmin/themes/pmahomme/img/b_view_add.png
new file mode 100644
index 0000000..9c2cff6
Binary files /dev/null and b/phpmyadmin/themes/pmahomme/img/b_view_add.png differ
diff --git a/phpmyadmin/themes/pmahomme/img/b_views.png b/phpmyadmin/themes/pmahomme/img/b_views.png
new file mode 100644
index 0000000..b1c78e3
Binary files /dev/null and b/phpmyadmin/themes/pmahomme/img/b_views.png differ
diff --git a/phpmyadmin/themes/pmahomme/img/bd_browse.png b/phpmyadmin/themes/pmahomme/img/bd_browse.png
new file mode 100644
index 0000000..d21edab
Binary files /dev/null and b/phpmyadmin/themes/pmahomme/img/bd_browse.png differ
diff --git a/phpmyadmin/themes/pmahomme/img/bd_deltbl.png b/phpmyadmin/themes/pmahomme/img/bd_deltbl.png
new file mode 100644
index 0000000..e7e4e59
Binary files /dev/null and b/phpmyadmin/themes/pmahomme/img/bd_deltbl.png differ
diff --git a/phpmyadmin/themes/pmahomme/img/bd_drop.png b/phpmyadmin/themes/pmahomme/img/bd_drop.png
new file mode 100644
index 0000000..4b10084
Binary files /dev/null and b/phpmyadmin/themes/pmahomme/img/bd_drop.png differ
diff --git a/phpmyadmin/themes/pmahomme/img/bd_edit.png b/phpmyadmin/themes/pmahomme/img/bd_edit.png
new file mode 100644
index 0000000..6478c24
Binary files /dev/null and b/phpmyadmin/themes/pmahomme/img/bd_edit.png differ
diff --git a/phpmyadmin/themes/pmahomme/img/bd_empty.png b/phpmyadmin/themes/pmahomme/img/bd_empty.png
new file mode 100644
index 0000000..cffb040
Binary files /dev/null and b/phpmyadmin/themes/pmahomme/img/bd_empty.png differ
diff --git a/phpmyadmin/themes/pmahomme/img/bd_export.png b/phpmyadmin/themes/pmahomme/img/bd_export.png
new file mode 100644
index 0000000..a02db90
Binary files /dev/null and b/phpmyadmin/themes/pmahomme/img/bd_export.png differ
diff --git a/phpmyadmin/themes/pmahomme/img/bd_firstpage.png b/phpmyadmin/themes/pmahomme/img/bd_firstpage.png
new file mode 100644
index 0000000..d2943fc
Binary files /dev/null and b/phpmyadmin/themes/pmahomme/img/bd_firstpage.png differ
diff --git a/phpmyadmin/themes/pmahomme/img/bd_ftext.png b/phpmyadmin/themes/pmahomme/img/bd_ftext.png
new file mode 100644
index 0000000..a0bdcc6
Binary files /dev/null and b/phpmyadmin/themes/pmahomme/img/bd_ftext.png differ
diff --git a/phpmyadmin/themes/pmahomme/img/bd_index.png b/phpmyadmin/themes/pmahomme/img/bd_index.png
new file mode 100644
index 0000000..25141bc
Binary files /dev/null and b/phpmyadmin/themes/pmahomme/img/bd_index.png differ
diff --git a/phpmyadmin/themes/pmahomme/img/bd_insrow.png b/phpmyadmin/themes/pmahomme/img/bd_insrow.png
new file mode 100644
index 0000000..5162577
Binary files /dev/null and b/phpmyadmin/themes/pmahomme/img/bd_insrow.png differ
diff --git a/phpmyadmin/themes/pmahomme/img/bd_lastpage.png b/phpmyadmin/themes/pmahomme/img/bd_lastpage.png
new file mode 100644
index 0000000..1827ee9
Binary files /dev/null and b/phpmyadmin/themes/pmahomme/img/bd_lastpage.png differ
diff --git a/phpmyadmin/themes/pmahomme/img/bd_nextpage.png b/phpmyadmin/themes/pmahomme/img/bd_nextpage.png
new file mode 100644
index 0000000..244cdbd
Binary files /dev/null and b/phpmyadmin/themes/pmahomme/img/bd_nextpage.png differ
diff --git a/phpmyadmin/themes/pmahomme/img/bd_prevpage.png b/phpmyadmin/themes/pmahomme/img/bd_prevpage.png
new file mode 100644
index 0000000..e0073cf
Binary files /dev/null and b/phpmyadmin/themes/pmahomme/img/bd_prevpage.png differ
diff --git a/phpmyadmin/themes/pmahomme/img/bd_primary.png b/phpmyadmin/themes/pmahomme/img/bd_primary.png
new file mode 100644
index 0000000..792bfa7
Binary files /dev/null and b/phpmyadmin/themes/pmahomme/img/bd_primary.png differ
diff --git a/phpmyadmin/themes/pmahomme/img/bd_sbrowse.png b/phpmyadmin/themes/pmahomme/img/bd_sbrowse.png
new file mode 100644
index 0000000..d21edab
Binary files /dev/null and b/phpmyadmin/themes/pmahomme/img/bd_sbrowse.png differ
diff --git a/phpmyadmin/themes/pmahomme/img/bd_select.png b/phpmyadmin/themes/pmahomme/img/bd_select.png
new file mode 100644
index 0000000..412926a
Binary files /dev/null and b/phpmyadmin/themes/pmahomme/img/bd_select.png differ
diff --git a/phpmyadmin/themes/pmahomme/img/bd_spatial.png b/phpmyadmin/themes/pmahomme/img/bd_spatial.png
new file mode 100644
index 0000000..c974720
Binary files /dev/null and b/phpmyadmin/themes/pmahomme/img/bd_spatial.png differ
diff --git a/phpmyadmin/themes/pmahomme/img/bd_unique.png b/phpmyadmin/themes/pmahomme/img/bd_unique.png
new file mode 100644
index 0000000..28227cb
Binary files /dev/null and b/phpmyadmin/themes/pmahomme/img/bd_unique.png differ
diff --git a/phpmyadmin/themes/pmahomme/img/col_drop.png b/phpmyadmin/themes/pmahomme/img/col_drop.png
new file mode 100644
index 0000000..681f862
Binary files /dev/null and b/phpmyadmin/themes/pmahomme/img/col_drop.png differ
diff --git a/phpmyadmin/themes/pmahomme/img/col_pointer.png b/phpmyadmin/themes/pmahomme/img/col_pointer.png
new file mode 100644
index 0000000..7147edb
Binary files /dev/null and b/phpmyadmin/themes/pmahomme/img/col_pointer.png differ
diff --git a/phpmyadmin/themes/pmahomme/img/col_pointer_ver.png b/phpmyadmin/themes/pmahomme/img/col_pointer_ver.png
new file mode 100644
index 0000000..1cbadec
Binary files /dev/null and b/phpmyadmin/themes/pmahomme/img/col_pointer_ver.png differ
diff --git a/phpmyadmin/themes/pmahomme/img/database.png b/phpmyadmin/themes/pmahomme/img/database.png
new file mode 100644
index 0000000..9cc16be
Binary files /dev/null and b/phpmyadmin/themes/pmahomme/img/database.png differ
diff --git a/phpmyadmin/themes/pmahomme/img/east-mini.png b/phpmyadmin/themes/pmahomme/img/east-mini.png
new file mode 100644
index 0000000..bee419d
Binary files /dev/null and b/phpmyadmin/themes/pmahomme/img/east-mini.png differ
diff --git a/phpmyadmin/themes/pmahomme/img/error.ico b/phpmyadmin/themes/pmahomme/img/error.ico
new file mode 100644
index 0000000..8f4d509
Binary files /dev/null and b/phpmyadmin/themes/pmahomme/img/error.ico differ
diff --git a/phpmyadmin/themes/pmahomme/img/eye.png b/phpmyadmin/themes/pmahomme/img/eye.png
new file mode 100644
index 0000000..ed38db2
Binary files /dev/null and b/phpmyadmin/themes/pmahomme/img/eye.png differ
diff --git a/phpmyadmin/themes/pmahomme/img/eye_grey.png b/phpmyadmin/themes/pmahomme/img/eye_grey.png
new file mode 100644
index 0000000..6fcae47
Binary files /dev/null and b/phpmyadmin/themes/pmahomme/img/eye_grey.png differ
diff --git a/phpmyadmin/themes/pmahomme/img/item.png b/phpmyadmin/themes/pmahomme/img/item.png
new file mode 100644
index 0000000..5465aaf
Binary files /dev/null and b/phpmyadmin/themes/pmahomme/img/item.png differ
diff --git a/phpmyadmin/themes/pmahomme/img/left_nav_bg.png b/phpmyadmin/themes/pmahomme/img/left_nav_bg.png
new file mode 100644
index 0000000..cb2a7ad
Binary files /dev/null and b/phpmyadmin/themes/pmahomme/img/left_nav_bg.png differ
diff --git a/phpmyadmin/themes/pmahomme/img/logo_left.png b/phpmyadmin/themes/pmahomme/img/logo_left.png
new file mode 100644
index 0000000..22134fc
Binary files /dev/null and b/phpmyadmin/themes/pmahomme/img/logo_left.png differ
diff --git a/phpmyadmin/themes/pmahomme/img/logo_right.png b/phpmyadmin/themes/pmahomme/img/logo_right.png
new file mode 100644
index 0000000..d61c628
Binary files /dev/null and b/phpmyadmin/themes/pmahomme/img/logo_right.png differ
diff --git a/phpmyadmin/themes/pmahomme/img/more.png b/phpmyadmin/themes/pmahomme/img/more.png
new file mode 100644
index 0000000..32aaf61
Binary files /dev/null and b/phpmyadmin/themes/pmahomme/img/more.png differ
diff --git a/phpmyadmin/themes/pmahomme/img/new_data.png b/phpmyadmin/themes/pmahomme/img/new_data.png
new file mode 100644
index 0000000..6f4e186
Binary files /dev/null and b/phpmyadmin/themes/pmahomme/img/new_data.png differ
diff --git a/phpmyadmin/themes/pmahomme/img/new_data_hovered.png b/phpmyadmin/themes/pmahomme/img/new_data_hovered.png
new file mode 100644
index 0000000..a470dbb
Binary files /dev/null and b/phpmyadmin/themes/pmahomme/img/new_data_hovered.png differ
diff --git a/phpmyadmin/themes/pmahomme/img/new_data_selected.png b/phpmyadmin/themes/pmahomme/img/new_data_selected.png
new file mode 100644
index 0000000..a75abe3
Binary files /dev/null and b/phpmyadmin/themes/pmahomme/img/new_data_selected.png differ
diff --git a/phpmyadmin/themes/pmahomme/img/new_data_selected_hovered.png b/phpmyadmin/themes/pmahomme/img/new_data_selected_hovered.png
new file mode 100644
index 0000000..04a2ad8
Binary files /dev/null and b/phpmyadmin/themes/pmahomme/img/new_data_selected_hovered.png differ
diff --git a/phpmyadmin/themes/pmahomme/img/new_struct.png b/phpmyadmin/themes/pmahomme/img/new_struct.png
new file mode 100644
index 0000000..6b77c13
Binary files /dev/null and b/phpmyadmin/themes/pmahomme/img/new_struct.png differ
diff --git a/phpmyadmin/themes/pmahomme/img/new_struct_hovered.png b/phpmyadmin/themes/pmahomme/img/new_struct_hovered.png
new file mode 100644
index 0000000..9c353c6
Binary files /dev/null and b/phpmyadmin/themes/pmahomme/img/new_struct_hovered.png differ
diff --git a/phpmyadmin/themes/pmahomme/img/new_struct_selected.png b/phpmyadmin/themes/pmahomme/img/new_struct_selected.png
new file mode 100644
index 0000000..142bf11
Binary files /dev/null and b/phpmyadmin/themes/pmahomme/img/new_struct_selected.png differ
diff --git a/phpmyadmin/themes/pmahomme/img/new_struct_selected_hovered.png b/phpmyadmin/themes/pmahomme/img/new_struct_selected_hovered.png
new file mode 100644
index 0000000..9a82bc4
Binary files /dev/null and b/phpmyadmin/themes/pmahomme/img/new_struct_selected_hovered.png differ
diff --git a/phpmyadmin/themes/pmahomme/img/north-mini.png b/phpmyadmin/themes/pmahomme/img/north-mini.png
new file mode 100644
index 0000000..8283839
Binary files /dev/null and b/phpmyadmin/themes/pmahomme/img/north-mini.png differ
diff --git a/phpmyadmin/themes/pmahomme/img/pause.png b/phpmyadmin/themes/pmahomme/img/pause.png
new file mode 100644
index 0000000..46a6318
Binary files /dev/null and b/phpmyadmin/themes/pmahomme/img/pause.png differ
diff --git a/phpmyadmin/themes/pmahomme/img/php_sym.png b/phpmyadmin/themes/pmahomme/img/php_sym.png
new file mode 100644
index 0000000..cd5e9b8
Binary files /dev/null and b/phpmyadmin/themes/pmahomme/img/php_sym.png differ
diff --git a/phpmyadmin/themes/pmahomme/img/play.png b/phpmyadmin/themes/pmahomme/img/play.png
new file mode 100644
index 0000000..6169d53
Binary files /dev/null and b/phpmyadmin/themes/pmahomme/img/play.png differ
diff --git a/phpmyadmin/themes/pmahomme/img/pma_logo2.png b/phpmyadmin/themes/pmahomme/img/pma_logo2.png
new file mode 100644
index 0000000..bc17b98
Binary files /dev/null and b/phpmyadmin/themes/pmahomme/img/pma_logo2.png differ
diff --git a/phpmyadmin/themes/pmahomme/img/pmd/1.png b/phpmyadmin/themes/pmahomme/img/pmd/1.png
new file mode 100644
index 0000000..48b9d3f
Binary files /dev/null and b/phpmyadmin/themes/pmahomme/img/pmd/1.png differ
diff --git a/phpmyadmin/themes/pmahomme/img/pmd/2.png b/phpmyadmin/themes/pmahomme/img/pmd/2.png
new file mode 100644
index 0000000..7545d86
Binary files /dev/null and b/phpmyadmin/themes/pmahomme/img/pmd/2.png differ
diff --git a/phpmyadmin/themes/pmahomme/img/pmd/2leftarrow.png b/phpmyadmin/themes/pmahomme/img/pmd/2leftarrow.png
new file mode 100644
index 0000000..c3565bc
Binary files /dev/null and b/phpmyadmin/themes/pmahomme/img/pmd/2leftarrow.png differ
diff --git a/phpmyadmin/themes/pmahomme/img/pmd/2leftarrow_m.png b/phpmyadmin/themes/pmahomme/img/pmd/2leftarrow_m.png
new file mode 100644
index 0000000..6ec8d81
Binary files /dev/null and b/phpmyadmin/themes/pmahomme/img/pmd/2leftarrow_m.png differ
diff --git a/phpmyadmin/themes/pmahomme/img/pmd/2rightarrow.png b/phpmyadmin/themes/pmahomme/img/pmd/2rightarrow.png
new file mode 100644
index 0000000..0a4e236
Binary files /dev/null and b/phpmyadmin/themes/pmahomme/img/pmd/2rightarrow.png differ
diff --git a/phpmyadmin/themes/pmahomme/img/pmd/2rightarrow_m.png b/phpmyadmin/themes/pmahomme/img/pmd/2rightarrow_m.png
new file mode 100644
index 0000000..e5ff1f0
Binary files /dev/null and b/phpmyadmin/themes/pmahomme/img/pmd/2rightarrow_m.png differ
diff --git a/phpmyadmin/themes/pmahomme/img/pmd/3.png b/phpmyadmin/themes/pmahomme/img/pmd/3.png
new file mode 100644
index 0000000..4617911
Binary files /dev/null and b/phpmyadmin/themes/pmahomme/img/pmd/3.png differ
diff --git a/phpmyadmin/themes/pmahomme/img/pmd/4.png b/phpmyadmin/themes/pmahomme/img/pmd/4.png
new file mode 100644
index 0000000..9b53459
Binary files /dev/null and b/phpmyadmin/themes/pmahomme/img/pmd/4.png differ
diff --git a/phpmyadmin/themes/pmahomme/img/pmd/5.png b/phpmyadmin/themes/pmahomme/img/pmd/5.png
new file mode 100644
index 0000000..51f536d
Binary files /dev/null and b/phpmyadmin/themes/pmahomme/img/pmd/5.png differ
diff --git a/phpmyadmin/themes/pmahomme/img/pmd/6.png b/phpmyadmin/themes/pmahomme/img/pmd/6.png
new file mode 100644
index 0000000..ed93cfe
Binary files /dev/null and b/phpmyadmin/themes/pmahomme/img/pmd/6.png differ
diff --git a/phpmyadmin/themes/pmahomme/img/pmd/7.png b/phpmyadmin/themes/pmahomme/img/pmd/7.png
new file mode 100644
index 0000000..7c7530f
Binary files /dev/null and b/phpmyadmin/themes/pmahomme/img/pmd/7.png differ
diff --git a/phpmyadmin/themes/pmahomme/img/pmd/8.png b/phpmyadmin/themes/pmahomme/img/pmd/8.png
new file mode 100644
index 0000000..451998d
Binary files /dev/null and b/phpmyadmin/themes/pmahomme/img/pmd/8.png differ
diff --git a/phpmyadmin/themes/pmahomme/img/pmd/FieldKey_small.png b/phpmyadmin/themes/pmahomme/img/pmd/FieldKey_small.png
new file mode 100644
index 0000000..8a55b16
Binary files /dev/null and b/phpmyadmin/themes/pmahomme/img/pmd/FieldKey_small.png differ
diff --git a/phpmyadmin/themes/pmahomme/img/pmd/Field_small.png b/phpmyadmin/themes/pmahomme/img/pmd/Field_small.png
new file mode 100644
index 0000000..4d80059
Binary files /dev/null and b/phpmyadmin/themes/pmahomme/img/pmd/Field_small.png differ
diff --git a/phpmyadmin/themes/pmahomme/img/pmd/Field_small_char.png b/phpmyadmin/themes/pmahomme/img/pmd/Field_small_char.png
new file mode 100644
index 0000000..dcaa1c6
Binary files /dev/null and b/phpmyadmin/themes/pmahomme/img/pmd/Field_small_char.png differ
diff --git a/phpmyadmin/themes/pmahomme/img/pmd/Field_small_date.png b/phpmyadmin/themes/pmahomme/img/pmd/Field_small_date.png
new file mode 100644
index 0000000..259a8d9
Binary files /dev/null and b/phpmyadmin/themes/pmahomme/img/pmd/Field_small_date.png differ
diff --git a/phpmyadmin/themes/pmahomme/img/pmd/Field_small_int.png b/phpmyadmin/themes/pmahomme/img/pmd/Field_small_int.png
new file mode 100644
index 0000000..70f3f38
Binary files /dev/null and b/phpmyadmin/themes/pmahomme/img/pmd/Field_small_int.png differ
diff --git a/phpmyadmin/themes/pmahomme/img/pmd/Header.png b/phpmyadmin/themes/pmahomme/img/pmd/Header.png
new file mode 100644
index 0000000..3e3e4e9
Binary files /dev/null and b/phpmyadmin/themes/pmahomme/img/pmd/Header.png differ
diff --git a/phpmyadmin/themes/pmahomme/img/pmd/Header_Linked.png b/phpmyadmin/themes/pmahomme/img/pmd/Header_Linked.png
new file mode 100644
index 0000000..cb0a4b3
Binary files /dev/null and b/phpmyadmin/themes/pmahomme/img/pmd/Header_Linked.png differ
diff --git a/phpmyadmin/themes/pmahomme/img/pmd/and_icon.png b/phpmyadmin/themes/pmahomme/img/pmd/and_icon.png
new file mode 100644
index 0000000..3767aba
Binary files /dev/null and b/phpmyadmin/themes/pmahomme/img/pmd/and_icon.png differ
diff --git a/phpmyadmin/themes/pmahomme/img/pmd/ang_direct.png b/phpmyadmin/themes/pmahomme/img/pmd/ang_direct.png
new file mode 100644
index 0000000..3bd28e8
Binary files /dev/null and b/phpmyadmin/themes/pmahomme/img/pmd/ang_direct.png differ
diff --git a/phpmyadmin/themes/pmahomme/img/pmd/bord.png b/phpmyadmin/themes/pmahomme/img/pmd/bord.png
new file mode 100644
index 0000000..351b959
Binary files /dev/null and b/phpmyadmin/themes/pmahomme/img/pmd/bord.png differ
diff --git a/phpmyadmin/themes/pmahomme/img/pmd/bottom.png b/phpmyadmin/themes/pmahomme/img/pmd/bottom.png
new file mode 100644
index 0000000..97abfc9
Binary files /dev/null and b/phpmyadmin/themes/pmahomme/img/pmd/bottom.png differ
diff --git a/phpmyadmin/themes/pmahomme/img/pmd/def.png b/phpmyadmin/themes/pmahomme/img/pmd/def.png
new file mode 100644
index 0000000..33d5593
Binary files /dev/null and b/phpmyadmin/themes/pmahomme/img/pmd/def.png differ
diff --git a/phpmyadmin/themes/pmahomme/img/pmd/display_field.png b/phpmyadmin/themes/pmahomme/img/pmd/display_field.png
new file mode 100644
index 0000000..a7d7cb4
Binary files /dev/null and b/phpmyadmin/themes/pmahomme/img/pmd/display_field.png differ
diff --git a/phpmyadmin/themes/pmahomme/img/pmd/downarrow1.png b/phpmyadmin/themes/pmahomme/img/pmd/downarrow1.png
new file mode 100644
index 0000000..80632dd
Binary files /dev/null and b/phpmyadmin/themes/pmahomme/img/pmd/downarrow1.png differ
diff --git a/phpmyadmin/themes/pmahomme/img/pmd/downarrow2.png b/phpmyadmin/themes/pmahomme/img/pmd/downarrow2.png
new file mode 100644
index 0000000..2c925e9
Binary files /dev/null and b/phpmyadmin/themes/pmahomme/img/pmd/downarrow2.png differ
diff --git a/phpmyadmin/themes/pmahomme/img/pmd/downarrow2_m.png b/phpmyadmin/themes/pmahomme/img/pmd/downarrow2_m.png
new file mode 100644
index 0000000..461eeef
Binary files /dev/null and b/phpmyadmin/themes/pmahomme/img/pmd/downarrow2_m.png differ
diff --git a/phpmyadmin/themes/pmahomme/img/pmd/exec.png b/phpmyadmin/themes/pmahomme/img/pmd/exec.png
new file mode 100644
index 0000000..d5eaa76
Binary files /dev/null and b/phpmyadmin/themes/pmahomme/img/pmd/exec.png differ
diff --git a/phpmyadmin/themes/pmahomme/img/pmd/exec_small.png b/phpmyadmin/themes/pmahomme/img/pmd/exec_small.png
new file mode 100644
index 0000000..d5162ea
Binary files /dev/null and b/phpmyadmin/themes/pmahomme/img/pmd/exec_small.png differ
diff --git a/phpmyadmin/themes/pmahomme/img/pmd/exitFullscreen.png b/phpmyadmin/themes/pmahomme/img/pmd/exitFullscreen.png
new file mode 100644
index 0000000..1683d55
Binary files /dev/null and b/phpmyadmin/themes/pmahomme/img/pmd/exitFullscreen.png differ
diff --git a/phpmyadmin/themes/pmahomme/img/pmd/favicon.ico b/phpmyadmin/themes/pmahomme/img/pmd/favicon.ico
new file mode 100644
index 0000000..29c2595
Binary files /dev/null and b/phpmyadmin/themes/pmahomme/img/pmd/favicon.ico differ
diff --git a/phpmyadmin/themes/pmahomme/img/pmd/grid.png b/phpmyadmin/themes/pmahomme/img/pmd/grid.png
new file mode 100644
index 0000000..6aee6e5
Binary files /dev/null and b/phpmyadmin/themes/pmahomme/img/pmd/grid.png differ
diff --git a/phpmyadmin/themes/pmahomme/img/pmd/help.png b/phpmyadmin/themes/pmahomme/img/pmd/help.png
new file mode 100644
index 0000000..fe200d8
Binary files /dev/null and b/phpmyadmin/themes/pmahomme/img/pmd/help.png differ
diff --git a/phpmyadmin/themes/pmahomme/img/pmd/help_relation.png b/phpmyadmin/themes/pmahomme/img/pmd/help_relation.png
new file mode 100644
index 0000000..8856604
Binary files /dev/null and b/phpmyadmin/themes/pmahomme/img/pmd/help_relation.png differ
diff --git a/phpmyadmin/themes/pmahomme/img/pmd/left_panel_butt.png b/phpmyadmin/themes/pmahomme/img/pmd/left_panel_butt.png
new file mode 100644
index 0000000..98ead4e
Binary files /dev/null and b/phpmyadmin/themes/pmahomme/img/pmd/left_panel_butt.png differ
diff --git a/phpmyadmin/themes/pmahomme/img/pmd/left_panel_tab.png b/phpmyadmin/themes/pmahomme/img/pmd/left_panel_tab.png
new file mode 100644
index 0000000..733588e
Binary files /dev/null and b/phpmyadmin/themes/pmahomme/img/pmd/left_panel_tab.png differ
diff --git a/phpmyadmin/themes/pmahomme/img/pmd/minus.png b/phpmyadmin/themes/pmahomme/img/pmd/minus.png
new file mode 100644
index 0000000..664956f
Binary files /dev/null and b/phpmyadmin/themes/pmahomme/img/pmd/minus.png differ
diff --git a/phpmyadmin/themes/pmahomme/img/pmd/or_icon.png b/phpmyadmin/themes/pmahomme/img/pmd/or_icon.png
new file mode 100644
index 0000000..5a12061
Binary files /dev/null and b/phpmyadmin/themes/pmahomme/img/pmd/or_icon.png differ
diff --git a/phpmyadmin/themes/pmahomme/img/pmd/pdf.png b/phpmyadmin/themes/pmahomme/img/pmd/pdf.png
new file mode 100644
index 0000000..8c110d3
Binary files /dev/null and b/phpmyadmin/themes/pmahomme/img/pmd/pdf.png differ
diff --git a/phpmyadmin/themes/pmahomme/img/pmd/plus.png b/phpmyadmin/themes/pmahomme/img/pmd/plus.png
new file mode 100644
index 0000000..11ef002
Binary files /dev/null and b/phpmyadmin/themes/pmahomme/img/pmd/plus.png differ
diff --git a/phpmyadmin/themes/pmahomme/img/pmd/query_builder.png b/phpmyadmin/themes/pmahomme/img/pmd/query_builder.png
new file mode 100644
index 0000000..13262f9
Binary files /dev/null and b/phpmyadmin/themes/pmahomme/img/pmd/query_builder.png differ
diff --git a/phpmyadmin/themes/pmahomme/img/pmd/relation.png b/phpmyadmin/themes/pmahomme/img/pmd/relation.png
new file mode 100644
index 0000000..ecc49fa
Binary files /dev/null and b/phpmyadmin/themes/pmahomme/img/pmd/relation.png differ
diff --git a/phpmyadmin/themes/pmahomme/img/pmd/reload.png b/phpmyadmin/themes/pmahomme/img/pmd/reload.png
new file mode 100644
index 0000000..63f0b6c
Binary files /dev/null and b/phpmyadmin/themes/pmahomme/img/pmd/reload.png differ
diff --git a/phpmyadmin/themes/pmahomme/img/pmd/resize.png b/phpmyadmin/themes/pmahomme/img/pmd/resize.png
new file mode 100644
index 0000000..3c0492a
Binary files /dev/null and b/phpmyadmin/themes/pmahomme/img/pmd/resize.png differ
diff --git a/phpmyadmin/themes/pmahomme/img/pmd/rightarrow1.png b/phpmyadmin/themes/pmahomme/img/pmd/rightarrow1.png
new file mode 100644
index 0000000..6d4f63b
Binary files /dev/null and b/phpmyadmin/themes/pmahomme/img/pmd/rightarrow1.png differ
diff --git a/phpmyadmin/themes/pmahomme/img/pmd/rightarrow2.png b/phpmyadmin/themes/pmahomme/img/pmd/rightarrow2.png
new file mode 100644
index 0000000..5cecf9e
Binary files /dev/null and b/phpmyadmin/themes/pmahomme/img/pmd/rightarrow2.png differ
diff --git a/phpmyadmin/themes/pmahomme/img/pmd/save.png b/phpmyadmin/themes/pmahomme/img/pmd/save.png
new file mode 100644
index 0000000..3e65b6a
Binary files /dev/null and b/phpmyadmin/themes/pmahomme/img/pmd/save.png differ
diff --git a/phpmyadmin/themes/pmahomme/img/pmd/small_tab.png b/phpmyadmin/themes/pmahomme/img/pmd/small_tab.png
new file mode 100644
index 0000000..bfa1b59
Binary files /dev/null and b/phpmyadmin/themes/pmahomme/img/pmd/small_tab.png differ
diff --git a/phpmyadmin/themes/pmahomme/img/pmd/table.png b/phpmyadmin/themes/pmahomme/img/pmd/table.png
new file mode 100644
index 0000000..caf214d
Binary files /dev/null and b/phpmyadmin/themes/pmahomme/img/pmd/table.png differ
diff --git a/phpmyadmin/themes/pmahomme/img/pmd/toggle_lines.png b/phpmyadmin/themes/pmahomme/img/pmd/toggle_lines.png
new file mode 100644
index 0000000..9ab3764
Binary files /dev/null and b/phpmyadmin/themes/pmahomme/img/pmd/toggle_lines.png differ
diff --git a/phpmyadmin/themes/pmahomme/img/pmd/top_panel.png b/phpmyadmin/themes/pmahomme/img/pmd/top_panel.png
new file mode 100644
index 0000000..6d8302f
Binary files /dev/null and b/phpmyadmin/themes/pmahomme/img/pmd/top_panel.png differ
diff --git a/phpmyadmin/themes/pmahomme/img/pmd/uparrow2_m.png b/phpmyadmin/themes/pmahomme/img/pmd/uparrow2_m.png
new file mode 100644
index 0000000..2c3b935
Binary files /dev/null and b/phpmyadmin/themes/pmahomme/img/pmd/uparrow2_m.png differ
diff --git a/phpmyadmin/themes/pmahomme/img/pmd/viewInFullscreen.png b/phpmyadmin/themes/pmahomme/img/pmd/viewInFullscreen.png
new file mode 100644
index 0000000..8692df6
Binary files /dev/null and b/phpmyadmin/themes/pmahomme/img/pmd/viewInFullscreen.png differ
diff --git a/phpmyadmin/themes/pmahomme/img/s_asc.png b/phpmyadmin/themes/pmahomme/img/s_asc.png
new file mode 100644
index 0000000..d518fa6
Binary files /dev/null and b/phpmyadmin/themes/pmahomme/img/s_asc.png differ
diff --git a/phpmyadmin/themes/pmahomme/img/s_asci.png b/phpmyadmin/themes/pmahomme/img/s_asci.png
new file mode 100644
index 0000000..da50ff9
Binary files /dev/null and b/phpmyadmin/themes/pmahomme/img/s_asci.png differ
diff --git a/phpmyadmin/themes/pmahomme/img/s_attention.png b/phpmyadmin/themes/pmahomme/img/s_attention.png
new file mode 100644
index 0000000..7f25781
Binary files /dev/null and b/phpmyadmin/themes/pmahomme/img/s_attention.png differ
diff --git a/phpmyadmin/themes/pmahomme/img/s_cancel.png b/phpmyadmin/themes/pmahomme/img/s_cancel.png
new file mode 100644
index 0000000..1997426
Binary files /dev/null and b/phpmyadmin/themes/pmahomme/img/s_cancel.png differ
diff --git a/phpmyadmin/themes/pmahomme/img/s_cancel2.png b/phpmyadmin/themes/pmahomme/img/s_cancel2.png
new file mode 100644
index 0000000..28c6083
Binary files /dev/null and b/phpmyadmin/themes/pmahomme/img/s_cancel2.png differ
diff --git a/phpmyadmin/themes/pmahomme/img/s_cog.png b/phpmyadmin/themes/pmahomme/img/s_cog.png
new file mode 100644
index 0000000..e90dd93
Binary files /dev/null and b/phpmyadmin/themes/pmahomme/img/s_cog.png differ
diff --git a/phpmyadmin/themes/pmahomme/img/s_db.png b/phpmyadmin/themes/pmahomme/img/s_db.png
new file mode 100644
index 0000000..9cc16be
Binary files /dev/null and b/phpmyadmin/themes/pmahomme/img/s_db.png differ
diff --git a/phpmyadmin/themes/pmahomme/img/s_desc.png b/phpmyadmin/themes/pmahomme/img/s_desc.png
new file mode 100644
index 0000000..f8d09cc
Binary files /dev/null and b/phpmyadmin/themes/pmahomme/img/s_desc.png differ
diff --git a/phpmyadmin/themes/pmahomme/img/s_error.png b/phpmyadmin/themes/pmahomme/img/s_error.png
new file mode 100644
index 0000000..bb615ff
Binary files /dev/null and b/phpmyadmin/themes/pmahomme/img/s_error.png differ
diff --git a/phpmyadmin/themes/pmahomme/img/s_error2.png b/phpmyadmin/themes/pmahomme/img/s_error2.png
new file mode 100644
index 0000000..e4f02e9
Binary files /dev/null and b/phpmyadmin/themes/pmahomme/img/s_error2.png differ
diff --git a/phpmyadmin/themes/pmahomme/img/s_fulltext.png b/phpmyadmin/themes/pmahomme/img/s_fulltext.png
new file mode 100644
index 0000000..9f8db13
Binary files /dev/null and b/phpmyadmin/themes/pmahomme/img/s_fulltext.png differ
diff --git a/phpmyadmin/themes/pmahomme/img/s_host.png b/phpmyadmin/themes/pmahomme/img/s_host.png
new file mode 100644
index 0000000..f27c337
Binary files /dev/null and b/phpmyadmin/themes/pmahomme/img/s_host.png differ
diff --git a/phpmyadmin/themes/pmahomme/img/s_info.png b/phpmyadmin/themes/pmahomme/img/s_info.png
new file mode 100644
index 0000000..f636683
Binary files /dev/null and b/phpmyadmin/themes/pmahomme/img/s_info.png differ
diff --git a/phpmyadmin/themes/pmahomme/img/s_lang.png b/phpmyadmin/themes/pmahomme/img/s_lang.png
new file mode 100644
index 0000000..a62fa50
Binary files /dev/null and b/phpmyadmin/themes/pmahomme/img/s_lang.png differ
diff --git a/phpmyadmin/themes/pmahomme/img/s_loggoff.png b/phpmyadmin/themes/pmahomme/img/s_loggoff.png
new file mode 100644
index 0000000..cc53f16
Binary files /dev/null and b/phpmyadmin/themes/pmahomme/img/s_loggoff.png differ
diff --git a/phpmyadmin/themes/pmahomme/img/s_notice.png b/phpmyadmin/themes/pmahomme/img/s_notice.png
new file mode 100644
index 0000000..7f25781
Binary files /dev/null and b/phpmyadmin/themes/pmahomme/img/s_notice.png differ
diff --git a/phpmyadmin/themes/pmahomme/img/s_okay.png b/phpmyadmin/themes/pmahomme/img/s_okay.png
new file mode 100644
index 0000000..5587dc6
Binary files /dev/null and b/phpmyadmin/themes/pmahomme/img/s_okay.png differ
diff --git a/phpmyadmin/themes/pmahomme/img/s_partialtext.png b/phpmyadmin/themes/pmahomme/img/s_partialtext.png
new file mode 100644
index 0000000..e671140
Binary files /dev/null and b/phpmyadmin/themes/pmahomme/img/s_partialtext.png differ
diff --git a/phpmyadmin/themes/pmahomme/img/s_passwd.png b/phpmyadmin/themes/pmahomme/img/s_passwd.png
new file mode 100644
index 0000000..82d6f26
Binary files /dev/null and b/phpmyadmin/themes/pmahomme/img/s_passwd.png differ
diff --git a/phpmyadmin/themes/pmahomme/img/s_process.png b/phpmyadmin/themes/pmahomme/img/s_process.png
new file mode 100644
index 0000000..e90dd93
Binary files /dev/null and b/phpmyadmin/themes/pmahomme/img/s_process.png differ
diff --git a/phpmyadmin/themes/pmahomme/img/s_really.png b/phpmyadmin/themes/pmahomme/img/s_really.png
new file mode 100644
index 0000000..f9902ef
Binary files /dev/null and b/phpmyadmin/themes/pmahomme/img/s_really.png differ
diff --git a/phpmyadmin/themes/pmahomme/img/s_reload.png b/phpmyadmin/themes/pmahomme/img/s_reload.png
new file mode 100644
index 0000000..345e687
Binary files /dev/null and b/phpmyadmin/themes/pmahomme/img/s_reload.png differ
diff --git a/phpmyadmin/themes/pmahomme/img/s_replication.png b/phpmyadmin/themes/pmahomme/img/s_replication.png
new file mode 100644
index 0000000..f51a177
Binary files /dev/null and b/phpmyadmin/themes/pmahomme/img/s_replication.png differ
diff --git a/phpmyadmin/themes/pmahomme/img/s_rights.png b/phpmyadmin/themes/pmahomme/img/s_rights.png
new file mode 100644
index 0000000..4fa395e
Binary files /dev/null and b/phpmyadmin/themes/pmahomme/img/s_rights.png differ
diff --git a/phpmyadmin/themes/pmahomme/img/s_sortable.png b/phpmyadmin/themes/pmahomme/img/s_sortable.png
new file mode 100644
index 0000000..e318e67
Binary files /dev/null and b/phpmyadmin/themes/pmahomme/img/s_sortable.png differ
diff --git a/phpmyadmin/themes/pmahomme/img/s_status.png b/phpmyadmin/themes/pmahomme/img/s_status.png
new file mode 100644
index 0000000..31dbb87
Binary files /dev/null and b/phpmyadmin/themes/pmahomme/img/s_status.png differ
diff --git a/phpmyadmin/themes/pmahomme/img/s_success.png b/phpmyadmin/themes/pmahomme/img/s_success.png
new file mode 100644
index 0000000..c9a2cfd
Binary files /dev/null and b/phpmyadmin/themes/pmahomme/img/s_success.png differ
diff --git a/phpmyadmin/themes/pmahomme/img/s_sync.png b/phpmyadmin/themes/pmahomme/img/s_sync.png
new file mode 100644
index 0000000..8545ba1
Binary files /dev/null and b/phpmyadmin/themes/pmahomme/img/s_sync.png differ
diff --git a/phpmyadmin/themes/pmahomme/img/s_tbl.png b/phpmyadmin/themes/pmahomme/img/s_tbl.png
new file mode 100644
index 0000000..437e76d
Binary files /dev/null and b/phpmyadmin/themes/pmahomme/img/s_tbl.png differ
diff --git a/phpmyadmin/themes/pmahomme/img/s_theme.png b/phpmyadmin/themes/pmahomme/img/s_theme.png
new file mode 100644
index 0000000..ca6feca
Binary files /dev/null and b/phpmyadmin/themes/pmahomme/img/s_theme.png differ
diff --git a/phpmyadmin/themes/pmahomme/img/s_top.png b/phpmyadmin/themes/pmahomme/img/s_top.png
new file mode 100644
index 0000000..de05174
Binary files /dev/null and b/phpmyadmin/themes/pmahomme/img/s_top.png differ
diff --git a/phpmyadmin/themes/pmahomme/img/s_vars.png b/phpmyadmin/themes/pmahomme/img/s_vars.png
new file mode 100644
index 0000000..73f060b
Binary files /dev/null and b/phpmyadmin/themes/pmahomme/img/s_vars.png differ
diff --git a/phpmyadmin/themes/pmahomme/img/s_views.png b/phpmyadmin/themes/pmahomme/img/s_views.png
new file mode 100644
index 0000000..b1c78e3
Binary files /dev/null and b/phpmyadmin/themes/pmahomme/img/s_views.png differ
diff --git a/phpmyadmin/themes/pmahomme/img/south-mini.png b/phpmyadmin/themes/pmahomme/img/south-mini.png
new file mode 100644
index 0000000..954c202
Binary files /dev/null and b/phpmyadmin/themes/pmahomme/img/south-mini.png differ
diff --git a/phpmyadmin/themes/pmahomme/img/spacer.png b/phpmyadmin/themes/pmahomme/img/spacer.png
new file mode 100644
index 0000000..c6008d7
Binary files /dev/null and b/phpmyadmin/themes/pmahomme/img/spacer.png differ
diff --git a/phpmyadmin/themes/pmahomme/img/sprites.png b/phpmyadmin/themes/pmahomme/img/sprites.png
new file mode 100644
index 0000000..318a435
Binary files /dev/null and b/phpmyadmin/themes/pmahomme/img/sprites.png differ
diff --git a/phpmyadmin/themes/pmahomme/img/toggle-ltr.png b/phpmyadmin/themes/pmahomme/img/toggle-ltr.png
new file mode 100644
index 0000000..964340c
Binary files /dev/null and b/phpmyadmin/themes/pmahomme/img/toggle-ltr.png differ
diff --git a/phpmyadmin/themes/pmahomme/img/toggle-rtl.png b/phpmyadmin/themes/pmahomme/img/toggle-rtl.png
new file mode 100644
index 0000000..c9b23b0
Binary files /dev/null and b/phpmyadmin/themes/pmahomme/img/toggle-rtl.png differ
diff --git a/phpmyadmin/themes/pmahomme/img/vertical_line.png b/phpmyadmin/themes/pmahomme/img/vertical_line.png
new file mode 100644
index 0000000..188417b
Binary files /dev/null and b/phpmyadmin/themes/pmahomme/img/vertical_line.png differ
diff --git a/phpmyadmin/themes/pmahomme/img/west-mini.png b/phpmyadmin/themes/pmahomme/img/west-mini.png
new file mode 100644
index 0000000..a13f083
Binary files /dev/null and b/phpmyadmin/themes/pmahomme/img/west-mini.png differ
diff --git a/phpmyadmin/themes/pmahomme/img/window-new.png b/phpmyadmin/themes/pmahomme/img/window-new.png
new file mode 100644
index 0000000..431fe85
Binary files /dev/null and b/phpmyadmin/themes/pmahomme/img/window-new.png differ
diff --git a/phpmyadmin/themes/pmahomme/img/zoom-minus-mini.png b/phpmyadmin/themes/pmahomme/img/zoom-minus-mini.png
new file mode 100644
index 0000000..4262ad4
Binary files /dev/null and b/phpmyadmin/themes/pmahomme/img/zoom-minus-mini.png differ
diff --git a/phpmyadmin/themes/pmahomme/img/zoom-plus-mini.png b/phpmyadmin/themes/pmahomme/img/zoom-plus-mini.png
new file mode 100644
index 0000000..4fabfd1
Binary files /dev/null and b/phpmyadmin/themes/pmahomme/img/zoom-plus-mini.png differ
diff --git a/phpmyadmin/themes/pmahomme/img/zoom-world-mini.png b/phpmyadmin/themes/pmahomme/img/zoom-world-mini.png
new file mode 100644
index 0000000..f50ca66
Binary files /dev/null and b/phpmyadmin/themes/pmahomme/img/zoom-world-mini.png differ
diff --git a/phpmyadmin/themes/pmahomme/info.inc.php b/phpmyadmin/themes/pmahomme/info.inc.php
new file mode 100644
index 0000000..d45f8ee
--- /dev/null
+++ b/phpmyadmin/themes/pmahomme/info.inc.php
@@ -0,0 +1,16 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * Theme information
+ *
+ * @package    PhpMyAdmin-theme
+ * @subpackage PMAHomme
+ */
+
+/**
+ * If you have problems or questions about this theme email
+ * mikehomme at users.sourceforge.net
+ */
+$theme_name = 'pmahomme';
+$theme_full_version = '1.1';
+?>
diff --git a/phpmyadmin/themes/pmahomme/jquery/images/ui-bg_flat_0_aaaaaa_40x100.png b/phpmyadmin/themes/pmahomme/jquery/images/ui-bg_flat_0_aaaaaa_40x100.png
new file mode 100644
index 0000000..5b5dab2
Binary files /dev/null and b/phpmyadmin/themes/pmahomme/jquery/images/ui-bg_flat_0_aaaaaa_40x100.png differ
diff --git a/phpmyadmin/themes/pmahomme/jquery/images/ui-bg_flat_75_ffffff_40x100.png b/phpmyadmin/themes/pmahomme/jquery/images/ui-bg_flat_75_ffffff_40x100.png
new file mode 100644
index 0000000..ac8b229
Binary files /dev/null and b/phpmyadmin/themes/pmahomme/jquery/images/ui-bg_flat_75_ffffff_40x100.png differ
diff --git a/phpmyadmin/themes/pmahomme/jquery/images/ui-bg_glass_55_fbf9ee_1x400.png b/phpmyadmin/themes/pmahomme/jquery/images/ui-bg_glass_55_fbf9ee_1x400.png
new file mode 100644
index 0000000..ad3d634
Binary files /dev/null and b/phpmyadmin/themes/pmahomme/jquery/images/ui-bg_glass_55_fbf9ee_1x400.png differ
diff --git a/phpmyadmin/themes/pmahomme/jquery/images/ui-bg_glass_65_ffffff_1x400.png b/phpmyadmin/themes/pmahomme/jquery/images/ui-bg_glass_65_ffffff_1x400.png
new file mode 100644
index 0000000..42ccba2
Binary files /dev/null and b/phpmyadmin/themes/pmahomme/jquery/images/ui-bg_glass_65_ffffff_1x400.png differ
diff --git a/phpmyadmin/themes/pmahomme/jquery/images/ui-bg_glass_75_dadada_1x400.png b/phpmyadmin/themes/pmahomme/jquery/images/ui-bg_glass_75_dadada_1x400.png
new file mode 100644
index 0000000..1d43b47
Binary files /dev/null and b/phpmyadmin/themes/pmahomme/jquery/images/ui-bg_glass_75_dadada_1x400.png differ
diff --git a/phpmyadmin/themes/pmahomme/jquery/images/ui-bg_glass_75_e6e6e6_1x400.png b/phpmyadmin/themes/pmahomme/jquery/images/ui-bg_glass_75_e6e6e6_1x400.png
new file mode 100644
index 0000000..86c2baa
Binary files /dev/null and b/phpmyadmin/themes/pmahomme/jquery/images/ui-bg_glass_75_e6e6e6_1x400.png differ
diff --git a/phpmyadmin/themes/pmahomme/jquery/images/ui-bg_glass_95_fef1ec_1x400.png b/phpmyadmin/themes/pmahomme/jquery/images/ui-bg_glass_95_fef1ec_1x400.png
new file mode 100644
index 0000000..4443fdc
Binary files /dev/null and b/phpmyadmin/themes/pmahomme/jquery/images/ui-bg_glass_95_fef1ec_1x400.png differ
diff --git a/phpmyadmin/themes/pmahomme/jquery/images/ui-bg_highlight-soft_75_cccccc_1x100.png b/phpmyadmin/themes/pmahomme/jquery/images/ui-bg_highlight-soft_75_cccccc_1x100.png
new file mode 100644
index 0000000..7c9fa6c
Binary files /dev/null and b/phpmyadmin/themes/pmahomme/jquery/images/ui-bg_highlight-soft_75_cccccc_1x100.png differ
diff --git a/phpmyadmin/themes/pmahomme/jquery/images/ui-icons_222222_256x240.png b/phpmyadmin/themes/pmahomme/jquery/images/ui-icons_222222_256x240.png
new file mode 100644
index 0000000..b273ff1
Binary files /dev/null and b/phpmyadmin/themes/pmahomme/jquery/images/ui-icons_222222_256x240.png differ
diff --git a/phpmyadmin/themes/pmahomme/jquery/images/ui-icons_2e83ff_256x240.png b/phpmyadmin/themes/pmahomme/jquery/images/ui-icons_2e83ff_256x240.png
new file mode 100644
index 0000000..09d1cdc
Binary files /dev/null and b/phpmyadmin/themes/pmahomme/jquery/images/ui-icons_2e83ff_256x240.png differ
diff --git a/phpmyadmin/themes/pmahomme/jquery/images/ui-icons_454545_256x240.png b/phpmyadmin/themes/pmahomme/jquery/images/ui-icons_454545_256x240.png
new file mode 100644
index 0000000..59bd45b
Binary files /dev/null and b/phpmyadmin/themes/pmahomme/jquery/images/ui-icons_454545_256x240.png differ
diff --git a/phpmyadmin/themes/pmahomme/jquery/images/ui-icons_888888_256x240.png b/phpmyadmin/themes/pmahomme/jquery/images/ui-icons_888888_256x240.png
new file mode 100644
index 0000000..6d02426
Binary files /dev/null and b/phpmyadmin/themes/pmahomme/jquery/images/ui-icons_888888_256x240.png differ
diff --git a/phpmyadmin/themes/pmahomme/jquery/images/ui-icons_cd0a0a_256x240.png b/phpmyadmin/themes/pmahomme/jquery/images/ui-icons_cd0a0a_256x240.png
new file mode 100644
index 0000000..2ab019b
Binary files /dev/null and b/phpmyadmin/themes/pmahomme/jquery/images/ui-icons_cd0a0a_256x240.png differ
diff --git a/phpmyadmin/themes/pmahomme/jquery/jquery-ui-1.9.2.custom.css b/phpmyadmin/themes/pmahomme/jquery/jquery-ui-1.9.2.custom.css
new file mode 100644
index 0000000..b08d903
--- /dev/null
+++ b/phpmyadmin/themes/pmahomme/jquery/jquery-ui-1.9.2.custom.css
@@ -0,0 +1,462 @@
+/*! jQuery UI - v1.9.2 - 2012-12-19
+* http://jqueryui.com
+* Includes: jquery.ui.core.css, jquery.ui.resizable.css, jquery.ui.selectable.css, jquery.ui.accordion.css, jquery.ui.autocomplete.css, jquery.ui.button.css, jquery.ui.datepicker.css, jquery.ui.dialog.css, jquery.ui.menu.css, jquery.ui.progressbar.css, jquery.ui.slider.css, jquery.ui.spinner.css, jquery.ui.tabs.css, jquery.ui.tooltip.css
+* To view and modify this theme, visit http://jqueryui.com/themeroller/?ffDefault=Verdana%2CArial%2Csans-serif&fwDefault=normal&fsDefault=1.1em&cornerRadius=4px&bgColorHeader=cccccc&bgTextureHeader=03_highlight_soft.png&bgImgOpacityHeader=75&borderColorHeader=aaaaaa&fcHeader=222222&iconColorHeader=222222&bgColorContent=ffffff&bgTextureContent=01_flat.png&bgImgOpacityContent=75&borderColorContent=aaaaaa&fcContent=222222&iconColorContent=222222&bgColorDefault=e6e6e6&bgTextureDefault=02_gla [...]
+* Copyright (c) 2012 jQuery Foundation and other contributors Licensed MIT */
+
+/* Layout helpers
+----------------------------------*/
+.ui-helper-hidden { display: none; }
+.ui-helper-hidden-accessible { border: 0; clip: rect(0 0 0 0); height: 1px; margin: -1px; overflow: hidden; padding: 0; position: absolute; width: 1px; }
+.ui-helper-reset { margin: 0; padding: 0; border: 0; outline: 0; line-height: 1.3; text-decoration: none; font-size: 100%; list-style: none; }
+.ui-helper-clearfix:before, .ui-helper-clearfix:after { content: ""; display: table; }
+.ui-helper-clearfix:after { clear: both; }
+.ui-helper-clearfix { zoom: 1; }
+.ui-helper-zfix { width: 100%; height: 100%; top: 0; left: 0; position: absolute; opacity: 0; filter:Alpha(Opacity=0); }
+
+
+/* Interaction Cues
+----------------------------------*/
+.ui-state-disabled { cursor: default !important; }
+
+
+/* Icons
+----------------------------------*/
+
+/* states and images */
+.ui-icon { display: block; text-indent: -99999px; overflow: hidden; background-repeat: no-repeat; }
+
+
+/* Misc visuals
+----------------------------------*/
+
+/* Overlays */
+.ui-widget-overlay { position: absolute; top: 0; left: 0; width: 100%; height: 100%; }
+.ui-resizable { position: relative;}
+.ui-resizable-handle { position: absolute;font-size: 0.1px; display: block; }
+.ui-resizable-disabled .ui-resizable-handle, .ui-resizable-autohide .ui-resizable-handle { display: none; }
+.ui-resizable-n { cursor: n-resize; height: 7px; width: 100%; top: -5px; left: 0; }
+.ui-resizable-s { cursor: s-resize; height: 7px; width: 100%; bottom: -5px; left: 0; }
+.ui-resizable-e { cursor: e-resize; width: 7px; right: -5px; top: 0; height: 100%; }
+.ui-resizable-w { cursor: w-resize; width: 7px; left: -5px; top: 0; height: 100%; }
+.ui-resizable-se { cursor: se-resize; width: 12px; height: 12px; right: 1px; bottom: 1px; }
+.ui-resizable-sw { cursor: sw-resize; width: 9px; height: 9px; left: -5px; bottom: -5px; }
+.ui-resizable-nw { cursor: nw-resize; width: 9px; height: 9px; left: -5px; top: -5px; }
+.ui-resizable-ne { cursor: ne-resize; width: 9px; height: 9px; right: -5px; top: -5px;}.ui-selectable-helper { position: absolute; z-index: 100; border:1px dotted black; }
+.ui-accordion .ui-accordion-header { display: block; cursor: pointer; position: relative; margin-top: 2px; padding: .5em .5em .5em .7em; zoom: 1; }
+.ui-accordion .ui-accordion-icons { padding-left: 2.2em; }
+.ui-accordion .ui-accordion-noicons { padding-left: .7em; }
+.ui-accordion .ui-accordion-icons .ui-accordion-icons { padding-left: 2.2em; }
+.ui-accordion .ui-accordion-header .ui-accordion-header-icon { position: absolute; left: .5em; top: 50%; margin-top: -8px; }
+.ui-accordion .ui-accordion-content { padding: 1em 2.2em; border-top: 0; overflow: auto; zoom: 1; }
+.ui-autocomplete {
+	position: absolute;
+	top: 0;
+	left: 0;
+	cursor: default;
+}
+
+/* workarounds */
+* html .ui-autocomplete { width:1px; } /* without this, the menu expands to 100% in IE6 */
+.ui-button { display: inline-block; position: relative; padding: 0; margin-right: .1em; cursor: pointer; text-align: center; zoom: 1; overflow: visible; } /* the overflow property removes extra width in IE */
+.ui-button, .ui-button:link, .ui-button:visited, .ui-button:hover, .ui-button:active { text-decoration: none; }
+.ui-button-icon-only { width: 2.2em; } /* to make room for the icon, a width needs to be set here */
+button.ui-button-icon-only { width: 2.4em; } /* button elements seem to need a little more width */
+.ui-button-icons-only { width: 3.4em; } 
+button.ui-button-icons-only { width: 3.7em; } 
+
+/*button text element */
+.ui-button .ui-button-text { display: block; line-height: 1.4;  }
+.ui-button-text-only .ui-button-text { padding: .4em 1em; }
+.ui-button-icon-only .ui-button-text, .ui-button-icons-only .ui-button-text { padding: .4em; text-indent: -9999999px; }
+.ui-button-text-icon-primary .ui-button-text, .ui-button-text-icons .ui-button-text { padding: .4em 1em .4em 2.1em; }
+.ui-button-text-icon-secondary .ui-button-text, .ui-button-text-icons .ui-button-text { padding: .4em 2.1em .4em 1em; }
+.ui-button-text-icons .ui-button-text { padding-left: 2.1em; padding-right: 2.1em; }
+/* no icon support for input elements, provide padding by default */
+input.ui-button { padding: .4em 1em; }
+
+/*button icon element(s) */
+.ui-button-icon-only .ui-icon, .ui-button-text-icon-primary .ui-icon, .ui-button-text-icon-secondary .ui-icon, .ui-button-text-icons .ui-icon, .ui-button-icons-only .ui-icon { position: absolute; top: 50%; margin-top: -8px; }
+.ui-button-icon-only .ui-icon { left: 50%; margin-left: -8px; }
+.ui-button-text-icon-primary .ui-button-icon-primary, .ui-button-text-icons .ui-button-icon-primary, .ui-button-icons-only .ui-button-icon-primary { left: .5em; }
+.ui-button-text-icon-secondary .ui-button-icon-secondary, .ui-button-text-icons .ui-button-icon-secondary, .ui-button-icons-only .ui-button-icon-secondary { right: .5em; }
+.ui-button-text-icons .ui-button-icon-secondary, .ui-button-icons-only .ui-button-icon-secondary { right: .5em; }
+
+/*button sets*/
+.ui-buttonset { margin-right: 7px; }
+.ui-buttonset .ui-button { margin-left: 0; margin-right: -.3em; }
+
+/* workarounds */
+button.ui-button::-moz-focus-inner { border: 0; padding: 0; } /* reset extra padding in Firefox */
+.ui-datepicker { width: 17em; padding: .2em .2em 0; display: none; }
+.ui-datepicker .ui-datepicker-header { position:relative; padding:.2em 0; }
+.ui-datepicker .ui-datepicker-prev, .ui-datepicker .ui-datepicker-next { position:absolute; top: 2px; width: 1.8em; height: 1.8em; }
+.ui-datepicker .ui-datepicker-prev-hover, .ui-datepicker .ui-datepicker-next-hover { top: 1px; }
+.ui-datepicker .ui-datepicker-prev { left:2px; }
+.ui-datepicker .ui-datepicker-next { right:2px; }
+.ui-datepicker .ui-datepicker-prev-hover { left:1px; }
+.ui-datepicker .ui-datepicker-next-hover { right:1px; }
+.ui-datepicker .ui-datepicker-prev span, .ui-datepicker .ui-datepicker-next span { display: block; position: absolute; left: 50%; margin-left: -8px; top: 50%; margin-top: -8px;  }
+.ui-datepicker .ui-datepicker-title { margin: 0 2.3em; line-height: 1.8em; text-align: center; }
+.ui-datepicker .ui-datepicker-title select { font-size:1em; margin:1px 0; }
+.ui-datepicker select.ui-datepicker-month-year {width: 100%;}
+.ui-datepicker select.ui-datepicker-month, 
+.ui-datepicker select.ui-datepicker-year { width: 49%;}
+.ui-datepicker table {width: 100%; font-size: .9em; border-collapse: collapse; margin:0 0 .4em; }
+.ui-datepicker th { padding: .7em .3em; text-align: center; font-weight: bold; border: 0;  }
+.ui-datepicker td { border: 0; padding: 1px; }
+.ui-datepicker td span, .ui-datepicker td a { display: block; padding: .2em; text-align: right; text-decoration: none; }
+.ui-datepicker .ui-datepicker-buttonpane { background-image: none; margin: .7em 0 0 0; padding:0 .2em; border-left: 0; border-right: 0; border-bottom: 0; }
+.ui-datepicker .ui-datepicker-buttonpane button { float: right; margin: .5em .2em .4em; cursor: pointer; padding: .2em .6em .3em .6em; width:auto; overflow:visible; }
+.ui-datepicker .ui-datepicker-buttonpane button.ui-datepicker-current { float:left; }
+
+/* with multiple calendars */
+.ui-datepicker.ui-datepicker-multi { width:auto; }
+.ui-datepicker-multi .ui-datepicker-group { float:left; }
+.ui-datepicker-multi .ui-datepicker-group table { width:95%; margin:0 auto .4em; }
+.ui-datepicker-multi-2 .ui-datepicker-group { width:50%; }
+.ui-datepicker-multi-3 .ui-datepicker-group { width:33.3%; }
+.ui-datepicker-multi-4 .ui-datepicker-group { width:25%; }
+.ui-datepicker-multi .ui-datepicker-group-last .ui-datepicker-header { border-left-width:0; }
+.ui-datepicker-multi .ui-datepicker-group-middle .ui-datepicker-header { border-left-width:0; }
+.ui-datepicker-multi .ui-datepicker-buttonpane { clear:left; }
+.ui-datepicker-row-break { clear:both; width:100%; font-size:0em; }
+
+/* RTL support */
+.ui-datepicker-rtl { direction: rtl; }
+.ui-datepicker-rtl .ui-datepicker-prev { right: 2px; left: auto; }
+.ui-datepicker-rtl .ui-datepicker-next { left: 2px; right: auto; }
+.ui-datepicker-rtl .ui-datepicker-prev:hover { right: 1px; left: auto; }
+.ui-datepicker-rtl .ui-datepicker-next:hover { left: 1px; right: auto; }
+.ui-datepicker-rtl .ui-datepicker-buttonpane { clear:right; }
+.ui-datepicker-rtl .ui-datepicker-buttonpane button { float: left; }
+.ui-datepicker-rtl .ui-datepicker-buttonpane button.ui-datepicker-current { float:right; }
+.ui-datepicker-rtl .ui-datepicker-group { float:right; }
+.ui-datepicker-rtl .ui-datepicker-group-last .ui-datepicker-header { border-right-width:0; border-left-width:1px; }
+.ui-datepicker-rtl .ui-datepicker-group-middle .ui-datepicker-header { border-right-width:0; border-left-width:1px; }
+
+/* IE6 IFRAME FIX (taken from datepicker 1.5.3 */
+.ui-datepicker-cover {
+    position: absolute; /*must have*/
+    z-index: -1; /*must have*/
+    filter: mask(); /*must have*/
+    top: -4px; /*must have*/
+    left: -4px; /*must have*/
+    width: 200px; /*must have*/
+    height: 200px; /*must have*/
+}.ui-dialog { position: absolute; top: 0; left: 0; padding: .2em; width: 300px; overflow: hidden; }
+.ui-dialog .ui-dialog-titlebar { padding: .4em 1em; position: relative;  }
+.ui-dialog .ui-dialog-title { float: left; margin: .1em 16px .1em 0; }
+.ui-dialog .ui-dialog-titlebar-close { position: absolute; right: .3em; top: 50%; width: 19px; margin: -10px 0 0 0; padding: 1px; height: 18px; }
+.ui-dialog .ui-dialog-titlebar-close span { display: block; margin: 1px; }
+.ui-dialog .ui-dialog-titlebar-close:hover, .ui-dialog .ui-dialog-titlebar-close:focus { padding: 0; }
+.ui-dialog .ui-dialog-content { position: relative; border: 0; padding: .5em 1em; background: none; overflow: auto; zoom: 1; }
+.ui-dialog .ui-dialog-buttonpane { text-align: left; border-width: 1px 0 0 0; background-image: none; margin: .5em 0 0 0; padding: .3em 1em .5em .4em; }
+.ui-dialog .ui-dialog-buttonpane .ui-dialog-buttonset { float: right; }
+.ui-dialog .ui-dialog-buttonpane button { margin: .5em .4em .5em 0; cursor: pointer; }
+.ui-dialog .ui-resizable-se { width: 14px; height: 14px; right: 3px; bottom: 3px; }
+.ui-draggable .ui-dialog-titlebar { cursor: move; }
+.ui-menu { list-style:none; padding: 2px; margin: 0; display:block; outline: none; }
+.ui-menu .ui-menu { margin-top: -3px; position: absolute; }
+.ui-menu .ui-menu-item { margin: 0; padding: 0; zoom: 1; width: 100%; }
+.ui-menu .ui-menu-divider { margin: 5px -2px 5px -2px; height: 0; font-size: 0; line-height: 0; border-width: 1px 0 0 0; }
+.ui-menu .ui-menu-item a { text-decoration: none; display: block; padding: 2px .4em; line-height: 1.5; zoom: 1; font-weight: normal; }
+.ui-menu .ui-menu-item a.ui-state-focus,
+.ui-menu .ui-menu-item a.ui-state-active { font-weight: normal; margin: -1px; }
+
+.ui-menu .ui-state-disabled { font-weight: normal; margin: .4em 0 .2em; line-height: 1.5; }
+.ui-menu .ui-state-disabled a { cursor: default; }
+
+/* icon support */
+.ui-menu-icons { position: relative; }
+.ui-menu-icons .ui-menu-item a { position: relative; padding-left: 2em; }
+
+/* left-aligned */
+.ui-menu .ui-icon { position: absolute; top: .2em; left: .2em; }
+
+/* right-aligned */
+.ui-menu .ui-menu-icon { position: static; float: right; }
+.ui-progressbar { height:2em; text-align: left; overflow: hidden; }
+.ui-progressbar .ui-progressbar-value {margin: -1px; height:100%; }.ui-slider { position: relative; text-align: left; }
+.ui-slider .ui-slider-handle { position: absolute; z-index: 2; width: 1.2em; height: 1.2em; cursor: default; }
+.ui-slider .ui-slider-range { position: absolute; z-index: 1; font-size: .7em; display: block; border: 0; background-position: 0 0; }
+
+.ui-slider-horizontal { height: .8em; }
+.ui-slider-horizontal .ui-slider-handle { top: -.3em; margin-left: -.6em; }
+.ui-slider-horizontal .ui-slider-range { top: 0; height: 100%; }
+.ui-slider-horizontal .ui-slider-range-min { left: 0; }
+.ui-slider-horizontal .ui-slider-range-max { right: 0; }
+
+.ui-slider-vertical { width: .8em; height: 100px; }
+.ui-slider-vertical .ui-slider-handle { left: -.3em; margin-left: 0; margin-bottom: -.6em; }
+.ui-slider-vertical .ui-slider-range { left: 0; width: 100%; }
+.ui-slider-vertical .ui-slider-range-min { bottom: 0; }
+.ui-slider-vertical .ui-slider-range-max { top: 0; }.ui-spinner { position:relative; display: inline-block; overflow: hidden; padding: 0; vertical-align: middle; }
+.ui-spinner-input { border: none; background: none; padding: 0; margin: .2em 0; vertical-align: middle; margin-left: .4em; margin-right: 22px; }
+.ui-spinner-button { width: 16px; height: 50%; font-size: .5em; padding: 0; margin: 0; text-align: center; position: absolute; cursor: default; display: block; overflow: hidden; right: 0; }
+.ui-spinner a.ui-spinner-button { border-top: none; border-bottom: none; border-right: none; } /* more specificity required here to overide default borders */
+.ui-spinner .ui-icon { position: absolute; margin-top: -8px; top: 50%; left: 0; } /* vertical centre icon */
+.ui-spinner-up { top: 0; }
+.ui-spinner-down { bottom: 0; }
+
+/* TR overrides */
+.ui-spinner .ui-icon-triangle-1-s {
+	/* need to fix icons sprite */
+	background-position:-65px -16px;
+}
+.ui-tabs { position: relative; padding: .2em; zoom: 1; } /* position: relative prevents IE scroll bug (element with position: relative inside container with overflow: auto appear as "fixed") */
+.ui-tabs .ui-tabs-nav { margin: 0; padding: .2em .2em 0; }
+.ui-tabs .ui-tabs-nav li { list-style: none; float: left; position: relative; top: 0; margin: 1px .2em 0 0; border-bottom: 0; padding: 0; white-space: nowrap; }
+.ui-tabs .ui-tabs-nav li a { float: left; padding: .5em 1em; text-decoration: none; }
+.ui-tabs .ui-tabs-nav li.ui-tabs-active { margin-bottom: -1px; padding-bottom: 1px; }
+.ui-tabs .ui-tabs-nav li.ui-tabs-active a, .ui-tabs .ui-tabs-nav li.ui-state-disabled a, .ui-tabs .ui-tabs-nav li.ui-tabs-loading a { cursor: text; }
+.ui-tabs .ui-tabs-nav li a, .ui-tabs-collapsible .ui-tabs-nav li.ui-tabs-active a { cursor: pointer; } /* first selector in group seems obsolete, but required to overcome bug in Opera applying cursor: text overall if defined elsewhere... */
+.ui-tabs .ui-tabs-panel { display: block; border-width: 0; padding: 1em 1.4em; background: none; }
+.ui-tooltip {
+	padding: 8px;
+	position: absolute;
+	z-index: 9999;
+	max-width: 300px;
+	-webkit-box-shadow: 0 0 5px #aaa;
+	box-shadow: 0 0 5px #aaa;
+}
+/* Fades and background-images don't work well together in IE6, drop the image */
+* html .ui-tooltip {
+	background-image: none;
+}
+body .ui-tooltip { border-width: 2px; }
+
+/* Component containers
+----------------------------------*/
+.ui-widget { font-family: Verdana,Arial,sans-serif; font-size: 1.1em; }
+.ui-widget .ui-widget { font-size: 1em; }
+.ui-widget input, .ui-widget select, .ui-widget textarea, .ui-widget button { font-family: Verdana,Arial,sans-serif; font-size: 1em; }
+.ui-widget-content { border: 1px solid #aaaaaa; background: #ffffff url(images/ui-bg_flat_75_ffffff_40x100.png) 50% 50% repeat-x; color: #222222; }
+.ui-widget-content a { color: #222222; }
+.ui-widget-header { border: 1px solid #aaaaaa; background: #cccccc url(images/ui-bg_highlight-soft_75_cccccc_1x100.png) 50% 50% repeat-x; color: #222222; font-weight: bold; }
+.ui-widget-header a { color: #222222; }
+
+/* Interaction states
+----------------------------------*/
+.ui-state-default, .ui-widget-content .ui-state-default, .ui-widget-header .ui-state-default { border: 1px solid #d3d3d3; background: #e6e6e6 url(images/ui-bg_glass_75_e6e6e6_1x400.png) 50% 50% repeat-x; font-weight: normal; color: #555555; }
+.ui-state-default a, .ui-state-default a:link, .ui-state-default a:visited { color: #555555; text-decoration: none; }
+.ui-state-hover, .ui-widget-content .ui-state-hover, .ui-widget-header .ui-state-hover, .ui-state-focus, .ui-widget-content .ui-state-focus, .ui-widget-header .ui-state-focus { border: 1px solid #999999; background: #dadada url(images/ui-bg_glass_75_dadada_1x400.png) 50% 50% repeat-x; font-weight: normal; color: #212121; }
+.ui-state-hover a, .ui-state-hover a:hover, .ui-state-hover a:link, .ui-state-hover a:visited { color: #212121; text-decoration: none; }
+.ui-state-active, .ui-widget-content .ui-state-active, .ui-widget-header .ui-state-active { border: 1px solid #aaaaaa; background: #ffffff url(images/ui-bg_glass_65_ffffff_1x400.png) 50% 50% repeat-x; font-weight: normal; color: #212121; }
+.ui-state-active a, .ui-state-active a:link, .ui-state-active a:visited { color: #212121; text-decoration: none; }
+
+/* Interaction Cues
+----------------------------------*/
+.ui-state-highlight, .ui-widget-content .ui-state-highlight, .ui-widget-header .ui-state-highlight  {border: 1px solid #fcefa1; background: #fbf9ee url(images/ui-bg_glass_55_fbf9ee_1x400.png) 50% 50% repeat-x; color: #363636; }
+.ui-state-highlight a, .ui-widget-content .ui-state-highlight a,.ui-widget-header .ui-state-highlight a { color: #363636; }
+.ui-state-error, .ui-widget-content .ui-state-error, .ui-widget-header .ui-state-error {border: 1px solid #cd0a0a; background: #fef1ec url(images/ui-bg_glass_95_fef1ec_1x400.png) 50% 50% repeat-x; color: #cd0a0a; }
+.ui-state-error a, .ui-widget-content .ui-state-error a, .ui-widget-header .ui-state-error a { color: #cd0a0a; }
+.ui-state-error-text, .ui-widget-content .ui-state-error-text, .ui-widget-header .ui-state-error-text { color: #cd0a0a; }
+.ui-priority-primary, .ui-widget-content .ui-priority-primary, .ui-widget-header .ui-priority-primary { font-weight: bold; }
+.ui-priority-secondary, .ui-widget-content .ui-priority-secondary,  .ui-widget-header .ui-priority-secondary { opacity: .7; filter:Alpha(Opacity=70); font-weight: normal; }
+.ui-state-disabled, .ui-widget-content .ui-state-disabled, .ui-widget-header .ui-state-disabled { opacity: .35; filter:Alpha(Opacity=35); background-image: none; }
+.ui-state-disabled .ui-icon { filter:Alpha(Opacity=35); } /* For IE8 - See #6059 */
+
+/* Icons
+----------------------------------*/
+
+/* states and images */
+.ui-icon { width: 16px; height: 16px; background-image: url(images/ui-icons_222222_256x240.png); }
+.ui-widget-content .ui-icon {background-image: url(images/ui-icons_222222_256x240.png); }
+.ui-widget-header .ui-icon {background-image: url(images/ui-icons_222222_256x240.png); }
+.ui-state-default .ui-icon { background-image: url(images/ui-icons_888888_256x240.png); }
+.ui-state-hover .ui-icon, .ui-state-focus .ui-icon {background-image: url(images/ui-icons_454545_256x240.png); }
+.ui-state-active .ui-icon {background-image: url(images/ui-icons_454545_256x240.png); }
+.ui-state-highlight .ui-icon {background-image: url(images/ui-icons_2e83ff_256x240.png); }
+.ui-state-error .ui-icon, .ui-state-error-text .ui-icon {background-image: url(images/ui-icons_cd0a0a_256x240.png); }
+
+/* positioning */
+.ui-icon-carat-1-n { background-position: 0 0; }
+.ui-icon-carat-1-ne { background-position: -16px 0; }
+.ui-icon-carat-1-e { background-position: -32px 0; }
+.ui-icon-carat-1-se { background-position: -48px 0; }
+.ui-icon-carat-1-s { background-position: -64px 0; }
+.ui-icon-carat-1-sw { background-position: -80px 0; }
+.ui-icon-carat-1-w { background-position: -96px 0; }
+.ui-icon-carat-1-nw { background-position: -112px 0; }
+.ui-icon-carat-2-n-s { background-position: -128px 0; }
+.ui-icon-carat-2-e-w { background-position: -144px 0; }
+.ui-icon-triangle-1-n { background-position: 0 -16px; }
+.ui-icon-triangle-1-ne { background-position: -16px -16px; }
+.ui-icon-triangle-1-e { background-position: -32px -16px; }
+.ui-icon-triangle-1-se { background-position: -48px -16px; }
+.ui-icon-triangle-1-s { background-position: -64px -16px; }
+.ui-icon-triangle-1-sw { background-position: -80px -16px; }
+.ui-icon-triangle-1-w { background-position: -96px -16px; }
+.ui-icon-triangle-1-nw { background-position: -112px -16px; }
+.ui-icon-triangle-2-n-s { background-position: -128px -16px; }
+.ui-icon-triangle-2-e-w { background-position: -144px -16px; }
+.ui-icon-arrow-1-n { background-position: 0 -32px; }
+.ui-icon-arrow-1-ne { background-position: -16px -32px; }
+.ui-icon-arrow-1-e { background-position: -32px -32px; }
+.ui-icon-arrow-1-se { background-position: -48px -32px; }
+.ui-icon-arrow-1-s { background-position: -64px -32px; }
+.ui-icon-arrow-1-sw { background-position: -80px -32px; }
+.ui-icon-arrow-1-w { background-position: -96px -32px; }
+.ui-icon-arrow-1-nw { background-position: -112px -32px; }
+.ui-icon-arrow-2-n-s { background-position: -128px -32px; }
+.ui-icon-arrow-2-ne-sw { background-position: -144px -32px; }
+.ui-icon-arrow-2-e-w { background-position: -160px -32px; }
+.ui-icon-arrow-2-se-nw { background-position: -176px -32px; }
+.ui-icon-arrowstop-1-n { background-position: -192px -32px; }
+.ui-icon-arrowstop-1-e { background-position: -208px -32px; }
+.ui-icon-arrowstop-1-s { background-position: -224px -32px; }
+.ui-icon-arrowstop-1-w { background-position: -240px -32px; }
+.ui-icon-arrowthick-1-n { background-position: 0 -48px; }
+.ui-icon-arrowthick-1-ne { background-position: -16px -48px; }
+.ui-icon-arrowthick-1-e { background-position: -32px -48px; }
+.ui-icon-arrowthick-1-se { background-position: -48px -48px; }
+.ui-icon-arrowthick-1-s { background-position: -64px -48px; }
+.ui-icon-arrowthick-1-sw { background-position: -80px -48px; }
+.ui-icon-arrowthick-1-w { background-position: -96px -48px; }
+.ui-icon-arrowthick-1-nw { background-position: -112px -48px; }
+.ui-icon-arrowthick-2-n-s { background-position: -128px -48px; }
+.ui-icon-arrowthick-2-ne-sw { background-position: -144px -48px; }
+.ui-icon-arrowthick-2-e-w { background-position: -160px -48px; }
+.ui-icon-arrowthick-2-se-nw { background-position: -176px -48px; }
+.ui-icon-arrowthickstop-1-n { background-position: -192px -48px; }
+.ui-icon-arrowthickstop-1-e { background-position: -208px -48px; }
+.ui-icon-arrowthickstop-1-s { background-position: -224px -48px; }
+.ui-icon-arrowthickstop-1-w { background-position: -240px -48px; }
+.ui-icon-arrowreturnthick-1-w { background-position: 0 -64px; }
+.ui-icon-arrowreturnthick-1-n { background-position: -16px -64px; }
+.ui-icon-arrowreturnthick-1-e { background-position: -32px -64px; }
+.ui-icon-arrowreturnthick-1-s { background-position: -48px -64px; }
+.ui-icon-arrowreturn-1-w { background-position: -64px -64px; }
+.ui-icon-arrowreturn-1-n { background-position: -80px -64px; }
+.ui-icon-arrowreturn-1-e { background-position: -96px -64px; }
+.ui-icon-arrowreturn-1-s { background-position: -112px -64px; }
+.ui-icon-arrowrefresh-1-w { background-position: -128px -64px; }
+.ui-icon-arrowrefresh-1-n { background-position: -144px -64px; }
+.ui-icon-arrowrefresh-1-e { background-position: -160px -64px; }
+.ui-icon-arrowrefresh-1-s { background-position: -176px -64px; }
+.ui-icon-arrow-4 { background-position: 0 -80px; }
+.ui-icon-arrow-4-diag { background-position: -16px -80px; }
+.ui-icon-extlink { background-position: -32px -80px; }
+.ui-icon-newwin { background-position: -48px -80px; }
+.ui-icon-refresh { background-position: -64px -80px; }
+.ui-icon-shuffle { background-position: -80px -80px; }
+.ui-icon-transfer-e-w { background-position: -96px -80px; }
+.ui-icon-transferthick-e-w { background-position: -112px -80px; }
+.ui-icon-folder-collapsed { background-position: 0 -96px; }
+.ui-icon-folder-open { background-position: -16px -96px; }
+.ui-icon-document { background-position: -32px -96px; }
+.ui-icon-document-b { background-position: -48px -96px; }
+.ui-icon-note { background-position: -64px -96px; }
+.ui-icon-mail-closed { background-position: -80px -96px; }
+.ui-icon-mail-open { background-position: -96px -96px; }
+.ui-icon-suitcase { background-position: -112px -96px; }
+.ui-icon-comment { background-position: -128px -96px; }
+.ui-icon-person { background-position: -144px -96px; }
+.ui-icon-print { background-position: -160px -96px; }
+.ui-icon-trash { background-position: -176px -96px; }
+.ui-icon-locked { background-position: -192px -96px; }
+.ui-icon-unlocked { background-position: -208px -96px; }
+.ui-icon-bookmark { background-position: -224px -96px; }
+.ui-icon-tag { background-position: -240px -96px; }
+.ui-icon-home { background-position: 0 -112px; }
+.ui-icon-flag { background-position: -16px -112px; }
+.ui-icon-calendar { background-position: -32px -112px; }
+.ui-icon-cart { background-position: -48px -112px; }
+.ui-icon-pencil { background-position: -64px -112px; }
+.ui-icon-clock { background-position: -80px -112px; }
+.ui-icon-disk { background-position: -96px -112px; }
+.ui-icon-calculator { background-position: -112px -112px; }
+.ui-icon-zoomin { background-position: -128px -112px; }
+.ui-icon-zoomout { background-position: -144px -112px; }
+.ui-icon-search { background-position: -160px -112px; }
+.ui-icon-wrench { background-position: -176px -112px; }
+.ui-icon-gear { background-position: -192px -112px; }
+.ui-icon-heart { background-position: -208px -112px; }
+.ui-icon-star { background-position: -224px -112px; }
+.ui-icon-link { background-position: -240px -112px; }
+.ui-icon-cancel { background-position: 0 -128px; }
+.ui-icon-plus { background-position: -16px -128px; }
+.ui-icon-plusthick { background-position: -32px -128px; }
+.ui-icon-minus { background-position: -48px -128px; }
+.ui-icon-minusthick { background-position: -64px -128px; }
+.ui-icon-close { background-position: -80px -128px; }
+.ui-icon-closethick { background-position: -96px -128px; }
+.ui-icon-key { background-position: -112px -128px; }
+.ui-icon-lightbulb { background-position: -128px -128px; }
+.ui-icon-scissors { background-position: -144px -128px; }
+.ui-icon-clipboard { background-position: -160px -128px; }
+.ui-icon-copy { background-position: -176px -128px; }
+.ui-icon-contact { background-position: -192px -128px; }
+.ui-icon-image { background-position: -208px -128px; }
+.ui-icon-video { background-position: -224px -128px; }
+.ui-icon-script { background-position: -240px -128px; }
+.ui-icon-alert { background-position: 0 -144px; }
+.ui-icon-info { background-position: -16px -144px; }
+.ui-icon-notice { background-position: -32px -144px; }
+.ui-icon-help { background-position: -48px -144px; }
+.ui-icon-check { background-position: -64px -144px; }
+.ui-icon-bullet { background-position: -80px -144px; }
+.ui-icon-radio-on { background-position: -96px -144px; }
+.ui-icon-radio-off { background-position: -112px -144px; }
+.ui-icon-pin-w { background-position: -128px -144px; }
+.ui-icon-pin-s { background-position: -144px -144px; }
+.ui-icon-play { background-position: 0 -160px; }
+.ui-icon-pause { background-position: -16px -160px; }
+.ui-icon-seek-next { background-position: -32px -160px; }
+.ui-icon-seek-prev { background-position: -48px -160px; }
+.ui-icon-seek-end { background-position: -64px -160px; }
+.ui-icon-seek-start { background-position: -80px -160px; }
+/* ui-icon-seek-first is deprecated, use ui-icon-seek-start instead */
+.ui-icon-seek-first { background-position: -80px -160px; }
+.ui-icon-stop { background-position: -96px -160px; }
+.ui-icon-eject { background-position: -112px -160px; }
+.ui-icon-volume-off { background-position: -128px -160px; }
+.ui-icon-volume-on { background-position: -144px -160px; }
+.ui-icon-power { background-position: 0 -176px; }
+.ui-icon-signal-diag { background-position: -16px -176px; }
+.ui-icon-signal { background-position: -32px -176px; }
+.ui-icon-battery-0 { background-position: -48px -176px; }
+.ui-icon-battery-1 { background-position: -64px -176px; }
+.ui-icon-battery-2 { background-position: -80px -176px; }
+.ui-icon-battery-3 { background-position: -96px -176px; }
+.ui-icon-circle-plus { background-position: 0 -192px; }
+.ui-icon-circle-minus { background-position: -16px -192px; }
+.ui-icon-circle-close { background-position: -32px -192px; }
+.ui-icon-circle-triangle-e { background-position: -48px -192px; }
+.ui-icon-circle-triangle-s { background-position: -64px -192px; }
+.ui-icon-circle-triangle-w { background-position: -80px -192px; }
+.ui-icon-circle-triangle-n { background-position: -96px -192px; }
+.ui-icon-circle-arrow-e { background-position: -112px -192px; }
+.ui-icon-circle-arrow-s { background-position: -128px -192px; }
+.ui-icon-circle-arrow-w { background-position: -144px -192px; }
+.ui-icon-circle-arrow-n { background-position: -160px -192px; }
+.ui-icon-circle-zoomin { background-position: -176px -192px; }
+.ui-icon-circle-zoomout { background-position: -192px -192px; }
+.ui-icon-circle-check { background-position: -208px -192px; }
+.ui-icon-circlesmall-plus { background-position: 0 -208px; }
+.ui-icon-circlesmall-minus { background-position: -16px -208px; }
+.ui-icon-circlesmall-close { background-position: -32px -208px; }
+.ui-icon-squaresmall-plus { background-position: -48px -208px; }
+.ui-icon-squaresmall-minus { background-position: -64px -208px; }
+.ui-icon-squaresmall-close { background-position: -80px -208px; }
+.ui-icon-grip-dotted-vertical { background-position: 0 -224px; }
+.ui-icon-grip-dotted-horizontal { background-position: -16px -224px; }
+.ui-icon-grip-solid-vertical { background-position: -32px -224px; }
+.ui-icon-grip-solid-horizontal { background-position: -48px -224px; }
+.ui-icon-gripsmall-diagonal-se { background-position: -64px -224px; }
+.ui-icon-grip-diagonal-se { background-position: -80px -224px; }
+
+
+/* Misc visuals
+----------------------------------*/
+
+/* Corner radius */
+.ui-corner-all, .ui-corner-top, .ui-corner-left, .ui-corner-tl { -moz-border-radius-topleft: 4px; -webkit-border-top-left-radius: 4px; -khtml-border-top-left-radius: 4px; border-top-left-radius: 4px; }
+.ui-corner-all, .ui-corner-top, .ui-corner-right, .ui-corner-tr { -moz-border-radius-topright: 4px; -webkit-border-top-right-radius: 4px; -khtml-border-top-right-radius: 4px; border-top-right-radius: 4px; }
+.ui-corner-all, .ui-corner-bottom, .ui-corner-left, .ui-corner-bl { -moz-border-radius-bottomleft: 4px; -webkit-border-bottom-left-radius: 4px; -khtml-border-bottom-left-radius: 4px; border-bottom-left-radius: 4px; }
+.ui-corner-all, .ui-corner-bottom, .ui-corner-right, .ui-corner-br { -moz-border-radius-bottomright: 4px; -webkit-border-bottom-right-radius: 4px; -khtml-border-bottom-right-radius: 4px; border-bottom-right-radius: 4px; }
+
+/* Overlays */
+.ui-widget-overlay { background: #aaaaaa url(images/ui-bg_flat_0_aaaaaa_40x100.png) 50% 50% repeat-x; opacity: .3;filter:Alpha(Opacity=30); }
+.ui-widget-shadow { margin: -8px 0 0 -8px; padding: 8px; background: #aaaaaa url(images/ui-bg_flat_0_aaaaaa_40x100.png) 50% 50% repeat-x; opacity: .3;filter:Alpha(Opacity=30); -moz-border-radius: 8px; -khtml-border-radius: 8px; -webkit-border-radius: 8px; border-radius: 8px; }
\ No newline at end of file
diff --git a/phpmyadmin/themes/pmahomme/layout.inc.php b/phpmyadmin/themes/pmahomme/layout.inc.php
new file mode 100644
index 0000000..7454cad
--- /dev/null
+++ b/phpmyadmin/themes/pmahomme/layout.inc.php
@@ -0,0 +1,140 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * configures general layout
+ * for detailed layout configuration please refer to the css files
+ *
+ * @package    PhpMyAdmin-theme
+ * @subpackage PMAHomme
+ */
+
+/**
+ * navi frame
+ */
+// navi frame width
+$GLOBALS['cfg']['NaviWidth']                = 240;
+
+// foreground (text) color for the navi frame
+$GLOBALS['cfg']['NaviColor']                = '#000';
+
+// background for the navi frame
+$GLOBALS['cfg']['NaviBackground']           = '#f3f3f3';
+
+// foreground (text) color of the pointer in navi frame
+$GLOBALS['cfg']['NaviPointerColor']         = '#000';
+
+// background of the pointer in navi frame
+$GLOBALS['cfg']['NaviPointerBackground']    = '#ddd';
+
+/**
+ * main frame
+ */
+// foreground (text) color for the main frame
+$GLOBALS['cfg']['MainColor']                = '#000';
+
+// background for the main frame
+$GLOBALS['cfg']['MainBackground']           = '#F5F5F5';
+
+// foreground (text) color of the pointer in browse mode
+$GLOBALS['cfg']['BrowsePointerColor']       = '#000';
+
+// background of the pointer in browse mode
+$GLOBALS['cfg']['BrowsePointerBackground']  = '#cfc';
+
+// foreground (text) color of the marker (visually marks row by clicking on it)
+// in browse mode
+$GLOBALS['cfg']['BrowseMarkerColor']        = '#000';
+
+// background of the marker (visually marks row by clicking on it) in browse mode
+$GLOBALS['cfg']['BrowseMarkerBackground']   = '#fc9';
+
+/**
+ * fonts
+ */
+/**
+ * the font family as a valid css font family value,
+ * if not set the browser default will be used
+ * (depending on browser, DTD and system settings)
+ */
+$GLOBALS['cfg']['FontFamily']           = 'sans-serif';
+/**
+ * fixed width font family, used in textarea
+ */
+$GLOBALS['cfg']['FontFamilyFixed']      = 'monospace';
+
+/**
+ * tables
+ */
+// border
+$GLOBALS['cfg']['Border']               = 0;
+// table header and footer color
+$GLOBALS['cfg']['ThBackground']         = '#D3DCE3';
+// table header and footer background
+$GLOBALS['cfg']['ThColor']              = '#000';
+// table data row background
+$GLOBALS['cfg']['BgOne']                = '#E5E5E5';
+// table data row background, alternate
+$GLOBALS['cfg']['BgTwo']                = '#D5D5D5';
+
+/**
+ * query window
+ */
+// Width of Query window
+$GLOBALS['cfg']['QueryWindowWidth']     = 600;
+// Height of Query window
+$GLOBALS['cfg']['QueryWindowHeight']    = 400;
+
+/**
+ * SQL Parser Settings
+ * Syntax colouring data
+ */
+$GLOBALS['cfg']['SQP']['fmtColor']      = array(
+    'comment'            => '#808000',
+    'comment_mysql'      => '',
+    'comment_ansi'       => '',
+    'comment_c'          => '',
+    'digit'              => '',
+    'digit_hex'          => 'teal',
+    'digit_integer'      => 'teal',
+    'digit_float'        => 'aqua',
+    'punct'              => 'fuchsia',
+    'alpha'              => '',
+    'alpha_columnType'   => '#f90',
+    'alpha_columnAttrib' => '#00f',
+    'alpha_reservedWord' => '#909',
+    'alpha_functionName' => '#f00',
+    'alpha_identifier'   => 'black',
+    'alpha_charset'      => '#6495ed',
+    'alpha_variable'     => '#800000',
+    'quote'              => '#008000',
+    'quote_double'       => '',
+    'quote_single'       => '',
+    'quote_backtick'     => ''
+);
+
+/**
+ * Chart colors
+ */
+
+ $GLOBALS['cfg']['chartColor'] = array(
+    'gradientIntensity'       => 50,
+    // The style of the chart title.
+    'titleColor'              => '#000',
+    'titleBgColor'            => '#E5E5E5',
+    // Chart border (0 for no border)
+    'border'                  => '#ccc',
+    // Chart background color.
+    'bgColor'                 => '#FBFBFB',
+    // when graph area gradient is used, this is the color of the graph
+    // area border
+    'graphAreaColor'          => '#D5D9DD',
+    // the background color of the graph area
+    'graphAreaGradientColor'  => $GLOBALS['cfg']['BgTwo'],
+    // the color of the grid lines in the graph area
+    'gridColor'               => '#E6E6E6',
+    // the color of the scale and the labels
+    'scaleColor'              => '#D5D9DD',
+
+ );
+
+?>
diff --git a/phpmyadmin/themes/pmahomme/screen.png b/phpmyadmin/themes/pmahomme/screen.png
new file mode 100644
index 0000000..1441fe2
Binary files /dev/null and b/phpmyadmin/themes/pmahomme/screen.png differ
diff --git a/phpmyadmin/themes/pmahomme/sprites.lib.php b/phpmyadmin/themes/pmahomme/sprites.lib.php
new file mode 100644
index 0000000..fdfd168
--- /dev/null
+++ b/phpmyadmin/themes/pmahomme/sprites.lib.php
@@ -0,0 +1,720 @@
+<?php
+/* AUTOGENERATED CONTENT - DO NOT EDIT */
+/* ALL CHANGES WILL BE UNDONE */
+/* RUN './scripts/generate-sprites' TO UPDATE THIS FILE */
+function PMA_sprites()
+{
+    return array(
+        'asc_order' => array(
+            'position' => '1',
+            'width'    => '16',
+            'height'   => '16'
+        ),
+        'b_bookmark' => array(
+            'position' => '2',
+            'width'    => '16',
+            'height'   => '16'
+        ),
+        'b_browse' => array(
+            'position' => '3',
+            'width'    => '16',
+            'height'   => '16'
+        ),
+        'b_calendar' => array(
+            'position' => '4',
+            'width'    => '16',
+            'height'   => '16'
+        ),
+        'b_chart' => array(
+            'position' => '5',
+            'width'    => '16',
+            'height'   => '16'
+        ),
+        'b_close' => array(
+            'position' => '6',
+            'width'    => '16',
+            'height'   => '16'
+        ),
+        'b_column_add' => array(
+            'position' => '7',
+            'width'    => '16',
+            'height'   => '16'
+        ),
+        'b_comment' => array(
+            'position' => '8',
+            'width'    => '16',
+            'height'   => '16'
+        ),
+        'bd_browse' => array(
+            'position' => '9',
+            'width'    => '16',
+            'height'   => '16'
+        ),
+        'b_dbstatistics' => array(
+            'position' => '10',
+            'width'    => '16',
+            'height'   => '16'
+        ),
+        'bd_deltbl' => array(
+            'position' => '11',
+            'width'    => '16',
+            'height'   => '16'
+        ),
+        'bd_drop' => array(
+            'position' => '12',
+            'width'    => '16',
+            'height'   => '16'
+        ),
+        'bd_edit' => array(
+            'position' => '13',
+            'width'    => '16',
+            'height'   => '16'
+        ),
+        'b_deltbl' => array(
+            'position' => '14',
+            'width'    => '16',
+            'height'   => '16'
+        ),
+        'bd_empty' => array(
+            'position' => '15',
+            'width'    => '16',
+            'height'   => '16'
+        ),
+        'bd_export' => array(
+            'position' => '16',
+            'width'    => '16',
+            'height'   => '16'
+        ),
+        'bd_firstpage' => array(
+            'position' => '17',
+            'width'    => '16',
+            'height'   => '16'
+        ),
+        'bd_ftext' => array(
+            'position' => '18',
+            'width'    => '16',
+            'height'   => '16'
+        ),
+        'bd_index' => array(
+            'position' => '19',
+            'width'    => '16',
+            'height'   => '16'
+        ),
+        'bd_insrow' => array(
+            'position' => '20',
+            'width'    => '16',
+            'height'   => '16'
+        ),
+        'bd_lastpage' => array(
+            'position' => '21',
+            'width'    => '16',
+            'height'   => '16'
+        ),
+        'bd_nextpage' => array(
+            'position' => '22',
+            'width'    => '16',
+            'height'   => '16'
+        ),
+        'b_docs' => array(
+            'position' => '23',
+            'width'    => '16',
+            'height'   => '16'
+        ),
+        'b_docsql' => array(
+            'position' => '24',
+            'width'    => '16',
+            'height'   => '16'
+        ),
+        'bd_prevpage' => array(
+            'position' => '25',
+            'width'    => '16',
+            'height'   => '16'
+        ),
+        'bd_primary' => array(
+            'position' => '26',
+            'width'    => '16',
+            'height'   => '16'
+        ),
+        'b_drop' => array(
+            'position' => '27',
+            'width'    => '16',
+            'height'   => '16'
+        ),
+        'bd_sbrowse' => array(
+            'position' => '28',
+            'width'    => '16',
+            'height'   => '16'
+        ),
+        'bd_select' => array(
+            'position' => '29',
+            'width'    => '16',
+            'height'   => '16'
+        ),
+        'bd_spatial' => array(
+            'position' => '30',
+            'width'    => '16',
+            'height'   => '16'
+        ),
+        'bd_unique' => array(
+            'position' => '31',
+            'width'    => '16',
+            'height'   => '16'
+        ),
+        'b_edit' => array(
+            'position' => '32',
+            'width'    => '16',
+            'height'   => '16'
+        ),
+        'b_empty' => array(
+            'position' => '33',
+            'width'    => '16',
+            'height'   => '16'
+        ),
+        'b_engine' => array(
+            'position' => '34',
+            'width'    => '16',
+            'height'   => '16'
+        ),
+        'b_event_add' => array(
+            'position' => '35',
+            'width'    => '16',
+            'height'   => '16'
+        ),
+        'b_events' => array(
+            'position' => '36',
+            'width'    => '16',
+            'height'   => '16'
+        ),
+        'b_export' => array(
+            'position' => '37',
+            'width'    => '16',
+            'height'   => '16'
+        ),
+        'b_firstpage' => array(
+            'position' => '38',
+            'width'    => '16',
+            'height'   => '16'
+        ),
+        'b_ftext' => array(
+            'position' => '39',
+            'width'    => '16',
+            'height'   => '16'
+        ),
+        'b_group' => array(
+            'position' => '40',
+            'width'    => '16',
+            'height'   => '16'
+        ),
+        'b_help' => array(
+            'position' => '41',
+            'width'    => '16',
+            'height'   => '16'
+        ),
+        'b_home' => array(
+            'position' => '42',
+            'width'    => '16',
+            'height'   => '16'
+        ),
+        'b_import' => array(
+            'position' => '43',
+            'width'    => '16',
+            'height'   => '16'
+        ),
+        'b_index_add' => array(
+            'position' => '44',
+            'width'    => '16',
+            'height'   => '16'
+        ),
+        'b_index' => array(
+            'position' => '45',
+            'width'    => '16',
+            'height'   => '16'
+        ),
+        'b_info' => array(
+            'position' => '46',
+            'width'    => '11',
+            'height'   => '11'
+        ),
+        'b_inline_edit' => array(
+            'position' => '47',
+            'width'    => '16',
+            'height'   => '16'
+        ),
+        'b_insrow' => array(
+            'position' => '48',
+            'width'    => '16',
+            'height'   => '16'
+        ),
+        'b_lastpage' => array(
+            'position' => '49',
+            'width'    => '16',
+            'height'   => '16'
+        ),
+        'b_minus' => array(
+            'position' => '50',
+            'width'    => '16',
+            'height'   => '16'
+        ),
+        'b_more' => array(
+            'position' => '51',
+            'width'    => '16',
+            'height'   => '16'
+        ),
+        'b_move' => array(
+            'position' => '52',
+            'width'    => '16',
+            'height'   => '16'
+        ),
+        'b_newdb' => array(
+            'position' => '53',
+            'width'    => '16',
+            'height'   => '16'
+        ),
+        'b_newtbl' => array(
+            'position' => '54',
+            'width'    => '16',
+            'height'   => '16'
+        ),
+        'b_nextpage' => array(
+            'position' => '55',
+            'width'    => '16',
+            'height'   => '16'
+        ),
+        'b_pdfdoc' => array(
+            'position' => '56',
+            'width'    => '16',
+            'height'   => '16'
+        ),
+        'b_plus' => array(
+            'position' => '57',
+            'width'    => '16',
+            'height'   => '16'
+        ),
+        'b_prevpage' => array(
+            'position' => '58',
+            'width'    => '16',
+            'height'   => '16'
+        ),
+        'b_primary' => array(
+            'position' => '59',
+            'width'    => '16',
+            'height'   => '16'
+        ),
+        'b_print' => array(
+            'position' => '60',
+            'width'    => '16',
+            'height'   => '16'
+        ),
+        'b_props' => array(
+            'position' => '61',
+            'width'    => '16',
+            'height'   => '16'
+        ),
+        'b_relations' => array(
+            'position' => '62',
+            'width'    => '16',
+            'height'   => '16'
+        ),
+        'b_routine_add' => array(
+            'position' => '63',
+            'width'    => '16',
+            'height'   => '16'
+        ),
+        'b_routines' => array(
+            'position' => '64',
+            'width'    => '16',
+            'height'   => '16'
+        ),
+        'b_save' => array(
+            'position' => '65',
+            'width'    => '16',
+            'height'   => '16'
+        ),
+        'b_sbrowse' => array(
+            'position' => '66',
+            'width'    => '16',
+            'height'   => '16'
+        ),
+        'b_sdb' => array(
+            'position' => '67',
+            'width'    => '10',
+            'height'   => '10'
+        ),
+        'b_search' => array(
+            'position' => '68',
+            'width'    => '16',
+            'height'   => '16'
+        ),
+        'b_selboard' => array(
+            'position' => '69',
+            'width'    => '16',
+            'height'   => '16'
+        ),
+        'b_select' => array(
+            'position' => '70',
+            'width'    => '16',
+            'height'   => '16'
+        ),
+        'b_snewtbl' => array(
+            'position' => '71',
+            'width'    => '16',
+            'height'   => '16'
+        ),
+        'b_spatial' => array(
+            'position' => '72',
+            'width'    => '16',
+            'height'   => '16'
+        ),
+        'b_sqldoc' => array(
+            'position' => '73',
+            'width'    => '16',
+            'height'   => '16'
+        ),
+        'b_sqlhelp' => array(
+            'position' => '74',
+            'width'    => '16',
+            'height'   => '16'
+        ),
+        'b_sql' => array(
+            'position' => '75',
+            'width'    => '16',
+            'height'   => '16'
+        ),
+        'b_table_add' => array(
+            'position' => '76',
+            'width'    => '16',
+            'height'   => '16'
+        ),
+        'b_tblanalyse' => array(
+            'position' => '77',
+            'width'    => '16',
+            'height'   => '16'
+        ),
+        'b_tblexport' => array(
+            'position' => '78',
+            'width'    => '16',
+            'height'   => '16'
+        ),
+        'b_tblimport' => array(
+            'position' => '79',
+            'width'    => '16',
+            'height'   => '16'
+        ),
+        'b_tblops' => array(
+            'position' => '80',
+            'width'    => '16',
+            'height'   => '16'
+        ),
+        'b_tbloptimize' => array(
+            'position' => '81',
+            'width'    => '16',
+            'height'   => '16'
+        ),
+        'b_tipp' => array(
+            'position' => '82',
+            'width'    => '16',
+            'height'   => '16'
+        ),
+        'b_trigger_add' => array(
+            'position' => '83',
+            'width'    => '16',
+            'height'   => '16'
+        ),
+        'b_triggers' => array(
+            'position' => '84',
+            'width'    => '16',
+            'height'   => '16'
+        ),
+        'b_unique' => array(
+            'position' => '85',
+            'width'    => '16',
+            'height'   => '16'
+        ),
+        'b_usradd' => array(
+            'position' => '86',
+            'width'    => '16',
+            'height'   => '16'
+        ),
+        'b_usrcheck' => array(
+            'position' => '87',
+            'width'    => '16',
+            'height'   => '16'
+        ),
+        'b_usrdrop' => array(
+            'position' => '88',
+            'width'    => '16',
+            'height'   => '16'
+        ),
+        'b_usredit' => array(
+            'position' => '89',
+            'width'    => '16',
+            'height'   => '16'
+        ),
+        'b_usrlist' => array(
+            'position' => '90',
+            'width'    => '16',
+            'height'   => '16'
+        ),
+        'b_view_add' => array(
+            'position' => '91',
+            'width'    => '16',
+            'height'   => '16'
+        ),
+        'b_view' => array(
+            'position' => '92',
+            'width'    => '16',
+            'height'   => '16'
+        ),
+        'b_views' => array(
+            'position' => '93',
+            'width'    => '16',
+            'height'   => '16'
+        ),
+        'col_drop' => array(
+            'position' => '94',
+            'width'    => '16',
+            'height'   => '16'
+        ),
+        'database' => array(
+            'position' => '95',
+            'width'    => '16',
+            'height'   => '16'
+        ),
+        'eye_grey' => array(
+            'position' => '96',
+            'width'    => '16',
+            'height'   => '16'
+        ),
+        'eye' => array(
+            'position' => '97',
+            'width'    => '16',
+            'height'   => '16'
+        ),
+        'item' => array(
+            'position' => '98',
+            'width'    => '9',
+            'height'   => '9'
+        ),
+        'more' => array(
+            'position' => '99',
+            'width'    => '13',
+            'height'   => '16'
+        ),
+        'new_data_hovered' => array(
+            'position' => '100',
+            'width'    => '16',
+            'height'   => '16'
+        ),
+        'new_data' => array(
+            'position' => '101',
+            'width'    => '16',
+            'height'   => '16'
+        ),
+        'new_data_selected_hovered' => array(
+            'position' => '102',
+            'width'    => '16',
+            'height'   => '16'
+        ),
+        'new_data_selected' => array(
+            'position' => '103',
+            'width'    => '16',
+            'height'   => '16'
+        ),
+        'new_struct_hovered' => array(
+            'position' => '104',
+            'width'    => '16',
+            'height'   => '16'
+        ),
+        'new_struct' => array(
+            'position' => '105',
+            'width'    => '16',
+            'height'   => '16'
+        ),
+        'new_struct_selected_hovered' => array(
+            'position' => '106',
+            'width'    => '16',
+            'height'   => '16'
+        ),
+        'new_struct_selected' => array(
+            'position' => '107',
+            'width'    => '16',
+            'height'   => '16'
+        ),
+        'pause' => array(
+            'position' => '108',
+            'width'    => '16',
+            'height'   => '16'
+        ),
+        'php_sym' => array(
+            'position' => '109',
+            'width'    => '16',
+            'height'   => '16'
+        ),
+        'play' => array(
+            'position' => '110',
+            'width'    => '16',
+            'height'   => '16'
+        ),
+        's_asci' => array(
+            'position' => '111',
+            'width'    => '16',
+            'height'   => '16'
+        ),
+        's_asc' => array(
+            'position' => '112',
+            'width'    => '16',
+            'height'   => '16'
+        ),
+        's_attention' => array(
+            'position' => '113',
+            'width'    => '16',
+            'height'   => '16'
+        ),
+        's_cancel2' => array(
+            'position' => '114',
+            'width'    => '16',
+            'height'   => '16'
+        ),
+        's_cancel' => array(
+            'position' => '115',
+            'width'    => '16',
+            'height'   => '16'
+        ),
+        's_cog' => array(
+            'position' => '116',
+            'width'    => '16',
+            'height'   => '16'
+        ),
+        's_db' => array(
+            'position' => '117',
+            'width'    => '16',
+            'height'   => '16'
+        ),
+        's_desc' => array(
+            'position' => '118',
+            'width'    => '16',
+            'height'   => '16'
+        ),
+        's_error2' => array(
+            'position' => '119',
+            'width'    => '11',
+            'height'   => '11'
+        ),
+        's_error' => array(
+            'position' => '120',
+            'width'    => '16',
+            'height'   => '16'
+        ),
+        's_host' => array(
+            'position' => '121',
+            'width'    => '16',
+            'height'   => '16'
+        ),
+        's_info' => array(
+            'position' => '122',
+            'width'    => '16',
+            'height'   => '16'
+        ),
+        's_lang' => array(
+            'position' => '123',
+            'width'    => '16',
+            'height'   => '16'
+        ),
+        's_loggoff' => array(
+            'position' => '124',
+            'width'    => '16',
+            'height'   => '16'
+        ),
+        's_notice' => array(
+            'position' => '125',
+            'width'    => '16',
+            'height'   => '16'
+        ),
+        's_okay' => array(
+            'position' => '126',
+            'width'    => '16',
+            'height'   => '16'
+        ),
+        's_passwd' => array(
+            'position' => '127',
+            'width'    => '16',
+            'height'   => '16'
+        ),
+        's_process' => array(
+            'position' => '128',
+            'width'    => '16',
+            'height'   => '16'
+        ),
+        's_really' => array(
+            'position' => '129',
+            'width'    => '11',
+            'height'   => '11'
+        ),
+        's_reload' => array(
+            'position' => '130',
+            'width'    => '16',
+            'height'   => '16'
+        ),
+        's_replication' => array(
+            'position' => '131',
+            'width'    => '16',
+            'height'   => '16'
+        ),
+        's_rights' => array(
+            'position' => '132',
+            'width'    => '16',
+            'height'   => '16'
+        ),
+        's_sortable' => array(
+            'position' => '133',
+            'width'    => '16',
+            'height'   => '16'
+        ),
+        's_status' => array(
+            'position' => '134',
+            'width'    => '16',
+            'height'   => '16'
+        ),
+        's_success' => array(
+            'position' => '135',
+            'width'    => '16',
+            'height'   => '16'
+        ),
+        's_sync' => array(
+            'position' => '136',
+            'width'    => '16',
+            'height'   => '16'
+        ),
+        's_tbl' => array(
+            'position' => '137',
+            'width'    => '16',
+            'height'   => '16'
+        ),
+        's_theme' => array(
+            'position' => '138',
+            'width'    => '16',
+            'height'   => '16'
+        ),
+        's_top' => array(
+            'position' => '139',
+            'width'    => '16',
+            'height'   => '16'
+        ),
+        's_vars' => array(
+            'position' => '140',
+            'width'    => '16',
+            'height'   => '16'
+        ),
+        's_views' => array(
+            'position' => '141',
+            'width'    => '16',
+            'height'   => '16'
+        ),
+        'window-new' => array(
+            'position' => '142',
+            'width'    => '16',
+            'height'   => '16'
+        ),
+    );
+}
+?>
diff --git a/phpmyadmin/themes/sprites.css.php b/phpmyadmin/themes/sprites.css.php
new file mode 100644
index 0000000..2c12589
--- /dev/null
+++ b/phpmyadmin/themes/sprites.css.php
@@ -0,0 +1,82 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * This file generates the CSS code for the sprites of a theme
+ *
+ * @package PhpMyAdmin-theme
+ */
+
+// unplanned execution path
+if (! defined('PMA_MINIMUM_COMMON')) {
+    exit();
+}
+
+$bg = $_SESSION['PMA_Theme']->getImgPath() . 'sprites.png';
+/* Check if there is a valid data file for sprites */
+if (is_readable($_SESSION['PMA_Theme']->getPath() . '/sprites.lib.php')) {
+
+?>
+/* Icon sprites */
+.icon {
+    margin: 0 .3em;
+    padding: 0 !important;
+    width: 16px;
+    height: 16px;
+    background-image: url('<?php echo $bg; ?>') !important;
+    background-repeat: no-repeat !important;
+    background-position: top left !important;
+}
+<?php
+
+    include_once $_SESSION['PMA_Theme']->getPath() . '/sprites.lib.php';
+    $sprites = array();
+    if (function_exists('PMA_sprites')) {
+        $sprites = PMA_sprites();
+    }
+    $template = ".ic_%s { background-position: 0 -%upx !important;%s%s }\n";
+    foreach ($sprites as $name => $data) {
+        // generate the CSS code for each icon
+        $width = '';
+        $height = '';
+        // if either the height or width of an icon is 16px,
+        // then it's pointless to set this as a parameter,
+        //since it will be inherited from the "icon" class
+        if ($data['width'] != 16) {
+            $width = " width: " . $data['width'] . "px;";
+        }
+        if ($data['height'] != 16) {
+            $height = " height: " . $data['height'] . "px;";
+        }
+        printf(
+            $template,
+            $name,
+            ($data['position'] * 16),
+            $width,
+            $height
+        );
+    }
+    // Here we map some of the classes that we
+    // defined above to other CSS selectors.
+    // The indexes of the array correspond to
+    // already defined classes and the values
+    // are the selectors that we want to map to.
+    $elements = array(
+        's_sortable' => 'img.sortableIcon',
+        's_asc'      => 'th.headerSortUp img.sortableIcon',
+        's_desc'     => 'th.headerSortDown img.sortableIcon'
+    );
+    $template = "%s { background-position: 0 -%upx; "
+              . "height: %upx; width: %upx; }\n";
+    foreach ($elements as $key => $value) {
+        if (isset($sprites[$key])) { // If the CSS class has been defined
+            printf(
+                $template,
+                $value,
+                ($sprites[$key]['position'] * 16),
+                $sprites[$key]['height'],
+                $sprites[$key]['width']
+            );
+        }
+    }
+}
+?>
diff --git a/phpmyadmin/themes/svg_gradient.php b/phpmyadmin/themes/svg_gradient.php
new file mode 100644
index 0000000..cb1211a
--- /dev/null
+++ b/phpmyadmin/themes/svg_gradient.php
@@ -0,0 +1,30 @@
+<?php
+/**
+ * Theme based generator for SVG gradient.
+ *
+ * @package PhpMyAdmin-theme
+ */
+header('Content-Type: image/svg+xml');
+header('Expires: ' . gmdate('D, d M Y H:i:s', time() + 3600) . ' GMT');
+
+function get_color($get_name, $default)
+{
+    // get color from GET args, only alphanumeric chcracters
+    $opts = array('options' => array('regexp' => '/^[a-z0-9]+$/i'));
+    $color = filter_input(INPUT_GET, $get_name, FILTER_VALIDATE_REGEXP, $opts);
+    if (preg_match('/^[a-f0-9]{6}$/', $color)) {
+        return '#' . $color;
+    }
+    return $color ? $color : $default;
+}
+?>
+<?php echo '<?xml version="1.0" ?>' ?>
+<svg xmlns="http://www.w3.org/2000/svg" preserveAspectRatio="none" version="1.0" width="100%" height="100%">
+    <defs>
+        <linearGradient id="linear-gradient" x1="0%" y1="0%" x2="0%" y2="100%">
+            <stop offset="0%" stop-color="<?php echo get_color('from', 'white') ?>" stop-opacity="1" />
+            <stop offset="100%" stop-color="<?php echo get_color('to', 'black') ?>" stop-opacity="1" />
+        </linearGradient>
+    </defs>
+    <rect width="100%" height="100%" style="fill:url(#linear-gradient);" />
+</svg>
diff --git a/phpmyadmin/transformation_overview.php b/phpmyadmin/transformation_overview.php
new file mode 100644
index 0000000..d47c5e8
--- /dev/null
+++ b/phpmyadmin/transformation_overview.php
@@ -0,0 +1,58 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ *
+ * @package PhpMyAdmin
+ */
+
+/**
+ * Gets some core libraries and displays a top message if required
+ */
+require_once './libraries/common.inc.php';
+require_once './libraries/transformations.lib.php';
+
+$response = PMA_Response::getInstance();
+$header   = $response->getHeader();
+$header->disableMenu();
+
+$types = PMA_getAvailableMIMEtypes();
+?>
+
+<h2><?php echo __('Available MIME types'); ?></h2>
+<?php
+foreach ($types['mimetype'] as $key => $mimetype) {
+
+    if (isset($types['empty_mimetype'][$mimetype])) {
+        echo '<i>' . $mimetype . '</i><br />';
+    } else {
+        echo $mimetype . '<br />';
+    }
+
+}
+?>
+<br />
+<h2><?php echo __('Available transformations'); ?></h2>
+<table width="90%">
+<thead>
+<tr>
+    <th><?php echo __('Browser transformation'); ?></th>
+    <th><?php echo _pgettext('for MIME transformation', 'Description'); ?></th>
+</tr>
+</thead>
+<tbody>
+<?php
+$odd_row = true;
+foreach ($types['transformation'] as $key => $transform) {
+    $desc = PMA_getTransformationDescription($types['transformation_file'][$key]);
+    ?>
+    <tr class="<?php echo $odd_row ? 'odd' : 'even'; ?>">
+        <td><?php echo $transform; ?></td>
+        <td><?php echo $desc; ?></td>
+    </tr>
+    <?php
+    $odd_row = !$odd_row;
+}
+?>
+</tbody>
+</table>
+
diff --git a/phpmyadmin/transformation_wrapper.php b/phpmyadmin/transformation_wrapper.php
new file mode 100644
index 0000000..bd3d9f9
--- /dev/null
+++ b/phpmyadmin/transformation_wrapper.php
@@ -0,0 +1,149 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ *
+ * @package PhpMyAdmin
+ */
+
+/**
+ *
+ */
+define('IS_TRANSFORMATION_WRAPPER', true);
+
+/**
+ * Gets a core script and starts output buffering work
+ */
+require_once './libraries/common.inc.php';
+require_once './libraries/transformations.lib.php'; // Transformations
+$cfgRelation = PMA_getRelationsParam();
+
+/**
+ * Ensures db and table are valid, else moves to the "parent" script
+ */
+require_once './libraries/db_table_exists.lib.php';
+
+
+/**
+ * Sets globals from $_REQUEST
+ */
+$request_params = array(
+    'cn',
+    'ct',
+    'newHeight',
+    'newWidth',
+    'resize',
+    'sql_query',
+    'transform_key',
+    'where_clause'
+);
+foreach ($request_params as $one_request_param) {
+    if (isset($_REQUEST[$one_request_param])) {
+        $GLOBALS[$one_request_param] = $_REQUEST[$one_request_param];
+    }
+}
+
+
+/**
+ * Get the list of the fields of the current table
+ */
+PMA_DBI_select_db($db);
+if (isset($where_clause)) {
+    $result = PMA_DBI_query(
+        'SELECT * FROM ' . PMA_Util::backquote($table) . ' WHERE ' . $where_clause . ';',
+        null,
+        PMA_DBI_QUERY_STORE
+    );
+    $row = PMA_DBI_fetch_assoc($result);
+} else {
+    $result = PMA_DBI_query(
+        'SELECT * FROM ' . PMA_Util::backquote($table) . ' LIMIT 1;',
+        null,
+        PMA_DBI_QUERY_STORE
+    );
+    $row = PMA_DBI_fetch_assoc($result);
+}
+
+// No row returned
+if (! $row) {
+    exit;
+} // end if (no record returned)
+
+$default_ct = 'application/octet-stream';
+
+if ($cfgRelation['commwork'] && $cfgRelation['mimework']) {
+    $mime_map = PMA_getMime($db, $table);
+    $mime_options = PMA_transformation_getOptions(
+        isset($mime_map[$transform_key]['transformation_options'])
+        ? $mime_map[$transform_key]['transformation_options'] : ''
+    );
+
+    foreach ($mime_options AS $key => $option) {
+        if (substr($option, 0, 10) == '; charset=') {
+            $mime_options['charset'] = $option;
+        }
+    }
+}
+
+// Only output the http headers
+$response = PMA_Response::getInstance();
+$response->getHeader()->sendHttpHeaders();
+
+// [MIME]
+if (isset($ct) && ! empty($ct)) {
+    $mime_type = $ct;
+} else {
+    $mime_type = (isset($mime_map[$transform_key]['mimetype'])
+        ? str_replace('_', '/', $mime_map[$transform_key]['mimetype'])
+        : $default_ct)
+    . (isset($mime_options['charset']) ? $mime_options['charset'] : '');
+}
+
+PMA_downloadHeader($cn, $mime_type);
+
+if (! isset($resize)) {
+    echo $row[$transform_key];
+} else {
+    // if image_*__inline.inc.php finds that we can resize,
+    // it sets $resize to jpeg or png
+
+    $srcImage = imagecreatefromstring($row[$transform_key]);
+    $srcWidth = ImageSX($srcImage);
+    $srcHeight = ImageSY($srcImage);
+
+    // Check to see if the width > height or if width < height
+    // if so adjust accordingly to make sure the image
+    // stays smaller then the $newWidth and $newHeight
+
+    $ratioWidth = $srcWidth/$newWidth;
+    $ratioHeight = $srcHeight/$newHeight;
+
+    if ($ratioWidth < $ratioHeight) {
+        $destWidth = $srcWidth/$ratioHeight;
+        $destHeight = $newHeight;
+    } else {
+        $destWidth = $newWidth;
+        $destHeight = $srcHeight/$ratioWidth;
+    }
+
+    if ($resize) {
+        $destImage = ImageCreateTrueColor($destWidth, $destHeight);
+    }
+
+    // ImageCopyResized($destImage, $srcImage, 0, 0, 0, 0,
+    // $destWidth, $destHeight, $srcWidth, $srcHeight);
+    // better quality but slower:
+    ImageCopyResampled(
+        $destImage, $srcImage, 0, 0, 0, 0, $destWidth,
+        $destHeight, $srcWidth, $srcHeight
+    );
+
+    if ($resize == 'jpeg') {
+        ImageJPEG($destImage, null, 75);
+    }
+    if ($resize == 'png') {
+        ImagePNG($destImage);
+    }
+    ImageDestroy($srcImage);
+    ImageDestroy($destImage);
+}
+?>
diff --git a/phpmyadmin/url.php b/phpmyadmin/url.php
new file mode 100644
index 0000000..f3954ff
--- /dev/null
+++ b/phpmyadmin/url.php
@@ -0,0 +1,22 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * URL redirector to avoid leaking Referer with some sensitive information.
+ *
+ * @package PhpMyAdmin
+ */
+
+/**
+ * Gets core libraries and defines some variables
+ */
+require_once './libraries/common.inc.php';
+
+if (! PMA_isValid($_GET['url'])
+    || ! preg_match('/^https?:\/\/[^\n\r]*$/', $_GET['url'])
+) {
+    header('Location: ' . $cfg['PmaAbsoluteUri']);
+} else {
+    header('Location: ' . $_GET['url']);
+}
+die();
+?>
diff --git a/phpmyadmin/user_password.php b/phpmyadmin/user_password.php
new file mode 100644
index 0000000..08cd45d
--- /dev/null
+++ b/phpmyadmin/user_password.php
@@ -0,0 +1,242 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * displays and handles the form where the user can change his password
+ * linked from index.php
+ *
+ * @package PhpMyAdmin
+ */
+
+/**
+ * Gets some core libraries
+ */
+require_once './libraries/common.inc.php';
+
+$response = PMA_Response::getInstance();
+$header   = $response->getHeader();
+$scripts  = $header->getScripts();
+$scripts->addFile('server_privileges.js');
+
+/**
+ * Displays an error message and exits if the user isn't allowed to use this
+ * script
+ */
+if (! $cfg['ShowChgPassword']) {
+    $cfg['ShowChgPassword'] = PMA_DBI_select_db('mysql');
+}
+if ($cfg['Server']['auth_type'] == 'config' || ! $cfg['ShowChgPassword']) {
+    PMA_Message::error(
+        __('You don\'t have sufficient privileges to be here right now!')
+    )->display();
+    exit;
+} // end if
+
+/**
+ * If the "change password" form has been submitted, checks for valid values
+ * and submit the query or logout
+ */
+if (isset($_REQUEST['nopass'])) {
+    if ($_REQUEST['nopass'] == '1') {
+        $password = '';
+    } else {
+        $password = $_REQUEST['pma_pw'];
+    }
+    $change_password_message = PMA_setChangePasswordMsg();
+    $msg = $change_password_message['msg'];
+    if (! $change_password_message['error']) {
+        PMA_changePassword($password, $msg, $change_password_message);
+    } else {
+        PMA_getChangePassMessage($change_password_message);
+    }
+}
+
+/**
+ * If the "change password" form hasn't been submitted or the values submitted
+ * aren't valid -> displays the form
+ */
+
+// Displays an error message if required
+if (isset($msg)) {
+    $msg->display();
+    unset($msg);
+}
+
+require_once './libraries/display_change_password.lib.php';
+echo PMA_getHtmlForChangePassword($username, $hostname);
+exit;
+
+/**
+ * Send the message as an ajax request
+ *
+ * @param array   $change_password_message
+ * @param string  $sql_query
+ *
+ * @return void
+ */
+function PMA_getChangePassMessage($change_password_message, $sql_query = '')
+{
+    if ($GLOBALS['is_ajax_request'] == true) {
+        /**
+         * If in an Ajax request, we don't need to show the rest of the page
+         */
+        $response = PMA_Response::getInstance();
+        if ($change_password_message['error']) {
+            $response->addJSON('message', $change_password_message['msg']);
+            $response->isSuccess(false);
+        } else {
+            $sql_query = PMA_Util::getMessage(
+                $change_password_message['msg'],
+                $sql_query,
+                'success'
+            );
+            $response->addJSON('message', $sql_query);
+        }
+        exit;
+    }
+}
+
+/**
+ * Generate the message
+ *
+ * @return array   error value and message
+ */
+function PMA_setChangePasswordMsg()
+{
+    $error = false;
+    $message = PMA_Message::success(__('The profile has been updated.'));
+
+    if (($_REQUEST['nopass'] != '1')) {
+        if (empty($_REQUEST['pma_pw']) || empty($_REQUEST['pma_pw2'])) {
+            $message = PMA_Message::error(__('The password is empty!'));
+            $error = true;
+        } elseif ($_REQUEST['pma_pw'] != $_REQUEST['pma_pw2']) {
+            $message = PMA_Message::error(__('The passwords aren\'t the same!'));
+            $error = true;
+        }
+    }
+    return array('error' => $error, 'msg' => $message);
+}
+
+/**
+ * Change the password
+ *
+ * @param string  $password
+ * @param string  $message
+ * @param array   $change_password_message
+ *
+ * @return void
+ */
+function PMA_changePassword($password, $message, $change_password_message)
+{
+    // Defines the url to return to in case of error in the sql statement
+    $_url_params = array();
+    $hashing_function = PMA_changePassHashingFunction();
+    $sql_query = 'SET password = '
+        . (($password == '') ? '\'\'' : $hashing_function . '(\'***\')');
+    PMA_ChangePassUrlParamsAndSubmitQuery(
+        $password, $_url_params, $sql_query, $hashing_function
+    );
+
+    $new_url_params = PMA_changePassAuthType($_url_params, $password);
+    PMA_getChangePassMessage($change_password_message, $sql_query);
+    PMA_changePassDisplayPage($message, $sql_query, $new_url_params);
+}
+
+/**
+ * Generate the hashing function
+ *
+ * @return string  $hashing_function
+ */
+function PMA_changePassHashingFunction()
+{
+    if (PMA_isValid($_REQUEST['pw_hash'], 'identical', 'old')) {
+        $hashing_function = 'OLD_PASSWORD';
+    } else {
+        $hashing_function = 'PASSWORD';
+    }
+    return $hashing_function;
+}
+
+/**
+ * Generate the error url and submit the query
+ *
+ * @param string  $password
+ * @param array   $_url_params
+ * @param string  $sql_query
+ * @param string  $hashing_function
+ *
+ * @return void
+ */
+function PMA_ChangePassUrlParamsAndSubmitQuery(
+    $password, $_url_params, $sql_query, $hashing_function
+) {
+    $err_url = 'user_password.php' . PMA_generate_common_url($_url_params);
+    $local_query = 'SET password = ' . (($password == '')
+        ? '\'\''
+        : $hashing_function . '(\'' . PMA_Util::sqlAddSlashes($password) . '\')');
+    if (! @PMA_DBI_try_query($local_query)) {
+        PMA_Util::mysqlDie(PMA_DBI_getError(), $sql_query, false, $err_url);
+    }
+}
+
+/**
+ * Change password authentication type
+ *
+ * @param array   $_url_params
+ * @param string  $password
+ *
+ * @return array   $_url_params
+ */
+function PMA_changePassAuthType($_url_params, $password)
+{
+    /**
+     * Changes password cookie if required
+     * Duration = till the browser is closed for password
+     * (we don't want this to be saved)
+     */
+
+    //    include_once "libraries/plugins/auth/AuthenticationCookie.class.php";
+    //    $auth_plugin = new AuthenticationCookie();
+    // the $auth_plugin is already defined in common.inc.php when this is used
+    global $auth_plugin;
+
+    if ($GLOBALS['cfg']['Server']['auth_type'] == 'cookie') {
+        $GLOBALS['PMA_Config']->setCookie(
+            'pmaPass-' . $GLOBALS['server'],
+            $auth_plugin->blowfishEncrypt(
+                $password,
+                $GLOBALS['cfg']['blowfish_secret']
+            )
+        );
+    }
+    /**
+     * For http auth. mode, the "back" link will also enforce new
+     * authentication
+     */
+    if ($GLOBALS['cfg']['Server']['auth_type'] == 'http') {
+        $_url_params['old_usr'] = 'relog';
+    }
+    return $_url_params;
+}
+
+/**
+ * Display the page
+ *
+ * @param string  $message
+ * @param string  $sql_query
+ * @param array   $_url_params
+ *
+ * @return void
+ */
+function PMA_changePassDisplayPage($message, $sql_query, $_url_params)
+{
+    echo '<h1>' . __('Change password') . '</h1>' . "\n\n";
+    echo PMA_Util::getMessage(
+        $message, $sql_query, 'success'
+    );
+    echo '<a href="index.php'.PMA_generate_common_url($_url_params)
+        .' target="_parent">'. "\n"
+        .'<strong>'.__('Back').'</strong></a>';
+    exit;
+}
+?>
diff --git a/phpmyadmin/version_check.php b/phpmyadmin/version_check.php
new file mode 100644
index 0000000..522e423
--- /dev/null
+++ b/phpmyadmin/version_check.php
@@ -0,0 +1,47 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * A caching proxy for retrieving version information from phpmyadmin.net
+ *
+ * @package PhpMyAdmin
+ */
+
+// Sets up the session
+define('PMA_MINIMUM_COMMON', true);
+require_once 'libraries/common.inc.php';
+
+// Get response text from phpmyadmin.net or from the session
+// Update cache every 6 hours
+if (isset($_SESSION['cache']['version_check'])
+    && time() < $_SESSION['cache']['version_check']['timestamp'] + 3600 * 6
+) {
+    $save = false;
+    $response = $_SESSION['cache']['version_check']['response'];
+} else {
+    $save = true;
+    $file = 'http://www.phpmyadmin.net/home_page/version.json';
+    if (ini_get('allow_url_fopen')) {
+        $response = file_get_contents($file);
+    } else if (function_exists('curl_init')) {
+        $curl_handle = curl_init($file);
+        curl_setopt($curl_handle, CURLOPT_RETURNTRANSFER, 1);
+        $response = curl_exec($curl_handle);
+    }
+}
+
+// Always send the correct headers
+header('Content-type: application/json; charset=UTF-8');
+
+// Save and forward the response only if in valid format
+$data = json_decode($response);
+if (is_object($data) && strlen($data->version) && strlen($data->date)) {
+    if ($save) {
+        $_SESSION['cache']['version_check'] = array(
+            'response' => $response,
+            'timestamp' => time()
+        );
+    }
+    echo $response;
+}
+
+?>
diff --git a/phpmyadmin/view_create.php b/phpmyadmin/view_create.php
new file mode 100644
index 0000000..cd2ec3b
--- /dev/null
+++ b/phpmyadmin/view_create.php
@@ -0,0 +1,235 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * handles creation of VIEWs
+ *
+ * @todo js error when view name is empty (strFormEmpty)
+ * @todo (also validate if js is disabled, after form submission?)
+ * @package PhpMyAdmin
+ */
+
+/**
+ *
+ */
+require_once './libraries/common.inc.php';
+
+/**
+ * Runs common work
+ */
+require './libraries/db_common.inc.php';
+$url_params['goto'] = $cfg['DefaultTabDatabase'];
+$url_params['back'] = 'view_create.php';
+
+$view_algorithm_options = array(
+    'UNDEFINED',
+    'MERGE',
+    'TEMPTABLE',
+);
+
+$view_with_options = array(
+    'CASCADED CHECK OPTION',
+    'LOCAL CHECK OPTION'
+);
+
+if (isset($_REQUEST['createview'])) {
+    /**
+     * Creates the view
+     */
+    $sep = "\r\n";
+
+    $sql_query = 'CREATE';
+
+    if (isset($_REQUEST['view']['or_replace'])) {
+        $sql_query .= ' OR REPLACE';
+    }
+
+    if (PMA_isValid($_REQUEST['view']['algorithm'], $view_algorithm_options)) {
+        $sql_query .= $sep . ' ALGORITHM = ' . $_REQUEST['view']['algorithm'];
+    }
+
+    $sql_query .= $sep . ' VIEW ' . PMA_Util::backquote($_REQUEST['view']['name']);
+
+    if (! empty($_REQUEST['view']['column_names'])) {
+        $sql_query .= $sep . ' (' . $_REQUEST['view']['column_names'] . ')';
+    }
+
+    $sql_query .= $sep . ' AS ' . $_REQUEST['view']['as'];
+
+    if (isset($_REQUEST['view']['with'])) {
+        $options = array_intersect($_REQUEST['view']['with'], $view_with_options);
+        if (count($options)) {
+            $sql_query .= $sep . ' WITH ' . implode(' ', $options);
+        }
+    }
+
+    if (PMA_DBI_try_query($sql_query)) {
+        
+        include_once './libraries/tbl_views.lib.php';
+        
+        // If different column names defined for VIEW
+        $view_columns = array();
+        if (isset($_REQUEST['view']['column_names'])) {
+            $view_columns = explode(',', $_REQUEST['view']['column_names']);
+        }
+        
+        $column_map = PMA_getColumnMap($_REQUEST['view']['as'], $view_columns);
+        $pma_tranformation_data = PMA_getExistingTranformationData($GLOBALS['db']);
+        
+        if ($pma_tranformation_data !== false) {
+            
+            // SQL for store new transformation details of VIEW
+            $new_transformations_sql = PMA_getNewTransformationDataSql(
+                $pma_tranformation_data, $column_map, $_REQUEST['view']['name'],
+                $GLOBALS['db']
+            );            
+            
+            // Store new transformations
+            if ($new_transformations_sql != '') {
+                PMA_DBI_try_query($new_transformations_sql);
+            }
+            
+        }
+        unset($pma_tranformation_data);
+        
+        if ($GLOBALS['is_ajax_request'] != true) {
+            $message = PMA_Message::success();
+            include './' . $cfg['DefaultTabDatabase'];
+        } else {
+            $response = PMA_Response::getInstance();
+            $response->addJSON(
+                'message',
+                PMA_Util::getMessage(
+                    PMA_Message::success(), $sql_query
+                )
+            );
+        }
+        
+        exit;
+        
+    } else {
+        if ($GLOBALS['is_ajax_request'] != true) {
+            $message = PMA_Message::rawError(PMA_DBI_getError());
+        } else {
+            $response = PMA_Response::getInstance();
+            $response->addJSON(
+                'message',
+                PMA_Message::error(
+                    "<i>" . htmlspecialchars($sql_query) . "</i><br /><br />"
+                    . PMA_DBI_getError()
+                )
+            );
+            $response->isSuccess(false);
+            exit;
+        }
+    }
+}
+
+// prefill values if not already filled from former submission
+$view = array(
+    'or_replace' => '',
+    'algorithm' => '',
+    'name' => '',
+    'column_names' => '',
+    'as' => $sql_query,
+    'with' => array(),
+);
+
+if (PMA_isValid($_REQUEST['view'], 'array')) {
+    $view = array_merge($view, $_REQUEST['view']);
+}
+
+$url_params['db'] = $GLOBALS['db'];
+$url_params['reload'] = 1;
+
+/**
+ * Displays the page
+ */
+$htmlString = '<!-- CREATE VIEW options -->'
+    . '<div id="div_view_options">'
+    . '<form method="post" action="view_create.php">'
+    . PMA_generate_common_hidden_inputs($url_params)
+    . '<fieldset>'
+    . '<legend>' . __('Create view')
+    . PMA_Util::showMySQLDocu('SQL-Syntax', 'CREATE_VIEW') . '</legend>'
+    . '<table class="rte_table">'
+    . '<tr><td><label for="or_replace">OR REPLACE</label></td>'
+    . '<td><input type="checkbox" name="view[or_replace]" id="or_replace"';
+if ($view['or_replace']) {
+    $htmlString .= ' checked="checked"';
+}
+$htmlString .= ' value="1" />'
+    . '</td>'
+    . '</tr>'
+    . '<tr>'
+    . '<td><label for="algorithm">ALGORITHM</label></td>'
+    . '<td><select name="view[algorithm]" id="algorithm">';
+
+foreach ($view_algorithm_options as $option) {
+    $htmlString .= '<option value="' . htmlspecialchars($option) . '"';
+    if ($view['algorithm'] === $option) {
+        $htmlString .= ' selected="selected"';
+    }
+    $htmlString .= '>' . htmlspecialchars($option) . '</option>';
+}
+
+$htmlString .= '</select>'
+    . '</td>'
+    . '</tr>'
+    . '<tr><td>' . __('VIEW name') . '</td>'
+    . '<td><input type="text" size="20" name="view[name]" onfocus="this.select()"'
+    . ' value="' . htmlspecialchars($view['name']) . '" />'
+    . '</td>'
+    . '</tr>'
+    . '<tr><td>' . __('Column names') . '</td>'
+    . '<td><input type="text" maxlength="100" size="50" name="view[column_names]"'
+    . ' onfocus="this.select()"'
+    . ' value="' . htmlspecialchars($view['column_names']) . '" />'
+    . '</td>'
+    . '</tr>'
+    . '<tr><td>AS</td>'
+    . '<td>'
+    . '<textarea name="view[as]" rows="' . $cfg['TextareaRows'] . '"'
+    . ' cols="' . $cfg['TextareaCols'] . '"'
+    . ' dir="' . $text_dir . '"';
+
+if ($GLOBALS['cfg']['TextareaAutoSelect'] || true) {
+    $htmlString .= ' onclick="selectContent(this, sql_box_locked, true)"';
+}
+
+$htmlString .= '>' . htmlspecialchars($view['as']) . '</textarea>'
+    . '</td>'
+    . '</tr>'
+    . '<tr><td>WITH</td>'
+    . '<td>';
+
+foreach ($view_with_options as $option) {
+    $htmlString .= '<input type="checkbox" name="view[with][]"';
+    if (in_array($option, $view['with'])) {
+        $htmlString .= ' checked="checked"';
+    }
+    $htmlString .= ' id="view_with_'
+        . str_replace(' ', '_', htmlspecialchars($option)) . '"'
+        . ' value="' . htmlspecialchars($option) . '" />'
+        . '<label for="view_with_' . str_replace(' ', '_', htmlspecialchars($option))
+        . '"> '
+        . htmlspecialchars($option) . '</label><br />';
+}
+
+$htmlString .= '</td>'
+    . '</tr>'
+    . '</table>'
+    . '</fieldset>';
+
+if ($GLOBALS['is_ajax_request'] != true) {
+    $htmlString .= '<fieldset class="tblFooters">'
+        . '<input type="submit" name="createview" value="' . __('Go') . '" />'
+        . '</fieldset>';
+} else {
+    $htmlString .= '<input type="hidden" name="createview" value="1" />'
+        . '<input type="hidden" name="ajax_request" value="1" />';
+}
+
+$htmlString .= '</form>'
+    . '</div>';
+
+echo $htmlString;
diff --git a/phpmyadmin/view_operations.php b/phpmyadmin/view_operations.php
new file mode 100644
index 0000000..8283f42
--- /dev/null
+++ b/phpmyadmin/view_operations.php
@@ -0,0 +1,102 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ *
+ * @package PhpMyAdmin
+ */
+
+/**
+ *
+ */
+require_once './libraries/common.inc.php';
+
+$pma_table = new PMA_Table($GLOBALS['table'], $GLOBALS['db']);
+
+/**
+ * Runs common work
+ */
+require './libraries/tbl_common.inc.php';
+$url_query .= '&goto=view_operations.php&back=view_operations.php';
+$url_params['goto'] = $url_params['back'] = 'view_operations.php';
+
+/**
+ * Gets tables informations
+ */
+
+require './libraries/tbl_info.inc.php';
+$reread_info = false;
+
+/**
+ * Updates if required
+ */
+if (isset($_REQUEST['submitoptions'])) {
+    $_message = '';
+    $warning_messages = array();
+
+    if (isset($_REQUEST['new_name'])) {
+        if ($pma_table->rename($_REQUEST['new_name'])) {
+            $_message .= $pma_table->getLastMessage();
+            $result = true;
+            $GLOBALS['table'] = $pma_table->getName();
+            $reread_info = true;
+            $reload = true;
+        } else {
+            $_message .= $pma_table->getLastError();
+            $result = false;
+        }
+    }
+}
+
+if (isset($result)) {
+    // set to success by default, because result set could be empty
+    // (for example, a table rename)
+    $_type = 'success';
+    if (empty($_message)) {
+        $_message = $result
+            ? __('Your SQL query has been executed successfully')
+            : __('Error');
+        // $result should exist, regardless of $_message
+        $_type = $result ? 'success' : 'error';
+    }
+    if (! empty($warning_messages)) {
+        $_message = new PMA_Message;
+        $_message->addMessages($warning_messages);
+        $_message->isError(true);
+        unset($warning_messages);
+    }
+    echo PMA_Util::getMessage(
+        $_message, $sql_query, $_type, $is_view = true
+    );
+    unset($_message, $_type);
+}
+
+$url_params['goto'] = 'view_operations.php';
+$url_params['back'] = 'view_operations.php';
+
+/**
+ * Displays the page
+ */
+?>
+<!-- Table operations -->
+<div class="operations_half_width">
+<form method="post" action="view_operations.php">
+<?php echo PMA_generate_common_hidden_inputs($GLOBALS['db'], $GLOBALS['table']); ?>
+<input type="hidden" name="reload" value="1" />
+<fieldset>
+    <legend><?php echo __('Operations'); ?></legend>
+
+    <table>
+    <!-- Change view name -->
+    <tr><td><?php echo __('Rename view to'); ?></td>
+        <td><input type="text" size="20" name="new_name" onfocus="this.select()"
+                value="<?php echo htmlspecialchars($GLOBALS['table']); ?>" />
+        </td>
+    </tr>
+    </table>
+</fieldset>
+<fieldset class="tblFooters">
+        <input type="submit" name="submitoptions" value="<?php echo __('Go'); ?>" />
+</fieldset>
+</form>
+</div>
+
diff --git a/phpmyadmin/webapp.php b/phpmyadmin/webapp.php
new file mode 100644
index 0000000..48da877
--- /dev/null
+++ b/phpmyadmin/webapp.php
@@ -0,0 +1,55 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * generate an WebApp file for Prism / WebRunner
+ *
+ * @package PhpMyAdmin
+ * @see     http://wiki.mozilla.org/Prism
+ */
+
+/**
+ * @ignore
+ */
+define('PMA_MINIMUM_COMMON', true);
+/**
+ * Gets core libraries and defines some variables
+ */
+require './libraries/common.inc.php';
+/**
+ * ZIP file handler.
+ */
+require './libraries/zip.lib.php';
+
+// ini file
+$parameters = array(
+    'id'        => 'phpMyAdmin@' . $_SERVER['HTTP_HOST'],
+    'uri'       => $GLOBALS['PMA_Config']->get('PmaAbsoluteUri'),
+    'status'    => 'yes',
+    'location'  => 'no',
+    'sidebar'   => 'no',
+    'navigation' => 'no',
+    'icon'      => 'phpMyAdmin',
+);
+
+// dom sript file
+// none need yet
+
+// icon
+$icon = 'favicon.ico';
+
+// name
+$name = 'phpMyAdmin.webapp';
+
+$ini_file = "[Parameters]\n";
+foreach ($parameters as $key => $value) {
+    $ini_file .= $key . '=' . $value . "\n";
+}
+
+PMA_downloadHeader($name, 'application/webapp', 0, false);
+
+$zip = new ZipFile;
+$zip->setDoWrite();
+$zip->addFile($ini_file, 'webapp.ini');
+$zip->addFile(file_get_contents($icon), 'phpMyAdmin.ico');
+$zip->file();
+?>

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/debian-med/openemr.git



More information about the debian-med-commit mailing list